/* ============================================================
   Kautilya POS — design system
   Calyirex "pos-*" token set: warm paper canvas, cool dark ink,
   a single deep-green brand/action hue, semantic state colors.
   Cut-corner cards and numbered blocks carried over from the
   original Elementum-inspired layout language.
   ============================================================ */

:root{
  /* canvas & surfaces */
  --pos-canvas:          #faf8f5;
  --pos-surface:         #ffffff;
  --pos-surface-sunken:  #f4f1ea;
  --pos-hairline:        #e7e2d9;
  --pos-hairline-strong: #d8d2c6;

  /* ink */
  --pos-ink:         #141a24;
  --pos-ink-2:       #5a6472;
  --pos-ink-3:       #8b94a3;
  --pos-ink-inverse: #fbfaf7;

  /* brand — the single action hue */
  --pos-brand:        #0e6b4f;
  --pos-brand-rgb:    14,107,79;
  --pos-brand-strong: #0b5a42;
  --pos-brand-tint:   #e9f4ef;
  --pos-brand-ink:    #ffffff;

  /* semantic states */
  --pos-success:      #0e6b4f;
  --pos-success-tint: #e9f4ef;
  --pos-danger:       #b3261e;
  --pos-danger-tint:  #fbeae8;
  --pos-warn:         #b45309;
  --pos-warn-tint:    #fdf1e3;
  --pos-info:         #1d4ed8;
  --pos-info-tint:    #e8eefb;

  --shadow-card: 0 1px 2px rgba(20,26,36,.04), 0 14px 32px -18px rgba(20,26,36,.14);

  --radius:        14px;
  --cut:           18px;
  --maxw:          clamp(1180px, 88vw, 1320px);

  --font-display:  'Geist', 'Segoe UI', sans-serif;
  --font-body:      'Geist', 'Segoe UI', sans-serif;
  --font-mono:      'Geist Mono', ui-monospace, monospace;

  --ease: cubic-bezier(.16,.8,.28,1);

  /* motion system — three curves max, "physical" personality:
     spring for entrances + card interaction, --ease for state
     changes (accordion/nav/tabs), --ease-snap for small utility
     feedback (links, icons, buttons). */
  --ease-spring: linear(
    0, 0.009, 0.035 2.1%, 0.141 4.4%, 0.723 12.9%,
    0.938 16.7%, 1.017 19.4%, 1.067 22.5%, 1.089 26.0%,
    1.079 30.3%, 1.049 36.0%, 1.024 42.6%, 1.011 50.3%,
    1.004 59.2%, 1.001 69.3%, 1
  );
  --ease-snap: cubic-bezier(0.22, 1, 0.36, 1);
}

*, *::before, *::after{ box-sizing: border-box; }
html{ color-scheme: light; scroll-behavior: smooth; }
body{
  margin: 0;
  background: var(--pos-canvas);
  color: var(--pos-ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img{ max-width: 100%; display: block; }
a{ color: inherit; text-decoration: none; }
ul{ margin: 0; padding: 0; list-style: none; }
h1,h2,h3,h4,h5{ font-family: var(--font-display); font-weight: 600; margin: 0; line-height: 1.08; letter-spacing: -0.01em; }
p{ margin: 0; }
button{ font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

.wrap{ max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }

.skip-link{
  position: absolute; left: -999px; top: 0; z-index: 999;
  background: var(--pos-brand); color: var(--pos-brand-ink); padding: 12px 18px; border-radius: 8px;
}
.skip-link:focus{ left: 24px; top: 24px; }

.accent-text{ color: var(--pos-brand); }

/* stat/section background texture */
body{
  background-image:
    radial-gradient(ellipse 900px 500px at 15% -10%, rgba(var(--pos-brand-rgb),.06), transparent 60%),
    radial-gradient(ellipse 700px 500px at 100% 10%, rgba(var(--pos-brand-rgb),.04), transparent 60%);
  background-repeat: no-repeat;
}

/* ---------- buttons ---------- */
.btn{
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 13px 26px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.95rem;
  border: 1px solid transparent;
  transition: transform .18s var(--ease), background-color .18s var(--ease), border-color .18s var(--ease), color .18s var(--ease);
  white-space: nowrap;
}
.btn:hover{ transform: translateY(-1px); }
.btn:active{ transform: translateY(0); }

.btn-accent{ background: var(--pos-brand); color: var(--pos-brand-ink); }
.btn-accent:hover{ background: var(--pos-brand-strong); }

.btn-outline{ border-color: var(--pos-hairline-strong); color: var(--pos-ink); }
.btn-outline:hover{ border-color: var(--pos-brand); color: var(--pos-brand); }

.btn-ghost{ color: var(--pos-ink); padding: 13px 18px; }
.btn-ghost:hover{ color: var(--pos-brand); }

.btn-lg{ padding: 16px 32px; font-size: 1rem; }
.btn-block{ width: 100%; }

/* ---------- page loader ---------- */
.page-loader{
  position: fixed; inset: 0; z-index: 999;
  display: flex; align-items: center; justify-content: center;
  background: var(--pos-canvas);
  opacity: 1;
  transition: opacity .5s var(--ease);
}
.page-loader.is-hidden{ opacity: 0; pointer-events: none; }

.loader-inner{ display: flex; flex-direction: column; align-items: center; gap: 14px; }
.loader-mark{ width: 78px; height: auto; overflow: visible; }
.loader-paper{ animation: loader-print 1.3s var(--ease) infinite; }
.loader-name{
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.5rem; color: var(--pos-ink);
  letter-spacing: -0.01em;
}
.loader-bar{
  width: 160px; height: 3px; border-radius: 999px;
  background: var(--pos-hairline-strong);
  overflow: hidden;
}
.loader-bar span{
  display: block; height: 100%; width: 40%; border-radius: inherit;
  background: var(--pos-brand);
  animation: loader-sweep 1s var(--ease) infinite;
}
.loader-credit{
  margin-top: 6px;
  font-size: .78rem; color: var(--pos-ink-3);
  transition: color .15s;
}
.loader-credit:hover{ color: var(--pos-brand); }

@keyframes loader-print{
  0%   { transform: translateY(-36px) rotate(0deg); }
  50%  { transform: translateY(-16px) rotate(1.2deg); }
  100% { transform: translateY(-36px) rotate(0deg); }
}
@keyframes loader-sweep{
  0%{ transform: translateX(-110%); }
  100%{ transform: translateX(260%); }
}
@media (prefers-reduced-motion: reduce){
  .loader-paper{ animation: none; transform: translateY(-24px); }
  .loader-bar span{ animation: none; }
}

/* ---------- header ---------- */
.site-header{
  position: sticky; top: 0; z-index: 100;
  background: rgba(250,248,245,.82);
  backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid var(--pos-hairline);
}
.header-inner{
  display: flex; align-items: center; justify-content: space-between;
  height: 76px;
  gap: 24px;
}
.logo{ display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.logo-icon{ width: 26px; height: 26px; color: var(--pos-brand); flex-shrink: 0; }
.logo-text{ display: flex; align-items: baseline; gap: 11px; }
.logo-main{
  font-family: 'Poppins', var(--font-display), sans-serif;
  font-weight: 800; font-size: 1.02rem; letter-spacing: .05em;
  text-transform: uppercase; color: var(--pos-brand);
  transition: opacity .15s var(--ease-snap);
}
.logo-main:hover{ opacity: .75; }
.logo-product{ font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; color: var(--pos-ink); transition: color .15s var(--ease-snap); }
.logo-product:hover{ color: var(--pos-brand); }
/* .logo-sep is gone (owner, 16 Sep): the separator dot was dropped from
   the lockup. The space between "Calyirex" and "Kautilya POS" is now the
   .logo-text flex gap alone, widened a little to keep the two names from
   reading as one phrase now that nothing divides them. */

.text-link{ text-decoration: underline; text-underline-offset: 2px; text-decoration-color: currentColor; opacity: .85; transition: opacity .15s var(--ease-snap); }
.text-link:hover{ opacity: 1; }

.main-nav{ display: flex; gap: 32px; margin-right: auto; margin-left: 48px; }
/* Nav, the product name and Sign in all sat on --pos-ink-2 (#5a6472),
   which reads as grey rather than as navigation. Moved to --pos-ink and
   half a weight up (owner, 16 Sep). Hover keeps a target by going to the
   brand green instead of ink, which it can no longer darken to. */
.main-nav a{ color: var(--pos-ink); font-size: .93rem; font-weight: 600; transition: color .15s; }
.main-nav a:hover{ color: var(--pos-brand); }

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

.nav-toggle{ display: none; flex-direction: column; gap: 5px; padding: 8px; }
.nav-toggle span{ width: 22px; height: 2px; background: var(--pos-ink); border-radius: 2px; }

.mobile-nav{
  display: none; flex-direction: column; gap: 4px;
  padding: 12px 24px 24px;
  border-bottom: 1px solid var(--pos-hairline);
  background: var(--pos-canvas);
}
.mobile-nav a{ padding: 12px 4px; color: var(--pos-ink-2); border-bottom: 1px solid var(--pos-hairline); }
.mobile-nav .btn{ margin-top: 12px; }

/* ---------- eyebrow / section head ---------- */
.eyebrow{
  display: inline-flex; align-items: center; gap: 10px;
  font-size: .82rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--pos-ink-2);
  margin-bottom: 18px;
}
.section-head{ max-width: 640px; margin-bottom: 56px; }
.section-head h2{ font-size: clamp(1.9rem, 3.4vw, 2.6rem); }

section{ padding: 110px 0; }
section + section{ border-top: 1px solid var(--pos-hairline); }

/* ---------- hero ---------- */
.hero{ padding-top: 90px; overflow: hidden; }
.hero-inner{
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  align-items: center;
  gap: 56px;
}
.hero h1{
  font-size: clamp(2.4rem, 5vw, 3.6rem);
  margin: 4px 0 26px;
}
.hero-sub{
  font-size: 1.08rem;
  color: var(--pos-ink-2);
  max-width: 480px;
  margin-bottom: 40px;
}
.hero-ctas{ display: flex; gap: 14px; flex-wrap: wrap; }

.trust-badges{
  display: flex; flex-wrap: wrap; gap: 10px 20px;
  margin-top: 28px;
}
.trust-badges li{
  display: flex; align-items: center; gap: 7px;
  font-size: .84rem; color: var(--pos-ink-2); font-weight: 500;
}
.badge-icon{ width: 16px; height: 16px; flex-shrink: 0; color: var(--pos-brand); }
.flag-in{
  display: inline-block;
  width: 18px; height: 12px;
  border-radius: 2px;
  overflow: hidden;
  flex-shrink: 0;
  background: linear-gradient(
    to bottom,
    #FF9933 0%, #FF9933 33%,
    #FFFFFF 33%, #FFFFFF 66%,
    #138808 66%, #138808 100%
  );
  box-shadow: 0 0 0 1px var(--pos-hairline-strong) inset;
}

.hero-visual{ display: flex; justify-content: center; perspective: 1200px; }

/* ---------- hero: big printer + receipt photo/stack ---------- */
.receipt-print-unit{
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 320px;
}
.receipt-printer{
  width: 100%;
  height: auto;
  position: relative;
  z-index: 2;
  filter: drop-shadow(0 10px 16px rgba(20,26,36,.20));
}
.printer-label{
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 10px;
  letter-spacing: .3px;
  fill: var(--pos-brand-ink);
}
.printer-sublabel{
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 5.5px;
  letter-spacing: .1px;
  fill: var(--pos-brand-ink);
  opacity: .65;
}
.printer-link{ cursor: pointer; }
.printer-link .printer-sublabel{ transition: opacity .15s var(--ease-snap); }
.printer-link:hover .printer-sublabel{ opacity: 1; }
.printer-link:focus-visible{
  outline: 2px solid var(--pos-brand-ink);
  outline-offset: 3px;
  border-radius: 3px;
}

.receipt-stack{
  position: relative;
  width: 100%;
  margin-top: -7px;
  z-index: 1;
}
/* "prints out of the machine" entrance — the big printer above is a fixed,
   always-visible anchor, so the stack itself can start fully hidden and
   unroll downward out from under it. Only armed by JS (see js/main.js), so
   a no-JS visitor always just sees the stack fully in place, never stuck
   hidden. */
.receipt-stack.js-print-armed{
  clip-path: inset(0 0 100% 0);
  transform: translateY(-6px);
  transition: clip-path .85s linear, transform .85s var(--ease-spring);
}
.receipt-stack.js-print-armed.is-visible{
  clip-path: inset(0 0 0% 0);
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce){
  .receipt-stack.js-print-armed,
  .receipt-stack.js-print-armed.is-visible{ clip-path: none; transform: none; transition: none; }
}
.receipt-photo{
  position: relative;
  z-index: 3;
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius);
  /* base shadow + a soft inset crease along the top edge, where the paper
     has just folded off the printer's slot */
  box-shadow: var(--shadow-card), inset 0 7px 6px -6px rgba(20,26,36,.28);
  transform: rotate(1.2deg);
  transform-style: preserve-3d;
  transform-origin: top center;
  will-change: transform;
  transition: transform .5s cubic-bezier(.22,1,.36,1), box-shadow .4s var(--ease);
}
.receipt-photo.is-tilting{ transition: transform .08s linear; }
.receipt-photo:hover{ box-shadow: 0 10px 20px rgba(20,26,36,.08), 0 32px 60px -20px rgba(20,26,36,.28), inset 0 7px 6px -6px rgba(20,26,36,.28); }

/* brief physical "flex" as the paper fully releases from the slot —
   played once via JS on the reveal's transitionend, not looped */
.receipt-photo.is-settling{ animation: receipt-settle .5s var(--ease-snap); }
@keyframes receipt-settle{
  0%   { transform: rotate(1.2deg) scaleY(1); }
  35%  { transform: rotate(1.2deg) scaleY(.985) translateY(2px); }
  70%  { transform: rotate(1.2deg) scaleY(1.006); }
  100% { transform: rotate(1.2deg) scaleY(1); }
}
@media (prefers-reduced-motion: reduce){
  .receipt-photo.is-settling{ animation: none; }
}

.receipt-ghost{
  position: absolute;
  top: 0; left: 50%;
  width: 92%;
  aspect-ratio: 1010 / 1558;
  background:
    linear-gradient(var(--pos-hairline), var(--pos-hairline)) no-repeat 14% 21% / 68% 2px,
    linear-gradient(var(--pos-hairline), var(--pos-hairline)) no-repeat 14% 27% / 68% 2px,
    linear-gradient(var(--pos-hairline), var(--pos-hairline)) no-repeat 14% 33% / 50% 2px,
    var(--pos-surface);
  border: 1px solid var(--pos-hairline-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  transition: transform .5s cubic-bezier(.22,1,.36,1);
}
.receipt-ghost.is-tilting{ transition: transform .08s linear; }
.receipt-ghost-1{ z-index: 2; transform: translateX(-50%) rotate(-7deg) translateY(10px); }
.receipt-ghost-2{ z-index: 1; width: 86%; transform: translateX(-50%) rotate(10deg) translateY(16px); opacity: .85; }


@media (prefers-reduced-motion: reduce){
  .receipt-photo, .receipt-ghost{ transition: none; }
}

/* ---------- positioning strip ---------- */
.positioning-inner{
  display: grid;
  grid-template-columns: minmax(0, 460px) minmax(0, 1fr);
  align-items: center;
  gap: 40px;
  text-align: left;
}
.positioning h2{ font-size: clamp(1.9rem, 3.6vw, 2.7rem); margin-bottom: 48px; }
.positioning-stat{
  display: flex; align-items: center; justify-content: flex-start;
  gap: 40px; flex-wrap: wrap;
  margin-bottom: 28px;
}
.positioning-copy .fine-print{ margin: 0; }
.stat-block{
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  background: var(--pos-surface);
  border: 1px solid var(--pos-hairline);
  box-shadow: var(--shadow-card);
  padding: 32px 40px;
  min-width: 260px;
  text-align: left;
}
.stat-accent{ border-color: rgba(var(--pos-brand-rgb),.35); background: linear-gradient(160deg, var(--pos-brand-tint), var(--pos-surface) 60%); }
.stat-label{ display: block; font-size: .82rem; color: var(--pos-ink-2); margin-bottom: 10px; }
.stat-value{ display: block; font-family: var(--font-display); font-size: 2.4rem; font-weight: 700; color: var(--pos-brand); }
.stat-value.stat-muted{ color: var(--pos-ink); font-size: 1.3rem; font-weight: 600; line-height: 1.3; }
.stat-unit{ display: block; font-size: .8rem; color: var(--pos-ink-3); margin-top: 6px; }
.stat-divider{ color: var(--pos-ink-3); font-family: var(--font-mono); font-size: .85rem; text-transform: uppercase; letter-spacing: .1em; }

.fine-print{ color: var(--pos-ink-3); font-size: .82rem; max-width: 620px; margin: 0 auto; }
.fine-print.center{ text-align: center; margin-top: 36px; }

/* ---------- positioning showcase: fanned dashboard mockups ----------
   Illustrative only — fictional "Sunrise Cafe" figures, not a real
   client's data. Modelled on Kautilya's Reports tab (stat row, sales
   trend, item heatmap, busiest-hours chart) but redrawn from scratch,
   never a screenshot. */
.positioning-showcase{
  position: relative;
  min-height: 580px;
  perspective: 1400px;
}
.showcase-panel{
  position: absolute;
  width: min(300px, 80%);
  background: var(--pos-surface);
  border: 1px solid var(--pos-hairline-strong);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
  cursor: pointer;
  padding: 18px 20px 20px;
  opacity: 0;
  transition: transform .9s var(--ease-spring), opacity .7s var(--ease-spring);
  will-change: transform;
}
/* fan order, back to front: e (left-inner) — a (centre) — d (right-inner) —
   c (far right), with b (far left, "Sales breakdown") pinned frontmost so
   its overlap with the centre card never hides it.

   The right-hand pair, c and f, is tightened at >=1500px only - see the
   min-width block just below the panel list. Everything here is the fan as
   originally drawn. */
.panel-b{ left: -1%; top: -8%; z-index: 1; width: min(240px, 64%); transform: rotate(-3deg) translateY(6px) scale(.92); }
.panel-e{ left: 6%; top: 41%; z-index: 2; width: min(250px, 66%); transform: rotate(-3deg) translateY(6px) scale(.92); }
.panel-a{ left: 30%; top: -4%; z-index: 5; transform: rotate(0deg) translateY(6px) scale(.92); }
.panel-d{ left: 34%; top: 24%; z-index: 3; width: min(250px, 66%); transform: rotate(3deg) translateY(6px) scale(.92); }
.panel-c{ right: -5%; top: 1%; z-index: 4; width: min(230px, 62%); transform: rotate(3deg) translateY(6px) scale(.92); }
.panel-f{ right: -7%; top: 32%; z-index: 2; width: min(270px, 70%); transform: rotate(-2deg) translateY(6px) scale(.92); }

/* --maxw is clamp(1180px, 88vw, 1320px), so 88vw stops growing at exactly
   1500px of viewport: at and above that the showcase column is frozen at
   772px and the fan's geometry stops changing. That is the only band where
   a fixed offset can hold a fixed gap, and it is the band the cards were
   complained about in on 4 Sep - c ("Busiest hours") and f (the WhatsApp
   bill) sat far enough right to leave a channel of empty page between them
   and the centre column, which read as a hole in the fan rather than part
   of it.

   Measured, not eyeballed: each panel was rendered alone as a flat
   silhouette and the pair compared row by row, which is the only way to get
   the true edge of a rotated card that also casts a shadow. At -5%/-7% the
   closest approach was 32px (a -> c) and 42px (d -> f); at -1%/-2% it is
   1px and 3px. Touching, not overlapping.

   Below 1500px the column shrinks while these cards keep their fixed px
   widths, so the fan closes on its own and this pair already overlaps by
   1450px. That is pre-existing and deliberately left alone: only c and f
   move, and only where the layout is stable enough for a number to mean
   anything. */
@media (min-width: 1500px){
  .panel-c{ right: -1%; }
  .panel-f{ right: -2%; }
}

.positioning-showcase.is-visible .panel-a{
  opacity: 1; transform: rotate(-1deg) translateY(0) scale(1);
  transition-delay: .05s;
}
.positioning-showcase.is-visible .panel-b{
  opacity: 1; transform: rotate(-14deg) translateY(30px) scale(1);
  transition-delay: .32s;
}
.positioning-showcase.is-visible .panel-e{
  opacity: 1; transform: rotate(-7deg) translateY(64px) scale(1);
  transition-delay: .18s;
}
.positioning-showcase.is-visible .panel-d{
  opacity: 1; transform: rotate(7deg) translateY(58px) scale(1);
  transition-delay: .24s;
}
.positioning-showcase.is-visible .panel-c{
  opacity: 1; transform: rotate(13deg) translateY(20px) scale(1);
  transition-delay: .4s;
}
.positioning-showcase.is-visible .panel-f{
  opacity: 1; transform: rotate(-4deg) translateY(28px) scale(1);
  transition-delay: .46s;
}

.panel-head{
  display: flex; align-items: center; gap: 7px;
  font-family: var(--font-display); font-weight: 600; font-size: .78rem;
  color: var(--pos-ink-2);
  margin-bottom: 14px;
}
.panel-dot{ width: 7px; height: 7px; border-radius: 50%; background: var(--pos-brand); flex-shrink: 0; }

.panel-stats{ display: flex; gap: 18px; margin-bottom: 14px; }
.panel-stat{ display: flex; flex-direction: column; gap: 3px; }
.panel-stat-label{ font-size: .64rem; text-transform: uppercase; letter-spacing: .06em; color: var(--pos-ink-3); }
.panel-stat-value{ font-family: var(--font-mono); font-weight: 600; font-size: .95rem; color: var(--pos-ink); }

.panel-trend, .panel-hours{
  display: flex; align-items: flex-end; gap: 4px;
  height: 56px;
}
.panel-trend span, .panel-hours span{
  flex: 1;
  height: var(--h);
  background: var(--pos-hairline-strong);
  border-radius: 2px 2px 0 0;
}
.panel-trend span.is-peak, .panel-hours span.is-peak{ background: var(--pos-brand); }

.panel-heatmap{ display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
.heat-tile{
  border-radius: 8px; padding: 10px 12px;
  display: flex; flex-direction: column; gap: 3px;
}
.heat-tile strong{ font-family: var(--font-mono); font-size: .82rem; }
.heat-tile span{ font-size: .68rem; opacity: .85; }
.heat-1{ background: rgba(var(--pos-brand-rgb), .85); color: var(--pos-brand-ink); }
.heat-2{ background: rgba(var(--pos-brand-rgb), .6); color: var(--pos-brand-ink); }
.heat-3{ background: rgba(var(--pos-brand-rgb), .38); color: var(--pos-ink); }
.heat-4{ background: rgba(var(--pos-brand-rgb), .26); color: var(--pos-ink); }
.heat-5{ background: rgba(var(--pos-brand-rgb), .17); color: var(--pos-ink); }
.heat-6{ background: rgba(var(--pos-brand-rgb), .1); color: var(--pos-ink); }

.panel-caption{ margin-top: 10px; font-size: .72rem; color: var(--pos-ink-3); }
.panel-caption strong{ color: var(--pos-ink); }

.panel-outlets{ display: flex; flex-direction: column; gap: 14px; }
.outlet-row{ display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: center; }
.outlet-name{ display: block; font-size: .8rem; font-weight: 600; color: var(--pos-ink); margin-bottom: 6px; }
.outlet-bar{ height: 6px; border-radius: 3px; background: var(--pos-surface-sunken); overflow: hidden; }
.outlet-bar span{ display: block; height: 100%; border-radius: 3px; background: var(--pos-brand); }
.outlet-figures{ font-family: var(--font-mono); font-size: .72rem; color: var(--pos-ink-2); text-align: right; line-height: 1.5; white-space: nowrap; }

/* Original illustration, not a copy of WhatsApp's UI/logo — evokes the
   general "green bubble, document card, double check-mark" chat language
   loosely enough to read as "sent by WhatsApp" (a real feature already
   promised in the hero's trust badges — "WhatsApp the bill, skip the
   paper") without reproducing any of WhatsApp's actual trademarked visual
   assets. */
.wa-header{
  display: flex; align-items: center; gap: 8px;
  background: linear-gradient(180deg, #0c8567, #0a7358);
  color: #fff;
  margin: -18px -20px 14px;
  padding: 10px 12px;
  border-radius: 11px 11px 0 0;
}
.wa-avatar{
  width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
  background: #fff; color: var(--pos-brand-strong);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--font-display); font-weight: 700; font-size: .72rem;
}
.wa-title{ display: flex; align-items: center; gap: 4px; flex: 1; min-width: 0; }
.wa-title-name{ font-family: var(--font-display); font-weight: 600; font-size: .76rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.wa-badge{ width: 12px; height: 12px; flex-shrink: 0; color: #5fd0a8; }
.wa-actions{ display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.wa-actions svg{ width: 15px; height: 15px; opacity: .92; }
.wa-bubble{ background: #dcf8c6; border-radius: 4px 10px 10px 10px; padding: 10px 12px; }
.wa-doc{
  display: flex; align-items: center; gap: 8px;
  background: var(--pos-surface);
  border-radius: 8px;
  padding: 8px 10px;
  margin-bottom: 8px;
}
.wa-doc-icon{
  background: #d64545; color: #fff;
  font-size: .58rem; font-weight: 700; letter-spacing: .02em;
  padding: 3px 6px; border-radius: 4px; flex-shrink: 0;
}
.wa-doc-name{ font-size: .74rem; font-weight: 600; color: var(--pos-ink); }
.wa-text{ font-size: .78rem; color: var(--pos-ink); line-height: 1.4; margin-bottom: 6px; }
.wa-meta{ display: block; text-align: right; font-size: .64rem; color: var(--pos-ink-3); }
.wa-check{ color: #34a3e0; font-weight: 700; }

.panel-insights{ display: flex; flex-direction: column; gap: 14px; }
.insight-row{ display: flex; gap: 10px; align-items: flex-start; }
/* Held emoji until 13 Sep 2026 (a person and a parcel). Replaced with inline
   SVG: emoji render as a different typeface on every OS, and this house does
   not put them in UI. The svg rule below is what sizes them now, in place of
   the font-size that used to scale the glyph. */
.insight-icon{
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 8px;
  background: var(--pos-brand-tint); color: var(--pos-brand);
}
.insight-icon svg{ width: 15px; height: 15px; }
.insight-row p{ font-size: .76rem; line-height: 1.42; color: var(--pos-ink-2); }
.insight-row strong{ color: var(--pos-ink); }

.positioning-showcase.is-visible .showcase-panel.is-tilting{ transition: transform .08s linear; }
.showcase-panel.is-raised{
  box-shadow: 0 4px 10px rgba(20,26,36,.08), 0 30px 56px -18px rgba(20,26,36,.38);
  transition: box-shadow .3s var(--ease-snap), transform .9s var(--ease-spring), opacity .7s var(--ease-spring);
}

@media (prefers-reduced-motion: reduce){
  .showcase-panel{ transition: none; }
}

/* ---------- reasons ---------- */
.reasons-grid{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}
.reason-card{
  position: relative;
  min-width: 0;
  background: var(--pos-surface);
  border: 1px solid var(--pos-hairline);
  box-shadow: var(--shadow-card);
  clip-path: polygon(var(--cut) 0, 100% 0, 100% calc(100% - var(--cut)), calc(100% - var(--cut)) 100%, 0 100%, 0 var(--cut));
  padding: 34px 32px;
}
.reason-card:hover{ border-color: rgba(var(--pos-brand-rgb),.35); background: var(--pos-surface-sunken); }
.reason-head{
  display: flex; align-items: center;
  gap: 12px;
  margin-bottom: 18px;
}
.reason-icon{
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  width: 46px; height: 46px;
  border-radius: 12px;
  background: var(--pos-brand-tint);
  color: var(--pos-brand);
}
.reason-icon svg{ width: 24px; height: 24px; }
/* hidden-until-revealed state only applies once JS has opted the card
   into the reveal system — never an unconditional default, so icons
   stay visible if JS/IntersectionObserver/reduced-motion skip reveal */
.reason-card.reveal .reason-icon{
  opacity: 0;
  transform: scale(.55) rotate(-8deg);
  transition: transform .55s var(--ease-spring) .12s, opacity .55s var(--ease-spring) .12s;
}
.reason-num{
  display: block;
  font-family: var(--font-mono);
  color: var(--pos-brand);
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .05em;
}
.reason-card h3{ font-size: 1.15rem; margin-bottom: 12px; }
.reason-card p{ color: var(--pos-ink-2); font-size: .94rem; }

/* ---------- restaurant section: auto-scrolling card carousel ----------
   Only #restaurant uses this — .reasons-grid (the other 3 card sections
   on this page) is untouched. See main.js for the cloning that doubles
   the track's content so -50% is a seamless loop, and for the touch/hover
   pause + highlight (Pointer Events, not CSS :hover — see that comment
   for why touch needs it). */
/* Fades the two edges instead of hard-clipping mid-card — with a
   continuously-scrolling track, a card is *always* partway in or out of
   view at both edges, which without this reads as the card being cut off
   by a bug rather than the intended "flowing past" look of a marquee. */
.carousel-viewport{
  overflow: hidden;
  overflow-x: clip;
  max-width: 100%;
  -webkit-mask-image: linear-gradient(to right, transparent, black 48px, black calc(100% - 48px), transparent);
  mask-image: linear-gradient(to right, transparent, black 48px, black calc(100% - 48px), transparent);
}
.carousel-track{
  display: flex;
  gap: 20px;
  width: max-content;
  animation-play-state: paused;
}
.carousel-track.is-doubled.is-visible{
  animation: carousel-scroll 56s linear infinite;
}
/* #retail scrolls the opposite way from #restaurant (right-to-left vs
   left-to-right) — a second keyframe animating the same -50%/0% range in
   reverse, applied via a modifier class so setUpCarousel() in main.js
   doesn't need to know or care which direction any given track runs. */
.carousel-track.is-reverse.is-doubled.is-visible{
  animation-name: carousel-scroll-reverse;
}
/* Needs >= the specificity of the .is-doubled.is-visible rule above — the
   `animation` shorthand there also resets animation-play-state to its
   default (running), so a lower-specificity override here would lose that
   fight even though it's a separate, later rule. Repeating
   .is-doubled.is-visible is what wins it. */
.carousel-track.is-doubled.is-visible.is-paused{ animation-play-state: paused; }
@keyframes carousel-scroll{
  from{ transform: translateX(0); }
  to{ transform: translateX(-50%); }
}
@keyframes carousel-scroll-reverse{
  from{ transform: translateX(-50%); }
  to{ transform: translateX(0); }
}
.carousel-track .reason-card{
  flex: 0 0 320px;
  width: 320px;
}
/* Cancels the sitewide .reason-card:hover lift here — the JS-driven
   .is-touched class below is the only highlight mechanism inside the
   carousel, so mouse and touch get identical behaviour. */
.carousel-track .reason-card:hover{
  transform: none;
  border-color: var(--pos-hairline);
  background: var(--pos-surface);
}
.carousel-track .reason-card.is-touched{
  transform: translateY(-8px);
  border-color: rgba(var(--pos-brand-rgb),.5);
  box-shadow: 0 4px 8px rgba(20,26,36,.06), 0 26px 46px -18px rgba(20,26,36,.24);
  background: var(--pos-surface-sunken);
  z-index: 2;
}
@media (max-width: 760px){
  .carousel-track .reason-card{ flex-basis: 260px; width: 260px; }
}
@media (prefers-reduced-motion: reduce){
  .carousel-track.is-doubled.is-visible{ animation: none; }
}

/* ---------- table billing: cards left, phone showcase right ---------- */
.table-billing-inner{
  display: grid;
  grid-template-columns: minmax(0, 440px) minmax(0, 1fr);
  align-items: stretch;
  gap: 56px;
}
.table-billing-cards{ display: flex; flex-direction: column; gap: 18px; }
.table-billing-cards .section-head{ margin-bottom: 10px; }

/* Illustrative phone mockups built from real (redacted-of-risk) Kautilya
   screenshots — the test store "Pizza Corner", never a real client's data,
   same rule as the positioning showcase above.

   Vertical cascade, matching the real vibecurb.pages.dev hero (verified
   directly via screenshot — a diagonal scatter of tilted cards, each in
   its own fixed lane, drifting from the top of the section to the bottom
   and fading out, not the semicircular left-right sweep an earlier,
   secondhand AI description of that site suggested). All three phones
   share one horizontal swing (--frame-x) and tilt (--frame-tilt) — an
   identical path, offset only in time — plus one parametrised @keyframes
   for Y (top → centre → bottom), depth (translateZ, scale), opacity and
   blur. Negative animation-delay staggers phones evenly from the first frame;
   `linear` timing with extra keyframe stops for the ease-in-out feel,
   same reasoning as the previous version (see below). */
.phone-showcase{
  /* --cascade-y needs to be roughly 4x the phone's own width for the
     three phones (each phase-shifted 1/3 of the loop, same shared path)
     to never overlap while both are meaningfully visible — verified
     empirically by pausing each pair at every 0.5% of the loop and
     checking getBoundingClientRect() intersection weighted by opacity.
     This ratio held constant from 195px-wide phones in a 480px container
     up to the same width in a 420px one — container size doesn't matter,
     only phone size does, since the collision is phone-to-phone, not
     phone-to-container. Only the 760px breakpoint below, where the phone
     itself shrinks to 128px, needs a smaller --cascade-y to match. */
  --cascade-y: 820px;
  --cascade-z-back: -160px;
  --cascade-z-front: 55px;
  --cascade-scale-min: .55;
  --cascade-scale-max: 1;
  --cascade-opacity-min: 0;
  --cascade-blur: 5px;
  position: relative;
  min-height: 480px;
  /* BOTH axes. `overflow-x: hidden` alone was the bug: per the CSS overflow
     spec, when one axis is hidden and the other is visible, the visible one
     computes to `auto`. That made this a Y scroll container, and the phones
     travel --cascade-y (820px) through a 480px box, so the section rendered
     with a live vertical scrollbar down its side. Clipping the cascade was
     always the intent; it was only ever asked for on one axis. */
  overflow: hidden;
  perspective: 1000px;
}
.phone-frame{
  position: absolute;
  top: 50%; left: 50%;
  width: 195px;
  aspect-ratio: 9 / 19.5;
  background: var(--pos-ink);
  border-radius: 34px;
  padding: 8px;
  box-shadow: var(--shadow-card);
  opacity: var(--cascade-opacity-min);
  animation: phone-cascade 26s linear infinite;
  animation-play-state: paused;
  will-change: transform, opacity, filter;
}
.phone-showcase.is-visible .phone-frame{ animation-play-state: running; }
/* Only 3 phones animate at a time (4 looked overcrowded) — evenly
   staggered a third of the loop apart each, so they circle continuously
   with no gap and no two ever bunched together in time. All three share
   one --frame-x/--frame-tilt (identical path, offset only in time)
   instead of each tracing a differently-shaped path — different shapes
   could cross each other unpredictably and read as two phones touching;
   identical paths keep a consistent phase-driven separation and give
   every phone the same flow. --static-x/--static-tilt are a separate,
   deliberately-varied set used only by the prefers-reduced-motion
   fallback below, which has no time-offset left to keep them apart. */
.frame-1{ --frame-x: 195px; --frame-tilt: 15deg; --static-x: 40px; --static-tilt: -6deg; animation-delay: 0s; }
.frame-2{ --frame-x: 195px; --frame-tilt: 15deg; --static-x: 195px; --static-tilt: 15deg; animation-delay: -8.67s; }
.frame-3{ --frame-x: 195px; --frame-tilt: 15deg; --static-x: 95px; --static-tilt: 5deg; animation-delay: -17.33s; }
.frame-4{ display: none; }

/* True semicircle: every phone starts on the RIGHT (top of the section),
   swings past centre to the LEFT at the vertical midpoint, and swings
   back to the RIGHT again by the bottom — identical shape for every
   phone (all three share --frame-x/--frame-tilt now), only the
   animation-delay phase differs per phone. Rotation mirrors the same
   curve so each phone visually "leans into" its turn. */
/* The "fully sharp" plateau (opacity 1, blur 0, biggest scale) is
   deliberately narrow — 42-58%, ~16% of the 26s duration (~4.2s) — and
   kept comfortably inside each phone's 33.3%-of-duration (8.67s) stagger
   gap from its neighbours. With a wider plateau, two adjacent phones'
   sharp windows overlapped in time as well as in position, so they'd
   both be large/sharp/dark at once and read as one phone stacked on
   another rather than a clear foreground/background pair. */
/* The entering/exiting keyframes (0/12/88/100%) use bigger --frame-x
   multipliers (1.2/.75 vs the old 1/.6) than the 42/50/58% swing-through-
   centre keyframes, so the top and bottom of the path sit further right
   without moving the sharp centred moment at all. 1.2/.75 — not higher —
   because 981px (the narrowest viewport still on the >980px --frame-x/
   --cascade-y tier) only has ~22px of horizontal margin left at that
   multiplier; higher values were verified to overflow there. */
@keyframes phone-cascade{
  0%   { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * 1.2)) translateY(calc(var(--cascade-y) * -1)) translateZ(var(--cascade-z-back)) rotate(var(--frame-tilt)) scale(var(--cascade-scale-min)); opacity: var(--cascade-opacity-min); filter: blur(var(--cascade-blur)); }
  12%  { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * .75)) translateY(calc(var(--cascade-y) * -.74)) translateZ(calc(var(--cascade-z-back) * .82)) rotate(calc(var(--frame-tilt) * .6)) scale(.62); opacity: .4; filter: blur(calc(var(--cascade-blur) * .78)); }
  42%  { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * -.35)) translateY(calc(var(--cascade-y) * -.06)) translateZ(calc(var(--cascade-z-back) * .06)) rotate(calc(var(--frame-tilt) * -.35)) scale(.96); opacity: .97; filter: blur(calc(var(--cascade-blur) * .04)); }
  50%  { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * -.9)) translateZ(var(--cascade-z-front)) rotate(calc(var(--frame-tilt) * -.9)) scale(var(--cascade-scale-max)); opacity: 1; filter: blur(0); }
  58%  { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * -.35)) translateY(calc(var(--cascade-y) * .06)) translateZ(calc(var(--cascade-z-back) * .06)) rotate(calc(var(--frame-tilt) * -.35)) scale(.96); opacity: .97; filter: blur(calc(var(--cascade-blur) * .04)); }
  88%  { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * .75)) translateY(calc(var(--cascade-y) * .74)) translateZ(calc(var(--cascade-z-back) * .82)) rotate(calc(var(--frame-tilt) * .6)) scale(.62); opacity: .4; filter: blur(calc(var(--cascade-blur) * .78)); }
  100% { transform: translate(-50%,-50%) translateX(calc(var(--frame-x) * 1.2)) translateY(var(--cascade-y)) translateZ(var(--cascade-z-back)) rotate(var(--frame-tilt)) scale(var(--cascade-scale-min)); opacity: var(--cascade-opacity-min); filter: blur(var(--cascade-blur)); }
}

.phone-frame::before{
  content: '';
  position: absolute;
  top: 8px; left: 50%;
  width: 46px; height: 16px;
  background: var(--pos-ink);
  border-radius: 0 0 12px 12px;
  transform: translateX(-50%);
  z-index: 1;
}
.phone-screen{
  position: relative;
  width: 100%; height: 100%;
  border-radius: 26px;
  overflow: hidden;
  background: var(--pos-surface);
  container-type: inline-size;
}
.phone-screen img{ width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }

/* ---------- phone showcase: illustrated mock screens ----------
   Not real screenshots — fictional "Sunrise Cafe" data, the same invented
   business already used in the positioning showcase above. Sized in
   container-query units (cqw), not px — the identical markup has to read
   correctly at wildly different sizes: a small circling phone (~130-195px
   wide) and the much larger spotlight (JS-computed, can exceed 500px), and
   a fixed px scale tuned for one would look cramped or oversized at the
   other. cqw resolves against .phone-screen's own width, so it scales
   fluidly with whichever frame it's currently rendered inside. */
.mock-screen{
  width: 100%; height: 100%;
  display: flex; flex-direction: column;
  font-family: var(--font-display);
  font-size: 4.6cqw;
  background: var(--pos-surface);
  color: var(--pos-ink);
}
.mock-head{
  background: var(--pos-brand);
  color: #fff;
  padding: 11cqw 6cqw 3cqw;
  flex-shrink: 0;
}
.mock-head .mock-title{ font-weight: 700; font-size: 1.15em; }
.mock-head .mock-sub{ opacity: .6; font-size: .8em; margin-top: .2em; }
.mock-body{
  flex: 1;
  padding: 4cqw;
  overflow: hidden;
  display: flex; flex-direction: column;
  gap: 3cqw;
}
.mock-stats{ display: grid; grid-template-columns: repeat(2,1fr); gap: 2cqw; margin: 4cqw 0 0; }
.mock-stat{ background: rgba(255,255,255,.1); border-radius: 1.6cqw; padding: 2.2cqw; }
.mock-stat-label{ font-size: .62em; text-transform: uppercase; letter-spacing: .04em; opacity: .6; }
.mock-stat-value{ font-weight: 700; font-size: 1.15em; margin-top: .15em; }
.mock-section-label{ font-size: .68em; text-transform: uppercase; letter-spacing: .05em; color: var(--pos-ink-3); font-weight: 700; }
.mock-table-grid{ display: grid; grid-template-columns: repeat(2,1fr); gap: 2.4cqw; }
.mock-table-card{ border: 1px dashed var(--pos-hairline-strong); border-radius: 2cqw; padding: 2.6cqw; }
.mock-t-name{ font-weight: 700; font-size: 1.05em; }
.mock-t-meta{ font-size: .68em; color: var(--pos-ink-3); margin-top: .3em; }
.mock-table-card.is-running{ border-style: solid; border-color: rgba(var(--pos-brand-rgb),.3); background: var(--pos-brand-tint); }
.mock-row{ display: flex; align-items: center; justify-content: space-between; border: 1px solid var(--pos-hairline); border-radius: 2cqw; padding: 2.6cqw 3cqw; }
.mock-row-label{ font-weight: 600; font-size: .92em; }
.mock-row-sub{ font-size: .66em; color: var(--pos-ink-3); margin-top: .2em; }
.mock-toggle{ width: 7.4cqw; height: 4cqw; border-radius: 999px; background: var(--pos-brand); position: relative; flex-shrink: 0; }
.mock-toggle::after{ content:''; position: absolute; top: .5cqw; right: .5cqw; width: 3cqw; height: 3cqw; border-radius: 50%; background: #fff; }
.mock-btn{ background: var(--pos-brand); color: #fff; text-align: center; font-weight: 700; font-size: .88em; border-radius: 2cqw; padding: 3cqw; margin-top: auto; }
.mock-btn-outline{ background: none; border: 1px solid var(--pos-hairline-strong); color: var(--pos-ink); }
.mock-numgrid{ display: grid; grid-template-columns: repeat(4,1fr); gap: 1.6cqw; }
.mock-num{ aspect-ratio: 1; display: flex; align-items: center; justify-content: center; border: 1px solid var(--pos-hairline); border-radius: 1.6cqw; font-weight: 700; font-size: .9em; }
.mock-num.is-active{ background: var(--pos-brand); color: #fff; border-color: var(--pos-brand); }
.mock-chip-row{ display: flex; gap: 1.6cqw; }
.mock-chip{ border: 1px solid var(--pos-hairline); border-radius: 999px; padding: 1.6cqw 3cqw; font-size: .78em; font-weight: 600; }
.mock-chip.is-active{ background: var(--pos-brand); color: #fff; border-color: var(--pos-brand); }
.mock-bill-line{ display: flex; justify-content: space-between; font-size: .86em; padding: 1cqw 0; }
.mock-bill-qty{ color: var(--pos-ink-3); margin-right: .4em; }
.mock-bill-total{ display: flex; justify-content: space-between; font-weight: 700; border-top: 1px dashed var(--pos-hairline-strong); padding-top: 2cqw; margin-top: 1cqw; }
.mock-bill-tax{ font-size: .66em; color: var(--pos-ink-3); display: flex; justify-content: space-between; }
.mock-ticket{ border: 1px solid var(--pos-hairline); border-radius: 2cqw; overflow: hidden; }
.mock-ticket-head{ background: var(--pos-brand-tint); color: var(--pos-brand-strong); font-weight: 700; font-size: .85em; padding: 1.8cqw 2.6cqw; display: flex; justify-content: space-between; }
.mock-ticket-body{ padding: 1.8cqw 2.6cqw; font-size: .78em; }
.mock-ticket-item{ padding: .6cqw 0; }

/* ---------- phone showcase: hover/touch a phone to bring it to centre ----------
   Hovering (desktop) or touching (mobile — see main.js, pointerenter/leave)
   a specific phone shows an enlarged, centred, static clone (.phone-spotlight)
   carrying that phone's screenshot, and hides the three circling phones.

   The circling phones are hidden via `opacity: 0 !important`, not
   display/visibility — hiding the very phone the pointer is over via
   visibility/display would remove it from hit-testing the instant it
   disappeared, which fires pointerleave immediately and flickers the focus
   straight back off. `!important` is required because CSS Animations sit
   above normal-specificity author rules in the cascade, so a plain class
   rule can't out-rank the running keyframe animation's own opacity value.

   The animation itself is never paused (no animation-play-state or
   currentTime changes) — it keeps running invisibly underneath, so letting
   go resumes the carousel exactly where it would have been, with no
   freeze-then-jump. */
.phone-spotlight{
  /* Sized in JS (main.js, sizeSpotlight()), not a fixed scale — the user
     wants the focused phone to nearly fill its container's height, but
     .phone-showcase's actual rendered height varies hugely by breakpoint
     (it's grid-stretched to match the cards column, which can be 1300px+
     tall on desktop) and its width even more so on narrow layouts, so a
     single CSS scale/percentage can't hit "nearly fill it" without either
     overflowing narrow containers or looking tiny in tall ones. JS reads
     the real container (and viewport) box at focus time and computes the
     largest phone that fits both while keeping the 9:19.5 aspect ratio —
     the classic "letterbox" fit, same idea as `object-fit: contain`, just
     done by hand since this isn't a replaced element. Width/height (not
     scale) are set directly so the transition below can animate them. */
  animation: none;
  opacity: 0;
  visibility: hidden;
  width: 253px;
  height: calc(253px * 19.5 / 9);
  transform: translate(-50%,-50%);
  z-index: 5;
  transition: opacity .2s var(--ease), width .2s var(--ease), height .2s var(--ease), visibility 0s linear .2s;
  pointer-events: none;
}
.phone-showcase.is-focused .phone-spotlight{
  opacity: 1;
  visibility: visible;
  transition: opacity .2s var(--ease), width .2s var(--ease), height .2s var(--ease);
}
.phone-showcase.is-focused .frame-1,
.phone-showcase.is-focused .frame-2,
.phone-showcase.is-focused .frame-3{
  opacity: 0 !important;
}

@media (prefers-reduced-motion: reduce){
  /* :not(.phone-spotlight) — the spotlight must stay hidden (opacity: 0,
     its own default) until focused; this rule would otherwise force it
     permanently visible on top of the three static phones below. */
  .phone-frame:not(.phone-spotlight){
    animation: none;
    opacity: 1; filter: none;
  }
  .frame-1, .frame-2, .frame-3{
    transform: translate(-50%,-50%) translateX(var(--static-x)) rotate(var(--static-tilt)) scale(.88);
  }
}

/* ---------- pricing ---------- */
.billing-toggle, .category-toggle{
  display: inline-flex; gap: 4px;
  background: var(--pos-surface);
  border: 1px solid var(--pos-hairline);
  padding: 5px;
  border-radius: 999px;
  margin-bottom: 48px;
}
.category-toggle{ margin-bottom: 20px; }
.toggle-btn{
  padding: 10px 20px;
  border-radius: 999px;
  font-size: .88rem; font-weight: 600;
  color: var(--pos-ink-2);
  display: flex; align-items: center; gap: 8px;
  transition: background-color .18s var(--ease), color .18s var(--ease);
}
.toggle-btn.is-active{ background: var(--pos-brand); color: var(--pos-brand-ink); }
.save-chip{
  font-size: .7rem; font-weight: 700;
  background: rgba(255,255,255,.2);
  padding: 2px 8px; border-radius: 999px;
}
.toggle-btn:not(.is-active) .save-chip{ background: var(--pos-brand-tint); color: var(--pos-brand); }

.pricing-grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 22px;
  align-items: stretch;
}
.price-card{
  position: relative;
  min-width: 0;
  background: var(--pos-surface);
  border: 1px solid var(--pos-hairline);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  padding: 36px 30px;
  display: flex;
  flex-direction: column;
}
.price-card-featured{
  border-color: var(--pos-brand);
  background: linear-gradient(180deg, var(--pos-brand-tint), var(--pos-surface) 45%);
}
.popular-chip{
  position: absolute; top: -13px; left: 30px;
  background: var(--pos-brand); color: var(--pos-brand-ink);
  font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 5px 12px; border-radius: 999px;
}
.price-card h3{ font-size: 1.3rem; margin-bottom: 6px; }
.price-tagline{ color: var(--pos-ink-2); font-size: .88rem; margin-bottom: 22px; }
.price-amount{ display: flex; align-items: baseline; gap: 6px; font-family: var(--font-display); margin-bottom: 4px; }
.currency{ font-size: 1.2rem; color: var(--pos-ink-2); }
.amount{ font-size: 2.4rem; font-weight: 700; }
.price-period{ font-size: .8rem; color: var(--pos-ink-3); }
.price-note{ font-size: .78rem; color: var(--pos-ink-3); margin-bottom: 18px; }
.price-desc{ color: var(--pos-ink-2); font-size: .92rem; margin-bottom: 24px; min-height: 42px; }
.price-features{ margin-top: 28px; display: flex; flex-direction: column; gap: 12px; }
/* [hidden] and .price-features{display:flex} are equal specificity, and
   author rules beat the UA stylesheet's [hidden]{display:none} at a tie —
   without this, the [hidden] attribute set on the retail/restaurant
   variant lists (see main.js's category toggle) would be silently
   ignored and both would show at once. */
.price-features[hidden]{ display: none; }
.price-features li{
  font-size: .88rem; color: var(--pos-ink-2);
  padding-left: 22px; position: relative;
}
.price-features li::before{
  content: '';
  position: absolute; left: 0; top: 7px;
  width: 10px; height: 10px;
  background: var(--pos-brand);
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
.price-features em{ color: var(--pos-ink-3); font-style: normal; }

/* ---------- compare table ---------- */
.table-scroll{ overflow-x: auto; border-radius: var(--radius); border: 1px solid var(--pos-hairline); box-shadow: var(--shadow-card); background: var(--pos-surface); }
.compare-table{ width: 100%; border-collapse: collapse; min-width: 640px; font-size: .9rem; }
.compare-table th, .compare-table td{ padding: 16px 20px; text-align: left; border-bottom: 1px solid var(--pos-hairline); white-space: nowrap; }
.compare-table thead th{
  font-family: var(--font-display); font-size: .95rem;
  color: var(--pos-ink); background: var(--pos-surface-sunken);
  position: sticky; top: 0;
}
.compare-table tbody th{ font-weight: 500; color: var(--pos-ink-2); white-space: normal; }
.compare-table tbody tr:hover{ background: rgba(20,26,36,.03); }
.compare-table tbody tr:last-child td, .compare-table tbody tr:last-child th{ border-bottom: none; }
.col-featured{ background: var(--pos-brand-tint); }
.yes{ color: var(--pos-brand); font-weight: 700; text-align: center; }
.no{ color: var(--pos-ink-3); text-align: center; }
.soon{ color: var(--pos-ink-3); font-size: .8rem; font-style: italic; }

/* ---------- FAQ ---------- */
.faq-inner{
  display: grid;
  grid-template-columns: minmax(0, 460px) minmax(540px, 1fr);
  gap: 48px;
  align-items: center;
}
.faq-list{ max-width: 460px; }
.faq-item{ border-bottom: 1px solid var(--pos-hairline); }
.faq-q{
  width: 100%;
  display: flex; align-items: center; justify-content: space-between;
  padding: 24px 4px;
  text-align: left;
  font-family: var(--font-display); font-size: 1.02rem; font-weight: 500;
}
.faq-icon{ position: relative; width: 18px; height: 18px; flex-shrink: 0; margin-left: 20px; }
.faq-icon::before, .faq-icon::after{
  content: ''; position: absolute; top: 50%; left: 50%;
  background: var(--pos-brand);
  transform: translate(-50%,-50%);
  transition: transform .25s var(--ease);
}
.faq-icon::before{ width: 14px; height: 2px; }
.faq-icon::after{ width: 2px; height: 14px; }
.faq-q[aria-expanded="true"] .faq-icon::after{ transform: translate(-50%,-50%) rotate(90deg) scale(0); }
.faq-a{
  display: grid; grid-template-rows: 0fr; overflow: hidden;
  transition: grid-template-rows .28s var(--ease);
}
.faq-a > p{ overflow: hidden; padding-right: 40px; color: var(--pos-ink-2); font-size: .94rem; }
.faq-item.is-open .faq-a{ grid-template-rows: 1fr; }
.faq-item.is-open .faq-a > p{ padding-bottom: 22px; }

/* ---------- FAQ: illustrated desktop screen, 3 rotating views ----------
   Purely decorative (aria-hidden) — original mockups, not copies of any
   reference image (two the user pointed to as style inspiration are a real
   client's actual sales dashboard, never to be used directly — see
   CLAUDE.md). Fictional "Sunrise Store" data throughout. Fixed rem-based
   sizing (not the phone showcase's cqw scaling) since this only ever
   renders at one relative size within its grid column, not across wildly
   different container widths.
   3 templates (#deskBilling, #deskToday, #deskSellers) get rotated into
   #deskMockBody every 1.5s by main.js. .desk-mock-body itself is just a
   sizing slot (min-height, so the card doesn't jump height between views)
   — the billing view supplies its own internal 2-column split
   (.desk-billing-view), since the other two views are single full-width
   blocks, not a fixed 2-column shape every view has to conform to. */
.faq-screen{ min-width: 0; }
.desk-mock{
  background: var(--pos-surface);
  border: 1px solid var(--pos-hairline);
  border-radius: var(--radius);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.desk-mock-top{
  display: flex; align-items: center; gap: 7px;
  padding: 12px 16px;
  background: var(--pos-ink);
}
.desk-dot{ width: 8px; height: 8px; border-radius: 50%; background: rgba(255,255,255,.25); }
.desk-mock-title{
  margin-left: 8px;
  font-size: .78rem; font-weight: 600; color: rgba(255,255,255,.65);
}
.desk-mock-body{ min-height: 360px; }
.desk-billing-view{
  display: grid;
  grid-template-columns: 1fr minmax(0, 240px);
  height: 100%;
}
.desk-menu{ padding: 20px; border-right: 1px solid var(--pos-hairline); }
.desk-cat-row{ display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 16px; }
.desk-cat{
  font-size: .74rem; font-weight: 600; color: var(--pos-ink-3);
  padding: 6px 12px; border-radius: 999px;
}
.desk-cat.is-active{ background: var(--pos-brand-tint); color: var(--pos-brand-strong); }
.desk-item-grid{ display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; }
.desk-item{
  border: 1px solid var(--pos-hairline);
  border-radius: 10px;
  padding: 12px;
  display: flex; flex-direction: column; gap: 6px;
}
.desk-item-name{ font-size: .82rem; font-weight: 600; }
.desk-item-price{ font-size: .78rem; color: var(--pos-brand); font-weight: 700; }
.desk-cart{ background: var(--pos-surface-sunken); padding: 20px 18px; display: flex; flex-direction: column; }
.desk-cart-head{ font-weight: 700; font-size: .9rem; margin-bottom: 12px; }
.desk-cart-line{ display: flex; justify-content: space-between; gap: 8px; font-size: .78rem; padding: 5px 0; color: var(--pos-ink-2); }
.desk-cart-line span:first-child{ min-width: 0; }
.desk-cart-line span:last-child{ flex-shrink: 0; white-space: nowrap; }
.desk-cart-tax{ display: flex; justify-content: space-between; gap: 8px; font-size: .7rem; color: var(--pos-ink-3); padding: 5px 0; }
.desk-cart-total{
  display: flex; justify-content: space-between; gap: 8px;
  font-weight: 700; font-size: .95rem;
  border-top: 1px dashed var(--pos-hairline-strong);
  margin-top: 6px; padding-top: 10px;
  white-space: nowrap;
}
.desk-cart-btn{
  margin-top: 14px;
  background: var(--pos-brand); color: #fff;
  text-align: center; font-weight: 700; font-size: .84rem;
  border-radius: 8px; padding: 11px;
}
/* ---------- FAQ desktop screen: "Today" and "Best sellers" views ---------- */
.desk-today, .desk-sellers{ padding: 22px 24px; }
.desk-today-stats{ display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.desk-today-stat{
  border: 1px solid var(--pos-hairline);
  border-radius: 10px;
  padding: 14px;
  display: flex; flex-direction: column; gap: 6px;
}
.desk-today-label{ font-size: .68rem; text-transform: uppercase; letter-spacing: .04em; color: var(--pos-ink-3); font-weight: 700; }
.desk-today-value{ font-size: 1.15rem; font-weight: 700; }
.desk-seller-grid{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.desk-seller{
  background: rgba(var(--pos-brand-rgb), .12);
  border-radius: 10px;
  padding: 12px;
  display: flex; flex-direction: column; gap: 4px;
}
.desk-seller-top{ background: var(--pos-brand); }
.desk-seller-value{ font-size: .95rem; font-weight: 700; }
.desk-seller-top .desk-seller-value, .desk-seller-top .desk-seller-name, .desk-seller-top .desk-seller-sold{ color: #fff; }
.desk-seller-name{ font-size: .74rem; font-weight: 600; }
.desk-seller-sold{ font-size: .68rem; color: var(--pos-ink-3); }
@media (max-width: 980px){
  .faq-inner{ grid-template-columns: 1fr; }
  .faq-screen{ display: none; }
}

/* ---------- final CTA ---------- */
.final-cta-inner{ text-align: center; }
.final-cta h2{ font-size: clamp(2rem, 4vw, 2.8rem); margin-bottom: 18px; }
.final-cta p{ color: var(--pos-ink-2); margin-bottom: 34px; font-size: 1.05rem; }

/* ---------- footer ---------- */
.site-footer{ border-top: 1px solid var(--pos-hairline); padding-top: 70px; }
.footer-inner{
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: 32px;
  padding-bottom: 50px;
}
.footer-brand p{ color: var(--pos-ink-3); font-size: .88rem; margin-top: 16px; max-width: 280px; }
.footer-col h5{ font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: var(--pos-ink-3); margin-bottom: 16px; }
.footer-col a{ display: block; color: var(--pos-ink-2); font-size: .9rem; padding: 6px 0; transition: color .15s; }
.footer-col a:hover{ color: var(--pos-brand); }
.footer-bottom{
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 10px;
  padding: 26px 0; border-top: 1px solid var(--pos-hairline);
  color: var(--pos-ink-3); font-size: .82rem;
}
/* "Made in India" moved here from the hero on 13 Sep 2026. It is not legally
   required - country-of-origin rules bind goods, not SaaS - and in the hero it
   was answering a question the shop owner had not asked, next to three badges
   that each killed a real objection. It costs nothing down here. */
.footer-made{ display: inline-flex; align-items: center; gap: 7px; }
.footer-tagline{ color: var(--pos-brand); font-style: italic; }

/* ---------- scroll reveal + hover lift ---------- */
.reveal{
  opacity: 0;
  transform: translateY(24px);
  filter: blur(6px);
  transition: opacity .7s var(--ease-spring), transform .7s var(--ease-spring), filter .7s var(--ease-spring);
  will-change: opacity, transform, filter;
}
.reveal.is-visible{ opacity: 1; transform: translateY(0); filter: blur(0); }

.reason-card, .price-card{
  transition: border-color .45s var(--ease-spring), background-color .45s var(--ease-spring),
              transform .45s var(--ease-spring), box-shadow .45s var(--ease-spring);
}
.reason-card:hover, .price-card:hover{
  transform: translateY(-6px);
  box-shadow: 0 4px 8px rgba(20,26,36,.05), 0 22px 40px -16px rgba(20,26,36,.20);
}
.price-card-featured:hover{ transform: translateY(-6px) scale(1.01); }

.reason-card p{ transition: opacity .3s var(--ease-snap); }
.reason-card:hover p{ opacity: .8; }

.reason-card.is-visible .reason-icon{ opacity: 1; transform: scale(1) rotate(0deg); }
.reason-card:hover .reason-icon{
  transition: transform .35s var(--ease-snap);
  transform: scale(1.08) rotate(-4deg);
}

@media (prefers-reduced-motion: reduce){
  .reveal{ opacity: 1; transform: none; filter: none; transition: none; }
  .reason-card, .price-card, .reason-card p{ transition: none; }
  .reason-card.reveal .reason-icon{ transition: none; }
  .reason-card:hover, .price-card:hover, .price-card-featured:hover{ transform: none; }
  .reason-card:hover .reason-icon{ transform: none; }
  .reason-card:hover p{ opacity: 1; }
}

.mobile-cta-bar{ display: none; }

/* ============================================================
   Responsive
   ============================================================ */
/* narrow end of the two-column positioning layout (981-1300px): the
   showcase container itself shrinks as the viewport does, so panel-c's
   generous desktop right-offset needs reining in before it overflows */
@media (max-width: 1300px){
  .panel-c{ right: -1%; }
  .panel-f{ right: -1%; }
  .phone-showcase{ --cascade-z-back: -140px; }
  .frame-1, .frame-2, .frame-3{ --frame-x: 150px; }
  .frame-1{ --static-x: 35px; }
  .frame-2{ --static-x: 150px; }
  .frame-3{ --static-x: 80px; }
  /* Same fragile band as above — .faq-inner's desktop minmax()s (460px +
     540px + 48px gap = 1048px combined minimum) exceed the available
     content width here (literally overflowed at 981px: measured 21px of
     real horizontal scroll, not a hypothetical), well before the 980px
     breakpoint switches it to a single column. */
  .faq-inner{ grid-template-columns: minmax(0, 360px) minmax(420px, 1fr); gap: 32px; }
  .faq-list{ max-width: 360px; }
}

@media (max-width: 980px){
  .hero-inner{ grid-template-columns: 1fr; }
  .hero-visual{ order: -1; }
  .positioning-inner{ grid-template-columns: 1fr; text-align: center; }
  .positioning-stat{ justify-content: center; }
  .positioning-copy .fine-print{ margin: 0 auto; }
  .positioning-showcase{ min-height: 480px; margin-top: 44px; }
  .panel-c{ right: 1%; }
  .panel-f{ right: 1%; }
  .reasons-grid{ grid-template-columns: 1fr; }
  .table-billing-inner{ grid-template-columns: 1fr; }
  .phone-showcase{ min-height: 420px; margin-top: 44px; }
  .frame-1, .frame-2, .frame-3{ --frame-x: 175px; }
  .frame-1{ --static-x: 45px; }
  .frame-2{ --static-x: 175px; }
  .frame-3{ --static-x: 90px; }
  .pricing-grid{ grid-template-columns: 1fr; max-width: 460px; margin: 0 auto; }
  .footer-inner{ grid-template-columns: 1fr 1fr; }

  /* full desktop nav only reliably fits from 980px up (measured: 5 links +
     Sign in + Get started overflows the header from ~761-900px) — hamburger
     nav covers the whole phone+tablet range instead of splitting at 760px */
  .main-nav, .header-actions{ display: none; }
  .nav-toggle{ display: flex; }
  .mobile-nav.is-open{ display: flex; }

  body{ padding-bottom: 76px; }
  .mobile-cta-bar{
    display: flex; gap: 10px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: rgba(250,248,245,.92);
    backdrop-filter: saturate(140%) blur(14px);
    border-top: 1px solid var(--pos-hairline);
  }
  .mobile-cta-bar .btn{ flex: 1; }
}

@media (max-width: 760px){
  section{ padding: 76px 0; }
  .positioning-stat{ flex-direction: column; }
  .positioning-showcase{
    position: static; min-height: 0; margin-top: 32px;
    display: flex; flex-direction: column; gap: 14px;
  }
  .positioning-showcase .showcase-panel,
  .positioning-showcase.is-visible .showcase-panel{
    position: static; width: 100%; transform: none; opacity: 1; transition: none;
  }
  .phone-showcase{
    min-height: 360px; margin-top: 32px;
    --cascade-y: 580px; --cascade-z-back: -100px; --cascade-z-front: 36px;
    --cascade-scale-min: .5; --cascade-scale-max: .8;
  }
  .phone-frame{ width: 128px; }
  .frame-1, .frame-2, .frame-3{ --frame-x: 115px; }
  .frame-1{ --static-x: 15px; }
  .frame-2{ --static-x: 115px; }
  .frame-3{ --static-x: 62px; }
  .footer-inner{ grid-template-columns: 1fr; }
}
