/* Khatiwada POS shared design system.
   CSS custom properties for the palette/type scale, plus the component
   classes reused across pages (nav, buttons, cards, form fields). One-off
   layout styles stay inline on the element (plain CSS syntax, not a
   framework). This file is the shared vocabulary, not everything. */

:root {
  --cream: #F7F4EC;
  --cream-2: #EFEADF;
  --tan-border: #DED8CA;
  --ink: #20211D;
  --ink-soft: #3E403A;
  --brown: #62645D;
  --brown-2: #818178;
  --terracotta: #E86118;
  --terracotta-dark: #C94F0F;
  --green: #1F5A43;
  --green-light: #2B7659;
  --green-mist: #E3F0E9;
  --white: #FFFFFF;
  --footer-muted: #AEB8B1;
  --footer-text-soft: #EFF3F0;
  --terracotta-light: #F28B4A;
  --green-accent: #8DBBA5;
  --green-text: var(--green);
  --terracotta-text: var(--terracotta-dark);
  --font-heading: 'Poppins', 'Noto Sans Devanagari', sans-serif;
  --font-body: 'Inter', 'Noto Sans Devanagari', sans-serif;
  --ease: cubic-bezier(.4, 0, .2, 1);
  --container: 1180px;
  --container-narrow: 780px;
  --radius-sm: 10px;
  --radius-md: 16px;
  --radius-lg: 24px;
  --shadow-sm: 0 1px 2px rgba(32,33,29,.05);
  --shadow-md: 0 16px 42px rgba(32,33,29,.08);
  /* Surfaces that were hardcoded hex until dark mode arrived. Light values are
     exactly what they were, so light mode is unchanged. */
  --nav-bg: #FAFAF9E8;
  --strip-bg: rgba(255,255,255,.32);
  --surface-warm: #F0E9DC;
  --surface-warm-2: #F2E7D7;
  --surface-green: #DFECE5;
  --surface-orange: #F4E3D5;
  --green-deep: #174834;
}

* { box-sizing: border-box; }
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .6s var(--ease), transform .6s var(--ease); }
.reveal.in-view { opacity: 1; transform: translateY(0); }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}

/* Keyboard-only focus ring. Scoped to :focus-visible (not :focus) so a mouse
   click doesn't show it -- only Tab navigation does. Without this, every
   button/link/field on the site was keyboard-invisible (no focus-visible
   rule existed anywhere except two narrow ones on the FAQ mascot widget). */
a, button, input, textarea, select {
  outline-offset: 2px;
}
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible, select:focus-visible {
  outline: 2px solid var(--terracotta);
  outline-offset: 2px;
}
body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
  transition: background-color .2s ease, color .2s ease;
}
main { font-family: var(--font-body); color: var(--ink); }
a { color: inherit; }
img, svg { max-width: 100%; }

/* ---- Nav ---- */
.site-nav {
  position: sticky; top: 0; z-index: 50;
  background: var(--nav-bg); backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--tan-border);
  box-shadow: 0 1px 0 rgba(38,36,32,0.03), 0 4px 16px rgba(38,36,32,0.04);
  font-family: var(--font-body);
}
.site-nav-inner {
  max-width: 1280px; margin: 0 auto; padding: 14px 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}
.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; flex-shrink: 0; }
.brand-name { font-family: var(--font-heading); font-size: 22px; font-weight: 700; color: var(--ink); letter-spacing: -0.3px; white-space: nowrap; }
.brand-name span { color: var(--terracotta); }
.nav-links { display: flex; align-items: center; gap: 28px; }
.nav-link { font-size: 16px; font-weight: 700; text-decoration: none; color: var(--ink); padding-bottom: 2px; border-bottom: 2px solid transparent; transition: color .2s var(--ease), border-color .2s var(--ease); }
.nav-link:hover { color: var(--terracotta-text); }
.nav-link.active { color: var(--terracotta); border-bottom: 2px solid var(--terracotta); }
.nav-right { display: flex; align-items: center; gap: 12px; }
.lang-switch { display: flex; background: var(--cream-2); border-radius: 999px; padding: 4px; position: relative; }
.lang-btn { border: none; cursor: pointer; padding: 8px 16px; border-radius: 999px; font-family: var(--font-body); font-size: 14px; font-weight: 800; background: transparent; color: #6B6259; transition: all .15s; }
.lang-btn:hover:not(.active) { color: var(--terracotta-text); }
.lang-btn.active { background: var(--terracotta); color: #FFF; }
.hamburger { border: 1px solid var(--tan-border); background: var(--white); border-radius: 12px; width: 44px; height: 44px; display: none; flex-direction: column; align-items: center; justify-content: center; gap: 4px; cursor: pointer; }
.hamburger span { width: 20px; height: 2.5px; background: var(--ink); border-radius: 2px; }
.mobile-menu { border-top: 1px solid var(--tan-border); padding: 12px 24px 20px; display: none; flex-direction: column; gap: 4px; background: var(--cream); }
.mobile-menu a { padding: 14px 8px; font-size: 17px; font-weight: 700; text-decoration: none; color: var(--ink); }
.mobile-menu a.active { color: var(--terracotta); }
.mobile-menu .btn-primary { margin-top: 8px; text-align: center; }
.lang-abbr { display: none; }

@media (max-width: 1059px) {
  /* Everything this block used to also do here (collapsing .nav-links to the
     hamburger, and the fixed-pixel brand/nav-right/lang-btn size trims) is
     dead: the later redesign layer below now handles the hamburger collapse
     at a wider 1120px breakpoint (so it always fires first) and uses fluid
     clamp()-based sizing for brand/nav spacing instead of these fixed values
     -- confirmed via computed styles, none of the old pixel values here were
     actually rendering. Only this swap survives as real, standalone
     behavior: "नेपाली" -> "ने" (same first syllable, like EN for English)
     saves space in the header row on narrow phones, where the full word
     would otherwise be the thing that runs the layout out of room. */
  .lang-full { display: none; }
  .lang-abbr { display: inline; }
}

/* ---- Buttons ---- */
.btn-primary {
  /* Background is the dark orange token, not the bright one -- white text on
     bright --terracotta measures ~2.8:1, below WCAG AA even for this button's
     large/bold text (needs 3:1 minimum). --terracotta-dark measures ~5.2:1.
     Bright terracotta stays reserved for icons/accents/small decorative use. */
  text-decoration: none; display: inline-block; border: none; cursor: pointer;
  background: var(--terracotta-dark); color: #FFF; font-family: var(--font-body);
  font-weight: 800; font-size: 18px; padding: 18px 36px; border-radius: 999px;
  box-shadow: 0 8px 24px rgba(249,115,22,0.28);
  transition: background-color .2s var(--ease), transform .2s var(--ease), box-shadow .2s var(--ease);
}
.btn-primary:hover:not(:disabled) {
  background: var(--terracotta-dark); transform: translateY(-2px);
  box-shadow: 0 12px 28px rgba(249,115,22,0.36);
}
.btn-primary:active:not(:disabled) { transform: translateY(0); }
.btn-primary:disabled { opacity: .6; cursor: not-allowed; }
.btn-primary.small { font-size: 15px; padding: 12px 22px; box-shadow: none; }
.btn-primary.small:hover:not(:disabled) { box-shadow: none; }
.btn-secondary {
  text-decoration: none; color: var(--green-text); font-weight: 800; font-size: 17px;
  padding: 18px 12px; border-radius: 999px; transition: color .2s var(--ease), background-color .2s var(--ease);
}
.btn-secondary:hover { background: var(--cream-2); }
.btn-text {
  border: none; background: none; cursor: pointer; color: var(--terracotta-text);
  font-weight: 700; font-size: 14px; padding: 0; font-family: var(--font-body);
  text-decoration: underline; transition: color .2s var(--ease);
}
.btn-text:hover { color: var(--terracotta); }

/* ---- Cards / auth form ---- */
.card {
  background: var(--white); border: 1px solid var(--tan-border); border-radius: 24px; padding: 40px;
  box-shadow: 0 12px 32px rgba(38,36,32,0.05);
  transition: box-shadow .25s var(--ease), transform .25s var(--ease);
}
.card:hover { box-shadow: 0 20px 44px rgba(38,36,32,0.09); transform: translateY(-2px); }
.auth-card { background: var(--white); border: 1px solid var(--tan-border); border-radius: 24px; padding: 36px 32px; box-shadow: 0 12px 32px rgba(38,36,32,0.06); max-width: 460px; margin: 0 auto; }
.field { display: flex; flex-direction: column; gap: 8px; margin-bottom: 20px; }
.field label { font-size: 14px; font-weight: 700; }
.field input, .field select {
  font-family: var(--font-body); font-size: 16px; padding: 14px 16px; border-radius: 12px;
  border: 1px solid var(--tan-border); background: var(--cream); color: var(--ink);
}
.field-hint { font-size: 13px; color: var(--brown-2); }
.field-error { font-size: 13px; color: var(--terracotta); }

/* ---- Footer ---- */
.site-footer { background: var(--ink); font-family: var(--font-body); color: var(--footer-text-soft); padding: 56px 24px 28px; }
.site-footer a { color: var(--footer-text-soft); text-decoration: none; font-size: 15px; font-weight: 600; }
.footer-heading { font-size: 13px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--footer-muted); margin-bottom: 16px; }

/* ---- FAQ chat bot ---- */
/* #faq-bot-launcher is a plain wrapper div (not a button -- it holds two
   real buttons, #faq-bot-open and #faq-bot-dismiss, and a button can't
   validly contain another button). Position/size/animation/the peeking
   slide all live here; the buttons inside just fill it. */
/* One height drives everything, and both widths derive from their own art's
   aspect ratio at that height -- so the two states always render at the same
   scale (only her pose changes) and it stays proportionate across phones,
   tablets, and desktops without a pile of per-breakpoint pixel values.
   Ratios: standing/waving art is 300x538 (0.5576), peeking art is 373x619
   (0.6027 -- wider because the edge she grips is drawn into it). */
#faq-bot-launcher {
  --mascot-h: clamp(150px, 21vh, 222px);
  position: fixed; right: 18px; bottom: 18px; z-index: 60;
  height: var(--mascot-h); width: calc(var(--mascot-h) * 0.5576);
  filter: drop-shadow(0 10px 22px rgba(38,36,32,0.22));
  animation: faqbot-bob 3.4s ease-in-out infinite;
  transition: right 0.25s ease, left 0.25s ease, opacity 0.2s ease;
  /* Stops the browser claiming the gesture for scrolling before the drag
     handler sees it -- without this, dragging her on a phone just scrolls. */
  touch-action: none;
}
#faq-bot-launcher.hidden { display: none; }
#faq-bot-launcher:hover, #faq-bot-launcher:focus-within { animation-play-state: paused; transform: translateY(-4px); }
/* While actually being dragged: no bob, no hover-lift, no position easing --
   all three would fight the inline transform that follows the pointer. */
#faq-bot-launcher.dragging,
#faq-bot-launcher.dragging:hover {
  animation: none; transition: none; cursor: grabbing;
  filter: drop-shadow(0 16px 30px rgba(38,36,32,0.32));
}
#faq-bot-open { cursor: grab; }
#faq-bot-launcher.dragging #faq-bot-open { cursor: grabbing; }
/* Moved to the left edge by dragging. `right: auto` matters -- without it
   both offsets apply and she'd stretch across the viewport. */
#faq-bot-launcher.side-left { right: auto; left: 18px; }
#faq-bot-open {
  display: block; width: 100%; height: 100%; position: relative;
  border: none; background: none; padding: 0; cursor: pointer; outline: none;
}
#faq-bot-open img { width: 100%; height: 100%; display: block; object-fit: contain; }
@keyframes faqbot-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes scanline { 0% { top: 14%; opacity: .9; } 50% { top: 78%; opacity: .5; } 100% { top: 14%; opacity: .9; } }
@media (prefers-reduced-motion: reduce) {
  .scan-mockup [style*="animation"] { animation: none !important; }
}

/* Real phone silhouettes for the scan mockup: an iPhone (Dynamic Island,
   left volume rocker, right power button) and an Android (punch-hole
   camera, right-side volume + power) rather than one generic rounded
   rectangle -- reinforces "works on your existing phone," either kind. */
/* Base frame. The iphone and android modifiers below deliberately diverge on
   frame material, corner radius and bezel, not just the camera cutout. With
   only the cutout differing the two read as the same handset photographed
   twice, which defeats the point of showing both. */
.phone-frame {
  position: relative; background: var(--ink); border-radius: 44px; padding: 14px;
  box-shadow: 0 20px 44px rgba(32,33,29,0.22); max-width: 300px; margin: 0 auto;
  transition: transform .3s var(--ease);
}
.phone-screen { background: var(--cream); border-radius: 32px; overflow: hidden; position: relative; display: flex; flex-direction: column; }
/* Clear the hardware. The island runs from 6px to 30px down the screen and the
   punch hole from 7px to 19px, so content starting at 28px and 20px respectively
   was tucking under them by a couple of pixels. */
/* iPhone: dark titanium, very round corners, thin even bezel, volume rocker on
   the LEFT and power on the right. */
.phone-frame.iphone {
  background: linear-gradient(150deg, #3A3D39 0%, #1B1D1A 26%, #161815 74%, #343739 100%);
  border-radius: 48px;
  padding: 13px;
}
.phone-frame.iphone .phone-screen { border-radius: 36px; }
.phone-frame.iphone .phone-screen { padding-top: 36px; }
/* Android, modelled on the Pixel 8 in the reference: warm champagne metal,
   noticeably squarer corners, slightly slimmer bezel, and both volume and power
   on the RIGHT edge. The metal is the strongest signal at a glance, which is
   why it carries the difference rather than the cutout alone. */
.phone-frame.android {
  background: linear-gradient(150deg, #43464A 0%, #17191C 24%, #121417 76%, #3C4044 100%);
  border-radius: 30px;
  /* The defining feature of the S20 Ultra in the reference is how little bezel
     there is: the screen runs almost to the edge. That, against the iPhone's
     chunky 13px surround, is what makes the two read as different handsets at a
     glance, far more than any colour difference would. */
  padding: 5px;
  box-shadow: 0 20px 44px rgba(23,25,28,.28);
}
.phone-frame.android .phone-screen { border-radius: 26px; }
/* Offsets are measured from the FRAME, so a 5px bezel needs different numbers
   from the iPhone's 13px one to land the hardware in the same place on screen. */
.phone-frame.android .punch-hole { top: 12px; }
.phone-frame.android .phone-statusbar { top: 9px; height: 18px; }
.phone-frame.android .phone-screen { padding-top: 26px; }

/* Side buttons, deliberately understated. In the iPhone 15 and S20 Ultra
   references these are thin, the same dark as the body, and protrude barely a
   couple of pixels: you read them as a bump in the silhouette rather than as a
   separate part. An earlier version made them 5px and lightened them with a
   highlight, which turned them into the loudest thing on the mockup and looked
   wrong, especially in the hero where two phones sit close and their buttons
   face each other across the gap. */
.side-btn {
  position: absolute;
  background: #23262A;
  border-radius: 1px;
}
.phone-frame.iphone .side-btn.volume-up   { left: -2px; top: 17%; width: 2px; height: 7%; }
.phone-frame.iphone .side-btn.volume-down { left: -2px; top: 26%; width: 2px; height: 7%; }
.phone-frame.iphone .side-btn.power       { right: -2px; left: auto; top: 19%; width: 2px; height: 10%; }
.phone-frame.android .side-btn.volume     { right: -2px; left: auto; top: 16%; width: 2px; height: 11%; }
.phone-frame.android .side-btn.power      { right: -2px; left: auto; top: 29%; width: 2px; height: 7%; }
/* The island and the punch hole are positioned against the FRAME, so their top
   offset has to clear the bezel (the frame's own 14px padding) before they land
   on the screen. They sat at 6px and 7px, i.e. 8px and 7px ABOVE the screen's
   top edge, buried inside the dark bezel where they were invisible. On a real
   iPhone or Pixel these sit clearly on the lit screen, and that is most of what
   makes each device recognisable as itself. */
.dynamic-island {
  position: absolute; top: 20px; left: 50%; transform: translateX(-50%);
  /* Proportional, not a fixed 82px. At the 260px frames this was tuned on, 82px
     was 35% of the screen; hardcoding it meant a narrower frame (the 210px pair
     in the Features hero) left too little room and the status bar icons
     collided with the island. Percentage keeps the proportions at any size. */
  width: 32%; max-width: 84px; min-width: 56px;
  height: 24px; background: #000; border-radius: 13px; z-index: 5;
  display: flex; align-items: center; justify-content: flex-end; padding-right: 7px;
}
/* The camera lens inside the island. Small, but without it the pill reads as a
   plain black blob rather than hardware. */
.dynamic-island::after {
  content: ""; width: 7px; height: 7px; border-radius: 50%;
  background: #14161a; box-shadow: inset 0 0 0 1px rgba(120,150,190,.55);
}
.punch-hole {
  position: absolute; top: 21px; left: 50%; transform: translateX(-50%);
  width: 12px; height: 12px; background: #000; border-radius: 50%; z-index: 5;
  box-shadow: inset 0 0 0 1.5px rgba(120,150,190,.4);
}
/* 3px nubs in the same colour as the bezel were effectively invisible. Slightly
   thicker with a lighter face so they read as physical buttons. */

/* Live sale simulation for the Features page: a real animated walkthrough
   (tap a tile, weight ticks up, price recalculates, the line item lands in
   the cart, the total updates) rather than a single static or looping
   scan-line moment. Runs only while scrolled into view (see the
   IntersectionObserver in the inline script) so it isn't burning cycles
   off-screen. */
.live-demo-mockup .phone-frame { position: relative; }
.live-demo-body { padding: 14px; display: flex; flex-direction: column; gap: 10px; flex: 1; }
.live-demo-tiles { display: flex; gap: 6px; }
.live-demo-tile {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  background: var(--white); border: 1px solid var(--tan-border); border-radius: 12px;
  padding: 8px 4px; font-family: var(--font-body); cursor: default;
  transition: transform .18s var(--ease), box-shadow .18s var(--ease), border-color .18s var(--ease);
}
.live-demo-tile span:nth-child(2) { font-size: 11px; font-weight: 700; color: var(--ink); }
.live-demo-tile small { font-size: 9px; color: var(--brown); }
.live-demo-tile-icon { width: 20px; height: 20px; border-radius: 6px; }
.live-demo-tile.tapped { transform: scale(.93); box-shadow: 0 0 0 2px var(--green-mist); border-color: var(--green); }
.live-demo-cart { display: flex; flex-direction: column; gap: 6px; min-height: 76px; }
.live-demo-cart-row {
  display: flex; justify-content: space-between; align-items: center; gap: 8px;
  background: var(--white); border: 1px solid var(--tan-border); border-radius: 10px;
  padding: 8px 10px; font-size: 11px; font-weight: 700; color: var(--ink);
}
.live-demo-cart-row small { font-weight: 400; color: var(--brown); }
.live-demo-cart-row.added { opacity: 0; transform: translateY(-8px) scale(.97); transition: opacity .3s var(--ease), transform .3s var(--ease); }
.live-demo-cart-row.added.in { opacity: 1; transform: translateY(0) scale(1); }
.live-demo-total {
  display: flex; justify-content: space-between; align-items: center;
  padding: 10px 12px; background: var(--green); color: var(--white);
  border-radius: 10px; font-weight: 800; font-size: 13px;
  margin-top: auto;
}
#liveDemoTotal { transition: color .2s ease; }
#liveDemoTotal.flash { color: var(--terracotta-light); }
.live-demo-modal[hidden] { display: none; }
.live-demo-modal {
  position: absolute; inset: 0; background: rgba(32,33,29,.4);
  display: flex; align-items: flex-end; padding: 16px; z-index: 6;
}
.live-demo-modal-card {
  background: var(--white); border-radius: 16px; padding: 16px; width: 100%;
  display: flex; flex-direction: column; gap: 12px;
}
.live-demo-modal-title { font-size: 13px; font-weight: 700; color: var(--ink); }
.live-demo-modal-title small { display: block; font-weight: 400; color: var(--brown); font-size: 11px; margin-top: 2px; }
.live-demo-readout {
  background: var(--green-mist); border-radius: 12px; padding: 14px;
  text-align: center; display: flex; flex-direction: column; gap: 4px;
}
.live-demo-readout strong { font-size: 22px; color: var(--green); font-family: var(--font-heading); }
.live-demo-readout span { font-size: 13px; font-weight: 700; color: var(--green); }
.live-demo-add-btn {
  background: var(--green); color: var(--white); text-align: center;
  border-radius: 10px; padding: 10px; font-weight: 800; font-size: 12px;
  transition: transform .12s ease, background .12s ease;
}
.live-demo-add-btn.pressed { transform: scale(.96); background: var(--green-light); }
.live-demo-variety-btn {
  width: 100%; display: flex; justify-content: space-between; align-items: center;
  background: var(--green-mist); border: 1px solid var(--green-mist); border-radius: 10px;
  padding: 10px 12px; font-family: var(--font-body); font-weight: 700; font-size: 12px;
  color: var(--green); text-align: left; cursor: default;
  transition: transform .12s ease, background .12s ease;
}
.live-demo-variety-btn span { font-weight: 700; }
.live-demo-variety-btn.tapped { transform: scale(.97); background: var(--green); color: var(--white); }
.live-demo-chips { display: flex; gap: 6px; }
.live-demo-chip {
  flex: 1; text-align: center; background: var(--green-mist); color: var(--green);
  border-radius: 999px; padding: 7px 0; font-size: 11px; font-weight: 700;
  transition: transform .12s ease, background .12s ease, color .12s ease;
}
.live-demo-chip.tapped { transform: scale(.94); background: var(--green); color: var(--white); }
/* Larger variant for the two Features-page live demos, which show more
   content per screen (variety picker + weight picker) than the simpler
   single-purpose scan mockups, so they get more room to read comfortably. */
.phone-frame-lg { width: 260px; max-width: 100%; aspect-ratio: 9 / 18.5; flex: 0 0 auto; display: flex; flex-direction: column; }
.phone-frame-lg .phone-screen { flex: 1; min-height: 0; }
.live-demo-pay-total {
  display: flex; justify-content: space-between; align-items: baseline;
  padding-bottom: 8px; border-bottom: 1px solid var(--tan-border);
  font-size: 12px; color: var(--brown);
}
.live-demo-pay-total strong { font-size: 18px; color: var(--ink); font-family: var(--font-heading); }
.live-demo-pay-toggle { display: flex; gap: 8px; }
.live-demo-pay-chip {
  flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 0; border-radius: 10px; border: 1px solid var(--tan-border);
  background: var(--white); color: var(--brown); font-weight: 700; font-size: 12px;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.live-demo-pay-chip.selected { background: var(--green); border-color: var(--green); color: var(--white); }
.live-demo-pay-label { font-size: 11px; font-weight: 700; color: var(--ink); }
.live-demo-pay-label small { font-weight: 400; color: var(--brown); }
.live-demo-change[hidden] { display: none; }
.live-demo-change {
  margin-top: 8px; display: flex; justify-content: space-between; align-items: center;
  background: var(--green-mist); border-radius: 10px; padding: 8px 12px;
  font-size: 12px; color: var(--green); font-weight: 700;
}
.live-demo-change strong { font-size: 15px; }
.live-demo-qr-box {
  margin: 8px auto 0; width: 96px; height: 96px; border-radius: 12px;
  background: var(--white); border: 1px dashed var(--tan-border);
  display: flex; align-items: center; justify-content: center; color: var(--ink);
}
.live-demo-qr-box svg { width: 56px; height: 56px; }

.faq-bot-hint {
  position: absolute; top: 2px; right: 82px; background: var(--white); border: 1px solid var(--tan-border);
  border-radius: 14px 14px 4px 14px; padding: 7px 13px; font-size: 12.5px; font-weight: 700; color: var(--ink);
  white-space: nowrap; box-shadow: 0 6px 16px rgba(38,36,32,0.12);
  opacity: 1; transition: opacity .25s var(--ease, ease); pointer-events: none;
}
/* Fixed-position widgets sit over whatever page content happens to be in
   that corner at a given scroll spot -- fading the label (not the mascot
   itself, still fully tappable) once the visitor has scrolled past the hero
   keeps her available without the "Need help?" bubble parking itself on top
   of unrelated content further down the page. */
#faq-bot-launcher.hint-scrolled .faq-bot-hint { opacity: 0; }
/* On the left edge the bubble flips to her other side, and the tail corner
   flips with it so it still points back toward her. */
#faq-bot-launcher.side-left .faq-bot-hint {
  right: auto; left: 82px; border-radius: 14px 14px 14px 4px;
}
/* The BUTTON is a full 44x44 touch target (Apple HIG minimum; Material
   says 48) but draws nothing itself -- the visible 26px circle is the inner
   span. Previously this was a 24x24 button sitting directly on top of the
   mascot: about half the minimum target, so on phones a near-miss landed on
   her and opened the chat instead of dismissing. Sits above the artwork
   (bottom:100%) rather than overlapping it, so a miss hits empty page. */
#faq-bot-dismiss {
  position: absolute; bottom: 100%; right: 0; z-index: 2;
  width: 44px; height: 44px; padding: 0; margin: 0 0 2px;
  background: none; border: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
#faq-bot-dismiss span {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--white); border: 1px solid var(--tan-border); color: var(--brown);
  font-size: 16px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 2px 8px rgba(38,36,32,0.18);
  transition: background 0.15s ease, color 0.15s ease, transform 0.15s ease;
}
#faq-bot-dismiss:hover span, #faq-bot-dismiss:focus-visible span {
  background: var(--cream-2); color: var(--terracotta-dark); transform: scale(1.12);
}
/* While peeking she sits partly off-screen to the right, so the button has
   to be pulled back inward or it'd hang off the edge with her. */
#faq-bot-launcher.peeking #faq-bot-dismiss { right: 18px; }
#faq-bot-launcher.side-left #faq-bot-dismiss { right: auto; left: 0; }
#faq-bot-launcher.side-left.peeking #faq-bot-dismiss { right: auto; left: 18px; }
/* Brief "I'll be here if you need me!" bubble -- shown once by
   faq-bot.js's showPeekMessage() right when she's tucked aside, then fades
   out and removes itself. Sits above her rather than over her face, and
   stacked clear of the dismiss button (which also lives above her now) so
   the two never overlap during the couple of seconds it's up. */
.faq-bot-peek-msg {
  position: absolute; bottom: 100%; margin-bottom: 50px; right: 18px;
  background: var(--white); border: 1px solid var(--tan-border);
  border-radius: 14px 14px 4px 14px; padding: 7px 13px; font-size: 12.5px; font-weight: 700; color: var(--ink);
  white-space: nowrap; box-shadow: 0 6px 16px rgba(38,36,32,0.12);
  opacity: 0; transform: translateY(4px); transition: opacity 0.35s ease, transform 0.35s ease; pointer-events: none;
}
.faq-bot-peek-msg.visible { opacity: 1; transform: translateY(0); }
#faq-bot-launcher.side-left .faq-bot-peek-msg {
  right: auto; left: 18px; border-radius: 14px 14px 14px 4px;
}
/* Dismissed state: swaps to a dedicated "peeking around the edge" pose
   (mascot-peeking.png -- same character, hands gripping a vertical edge,
   drawn into the art itself) instead of just cropping the standing/waving
   image. Height is deliberately kept equal to the full state's (222px) --
   an earlier version sized this box bigger, which made the "minimized"
   state visually larger than the normal one on real devices (caught via
   tablet screenshots). Width is derived from the peeking art's own aspect
   ratio at that same height, so only her pose changes between states, not
   her on-screen scale. The art's edge/pole sits at 79.2% of its own width,
   with her fingertips curling slightly past it to 87.1% -- right is set so
   that point lands exactly on the viewport's real right edge, so she reads
   as gripping the actual browser edge rather than a floating box. Persisted
   site-wide via localStorage (see STATE_KEY in faq-bot.js), so once tucked
   aside she stays peeking on every page, not just the one it happened on.
   The `right` offset is derived, not hand-tuned: it keeps that grip point a
   fixed ~10px inside the viewport at any --mascot-h (0.208 is how far the
   pole sits from the art's right edge, x its 0.6027 aspect ratio). */
#faq-bot-launcher.peeking {
  width: calc(var(--mascot-h) * 0.6027);
  right: calc(10px - var(--mascot-h) * 0.1254);
}
/* Mirrored for the left edge -- and it really is a mirror: the left-facing
   artwork puts its pole at 20.6% from ITS left, the exact reflection of
   79.2% from the right, so the same derived offset works on both sides.
   (A separate illustration, not transform: scaleX(-1) -- flipping would put
   her saree's red pallu on the wrong shoulder, see faq-bot.js.) */
#faq-bot-launcher.side-left.peeking {
  right: auto;
  left: calc(10px - var(--mascot-h) * 0.1254);
}
#faq-bot-launcher.peeking .faq-bot-hint { display: none; }

/* "Help" button in the nav -- the only way back once she's fully hidden, so
   it's display:none until then rather than permanently occupying nav space
   (the header row is already tight on phones). Desktop uses the one in
   .nav-right, mobile the one in the dropdown; never both at once. */
.faq-bot-restore {
  display: none; cursor: pointer; font-family: var(--font-body); font-weight: 700;
  background: var(--cream-2); color: var(--terracotta-text);
  border: 1px solid var(--tan-border); border-radius: 999px;
  padding: 8px 16px; font-size: 14px;
}
.faq-bot-restore:hover { background: var(--white); border-color: var(--terracotta); }
.faq-bot-restore-desktop.visible { display: inline-flex; align-items: center; }
.faq-bot-restore-mobile.visible { display: block; width: 100%; text-align: center; }
@media (max-width: 1059px) { .faq-bot-restore-desktop.visible { display: none; } }
@media (min-width: 1060px) { .faq-bot-restore-mobile.visible { display: none; } }
#faq-bot-panel {
  position: fixed; right: 18px; bottom: 18px; z-index: 61;
  /* The cap used to be 500px, which on a 812px phone left the transcript
     186px -- not enough for one full answer, so the top of every reply was
     already scrolled out of view as it arrived. dvh (with a vh fallback for
     older browsers) because the mobile URL bar makes vh overshoot. */
  width: min(340px, calc(100vw - 36px));
  max-height: min(600px, calc(100vh - 36px));
  max-height: min(600px, calc(100dvh - 36px));
  background: var(--white); border: 1px solid var(--tan-border); border-radius: 20px;
  box-shadow: 0 24px 60px rgba(38,36,32,0.28); display: flex; flex-direction: column; overflow: hidden;
}
#faq-bot-panel[hidden] { display: none; }
/* The panel follows her to whichever edge she was dragged to -- opening a
   chat on the opposite side from the thing you just tapped reads as a
   different, unrelated element. */
#faq-bot-panel.side-left { right: auto; left: 18px; }
.faq-bot-header { background: var(--green); color: var(--cream); padding: 14px 12px 14px 16px; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.faq-bot-header .faq-bot-avatar { width: 34px; height: 34px; flex-shrink: 0; border-radius: 50%; overflow: hidden; }
.faq-bot-header .faq-bot-avatar img { width: 100%; height: 100%; display: block; object-fit: cover; object-position: top center; }
.faq-bot-header .faq-bot-title { font-family: var(--font-heading); font-weight: 700; font-size: 15px; flex: 1; line-height: 1.3; }
.faq-bot-header .faq-bot-sub { display: block; font-family: var(--font-body); font-weight: 400; font-size: 11.5px; color: #DCFCE7; }
#faq-bot-close {
  background: none; border: none; color: var(--cream); font-size: 22px; cursor: pointer; line-height: 1;
  padding: 4px 6px; flex-shrink: 0; font-family: var(--font-body);
}
#faq-bot-messages { flex: 1; overflow-y: auto; padding: 14px 16px; display: flex; flex-direction: column; gap: 10px; background: var(--cream); min-height: 190px; }
.faq-bot-msg { max-width: 88%; padding: 9px 13px; border-radius: 14px; font-size: 13.5px; line-height: 1.55; }
.faq-bot-msg.bot { background: var(--white); border: 1px solid var(--tan-border); align-self: flex-start; border-bottom-left-radius: 4px; color: var(--ink); }
.faq-bot-msg.user { background: var(--terracotta); color: #fff; align-self: flex-end; border-bottom-right-radius: 4px; font-weight: 600; }
/* The disclosure row that owns the full question list. It carries the border
   the menu used to, so the panel keeps the same seam whether the list is open
   or shut. Chevron via ::after, not a child element: script.js's applyLang
   sets textContent on every [data-en] node it finds, and a real child would
   be wiped on the first language toggle. */
#faq-bot-menu-toggle {
  display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%;
  border: none; border-top: 1px solid var(--tan-border); background: var(--white);
  color: var(--terracotta-text); font-family: var(--font-body); font-weight: 800;
  font-size: 12.5px; text-align: left; padding: 11px 14px; cursor: pointer; flex-shrink: 0;
}
#faq-bot-menu-toggle:hover { background: var(--cream-2); }
#faq-bot-menu-toggle::after { content: "\25BE"; font-size: 13px; transition: transform .2s var(--ease); }
#faq-bot-panel.menu-open #faq-bot-menu-toggle::after { transform: rotate(180deg); }
/* Only rendered while open, so a closed list costs nothing but the row above.
   Capped in vh rather than at a flat 190px -- the old fixed height showed 4 of
   15 questions on every screen size, tall ones included. */
#faq-bot-menu { display: none; padding: 4px 14px 14px; flex-direction: column; gap: 7px; background: var(--white); max-height: min(300px, 34vh); overflow-y: auto; flex-shrink: 0; }
#faq-bot-panel.menu-open #faq-bot-menu { display: flex; }
/* While the list is open the transcript sizes to its content instead of
   holding a 190px floor -- otherwise the opening state is a greeting followed
   by a large blank gap. The floor matters only once the list folds away and
   the transcript becomes the main surface. */
#faq-bot-panel.menu-open #faq-bot-messages { min-height: 0; }
.faq-bot-chip {
  text-align: left; background: var(--cream-2); border: 1px solid var(--tan-border); border-radius: 10px;
  padding: 8px 12px; font-size: 13px; font-weight: 700; color: var(--terracotta-text); cursor: pointer;
  font-family: var(--font-body);
}
.faq-bot-chip:hover { background: var(--white); border-color: var(--terracotta); }
/* Suggestion chips rendered inside a bot message (follow-ups after an answer,
   or the "did you mean" list when the matcher isn't confident) -- same chip
   look as the standing menu, a step smaller so they read as part of the
   conversation rather than a second menu. */
.faq-bot-suggest { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.faq-bot-suggest .faq-bot-chip { font-size: 12.5px; padding: 7px 10px; background: var(--cream); }
#faq-bot-input-form {
  display: flex; gap: 8px; padding: 10px 14px; background: var(--white);
  border-top: 1px solid var(--tan-border); flex-shrink: 0;
}
#faq-bot-input {
  flex: 1; min-width: 0; font-family: var(--font-body); font-size: 13.5px;
  padding: 9px 12px; border-radius: 10px; border: 1px solid var(--tan-border); background: var(--cream);
}
#faq-bot-input-form button {
  border: none; cursor: pointer; background: var(--terracotta); color: #fff; font-weight: 700;
  font-size: 13px; font-family: var(--font-body); border-radius: 10px; padding: 0 16px; flex-shrink: 0;
}
#faq-bot-input-form button:hover { background: var(--terracotta-dark); }
@media (max-width: 480px) {
  /* No width/height overrides here any more -- --mascot-h's clamp() scales
     her smoothly across devices, and both states derive their width from it,
     so a per-breakpoint pixel override would just reintroduce the drift
     between states that had to be fixed once already. */
  #faq-bot-launcher { right: 10px; bottom: 10px; }
  #faq-bot-launcher.side-left { right: auto; left: 10px; }
  #faq-bot-launcher.peeking { right: calc(4px - var(--mascot-h) * 0.1254); }
  #faq-bot-launcher.side-left.peeking { right: auto; left: calc(4px - var(--mascot-h) * 0.1254); }
  .faq-bot-hint { font-size: 11.5px; padding: 6px 10px; right: calc(var(--mascot-h) * 0.44); }
  #faq-bot-launcher.side-left .faq-bot-hint { right: auto; left: calc(var(--mascot-h) * 0.44); }
  .faq-bot-peek-msg { font-size: 11.5px; padding: 6px 10px; right: 12px; }
  #faq-bot-launcher.side-left .faq-bot-peek-msg { right: auto; left: 12px; }
  #faq-bot-dismiss { width: 48px; height: 48px; }
  #faq-bot-launcher.peeking #faq-bot-dismiss { right: 12px; }
  #faq-bot-launcher.side-left.peeking #faq-bot-dismiss { right: auto; left: 12px; }
  /* Panel already spans edge-to-edge here (left AND right both set), so it
     needs no side variant -- and .side-left's `right: auto` would actually
     break that, hence resetting it back. */
  /* Edge-to-edge on phones, so the extra height is worth taking too -- the
     panel is the whole interaction at this size, not a corner overlay. */
  #faq-bot-panel { right: 8px; bottom: 8px; left: 8px; width: auto; }
  #faq-bot-panel.side-left { right: 8px; left: 8px; }
  #faq-bot-panel { max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); }
}

/* ---- Utility ---- */
.kicker { display: inline-flex; align-items: center; gap: 8px; background: var(--cream-2); color: var(--terracotta-text); font-weight: 800; font-size: 14px; padding: 8px 16px; border-radius: 999px; margin-bottom: 24px; }
.section-title { font-family: var(--font-heading); font-weight: 800; margin: 0 0 16px; color: var(--ink); line-height: 1.2; letter-spacing: -0.4px; }

/* Real product screenshots (the homepage's "See it in action" gallery) --
   a gentle zoom on hover gives them a touch of depth/interactivity instead
   of sitting completely flat, without needing a new HTML class since
   <figure> is already the real element wrapping each one. */
main figure { overflow: hidden; }
main figure img { transition: transform .4s var(--ease); }
main figure:hover img { transform: scale(1.04); }

/* ---- Mobile tightening (the site is inline-style-heavy, so a few !importants are the pragmatic fix here) ---- */
@media (max-width: 480px) {
  .hero-mockup { max-width: 260px !important; }
  .hero-mockup-body { padding: 14px !important; gap: 12px !important; }
  .hero-mockup-scan { height: 100px !important; }
}

/* ---- Family shop photo, shrunk on mobile so it doesn't outweigh the
   text it sits next to once it wraps below on narrow screens ---- */
@media (max-width: 680px) {
  .family-shop-img { max-width: 160px !important; min-width: 0 !important; margin: 0 auto !important; }
}

/* ---- Sticky mobile CTA (homepage only) ---- */
.sticky-mobile-cta { display: none; }
@media (max-width: 680px) {
  .sticky-mobile-cta {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 55;
    background: var(--cream); border-top: 1px solid var(--tan-border);
    padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
    box-shadow: 0 -4px 16px rgba(38,36,32,0.08);
  }
  .sticky-mobile-cta .btn-primary { display: block; width: 100%; text-align: center; }
  /* Keeps the mascot from sitting behind the new bottom bar -- scoped to
     :has() so it only shifts up on pages that actually have the bar. */
  body:has(.sticky-mobile-cta) #faq-bot-launcher { bottom: calc(70px + env(safe-area-inset-bottom)); }
}

/* Password show/hide toggle (password-toggle.js wires this up). */
.password-field {
  position: relative;
  display: block;
}
.password-field input {
  width: 100%;
  box-sizing: border-box;
  padding-right: 42px;
}
.password-toggle {
  position: absolute;
  top: 50%;
  right: 6px;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  background: none;
  color: var(--brown);
  cursor: pointer;
  border-radius: 6px;
}
.password-toggle:hover { color: var(--ink); background: rgba(0, 0, 0, 0.06); }
.password-toggle:focus-visible { outline: 2px solid var(--terracotta); outline-offset: 1px; }


/* ========================================================================
   2026 product led redesign
   ======================================================================== */

body { background: var(--cream); color: var(--ink); }
main { overflow: clip; }
.container { width: min(calc(100% - 40px), var(--container)); margin-inline: auto; }
.container-narrow { max-width: var(--container-narrow); }
.section { padding-block: clamp(72px, 8vw, 108px); }
.section-soft { background: var(--cream-2); }
.section-dark { background: #1D2822; color: #fff; }

.site-nav { background: var(--nav-bg); backdrop-filter: blur(16px); border-bottom: 1px solid rgba(222,216,202,.8); box-shadow: none; transition: box-shadow .25s var(--ease); }
/* Toggled by script.js once the page has scrolled a few px -- gives the nav
   a sense of lifting above the content sliding beneath it, rather than a
   flat bar that's identical whether the page is at the very top or not. */
.site-nav.is-scrolled { box-shadow: var(--shadow-md); }
.site-nav-inner { max-width: var(--container); min-height: 72px; padding: 10px 0; flex-wrap: nowrap; }
.brand { gap: 10px; }
.brand img { width: 38px; height: 38px; }
.brand-name { font-family: var(--font-heading); font-size: 18px; font-weight: 700; letter-spacing: -.02em; }
.brand-name span { color: var(--terracotta); }
.nav-links { gap: 24px; }
.nav-link {
  font-size: 14px; font-weight: 600; color: var(--brown); border: 0; padding: 10px 0;
  position: relative; transition: color .2s var(--ease), opacity .2s var(--ease);
}
.nav-link:hover, .nav-link.active { color: var(--ink); border: 0; }
/* Animated underline: grown in via transform (GPU-friendly) rather than a
   width/border change, on both hover and the current-page .active state --
   fast/snappy to match a direct hover response. */
.nav-link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 3px; height: 2px; border-radius: 3px;
  background: var(--terracotta); transform: scaleX(0); transform-origin: left;
  transition: transform .2s cubic-bezier(0.4, 0, 0.6, 1);
}
.nav-link:hover::after, .nav-link.active::after { transform: scaleX(1); }
/* Squareup.com's own top nav does this on every hover: the item under the
   cursor stays full-strength while its siblings mute, so attention follows
   the pointer -- confirmed live via computed styles, not guessed. Square
   pairs it with a full mega-menu per item; this nav has no per-item dropdown
   content to match that with, so just the attention-shift itself is ported,
   scoped to a flat nav. Slower fade-out than the underline's snappy grow-in,
   same asymmetry Square's own tab component uses (fast in, slower settle). */
.nav-links:hover .nav-link:not(:hover):not(.active) { opacity: .55; transition: opacity .3s var(--ease); }
.nav-right { gap: 10px; }
.nav-login { font-size: 14px; font-weight: 700; text-decoration: none; color: var(--ink); padding: 10px 8px; }
.nav-login:hover { color: var(--green); }
.lang-switch { background: transparent; border: 1px solid var(--tan-border); padding: 2px; }
.lang-btn { padding: 6px 10px; font-size: 12px; color: var(--brown); }
.lang-btn.active { background: var(--white); color: var(--ink); box-shadow: var(--shadow-sm); }
.hamburger { border-radius: 10px; box-shadow: none; }
.mobile-menu { background: var(--cream); }

.btn-primary {
  min-height: 48px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--green); border-radius: 12px; background: var(--green); color: #fff;
  padding: 0 22px; font-size: 15px; font-weight: 750; line-height: 1; box-shadow: none;
  transition: background-color .18s var(--ease), border-color .18s var(--ease), transform .18s var(--ease);
}
.btn-primary:hover:not(:disabled) { background: var(--green-deep); border-color: var(--green-deep); transform: translateY(-1px); box-shadow: none; }
.btn-primary.small { min-height: 42px; padding: 0 17px; font-size: 13px; }
.btn-secondary {
  min-height: 48px; display: inline-flex; align-items: center; justify-content: center; text-decoration: none;
  padding: 0 22px; border: 1px solid #BFC0B8; border-radius: 12px; background: transparent;
  color: var(--ink); font-size: 15px; font-weight: 700;
}
.btn-secondary:hover { background: var(--white); border-color: var(--ink); }
.btn-text, .text-link { color: var(--green); }
.full-button { width: 100%; }

.eyebrow { display: inline-block; margin-bottom: 14px; font-size: 12px; line-height: 1.3; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; color: var(--green); }
.eyebrow.light { color: #B8D5C6; }
.display-title { max-width: 620px; margin: 0 0 22px; font-family: var(--font-heading); font-size: clamp(42px, 5.6vw, 72px); line-height: .99; letter-spacing: -.055em; font-weight: 800; color: var(--ink); }
.display-title span { color: var(--terracotta); }
.page-title { max-width: 760px; margin: 0 0 20px; font-family: var(--font-heading); font-size: clamp(38px, 4.6vw, 58px); line-height: 1.04; letter-spacing: -.045em; font-weight: 750; color: var(--ink); }
.section-title { margin: 0 0 16px; font-family: var(--font-heading); font-size: clamp(32px, 4vw, 48px); line-height: 1.08; letter-spacing: -.04em; font-weight: 750; color: var(--ink); }
.light-title { color: #fff; }
.lead { max-width: 650px; margin: 0; font-size: clamp(17px, 1.8vw, 20px); line-height: 1.65; color: var(--brown); }
.section-heading { margin-bottom: 48px; }
.section-heading > p, .split-heading > p { color: var(--brown); line-height: 1.7; }
.centered-heading { text-align: center; margin-inline: auto; }
.centered-heading .section-title, .centered-heading .page-title, .centered-heading .lead { margin-inline: auto; }
.centered-heading > p { max-width: 680px; margin: 0 auto; }
.split-heading { display: grid; grid-template-columns: 1.05fr .75fr; gap: 64px; align-items: end; }

.hero-section { padding: clamp(56px, 7vw, 92px) 0 clamp(64px, 8vw, 100px); }
.hero-grid { display: grid; grid-template-columns: minmax(0,.86fr) minmax(0,1.14fr); gap: clamp(46px, 6vw, 88px); align-items: center; }
.hero-scan-showcase { display: grid; grid-template-columns: minmax(0,1.15fr) minmax(min(280px, 100%),.85fr); gap: clamp(46px, 6vw, 88px); align-items: center; }
.hero-copy { max-width: 560px; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.micro-trust { display: flex; flex-wrap: wrap; gap: 9px 20px; margin-top: 24px; color: var(--brown); font-size: 12px; font-weight: 700; }
.micro-trust span { display: inline-flex; align-items: center; gap: 7px; }
.micro-trust span::before { content: ""; width: 7px; height: 7px; border: 2px solid var(--green); border-radius: 50%; }
.product-window {
  overflow: hidden; border: 1px solid var(--tan-border); border-radius: var(--radius-lg);
  background: var(--white); box-shadow: var(--shadow-md);
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
}
.product-window img { display: block; width: 100%; height: auto; transition: transform .4s var(--ease); }
/* The live site wraps screenshots in a plain <figure> with a hover zoom
   (main figure:hover img). This redesign replaced that with the browser-
   chrome device frame, which had no hover feedback at all -- restoring the
   same "feels interactive" quality here instead, scaled down slightly since
   the frame itself now also lifts. */
.product-window:hover { transform: translateY(-3px); box-shadow: 0 20px 44px rgba(32,33,29,0.14); }
.product-window:hover img { transform: scale(1.025); }
.product-window-bar { min-height: 40px; display: flex; align-items: center; gap: 6px; padding: 0 14px; border-bottom: 1px solid var(--tan-border); background: #FBFAF7; }
.product-window-bar > span { width: 7px; height: 7px; border-radius: 50%; background: #C9C3B7; }
.product-window-bar small { margin-left: 7px; font-size: 11px; font-weight: 700; color: var(--brown-2); }
.product-window-hero { transform: rotate(.25deg); }
.product-window-hero:hover { transform: rotate(.25deg) translateY(-3px); }
.hero-phone-wrap { display: flex; justify-content: center; }
.hero-phone-wrap .phone-frame { transform: rotate(.25deg); }
.hero-phone-wrap .phone-frame:hover { transform: rotate(.25deg) translateY(-4px); }
.live-demo-mockup .phone-frame:hover, .scan-mockup .phone-frame:hover { transform: translateY(-4px); }

.proof-strip { border-top: 1px solid var(--tan-border); border-bottom: 1px solid var(--tan-border); background: var(--strip-bg); }
.proof-strip-inner { min-height: 88px; display: flex; justify-content: space-between; align-items: center; gap: 28px; }
.proof-strip strong { font-size: 13px; color: var(--ink); }
.shop-type-row { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; }
.shop-type-row span { padding: 7px 11px; border: 1px solid var(--tan-border); border-radius: 999px; background: var(--white); color: var(--brown); font-size: 12px; font-weight: 700; }

/* ---- Customise-by filter (ported from squareup.com/au/en's own component,
   verified live via computed styles rather than guessed): a pill tab bar
   that swaps the headline + card grid below it, and sticks under the main
   nav once scrolled past. Square pairs this with per-vertical product
   differences (different POS features for restaurants vs. retail vs.
   beauty); KPOS is one product for every shop type, so the tabs swap which
   real feature matters most to THAT kind of shop, not fake different
   features -- same product, different emphasis, same screenshots reused
   across tabs where honest. ---- */
.customise-section { padding: 48px 0 clamp(56px, 7vw, 88px); }
.customise-bar {
  position: sticky; z-index: 40; top: 72px;
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 14px 0; margin-bottom: 40px;
  background: var(--cream); border-bottom: 1px solid var(--tan-border);
}
.customise-label { font-family: var(--font-heading); font-weight: 700; font-size: 15px; color: var(--ink); white-space: nowrap; }
.customise-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.customise-tab {
  position: relative; overflow: hidden; cursor: pointer;
  border: 1px solid var(--tan-border); border-radius: 999px; padding: 8px 18px;
  font-family: var(--font-body); font-size: 13px; font-weight: 700;
  background: var(--white); color: var(--ink-soft);
  transition: color .3s var(--ease), border-color .3s var(--ease), background-size .3s var(--ease);
  background-image: linear-gradient(var(--ink), var(--ink));
  background-repeat: no-repeat; background-position: center; background-size: 0% 100%;
}
/* Fill-wipe hover: a same-color gradient layer sized at 0% grows to 100% on
   hover, rather than a flat background swap -- Square's own inactive-tab
   hover does exactly this (confirmed via computed background-size
   transition on the live site). Skipped for the already-active tab, which
   uses a persistent fill instead of a hover effect. */
.customise-tab:hover:not(.active) { background-size: 100% 100%; color: var(--white); border-color: var(--ink); }
.customise-tab.active { background-size: 100% 100%; color: var(--white); border-color: var(--ink); }
.customise-panel { display: none; }
.customise-panel.active { display: block; }
/* Same grid pattern as .product-feature further down (image one side, copy
   the other) -- one real cashier screenshot per tab, showing a cart built
   from products that shop type actually sells, rather than three small
   crops of the same couple of generic screenshots reused everywhere. */
.customise-feature { display: grid; grid-template-columns: minmax(0,1.16fr) minmax(min(260px, 100%),.84fr); gap: clamp(42px, 6vw, 82px); align-items: center; }
.customise-feature-copy { max-width: 440px; }
.customise-feature-copy .section-title { max-width: none; }
/* Cashier (primary) stacked above admin (secondary, slightly smaller and
   inset) -- till screen is the thing every shop uses daily, the back office
   is the supporting detail, not equal billing. */
.customise-shots { display: flex; flex-direction: column; gap: 22px; }
.customise-shots .admin-shot { width: 88%; margin-left: auto; }
@media (max-width: 860px) {
  .customise-bar { top: 64px; }
  .customise-feature { grid-template-columns: minmax(0, 1fr); }
}

.benefit-list { display: grid; grid-template-columns: repeat(3,1fr); border-top: 1px solid var(--tan-border); border-bottom: 1px solid var(--tan-border); }
.benefit-list article { padding: 34px 34px 34px 0; }
.benefit-list article + article { padding-left: 34px; border-left: 1px solid var(--tan-border); }
.benefit-number { display: block; margin-bottom: 26px; color: var(--terracotta); font-size: 12px; font-weight: 800; letter-spacing: .08em; }
.benefit-list h3 { margin: 0 0 10px; font-family: var(--font-heading); font-size: 20px; }
.benefit-list p { margin: 0; color: var(--brown); font-size: 14px; line-height: 1.65; }

.product-tour { display: flex; flex-direction: column; gap: 42px; }
.product-feature { display: grid; grid-template-columns: minmax(0,1.16fr) minmax(min(260px, 100%),.84fr); gap: clamp(42px, 6vw, 82px); align-items: center; padding: 24px 0; }
.product-feature.reverse { grid-template-columns: minmax(min(260px, 100%),.84fr) minmax(0,1.16fr); }
.product-feature.reverse .product-window { order: 2; }
.product-feature-copy { max-width: 440px; }
.product-feature-copy h3, .feature-copy h2 { margin: 0 0 14px; font-family: var(--font-heading); font-size: clamp(26px,3vw,36px); line-height: 1.14; letter-spacing: -.035em; }
.product-feature-copy p, .feature-copy p { margin: 0; color: var(--brown); line-height: 1.72; }
.center-action { display: flex; justify-content: center; margin-top: 54px; }

.story-grid { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,.9fr); gap: clamp(48px,7vw,96px); align-items: center; }
.story-grid-hero { grid-template-columns: minmax(0,.88fr) minmax(0,1.12fr); }
.story-image { overflow: hidden; border-radius: var(--radius-lg); border: 1px solid var(--tan-border); background: var(--white); box-shadow: var(--shadow-md); }
.story-image img { width: 100%; display: block; object-fit: cover; }
.story-copy > p { color: var(--brown); line-height: 1.75; font-size: 16px; }
.text-link { display: inline-flex; gap: 8px; align-items: center; margin-top: 18px; text-decoration: none; font-weight: 800; }
.text-link:hover { color: var(--terracotta-dark); }
.story-links { display: flex; flex-wrap: wrap; gap: 8px 28px; margin-top: 18px; }
.story-links .text-link { margin-top: 0; }

.onboarding-grid { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(54px,8vw,110px); align-items: start; }
.steps-list { list-style: none; margin: 0; padding: 0; }
.steps-list li { display: grid; grid-template-columns: 54px 1fr; gap: 18px; padding: 24px 0; border-top: 1px solid rgba(255,255,255,.14); }
.steps-list li:last-child { border-bottom: 1px solid rgba(255,255,255,.14); }
.steps-list > li > span { color: #B8D5C6; font-size: 12px; font-weight: 800; letter-spacing: .08em; }
.steps-list strong { display: block; margin-bottom: 6px; font-family: var(--font-heading); font-size: 18px; }
.steps-list p { margin: 0; color: #BFC9C2; line-height: 1.6; font-size: 14px; }

.final-cta-section { padding: clamp(70px, 8vw, 110px) 0; }
.final-cta-card { padding: clamp(34px,5vw,58px); border: 1px solid var(--tan-border); border-radius: var(--radius-lg); background: var(--surface-warm); display: flex; justify-content: space-between; gap: 36px; align-items: center; }
.final-cta-card h2 { max-width: 650px; margin: 0; font-family: var(--font-heading); font-size: clamp(28px,3.4vw,42px); line-height: 1.13; letter-spacing: -.035em; }
.final-cta-card .hero-actions { margin: 0; flex-shrink: 0; }

.page-hero { padding: clamp(64px, 8vw, 104px) 0; }
.page-hero-grid { display: grid; grid-template-columns: minmax(0,.8fr) minmax(0,1.2fr); gap: clamp(48px,7vw,100px); align-items: center; }
.feature-stack { display: flex; flex-direction: column; gap: 92px; }
.feature-showcase { display: grid; grid-template-columns: minmax(0,1.08fr) minmax(min(280px, 100%),.92fr); gap: clamp(46px,7vw,96px); align-items: center; }
.feature-showcase.reverse { grid-template-columns: minmax(min(280px, 100%),.92fr) minmax(0,1.08fr); }
.feature-showcase.reverse > :first-child { order: 2; }
.feature-copy { max-width: 500px; }
.feature-window { box-shadow: var(--shadow-md); }
.icon-visual { min-height: 360px; display: grid; place-items: center; border: 1px solid var(--tan-border); border-radius: var(--radius-lg); background: var(--surface-warm-2); overflow: hidden; }
.icon-visual.green { background: var(--surface-green); }
.icon-visual.orange { background: var(--surface-orange); }
.icon-visual img { width: min(56%, 260px); max-height: 260px; object-fit: contain; }
.plain-check-list { list-style: none; padding: 0; margin: 22px 0 0; display: grid; gap: 11px; }
.plain-check-list li { position: relative; padding-left: 24px; color: var(--ink-soft); line-height: 1.55; }
.plain-check-list li::before { content: "✓"; position: absolute; left: 0; top: 0; color: var(--green); font-weight: 900; }

.pricing-hero { padding-bottom: 28px; }
.pricing-section { padding-top: 30px; }
.pricing-layout { display: grid; grid-template-columns: minmax(0,1.08fr) minmax(min(300px, 100%),.72fr); gap: clamp(44px,7vw,90px); align-items: start; }
.pricing-card-new { padding: clamp(30px,4vw,46px); border: 1px solid var(--tan-border); border-radius: var(--radius-lg); background: var(--white); box-shadow: var(--shadow-md); }
.pricing-card-head h2 { margin: 0 0 12px; font-family: var(--font-heading); font-size: clamp(28px,3vw,38px); letter-spacing: -.035em; }
.pricing-card-head p { margin: 0; color: var(--brown); line-height: 1.7; }
.pricing-status { margin: 30px 0; padding: 20px 0; border-top: 1px solid var(--tan-border); border-bottom: 1px solid var(--tan-border); display: flex; flex-direction: column; gap: 7px; }
.pricing-status span { color: var(--terracotta); font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .08em; }
.pricing-status strong { font-size: 18px; }
.large-list { margin-bottom: 30px; gap: 14px; }
.pricing-note { padding: 12px 0; position: sticky; top: 104px; }
.pricing-note h3 { margin: 0 0 14px; font-family: var(--font-heading); font-size: 26px; letter-spacing: -.025em; }
.pricing-note p { color: var(--brown); line-height: 1.75; }
.faq-list-simple { border-top: 1px solid var(--tan-border); }
.faq-list-simple details { border-bottom: 1px solid var(--tan-border); }
.faq-list-simple summary { cursor: pointer; list-style: none; padding: 22px 42px 22px 0; position: relative; font-weight: 750; color: var(--ink); }
.faq-list-simple summary::-webkit-details-marker { display: none; }
.faq-list-simple summary::after { content: "+"; position: absolute; right: 0; top: 18px; color: var(--green); font-size: 22px; }
.faq-list-simple details[open] summary::after { content: "−"; }
.faq-list-simple details p { margin: -4px 0 24px; color: var(--brown); line-height: 1.7; }

.timeline-wrap { max-width: 1040px; }
.timeline { border-top: 1px solid var(--tan-border); }
.timeline article { display: grid; grid-template-columns: 120px 1fr; gap: 28px; padding: 28px 0; border-bottom: 1px solid var(--tan-border); }
.timeline article > span { color: var(--terracotta); font-weight: 800; }
.timeline h3 { margin: 0 0 8px; font-family: var(--font-heading); font-size: 20px; }
.timeline p { margin: 0; color: var(--brown); line-height: 1.65; }
.values-section { max-width: 1050px; }
.values-row { display: grid; grid-template-columns: repeat(3,1fr); border-top: 1px solid var(--tan-border); border-bottom: 1px solid var(--tan-border); }
.values-row article { padding: 32px 30px 32px 0; }
.values-row article + article { padding-left: 30px; border-left: 1px solid var(--tan-border); }
.values-row h3 { margin: 0 0 10px; font-family: var(--font-heading); font-size: 20px; }
.values-row p { margin: 0; color: var(--brown); line-height: 1.7; font-size: 14px; }

.contact-hero { padding-bottom: 100px; }
.contact-grid { display: grid; grid-template-columns: minmax(0,.85fr) minmax(min(360px, 100%),.75fr); gap: clamp(52px,8vw,110px); align-items: start; }
.contact-intro { padding-top: 12px; }
.contact-points { margin-top: 40px; border-top: 1px solid var(--tan-border); }
.contact-points > div { padding: 18px 0; border-bottom: 1px solid var(--tan-border); display: flex; flex-direction: column; gap: 6px; }
.contact-points span { color: var(--brown-2); font-size: 11px; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.contact-points strong { font-size: 14px; }
.contact-form-card { padding: clamp(28px,4vw,40px); border: 1px solid var(--tan-border); border-radius: var(--radius-lg); background: var(--white); box-shadow: var(--shadow-md); }
.contact-form { display: flex; flex-direction: column; }
.contact-success { flex-direction: column; align-items: flex-start; gap: 10px; }
.success-mark { width: 46px; height: 46px; display: grid; place-items: center; border-radius: 50%; background: var(--green); color: #fff; font-weight: 900; font-size: 20px; }
.contact-success h2 { margin: 8px 0 0; font-family: var(--font-heading); }
.contact-success p { margin: 0; color: var(--brown); }
.field { gap: 7px; margin-bottom: 18px; }
.field > span, .field label { font-size: 13px; font-weight: 750; }
.field input, .field select, .field textarea {
  width: 100%; font-family: var(--font-body); font-size: 15px; padding: 13px 14px; border-radius: 10px;
  border: 1px solid var(--tan-border); background: var(--white); color: var(--ink); transition: border-color .15s, box-shadow .15s;
}
.field textarea { resize: vertical; min-height: 128px; }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 3px rgba(31,90,67,.12); }
.field-error { color: #B53B34; }

.legal-page { padding: clamp(72px,8vw,110px) 0; }
.legal-header { padding-bottom: 42px; border-bottom: 1px solid var(--tan-border); }
.legal-updated { margin: 0 0 20px; color: var(--brown-2); font-size: 13px; font-weight: 700; }
.legal-content section { display: grid; grid-template-columns: 56px 1fr; gap: 20px; padding: 32px 0; border-bottom: 1px solid var(--tan-border); }
.legal-number { color: var(--terracotta); font-size: 11px; font-weight: 800; letter-spacing: .08em; }
.legal-content h2 { margin: 0 0 10px; font-family: var(--font-heading); font-size: 21px; }
.legal-content p { margin: 0; color: var(--brown); line-height: 1.75; }

.auth-card { border-radius: var(--radius-lg); border-color: var(--tan-border); box-shadow: var(--shadow-md); }
.auth-card .btn-primary { border-radius: 10px; }

.card { border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
.card:hover { transform: none; box-shadow: var(--shadow-sm); }

.site-footer { background: #17221C; padding: 58px 0 26px; }
.footer-grid { width: min(calc(100% - 40px), var(--container)); margin: 0 auto; display: grid; grid-template-columns: 1.8fr repeat(3, .7fr); gap: 54px; }
.footer-brand { display: inline-flex; align-items: center; gap: 10px; color: #fff; text-decoration: none; font-family: var(--font-heading); font-size: 17px; font-weight: 700; }
.footer-brand strong { color: #F3945E; }
.footer-brand-block p { max-width: 360px; margin: 18px 0 0; color: #B7C2BA; font-size: 13px; line-height: 1.7; }
.footer-heading { color: #AEB8B1; font-size: 11px; }
.footer-links { display: flex; flex-direction: column; gap: 11px; }
.site-footer .footer-links a { color: #E8EEE9; font-size: 13px; font-weight: 600; }
.site-footer .footer-links a:hover { color: #fff; }
.footer-bottom { width: min(calc(100% - 40px), var(--container)); margin: 44px auto 0; padding-top: 20px; border-top: 1px solid rgba(255,255,255,.1); display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap; color: #95A099; font-size: 11px; }

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

@media (max-width: 1120px) {
  .site-nav-inner { width: min(calc(100% - 28px), var(--container)); }
  .nav-links, .nav-login, a.nav-cta-desktop.btn-primary { display: none; }
  .hamburger { display: flex; }
  .mobile-menu.open { display: flex; }
  .footer-grid { grid-template-columns: 1.5fr repeat(3,1fr); gap: 34px; }
}

@media (max-width: 820px) {
  .container { width: min(calc(100% - 32px), var(--container)); }
  .section { padding-block: 68px; }
  .hero-grid, .page-hero-grid, .story-grid, .story-grid-hero, .onboarding-grid, .pricing-layout, .contact-grid, .split-heading, .feature-showcase, .feature-showcase.reverse, .product-feature, .product-feature.reverse, .hero-scan-showcase { grid-template-columns: minmax(0, 1fr); }
  .hero-section { padding-top: 46px; }
  .display-title { font-size: clamp(42px, 11.5vw, 58px); }
  .page-title { font-size: clamp(36px, 9vw, 48px); }
  .product-window-hero { transform: none; }
  .proof-strip-inner { align-items: flex-start; flex-direction: column; padding-block: 20px; }
  .shop-type-row { justify-content: flex-start; }
  .benefit-list, .values-row { grid-template-columns: minmax(0, 1fr); }
  .benefit-list article, .benefit-list article + article, .values-row article, .values-row article + article { padding: 25px 0; border-left: 0; }
  .benefit-list article + article, .values-row article + article { border-top: 1px solid var(--tan-border); }
  .product-feature.reverse .product-window, .feature-showcase.reverse > :first-child { order: 0; }
  .feature-stack { gap: 66px; }
  .icon-visual { min-height: 280px; }
  .pricing-note { position: static; }
  .final-cta-card { align-items: flex-start; flex-direction: column; }
  .final-cta-card .hero-actions { width: 100%; }
  .timeline article { grid-template-columns: 78px 1fr; }
  .footer-grid { grid-template-columns: 1.35fr 1fr 1fr; }
  .footer-grid > :last-child { grid-column: 2 / 4; }
}

@media (max-width: 560px) {
  .site-nav-inner { width: calc(100% - 24px); min-height: 64px; padding: 8px 0; }
  .brand-name { font-size: 16px; }
  .brand img { width: 34px; height: 34px; }
  .lang-switch { display: flex; }
  .lang-btn { padding: 5px 8px; }
  .hero-actions { display: grid; grid-template-columns: minmax(0, 1fr); width: 100%; }
  .hero-actions .btn-primary, .hero-actions .btn-secondary { width: 100%; }
  .micro-trust { display: grid; grid-template-columns: minmax(0, 1fr); }
  .product-window, .story-image, .contact-form-card, .pricing-card-new, .final-cta-card { border-radius: 16px; }
  .product-window-bar { min-height: 36px; }
  .section-heading { margin-bottom: 34px; }
  .timeline article { grid-template-columns: minmax(0, 1fr); gap: 8px; }
  .legal-content section { grid-template-columns: 38px 1fr; gap: 12px; }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand-block { grid-column: 1 / -1; }
  .footer-grid > :last-child { grid-column: auto; }
  .sticky-mobile-cta { position: sticky; bottom: 0; z-index: 45; display: block; padding: 10px 12px max(10px, env(safe-area-inset-bottom)); background: var(--nav-bg); backdrop-filter: blur(12px); border-top: 1px solid var(--tan-border); }
  .sticky-mobile-cta .btn-primary { width: 100%; display: flex; align-items: center; justify-content: center; text-align: center; }
  #faq-bot-launcher { bottom: 76px; }
  #faq-bot-panel { bottom: 76px; }
}


/* Auth page */
.auth-page-redesign { padding: clamp(54px,7vw,92px) 0 100px; }
.auth-page-grid { display: grid; grid-template-columns: minmax(0,.95fr) minmax(min(380px, 100%),.72fr); gap: clamp(50px,8vw,110px); align-items: start; }
.auth-context { padding-top: 18px; position: sticky; top: 104px; }
.auth-context h1 { max-width: 560px; margin: 0 0 18px; font-family: var(--font-heading); font-size: clamp(34px,4vw,52px); line-height: 1.06; letter-spacing: -.045em; }
.auth-context > p { max-width: 520px; margin: 0 0 30px; color: var(--brown); line-height: 1.72; }
.auth-context-image { overflow: hidden; max-width: 520px; border-radius: 18px; border: 1px solid var(--tan-border); }
.auth-context-image img { width: 100%; display: block; }
.auth-form-wrap { width: 100%; max-width: 470px; margin-left: auto; }
.auth-form-wrap > div:last-child { color: var(--brown); }
.auth-card { max-width: none; padding: clamp(28px,4vw,38px); }
@media (max-width: 820px) {
  .auth-page-grid { grid-template-columns: minmax(0, 1fr); }
  .auth-context { position: static; }
  .auth-context-image { display: none; }
  .auth-form-wrap { max-width: 520px; margin: 0; }
}

/* Nepali type correction. The tight negative letter-spacing tuned for
   Poppins/Latin at these display sizes (as low as -.055em) collides
   Devanagari conjuncts and matras instead of just tracking Latin letters
   closer together -- that's the cause of the broken/overlapping look in
   Nepali headings, not a missing font weight (all needed Noto Sans
   Devanagari weights are loaded). html[lang] is already set correctly by
   script.js's applyLang(), so this scopes cleanly without touching English. */
html[lang="ne"] .brand-name,
html[lang="ne"] .section-title,
html[lang="ne"] .display-title,
html[lang="ne"] .page-title,
html[lang="ne"] .product-feature-copy h3, html[lang="ne"] .feature-copy h2,
html[lang="ne"] .final-cta-card h2,
html[lang="ne"] .pricing-card-head h2,
html[lang="ne"] .pricing-note h3,
html[lang="ne"] .auth-context h1 {
  letter-spacing: normal;
}
html[lang="ne"] .display-title { line-height: 1.35; }
html[lang="ne"] .page-title, html[lang="ne"] .section-title, html[lang="ne"] .auth-context h1 { line-height: 1.3; }

/* Language-toggle live demo (Features page, last article) */
.live-demo-search {
  background: var(--white); border: 1px solid var(--tan-border); border-radius: 10px;
  padding: 9px 12px; font-size: 11px; color: var(--brown);
}

/* Shared "full app chrome" pieces reused across every live-demo phone mockup */
.live-demo-quickadd {
  background: var(--cream-2); border: 1px dashed var(--tan-border); border-radius: 10px;
  padding: 8px 12px; font-size: 11px; font-weight: 700; color: var(--brown);
  text-align: center;
}
.live-demo-cart-header {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 11px; font-weight: 800; color: var(--ink); padding: 0 2px;
}
.live-demo-cart-header .live-demo-cart-clear {
  font-weight: 700; color: var(--red, #dc2626); font-size: 10px;
}
.live-demo-bottom-row {
  display: flex; align-items: stretch; gap: 8px; margin-top: auto;
}
.live-demo-camera-btn {
  flex: 0 0 auto; width: 42px; display: flex; align-items: center; justify-content: center;
  background: var(--terracotta); color: var(--white); border: none; border-radius: 10px;
}
.live-demo-lang-btn {
  border: none; background: var(--cream-2); color: var(--ink); font-weight: 800;
  font-size: 11px; padding: 5px 10px; border-radius: 999px; flex: 0 0 auto;
  transition: transform .12s ease, background .12s ease;
}
.live-demo-lang-btn.tapped { transform: scale(.93); background: var(--green); color: var(--white); }
.live-demo-lang-cart {
  background: var(--white); border: 1px solid var(--tan-border); border-radius: 12px;
  padding: 10px 12px; display: flex; flex-direction: column; gap: 8px;
}
.live-demo-lang-cart-head {
  display: flex; justify-content: space-between; align-items: center;
  font-size: 12px; font-weight: 700; color: var(--ink);
  padding-bottom: 6px; border-bottom: 1px solid var(--tan-border);
}
.live-demo-lang-cart-head span:last-child { font-weight: 700; color: var(--red, #dc2626); font-size: 11px; }
[id^="liveDemo"][id$="Label"], [id$="Sub"] { transition: opacity .16s ease; }
.swap-out { opacity: 0; }

/* Barcode-scan live demo: camera view + continuous scanline, a brief
   "found" flash on detection, then the item lands in the cart below,
   matching the same add-to-cart language as the other live demos. */
.live-demo-scan-box[hidden] { display: none; }
.live-demo-scan-btn[hidden] { display: none; }
.live-demo-scan-btn {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--terracotta); color: var(--white); border: none;
  border-radius: 12px; padding: 14px; font-weight: 800; font-size: 13px;
  transition: transform .12s ease, background .12s ease;
}
.live-demo-scan-btn.tapped { transform: scale(.96); background: var(--terracotta-dark); }
.live-demo-scan-box {
  position: relative; background: var(--white); border: 2px dashed var(--tan-border);
  border-radius: 14px; height: 110px; display: flex; align-items: center;
  justify-content: center; overflow: hidden; transition: border-color .2s ease;
}
.live-demo-scan-box.found { border-color: var(--green); border-style: solid; }
.live-demo-scanline {
  position: absolute; left: 12px; top: 14%; width: calc(100% - 24px); height: 2px;
  background: var(--terracotta); border-radius: 2px;
  animation: scanline 2.4s ease-in-out infinite;
}
.live-demo-scan-box.found .live-demo-scanline { background: var(--green); animation: none; top: 50%; }
.live-demo-scan-toast {
  position: absolute; top: 8px; right: 8px; background: var(--green); color: var(--white);
  font-size: 10px; font-weight: 800; padding: 3px 8px; border-radius: 999px;
  opacity: 0; transform: translateY(-4px); transition: opacity .2s ease, transform .2s ease;
}
.live-demo-scan-toast.show { opacity: 1; transform: translateY(0); }

/* Phone status bar (injected via script.js, see there for why) */
/* The status bar sits LEVEL with the camera, time to the left of it and the
   signal icons to the right, exactly as a real phone does. It used to be a
   normal flow child, so the screen's own padding-top pushed the whole bar down
   BELOW the island, roughly 30px off on the iPhone and 25px on the Android.
   No real device does that, and it was the main thing making these read as
   drawings rather than phones.
   Taken out of flow and pinned to the same vertical band as the hardware. The
   island is 82px wide and centred, leaving roughly 75px clear each side on a
   232px screen, so the time and icons never collide with it. */
.phone-statusbar {
  position: absolute; left: 0; right: 0; z-index: 6;
  display: flex; align-items: center; justify-content: space-between;
  /* 16px of side padding pushed the icon cluster inward far enough to overlap
     the island by 2px. 10px keeps it clear on the narrowest frame we use. */
  padding: 0 9px; font-size: 11px; font-weight: 700; color: var(--ink);
}
/* The island spans 6px to 30px down the screen, so a 24px bar at 6px shares its
   centre line. The punch hole spans 7px to 19px, centred at 13px, so an 18px
   bar at 4px matches. */
.phone-frame.iphone .phone-statusbar { top: 6px; height: 24px; }
.phone-frame.android .phone-statusbar { top: 4px; height: 18px; }
.phone-statusbar-icons { display: flex; align-items: center; gap: 3px; color: var(--ink); }
.phone-statusbar-icons svg { display: block; fill: currentColor; width: 13px; height: 9px; }
/* The battery is wider than the signal and wifi glyphs. */
.phone-statusbar-icons svg:last-child { width: 19px; }

/* The hand-built Admin and Reports phone mockups that used to live here were
   replaced on 2026-08-22 with real captures of the mobile admin panel
   (screenshot-admin-mobile.jpg, screenshot-reports-mobile.jpg), now that it is
   genuinely usable on a phone. Their ~65 lines of .admin-mock-* rules are gone
   with them; see .phone-shot at the end of this file. The old comment argued
   markup would "never go stale the way screenshots do", which was true of the
   palette and false of the product: the mock showed a Nepali admin UI the real
   admin has never had. */

/* ---------------------------------------------------------------------------
   Dark mode.

   Follows the phone or browser setting by default, with an optional toggle that
   overrides it either way. The whole thing is token swaps on :root, so no
   component rule needed changing.

   Two decisions worth recording, because both are easy to get wrong:

   1. The brand green is NOT reused as-is. #1F5A43 is deep enough to nearly
      disappear against a dark background, so dark mode lightens it. A straight
      inversion of a dark-green-on-cream brand produces unreadable buttons.

   2. The phone mockups stay LIGHT in both modes, see .phone-frame below. They
      depict the POS, which is deliberately locked to light mode (its own
      stylesheets carry color-scheme: only light), so darkening them here would
      show customers a product that does not exist.
   --------------------------------------------------------------------------- */
:root { color-scheme: light; }

/* The dark token set, defined once and applied by both the media query (auto)
   and the explicit [data-theme="dark"] (manual override). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --cream: #15171A;
    --cream-2: #1B1E21;
    --tan-border: #2F3439;
    --ink: #EDEAE3;
    --ink-soft: #C7C4BC;
    --brown: #9AA09B;
    --brown-2: #7C827D;
    --terracotta: #F0762E;
    --terracotta-dark: #C94F0F;  /* NOT lightened: buttons put white text on this, and
                                    lightening it drops that from 4.56:1 to 3.41:1, undoing the
                                    deliberate contrast fix from the 2026-08-21 review. */
    --terracotta-light: #FF9E62;
    --terracotta-text: #FF9457;
    --green: #2E7D5B;  /* --green is a BACKGROUND with white text in several places
                          (FAQ header, success mark, a solid button), so it cannot be
                          lightened freely: #4FA882 looked right but measured 2.89:1
                          against white. #2E7D5B holds 5.00:1 and still reads clearly
                          against the dark page. Light green for TEXT is --green-text. */
    --green-light: #4FA882;
    --green-mist: #1A3A2D;
    --green-accent: #8DBBA5;
    --green-text: #6FCBA1;
    --white: #1E2126;
    --footer-muted: #8C948E;
    --footer-text-soft: #E4E9E5;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
    --nav-bg: rgba(21,23,26,.92);
    --strip-bg: rgba(255,255,255,.04);
    --surface-warm: #22262A;
    --surface-warm-2: #23282C;
    --surface-green: #1B322A;
    --surface-orange: #2E2620;
    --green-deep: #245F46;
    --shadow-md: 0 16px 42px rgba(0,0,0,.45);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --cream: #15171A;
  --cream-2: #1B1E21;
  --tan-border: #2F3439;
  --ink: #EDEAE3;
  --ink-soft: #C7C4BC;
  --brown: #9AA09B;
  --brown-2: #7C827D;
  --terracotta: #F0762E;
  --terracotta-dark: #C94F0F;  /* see the note in the media query block above */
  --terracotta-light: #FF9E62;
  --terracotta-text: #FF9457;
  --green: #2E7D5B;  /* see the note in the media query block above */
  --green-light: #4FA882;
  --green-mist: #1A3A2D;
  --green-accent: #8DBBA5;
  --green-text: #6FCBA1;
  --white: #1E2126;
  --footer-muted: #8C948E;
  --footer-text-soft: #E4E9E5;
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --nav-bg: rgba(21,23,26,.92);
  --strip-bg: rgba(255,255,255,.04);
  --surface-warm: #22262A;
  --surface-warm-2: #23282C;
  --surface-green: #1B322A;
  --surface-orange: #2E2620;
  --green-deep: #245F46;
  --shadow-md: 0 16px 42px rgba(0,0,0,.45);
}

/* The phone mockups depict the real POS, which is permanently light. Custom
   properties inherit, so redefining the light values here pins everything
   inside the frame back to light regardless of the page theme, without any
   component inside needing to know a theme exists. */
.phone-frame,
.tablet-frame,
.product-window {
  color-scheme: light;
  /* Re-establish `color` from the pinned token, not just the tokens themselves.
     `color` INHERITS, so anything inside that does not set its own colour would
     otherwise inherit the dark theme's ink from <body> and render light text on
     a cream phone screen. Redefining the custom properties alone does not fix
     that, because the inherited value was already computed further up the tree.
     Caught by diffing every computed colour inside these frames across both
     themes: backgrounds matched, 126 elements' text did not. */
  color: var(--ink);
  --cream: #F7F4EC;
  --cream-2: #EFEADF;
  --tan-border: #DED8CA;
  --ink: #20211D;
  --ink-soft: #3E403A;
  --brown: #62645D;
  --brown-2: #818178;
  --white: #FFFFFF;
  --green: #1F5A43;
  --green-light: #2B7659;
  --green-mist: #E3F0E9;
  --green-text: #1F5A43;
  --terracotta: #E86118;
  --terracotta-dark: #C94F0F;
  --terracotta-text: #C94F0F;
}

/* Theme toggle button in the nav. */
.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; flex: 0 0 auto;
  background: transparent; border: 1px solid var(--tan-border);
  border-radius: 10px; color: var(--ink); cursor: pointer;
  transition: background .2s var(--ease), border-color .2s var(--ease);
}
.theme-toggle:hover { background: var(--cream-2); border-color: var(--brown-2); }
.theme-toggle svg { display: block; width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; }
.theme-toggle .icon-moon { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-sun { display: none; }
:root[data-theme="dark"] .theme-toggle .icon-moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .icon-sun { display: none; }
  :root:not([data-theme="light"]) .theme-toggle .icon-moon { display: block; }
}

/* ---------------------------------------------------------------------------
   Features hero: the same cashier on an Android and an iPhone, side by side.

   This slot used to be a desktop browser window showing a screenshot, which
   made the opening image of the product tour argue for a computer on exactly
   the page that spends the rest of its length showing phones. Two real device
   silhouettes make the compatibility point without a word of copy: the punch
   hole reads Android, the island reads iPhone, and the captions remove any
   doubt.

   They stay side by side at every width rather than stacking. Stacked, the
   reader sees one phone at a time and the whole point (it works on both) is
   lost, so they scale down together instead.
   --------------------------------------------------------------------------- */
.hero-devices {
  display: flex; align-items: flex-end; justify-content: center;
  gap: clamp(10px, 3vw, 26px);
}
.hero-device {
  margin: 0; display: flex; flex-direction: column; align-items: center; gap: 10px;
  flex: 1 1 0; min-width: 0; max-width: 210px;
  /* `main figure { overflow: hidden }` exists for the image figures that have a
     hover zoom. These are <figure> too, so they inherited it and it silently
     clipped the side buttons, which sit 5px outside the frame. The buttons were
     rendering the whole time, just cut off. */
  overflow: visible;
}
/* A slight stagger stops the pair reading as one wide slab. */
/* margin, not transform: a transform does not affect the layout box, so the
   shifted caption fell outside the container and got clipped. */
.hero-device:first-child { margin-top: 14px; }
.hero-device figcaption {
  font-size: 12px; font-weight: 800; letter-spacing: .06em; text-transform: uppercase;
  color: var(--brown); white-space: nowrap;
}
.hero-devices .phone-frame-lg { width: 100%; }

/* The cashier's own header strip inside a mockup. The other mockups build this
   with inline styles; naming it keeps the two hero phones consistent with each
   other and with the real app. */
.live-demo-topbar {
  display: flex; align-items: center; gap: 8px; flex: 0 0 auto;
  background: var(--white); padding: 10px 12px;
  border-bottom: 1px solid var(--tan-border);
}
.live-demo-badge {
  width: 21px; height: 21px; border-radius: 7px; background: var(--green); color: var(--white);
  font-family: var(--font-heading); font-weight: 700; font-size: 11px;
  display: flex; align-items: center; justify-content: center; flex: 0 0 auto;
}
.live-demo-shop {
  font-family: var(--font-heading); font-weight: 700; font-size: 12px; color: var(--ink);
  flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.live-demo-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }

@media (max-width: 560px) {
  .hero-device figcaption { font-size: 10.5px; letter-spacing: .04em; }
  .hero-devices { gap: 8px; }
}

/* The hero pair are the narrowest frames on the site, so the status bar has to
   shrink with them or the icons run into the island. Measured, not guessed. */
.hero-devices .phone-statusbar { font-size: 9.5px; padding: 0 7px; }
.hero-devices .phone-statusbar-icons { gap: 2px; }
.hero-devices .phone-statusbar-icons svg { width: 11px; height: 8px; }
.hero-devices .phone-statusbar-icons svg:last-child { width: 16px; }

/* ---------------------------------------------------------------------------
   Landscape tablet, for the "See the actual product" screenshots on the home
   page.

   These were browser windows with a fake title bar, which framed the product as
   something you run on a computer. The screenshots themselves are real and stay
   exactly as they were; only the frame changed, so the section still proves the
   product exists while showing the device a shop would actually stand on the
   counter.

   Modelled on the iPad Pro 11 in the reference: one even bezel all the way
   round rather than a phone's tapered look, moderate corners, and the front
   camera on what is the SHORT edge in portrait, which lands on the left edge
   once the device is turned landscape.
   --------------------------------------------------------------------------- */
.tablet-frame {
  position: relative;
  background: linear-gradient(150deg, #3A3D39 0%, #1B1D1A 26%, #161815 74%, #343739 100%);
  border-radius: 26px;
  padding: 14px 20px;
  box-shadow: 0 22px 48px rgba(32,33,29,.24);
  max-width: 100%;
}
.tablet-screen {
  background: var(--cream);
  border-radius: 12px;
  overflow: hidden;
  line-height: 0;
}
.tablet-screen img { display: block; width: 100%; height: auto; }
/* Left edge, vertically centred: an iPad Pro 11 turned on its side. */
.tablet-cam {
  position: absolute; left: 8px; top: 50%; transform: translateY(-50%);
  width: 5px; height: 5px; border-radius: 50%;
  background: #0C0E10; box-shadow: inset 0 0 0 1px rgba(120,150,190,.45);
}
@media (max-width: 560px) {
  .tablet-frame { border-radius: 18px; padding: 9px 13px; }
  .tablet-screen { border-radius: 8px; }
  .tablet-cam { left: 5px; width: 4px; height: 4px; }
}


/* ---------------------------------------------------------------------------
   Fluid nav: fits any width without per-device budgeting

   The nav was previously sized by hand at each breakpoint, with a comment
   budgeting the row in exact pixels ("brand 202 + full pill 127 + hamburger 44
   + gaps"). That approach held right up until the theme toggle was added to
   .nav-right, which spent 36px + a gap that nobody re-measured, and the row
   started overflowing at 320px on every page in the site. Hand-budgeted layout
   only stays correct while everyone who edits it redoes the arithmetic.

   So the row is made intrinsically fluid instead, and the sizes below are
   ratios rather than fixed numbers:

     - .nav-right never shrinks. Those are tap targets; squashing a 44px
       hamburger to make room for a wordmark is the wrong trade.
     - .brand absorbs all the pressure. It shrinks, then its text scales down
       with the viewport, then as a last resort it ellipsises.
     - gaps scale with the viewport rather than stepping at a breakpoint.

   The practical effect is that the row can no longer push the page sideways.
   Add another control to .nav-right later and the brand yields to it, which is
   a visible squeeze rather than a horizontal scrollbar on every page.

   Deliberately NOT done here: overflow-x: hidden on body. That would have
   silenced this bug rather than fixed it, and silenced the next one too.
   --------------------------------------------------------------------------- */
.site-nav-inner { gap: clamp(8px, 2.5vw, 16px); }

.brand {
  /* min-width: 0 is what actually lets a flex item shrink below its content
     size; without it the text refuses to give ground and the row overflows. */
  min-width: 0;
  flex: 0 1 auto;
}
.brand-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* Floor is 14px: measured, "Khatiwada POS" still fits the 320px row at that
     size, and it is the smallest the wordmark stays legible at. */
  font-size: clamp(14px, 4.2vw, 18px);
}
.brand img { flex-shrink: 0; }

.nav-right {
  flex: 0 0 auto;
  gap: clamp(6px, 2vw, 10px);
}

/* Smallest phones still in use (320px: iPhone SE 1st gen, older budget
   Androids). At this width the full "Khatiwada POS" wordmark, the theme
   toggle, the EN/ने pill and the hamburger together need about 306px against
   296px of container, so the wordmark was ellipsising.

   The ~14px is bought back from the logo mark and the language pill's padding,
   NOT from the theme toggle or the hamburger. Those two are tap targets and
   are already at or under the 44px guideline; trading real touch accuracy for
   a few characters of brand name is the wrong way round. */
@media (max-width: 359px) {
  .brand img { width: 28px; height: 28px; }
  .lang-btn { padding: 5px 6px; }
  /* Measured: at 320px the wordmark wanted 107px and had 103px. The gap
     between mark and wordmark is the cheapest 4px on the row. */
  .brand { gap: 6px; }
}

/* Below ~300px (Galaxy Fold cover screen and similar) the wordmark cannot fit
   at any readable size, and "Khatiw..." reads as a rendering fault rather than
   a brand. The logo mark alone is the honest fallback; the full name is still
   one tap away in the menu and in the page title. */
@media (max-width: 299px) {
  .brand-name { display: none; }
}

/* A real captured screen filling a phone mockup, replacing the hand-built
   imitation that used to sit here. object-fit: cover with a top anchor means
   the android and iphone frames, whose screen areas differ slightly (250x498
   against 234x472), both crop a few pixels off the bottom rather than
   distorting the screenshot. The status bar is still injected above this by
   script.js and .phone-screen's padding-top keeps clear of it. */
.phone-shot {
  flex: 1;
  min-height: 0;
  width: 100%;
  display: block;
  object-fit: cover;
  object-position: top center;
}
