/* ============================================================
   تابلي (Tabli) — Universal Token Design System (RTL / Arabic-first)
   Light theme only (dark-mode media query intentionally removed).
   Shared stylesheet for all mockup pages.
   ============================================================ */

:root {
  /* surfaces */
  --bg: #f6f7f9;
  --surface: #eef0f3;
  --surface-deep: #e3e6eb;
  --card: #ffffff;
  --popover: #ffffff;
  --border: #e2e4ea;

  /* text */
  --text-primary: #16181d;
  --text-secondary: #5b606e;
  --text-muted: #8b909c;
  --text-faint: #aeb3bd;
  --text-inverse: #ffffff;

  /* accents */
  --accent-primary: #5b6df8;
  --accent-secondary: #8a5cf6;
  --accent-tertiary: #2a9fd6;
  --accent-foreground: #ffffff;
  --highlight: #d99a1b;
  --segment-1: #16a673;
  --segment-2: #e0506b;

  --destructive: #e0506b;
  --destructive-foreground: #ffffff;
  --success: #16a673;
  --success-foreground: #ffffff;

  --gradient-brand: linear-gradient(135deg, #6d7cfb 0%, #8a5cf6 100%);
  --gradient-premium: linear-gradient(135deg, #8a5cf6 0%, #d99a1b 100%);

  /* shadows (flat, token-driven — no neumorphic inset/raised pairing) */
  --shadow-button: 0 2px 8px rgba(91, 109, 248, .35);
  --shadow-card: 0 1px 2px rgba(20, 22, 28, .04), 0 6px 16px rgba(20, 22, 28, .05);
  --shadow-card-hover: 0 10px 28px rgba(20, 22, 28, .10);
  --shadow-float: 0 16px 40px rgba(20, 22, 28, .16);
  --shadow-mockup: 0 28px 64px rgba(20, 22, 28, .22);
  --shadow-ring: 0 0 0 3px color-mix(in srgb, var(--accent-primary) 18%, transparent);

  /* radii */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 12px;
  --radius-xl: 16px;

  --sidebar-w: 282px;
  --content-max: 1240px;

  --ease: cubic-bezier(.4, 0, .2, 1);
  --ease-spring: cubic-bezier(.34, 1.56, .64, 1);
  --dur-fast: .15s;
  --dur: .25s;
  --dur-slow: .45s;

  /* legacy token aliases (kept so existing inline var() references resolve through the new system) */
  --primary: var(--accent-primary);
  --info: var(--accent-tertiary);
  --warning: var(--highlight);
  --danger: var(--destructive);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text-primary);
  font-family: "Cairo", "Segoe UI", sans-serif;
  font-weight: 400;
  direction: rtl;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4, p { margin: 0; font-weight: 500; }
b, strong { font-weight: 500; }
::selection { background: var(--accent-primary); color: var(--accent-foreground); }

/* ---------- Scrollbar polish ---------- */
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-faint); }

/* ============================================================
   Motion system
   ============================================================ */

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
  from { opacity: 0; } to { opacity: 1; }
}
@keyframes scaleIn {
  from { opacity: 0; transform: scale(.96); } to { opacity: 1; transform: scale(1); }
}
@keyframes shimmer {
  0% { background-position: -300px 0; } 100% { background-position: 300px 0; }
}
@keyframes pulseDot {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--destructive) 45%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--destructive) 0%, transparent); }
}
@keyframes spin { to { transform: rotate(360deg); } }

body { animation: fadeIn var(--dur-slow) var(--ease); }

/* fill-mode was `both` (not `backwards`) until a live bug was found: fadeInUp's
   final keyframe sets `transform: translateY(0)` — a non-`none` value even
   though it's visually an identity transform — and `both` makes that persist
   forever after the animation ends (that's what `forwards`/`both` mean). Per
   the CSS spec, ANY non-`none` transform on an element makes it a new
   containing block for `position: fixed`/`absolute` descendants — so every
   direct child of `.main`/`.grid` silently became a fixed-position containing
   block once its entrance animation finished, breaking every full-screen
   `position: fixed` modal overlay nested inside one (e.g. the branch
   create/edit card, the product create/edit modal) — the modal centered
   itself against that small child's own box instead of the real viewport,
   clipping its top off-screen. `backwards` still holds the FROM keyframe
   during `animation-delay` (unchanged entrance behavior) but does not persist
   the TO keyframe's transform after the animation ends, so `transform`
   reverts to its unanimated value (`none`) once the fade-in completes. */
.animate-fade-up,
.main > * { animation: fadeInUp var(--dur-slow) var(--ease-spring) backwards; }
.main > *:nth-child(1) { animation-delay: .02s; }
.main > *:nth-child(2) { animation-delay: .06s; }
.main > *:nth-child(3) { animation-delay: .1s; }
.main > *:nth-child(4) { animation-delay: .14s; }
.main > *:nth-child(5) { animation-delay: .18s; }
.main > *:nth-child(n+6) { animation-delay: .22s; }

.grid > * { animation: fadeInUp var(--dur) var(--ease-spring) backwards; }
.grid > *:nth-child(1) { animation-delay: .04s; }
.grid > *:nth-child(2) { animation-delay: .08s; }
.grid > *:nth-child(3) { animation-delay: .12s; }
.grid > *:nth-child(4) { animation-delay: .16s; }
.grid > *:nth-child(5) { animation-delay: .2s; }
.grid > *:nth-child(6) { animation-delay: .24s; }
.grid > *:nth-child(n+7) { animation-delay: .28s; }

.nav-link, .btn, .card, .stat-card, .feature-card, .price-card, table.data-table tr,
.toggle, .progress-bar, .input, .select, .textarea, .pill-tab, .dropdown-menu, .badge {
  transition: box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease),
              background var(--dur) var(--ease), color var(--dur) var(--ease),
              opacity var(--dur) var(--ease), border-color var(--dur) var(--ease);
}

/* Hover-lift: the standard hover treatment for primary CTAs and raised cards */
.hover-lift:hover,
.btn-primary:hover,
.card.neu-raised:hover,
.stat-card.neu-raised:hover,
.feature-card.neu-raised:hover,
.price-card.neu-raised:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-card-hover);
}

/* Animated underline on links */
.link-underline {
  position: relative;
  padding-bottom: 2px;
}
.link-underline::after {
  content: "";
  position: absolute; bottom: 0; right: 0; left: 0; height: 1.5px; border-radius: 2px;
  background: var(--accent-primary); transform: scaleX(0); transform-origin: right;
  transition: transform var(--dur) var(--ease-spring);
}
.link-underline:hover::after { transform: scaleX(1); }

.skeleton {
  background: linear-gradient(90deg, var(--surface) 25%, var(--surface-deep) 37%, var(--surface) 63%);
  background-size: 400px 100%;
  animation: shimmer 1.4s ease infinite;
  border-radius: var(--radius-md);
}

.spinner {
  width: 18px; height: 18px; border-radius: 50%;
  border: 2.5px solid color-mix(in srgb, var(--accent-foreground) 40%, transparent); border-top-color: var(--accent-foreground);
  animation: spin .7s linear infinite; display: inline-block;
}

/* ---------- Surfaces (flat token system; class names kept stable for markup compatibility) ---------- */

.neu-raised, .bg-card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
}
.neu-inset, .bg-surface {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.neu-flat, .bg-surface-deep {
  background: var(--surface-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.bg-popover { background: var(--popover); border: 1px solid var(--border); }

.card {
  padding: 26px;
  will-change: transform;
}

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

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--text-primary);
  font-weight: 500;
  font-size: 13px;
  font-family: inherit;
  cursor: pointer;
}
.btn:hover { background: var(--surface-deep); }
.btn:active, .btn.is-active { background: var(--surface-deep); }
.btn-primary { background: var(--accent-primary); color: var(--accent-foreground); border-color: transparent; box-shadow: var(--shadow-button); }
.btn-primary:hover { filter: brightness(1.06); }
.btn-danger { background: var(--destructive); color: var(--destructive-foreground); border-color: transparent; }
.btn-danger:hover { opacity: .9; }
.btn-success { background: var(--success); color: var(--success-foreground); border-color: transparent; }
.btn-success:hover { opacity: .9; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--text-secondary); }
.btn-ghost:hover { background: var(--surface); color: var(--text-primary); }
.btn-sm { padding: 6px 12px; font-size: 12.5px; }
.btn-lg { padding: 12px 22px; font-size: 14px; }
.btn-block { width: 100%; }
.btn-icon { width: 42px; height: 42px; padding: 0; border-radius: 50%; }
.btn[disabled] { opacity: .5; cursor: not-allowed; transform: none !important; }

/* ---------- Forms ---------- */

.field { margin-bottom: 18px; }
.field label {
  display: block;
  font-size: 13px;
  font-weight: 500;
  color: var(--text-secondary);
  margin-bottom: 8px;
}
.input, .select, .textarea {
  width: 100%;
  border: 1px solid var(--border);
  outline: none;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 400;
  font-family: inherit;
}
.input:focus, .select:focus, .textarea:focus {
  border-color: var(--accent-primary);
  box-shadow: var(--shadow-ring);
}
.textarea { resize: vertical; min-height: 90px; }
.field-hint { font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.field-internal { border: 1px dashed var(--highlight); }
.field-internal-tag {
  display: inline-block; font-size: 11px; background: var(--highlight); color: var(--text-inverse);
  padding: 2px 8px; border-radius: var(--radius-sm); margin-right: 8px; vertical-align: middle; font-weight: 500;
}

.search-input { position: relative; }
.search-input input { padding-right: 42px; }
.search-input .ic {
  position: absolute; right: 14px; top: 50%; transform: translateY(-50%); color: var(--text-faint); font-size: 14px;
}

.toggle { position: relative; width: 48px; height: 26px; border-radius: 20px; cursor: pointer; background: var(--surface-deep); border: 1px solid var(--border); }
.toggle::after {
  content: ""; position: absolute; top: 2px; right: 2px; width: 20px; height: 20px;
  border-radius: 50%; background: var(--card); box-shadow: var(--shadow-card);
  transition: right var(--dur) var(--ease-spring), left var(--dur) var(--ease-spring);
}
.toggle.on { background: var(--gradient-brand); border-color: transparent; }
.toggle.on::after { right: 24px; background: var(--accent-foreground); }

/* ---------- Layout shells ---------- */

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

.sidebar {
  width: var(--sidebar-w);
  flex-shrink: 0;
  background: var(--card);
  border-left: 1px solid var(--border);
  padding: 26px 18px;
  display: flex;
  flex-direction: column;
  gap: 22px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  z-index: 20;
}

.sidebar .brand {
  display: flex; align-items: center; gap: 12px; padding: 6px 10px 18px;
  border-bottom: 1px solid var(--border);
}
/* Wraps just the logo+name+role-tag (not the notification bell) so the
   mobile drawer breakpoint below can center this group independently —
   a plain flex row identical to .brand's own previous layout, so desktop
   appearance is unchanged (this rule only becomes visually different
   from before once the mobile override below adds absolute positioning). */
.sidebar .brand-identity { display: flex; align-items: center; gap: 12px; }
.sidebar .brand .logo {
  width: 44px; height: 44px; border-radius: var(--radius-lg); background: var(--gradient-brand);
  display: flex; align-items: center; justify-content: center; color: var(--accent-foreground); font-weight: 500;
}
.sidebar .brand .name { font-weight: 500; font-size: 16px; }
.sidebar .brand .role-tag { font-size: 11px; color: var(--text-muted); }
/* Optional Super-Admin-editable secondary tagline (tenancy.
   platform_branding_config.tagline_text) — a smaller subtitle directly
   beneath the main logo+wordmark, the one place this field previously had
   no display location at all despite being saveable in the branding form. */
.sidebar .brand .tagline,
.mobile-header-bar .tagline { font-size: 10.5px; color: var(--text-muted); margin-top: 1px; }

/* Wordmark ("تابلي") — sidebar brand name, auth logo-row, marketing nav */
.sidebar .brand .name,
.logo-row strong,
.mkt-nav > .flex.items-center.gap-12 > strong {
  font-family: "Reem Kufi", "Cairo", sans-serif;
  font-weight: 700;
}

.nav-group { display: flex; flex-direction: column; gap: 4px; }
.nav-group .group-label {
  font-size: 11px; color: var(--text-faint); font-weight: 500; padding: 14px 12px 4px;
  text-transform: uppercase; letter-spacing: .6px;
}
.nav-link {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-radius: var(--radius-md);
  font-size: 13.5px; font-weight: 400; color: var(--text-secondary); position: relative;
}
.nav-link .ic { width: 22px; text-align: center; transition: transform var(--dur) var(--ease-spring); }
.nav-link .nav-badge {
  margin-right: auto; font-size: 11px; font-weight: 500; background: var(--destructive); color: var(--destructive-foreground);
  border-radius: 10px; padding: 1px 7px;
}
.nav-link:hover { color: var(--text-primary); background: var(--surface); }
.nav-link.active {
  color: var(--accent-primary);
  background: var(--surface);
  font-weight: 500;
}
.nav-link.active::before {
  content: ""; position: absolute; right: -18px; top: 50%; translate: 0 -50%;
  width: 3px; height: 60%; border-radius: 4px; background: var(--gradient-brand);
}

.sidebar-footer { margin-top: auto; padding-top: 14px; border-top: 1px solid var(--border); display: flex; flex-direction: column; gap: 12px; }
.user-card {
  display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: var(--radius-md); cursor: pointer;
}
.user-card:hover { background: var(--surface); }
.user-card .meta { flex: 1; min-width: 0; }
.user-card .meta strong { display: block; font-size: 13.5px; font-weight: 500; }
.user-card .meta span { display: block; font-size: 11.5px; color: var(--text-muted); }
.user-card .chev { color: var(--text-faint); font-size: 12px; }

.main {
  flex: 1;
  min-width: 0;
  padding: 24px 32px 70px;
  display: flex;
  flex-direction: column;
  gap: 22px;
}

/* Full-bleed shell with centered 1240px content grid:
   topbar stays edge-to-edge across .main; every other direct
   child of .main is capped + centered for readability. */
.main > *:not(.topbar) {
  width: 100%;
  max-width: var(--content-max);
  margin-left: auto;
  margin-right: auto;
}

.topbar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 26px; gap: 24px;
  position: sticky; top: 14px; z-index: 15;
  background: var(--card);
  backdrop-filter: blur(6px);
}
.topbar .title h1 { font-size: 20px; font-weight: 500; letter-spacing: -.2px; }
.topbar .title .breadcrumb { font-size: 12px; color: var(--text-muted); margin-top: 5px; }
.topbar .title .breadcrumb a { color: var(--text-muted); }
.topbar .title .breadcrumb a:hover { color: var(--accent-primary); }
.topbar .actions { display: flex; align-items: center; gap: 14px; }
.topbar .tb-search { width: 240px; }
.topbar .tb-search .input { padding: 10px 42px 10px 16px; }

.avatar { width: 42px; height: 42px; border-radius: 50%; background: var(--gradient-brand); color: var(--accent-foreground); display: flex; align-items: center; justify-content: center; font-weight: 500; }
.avatar-sm { width: 32px; height: 32px; font-size: 12px; }

.icon-btn { position: relative; width: 42px; height: 42px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; background: var(--surface); border: 1px solid var(--border); font-size: 16px; }
.icon-btn:hover { background: var(--surface-deep); }
.icon-btn .dot { position: absolute; top: 8px; left: 8px; width: 9px; height: 9px; border-radius: 50%; background: var(--destructive); animation: pulseDot 1.8s ease infinite; }

/* ---------- Dropdown / popover ---------- */

.dropdown { position: relative; }
.dropdown-menu {
  position: absolute; left: 0; top: calc(100% + 12px); width: 290px;
  background: var(--popover); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow-float);
  padding: 10px; z-index: 30; animation: scaleIn var(--dur) var(--ease-spring) both;
  transform-origin: top left;
}
.dropdown-menu.wide { width: 340px; }
.dropdown-menu .dd-header { padding: 10px 12px; font-size: 13px; font-weight: 500; display: flex; justify-content: space-between; align-items: center; }
.dropdown-menu .dd-header a { font-size: 12px; color: var(--accent-primary); font-weight: 500; }
.dropdown-item { display: flex; gap: 12px; align-items: flex-start; padding: 10px 12px; border-radius: var(--radius-sm); }
.dropdown-item:hover { background: var(--surface); }
.dropdown-item .ic { font-size: 16px; margin-top: 1px; }
.dropdown-item .meta strong { display: block; font-size: 13px; font-weight: 500; }
.dropdown-item .meta span { display: block; font-size: 11.5px; color: var(--text-muted); margin-top: 2px; }
.dropdown-divider { height: 1px; background: var(--border); margin: 6px 4px; }

/* ---------- Grids / stat cards ---------- */

.grid { display: grid; gap: 22px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-5 { grid-template-columns: repeat(5, 1fr); }

.stat-card { padding: 24px; display: flex; flex-direction: column; gap: 10px; position: relative; overflow: hidden; }
.stat-card .label { font-size: 13px; color: var(--text-muted); font-weight: 500; }
.stat-card .value { font-size: 27px; font-weight: 500; letter-spacing: -.3px; font-family: "Bricolage Grotesque", monospace; }
.stat-card .delta { font-size: 12px; font-weight: 500; display: inline-flex; align-items: center; gap: 4px; }
.stat-card .delta.up { color: var(--success); }
.stat-card .delta.down { color: var(--destructive); }
.stat-card .icon-badge {
  width: 46px; height: 46px; border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center;
  font-size: 20px; background: var(--surface); border: 1px solid var(--border);
}
.stat-card .mini-chart { display: flex; align-items: flex-end; gap: 4px; height: 30px; margin-top: 4px; }
.stat-card .mini-chart span { flex: 1; background: var(--accent-primary); opacity: .35; border-radius: 3px; }

/* ---------- Badges / status pills (token tints via color-mix, auto light/dark) ---------- */

.badge {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 20px;
  font-size: 12px; font-weight: 500;
}
.badge-dot { width: 7px; height: 7px; border-radius: 50%; }
.badge-pending { background: color-mix(in srgb, var(--highlight) 16%, transparent); color: var(--highlight); }
.badge-pending .badge-dot { background: var(--highlight); }
.badge-kitchen { background: color-mix(in srgb, var(--accent-secondary) 16%, transparent); color: var(--accent-secondary); }
.badge-kitchen .badge-dot { background: var(--accent-secondary); }
.badge-delivery { background: color-mix(in srgb, var(--accent-tertiary) 16%, transparent); color: var(--accent-tertiary); }
.badge-delivery .badge-dot { background: var(--accent-tertiary); }
.badge-delivered { background: color-mix(in srgb, var(--success) 16%, transparent); color: var(--success); }
.badge-delivered .badge-dot { background: var(--success); }
.badge-canceled { background: color-mix(in srgb, var(--destructive) 16%, transparent); color: var(--destructive); }
.badge-canceled .badge-dot { background: var(--destructive); }
.badge-muted { background: var(--surface-deep); color: var(--text-muted); }

/* ---------- Tabs / breadcrumb pill ---------- */

.tabs { display: flex; gap: 4px; padding: 4px; border-radius: var(--radius-lg); background: var(--surface); border: 1px solid var(--border); width: fit-content; }
.tabs .tab { padding: 8px 16px; border-radius: var(--radius-md); font-size: 13px; font-weight: 500; color: var(--text-muted); cursor: pointer; }
.tabs .tab.active { background: var(--card); color: var(--accent-primary); box-shadow: var(--shadow-card); }

.crumb-pills { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-muted); flex-wrap: wrap; }
.crumb-pills a { padding: 4px 10px; border-radius: var(--radius-sm); }
.crumb-pills a:hover { background: var(--surface); color: var(--accent-primary); }
.crumb-pills .sep { opacity: .5; }
.crumb-pills .current { color: var(--text-primary); font-weight: 500; }

/* ---------- Toolbar (filters / search / bulk actions) ---------- */

.toolbar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap; padding: 16px 20px;
}
.toolbar .grow { flex: 1; min-width: 200px; }
.toolbar .select, .toolbar .input { width: auto; min-width: 160px; }
.bulk-bar {
  display: flex; align-items: center; justify-content: space-between; padding: 14px 20px;
  background: color-mix(in srgb, var(--accent-primary) 8%, transparent);
  border: 1px dashed var(--accent-primary); border-radius: var(--radius-lg);
}

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

.table-wrap { overflow-x: auto; }
table.data-table { width: 100%; border-collapse: collapse; }
table.data-table th {
  text-align: right; font-size: 11.5px; color: var(--text-muted); font-weight: 500;
  padding: 12px 16px; border-bottom: 1px solid var(--border); text-transform: uppercase; letter-spacing: .3px;
  position: sticky; top: 0; background: var(--card);
}
table.data-table th.checkbox-col, table.data-table td.checkbox-col { width: 36px; }
table.data-table td {
  padding: 14px 16px; font-size: 13.5px; font-weight: 400; border-bottom: 1px solid var(--border);
}
table.data-table tr:last-child td { border-bottom: none; }
table.data-table tr:hover td { background: var(--surface); }
table.data-table .row-sub { font-size: 12px; color: var(--text-muted); margin-top: 3px; }

.pagination { display: flex; align-items: center; justify-content: space-between; padding: 16px 4px 4px; }
.pagination .pages { display: flex; gap: 6px; }
.pagination .page-btn {
  width: 34px; height: 34px; border-radius: var(--radius-md); display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 500; color: var(--text-muted); background: var(--surface); border: 1px solid var(--border); cursor: pointer;
}
.pagination .page-btn.active { color: var(--accent-foreground); background: var(--accent-primary); border-color: transparent; }

/* ---------- Progress / limit usage ---------- */

.progress { height: 10px; border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-deep); }
.progress-bar { height: 100%; background: var(--accent-primary); border-radius: var(--radius-sm); transition: width .6s var(--ease-spring); }
.progress-bar.warn { background: var(--highlight); }
.progress-bar.danger { background: var(--destructive); }

/* ---------- Spacing rhythm ---------- */

.py-10 { padding-top: 40px; padding-bottom: 40px; }
.py-7 { padding-top: 28px; padding-bottom: 28px; }
.space-y-4 > * + * { margin-top: 16px; }
.gap-6 { gap: 24px; }
.gap-8 { gap: 32px; }
@media (min-width: 768px) {
  .md\:py-14 { padding-top: 56px; padding-bottom: 56px; }
  .md\:py-10 { padding-top: 40px; padding-bottom: 40px; }
}

/* ---------- Misc ---------- */

.flex { display: flex; }
.flex-col { display: flex; flex-direction: column; }
.flex-wrap { flex-wrap: wrap; }
.items-center { align-items: center; }
.items-start { align-items: flex-start; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.gap-8 { gap: 8px; }
.gap-12 { gap: 12px; }
.gap-16 { gap: 16px; }
.gap-20 { gap: 20px; }
.mt-8 { margin-top: 8px; }
.mt-16 { margin-top: 16px; }
.mt-24 { margin-top: 24px; }
.mb-16 { margin-bottom: 16px; }
.text-primary { color: var(--text-primary); }
.text-secondary { color: var(--text-secondary); }
.text-muted { color: var(--text-muted); }
.text-faint { color: var(--text-faint); }
.text-inverse { color: var(--text-inverse); }
.text-accent-primary { color: var(--accent-primary); }
.text-destructive { color: var(--destructive); }
.font-mono { font-family: "Bricolage Grotesque", monospace; font-variant-numeric: tabular-nums; }
.text-sm { font-size: 13px; }
.text-xs { font-size: 11.5px; }
.text-center { text-align: center; }
.w-full { width: 100%; }
.rounded-md { border-radius: var(--radius-sm); }
.rounded-xl { border-radius: var(--radius-lg); }
.rounded-2xl { border-radius: var(--radius-xl); }
.shadow-button { box-shadow: var(--shadow-button); }
.shadow-card { box-shadow: var(--shadow-card); }
.shadow-card-hover { box-shadow: var(--shadow-card-hover); }
.shadow-float { box-shadow: var(--shadow-float); }
.shadow-mockup { box-shadow: var(--shadow-mockup); }
.bg-accent-primary { background: var(--accent-primary); }
.bg-gradient-brand { background: var(--gradient-brand); }
.bg-gradient-premium { background: var(--gradient-premium); }
.bg-destructive { background: var(--destructive); }
.section-title { font-size: 16px; font-weight: 500; margin-bottom: 4px; letter-spacing: -.1px; }
.section-sub { font-size: 13px; color: var(--text-muted); margin-bottom: 18px; }
.divider { height: 1px; background: var(--border); margin: 20px 0; }
.empty-state { text-align: center; padding: 60px 20px; color: var(--text-muted); }
.empty-state .ic { font-size: 38px; margin-bottom: 14px; opacity: .6; }
.pill-tabs { display: flex; gap: 8px; flex-wrap: wrap; }
.pill-tab { padding: 8px 16px; border-radius: 30px; font-size: 13px; font-weight: 500; color: var(--text-muted); cursor: pointer; background: var(--surface); border: 1px solid var(--border); }
.pill-tab.active { background: var(--accent-primary); color: var(--accent-foreground); border-color: transparent; }
.pill-tab:hover:not(.active) { background: var(--surface-deep); }

.qr-box {
  width: 160px; height: 160px; border-radius: var(--radius-lg);
  background: repeating-linear-gradient(45deg, var(--surface-deep) 0 8px, var(--surface) 8px 16px);
  border: 1px solid var(--border);
  display: flex; align-items: center; justify-content: center; color: var(--text-muted); font-size: 12px; font-weight: 500;
}

.mockup-note {
  position: fixed; bottom: 14px; left: 14px; z-index: 50;
  background: var(--text-primary); color: var(--bg); font-size: 11px; padding: 8px 14px; border-radius: var(--radius-md); opacity: .85;
}

.kbd { font-size: 11px; font-weight: 500; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 2px 6px; color: var(--text-muted); }

/* ---------- Ambient / glow / glass treatments (modern SaaS surface language) ---------- */

.bg-ambient { position: relative; isolation: isolate; overflow: hidden; }
.bg-ambient::before, .bg-ambient::after {
  content: ""; position: absolute; z-index: -1; border-radius: 50%; filter: blur(70px); pointer-events: none;
}
.bg-ambient::before {
  width: 520px; height: 520px; top: -180px; left: -120px;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-primary) 35%, transparent) 0%, transparent 70%);
}
.bg-ambient::after {
  width: 420px; height: 420px; bottom: -160px; right: -100px;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent-secondary) 30%, transparent) 0%, transparent 70%);
}

.gradient-text {
  background: var(--gradient-brand);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--accent-primary);
}

.glass {
  background: color-mix(in srgb, var(--card) 72%, transparent);
  backdrop-filter: blur(14px);
  border: 1px solid color-mix(in srgb, var(--border) 70%, transparent);
}

.glow-ring {
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent-primary) 30%, transparent),
              0 18px 50px -12px color-mix(in srgb, var(--accent-primary) 45%, transparent);
}

.btn-primary { position: relative; }
.btn-primary:hover {
  box-shadow: var(--shadow-button), 0 0 28px color-mix(in srgb, var(--accent-primary) 40%, transparent);
}

/* Native, zero-JS accordion for FAQs */
.faq-item { padding: 18px 22px; cursor: pointer; }
.faq-item summary { list-style: none; font-weight: 500; font-size: 14.5px; display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after { content: "+"; font-size: 18px; color: var(--accent-primary); transition: transform var(--dur) var(--ease-spring); flex-shrink: 0; }
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item p { margin-top: 14px; font-size: 13.5px; color: var(--text-muted); line-height: 1.8; }

.logo-cloud { display: flex; align-items: center; justify-content: center; gap: 46px; flex-wrap: wrap; opacity: .55; }
.logo-cloud span { font-weight: 500; font-size: 15px; color: var(--text-muted); letter-spacing: .2px; }

.quote-mark { font-size: 40px; line-height: 1; color: var(--accent-primary); font-weight: 500; opacity: .5; }

/* ---------- Marketing site ---------- */

.mkt-nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 60px; position: sticky; top: 0; z-index: 10;
  /* Solid --card background (not the previous semi-transparent blur) —
     real bug found live via screenshot: the translucent bar read as part
     of the scrolling page content instead of a clearly separate fixed
     header. Matches the dashboard sidebar's own solid --card + border
     language for visual consistency across the whole app, per the
     project owner's explicit request. */
  background: var(--card);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
  transition: transform var(--dur) var(--ease-spring);
}
/* Logo link — a distinct class (not just the shared .flex/.gap-12 utility
   combo) so the mobile-collapse rule below can target the CTA wrapper
   specifically without also matching this link (see the real bug this
   fixed: .mkt-nav > .flex.gap-12 accidentally matched both the CTA
   wrapper AND this logo link, since both carried "flex" + "gap-12" —
   the logo was rendering with display:none on every mobile viewport,
   confirmed live via a real Playwright run, not a color/asset issue). */
.mkt-nav-logo-link { text-decoration: none; }
.mkt-nav .links { display: flex; gap: 30px; font-weight: 500; font-size: 14px; color: var(--text-muted); }
.mkt-nav .links a.link-underline { position: relative; padding-bottom: 4px; }
.mkt-nav .links a:hover { color: var(--text-primary); }
.mkt-nav .links a.active { color: var(--accent-primary); }

/* ── Marketing nav responsive collapse (Phase 10.1 amendment 2 / spec 042) ─
   Below 1024px (same breakpoint as the dashboard sidebar drawer), the 5
   inline nav links + the CTA collapse behind a hamburger (☰) toggle. The
   logo stays visible in the top bar at all widths. The mobile menu is a
   dropdown panel that slides down from the top bar, with a backdrop that
   closes it on tap-out. At desktop (≥1024px) the horizontal nav bar is
   unchanged. Uses only existing CSS custom properties. */

.mkt-nav-toggle {
  display: none;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text-primary);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  align-items: center;
  justify-content: center;
}
.mkt-nav-toggle:hover { background: var(--surface); }

.mkt-nav-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 24;
  background: rgba(0, 0, 0, 0.35);
}

/* Full-height slide-in drawer (real bug found live via screenshot: this
   used to be a small rounded dropdown box floating under the top bar,
   overlapping content awkwardly). Reuses the exact same fixed/partial-width
   /full-height/transform-slide scheme as the dashboard .sidebar drawer
   (Phase 10.1) — same --sidebar-w cap at 80vw, same translateX(100%) hidden
   state, same box-shadow — per the project owner's explicit instruction to
   reuse that pattern rather than invent a second one. */
.mkt-nav-mobile-menu {
  display: flex;
  position: fixed;
  inset-inline-start: 0;
  top: 0;
  bottom: 0;
  width: min(var(--sidebar-w), 80vw);
  height: 100vh;
  flex-direction: column;
  gap: 4px;
  padding: 84px 16px 16px;
  background: var(--card);
  box-shadow: 4px 0 24px rgba(0, 0, 0, 0.18);
  z-index: 50;
  transform: translateX(100%);
  transition: transform var(--dur) var(--ease-spring);
  pointer-events: none;
}
.mkt-nav[data-menu-open="true"] .mkt-nav-mobile-menu {
  transform: translateX(0);
  pointer-events: auto;
}
.mkt-nav-mobile-menu a {
  display: block;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  font-size: 15px;
  font-weight: 500;
  color: var(--text-secondary);
}
.mkt-nav-mobile-menu a:hover { background: var(--surface); color: var(--text-primary); }
.mkt-nav-mobile-menu a.active { color: var(--accent-primary); }
.mkt-nav-mobile-menu .btn { margin-top: 8px; text-align: center; }

@media (max-width: 1023px) {
  .mkt-nav { padding: 14px 16px; position: sticky; }
  .mkt-nav .links { display: none; }
  .mkt-nav-cta { display: none; }
  .mkt-nav-toggle { display: flex; }
  /* Centered logo (project owner's explicit preference — applies
     consistently everywhere a logo appears in a mobile header/drawer
     context, matching the dashboard sidebar drawer's own centered brand
     block). `left` + `translateX(-50%)` centers within the relative
     .mkt-nav regardless of RTL/LTR — both are physical, not logical,
     properties, so no direction-conditional override is needed. */
  .mkt-nav-logo-link {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }
  .mkt-nav[data-menu-open="true"] .mkt-nav-backdrop { display: block; }
  /* Hide-on-scroll-down / reveal-on-scroll-up (item 3) — desktop nav is a
     different, non-collapsed presentation so this is gated to mobile only. */
  .mkt-nav[data-hidden="true"] { transform: translateY(-100%); }
}

@media (min-width: 1024px) {
  .mkt-nav-toggle { display: none; }
  .mkt-nav-backdrop { display: none; }
  .mkt-nav-mobile-menu { display: none; }
}

.hero { padding: 90px 60px 70px; display: flex; align-items: center; gap: 60px; }
.hero .copy { flex: 1; }
.hero h1 { font-size: 44px; font-weight: 500; line-height: 1.28; letter-spacing: -.6px; margin-top: 18px; }
.hero p { font-size: 17px; color: var(--text-muted); margin-top: 20px; line-height: 1.85; font-weight: 400; max-width: 540px; }
.hero .cta-row { display: flex; gap: 14px; margin-top: 32px; }
.hero .visual { flex: 1; height: 400px; border-radius: var(--radius-xl); }

.mkt-section { padding: 70px 60px; }
.mkt-section .heading { text-align: center; max-width: 660px; margin: 0 auto 44px; }
.mkt-section .heading .eyebrow { color: var(--accent-primary); font-weight: 500; font-size: 12.5px; text-transform: uppercase; letter-spacing: 1px; }
.mkt-section .heading h2 { font-size: 30px; font-weight: 500; margin-top: 8px; letter-spacing: -.4px; }
.mkt-section .heading p { color: var(--text-muted); margin-top: 14px; font-size: 15px; line-height: 1.8; font-weight: 400; }

.feature-card { padding: 28px; display: flex; flex-direction: column; gap: 14px; }
.feature-card .ic { width: 50px; height: 50px; border-radius: var(--radius-lg); background: var(--gradient-brand); color: var(--accent-foreground); display: flex; align-items: center; justify-content: center; font-size: 22px; }
.feature-card:hover .ic { transform: scale(1.08) rotate(-4deg); }
.feature-card .ic { transition: transform var(--dur) var(--ease-spring); }
.feature-card h3 { font-size: 15.5px; font-weight: 500; }
.feature-card p { font-size: 13.5px; color: var(--text-muted); line-height: 1.75; font-weight: 400; }

.price-card { padding: 34px; display: flex; flex-direction: column; gap: 18px; position: relative; }
.price-card.featured { box-shadow: 0 0 0 2px var(--accent-primary), var(--shadow-card-hover); }
.price-card .tag { position: absolute; top: -14px; right: 28px; background: var(--gradient-brand); color: var(--accent-foreground); font-size: 11px; font-weight: 500; padding: 6px 14px; border-radius: 20px; }
.price-card .amount { font-size: 34px; font-weight: 500; letter-spacing: -.4px; font-family: "Bricolage Grotesque", monospace; }
.price-card .amount span { font-size: 14px; color: var(--text-muted); font-weight: 400; }
.price-card ul { display: flex; flex-direction: column; gap: 13px; font-size: 13.5px; font-weight: 400; }
.price-card ul li::before { content: "✓ "; color: var(--success); font-weight: 500; }

.footer { padding: 54px 60px; border-top: 1px solid var(--border); display: flex; justify-content: space-between; color: var(--text-muted); font-size: 13px; }

/* ---------- Auth pages ---------- */

.auth-shell { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 40px; }
.auth-card { width: 420px; padding: 40px; animation: scaleIn var(--dur-slow) var(--ease-spring) both; }
.auth-card .logo-row { display: flex; align-items: center; gap: 12px; justify-content: center; margin-bottom: 28px; }
.auth-card .logo-row .logo { width: 46px; height: 46px; border-radius: var(--radius-lg); background: var(--gradient-brand); color: var(--accent-foreground); display: flex; align-items: center; justify-content: center; font-weight: 500; }
.role-switch { display: flex; gap: 6px; margin-bottom: 26px; background: var(--surface); border: 1px solid var(--border); padding: 4px; border-radius: var(--radius-lg); }
.role-switch .opt { flex: 1; text-align: center; padding: 9px; border-radius: var(--radius-md); font-size: 12px; font-weight: 500; color: var(--text-muted); }
.role-switch .opt.active { background: var(--accent-primary); color: var(--accent-foreground); }

@media (max-width: 1100px) {
  .grid-4, .grid-5 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 880px) {
  .hero { flex-direction: column; padding: 40px 24px; }
  .mkt-nav { padding: 16px 24px; }
  .mkt-section { padding: 40px 24px; }
  .topbar .tb-search { display: none; }
  /* Marketing footer: stack vertically at narrow widths so the two link
     groups don't overflow horizontally. The footer's own .footer rule is
     justify-content: space-between (two columns side-by-side); below 880px
     it becomes a single column with the link groups wrapping. */
  .footer { flex-direction: column; gap: 16px; padding: 40px 24px; }
  .footer .footer-links { align-items: flex-start !important; }
  .footer .footer-links-main, .footer .footer-links-legal { flex-wrap: wrap; gap: 12px 16px; }
  /* Auth card: the fixed 420px width overflows at ≤880px; constrain to
     the viewport with internal padding. */
  .auth-card { width: 100%; max-width: 420px; padding: 28px 22px; }
  .auth-shell { padding: 20px 16px; }
}

/* ── Responsive sidebar drawer (Phase 10.1 amendment / spec 042) ────────
   Fixes the real, severe bug found live by the project owner via Chrome
   DevTools device emulation (320×643): below 880px the prior rule
   `.sidebar { width: 100%; height: auto; position: relative; }` rendered
   the sidebar as a permanently-open, full-viewport-width panel that
   completely covered the page content on mobile — no toggle, no drawer,
   no way to reach the actual page. This block replaces that broken
   behavior with a proper drawer pattern at a single 1024px breakpoint:
     · ≥1024px: sidebar is permanent alongside content (unchanged desktop)
     · <1024px: sidebar is hidden by default, slides over content as an
       overlay drawer when the user taps the hamburger (☰) button, with
       a backdrop that closes the drawer on tap-out. The main content
       is fully visible and usable at full width underneath at all times.
   This applies to every dashboard route (Super Admin, Owner, Cashier)
   via the three shared sidebar components + the three shared layouts —
   no per-page patches. Storefront pages don't use .app-shell/.sidebar
   (they have their own bespoke headers) and are unaffected by this rule.
   Uses only existing CSS custom properties — no new colors/fonts/tokens. */

/* Hamburger toggle button — only visible below the 1024px breakpoint.
   Fixed in the top-start corner, high z-index so it stays reachable
   above the backdrop and the drawer. The three sidebar client
   components render this button as their first child. */
.nav-drawer-toggle {
  display: none;
  position: fixed;
  top: 12px;
  inset-inline-start: 12px;
  z-index: 60;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--card);
  color: var(--text-primary);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.nav-drawer-toggle:hover { background: var(--surface); }

/* Persistent mobile header bar (real bug found live via screenshot: below
   1024px there was no header "bar" at all, only the lone floating
   hamburger button — so the logo was only ever visible once the drawer
   was opened, not in the default closed state, and there was nothing to
   apply a distinct background or scroll-hide behavior to). Wraps the
   hamburger toggle + a centered logo/wordmark as one fixed-position unit
   spanning the full top of the viewport, matching the marketing nav's own
   solid --card background + border-bottom language for consistency, and
   sharing the same hide-on-scroll mechanism (useHideOnScroll) via the
   data-hidden attribute. Rendered by the three dashboard sidebar
   components (Owner/Cashier/Super Admin), replacing the bare toggle
   button that previously had no bar behind it. */
.mobile-header-bar {
  display: none;
  position: fixed;
  top: 0;
  inset-inline-start: 0;
  right: 0;
  height: 60px;
  z-index: 45;
  align-items: center;
  padding: 0 12px;
  background: var(--card);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
  transition: transform var(--dur) var(--ease-spring);
}
.mobile-header-bar[data-hidden="true"] { transform: translateY(-100%); }
.mobile-header-bar .brand-identity {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 10px;
}
.mobile-header-bar .logo { width: 32px; height: 32px; }
.mobile-header-bar .name { font-weight: 600; font-size: 15px; }
/* The toggle button lives inside this already-fixed bar, so it no longer
   needs its own fixed positioning/shadow — just flows normally at the
   bar's inline-start edge. */
.mobile-header-bar .nav-drawer-toggle {
  position: static;
  box-shadow: none;
}

/* Backdrop — only visible when the drawer is open below the breakpoint.
   Covers the main content so a tap anywhere outside the drawer closes it. */
.nav-drawer-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(0, 0, 0, 0.45);
}

/* Drawer-open state (toggled by the sidebar client components via the
   `data-drawer-open` attribute on the .app-shell). Below the breakpoint,
   the sidebar slides in from the inline-start edge (right in RTL, left
   in LTR — `inset-inline-start` resolves correctly for both) as a
   fixed-position overlay, and the backdrop fades in. */
@media (max-width: 1023px) {
  .nav-drawer-toggle { display: flex; }
  .mobile-header-bar { display: flex; }
  /* Real bug found live via screenshot: every dashboard page's own
     .topbar (page title row, e.g. Owner dashboard's "لوحة تحكم صاحب
     المطعم" card) carries `position: sticky; top: 14px` for desktop
     scrolling — harmless there, but on mobile it stacked underneath the
     new fixed .mobile-header-bar and became the thing that visibly stuck
     while scrolling, not the logo. .mobile-header-bar (added this same
     project phase) is the one element that should stay pinned on mobile,
     matching the marketing nav's own sticky-logo header at the same
     breakpoint — so .topbar's sticky is switched off here, letting it
     scroll normally like every other card.
     Shared across Owner/Cashier/Super Admin dashboards. */
  .topbar { position: static; top: auto; }

  .sidebar {
    position: fixed;
    inset-inline-start: 0;
    top: 0;
    bottom: 0;
    width: min(var(--sidebar-w), 80vw);
    height: 100vh;
    z-index: 50;
    transform: translateX(0);
    transition: transform var(--dur) var(--ease-spring);
    box-shadow: 4px 0 24px rgba(0, 0, 0, 0.18);
  }
  /* RTL: the sidebar lives on the right edge natively (border-left above),
     so to slide it OFF-screen we translate it +100% (to the right). In LTR
     it would translate -100%. The `dir="rtl"` on <html> means translateX
     positive is visually-rightward. We hide by default below the breakpoint
     and reveal on data-drawer-open="true". */
  .app-shell:not([data-drawer-open="true"]) .sidebar {
    transform: translateX(100%);
    pointer-events: none;
  }
  .app-shell[data-drawer-open="true"] .nav-drawer-backdrop {
    display: block;
  }
  /* Real bug found live by the project owner via screenshots: the fixed
     hamburger toggle stayed visible even while the drawer was open,
     overlapping the drawer's own logo (both anchored to the same top-
     start corner). The drawer already closes via a backdrop tap or a
     nav-link tap (existing, already-tested behavior) — hiding the
     floating toggle whenever the drawer is open removes the overlap
     entirely rather than trying to reposition two elements sharing the
     same corner. */
  .app-shell[data-drawer-open="true"] .nav-drawer-toggle {
    display: none;
  }

  /* Sticky drawer header (real bug found live: the logo wasn't visible at
     all once the drawer's own nav list was scrolled, since .brand was
     just a normal top-of-list flex child inside .sidebar's own scroll
     container). Pins the whole brand row at the top of the drawer. */
  .sidebar .brand {
    position: sticky;
    top: -26px;
    margin: -26px -18px 0;
    padding: 26px 18px 18px;
    background: var(--card);
    z-index: 10;
  }
  /* Centered icon+wordmark (project owner's explicit preference — matches
     the marketing nav's own centered-logo treatment at the same
     breakpoint). .brand-identity wraps just the logo+name+role-tag (see
     the sidebar components' own JSX) so it can be centered independently
     of the notification bell, which stays a normal flex sibling at its
     existing position rather than being absolutely positioned itself. */
  .sidebar .brand-identity {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }

  /* Main content takes full width below the breakpoint — no sidebar
     pushing it, since the sidebar is now an overlay drawer. The
     .app-shell stays flex (row) so the sidebar's fixed positioning
     takes it out of flow without affecting main's width. */
  .main { padding-inline-start: 16px; padding-top: 76px; }
}

@media (min-width: 1024px) {
  /* Desktop: sidebar permanent — no toggle, no drawer, unchanged behavior. */
  .nav-drawer-toggle { display: none; }
  .mobile-header-bar { display: none; }
  .nav-drawer-backdrop { display: none; }
  .app-shell .sidebar { transform: none; pointer-events: auto; }
}
@media (max-width: 640px) {
  .grid-4, .grid-3, .grid-2, .grid-5 { grid-template-columns: 1fr; }
  .main { padding: 18px; }
}
/* Walk-in order receipt (Phase 5.4 / spec 019) — window.print() shows only
   the .receipt-print-only region, hiding the rest of the dashboard chrome
   (sidebar + every other child rendered inside .main). .receipt-print-only
   stays display:none on screen and is only ever made visible in print. */
.receipt-print-only { display: none; }
.receipt-divider { border: none; border-top: 1px dashed #666; margin: 6px 0; }
.receipt-field { font-size: 12px; margin-bottom: 3px; }
.receipt-sub-line { font-size: 11px; color: #555; }
.receipt-footer { text-align: center; font-size: 10px; color: #999; margin-top: 8px; }

/* ── Phase 10.1 / spec 042 — Mobile floor (≤480px) ─────────────────────
   The shared stylesheet previously had 768/1100/880/640/print @media
   blocks but no explicit ≤480px floor. The 640px block already collapses
   the grids to 1fr, so this block reinforces that for the spec's Mobile
   reference width (≤480px) AND adds the FR-005 (wide tables scroll within
   their own container, never force the whole page to scroll) and FR-006
   (modals fit within the viewport, never force the underlying page to
   scroll, close action reachable) constraints that the 640px block did
   not carry. Touch-target minimum (FR-004, 44×44 on Cashier + public
   checkout Mobile screens) is enforced in the US2 phase via a separate
   rule below; this block is layout-only. Uses only existing CSS custom
   properties — no new colors/fonts/tokens (research.md Decision 5). */
@media (max-width: 480px) {
  /* Reinforce single-column grids (640px already does this, but make it
     explicit at the Mobile floor so a future 640px change doesn't
     silently regress Mobile). */
  .grid-2, .grid-3, .grid-4, .grid-5 { grid-template-columns: 1fr; }

  /* FR-005: wide data tables scroll horizontally within their own
     container, never force the whole page to scroll. .table-wrap
     already has overflow-x: auto (line 507); add max-width: 100% so the
     wrapper itself never exceeds the viewport and triggers the internal
     scroll rather than pushing the page wide. */
  .table-wrap { max-width: 100%; overflow-x: auto; }

  /* FR-006: modals fit within the Mobile viewport. The Owner
     order-detail modal, the product create/edit modal, the
     printer-registration modal, and the storefront product-detail sheet
     all use a fixed-position overlay + .card.neu-raised inner panel.
     Constrain the inner panel to the viewport with internal scroll, so
     the modal never forces the underlying page to scroll and the close
     action stays reachable. */
  .card.neu-raised {
    max-width: 100vw;
    max-height: 100vh;
    overflow-y: auto;
  }

  /* Reduce topbar padding so the topbar controls (filters, search,
     dropdowns) remain usable at 390px without forcing horizontal
     scroll. The 880px block already hides .tb-search; this block further
     tightens the topbar for the phone floor. */
  .topbar { padding: 12px 14px; gap: 12px; flex-wrap: wrap; }
  .topbar .actions { gap: 8px; flex-wrap: wrap; }

  /* Tighten main content padding for the phone floor. The 640px block
     already sets .main { padding: 18px }; this block narrows it further
     to keep content within a 390px viewport. */
  .main { padding: 12px; }

  /* FR-004 touch-target floor for Cashier Dashboard + public checkout
     Mobile screens (US2): every interactive target ≥44×44 CSS pixels at
     ≤480px. Owner/Super Admin/marketing/auth screens are not held to
     this minimum (they're back-office/anonymous surfaces used on larger
     screens), but the rule is global because it does no harm on those
     screens at Mobile width — a 44px button is still clickable with a
     mouse on a back-office screen viewed at phone width, and the rule
     only fires at ≤480px so Desktop is unaffected. For icon-only
     buttons that visually stay small, min-width/min-height grows the hit
     area without changing the visual icon size.
     2026-07-21: added `.nav-link` — a real live Playwright run found the
     Cashier sidebar's own logout button (cashier-sidebar.tsx, className
     "nav-link", a bare <button> with no .btn/.btn-sm/role="button") at
     38px tall, missed by the original selector since it's none of those
     three. Confirmed via the failing test's own page snapshot (DOM-order
     index matched exactly this button, not any dev-tooling element) —
     reproduced identically across all 3 Cashier screens that render this
     shared sidebar (order-walkin, shift-open, shift-close), one root
     cause, one fix. */
  .btn, .btn-sm, [role="button"], .nav-link {
    min-height: 44px;
    min-width: 44px;
  }
}

/* ── Phase 12.1 — Notification bell dropdown + inbox (spec 043) ─────────
   Shared across Owner, Super Admin, and Cashier sidebars. Uses only
   existing CSS custom properties — no new colors/fonts/tokens. */

.bell-wrap { position: relative; margin-inline-start: auto; }
.bell-btn { position: relative; }
.bell-badge {
  position: absolute; top: -4px; inset-inline-end: -4px;
  background: var(--destructive); color: var(--destructive-foreground);
  font-size: 10px; font-weight: 700; border-radius: 10px;
  min-width: 18px; height: 18px; display: flex; align-items: center; justify-content: center;
  padding: 0 5px; font-family: "Bricolage Grotesque", monospace;
}
.bell-dropdown {
  position: absolute; top: calc(100% + 8px); inset-inline-end: 0;
  width: 340px; max-width: 90vw;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: 0 8px 32px rgba(0,0,0,0.12);
  z-index: 30; overflow: hidden;
}
.bell-dropdown-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 16px; border-bottom: 1px solid var(--border);
}
.bell-dropdown-list { max-height: 360px; overflow-y: auto; }
.bell-item {
  display: flex; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--border);
  cursor: pointer;
}
.bell-item:hover { background: var(--surface); }
.bell-item.unread { background: color-mix(in srgb, var(--accent-primary) 6%, transparent); }
.bell-item-icon { width: 32px; height: 32px; border-radius: var(--radius-md); background: var(--surface); display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.bell-item-body { flex: 1; min-width: 0; }
.bell-item-title { font-size: 13.5px; font-weight: 500; color: var(--text-primary); }
.bell-item.unread .bell-item-title { font-weight: 600; }

/* Inbox page */
.notif-item {
  display: flex; gap: 16px; padding: 18px 20px;
  border-radius: var(--radius-md); border: 1px solid var(--border);
  background: var(--card);
}
.notif-item.unread {
  border-color: color-mix(in srgb, var(--accent-primary) 30%, var(--border));
  background: color-mix(in srgb, var(--accent-primary) 4%, var(--card));
}
.notif-icon {
  width: 44px; height: 44px; border-radius: var(--radius-md);
  display: flex; align-items: center; justify-content: center;
  font-size: 20px; flex-shrink: 0; background: var(--surface);
}
.notif-icon-warning { background: color-mix(in srgb, #f59e0b 15%, var(--surface)); }
.notif-icon-danger { background: color-mix(in srgb, var(--destructive) 12%, var(--surface)); }
.notif-icon-info { background: color-mix(in srgb, var(--accent-primary) 10%, var(--surface)); }
.notif-icon-success { background: color-mix(in srgb, var(--success) 12%, var(--surface)); }
.notif-body { flex: 1; min-width: 0; }
.notif-filter.active { background: var(--accent-primary); color: var(--accent-foreground); }

@media print {
  @page {
    size: 80mm auto;
    margin: 4mm;
  }
  .sidebar { display: none !important; }
  .main > *:not(.receipt-print-only) { display: none !important; }
  .receipt-print-only { display: block !important; }
}

/* ── Marketing Site animations (item 3 follow-up) ─────────────────────── */

/* Scroll-triggered fade+slide-up. The AnimatedOnScroll component adds
   .animate-visible when the element enters the viewport. */
.animate-on-scroll {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.animate-on-scroll.animate-visible {
  opacity: 1;
  transform: translateY(0);
}

/* Rotating headline text — words stack, only the active one is visible. */
.rotating-text-container {
  display: inline-block;
  position: relative;
  min-width: 80px;
  text-align: center;
}
.rotating-text-word {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 0.4s ease, transform 0.4s ease;
  background: linear-gradient(135deg, var(--accent-primary), var(--accent-secondary, #34c9c2));
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.rotating-text-word.active {
  opacity: 1;
  transform: translateY(0);
  position: relative;
}

/* Elevated CTA buttons — premium shadow, not just a border/color change. */
.hero .btn-primary.btn-lg,
.mkt-section .btn-primary.btn-lg {
  box-shadow: 0 8px 24px -4px color-mix(in srgb, var(--accent-primary) 40%, transparent),
              0 4px 12px -2px color-mix(in srgb, var(--accent-primary) 30%, transparent);
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}
.hero .btn-primary.btn-lg:hover,
.mkt-section .btn-primary.btn-lg:hover {
  box-shadow: 0 12px 32px -4px color-mix(in srgb, var(--accent-primary) 50%, transparent),
              0 6px 16px -2px color-mix(in srgb, var(--accent-primary) 35%, transparent);
  transform: translateY(-2px);
}
