/* =============================================================
   FRAMEFLOW — DESIGN SYSTEM
   Light "Aurora" theme (indigo → violet). Inter font.
   Clean, professional, counter-friendly.
   The whole app is token-driven; the AURORA THEME LAYER at the
   foot of this file adds the motion, depth and gradient accents
   on top of these tokens.
   ============================================================= */

/* -----------------------------------------------------------
   TOKENS
   ----------------------------------------------------------- */
:root {
  /* Brand — indigo → violet accent */
  --teal:          #6366f1;
  --teal-dim:      #4f46e5;
  --teal-muted:    #a5b4fc;
  --teal-glow:     rgba(99,102,241,0.20);
  --teal-subtle:   rgba(99,102,241,0.09);

  /* Backgrounds — airy light greys, white cards */
  --bg:            #eef0f4;
  --surface:       #ffffff;
  --surface-raised:#f4f6f9;
  --surface-high:  #e9ecf2;

  /* Borders — hairline */
  --border:        #e4e7ee;
  --border-bright: #d3d8e2;

  /* Text — near-black, soft greys */
  --text:          #1b1d23;
  --text-secondary:#5b6270;
  --text-muted:    #98a0ad;

  /* Sidebar — clean white */
  --sidebar-bg:    #ffffff;
  --sidebar-w:     232px;

  /* Semantic (kept vivid; tints read fine on light) */
  --green:  #16a34a; --green-bg:  rgba(22,163,74,0.10);
  --amber:  #d97706; --amber-bg:  rgba(217,119,6,0.10);
  --red:    #dc2626; --red-bg:    rgba(220,38,38,0.10);
  --blue:   #2563eb; --blue-bg:   rgba(37,99,235,0.10);
  --purple: #7c3aed; --purple-bg: rgba(124,58,237,0.10);
  --orange: #ea580c; --orange-bg: rgba(234,88,12,0.10);

  /* Geometry & depth — rounder, soft daylight shadows */
  --header-h:      58px;
  --radius-sm:     8px;
  --radius:        12px;
  --radius-lg:     18px;
  --radius-xl:     24px;
  --shadow:        0 1px 2px rgba(17,24,39,0.05), 0 1px 3px rgba(17,24,39,0.08);
  --shadow-md:     0 12px 32px -10px rgba(17,24,39,0.16), 0 3px 8px rgba(17,24,39,0.06);
  --shadow-lg:     0 32px 72px -18px rgba(17,24,39,0.30), 0 8px 24px -10px rgba(17,24,39,0.18);
  --font:          'Inter', 'Segoe UI', system-ui, sans-serif;
  --font-mono:     'SF Mono', 'Fira Code', 'Consolas', monospace;
  --ease:          cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring:   cubic-bezier(0.22, 1.2, 0.36, 1);

  /* Liquid Glass — shared recipe for every frosted surface (see the
     LIQUID GLASS LAYER at the foot of this file). Backgrounds stay
     ≥66% opaque so text keeps AA contrast even where backdrop-filter
     isn't supported and the blur silently no-ops. */
  --glass-blur:      blur(22px) saturate(170%);
  --glass-blur-soft: blur(14px) saturate(150%);
  --glass-bg:        color-mix(in srgb, var(--surface) 66%, transparent);
  --glass-bg-strong: color-mix(in srgb, var(--surface) 84%, transparent);
  /* Near-solid tier for pick-lists (nav dropdown, autocompletes): those sit
     inside surfaces that already have backdrop-filter, and a nested
     backdrop-filter can't re-frost the page behind — the blur silently
     no-ops, so translucency there is pure ghosting with no frost. */
  --glass-bg-opaque: color-mix(in srgb, var(--surface) 96%, transparent);
  --glass-border:    rgba(255,255,255,0.55);
  --glass-edge:      0 0 0 1px rgba(17,24,39,0.05);
  --glass-inset:     inset 0 1px 0 rgba(255,255,255,0.65);
}

/* -----------------------------------------------------------
   DARK THEME — same tokens, dark values. Applied by setting
   data-theme="dark" on <html> (see app.js applyTheme / index.html's
   early inline script, which sets this before first paint so there's
   no flash of the light theme). Everything below :root already reads
   these tokens, so most of the app adapts automatically — only a
   handful of spots hardcoded an actual colour instead of a token
   (page header glass, text selection, scrollbar, two legacy badges,
   the native date-picker) and those get their own dark overrides
   further down, right next to what they're overriding.
   ----------------------------------------------------------- */
html[data-theme="dark"] {
  --teal:          #6366f1;
  --teal-dim:      #a5b4fc;
  --teal-muted:    #4f46e5;
  --teal-glow:     rgba(99,102,241,0.28);
  --teal-subtle:   rgba(99,102,241,0.16);

  --bg:            #0c0c14;
  --surface:       #17171f;
  --surface-raised:#1e1e29;
  --surface-high:  #272733;

  --border:        rgba(255,255,255,0.09);
  --border-bright: rgba(255,255,255,0.17);

  --text:          #f2f2f7;
  --text-secondary:#c2c2d2;
  --text-muted:    #85859c;

  --sidebar-bg:    #121219;

  --green:  #22c55e; --green-bg:  rgba(34,197,94,0.16);
  --amber:  #f59e0b; --amber-bg:  rgba(245,158,11,0.16);
  --red:    #f87171; --red-bg:    rgba(248,113,113,0.16);
  --blue:   #60a5fa; --blue-bg:   rgba(96,165,250,0.16);
  --purple: #c084fc; --purple-bg: rgba(192,132,252,0.16);
  --orange: #fb923c; --orange-bg: rgba(251,146,60,0.16);

  --shadow:        0 1px 2px rgba(0,0,0,0.35), 0 1px 3px rgba(0,0,0,0.3);
  --shadow-md:     0 12px 32px -10px rgba(0,0,0,0.55), 0 3px 8px rgba(0,0,0,0.3);
  --shadow-lg:     0 32px 72px -18px rgba(0,0,0,0.65), 0 8px 24px -10px rgba(0,0,0,0.45);

  --glass-bg:        color-mix(in srgb, var(--surface) 60%, transparent);
  --glass-bg-strong: color-mix(in srgb, var(--surface) 82%, transparent);
  --glass-bg-opaque: color-mix(in srgb, var(--surface) 95%, transparent);
  --glass-border:    rgba(255,255,255,0.13);
  --glass-edge:      0 0 0 1px rgba(0,0,0,0.35);
  --glass-inset:     inset 0 1px 0 rgba(255,255,255,0.09);

  color-scheme: dark;
}

/* -----------------------------------------------------------
   RESET
   ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
  height: 100%;
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  /* This is meant to run like an app, not a zoomable webpage — the
     viewport meta tag's user-scalable=no covers most mobile browsers, but
     recent iOS Safari ignores that specifically for pinch-zoom, so this
     backs it up: pan-x/pan-y allow normal scrolling, omitting pinch-zoom
     from the value is what actually blocks it there. */
  touch-action: pan-x pan-y;
}
a { color: var(--teal); text-decoration: none; }
a:hover { text-decoration: underline; }
/* touch-action: manipulation stops mobile browsers treating quick repeat
   taps (e.g. punching in a PIN) as a double-tap-to-zoom gesture, and drops
   the ~300ms tap delay along with it — applies everywhere, not just the
   PIN pad, since it's a pure improvement with no accessibility downside
   (pinch-zoom elsewhere on the page is untouched). */
button { cursor: pointer; font-family: inherit; touch-action: manipulation; }
input, select, textarea { font-family: inherit; color: var(--text); }
ul { list-style: none; }
h1 { font-size: 22px; font-weight: 700; }
h2 { font-size: 17px; font-weight: 600; }
h3 { font-size: 15px; font-weight: 600; }
h4 { font-size: 13px; font-weight: 600; }
p  { line-height: 1.6; }

/* -----------------------------------------------------------
   LAYOUT
   ----------------------------------------------------------- */
#app {
  display: flex;
  height: 100vh;
  overflow: hidden;
}

/* -----------------------------------------------------------
   SIDEBAR
   ----------------------------------------------------------- */
#sidebar {
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
}

.sidebar-header {
  padding: 20px 16px 16px;
  border-bottom: 1px solid var(--border);
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
}

.nav-caret {
  display: none;
  margin-left: auto;
  font-size: 14px;
  color: var(--text-muted);
  transition: transform 0.18s var(--ease);
}

/* Current page name — mobile-only, see the max-width:600px block below. */
.sidebar-page-label { display: none; }

.logo-icon-wrap {
  width: 34px;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.logo-name {
  font-size: 16px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.3px;
}
.logo-name-accent {
  background: linear-gradient(120deg, var(--teal), #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* -----------------------------------------------------------
   FRAMEFLOW LOGO MARK (shared SVG)
   ----------------------------------------------------------- */
.ff-mark {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}
.ff-mark .ff-frame { stroke-linecap: round; }

/* Nav section label */
.nav-section-label {
  padding: 16px 16px 6px;
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
}

.nav-list {
  padding: 10px 8px;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 12px;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
  color: var(--text-secondary);
  font-size: 14px;
  font-weight: 500;
  user-select: none;
  position: relative;
}
.nav-item:hover  { background: var(--surface-raised); color: var(--text); }
.nav-item.active {
  background: var(--teal-subtle);
  color: var(--teal);
}
.nav-item.active .nav-icon { color: var(--teal); }

/* New Job — filled teal button so it reads as the primary action */
.nav-item-cta {
  background: var(--teal);
  color: #fff;
  font-weight: 600;
  margin-bottom: 8px;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.12);
}
.nav-item-cta .nav-icon { color: #fff; }
.nav-item-cta:hover,
.nav-item-cta.active {
  background: var(--teal-dim);
  color: #fff;
}
.nav-item-cta.active .nav-icon { color: #fff; }

/* -----------------------------------------------------------
   FLOATING "NEW JOB" BUTTON (FAB)
   ----------------------------------------------------------- */
#fab-new-job {
  position: fixed;
  right: 28px;
  bottom: 28px;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 15px 24px;
  border: none;
  border-radius: 999px;
  background: var(--teal);
  color: #fff;
  font-family: var(--font);
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(20,184,166,0.35), 0 2px 6px rgba(0,0,0,0.18);
  transition: background 0.14s, transform 0.1s, box-shadow 0.14s;
}
#fab-new-job i { font-size: 20px; }
#fab-new-job:hover {
  background: var(--teal-dim);
  box-shadow: 0 8px 24px rgba(20,184,166,0.45), 0 3px 8px rgba(0,0,0,0.22);
}
/* Scan mode (Production) — icon only, a barcode glyph doesn't need a label.
   Round rather than the default pill, same treatment the whole button
   already gets on mobile. */
#fab-new-job.fab-icon-only {
  width: 54px; height: 54px; padding: 0; justify-content: center; border-radius: 50%;
}
/* No point offering a scan shortcut on a machine with no camera — see
   FF.hasCamera in app.js, which actually probes for one rather than
   guessing from screen size or input type (an iPad with a mouse attached
   still reports hover:hover/pointer:fine, so that would've hidden it on a
   real iPad+mouse setup too). */
body.no-camera #fab-new-job.fab-icon-only { display: none; }
#fab-new-job:active { transform: scale(0.96); }
#fab-new-job.hidden { display: none; }

/* Quote → Job conversion banner on the New Job page */
.convert-banner {
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--teal-subtle);
  border: 1px solid rgba(99,102,241,0.3);
  border-left: 3px solid var(--teal);
  color: var(--text);
  border-radius: var(--radius);
  padding: 11px 14px;
  margin-bottom: 12px;
  font-size: 13px;
  line-height: 1.4;
}
.convert-banner i { color: var(--teal); font-size: 18px; flex-shrink: 0; }

/* Collapsible price breakdown on the New Job page */
.breakdown-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.breakdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: none;
  background: transparent;
  color: var(--teal);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  padding: 4px 6px;
  border-radius: var(--radius-sm);
  transition: background 0.12s;
}
.breakdown-toggle:hover { background: var(--teal-subtle); }
.breakdown-toggle i { font-size: 14px; }

.nav-icon  { font-size: 18px; flex-shrink: 0; width: 20px; }
.nav-label { font-size: 14px; }

.nav-placeholder { opacity: 0.5; }
.nav-phase-badge {
  margin-left: auto;
  font-size: 10px;
  font-weight: 600;
  background: var(--surface-high);
  color: var(--text-muted);
  border-radius: 20px;
  padding: 2px 7px;
  border: 1px solid var(--border);
}

/* Sub-items */
.nav-sub-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 10px 6px 38px;
  font-size: 13px;
  font-weight: 400;
  cursor: pointer;
  color: var(--text-muted);
  border-radius: var(--radius);
  transition: background 0.12s, color 0.12s;
  user-select: none;
}
.nav-sub-item:hover  { background: var(--surface-raised); color: var(--text-secondary); }
.nav-sub-item.active { color: var(--teal); background: var(--teal-subtle); }
.nav-sub-icon { font-size: 10px; flex-shrink: 0; }

.sidebar-footer {
  padding: 12px 16px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  gap: 7px;
}
.sidebar-footer strong { color: var(--text-secondary); }

/* -----------------------------------------------------------
   MAIN CONTENT
   ----------------------------------------------------------- */
#main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  background: var(--bg);
}

#page-header {
  height: var(--header-h);
  padding: 0 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
#page-title {
  font-size: 18px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.3px;
}
#page-actions { display: flex; gap: 8px; align-items: center; }

#page-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px;
}

/* -----------------------------------------------------------
   LOADING
   ----------------------------------------------------------- */
#loading-spinner {
  position: absolute;
  inset: 0;
  background: rgba(15,17,21,0.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  backdrop-filter: blur(2px);
}
#loading-spinner.hidden { display: none; }

.spinner-ring {
  width: 32px; height: 32px;
  border: 2px solid var(--border);
  border-top-color: var(--teal);
  border-radius: 50%;
  animation: spin 0.65s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.spinner-inline {
  color: var(--text-muted);
  font-size: 13px;
  padding: 32px;
  text-align: center;
}

/* -----------------------------------------------------------
   BUTTONS
   ----------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border-radius: var(--radius);
  border: 1px solid transparent;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, box-shadow 0.12s, opacity 0.12s;
  white-space: nowrap;
  flex-shrink: 0;
}
.btn:disabled { opacity: 0.4; cursor: not-allowed; }

.btn-primary {
  background: var(--teal);
  color: #0f1115;
  font-weight: 600;
}
.btn-primary:hover { background: var(--teal-dim); box-shadow: 0 0 0 3px var(--teal-glow); }

.btn-secondary {
  background: var(--surface-raised);
  color: var(--text-secondary);
  border-color: var(--border);
}
.btn-secondary:hover { background: var(--surface-high); color: var(--text); border-color: var(--border-bright); }

.btn-danger {
  background: var(--red-bg);
  color: var(--red);
  border-color: rgba(239,68,68,0.2);
}
.btn-danger:hover { background: rgba(239,68,68,0.18); }

.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
  border-color: transparent;
}
.btn-ghost:hover { background: var(--surface-raised); color: var(--text); }

.btn-sm  { padding: 5px 11px; font-size: 12px; border-radius: var(--radius-sm); }
.btn-lg  { padding: 10px 22px; font-size: 14px; font-weight: 600; }
.btn-block { width: 100%; justify-content: center; }

/* -----------------------------------------------------------
   FORMS
   ----------------------------------------------------------- */
label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-secondary);
  letter-spacing: 0.2px;
}
label.inline-label {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  font-weight: 400;
  font-size: 13px;
  color: var(--text);
}

input[type="text"],
input[type="number"],
input[type="tel"],
input[type="email"],
input[type="date"],
input[type="file"],
select,
textarea {
  width: 100%;
  /* original dark field, but larger padding + text for easier reading/typing */
  padding: 12px 14px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-size: 15px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--teal);
  box-shadow: 0 0 0 3px var(--teal-glow);
}
input::placeholder, textarea::placeholder { color: var(--text-muted); }
textarea { resize: vertical; line-height: 1.5; }

/* Native date input — the popup calendar itself is OS/browser-drawn and out
   of our hands, but tint its icon to the brand indigo (default is a flat
   black glyph that clashes with the rest of the theme) and hint a light
   scheme so the popup itself isn't a jarring dark/system-themed panel. */
input[type="date"] { color-scheme: light; }
html[data-theme="dark"] input[type="date"] { color-scheme: dark; }
/* iOS Safari draws date inputs as a native control with a fixed intrinsic
   width that ignores width:100% — on phones they ran off the card edge
   (New Job's Date/Due Date). Strip the native appearance so they size like
   every other field. iOS also centres the value text; pin it left to match
   the rest of the form, and give the value a floor height because an empty
   appearance-none date input collapses on iOS. */
input[type="date"] {
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  max-width: 100%;
}
input[type="date"]::-webkit-date-and-time-value {
  text-align: left;
  min-height: 1.4em;
}
input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  border-radius: 6px;
  padding: 3px;
  filter: invert(29%) sepia(94%) saturate(1946%) hue-rotate(231deg) brightness(97%) contrast(101%);
  transition: background 0.12s;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover { background: var(--teal-subtle); }

.settings-form label    { margin-bottom: 14px; }
.settings-form textarea { resize: vertical; }

.form-grid-2 { display: grid; grid-template-columns: 1fr 1fr;         gap: 12px; margin-bottom: 12px; }
.form-grid-3 { display: grid; grid-template-columns: 1fr 1fr 1fr;     gap: 12px; margin-bottom: 12px; }
.form-grid-4 { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; gap: 10px; margin-bottom: 12px; }
.form-row    { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; margin-bottom: 12px; }
.form-actions {
  display: flex;
  gap: 8px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.readonly-row {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  background: var(--teal-subtle);
  border: 1px solid rgba(99,102,241,0.25);
  border-radius: var(--radius);
  margin-bottom: 12px;
  font-size: 13px;
  color: var(--teal);
}
.readonly-row strong { color: var(--text); font-size: 15px; }
.readonly-label { color: var(--text-muted); font-size: 12px; margin-right: 4px; }

/* -----------------------------------------------------------
   CARDS
   ----------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  user-select: none;
}
.card-header h3 { margin: 0; color: var(--text); }
.card-toggle { color: var(--text-muted); font-size: 12px; }

.card-body { padding: 18px; }
.card-body.collapsed { display: none; }

/* Customer card — always open, no pointer cursor on header */
.customer-card { overflow: visible; }
.customer-card-header {
  cursor: default;
  background: var(--teal);
  border-bottom-color: var(--teal-dim);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.customer-card-header h3 { color: #fff; font-size: 16px; }

/* Section dividers within the customer card */
.form-section-label {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--teal);
  margin: 16px 0 8px;
  padding-bottom: 6px;
  border-bottom: 2px solid var(--teal);
}
.form-section-label:first-child { margin-top: 4px; }

/* Slightly roomier inputs inside the customer card */
.customer-card .card-body input,
.customer-card .card-body textarea,
.customer-card .card-body select {
  font-size: 15px;
  padding: 9px 11px;
}
.customer-card .card-body textarea { min-height: 64px; }

/* -----------------------------------------------------------
   SECTION HEADINGS (within pages)
   ----------------------------------------------------------- */
.section-heading {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
  margin-bottom: 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

/* -----------------------------------------------------------
   TABLES
   ----------------------------------------------------------- */
.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
.data-table thead tr {
  border-bottom: 1px solid var(--border);
}
.data-table th {
  padding: 10px 14px;
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  white-space: nowrap;
  background: var(--surface);
}
.data-table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.data-table tbody tr { transition: background 0.1s; }
.data-table tbody tr:hover td { background: var(--surface-raised); }
.data-table tbody tr:last-child td { border-bottom: none; }

.job-row       { cursor: pointer; }
.job-complete td { color: var(--text-muted); }
.job-complete td:last-child { text-decoration: none; }
.owing         { color: var(--amber); font-weight: 600; }
.total-row td  { font-weight: 700; }
.center        { text-align: center; }
.desc-cell     { max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text-secondary); }
.table-footer  { padding: 10px 14px; font-size: 12px; color: var(--text-muted); border-top: 1px solid var(--border); background: var(--surface); }
.table-wrap    { border: 1px solid var(--border); border-radius: var(--radius-lg); overflow: hidden; background: var(--surface); }

/* Job List column-header totals — the Total/Left to Pay sums for whichever
   jobs are currently filtered into view (e.g. a date range), tucked right
   after their matching header label so "how much did we take" is a quiet
   glance rather than a shouty banner. Kept inline (not stacked below) so
   this header cell stays the same single-line height as every other one —
   stacking it underneath made just these two headers two lines tall and
   left the rest of the row looking vertically adrift in the extra space. */
.th-total {
  text-transform: none;
  letter-spacing: normal;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-secondary);
  margin-left: 5px;
  white-space: nowrap;
}
.th-total::before { content: '\00b7'; margin-right: 5px; color: var(--text-muted); }
.th-total.owing { color: var(--amber); }

/* Paper types table — sheet/roll rows show two size inputs side by side. */
.paper-dims-cell { display: flex; gap: 6px; }
.paper-dim-input { width: 90px !important; }

.settings-table { width: 100%; border-collapse: collapse; margin-bottom: 16px; font-size: 13px; }
.settings-table th, .settings-table td { padding: 9px 11px; border: 1px solid var(--border); text-align: left; }
.settings-table th { background: var(--surface-raised); font-size: 11px; font-weight: 600; color: var(--text-secondary); }

/* -----------------------------------------------------------
   HELP SYSTEM — clickable "?" icons + explanation callouts
   ----------------------------------------------------------- */
.help-tip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  border-radius: 50%;
  background: var(--teal);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  vertical-align: middle;
  margin-left: 6px;
  user-select: none;
  transition: background 0.12s, transform 0.08s;
}
.help-tip:hover   { background: var(--teal-dark, #14605f); }
.help-tip:active  { transform: scale(0.9); }
.help-tip.is-open { background: var(--teal-dark, #14605f); }

.help-text {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-left: 3px solid var(--teal);
  border-radius: var(--radius-lg, 8px);
  padding: 12px 14px;
  margin: 8px 0 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-secondary);
  max-width: 640px;
}
.help-link {
  color: var(--teal);
  cursor: pointer;
  font-weight: 500;
  white-space: nowrap;
}
.help-link:hover { text-decoration: underline; }

/* Hourly rate calculator (Shop Details) */
.rate-calc-toggle { margin: 2px 0 6px; }
.rate-calc {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-left: 3px solid var(--teal);
  border-radius: var(--radius-lg, 8px);
  padding: 14px 16px; margin: 8px 0 16px; max-width: 640px;
  display: flex; flex-direction: column; gap: 12px;
}
.rate-calc-intro { margin: 0; font-size: 13px; color: var(--text-secondary); }

/* Shop logo upload (Settings → Shop Details). Preview keeps a white
   background in both themes — the logo prints on white card stock, so
   the preview should show it the way paper will. */
.settings-logo-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 2px 0 10px; }
.settings-logo-preview {
  width: 132px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  border: 1px dashed var(--border-bright); border-radius: var(--radius);
  background: #fff; overflow: hidden; padding: 4px;
}
.settings-logo-preview img  { max-width: 100%; max-height: 100%; }
.settings-logo-preview span { font-size: 11px; color: #94a3b8; }

.card-style-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.card-style-row select { width: auto; }

/* Shop settings sub-tabs — one form, groups shown/hidden */
.shop-sub { display: none; }
.shop-sub.active { display: block; }

/* Collection card designer: option ticks + live preview.
   Preview cards are 85x55mm at 2.7px/mm (229.5 x 148.5px) so the
   layout proportions match the generated PDF. Always light-on-white
   or the card's own dark ink — cards are paper, not themed UI. */
.card-opts { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 12px; }
.card-opts .card-opt { display: flex; flex-direction: row; align-items: center; gap: 8px; font-size: 14px; margin-bottom: 0; }
.card-opts input[type="checkbox"] { width: auto; margin: 0; }

/* Fixed / read-only settings input (e.g. the tracking link) — visibly locked. */
.settings-form input:disabled { opacity: 0.6; cursor: not-allowed; }

.card-preview-row { display: flex; gap: 14px; flex-wrap: wrap; margin: 4px 0 14px; }
.card-preview {
  width: 229.5px; height: 148.5px;
  border: 1px solid var(--border-bright); border-radius: 8px;
  position: relative; overflow: hidden;
  background: #fff; color: #111;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 4px; text-align: center;
}
/* Front card centres its logo/name/phone stack in the space ABOVE the
   "Powered by" strip (which is absolutely pinned at the bottom), matching
   the PDF — so a thin logo or a logo-only card sits balanced, not with a
   dead gap. The back overrides this with cp-back. */
.card-preview:not(.cp-back) { padding-bottom: 22px; }
.card-preview.cp-aurora {
  background-image:
    radial-gradient(circle at 0% 0%,     rgba(99,102,241,0.16),  transparent 62%),
    radial-gradient(circle at 100% 100%, rgba(139,92,246,0.16),  transparent 62%),
    radial-gradient(circle at 100% 0%,   rgba(34,211,238,0.12),  transparent 50%),
    radial-gradient(circle at 0% 100%,   rgba(236,72,153,0.10),  transparent 50%);
}
.card-preview.cp-dark {
  background-color: #131230; color: #fff;
  background-image:
    radial-gradient(circle at 0% 0%,     rgba(99,102,241,0.45),  transparent 62%),
    radial-gradient(circle at 100% 100%, rgba(139,92,246,0.45),  transparent 62%),
    radial-gradient(circle at 100% 0%,   rgba(34,211,238,0.34),  transparent 50%),
    radial-gradient(circle at 0% 100%,   rgba(236,72,153,0.27),  transparent 50%);
}
.cp-logo img { max-width: 167px; max-height: 57px; display: block; }
.cp-bigname  { font-size: 17px; font-weight: 800; letter-spacing: -0.2px; }
.cp-name     { font-size: 10px; font-weight: 700; }
.cp-name:empty, .cp-phone:empty, .cp-url:empty { display: none; }
.cp-phone   { font-size: 9px; opacity: 0.75; }
.cp-powered { position: absolute; bottom: 16px; left: 0; right: 0; font-size: 8.5px; color: #8b8f9c; }
.cp-powered b { color: #6366f1; }
.card-preview.cp-dark .cp-powered b { color: #a5b4fc; }
.cp-back { justify-content: flex-start; padding-top: 9px; }
.cp-caption { font-size: 8px; letter-spacing: 1.5px; opacity: 0.7; }
.cp-url     { font-size: 11px; font-weight: 700; color: #6366f1; white-space: nowrap; max-width: 94%; overflow: hidden; text-overflow: ellipsis; }
.card-preview.cp-dark .cp-url { color: #a5b4fc; }
.cp-sticker {
  position: absolute; bottom: 11px; left: 50%; transform: translateX(-50%);
  width: 157px; height: 88px;
  border: 1px dashed #999; border-radius: 5px;
  display: flex; align-items: center; justify-content: center;
  font-size: 8px; color: #999;
}
.card-preview.cp-dark .cp-sticker { border-color: #cbd5e1; color: #cbd5e1; }
.cp-dims { display: none; font-size: 10px; color: #94a3b8; }
.card-preview.cp-template .cp-dims { display: block; }
.card-preview.cp-template .cp-logo, .card-preview.cp-template .cp-name,
.card-preview.cp-template .cp-phone, .card-preview.cp-template .cp-powered,
.card-preview.cp-template .cp-caption, .card-preview.cp-template .cp-url { display: none; }
.card-preview.cp-template { background: #fff; color: #111; }
.cp-back.cp-template .cp-dims { position: absolute; top: 14px; left: 0; right: 0; }
.rate-calc-hint  { font-weight: 400; color: var(--text-muted); font-size: 11px; }
.rate-calc-result {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border-top: 1px solid var(--border); padding-top: 12px; font-size: 14px;
  color: var(--text-secondary); flex-wrap: wrap;
}
.rate-calc-result strong { color: var(--teal); font-size: 20px; font-weight: 700; }

/* Running-cost table inside the rate calculator */
.rate-calc-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rate-calc-table { width: 100%; border-collapse: collapse; font-size: 13px; min-width: 460px; }
.rate-calc-table th {
  text-align: left; font-size: 10px; font-weight: 600; letter-spacing: 0.04em;
  text-transform: uppercase; color: var(--text-secondary);
  padding: 4px 8px 8px; border-bottom: 1px solid var(--border);
}
.rate-calc-table td { padding: 5px 8px; vertical-align: middle; }
.rate-calc-table tbody tr + tr td { border-top: 1px solid var(--border); }
.rate-calc-table input[type="text"],
.rate-calc-table input[type="number"],
.rate-calc-table select { width: 100%; padding: 7px 9px; font-size: 13px; }
.rate-calc-costs th:nth-child(2), .rate-calc-costs td:nth-child(2) { width: 130px; }
.rate-calc-costs th:nth-child(3), .rate-calc-costs td:nth-child(3) { width: 120px; }
.rate-calc-costs th:nth-child(4), .rate-calc-costs td:nth-child(4) { width: 90px; }
.rate-calc-costs th:nth-child(5), .rate-calc-costs td:nth-child(5) { width: 34px; text-align: center; }
.rate-calc-staff th:nth-child(2), .rate-calc-staff td:nth-child(2) { width: 140px; }
.rate-calc-staff th:nth-child(3), .rate-calc-staff td:nth-child(3) { width: 34px; text-align: center; }
.rate-calc-sub { margin: 4px 0 0; font-size: 12.5px; color: var(--text-secondary); }

/* -----------------------------------------------------------
   VAT REGISTERED — prominent toggle-switch card
   ----------------------------------------------------------- */
.vat-toggle-card {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px 16px; margin: 6px 0 14px; max-width: 640px;
  background: var(--surface); border: 1px solid var(--border-bright);
  border-radius: var(--radius-lg);
  transition: border-color 0.22s var(--ease), background 0.22s var(--ease), box-shadow 0.22s var(--ease);
}
.vat-toggle-card.is-on {
  border-color: var(--teal-muted);
  background: var(--teal-subtle);
  box-shadow: 0 8px 22px -12px var(--teal-glow);
}
.vat-toggle-title {
  display: flex; align-items: center; gap: 6px;
  font-size: 14px; font-weight: 600; color: var(--text);
}
.vat-toggle-sub { margin-top: 2px; font-size: 12px; color: var(--text-secondary); }

.vat-switch { position: relative; flex-shrink: 0; cursor: pointer; line-height: 0; }
.vat-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.vat-switch-track {
  display: block; width: 52px; height: 30px; border-radius: 999px;
  background: var(--surface-high); border: 1px solid var(--border-bright);
  transition: background 0.22s var(--ease), border-color 0.22s var(--ease);
}
.vat-switch-thumb {
  position: absolute; top: 3px; left: 3px; width: 24px; height: 24px;
  border-radius: 50%; background: #fff;
  box-shadow: 0 2px 5px rgba(17,24,39,0.28);
  transition: transform 0.24s var(--ease-spring);
}
.vat-switch input:checked + .vat-switch-track {
  background: linear-gradient(135deg, #6366f1, #7c3aed); border-color: transparent;
}
.vat-switch input:checked + .vat-switch-track .vat-switch-thumb { transform: translateX(22px); }
.vat-switch input:focus-visible + .vat-switch-track { box-shadow: 0 0 0 3.5px var(--teal-subtle); }

/* VAT rate + number — revealed only when the switch is on */
.vat-details {
  max-width: 640px; overflow: hidden;
  max-height: 0; opacity: 0; margin: 0;
  transition: max-height 0.32s var(--ease), opacity 0.24s var(--ease), margin 0.32s var(--ease);
}
.vat-details.is-open { max-height: 260px; opacity: 1; margin: 0 0 4px; }
.rc-amt-cell { display: flex; align-items: center; gap: 5px; }
.rc-amt-cell .rc-cur { color: var(--text-muted); flex-shrink: 0; }
.rc-weekly { color: var(--text-secondary); white-space: nowrap; font-variant-numeric: tabular-nums; }
.rate-calc-table tfoot td {
  border-top: 2px solid var(--border-bright); padding-top: 9px; font-variant-numeric: tabular-nums;
}
.rc-total-label { text-align: right; font-weight: 600; color: var(--text); }
.rc-total-val   { font-weight: 700; color: var(--text); }
.rate-calc-table .btn-danger { padding: 4px 8px; }
.help-text code  { font-family: var(--font-mono, monospace); font-size: 12px; background: var(--surface); padding: 1px 4px; border-radius: 3px; }
.help-text p     { margin: 0 0 8px; }
.help-text p:last-child { margin-bottom: 0; }
.help-text strong { color: var(--text); }
.help-text ul    { margin: 6px 0; padding-left: 20px; }
.help-text li    { margin-bottom: 4px; }
.th-help { font-weight: inherit; }

/* -----------------------------------------------------------
   BADGES
   ----------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 9px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  letter-spacing: 0.2px;
}
.badge-grey        { background: var(--surface-high);  color: var(--text-secondary); }
.badge-teal        { background: var(--teal-subtle);    color: var(--teal-dim); }
.badge-blue        { background: var(--blue-bg);        color: var(--blue); }
.badge-light-blue  { background: rgba(34,211,238,0.1);  color: #22d3ee; }
.badge-amber       { background: var(--amber-bg);       color: var(--amber); }
.badge-orange      { background: var(--orange-bg);      color: var(--orange); }
.badge-purple      { background: var(--purple-bg);      color: var(--purple); }
.badge-dark-green  { background: rgba(16,185,129,0.1);  color: #10b981; }
.badge-bright-green{ background: var(--green-bg);       color: var(--green); }
.badge-open        { background: var(--surface-high);   color: var(--text-muted); }
.badge-ordered     { background: var(--blue-bg);        color: var(--blue); }
.badge-in_production { background: var(--amber-bg);     color: var(--amber); }
.badge-complete    { background: var(--green-bg);       color: var(--green); }

.item-badge-warning {
  display: inline-block;
  background: var(--amber-bg);
  color: var(--amber);
  padding: 2px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 600;
}

/* -----------------------------------------------------------
   TABS
   ----------------------------------------------------------- */
.tab-bar {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  padding: 0 4px;
  /* On narrow screens (phones/iPads) tabs scroll sideways instead of
     wrapping or clipping, so every tab stays reachable. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.tab-bar::-webkit-scrollbar { display: none; }
.tab-btn {
  padding: 10px 16px;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.tab-btn:hover  { color: var(--text-secondary); }
.tab-btn.active { color: var(--teal); border-bottom-color: var(--teal); }

/* Section sub-tabs (Records, Production) sit above hosted page content */
.section-subtabs { margin-bottom: 16px; }
.section-subtabs .nav-phase-badge { margin-left: 6px; }

/* Job Book has two tab levels — make them clearly distinct.
   Primary tabs (Jobs / Workshop / Customers / Quotes) read as the main
   heading; the Workshop sub-tabs (Frames / Prints / Items) are a step
   down but still larger than the default tab. */
#jobbook-tabs .tab-btn {
  font-size: 17px;
  font-weight: 600;
  padding: 13px 22px;
  flex: 0 0 auto;
}
.workshop-subtabs .tab-btn {
  font-size: 15px;
  font-weight: 600;
  padding: 10px 18px;
  flex: 0 0 auto;
}
/* The Workshop bar nests directly under the primary bar — tighten the
   gap so the two levels read as a group. */
.workshop-subtabs { margin-top: 4px; margin-bottom: 16px; }

/* Phones / small tablets: scale both levels down so they fit, and fall
   back to horizontal scroll (from .tab-bar) if they still overflow. */
@media (max-width: 700px) {
  #jobbook-tabs .tab-btn      { font-size: 15px; padding: 11px 15px; }
  .workshop-subtabs .tab-btn  { font-size: 13.5px; padding: 9px 13px; }
}
@media (max-width: 420px) {
  #jobbook-tabs .tab-btn      { font-size: 14px; padding: 10px 12px; }
  .workshop-subtabs .tab-btn  { font-size: 13px; padding: 8px 11px; }
}

/* -----------------------------------------------------------
   MODAL
   ----------------------------------------------------------- */
#modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
  backdrop-filter: blur(4px);
}
#modal-overlay.hidden { display: none; }
body.modal-open { overflow: hidden; }

#modal-box {
  background: var(--surface);
  border: 1px solid var(--border-bright);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  width: min(960px, 100%);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
#modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
}
#modal-header h2 { font-size: 15px; font-weight: 600; margin: 0; }
#modal-close {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-secondary);
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  padding: 0;
}
#modal-close:hover { background: var(--surface-high); color: var(--text); }
#modal-body   { flex: 1; overflow-y: auto; overflow-x: hidden; padding: 20px; }
#modal-footer { padding: 14px 20px; border-top: 1px solid var(--border); display: flex; gap: 8px; flex-shrink: 0; }

/* -----------------------------------------------------------
   TOASTS
   ----------------------------------------------------------- */
#toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.toast {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  border-radius: var(--radius-lg);
  font-size: 13px;
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--border);
  opacity: 0;
  transform: translateY(8px) scale(0.97);
  transition: opacity 0.25s, transform 0.25s;
  max-width: 340px;
  background: var(--surface-raised);
}
.toast.visible   { opacity: 1; transform: translateY(0) scale(1); }
.toast-success   { border-color: rgba(34,197,94,0.3);  color: var(--green); }
.toast-error     { border-color: rgba(239,68,68,0.3);  color: var(--red); }
.toast-warning   { border-color: rgba(245,158,11,0.3); color: var(--amber); }
.toast-info      { border-color: rgba(59,130,246,0.3); color: var(--blue); }

/* -----------------------------------------------------------
   UTILITY
   ----------------------------------------------------------- */
.empty-state {
  padding: 48px 24px;
  text-align: center;
  color: var(--text-muted);
  font-size: 14px;
}
.empty-state a { color: var(--teal); }
.muted   { color: var(--text-muted) !important; }
.hidden  { display: none !important; }

/* Theme toggle transition (FF.setTheme) — 1.6s, no reload. Cover fades to
   black, a plain white (not brand-coloured — colour tinting here read as
   cheap) sun/moon flips over card-style to reveal the other, then either
   the cover flashes to white before clearing (switching to light) or it
   just clears straight from black (switching to dark, already the right
   tone). The live theme swap happens at 350ms, hidden behind the fully
   opaque cover, so what's revealed underneath is already correct. */
#theme-transition {
  position: fixed; inset: 0; z-index: 99999; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: #050505;
  opacity: 0;
  animation: themeCoverToDark 1.6s ease-in-out forwards;
}
#theme-transition.to-light { animation-name: themeCoverToLight; }

@keyframes themeCoverToDark {
  0%   { opacity: 0; }
  22%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { opacity: 0; }
}
@keyframes themeCoverToLight {
  0%   { opacity: 0; background: #050505; }
  22%  { opacity: 1; background: #050505; }
  68%  { background: #050505; }
  80%  { background: #fff; }
  82%  { opacity: 1; background: #fff; }
  100% { opacity: 0; background: #fff; }
}

.theme-transition-icon {
  position: absolute;
  font-size: 60px;
  color: #fff;
  opacity: 0;
}
.theme-transition-icon.icon-out { animation: themeIconFlipOut 1.6s ease-in-out forwards; }
.theme-transition-icon.icon-in  { animation: themeIconFlipIn  1.6s ease-in-out forwards; }

/* Holds, then flips away (edge-on at 90deg) right as the incoming icon
   flips in from the opposite edge — a card-flip handoff, not a fade. */
@keyframes themeIconFlipOut {
  0%, 22% { opacity: 0; transform: rotateY(0deg); }
  30%     { opacity: 1; transform: rotateY(0deg); }
  40%     { opacity: 1; transform: rotateY(0deg); }
  48%     { opacity: 0; transform: rotateY(90deg); }
  100%    { opacity: 0; transform: rotateY(90deg); }
}
@keyframes themeIconFlipIn {
  0%, 48% { opacity: 0; transform: rotateY(-90deg); }
  56%     { opacity: 1; transform: rotateY(0deg); }
  68%     { opacity: 1; transform: rotateY(0deg); }
  80%     { opacity: 0; transform: rotateY(0deg); }
  100%    { opacity: 0; transform: rotateY(0deg); }
}
@media (prefers-reduced-motion: reduce) {
  #theme-transition, .theme-transition-icon { animation: none !important; opacity: 0 !important; }
}

hr       { border: none; border-top: 1px solid var(--border); margin: 20px 0; }
code     { font-family: var(--font-mono); background: var(--surface-high); padding: 2px 6px; border-radius: var(--radius-sm); font-size: 12px; }
.error-detail { font-size: 12px; color: var(--red); word-break: break-all; margin-top: 8px; }

/* -----------------------------------------------------------
   DASHBOARD ENTRANCE ANIMATION
   ----------------------------------------------------------- */
@keyframes dashIn {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
.dash-animate {
  opacity: 0;
  animation: dashIn 0.45s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

/* -----------------------------------------------------------
   DASHBOARD
   ----------------------------------------------------------- */
/* -----------------------------------------------------------
   FULL-SCREEN SPLASH / GREETING
   ----------------------------------------------------------- */
@keyframes splashIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes splashContentIn {
  from { opacity: 0; transform: translateY(20px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes splashOut {
  from { opacity: 1; }
  to   { opacity: 0; }
}

#ff-splash {
  position: fixed;
  inset: 0;
  z-index: 9999;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  animation: splashIn 0.4s ease forwards;
  cursor: pointer;
}
#ff-splash.splash-out {
  animation: splashOut 0.65s cubic-bezier(0.4, 0, 0.2, 1) forwards;
}

/* Soft indigo→violet aurora glow behind the logo */
.splash-aurora {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(closest-side at 42% 40%, rgba(99,102,241,0.26), transparent 70%),
    radial-gradient(closest-side at 60% 55%, rgba(168,85,247,0.22), transparent 70%);
  filter: blur(6px);
  opacity: 0;
  animation: auroraGlow 2.2s ease-out 0.15s forwards;
}
@keyframes auroraGlow {
  0%   { opacity: 0; transform: scale(0.85); }
  60%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1.05); }
}
/* Slow rotating colour wash for depth + life */
.splash-aurora::after {
  content: "";
  position: absolute;
  inset: -25%;
  background: conic-gradient(from 0deg,
    transparent 0%, rgba(168,85,247,0.12) 18%, transparent 40%,
    rgba(99,102,241,0.14) 60%, transparent 82%, rgba(168,85,247,0.10) 100%);
  filter: blur(40px);
  opacity: 0.7;
  animation: auroraSpin 16s linear infinite;
}
/* Breathing core glow right behind the logo */
.splash-aurora::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(closest-side at 50% 46%, rgba(99,102,241,0.30), transparent 62%);
  opacity: 0;
  animation: auroraPulse 2.8s ease-in-out 0.7s infinite;
}
@keyframes auroraSpin  { to { transform: rotate(360deg); } }
@keyframes auroraPulse {
  0%, 100% { opacity: 0.25; transform: scale(0.94); }
  50%      { opacity: 0.60; transform: scale(1.10); }
}

.splash-inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
  padding: 24px;
  width: 100%;
  max-width: 680px;
}

.splash-logo {
  display: flex;
  align-items: center;
  gap: 20px;
  font-size: 46px;
  font-weight: 800;
  letter-spacing: -0.5px;
  margin-bottom: 18px;
}
.splash-wordmark {
  color: var(--text);
  opacity: 0;
  transform: translateX(-8px);
  animation: wordmarkIn 0.6s var(--ease-spring) 0.9s forwards;
}

/* Staged reveal: greeting + sub fade up after the logo animates */
.splash-greeting {
  font-size: clamp(26px, 6vw, 62px);
  font-weight: 700;
  color: var(--text);
  letter-spacing: -1.5px;
  line-height: 1.08;
  max-width: 100%;
  overflow-wrap: break-word;
  opacity: 0;
  animation: splashContentIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) 1.25s both;
}
.splash-name {
  background: linear-gradient(120deg, var(--teal), #a855f7);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: transparent;
}

.splash-sub {
  font-size: 16px;
  color: var(--text-muted);
  font-weight: 400;
  opacity: 0;
  animation: splashContentIn 0.6s cubic-bezier(0.22, 1, 0.36, 1) 1.45s both;
}

/* -----------------------------------------------------------
   LOGO MARK ANIMATION (splash)
   ----------------------------------------------------------- */
.ff-mark-lg {
  width: 104px;
  height: 104px;
  filter: drop-shadow(0 12px 34px rgba(99,102,241,0.45));
  /* Springs in and settles, then keeps a slow breathing glow */
  animation: logoPop 1s var(--ease-spring) both,
             logoBreathe 3.4s ease-in-out 1.2s infinite;
}
@keyframes logoPop {
  0%   { opacity: 0; transform: scale(0.55) rotate(-10deg); }
  55%  { opacity: 1; }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
@keyframes logoBreathe {
  0%, 100% { filter: drop-shadow(0 12px 30px rgba(99,102,241,0.38)); }
  50%      { filter: drop-shadow(0 16px 46px rgba(129,90,247,0.65)); }
}
/* Frame draws itself, then the flow bars slide in staggered */
.ff-mark-lg .ff-frame {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  animation: frameDraw 1s cubic-bezier(0.65, 0, 0.35, 1) 0.2s forwards;
}
.ff-mark-lg .ff-bar {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: left center;
  transform: translateX(-6px) scaleX(0.4);
}
.ff-mark-lg .ff-bar:nth-of-type(2) { animation: barIn 0.5s var(--ease-spring) 0.95s forwards; }
.ff-mark-lg .ff-bar:nth-of-type(3) { animation: barIn 0.5s var(--ease-spring) 1.10s forwards; }
.ff-mark-lg .ff-bar:nth-of-type(4) { animation: barIn 0.5s var(--ease-spring) 1.25s forwards; }

@keyframes frameDraw {
  from { stroke-dashoffset: 100; }
  to   { stroke-dashoffset: 0; }
}
@keyframes barIn {
  from { opacity: 0; transform: translateX(-6px) scaleX(0.4); }
  to   { opacity: 1; transform: translateX(0) scaleX(1); }
}
@keyframes wordmarkIn {
  to { opacity: 1; transform: translateX(0); }
}

/* Splash scales down on tablets and phones so nothing overflows */
@media (max-width: 640px) {
  .ff-mark-lg   { width: 74px; height: 74px; }
  .splash-logo  { font-size: 30px; gap: 13px; margin-bottom: 12px; }
  .splash-inner { gap: 12px; padding: 20px; }
  .splash-sub   { font-size: 14px; }
}
@media (max-width: 380px) {
  .ff-mark-lg  { width: 58px; height: 58px; }
  .splash-logo { font-size: 24px; gap: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .ff-mark-lg .ff-frame,
  .ff-mark-lg .ff-bar,
  .ff-mark-lg,
  .splash-wordmark,
  .splash-greeting,
  .splash-sub,
  .splash-aurora,
  .splash-aurora::before,
  .splash-aurora::after {
    animation-duration: 0.01s !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
  }
}

.splash-name-btn { margin-top: 8px; }

.splash-name-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}

/* Greeting banner */
.greeting-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  margin-bottom: 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  gap: 16px;
  overflow: hidden;
}

@keyframes greetingOut {
  0%   { opacity: 1; transform: translateY(0);    max-height: 200px; padding: 20px 24px; margin-bottom: 20px; }
  55%  { opacity: 0; transform: translateY(-10px); max-height: 200px; padding: 20px 24px; margin-bottom: 20px; }
  100% { opacity: 0; transform: translateY(-10px); max-height: 0;     padding: 0 24px;   margin-bottom: 0; }
}
.greeting-banner.fade-out {
  animation: greetingOut 1.4s cubic-bezier(0.4, 0, 0.2, 1) forwards;
  pointer-events: none;
}
.greeting-text {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.greeting-line {
  font-size: 22px;
  font-weight: 700;
  color: var(--text);
  letter-spacing: -0.4px;
  line-height: 1.2;
}
.greeting-name { color: var(--teal); }
.greeting-sub  { font-size: 13px; color: var(--text-muted); }
.name-edit-inline { display: flex; align-items: center; gap: 8px; }

/* Dashboard stat cards — click any card to choose what it shows
   (Dashboard.openStatPicker). Styled as frosted "Liquid Glass" panels
   floating over a soft animated aurora wash, so the blur has something
   colourful behind it to refract — plain blur over a flat background
   barely reads as glass at all. Staggered fade-in + a light sheen on
   hover keep it feeling alive without being distracting at rest. */
.stat-cards-wrap {
  position: relative;
  overflow: hidden;
  margin-bottom: 24px;
  padding: 20px;
  border: 2px solid rgba(168,85,247,0.45);
  border-radius: var(--radius-xl);
}
.stat-cards-aurora {
  position: absolute;
  inset: -30px -10px;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(closest-side at 15% 30%, rgba(99,102,241,0.16), transparent 70%),
    radial-gradient(closest-side at 55% 75%, rgba(168,85,247,0.14), transparent 70%),
    radial-gradient(closest-side at 90% 20%, rgba(99,102,241,0.12), transparent 70%);
  filter: blur(30px);
  animation: statsAuroraDrift 14s ease-in-out infinite alternate;
}
@keyframes statsAuroraDrift {
  0%   { transform: translate(0, 0) scale(1); }
  100% { transform: translate(2%, -3%) scale(1.06); }
}

.stat-cards {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}

.stat-card {
  position: relative;
  overflow: hidden;
  background: color-mix(in srgb, var(--surface) 62%, transparent);
  backdrop-filter: blur(18px) saturate(160%);
  -webkit-backdrop-filter: blur(18px) saturate(160%);
  border: 1px solid rgba(255,255,255,0.6);
  border-radius: var(--radius-lg);
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 1px 0 rgba(255,255,255,0.7) inset, var(--shadow);
  transition: transform 0.2s var(--ease-spring), box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
  animation: statCardIn 0.5s var(--ease) both;
}
.stat-card::before {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.5) 48%, transparent 65%);
  transform: translateX(-130%);
  transition: transform 0.7s ease;
  pointer-events: none;
}
.stat-card:hover::before { transform: translateX(130%); }
.stat-card:hover {
  transform: translateY(-3px);
  box-shadow: 0 1px 0 rgba(255,255,255,0.8) inset, var(--shadow-md);
  border-color: var(--teal-muted);
}
.stat-card:active { transform: translateY(-1px) scale(0.99); }

@keyframes statCardIn {
  from { opacity: 0; transform: translateY(10px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.stat-card-icon {
  width: 36px;
  height: 36px;
  border-radius: var(--radius);
  background: linear-gradient(135deg, var(--teal), var(--purple));
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 19px;
  margin-bottom: 4px;
  box-shadow: 0 1px 0 rgba(255,255,255,0.35) inset, 0 4px 10px -4px rgba(99,102,241,0.5);
}
.stat-card-warn .stat-card-icon {
  background: linear-gradient(135deg, var(--amber), var(--red));
  box-shadow: 0 1px 0 rgba(255,255,255,0.35) inset, 0 4px 10px -4px rgba(217,119,6,0.5);
}

.stat-value {
  font-size: 28px;
  font-weight: 700;
  color: var(--text);
  line-height: 1;
  letter-spacing: -0.5px;
}
/* A quick pulse the instant the count-up lands on its final number — gives
   a clear "done" beat even when there were only a couple of digits to
   tick through (e.g. counting 0→3 barely reads as motion on its own). */
.stat-value-land { animation: statValueLand 0.26s var(--ease-spring); }
@keyframes statValueLand {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.14); color: var(--teal-dim); }
  100% { transform: scale(1); }
}
.stat-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}

@media (prefers-reduced-motion: reduce) {
  .stat-cards-aurora, .stat-card { animation: none; }
  .stat-card::before { display: none; }
  .stat-card:hover { transform: none; }
}

/* Stat card picker modal (Dashboard.openStatPicker) */
.stat-picker-list { display: flex; flex-direction: column; gap: 4px; max-height: 60vh; overflow-y: auto; }
.stat-picker-opt {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  background: none; border: 1px solid transparent; border-radius: var(--radius);
  font-family: inherit; font-size: 14px; font-weight: 500; color: var(--text);
  cursor: pointer; text-align: left;
  transition: background 0.12s, border-color 0.12s;
}
.stat-picker-opt:hover { background: var(--surface-raised); }
.stat-picker-opt.active { background: var(--teal-subtle); border-color: var(--teal-muted); color: var(--teal-dim); font-weight: 600; }
.stat-picker-icon {
  width: 28px; height: 28px; border-radius: var(--radius-sm); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--surface-high); color: var(--text-secondary); font-size: 15px;
}
.stat-picker-opt.active .stat-picker-icon { background: var(--teal-subtle); color: var(--teal); }
.stat-picker-check { margin-left: auto; color: var(--teal); font-size: 16px; }

.quick-actions {
  display: flex;
  gap: 12px;
  margin-bottom: 24px;
  flex-wrap: wrap;
}

.quick-action-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  transition: border-color 0.12s, color 0.12s, background 0.12s;
}
.quick-action-btn:hover {
  border-color: var(--teal);
  color: var(--teal);
  background: var(--teal-subtle);
}
.qa-icon { font-size: 20px; color: var(--teal); }

.dashboard-section h3 {
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  margin-bottom: 12px;
}
.dashboard-table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

/* -----------------------------------------------------------
   NEW JOB PAGE
   ----------------------------------------------------------- */
.newjob-layout {
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: 16px;
  align-items: start;
}
.newjob-left  { display: flex; flex-direction: column; gap: 12px; }
.newjob-right { position: sticky; top: 0; }

.items-list { padding: 12px; display: flex; flex-direction: column; gap: 8px; }

/* Add Frame Item — primary action on the frames panel: brighter + bigger
   than a plain secondary button so it reads as the clear next step. */
.add-frame-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: calc(100% - 24px);
  margin: 0 12px 12px;
  padding: 13px 18px;
  font-size: 14px;
  font-weight: 600;
  color: var(--text);
  background: var(--surface-high);
  border: 1px solid var(--border-bright);
  border-radius: var(--radius-lg);
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s, color 0.12s;
}
.add-frame-btn:hover {
  background: var(--teal-subtle);
  border-color: var(--teal);
  color: var(--teal);
}

/* Empty state shown when no frames have been added yet. */
.items-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 4px;
  padding: 28px 16px 20px;
  color: var(--text-muted);
}
.items-empty i { font-size: 34px; color: var(--text-secondary); margin-bottom: 6px; }
.items-empty-title { font-size: 14px; font-weight: 600; color: var(--text); margin: 0; }
.items-empty-sub   { font-size: 12.5px; color: var(--text-muted); margin: 0; }

.item-summary {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  /* extra right padding reserves room for the absolute delete (✕) button */
  padding: 12px 42px 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-raised);
  cursor: pointer;
  transition: border-color 0.12s, background 0.12s;
  position: relative;
}
.item-summary:hover { border-color: var(--teal); background: var(--teal-subtle); }
.item-summary-text   { flex: 1; min-width: 0; }
.item-summary-info   { min-width: 0; }
.item-summary-info strong { font-size: 13px; color: var(--text); }
.item-summary-detail {
  font-size: 13.5px; color: var(--text); margin-top: 6px;
  font-family: var(--font);
  font-variant-numeric: tabular-nums;
  display: flex; flex-wrap: wrap; gap: 4px 16px;
}
.sum-spec b {
  color: var(--teal); font-weight: 700; font-family: var(--font);
  text-transform: uppercase; font-size: 10.5px; letter-spacing: 0.05em;
  margin-right: 5px;
}
.sum-empty { color: var(--text-muted); font-style: italic; }
.item-price {
  display: inline-flex;
  align-items: center;
  background: var(--teal-glow);
  color: var(--teal);
  padding: 2px 9px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 700;
  margin-left: 8px;
}
.item-delete { position: absolute; top: 10px; right: 10px; flex-shrink: 0; }
.item-incomplete { border-color: rgba(245,158,11,0.3); }

.frame-form  { border-radius: var(--radius-lg); }

/* Mount border inline input */
.mount-border-input {
  width: 62px !important; font-family: var(--font-mono); font-size: 15px !important;
  text-align: center;
}
/* Hide number spinners — type the value directly */
.mount-border-input { -moz-appearance: textfield; appearance: textfield; }
.mount-border-input::-webkit-outer-spin-button,
.mount-border-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Border label + value inline with the mount code, grouped in the code box. */
.mount-border-inline {
  display: flex; flex-direction: row; align-items: center; gap: 6px;
  flex-shrink: 0;
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-secondary);
}
.mount-border-unit { font-size: 12px; color: var(--text-muted); text-transform: none; }

/* "Different each side" toggle + the 4-input layout it reveals. Uneven
   borders are the exception, so this stays a small opt-in checkbox rather
   than permanent UI weight on every mount row. */
.mount-border-toggle {
  display: flex; flex-direction: row; align-items: center; gap: 6px;
  margin: 8px 0 0 2px;
  font-family: var(--font); font-size: 12px; font-weight: 500;
  color: var(--text-secondary); cursor: pointer;
}
.mount-border-toggle input[type="checkbox"] {
  width: 15px; height: 15px; accent-color: var(--teal); cursor: pointer;
}
.mount-border-toggle:hover { color: var(--text); }
.mount-border-sides {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
  margin-top: 8px;
}
.mount-border-side {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: var(--surface-raised); border: 1px solid var(--border-bright);
  border-radius: var(--radius); padding: 6px 4px;
}
.mount-border-side span:first-child {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.04em; color: var(--text-muted);
}
.mount-border-side .mount-border-input { width: 100% !important; }
@media (max-width: 480px) {
  .mount-border-sides { grid-template-columns: repeat(2, 1fr); }
}

/* Additional Labour — a manual minutes add-on, styled to match the mount
   border input it borrows from (small mono box + unit suffix). */
.extra-labour-row { padding: 2px 0 4px; }

/* Frame name — the title of the item, so brighter label + larger,
   bolder input than a standard field. */
.fi-name-label {
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-secondary);
  margin-bottom: 12px;
}
.fi-name-input {
  font-size: 17px !important; font-weight: 600;
  padding: 11px 14px !important;
  border-width: 2px !important; border-color: var(--border-bright) !important;
}
.fi-name-input::placeholder { font-weight: 400; }
.fi-name-input:focus { border-color: var(--teal) !important; }

/* Prominent size widget */
.fi-size-widget {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface-raised); border: 2px solid var(--border-bright);
  border-radius: var(--radius-lg); padding: 16px 20px; margin-bottom: 8px;
}
.fi-size-field { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px; }
.fi-size-unit  { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: var(--text-muted); }
.fi-size-num {
  font-size: 34px !important; font-weight: 700 !important; text-align: center;
  width: 100%; background: transparent; border: none;
  border-bottom: 2px solid var(--border-bright); padding: 6px 0; color: var(--text);
  transition: border-color 0.15s;
}
.fi-size-num:focus { border-bottom-color: var(--teal); outline: none; }
/* Hide number spinners — type the value directly */
.fi-size-num { -moz-appearance: textfield; appearance: textfield; }
.fi-size-num::-webkit-outer-spin-button,
.fi-size-num::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.fi-size-suffix { font-size: 12px; color: var(--text-muted); font-weight: 500; }
.fi-size-sep   { font-size: 22px; color: var(--text-muted); font-weight: 300; padding-top: 16px; flex-shrink: 0; }

/* Moulding info box — two prices side by side */
.mi-name   { display: block; font-weight: 500; color: var(--text); margin-bottom: 3px; }
.mi-prices { display: flex; gap: 16px; flex-wrap: wrap; }
.mi-price-item { font-size: 12px; color: var(--text-secondary); }
.mi-price-item b { color: var(--teal); font-family: var(--font-mono); font-weight: 600; }
.mi-unavail { color: var(--text-secondary); font-style: italic; font-weight: normal; }
.mi-disc    { color: #2a9; font-size: 11px; font-weight: normal; }

/* Order method buttons (bottom of price panel) */
.order-method-slot:not(:empty) { padding: 0 16px 14px; }
.order-method-panel {
  border-top: 1px solid var(--border); margin-top: 16px; padding-top: 14px;
}
.order-method-title {
  font-size: 11px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-muted); margin-bottom: 8px;
}
.order-method-row { display: flex; gap: 8px; }
.order-method-btn {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 8px 6px; border-radius: var(--radius); border: 1px solid var(--border);
  background: var(--surface-raised); cursor: pointer; transition: border-color 0.15s, background 0.15s;
}
.order-method-btn:hover { border-color: var(--teal); background: var(--teal-subtle); }
.order-method-btn.active { border-color: var(--teal); background: var(--teal-glow); }
.order-method-btn-label { font-size: 13px; font-weight: 600; color: var(--text); }
.order-method-btn.active .order-method-btn-label { color: var(--teal); }
.order-method-btn-desc  { font-size: 10px; color: var(--text-muted); text-align: center; }

/* Section labels inside frame form — structural headers, so brighter +
   bolder than muted, with a teal accent tick to anchor each section. */
.fi-section-label {
  display: flex; align-items: center; gap: 7px;
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-secondary);
  margin: 20px 0 9px; padding-bottom: 6px;
  border-bottom: 1px solid var(--border-bright);
}
.fi-section-label::before {
  content: ''; width: 3px; height: 13px; border-radius: 2px;
  background: var(--teal); flex-shrink: 0;
}

/* Moulding item card */
.moulding-item { margin-bottom: 8px; }
.moulding-code-row {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface-raised); border: 1px solid var(--border-bright);
  border-radius: var(--radius); padding: 8px 10px;
  transition: border-color 0.12s;
}
.moulding-code-row:focus-within { border-color: var(--teal); }
.frame-code-input {
  flex: 1; min-width: 0; font-family: var(--font-mono); font-size: 15px !important;
  color: var(--teal) !important;
  border-color: var(--teal) !important;
}
.frame-code-input::placeholder { color: var(--teal); opacity: 0.6; }

/* Chop / Length pill toggle */
.chop-length-toggle {
  display: flex; border: 1px solid var(--border-bright); border-radius: var(--radius-sm); overflow: hidden; flex-shrink: 0;
}
.toggle-opt {
  display: flex; align-items: center; gap: 0; padding: 3px 10px;
  font-size: 12px; cursor: pointer; color: var(--text-secondary);
  user-select: none; white-space: nowrap; transition: background 0.15s, color 0.15s;
}
.toggle-opt:has(input:checked) { background: var(--teal); color: #fff; }
.toggle-opt input[type="radio"] { display: none; }

/* Info box that slides under code input when a code is resolved */
.moulding-info-box {
  font-size: 12px; padding: 4px 10px;
  background: var(--surface); border: 1px solid var(--border-bright); border-top: none;
  border-radius: 0 0 var(--radius) var(--radius);
  color: var(--text-secondary);
}
.moulding-info-found    { color: var(--teal); }
.moulding-info-notfound { color: var(--amber); }
.moulding-info-loading  { color: var(--text-muted); font-style: italic; }
/* Material too big for its sheet — clear inline error. */
.moulding-info-oversize {
  color: var(--text-secondary);
  background: var(--red-bg);
  border-color: rgba(239,68,68,0.35);
}
.moulding-info-oversize .mi-oversize {
  display: block; margin-top: 2px;
  color: var(--red); font-weight: 600;
}
.moulding-info-oversize .mi-suggest {
  display: block; margin-top: 1px;
  color: var(--teal); font-weight: 600;
}

/* Wood length warning under the external-size row. */
.length-warning {
  margin: 6px 0 2px;
  padding: 7px 10px;
  font-size: 12px; font-weight: 600;
  color: var(--red);
  background: var(--red-bg);
  border: 1px solid rgba(239,68,68,0.35);
  border-radius: var(--radius);
}

/* + Add moulding button */
.moulding-add-btn {
  display: inline-flex; align-items: center; gap: 4px;
  margin-top: 4px; margin-bottom: 4px;
  padding: 4px 12px; font-size: 12px; font-family: var(--font);
  color: var(--teal-muted); background: transparent;
  border: 1px dashed var(--teal-muted); border-radius: var(--radius);
  cursor: pointer; transition: background 0.15s;
}
.moulding-add-btn:hover { background: rgba(91,141,134,0.10); }

/* Remove button inside moulding row */
.moulding-remove {
  background: none; border: none; color: var(--text-muted);
  font-size: 13px; padding: 0 2px; line-height: 1; cursor: pointer;
  flex-shrink: 0; transition: color 0.15s;
}
.moulding-remove:hover { color: var(--red); }


.fc-info { font-size: 12px; color: var(--text-muted); }
.fc-found    { color: var(--green); }
.fc-notfound { color: var(--red); }

.extra-row   { display: flex; gap: 8px; align-items: center; margin-bottom: 6px; }
.extra-desc  { flex: 1; }
.extra-price { width: 90px !important; }

/* Breakdown panel */
.breakdown-empty {
  color: var(--text-muted);
  font-size: 13px;
  padding: 24px;
  text-align: center;
}
.breakdown-section       { margin-bottom: 15px; }
.breakdown-section-title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--text-muted);
  padding: 4px 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 7px;
}
.breakdown-line {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 8px;
  align-items: baseline;
  padding: 4px 0;
  font-size: 12.5px;
}
.breakdown-label  { color: var(--text-secondary); }
.breakdown-detail { color: var(--text-muted); font-size: 11.5px; font-family: var(--font-mono); }
.breakdown-cost   { font-weight: 500; text-align: right; white-space: nowrap; color: var(--text); }

.breakdown-totals {
  border-top: 1px solid var(--border);
  margin-top: 14px;
  padding-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.breakdown-total-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 13px;
  padding: 2px 0;
  color: var(--text-secondary);
}
.breakdown-cost-net { color: var(--text-muted); font-size: 12px; }
.breakdown-rounding { color: var(--text-muted); font-size: 12px; font-style: italic; }
.breakdown-sell     { color: var(--teal); font-weight: 600; font-size: 14px; }
.breakdown-grand-total {
  font-size: 17px;
  font-weight: 700;
  color: var(--text);
  border-top: 1px solid var(--border);
  padding-top: 10px;
  margin-top: 4px;
}
.breakdown-errors { margin-top: 10px; }
.breakdown-error  { color: var(--amber); font-size: 12px; padding: 3px 0; }

.breakdown-override {
  color: var(--amber);
  font-weight: 700;
  font-size: 15px;
  background: var(--amber-bg);
  border-radius: var(--radius);
  padding: 8px 10px;
  margin-top: 6px;
}
.breakdown-override-note { font-weight: 500; font-size: 11px; text-transform: none; }

/* Special-price override input, under the breakdown panel in the frame drawer */
.price-override-field { margin-top: 12px; }
.price-override-field > label {
  display: block; font-size: 12px; color: var(--text-secondary); margin-bottom: 6px;
}
.price-override-input-wrap {
  display: flex; align-items: center; gap: 8px;
}
.price-override-input-wrap .currency-prefix {
  color: var(--text-muted); font-size: 14px;
}
.price-override-input-wrap input {
  width: 120px;
}
.link-btn {
  background: none; border: none; padding: 0;
  color: var(--teal); font-size: 12.5px; font-weight: 600;
  cursor: pointer; text-decoration: underline;
}
.link-btn:hover { color: var(--teal-dim); }

/* -----------------------------------------------------------
   BARCODE SCANNING (Production → Scan)
   ----------------------------------------------------------- */
.scan-wrap { max-width: 560px; margin: 0 auto; width: 100%; }

/* Zoom chips — shown only when the camera supports zoom (helps phones
   without macro focus scan the small labels from further away). */
.scan-zoom { display: flex; gap: 8px; justify-content: center; margin-top: 10px; }
.scan-zoom-btn {
  padding: 6px 16px;
  border-radius: 999px;
  border: 1px solid var(--border-bright);
  background: var(--surface-raised);
  color: var(--text);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.scan-zoom-btn.active { background: var(--teal); border-color: var(--teal); color: #fff; }
.scan-cam-card { padding: 14px; overflow: hidden; }
/* html5-qrcode sets an inline px width on this element to match the camera
   resolution — force it back to the container so it can't push the whole
   scan column (and the buttons below) wider than the phone screen. */
.scan-reader {
  width: 100% !important; max-width: 100%;
  border-radius: 10px; overflow: hidden;
  background: #000; min-height: 60px;
}
.scan-reader > * { max-width: 100% !important; }
.scan-reader video, .scan-reader canvas { width: 100% !important; height: auto !important; display: block; }
.scan-controls { margin-top: 12px; }
.scan-controls .btn { width: 100%; }
.scan-status { margin: 12px 0 0; font-size: 13px; color: var(--text-secondary); line-height: 1.5; }
.scan-status b { color: var(--text); }

.scan-result { margin-top: 16px; }
.scan-job { padding: 14px; }
.scan-job-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; padding-bottom: 10px; margin-bottom: 6px;
  border-bottom: 1px solid var(--border);
}
.scan-job-num  { font-size: 18px; font-weight: 700; color: var(--text); }
.scan-job-cust { font-size: 13px; color: var(--text-secondary); margin-top: 2px; }

.scan-items { display: flex; flex-direction: column; }
.scan-item {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 11px 2px; border-bottom: 1px solid var(--border);
}
.scan-item:last-child { border-bottom: none; }
.scan-item-main { min-width: 0; flex: 1; }
.scan-item-name { font-size: 14px; color: var(--text); word-break: break-word; }
.scan-item-kind {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--teal); margin-right: 4px;
}
.scan-item-stage { margin-top: 5px; }
.scan-advance { white-space: nowrap; flex-shrink: 0; }
.scan-item-final { font-size: 12px; color: var(--text-muted); white-space: nowrap; flex-shrink: 0; }
.scan-notfound { padding: 14px; color: var(--amber); font-size: 14px; }

/* On phones, drop the advance button to its own full-width line under the
   item so nothing is forced off the side and the tap target is bigger. */
@media (max-width: 600px) {
  .scan-item { flex-wrap: wrap; }
  .scan-advance { width: 100%; margin-top: 8px; }
}

/* Inline stage controls inside the Job detail Frames/Prints/Extras tabs */
.jd-stage {
  margin-top: 10px; padding-top: 10px;
  border-top: 1px dashed var(--border);
}
.jd-stage-top { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.jd-stage-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.04em;
  color: var(--text-muted); margin-right: 2px;
}
.jd-advance { margin-left: auto; white-space: nowrap; }
.jd-stage-final { margin-left: auto; font-size: 12px; color: var(--text-muted); }
.jd-stage-jump { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.jd-stage-chip {
  font-size: 12px; padding: 4px 10px; border-radius: 999px; cursor: pointer;
  background: var(--surface-raised); color: var(--text-secondary);
  border: 1px solid var(--border-bright);
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.jd-stage-chip:hover:not(:disabled) { border-color: var(--teal); color: var(--teal); }
.jd-stage-chip.is-current { background: var(--teal); color: #fff; border-color: var(--teal); cursor: default; opacity: 0.9; }

/* Printable job labels — a shop copy (job number, price, barcode, due
   date) and a customer copy (a random tracking code, NOT the job number
   — see supabase_tracking_portal.sql). Used both right after confirming
   a job and when reprinting from the Job Book.

   Sized for real 2.25in x 1.25in thermal labels at 203dpi. Each label is
   its own @page, so a 2-label job prints as 2 pages — one label fed per
   page, which is how thermal/AirPrint label printers expect it. On
   screen they render at the same physical size as a small side-by-side
   preview; on paper the dashed border and gap disappear and each one
   fills its own label exactly. */
.ff-label-sheet {
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
  margin: 16px 0;
}
.ff-label {
  width: 2.25in;
  height: 1.25in;
  box-sizing: border-box;
  padding: 0.09in 0.13in;
  overflow: hidden;
  border: 1px dashed var(--border-bright);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  font-family: var(--font);
  color: #000;
  background: #fff;
  page: ff-label;
}

/* Shop label */
.ff-label-shop-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
}
.ff-label-jobnum {
  font-size: 15pt; font-weight: 800; font-family: var(--font-mono); letter-spacing: 0.3px;
}
.ff-label-price { font-size: 12pt; font-weight: 700; white-space: nowrap; }
.ff-label-barcode { width: 100%; height: 0.42in; margin-top: auto; }
/* Customer tracking QR — square, centred under the readable code. */
.ff-label-qr { width: 0.52in; height: 0.52in; margin: 2px auto 0; display: block; image-rendering: pixelated; }
.ff-label-due { font-size: 8pt; font-weight: 600; text-align: center; }

/* Customer label — mirrors the printed PDF design (FF.printLabels):
   small letter-spaced caption, big bold sans code, short accent rule. */
.ff-label-customer {
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 3px;
}
.ff-label-caption {
  font-size: 6pt; font-weight: 500; letter-spacing: 2.5px;
  text-transform: uppercase;
}
.ff-label-scan { font-size: 6.5pt; font-weight: 600; letter-spacing: 0.5px; margin-top: 3px; }
.ff-label-code {
  font-size: 13pt; font-weight: 700; font-family: var(--font);
  letter-spacing: 2px; white-space: nowrap;
}
.ff-label-rule { width: 0.6in; border-top: 1.5px solid #000; margin-top: 2px; }

/* Chrome-only hint for a bare Ctrl+P; Safari ignores named @page rules
   entirely, so the real page sizing happens in FF.printLabels(), which
   injects an unnamed `@page { size: 2.25in 1.25in }` for the duration
   of the print. All label-print buttons go through that helper. */
@page ff-label {
  size: 2.25in 1.25in;
  margin: 0;
}

@media print {
  /* Page-break properties are ignored on flex items, so the sheet must
     become a plain block for each label to land on its own page. */
  .ff-label-sheet { display: block; gap: 0; margin: 0; }
  .ff-label {
    border: none; border-radius: 0; margin: 0;
    /* Two Safari/AirPrint traps here. (1) Printers advertise the
       printable area, not the sticker size — the RW401AP reports
       2.25x1.25 stock as a 2.2x1.2in page, and Safari ignores @page
       size, so a full 2.25x1.25 label overflows and spills onto extra
       pages. (2) Safari lays the print document out at the SCREEN
       viewport width, so percentage widths balloon to screen size and
       tile across a dozen pages. Fixed dimensions just inside the
       printable area are the only thing that lands 1 label = 1 page. */
    width: 2.1in;
    height: 1.1in;
    break-after: page;
    page-break-after: always; /* Safari/AirPrint only honours the legacy syntax */
  }
  .ff-label:last-child { break-after: auto; page-break-after: auto; }
  /* Only the labels themselves should print from the "Job Confirmed"
     screen — not the checkmark, heading or action buttons. */
  .confirmed-check, .job-confirmed > h2, .confirmed-actions { display: none !important; }
}

.running-total {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 18px;
  background: var(--teal-subtle);
  border-top: 1px solid rgba(99,102,241,0.22);
}
.running-total-label  { font-size: 12px; font-weight: 600; color: var(--teal); text-transform: uppercase; letter-spacing: 0.5px; }
.running-total-amount { font-size: 26px; font-weight: 700; color: var(--teal); letter-spacing: -0.5px; }

/* -----------------------------------------------------------
   FRAME BUILDER DRAWER
   Slides in from the right over a dimmed backdrop. Holds the
   .frame-form card: scrollable body + footer pinned to the
   bottom carrying the live per-frame total.
   ----------------------------------------------------------- */
.drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.6);
  backdrop-filter: blur(3px);
  z-index: 1100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.25s ease, visibility 0.25s ease;
}
.drawer-overlay.open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}
body.drawer-open { overflow: hidden; }

.drawer {
  width: min(560px, 100%);
  max-height: 90vh;
  background: var(--surface);
  border: 1px solid var(--border-bright);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateY(12px) scale(0.97);
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
}
.drawer-overlay.open .drawer { transform: translateY(0) scale(1); }

/* The frame-form card fills the panel; body scrolls, header + footer pinned. */
#frame-drawer-body {
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0;
}
#frame-drawer .frame-form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  border: none;
  border-radius: 0;
  background: transparent;
}
#frame-drawer .card-body {
  flex: 1 1 auto;
  overflow-y: auto;
  min-height: 0;
}

/* Drawer title bar */
.drawer-header {
  flex-shrink: 0;
  cursor: default;
  gap: 12px;
}
.drawer-header h3 {
  font-size: 15px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.drawer-close {
  flex-shrink: 0;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-secondary);
  width: 30px; height: 30px;
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; cursor: pointer; padding: 0;
  transition: background 0.12s, color 0.12s;
}
.drawer-close:hover { background: var(--surface-high); color: var(--text); }

/* Price breakdown block inside the drawer body */
.drawer-breakdown {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
}

/* A confirmed frame's price, held as-is until Recalculate is explicitly
   clicked — deliberately plainer than the breakdown panel (no line items)
   since there's nothing to show but the number that was agreed. */
.price-locked-box {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  text-align: center;
}
.price-locked-amount { font-size: 22px; font-weight: 700; color: var(--text); }
.price-locked-note {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  font-size: 12px; color: var(--text-muted); margin: 6px 0 12px;
}

/* Footer pinned to the bottom of the drawer */
.drawer-footer {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 20px;
  border-top: 1px solid var(--border);
  background: var(--surface-raised);
}
.drawer-footer-total { display: flex; flex-direction: column; gap: 2px; }
.drawer-footer-label {
  font-size: 10px; font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.06em; color: var(--text-muted);
}
.drawer-footer-total strong {
  font-size: 22px; font-weight: 700; color: var(--teal); letter-spacing: -0.5px;
}
.drawer-footer-actions { display: flex; gap: 8px; flex-shrink: 0; }

/* On narrow screens the panel uses (almost) the full viewport. */
@media (max-width: 640px) {
  .drawer-overlay { padding: 12px; }
  .drawer { width: 100%; max-height: 94vh; }
  .drawer-footer-total strong { font-size: 19px; }
}

/* -----------------------------------------------------------
   TRADE CUSTOMER AUTOCOMPLETE
   ----------------------------------------------------------- */
.trade-ac-wrap {
  position: relative;
}

/* Returning-customer lookup on the New Job contact fields. The dropdown
   (.ac-dropdown) anchors to the bottom of the whole contact block. */
.cust-ac-wrap {
  position: relative;
}

/* Settings → Production: the up/down reorder buttons sit side by side. */
.prod-stage-order {
  white-space: nowrap;
}
.prod-stage-order .btn {
  padding: 2px 8px;
}

/* Callout box used for the "how stages work" explainer. */
.settings-help-box {
  background: var(--teal-subtle);
  border-left: 3px solid var(--teal);
  border-radius: var(--radius);
  padding: 10px 14px;
  margin: 10px 0;
}
.settings-help-box ul {
  margin: 6px 0 0;
  padding-left: 18px;
}
.settings-help-box li {
  margin: 4px 0;
}

.ac-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--surface-high);
  border: 1px solid var(--border-bright);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  z-index: 200;
  max-height: 260px;
  overflow-y: auto;
}

.ac-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 12px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  font-size: 14px;
  transition: background 0.1s;
}
.ac-item:last-child { border-bottom: none; }
.ac-item:hover { background: var(--teal-subtle); }

.ac-biz     { font-weight: 600; color: var(--text); }
.ac-contact { font-size: 12px; color: var(--text-muted); }

.ac-item-add {
  color: var(--teal);
  font-size: 13px;
  font-style: italic;
  background: var(--surface);
}
.ac-item-add:hover { background: var(--teal-subtle); }

/* -----------------------------------------------------------
   PRODUCT CODE AUTOCOMPLETE (frame form inputs)
   ----------------------------------------------------------- */
.code-ac-wrap {
  position: relative;
  flex: 1;
  min-width: 0;
}

.code-ac-wrap > input {
  width: 100%;
}

.code-ac-dropdown {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  min-width: 220px;
  background: var(--surface-high);
  border: 1px solid var(--border-bright);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  z-index: 300;
  max-height: 220px;
  overflow-y: auto;
}

.ac-code {
  font-weight: 600;
  color: var(--text);
  font-size: 13px;
  flex-shrink: 0;
}

.ac-desc {
  font-size: 12px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* -----------------------------------------------------------
   TRADE CUSTOMERS SETTINGS TABLE
   ----------------------------------------------------------- */
.tc-header-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.tc-table td:last-child { white-space: nowrap; }
.required { color: var(--red); font-size: 12px; }

/* -----------------------------------------------------------
   INVOICE MODAL
   ----------------------------------------------------------- */
#invoice-content { font-size: 14px; }

.inv-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 20px;
  padding-bottom: 16px;
  border-bottom: 2px solid var(--border-bright);
}
.inv-shop-name { font-size: 18px; font-weight: 700; color: var(--teal); }
.inv-date      { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.inv-customer-block { text-align: right; }
.inv-biz       { font-size: 15px; font-weight: 700; color: var(--text); }

.inv-table { width: 100%; border-collapse: collapse; margin-top: 8px; }
.inv-table th,
.inv-table td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--border); font-size: 13px; }
.inv-table th  { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); }
.inv-table .center { text-align: center; }
.inv-table .right  { text-align: right; }
.inv-total-row td  { border-top: 2px solid var(--border-bright); border-bottom: none; font-size: 14px; }
.inv-owing  { color: var(--amber); }
.inv-complete td { opacity: 0.55; }

@media print {
  #sidebar, #page-header, #modal-header, #modal-footer, #toast-container,
  .job-detail-actions { display: none !important; }
  #modal-overlay { position: static !important; background: none !important; }
  #modal-box     { box-shadow: none !important; border: none !important; max-width: 100% !important; }
  #modal-body    { padding: 0 !important; }
  body, #app     { height: auto !important; overflow: visible !important; }
  /* #app sits in the DOM before #modal-overlay and isn't fixed-position, so
     without this it prints in full behind the modal — e.g. the entire New
     Job form printing alongside (or instead of) a label. Only apply this
     while a modal is actually open, since some pages (e.g. the batch order
     list) print their own content directly, with no modal involved. */
  body.modal-open #app { display: none !important; }
  .inv-shop-name { color: #000 !important; }
  .inv-table th  { color: #555 !important; }
  .inv-owing     { color: #b45309 !important; }
}

/* -----------------------------------------------------------
   JOB LIST PAGE
   ----------------------------------------------------------- */
.joblist-layout { display: flex; flex-direction: column; gap: 14px; }

.joblist-toolbar {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.joblist-toolbar input[type="text"] { max-width: 480px; }

.joblist-search-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.joblist-search-row input[type="text"] { flex: 1; min-width: 200px; }

/* Date filter — deliberately plain, matching the search box's own shape/font
   rather than the coloured "quick-filter" chip style, since it sits right
   next to search and should read as part of the same control, not a badge. */
.date-filter-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 14px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.date-filter-btn:hover { border-color: var(--border-bright); }
.date-filter-btn.is-active { border-color: var(--teal); color: var(--teal-dim); }
.date-filter-btn i { font-size: 15px; opacity: 0.85; }
.date-filter-clear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%; color: var(--text-muted);
}
.date-filter-clear:hover { color: var(--text); background: var(--surface-high); }

.filter-row { display: flex; gap: 14px; align-items: center; flex-wrap: wrap; }
.filter-row label { flex-direction: row; align-items: center; gap: 6px; font-weight: 400; font-size: 13px; color: var(--text-secondary); }
.filter-row select, .filter-row input { width: auto; }

/* Base "chip" pill — the saved-filter chips build on this. */
.quick-filter {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 7px 12px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-raised);
  border: 1px solid var(--border-bright);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.14s var(--ease), border-color 0.14s var(--ease),
              color 0.14s var(--ease), box-shadow 0.14s var(--ease), transform 0.08s var(--ease);
}
.quick-filter i { font-size: 15px; opacity: 0.85; }
.quick-filter:active { transform: translateY(1px); }

/* -----------------------------------------------------------
   CUSTOM FILTER BAR — saved-filter chips + the "Filter +" button
   ----------------------------------------------------------- */
.filter-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* "Filter +" builder button — indigo accent so it reads as the primary
   "make a filter" affordance among the neutral worklist chips. */
.filter-add {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 8px 6px 13px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  color: var(--teal-dim);
  background: var(--teal-subtle);
  border: 1px solid var(--teal-muted);
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.14s var(--ease), border-color 0.14s var(--ease), transform 0.08s var(--ease);
}
.filter-add:hover  { background: var(--teal-glow); border-color: var(--teal-dim); }
.filter-add:active { transform: translateY(1px); }
.filter-add > i { font-size: 15px; }
.filter-add-plus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px; height: 19px;
  border-radius: 999px;
  background: var(--teal-dim);
  color: #fff;
}
.filter-add-plus i { font-size: 12px; }

/* Saved-filter chip = one pill split into an "apply" main and an "edit" pencil.
   --chip / --chip-bg are set inline per filter from its chosen colour. Sized to
   match the "Filter +" button so the bar reads as one row of equal pills. */
.qf-saved {
  --chip: var(--teal-dim);
  --chip-bg: var(--teal-subtle);
  display: inline-flex;
  align-items: stretch;
  padding: 0;                 /* reset the base .quick-filter padding — the inner
                                 buttons carry their own, else the pill bloats */
  background: var(--surface-raised);
  border: 1px solid var(--border-bright);
  border-radius: 999px;
  overflow: hidden;
  transition: border-color 0.14s var(--ease), background 0.14s var(--ease);
}
.qf-saved:hover { border-color: var(--chip); }
.qf-saved .qf-main {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 8px 6px 12px;
  font-family: var(--font);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-secondary);
  background: transparent;
  border: none;
  cursor: pointer;
}
.qf-saved .qf-main i { font-size: 14px; color: var(--chip); }
.qf-saved .qf-edit {
  display: inline-flex;
  align-items: center;
  padding: 0 8px;
  color: var(--text-muted);
  background: transparent;
  border: none;
  border-left: 1px solid var(--border);
  cursor: pointer;
  transition: color 0.14s var(--ease), background 0.14s var(--ease);
}
.qf-saved .qf-edit i { font-size: 13px; }
.qf-saved .qf-edit:hover { color: var(--chip); background: var(--chip-bg); }
.qf-saved .qf-count {
  min-width: 18px; padding: 0 6px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px; font-weight: 700; line-height: 1;
  border-radius: 999px; background: var(--surface-high); color: var(--text-secondary);
}
.qf-saved.active { background: var(--chip-bg); border-color: var(--chip); }
.qf-saved.active .qf-main  { color: var(--chip); }
.qf-saved.active .qf-edit  { border-left-color: var(--chip); }
.qf-saved.active .qf-count { background: var(--chip); color: #fff; }

/* -----------------------------------------------------------
   FILTER BUILDER (modal body)
   ----------------------------------------------------------- */
.fb { display: flex; flex-direction: column; gap: 14px; }
.fb-name {
  display: flex; flex-direction: column; gap: 5px;
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-muted);
}
.fb-name input {
  font-size: 14px; font-weight: 400; text-transform: none; letter-spacing: 0;
  color: var(--text); padding: 9px 11px;
  border: 1px solid var(--border-bright); border-radius: var(--radius); background: var(--surface);
}
/* Colour picker — a row of solid swatches; the active one gets a ring */
.fb-color { display: flex; align-items: center; gap: 12px; }
.fb-color-label {
  font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-muted);
}
.fb-swatches { display: flex; gap: 8px; }
.fb-swatch {
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--sw); border: 2px solid var(--surface);
  box-shadow: 0 0 0 1px var(--border-bright);
  cursor: pointer; padding: 0;
  transition: transform 0.1s var(--ease), box-shadow 0.12s var(--ease);
}
.fb-swatch:hover { transform: scale(1.1); }
.fb-swatch.active { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--sw); }

.fb-match { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--text-secondary); }
.fb-match select { width: auto; padding: 5px 8px; }
.fb-conds { display: flex; flex-direction: column; gap: 8px; }
.fb-cond {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px; background: var(--surface-raised);
  border: 1px solid var(--border); border-radius: var(--radius);
}
.fb-input {
  width: auto; padding: 7px 9px; font-size: 13px;
  border: 1px solid var(--border-bright); border-radius: var(--radius-sm); background: var(--surface);
}
.fb-field { min-width: 150px; }
.fb-op    { min-width: 120px; }
.fb-num   { width: 88px; }
.fb-val   { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 130px; }
.fb-val .fb-text, .fb-val input[type="date"], .fb-val > select { flex: 1; min-width: 120px; }
.fb-and   { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.fb-remove {
  margin-left: auto;
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: none; background: transparent;
  color: var(--text-muted); border-radius: var(--radius-sm); cursor: pointer;
}
.fb-remove:hover { color: var(--red); background: var(--red-bg); }
.fb-add { align-self: flex-start; }

.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.detail-grid > div {
  padding: 10px 12px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.detail-grid strong { display: block; font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); margin-bottom: 3px; }

.detail-due-edit { display: flex; align-items: center; gap: 8px; }
.detail-due-edit .due-date-input { flex: 1; }

.asap-toggle {
  flex-shrink: 0;
  font-size: 11px; font-weight: 800; letter-spacing: 0.04em;
  padding: 5px 10px; border-radius: 999px; cursor: pointer; font-family: inherit;
  border: 1px solid var(--border-bright); background: var(--surface); color: var(--text-muted);
  transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}
.asap-toggle:hover { border-color: var(--red); color: var(--red); }
.asap-toggle.is-on { background: var(--red); border-color: var(--red); color: #fff; }

/* Held for next batch — amber (a "waiting" colour, matching Overdue
   elsewhere) rather than ASAP's red, so the two different concepts
   (customer urgency vs. production scheduling) don't read as the same
   thing at a glance. */
.hold-next-batch-toggle:hover { border-color: var(--amber); color: var(--amber); }
.hold-next-batch-toggle.is-on { background: var(--amber); border-color: var(--amber); color: #fff; }

.asap-check { margin: -6px 0 14px; }
.asap-check input { width: auto; }
.detail-grid-small { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 8px 0; }
.detail-grid-small > div { padding: 8px 10px; background: var(--surface-raised); border: 1px solid var(--border); border-radius: var(--radius); font-size: 13px; }
.detail-grid-small strong { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); }
.detail-code-desc { font-size: 11px; font-style: italic; color: var(--text-muted); margin-top: 2px; }

.frame-detail-card { border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 14px; margin-bottom: 10px; background: var(--surface-raised); }
.frame-detail-card h4 { margin-bottom: 10px; color: var(--text); }
.notes-text { font-size: 12px; margin-top: 8px; color: var(--text-secondary); padding: 8px 10px; background: var(--surface); border-radius: var(--radius); }
.job-detail-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }

/* Job confirmed */
.job-confirmed { text-align: center; padding: 24px 16px; }
.confirmed-check { font-size: 52px; color: var(--green); line-height: 1; margin-bottom: 12px; }
.confirmed-jobnumber {
  font-size: 26px;
  font-weight: 700;
  color: var(--teal);
  margin: 8px 0;
  font-family: var(--font-mono);
  letter-spacing: 1px;
}
.confirmed-actions { display: flex; gap: 10px; justify-content: center; margin-top: 16px; flex-wrap: wrap; }

/* -----------------------------------------------------------
   SETTINGS PAGE
   ----------------------------------------------------------- */
.settings-layout {
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 20px;
  align-items: start;
}

.settings-nav { display: flex; flex-direction: column; gap: 2px; }
.settings-nav-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  text-align: left;
  padding: 9px 12px;
  border: none;
  background: transparent;
  border-radius: var(--radius);
  font-family: var(--font);
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  cursor: pointer;
  transition: background 0.12s, color 0.12s;
}
.settings-nav-btn:hover  { background: var(--surface-raised); color: var(--text); }
.settings-nav-btn.active { background: var(--teal-subtle); color: var(--teal); }
.settings-version {
  margin-top: 14px; padding: 10px 12px 0;
  border-top: 1px solid var(--border);
  font-size: 11px; color: var(--text-muted);
}

.settings-main { min-width: 0; }
#settings-subnav:not(:empty) { margin-bottom: 14px; }
.settings-subnav-bar { display: flex; flex-wrap: wrap; gap: 4px; }

.settings-content {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px;
}
.settings-content h2 {
  font-size: 17px;
  margin-bottom: 6px;
  color: var(--text);
}
.settings-content h3 { font-size: 14px; margin: 22px 0 10px; color: var(--text); }
.settings-help { font-size: 13px; color: var(--text-muted); margin-bottom: 18px; line-height: 1.6; }

.labour-table-block { margin-bottom: 24px; }
.labour-table-block h3 { display: flex; align-items: center; gap: 10px; }

.csv-upload-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); gap: 14px; }
.csv-upload-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 16px;
  background: var(--surface-raised);
}
.csv-upload-card h4 { margin-bottom: 6px; color: var(--text); }
.csv-upload-card p  { font-size: 12px; margin-bottom: 12px; line-height: 1.6; color: var(--text-muted); }
.csv-upload-card input[type="file"] { display: block; margin-bottom: 8px; font-size: 13px; color: var(--text-secondary); }
.upload-status { display: block; font-size: 12px; color: var(--text-muted); }
.upload-status.success  { color: var(--green); }
.upload-status.error    { color: var(--red); }
.upload-status.uploading{ color: var(--blue); }

/* -----------------------------------------------------------
   SUPPLIER CARDS
   ----------------------------------------------------------- */
.supplier-cards { display: flex; flex-direction: column; gap: 16px; margin-top: 16px; }

.supplier-card {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}

.sup-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: var(--surface-high);
  border-bottom: 1px solid var(--border);
}
.sup-card-name { font-size: 15px; font-weight: 600; color: var(--text); }
.sup-card-actions { display: flex; gap: 6px; }

.sup-discounts {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 10px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
  font-size: 12px;
  overflow-x: auto;
}
.disc-label { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; color: var(--text-muted); white-space: nowrap; margin-right: 2px; }
.disc-input.disc-small { width: 48px !important; padding: 3px 5px; font-size: 12px; }

.staff-switch-row { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.staff-switch-label { font-size: inherit; color: inherit; }
.sup-discounts label { white-space: nowrap; }

.sup-section {
  padding: 10px 16px;
  border-bottom: 1px solid var(--border);
}
.sup-section-label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--text-muted);
  margin-bottom: 6px;
}
.sup-section-help { font-size: 12px; color: var(--text-muted); margin-bottom: 8px; }

.sup-override-search { display: flex; gap: 8px; align-items: center; }
.sup-override-search input { width: 160px; }
.sup-ovr-block { margin-top: 10px; padding: 10px; background: var(--surface-high); border-radius: var(--radius); }
.sup-ovr-desc { font-size: 13px; color: var(--text); margin-bottom: 8px; }
.sup-ovr-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; font-size: 13px; }

.sup-ovr-toggle { margin-top: 10px; font-size: 12px; }
.sup-ovr-list { margin-top: 8px; }

.sup-ovr-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.sup-ovr-table th {
  text-align: left; padding: 4px 8px;
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-muted); border-bottom: 1px solid var(--border);
}
.sup-ovr-table td { padding: 6px 8px; border-bottom: 1px solid var(--border); vertical-align: middle; }
.sup-ovr-table tbody tr:last-child td { border-bottom: none; }
.sup-ovr-table tbody tr:hover { background: var(--surface-high); }
.sup-ovr-code { font-family: monospace; font-size: 12px; color: var(--text); }
.sup-ovr-actions { display: flex; gap: 5px; white-space: nowrap; }

.sup-upload-section { padding: 10px 16px; }

.sup-file-list { margin-bottom: 10px; }
.sup-file-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 7px 10px;
  margin-bottom: 4px;
  background: var(--surface-high);
  border-radius: var(--radius);
}
.sup-file-info { display: flex; flex-direction: column; flex: 1; min-width: 0; }
.sup-file-name { font-size: 13px; font-weight: 500; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sup-file-meta { font-size: 11px; color: var(--text-muted); margin-top: 2px; }
.sup-file-date { font-size: 11px; color: var(--text-secondary); margin-top: 1px; }
.sup-replace-btn { cursor: pointer; white-space: nowrap; flex-shrink: 0; }

.sup-upload-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.sup-upload-btn {
  cursor: pointer;
  white-space: nowrap;
}

.search-row { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.colour-swatch { display: inline-block; padding: 2px 8px; border-radius: var(--radius-sm); font-size: 12px; background: var(--surface-high); color: var(--text-secondary); }

/* -----------------------------------------------------------
   BATCH & ORDERS PAGE
   ----------------------------------------------------------- */
.batch-layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 16px;
  align-items: start;
}

.batch-sidebar {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px;
}
.batch-sidebar h3 {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 1px;
  color: var(--text-muted);
  margin-bottom: 10px;
}

.batch-list-item {
  padding: 10px 11px;
  border-radius: var(--radius);
  cursor: pointer;
  margin-bottom: 3px;
  border: 1px solid transparent;
  transition: border-color 0.12s, background 0.12s;
}
.batch-list-item:hover { border-color: var(--border); background: var(--surface-raised); }
.batch-list-item.active { border-color: var(--teal); background: var(--teal-subtle); }
.batch-list-item strong { display: flex; justify-content: space-between; font-size: 13px; color: var(--text); }
.batch-status-icon { font-size: 14px; }
.unassigned-info { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }

.batch-main {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.batch-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
  flex-wrap: wrap;
  gap: 10px;
}
.batch-header h2 { font-size: 16px; color: var(--text); margin: 0; }
.batch-meta { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; font-size: 12px; color: var(--text-muted); }
.batch-actions { display: flex; gap: 8px; }

.order-list { padding: 16px; }
.order-section { margin-bottom: 24px; }

/* Batch order list — note listing carried-over jobs whose materials were
   already ordered with their original batch (excluded from the totals). */
.order-carried-note {
  display: flex; align-items: flex-start; gap: 8px;
  font-size: 13px; color: var(--text-secondary); line-height: 1.5;
  background: var(--amber-bg); border: 1px solid var(--amber);
  border-radius: 8px; padding: 10px 12px; margin-bottom: 18px;
}
.order-carried-note i { color: var(--amber); font-size: 16px; margin-top: 1px; }
.order-section h3 {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--text-muted);
  margin-bottom: 10px;
  display: flex;
  align-items: center;
  gap: 8px;
}
.order-section h3::after {
  content: '';
  flex: 1;
  border-top: 1px solid var(--border);
}

.production-header {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  background: var(--surface-raised);
  border-bottom: 1px solid var(--border);
}
.prod-stats  { display: flex; gap: 20px; flex-wrap: wrap; }
.prod-stat   { font-size: 13px; color: var(--text-secondary); }
.prod-stat strong { color: var(--teal); font-size: 15px; }
.progress-bar  { background: var(--surface-high); border-radius: 20px; height: 6px; overflow: hidden; }
.progress-fill { background: var(--teal); height: 100%; border-radius: 20px; transition: width 0.4s ease; }
.production-table td { vertical-align: top; padding: 10px 14px; }

/* -----------------------------------------------------------
   PLACEHOLDER PAGES
   ----------------------------------------------------------- */
.placeholder-page {
  text-align: center;
  padding: 80px 40px;
  color: var(--text-muted);
}
.placeholder-icon { font-size: 64px; color: var(--border); margin-bottom: 16px; }
.placeholder-page h2 { font-size: 20px; color: var(--text-secondary); margin-bottom: 10px; }
.placeholder-page p  { font-size: 14px; max-width: 420px; margin: 0 auto 8px; }

/* -----------------------------------------------------------
   SETUP / ERROR SCREENS
   ----------------------------------------------------------- */
.setup-required, .startup-screen {
  max-width: 560px;
  margin: 60px auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  padding: 36px;
  box-shadow: var(--shadow-md);
}
.setup-required h2 { color: var(--teal); margin-bottom: 14px; }
.setup-required ol, .setup-required ul { padding-left: 20px; margin: 12px 0; line-height: 2.2; }
.startup-screen    { text-align: center; }
.startup-logo-row  { display: flex; align-items: center; justify-content: center; gap: 12px; margin-bottom: 20px; }
.startup-logo      { font-size: 30px; font-weight: 800; color: var(--text); letter-spacing: -1px; }

/* -----------------------------------------------------------
   JOB NUMBER STYLE
   ----------------------------------------------------------- */
.job-number {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 600;
  color: var(--text-secondary);
  background: var(--surface-raised);
  padding: 2px 7px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}

/* -----------------------------------------------------------
   PRINT STYLES
   ----------------------------------------------------------- */
@media print {
  #sidebar, #page-header, #page-actions, .btn, .tab-bar,
  #toast-container, .joblist-toolbar { display: none !important; }
  #main-content { overflow: visible; }
  #page-body    { overflow: visible; padding: 0; }
  body          { background: white; color: black; }
  .data-table th, .data-table td { border-color: #ccc; color: black; }
}

/* -----------------------------------------------------------
   RESPONSIVE
   ----------------------------------------------------------- */
@media (max-width: 1024px) {
  .newjob-layout  { grid-template-columns: 1fr; }
  .newjob-right   { position: static; }
  .stat-cards     { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  .settings-layout { grid-template-columns: 1fr; }
  .settings-nav    { flex-direction: row; flex-wrap: wrap; }
  .settings-version { flex: 0 0 100%; margin-top: 6px; border-top: none; }
  .batch-layout    { grid-template-columns: 1fr; }
  .form-grid-4     { grid-template-columns: 1fr 1fr; }
  .detail-grid     { grid-template-columns: 1fr; }
}
@media (max-width: 600px) {
  /* Sidebar collapses to a slim top bar; tapping the logo drops the full
     nav down over the content instead of squeezing every item into a rail. */
  #app { flex-direction: column; }
  #sidebar {
    width: 100%;
    min-width: 0;
    flex-direction: row;
    align-items: center;
    border-right: none;
    border-bottom: 1px solid var(--border);
    overflow: visible;
    position: relative;
    z-index: 40;
  }
  .sidebar-header { flex: 1; padding: 12px 14px; border-bottom: none; cursor: pointer; }
  .nav-caret { display: inline-block; }
  #sidebar.menu-open .nav-caret { transform: rotate(180deg); }

  .nav-list {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    max-height: 0;
    overflow-y: auto;
    padding: 0 8px;
    background: var(--sidebar-bg);
    border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-md);
    transition: max-height 0.18s var(--ease);
  }
  #sidebar.menu-open .nav-list { max-height: 70vh; padding: 8px; }

  .sidebar-footer { display: none; }

  /* The email/staff chip is inserted as a sidebar-footer sibling, so on
     desktop it sits below the nav; on mobile #sidebar becomes a row and it
     tries to join that row too, squeezed down to nothing next to the logo.
     Show the current page name in that spot instead — more useful at a
     glance, and it's already tracked by setPageTitle(). (The chip itself
     is hidden further down, right after its own base .sidebar-user rule —
     doing it here too was getting overridden by that later, unconditional
     rule since media queries don't add specificity, just a condition.) */
  .sidebar-page-label {
    display: block;
    margin-left: auto;
    font-size: 12px; font-weight: 600; color: var(--text-secondary);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 38vw;
  }

  /* FAB is a labelled duplicate of the sidebar's New Job — shrink it to a
     round icon so it stops running off the edge, and drop the text. */
  #fab-new-job { right: 16px; bottom: 16px; width: 54px; height: 54px; padding: 0; justify-content: center; border-radius: 50%; }
  #fab-new-job span { display: none; }
  #fab-new-job i { font-size: 24px; }

  #page-body { padding: 12px; }
  .stat-cards { grid-template-columns: 1fr 1fr; }
  .form-grid-2, .form-grid-3 { grid-template-columns: 1fr; }

  /* Header was overflowing on New Job: title + two large action buttons
     didn't fit ~390px and the primary "Confirm Job" got clipped by the
     page's overflow-x:hidden. Tighten padding + shrink the actions so both
     buttons stay on screen and tappable. */
  /* #page-title now duplicates the page name already shown in the mobile
     top bar (see .sidebar-page-label) — drop it here rather than show the
     same word twice; #page-actions (the real buttons, e.g. Confirm Job)
     stays and just gets pushed to the start of the row on its own. */
  #page-header  { padding: 0 12px; gap: 10px; }
  #page-title   { display: none; }
  #page-actions { gap: 6px; }
  #page-actions .btn-lg { padding: 9px 13px; font-size: 13px; }
  /* Nothing left in the bar at all (no title shown here, no actions) —
     set by FF._updatePageHeader() in app.js. Collapse it rather than show
     an empty strip on every page that has no header buttons. */
  #page-header.is-empty-mobile { display: none; }

  /* Multi-column detail cards (frame/print spec) were fixed at 3 columns,
     far too tight on a phone. Drop to 2. */
  .detail-grid-small { grid-template-columns: 1fr 1fr; }

  /* Modal + drawer on a phone: give them nearly the whole screen (the 20px
     desktop gutter wastes scarce width) and size against the *dynamic*
     viewport — 90vh ignores iOS Safari's collapsing URL bar, which left the
     footer buttons hiding behind it. Older browsers drop the dvh line and
     keep the base 90vh. */
  #modal-overlay { padding: 10px; }
  .drawer-overlay { padding: 10px; }
  #modal-box, .drawer { max-height: calc(100dvh - 20px); }

  /* Toasts pinned to the right could run off a narrow screen; stretch the
     strip across the bottom instead. z-index already carries them over the
     FAB, and they dismiss themselves. */
  #toast-container { left: 12px; right: 12px; bottom: 12px; }
}

/* Wide data-tables (Job Book list, Frames/Prints/Items lists — up to 9
   columns) were clipped on narrow screens with no way to reach the hidden
   columns, because the page hides horizontal overflow. Let each table scroll
   sideways on its own instead. Headers already never wrap, so columns stay
   aligned; you swipe to see Stage/Wood/etc. */
@media (max-width: 700px) {
  .data-table,
  .settings-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
}

/* -----------------------------------------------------------
   PRODUCTION BOARD
   Touch-first kanban: stage columns scroll sideways on small
   screens; tap a card to open the stage picker.
   ----------------------------------------------------------- */
.board-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.board-toolbar input[type="text"] {
  flex: 1 1 280px;
  min-width: 0;
}
.board-hint { color: var(--text-muted); font-size: 12px; }

.board-columns {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 8px;
}
.board-col {
  flex: 0 0 230px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 230px);
  /* The header sits flush against the top with its own square corners —
     without clipping, the column's rounded corner shows through faintly
     underneath it. */
  overflow: hidden;
}
.board-col-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 2px solid var(--sc, var(--border-bright));
  position: sticky;
  top: 0;
}
.board-col-name  { font-weight: 600; font-size: 13px; color: var(--text); }
.board-col-count {
  font-size: 12px; font-weight: 600;
  background: var(--surface-high); color: var(--text-secondary);
  border-radius: 10px; padding: 1px 8px; min-width: 22px; text-align: center;
}
.board-col-body {
  padding: 10px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  overflow-y: auto;
}
.board-empty { color: var(--text-muted); text-align: center; padding: 8px 0; font-size: 13px; }

.board-card {
  background: var(--surface-high);
  border: 1px solid var(--border);
  border-left: 3px solid var(--sc, var(--border-bright));
  border-radius: 6px;
  padding: 9px 10px;
  cursor: pointer;
  transition: border-color 0.12s, transform 0.06s;
}
.board-card:hover  { border-color: var(--border-bright); }
.board-card:active { transform: scale(0.98); }

/* ASAP-flagged job — a ring around the whole card so it stands out at a
   glance across every column, independent of the stage-colour accent
   stripe on the left edge. */
.board-card.is-urgent {
  box-shadow: 0 0 0 2px var(--red), 0 0 0 5px var(--red-bg);
}
.board-card-asap {
  margin-left: auto;
  font-size: 10px; font-weight: 800; letter-spacing: 0.04em;
  color: #fff; background: var(--red);
  border-radius: 20px; padding: 2px 8px;
}

/* Job carried over from an earlier batch (leftover work) — same ring
   grammar as ASAP but in amber. ASAP wins if a card is both. */
.board-card.is-carried {
  box-shadow: 0 0 0 2px var(--amber), 0 0 0 5px var(--amber-bg);
}
.board-card-due {
  margin-left: auto;
  font-size: 10px; font-weight: 800; letter-spacing: 0.04em;
  color: #fff; background: var(--amber);
  border-radius: 20px; padding: 2px 8px;
}

.board-card-top {
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
}
.board-card-top strong { font-size: 14px; color: var(--text); }
.board-card-cust { font-size: 12px; color: var(--text-secondary); }
.board-card-desc {
  font-size: 12.5px; color: var(--text); margin-top: 3px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Cutting size is the headline number for the bench. */
.board-card-size {
  font-size: 16px; font-weight: 700; color: var(--text);
  margin-top: 5px; letter-spacing: 0.2px;
}
.board-card-mould {
  font-size: 12.5px; color: var(--text-secondary); margin-top: 3px;
}
.board-card-mats {
  font-size: 11.5px; color: var(--text-muted); margin-top: 2px;
}
/* Product description(s) for whichever code line sits directly above —
   one step smaller/quieter so the code itself still reads first. */
.board-card-code-desc {
  font-size: 10.5px; font-style: italic; color: var(--text-muted); margin-top: 1px;
}
/* Count badge on a card representing several identical items grouped
   together (same job + same spec, sitting in the same stage). */
.board-card-count {
  margin-left: auto;
  font-size: 11px; font-weight: 700;
  background: var(--teal-subtle); color: var(--teal-dim);
  border-radius: 20px; padding: 1px 8px;
}

/* Select mode — cards get a checkbox and stop opening the move picker on
   tap; tapping toggles selection for the bulk action bar instead. */
.board-card.is-selectable { padding-left: 30px; position: relative; }
.board-card-check {
  position: absolute; left: 8px; top: 9px;
  font-size: 16px; color: var(--text-muted);
}
.board-card.is-selected {
  border-color: var(--teal);
  background: var(--teal-subtle);
}
.board-card.is-selected .board-card-check { color: var(--teal); }
.board-select-toggle.is-active {
  background: var(--teal); border-color: var(--teal); color: #fff;
}
.board-week-pill.is-active {
  background: var(--amber); border-color: var(--amber); color: #fff;
}
.board-week-pill-count {
  display: inline-block; margin-left: 2px;
  background: var(--surface-high); color: var(--text-secondary);
  border-radius: 10px; padding: 0 6px; font-size: 11px; font-weight: 700;
}
.board-week-pill.is-active .board-week-pill-count { background: rgba(255,255,255,0.25); color: #fff; }

/* Per-stage accent colour comes from each stage's own `color` (set inline as
   --sc by board.js stageColor()), so it always matches the stage badge. */

/* Stage picker modal — info first, then the move controls. */
.board-frame-sub {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.board-frame-cust { font-size: 15px; font-weight: 600; color: var(--text); }

.board-spec {
  display: flex; flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.board-spec-row {
  display: flex; gap: 12px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border);
}
.board-spec-row:last-child { border-bottom: none; }
.board-spec-k { flex: 0 0 110px; color: var(--text-muted); font-size: 13px; }
.board-spec-v { flex: 1 1 auto; color: var(--text); font-size: 14px; }
.board-spec-v strong { font-size: 16px; }
.board-spec-desc { font-size: 12px; font-style: italic; color: var(--text-muted); margin-top: 2px; }
.board-frame-notes {
  margin-top: 10px; font-size: 13px; color: var(--text-secondary);
}

.board-move { margin-top: 18px; }
/* Quantity control on a grouped card's picker — lets part of an identical
   batch move on (e.g. ran short on moulding) while the rest stay behind. */
.board-qty-row {
  display: flex; align-items: center; gap: 8px;
  margin-bottom: 12px; font-size: 13px; color: var(--text-secondary);
}
.board-qty-row label { flex-shrink: 0; }
.board-qty-row input[type="number"] { width: 70px; padding: 8px 10px; text-align: center; }
.board-next-btn { width: 100%; font-size: 15px; padding: 13px; justify-content: center; }
.board-next-btn .ph-arrow-right { font-size: 15px; }
.board-done-note { color: var(--text-muted); text-align: center; margin: 4px 0 8px; }
.board-move-label { color: var(--text-muted); font-size: 12px; margin: 14px 0 7px; }
.board-stage-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.board-stage-chip {
  padding: 7px 12px;
  background: var(--surface-high);
  border: 1px solid var(--border);
  border-radius: 16px;
  color: var(--text-secondary);
  font-size: 13px;
  font-family: var(--font);
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.board-stage-chip:hover:not(:disabled) { border-color: var(--teal); color: var(--teal); background: var(--teal-subtle); }
.board-stage-chip.is-current { opacity: 0.5; cursor: default; }
.board-openjob-btn { width: 100%; margin-top: 16px; }

/* Bulk action bar — appears while Select mode is on, sticky along the
   bottom so it's reachable regardless of how far the board has scrolled. */
.board-bulkbar {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  margin-top: 10px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
}
.board-bulkbar.hidden { display: none; }
.board-bulkbar-count { font-size: 13px; font-weight: 600; color: var(--text); }
.board-bulkbar-label { font-size: 12px; color: var(--text-muted); }
.board-bulkbar .board-stage-chips { flex: 1 1 auto; }
.board-bulkbar-done { margin-left: auto; }

/* On phones, let columns take more of the width so cards are readable. */
@media (max-width: 600px) {
  .board-col { flex-basis: 78vw; max-height: none; }
  .board-columns { scroll-snap-type: x mandatory; }
  .board-col { scroll-snap-align: start; }
  .board-bulkbar { flex-direction: column; align-items: stretch; }
  .board-bulkbar-done { margin-left: 0; }
}

/* =============================================================
   AURORA THEME LAYER
   -------------------------------------------------------------
   Motion, depth and gradient accents layered on top of the
   token-driven base above. (Formerly the reversible
   theme-sleek.css overlay, now folded in permanently.)
   ============================================================= */

/* -----------------------------------------------------------
   A. GLOBAL — light canvas with a faint aurora wash
   ----------------------------------------------------------- */
html { scroll-behavior: smooth; }
body {
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  background: var(--bg);
}
/* The aurora wash lives on a FIXED underlay (not body's own background) so
   it sits beneath the app even though only #page-body scrolls — and so the
   Liquid Glass surfaces (see the layer at the foot of this file) always have
   real colour behind them to blur. A plain grey behind frosted glass barely
   reads as glass at all. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(1000px 640px at 88% -12%, rgba(124,58,237,0.16), transparent 62%),
    radial-gradient(900px 620px at -10% 18%,  rgba(99,102,241,0.15), transparent 56%),
    radial-gradient(820px 560px at 50% 115%,  rgba(34,211,238,0.10), transparent 60%),
    var(--bg);
}
html[data-theme="dark"] body::before {
  background:
    radial-gradient(1000px 640px at 88% -12%, rgba(124,58,237,0.20), transparent 62%),
    radial-gradient(900px 620px at -10% 18%,  rgba(99,102,241,0.17), transparent 56%),
    radial-gradient(820px 560px at 50% 115%,  rgba(34,211,238,0.09), transparent 60%),
    var(--bg);
}
h1, h2, h3, h4, .logo-name { letter-spacing: -0.02em; color: var(--text); }
::selection { background: rgba(99,102,241,0.22); color: var(--text); }

/* Scrollbars */
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: #c7cdd9; border-radius: 10px;
  border: 3px solid transparent; background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: #aab2c2; background-clip: content-box; }
html[data-theme="dark"] ::-webkit-scrollbar-thumb { background: #3a3a4a; background-clip: content-box; }
html[data-theme="dark"] ::-webkit-scrollbar-thumb:hover { background: #4a4a5e; background-clip: content-box; }

/* -----------------------------------------------------------
   B. SIDEBAR — white, with a glowing active accent bar
   ----------------------------------------------------------- */
#sidebar { border-right: 1px solid var(--border); box-shadow: 1px 0 0 rgba(17,24,39,0.02); }
.logo-icon-wrap {
  background: none;
  border: none;
  filter: drop-shadow(0 4px 10px rgba(99,102,241,0.30));
}
.nav-item {
  border-radius: 11px; margin: 2px 10px; position: relative; color: var(--text-secondary);
  transition: background 0.18s var(--ease), color 0.18s var(--ease), transform 0.12s var(--ease);
}
.nav-item:hover { background: var(--surface-high); color: var(--text); }
.nav-item:active { transform: scale(0.98); }
.nav-item.active { background: var(--teal-subtle); color: var(--teal-dim); }
.nav-item.active .nav-icon { color: var(--teal); }
.nav-item.active::before {
  content: ""; position: absolute; left: -10px; top: 50%;
  width: 3px; height: 18px; background: linear-gradient(180deg,#6366f1,#7c3aed);
  border-radius: 0 3px 3px 0; transform: translateY(-50%);
  box-shadow: 0 0 12px var(--teal-glow);
}
.nav-icon { transition: transform 0.18s var(--ease); }
.nav-item:hover .nav-icon { transform: translateX(1px); }
/* New Job CTA — gradient pill */
.nav-item-cta, .nav-item-cta:hover, .nav-item-cta.active {
  background: linear-gradient(135deg, #6366f1, #7c3aed) !important;
  color: #fff !important;
  box-shadow: 0 8px 20px -6px rgba(99,102,241,0.5);
}
.nav-item-cta .nav-icon, .nav-item-cta.active .nav-icon { color: #fff; }

/* -----------------------------------------------------------
   C. BUTTONS — gradient primary, gentle lift & press
   ----------------------------------------------------------- */
.btn {
  border-radius: 11px;
  transition: transform 0.15s var(--ease), box-shadow 0.2s var(--ease),
              background 0.2s var(--ease), border-color 0.2s var(--ease);
  will-change: transform;
}
.btn:hover  { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.975); }
.btn-primary {
  background: linear-gradient(135deg, #6366f1 0%, #7c3aed 100%);
  color: #fff;
  box-shadow: 0 4px 14px -4px rgba(99,102,241,0.55);
}
.btn-primary:hover {
  background: linear-gradient(135deg, #6f72f3 0%, #8b46f0 100%);
  box-shadow: 0 10px 24px -6px rgba(99,102,241,0.6);
}
.btn-secondary {
  background: var(--surface);
  border: 1px solid var(--border-bright);
  color: var(--text);
}
.btn-secondary:hover { background: var(--surface-high); }
.btn-lg { border-radius: 13px; }

/* -----------------------------------------------------------
   D. INPUTS — white fields, indigo focus ring
   ----------------------------------------------------------- */
input[type="text"], input[type="number"], input[type="tel"],
input[type="email"], input[type="date"], input[type="search"],
select, textarea {
  border-radius: 11px;
  background: var(--surface);
  border: 1px solid var(--border-bright);
  transition: border-color 0.18s var(--ease), box-shadow 0.18s var(--ease), background 0.18s var(--ease);
}
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--teal) !important;
  box-shadow: 0 0 0 3.5px var(--teal-subtle);
}

/* -----------------------------------------------------------
   E. CARDS, TABLES & ROWS
   ----------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  transition: box-shadow 0.25s var(--ease), border-color 0.25s var(--ease);
}
.data-table { background: var(--surface); }
.data-table thead tr { background: var(--surface-raised); }
.data-table tbody tr, .job-row {
  transition: background 0.15s var(--ease);
}
.job-row { cursor: pointer; }
.data-table tbody tr:hover td, .job-row:hover { background: var(--teal-subtle); }

/* Board cards — white tiles that lift on hover */
.board-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  transition: transform 0.16s var(--ease), box-shadow 0.22s var(--ease), border-color 0.22s var(--ease);
}
.board-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--teal-muted);
}
.board-col { background: var(--surface-raised); border-radius: var(--radius-lg); }

/* -----------------------------------------------------------
   F. TABS — animated active underline
   ----------------------------------------------------------- */
.tab-btn {
  border-radius: 9px 9px 0 0; color: var(--text-secondary);
  transition: color 0.2s var(--ease), background 0.2s var(--ease), box-shadow 0.25s var(--ease);
}
.tab-btn:hover { color: var(--text); }
.tab-btn.active { color: var(--teal-dim); box-shadow: inset 0 -2px 0 0 var(--teal); }

/* -----------------------------------------------------------
   G. BADGES — crisp pills
   ----------------------------------------------------------- */
.badge { border-radius: 7px; font-weight: 600; letter-spacing: 0.01em; }

/* -----------------------------------------------------------
   H. HEADER — frosted glass
   ----------------------------------------------------------- */
#page-header {
  /* color-mix on var(--surface) rather than a hardcoded white — adapts
     automatically to whichever theme is active instead of needing a
     separate dark override. */
  background: color-mix(in srgb, var(--surface) 72%, transparent);
  backdrop-filter: saturate(150%) blur(10px);
  -webkit-backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--border);
}

/* -----------------------------------------------------------
   I. MODAL — frosted scrim + spring entrance
   ----------------------------------------------------------- */
#modal-overlay {
  background: rgba(28,28,46,0.30);
  backdrop-filter: blur(8px) saturate(120%);
  -webkit-backdrop-filter: blur(8px) saturate(120%);
}
#modal-overlay:not(.hidden) { animation: ff-fade 0.22s var(--ease) both; }
#modal-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-lg);
  animation: ff-modal-in 0.32s var(--ease-spring) both;
}

/* -----------------------------------------------------------
   J. FAB + TOASTS
   ----------------------------------------------------------- */
#fab-new-job {
  background: linear-gradient(135deg, #6366f1, #7c3aed);
  box-shadow: 0 14px 32px -10px rgba(99,102,241,0.65), var(--shadow-md);
  transition: transform 0.18s var(--ease-spring), box-shadow 0.22s var(--ease);
}
#fab-new-job:hover { transform: translateY(-2px) scale(1.03); }
.toast {
  border-radius: 12px;
  box-shadow: var(--shadow-md);
  border: 1px solid var(--border);
}

/* -----------------------------------------------------------
   K. PAGE / CONTENT ENTRANCE ANIMATIONS
   ----------------------------------------------------------- */
.newjob-layout, .joblist-layout, .batch-layout, .settings-layout,
.section-content, .placeholder-page, .startup-screen,
.dashboard-grid, .dashboard-content, .board-columns {
  animation: ff-fade-up 0.3s var(--ease) both;
}
@keyframes ff-fade-up { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes ff-fade    { from { opacity: 0; } to { opacity: 1; } }
@keyframes ff-modal-in { from { opacity: 0; transform: translateY(14px) scale(0.97); } to { opacity: 1; transform: none; } }

/* -----------------------------------------------------------
   L. POLISH / EDGE-CASE SWEEP
   Mop up the few values that don't flow through the design
   tokens, so nothing on a less-used screen still reads in the
   old dark-teal palette. Plus a couple of consistency touches
   so every screen shares the same motion.
   ----------------------------------------------------------- */

/* --- Off-palette teal-green leftovers ------------------------ */
.help-tip:hover,
.help-tip.is-open { background: var(--teal-dim); }
.moulding-add-btn        { color: var(--teal-dim); border-color: var(--teal-muted); }
.moulding-add-btn:hover  { background: var(--teal-subtle); border-color: var(--teal); color: var(--teal-dim); }
.mi-disc { color: var(--green); }

/* --- Badges tuned for a dark bg had too little contrast on light --- */
.badge-light-blue { background: rgba(8,145,178,0.12);  color: #0e7490; }
.badge-dark-green { background: rgba(5,150,105,0.12);   color: #047857; }
/* ...and vice versa — brighter variants for an actual dark background. */
html[data-theme="dark"] .badge-light-blue { background: rgba(34,211,238,0.14); color: #22d3ee; }
html[data-theme="dark"] .badge-dark-green { background: rgba(16,185,129,0.14); color: #34d399; }

/* --- Customer card header → aurora gradient ------------------ */
.customer-card-header {
  background: linear-gradient(135deg, #6366f1, #7c3aed);
  border-bottom-color: transparent;
}

.quick-action-btn {
  transition: transform 0.16s var(--ease), border-color 0.16s var(--ease),
              color 0.16s var(--ease), background 0.16s var(--ease), box-shadow 0.22s var(--ease);
}
.quick-action-btn:hover { transform: translateY(-1px); box-shadow: var(--shadow); }

/* --- Settings: glowing active bar, matching the sidebar ------ */
.settings-nav-btn { position: relative; border-radius: 10px; }
.settings-nav-btn.active { background: var(--teal-subtle); color: var(--teal-dim); }
.settings-nav-btn.active::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 3px; height: 16px; background: linear-gradient(180deg,#6366f1,#7c3aed);
  border-radius: 0 3px 3px 0; transform: translateY(-50%);
  box-shadow: 0 0 10px var(--teal-glow);
}

/* --- Batch list active item: accent bar for parity ---------- */
.batch-list-item.active { border-color: var(--teal-muted); }

/* --- Progress bar → gradient fill --------------------------- */
.progress-fill { background: linear-gradient(90deg, #6366f1, #7c3aed); }

/* --- Job list: "ready to call" rows get a soft green accent -- */
.data-table tbody tr.job-ready-call td { background: var(--green-bg); }
.data-table tbody tr.job-ready-call td:first-child { box-shadow: inset 3px 0 0 var(--green); }

/* --- Job list: rows that still owe money get a soft amber accent.
   (A ready-to-call row wins the tint if it's somehow both.) --------- */
.data-table tbody tr.job-owing:not(.job-ready-call) td { background: var(--amber-bg); }
.data-table tbody tr.job-owing:not(.job-ready-call) td:first-child { box-shadow: inset 3px 0 0 var(--amber); }

/* --- Job list Done / Called / Paid — labelled pill toggles.
   Bigger tap targets and self-explanatory vs. bare checkboxes; the
   native checkbox drives state and the pill lights up via :has(). ---- */
.status-cell { white-space: nowrap; text-align: right; }
/* Minimal icon toggles — three INDEPENDENT taps (Called / Paid / Collected).
   Independent by design: a customer can pay at order time without being called.
   Quiet grey by default; lights into a soft colour disc when on, via :has(). */
.status-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; margin: 0 1px; border-radius: 50%;
  color: var(--text-muted); cursor: pointer; user-select: none;
  transition: background .15s var(--ease), color .15s var(--ease), transform .1s var(--ease);
}
.status-toggle input { position: absolute; opacity: 0; width: 0; height: 0; }
.status-toggle i { font-size: 18px; }
.status-toggle:hover  { background: var(--surface-high); color: var(--text-secondary); }
.status-toggle:active { transform: scale(0.88); }
.status-toggle.status-called:has(:checked)    { color: var(--blue);     background: var(--blue-bg); }
.status-toggle.status-paid:has(:checked)      { color: var(--green);    background: var(--green-bg); }
.status-toggle.status-collected:has(:checked) { color: var(--teal-dim); background: var(--teal-subtle); }
/* A ticked icon all but vanished on the dark theme (a 16% tint on a dark
   surface). Ring it in its own state colour with a soft glow — the same
   liquid-glass language as the overlays — so ticked states read at a
   glance on both themes. currentColor inherits from the rules above. */
.status-toggle:has(:checked) {
  box-shadow: inset 0 0 0 1.5px color-mix(in srgb, currentColor 65%, transparent),
              0 0 12px color-mix(in srgb, currentColor 35%, transparent);
}

/* Button variant — job detail popup: labelled rectangles, big tap targets */
.detail-status-row { grid-column: 1 / -1; display: flex; gap: 10px; margin-top: 6px; }
.status-btn {
  flex: 1; display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 12px 14px; border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-secondary);
  font-size: 14px; font-weight: 600; cursor: pointer; user-select: none;
  transition: background .15s var(--ease), color .15s var(--ease), border-color .15s var(--ease);
}
.status-btn input { position: absolute; opacity: 0; width: 0; height: 0; }
.status-btn i { font-size: 18px; }
.status-btn:hover { border-color: var(--teal); color: var(--text); }
.status-btn.status-called:has(:checked)    { color: var(--blue);     border-color: var(--blue);  background: var(--blue-bg); }
.status-btn.status-paid:has(:checked)      { color: var(--green);    border-color: var(--green); background: var(--green-bg); }
.status-btn.status-collected:has(:checked) { color: var(--teal-dim); border-color: var(--teal);  background: var(--teal-subtle); }
/* Same glow treatment as the list's .status-toggle icons. */
.status-btn:has(:checked) {
  box-shadow: 0 0 12px color-mix(in srgb, currentColor 30%, transparent);
}
@media (max-width: 480px) { .detail-status-row { flex-wrap: wrap; } }

#confirm-overlay { position: fixed; inset: 0; z-index: 5000; align-items: center; justify-content: center; background: rgba(20,24,40,0.5); padding: 24px; }
.confirm-box { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 24px; max-width: 400px; width: 100%; }
.confirm-title { font-size: 19px; font-weight: 700; color: var(--text); margin: 0 0 8px; }
.confirm-msg { font-size: 15px; color: var(--text-secondary); line-height: 1.55; margin: 0 0 20px; }
.confirm-msg p { margin: 0 0 10px; }
/* Compile-batch dialog — opt-in row for jobs held for the next batch. */
.compile-held-row {
  display: flex; flex-direction: row; align-items: center; gap: 8px;
  font-size: 14px; color: var(--text);
  background: var(--surface-high); border: 1px solid var(--border);
  border-radius: 8px; padding: 9px 12px; margin-top: 4px;
  cursor: pointer;
}
.confirm-actions { display: flex; justify-content: flex-end; gap: 10px; }

/* --- Job list: "3/7 ready" per-job progress under the stage badge -- */
.stage-progress {
  display: flex; align-items: center; gap: 6px;
  margin-top: 5px; font-size: 11px; font-weight: 600; color: var(--text-muted);
}
.stage-progress-bar {
  display: inline-block; width: 38px; height: 5px; border-radius: 3px;
  background: var(--surface-high); overflow: hidden; flex-shrink: 0;
}
.stage-progress-bar > span { display: block; height: 100%; background: var(--green); border-radius: 3px; }

/* --- Setup / startup screens: soft daylight depth ----------- */
.setup-required, .startup-screen { box-shadow: var(--shadow-md); }
.confirmed-jobnumber { color: var(--teal-dim); }

/* --- Board: keep the touch kanban on-palette ---------------- */
/* Sticky column head needs an opaque fill so cards don't show through. */
.board-col-head { background: var(--surface-raised); }
.board-stage-chip:hover:not(:disabled) {
  border-color: var(--teal); color: var(--teal-dim); background: var(--teal-subtle);
}

/* -----------------------------------------------------------
   N. PREMIUM DATA-TABLE POLISH
   Long tables (Products, job lists) get sticky headers, quiet
   zebra striping and a smoother row hover so scanning thousands
   of rows feels like a proper data tool rather than a dump.
   ----------------------------------------------------------- */

/* Header rides along as you scroll the page body. An opaque tint +
   hairline shadow keep it legible over rows sliding underneath. */
.settings-table thead th,
.data-table thead th {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--surface-raised);
  box-shadow: inset 0 -1px 0 var(--border), 0 2px 6px -4px rgba(17,24,39,0.18);
}

/* Zebra striping — barely-there, just enough to trace a row across. */
.settings-table tbody tr:nth-child(even) td { background: rgba(99,102,241,0.022); }
.settings-table tbody tr {
  transition: background 0.14s var(--ease);
}
.settings-table tbody tr:hover td { background: var(--teal-subtle); }

/* The "N more not shown" cap row: calm, centred, non-clickable feel. */
.prod-cap-note td {
  text-align: center;
  font-size: 12px;
  padding: 12px 11px !important;
  background: var(--surface-raised) !important;
}
.prod-cap-note:hover td { background: var(--surface-raised) !important; }

/* Spot-price field sits flush and quiet until focused. */
.settings-table input.spot-price {
  padding: 6px 8px;
  font-size: 12.5px;
}

/* Markup table money fields — wide enough that the number and the number-
   input spinner never clip the value (e.g. "1234.56"). */
.markup-cell {
  width: 96px;
  box-sizing: border-box;
  text-align: right;
  font-variant-numeric: tabular-nums;
}
/* Frame-size fields on the markup page — equal width and baseline-aligned so
   the two "small / large" rows read level. */
.markup-size-input {
  width: 78px;
  box-sizing: border-box;
  vertical-align: middle;
  font-variant-numeric: tabular-nums;
}

/* Small/large frame-size config block on the Markup page — two aligned
   fields in a soft card so the inputs and labels line up cleanly. */
.markup-size-config {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 14px 24px;
  margin: 6px 0 18px;
  padding: 14px 16px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.msc-field  { display: flex; flex-direction: column; gap: 7px; }
.msc-label  {
  font-size: 12px; font-weight: 600; color: var(--text-secondary);
  display: flex; align-items: center; gap: 5px;
}
.msc-inputs {
  display: flex; align-items: center; gap: 7px;
  font-size: 13px; color: var(--text-secondary);
}
.msc-times  { color: var(--text-muted); }

/* Price-rounding row in Shop Details — two dropdowns and connective text on
   one baseline that wraps gracefully on narrow screens. */
.rounding-fields {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
}
.rounding-fields select { width: auto; }
.rounding-to { color: var(--text-secondary); font-size: 13px; }

/* Product count / status text reads as a soft caption. */
#product-count { font-size: 12px; font-weight: 500; }

/* -----------------------------------------------------------
   M. Respect reduced-motion preferences
   ----------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* -----------------------------------------------------------
   QUANTITY STEPPER — New Job frame drawer + print form
   Touch-friendly ± control, themed on the Aurora tokens.
   ----------------------------------------------------------- */
.fi-qty-block { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin: 16px 0 2px; }
.p-qty-field  { display: flex; align-items: center; gap: 12px; margin: 10px 0; }

.fi-qty-label {
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-secondary);
}

.qty-stepper {
  display: inline-flex; align-items: center;
  border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  overflow: hidden; background: var(--surface); box-shadow: var(--shadow);
}
.qty-btn {
  width: 40px; height: 40px; border: none; background: var(--surface-raised);
  color: var(--text); font-size: 22px; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.15s var(--ease), color 0.15s var(--ease);
}
.qty-btn:hover  { background: var(--teal-subtle); color: var(--teal-dim); }
.qty-btn:active { background: var(--teal-glow); }
.qty-input {
  width: 56px; height: 40px; border: none;
  border-left: 1px solid var(--border); border-right: 1px solid var(--border);
  text-align: center; font-size: 15px; font-weight: 600; color: var(--text);
  background: var(--surface); -moz-appearance: textfield;
}
.qty-input:focus { outline: none; background: var(--teal-subtle); }
.qty-input::-webkit-outer-spin-button,
.qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.fi-qty-total { font-size: 13px; color: var(--text-secondary); font-weight: 500; }
.fi-qty-total strong { color: var(--text); }
.fi-qty-hint { font-size: 12px; color: var(--text-muted); margin: 0 0 4px; }

/* Inline "×N" pill on item summary cards + the price breakdown tag */
.qty-badge {
  display: inline-block; margin-left: 4px; padding: 1px 8px; border-radius: 999px;
  background: var(--teal-subtle); color: var(--teal-dim);
  font-size: 12px; font-weight: 600; vertical-align: middle;
}
.qty-tag { color: var(--text-muted); font-weight: 500; font-size: 0.85em; }

/* -----------------------------------------------------------
   AUTH GATE + SETUP WIZARD (js/auth.js)
   ----------------------------------------------------------- */
body.auth-open { overflow: hidden; }
#auth-screen, #staff-screen {
  position: fixed; inset: 0; z-index: 3000;
  display: flex; align-items: center; justify-content: center;
  padding: 24px; overflow-y: auto;
  background:
    radial-gradient(120% 120% at 85% -10%, rgba(168,85,247,0.16), transparent 55%),
    radial-gradient(120% 120% at -10% 0%, rgba(99,102,241,0.18), transparent 55%),
    var(--bg);
}
#staff-screen { z-index: 3001; }

/* The customer-facing front door (Framer/Customer gate + order tracking)
   is always dark for a clean, branded look — independent of the shop's
   own in-app light/dark choice, which the customer never sets. */
#auth-screen {
  --bg: #0c0c14; --surface: #17171f; --surface-raised: #1e1e29; --surface-high: #272733;
  --border: rgba(255,255,255,0.09); --border-bright: rgba(255,255,255,0.17);
  --text: #f2f2f7; --text-secondary: #c2c2d2; --text-muted: #85859c;
  --teal: #6366f1; --teal-dim: #a5b4fc; --teal-muted: #4f46e5; --teal-subtle: rgba(99,102,241,0.16);
  --green: #22c55e; --amber: #f59e0b; --red: #f87171; --blue: #60a5fa; --purple: #c084fc;
  --shadow-lg: 0 32px 72px -18px rgba(0,0,0,0.65), 0 8px 24px -10px rgba(0,0,0,0.45);
  /* Dark glass for the card itself (hard-coded, not derived, so it can't
     fall back to the light surface). */
  --glass-bg: rgba(23,23,31,0.72); --glass-bg-strong: rgba(23,23,31,0.92);
  --glass-bg-opaque: rgba(23,23,31,0.97); --glass-border: rgba(255,255,255,0.12);
  --glass-edge: 0 0 0 1px rgba(0,0,0,0.35); --glass-inset: inset 0 1px 0 rgba(255,255,255,0.08);
}

.auth-card {
  width: 100%; max-width: 420px; margin: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: 34px 30px; text-align: center;
}
.auth-logo { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 20px; }
.auth-wordmark { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; color: var(--text); }
.auth-wordmark .accent { background: linear-gradient(120deg, var(--teal), var(--purple)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.auth-title { font-size: 23px; font-weight: 700; letter-spacing: -0.01em; margin: 0 0 6px; color: var(--text); }
.auth-sub { color: var(--text-secondary); margin: 0 0 22px; font-size: 15px; }

.auth-choices { display: flex; flex-direction: column; gap: 12px; }
.auth-choice {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 20px; border: 1px solid var(--border-bright); border-radius: var(--radius);
  background: var(--surface-raised); cursor: pointer; color: var(--text); font-family: inherit;
  transition: border-color .15s var(--ease), background .15s var(--ease), transform .1s var(--ease);
}
.auth-choice:hover { border-color: var(--teal); background: var(--teal-subtle); }
.auth-choice:active { transform: scale(.99); }
.auth-choice i { font-size: 26px; color: var(--teal-dim); }
.auth-choice-t { font-weight: 700; font-size: 16px; }
.auth-choice-s { font-size: 13px; color: var(--text-muted); }

.auth-field { text-align: left; margin-bottom: 14px; }
.auth-field label { display: block; font-size: 13px; font-weight: 600; color: var(--text-secondary); margin-bottom: 5px; }
.auth-opt { font-weight: 400; color: var(--text-muted); }
.auth-input {
  width: 100%; padding: 11px 13px; font-size: 15px;
  border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font-family: inherit;
}
.auth-input:focus { outline: none; border-color: var(--teal); box-shadow: 0 0 0 3px var(--teal-subtle); }

.auth-btn {
  width: 100%; padding: 12px 16px; font-size: 15px; font-weight: 600; font-family: inherit;
  border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-secondary); cursor: pointer;
  transition: background .15s var(--ease), border-color .15s var(--ease);
}
.auth-btn:hover { background: var(--surface-high); }
.auth-btn-primary {
  border: none; color: #fff;
  background: linear-gradient(120deg, var(--teal), var(--purple));
  box-shadow: 0 6px 18px -8px var(--teal-glow);
}
.auth-btn-primary:hover { filter: brightness(1.05); }
.auth-btn-primary:disabled { opacity: .7; cursor: default; }

.auth-error { display: none; color: var(--red); background: var(--red-bg); border-radius: var(--radius-sm); padding: 9px 12px; font-size: 13.5px; margin-bottom: 12px; text-align: left; }
.auth-link { background: none; border: none; color: var(--teal-dim); font-weight: 600; cursor: pointer; font-size: 14px; font-family: inherit; padding: 0; }
.auth-link:hover { text-decoration: underline; }
.auth-switch { margin: 16px 0 0; font-size: 14px; color: var(--text-secondary); }
.auth-back { display: inline-block; margin-top: 16px; color: var(--text-muted); }
.auth-note { font-size: 13.5px; color: var(--text-muted); margin: 4px 0 18px; text-align: left; }

.pin-dots { display: flex; justify-content: center; gap: 14px; margin: 6px 0 22px; }
.pin-dot {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--border-bright); background: transparent;
  transition: background .1s var(--ease), border-color .1s var(--ease);
}
.pin-dot.is-filled { background: var(--teal); border-color: var(--teal); }
.pin-dots.pin-shake { animation: pin-shake .32s var(--ease); }
@keyframes pin-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-8px); }
  40% { transform: translateX(8px); }
  60% { transform: translateX(-6px); }
  80% { transform: translateX(6px); }
}

.pin-keypad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-bottom: 8px; }
.pin-key {
  padding: 16px 0; font-size: 19px; font-weight: 600; font-family: inherit;
  border: 1px solid var(--border-bright); border-radius: var(--radius-sm);
  background: var(--surface-raised); color: var(--text); cursor: pointer;
  transition: background .15s var(--ease), border-color .15s var(--ease);
}
.pin-key:hover { border-color: var(--teal); background: var(--teal-subtle); }
.pin-key:active { transform: scale(.97); }
.pin-key-ghost { visibility: hidden; pointer-events: none; }
.pin-key-back { font-size: 16px; color: var(--text-muted); }

/* Shop's own logo at the top of the tracking result (replaces the
   FrameFlow mark when the shop enables it). */
.track-shop-logo { margin-bottom: 10px; }
.track-shop-logo img { max-width: 200px; max-height: 84px; object-fit: contain; }
.track-heading { font-size: 15px; font-weight: 600; color: var(--text-muted); margin: 0 0 18px; letter-spacing: 0.02em; }

/* Contact line at the base — a tidy stacked block instead of a run-on
   sentence, so phone + email don't wrap awkwardly. */
.track-contact {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  margin: 18px 0 6px; font-size: 14px; color: var(--text-muted);
}
.track-contact a { color: var(--teal-dim); text-decoration: none; font-weight: 600; }
.track-contact a:hover { text-decoration: underline; }

.track-status {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 16px; border-radius: 999px;
  background: color-mix(in srgb, var(--st-color) 12%, transparent);
  color: var(--st-color); font-weight: 600; font-size: 14px;
  margin: 0 auto 20px;
}
.track-status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--st-color); flex-shrink: 0; }
.track-progress {
  width: 100%; height: 8px; border-radius: 4px;
  background: var(--surface-high); overflow: hidden;
  margin: -12px 0 20px;
}
.track-progress > span { display: block; height: 100%; background: var(--amber); border-radius: 4px; transition: width 0.3s var(--ease); }
.track-details {
  text-align: left; display: flex; flex-direction: column; gap: 10px;
  padding: 16px; background: var(--surface-raised); border: 1px solid var(--border);
  border-radius: var(--radius); margin-bottom: 16px;
}
.track-details > div { display: flex; justify-content: space-between; gap: 12px; font-size: 14px; }
.track-details span { color: var(--text-muted); }
.track-details strong { color: var(--text); font-weight: 600; text-align: right; }

.wiz-card { max-width: 460px; }
.wiz-progress { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: 22px; flex-wrap: wrap; }
.wiz-dot { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--text-muted); white-space: nowrap; }
.wiz-dot span { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; background: var(--surface-high); color: var(--text-muted); font-size: 12px; }
.wiz-dot.is-on span { background: linear-gradient(135deg, var(--teal), var(--purple)); color: #fff; }
.wiz-dot.is-on { color: var(--text); }
.wiz-dot.is-done span { background: var(--teal-subtle); color: var(--teal-dim); }
.wiz-line { width: 16px; height: 1px; background: var(--border-bright); }
.wiz-body { text-align: left; }
.wiz-body .auth-title, .wiz-body .auth-sub { text-align: left; }
.wiz-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 20px; }
.wiz-actions .auth-btn { width: auto; padding: 11px 20px; }
.wiz-check { display: flex; align-items: center; gap: 9px; font-size: 14.5px; color: var(--text); margin: 4px 0 14px; cursor: pointer; }
.wiz-check input { width: 17px; height: 17px; accent-color: var(--teal); }

.sidebar-user { display: flex; align-items: center; gap: 8px; padding: 8px 20px 14px; }
.sidebar-user-email { flex: 1; min-width: 0; font-size: 12px; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-logout { flex: none; width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border); background: var(--surface); color: var(--text-secondary); cursor: pointer; display: grid; place-items: center; font-size: 16px; }
.sidebar-logout:hover { background: var(--red-bg); color: var(--red); border-color: var(--red-bg); }
@media (max-width: 600px) {
  /* Placed after the base .sidebar-user rule above on purpose — an earlier
     copy of this same override, inside the main mobile media-query block,
     was losing the cascade to that unconditional rule since a media query
     doesn't add specificity, only a later position in the file wins. */
  .sidebar-user { display: none; }
}

@media (max-width: 480px) { .auth-card { padding: 26px 20px; } }

/* -----------------------------------------------------------
   TO ORDER — rolling materials order list (js/toorder.js)
   ----------------------------------------------------------- */
.toorder-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 18px; flex-wrap: wrap; }
.toorder-title { margin: 0 0 2px; }
.order-supplier { margin-bottom: 18px; border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow); }
.order-supplier-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 11px 15px; background: var(--surface-raised); border-bottom: 1px solid var(--border); }
.order-sup-check { display: flex; align-items: center; gap: 9px; font-weight: 700; font-size: 15px; color: var(--text); cursor: pointer; }
.order-sup-check input, .order-check { width: 17px; height: 17px; accent-color: var(--teal); cursor: pointer; }
.order-table { margin: 0; }
.order-table td { vertical-align: middle; }
.order-check-cell { width: 44px; text-align: center; }
.order-qty { white-space: nowrap; font-variant-numeric: tabular-nums; }
.order-jobs { font-size: 13px; }
.order-code { white-space: nowrap; }
.order-sizes { display: flex; flex-direction: column; gap: 3px; }
.order-size { font-variant-numeric: tabular-nums; }
.sheet-head { margin: 28px 0 12px; }
.sheet-head h3 { margin: 0 0 2px; }
.order-sup-name { font-weight: 700; font-size: 15px; color: var(--text); }
.board-card-ordered { display: inline-flex; align-items: center; gap: 4px; margin-top: 5px; font-size: 11px; font-weight: 600; color: var(--green); background: var(--green-bg); padding: 2px 8px; border-radius: 999px; }

/* =============================================================
   LIQUID GLASS LAYER
   -------------------------------------------------------------
   Apple-style "liquid glass": frosted, translucent surfaces with
   a specular top highlight, floating over the fixed aurora wash
   (body::before, Aurora layer A). Everything reads the --glass-*
   tokens defined up in :root / the dark block, so both themes
   share one recipe. Ordered after every other layer on purpose —
   these are cascade overrides, same trick as the Aurora layer.
   ============================================================= */

/* --- 1. Let the aurora show through the app shell ------------ */
#main-content { background: transparent; }

/* --- 2. Chrome: sidebar + page header ------------------------ */
#sidebar {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-right: 1px solid var(--glass-border);
  box-shadow: var(--glass-edge);
}
#page-header {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid var(--glass-border);
  box-shadow: var(--glass-edge);
}
/* Mobile dropdown nav rides over page content. It lives INSIDE #sidebar,
   which already has backdrop-filter — a nested backdrop-filter can't frost
   the page behind it (the blur no-ops), so translucency here was pure
   ghosting: page text showed through the menu. Near-solid instead; the
   border + shadow keep the glass look. */
@media (max-width: 600px) {
  .nav-list {
    background: var(--glass-bg-opaque);
    box-shadow: var(--glass-inset), var(--shadow-lg);
  }
}

/* --- 3. Content panels: one shared glass recipe --------------- */
.card,
.table-wrap,
.dashboard-table-wrap,
.settings-content,
.joblist-toolbar,
.batch-sidebar,
.batch-main,
.order-supplier,
.board-col {
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur-soft);
  -webkit-backdrop-filter: var(--glass-blur-soft);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-inset), var(--glass-edge), var(--shadow);
}
/* Tables inside glass panels shouldn't repaint them opaque. */
.data-table { background: transparent; }
.data-table th { background: transparent; }
/* Sticky headers blur the rows sliding beneath them — the one spot the
   glass effect is functional, not just decorative. */
.settings-table thead th,
.data-table thead th {
  background: color-mix(in srgb, var(--surface-raised) 76%, transparent);
  backdrop-filter: var(--glass-blur-soft);
  -webkit-backdrop-filter: var(--glass-blur-soft);
}
.table-footer { background: transparent; }
.board-col-head {
  background: color-mix(in srgb, var(--surface-raised) 72%, transparent);
  backdrop-filter: var(--glass-blur-soft);
  -webkit-backdrop-filter: var(--glass-blur-soft);
}

/* --- 4. Floating surfaces: modal, drawer, confirm, toasts, menus.
   More opaque than the panels — these carry dense text and sit over
   arbitrary content, so legibility wins over transparency. -------- */
#modal-box,
.drawer,
.confirm-box,
.toast,
.board-bulkbar,
.auth-card,
.setup-required,
.startup-screen {
  background: var(--glass-bg-strong);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-inset), var(--glass-edge), var(--shadow-lg);
}
.toast { box-shadow: var(--glass-inset), var(--glass-edge), var(--shadow-md); }
/* Autocomplete pick-lists sit inside glass cards, where a nested
   backdrop-filter can't frost what's behind (see --glass-bg-opaque note in
   :root) — and you pick options from them, so legibility wins outright. */
.ac-dropdown, .code-ac-dropdown {
  background: var(--glass-bg-opaque);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-inset), var(--glass-edge), var(--shadow-md);
}
/* Pinned drawer/modal footers repainted opaque — let the glass through. */
.drawer-footer, #modal-footer { background: transparent; }

/* Loading scrim — frosted in the page's own tone, not a hard black. */
#loading-spinner {
  background: color-mix(in srgb, var(--bg) 45%, transparent);
  backdrop-filter: blur(8px) saturate(140%);
  -webkit-backdrop-filter: blur(8px) saturate(140%);
}

/* --- 5. Controls: capsule buttons with a specular highlight ---- */
.btn { border-radius: 999px; }
.btn-sm, .btn-lg { border-radius: 999px; }
.btn-primary {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35),
              0 4px 14px -4px rgba(99,102,241,0.55);
}
.btn-primary:hover {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4),
              0 10px 24px -6px rgba(99,102,241,0.6);
}
.btn-secondary {
  background: var(--glass-bg-strong);
  backdrop-filter: var(--glass-blur-soft);
  -webkit-backdrop-filter: var(--glass-blur-soft);
  border-color: var(--glass-border);
  box-shadow: var(--glass-inset), var(--glass-edge);
}
.btn-secondary:hover { background: var(--surface-high); }
#fab-new-job {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.4),
              0 14px 32px -10px rgba(99,102,241,0.65), var(--shadow-md);
}
.nav-item-cta, .nav-item-cta:hover, .nav-item-cta.active {
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.35),
              0 8px 20px -6px rgba(99,102,241,0.5);
}
/* Inputs stay near-solid (form legibility), just softened corners. */
input[type="text"], input[type="number"], input[type="tel"],
input[type="email"], input[type="date"], input[type="search"],
select, textarea { border-radius: 12px; }

/* --- 6. Dashboard stat panel — retune to the shared tokens ----- */
.stat-cards-wrap {
  border: 1px solid var(--glass-border);
  background: color-mix(in srgb, var(--surface) 30%, transparent);
  box-shadow: var(--glass-edge);
}
.stat-card {
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-inset), var(--glass-edge), var(--shadow);
}
html[data-theme="dark"] .stat-card::before {
  background: linear-gradient(115deg, transparent 30%, rgba(255,255,255,0.10) 48%, transparent 65%);
}

/* --- 7. Quiet glass on the pill chips ------------------------- */
.quick-filter, .qf-saved, .date-filter-btn {
  background: var(--glass-bg-strong);
  backdrop-filter: var(--glass-blur-soft);
  -webkit-backdrop-filter: var(--glass-blur-soft);
}
.qf-saved.active { background: var(--chip-bg); }

/* Tab bars sit directly on the aurora — no opaque strip behind them. */
.tab-bar { background: transparent; }

/* --- 8. Accessibility + print safety nets --------------------- */
/* Users who ask the OS for less transparency get solid surfaces. */
@media (prefers-reduced-transparency: reduce) {
  :root, html[data-theme="dark"] {
    --glass-bg:        var(--surface);
    --glass-bg-strong: var(--surface);
    --glass-bg-opaque: var(--surface);
    --glass-blur:      none;
    --glass-blur-soft: none;
    --glass-border:    var(--border);
  }
}
@media print {
  body::before { display: none; }
  .card, .table-wrap, .dashboard-table-wrap { background: #fff; box-shadow: none; }
}
