/* ============================================================================
 *  Loyal Sathi — the public website.
 *
 *  Built on the same tokens.css the product uses, so the marketing site and
 *  the app it is selling look like one company. Deliberately separate from
 *  app.css and admin.css: those two are laid out for a phone held at a counter
 *  and a desk panel respectively, and neither wants a wide marketing page's
 *  rules leaking in.
 *
 *  Nothing here is themed per partner. A shop's colours belong on a shop's
 *  pages; this is ours.
 * ==========================================================================*/

/* ---------------------------------------------------------------- brand ---
 * Loyal Sathi's own colours, taken from the wordmark: a cream mark on a deep
 * aubergine that fades almost to black.
 *
 * Overridden here rather than in tokens.css on purpose. tokens.css is shared
 * with every shop's card and panel, and a shop's colours are the shop's own —
 * editing the palette there would repaint every partner on the platform. This
 * file is only ever loaded by the public website, so redefining the tokens is
 * contained to our own pages.
 * -------------------------------------------------------------------------*/
:root{
  --plum:        #1D0328;   /* the lighter end of the logo's background */
  --plum-deep:   #0A020D;   /* the darker end */
  --plum-soft:   #2E0B3D;   /* raised surfaces on dark */
  --plum-line:   #3D1A4D;   /* hairlines on dark */
  --cream-brand: #EFE5CA;   /* the wordmark itself */

  /* Cream is a light tint, so it can only carry text on the dark ground.
     This deeper gold-brown is what brand-coloured text uses on light
     surfaces, where cream would be invisible. */
  --cream-ink:   #6B5423;

  /* The site's own semantic layer, built on those two. */
  --bg:          #FBF8F1;
  --surface:     #FFFFFF;
  --surface-2:   #F5EFE3;
  --surface-3:   #EDE4D3;
  --line:        #E4DAC6;
  --line-strong: #CFC1A6;

  --text:        #1A0A22;
  --text-muted:  #5C4A66;
  --text-soft:   #8B7A94;
  --text-on-dark:#EFE5CA;

  --grad-plum:   linear-gradient(155deg, #2A0B38 0%, #1D0328 45%, #0A020D 100%);
  --grad-cream:  linear-gradient(135deg, #F6EEDA 0%, #EFE5CA 55%, #E3D5B2 100%);

  --font-brand:  'Montserrat', 'Segoe UI', system-ui, -apple-system, Arial, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

body{
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-brand);
  font-size: var(--t-base);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

/* The scroll bug that bit the app twice: overflow on <body> makes it a scroll
   container that cannot scroll, and it then eats the mouse wheel instead of
   passing it to the root. Keep both on <html>. */
html{ overflow-x: hidden; }

img{ max-width: 100%; height: auto; display: block; }
a{ color: var(--plum); text-underline-offset: 3px; }

.wrap{ width: 100%; max-width: 1080px; margin: 0 auto; padding: 0 var(--s-5); }
.wrap-narrow{ max-width: 720px; }

/* --------------------------------------------------------------- header --- */
.site-head{
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in oklab, var(--bg) 88%, transparent);
  backdrop-filter: saturate(160%) blur(12px);
  border-bottom: 1px solid var(--line);
}
.site-head .wrap{
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-4); min-height: 68px;
}
.site-brand{
  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: var(--font-brand); font-size: var(--t-lg); font-weight: 700;
  color: var(--plum); text-decoration: none; letter-spacing: var(--track-tight);
}
.site-brand img{ width: 34px; height: 34px; border-radius: var(--r-md); }

.site-nav{ display: flex; align-items: center; gap: var(--s-1); }
.site-nav a{
  padding: 8px 12px; border-radius: var(--r-md); text-decoration: none;
  color: var(--text-muted); font-size: var(--t-sm); font-weight: 550;
  white-space: nowrap;
}
.site-nav a:hover{ color: var(--text); background: var(--surface-2); }
.site-nav a[aria-current="page"]{ color: var(--plum); background: var(--surface-2); }

/* The menu collapses to the two things that matter on a phone: pricing and
   the call to action. The rest is reachable from the footer. */
.site-nav .nav-more{ display: inline-flex; gap: var(--s-1); }
@media (max-width: 720px){
  .site-nav .nav-more{ display: none; }
  .site-head .wrap{ min-height: 60px; }
}

/* --------------------------------------------------------------- buttons -- */
.btn{
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  padding: 12px 22px; border: 0; border-radius: var(--r-full);
  font-family: var(--font-brand); font-size: var(--t-sm); font-weight: 650;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: transform var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
  background: var(--plum); color: var(--text-on-dark);
}
.btn:hover{ transform: translateY(-1px); box-shadow: var(--shadow-md); }
.btn:active{ transform: none; }
.btn-gold{ background: var(--grad-cream); color: var(--plum); }
.btn-ghost{
  background: transparent; color: var(--plum);
  box-shadow: inset 0 0 0 1.5px var(--line-strong);
}
.btn-ghost:hover{ background: var(--surface-2); }
.btn-lg{ padding: 15px 30px; font-size: var(--t-md); }
.btn[disabled]{ opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

/* ----------------------------------------------------------------- hero --- */
.hero{
  background: var(--grad-plum);
  color: var(--text-on-dark);
  padding: clamp(56px, 9vw, 104px) 0 clamp(64px, 10vw, 120px);
  position: relative; overflow: hidden;
}
/* A soft cream bloom off to one side, so the flat aubergine has some depth
   without anything sitting on top of the words. */
.hero::after{
  content: ""; position: absolute; inset: -30% -20% auto 45%;
  height: 720px;
  background: radial-gradient(closest-side,
              color-mix(in oklab, var(--cream-brand) 16%, transparent), transparent 70%);
  pointer-events: none;
}
.hero .wrap{ position: relative; z-index: 1; }
.hero h1{
  font-family: var(--font-brand);
  font-size: clamp(2.1rem, 5.4vw, 3.6rem);
  line-height: var(--lh-tight); letter-spacing: var(--track-tight);
  /* The hero grid already sets the column width, so a tight ch cap here only
     forced a fourth line. Let it fill the column it is given. */
  margin: 0 0 var(--s-4);
  text-wrap: balance;
}
.hero p.lede{
  font-size: clamp(1.02rem, 2.1vw, 1.2rem);
  max-width: 56ch; margin: 0 0 var(--s-6);
  color: color-mix(in oklab, var(--text-on-dark) 82%, transparent);
}
.hero .acts{ display: flex; gap: var(--s-3); flex-wrap: wrap; }
.hero .note{
  margin-top: var(--s-5); font-size: var(--t-sm);
  color: color-mix(in oklab, var(--text-on-dark) 62%, transparent);
}
/* The eyebrow only ever sits on the dark hero, so it takes the cream itself.
   --cream-ink is the light-background variant and would be near-invisible
   here. */
.eyebrow{
  display: inline-block; margin-bottom: var(--s-3);
  font-size: var(--t-xs); font-weight: 700; letter-spacing: var(--track-wide);
  text-transform: uppercase;
  color: color-mix(in oklab, var(--cream-brand) 78%, transparent);
}

/* -------------------------------------------------------------- sections -- */
.section{ padding: clamp(52px, 8vw, 88px) 0; }
.section-alt{ background: var(--surface-2); }
.section-head{ max-width: 62ch; margin: 0 0 var(--s-8); }
.section-head.centred{ margin-inline: auto; text-align: center; }
.section-head h2{
  font-family: var(--font-brand);
  font-size: clamp(1.6rem, 3.4vw, 2.3rem);
  line-height: var(--lh-snug); letter-spacing: var(--track-tight);
  margin: 0 0 var(--s-3); color: var(--plum);
}
.section-head p{ margin: 0; color: var(--text-muted); font-size: var(--t-md); }

/* ----------------------------------------------------------------- grid --- */
.grid{ display: grid; gap: var(--s-5); }
.grid-3{ grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-2{ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.card{
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-xl); padding: var(--s-6);
  box-shadow: var(--shadow-xs);
}
.card h3{
  font-size: var(--t-md); font-weight: 650; margin: 0 0 var(--s-2);
  color: var(--plum);
}
.card p{ margin: 0; color: var(--text-muted); font-size: var(--t-sm); }
/* Drawn icons, not emoji.
   Emoji are rendered by the operating system, so the same page looks like six
   different products across Windows, Android and iOS, and they sit at
   whatever weight and colour the vendor chose. These come from the app's own
   sprite: one stroke weight, our own colour, identical everywhere. */
.card .ico{
  width: 46px; height: 46px; border-radius: var(--r-lg);
  display: grid; place-items: center; margin-bottom: var(--s-5);
  background: linear-gradient(150deg,
              color-mix(in oklab, var(--plum) 10%, var(--surface)),
              color-mix(in oklab, var(--plum) 4%, var(--surface)));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--plum) 12%, transparent);
  color: var(--plum);
}
.card .ico svg{ width: 22px; height: 22px; }

/* One shared rule for every sprite icon on the site. */
.i{
  width: 20px; height: 20px; display: inline-block; vertical-align: -.18em;
  fill: none; stroke: currentColor; stroke-width: 1.75;
  stroke-linecap: round; stroke-linejoin: round;
}
.i-lg{ width: 22px; height: 22px; }

/* --------------------------------------------------------------- numbers -- */
.steps{ counter-reset: step; }

/* The number sits in normal flow above the heading, not absolutely over it.
   Positioned absolutely it printed straight on top of the first word — the
   padding meant to clear it only moved the text down, never across. */
.steps .card::before{
  counter-increment: step; content: counter(step);
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: var(--r-full);
  margin-bottom: var(--s-4);
  background: var(--plum); color: var(--cream-brand);
  font-size: var(--t-sm); font-weight: 700; font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- pricing -- */
.plans{ display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); align-items: start; }
.plan{
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-2xl); padding: var(--s-6);
  display: flex; flex-direction: column; height: 100%;
}
.plan.featured{
  border-color: var(--cream-ink); box-shadow: var(--shadow-md);
  position: relative;
}
/* Cream on white would barely read as a badge, so the "most popular" tag is
   the dark ground with the cream on it — the wordmark's own contrast. */
.plan.featured .tag{
  position: absolute; top: -12px; left: var(--s-6);
  background: var(--plum); color: var(--cream-brand);
  font-size: var(--t-xs); font-weight: 700; letter-spacing: var(--track-wide);
  text-transform: uppercase; padding: 5px 12px; border-radius: var(--r-full);
}
.plan h3{ font-size: var(--t-lg); margin: 0 0 var(--s-1); color: var(--plum); }
.plan .blurb{ color: var(--text-muted); font-size: var(--t-sm); margin: 0 0 var(--s-5); min-height: 2.6em; }
.plan .price{
  font-family: var(--font-brand); font-size: var(--t-3xl);
  color: var(--plum); line-height: 1; margin-bottom: var(--s-1);
}
.plan .per{ color: var(--text-soft); font-size: var(--t-sm); margin-bottom: var(--s-5); }
.plan ul{ list-style: none; margin: 0 0 var(--s-6); padding: 0; display: grid; gap: var(--s-2); }
.plan li{
  display: flex; gap: var(--s-2); align-items: flex-start;
  font-size: var(--t-sm); color: var(--text);
}
.plan li .tick{ color: var(--ok); flex: none; font-weight: 700; }
.plan li.off{ color: var(--text-soft); }
.plan li.off .tick{ color: var(--line-strong); }
.plan .btn{ margin-top: auto; width: 100%; }

/* ----------------------------------------------------------------- forms -- */
.form-card{
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-2xl); padding: clamp(24px, 4vw, 40px);
  box-shadow: var(--shadow-sm);
}
.field{ margin-bottom: var(--s-5); }
.field label, .field .lbl{
  display: block; font-size: var(--t-sm); font-weight: 600;
  margin-bottom: var(--s-2); color: var(--text);
}
.field .req{ color: var(--danger); }
.field input, .field select, .field textarea{
  width: 100%; padding: 12px 14px;
  border: 1.5px solid var(--line-strong); border-radius: var(--r-md);
  background: var(--surface); color: var(--text);
  font-family: var(--font-brand); font-size: var(--t-base);
  transition: border-color var(--dur-fast) var(--ease);
}
.field input:focus, .field select:focus, .field textarea:focus{
  outline: none; border-color: var(--plum);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--plum) 18%, transparent);
}
.field textarea{ min-height: 120px; resize: vertical; }
.field .hint{ margin-top: var(--s-2); font-size: var(--t-xs); color: var(--text-soft); }
.field.bad input, .field.bad select, .field.bad textarea{ border-color: var(--danger); }
.field .err{ margin-top: var(--s-2); font-size: var(--t-xs); color: var(--danger); font-weight: 550; }

/* Two fields side by side, stretched so a field with a hint under it does not
   sit lower than the one beside it — the alignment bug from the admin panel. */
.field-row{ display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); align-items: stretch; }
.field-row .field{ display: flex; flex-direction: column; }
.field-row .field .hint{ margin-top: auto; padding-top: var(--s-2); }

/* The subdomain field shows the address being built as it is typed. */
.slug-wrap{ display: flex; align-items: stretch; }
.slug-wrap input{ border-radius: var(--r-md) 0 0 var(--r-md); border-right: 0; }
.slug-wrap .suffix{
  display: flex; align-items: center; padding: 0 14px;
  background: var(--surface-2); border: 1.5px solid var(--line-strong);
  border-left: 0; border-radius: 0 var(--r-md) var(--r-md) 0;
  color: var(--text-muted); font-size: var(--t-sm); white-space: nowrap;
}

.msg{
  padding: 14px 16px; border-radius: var(--r-lg); margin-bottom: var(--s-5);
  font-size: var(--t-sm);
}
.msg.ok{ background: var(--ok-bg); color: var(--ok); }
.msg.err{ background: var(--danger-bg); color: var(--danger); }
.msg.info{ background: var(--info-bg); color: var(--info); }

/* Bots fill in everything they can see, including what they should not. */
.hp{ position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ------------------------------------------------------------------ cta --- */
.cta-band{
  background: var(--grad-plum); color: var(--text-on-dark);
  border-radius: var(--r-2xl); padding: clamp(32px, 5vw, 56px);
  text-align: center;
}
.cta-band h2{
  font-family: var(--font-brand); margin: 0 0 var(--s-3);
  font-size: clamp(1.5rem, 3.2vw, 2.1rem); letter-spacing: var(--track-tight);
}
.cta-band p{ margin: 0 0 var(--s-6); color: color-mix(in oklab, var(--text-on-dark) 78%, transparent); }

/* --------------------------------------------------------------- footer --- */
.site-foot{
  border-top: 1px solid var(--line); background: var(--surface-2);
  padding: var(--s-10) 0 var(--s-8); margin-top: var(--s-4);
  font-size: var(--t-sm);
}
.foot-grid{
  display: grid; gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  margin-bottom: var(--s-8);
}
.foot-grid h4{
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: var(--track-wide);
  color: var(--text-soft); margin: 0 0 var(--s-3); font-weight: 700;
}
.foot-grid ul{ list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.foot-grid a{ color: var(--text-muted); text-decoration: none; }
.foot-grid a:hover{ color: var(--plum); text-decoration: underline; }
.foot-base{
  border-top: 1px solid var(--line); padding-top: var(--s-5);
  display: flex; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap;
  color: var(--text-soft); font-size: var(--t-xs);
}

/* ------------------------------------------------------------------ prose - */
.prose h2{
  font-family: var(--font-brand); color: var(--plum);
  font-size: var(--t-xl); margin: var(--s-8) 0 var(--s-3);
  letter-spacing: var(--track-tight);
}
.prose h3{ font-size: var(--t-md); margin: var(--s-6) 0 var(--s-2); color: var(--plum); }
.prose p, .prose li{ color: var(--text-muted); }
.prose ul, .prose ol{ padding-left: var(--s-5); display: grid; gap: var(--s-2); }
.prose .updated{ color: var(--text-soft); font-size: var(--t-sm); }

.sr-only{
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

@media (prefers-reduced-motion: reduce){
  *{ animation-duration: .01ms !important; transition-duration: .01ms !important; }
  .btn:hover{ transform: none; }
}

/* ============================================================================
 *  The live demo in the hero
 *
 *  A shop owner deciding whether to buy this does not want to read about a
 *  stamp card — they want to see one. So the hero carries a working miniature:
 *  press the button, a stamp lands; fill the card, the reward unlocks; press a
 *  colour, the whole thing repaints in that shop's palette.
 *
 *  It is the product's real behaviour in one small frame, and the colour
 *  swatches make the white-label promise something you can try rather than
 *  something you have to believe.
 * ==========================================================================*/
.hero-grid{
  display: grid; gap: clamp(32px, 5vw, 64px);
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  align-items: center;
}
@media (max-width: 900px){
  .hero-grid{ grid-template-columns: 1fr; }
  .hero-demo{ margin-inline: auto; }
}

.hero-demo{ width: 100%; max-width: 340px; justify-self: end; }

/* The phone. Deliberately understated — it frames the card without becoming
   a drawing of a handset. */
.demo-phone{
  border-radius: 32px; padding: 14px;
  background: color-mix(in oklab, var(--cream-brand) 12%, transparent);
  box-shadow: 0 24px 60px rgba(0,0,0,.45), inset 0 0 0 1px color-mix(in oklab, var(--cream-brand) 18%, transparent);
}
.demo-screen{
  border-radius: 22px; overflow: hidden;
  background: var(--demo-bg, #FFFFFF);
  transition: background var(--dur) var(--ease);
}

.demo-top{
  padding: 16px 18px 14px;
  background: var(--demo-main, #16323F);
  color: var(--demo-on-main, #fff);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.demo-shop{ font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.demo-sub{
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  opacity: .72; margin-top: 2px;
}
.demo-count{
  display: flex; align-items: baseline; gap: 6px; margin-top: 12px;
  font-weight: 700;
}
.demo-count b{ font-size: 26px; line-height: 1; }
.demo-count span{ font-size: 12px; opacity: .7; }

.demo-body{ padding: 16px 18px 18px; }

.demo-dots{
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px;
  margin-bottom: 14px;
}
.demo-dot{
  aspect-ratio: 1; border-radius: 50%;
  border: 1.5px dashed color-mix(in oklab, var(--demo-main, #16323F) 28%, transparent);
  display: grid; place-items: center;
  color: var(--demo-accent, #D9A93A);
  font-size: 13px; font-weight: 700;
  transition: transform var(--dur) var(--ease-back), background var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.demo-dot.on{
  border-style: solid;
  border-color: var(--demo-main, #16323F);
  background: var(--demo-main, #16323F);
  color: var(--demo-accent, #D9A93A);
}
.demo-dot.pop{ transform: scale(1.22); }

.demo-note{
  font-size: 12px; color: #5F7078; text-align: center;
  min-height: 2.6em; line-height: 1.35;
}
.demo-note b{ color: var(--demo-main, #16323F); }
.demo-note.win{ color: var(--demo-main, #16323F); font-weight: 650; }

.demo-actions{ display: flex; gap: 8px; margin-top: 12px; }
.demo-btn{
  flex: 1; border: 0; cursor: pointer; border-radius: 999px;
  padding: 11px 12px; font-family: var(--font-brand);
  font-size: 12.5px; font-weight: 650;
  background: var(--demo-main, #16323F); color: var(--demo-on-main, #fff);
  transition: filter var(--dur-fast) var(--ease);
}
.demo-btn:hover{ filter: brightness(1.12); }
.demo-btn.ghost{
  background: transparent; color: var(--demo-main, #16323F);
  box-shadow: inset 0 0 0 1.5px color-mix(in oklab, var(--demo-main, #16323F) 30%, transparent);
}

/* The colour picker under the phone — the white-label promise, tryable. */
.demo-themes{
  margin-top: var(--s-5); text-align: center;
}
.demo-themes .lbl{
  display: block; font-size: var(--t-xs); letter-spacing: var(--track-wide);
  text-transform: uppercase; margin-bottom: var(--s-3);
  color: color-mix(in oklab, var(--text-on-dark) 58%, transparent);
}
.demo-swatches{ display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
.demo-swatch{
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer; padding: 0;
  border: 2px solid transparent;
  outline-offset: 3px;
  transition: transform var(--dur-fast) var(--ease-back), border-color var(--dur-fast) var(--ease);
}
.demo-swatch:hover{ transform: scale(1.12); }
.demo-swatch[aria-pressed="true"]{
  border-color: var(--cream-brand);
  transform: scale(1.12);
}

/* --------------------------------------------------------- proof strip --- */
.proof{
  border-top: 1px solid color-mix(in oklab, var(--cream-brand) 14%, transparent);
  margin-top: clamp(36px, 5vw, 56px); padding-top: clamp(24px, 3vw, 32px);
  display: grid; gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
.proof div{ text-align: center; }
.proof b{
  display: block; font-size: clamp(1.4rem, 2.6vw, 1.9rem); font-weight: 800;
  color: var(--cream-brand); line-height: 1;
}
.proof span{
  display: block; margin-top: 6px; font-size: var(--t-xs);
  letter-spacing: var(--track-wide); text-transform: uppercase;
  color: color-mix(in oklab, var(--text-on-dark) 55%, transparent);
}

@media (prefers-reduced-motion: reduce){
  .demo-dot, .demo-swatch, .demo-screen, .demo-top{ transition: none; }
  .demo-dot.pop{ transform: none; }
}

/* A ghost button that sits on the dark hero rather than a light section. */
.btn-ondark{
  background: transparent; color: var(--cream-brand);
  box-shadow: inset 0 0 0 1.5px color-mix(in oklab, var(--cream-brand) 34%, transparent);
}
.btn-ondark:hover{ background: color-mix(in oklab, var(--cream-brand) 10%, transparent); }

/* tokens.css sets every heading in Playfair, which is the product's voice.
   The website speaks in the wordmark's own typeface instead, so headings are
   reclaimed here rather than by editing the shared file — the app's cards and
   panels keep their serif. */
.site-head, .site-foot, main h1, main h2, main h3, main h4,
.card h3, .plan h3, .section-head h2, .cta-band h2, .prose h2, .prose h3{
  font-family: var(--font-brand);
}
main h1, main h2, main h3, main h4{ letter-spacing: var(--track-tight); }
.card h3{ font-weight: 700; font-size: var(--t-md); }

/* Slightly stronger icon tiles — the first pass was so pale the icon floated. */
.card .ico{
  background: linear-gradient(150deg,
              color-mix(in oklab, var(--plum) 14%, var(--surface)),
              color-mix(in oklab, var(--plum) 6%, var(--surface)));
  box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--plum) 16%, transparent);
}

/* --------------------------------------------------------------- reward --- */
/* The moment the card fills. A stamp card's whole point is the payoff, so the
   demo has to show it rather than quietly say "card full". */
.demo-screen.won .demo-top{
  background: var(--demo-main, #16323F);
  box-shadow: inset 0 -2px 0 var(--demo-accent, #D9A93A);
}
.demo-reward{
  display: none; text-align: center; padding: 4px 0 2px;
}
.demo-screen.won .demo-reward{ display: block; }
.demo-screen.won .demo-note{ display: none; }
.demo-reward .r-ico{
  width: 46px; height: 46px; margin: 0 auto 8px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--demo-main, #16323F); color: var(--demo-accent, #D9A93A);
  animation: ls-pop .5s var(--ease-back) both;
}
.demo-reward .r-ico svg{ width: 24px; height: 24px; }
.demo-reward strong{
  display: block; font-size: 14px; color: var(--demo-main, #16323F);
  animation: ls-rise .45s var(--ease-out) .06s both;
}
.demo-reward span{
  display: block; font-size: 11.5px; color: #5F7078; margin-top: 3px;
  animation: ls-rise .45s var(--ease-out) .12s both;
}
@keyframes ls-pop{
  0%{ transform: scale(.4) rotate(-14deg); opacity: 0; }
  60%{ transform: scale(1.12) rotate(4deg); }
  100%{ transform: scale(1) rotate(0); opacity: 1; }
}
@keyframes ls-rise{
  from{ transform: translateY(8px); opacity: 0; }
  to{ transform: none; opacity: 1; }
}

/* Confetti. Absolutely positioned inside the phone so nothing escapes onto
   the page and nothing shifts the layout. */
.demo-phone{ position: relative; }
.confetti{
  position: absolute; inset: 0; overflow: hidden; pointer-events: none;
  border-radius: 32px; z-index: 2;
}
.confetti i{
  position: absolute; top: -12px; width: 7px; height: 11px; border-radius: 1px;
  opacity: 0; animation: ls-fall var(--dur-fall, 1500ms) linear forwards;
}
@keyframes ls-fall{
  0%   { opacity: 1; transform: translate3d(0,0,0) rotate(0); }
  100% { opacity: 0; transform: translate3d(var(--dx, 0), 340px, 0) rotate(var(--spin, 540deg)); }
}
@media (prefers-reduced-motion: reduce){
  .confetti{ display: none; }
  .demo-reward .r-ico, .demo-reward strong, .demo-reward span{ animation: none; }
}

/* --------------------------------------------------- monthly / yearly --- */
.bill-toggle{
  display: inline-flex; gap: 4px; padding: 4px; margin: 0 auto var(--s-8);
  background: var(--surface-3); border-radius: var(--r-full);
  position: relative; left: 50%; transform: translateX(-50%);
}
.bill-toggle button{
  border: 0; cursor: pointer; border-radius: var(--r-full);
  padding: 10px 20px; font-family: var(--font-brand);
  font-size: var(--t-sm); font-weight: 650; color: var(--text-muted);
  background: transparent;
  display: inline-flex; align-items: center; gap: var(--s-2);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.bill-toggle button:hover{ color: var(--text); }
.bill-toggle button.on{
  background: var(--plum); color: var(--cream-brand);
  box-shadow: var(--shadow-sm);
}
.bill-toggle .save{
  font-size: var(--t-xs); font-weight: 700; padding: 3px 8px;
  border-radius: var(--r-full); white-space: nowrap;
  background: var(--ok-bg); color: var(--ok);
}
.bill-toggle button.on .save{
  background: color-mix(in oklab, var(--cream-brand) 22%, transparent);
  color: var(--cream-brand);
}
.per-save{ color: var(--ok); font-weight: 650; }

@media (max-width: 460px){
  .bill-toggle button{ padding: 9px 14px; font-size: var(--t-xs); }
}
