:root[data-theme="dark"] {
  --bg: #0d0620;
  --bg-2: #170b35;
  --ink: #f3eefc;
  --ink-dim: #a89bc4;
  --line: #2e1f52;
  /* Sampled directly from the client's own Instagram brand post (deep
     violet curtain, vivid magenta-purple highlight, coral-red accent
     stroke) rather than designed independently -- this IS the actual
     brand identity, not an interpretation of it. Still tracks the
     CMS-driven --accent (shop brand color / seasonal theme) once JS sets
     it, falling back to this brand-accurate purple before that happens. */
  --copper: var(--accent, #a55fd9);
  --copper-2: var(--accent-2, #6a2fb0);
  --panel: #170e30;
  --shadow: rgba(0,0,0,0.55);
  --danger: #e75660;
  --ok: #6fb87f;
  --info: #4a8a96;
}
:root[data-theme="light"] {
  --bg: #f7f3fc;
  --bg-2: #efe4fa;
  --ink: #1d1130;
  --ink-dim: #6f5f8f;
  --line: #ded0f0;
  --copper: var(--accent, #7c3aed);
  --copper-2: var(--accent-2, #5b21b6);
  --panel: #ffffff;
  --shadow: rgba(30,10,50,0.12);
  --danger: #c53142;
  --ok: #3d7548;
  --info: #2e6e7a;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
/* A slim, brand-colored scrollbar applied everywhere -- several places in
   this layout legitimately nest independently-scrollable regions (the
   sticky POS cart scrolling within the main content area, the cart's own
   item list scrolling within that), and Windows' wide native scrollbar
   (15-17px) made stacked adjacent scrollbars from nested containers look
   like a confusing, oversized empty gutter along the edge. This keeps
   every individual scrollbar thin enough that even several stacked next
   to each other stay unobtrusive. */
* { scrollbar-width: thin; scrollbar-color: var(--copper) transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--copper) 55%, transparent); border-radius: 999px; }
*::-webkit-scrollbar-thumb:hover { background: var(--copper); }
body {
  margin: 0;
  background:
    radial-gradient(circle at 15% 0%, var(--bg-2), var(--bg) 55%);
  color: var(--ink);
  font-family: 'IBM Plex Sans Arabic', 'Space Grotesk', 'Segoe UI', Tahoma, Arial, sans-serif;
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
  transition: background 0.3s ease, color 0.3s ease;
}
/* A genuine halftone dot-screen (Ben-Day dots) -- the classic comic-book
   printing texture, matching both the explicit style request and the
   dot-screen texture already visible in the client's own brand posts.
   Landing page only; kept as texture (never competing with text) via low
   opacity and placement behind all real content. */
body:has(#authScreen:not([hidden])) {
  background-image:
    radial-gradient(circle, color-mix(in srgb, var(--copper) 14%, transparent) 3px, transparent 3.2px),
    radial-gradient(circle at 15% 0%, var(--bg-2), var(--bg) 55%);
  background-repeat: repeat, no-repeat;
  background-size: 22px 22px, auto;
  background-position: 0 0, 0 0;
}
[dir="ltr"] body { font-family: 'Space Grotesk', 'IBM Plex Sans Arabic', 'Segoe UI', Tahoma, Arial, sans-serif; }

.grain {
  position: fixed; inset: 0; pointer-events: none; opacity: 0.05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.topbar { display: flex; align-items: center; justify-content: space-between; padding: 22px 5vw; }
.brand { display: flex; align-items: center; gap: 10px; }
.brand-name { font-weight: 900; font-size: 1.15rem; letter-spacing: 0.5px; }
.brand-dot { color: var(--copper); }
.steam-icon { width: 30px; height: 30px; }
.brand-mark.small .steam-icon { width: 22px; height: 22px; }
.cup { fill: var(--copper); }
.steam { fill: none; stroke: var(--ink-dim); stroke-width: 1.6; stroke-linecap: round; opacity: 0.7; }
.s1 { animation: rise 3.2s ease-in-out infinite; }
.s2 { animation: rise 3.2s ease-in-out 0.5s infinite; }
.s3 { animation: rise 3.2s ease-in-out 1s infinite; }
@keyframes rise { 0% { transform: translateY(0); opacity: 0; } 20% { opacity: 0.8; } 100% { transform: translateY(-6px); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .steam { animation: none; opacity: 0.5; } .view.active { animation: none; } }

.topbar-controls, .side-controls { display: flex; gap: 8px; }
.pill-btn {
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  border-radius: 999px; padding: 8px 16px; font-family: inherit; font-weight: 500;
  cursor: pointer; font-size: 0.85rem; transition: border-color 0.2s, color 0.2s;
}
.pill-btn:hover, .pill-btn:focus-visible { border-color: var(--copper); color: var(--copper); }
.icon-btn { padding: 8px; display: flex; align-items: center; justify-content: center; }
.icon-btn svg { fill: currentColor; }

.stage { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: 6vw; align-items: center; padding: 4vh 5vw 6vh; max-width: 1180px; margin: 0 auto; }
@media (max-width: 880px) { .stage { grid-template-columns: 1fr; gap: 40px; } }

.eyebrow { color: var(--copper); font-size: 0.92rem; font-weight: 700; margin: 0 0 14px; }
.pitch h1 { font-size: clamp(2rem, 4vw, 3.1rem); line-height: 1.15; margin: 0 0 18px; font-weight: 900; color: var(--ink); }
.pitch .sub { color: var(--ink-dim); font-size: 1.02rem; line-height: 1.7; max-width: 46ch; margin: 0 0 24px; }
.pitch-list { list-style: none; padding: 0; margin: 0 0 28px; display: flex; flex-direction: column; gap: 10px; }
.pitch-list li { position: relative; padding-inline-start: 26px; color: var(--ink); font-size: 0.95rem; }
.pitch-list li::before { content: "\2022"; position: absolute; inset-inline-start: 2px; top: -3px; font-size: 1.3rem; line-height: 1; color: var(--copper); }

.brand-mosaic { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; padding: 0 5vw 10px; max-width: 900px; margin: 0 auto; }
.brand-mosaic img { width: 64px; height: 64px; object-fit: cover; border-radius: 12px; border: 1px solid var(--line); filter: grayscale(0.55) contrast(1.05); opacity: 0.85; transition: filter 0.25s, opacity 0.25s, transform 0.2s; }
.brand-mosaic img:hover { filter: grayscale(0) contrast(1.1); opacity: 1; transform: translateY(-3px); }
@media (max-width: 520px) { .brand-mosaic img { width: 48px; height: 48px; } }

.ticket { background: var(--panel); border: 2px solid color-mix(in srgb, var(--ink) 85%, transparent); border-top: none; border-radius: 0 0 18px 18px; padding: 34px 30px; box-shadow: 6px 6px 0 color-mix(in srgb, var(--copper) 70%, transparent); position: relative; overflow: hidden; margin: -1px auto 0; max-width: 400px; }
.ticket::before { content: ""; position: absolute; top: 0; inset-inline: 0; height: 4px; background: linear-gradient(90deg, var(--copper-2), var(--copper), #c2478f); }
.tabs { display: flex; gap: 6px; margin-bottom: 26px; border-bottom: 1px dashed var(--line); padding-bottom: 14px; }
.tab { flex: 1; background: none; border: none; color: var(--ink-dim); font-family: inherit; font-size: 0.92rem; font-weight: 700; padding: 8px; cursor: pointer; border-radius: 8px; transition: color 0.2s, background 0.2s; }
.tab.active { color: var(--copper); background: color-mix(in srgb, var(--copper) 12%, transparent); }

.panel-form { display: none; flex-direction: column; gap: 6px; }
.panel-form.active { display: flex; }
.panel-form label { font-size: 0.8rem; color: var(--ink-dim); margin-top: 10px; }
input, select {
  background: var(--bg); border: 1px solid var(--line); color: var(--ink);
  border-radius: 10px; padding: 12px 14px; font-family: inherit; font-size: 0.95rem; outline: none; transition: border-color 0.2s;
}
input:focus-visible, select:focus-visible { border-color: var(--copper); }

.primary-btn {
  margin-top: 20px; background: linear-gradient(135deg, var(--copper-2), var(--copper) 65%, #c2478f);
  color: #fff; border: 2px solid color-mix(in srgb, var(--ink) 85%, transparent); border-radius: 10px; padding: 13px; font-weight: 800;
  font-family: inherit; font-size: 0.98rem; cursor: pointer; transition: transform 0.12s, box-shadow 0.12s;
  box-shadow: 3px 3px 0 color-mix(in srgb, var(--ink) 85%, transparent);
}
.primary-btn:hover { transform: translate(-1px, -1px); box-shadow: 4px 4px 0 color-mix(in srgb, var(--ink) 85%, transparent); }
.primary-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 color-mix(in srgb, var(--ink) 85%, transparent); }
.primary-btn.small { margin-top: 0; padding: 11px 18px; white-space: nowrap; }
.primary-btn.full { width: 100%; }
.primary-btn:focus-visible, .tab:focus-visible, .ghost-btn:focus-visible { outline: 2px solid var(--copper); outline-offset: 2px; }

.form-note { color: var(--ink-dim); font-size: 0.76rem; margin: 12px 2px 0; text-align: center; }
.form-error { margin-top: 14px; color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); border: 1px solid color-mix(in srgb, var(--danger) 40%, transparent); border-radius: 8px; padding: 10px 12px; font-size: 0.85rem; }

.site-footer { text-align: center; padding: 20px; }
.dev-gate { color: var(--ink-dim); font-size: 0.78rem; cursor: pointer; border-bottom: 1px dotted var(--line); padding-bottom: 2px; }
.dev-gate:hover { color: var(--copper); }
.dev-art[hidden] { display: none; }
.dev-art { display: block; margin: 12px auto 0; max-width: 160px; border-radius: 12px; border: 1px solid var(--line); }

/* ===== App shell ===== */
.app-frame { display: grid; grid-template-columns: 240px 1fr; height: 100vh; height: 100dvh; overflow: hidden; }
@media (max-width: 820px) { .app-frame { grid-template-columns: minmax(0, 1fr); height: auto; overflow: visible; } }
.side-nav { background: var(--panel); border-inline-end: 1px solid var(--line); padding: 22px 16px; display: flex; flex-direction: column; gap: 18px; height: 100vh; height: 100dvh; overflow-y: auto; }
.side-brand { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 0.95rem; }
.side-nav nav { display: flex; flex-direction: column; gap: 4px; }
.nav-item {
  display: flex; align-items: center; gap: 11px; text-align: start; background: none; border: none;
  border-inline-start: 3px solid transparent; color: var(--ink-dim); font-family: inherit; font-size: 0.92rem;
  padding: 11px 12px; border-radius: 8px; cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.nav-item svg { flex-shrink: 0; opacity: 0.75; transition: opacity 0.15s; }
.nav-item:hover { color: var(--ink); background: color-mix(in srgb, var(--line) 45%, transparent); }
.nav-item:hover svg { opacity: 1; }
.nav-item.active { background: color-mix(in srgb, var(--copper) 15%, transparent); color: var(--copper); font-weight: 700; border-inline-start-color: var(--copper); }
.nav-item.active svg { opacity: 1; }
/* Each group gets a real dividing rule above its label rather than just
   extra whitespace -- with ~15 destinations in one column, spacing alone
   wasn't enough to make the sections read as distinct at a glance, which
   is what made the sidebar feel like one long undifferentiated list. */
.nav-group-label {
  margin: 18px 0 4px; padding: 12px 12px 0; font-size: 0.7rem; font-weight: 800;
  letter-spacing: 0.8px; text-transform: uppercase; color: var(--ink-dim); opacity: 0.85;
  border-top: 1px solid var(--line);
}
.nav-group-label:first-child { margin-top: 0; padding-top: 0; border-top: none; }
/* Every rule this media query overrides (.side-nav, .side-nav nav,
   .nav-item) MUST already be defined above this point in the file --
   with equal CSS specificity, source order decides, and a media query
   placed before the rule it's meant to override is silently ignored on
   matching viewports. This exact mistake (query before base rule) is what
   caused the mobile nav to consume the full screen height in column
   layout, hiding all real app content below the fold. */
@media (max-width: 820px) {
  .side-nav { position: sticky; top: 0; z-index: 5; flex-direction: row; flex-wrap: wrap; height: auto; max-height: 40vh; overflow-y: auto; align-items: flex-start; gap: 8px; }
  .side-nav nav { flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .side-nav .nav-item { flex: 0 0 auto; font-size: 0.78rem; padding: 7px 10px; background: color-mix(in srgb, var(--line) 40%, transparent); border-radius: 999px; border-inline-start: none; }
  .side-nav .nav-item svg { display: none; }
  .side-nav .nav-item.active { background: var(--copper); color: #fff; }
  /* The compact wrapped chip-row has no room or need for section headers
     -- each pill is already self-descriptive on its own. Without this,
     group labels rendered as confusing plain-text chips indistinguishable
     from actual clickable buttons in the same row. */
  .nav-group-label { display: none; }
}

/* Collapsible sidebar -- gives products the FULL width on demand, on any
   screen size, not just mobile. Both tracks animate together so the
   content smoothly expands into the freed space rather than jumping. */
.app-frame { transition: grid-template-columns 0.25s ease; }
.side-nav { transition: opacity 0.2s ease; }
.app-frame.nav-collapsed { grid-template-columns: 0 1fr; }
.app-frame.nav-collapsed .side-nav { padding: 22px 0; opacity: 0; pointer-events: none; overflow: hidden; }
/* Collapsing the sidebar frees up real horizontal space -- use it to make
   product cards genuinely bigger and clearer, not just to cram in more
   columns at the same small size. */
.app-frame.nav-collapsed .product-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 14px; }
.side-nav-toggle {
  position: fixed; top: 14px; inset-inline-start: 14px; z-index: 50;
  width: 38px; height: 38px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink); font-size: 1.1rem; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px var(--shadow);
}
.side-nav-toggle:hover { border-color: var(--copper); color: var(--copper); }
/* On mobile the sidebar is already a compact wrapped chip row (see the
   820px block above), not a wide column -- collapsing it there wouldn't
   free meaningful space and would just hide navigation, so the toggle is
   only shown above that breakpoint. */
@media (max-width: 820px) { .side-nav-toggle { display: none; } }

/* Category tabs: a fixed min-height stops the whole toolbar from
   collapsing/expanding (and everything below it shifting) between an
   empty and populated state, or as tabs wrap across rows. */
.filter-tabs { min-height: 38px; }

.ghost-btn { background: none; border: 1px solid var(--line); color: var(--ink-dim); border-radius: 8px; padding: 9px 16px; font-family: inherit; cursor: pointer; font-size: 0.85rem; transition: border-color 0.2s, color 0.2s; }
.ghost-btn:hover { border-color: var(--copper); color: var(--copper); }
.ghost-btn.full { width: 100%; margin-top: auto; }

.app-main { padding: 26px 4vw 60px; max-width: 1200px; height: 100vh; height: 100dvh; overflow-y: auto; }
@media (max-width: 820px) { .app-main { height: auto; overflow-y: visible; } }
.view { display: none; }
.view.active { display: block; animation: viewFadeIn 0.28s ease; }
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
.view-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 18px; }

.sub-banner { background: color-mix(in srgb, var(--danger) 15%, transparent); border: 1px solid color-mix(in srgb, var(--danger) 45%, transparent); color: var(--danger); border-radius: 10px; padding: 12px 16px; margin-bottom: 20px; font-size: 0.88rem; }

.card { background: var(--panel); border: 1px solid var(--line); border-radius: 16px; padding: 22px; margin-bottom: 20px; }
.card h3 { margin: 0 0 16px; font-size: 1rem; color: var(--copper); }
.inline-form { display: flex; flex-direction: column; gap: 10px; }
.inline-form .row { display: flex; gap: 10px; flex-wrap: wrap; }
.inline-form input, .inline-form select { flex: 1; min-width: 140px; }
.chip-row { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 14px; }
.chip { background: var(--bg); border: 1px solid var(--line); border-radius: 999px; padding: 6px 14px; font-size: 0.82rem; }

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

.product-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(115px, 1fr)); gap: 12px; }
.product-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px; overflow: hidden; cursor: pointer;
  transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s; text-align: center; position: relative;
}
.product-card::before { content: ""; position: absolute; top: 0; inset-inline: 0; height: 1px; background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--copper) 45%, transparent), transparent); opacity: 0; transition: opacity 0.15s; }
.product-card:hover { transform: translate(-2px, -2px); border-color: var(--copper); box-shadow: 3px 3px 0 var(--copper); }
.product-card:hover::before { opacity: 1; }
.product-card .thumb { width: 100%; aspect-ratio: 1; object-fit: cover; background: var(--bg); }
.product-card .thumb.placeholder { display: flex; align-items: center; justify-content: center; color: var(--ink-dim); font-size: 1.6rem; }
.product-card .pname { font-size: 0.85rem; font-weight: 700; padding: 8px 8px 2px; }
.product-card .pprice { font-size: 0.78rem; color: var(--copper); padding-bottom: 10px; font-variant-numeric: tabular-nums; font-weight: 600; }
.quick-edit-btn { position: absolute; top: 6px; inset-inline-end: 6px; z-index: 3; width: 26px; height: 26px; border-radius: 50%; border: none; background: rgba(0,0,0,0.55); color: #fff; font-size: 0.75rem; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.quick-edit-btn:hover { background: rgba(0,0,0,0.75); }
.product-grid.manage .product-card { cursor: default; position: relative; }
.product-grid.manage .pactions { display: flex; gap: 6px; padding: 0 8px 10px; }
.product-grid.manage .pactions button { flex: 1; font-size: 0.72rem; padding: 6px; border-radius: 6px; border: 1px solid var(--line); background: var(--bg); color: var(--ink-dim); cursor: pointer; }
.product-grid.manage .pactions button:hover { color: var(--copper); border-color: var(--copper); }

.pos-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(230px, 280px); gap: 16px; align-items: start; }
/* Only collapse to a single column on genuinely phone-sized screens --
   the previous 900px threshold caught virtually every real POS tablet
   (iPad portrait is ~768-834px), pushing the cart out of its fixed
   sidebar position and into the normal scroll flow: the cashier would
   have to scroll past every product to reach checkout. */
@media (max-width: 580px) { .pos-grid { grid-template-columns: 1fr; } }
.pos-toolbar { margin-bottom: 14px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.pos-toolbar #posSearch { flex: 1 1 180px; min-width: 0; }
.pos-toolbar input { flex: 1; width: auto; }
.pos-toolbar .ghost-btn.small { white-space: nowrap; flex-shrink: 0; }
/* The cart stays fixed in place and reachable while products scroll
   beside it, instead of drifting away or ending up buried below a long
   product list -- this is the fix for "the cart floats/moves around" on
   tablets specifically. Works whether the nearest scrolling ancestor is
   .app-main (desktop/tablet) or the page itself (narrow/mobile mode,
   where .app-main switches to overflow:visible) -- position:sticky
   adapts to whichever applies. */
/* Cart panel: exactly ONE scrollbar.
   It used to be scrollable itself AND contain a separately scrollable item
   list, so two scrollbars sat stacked on top of each other and it was
   ambiguous which one a drag would move. The fix is to scroll at the PANEL
   level only and let the item list size naturally. Scrolling the inner list
   instead would have been wrong here: the summary block (discount, delivery
   fields, totals, payment methods) sits between the list and the button, so
   clipping the panel would strand those fields out of reach on a short
   screen -- worse than the original problem. */
.pos-cart {
  position: sticky; top: 12px; align-self: start;
  max-height: calc(100vh - 24px); max-height: calc(100dvh - 24px);
  overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column;
}
.pos-cart h3 { margin: 0 0 12px; color: var(--copper); font-size: 1rem; flex-shrink: 0; }
.cart-items {
  display: flex; flex-direction: column; gap: 8px;
  min-height: 60px; margin-bottom: 14px;
  /* Must not shrink: as a flex child it would otherwise be squeezed below
     its content height while its rows keep their own size, so the rows
     spilled out and rendered on top of the discount/totals fields below. */
  flex-shrink: 0;
}
.cart-summary, .pos-cart > select { flex-shrink: 0; }
/* Pinned to the bottom edge of the panel so it stays reachable however long
   the cart gets. The opaque backing band matters: as a sticky element the
   summary scrolls BEHIND it, and without a background the totals showed
   through the button and read as a rendering fault. */
.pos-cart #checkoutBtn {
  margin-top: auto; position: sticky; bottom: 0; flex-shrink: 0;
  box-shadow: 0 -10px 12px -6px var(--panel), 0 0 0 8px var(--panel);
}
/* Below the two-column breakpoint the cart stacks under the products, where
   constraining it to the viewport height serves no purpose -- it grows with
   its content and the page scrolls, still a single scrollbar. */
@media (max-width: 820px) {
  .pos-cart { position: static; max-height: none; overflow: visible; }
}
.cart-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.85rem; border-bottom: 1px solid var(--line); padding-bottom: 6px; }
.cart-row .qty-controls { display: flex; align-items: center; gap: 6px; }
.cart-row .qty-controls button { width: 22px; height: 22px; border-radius: 6px; border: 1px solid var(--line); background: var(--bg); color: var(--ink); cursor: pointer; }
.cart-row .qty-controls .cr-remove { margin-inline-start: 4px; font-size: 0.75rem; display: inline-flex; align-items: center; justify-content: center; }
.cart-row .qty-controls .cr-remove svg { display: block; }
.cart-row .qty-controls .cr-remove:hover { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent); }
.cart-summary { border-top: 1px dashed var(--line); padding-top: 12px; margin-top: 6px; }
.cart-summary label { font-size: 0.78rem; color: var(--ink-dim); }
.cart-summary input { width: 100%; margin: 6px 0 10px; }
.cart-line[hidden] { display: none; }
.cart-line { display: flex; justify-content: space-between; font-size: 0.85rem; padding: 4px 0; color: var(--ink-dim); }
.cart-line.total { color: var(--ink); font-weight: 800; font-size: 1.05rem; }
.pay-methods { display: flex; gap: 12px; margin: 14px 0; flex-wrap: wrap; font-size: 0.85rem; }
.pay-methods label { display: flex; align-items: center; gap: 6px; }
.empty-hint { color: var(--ink-dim); font-size: 0.85rem; text-align: center; padding: 20px 0; }
.empty-hint.illustrated, .emp-empty.illustrated { display: flex; flex-direction: column; align-items: center; gap: 10px; }
.empty-hint.illustrated img, .emp-empty.illustrated img { width: 72px; height: 72px; object-fit: cover; border-radius: 14px; border: 1px solid var(--line); filter: grayscale(0.5); }

.report-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; margin-bottom: 20px; }
@media (max-width: 700px) { .report-grid { grid-template-columns: 1fr; } }
.card.stat h2 { margin: 0; font-size: 1.8rem; }
.bars { display: flex; flex-direction: column; gap: 10px; }
.bars.tall { flex-direction: row; align-items: flex-end; gap: 8px; height: 160px; }
.bar-row { display: flex; align-items: center; gap: 10px; font-size: 0.82rem; }
.bar-row .bar-label { width: 80px; color: var(--ink-dim); flex-shrink: 0; }
.bar-row .bar-track { flex: 1; background: var(--bg); border-radius: 6px; overflow: hidden; height: 12px; }
.bar-row .bar-fill { height: 100%; background: linear-gradient(90deg, var(--copper-2), var(--copper)); }
.bars.tall .month-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 6px; }
.bars.tall .month-fill { width: 100%; background: linear-gradient(180deg, var(--copper-2), var(--copper)); border-radius: 4px 4px 0 0; min-height: 2px; }
.bars.tall .month-label { font-size: 0.68rem; color: var(--ink-dim); }

.emp-list { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 10px; }
.emp-list li { display: flex; justify-content: space-between; align-items: center; border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px; font-size: 0.9rem; gap: 10px; flex-wrap: wrap; }
.tag { font-size: 0.72rem; padding: 3px 9px; border-radius: 999px; background: color-mix(in srgb, var(--copper) 15%, transparent); color: var(--copper); font-weight: 700; }
.tag.off { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }

/* Professional stock-level indicator: a proportional bar (relative to
   2x the low-stock threshold, a genuinely useful "how close to running
   out" reference with zero extra setup) plus the exact remaining
   quantity in a color matching severity -- clearer than a plain in/out
   text tag alone. */
.inv-row { flex-direction: column; align-items: stretch !important; gap: 8px !important; }
.inv-row-main { display: flex; flex-direction: column; gap: 6px; }
.inv-name { font-weight: 600; }
.stock-bar-track { height: 6px; border-radius: 999px; background: color-mix(in srgb, var(--line) 60%, transparent); overflow: hidden; }
.stock-bar-fill { height: 100%; border-radius: 999px; transition: width 0.3s ease; }
.stock-bar-fill.healthy { background: var(--ok); }
.stock-bar-fill.low { background: #d4a017; }
.stock-bar-fill.out { background: var(--danger); }
.inv-row-side { display: flex; justify-content: space-between; align-items: center; }
.stock-qty { font-weight: 800; font-size: 1rem; }
.stock-qty small { font-weight: 500; font-size: 0.72rem; color: var(--ink-dim); }
.stock-qty.healthy { color: var(--ink); }
.stock-qty.low { color: #d4a017; }
.stock-qty.out { color: var(--danger); }

/* Date-group headers inside a plain emp-list -- a subtle divider, not a
   full list item, so scanning "which day was this expense" is instant. */
.list-date-header { border: none !important; background: none !important; padding: 4px 4px 0 !important; font-size: 0.72rem; font-weight: 700; color: var(--ink-dim); text-transform: uppercase; letter-spacing: 0.4px; }

.order-type-toggle { display: flex; align-items: center; gap: 8px; font-size: 0.88rem; font-weight: 600; padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; margin: 10px 0; cursor: pointer; transition: border-color 0.2s, background 0.2s; }
.order-type-toggle:has(input:checked) { border-color: var(--copper); background: color-mix(in srgb, var(--copper) 8%, transparent); }
.emp-empty { color: var(--ink-dim); font-size: 0.85rem; }

.plan-row { display: flex; gap: 10px; margin: 16px 0; flex-wrap: wrap; }
.plan-btn.active { border-color: var(--copper); color: var(--copper); }

/* Printable receipt — hidden on screen, shown only in the print dialog */
.receipt-print { display: none; }
/* Without this, a thermal receipt printer used through the browser's
   normal print dialog (rather than raw ESC/POS bytes) has no defined
   page size to work from, so it falls back to the printer driver's
   default -- typically A4 or Letter, ~297mm/279mm tall. Since a thermal
   printer feeds continuous roll paper rather than fixed sheets, it just
   keeps feeding BLANK paper trying to fill that height, producing an
   extremely long mostly-empty printout with the actual receipt content
   only at the very top. "auto" for the height is the fix: it tells the
   browser to size the page to exactly match the receipt's real content
   height, not a fixed paper-size default. The width should match
   whichever paper width the shop's printer actually uses; 80mm is the
   more common of the two supported widths, so it's the default here --
   a 58mm-only shop can still print fine on this since the receipt
   content itself doesn't exceed 58mm's usable width, it just leaves a
   bit of extra margin instead of being cut off. */
@page { size: 80mm auto; margin: 0; }

@media print {
  /* Scoped to a class the browser adapter toggles on <body> right
     before calling window.print() (see printerEngine.js), rather than
     a :has() selector -- :has() is only supported on fairly recent
     browser versions, and some budget Android POS tablets ship an
     embedded WebView old enough to not support it. Since an
     unsupported selector makes the WHOLE rule invalid (not just that
     one clause), that failure mode is silent and total: nothing gets
     hidden, so the entire page prints alongside the receipt overlay --
     which is exactly what "receipt prints cropped/mixed with other
     content" looks like. A plain class works on every browser, full
     stop. Still scoped (not a bare "hide everything" rule) for the
     same original reason: this stylesheet is also shared by menu.html,
     which never adds this class, so its printing is untouched. */
  body.nexa-printing-receipt * { visibility: hidden; }
  body.nexa-printing-receipt .receipt-print, body.nexa-printing-receipt .receipt-print * { visibility: visible; }
  /* Width is the printer's REAL printable area, not the raw paper
     width -- an 80mm thermal roll's actual printable zone is ~72mm
     (confirmed by this exact printer driver's own "80(72)mm" paper
     size option: the extra 8mm is a hardware margin no thermal head
     can reach). Sizing content to the full 80mm meant the far edge
     (the price, leftmost in this RTL layout) silently fell in that
     unprintable margin and was cut off by the printer itself --
     never visible in an on-screen preview, only on the actual paper.
     margin: 0 auto centers the narrower content within the full
     80mm @page so it isn't pushed to one side. */
  .receipt-print { display: block; position: fixed; inset: 0; padding: 14px 6px; font-family: 'IBM Plex Sans Arabic', 'Space Grotesk', monospace; font-weight: 600; color: #000; background: #fff; width: 272px; margin: 0 auto; line-height: 1.4; }
  /* 58mm ≈ 219px and 80mm ≈ 302px at 96dpi -- matches whichever width the
     shop actually configured (see printerEngine.js's dynamic @page
     injection, which sets the OS print dialog's page size to the same
     value at print time). */
  .receipt-print[data-paper-width="58mm"] { width: 189px; font-size: 0.85em; }

  .receipt-print .r-reprint-badge { text-align: center; font-weight: 800; border: 2px solid #000; padding: 3px; margin-bottom: 8px; letter-spacing: 1px; text-transform: uppercase; font-size: 0.75rem; }
  .receipt-print h3 { margin: 4px 0 2px; text-align: center; font-size: 1.15rem; font-weight: 800; letter-spacing: 1.5px; text-transform: uppercase; }
  .receipt-print .r-sub { text-align: center; font-size: 0.72rem; margin: 1px 0; color: #000; }
  /* Delivery info gets its own, noticeably larger size -- it was
     previously reusing the smallest text class on the receipt (meant
     for the store's own header subtext), which is why it read as too
     small; a courier reading this while standing at a door needs it
     to be easy to read at a glance. */
  .receipt-print .r-delivery-title { text-align: center; font-size: 0.95rem; font-weight: 800; margin: 6px 0 4px; }
  .receipt-print .r-delivery { text-align: center; font-size: 0.92rem; font-weight: 700; margin: 3px 0; color: #000; line-height: 1.5; }
  /* A solid divider bar -- the previous version used a repeating
     diamond-and-space text pattern, which is visually a broken/
     interrupted line; a plain solid rule prints as one continuous,
     unambiguous mark on a thermal head instead. */
  .receipt-print .r-divider { border: none; border-top: 2.5px solid #000; margin: 10px 0; height: 0; }
  .receipt-print hr { border: none; border-top: 2px solid #000; margin: 8px 0; }

  /* Order-number badge -- a small boxed "ticket stub" feel instead of a
     plain "#12" line lost among everything else. */
  .receipt-print .r-order-badge { display: flex; justify-content: space-between; align-items: center; border: 1.5px solid #000; border-radius: 3px; padding: 4px 8px; margin: 8px 0; font-size: 0.78rem; font-weight: 600; }
  .receipt-print .r-order-badge b { font-size: 1rem; font-weight: 800; }

  /* Item rows: bold name with a solid leader running to the price
     (previously dotted, which can print as faint disconnected specks
     on a thermal head) -- the classic organized menu/receipt look,
     makes a long item list feel intentional and easy to scan instead
     of a flat list of numbers. */
  .receipt-print .r-line { display: flex; align-items: baseline; gap: 4px; font-size: 0.84rem; padding: 3px 0; font-weight: 600; }
  .receipt-print .r-line .r-name { font-weight: 800; white-space: nowrap; overflow: hidden; }
  .receipt-print .r-line .r-dots { flex: 1; border-bottom: 1.2px solid #000; margin-bottom: 4px; min-width: 8px; }
  .receipt-print .r-line .r-amt { white-space: nowrap; font-variant-numeric: tabular-nums; font-weight: 700; }
  .receipt-print .r-mod { font-size: 0.68rem; color: #333; padding-inline-start: 14px; margin-top: -2px; }

  /* The total is the single most important number on the page -- boxed
     and enlarged so it's genuinely impossible to miss, not just another
     line the same size as everything else. */
  .receipt-print .r-total-box { border: 2px solid #000; border-radius: 4px; padding: 8px 10px; margin: 10px 0; display: flex; justify-content: space-between; align-items: center; }
  .receipt-print .r-total-box .r-total-label { font-size: 0.8rem; font-weight: 700; letter-spacing: 1px; text-transform: uppercase; }
  .receipt-print .r-total-box .r-total-amt { font-size: 1.25rem; font-weight: 800; }
  .receipt-print .r-line.r-discount { font-size: 0.75rem; color: #333; }
  .receipt-print .r-payment-tag { text-align: center; font-size: 0.72rem; letter-spacing: 0.5px; text-transform: uppercase; margin: 4px 0 8px; font-weight: 700; }

  .receipt-print .r-footer { text-align: center; font-size: 0.75rem; font-style: italic; margin: 10px 0 4px; }
  .receipt-print .r-close-mark { text-align: center; font-size: 0.9rem; letter-spacing: 4px; margin-top: 6px; }
  .receipt-print .r-close-mark::before { content: '✦'; }
}

/* Locked/expired subscription screen */
.locked-screen[hidden] { display: none; }
.locked-screen {
  min-height: 100vh; min-height: 100dvh; display: flex; align-items: center; justify-content: center; padding: 24px;
  background:
    radial-gradient(circle at 20% 20%, color-mix(in srgb, var(--accent, var(--copper)) 18%, transparent), transparent 45%),
    radial-gradient(circle at 80% 80%, color-mix(in srgb, var(--accent-2, var(--accent, var(--copper))) 14%, transparent), transparent 45%),
    var(--bg);
}
.locked-screen h2 { margin: 0 0 10px; font-size: 1.5rem; }
.locked-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 22px;
  padding: 40px 36px; box-shadow: 0 40px 80px var(--shadow); position: relative;
  max-width: 480px; width: 100%; text-align: center;
}
.locked-icon-wrap {
  width: 72px; height: 72px; border-radius: 50%; margin: 0 auto 18px;
  background: color-mix(in srgb, var(--accent, var(--copper)) 15%, transparent);
  display: flex; align-items: center; justify-content: center;
}
.locked-subtext { color: var(--ink-dim); font-size: 0.9rem; margin: 0 0 24px; }
.locked-not-you { position: absolute; top: 18px; inset-inline-end: 18px; font-size: 0.78rem; }

/* Pricing cards -- replaces plain unstyled buttons with a proper visual
   hierarchy: plan name, price prominent, clear call-to-action feel. */
.pricing-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 0 0 20px; }
.pricing-card {
  background: var(--bg); border: 1.5px solid var(--line); border-radius: 14px; padding: 16px 10px;
  cursor: pointer; transition: border-color 0.2s, transform 0.15s; text-align: center; font-family: inherit;
}
.pricing-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.pricing-card .plan-name { font-size: 0.8rem; color: var(--ink-dim); margin: 0 0 6px; }
.pricing-card .plan-price { font-size: 1.05rem; font-weight: 800; color: var(--ink); margin: 0; }

/* Recent orders / void action */
.emp-list .void-btn { font-size: 0.75rem; padding: 8px 12px; min-height: 36px; border-radius: 6px; border: 1px solid var(--danger); color: var(--danger); background: none; cursor: pointer; }
.emp-list .void-btn:hover { background: color-mix(in srgb, var(--danger) 12%, transparent); }
@media (pointer: coarse) {
  .emp-list .void-btn { min-height: 44px; padding: 10px 14px; }
}
@media (max-width: 480px) {
  .emp-list li { flex-direction: column; align-items: flex-start !important; gap: 10px; }
  .emp-list li > span:last-child { width: 100%; }
  .emp-list .void-btn { flex: 1 1 calc(50% - 6px); text-align: center; }
}
.tag.voided { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); text-decoration: line-through; }

/* Sidebar logo (custom upload or rotating artistic image) */
.side-logo { width: 22px; height: 22px; border-radius: 6px; object-fit: cover; border: 1px solid var(--line); }

/* Receipt logo/reprint badge (printer engine) */
.receipt-print .r-logo { max-width: 60px; display: block; margin: 0 auto 6px; }

/* Floor plan editor — real drag-and-drop canvas */
.floor-plan-toolbar { margin-bottom: 10px; }
.floor-plan-canvas {
  position: relative; width: 100%; min-height: 340px; background: var(--bg);
  border: 1px dashed var(--line); border-radius: 12px; overflow: hidden; touch-action: none;
}
.floor-table {
  position: absolute; width: 84px; height: 84px; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 2px; background: var(--panel);
  border: 2px solid var(--line); cursor: grab; user-select: none; touch-action: none;
  font-size: 0.78rem; text-align: center; padding: 4px; transition: box-shadow 0.15s;
}
.floor-table.shape-square { border-radius: 10px; }
.floor-table.shape-round { border-radius: 50%; }
.floor-table.shape-rect { width: 120px; height: 66px; border-radius: 8px; }
.floor-table.dragging { cursor: grabbing; box-shadow: 0 8px 20px rgba(0,0,0,0.35); z-index: 5; }
.floor-table .ft-label { font-weight: 800; }
.floor-table .ft-seats { color: var(--ink-dim); font-size: 0.68rem; }
@media (min-width: 700px) { .floor-plan-canvas { min-height: 460px; } }

/* Modifier selection modal — touch-friendly, never overflows the viewport */
.modal-overlay {
  position: fixed; inset: 0; background: rgba(0,0,0,0.55); z-index: 50;
  display: flex; align-items: flex-end; justify-content: center;
}
.modal-overlay[hidden] { display: none !important; }
@media (min-width: 640px) { .modal-overlay { align-items: center; } }
.modal-box {
  background: var(--panel); border: 1px solid var(--line); border-radius: 18px 18px 0 0;
  width: 100%; max-width: 480px; max-height: 88vh; overflow-y: auto; padding: 20px;
  box-shadow: 0 -10px 40px rgba(0,0,0,0.4);
}
@media (min-width: 640px) { .modal-box { border-radius: 18px; max-height: 80vh; } }

.modifier-group { margin-bottom: 18px; }
.modifier-group-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.modifier-group-head h4 { margin: 0; font-size: 0.95rem; }
.modifier-required-badge {
  font-size: 0.68rem; padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); font-weight: 700;
}
.modifier-optional-badge {
  font-size: 0.68rem; padding: 2px 8px; border-radius: 999px;
  background: color-mix(in srgb, var(--ink-dim) 15%, transparent); color: var(--ink-dim);
}
.modifier-option {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; margin-bottom: 8px;
  cursor: pointer; min-height: 44px; /* touch target */ transition: border-color 0.15s, background 0.15s;
}
.modifier-option:active { transform: scale(0.99); }
.modifier-option.selected { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.modifier-option input { width: 20px; height: 20px; flex-shrink: 0; }
.modifier-option .mo-name { flex: 1; font-size: 0.9rem; }
.modifier-option .mo-price { font-size: 0.82rem; color: var(--copper, var(--accent)); white-space: nowrap; }
.modifier-summary { border-top: 1px dashed var(--line); padding-top: 12px; margin: 14px 0; }

/* Cart line modifier sub-text */
.cart-row { align-items: flex-start; }
.cart-row .cr-info { display: flex; flex-direction: column; gap: 2px; }
.cart-row .cr-mods { font-size: 0.72rem; color: var(--ink-dim); }
.cart-row .cr-edit { background: none; border: none; color: var(--accent); font-size: 0.72rem; cursor: pointer; padding: 0; text-align: start; }

/* Receipt modifier sub-lines */
.receipt-print .r-mod { font-size: 0.68rem; color: #333; padding-inline-start: 12px; }

/* Split Bills mode buttons */
.split-mode-btn.selected { border-color: var(--accent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }

/* Responsive/touch fixes (phone/tablet/iPad audit) */

/* Admin dashboard stats: was a hardcoded inline 4-column grid that no
   media query could ever override (inline styles beat external CSS).
   Now a real responsive class: 4 columns desktop, 2 on tablet, 1 on phone. */
.dash-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
@media (max-width: 900px) { .dash-stats-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .dash-stats-grid { grid-template-columns: 1fr; } }

/* Cart qty +/- buttons were 22x22px -- well under the ~44px minimum
   reliable touch-target size (Apple/Google HIG guidance). Real problem
   for phone/tablet use specifically, not just a desktop cosmetic choice. */
.cart-row .qty-controls button { width: 36px; height: 36px; font-size: 1rem; }
@media (pointer: coarse) {
  .cart-row .qty-controls button { width: 44px; height: 44px; }
}

/* Floor plan: a table dragged to a position on a wide desktop screen must
   still be reachable (not clipped off-canvas) when the same layout is
   opened later on a narrower phone/tablet -- clamp on render, not just
   during drag. */
.floor-plan-canvas { overflow: auto; -webkit-overflow-scrolling: touch; }

/* General small-phone safety: prevent any residual horizontal scroll from
   a fixed-width element anywhere in the app. */
html, body { max-width: 100%; overflow-x: hidden; }

/* Subscription countdown card */
.sub-status-card { background: linear-gradient(135deg, var(--accent), var(--accent-2, var(--accent))); color: #fff; }
.sub-status-card .eyebrow { color: rgba(255,255,255,0.85); }
.sub-progress-track { width: 100%; height: 6px; background: rgba(255,255,255,0.25); border-radius: 999px; margin: 10px 0 16px; overflow: hidden; }
.sub-progress-fill { height: 100%; background: #fff; border-radius: 999px; transition: width 0.4s ease; }
.sub-countdown { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; text-align: center; }
.sub-countdown > div { background: rgba(0,0,0,0.18); border-radius: 10px; padding: 10px 4px; }
.sub-countdown span { display: block; font-size: 1.4rem; font-weight: 800; font-variant-numeric: tabular-nums; }
.sub-countdown small { font-size: 0.68rem; opacity: 0.85; }
@media (max-width: 420px) { .sub-countdown span { font-size: 1.1rem; } }

@keyframes toastIn { from { opacity: 0; transform: translateX(20px); } to { opacity: 1; transform: translateX(0); } }
@keyframes newOrderBannerSlide { from { transform: translateY(-100%); } to { transform: translateY(0); } }
/* Deliberately scoped to :not([hidden]) -- an unscoped "#newOrderBanner
   { display: flex }" would be an inline-style-equivalent override that
   always wins over the browser's own [hidden]{display:none} rule,
   which was the confirmed cause of a real reported bug: the banner
   never actually disappearing no matter what (dismiss button, the
   20-second auto-hide timer) since its visual display was controlled by
   this rule, not by the hidden attribute the code was correctly toggling. */
#newOrderBanner:not([hidden]) { display: flex; }

/* Seasonal themes -- platform-wide, applied via [data-season] on <html>,
   set only by the Super Admin (cms_settings.seasonal_theme). Off by
   default ('none' or no attribute at all means normal NEXA branding is
   completely untouched). Each theme shifts the accent colors and adds a
   small tasteful banner strip -- not a full graphic overhaul, since that's
   a much larger undertaking than a color/decoration layer. */
.season-banner { display: none; text-align: center; padding: 10px 12px; font-size: 0.78rem; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase; box-shadow: 0 2px 12px rgba(0,0,0,0.25); position: relative; z-index: 2; }
[data-season]:not([data-season="none"]) .season-banner { display: block; }
[data-season="christmas"] .season-banner { background: linear-gradient(90deg, #a8342a, #c0392b, #1e8449, #166638); color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
[data-season="ramadan"] .season-banner { background: linear-gradient(90deg, #3a2454, #4a2f6b, #96700a, #b8860b); color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
[data-season="eid"] .season-banner { background: linear-gradient(90deg, #0b7d62, #0e9c7a, #c9a02e, #d4af37); color: #06231b; text-shadow: 0 1px 1px rgba(255,255,255,0.25); }
[data-season="mothers_day"] .season-banner { background: linear-gradient(90deg, #d1638a, #e0779c, #8a5aa3, #9b6bb3); color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
[data-season="halloween"] .season-banner { background: linear-gradient(90deg, #1a0f2e, #ff7518, #1a0f2e, #6b2fa0); color: #ffb347; text-shadow: 0 0 6px rgba(255,117,24,0.6); }
[data-season="horror"] .season-banner { background: linear-gradient(90deg, #1a0000, #4a0000, #1a0000); color: #ff2b2b; text-shadow: 0 0 8px rgba(255,0,0,0.7); animation: horrorFlicker 3s infinite; }
[data-season="valentines"] .season-banner { background: linear-gradient(90deg, #8a1538, #e0245e, #ff6b9d, #e0245e); color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
[data-season="mens_day"] .season-banner { background: linear-gradient(90deg, #1a3a5c, #2c5f8a, #4a90c2); color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
[data-season="womens_day"] .season-banner { background: linear-gradient(90deg, #7b2d8e, #b04bc4, #e07bd4); color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.3); }
[data-season="luxury"] .season-banner { background: linear-gradient(90deg, #0a0a0a, #2a2410, #d4af37, #2a2410, #0a0a0a); color: #f4e5b8; text-shadow: 0 0 8px rgba(212,175,55,0.6); letter-spacing: 0.6px; }
[data-season="opulent_money"] .season-banner { background: linear-gradient(90deg, #0d2818, #1b5e20, #d4af37, #1b5e20, #0d2818); color: #fff2c9; text-shadow: 0 1px 3px rgba(0,0,0,0.5); }
/* Iraq: a refined, professional take rather than a flat flag-color slap
   -- deep crimson and near-black with a warm gold accent sweep, echoing
   the palette without looking like a literal flag banner. */
[data-season="iraq"] .season-banner { background: linear-gradient(90deg, #1a1a1a, #3a3a40, #2a2a2e, #3a3a40, #1a1a1a); color: #f0f0f2; text-shadow: 0 1px 3px rgba(0,0,0,0.6); }
/* NEXA Dark & NEXA Midnight Sky: restrained, near-monochrome gradients
   with a single accent sweep -- the "big company" look is precisely
   about NOT using many colors at once. */
[data-season="nexa_dark"] .season-banner { background: linear-gradient(90deg, #0d0620, #3d1f7a, #9b4fd6, #3d1f7a, #0d0620); color: #f0e6ff; text-shadow: 0 0 10px rgba(155,79,214,0.5); letter-spacing: 0.4px; }
[data-season="nexa_midnight_sky"] .season-banner { background: linear-gradient(90deg, #0d1128, #2b2467, #8b7fd6, #2b2467, #0d1128); color: #e8e4ff; text-shadow: 0 0 10px rgba(139,127,214,0.4); letter-spacing: 0.4px; }
/* Happiness: genuinely joyful multi-tone gradient (pink/yellow/turquoise)
   instead of a single flat orange -- paired with the confetti effect
   below for a real celebratory feel. */
[data-season="happiness"] .season-banner { background: linear-gradient(90deg, #ff6b9d, #ffd23f, #06d6a0, #ff6b9d); color: #1a1a2e; text-shadow: 0 1px 2px rgba(255,255,255,0.3); font-weight: 800; }
@keyframes horrorFlicker { 0%, 91%, 93%, 100% { opacity: 1; } 92% { opacity: 0.55; } 96% { opacity: 0.75; } }

/* Professional Aurora Mesh -- large, softly blurred gradient blobs that
   drift slowly and independently, blending into one another. This is the
   same technique behind Stripe/Linear/Vercel-style landing page
   backgrounds: understated, premium, and entirely typographic/geometric
   -- no emoji, no literal falling objects. Each theme only supplies its
   own two or three colors; the motion and blur are shared. */
.aurora-fx { position: fixed; inset: 0; pointer-events: none; z-index: 5; overflow: hidden; display: none; }
[data-season] .aurora-fx { display: block; }
.aurora-blob { position: absolute; border-radius: 50%; filter: blur(60px); opacity: 0.55; will-change: transform; }
.aurora-blob.b1 { width: 46vw; height: 46vw; top: -10%; inset-inline-start: -8%; background: radial-gradient(circle, var(--fx-c1, #666) 0%, transparent 70%); animation: auroraDrift1 22s ease-in-out infinite; }
.aurora-blob.b2 { width: 38vw; height: 38vw; bottom: -12%; inset-inline-end: -6%; background: radial-gradient(circle, var(--fx-c2, #444) 0%, transparent 70%); animation: auroraDrift2 26s ease-in-out infinite; }
.aurora-blob.b3 { width: 30vw; height: 30vw; top: 35%; inset-inline-start: 40%; background: radial-gradient(circle, var(--fx-c3, #888) 0%, transparent 70%); animation: auroraDrift3 30s ease-in-out infinite; }
/* Ambient background motion is deliberately DISABLED across every theme.
   The drifting blobs, twinkling stars and sweeping streaks previously ran
   on an infinite loop regardless of what the user was doing -- on a till
   tablet that is on all day, that reads as restless/unprofessional and
   burns GPU and battery continuously for zero functional benefit. The
   themes keep their colors and static texture; only the perpetual motion
   is gone, so the screen is completely still unless the user acts. */
.aurora-blob, .starfield, .data-streak, .s1, .s2, .s3 { animation: none !important; }
[data-season="horror"] .season-banner { animation: none !important; }
.aurora-blob { opacity: 0.35; }
.data-streak { opacity: 0.25; }
@keyframes auroraDrift1 { 0%, 100% { transform: none; } }
@keyframes auroraDrift2 { 0%, 100% { transform: none; } }
@keyframes auroraDrift3 { 0%, 100% { transform: none; } }

[data-season="halloween"] { --fx-c1: #ff7518; --fx-c2: #3a0a5c; --fx-c3: #ff4500; }
[data-season="luxury"] { --fx-c1: #d4af37; --fx-c2: #8a6d1a; --fx-c3: #f4e5b8; }
[data-season="opulent_money"] { --fx-c1: #1b5e20; --fx-c2: #d4af37; --fx-c3: #0d2818; }
[data-season="happiness"] { --fx-c1: #ff6b9d; --fx-c2: #ffd23f; --fx-c3: #06d6a0; }
[data-season="nexa_dark"] { --fx-c1: #9b4fd6; --fx-c2: #0d0620; --fx-c3: #c084f5; }
[data-season="nexa_midnight_sky"] { --fx-c1: #8b7fd6; --fx-c2: #2b2467; --fx-c3: #4a3f8f; }

/* Midnight Sky's real CSS starfield -- built entirely from layered
   radial-gradient background-images (a standard, well-established CSS
   technique for star/dot fields), not emoji. A slow, near-imperceptible
   twinkle via opacity keeps it feeling alive without being distracting. */
.starfield {
  position: absolute; inset: 0;
  background-image:
    radial-gradient(1.5px 1.5px at 10% 20%, #fff, transparent),
    radial-gradient(1px 1px at 25% 65%, #fff, transparent),
    radial-gradient(2px 2px at 40% 15%, #fff, transparent),
    radial-gradient(1px 1px at 55% 80%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 70% 35%, #fff, transparent),
    radial-gradient(1px 1px at 85% 60%, #fff, transparent),
    radial-gradient(2px 2px at 92% 12%, #fff, transparent),
    radial-gradient(1px 1px at 15% 90%, #fff, transparent),
    radial-gradient(1.5px 1.5px at 60% 50%, #fff, transparent),
    radial-gradient(1px 1px at 33% 40%, #fff, transparent);
  background-repeat: no-repeat;
  opacity: 0.7;
  animation: starTwinkle 4s ease-in-out infinite;
}
@keyframes starTwinkle { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.9; } }

/* NEXA Dark's signature effect: a faint circuit-style grid with glowing
   light streaks sweeping diagonally across it on a loop -- visually
   echoing the actual work of a POS system (transactions/data moving
   through in real time), not just decoration. The grid itself is a
   single repeating linear-gradient (a standard, lightweight CSS
   technique), and each streak is a thin glowing bar that travels the
   full diagonal at a different speed and delay for a layered feel. */
.circuit-grid {
  position: absolute; inset: 0; overflow: hidden;
  background-image:
    linear-gradient(rgba(99,102,241,0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(99,102,241,0.08) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 40%, #000 40%, transparent 100%);
}
.data-streak {
  position: absolute; top: -20%; width: 2px; height: 140%;
  background: linear-gradient(180deg, transparent, rgba(129,140,248,0.9), transparent);
  filter: blur(0.5px);
  transform: rotate(20deg);
  animation: dataFlow linear infinite;
}
.data-streak.d1 { left: 15%; animation-duration: 5s; animation-delay: 0s; }
.data-streak.d2 { left: 50%; animation-duration: 6.5s; animation-delay: 1.8s; }
.data-streak.d3 { left: 78%; animation-duration: 4.5s; animation-delay: 3.2s; }
@keyframes dataFlow {
  0%   { transform: rotate(20deg) translateY(-60%); opacity: 0; }
  10%  { opacity: 1; }
  90%  { opacity: 1; }
  100% { transform: rotate(20deg) translateY(60%); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .data-streak { animation: none; opacity: 0; } }

.version-badge { display: inline-block; font-size: 0.68rem; color: var(--ink-dim); background: color-mix(in srgb, var(--line) 60%, transparent); border-radius: 20px; padding: 2px 9px; margin-inline-start: 8px; font-weight: 600; letter-spacing: 0.3px; }

/* Primary call-to-action -- a quiet, confident, solid-color button.
   Previously an "ink stamp" with a press bounce and ripple bloom;
   that read as playful rather than the formal, trustworthy tone the
   product now calls for, so this version is deliberately restrained:
   one solid fill in the shop's own brand color, a small amount of
   letter-spacing for a considered typographic feel, and only the
   subtlest press feedback. */
.shimmer-btn {
  border-radius: 8px; border: none; cursor: pointer;
  padding: 14px 32px; font-family: inherit; font-size: 0.95rem; font-weight: 700; letter-spacing: 0.3px;
  color: #fff; background: var(--copper);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--copper) 35%, transparent);
  transition: background 0.2s ease, box-shadow 0.2s ease, transform 0.12s ease;
}
.shimmer-btn:hover { background: color-mix(in srgb, var(--copper) 90%, black); box-shadow: 0 4px 16px color-mix(in srgb, var(--copper) 45%, transparent); }
.shimmer-btn:active { transform: scale(0.98); }
.shimmer-btn.full { width: 100%; }

/* =====================================================================
   Enterprise data table + dropdown action menu (Super Admin shops list).
   Replaces the old scattered-buttons-per-row list with a proper table:
   fixed columns, one row per shop, one compact action menu per row.
   ===================================================================== */
.shops-toolbar { display: flex; align-items: center; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; }
.shops-toolbar input[type="search"] { flex: 1; min-width: 200px; margin-bottom: 0; }
.filter-tabs { display: flex; gap: 4px; flex-wrap: wrap; background: var(--bg-2); padding: 5px; border-radius: 12px; border: 1px solid var(--line); }
.filter-tabs.compact-rows { flex-wrap: nowrap; overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; padding-bottom: 4px; }
.filter-tabs.compact-rows .filter-tab { flex-shrink: 0; }
.filter-tab {
  font-family: inherit; font-size: 0.82rem; font-weight: 600; padding: 8px 14px; border-radius: 8px;
  border: 1px solid transparent; background: none; color: var(--ink-dim); cursor: pointer; transition: all 0.15s; white-space: nowrap;
}
.filter-tab:hover { color: var(--copper); }
.filter-tab.active { background: var(--panel); border-color: var(--line); color: var(--copper); box-shadow: 0 2px 6px var(--shadow); }

.shops-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 12px; background: var(--panel); }
.shops-table { width: 100%; border-collapse: collapse; font-size: 0.87rem; min-width: 820px; }
.shops-table th {
  text-align: start; padding: 12px 16px; font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--ink-dim); font-weight: 700; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--line) 30%, transparent);
  white-space: nowrap;
}
.shops-table td { padding: 14px 16px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.shops-table tbody tr:last-child td { border-bottom: none; }
.shops-table tbody tr:hover { background: color-mix(in srgb, var(--copper) 4%, transparent); }
.shop-name-cell { display: flex; align-items: center; gap: 10px; font-weight: 700; }
.shop-name-cell .shop-logo { width: 32px; height: 32px; border-radius: 8px; object-fit: cover; flex-shrink: 0; }
.shop-name-cell .shop-logo-fallback { width: 32px; height: 32px; border-radius: 8px; background: var(--line); display: flex; align-items: center; justify-content: center; font-size: 0.7rem; color: var(--ink-dim); flex-shrink: 0; }
.shop-meta-row { font-size: 0.76rem; color: var(--ink-dim); font-weight: 400; margin-top: 2px; }
.status-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 0.72rem; font-weight: 700; padding: 4px 10px; border-radius: 999px; }
.status-badge.status-active { background: color-mix(in srgb, var(--ok) 18%, transparent); color: var(--ok); }
.status-badge.status-trial { background: color-mix(in srgb, var(--copper) 15%, transparent); color: var(--copper); }
.status-badge.status-suspended { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }
.badge-new { background: var(--ok); color: #06231b; font-size: 0.62rem; font-weight: 800; padding: 2px 7px; border-radius: 999px; margin-inline-start: 6px; }

/* Action dropdown -- one compact "..." trigger per row instead of a wall
   of buttons; menu opens as a floating panel, closes on click-outside
   (reusing the same interaction pattern as the notification bell). */
.action-menu-trigger {
  width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--line); background: none;
  color: var(--ink-dim); cursor: pointer; font-size: 1.1rem; line-height: 1; display: flex; align-items: center; justify-content: center;
}
.action-menu-trigger:hover { border-color: var(--copper); color: var(--copper); }
.action-menu {
  position: fixed; z-index: 50; min-width: 220px; background: var(--panel); border: 1px solid var(--line);
  border-radius: 10px; box-shadow: 0 12px 32px var(--shadow); padding: 6px; display: flex; flex-direction: column; gap: 2px;
}
.action-menu button {
  font-family: inherit; text-align: start; background: none; border: none; color: var(--ink); font-size: 0.85rem;
  padding: 9px 12px; border-radius: 7px; cursor: pointer; display: flex; align-items: center; gap: 8px; width: 100%;
}
.action-menu button:hover { background: color-mix(in srgb, var(--copper) 10%, transparent); }
.action-menu button.danger-action { color: var(--danger); }
.action-menu button.danger-action:hover { background: color-mix(in srgb, var(--danger) 10%, transparent); }
.action-menu button:disabled { opacity: 0.4; cursor: not-allowed; }
.action-menu button:disabled:hover { background: none; }
.action-menu .menu-divider { height: 1px; background: var(--line); margin: 4px 2px; }
.action-menu .menu-days-input { display: flex; gap: 6px; padding: 6px 8px; align-items: center; }
.action-menu .menu-days-input input { width: 60px; padding: 6px 8px; font-size: 0.8rem; margin: 0; }

/* =====================================================================
   Freshness Monitor -- bakery/pastry shelf-life countdown timers. Cards
   shift color as they approach expiry (calm -> warning -> urgent), with a
   pulsing animation only in the urgent zone so it's impossible to miss
   without being distracting the rest of the time.
   ===================================================================== */
.freshness-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.freshness-card { border-radius: 14px; padding: 16px; border: 2px solid var(--line); background: var(--panel); text-align: center; transition: border-color 0.3s, background 0.3s; }
.freshness-card.fresh { border-color: var(--ok); }
.freshness-card.warning { border-color: #d4a017; }
.freshness-card.urgent { border-color: var(--danger); background: color-mix(in srgb, var(--danger) 8%, var(--panel)); animation: freshnessPulse 1.2s ease-in-out infinite; }
@keyframes freshnessPulse { 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--danger) 40%, transparent); } 50% { box-shadow: 0 0 0 8px transparent; } }
.freshness-card .fc-name { font-weight: 800; font-size: 0.95rem; margin-bottom: 4px; }
.freshness-card .fc-qty { font-size: 0.75rem; color: var(--ink-dim); margin-bottom: 10px; }
.freshness-card .fc-timer { font-size: 1.6rem; font-weight: 900; font-variant-numeric: tabular-nums; }
.freshness-card.fresh .fc-timer { color: var(--ok); }
.freshness-card.warning .fc-timer { color: #d4a017; }
.freshness-card.urgent .fc-timer { color: var(--danger); }
.freshness-card .fc-expired { font-size: 0.85rem; font-weight: 800; color: var(--danger); }

.delivery-info-block[hidden] { display: none; }
.delivery-info-block { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }

/* Kitchen-ticket field toggles (owner settings).
   Each option is a full clickable row rather than a bare checkbox: these are
   tapped on a counter tablet, where a 13px checkbox alone is an unreliable
   target. */
.kt-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.86rem;
  user-select: none;
}
.kt-opt:hover { border-color: var(--copper); }
.kt-opt input { flex: 0 0 auto; width: 17px; height: 17px; cursor: pointer; }
.kt-opt span { flex: 1; }

/* ---------- Daily shift report ---------- */
.shift-report-block { margin-bottom: 18px; }
.shift-report-block h4 {
  margin: 14px 0 6px;
  font-size: 0.98rem;
  color: var(--copper);
}
table.report-inline-table {
  width: 100%;
  border-collapse: collapse;
  margin: 6px 0 10px;
  font-size: 0.85rem;
}
table.report-inline-table td,
table.report-inline-table th {
  padding: 7px 8px;
  border-bottom: 1px solid var(--line);
  text-align: start;
}
table.report-inline-table th {
  font-weight: 700;
  opacity: 0.8;
  font-size: 0.8rem;
}
/* The report is a wide table on a narrow till screen, so it scrolls
   horizontally rather than squashing columns into unreadable slivers. */
#shiftDayReportBody { overflow-x: auto; }

/* ---------- Simplified inventory entry ---------- */
.simple-step { margin-bottom: 16px; }
.simple-q {
  display: block;
  font-weight: 700;
  font-size: 0.9rem;
  margin-bottom: 7px;
}
.simple-step input,
.simple-step select { width: 100%; }
.choice-row { display: flex; gap: 8px; flex-wrap: wrap; }
/* Big tap targets: these are pressed on a counter tablet, often in a hurry
   and sometimes with wet hands, where a small radio button is unusable. */
.choice-btn {
  flex: 1;
  min-width: 96px;
  padding: 13px 10px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: transparent;
  color: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
  transition: border-color .15s, background .15s;
}
.choice-btn:hover { border-color: var(--copper); }
.choice-btn.selected {
  border-color: var(--copper);
  background: color-mix(in srgb, var(--copper) 16%, transparent);
  color: var(--copper);
}
.simple-summary {
  margin: 4px 0 14px;
  font-size: 0.84rem;
  line-height: 1.8;
  opacity: 0.85;
  min-height: 1.2em;
}

/* ---------- Shelf-life card actions ---------- */
.fc-actions {
  display: flex;
  gap: 6px;
  margin-top: 10px;
}
.fc-btn {
  flex: 1;
  padding: 8px 6px;
  border-radius: 8px;
  border: 1px solid currentColor;
  background: transparent;
  color: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  cursor: pointer;
  opacity: 0.85;
}
.fc-btn:hover { opacity: 1; }
.fc-btn.waste { color: var(--danger); }
.fc-btn.done { color: var(--ok); }

/* ---------- Sign-in wordmark (replaced the decorative arch) ---------- */
.auth-brand {
  text-align: center;
  margin: 0 auto 26px;
  line-height: 1;
}
.auth-brand-mark {
  display: block;
  font-size: clamp(2.1rem, 7vw, 2.9rem);
  font-weight: 800;
  letter-spacing: 0.22em;
  /* Letter-spacing adds trailing space after the last glyph, which makes a
     centred wordmark sit visibly left of centre. */
  text-indent: 0.22em;
  background: linear-gradient(120deg, var(--copper-2), var(--copper) 55%, #c2478f);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.auth-brand-sub {
  display: block;
  margin-top: 10px;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  color: var(--ink-dim);
}
