/* ============================================================
   CEMENT PLANT ERP - custom stylesheet (no external framework,
   so the app keeps working even with no internet on the plant floor)
   ============================================================ */

:root {
  --bg: #eef1f6;
  --surface: #ffffff;
  --surface-soft: #f7f8fc;
  --ink: #1b1f2e;
  --ink-soft: #667085;
  --border: #e3e6ef;
  --radius: 18px;
  --radius-sm: 12px;
  --shadow-sm: 0 1px 2px rgba(16, 24, 40, .06);
  --shadow-md: 0 6px 18px rgba(16, 24, 40, .08);
  --shadow-lg: 0 16px 40px rgba(16, 24, 40, .18);

  --app-max-width: 440px;

  --sidebar-from: #161a29;
  --sidebar-to: #242b42;
  --sidebar-ink: #a7adc4;
  --sidebar-active: rgba(255, 255, 255, .08);

  --primary: #2563eb;
  /* modern blue - app brand / links / active nav */
  --primary-dark: #1d4ed8;
  --primary-soft: #e6eefe;
  --accent: #e2a13d;
  /* safety amber - plant signage colour, kept for targets/production */
  --accent-soft: #fdf1de;
  --accent-ink: #3a2a08;
  --good: #16a34a;
  --good-soft: #e3f7ea;
  --bad: #dc3b2e;
  --bad-soft: #fbe6e3;
  --info: #2d6ca8;
  --info-soft: #e3ecf6;
  /* hot pink - "act now" (Need Vehicle, Priority Tasks); nothing else uses it */
  --urgent: #db2777;
  --urgent-soft: #fce7f3;
  --urgent-ring: #f9a8d4;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 14.5px;
  line-height: 1.5;
  opacity: 1;
  transition: opacity .18s ease;
}

/* Every internal link navigation fades the outgoing page out (app.js adds
   this class then delays the real navigation briefly) so switching pages,
   including bottom-tab-bar taps, reads as one smooth app transition
   instead of a hard browser flash-to-white. */
body.page-leaving {
  opacity: 0;
}

/* Every page fades its content in on load - pure CSS, so it plays
   immediately even before app.js finishes, on every page including ones
   loaded inside the Masters popup iframe. Opacity-only on purpose: a
   `transform` here (even translateY(0) left behind by fill-mode:both)
   would make .content a new containing block for its position:fixed
   descendants (the Masters modal, notification panel, alert popup all
   live inside .content) and silently break their full-screen overlay. */
@keyframes pageContentIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

a {
  color: var(--primary);
  text-decoration: none;
}

a:hover {
  text-decoration: none;
}

.eyebrow {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  border: 1px solid var(--border);
  padding: 2px 8px;
  border-radius: 3px;
  background: var(--surface);
}

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

.sidebar {
  width: 236px;
  flex-shrink: 0;
  background: linear-gradient(180deg, var(--sidebar-from), var(--sidebar-to));
  color: var(--sidebar-ink);
  padding: 0 10px 20px;
}

.sidebar-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 8px 16px;
  margin: 0 -10px 4px;
  padding-left: 18px;
  padding-right: 18px;
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.brand-badge {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 9px;
  background: linear-gradient(135deg, var(--accent), #ffd485);
  color: #3a2405;
  font-weight: 800;
  font-size: 15px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 3px 8px rgba(0, 0, 0, .3);
}

.brand-logo {
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  border-radius: 9px;
  object-fit: cover;
  box-shadow: 0 3px 8px rgba(0, 0, 0, .3);
}

.sidebar-brand-text {
  display: flex;
  flex-direction: column;
  color: #fff;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .01em;
  line-height: 1.25;
}

.sidebar-brand-text small {
  display: block;
  font-weight: 400;
  font-size: 10.5px;
  letter-spacing: .08em;
  color: var(--accent);
  text-transform: uppercase;
  margin-top: 2px;
}

.sidebar-group-label {
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: #7d8399;
  padding: 16px 8px 6px;
}

.sidebar-group-label.is-collapsible {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  user-select: none;
}

.sidebar-group-label.is-collapsible::after {
  content: '';
  width: 6px;
  height: 6px;
  margin-right: 4px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform .15s ease;
}

.sidebar-group-label.is-collapsed::after { transform: rotate(-45deg); }
.sidebar-group-label.is-collapsible:hover { color: #aab0c4; }
.sidebar-group-body[hidden] { display: none; }

.sidebar a.nav-link {
  display: flex;
  align-items: center;
  gap: 11px;
  margin: 1px 0;
  padding: 9px 12px;
  border-radius: var(--radius-sm);
  color: var(--sidebar-ink);
  font-size: 13.5px;
  transition: background .15s ease, color .15s ease;
}

.sidebar a.nav-link svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  opacity: .85;
}

.sidebar a.nav-link:hover {
  background: var(--sidebar-active);
  color: #fff;
  text-decoration: none;
}

.sidebar a.nav-link:hover svg {
  opacity: 1;
}

.sidebar a.nav-link.active {
  background: linear-gradient(135deg, var(--primary), #6d63f2);
  color: #fff;
  font-weight: 600;
  box-shadow: 0 4px 12px rgba(79, 70, 229, .4);
}

.sidebar-backdrop {
  display: none;
}

/* ---------- bottom tab bar (mobile app-style nav) ---------- */
.bottom-tabbar {
  display: none;
  position: relative;
}

.tab-indicator {
  position: absolute;
  top: 4px;
  height: calc(100% - 8px);
  border-radius: 14px;
  background: linear-gradient(135deg, var(--primary-soft), var(--accent-soft));
  transition: transform .32s cubic-bezier(.34, 1.1, .4, 1), width .32s cubic-bezier(.34, 1.1, .4, 1);
  z-index: 0;
  pointer-events: none;
}

.tab-link {
  position: relative;
  z-index: 1;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  padding: 8px 4px 7px;
  color: var(--ink-soft);
  font-size: 10.5px;
  font-weight: 600;
  border: none;
  background: none;
  cursor: pointer;
  font-family: inherit;
  transition: color .2s ease;
}

.tab-link:hover {
  text-decoration: none;
  color: var(--ink);
}

.tab-link svg {
  width: 21px;
  height: 21px;
  transition: transform .3s cubic-bezier(.34, 1.56, .64, 1);
}

.tab-link.active {
  color: var(--primary);
}

.tab-link.active svg {
  transform: translateY(-1px) scale(1.08);
}

.main {
  flex: 1;
  min-width: 0;
}

/* Company name bar - pinned to the very top of every page (sidebar is a
   slide-in drawer app-wide, see the "app-style layout" block further down,
   so without this the company name would only ever be visible once the
   drawer is opened). Sticky, not fixed, so it scrolls up with the page but
   stops and stays pinned at the top instead of scrolling away. */
.brand-topbar {
  position: sticky;
  top: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
}

.brand-topbar-logo {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
}

.brand-topbar-badge {
  width: 28px;
  height: 28px;
  border-radius: 8px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .8);
  color: var(--primary-dark);
  font-weight: 800;
  font-size: 14px;
}

.brand-topbar-name {
  flex: 1;
  font-weight: 700;
  font-size: 15px;
  letter-spacing: .01em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.brand-topbar-logout {
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .8);
  color: var(--primary-dark);
}

.brand-topbar-logout svg {
  width: 15px;
  height: 15px;
}

.brand-topbar-logout:hover {
  background: #fff;
}

.topbar {
  background: rgba(255, 255, 255, .9);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border);
  padding: 12px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: sticky;
  top: 52px;
  /* sits right below the sticky .brand-topbar instead of underneath it */
  z-index: 20;
  gap: 12px;
}

.topbar-title {
  font-size: 18px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.topbar-user {
  font-size: 13px;
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  gap: 10px;
  flex-shrink: 0;
}

.topbar-user strong {
  color: var(--ink);
}

.topbar-icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--surface-soft);
  color: var(--ink-soft);
  transition: background .15s ease, color .15s ease;
  flex-shrink: 0;
}

.topbar-icon-btn:hover {
  background: var(--primary-soft);
  color: var(--primary-dark);
}

.topbar-icon-btn svg {
  width: 17px;
  height: 17px;
}

.sku-row-card {
  background: var(--primary-soft);
  border: 1px solid var(--border);
  box-shadow: none;
}

.sku-row-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 12px;
  font-size: 14px;
  color: var(--ink);
}

.sku-row-head .icon-chip {
  margin-bottom: 0;
  background: rgba(255, 255, 255, .8);
}

.sku-row-remove-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-left: auto;
  border-radius: 7px;
  background: transparent;
  color: var(--ink-soft);
  flex-shrink: 0;
  transition: background .15s ease, color .15s ease;
}

.sku-row-remove-btn svg {
  width: 14px;
  height: 14px;
}

.sku-row-remove-btn:hover {
  background: #fee2e2;
  color: #dc2626;
}

/* The Bags field is now the row's last child (the old Remove-button div
   used to hold that spot) - cancel filter-form's :last-child button-align
   flex hack so it goes back to a normal label-above-input block. */
.item-row .filter-form>div:last-child {
  display: block;
  align-items: unset;
}

/* ---------- Masters bottom-sheet modal (Settings page) - opens a master
   page inline in an iframe instead of navigating away. See settings.php
   and header.php's $embedMode. ---------- */
.masters-modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(12, 14, 24, .55);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  opacity: 0;
  pointer-events: none;
  transition: opacity .28s ease;
}

.masters-modal-overlay.is-open {
  opacity: 1;
  pointer-events: auto;
}

.masters-modal {
  background: var(--surface);
  width: 100%;
  max-width: var(--app-max-width);
  height: 70vh;
  border-radius: 20px 20px 0 0;
  box-shadow: 0 -10px 40px rgba(0, 0, 0, .3);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateY(100%);
  transition: transform .38s cubic-bezier(.32, .72, 0, 1);
}

.masters-modal-overlay.is-open .masters-modal {
  transform: translateY(0);
}

/* Filter bottom-sheet reuses the whole .masters-modal shell (same overlay,
   slide-up, header+close), just shorter - filters are usually a handful of
   fields, not a full page of content. */
.filter-modal-sm {
  height: 50vh;
}

/* Utilities hub's popup needs more room than the default 70vh Masters
   sheet - taller so its multi-section pages (form + history list) don't
   feel cramped. */
.masters-modal-lg {
  height: 80vh;
}

.filter-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
}

.masters-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  flex-shrink: 0;
  border-bottom: 1px solid var(--border);
  font-weight: 700;
  font-size: 15px;
  background: var(--primary-soft);
  color: var(--ink);
}

.masters-modal-close {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  border: none;
  flex-shrink: 0;
  background: rgba(0, 0, 0, .06);
  color: var(--ink-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

.masters-modal-close:hover {
  background: rgba(0, 0, 0, .12);
}

.masters-modal-frame {
  flex: 1;
  width: 100%;
  border: none;
}

/* ---------- notification bell panel (reuses the same bottom-sheet look
   as the Masters popup above, swapping the iframe for a scrollable list). ---------- */
.notif-modal-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
}

.notif-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  margin-bottom: 10px;
  background: var(--surface-soft);
  border-left: 4px solid var(--border);
  transition: background .15s ease;
}

.notif-item-unread {
  background: var(--info-soft);
  border-left-color: var(--info);
}

.notif-item-link {
  flex: 1;
  min-width: 0;
  text-decoration: none;
  color: inherit;
  display: block;
}

.notif-item-link:active {
  opacity: .8;
}

.notif-item-title {
  font-weight: 700;
  font-size: 13.5px;
  color: var(--ink);
}

.notif-item-meta {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 3px;
}

.notif-item-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.notif-item-read-btn {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .8);
  color: var(--ink-soft);
  cursor: pointer;
  padding: 0;
  font-family: inherit;
  flex-shrink: 0;
}

.notif-item-read-btn svg {
  width: 13px;
  height: 13px;
}

.notif-item-read-btn:hover {
  background: var(--good-soft);
  color: var(--good);
}

.user-avatar {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-weight: 700;
  font-size: 12.5px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.role-badge {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: 999px;
  white-space: nowrap;
}

.role-badge.role-admin {
  background: var(--primary-soft);
  color: var(--primary-dark);
}

.role-badge.role-plant {
  background: var(--accent-soft);
  color: var(--accent-ink);
}

.role-badge.role-cf {
  background: var(--info-soft);
  color: var(--info);
}

.content {
  padding: 22px 24px 48px;
  animation: pageContentIn .34s cubic-bezier(.22, .88, .38, 1) both;
}

/* ---------- cards / grid ---------- */
.card {
  background: linear-gradient(145deg, #ffffff 0%, var(--primary-soft) 62%, var(--accent-soft) 135%);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 18px 20px;
  margin-bottom: 20px;
  transition: box-shadow .15s ease;
}

.card h2,
.card h3 {
  margin-top: 0;
}

.card>h2:first-child,
.card>h3:first-child {
  display: flex;
  align-items: center;
  gap: 10px;
}

/* Whole-card colour accents - a stronger tint + left border for a card
   that should stand out as a distinct, colourful block on the page
   instead of the default subtle blue/amber wash every card gets. */
.card-accent-purple {
  border-left: 4px solid transparent;
  background: linear-gradient(120deg, #8b6ff0, #6d4fd6);
}

.card-accent-purple h3 {
  color: #fff;
}

.card-accent-purple .icon-chip {
  background: rgba(255, 255, 255, .25) !important;
  color: #fff !important;
}

.card-accent-purple .help-text {
  color: rgba(255, 255, 255, .75);
}

/* ---------- icon chips (heading icons + stat badges) ---------- */
.icon-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 9px;
  flex-shrink: 0;
  margin-bottom: 6px;
}

.icon-chip svg {
  width: 16px;
  height: 16px;
}

.icon-chip-lg {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  margin-bottom: 10px;
}

.icon-chip-lg svg {
  width: 22px;
  height: 22px;
}

.icon-chip-green {
  background: var(--good-soft);
  color: var(--good);
}

.icon-chip-amber {
  background: var(--accent-soft);
  color: #a86a12;
}

.icon-chip-blue {
  background: var(--info-soft);
  color: var(--info);
}

.icon-chip-red {
  background: var(--bad-soft);
  color: var(--bad);
}

.icon-chip-purple {
  background: var(--primary-soft);
  color: var(--primary-dark);
}

/* Heading text picks up the same colour as its page's icon chip */
.heading-text-green {
  color: var(--good);
}

.heading-text-amber {
  color: #a86a12;
}

.heading-text-blue {
  color: var(--info);
}

.heading-text-red {
  color: var(--bad);
}

.heading-text-purple {
  color: var(--primary-dark);
}

.grid {
  display: grid;
  gap: 16px;
}

.grid-2 {
  grid-template-columns: repeat(2, 1fr);
}

.grid-3 {
  grid-template-columns: repeat(3, 1fr);
}

.grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

/* The app shell is always mobile-width now (see var(--app-max-width)), so
   these only need to protect against genuinely tiny phones - grid-2 should
   stay 2-up almost everywhere; grid-3/4 need a bit more room before that's
   comfortable. NOTE: 380px used to be the grid-2 collapse point, but that's
   wider than very common phones like the 375px-wide iPhone SE/8/X/11 Pro,
   so fields were stacking instead of sitting side by side on ordinary
   devices - pulled down to 300px so grid-2 only collapses on genuinely
   tiny screens. */
@media (max-width: 480px) {

  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr 1fr;
  }
}

@media (max-width: 300px) {

  .grid-2,
  .grid-3,
  .grid-4 {
    grid-template-columns: 1fr;
  }
}

.stat-card {
  text-align: center;
}

.stat-card .stat-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-soft);
  font-weight: 700;
}

.stat-card .stat-value {
  font-size: 26px;
  font-weight: 700;
  margin-top: 4px;
}

.stat-card .stat-sub {
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 2px;
}

.stat-card-compact {
  padding: 14px 16px;
}

.stat-card-compact .stat-value {
  font-size: 18px;
}

.stat-card-compact .stat-label {
  font-size: 10px;
}

.stat-card-compact .stat-sub {
  font-size: 11px;
}

/* ---------- native-app dashboard components ---------- */
.welcome-card {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}

.welcome-avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  flex-shrink: 0;
  background: linear-gradient(135deg, var(--primary), #6d94f5);
  color: #fff;
  font-weight: 700;
  font-size: 19px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: var(--shadow-md);
}

.welcome-name {
  font-size: 17px;
  font-weight: 700;
}

.welcome-sub {
  font-size: 12.5px;
  color: var(--ink-soft);
}

/* Glassy blue hero card - the dashboard's opening "welcome back" moment */
.welcome-hero {
  position: relative;
  overflow: hidden;
  background: var(--primary-soft);
  border-radius: var(--radius);
  padding: 20px;
  color: var(--ink);
  box-shadow: var(--shadow-sm);
  margin-bottom: 20px;
}

.welcome-hero::after {
  content: '';
  position: absolute;
  top: -45%;
  right: -18%;
  width: 65%;
  height: 150%;
  background: radial-gradient(circle, rgba(37, 99, 235, .12), transparent 70%);
  pointer-events: none;
}

.welcome-hero-top {
  display: flex;
  align-items: center;
  gap: 12px;
  position: relative;
  z-index: 1;
}

.welcome-hero-greeting {
  font-size: 12.5px;
  color: var(--ink-soft);
}

.welcome-hero-name {
  font-size: 19px;
  font-weight: 700;
  color: var(--ink);
}

/* Row of round icon buttons (Notifications, Settings, Logout) pinned to
   the far right of the welcome-hero - a shared class instead of a
   separate one per icon, so adding another button is just one more
   .welcome-hero-icon-btn in the row. */
.welcome-hero-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex-shrink: 0;
}

.welcome-hero-icon-btn {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .8);
  color: var(--primary-dark);
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
}

.welcome-hero-icon-btn svg {
  width: 17px;
  height: 17px;
}

.welcome-hero-icon-btn:hover {
  background: #fff;
}

.notif-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 3px;
  border-radius: 999px;
  background: #e0554f;
  color: #fff;
  font-size: 9.5px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
  box-shadow: 0 0 0 2px rgba(0, 0, 0, .15);
}

/* Generic colourful page header - auto-rendered by header.php on any page
   that sets $hideTopbar without $customHero, using that page's own
   heading icon/colour so every screen gets a distinct accent for free. */
.page-header {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  margin-bottom: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.page-header .icon-chip-lg {
  margin-bottom: 0;
}

.page-header-title {
  font-size: 16.5px;
  font-weight: 700;
}

/* Tinted variants keyed to the page's own heading icon colour, so the
   header bar itself carries colour instead of staying plain white with
   only the icon chip standing out. Light wash, not a solid fill - and the
   icon-chip-lg gets a near-white circle instead of its own same-shade
   soft background, so it doesn't just blend into the header behind it. */
.page-header-green {
  background: var(--good-soft);
  border-color: transparent;
}

.page-header-amber {
  background: var(--accent-soft);
  border-color: transparent;
}

.page-header-blue {
  background: var(--info-soft);
  border-color: transparent;
}

.page-header-red {
  background: var(--bad-soft);
  border-color: transparent;
}

.page-header-purple {
  background: #f1edfe;
  border-color: transparent;
}

.page-header-green .icon-chip-lg,
.page-header-amber .icon-chip-lg,
.page-header-blue .icon-chip-lg,
.page-header-red .icon-chip-lg,
.page-header-purple .icon-chip-lg {
  background: rgba(255, 255, 255, .8);
}

.page-header-settings {
  margin-left: auto;
  flex-shrink: 0;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--surface-soft);
  color: var(--ink-soft);
  border: none;
  cursor: pointer;
  font-family: inherit;
  padding: 0;
}

.page-header-settings svg {
  width: 16px;
  height: 16px;
}

.page-header-settings:hover {
  background: var(--border);
}

/* Filter icon while a filter is applied (see the filter sheet in app.js). */
.page-header-settings.has-filter {
  position: relative;
  color: var(--accent, #4f46e5);
}

.page-header-settings.has-filter::after {
  content: '';
  position: absolute;
  top: 5px;
  right: 5px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--bad, #e5484d);
  border: 1.5px solid var(--surface, #fff);
}

/* When both Settings and the filter/extra icon appear together (e.g. Admin
   viewing a page with a filter sheet), only the first should absorb the
   auto-margin that pushes the group to the right. */
.page-header-settings+.page-header-settings {
  margin-left: 0;
}

.welcome-hero-sub {
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  position: relative;
  z-index: 1;
}

.section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 22px 0 10px;
}

.section-head h3 {
  margin: 0;
  font-size: 15.5px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.section-head h3 .icon-chip {
  margin-bottom: 0;
}

/* Notification bell moved out of the welcome-hero (next to Settings) onto
   the "Today's Snapshot" section-head instead, so it sits on plain page
   background rather than the hero's dark gradient - needs its own solid
   colour instead of reusing .welcome-hero-icon-btn's translucent-white look. */
.section-notif-btn {
  position: relative;
  width: 34px;
  height: 34px;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  background: var(--bad-soft);
  color: var(--bad);
  border: none;
  padding: 0;
  cursor: pointer;
  font-family: inherit;
}

.section-notif-btn svg {
  width: 16px;
  height: 16px;
}

/* ---------- "Activity card" row - white cards with an icon-circle+label
   row on top and a big value below, used app-wide for every stat summary
   row (dashboards, reports, list pages). ---------- */
.activity-card-row {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 2px;
}

.activity-card-row::-webkit-scrollbar {
  display: none;
}

.activity-card {
  flex: 0 0 150px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  display: block;
}

.activity-card-top {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
}

.activity-card-icon {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.activity-card-icon svg {
  width: 14px;
  height: 14px;
}

.activity-card-label {
  flex: 1;
  min-width: 0;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.activity-card-view {
  flex-shrink: 0;
  color: var(--ink-soft);
  display: flex;
}

.activity-card-view svg {
  width: 13px;
  height: 13px;
}

.activity-card-value {
  font-size: 22px;
  font-weight: 700;
  color: var(--ink);
}

.activity-card-icon-purple { background: #f1edfe; color: #6d4fd6; }
.activity-card-icon-red { background: var(--bad-soft); color: var(--bad); }
.activity-card-icon-blue { background: var(--info-soft); color: var(--info); }
.activity-card-icon-green { background: var(--good-soft); color: var(--good); }
.activity-card-icon-amber { background: var(--accent-soft); color: #a86a12; }

.section-notif-btn:hover {
  background: var(--bad);
  color: #fff;
}

.section-head-link {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--primary);
  display: flex;
  align-items: center;
  gap: 2px;
  flex-shrink: 0;
}

.pending-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 16px;
}

.pending-card-title {
  font-size: 15.5px;
  font-weight: 700;
  margin-top: 8px;
  line-height: 1.35;
}

.pending-card-meta {
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 4px;
}

.pending-card-stats {
  display: flex;
  gap: 18px;
  font-size: 13px;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

.pending-card-stats>div {
  display: flex;
  align-items: center;
  gap: 5px;
  color: var(--ink-soft);
}

.pending-card-stats svg {
  width: 15px;
  height: 15px;
}

.pending-card-stats strong {
  color: var(--ink);
}

.pending-card-actions {
  display: flex;
  gap: 10px;
  margin-top: 14px;
}

.pending-card-actions .btn {
  flex: 1;
}

/* ---------- Plant Head's Tasks page - the whole task box is the tap
   target; an empty tick-box on the right is the visual cue that it's
   tappable, a filled checkmark replaces it once a task is done
   (non-interactive at that point - there's no un-complete). ---------- */
.task-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.task-row-title {
  font-weight: 700;
  font-size: 13.5px;
}

.task-row-check {
  flex-shrink: 0;
  display: flex;
  color: var(--good);
}

.task-row-check svg {
  width: 20px;
  height: 20px;
}

.task-row-tickbox {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  border-radius: 8px;
  border: 2px solid var(--border);
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  color: transparent;
}

.task-row-btn:hover .task-row-tickbox {
  border-color: var(--good);
}

.task-row-tickbox svg {
  width: 14px;
  height: 14px;
}

.task-row-form {
  margin: 0;
}

.task-row-btn {
  width: 100%;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.task-row-btn:active {
  transform: scale(.98);
}

/* ---------- red "task pending" banner on Plant Head's dashboard ---------- */
.task-pending-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  background: linear-gradient(135deg, #e0554f, #c23324);
  color: #fff;
  text-decoration: none;
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  margin-bottom: 16px;
  box-shadow: 0 6px 18px rgba(194, 51, 36, .35);
}

.task-pending-banner svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
}

.task-pending-banner-title {
  font-size: 14.5px;
  font-weight: 700;
}

.task-pending-banner-sub {
  font-size: 12.5px;
  opacity: .9;
  margin-top: 1px;
}

.task-pending-banner-arrow {
  margin-left: auto;
  flex-shrink: 0;
}

/* ---------- highlighted task chips inside the "Tasks Pending" popup ---------- */
/* Plain numbered list of pending task titles inside the "Tasks Pending"
   popup - no per-task colour/chip styling, just simple text. */
.modal-task-list {
  margin: 0;
  padding-left: 20px;
  text-align: left;
  color: var(--ink);
}

.modal-task-list li {
  margin-bottom: 5px;
  font-size: 12.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.modal-task-list li:last-child {
  margin-bottom: 0;
}

.quick-actions-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.action-tile {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px;
  border-radius: 16px;
  text-decoration: none;
  min-height: 44px;
}

/* Full-width illustration area anchored near the bottom, label+arrow
   pinned to the top (see .action-tile-bottom's order below) - an actual
   unDraw illustration (see tabIllustration() in includes/functions.php),
   not a line icon, matching the reference's big-graphic composition. */
.action-tile-icon {
  order: 2;
  position: relative;
  width: 100%;
  margin-top: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}

.action-tile-icon svg {
  width: 100%;
  height: 84px;
  margin: 0 auto;
  display: block;
}

.action-tile-bottom {
  order: 1;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 6px;
}

.action-tile-label {
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.25;
}

.action-tile-bottom svg {
  width: 15px;
  height: 15px;
  color: var(--ink-soft);
  flex-shrink: 0;
  margin-top: 1px;
}

.action-tile-amber {
  background: var(--accent-soft);
  --primary-svg-color: #d99a2b;
}

.action-tile-purple {
  background: #f1edfe;
  --primary-svg-color: #8b6ff0;
}

.action-tile-green {
  background: var(--good-soft);
  --primary-svg-color: var(--good);
}

.action-tile-red {
  background: var(--bad-soft);
  --primary-svg-color: var(--bad);
}

.action-tile-blue {
  background: var(--info-soft);
  --primary-svg-color: var(--info);
}

/* A tile with work held up behind it (tileAttentionBadge() in
   includes/functions.php) - light red whatever its usual colour, so red only
   ever means "needs you now". */
.action-tile.needs-attention,
body.page-dashboard .action-tile.needs-attention {
  background: linear-gradient(180deg, #fff5f4 0%, var(--bad-soft) 100%);
  box-shadow: inset 0 0 0 1.5px rgba(220, 59, 46, .3);
  --primary-svg-color: var(--bad);
}
.action-tile-attention {
  order: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: -4px;
  font-size: 10.5px;
  font-weight: 500;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--bad);
}
.action-tile-attention-dot {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
  border-radius: 50%;
  background: var(--bad);
  color: #fff;
  font-size: 10px;
  line-height: 15px;
  text-align: center;
  letter-spacing: 0;
}
.action-tile-attention-reason {
  order: 1;
  margin-top: -8px;
  font-size: 11.5px;
  color: var(--bad);
  line-height: 1.3;
}

/* Shared by the Utilities hub AND the Settings > Masters grid - both reuse
   .action-tile's whole look (see above) but are real <button>s (they open a
   modal iframe, not a page navigation) instead of <a> tags, so this resets
   the browser's default button chrome (.action-tile itself still supplies
   padding/radius/layout). On top of that they get their own frosted-glass
   treatment (see .card-glass below, same idea per-colour) instead of
   .action-tile's flat soft-tint background - scoped to .glass-tile
   specifically so the plain dashboard Quick Actions tiles that also use
   .action-tile-red etc. are untouched. */
.glass-tile {
  position: relative;
  overflow: hidden;
  border: none;
  background: none;
  font-family: inherit;
  cursor: pointer;
  text-align: left;
  width: 100%;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
}

.glass-tile::after {
  content: '';
  position: absolute;
  top: -40%;
  right: -20%;
  width: 65%;
  height: 140%;
  background: radial-gradient(circle, rgba(255, 255, 255, .35), transparent 70%);
  pointer-events: none;
}

.glass-tile.action-tile-red {
  background: linear-gradient(135deg, rgba(220, 59, 46, .16), rgba(255, 255, 255, .08));
  border: 1px solid rgba(220, 59, 46, .3);
  box-shadow: 0 8px 22px rgba(220, 59, 46, .16), inset 0 1px 0 rgba(255, 255, 255, .5);
}

.glass-tile.action-tile-amber {
  background: linear-gradient(135deg, rgba(226, 161, 61, .22), rgba(255, 220, 150, .10));
  border: 1px solid rgba(226, 161, 61, .4);
  box-shadow: 0 8px 22px rgba(226, 161, 61, .18), inset 0 1px 0 rgba(255, 255, 255, .5);
}

.glass-tile.action-tile-green {
  background: linear-gradient(135deg, rgba(22, 163, 74, .16), rgba(255, 255, 255, .08));
  border: 1px solid rgba(22, 163, 74, .32);
  box-shadow: 0 8px 22px rgba(22, 163, 74, .16), inset 0 1px 0 rgba(255, 255, 255, .5);
}

.glass-tile.action-tile-blue {
  background: linear-gradient(135deg, rgba(45, 108, 168, .16), rgba(255, 255, 255, .08));
  border: 1px solid rgba(45, 108, 168, .32);
  box-shadow: 0 8px 22px rgba(45, 108, 168, .16), inset 0 1px 0 rgba(255, 255, 255, .5);
}

.glass-tile.action-tile-purple {
  background: linear-gradient(135deg, rgba(139, 111, 240, .18), rgba(255, 255, 255, .08));
  border: 1px solid rgba(139, 111, 240, .32);
  box-shadow: 0 8px 22px rgba(139, 111, 240, .18), inset 0 1px 0 rgba(255, 255, 255, .5);
}

/* Icon badge sits on its own frosted-white circle instead of the flat
   soft-tint .icon-chip-red/-amber/etc normally use, so it reads clearly
   against the tinted glass tile behind it - the colour variant class still
   supplies the icon's own stroke colour. */
.glass-tile .icon-chip-lg {
  background: rgba(255, 255, 255, .55);
  backdrop-filter: blur(6px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* ---------- glassy highlight card (headline totals) ---------- */
.card-glass {
  position: relative;
  background: linear-gradient(135deg, rgba(226, 161, 61, .22), rgba(255, 220, 150, .10));
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid rgba(226, 161, 61, .4);
  box-shadow: 0 8px 28px rgba(226, 161, 61, .22), inset 0 1px 0 rgba(255, 255, 255, .5);
  overflow: hidden;
}

.card-glass::after {
  content: '';
  position: absolute;
  top: -40%;
  right: -20%;
  width: 65%;
  height: 140%;
  background: radial-gradient(circle, rgba(255, 255, 255, .35), transparent 70%);
  pointer-events: none;
}

.card-glass .stat-label {
  color: #8a5a10;
}

.card-glass .stat-value {
  color: #5c3b06;
}

.card-glass .stat-sub {
  color: #93672a;
}

.card-glass .icon-chip,
.card-glass .icon-chip-lg {
  background: rgba(255, 255, 255, .55);
  backdrop-filter: blur(6px);
  color: #a3690f;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .6);
}

/* ---------- forms ---------- */
label {
  display: block;
  font-size: 13px;
  font-weight: 700;
  margin: 12px 0 4px;
  color: var(--primary-dark);
}

input[type=text],
input[type=number],
input[type=date],
input[type=time],
input[type=datetime-local],
input[type=password],
input[type=file],
input[type=url],
input[type=email],
input[type=tel],
input[type=month],
select,
textarea {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: 12px;
  font-size: 14px;
  background: #fff;
  color: var(--ink);
  font-family: inherit;
}

input:focus,
select:focus,
textarea:focus {
  outline: 3px solid var(--primary-soft);
  outline-offset: 0;
  border-color: var(--primary);
}

/* ---------- show/hide (eye) toggle every password field gets, added by
   assets/js/password-toggle.js - wraps the input rather than styling it
   directly, so each page's own input sizing/border rules keep applying. ---------- */
.pw-toggle-wrap {
  position: relative;
  display: block;
  width: 100%;
}
.pw-toggle-wrap input[type=password],
.pw-toggle-wrap input[type=text] {
  width: 100%;
  box-sizing: border-box;
  padding-right: 40px;
}
.pw-toggle-btn {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: none;
  padding: 0;
  cursor: pointer;
  color: var(--ink-soft);
  border-radius: 8px;
}
.pw-toggle-btn:hover {
  color: var(--ink);
  background: var(--surface-soft);
}
.pw-toggle-btn svg {
  width: 18px;
  height: 18px;
}

.form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px 14px;
}

.form-row>div {
  min-width: 0;
}

@media (max-width: 300px) {
  .form-row {
    grid-template-columns: 1fr;
  }
}

.help-text {
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 3px;
}

/* ---------- filter bars (the "Filters" accordion on list/report pages) -
   same .form-row grid as any other 2-up form, but each field sits in its
   own tinted chip so the filter row reads as a distinct, colourful block
   instead of bare labels - the div with the submit button is left plain
   since a coloured card behind a button already carries its own style. */
/* NOTE: this used to key off :has(> label) to skip the trailing submit-
   button div, but :has() isn't supported in every browser this app runs
   on - when it silently fails, the background rules below drop out while
   the unconditional label colour rule still applies, leaving white label
   text on the page's plain white background (invisible). A later
   :not(:last-child) attempt at fixing that also broke filter-forms with
   no trailing button div at all (e.g. Damage/Time on Packing Update) -
   whichever field happened to be last lost its background the same way.
   Simplest fix that can't go wrong: colour every direct-child div
   unconditionally, no exceptions, so a coloured background and the label
   colour rule always apply together. A button sitting inside a tinted
   chip is a harmless cosmetic detail - invisible text is not.
   Light wash, not a solid fill - and the label colour is a single dark
   ink-soft tone (not per-chip white) so it stays legible on every one of
   these pastel backgrounds instead of needing to be matched per colour. */
.filter-form>div {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 7px 10px 8px;
}

.filter-form>div:nth-of-type(4n+1) {
  background: var(--info-soft);
  border-color: transparent;
}

.filter-form>div:nth-of-type(4n+2) {
  background: var(--accent-soft);
  border-color: transparent;
}

.filter-form>div:nth-of-type(4n+3) {
  background: var(--good-soft);
  border-color: transparent;
}

.filter-form>div:nth-of-type(4n) {
  background: #f1edfe;
  border-color: transparent;
}

.filter-form label {
  margin: 0 0 4px;
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--ink-soft);
}

.filter-form input,
.filter-form select {
  padding: 7px 9px;
  font-size: 13px;
  background: var(--surface);
}

.filter-form>div:last-child {
  display: flex;
  align-items: flex-end;
}

.filter-form .btn {
  width: 100%;
}

.packing-selector-strip {
  background: linear-gradient(135deg, #2563eb, #6d4fd6);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 14px 16px;
}

.packing-selector-strip label {
  color: #fff;
}

.packing-selector-strip .help-text {
  color: rgba(255, 255, 255, .75);
}

.revised-box {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--accent-soft);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 6px 10px;
  margin: 10px -10px 0;
  font-size: 13px;
  color: #a86a12;
}

.revised-box svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 1px;
  color: #a86a12;
}

.revised-box .revised-time {
  font-weight: 400;
  color: #a86a12;
  opacity: .8;
  font-size: 12px;
}

.revised-box .revised-detail {
  margin-top: 2px;
}

/* The new value in a Revised note - the one thing that actually changed
   (see revisionChangeParts() in includes/admin-review.php). */
.revised-box .revised-new {
  font-weight: 700;
  color: #7a4a00;
  background: rgba(245, 158, 11, .28);
  border-radius: 4px;
  padding: 0 4px;
}

/* The same box, inside a row's expanded detail (no negative side margins). */
.revised-box-inline {
  margin: 10px 0 0;
}

/* Same layout as .revised-box, but red (--bad) instead of amber - a vehicle
   whose fixed capacity no longer matches its batch's total MT (see
   blockedByAssignedVehicleMismatch()/batch-cards.php) needs Admin to
   actually go fix something, not just a heads-up. */
.mismatch-box {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--bad-soft);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 6px 10px;
  margin: 10px -10px 0;
  font-size: 13px;
  color: var(--bad);
}

.mismatch-box svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  margin-top: 1px;
  color: var(--bad);
}

.mismatch-box .revised-detail {
  margin-top: 2px;
}

/* Left-edge accent on a collapsed batch card that has a mismatch popup
   waiting inside it (see the <details data-has-mismatch> markup in
   batch-cards.php) - visible even before Admin expands the card. */
.card[data-has-mismatch="1"] {
  border-left: 4px solid var(--bad);
}

/* Live running total inside the "Fix SKUs to Match Vehicle" popup - red
   while it still doesn't match the vehicle's fixed capacity, green the
   instant it does (see the recompute() script in batch-cards.php). */
.sku-fix-total-row .sku-fix-total {
  color: var(--bad);
}

.sku-fix-total-row.sku-fix-match .sku-fix-total {
  color: var(--good);
}

/* Highlighted box under a SKU line whose target was partly (or fully)
   pre-filled from another completed batch's Live Stock instead of needing
   fresh packing - see applyLiveStockCarryForward() in includes/functions.php.
   Same layout AND colour as .revised-box (amber/yellow), but with a solid
   round icon badge instead of a plain glyph, so it reads as highlighted. */
.carry-forward-box {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  background: var(--accent-soft);
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 8px 10px;
  margin: 10px -10px 0;
  font-size: 13px;
  color: #a86a12;
}

.carry-forward-icon {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #a86a12;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}

.carry-forward-icon svg {
  width: 12px;
  height: 12px;
}

.carry-forward-detail {
  margin-top: 2px;
  font-weight: 400;
}

/* Batch card "Remarks" dropdown: carry-forward / moved-out / revised notes,
   kept small and light grey so they don't outshine the SKU lines. */
.remarks-box {
  margin-top: 10px;
}

.remarks-box > summary {
  cursor: pointer;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-soft, #6b7280);
  padding: 2px 0;
}

.remarks-body .revised-box,
.remarks-body .carry-forward-box {
  background: #f3f4f6;
  color: #6b7280;
  margin: 6px 0 0;
  padding: 4px 8px;
  font-size: 12px;
}

.remarks-body .revised-box svg,
.remarks-body .revised-box .revised-time,
.remarks-body .revised-box .revised-new {
  color: #6b7280;
}

.remarks-body .revised-box .revised-new {
  background: #e5e7eb;
}

.remarks-body .carry-forward-icon {
  background: #9ca3af;
  width: 18px;
  height: 18px;
}

.remarks-body .carry-forward-icon svg {
  width: 10px;
  height: 10px;
}

/* ---------- photo capture (production entry / nozzle reset) ---------- */
.photo-capture {
  margin-top: 14px;
}

.photo-capture-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.photo-preview {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}

.photo-preview img {
  width: 84px;
  height: 84px;
  object-fit: cover;
  border-radius: 10px;
  border: 1px solid var(--border);
}

/* Compact variant when the photo capture widget sits inside a half-width
   nozzle-box column (e.g. inward-entry's Slip/Photo box) */
.nozzle-box .photo-capture {
  margin-top: 0;
}

.nozzle-box .photo-preview {
  gap: 6px;
}

.nozzle-box .photo-preview img {
  width: 40px;
  height: 40px;
  border-radius: 8px;
}

/* ---------- batch-complete popup ---------- */
.modal-overlay {
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(20, 20, 30, .55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  opacity: 0;
  animation: modalOverlayIn .25s ease forwards;
}

.modal-overlay.is-closing {
  animation: modalOverlayOut .2s ease forwards;
}

.modal-box {
  background: var(--surface);
  border-radius: 16px;
  padding: 32px 28px;
  max-width: 360px;
  width: 100%;
  text-align: center;
  box-shadow: 0 20px 50px rgba(0, 0, 0, .3);
  opacity: 0;
  transform: scale(.9) translateY(14px);
  animation: modalBoxIn .32s cubic-bezier(.34, 1.4, .64, 1) .05s forwards;
}

.modal-overlay.is-closing .modal-box {
  animation: modalBoxOut .2s ease forwards;
}

@keyframes modalOverlayIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes modalOverlayOut {
  from { opacity: 1; }
  to { opacity: 0; }
}

@keyframes modalBoxIn {
  from { opacity: 0; transform: scale(.9) translateY(14px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}

@keyframes modalBoxOut {
  from { opacity: 1; transform: scale(1) translateY(0); }
  to { opacity: 0; transform: scale(.94) translateY(8px); }
}

.modal-box-head {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 12px;
  text-align: left;
  margin-bottom: 10px;
}

.modal-box-head .icon-chip-lg {
  margin-bottom: 0;
}

.modal-box h3 {
  margin: 6px 0;
  font-size: 19px;
}

.modal-box p {
  color: var(--ink-soft);
  font-size: 14px;
  margin: 0 0 20px;
}

.modal-box .btn {
  width: 100%;
}

/* ---------- Mark Loading popups (includes/partials/batch-cards.php:
   .load-damage-modal / .load-extra-modal) - one card per SKU, headed with
   its name + token, so it's clear which choices belong to which SKU. The
   title and Save/Back stay put and only the SKU list scrolls, so the popup
   never runs off a short or phone screen. Moved to <body> while open (see
   openPop()), above the tab bar (1002) and a "⋮" panel popup (1051). ---------- */
.load-pop-overlay { z-index: 1060; }
.modal-box.load-pop {
  max-width: 540px;
  max-height: calc(100vh - 32px);
  max-height: calc(100dvh - 32px);
  display: flex;
  flex-direction: column;
  padding: 0;
  text-align: left;
  overflow: hidden;
}
.load-pop-head { flex-shrink: 0; margin: 0; padding: 16px 20px 14px; }
.load-pop-head h3 { margin: 0; line-height: 1.25; }
.load-pop-sub { margin-top: 3px; font-size: 12.5px; color: var(--ink-soft); }
.load-pop-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 14px 20px 2px;
}
.load-pop-foot {
  flex-shrink: 0;
  display: flex;
  gap: 8px;
  padding: 12px 20px 16px;
  border-top: 1px solid var(--ui-line, var(--border));
  background: var(--surface);
}
.load-pop-sku {
  margin-bottom: 14px;
  border: 1px solid var(--ui-line, var(--border));
  border-left: 4px solid var(--accent);
  border-radius: 14px;
  overflow: hidden;
}
.load-pop-sku-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 10px;
  padding: 10px 14px;
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.load-pop-sku-no {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}
.load-pop-sku-no:empty { display: none; }
.load-pop-sku-name { font-size: 15px; font-weight: 800; line-height: 1.25; }
.load-pop-sku-token {
  margin-left: auto;
  padding: 2px 10px;
  border: 1px solid rgba(226, 161, 61, .5);
  border-radius: 999px;
  background: #fff;
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
}
.load-pop-sku-body { padding: 12px 14px 14px; }
.load-pop-stats { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.load-pop-stat {
  padding: 3px 9px;
  border: 1px solid var(--ui-line, var(--border));
  border-radius: 8px;
  background: var(--surface-soft);
  color: var(--ink-soft);
  font-size: 12px;
  white-space: nowrap;
}
.load-pop-stat b { color: var(--ink); font-size: 13px; }
.load-pop-stat.is-need,
.load-pop-stat.is-need b { border-color: transparent; background: var(--bad-soft); color: var(--bad); }
.load-pop-q { font-size: 14px; font-weight: 700; color: var(--ink); }
.load-pop-need { color: var(--bad); }
.load-pop-why { margin: 2px 0 10px; font-size: 12.5px; color: var(--ink-soft); }
.load-pop-opts { display: flex; flex-direction: column; gap: 8px; }
.load-pop-opt {
  padding: 10px 12px;
  border: 1.5px solid var(--ui-line, var(--border));
  border-radius: 12px;
  transition: border-color .15s ease, background .15s ease;
}
.load-pop-opt:has(input:checked) { border-color: var(--ui-primary, var(--primary)); background: var(--ui-primary-soft, var(--primary-soft)); }
.load-pop-opt.is-off { opacity: .55; }
.load-pop-opt.is-off select { display: none; }
.load-pop-opt label { display: flex; align-items: flex-start; gap: 10px; margin: 0; font-size: 13.5px; font-weight: 700; color: var(--ink); cursor: pointer; }
.load-pop-opt.is-off label { cursor: default; }
.load-pop-opt input[type=radio] { flex-shrink: 0; width: auto; margin: 3px 0 0; }
.load-pop-opt-note { display: block; margin-top: 2px; font-size: 12.5px; font-weight: 400; color: var(--ink-soft); }
.load-pop-opt select { width: calc(100% - 23px); margin: 8px 0 0 23px; }

@media (max-width: 600px) {
  .load-pop-overlay { padding: 10px; }
  .modal-box.load-pop { width: 100%; max-height: calc(100vh - 20px); max-height: calc(100dvh - 20px); }
  .load-pop-head { padding: 14px 16px 12px; }
  .load-pop-head h3 { font-size: 17px; }
  .load-pop-body { padding: 12px 12px 2px; }
  .load-pop-foot { padding: 10px 12px calc(12px + env(safe-area-inset-bottom)); }
  .load-pop-sku-head { padding: 9px 12px; }
  .load-pop-sku-token { margin-left: 0; }
  .load-pop-sku-body { padding: 10px 12px 12px; }
  .load-pop-opt select { width: 100%; margin-left: 0; }
}

/* ---------- Live cross-role alert popup (assets/js/live-alert-popup.js) -
   reuses .modal-overlay/.modal-box above for the same look/animation as
   every other app popup, this just styles the item list + snooze row
   inside it. ---------- */
.live-alert-box {
  max-width: 400px;
  text-align: left;
}

.live-alert-list {
  max-height: 280px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 10px;
}

.live-alert-item {
  display: block;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  text-decoration: none;
  color: inherit;
  transition: background .15s ease;
}

.live-alert-item:hover {
  background: var(--primary-soft);
}

.live-alert-item-title {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
}

.live-alert-item-meta {
  font-size: 11.5px;
  color: var(--ink-soft);
  margin-top: 2px;
}

.live-alert-more {
  font-size: 12px;
  color: var(--ink-soft);
  text-align: center;
  margin: 0 0 12px;
}

.live-alert-snooze-label {
  font-size: 12px;
  color: var(--ink-soft);
  margin: 0 0 8px;
  text-align: center;
}

.live-alert-snooze-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  justify-content: center;
}

.live-alert-snooze-btn {
  flex: 1 1 auto;
  min-width: 58px;
  padding: 8px 6px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  font-size: 12.5px;
  font-weight: 700;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.live-alert-snooze-btn:hover {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

/* ---------- live clock bar (ticks every second via JS - see the page
   that renders it) so a value on screen never goes stale while the page
   sits open, and any .live-datetime input auto-tracks "now" until the
   user edits it themselves. ---------- */
.live-clock-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: linear-gradient(135deg, var(--primary), #6d63f2);
  color: #fff;
  font-weight: 700;
  font-size: 13.5px;
  letter-spacing: .01em;
  padding: 10px 14px;
  border-radius: 999px;
  margin-bottom: 16px;
  box-shadow: 0 4px 14px rgba(37, 99, 235, .3);
}

.live-clock-icon {
  display: flex;
  flex-shrink: 0;
}

.live-clock-icon svg {
  width: 15px;
  height: 15px;
}

/* ---------- nozzle entry boxes (packing update) ---------- */
.nozzle-box {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  min-width: 0;
}

.nozzle-box-left {
  background: var(--info-soft);
  border-color: transparent;
}

.nozzle-box-right {
  background: var(--accent-soft);
  border-color: transparent;
}

.nozzle-box-purple {
  background: #f1edfe;
  border-color: transparent;
}

.nozzle-box-green {
  background: var(--good-soft);
  border-color: transparent;
}

.nozzle-box-head {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink);
}

.nozzle-box-head .icon-chip {
  margin-bottom: 0;
  width: 26px;
  height: 26px;
  background: rgba(255, 255, 255, .8);
}

.nozzle-box-head .icon-chip svg {
  width: 14px;
  height: 14px;
}

.nozzle-box label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-soft);
  font-weight: 700;
  margin: 0 0 3px;
}

.nozzle-box input,
.nozzle-box select {
  font-size: 13px;
  font-weight: 600;
  padding: 6px 8px;
  background: var(--surface);
  border-radius: 9px;
  width: 100%;
}

.nozzle-box input[type=number] {
  font-size: 16px;
  font-weight: 700;
}

.section-divider {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 24px 0 4px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  font-weight: 700;
  font-size: 14.5px;
  color: var(--ink-soft);
}

.section-divider svg {
  width: 16px;
  height: 16px;
}

.readonly-calc {
  background: var(--surface-soft);
  font-weight: 700;
  color: var(--accent-ink);
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 9px 18px;
  border-radius: 999px;
  border: 1px solid transparent;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  text-align: center;
  transition: transform .1s ease, box-shadow .15s ease, background .15s ease;
}

.btn svg {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
}

.btn:hover {
  text-decoration: none;
}

.btn-primary {
  background: var(--primary);
  color: #fff;
  box-shadow: 0 3px 10px rgba(79, 70, 229, .3);
}

.btn-primary:hover {
  background: var(--primary-dark);
}

.btn-accent {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: 0 3px 10px rgba(226, 161, 61, .3);
}

.btn-accent:hover {
  background: #cf8f30;
}

.btn-outline {
  background: #fff;
  border-color: var(--border);
  color: var(--ink);
}

.btn-outline:hover {
  background: var(--surface-soft);
}

.btn-danger {
  background: var(--bad);
  color: #fff;
}

/* "⋮" menu that hides Delete one click away so it can't be hit by
   accident - see the .more-menu toggle in assets/js/app.js. */
.more-menu {
  position: relative;
  display: inline-block;
  vertical-align: middle;
}
.more-menu-btn {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--ink);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}
.more-menu-btn:hover { background: var(--surface-soft); }
.more-menu-sm .more-menu-btn { width: 26px; height: 26px; font-size: 16px; border-color: transparent; background: transparent; }
.more-menu-sm .more-menu-btn:hover { border-color: var(--border); }
.more-menu-pop {
  display: none;
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: 50;
  min-width: 150px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface);
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.16);
}
.more-menu-right .more-menu-pop { left: auto; right: 0; }
.more-menu.open .more-menu-pop { display: block; }
.card:has(.more-menu.open) { overflow: visible !important; }
.more-menu-pop form { display: block !important; margin: 0 !important; }
.more-menu-pop .btn { display: block; width: 100%; text-align: left; }

.btn-sm {
  padding: 5px 11px;
  font-size: 12px;
}

.btn-sm svg {
  width: 12px;
  height: 12px;
}

.btn-icon {
  padding: 6px;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
}

/* Soft-tinted secondary buttons - a colourful alternative to the plain
   white/border .btn-outline, for actions that deserve a bit more presence
   without being the primary accent button. */
.btn-tint-blue {
  background: linear-gradient(135deg, var(--primary), #1d4ed8);
  color: #fff;
}

.btn-tint-blue:hover {
  filter: brightness(1.06);
}

.btn-tint-green {
  background: linear-gradient(135deg, var(--good), #128a3e);
  color: #fff;
}

.btn-tint-green:hover {
  filter: brightness(1.06);
}

.btn-tint-amber {
  background: linear-gradient(135deg, var(--accent), #a86a12);
  color: #fff;
}

.btn-tint-amber:hover {
  filter: brightness(1.06);
}

.btn-tint-purple {
  background: linear-gradient(135deg, #8b6ff0, #6d4fd6);
  color: #fff;
}

.btn-tint-purple:hover {
  filter: brightness(1.06);
}

/* Solid gradient "highlight" button - stronger presence than the soft
   tints above, for a secondary link that should still catch the eye. */
.btn-highlight-purple {
  background: linear-gradient(135deg, var(--primary), #6d63f2);
  color: #fff;
  box-shadow: 0 3px 10px rgba(109, 99, 242, .35);
}

.btn-highlight-purple:hover {
  filter: brightness(1.06);
}

/* ---------- detail-record sub-tabs (e.g. C&F partner: Profile / Personal /
   Territory / Pricing / Token Returns) - a horizontal, scrollable pill strip
   under a record's hero header, separate from the app-wide sidebar/bottom
   tab bar which stays on the record's own top-level menu item throughout. */
.cf-detail-tabs {
  display: flex;
  gap: 6px;
  margin-bottom: 14px;
  padding-bottom: 2px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.cf-detail-tabs::-webkit-scrollbar {
  display: none;
}

.cf-detail-tab {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: 6px;
  padding: 9px 16px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: #fff;
  color: var(--ink-soft);
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.cf-detail-tab svg {
  width: 15px;
  height: 15px;
}

.cf-detail-tab:hover {
  color: var(--ink);
  text-decoration: none;
}

.cf-detail-tab.active {
  border-color: transparent;
  background: linear-gradient(135deg, var(--primary), #6d63f2);
  color: #fff;
  box-shadow: 0 3px 8px rgba(79, 70, 229, .3);
}

/* ---------- C&F partner detail page family (hero + per-tab cards) ---------- */
.cf-detail-hero { display:flex; align-items:center; justify-content:space-between; gap:14px; margin-bottom:14px; padding:16px; border:1px solid var(--border); border-radius:16px; background:linear-gradient(135deg,#fff,var(--primary-soft)); box-shadow:var(--shadow-sm); }
.cf-detail-hero-main { display:flex; align-items:center; gap:11px; min-width:0; }
.cf-detail-avatar { display:flex; align-items:center; justify-content:center; width:42px; height:42px; flex:0 0 42px; border-radius:13px; background:#fff; color:var(--primary); font-size:19px; font-weight:800; box-shadow:0 3px 10px rgba(37,99,235,.12); }
.cf-detail-hero h2 { overflow:hidden; margin:0 0 4px; font-size:19px; text-overflow:ellipsis; white-space:nowrap; }
.cf-detail-hero p { margin:0; color:var(--ink-soft); font-size:11px; }
.cf-detail-card { margin:0 0 14px; min-width:0; padding:17px; background:linear-gradient(145deg,#fff 0%,#f4f7ff 100%); }
.cf-detail-card form { min-width:0; }
.cf-detail-card .form-row { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:14px; margin-bottom:14px; }
.cf-detail-card .form-row > div { min-width:0; }
.cf-detail-card label { display:block; margin-bottom:6px; color:var(--ink-soft); font-size:12px; font-weight:700; line-height:1.25; }
.cf-detail-card input:not([type="checkbox"]), .cf-detail-card select, .cf-detail-card textarea { width:100%; min-width:0; box-sizing:border-box; padding:10px 12px; border:1px solid #d9deea; border-radius:10px; background:var(--surface-soft); color:var(--ink); font-size:14px; font-family:inherit; transition:border-color .18s ease, box-shadow .18s ease, background .18s ease; }
.cf-detail-card input:not([type="checkbox"]):not(textarea), .cf-detail-card select { height:42px; }
.cf-detail-card input:not([type="checkbox"]):focus, .cf-detail-card select:focus, .cf-detail-card textarea:focus { background:#fff; border-color:var(--primary); box-shadow:0 0 0 3px var(--primary-soft); outline:0; }
.cf-detail-card input:-webkit-autofill, .cf-detail-card input:-webkit-autofill:hover, .cf-detail-card input:-webkit-autofill:focus { -webkit-text-fill-color:var(--ink); -webkit-box-shadow:0 0 0 1000px var(--surface-soft) inset; transition:background-color 9999s ease-out 0s; }
.cf-detail-card input[type="checkbox"] { width:auto; }
.cf-detail-card .radio-group { display:flex; align-items:center; gap:14px; min-height:42px; }
.cf-detail-card .radio-group label { display:flex; align-items:center; gap:6px; margin:0; color:var(--ink); font-weight:600; }
.cf-detail-card .radio-group input { accent-color:var(--primary); }
.cf-detail-card [data-admin-child-row]::before { display:block; margin:0 0 6px; color:var(--ink-soft); font-size:12px; font-weight:700; }
.cf-detail-card [data-admin-child-row="0"]::before { display:none; }
.cf-detail-card [data-admin-child-row]:not([data-admin-child-row="0"])::before { content:'Do you have another child?'; }
.cf-detail-card h3 { display:flex; align-items:center; gap:9px; margin:0 0 16px; padding-bottom:11px; border-bottom:1px solid rgba(37,99,235,.12); font-size:16px; }
.cf-detail-card h3 .icon-chip { margin:0; }
.cf-doc-list { display:flex; flex-wrap:wrap; gap:8px; }
.cf-doc-list a { display:inline-flex; align-items:center; gap:6px; padding:8px 10px; border:1px solid var(--border); border-radius:8px; color:var(--primary); font-size:12px; font-weight:700; }
.cf-detail-map { height:280px; border-radius:10px; margin-top:14px; overflow:hidden; border:1px solid var(--border); }
.cf-pricing-row { border-top:1px solid var(--border); padding:14px 0; }
.cf-pricing-row:first-of-type { border-top:0; padding-top:0; }
.cf-pricing-row-title { display:flex; align-items:center; gap:8px; font-weight:700; margin-bottom:10px; line-height:1.3; }
.cf-pricing-row-toggle { display:inline-flex; align-items:center; justify-content:center; width:25px; height:25px; margin-left:auto; padding:0; border:0; border-radius:7px; background:var(--primary-soft); color:var(--primary); cursor:pointer; }
.cf-pricing-row-toggle svg { width:15px; height:15px; transition:transform .2s ease; }
.cf-pricing-row.is-collapsed { padding-bottom:14px; }
.cf-pricing-row.is-collapsed .cf-pricing-row-title { margin-bottom:0; }
.cf-pricing-row.is-collapsed .cf-pricing-row-toggle svg { transform:rotate(-90deg); }
.cf-pricing-row.is-collapsed > .form-row { display:none; }

/* ---------- C&F partner-facing portal (dashboard/cf.php, order-details,
   delivery-photos, marketing-box) - one glass-card design system shared by
   the whole partner portal. Previously duplicated (and drifting out of
   sync - individual pages ended up with different subsets of tint
   variants, and dashboard/cf.php was missing .cf-receipt-btn entirely,
   rendering an unstyled link) in each page's own <style> block; centralised
   here so every page gets the complete, consistent set. */
.cf-glass-card { padding:16px; border-radius:18px; background:rgba(255,255,255,.62); border:1.5px solid rgba(226,232,240,1); box-shadow:0 2px 8px rgba(15,23,42,.05), 0 10px 26px rgba(40,55,90,.08), inset 0 1px 0 rgba(255,255,255,.9); backdrop-filter:blur(16px); -webkit-backdrop-filter:blur(16px); margin-bottom:12px; }
.cf-glass-card.is-primary { background:linear-gradient(160deg,rgba(255,255,255,.78),rgba(226,238,254,.6)); border-color:rgba(37,99,235,.22); }
.cf-glass-card.is-green { background:linear-gradient(160deg,rgba(255,255,255,.78),rgba(227,247,234,.6)); border-color:rgba(22,163,74,.24); }
.cf-glass-card.is-amber { background:linear-gradient(160deg,rgba(255,255,255,.78),rgba(253,241,222,.6)); border-color:rgba(226,161,61,.3); }
.cf-glass-card.is-blue { background:linear-gradient(160deg,rgba(255,255,255,.78),rgba(227,236,246,.6)); border-color:rgba(45,108,168,.24); }
.cf-glass-card.is-red { background:linear-gradient(160deg,rgba(255,255,255,.78),rgba(251,230,227,.6)); border-color:rgba(220,59,46,.24); }

.cf-clickable-card { display:block; color:inherit; text-decoration:none; cursor:pointer; }
.cf-clickable-card:hover { color:inherit; text-decoration:none; border-color:var(--primary); transform:translateY(-1px); }

.cf-fields-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
.cf-field-label { color:var(--ink-soft); font-size:10px; font-weight:700; text-transform:uppercase; }
.cf-field-value { margin-top:3px; overflow:hidden; color:var(--ink); font-size:14px; font-weight:800; text-overflow:ellipsis; white-space:nowrap; }
@media (max-width:360px) { .cf-fields-grid { grid-template-columns:1fr; } }

.cf-order-detail-head { display:flex; align-items:center; gap:12px; }
.cf-order-detail-icon { display:flex; align-items:center; justify-content:center; width:42px; height:42px; flex:0 0 42px; border-radius:13px; background:rgba(255,255,255,.75); color:var(--primary); }
.cf-order-detail-icon svg { width:19px; height:19px; }
.cf-order-detail-title { min-width:0; }
.cf-order-detail-title strong { display:block; overflow:hidden; font-size:16px; font-weight:850; color:var(--ink); text-overflow:ellipsis; white-space:nowrap; }
.cf-order-detail-title span { display:block; margin-top:2px; color:var(--ink-soft); font-size:12px; }

.cf-receipt-btn { display:flex; align-items:center; justify-content:center; gap:8px; width:100%; margin-top:14px; padding:12px; border-radius:13px; background:var(--primary); color:#fff; font-size:13px; font-weight:800; text-decoration:none; box-shadow:0 6px 14px rgba(37,99,235,.25); }
.cf-receipt-btn:hover { background:var(--primary-dark); color:#fff; text-decoration:none; }
.cf-receipt-btn svg { width:16px; height:16px; }

.cf-teaser-card { display:flex; align-items:center; gap:12px; }
.cf-teaser-card-body { flex:1; min-width:0; }
.cf-teaser-arrow { display:flex; flex-shrink:0; color:var(--ink-soft); }
.cf-teaser-arrow svg { width:18px; height:18px; display:block; }
.cf-detail-actions { display:flex; flex-wrap:wrap; gap:8px; margin-top:4px; padding-bottom:82px; }
@media (max-width:360px) { .cf-detail-card .form-row { grid-template-columns:minmax(0,1fr); } }
@media (max-width:480px) { .cf-detail-hero { align-items:flex-start; flex-direction:column; } }

/* ---------- segmented toggle (e.g. FIFO / LIFO) ---------- */
.segmented {
  display: inline-flex;
  background: var(--surface-soft);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 3px;
  gap: 2px;
}

.segmented-btn {
  border: none;
  background: none;
  padding: 8px 20px;
  border-radius: 999px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink-soft);
  cursor: pointer;
  font-family: inherit;
  transition: background .15s ease, color .15s ease;
}

.segmented-btn:hover {
  color: var(--ink);
}

.segmented-btn.active {
  background: linear-gradient(135deg, var(--primary), #6d63f2);
  color: #fff;
  box-shadow: 0 3px 8px rgba(79, 70, 229, .35);
}

.segmented-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
}

.segmented-btn svg {
  width: 14px;
  height: 14px;
}

.segmented-alert .segmented-btn.active {
  background: linear-gradient(135deg, var(--bad), #e0554f);
  box-shadow: 0 3px 8px rgba(220, 59, 46, .35);
}

/* Full-width variant - for toggles with 3+ options (e.g. Left/Right/Both)
   that need room to breathe instead of the default shrink-to-content
   .segmented, which crowds that many options together. */
.segmented-full {
  display: flex;
  width: 100%;
}

.segmented-full .segmented-btn {
  flex: 1;
  justify-content: center;
  padding-left: 8px;
  padding-right: 8px;
}

/* Status-coloured segmented toggle (labour attendance: Full Day / Half
   Day / Absent) - the active colour depends on which option is picked,
   not on the group as a whole like .segmented-alert does. */
.segmented-btn[data-status="full_day"].active {
  background: linear-gradient(135deg, var(--good), #128a3e);
  box-shadow: 0 3px 8px rgba(22, 163, 74, .35);
}

.segmented-btn[data-status="half_day"].active {
  background: linear-gradient(135deg, var(--accent), #c9822a);
  box-shadow: 0 3px 8px rgba(226, 161, 61, .35);
}

.segmented-btn[data-status="absent"].active {
  background: linear-gradient(135deg, var(--bad), #b82c20);
  box-shadow: 0 3px 8px rgba(220, 59, 46, .35);
}

/* ---------- tables ---------- */
table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13.5px;
}

thead th {
  text-align: left;
  background: var(--primary-soft);
  border-bottom: 2px solid var(--primary);
  padding: 9px 10px;
  font-size: 11.5px;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--primary-dark);
}

tbody td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--border);
}

tbody tr:hover {
  background: var(--surface-soft);
}

.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* ---------- row cards (used instead of tables everywhere) ---------- */
.row-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.row-card {
  background: linear-gradient(120deg, var(--surface-soft) 0%, var(--primary-soft) 160%);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  box-shadow: var(--shadow-sm);
  transition: box-shadow .15s ease;
}

.row-card:hover {
  box-shadow: 0 4px 12px rgba(16, 24, 40, .10);
}

/* Status-tinted variants - a soft background wash keyed to payment/status
   colour, so list pages can show it at a glance across every row instead
   of the flat default gradient. Light tint, not a solid fill - text stays
   the normal dark ink/ink-soft tones throughout (no per-variant colour
   overrides needed, which also avoids ever landing on invisible white
   text on a light background). */
.row-card-paid {
  background: var(--good-soft);
}

.row-card-pending {
  background: var(--accent-soft);
}

.row-card-info {
  background: var(--info-soft);
}

.row-card-good {
  background: var(--good-soft);
}

.row-card-neutral {
  background: var(--surface-soft);
}

/* Distinct from .row-card-pending (amber, used app-wide e.g. payments) -
   this one's red, scoped to Tasks where "pending" means overdue/needs
   attention right now rather than just an in-progress status. */
.row-card-bad {
  background: var(--bad-soft);
}

.row-card-paid,
.row-card-pending,
.row-card-info,
.row-card-good,
.row-card-neutral,
.row-card-bad {
  border-color: transparent;
}

.row-card-fields {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 10px 16px;
}

.row-card-fields .field-label {
  font-size: 10.5px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--ink-soft);
  font-weight: 700;
}

.row-card-fields .field-value {
  font-size: 13.5px;
  margin-top: 2px;
}

/* Collapsible row card - summary line only until clicked open */
details.row-card {
  padding: 0;
}

details.row-card>summary {
  list-style: none;
  cursor: pointer;
  padding: 12px 16px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

details.row-card>summary::-webkit-details-marker,
details.row-card>summary::marker {
  display: none;
  content: '';
}

details.row-card>summary:hover {
  background: rgba(0, 0, 0, .02);
}

details.row-card[open]>summary {
  border-bottom: 1px solid var(--border);
}

.row-card-heading {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  font-size: 13.5px;
  min-width: 0;
}

.row-card-heading strong {
  font-weight: 700;
}

.row-card-heading .text-soft {
  font-size: 12.5px;
}

.row-card-detail {
  padding: 12px 16px;
}

.row-chevron {
  flex-shrink: 0;
  color: var(--ink-soft);
  transition: transform .2s ease;
}

.row-chevron svg {
  width: 16px;
  height: 16px;
}

details.row-card[open] .row-chevron {
  transform: rotate(180deg);
}

/* ---------- batch summary card (compact overview, collapsible) ---------- */
details.card {
  padding: 0;
}

details.card>summary {
  list-style: none;
  cursor: pointer;
  padding: 18px 20px;
}

details.card>summary::-webkit-details-marker,
details.card>summary::marker {
  display: none;
  content: '';
}

details.card>summary:hover {
  background: var(--surface-soft);
}

details.card[open]>summary {
  border-bottom: 1px solid var(--border);
}

/* Generic collapsible-card body padding (details.card>summary has its own
   padding above; content is 0-padded by default so this restores it for
   whatever follows the summary) - used wherever a plain .card section
   becomes a collapsed-by-default accordion outside the batch list. */
.card-detail {
  padding: 18px 20px;
}

.batch-chevron {
  flex-shrink: 0;
  color: var(--ink-soft);
  transition: transform .2s ease;
}

.batch-chevron svg {
  width: 18px;
  height: 18px;
}

details.card[open] .batch-chevron {
  transform: rotate(180deg);
}

.batch-detail {
  padding: 18px 20px;
}

.batch-card-active {
  border-left: 4px solid var(--good);
}

/* fully completed */
.batch-card-completed {
  border-left: 4px solid var(--primary);
}

.batch-card-pending {
  border-left: 4px solid var(--accent);
}

/* packed, no vehicle yet - see buildBatchGroups()'s "Need Vehicle" status.
   The extra "body" outranks the mobile dashboard's borderless .card. */
body details.card.batch-card-urgent {
  border-left: 4px solid var(--urgent);
  background: linear-gradient(100deg, var(--urgent-soft) 0%, #fff 45%);
  box-shadow: 0 0 0 1px var(--urgent-ring), 0 6px 22px rgba(219, 39, 119, .12);
}

/* A Priority Tasks link just opened this card (dashboard/admin.php). */
.batch-card-flash {
  animation: batchCardFlash 1.4s ease-out;
}

@keyframes batchCardFlash {
  0%, 30% { box-shadow: 0 0 0 4px var(--urgent-ring), 0 10px 30px rgba(219, 39, 119, .25); }
}

/* ---------- Priority Tasks (top of dashboard/admin.php) ----------
   includes/partials/priority-tasks.php. The first task is the one to do
   now: on page open it pops in with a star burst and a shine, then keeps a
   slow glow and a twinkling star. #livePriorityTasks.is-settled (set by the
   live refresh) skips the one-time open effects so they don't replay. */
.priority-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 6px;
}

.priority-slider {
  flex-direction: row;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  /* room for the cards' shadow/glow, which overflow-x would otherwise clip */
  margin: -6px -4px 0;
  padding: 6px 4px 14px;
  scrollbar-width: none;
}

.priority-slider::-webkit-scrollbar {
  display: none;
}

.priority-slider > .priority-task {
  flex: 0 0 88%;
  box-sizing: border-box;
  scroll-snap-align: start;
}

.priority-task {
  --kind: var(--urgent);
  --kind-soft: var(--urgent-soft);
  position: relative;
  display: block;
  padding: 13px 14px;
  border-radius: 16px;
  border-left: 4px solid var(--kind);
  background: var(--surface);
  box-shadow: 0 4px 16px rgba(15, 23, 42, .06);
  color: var(--ink);
  text-decoration: none;
}

.priority-task-release {
  --kind: var(--accent);
  --kind-soft: var(--accent-soft);
}

.priority-task-message {
  --kind: var(--good);
  --kind-soft: var(--good-soft);
}

.priority-task-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.priority-task-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  background: var(--kind-soft);
  color: var(--kind);
}

.priority-task-icon svg {
  width: 19px;
  height: 19px;
}

.priority-task-body {
  flex: 1;
  min-width: 0;
}

.priority-task-title {
  display: block;
  font-size: 14.5px;
  font-weight: 700;
  line-height: 1.3;
}

.priority-task-sub {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-soft);
}

.priority-task-go {
  flex: none;
  color: var(--ink-soft);
}

.priority-task-go svg {
  width: 18px;
  height: 18px;
}

.priority-task.is-top {
  padding-top: 12px;
  background: linear-gradient(135deg, #fff 0%, var(--urgent-soft) 100%);
  box-shadow: 0 0 0 1.5px var(--urgent-ring), 0 8px 24px rgba(219, 39, 119, .16);
  animation: priorityPop .6s cubic-bezier(.2, .9, .3, 1.3) both, priorityGlow 2.4s ease-in-out .6s infinite;
}

.priority-task.is-top .priority-task-icon {
  background: var(--kind);
  color: #fff;
}

/* one-time shine sweep across the top task on open */
.priority-task.is-top::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(110deg, transparent 35%, rgba(255, 255, 255, .8) 50%, transparent 65%) no-repeat;
  background-size: 250% 100%;
  background-position: 150% 0;
  pointer-events: none;
  animation: priorityShine 1.1s ease-out .45s both;
}

.priority-top-tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-bottom: 9px;
  padding: 3px 10px 3px 5px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--urgent), #f59e0b);
  color: #fff;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .06em;
  text-transform: uppercase;
  box-shadow: 0 3px 10px rgba(219, 39, 119, .3);
}

.priority-star {
  display: inline-flex;
}

.priority-star svg {
  width: 15px;
  height: 15px;
  fill: #fde047;
  filter: drop-shadow(0 0 3px rgba(253, 224, 71, .9));
  animation: starTwinkle 1.8s ease-in-out infinite;
}

.priority-sparkles {
  position: absolute;
  top: 22px;
  left: 24px;
  pointer-events: none;
}

.priority-sparkle {
  position: absolute;
  top: -6px;
  left: -6px;
  opacity: 0;
  animation: sparkleBurst 1.3s ease-out .25s both;
}

.priority-sparkle svg {
  width: 15px;
  height: 15px;
  fill: #f59e0b;
}

.priority-sparkle-1 { --dx: -20px; --dy: -24px; }
.priority-sparkle-2 { --dx: 34px; --dy: -30px; }
.priority-sparkle-3 { --dx: 78px; --dy: -18px; animation-delay: .35s; }
.priority-sparkle-4 { --dx: -26px; --dy: 14px; animation-delay: .4s; }
.priority-sparkle-5 { --dx: 120px; --dy: -26px; animation-delay: .3s; }
.priority-sparkle-2 svg, .priority-sparkle-4 svg { fill: var(--urgent); width: 11px; height: 11px; }

#livePriorityTasks.is-settled .priority-task.is-top {
  animation: priorityGlow 2.4s ease-in-out infinite;
}

#livePriorityTasks.is-settled .priority-task.is-top::after,
#livePriorityTasks.is-settled .priority-sparkles {
  display: none;
}

@keyframes priorityPop {
  0% { opacity: 0; transform: translateY(8px) scale(.96); }
  100% { opacity: 1; transform: none; }
}

@keyframes priorityGlow {
  0%, 100% { box-shadow: 0 0 0 1.5px var(--urgent-ring), 0 8px 24px rgba(219, 39, 119, .16); }
  50% { box-shadow: 0 0 0 4px rgba(249, 168, 212, .55), 0 10px 30px rgba(219, 39, 119, .28); }
}

@keyframes priorityShine {
  0% { background-position: 150% 0; }
  100% { background-position: -50% 0; }
}

@keyframes starTwinkle {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50% { transform: scale(1.3) rotate(36deg); }
}

@keyframes sparkleBurst {
  0% { opacity: 0; transform: translate(0, 0) scale(.2) rotate(0deg); }
  25% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(1.1) rotate(180deg); }
}

@media (prefers-reduced-motion: reduce) {
  .pill-urgent,
  .batch-card-flash,
  .priority-task.is-top,
  .priority-star svg {
    animation: none !important;
  }
  .priority-task.is-top::after,
  .priority-sparkles {
    display: none;
  }
}

/* ---------- Daily target party-popper (assets/js/target-celebration.js) ----------
   Above everything else in the app (its highest layer is 1200); the canvas
   never takes taps, the banner closes on tap. */
.target-celebrate-canvas {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 3000;
}

.target-celebrate-popper {
  position: fixed;
  bottom: 84px;
  font-size: 46px;
  line-height: 1;
  pointer-events: none;
  z-index: 3001;
  animation: popperFire 3.2s ease-out both;
}

.target-celebrate-popper-left {
  left: 6px;
  --flip: 1;
}

/* the emoji fires up-right - mirrored so this one fires up-left */
.target-celebrate-popper-right {
  right: 6px;
  --flip: -1;
}

@keyframes popperFire {
  0% { opacity: 0; transform: scaleX(var(--flip)) scale(.3) rotate(20deg); }
  12% { opacity: 1; transform: scaleX(var(--flip)) scale(1.35) rotate(-12deg); }
  22% { transform: scaleX(var(--flip)) scale(.95) rotate(4deg); }
  32% { transform: scaleX(var(--flip)) scale(1.05) rotate(0deg); }
  80% { opacity: 1; transform: scaleX(var(--flip)) scale(1); }
  100% { opacity: 0; transform: scaleX(var(--flip)) scale(.8) translateY(10px); }
}

.target-celebrate-banner {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 72px);
  left: 50%;
  display: flex;
  align-items: center;
  gap: 12px;
  width: max-content;
  max-width: calc(100vw - 32px);
  padding: 13px 18px 13px 14px;
  border-radius: 18px;
  background: linear-gradient(135deg, #fff 0%, var(--urgent-soft) 55%, #fef3c7 100%);
  box-shadow: 0 0 0 1.5px var(--urgent-ring), 0 18px 44px rgba(219, 39, 119, .28);
  color: var(--ink);
  cursor: pointer;
  z-index: 3002;
  transform: translateX(-50%);
  animation: celebrateBannerIn .55s cubic-bezier(.2, .9, .3, 1.35) both;
}

.target-celebrate-banner.is-leaving {
  animation: celebrateBannerOut .35s ease-in both;
}

.target-celebrate-emoji {
  flex: none;
  font-size: 32px;
  line-height: 1;
  animation: starTwinkle 1.4s ease-in-out infinite;
}

.target-celebrate-title {
  display: block;
  font-size: 16px;
  font-weight: 800;
  color: var(--urgent);
  letter-spacing: -.01em;
}

.target-celebrate-sub {
  display: block;
  margin-top: 2px;
  font-size: 12.5px;
  color: var(--ink-soft);
}

@keyframes celebrateBannerIn {
  0% { opacity: 0; transform: translateX(-50%) translateY(-18px) scale(.85); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}

@keyframes celebrateBannerOut {
  to { opacity: 0; transform: translateX(-50%) translateY(-12px) scale(.95); }
}

@media (prefers-reduced-motion: reduce) {
  .target-celebrate-banner,
  .target-celebrate-banner.is-leaving,
  .target-celebrate-emoji {
    animation: none;
  }
}

/* still in production */

.token-badges {
  display: flex;
  flex-shrink: 0;
}

.token-badge {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 8.5px;
  font-weight: 700;
  color: #fff;
  border: 2px solid var(--surface);
  margin-left: -9px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .15);
}

.token-badge:first-child {
  margin-left: 0;
}

.token-badge-green {
  background: var(--good);
}

.token-badge-blue {
  background: var(--info);
}

.token-badge-amber {
  background: var(--accent);
}

.token-badge-red {
  background: var(--bad);
}

.token-badge-purple {
  background: var(--primary);
}

.progress-bar {
  height: 8px;
  background: var(--border);
  border-radius: 999px;
  overflow: hidden;
  margin-top: 4px;
}

.progress-bar-fill {
  height: 100%;
  background: var(--primary);
  border-radius: 999px;
  transition: width .3s ease;
}

.batch-summary-header {
  display: flex;
  align-items: center;
  gap: 8px;
}

.batch-summary-title {
  flex: 1;
  min-width: 0;
}

/* Flex so the Revised dot sits right by the batch no - only the rest of
   the line is cut with "...", so the dot's "Revised" label isn't clipped. */
.batch-summary-name {
  display: flex;
  align-items: center;
  gap: 5px;
  min-width: 0;
  font-weight: 700;
  font-size: 12.5px;
  white-space: nowrap;
}
/* Status pill / Needs Attention column never shrinks - the title gives way (cut with "...") instead of overlapping it. */
.batch-summary-header .batch-summary-status { flex-shrink: 0; white-space: nowrap; }
.batch-summary-header .batch-summary-name { overflow: hidden; }
.batch-summary-name-rest {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Admin changed this batch no / SKU in the last 2 days - see batch-cards.php,
   whose script shows the .revised-tip "Revised" label on hover or tap. */
.revised-dot {
  display: inline-block;
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  margin: -2px 0 0 5px;
  vertical-align: middle;
  border: 1px solid #eab308;
  border-radius: 50%;
  background: #facc15;
  box-shadow: 0 0 0 2px rgba(250, 204, 21, .3);
  cursor: help;
  outline: 0;
}
.batch-summary-name .revised-dot { margin: 0; }
.batch-summary-name .pill { flex-shrink: 0; }
.revised-tip {
  display: none;
  position: fixed;
  z-index: 3100;
  padding: 3px 8px;
  border-radius: 6px;
  background: #1b1f2e;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
  transform: translateY(-50%);
}

.batch-summary-collapsed-sub {
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 1px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.batch-summary-sub {
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-top: 1px;
}

.batch-summary-progress-label {
  display: flex;
  justify-content: space-between;
  font-size: 12.5px;
  color: var(--ink-soft);
  margin-top: 14px;
}

.batch-summary-progress-label strong {
  color: var(--ink);
  font-weight: 700;
}

.batch-line-list {
  margin-top: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.batch-line-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 13px;
  padding: 6px 10px;
  margin: 0 -10px;
  border-radius: 8px;
}

.batch-line-row .batch-line-name {
  color: var(--ink-soft);
  font-size: 11.5px;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Status icon kept as its own fixed-width column (not part of the
   truncating name text) so it's always visible on the single line no
   matter how long the product name is - a plain "Complete" pill inside
   .batch-line-name was getting swallowed by the ellipsis truncation. */
.batch-line-row .batch-line-status {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-left: 8px;
}

.batch-line-row .batch-line-status svg {
  width: 14px;
  height: 14px;
}

.batch-line-status-done {
  color: var(--good);
}

.batch-line-status-progress {
  color: var(--accent);
}

.batch-line-row .batch-line-progress {
  font-weight: 600;
  flex-shrink: 0;
  margin-left: 12px;
}

.batch-line-row .batch-line-actions {
  display: flex;
  gap: 8px;
  margin-left: 12px;
  flex-shrink: 0;
}

/* "i" next to a SKU: tap (or hover) to see that SKU's own batch no. */
.sku-info-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 15px;
  height: 15px;
  margin-left: 6px;
  padding: 0;
  border: 1px solid var(--ink-soft);
  border-radius: 50%;
  background: transparent;
  color: var(--ink-soft);
  font: italic 700 10px/1 Georgia, serif;
  cursor: pointer;
  vertical-align: middle;
}
.sku-info-pop {
  margin-left: 6px;
  padding: 2px 7px;
  border-radius: 6px;
  background: var(--surface-2, #eef0f6);
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
}
.sku-info-pop[hidden] { display: none; }

/* Phones: small collapsed batch card - batch no + Local / Part Load + status on one line (wrapping if needed),
   token badges on a tiny line below; MT and SKU / batch-number sub-lines are left for the open card. */
@media (max-width: 600px) {
  body details.card[id^="batchGroup"] { padding: 0 !important; margin-bottom: 8px; -webkit-tap-highlight-color: transparent; }
  /* Touch / hover must not paint a square box inside the rounded card (it cut the pink card's left edge). */
  body details.card[id^="batchGroup"] > summary,
  body details.card[id^="batchGroup"] > summary:hover,
  body details.card[id^="batchGroup"] > summary:active,
  body details.card[id^="batchGroup"] > summary:focus { background: transparent; border-radius: inherit; outline: 0; }
  body details.card[id^="batchGroup"][open] > summary { border-radius: 17px 17px 0 0; }
  body details.card > summary.batch-summary-header { padding: 8px 12px; flex-wrap: nowrap; align-items: center; column-gap: 8px; }
  .batch-summary-header .batch-summary-title { order: 1; flex: 1 1 0; min-width: 0; }
  .batch-summary-header .batch-summary-status { order: 2; }
  .batch-summary-header .batch-chevron { order: 3; }
  .batch-summary-header .token-badges { order: 0; flex: 0 0 auto; }
  .batch-summary-header .token-badge { width: 20px; height: 20px; font-size: 7px; margin-left: -7px; }
  .batch-summary-header .token-badge:first-child { margin-left: 0; }
  .batch-summary-header .batch-summary-name { flex-wrap: wrap; white-space: normal; overflow: visible; font-size: 14px; row-gap: 3px; gap: 4px; }
  /* Local, Part Load and the status pill all the same small size */
  .batch-summary-header .batch-summary-name .pill,
  .batch-summary-header .batch-summary-status .pill { font-size: 9.5px !important; padding: 3px 8px !important; line-height: 1.2; font-weight: 700; }
  .batch-summary-header .batch-summary-name-rest { font-size: 12px; font-weight: 600; white-space: nowrap; overflow: visible; }
  .batch-summary-header .batch-summary-collapsed-sub { display: none; }
  .batch-summary-header .batch-summary-status .action-tile-attention { font-size: 9px; }
}
@media (min-width: 601px) {
  .batch-summary-header .batch-sub-nos { display: none; }
}

/* Desktop: name takes the free space; status icon and progress sit in fixed-width
   columns so every SKU line lines up whatever the name length. */
@media (min-width: 601px) {
  .batch-line-row .batch-line-name { flex: 1 1 auto; }
  .batch-line-row .batch-line-status { width: 20px; }
  .batch-line-row .batch-line-progress { width: 330px; text-align: right; }
}

/* Phones: the SKU name gets its own full line (never cut off), with the
   status icon, progress + remaining and Edit wrapping onto the next. */
@media (max-width: 600px) {
  /* Each SKU is a tidy two-line block: name + ⓘ ... Remarks on top; status icon, progress and menu below. */
  .batch-line-list { gap: 0; }
  .batch-line-row { display: grid; grid-template-columns: auto 1fr auto; grid-template-rows: auto auto; align-items: center; column-gap: 8px; row-gap: 6px; padding: 12px 10px; border-bottom: 1px solid var(--border); border-radius: 0; }
  .batch-line-list .batch-line-row:last-of-type { border-bottom: 0; }
  .batch-line-row .batch-line-name { display: contents; }
  .batch-line-row .batch-line-title { grid-column: 1 / 3; grid-row: 1; white-space: normal; font-size: 13.5px; font-weight: 600; color: var(--ink); }
  .batch-line-row .remarks-btn { grid-column: 3; grid-row: 1; justify-self: end; }
  .batch-line-row .batch-line-status { grid-column: 1; grid-row: 2; margin-left: 0; }
  .batch-line-row .batch-line-progress { grid-column: 2; grid-row: 2; margin-left: 0; width: auto; text-align: left; font-size: 12.5px; }
  .batch-line-row .batch-line-actions { grid-column: 3; grid-row: 2; margin-left: 0; justify-self: end; }
}

.batch-line-row-done {
  background: var(--good-soft);
  border-radius: 8px;
  padding: 6px 10px;
  margin: 0 -10px;
}

.batch-line-row-done .batch-line-name {
  font-weight: 600;
}

.batch-line-row-done .batch-line-name .pill {
  margin-left: 6px;
}

/* Inline SKU edit form - toggled open right under its own row's Edit
   button (see batch-cards.php) instead of navigating to a form at the
   top of the page, so it's obvious which SKU you're editing. */
.sku-edit-panel {
  background: var(--primary-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  margin: 2px 0 8px;
}

.sku-edit-panel .form-row {
  margin: 0;
}

/* Mini collapsible section header - same look as .section-divider, but
   as a clickable <summary> with its own chevron, for a sub-section inside
   a form that should stay collapsed until the user opens it. */
.mini-collapse>summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 24px 0 4px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  font-weight: 700;
  font-size: 14.5px;
  color: var(--ink-soft);
}

.mini-collapse>summary::-webkit-details-marker,
.mini-collapse>summary::marker {
  display: none;
  content: '';
}

.mini-collapse>summary svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.mini-collapse-chevron {
  margin-left: auto;
  flex-shrink: 0;
  color: var(--ink-soft);
  transition: transform .2s ease;
}

.mini-collapse-chevron svg {
  width: 16px;
  height: 16px;
}

.mini-collapse[open] .mini-collapse-chevron {
  transform: rotate(180deg);
}

.row-card-actions {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 2px;
}

.row-card-empty {
  color: var(--ink-soft);
  font-size: 13.5px;
  padding: 10px 2px;
}

/* ---------- badges / status pills ---------- */
.pill {
  display: inline-block;
  padding: 2px 10px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: .02em;
}

.pill-active {
  background: var(--good-soft);
  color: var(--good);
}

.pill-completed {
  background: var(--info-soft);
  color: var(--info);
}

.pill-inactive,
.pill-exhausted {
  background: #f1f1f1;
  color: #888;
}

.pill-pending {
  background: var(--accent-soft);
  color: #a86a12;
}

/* Red pending pill for Tasks - see .row-card-bad above. */
.pill-bad {
  background: var(--bad-soft);
  color: var(--bad);
}

/* "Need Vehicle" - solid and pulsing so it can't be read as just another
   amber pending state (see buildBatchGroups()). */
.pill-urgent {
  background: var(--urgent);
  color: #fff;
  animation: urgentPulse 2s ease-out infinite;
}

@keyframes urgentPulse {
  0% { box-shadow: 0 0 0 0 rgba(219, 39, 119, .5); }
  70% { box-shadow: 0 0 0 7px rgba(219, 39, 119, 0); }
  100% { box-shadow: 0 0 0 0 rgba(219, 39, 119, 0); }
}

.pill-garbage {
  background: var(--bad-soft);
  color: var(--bad);
}

/* "Revised" tag on a record Admin edited after Plant Head logged it - see
   revisedPill() in includes/admin-review.php. Dashed outline so it can't be
   mistaken for the solid amber Pending pill next to it. */
.pill-revised {
  background: var(--accent-soft);
  color: #a86a12;
  border: 1px dashed #a86a12;
  padding: 1px 9px;
}

.pill-select {
  border: none;
  border-radius: 999px;
  padding: 5px 10px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .02em;
  cursor: pointer;
}

.pill-select-pending {
  background: var(--accent-soft);
  color: #a86a12;
}

.pill-select-paid {
  background: var(--good-soft);
  color: var(--good);
}

.pill-select-partial {
  background: var(--info-soft);
  color: var(--info);
}

/* ---------- alerts ---------- */
.alert {
  padding: 11px 16px;
  border-radius: var(--radius-sm);
  margin-bottom: 16px;
  font-size: 13.5px;
  position: relative;
  padding-right: 40px;
}

.alert svg {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.alert-success {
  background: var(--good-soft);
  color: var(--good);
}

.alert-danger {
  background: var(--bad-soft);
  color: var(--bad);
}

.alert-info {
  background: var(--info-soft);
  color: var(--info);
}

.alert-close {
  position: absolute;
  right: 10px;
  top: 8px;
  background: none;
  border: none;
  font-size: 16px;
  cursor: pointer;
  color: inherit;
  opacity: .6;
}

.alert-close:hover {
  opacity: 1;
}

/* ---------- login page ---------- */
body.login-body {
  margin: 0;
  min-height: 100dvh;
  background: #f5f6f8;
}

.login-page {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: minmax(420px, 1.08fr) minmax(480px, .92fr);
  overflow: hidden;
  background: #fff;
}

.login-showcase {
  position: relative;
  min-height: 100dvh;
  padding: 36px clamp(36px, 5vw, 76px);
  overflow: hidden;
  color: #fff;
  background:
    radial-gradient(circle at 15% 15%, rgba(255, 255, 255, .1), transparent 28%),
    radial-gradient(circle at 88% 82%, rgba(239, 68, 68, .18), transparent 30%),
    linear-gradient(145deg, #111827 0%, #182235 52%, #202b3e 100%);
}

.login-showcase::before {
  content: '';
  position: absolute;
  width: 320px;
  height: 320px;
  left: -190px;
  top: 28%;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: 50%;
  box-shadow: 0 0 0 70px rgba(255, 255, 255, .025), 0 0 0 140px rgba(255, 255, 255, .02);
}

.login-graphic {
  position: absolute;
  right: -10%;
  bottom: -2px;
  width: 92%;
  opacity: .12;
  filter: brightness(0) invert(1);
  pointer-events: none;
}

.login-topbar {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 12px;
  color: #fff;
}

.login-topbar-logo {
  width: 42px;
  height: 42px;
  padding: 3px;
  border-radius: 12px;
  object-fit: cover;
  background: #fff;
  flex-shrink: 0;
}

.login-topbar-badge {
  width: 26px;
  height: 26px;
  border-radius: 8px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, .18);
  font-weight: 800;
  font-size: 13px;
}

.login-topbar-name {
  font-weight: 750;
  font-size: 18px;
  letter-spacing: .01em;
}

.login-showcase-copy {
  position: relative;
  z-index: 2;
  max-width: 610px;
  margin-top: clamp(110px, 17vh, 190px);
}

.login-kicker,
.login-welcome {
  display: inline-block;
  color: #ef4444;
  font-size: 12px;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .13em;
}

.login-showcase-copy h2 {
  margin: 18px 0 20px;
  font-size: clamp(38px, 4.4vw, 66px);
  line-height: 1.06;
  letter-spacing: -.045em;
}

.login-showcase-copy p {
  max-width: 560px;
  margin: 0;
  color: #aeb9c9;
  font-size: clamp(15px, 1.2vw, 18px);
  line-height: 1.75;
}

.login-feature-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 26px;
  margin-top: 34px;
  color: #d7dde7;
  font-size: 13px;
  font-weight: 650;
}

.login-feature-row span::before {
  content: '\2713';
  display: inline-grid;
  place-items: center;
  width: 19px;
  height: 19px;
  margin-right: 8px;
  border-radius: 50%;
  color: #fff;
  background: #dc2626;
  font-size: 11px;
}

.login-panel {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding: 32px clamp(30px, 5vw, 78px) 22px;
  background: #fff;
}

.login-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.login-card {
  width: 430px;
  max-width: 100%;
}

.login-card h1 {
  margin: 7px 0 8px;
  font-size: 30px;
  line-height: 1.2;
  letter-spacing: -.035em;
}

.login-social-footer {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 25px;
  color: #98a2b3;
}

.login-social-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .08em;
}

.login-social-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.login-social-btn {
  width: 32px;
  height: 32px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #e4e7ec;
  background: #fff;
  color: #667085;
  transition: transform .18s ease, background .18s ease, color .18s ease;
}

.login-social-btn svg {
  width: 17px;
  height: 17px;
}

.login-social-btn:hover {
  color: #fff;
  transform: translateY(-2px);
}

.login-social-btn-instagram:hover { background: linear-gradient(135deg, #f58529, #dd2a7b, #8134af, #515bd4); }
.login-social-btn-facebook:hover { background: #1877f2; }
.login-social-btn-youtube:hover { background: #ff0000; }
.login-social-btn-whatsapp:hover { background: #25d366; }
.login-social-btn-website:hover { background: rgba(255, 255, 255, .4); }

/* ---------- Settings > Social Media Links form - each field gets the
   platform's own brand-coloured icon badge next to its label (see
   socialIcon() in includes/functions.php), same brand colours as the login
   page's "Follow us" row, so Admin can see at a glance which is which. ---------- */
.social-field-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.social-field-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 700;
  font-size: 13px;
  color: var(--ink);
  margin-bottom: 6px;
}

.social-field-icon {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}

.social-field-icon svg {
  width: 14px;
  height: 14px;
}

.social-field-icon-instagram { background: linear-gradient(135deg, #f58529, #dd2a7b, #8134af, #515bd4); }
.social-field-icon-facebook { background: #1877f2; }
.social-field-icon-youtube { background: #ff0000; }
.social-field-icon-whatsapp { background: #25d366; }
.social-field-icon-website { background: var(--ink-soft); }

.login-card .eyebrow {
  margin-bottom: 14px;
}

.login-logo {
  width: 72px;
  height: 72px;
  border-radius: 18px;
  margin: 0 0 26px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #fff;
  color: #3a2405;
  font-weight: 700;
  font-size: 30px;
  border: 1px solid #eaecf0;
  box-shadow: 0 10px 30px rgba(16, 24, 40, .1);
}

.login-logo img {
  width: 100%;
  height: 100%;
  border-radius: 20px;
  object-fit: cover;
}

.login-header-center {
  text-align: left;
  margin-bottom: 30px;
}

.login-header-center p { margin: 0; color: #667085; font-size: 14px; }

.login-header-center .eyebrow {
  margin-bottom: 10px;
}

/* Pill-shaped icon inputs + gradient pill button - see modules/auth/login.php */
.login-form {
  margin-top: 0;
}

.login-field { margin-bottom: 20px; }
.login-field > label { display: block; margin-bottom: 8px; color: #344054; font-size: 13px; font-weight: 700; }

.login-input-group {
  position: relative;
}

.login-input-group .login-input-icon {
  position: absolute;
  left: 18px;
  top: 50%;
  transform: translateY(-50%);
  color: #98a2b3;
  display: flex;
  pointer-events: none;
}

.login-input-group .login-input-icon svg {
  width: 16px;
  height: 16px;
}

.login-input-group input {
  width: 100%;
  height: 52px;
  padding: 13px 18px 13px 48px;
  border-radius: 12px;
  border: 1px solid #d0d5dd;
  background: #fff;
  font-size: 14px;
  color: var(--ink);
}

.login-input-group input:focus {
  border-color: #ef4444;
  background: #fff;
  outline: none;
  box-shadow: 0 0 0 4px rgba(239, 68, 68, .1);
}

.login-submit-btn {
  display: block;
  width: 100%;
  margin-top: 8px;
  min-height: 52px;
  padding: 14px 20px;
  border-radius: 12px;
  border: none;
  background: linear-gradient(135deg, #e11d2e, #b91c1c);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  letter-spacing: .01em;
  box-shadow: 0 10px 22px rgba(185, 28, 28, .2);
  cursor: pointer;
  font-family: inherit;
}

.login-submit-btn span { float: right; font-size: 20px; line-height: 18px; }
.login-submit-btn:focus-visible { outline: 3px solid rgba(225, 29, 46, .25); outline-offset: 3px; }

.login-submit-btn:hover {
  filter: brightness(.96);
  transform: translateY(-1px);
}

.login-cf-register-link {
  font-size: 13px;
  font-weight: 750;
  color: #c81e2b;
}

.login-cf-register-link:hover {
  color: #991b1b;
}

.login-register-box { margin-top: 28px; padding: 16px; border: 1px solid #eaecf0; border-radius: 12px; background: #f9fafb; text-align: center; color: #667085; font-size: 13px; }
.login-register-box span { margin-right: 4px; }
.login-security-note { margin: 14px 0 0; text-align: center; color: #98a2b3; font-size: 11.5px; }

@media (max-width: 900px) {
  body.login-body { background: #f5f6f8; }
  .login-page { display: block; min-height: 100dvh; background: #f5f6f8; overflow: visible; }
  .login-showcase { min-height: 230px; padding: 24px 28px; }
  .login-showcase-copy { margin-top: 38px; }
  .login-showcase-copy h2 { margin: 10px 0; font-size: 32px; }
  .login-showcase-copy p, .login-feature-row { display: none; }
  .login-graphic { width: 58%; right: -3%; opacity: .09; }
  .login-panel { min-height: calc(100dvh - 190px); margin-top: -40px; padding: 0 20px 22px; border-radius: 28px 28px 0 0; position: relative; z-index: 3; }
  .login-wrap { align-items: flex-start; }
  .login-card { width: 460px; padding: 38px 14px 18px; }
  .login-logo { margin-bottom: 20px; }
}

@media (max-width: 480px) {
  .login-showcase { min-height: 205px; padding: 20px; }
  .login-topbar-logo { width: 36px; height: 36px; }
  .login-topbar-name { font-size: 16px; }
  .login-showcase-copy { margin-top: 30px; }
  .login-kicker { font-size: 10px; }
  .login-showcase-copy h2 { font-size: 27px; }
  .login-panel { min-height: calc(100dvh - 165px); padding: 0 14px 18px; }
  .login-card { padding: 30px 8px 14px; }
  .login-logo { width: 62px; height: 62px; border-radius: 15px; }
  .login-card h1 { font-size: 25px; }
  .login-header-center { margin-bottom: 24px; }
  .login-field { margin-bottom: 16px; }
  .login-register-box { margin-top: 22px; }
}

.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;
}

.text-soft {
  color: var(--ink-soft);
}

.mt-0 {
  margin-top: 0;
}

.mb-0 {
  margin-bottom: 0;
}

.text-right {
  text-align: right;
}

.flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
}

/* ---------- adaptive application shell ----------
   Desktop gets a permanent navigation workspace. Phones/tablets get a
   native-app shell with a drawer, compact header and thumb-friendly tabs. */
.mobile-menu-btn { display: none; }

@media (min-width: 901px) {
  .app-shell { display: flex; max-width: none; min-height: 100vh; margin: 0; background: var(--bg); box-shadow: none; }
  .sidebar { position: sticky; top: 0; width: 260px; height: 100vh; padding-bottom: 28px; overflow-y: auto; transform: none; box-shadow: 8px 0 28px rgba(16,24,40,.08); z-index: 40; }
  .sidebar-backdrop, .bottom-tabbar, .brand-topbar { display: none !important; }
  .main { flex: 1; width: auto; min-width: 0; }
  .topbar { top: 0; min-height: 64px; padding: 12px clamp(24px,3vw,42px); }
  .topbar-title { font-size: 19px; }
  .content { width: 100%; max-width: 1600px; margin: 0 auto; padding: 28px clamp(24px,3vw,42px) 56px; }
  .card { padding: 21px 23px; }
  .grid { gap: 20px; }
  .activity-card-row { display: grid; grid-template-columns: repeat(auto-fit,minmax(180px,1fr)); gap: 14px; overflow: visible; }
  .activity-card { min-width: 0; padding: 17px; }
  .quick-actions-grid { grid-template-columns: repeat(4,minmax(0,1fr)); gap: 14px; }
  .action-tile { min-height: 160px; padding: 18px; }
  .section-head { margin-top: 28px; }
  .table-wrap { overflow-x: auto; }
  .embed-content { max-width: 1200px; padding: 24px; }
}

@media (max-width: 900px) {
  body:not(.login-body) { background: #e9edf4; }
  body.nav-open { overflow: hidden; }
  .app-shell { position: relative; display: block; width: 100%; min-height: 100dvh; max-width: none; margin: 0; background: linear-gradient(180deg,#f8faff 0,#f2f4f8 190px); box-shadow: none; }
  .main { width: 100%; min-width: 0; }
  .bottom-tabbar { display: flex; position: fixed; left: 0; right: 0; bottom: 0; margin: 0; padding: 3px 4px max(3px,env(safe-area-inset-bottom)); background: rgba(255,255,255,.96); backdrop-filter: blur(16px); border-top: 1px solid rgba(208,213,221,.8); box-shadow: 0 -8px 28px rgba(16,24,40,.1); z-index: 1002; }
  .tab-link { min-width: 0; min-height: 58px; padding: 7px 2px 5px; font-size: 9.5px; }
  .tab-link svg { width: 20px; height: 20px; }
  .tab-indicator { top: 5px; height: calc(100% - 10px); border-radius: 13px; }
  .sidebar { position: fixed; inset: 0 auto 0 0; width: min(82vw,300px); height: 100dvh; padding-bottom: 80px; overflow-y: auto; transform: translateX(-105%); transition: transform .28s cubic-bezier(.22,.8,.3,1); box-shadow: 18px 0 42px rgba(0,0,0,.28); z-index: 1004; }
  .sidebar.is-open { transform: translateX(0); }
  .sidebar-backdrop { display: block; position: fixed; inset: 0; background: rgba(15,23,42,.55); backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity .22s ease; z-index: 1003; }
  .sidebar-backdrop.is-open { opacity: 1; pointer-events: auto; }
  .brand-topbar { top: 0; min-height: 58px; padding: 10px 14px; background: rgba(255,255,255,.94); color: var(--ink); backdrop-filter: blur(14px); }
  .mobile-menu-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; flex: 0 0 36px; padding: 0; border: 1px solid var(--border); border-radius: 11px; background: var(--surface-soft); color: var(--ink); }
  .mobile-menu-btn svg { width: 18px; height: 18px; }
  .brand-topbar-logo,.brand-topbar-badge { width: 32px; height: 32px; }
  .brand-topbar-name { font-size: 14px; }
  .brand-topbar-logout { width: 34px; height: 34px; background: var(--bad-soft); color: var(--bad); }
  .topbar { position: relative; top: auto; padding: 14px 16px 8px; background: transparent; border: 0; box-shadow: none; backdrop-filter: none; }
  .topbar-title { width: 100%; font-size: 20px; white-space: normal; }
  .topbar-user { width: 100%; justify-content: flex-start; gap: 8px; }
  .topbar-user strong { display: inline; max-width: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .topbar-user > a:last-child { display: none; }
  .content { padding: 12px 12px calc(82px + env(safe-area-inset-bottom)); }
  .card { padding: 16px; margin-bottom: 14px; border-radius: 16px; }
  .grid { gap: 12px; }
  .grid-3,.grid-4 { grid-template-columns: repeat(2,minmax(0,1fr)); }
  .table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 12px; }
  .table-wrap table { min-width: 680px; }
  input,select,textarea,button { font-size: 16px; }
  .btn,.button,button[type=submit],input[type=submit] { min-height: 44px; }
  .embed-content { max-width: none; padding: 14px 12px; }
  .embed-mode .content { padding-bottom: 18px; }
  body.role-plant .mobile-menu-btn { display: none; }

  /* Flutter-inspired mobile dashboard: flat surfaces, strong hierarchy and
     comfortable touch spacing. Scoped to dashboards so data-entry screens
     keep their denser, task-focused layout. */
  body.page-dashboard .app-shell {
    background: #f4f6fa;
  }
  body.page-dashboard .brand-topbar {
    min-height: 64px;
    padding: 11px 16px;
    border-bottom-color: rgba(226,232,240,.75);
    box-shadow: 0 4px 18px rgba(15,23,42,.055);
  }
  body.page-dashboard .brand-topbar-name {
    font-size: 15px;
    font-weight: 800;
  }
  body.page-dashboard .mobile-menu-btn {
    border: 0;
    background: #eef2ff;
    color: #4f46e5;
  }
  body.page-dashboard .content {
    padding: 14px 14px calc(90px + env(safe-area-inset-bottom));
  }
  body.page-dashboard .welcome-hero {
    position: relative;
    overflow: hidden;
    margin: 0 0 22px;
    padding: 20px;
    border: 0;
    border-radius: 22px;
    background: #4f46e5;
    box-shadow: 0 14px 30px rgba(79,70,229,.2);
  }
  body.page-dashboard .welcome-hero::after {
    content: '';
    position: absolute;
    width: 130px;
    height: 130px;
    right: -52px;
    top: -60px;
    border-radius: 50%;
    background: rgba(255,255,255,.1);
    box-shadow: -44px 104px 0 8px rgba(255,255,255,.055);
  }
  body.page-dashboard .welcome-hero-top { position: relative; z-index: 1; }
  body.page-dashboard .welcome-avatar {
    width: 52px;
    height: 52px;
    border: 2px solid rgba(255,255,255,.22);
    background: rgba(255,255,255,.16);
    color: #fff;
    box-shadow: none;
  }
  body.page-dashboard .welcome-hero-greeting { color: rgba(255,255,255,.72); }
  body.page-dashboard .welcome-hero-name { color: #fff; font-size: 19px; }
  body.page-dashboard .welcome-hero-icon-btn {
    border: 1px solid rgba(255,255,255,.18);
    background: rgba(255,255,255,.13);
    color: #fff;
  }
  body.page-dashboard .section-head { margin: 24px 2px 11px; }
  body.page-dashboard .section-head h3 { font-size: 16px; letter-spacing: -.015em; }
  body.page-dashboard .section-head .icon-chip {
    width: 32px;
    height: 32px;
    border-radius: 10px;
    box-shadow: none;
  }
  body.page-dashboard .card {
    padding: 18px;
    border: 0;
    border-radius: 18px;
    background: #fff;
    box-shadow: 0 5px 20px rgba(15,23,42,.055);
  }
  body.page-dashboard .progress-bar { height: 7px; background: #edf0f6; }
  body.page-dashboard .progress-bar-fill { border-radius: 999px; background: #4f46e5; }
  body.page-dashboard .activity-card-row {
    gap: 12px;
    margin: 0 -14px;
    padding: 0 14px 8px;
    scroll-padding-left: 14px;
    scroll-snap-type: x proximity;
  }
  body.page-dashboard .activity-card {
    flex-basis: 158px;
    padding: 15px;
    border: 0;
    border-radius: 18px;
    box-shadow: 0 4px 16px rgba(15,23,42,.065);
    scroll-snap-align: start;
  }
  body.page-dashboard .activity-card-top { margin-bottom: 17px; }
  body.page-dashboard .activity-card-icon { width: 32px; height: 32px; border-radius: 10px; }
  body.page-dashboard .activity-card-icon svg { width: 16px; height: 16px; }
  body.page-dashboard .activity-card-value { font-size: 25px; letter-spacing: -.035em; }
  body.page-dashboard .activity-card-view { opacity: .65; }
  body.page-dashboard .quick-actions-grid { gap: 12px; }
  body.page-dashboard .action-tile {
    min-height: 146px;
    padding: 15px;
    border: 0;
    border-radius: 20px;
    box-shadow: 0 4px 16px rgba(15,23,42,.045);
  }
  body.page-dashboard .action-tile-icon svg { height: 76px; }
  body.page-dashboard .action-tile-label { font-size: 12.5px; }
  body.page-dashboard .bottom-tabbar {
    left: 10px;
    right: 10px;
    bottom: max(9px,env(safe-area-inset-bottom));
    padding: 5px;
    border: 1px solid rgba(226,232,240,.9);
    border-radius: 21px;
    box-shadow: 0 12px 34px rgba(15,23,42,.18);
  }
  body.page-dashboard .tab-link { min-height: 56px; border-radius: 16px; }
  body.page-dashboard .tab-indicator { top: 5px; height: calc(100% - 10px); background: #eef2ff; border-radius: 16px; }
  body.page-dashboard .tab-link.active { color: #4f46e5; }
}

@media (max-width: 480px) {
  .content { padding-left: 10px; padding-right: 10px; }
  .card { padding: 14px; }
  .stat-card .stat-value { font-size: 21px; }
  .role-badge { display: none; }
  table { font-size: 12px; }
  .form-row { grid-template-columns: minmax(0,1fr); }
}

@media (max-width: 340px) {
  .grid-2,.grid-3,.grid-4 { grid-template-columns: 1fr; }
  .tab-link span { font-size: 8.5px; }
}

/* Phones: the "⋮" menu opens as a sheet sitting just above the bottom tab
   bar instead of dropping below its button, where long menus (vehicle
   options) ran off the screen behind the tab bar. It can't simply stack
   over the tab bar - the menu lives inside the page's own stacking layer -
   so it's lifted clear of it instead. */
@media (max-width: 900px) {
  .more-menu-pop,
  .more-menu-right .more-menu-pop {
    position: fixed;
    top: auto;
    left: 10px;
    right: 10px;
    bottom: calc(86px + env(safe-area-inset-bottom));
    z-index: 1010;
    min-width: 0 !important;
    max-height: calc(100dvh - 170px);
    overflow-y: auto;
    padding: 10px;
    border-radius: 16px;
    box-shadow: 0 0 0 100vmax rgba(15, 23, 42, 0.45), 0 -8px 28px rgba(15, 23, 42, 0.2);
  }
  .more-menu-pop .btn { padding: 11px 14px; font-size: 14px; margin-bottom: 6px; }
  .more-menu-pop .btn:last-child { margin-bottom: 0; }
}

/* Edit / message panels opened from a "⋮" menu show as a popup - see the
   panel toggle in includes/partials/batch-cards.php, which moves the panel
   to <body> while it's open. */
.sku-panel-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1050;
  background: rgba(15, 23, 42, 0.5);
}
/* Centred with inset + margin:auto, not transform - a transform would trap
   any position:fixed popup inside it (e.g. Mark Loading's damage popup). */
.sku-edit-panel.sku-panel-popup {
  position: fixed;
  z-index: 1051;
  inset: 0;
  width: min(560px, calc(100vw - 24px));
  height: fit-content;
  max-height: calc(100dvh - 40px);
  overflow-y: auto;
  margin: auto !important;
  padding: 0 16px 16px;
  background: var(--surface);
  border-radius: 16px;
  box-shadow: 0 20px 50px rgba(15, 23, 42, 0.3);
}
.sku-panel-popup-head { display: none; }
.sku-panel-popup > .sku-panel-popup-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  position: sticky;
  top: 0;
  z-index: 1;
  margin: 0 -16px 12px;
  padding: 14px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: 15px;
}
.sku-panel-popup-close {
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: var(--surface-soft);
  color: var(--ink);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
/* Hammer Life line on the Processing Report - renderHammerLife() in includes/hammer.php. */
.hammer-line {
  margin: 16px 0 0;
}
.hammer-line-track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: var(--border);
}
.hammer-line-fill {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-radius: 999px;
  background: var(--primary);
}
.hammer-line-fill.is-due { background: var(--accent); }
.hammer-line-fill.is-over { background: var(--bad); }
.hammer-line-fill.is-past { background: #9aa3b8; }
/* Run since the last rotation, drawn over the fill with its label above. */
.hammer-line.has-now { margin-top: 30px; }
.hammer-line-since {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 0 999px 999px 0;
  background: var(--good);
}
.hammer-line-now {
  position: absolute;
  bottom: 16px;
  transform: translateX(-50%);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--good);
  white-space: nowrap;
}
.hammer-line-now.is-left { transform: none; }
.hammer-line-now.is-right { transform: translateX(-100%); }
.hammer-line-tick {
  position: absolute;
  top: -4px;
  bottom: -4px;
  width: 2px;
  margin-left: -1px;
  border-radius: 1px;
  background: var(--ink-soft);
  opacity: .45;
}
.hammer-line-dot {
  position: absolute;
  top: 50%;
  width: 22px;
  height: 22px;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 2px solid var(--surface);
  box-shadow: var(--shadow-sm);
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
}
.hammer-line-dot-rotate { background: var(--accent); color: var(--accent-ink); }
.hammer-line-dot-change { background: var(--good); color: #fff; }
.hammer-line-dot-start { background: var(--surface-soft); color: var(--ink-soft); border-color: var(--border); }
.hammer-line-dot-now { background: var(--good); box-shadow: 0 0 0 3px var(--good-soft); }
.hammer-events .hammer-line-dot-now { width: 14px; height: 14px; margin: 4px; }
.hammer-line-scale {
  position: relative;
  height: 16px;
  margin-top: 6px;
  font-size: 11px;
  color: var(--ink-soft);
}
.hammer-line-scale span {
  position: absolute;
  transform: translateX(-50%);
  white-space: nowrap;
}
.hammer-line-scale span.is-start { transform: none; }
.hammer-line-scale span.is-end { transform: translateX(-100%); }
.hammer-events {
  list-style: none;
  margin: 12px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-size: 13px;
}
.hammer-events li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
}
.hammer-events .hammer-line-dot {
  position: static;
  flex: 0 0 auto;
  transform: none;
}
.hammer-events-meta {
  font-size: 12px;
  margin-top: 2px;
}
.hammer-events-meta .pill {
  font-size: 10.5px;
  padding: 1px 8px;
}
.hammer-past {
  padding-top: 12px;
  margin-top: 12px;
  border-top: 1px solid var(--border);
}

/* Plant Head dashboard: a batch whose vehicle is waiting on Plant Head -
   pinned to the top of All Batches (dashboard/plant-head.php). */
body details.card.batch-card-attention {
  border-left: 4px solid var(--bad);
  background: linear-gradient(100deg, var(--bad-soft) 0%, #fff 45%);
  box-shadow: 0 0 0 1px rgba(220, 59, 46, .3);
}

/* Urgent batch (Admin put it on top): red edge, tint and ring so Plant Head spots it at once. */
body details.card.batch-card-priority {
  border-left: 5px solid var(--bad);
  background: linear-gradient(100deg, var(--bad-soft) 0%, #fff 55%);
  box-shadow: 0 0 0 1.5px rgba(220, 59, 46, .55), 0 6px 20px rgba(220, 59, 46, .16);
}
body details.card.batch-card-priority .pill-bad { background: var(--bad); color: #fff; }

/* Remarks notes: one line each, sit directly under their SKU row. */
.remarks-body .revised-box > div,
.remarks-body .carry-forward-box > div {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 8px;
}

.remarks-body .revised-detail,
.remarks-body .carry-forward-detail {
  margin-top: 0;
}

.remarks-body .revised-box,
.remarks-body .carry-forward-box {
  align-items: center;
}

.remarks-body .carry-forward-box .btn {
  padding: 1px 8px;
}

.remarks-btn {
  margin-left: 8px;
  padding: 0 8px;
  font-size: 11px;
  line-height: 18px;
  color: #6b7280;
  background: #f3f4f6;
  border: 1px solid #e5e7eb;
  border-radius: 999px;
  cursor: pointer;
}

.remarks-btn:hover {
  background: #e5e7eb;
}

/* Quick Actions (Plant Head and Admin dashboards): wide, short tiles - label + arrow on top,
   the picture sitting bottom-right, a thin coloured edge. */
body.page-dashboard .quick-actions-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
body.page-dashboard .action-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-height: 112px !important;
  padding: 13px 14px !important;
  border: 0;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1.5px rgba(15, 23, 42, .08), 0 4px 14px rgba(15, 23, 42, .04);
}
body.page-dashboard .action-tile-amber { box-shadow: inset 0 0 0 1.5px rgba(234, 179, 8, .3), 0 4px 14px rgba(15, 23, 42, .04); }
body.page-dashboard .action-tile-purple { box-shadow: inset 0 0 0 1.5px rgba(124, 92, 255, .25), 0 4px 14px rgba(15, 23, 42, .04); }
body.page-dashboard .action-tile-green { box-shadow: inset 0 0 0 1.5px rgba(16, 185, 129, .3), 0 4px 14px rgba(15, 23, 42, .04); }
body.page-dashboard .action-tile-blue { box-shadow: inset 0 0 0 1.5px rgba(59, 130, 246, .3), 0 4px 14px rgba(15, 23, 42, .04); }
body.page-dashboard .action-tile.needs-attention { box-shadow: inset 0 0 0 1.5px rgba(220, 59, 46, .55), 0 4px 14px rgba(220, 59, 46, .08); }
body.page-dashboard .action-tile-bottom { position: relative; z-index: 2; }
body.page-dashboard .action-tile-label { font-size: 14.5px; font-weight: 800; }
body.page-dashboard .action-tile-attention { position: relative; z-index: 2; margin-top: 0; font-size: 10.5px; font-weight: 600; }
body.page-dashboard .action-tile-icon {
  position: absolute;
  right: 8px;
  bottom: 4px;
  width: 64%;
  height: 66%;
  margin: 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  pointer-events: none;
}
body.page-dashboard .action-tile-icon svg { width: 100%; height: 100% !important; margin: 0; }
@media (min-width: 901px) {
  body.page-dashboard .quick-actions-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 14px; }
  body.page-dashboard .action-tile { min-height: 132px !important; padding: 16px 18px !important; }
  body.page-dashboard .action-tile-label { font-size: 15.5px; }
}

/* Admin Quick Actions: Water Tanker / Diesel as short half-width tiles, Send Daily Report Message full width, so the grid has no orphan. */
body.page-dashboard .action-tile-compact { min-height: 78px !important; }
body.page-dashboard .action-tile-compact .action-tile-icon { width: 46%; height: 78%; }
body.page-dashboard .action-tile-wide { grid-column: 1 / -1; min-height: 84px !important; }
body.page-dashboard .action-tile-wide .action-tile-icon { width: 34%; }
@media (min-width: 901px) {
  body.page-dashboard .action-tile-compact { grid-column: span 2; min-height: 92px !important; }
}

/* Dashboard stat cards (Today's Snapshot, Stock Overview): compact - cards size to their own content, not to the tallest one. */
body.page-dashboard .activity-card-row { align-items: start; }
body.page-dashboard .activity-card { padding: 12px 14px; min-height: 0; }
body.page-dashboard .activity-card-top { margin-bottom: 8px; }
body.page-dashboard .activity-card-value { font-size: 22px; line-height: 1.15; }

/* Same height for every card in a row; on phones the per-SKU packing lines stay out of the card (they're in the Packing report). */
body.page-dashboard .activity-card-row { align-items: stretch; }
/* The per-SKU bag lines sit behind the arrow on the Packing (bags) card (hidden until tapped), so every snapshot card stays the same size. */
#liveTodayPackedBreakdown[hidden] { display: none; }

/* Admin Quick Actions: every tile the same size (no wide / double tiles) - 2 columns on phones, 4 on desktop, short tiles. */
body.page-dashboard .action-tile-compact,
body.page-dashboard .action-tile-wide { grid-column: auto !important; min-height: 112px !important; }
body.page-dashboard .action-tile-compact .action-tile-icon,
body.page-dashboard .action-tile-wide .action-tile-icon { width: 64%; height: 66%; }
@media (min-width: 901px) {
  body.page-dashboard .quick-actions-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  body.page-dashboard .action-tile,
  body.page-dashboard .action-tile-compact,
  body.page-dashboard .action-tile-wide { min-height: 120px !important; padding: 14px 16px !important; }
  body.page-dashboard .action-tile-label { font-size: 15px; }
}

/* Needs-attention tiles: the red badge becomes a small pill on its own line and the picture sits lower / smaller, so they never overlap. */
body.page-dashboard .action-tile.needs-attention { min-height: 124px !important; }
body.page-dashboard .action-tile.needs-attention .action-tile-attention {
  align-self: flex-start;
  gap: 5px;
  margin-top: 4px;
  padding: 3px 9px 3px 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .85);
  box-shadow: 0 1px 4px rgba(220, 59, 46, .18);
  font-size: 9.5px;
  letter-spacing: .05em;
}
body.page-dashboard .action-tile.needs-attention .action-tile-icon { width: 50%; height: 52%; right: 6px; bottom: 4px; }
body.page-dashboard .action-tile.needs-attention { min-height: 136px !important; }
body.page-dashboard .action-tile.needs-attention .action-tile-icon { width: 46%; height: 45%; right: 8px; bottom: 6px; }

/* Packing Update > Today's Production: entry rows show their bags / MT up front; details as tidy tiles with the photo beside them. */
.packing-entry-card > summary { display: flex; align-items: center; gap: 10px; }
.packing-entry-card .row-card-heading { flex: 1; min-width: 0; }
.packing-entry-total { flex-shrink: 0; font-size: 12.5px; color: var(--ink-soft); background: rgba(255,255,255,.7); border-radius: 999px; padding: 4px 11px; white-space: nowrap; }
.packing-entry-total strong { color: var(--ink); font-size: 14px; }
.packing-entry-card .row-card-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 10px; align-items: stretch; }
.packing-entry-card .row-card-fields > div { background: rgba(255,255,255,.75); border-radius: 12px; padding: 9px 12px; }
.packing-entry-card .row-card-fields .field-value { font-size: 15px; font-weight: 700; margin-top: 2px; }
.packing-entry-card .row-card-fields > div:has(img) { grid-column: span 2; display: flex; align-items: center; gap: 12px; }
@media (max-width: 600px) {
  .packing-entry-total { font-size: 11.5px; padding: 3px 9px; }
  .packing-entry-card .row-card-fields { grid-template-columns: 1fr 1fr; }
}

/* Batch card: small icon in the top row that shows / hides the Batch Message */
.batch-msg-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--ink-soft);
  cursor: pointer;
}
.batch-msg-icon svg { width: 16px; height: 16px; }
.batch-msg-icon:hover { border-color: var(--border); color: var(--ink); background: var(--surface-soft); }
.bilty-block[hidden] { display: none; }

/* Batch Message preview on the batch card (per-line sizes are set inline) */
.batch-msg-preview { margin-top: 8px; padding: 10px 12px; border: 1px solid var(--border); border-radius: 12px; background: var(--surface-soft); color: var(--ink); line-height: 1.45; word-break: break-word; }

/* Edit Batch details popup: compact two-column form (one column on very narrow phones) */
.batch-edit-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; align-items: end; }
.batch-edit-form > div { min-width: 0; flex: none !important; }
.batch-edit-form .be-full { grid-column: 1 / -1; }
.batch-edit-form label { margin: 0 0 3px; font-size: 12px; }
.batch-edit-form input, .batch-edit-form select, .batch-edit-form textarea { min-height: 38px; padding: 7px 10px; font-size: 14px; border-radius: 10px; width: 100%; box-sizing: border-box; }
.batch-edit-form textarea { min-height: 60px; }
@media (max-width: 380px) { .batch-edit-form { grid-template-columns: 1fr; } }

/* "Batch to be printed" icon -> what goes on each bag (batch card) */
.batch-print-panel { margin-top: 8px; }
.batch-print-panel .bp-label { margin-bottom: 8px; }
.batch-print-panel .bp-label:last-child { margin-bottom: 0; }
.bp-label { padding: 10px 12px; border: 1px dashed var(--border); border-radius: 12px; background: var(--surface-soft); }
.bp-name { font-size: 15px; font-weight: 800; color: var(--ink); }
.bp-line { white-space: pre-wrap; margin-top: 2px; font-size: 14px; color: var(--ink); word-break: break-word; }
.bp-line.bp-missing { color: var(--bad); font-weight: 600; font-size: 13px; }

/* Quick Actions: every tile exactly the same size (needs-attention ones used to be taller than the rest). */
body.page-dashboard .quick-actions-grid { grid-auto-rows: 1fr; }
body.page-dashboard .action-tile,
body.page-dashboard .action-tile-compact,
body.page-dashboard .action-tile-wide,
body.page-dashboard .action-tile.needs-attention { min-height: 136px !important; height: 100%; box-sizing: border-box; }

/* "Batch to be printed": one small bold line per SKU, always visible on the batch card */
.batch-print-lines { margin-top: 4px; }
.bp-oneline { font-size: 12.5px; font-weight: 700; line-height: 1.45; color: var(--ink); white-space: pre-wrap; word-break: break-word; }
.bp-oneline.bp-missing { color: var(--bad); font-weight: 600; }

/* "Batch to be printed" row: closed by default, the arrow opens the per-SKU print lines */
.batch-print-details { margin-top: 8px; }
.batch-print-details > summary { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; cursor: pointer; list-style: none; font-size: 14px; font-weight: 700; color: var(--ink); }
.batch-print-details > summary::-webkit-details-marker { display: none; }
.batch-print-details .bp-chevron { display: inline-flex; margin-left: 2px; color: var(--ink-soft); }
.batch-print-details .bp-chevron svg { width: 16px; height: 16px; transition: transform .2s ease; }
.batch-print-details[open] .bp-chevron svg { transform: rotate(180deg); }

.bp-oneline .bp-sku { color: var(--ink-soft); font-weight: 600; }
.bp-oneline:not(.bp-missing) { color: #111827; }

/* Payment received radios in the batch details popups */
.be-radios { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 2px 0 4px; }
.be-radios label { display: inline-flex; align-items: center; gap: 6px; margin: 0; font-size: 13px; font-weight: 600; cursor: pointer; }
.batch-edit-form .be-radios input[type=radio], .be-radios input[type=radio] { width: auto; min-height: 0; padding: 0; }

/* Hammers page: Hammer Status is a closed card until tapped */
.hammer-status-card > summary { display: flex; align-items: center; gap: 10px; cursor: pointer; list-style: none; }
.hammer-status-card > summary::-webkit-details-marker { display: none; }
.hammer-status-card .hs-title { font-size: 17px; }
.hammer-status-card .hs-meta { margin-left: auto; font-size: 13px; color: var(--ink-soft); font-weight: 600; white-space: nowrap; }
.hammer-status-card .hs-chevron { display: inline-flex; color: var(--ink-soft); }
.hammer-status-card .hs-chevron svg { width: 18px; height: 18px; transition: transform .2s ease; }
.hammer-status-card[open] .hs-chevron svg { transform: rotate(180deg); }

.pk-toggle { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 8px; background: transparent; color: var(--ink-soft); cursor: pointer; flex-shrink: 0; }
.pk-toggle:hover { background: var(--surface-soft); }
.pk-toggle svg { width: 18px; height: 18px; transition: transform .2s ease; }
.pk-toggle.is-open svg { transform: rotate(180deg); }

/* Hammer line: gradient fill is set inline; the run-since-rotation segment becomes a light overlay so the gradient shows;
   each rotation / change dot gets its exact MT written above it. */
.hammer-line-since { background: rgba(255, 255, 255, .32); }
.hammer-line.has-dots { margin-top: 30px; }
.hammer-line-dot-mt {
  position: absolute;
  bottom: 16px;
  transform: translateX(-50%);
  font-size: 11px;
  font-weight: 800;
  color: var(--ink);
  white-space: nowrap;
}

/* Hammer line with a rotation dot AND the "since rotation" label: the label goes on its own row above the dot's MT,
   so the two never print over each other (phones especially). */
.hammer-line.has-now.has-dots { margin-top: 52px; }
.hammer-line.has-now.has-dots .hammer-line-now { bottom: 34px; }
.hammer-line.has-now.has-dots .hammer-line-now::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 100%;
  height: 16px;
  border-left: 1px dashed currentColor;
  opacity: .5;
}
.hammer-line.has-now.has-dots .hammer-line-now.is-left::after { left: 0; }
.hammer-line.has-now.has-dots .hammer-line-now.is-right::after { left: 100%; }

/* Dashboard Hammers card: no 0 / 60 / 70 / 120 scale, tighter spacing */
.hammer-card-compact .hammer-line-scale { display: none; }
.hammer-card-compact .hammer-line { margin-top: 0; }
.hammer-card-compact .hammer-line.has-now, .hammer-card-compact .hammer-line.has-dots { margin-top: 26px; }
.hammer-card-compact .hammer-line-track { height: 8px; }
.hammer-card-compact .hammer-line-dot { width: 18px; height: 18px; font-size: 10px; }
.hammer-card-compact .hammer-line-now, .hammer-card-compact .hammer-line-dot-mt { bottom: 12px; font-size: 10.5px; }

/* Dashboard Hammers card: keep the labels on their own rows so nothing overlaps the heading */
.hammer-card-compact .hammer-line.has-now, .hammer-card-compact .hammer-line.has-dots { margin-top: 44px; }
.hammer-card-compact .hammer-line-dot-mt { bottom: 12px; }
.hammer-card-compact .hammer-line-now { bottom: 28px; }

/* Hammers dashboard card: the 'since rotation' label sits under the bar, nothing else below it */
.hammer-card-compact .hammer-line.has-now, .hammer-card-compact .hammer-line.has-dots { margin-top: 22px; margin-bottom: 20px; }
.hammer-card-compact .hammer-line-now { bottom: auto; top: 14px; }
.hammer-card-compact .hammer-line-dot-mt { bottom: 12px; }
.hammer-card-compact .help-text:empty { display: none; }

/* Hammers dashboard card: 'since rotation' label clear of the rotation dot */
.hammer-card-compact .hammer-line-now { top: 20px; }
.hammer-card-compact .hammer-line.has-now, .hammer-card-compact .hammer-line.has-dots { margin-bottom: 28px; }

/* Dashboard Hammers card: the label sits under the bar, so the dashed connector line is not needed (it ran through the text) */
.hammer-card-compact .hammer-line.has-now.has-dots .hammer-line-now::after { display: none; }
.hammer-card-compact .hammer-line.has-now.has-dots .hammer-line-now { bottom: auto; top: 20px; }
.hammer-card-compact .hammer-line.has-now.has-dots { margin-top: 30px; }
