/* =====================================================================
   iPriceBD — stylesheet
   ---------------------------------------------------------------------
   Mobile-first. The unconditional rules are the phone; every width query
   below adds to them and none subtracts, so the phone layout cannot be
   broken by a desktop change.

   Width breakpoints actually present in this file, narrowest first (the
   max-width ones sit next to the component they adjust, not in a block at
   the end - search for the query text to find them):

     (max-width:359px)       7 blocks
     (max-width:379px)       2 blocks
     (max-width:380px)       1 block
     (max-width:419px)       1 block
     (min-width:768px)       2 blocks
     (min-width:1080px)      1 block
     (min-width:1440px)      1 block

   Plus 7 @media (prefers-color-scheme:dark) blocks and 15
   @media (prefers-reduced-motion) blocks, also inline next to what they
   affect.

   Theming is by custom property. :root holds the light palette; the dark
   blocks redefine only the tokens, guarded as
   :root:not([data-theme="light"]) inside @media (prefers-color-scheme:dark).
   data-theme is an authoring hook only - nothing in the shipped JS writes
   it. Put data-theme="light" on <html> by hand to pin the light palette.
   ===================================================================== */

@import url('fonts.css');

/* ============================================================
   Type — Outfit (titles) + Archivo (body), embedded as
   variable WOFF2 data URIs so the file stays self-contained.
   ============================================================ */

/* ============================================================
   iPrice BD — design tokens
   ============================================================ */
:root{
  color-scheme: light dark;
  /* None of Outfit, Archivo or Inter ships the Bengali taka sign (U+09F3),
     so it silently falls back per-character. Naming Bengali faces explicitly -
     after the Latin font, before the generic - keeps that glyph predictable
     instead of leaving it to whatever the platform picks. */
  --bn:'Noto Sans Bengali','Hind Siliguri','Nirmala UI','Shonar Bangla';
  --dv:'Noto Sans Devanagari','Hind','Nirmala UI','Mangal';
  --font-title:'Outfit','Archivo',var(--bn),var(--dv),-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --font-body:'Archivo',var(--bn),var(--dv),-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --font-caption:'Inter',var(--bn),var(--dv),-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  --bg-top:#eceef1;
  --bg-bot:#fbfcfd;
  --card:#ffffff;
  --card-2:#fbfdff;
  --ink:#0c0c0c;
  --ink-2:#3b3b3b;
  --muted:#76767c;
  --line:#e6e6e8;
  --line-2:#efeff1;
  /* Brand: yellow + black. Yellow is never used for text on a light ground -
     it only ever appears as a fill with black on top. */
  --yellow:#f2e94b;
  --yellow-deep:#e3d92f;
  --yellow-soft:#fcf9dd;
  --yellow-ink:#1a1800;
  /* hairline for the inset box: light enough to stay a whisper on white,
     warm enough to read as yellow rather than the grey it replaces */
  --yellow-line:color-mix(in srgb, var(--yellow-deep) 62%, #fff);
  /* Yellow is reserved for one accent per section; these carry the quieter
     surfaces that used to be saturated. */
  --tint:#f6f6f3;
  --tint-2:#ededea;
  /* The old blue/green/violet token names are kept so every existing rule keeps
     resolving; they now point at the black-and-yellow system. */
  --blue:#0c0c0c;
  --blue-ink:#0c0c0c;
  --blue-soft:var(--tint-2);
  --green:var(--yellow);
  --green-ink:#1a1800;
  --green-soft:var(--yellow-soft);
  --lime:var(--yellow);
  --lime-ink:var(--yellow-ink);
  --cta-bg:#0c0c0c;
  --cta-ink:#ffffff;
  --violet:#0c0c0c;
  --violet-soft:var(--tint-2);
  --amber-soft:var(--yellow-soft);
  --amber-ink:#1a1800;
  /* What each route's fee costs you, and what it does not. The fee is a
     coloured line of text now rather than a filled chip, so these are inks and
     each was checked on all three grounds it is read on - white, the chosen
     card's yellow, which stays yellow in dark too, and the dark card. */
  --fee-bad:#b81f26;  --fee-good:#0b6e37;     /* 6.44 / 6.36 on white, 5.52 / 5.46 on yellow */
  --fee-bad-dk:#f5766f; --fee-good-dk:#3fdc86; /* 6.70 / 10.26 on the dark card */
  /* Toned down: the wide 30px ambient layer was reading as grey haze once a
     page had several cards stacked on it. Tighter and lighter, so a card still
     sits above the page without the page looking dirty. Dark mode keeps its own
     values — a shadow on a dark ground reads as depth, not haze. */
  --shadow-s:0 1px 2px rgba(12,12,12,.04);
  --shadow-m:0 1px 3px rgba(12,12,12,.04), 0 6px 16px rgba(12,12,12,.045);
  --shadow-l:0 2px 6px rgba(12,12,12,.05), 0 14px 32px rgba(12,12,12,.07);
  --lift:0 4px 10px rgba(12,12,12,.06), 0 18px 38px rgba(12,12,12,.09);
  --r-lg:26px;
  --r-md:18px;
  --pad:14px;
  --ease:cubic-bezier(.22,1,.36,1);
  /* overshoots slightly, which is what separates a spring from a slide */
  --pop:cubic-bezier(.34,1.42,.64,1);
  --ease-soft:cubic-bezier(.33,.9,.3,1);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg-top:#0a0a0a;
    --bg-bot:#111110;
    --card:#191918;
    --card-2:#212120;
    /* These two had no dark value at all, so every surface built on them — the
       plain region box, the gift row, the payment badges, the chip fills — kept
       its near-white light value and the theme looked half-applied. */
    --tint:#151514;
    --tint-2:#242422;
    --ink:#f5f5f2;
    --ink-2:#cfcfc8;
    --muted:#8f8f88;
    --line:#2a2a26;
    --line-2:#212120;
    --yellow:#f2e94b;
    --yellow-deep:#e3d92f;
    --yellow-soft:#3a3714;
    --yellow-ink:#f7f3c8;
    --blue:var(--yellow);
    --blue-ink:var(--yellow);
    --blue-soft:#332f12;
    --green:var(--yellow);
    --green-ink:#f0e97e;
    --green-soft:#332f12;
    --lime:var(--yellow);
    --lime-ink:#1a1800;
    --cta-bg:#f5f5f2;
    --cta-ink:#0c0c0c;
    --violet:var(--yellow);
    --violet-soft:#2a2a26;
    --amber-soft:#332f12;
    --amber-ink:#f0e97e;
    --shadow-s:0 1px 2px rgba(0,0,0,.35);
    --shadow-m:0 1px 2px rgba(0,0,0,.3), 0 8px 22px rgba(0,0,0,.35);
    --shadow-l:0 2px 4px rgba(0,0,0,.3), 0 18px 40px rgba(0,0,0,.45);
    --lift:0 4px 10px rgba(0,0,0,.35), 0 22px 48px rgba(0,0,0,.5);
  }
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;
  font-family:var(--font-body);
  font-size:13px;
  line-height:1.45;
  color:var(--ink);
  background:var(--bg-bot);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
.page{
  min-height:100dvh;
  background:
    radial-gradient(120% 60% at 50% 0%, var(--bg-top) 0%, var(--bg-bot) 62%),
    var(--bg-bot);
}
/* the docked bar is fixed, so the page has to leave room for it itself */
.shell{max-width:460px;margin:0 auto;padding:0 var(--pad) calc(40px + var(--dock-h, 0px))}
@media (min-width:768px){
  .shell{max-width:520px}
  :root{--pad:18px}
}
img{max-width:100%}
button,input,select,textarea{font-family:inherit}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;text-align:left}
a{color:inherit;text-decoration:none}
svg{display:block}
.icon{width:20px;height:20px;flex:none}
.flag{width:18px;height:12px;flex:none}
:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:10px}
/* ============================================================
   Scroll progress + back to top
   ============================================================ */
.progress{
  position:fixed;top:0;left:0;height:3px;width:100%;
  transform:scaleX(0);transform-origin:0 50%;
  background:linear-gradient(90deg,#0c0c0c,var(--yellow));
  z-index:90;pointer-events:none;
  transition:transform .08s linear, opacity .3s ease;
  opacity:0;
}
.progress.on{opacity:1}
.totop{
  position:fixed;right:14px;bottom:calc(var(--dock-h, 0px) + 20px);z-index:80;
  width:42px;height:42px;border-radius:50%;
  background:var(--card);color:var(--blue-ink);
  border:1px solid var(--line);
  box-shadow:var(--shadow-l);
  display:grid;place-items:center;
  opacity:0;visibility:hidden;
  translate:0 14px;scale:.85;
  transition:opacity .3s ease, translate .4s var(--ease), scale .4s var(--ease), visibility .3s;
}
.totop.on{opacity:1;visibility:visible;translate:0 0;scale:1}
.totop:hover{background:var(--blue);color:#fff;border-color:transparent}
.totop:active{scale:.92}
.totop svg{width:16px;height:16px;rotate:-90deg}
/* ============================================================
   Header
   ============================================================ */
/* ---------- top bar ----------
   The veil is a pseudo-element, not a background on the bar itself. The bar
   lives inside the 460px shell, so a background on it stopped at the content
   column and page content scrolled past beside it, against a hard vertical
   edge. The veil breaks out to the full viewport width instead, and its mask
   fades it out at the bottom so content dissolves under the bar rather than
   sliding behind a line. */
.topbar{
  display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding:16px 0 14px;
  position:sticky;top:0;z-index:40;
}
.topbar::before{
  content:"";position:absolute;z-index:-1;pointer-events:none;
  top:0;bottom:-20px;
  left:50%;width:100vw;margin-left:-50vw;   /* body already hides overflow-x */
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 100%);
  mask-image:linear-gradient(180deg,#000 0%,#000 62%,transparent 100%);
  transition:backdrop-filter .25s ease, background .25s ease;
}
/* once something is actually underneath it, the veil deepens */
.topbar.is-stuck::before{
  backdrop-filter:blur(16px) saturate(1.3);
  -webkit-backdrop-filter:blur(16px) saturate(1.3);
  background:color-mix(in srgb, var(--bg-top) 55%, transparent);
}
@media (prefers-reduced-motion:reduce){.topbar::before{transition:none}}
.brand{display:flex;align-items:flex-start;gap:9px;min-width:0}
.brand .mark{
  width:26px;height:26px;margin-top:1px;color:var(--ink);flex:none;
  transition:rotate .6s var(--ease), scale .4s var(--ease);
}
.brand:hover .mark{rotate:-8deg;scale:1.1}
.brand h1{margin:0;font-size:21px;line-height:1.1;letter-spacing:-.4px;font-weight:800}
.brand p{margin:3px 0 0;font-size:11.5px;color:var(--muted);letter-spacing:.1px}
.cur{position:relative;flex:none}
.cur-btn{
  display:flex;align-items:center;gap:7px;
  padding:8px 11px;
  background:var(--card);
  border:1px solid var(--line);
  border-radius:999px;
  box-shadow:var(--shadow-s);
  font-size:13px;font-weight:700;letter-spacing:.2px;
  transition:box-shadow .25s ease, scale .2s var(--ease), border-color .25s ease;
}
.cur-btn:hover{box-shadow:var(--shadow-m);border-color:rgba(12,12,12,.25)}
.cur-btn:active{scale:.96}
.cur-btn .chev{width:12px;height:12px;color:var(--muted);transition:rotate .28s var(--ease)}
.cur.open .cur-btn .chev{rotate:180deg}
.cur-btn #curLabel{display:inline-block;min-width:30px}
.cur-menu{
  position:absolute;right:0;top:calc(100% + 8px);
  min-width:162px;
  background:var(--card);
  border:1px solid var(--line);
  border-radius:14px;
  box-shadow:var(--shadow-l);
  padding:5px;
  z-index:50;
  opacity:0;visibility:hidden;
  translate:0 -8px;scale:.96;
  transform-origin:100% 0;
  transition:opacity .22s ease, translate .28s var(--ease), scale .28s var(--ease), visibility .22s;
}
.cur.open .cur-menu{opacity:1;visibility:visible;translate:0 0;scale:1}
.cur-menu button{
  display:flex;align-items:center;gap:9px;width:100%;
  padding:9px 10px;border-radius:10px;
  font-size:13px;font-weight:600;
  transition:background .18s ease, translate .18s var(--ease);
}
.cur-menu button:hover,.cur-menu button:focus-visible{background:var(--line-2);translate:2px 0}
.cur-menu button[aria-selected="true"]{color:var(--blue-ink)}
.cur-menu .tick{width:14px;height:14px;margin-left:auto;opacity:0;scale:.5;color:var(--blue);flex:none;transition:opacity .25s ease, scale .35s var(--ease)}
.cur-menu button[aria-selected="true"] .tick{opacity:1;scale:1}
.cur-menu small{color:var(--muted);font-weight:500}
/* ============================================================
   Hero
   ============================================================ */
.hero{
  position:relative;
  overflow:hidden;
  border-radius:var(--r-lg);
  padding:16px 16px 18px;
  background:
    radial-gradient(120% 90% at 76% 8%, #46411f 0%, rgba(70,65,31,0) 58%),
    linear-gradient(160deg,#1d1d1a 0%, #0b0b0a 100%);
  border:1px solid rgba(242,233,75,.16);
  color:#f5f5f2;
  box-shadow:var(--shadow-m);
}
/* The hero is dark in both schemes now, so it needs no separate dark rule. */
.pill{
  display:inline-flex;align-items:center;gap:6px;
  padding:5px 11px 5px 8px;
  background:rgba(242,233,75,.14);
  color:var(--yellow);
  border-radius:999px;
  font-size:11.5px;font-weight:700;
  animation:riseIn .7s var(--ease) both;
  animation-delay:.05s;
}
.pill svg{width:13px;height:13px;animation:flicker 2.6s ease-in-out infinite}
@keyframes flicker{0%,100%{scale:1;opacity:1}50%{scale:1.14;opacity:.82}}
/* The headline needs the full column to stay on two lines; only the
   paragraph is narrowed. The headline deliberately overruns the artwork; the
   copy sits at z-index 2 so it stays legible over it. */
.hero-copy{position:relative;z-index:2;max-width:70%}
@media (max-width:359px){.hero-copy{max-width:80%}}
.hero h2{margin:12px 0 0;font-size:clamp(22.5px,6.6vw,28px);line-height:1.08;letter-spacing:-.9px;font-weight:800}
/* each headline line wipes up from behind its own mask */
.hero h2 .ln{display:block;overflow:hidden;padding-bottom:2px}
.hero h2 .ln > span{display:block;animation:wipeUp .9s var(--ease) both}
.hero h2 .ln:nth-child(1) > span{animation-delay:.16s}
.hero h2 .ln:nth-child(2) > span{animation-delay:.3s}
/* Inline (not inline-block) so a wrapped headline yields one snug marker per
   line instead of one bar the full width of the column. */
.hero h2 .accent{
  display:inline;
  color:#0c0c0c;
  font-style:normal;
  padding:.02em .12em;
  background:linear-gradient(180deg,transparent 10%,var(--yellow) 10%,var(--yellow) 94%,transparent 94%);
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}
/* The marker sweeps in once the headline has landed. */
.hero h2 .accent{background-size:100% 100%;background-repeat:no-repeat;animation:marker 1s var(--ease) .75s both}
@keyframes marker{from{background-size:0% 100%}to{background-size:100% 100%}}
@keyframes sheen{0%,72%{background-position:120% 0}100%{background-position:-40% 0}}
.hero .lede{
  margin:10px 0 0;max-width:24ch;
  font-size:12px;line-height:1.5;color:#c4c4bc;opacity:1;
  animation:riseIn .8s var(--ease) both;animation-delay:.46s;
}
.hero-cta{
  margin-top:16px;
  display:inline-flex;align-items:center;gap:8px;
  background:var(--yellow);color:#0c0c0c;
  padding:10px 9px 10px 15px;
  border-radius:999px;
  font-size:12.5px;font-weight:700;
  box-shadow:var(--shadow-m);
  border:0;
  animation:riseIn .8s var(--ease) both;animation-delay:.58s;
  transition:box-shadow .3s ease, translate .3s var(--ease), scale .2s var(--ease);
}
.hero-cta:hover{box-shadow:var(--lift);translate:0 -2px}
.hero-cta:active{scale:.97}
.hero-cta .dot{
  width:22px;height:22px;border-radius:50%;
  background:#0c0c0c;color:var(--yellow);
  display:grid;place-items:center;flex:none;
  transition:translate .3s var(--ease);
}
.hero-cta:hover .dot{translate:3px 0}
.hero-cta .dot svg{width:12px;height:12px}
/* ---------- hero illustration ----------
   The approved globe scene, recomposed for a right-hand box: six marks
   counter-orbiting with true occlusion, and the two price tags held apart,
   each swaying along a short stretch of its curve. */
.art{
  position:absolute;right:0;top:34px;
  width:206px;z-index:1;pointer-events:none;
  animation:riseIn .9s var(--ease) both;animation-delay:.5s;
}
@media (max-width:359px){.art{width:166px;right:0}}
.art-svg{display:block;width:100%;height:auto}
/* pointer parallax still drives --px/--py on #art */
.plx{translate:calc(var(--px,0px) * .6) calc(var(--py,0px) * .6);transition:translate .5s var(--ease-soft)}
@media (prefers-reduced-motion:reduce){.plx{translate:none}}
/* hero entrance keyframes */
@keyframes riseIn{from{opacity:0;translate:0 14px}to{opacity:1;translate:0 0}}
@keyframes wipeUp{from{opacity:0;translate:0 100%}to{opacity:1;translate:0 0}}
@keyframes popIn{from{opacity:0;scale:.7}to{opacity:1;scale:1}}
@keyframes phoneIn{from{opacity:0;translate:0 26px;rotate:6deg}to{opacity:1;translate:0 0;rotate:0deg}}
@keyframes chipIn{from{opacity:0;scale:.3;rotate:-18deg}to{opacity:1;scale:1;rotate:0deg}}
@keyframes fadeIn{from{opacity:0}to{opacity:.55}}
/* the independent translate property, so it composes with a transform
   rather than replacing it */
@keyframes bob{0%,100%{translate:0 0}50%{translate:0 -6px}}
/* the shine that sweeps the gift card; the rule referenced this by name
   but the keyframes were never written, leaving a static white streak */
@keyframes glint{0%{translate:-120% 0}55%,100%{translate:120% 0}}
/* the two cards behind the face card fan out as the promo scrolls in */
@keyframes deal{from{opacity:0;rotate:-9deg;translate:0 0}
                 to{opacity:1;rotate:var(--rot);translate:var(--tx) var(--ty)}}
/* ============================================================
   Search
   ============================================================ */
.search{
  margin-top:16px;
  display:flex;align-items:center;gap:10px;
  background:var(--card);
  border:1px solid var(--line);
  border-radius:999px;
  padding:6px 6px 6px 16px;
  box-shadow:var(--shadow-m);
  transition:box-shadow .3s ease, border-color .25s ease;
}
.search:focus-within{border-color:rgba(12,12,12,.35);box-shadow:0 0 0 4px rgba(242,233,75,.45),var(--shadow-m)}
.search .icon{color:var(--muted);transition:color .25s ease, scale .3s var(--ease)}
.search:focus-within .icon{color:var(--blue);scale:1.1}
.search input{
  flex:1;min-width:0;border:0;outline:0;background:none;
  font-family:var(--font-body);
  font-size:14px;color:var(--ink);padding:11px 0;
}
.search input::placeholder{color:var(--muted)}
.search input::-webkit-search-cancel-button{display:none}
/* ---------- type-ahead ----------
   Matches are offered as you type rather than only filtering the lists below,
   so the answer arrives before you finish the word. */
.search-wrap{position:relative;z-index:30}
.ac{
  position:absolute;left:0;right:0;top:calc(100% + 8px);
  background:var(--card);
  border:1px solid var(--line);
  border-radius:20px;
  box-shadow:0 22px 44px rgba(12,12,12,.16), var(--shadow-m);
  overflow:hidden;
  max-height:min(56vh,360px);overflow-y:auto;
  animation:acIn .22s var(--ease) both;
}
@keyframes acIn{from{opacity:0;translate:0 -6px;scale:.99}to{opacity:1;translate:0 0;scale:1}}
@media (prefers-reduced-motion:reduce){.ac{animation:none}}
.ac-item{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center;gap:11px;
  width:100%;padding:9px 13px;
  border-bottom:1px solid var(--line-2);
  transition:background .16s ease;
}
.ac-item:last-child{border-bottom:0}
.ac-item:hover,.ac-item.on{background:var(--tint)}
.ac-item.on{box-shadow:inset 3px 0 0 var(--yellow-deep)}
/* the clone still carries grid-area:ico from the row grid, which would drop it
   into an implicit area of this grid */
.ac .row-ico,.ac .gico{grid-area:auto;width:36px;height:36px;border-radius:11px;
  animation:none;scale:1;rotate:0deg}
.ac .row-ico svg{width:36px;height:36px}
.ac .gico{font-size:12px}
.ac-tx{min-width:0}
.ac-tx b{display:block;font-size:13px;font-weight:700;letter-spacing:-.2px;line-height:1.25;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* inherit would hand this the theme's text colour — light ink on a yellow
   highlight in dark mode. The highlight is always yellow, so the ink is
   always dark. */
.ac-tx b mark{background:var(--yellow);color:#0c0c0c;border-radius:3px;padding:0 1px}
.ac-tx span{display:block;font-size:10px;color:var(--muted);line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ac-val{
  display:flex;align-items:center;gap:5px;flex:none;
  font-family:var(--font-body);font-size:12.5px;font-weight:800;
  letter-spacing:-.2px;font-variant-numeric:tabular-nums;
}
.ac-val .flag{width:14px;height:9.6px}
/* each row fades in on its own beat so the list assembles rather than snaps */
.ac-item{animation:acRow .26s var(--ease) both}
@keyframes acRow{from{opacity:0;translate:0 5px}to{opacity:1;translate:0 0}}
@media (prefers-reduced-motion:reduce){.ac-item{animation:none}}
.search .clear{
  width:22px;height:22px;border-radius:50%;flex:none;
  background:var(--line-2);color:var(--muted);
  display:grid;place-items:center;
  opacity:0;visibility:hidden;scale:.6;
  transition:opacity .2s ease, scale .28s var(--ease), visibility .2s, background .2s;
}
.search .clear.on{opacity:1;visibility:visible;scale:1}
.search .clear:hover{background:var(--blue-soft);color:var(--blue-ink)}
.search .clear svg{width:9px;height:9px}
.search .go{
  width:38px;height:38px;border-radius:50%;flex:none;
  background:var(--tint-2);color:var(--ink);
  display:grid;place-items:center;
  transition:translate .2s var(--ease), background .2s ease, color .2s ease, scale .2s var(--ease);
}
.search .go:hover{background:#0c0c0c;color:var(--yellow);translate:2px 0}
.search .go:active{scale:.9}
.search .go svg{width:15px;height:15px}
/* The gap is a margin on the container, not padding on the grid item: padding
   on a 0fr item still occupies space, leaving a dead band when there is no
   query. As a margin it animates in and collapses to nothing. */
.results{
  display:grid;grid-template-rows:0fr;margin-top:0;
  transition:grid-template-rows .34s var(--ease), margin-top .34s var(--ease), opacity .25s ease;
  opacity:0;
}
.results.on{grid-template-rows:1fr;margin-top:11px;opacity:1}
.results > span{overflow:hidden;display:block;padding:0 6px 1px;font-size:11px;color:var(--muted)}
.results b{color:var(--blue-ink);font-weight:700}
/* ============================================================
   Quick links
   ============================================================ */
.quick{
  margin-top:14px;
  background:var(--card);
  border:0;
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-m);
  display:grid;grid-template-columns:repeat(4,1fr);
  overflow:hidden;
}
@media (max-width:359px){.quick{grid-template-columns:repeat(2,1fr)}}
.quick a{
  padding:18px 9px 15px;text-align:center;
  display:flex;flex-direction:column;align-items:center;gap:7px;
  border-right:1px solid var(--line-2);
  position:relative;
  transition:background .2s ease, translate .28s var(--ease);
}
.quick a:last-child{border-right:0}
.quick a:hover{background:var(--card-2);translate:0 -3px}
.quick a:active{translate:0 -1px;scale:.97}
@media (max-width:359px){
  .quick a:nth-child(2n){border-right:0}
  .quick a:nth-child(-n+2){border-bottom:1px solid var(--line-2)}
}
.qi{
  width:38px;height:38px;border-radius:11px;
  display:grid;place-items:center;flex:none;
  transition:scale .35s var(--ease), rotate .45s var(--ease), box-shadow .3s ease;
}
.quick a:hover .qi{scale:1.14;rotate:-7deg;box-shadow:var(--shadow-m)}
.qi svg{width:19px;height:19px}
.qi.b{background:var(--blue-soft);color:var(--blue-ink)}
.qi.g{background:var(--yellow);color:#0c0c0c}
.qi.v{background:var(--violet-soft);color:var(--violet)}
.qi.a{background:var(--amber-soft);color:var(--amber-ink)}
.quick b{font-size:11.5px;font-weight:700;letter-spacing:-.1px;line-height:1.2}
.quick .sub{
  font-size:9.5px;line-height:1.35;color:var(--muted);
  display:flex;align-items:center;gap:3px;justify-content:center;flex-wrap:wrap;
}
.quick .sub svg{width:9px;height:9px;color:var(--blue);flex:none;transition:translate .25s var(--ease)}
.quick a:hover .sub svg{translate:3px 0}
/* ============================================================
   Sections
   ============================================================ */
.section{margin-top:26px}
/* brief glow when a quick-link jumps you here */
@keyframes targetPulse{
  0%  {box-shadow:0 0 0 0 rgba(242,233,75,.75)}
  100%{box-shadow:0 0 0 16px rgba(242,233,75,0)}
}
.target .list,.target.promo,.target.bonus,.target .why-grid{animation:targetPulse 1.1s ease-out 2;border-radius:var(--r-lg)}
.sec-head{display:flex;align-items:center;gap:11px;margin-bottom:11px;padding:0 2px}
.sec-ico{
  width:34px;height:34px;border-radius:11px;
  display:grid;place-items:center;flex:none;color:#fff;
  transition:rotate .5s var(--ease), scale .35s var(--ease);
}
.sec-head:hover .sec-ico{rotate:-8deg;scale:1.08}
.sec-ico svg{width:18px;height:18px}
.sec-ico.b{background:#0c0c0c;color:var(--yellow)}
.sec-ico.v{background:#0c0c0c;color:var(--yellow)}
.sec-head h3{margin:0;font-size:17.5px;font-weight:800;letter-spacing:-.4px;line-height:1.15}
.sec-head p{margin:2px 0 0;font-size:11px;color:var(--muted)}
.sec-head .more{
  margin-left:auto;display:flex;align-items:center;gap:4px;
  font-size:12px;font-weight:700;color:var(--blue-ink);flex:none;
  transition:gap .25s var(--ease)
}
.sec-head .more:hover{gap:8px}
.sec-head .more svg{width:12px;height:12px}
.list{
  background:var(--card);
  border:0;
  border-radius:var(--r-lg);
  box-shadow:var(--shadow-m);
  overflow:hidden;
}
/* The separator lives on the detail panel that follows each row, so a
   collapsed panel still draws exactly one divider and never doubles it. */
/* One band: mark, name, prices and saving all centred on the same line, so
   nothing sits high while its neighbour sits low. The name column is the only
   flexible one, so it is what gives way when the row gets narrow. */
.row{
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto auto;
  grid-template-areas:"ico info prices save";
  align-items:center;
  column-gap:9px;
  width:100%;padding:13px 11px;
  position:relative;
  transition:background .2s ease;
}
@media (max-width:380px){
  .row{column-gap:8px;padding:12px 10px}
  .prices{gap:8px}
  .save{margin-left:7px}
}
/* Below about 360px four columns stop fitting: the name column collapses and
   the rows grow taller than the screen. There the prices drop to their own
   line rather than squeezing the name out of existence. */
@media (max-width:359px){
  .row{
    grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-areas:"ico info save" "ico prices save";
    row-gap:7px;
  }
  .prices{justify-content:flex-start;margin-left:0}
}
.row-ico,.gico{grid-area:ico}
.row-info{grid-area:info}
.prices{grid-area:prices;display:flex;align-items:center;gap:9px;min-width:0}
.save{grid-area:save}
.row:hover{background:var(--card-2)}
.row:active{scale:.995}
/* accent rail slides in on hover / while open */
.row::before{
  content:"";position:absolute;left:0;top:8px;bottom:8px;width:3px;
  border-radius:0 3px 3px 0;
  background:var(--blue);
  scale:0 1;transform-origin:0 50%;
  transition:scale .28s var(--ease);
}
.row:hover::before,.row[aria-expanded="true"]::before{scale:1 1}
.row-ico{width:40px;height:40px;border-radius:13px;flex:none;overflow:hidden;box-shadow:var(--shadow-s);transition:scale .3s var(--ease), rotate .4s var(--ease)}
.row-ico svg{width:40px;height:40px}
.row:hover .row-ico,.row:hover .gico{scale:1.08;rotate:-5deg}
.gico{
  position:relative;
  width:40px;height:40px;border-radius:13px;flex:none;
  display:grid;place-items:center;
  background-image:radial-gradient(120% 90% at 26% 18%, rgba(255,255,255,.42), rgba(255,255,255,0) 58%),
                   linear-gradient(145deg,var(--c1),var(--c2));
  box-shadow:var(--shadow-s), inset 0 0 0 1px rgba(255,255,255,.14);
  font-size:14px;font-weight:900;color:#fff;letter-spacing:-.5px;
  box-shadow:var(--shadow-s);
  background:linear-gradient(145deg,var(--c1),var(--c2));
  text-shadow:0 1px 2px rgba(0,0,0,.3);
  transition:scale .3s var(--ease), rotate .4s var(--ease);
}
/* flex-basis 0 + min-width 0 lets the name column shrink instead of
   overflowing on top of the price columns at 360-375px. */
.row-info{flex:1 1 0;min-width:0}
/* The name may take a second line rather than truncate — a clipped product
   name is worse than a taller row — but it stays centred on the same band as
   the prices, so nothing sits high while its neighbour sits low. */
.row-info{display:flex;flex-direction:column;justify-content:center;min-height:46px}
.row-info b{
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;
  font-size:14px;font-weight:700;letter-spacing:-.25px;line-height:1.22;
  overflow-wrap:break-word;
}
.row-info em{
  display:block;font-style:normal;font-size:10px;color:var(--ink-2);
  opacity:.75;line-height:1.3;margin-top:1px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
/* Pack size and category share one line; two stacked grey lines made the
   game rows taller than the service rows for no gain. */
.row-info .cat{display:inline}
.row-info .cat{font-size:9.5px;color:var(--muted)}
.row-info .cat::before{content:" · ";color:var(--muted);opacity:.6}
/* Both prices on ONE row, hard right, flag inline with the figure. */
.prices{justify-content:flex-end;margin-left:auto;gap:14px}
/* Sized to its own digits, each price started wherever the previous column
   happened to end: nine rows put the India flag at four different x positions
   and the US flag at three. A column wide enough for the widest figure in the
   catalogue (5 digits and a comma, 59px measured) puts every flag on one
   vertical and every figure 18px after it, which is how a price list is read. */
.price{flex:none;display:flex;align-items:center;gap:5px;min-width:60px;padding:0;border:0}
.price .flag{width:13px;height:8.9px}
.price .amt{font-size:13px;font-weight:800;letter-spacing:-.3px;white-space:nowrap}
.price .per{font-size:9px;color:var(--muted);font-weight:600}
.save{
  flex:none;background:var(--yellow-soft);border-radius:15px;
  /* The chip sits between the prices and the edge, so its width decides where
     the prices start. 54px let a four-figure saving push it to 62 and drag the
     whole price block 8px left on those rows. */
  padding:7px 9px;min-width:62px;margin-left:8px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;
  border:1px solid rgba(200,188,40,.28);
  transition:scale .3s var(--ease), background .3s ease, border-color .3s ease;
}
/* The full-strength yellow is held back for the row you are actually on. */
.row:hover .save,.row[aria-expanded="true"] .save{background:var(--yellow);border-color:transparent}
.row:hover .save{scale:1.05}
.save > i{display:block;font-style:normal;font-family:var(--font-caption);font-size:8.5px;
  font-weight:700;color:#1a1800;opacity:.7;line-height:1.2}
.save b{display:block;font-family:var(--font-body);font-size:13.5px;font-weight:800;
  color:#0c0c0c;letter-spacing:-.3px;white-space:nowrap;line-height:1.15;
  font-variant-numeric:tabular-nums}
.row .chev{width:12px;height:12px;color:var(--muted);flex:none;opacity:.6;transition:rotate .3s var(--ease), color .2s}
/* Reclaim ~20px for the name column on the narrowest phones. */
.row .chev{display:none}
/* The divider used to live on the panel that followed each row. With the
   panel gone it belongs on the rows themselves. */
.list .row + .row{border-top:1px solid var(--line)}
.section[hidden]{display:none}
/* ============================================================
   Quick-link promo badges
   ============================================================ */
.qbadge{
  position:absolute;top:7px;right:7px;
  background:#0c0c0c;
  color:var(--yellow);
  font-size:7.5px;font-weight:800;letter-spacing:.3px;
  padding:4px 8px;border-radius:999px;
  white-space:nowrap;
  box-shadow:0 3px 8px rgba(12,12,12,.28);
  animation:badgePop .6s var(--ease) both;
  z-index:2;
}
@keyframes badgePop{from{opacity:0;scale:.4;rotate:-12deg}to{opacity:1;scale:1;rotate:0deg}}
.quick a:hover .qbadge{animation:badgeNudge .5s var(--ease)}
@keyframes badgeNudge{0%,100%{translate:0 0}50%{translate:0 -2px}}
/* ============================================================
   Why iPrice BD
   ============================================================ */
.sec-ico.t{background:#0c0c0c;color:var(--yellow)}
/* Bento tiles, after the reference's blue / lime / black stat row. */
.why-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.why-item{
  display:flex;flex-direction:column;gap:9px;
  padding:17px 15px;
  border-radius:22px;
  background:var(--card);
  border:1px solid var(--line);
  box-shadow:var(--shadow-m);
  transition:translate .3s var(--ease), box-shadow .3s ease;
}
.why-item:hover{translate:0 -3px;box-shadow:var(--lift)}
.why-item.k1{background:var(--card);border-color:var(--line)}
.why-item.k2{background:linear-gradient(150deg,#f7f28a,#f2e94b);border-color:rgba(200,188,40,.4)}
.why-item.k3{background:linear-gradient(155deg,#1e1e1c,#0c0c0c);border-color:transparent}
.why-item.k4{background:var(--card)}
.why-item.k2 b,.why-item.k2 > span:last-child{color:#1a1800}
.why-item.k2 > span:last-child{opacity:.72}
.why-item.k3 b{color:#fff}
.why-item.k3 > span:last-child{color:#adada4}
.why-item.k3 .wi{background:rgba(242,233,75,.16);color:var(--yellow)}
.why-item.k2 .wi{background:rgba(26,24,0,.14);color:#1a1800}
.wi{
  width:32px;height:32px;border-radius:10px;
  display:grid;place-items:center;flex:none;
  transition:scale .35s var(--ease), rotate .4s var(--ease);
}
.why-item:hover .wi{scale:1.12;rotate:-7deg}
.wi svg{width:17px;height:17px}
.wi.g{background:var(--green-soft);color:var(--green-ink)}
.wi.b{background:var(--blue-soft);color:var(--blue-ink)}
.wi.v{background:var(--violet-soft);color:var(--violet)}
.wi.a{background:var(--amber-soft);color:var(--amber-ink)}
.why-item b{font-size:14.5px;font-weight:700;letter-spacing:-.25px;line-height:1.25}
.why-item > span:last-child{font-size:9.5px;color:var(--muted);line-height:1.35}
/* ============================================================
   Welcome bonus (WhatsApp)
   ============================================================ */
.bonus{
  margin-top:16px;
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto auto;
  grid-template-areas:"ico copy cta x";
  align-items:center;gap:6px 10px;
  padding:13px 14px;
  border-radius:var(--r-lg);
  background:linear-gradient(120deg,#ffffff 0%,#f6f6f4 100%);
  border:1px solid var(--line);
  box-shadow:var(--shadow-m);
  position:relative;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .bonus{
    background:linear-gradient(120deg,#1c1c1a 0%,#141413 100%);
    border-color:rgba(242,233,75,.22);
  }
}
.bonus-ico{
  grid-area:ico;
  width:34px;height:34px;border-radius:11px;
  display:grid;place-items:center;
  background:var(--yellow);
  color:#0c0c0c;
  box-shadow:0 6px 14px rgba(200,188,40,.45);
  animation:bob 6s ease-in-out infinite;
}
.bonus-ico svg{width:18px;height:18px}
.bonus-copy{grid-area:copy;min-width:0}
.bonus-copy b{display:block;font-size:13px;font-weight:800;letter-spacing:-.3px;line-height:1.2}
.bonus-copy span{display:block;font-size:9.5px;color:var(--ink-2);opacity:.8;margin-top:2px}
.bonus-cta{
  grid-area:cta;
  display:inline-flex;align-items:center;justify-content:center;gap:6px;
  background:#0c0c0c;color:#fff;
  padding:8px 12px;border-radius:999px;
  font-size:10.5px;font-weight:800;white-space:nowrap;
  box-shadow:0 6px 14px rgba(12,12,12,.3);
  transition:translate .25s var(--ease), box-shadow .25s ease, scale .18s var(--ease);
}
.bonus-cta:hover{translate:0 -2px;box-shadow:0 12px 22px rgba(12,12,12,.4)}
.bonus-cta:active{scale:.96}
.bonus-cta svg{width:13px;height:13px;color:#25D366}
/* Below ~420px the inline button squeezes the copy into awkward wraps,
   so the CTA drops to its own full-width row instead. */
@media (max-width:419px){
  .bonus{grid-template-columns:auto minmax(0,1fr) auto;
         grid-template-areas:"ico copy x" "cta cta cta";gap:9px}
  .bonus-cta{width:100%}
}
.bonus-x{
  grid-area:x;align-self:start;
  width:22px;height:22px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--tint-2);color:var(--muted);
  border:none;padding:0;
  transition:background .16s ease, color .16s ease, scale .16s var(--ease);
}
.bonus-x svg{width:9px;height:9px}
.bonus-x:hover{background:#0c0c0c;color:#fff}
.bonus-x:active{scale:.9}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .bonus-x:hover{background:var(--yellow);color:#0c0c0c}
}
/* ---------- docked to the bottom of the screen ----------
   Fixed, and deliberately a child of <body>. A .view runs an entrance animation
   on translate with fill both, which makes it the containing block for every
   fixed descendant for good — nested inside one, the bar would dock to the
   bottom of the page's content instead of the screen. Same reason the filter
   sheet lives out here. */
.dock{
  position:fixed;z-index:70;
  left:50%;translate:-50% 0;
  bottom:max(10px, env(safe-area-inset-bottom));
  width:min(460px,100vw);
  padding:0 var(--pad);
  pointer-events:none;                  /* the gutters either side stay live */
  /* No fill mode, and the entrance rides on transform rather than translate.
     With backwards the from-keyframe applies whenever the animation has not
     run, which parks the bar 140% below the screen for good if animations are
     ever held up; unfilled, the resting state is simply where it sits. */
  animation:dockUp .55s var(--pop);
}
.dock .bonus{
  pointer-events:auto;
  margin-top:0;
  /* --r-lg is 26px, which is the radius the hero, the lists and the promo share
     — on a bar only 80px tall it is a third of the height and reads as a
     lozenge. One step down the same scale, not an arbitrary number. */
  border-radius:var(--r-md);
  padding:11px 12px;
  gap:5px 9px;
  box-shadow:var(--shadow-l);
}
.dock.out{animation:dockDown .3s var(--ease) forwards}
@keyframes dockUp{from{opacity:0;transform:translateY(140%)}}
@keyframes dockDown{to{opacity:0;transform:translateY(140%)}}
@media (prefers-reduced-motion:reduce){.dock,.dock.out{animation:none}}
/* ============================================================
   Promo
   ============================================================ */
.promo{
  margin-top:22px;position:relative;overflow:hidden;
  border-radius:var(--r-lg);
  padding:16px 15px 17px;
  background:linear-gradient(150deg,#1e1e1c 0%,#0c0c0c 100%);
  border:1px solid rgba(12,12,12,.9);
  color:#f5f5f2;
  box-shadow:var(--shadow-m);
  perspective:700px;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .promo{
    background:linear-gradient(135deg,#3a3714 0%,#242208 100%);
    border-color:rgba(242,233,75,.28);
  }
}
.promo .tag{
  display:inline-block;
  font-size:9.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;
  color:#0c0c0c;
  background:var(--yellow);
  padding:4px 9px;border-radius:999px;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .promo .tag{background:#0c0c0c;color:var(--yellow)}
}
.promo h4{margin:10px 0 0;font-size:18.5px;line-height:1.2;letter-spacing:-.55px;font-weight:800;max-width:60%}
.promo .lede{margin:7px 0 0;font-size:11px;line-height:1.45;color:#c9c9c2;opacity:1;max-width:58%}
.promo .btn{
  margin-top:13px;
  display:inline-flex;align-items:center;gap:7px;
  background:var(--yellow);color:#0c0c0c;
  padding:9px 14px;border-radius:999px;
  font-size:11.5px;font-weight:700;
  box-shadow:0 8px 18px rgba(200,188,40,.35);
  transition:translate .28s var(--ease), box-shadow .28s ease, scale .18s var(--ease);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .promo .btn{color:#0c0c0c}
}
.promo .btn:hover{translate:0 -2px;box-shadow:0 14px 26px rgba(200,188,40,.45)}
.promo .btn:active{scale:.96}
.promo .btn svg{width:12px;height:12px;transition:translate .25s var(--ease)}
.promo .btn:hover svg{translate:3px 0}
.promo-art{position:absolute;right:4px;top:30px;width:150px;height:136px;pointer-events:none}
@media (max-width:359px){.promo-art{width:116px;right:-10px;opacity:.9}}
/* Stacked deck: two cards sit behind the face card so the visual reads as a
   balance you hold rather than a single voucher. They are decoration only,
   which is why they are empty elements. */
/* nudged right of where the single card sat, so the fanned backs keep clear
   of the headline column */
.deck{position:absolute;left:13px;top:13px;width:124px;height:80px}
.gc-back{
  position:absolute;inset:0;border-radius:15px;
  background:linear-gradient(140deg,rgba(251,246,143,.5),rgba(227,217,47,.42));
  border:1px solid rgba(242,233,75,.4);
  box-shadow:0 10px 20px rgba(0,0,0,.34);
  rotate:var(--rot);translate:var(--tx) var(--ty);
}
.gc-back.b1{--rot:-15deg;--tx:-7px;--ty:5px}
.gc-back.b2{--rot:-21deg;--tx:-11px;--ty:8px;opacity:.72}
.js .promo .gc-back{opacity:0}
.js .promo.in .gc-back{animation:deal .75s var(--ease) both}
.js .promo.in .gc-back.b1{animation-delay:.3s}
.js .promo.in .gc-back.b2{animation-delay:.44s;opacity:.72}
@media (prefers-reduced-motion:reduce){
  .js .promo .gc-back,.js .promo.in .gc-back{opacity:1;animation:none}
  .js .promo.in .gc-back.b2{opacity:.72}
}
.gc{
  position:absolute;left:0;top:0;
  width:124px;height:80px;border-radius:15px;
  background:linear-gradient(140deg,#fbf68f 0%,#f2e94b 55%,#e3d92f 100%);
  z-index:2;
  box-shadow:0 16px 30px rgba(0,0,0,.5);
  color:#0c0c0c;                       /* one ink value, not two */
  padding:10px 12px;overflow:hidden;
  rotate:-9deg;
  transform-style:preserve-3d;
  transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
  transition:transform .45s var(--ease-soft), box-shadow .4s ease;
  animation:bob 8s ease-in-out infinite;
}
.promo:hover .gc{box-shadow:0 22px 38px rgba(0,0,0,.6)}
/* region tag sits in a black pill so it reads as a label, not stray type */
.gc .r{
  display:inline-flex;align-items:center;gap:4px;
  background:#0c0c0c;color:var(--yellow);
  border-radius:999px;padding:3px 7px;
  font-family:var(--font-caption);
  font-size:6.5px;font-weight:800;letter-spacing:.6px;
}
.gc .r .flag{width:11px;height:7.5px}
.gc .v{
  display:block;margin-top:7px;
  font-family:var(--font-title);
  font-size:30px;font-weight:800;letter-spacing:-1.6px;line-height:1;color:#0c0c0c;
}
.gc .s{
  display:block;margin-top:1px;
  font-family:var(--font-caption);
  font-size:7px;font-weight:700;letter-spacing:.3px;color:#1a1800;opacity:.72;
}
/* black disc bleeding off the corner, echoing the brand's circular marks */
.gc::after{
  content:"";position:absolute;right:-18px;bottom:-24px;
  width:66px;height:66px;border-radius:50%;background:rgba(12,12,12,.12);
}
/* shine sweeping over the card */
.gc::before{
  content:"";position:absolute;top:-50%;left:0;width:100%;height:200%;
  background:linear-gradient(72deg,transparent 42%,rgba(255,255,255,.6) 50%,transparent 58%);
  animation:glint 6s ease-in-out 2.2s infinite;
}
@media (prefers-reduced-motion:reduce){.gc::before{animation:none;opacity:0}}
/* Floating app marks on the promo card. The brand symbols carry their own
   backgrounds, so they bleed to the edge of the tile and the tile just clips
   them; the bare Apple glyph sits inset on black instead. These base rules
   were lost when the gift card was rebuilt, which left the marks at their
   intrinsic SVG size. */
.chip{
  width:30px;height:30px;border-radius:9px;
  display:grid;place-items:center;
  background:var(--card);
  overflow:hidden;
}
.chip svg{width:30px;height:30px}
.chip.sm{width:26px;height:26px;border-radius:8px}
.chip.sm svg{width:26px;height:26px}
.chip.dark{background:#0c0c0c;color:#fff}
.chip.dark svg{width:15px;height:15px}
.promo-art .chip{box-shadow:0 8px 18px rgba(12,12,12,.4);position:absolute;z-index:3;
  animation:bob 6.5s ease-in-out infinite}
.p-apple{right:8px;top:2px}   .p-apple{animation-delay:.2s}
.p-spotify{right:0;top:40px}  .p-spotify{animation-delay:1.1s;animation-duration:7.4s}
.p-netflix{right:34px;top:82px} .p-netflix{animation-delay:2s;animation-duration:6.1s}
.p-yt{right:2px;top:84px}     .p-yt{animation-delay:.7s;animation-duration:7.8s}
/* ============================================================
   Footer
   ============================================================ */
.foot{margin-top:26px;text-align:center;padding:0 8px}
.foot p{margin:0;font-size:10px;line-height:1.6;color:var(--muted)}
/* ============================================================
   Typography roles
   Outfit -> titles | Archivo -> body | Inter -> captions
   (Outfit carries a full 100-900 range, so titles sit at 800.)
   ============================================================ */
.brand h1,
.hero h2,
.sec-head h3,
.promo h4,
.quick b,
.row-info b,
.why-item b,
.bonus-copy b,
.empty b,
.save b,
.yr b,
.gc .v{
  font-family:var(--font-title);
  font-weight:800;
}
.brand h1{letter-spacing:-.5px}
.hero h2{letter-spacing:-.8px;line-height:1.05}
/* size is fluid now, so the narrow break only needs the tighter tracking */
.sec-head h3{letter-spacing:-.4px}
.promo h4{letter-spacing:-.5px;line-height:1.16}
.bonus-copy b{letter-spacing:-.3px}
.quick b{letter-spacing:-.2px}
.row-info b,.why-item b{letter-spacing:-.2px}
.save b{font-size:13.5px;letter-spacing:-.3px;color:#0c0c0c}
.gc .v{letter-spacing:-1.2px}
/* Prices stay in Archivo: it holds up far better at 12px than a display
   face, and tabular figures keep the two columns vertically aligned. */
/* Archivo draws $ taller than its digits, overshooting cap-height and
   baseline; ₹ and ৳ sit correctly. Scale only the dollar glyph back. */
.cur{font-style:normal;font-size:.76em;letter-spacing:-.01em}
.price .amt,.bar .val{
  font-family:var(--font-body);
  font-variant-numeric:tabular-nums;
  font-weight:700;
}
/* The taka sign comes from a fallback face and lands lighter and narrower than
   Archivo's figures; a slight bump evens the pairing out. */
.amt,.save b,.yr b,.mini b{font-feature-settings:"tnum" 1}
.brand p,
.pill,
.promo .tag,
.quick .sub,
.row-info .cat,
.price .per,
.save i,
.save small,
.qbadge,
.foot p,
.results > span,
.cur-menu small,
.mini small,
.yr small,
.bar .lbl,
.gc .r,
.gc .s{
  font-family:var(--font-caption);
}
/* Inter runs a touch large at caption sizes; nudge tracking back out. */
.qbadge,.promo .tag{letter-spacing:.45px}
/* Reference leans on small, wide-tracked uppercase labels. */
.pill,.sec-head p,.quick .sub{font-weight:600}
.pill{text-transform:uppercase;letter-spacing:.7px;font-size:10px}
.save i,.save small,.yr small{letter-spacing:.1px}
/* ============================================================
   Indic typography
   Bengali and Devanagari carry their meaning in the conjuncts and in the
   headstroke that runs along the top of the line, so the tight tracking and
   the uppercasing that suit the Latin setting actively damage them. Anything
   carrying a translated string relaxes back to normal spacing, keeps its case,
   and gets a little more leading for the ascenders to breathe.
   ============================================================ */
html[lang="bn"] [data-t], html[lang="hi"] [data-t],
html[lang="bn"] [data-tph], html[lang="hi"] [data-tph]{
  letter-spacing:normal;
  text-transform:none;
  line-height:1.45;
}
html[lang="bn"] h2 [data-t], html[lang="hi"] h2 [data-t],
html[lang="bn"] h3[data-t], html[lang="hi"] h3[data-t],
html[lang="bn"] h4[data-t], html[lang="hi"] h4[data-t]{line-height:1.3}
html[lang="bn"] .pill, html[lang="hi"] .pill{letter-spacing:normal;text-transform:none;font-size:11px}
html[lang="bn"] .gc .r, html[lang="hi"] .gc .r{letter-spacing:normal;font-size:6px}
html[lang="bn"] .qbadge, html[lang="hi"] .qbadge{letter-spacing:normal}
/* Indic runs longer than the Latin setting, so the promo copy gives up a little
   width to keep clear of the gift card behind it */
html[lang="bn"] .promo h4, html[lang="hi"] .promo h4{max-width:55%;font-size:17px;line-height:1.32}
html[lang="bn"] .promo .lede, html[lang="hi"] .promo .lede{max-width:55%}
/* Indic glyphs run optically larger, so the smallest captions come back a step */
html[lang="bn"] .row-info em, html[lang="hi"] .row-info em,
html[lang="bn"] .cat, html[lang="hi"] .cat{font-size:10.5px;letter-spacing:normal;text-transform:none}
/* ============================================================
   Loading
   Digits rolling the way the saving counts up when a row scrolls in, so the
   wait and the settled state are the same gesture.
   ============================================================ */
.boot{display:none}
.js .boot{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;
  position:fixed;inset:0;z-index:200;
  background:linear-gradient(150deg,#1e1e1c,#0c0c0c);
  transition:opacity .45s ease;
}
.js .boot.gone{opacity:0;pointer-events:none}
.roll{
  display:flex;align-items:center;gap:1px;
  color:var(--yellow);
  font-family:var(--font-title);
  font-size:clamp(38px,11vw,48px);font-weight:800;letter-spacing:-2px;
  height:1.2em;overflow:hidden;
}
.roll-cur{font-size:.68em;margin-right:3px;opacity:.85}
.roll .dig{display:block;height:1.2em;overflow:hidden;width:.6em;text-align:center}
.roll .dig i{display:block;height:1.2em;line-height:1.2em;font-style:normal;
  animation:roll 1.5s cubic-bezier(.6,0,.35,1) infinite}
.roll .d2 i{animation-duration:1.9s}
.roll .d3 i{animation-duration:1.15s}
@keyframes roll{from{translate:0 0}to{translate:0 -1000%}}
.boot-cap{
  margin:0;font-family:var(--font-caption);
  font-size:11px;font-weight:600;color:#adada4;letter-spacing:.2px;
  animation:capPulse 1.8s ease-in-out infinite;
}
@keyframes capPulse{0%,100%{opacity:.5}50%{opacity:1}}
/* nothing to watch means nothing worth waiting for: skip the curtain entirely */
@media (prefers-reduced-motion:reduce){.js .boot{display:none}}
/* ============================================================
   Views
   Three screens behind the hash: home, a section listing, and an item page.
   Only one is in the document flow at a time, so nothing below it can be
   reached by scrolling past a hidden screen.
   ============================================================ */
#v-home[hidden],.view[hidden]{display:none}
/* An id outweighs the UA's [hidden]{display:none}, so these two need to say
   it themselves — the script sets hidden on #lpList when nothing matches,
   and an empty flex box still carried its own 16px top margin. */
#lpList[hidden],#v-detail[hidden]{display:none}
.view{animation:viewIn .32s var(--ease) both}
@keyframes viewIn{from{opacity:0;translate:0 10px}to{opacity:1;translate:0 0}}
@media (prefers-reduced-motion:reduce){.view{animation:none}}

.lp-top{display:flex;align-items:center;gap:12px;padding:8px 0 4px}
.lp-back{
  flex:none;width:36px;height:36px;border-radius:50%;
  display:grid;place-items:center;
  background:var(--card);border:1px solid var(--line);
  box-shadow:var(--shadow-s);color:var(--ink);
  transition:translate .22s var(--ease), box-shadow .22s ease, scale .16s var(--ease);
}
.lp-back svg{width:14px;height:14px;rotate:180deg}
.lp-back:hover{translate:-2px 0;box-shadow:var(--shadow-m)}
.lp-back:active{scale:.94}
.lp-ttl{min-width:0}
.lp-ttl h2{margin:0;font-family:var(--font-title);font-size:20px;font-weight:800;letter-spacing:-.5px;line-height:1.15}
.lp-ttl p{margin:4px 0 0;font-size:11px;color:var(--muted);line-height:1.45}

.lp-search{margin-top:16px}
/* the label and the running count share a line */
.lp-lbl{display:flex;align-items:baseline;gap:10px;margin:20px 0 9px}
.lp-lbl .lbl{margin:0}
.lp-count{margin-left:auto;font-family:var(--font-caption);font-size:10.5px;
  font-weight:700;color:var(--muted);white-space:nowrap}
/* Chips wrap onto as many lines as they need: a sideways scroller cuts the
   chip it stops on, and half a chip reads as a rendering fault. */
.wrapchips{display:flex;gap:7px;flex-wrap:wrap}
/* One scale for the whole page: 20px between sections, 9-10px between the
   parts of one thing, 4-5px for a pair that belongs on a single breath. */
.lbl{font-family:var(--font-caption);font-size:9px;font-weight:800;letter-spacing:.7px;
  text-transform:uppercase;color:var(--muted);margin:20px 0 9px;line-height:1.4}
.chip-b .ct{
  font-size:9px;font-weight:800;color:var(--muted);
  background:var(--tint-2);border-radius:999px;padding:1px 5px;margin-left:5px;
}
.chip-b.on .ct{background:rgba(255,255,255,.2);color:#fff}
.chip-b{
  flex:none;border:1px solid var(--line);background:var(--card);
  border-radius:999px;padding:7px 12px;
  font-family:var(--font-caption);font-size:10.5px;font-weight:700;color:var(--ink-2);
  white-space:nowrap;
  transition:background .2s ease, color .2s ease, border-color .2s ease, scale .16s var(--ease);
}
.chip-b:hover{border-color:var(--ink-2)}
.chip-b:active{scale:.95}
.chip-b.on{background:#0c0c0c;border-color:#0c0c0c;color:#fff}

/* ---------- the listing is a stack of cards ----------
   One slab with rules through it reads as a table, and a table is something
   you scan rather than choose from. Separate cards give each option its own
   edge, so the eye can pick one up on its own and the tap target is obvious.
   The wrapper drops the slab's own background, or every card would sit on a
   second white rectangle. */
#lpList{
  margin-top:16px;
  /* the gap has to clear the lift (4px) and the ring (3px) with room to spare,
     or a raised card reads as sitting on top of its neighbour */
  display:flex;flex-direction:column;gap:14px;
  background:none;border-radius:0;box-shadow:none;overflow:visible;
}
#lpList .row{
  cursor:pointer;
  background:var(--card);
  border:1px solid var(--line);
  border-radius:20px;
  padding:13px 11px;
  overflow:hidden;                       /* keeps the accent rail inside the corner */
  box-shadow:var(--shadow-s);
  transition:translate .24s var(--ease), box-shadow .24s ease,
             border-color .2s ease, background .2s ease;
}
/* The slab's divider rule (.list .row + .row) already draws exactly the 1px
   line these cards want for their own top edge, so it is left alone. An earlier
   version zeroed it here to kill the divider — which also deleted the top
   border of every card after the first, and read as the card above covering it. */
/* ---------- how a card answers ----------
   Up on hover, down on the press, with a rail arriving from the left. The
   easing overshoots a little so the lift reads as a spring rather than a slide,
   and three things move on it — the card, the mark and the name — which is
   what makes the gesture feel alive rather than merely animated.
   The press keeps the border at 1px and puts the emphasis in a pale ring, so
   nothing inside the card shifts by a pixel when it is held down. */
#lpList .row{
  transition:translate .24s var(--pop), border-color .16s ease,
             box-shadow .16s ease, background .18s ease;
}
#lpList .row::before{
  top:0;bottom:0;left:0;width:4px;border-radius:0;
  background:var(--yellow);
  scale:1 1;translate:-4px 0;
  transition:translate .24s var(--pop), background .16s ease;
}
#lpList .row .row-info{transition:translate .24s var(--pop)}

/* z-index so the raised card is never clipped by the sibling painted after it */
#lpList .row:hover,#lpList .row:active,#lpList .row:focus-visible{
  z-index:2;
}
#lpList .row:hover{translate:0 -4px;border-color:rgba(12,12,12,.22);box-shadow:none}
#lpList .row:hover::before{translate:0 0}
#lpList .row:hover .row-info{translate:5px 0}
#lpList .row:hover .row-ico,#lpList .row:hover .gico{scale:1.12;rotate:-7deg}
#lpList .row:hover .save{scale:1.07}

#lpList .row:active{
  translate:0 2px;
  border-color:#0c0c0c;
  box-shadow:0 0 0 3px var(--yellow-soft);
}
#lpList .row:active::before{translate:0 0;background:#0c0c0c}
#lpList .row:active .row-info{translate:5px 0}

#lpList .row:focus-visible{
  translate:0 0;outline:none;
  border-color:#0c0c0c;
  box-shadow:0 0 0 3px var(--yellow);
}
#lpList .row:focus-visible::before{translate:0 0;background:#0c0c0c}

@media (prefers-reduced-motion:reduce){
  #lpList .row,#lpList .row::before,#lpList .row .row-info{transition:none}
  #lpList .row:hover,#lpList .row:active{translate:0 0}
}
/* A pack label like "130 eFootball Coins - Sports" cannot fit one line beside
   two prices and a chip. In the ruled list it had to truncate; a card can just
   be a few pixels taller, so here it wraps to a second line instead. */
#lpList .row-info em{white-space:normal;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
@media (max-width:379px){
  #lpList{gap:12px}
  #lpList .row{padding:12px 10px;border-radius:18px}
}
.lp-none{margin:26px 0 0;text-align:center;font-size:12px;line-height:1.5;color:var(--muted)}

.dt-mark{display:inline-grid;place-items:center}
.dt-mark .row-ico,.dt-mark .gico{width:56px;height:56px;border-radius:18px;animation:none}
.dt-mark .row-ico svg{width:56px;height:56px}
.dt-mark .gico{font-size:17px}
/* ---------- item page ----------
   The supplied reference, rebuilt in the brand: the two regions read as a
   before and after rather than two equal options, so the yellow goes on the
   one you are meant to pick and nowhere else. */
/* Black, so the page opens on the product rather than on another white card,
   and the brand mark gets a ground to sit against. */
.dt-hero{
  display:flex;align-items:flex-start;gap:15px;
  background:linear-gradient(155deg,#1e1e1c,#0c0c0c);
  border:1px solid rgba(255,255,255,.06);border-radius:var(--r-lg);
  padding:17px 16px;margin-top:16px;box-shadow:var(--shadow-m);
  color:#f5f5f2;
}
/* a mark with a transparent field would disappear on black */
.dt-mark .row-ico{background:#fff}
.dt-mark{flex:none;display:grid;place-items:center}
.dt-mark .row-ico,.dt-mark .gico{width:58px;height:58px;border-radius:18px;animation:none;scale:1;rotate:0deg}
.dt-mark .row-ico svg{width:58px;height:58px}
.dt-mark .gico{font-size:18px}
.dt-id{min-width:0}
.dt-id b{display:block;font-family:var(--font-title);font-size:19px;font-weight:800;
  letter-spacing:-.5px;line-height:1.22;color:#fff}
.dt-meta{margin:8px 0 0;display:flex;flex-wrap:wrap;align-items:center;gap:6px;
  font-family:var(--font-caption);font-size:10px;line-height:1.5;color:var(--muted)}
.dt-meta{color:#adada4}
.dt-meta .pub{font-weight:600}
.dt-meta .tg{background:rgba(255,255,255,.1);border-radius:6px;padding:3px 8px;
  font-weight:700;color:#e8e8e3}
.dt-desc{margin:10px 0 0;font-size:11.5px;line-height:1.55;color:#adada4}

/* The plans are one control, so they read as one control: equal columns
   across the full width rather than three pills adrift on the left. */
#dtPlans{
  margin-bottom:0;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(0,1fr));gap:8px;
}
#dtPlans .chip-b{
  justify-content:center;text-align:center;padding:11px 8px;border-radius:14px;
}

/* label left, the explainer opposite it, on the row the label already had */
.dt-cmphead{display:flex;align-items:baseline;gap:10px;margin:20px 0 0}
.dt-cmphead .lbl{margin:0}
.dt-whatfee{
  margin-left:auto;display:inline-block;white-space:nowrap;
  background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--font-caption);font-size:9.5px;font-weight:700;
  color:var(--muted);text-decoration:underline;text-underline-offset:3px;
  text-decoration-color:color-mix(in srgb, currentColor 40%, transparent);
  transition:color .16s ease;
}
.dt-whatfee svg{display:inline-block;width:12px;height:12px;vertical-align:-2px;margin-right:5px}
.dt-whatfee:hover{color:var(--ink)}
.dt-whatfee:focus-visible{outline:2px solid var(--yellow-deep);outline-offset:3px;border-radius:5px}
.dt-cmphead + .cmp{margin-top:9px}

.dt-card{
  margin-top:20px;padding:16px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:var(--shadow-m);
}
.cmp{display:grid;grid-template-columns:1fr 1fr;column-gap:10px;row-gap:0;
  /* name, total, toggle, then the working's own three rows - six lines both
     cards sit on, so a label that takes two lines on one side cannot tilt the
     rows under it against the other */
  grid-template-rows:auto auto auto auto auto auto}
@media (max-width:379px){.cmp{grid-template-columns:1fr}}
/* Two separate ideas, kept separate. `.best` is which region is objectively
   cheaper — a fact about the prices, so the tag belongs to it whichever side
   it lands on, and saying India is best when it is not would be the one thing
   that makes the whole comparison untrustworthy. `.on` is which region you
   picked, and that is what the yellow follows. They start on the same box. */
.cmp-box{
  /* Subgrid: the pair is the same height by construction, and the four rows
     land on the same four lines even though the US total is a range that wraps
     where India's single figure does not. min-width:0 lets a box shrink to its
     track - without it the LOWEST badge makes one card wider than its column
     and shoves the other out of the card. */
  display:grid;grid-template-rows:subgrid;grid-row:span 6;width:100%;min-width:0;
  position:relative;border-radius:18px;padding:13px 12px;text-align:left;
  /* both borders the same width, or the subgrid tracks start half a pixel
     apart and the rows stop lining up */
  background:var(--card);border:1.5px solid var(--line);
  transition:translate .2s var(--pop), border-color .16s ease,
             box-shadow .16s ease, background .18s ease;
}
.cmp-box:hover{translate:0 -2px;border-color:rgba(12,12,12,.24)}
.cmp-box:active{translate:0 1px}
.cmp-box:focus-visible{outline:none;border-color:#0c0c0c;box-shadow:0 0 0 3px var(--yellow)}
.cmp-box.on{background:linear-gradient(150deg,#fdfbe4,#f7f28a);border-color:var(--yellow-deep)}
.cmp-box.on:hover{border-color:var(--yellow-deep)}
@media (prefers-reduced-motion:reduce){
  .cmp-box,.cmp-box:hover,.cmp-box:active{transition:none;translate:0 0}
}
/* one row: the country and, on the cheaper side, its badge */
.cmp-top{display:flex;align-items:center;flex-wrap:wrap;gap:5px 8px;min-height:20px}
.cmp-h{display:flex;align-items:center;gap:6px;
  font-family:var(--font-caption);font-size:10.5px;font-weight:800;
  letter-spacing:.2px;line-height:1.4;color:var(--muted)}
/* The answer. Everything under the toggle is the working, and is set small
   and light so the eye reaches what is paid first. */
.cmp-pay{display:block;margin-top:8px}
.cmp-lbl{display:block;font-style:normal;font-family:var(--font-caption);font-size:8.5px;
  font-weight:800;letter-spacing:.7px;text-transform:uppercase;line-height:1.3;color:var(--muted)}
.cmp-box.on .cmp-lbl{color:#1a1800;opacity:.72}
.cmp-t{display:block;margin-top:2px;font-family:var(--font-title);font-size:23px;font-weight:800;
  letter-spacing:-.9px;line-height:1.08;color:var(--ink)}
.cmp-box.on .cmp-t{font-size:26px;color:#0c0c0c}
.cmp-t .to,.cmp-r .to{font-size:.68em;font-weight:700;letter-spacing:0;opacity:.7;padding:0 2px}

/* the toggle: label left, caret hard right, one row of its own */
.cmp-more{display:flex;align-items:center;gap:6px;margin-top:9px;
  font-family:var(--font-caption);font-size:9.5px;font-weight:800;color:var(--muted)}
.cmp-more i{font-style:normal}
.cmp-box.on .cmp-more{color:#1a1800;opacity:.78}
.cmp-car{width:12px;height:12px;flex:none;margin-left:auto;
  transition:rotate .22s var(--ease)}
.cmp.shut .cmp-car{rotate:-90deg}
@media (prefers-reduced-motion:reduce){.cmp-car{transition:none}}

/* the working */
.cmp-maths{display:grid;grid-template-rows:subgrid;grid-row:span 3;
  margin-top:7px;padding-top:7px;border-top:1px solid var(--line)}
.cmp-box.on .cmp-maths{border-top-color:rgba(26,24,0,.2)}
.cmp.shut .cmp-maths{display:none}
/* label column and value column. The value never leaves the row; the label
   wraps inside its own column, and because the rate is one unbreakable span
   the break falls at the space rather than through the number. */
.cmp-r{display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:3px 0}
.cmp-r:first-child{padding-top:0}
.cmp-r i{flex:1 1 auto;min-width:0;font-style:normal;font-family:var(--font-caption);
  font-size:9px;font-weight:700;line-height:1.35;color:var(--muted)}
.cmp-fr{white-space:nowrap}
.cmp-box.on .cmp-r i{color:#1a1800;opacity:.72}
.cmp-r b{flex:none;margin-left:auto;font-family:var(--font-title);font-size:12px;font-weight:700;
  letter-spacing:-.2px;text-align:right;color:var(--ink-2)}
.cmp-box.on .cmp-r b{color:#1a1800;opacity:.82}
/* The fee keeps its colour but loses its pill. Inside the working, a filled
   chip carried more weight than the total above it, which is the one thing
   this card must not do. */
.cmp-fl{display:inline-flex;align-items:center;flex-wrap:wrap;gap:1px 4px}
.cmp-fl svg{width:11px;height:11px;flex:none}
.cmp-r.warn i,.cmp-box.on .cmp-r.warn i,
.cmp-r.warn b,.cmp-box.on .cmp-r.warn b{color:var(--fee-bad);opacity:1}
.cmp-r.ok i,.cmp-box.on .cmp-r.ok i,
.cmp-r.ok b,.cmp-box.on .cmp-r.ok b{color:var(--fee-good);opacity:1}
.cmp-box.on .cmp-h{color:color-mix(in srgb, #1a1800 75%, transparent)}
.cmp-h .flag{width:15px;height:10px;border-radius:2px}
.cmp-tag{
  margin-left:auto;
  display:inline-flex;align-items:center;gap:5px;
  background:#0c0c0c;color:var(--yellow);
  font-family:var(--font-caption);font-size:8px;font-weight:800;letter-spacing:.6px;
  padding:4px 10px;border-radius:999px;
}
.cmp-tag svg{width:11.5px;height:11.5px;flex:none}
.cmp-tag i{font-style:normal}
/* the tag belongs to the cheaper box, which is not always the chosen one */
.cmp-box:not(.best) .cmp-tag{display:none}
/* ---------- price alerts ---------- */
.dt-alert{
  display:flex;align-items:center;gap:12px;margin-top:20px;
  padding:15px;border-radius:var(--r-lg);
  background:linear-gradient(120deg,#fffdf0,#fdfbe4);
  border:1.5px solid var(--yellow-deep);
}
.dt-alico{flex:none;width:32px;height:32px;border-radius:11px;display:grid;place-items:center;
  background:var(--yellow);color:#1a1800}
.dt-alico svg{width:16px;height:16px}
.dt-altx{flex:1;min-width:0}
.dt-altx b{display:block;font-size:12px;font-weight:800;letter-spacing:-.2px;line-height:1.35;color:#1a1800}
.dt-altx span{display:block;margin-top:5px;font-size:10px;line-height:1.45;color:var(--ink-2);opacity:.75}
.dt-alcta{
  flex:none;display:inline-flex;align-items:center;gap:6px;
  background:#0c0c0c;color:#fff;border-radius:999px;padding:9px 13px;
  font-family:var(--font-caption);font-size:10.5px;font-weight:700;white-space:nowrap;
  transition:scale .16s var(--ease), box-shadow .22s ease;
}
.dt-alcta:hover{box-shadow:0 8px 18px rgba(12,12,12,.28)}
.dt-alcta:active{scale:.96}
.dt-alcta svg{width:13px;height:13px;color:#25D366}
@media (max-width:359px){
  .dt-alert{flex-wrap:wrap}
  .dt-alcta{margin-left:44px}
}

/* The card, this row and the button all sit one padding in from the panel, so
   their text starts on the same line. Before, the row sat at the panel margin
   and hung left of the column the cards had already set. */
/* 🚫 Not on the India store.
   Red is the ink the fee rows already use for "this one costs you" - the only
   negative in a palette that is otherwise yellow and black - so the state
   reads without teaching a new colour. The panel is a wash of that ink rather
   than a filled red box: the message is "we cannot sell you this", not an
   error the buyer caused. */
.dt-bk{margin-bottom:14px;padding:14px 15px;border-radius:var(--r-md);
  background:color-mix(in srgb,var(--fee-bad) 7%,var(--card));
  border:1.5px solid color-mix(in srgb,var(--fee-bad) 26%,var(--card))}
.dt-bk-top{display:flex;align-items:center;gap:9px;margin-bottom:9px}
.dt-bk-rg{display:inline-flex;align-items:center;gap:7px;min-width:0;
  font-family:var(--font-caption);font-size:11px;font-weight:800;color:var(--ink)}
.dt-bk-rg .flag{width:17px;height:12px;border-radius:2px;display:block;flex:none}
.dt-bk-pill{margin-left:auto;flex:none;display:inline-flex;align-items:center;
  padding:3px 9px;border-radius:999px;background:var(--fee-bad);color:#fff;
  font-family:var(--font-caption);font-size:9.5px;font-weight:800;letter-spacing:.4px;
  text-transform:uppercase;white-space:nowrap}
/* Icon left, words right - the same grammar as the alert box below, so the
   two read as the same kind of object rather than two inventions. */
.dt-bk-body{display:flex;align-items:flex-start;gap:11px}
.dt-bk-ico{flex:none;width:32px;height:32px;border-radius:11px;
  display:grid;place-items:center;background:var(--fee-bad);color:#fff}
.dt-bk-ico svg{width:17px;height:17px;display:block}
.dt-bk-tx{flex:1;min-width:0}
.dt-bk-h{display:block;font-family:var(--font-title);font-size:17px;font-weight:800;
  letter-spacing:-.4px;color:var(--fee-bad)}
.dt-bk-p{margin:5px 0 0;font-family:var(--font-body);font-size:12.5px;line-height:1.65;
  color:var(--ink);opacity:.85}
/* The way out. Same row grammar as the lists, so it reads as "these instead"
   rather than as an unrelated promo block. */
.dt-bk-lbl{margin-top:2px}
.dt-alts{display:flex;flex-direction:column;gap:9px}
.dt-alt{display:flex;align-items:center;gap:11px;width:100%;
  padding:11px 12px;border-radius:14px;text-align:left;cursor:pointer;
  background:var(--card);border:1px solid var(--line);
  transition:border-color .18s ease, translate .18s var(--ease)}
.dt-alt:hover{border-color:var(--yellow-deep);translate:0 -1px}
.dt-alt .gico,.dt-alt .row-ico{width:36px;height:36px;border-radius:11px}
.dt-alt .row-ico svg{width:36px;height:36px}
.dt-alt-x{flex:1;min-width:0}
.dt-alt-n{display:block;font-family:var(--font-body);font-size:13.5px;font-weight:700;
  color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* One line, always. Wrapped onto two it stopped looking like a value and
   started looking like a paragraph, and it pushed the row out of rhythm. */
.dt-alt-s{display:block;margin-top:2px;font-family:var(--font-body);font-size:11px;
  font-weight:700;color:var(--fee-good);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Capped, because the denomination is the one string here with no upper bound
   - "60 Genesis Crystals" is three times "80 CP" and it was eating the saving
   line's width. Past the cap it wraps instead of taking the room. */
.dt-alt-p{flex:none;text-align:right;max-width:84px}
.dt-alt-p b{display:block;font-family:var(--font-title);font-size:15.5px;font-weight:800;
  letter-spacing:-.4px;color:var(--ink)}
.dt-alt-p i{display:block;margin-top:1px;font-style:normal;line-height:1.35;
  font-family:var(--font-caption);font-size:10px;color:var(--muted)}
/* [hidden] ties with a single class on specificity and loses the display.
   #dtPlans is worse: it carries an id rule AND a second one inside the 768px
   query, both (1,0,0), so the attribute was set and simply ignored - the plan
   chips stayed on screen on desktop for an item that has no plans to pick.
   (1,1,0) beats both wherever they sit in the file. */
.dt-bk[hidden],.dt-alts[hidden],.dt-bk-lbl[hidden]{display:none}
#dtPlans[hidden],#dtPlanLbl[hidden]{display:none}
/* nothing in the buy stack is true without an India price */
.dt-card.blocked .dt-cmphead,.dt-card.blocked .cmp,.dt-card.blocked .dt-panel,
.dt-card.blocked .dt-total,.dt-card.blocked .dt-cta,.dt-card.blocked .dt-pay{display:none}
/* a saving figure on a row we cannot sell is the same lie, one page earlier */
.row.not-in .prices,.row.not-in .save{display:none}
.row.not-in .row-na{display:inline-flex;align-items:center;flex:none;
  margin-left:auto;padding:4px 10px;border-radius:999px;
  background:color-mix(in srgb,var(--fee-bad) 11%,var(--card));color:var(--fee-bad);
  font-family:var(--font-caption);font-size:9.5px;font-weight:800;letter-spacing:.3px;
  text-transform:uppercase;white-space:nowrap}

.dt-panel{position:relative;display:flex;align-items:flex-start;gap:11px;
  margin-top:14px;padding:17px 13px 13px;border-radius:16px;
  background:linear-gradient(150deg,#fdfbe4,#f7f28a);border:1.5px solid var(--yellow-deep)}
/* The saving said again as a proportion, where a discount sticker goes. It
   sits half outside the corner so it reads as applied to the panel rather
   than printed inside it, and green because it is the one figure here that
   is nothing but good news. #06331c on #26D872 is 7.44:1, which holds at
   9.5px. The panel is pinned light in both themes, so the pill is too. */
.dt-badge{position:absolute;top:-10px;right:12px;z-index:2;
  display:inline-flex;align-items:center;gap:4px;
  padding:3px 9px;border-radius:999px;background:#26D872;color:#06331c;
  font-family:var(--font-caption);font-size:9.5px;font-weight:800;letter-spacing:.2px;
  white-space:nowrap}
.dt-badge svg{width:11px;height:11px;flex:none}
/* [hidden] alone ties with .dt-badge on specificity and loses the display */
.dt-badge[hidden]{display:none}
.dt-bi{flex:none;width:34px;height:34px;border-radius:12px;display:grid;place-items:center;
  background:#0c0c0c}
.dt-bi svg{width:16px;height:16px;color:var(--yellow)}
/* One sentence carrying both figures: what you save, and the thing you buy to
   save it. The two were a heading and a labelled table before, which made the
   denomination read as a second decision instead of the same one. */
.dt-bsay{flex:1;min-width:0;margin:0;font-family:var(--font-body);font-size:12px;font-weight:700;
  line-height:1.55;color:#1a1800}
.dt-bsay b{font-family:var(--font-title);font-size:19px;font-weight:800;letter-spacing:-.7px;
  color:#0c0c0c;white-space:nowrap}
/* the rupee figure is the smaller of the two: it is the instruction, not the
   reward, and set equal it competed with the saving */
.dt-bsay b.rup{font-size:15px;letter-spacing:-.4px}
/* The one number the buyer is actually charged, on its own line with nothing
   else in it: label left, figure right, out of the panel so it cannot be read
   as part of the saving. */
.dt-total{display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:11px;padding:11px 13px;border-radius:14px;
  background:var(--tint);border:1.5px solid var(--line)}
.dt-tl{font-family:var(--font-caption);font-size:10px;font-weight:800;letter-spacing:.5px;
  text-transform:uppercase;color:var(--muted)}
.dt-tv{font-family:var(--font-title);font-size:24px;font-weight:800;letter-spacing:-.9px;
  line-height:1.1;color:var(--ink)}
.dt-cta{
  display:flex;align-items:center;justify-content:center;gap:8px;
  margin-top:13px;padding:15px 12px;border-radius:16px;
  background:var(--yellow);color:#1a1800;
  font-family:var(--font-body);font-size:14px;font-weight:800;letter-spacing:-.2px;
  transition:translate .24s var(--ease), background .24s ease, scale .16s var(--ease);
}
.dt-cta:hover{translate:0 -2px;background:var(--yellow-deep)}
.dt-cta:active{scale:.98}
.dt-cta svg{width:14px;height:14px;flex:none}
.dt-pay{margin:14px 0 2px;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:7px;font-family:var(--font-caption);font-size:10px;line-height:1.6;color:var(--muted)}
.dt-pay .pay{background:var(--tint-2);border:1px solid var(--line);border-radius:6px;
  padding:2px 7px;font-weight:700;color:var(--ink-2)}

.dt-trust{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}
.dt-t{background:var(--card);border:1px solid var(--line);border-radius:16px;
  padding:15px 10px;text-align:center;box-shadow:var(--shadow-s)}
.dt-t .wi{margin:0 auto 10px}
.dt-t b{display:block;font-size:11px;font-weight:800;letter-spacing:-.2px;line-height:1.3}
/* :not(.wi) matters. Without it this rule also matched the icon's own span,
   and .dt-t span beats .wi on specificity — display:block replaced the grid
   that was centring the glyph, dropping it to the top of its tile. */
.dt-t span:not(.wi){display:block;margin-top:5px;font-size:9px;color:var(--muted);line-height:1.45}

/* desktop only - the phone's guide has never carried a label */
.dt-p-guide .lbl{display:none}
.dt-guide{
  display:flex;align-items:center;gap:12px;margin-top:14px;
  padding:15px;border-radius:var(--r-lg);
  background:var(--card);border:1px solid var(--line);box-shadow:var(--shadow-s);
  transition:translate .24s var(--ease), box-shadow .24s ease;
}
.dt-guide:hover{translate:0 -2px;box-shadow:var(--shadow-m)}
.dt-gico{flex:none;width:32px;height:32px;border-radius:11px;display:grid;place-items:center;
  background:#0c0c0c;color:var(--yellow)}
.dt-gico svg{width:15px;height:15px}
.dt-gtx{flex:1;min-width:0}
.dt-gtx b{display:block;font-size:11.5px;font-weight:800;letter-spacing:-.2px;line-height:1.4}
.dt-gtx span{display:block;margin-top:5px;font-size:10px;color:var(--muted);line-height:1.45}
.dt-gchev{width:12px;height:12px;color:var(--muted);flex:none}

/* ============================================================
   Dark theme corrections
   Black is the loudest surface on a white page and the quietest on a dark one.
   Everything that leaned on #0c0c0c for emphasis is re-pointed here at the
   tokens that carry emphasis in the dark: yellow, or the light CTA fill.
   Nothing in this block exists outside the dark media query, so the light
   design is exactly as it was.
   ============================================================ */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .dt-hero{
    background:linear-gradient(155deg,#232320,#191918);
    border-color:rgba(242,233,75,.18);
  }
  :root:not([data-theme="light"]) .dt-mark .row-ico{background:#fff}

  /* a black button on a dark page is a hole; the light fill is the CTA here */
  /* Alerts are a secondary ask sitting on the same page as the gift-card CTA,
     so this button stays in the yellow family without taking the primary fill:
     a soft wash with a hairline ring. The ring is an inset shadow rather than a
     border so the button does not change size between themes. */
  :root:not([data-theme="light"]) .dt-alcta{
    background:rgba(242,233,75,.14);
    box-shadow:inset 0 0 0 1px rgba(242,233,75,.45);
    color:var(--yellow);
  }
  :root:not([data-theme="light"]) .dt-alcta:hover{
    background:rgba(242,233,75,.22);
    box-shadow:inset 0 0 0 1px rgba(242,233,75,.7);
  }
  /* the welcome-bonus button is the same kind of ask on the same kind of card,
     so it takes the same wash rather than staying a black pill on a dark panel */
  :root:not([data-theme="light"]) .bonus-cta{
    background:rgba(242,233,75,.14);
    box-shadow:inset 0 0 0 1px rgba(242,233,75,.45);
    color:var(--yellow);
  }
  :root:not([data-theme="light"]) .bonus-cta:hover{
    background:rgba(242,233,75,.22);
    box-shadow:inset 0 0 0 1px rgba(242,233,75,.7);
  }
  :root:not([data-theme="light"]) .chip-b.on{
    background:var(--cta-bg);border-color:var(--cta-bg);color:var(--cta-ink);
  }
  :root:not([data-theme="light"]) .chip-b.on .ct{background:rgba(12,12,12,.14);color:#0c0c0c}

  /* cream panels, re-grounded */
  :root:not([data-theme="light"]) .dt-alert{
    background:linear-gradient(120deg,#332f12,#262309);
    border-color:rgba(242,233,75,.4);
  }
  :root:not([data-theme="light"]) .dt-altx b{color:var(--yellow)}
  :root:not([data-theme="light"]) .dt-altx span{color:var(--ink-2);opacity:.8}

  /* The saving chip stays a yellow container in both themes rather than going
     dark-olive here — it is the one figure on the row that should shout. A
     yellow container always takes black ink, whatever the theme. */
  :root:not([data-theme="light"]) .save{
    background:var(--yellow);border-color:var(--yellow-deep);
  }
  :root:not([data-theme="light"]) .save b{color:#0c0c0c}
  :root:not([data-theme="light"]) .save > i{color:#1a1800;opacity:.72}
  :root:not([data-theme="light"]) .sv b{color:var(--yellow)}

  /* the plain region box needs an edge to exist against the card */
  /* The plain box is grey on white because grey is the quiet end of a light
     page. On a dark one grey is just hard to read, so the quiet side keeps the
     light ink and lets the yellow box do the standing out. */
  /* Every one of these is scoped to :not(.on). `:root:not(...) .cmp-box` beats
     a plain `.cmp-box.on`, so without it the dark theme repainted the SELECTED
     box in the unselected colours — a yellow fill replaced by dark grey with
     near-black text still on it, which is all but unreadable. Excluding the
     chosen box here lets it fall through to the light rules, which are the
     right ones for a yellow fill in either theme. */
  :root:not([data-theme="light"]) .cmp-box:not(.on){background:var(--tint);border-color:var(--line)}
  /* .cmp-h holds a flag, so its softening goes in the colour — opacity would
     take the flag down with the label. The rows below are text alone. */
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-h{
    color:color-mix(in srgb, var(--ink-2) 90%, transparent);
  }
  /* The working is 9px, where --muted on a dark card measures 3.25:1. It takes
     the same lift the old line had, and the total keeps full ink. */
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-lbl,
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-more,
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-r i{color:var(--ink-2);opacity:.92}
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-r b{color:var(--ink)}
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-t{color:var(--ink)}
  /* the two fee colours are mixed for a dark ground rather than dropped */
  /* only the plain card goes dark - the chosen one keeps its yellow in both
     themes, so it keeps the light values too */
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-r.warn i,
  /* The blocked panel sits on the dark card, so it takes the -dk inks the
     fee rows already use there. #b81f26 on #191918 is 2.1:1 - unreadable. */
  :root:not([data-theme="light"]) .dt-bk{
    background:color-mix(in srgb,var(--fee-bad-dk) 9%,var(--card));
    border-color:color-mix(in srgb,var(--fee-bad-dk) 30%,var(--card))}
  :root:not([data-theme="light"]) .dt-bk-h{color:var(--fee-bad-dk)}
  :root:not([data-theme="light"]) .dt-bk-pill{background:var(--fee-bad-dk);color:#2a0b08}
  :root:not([data-theme="light"]) .dt-bk-ico{background:var(--fee-bad-dk);color:#2a0b08}
  :root:not([data-theme="light"]) .dt-alt-s{color:var(--fee-good-dk)}
  :root:not([data-theme="light"]) .row.not-in .row-na{
    background:color-mix(in srgb,var(--fee-bad-dk) 14%,var(--card));color:var(--fee-bad-dk)}
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-r.warn b{color:var(--fee-bad-dk)}
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-r.ok i,
  :root:not([data-theme="light"]) .cmp-box:not(.on) .cmp-r.ok b{color:var(--fee-good-dk)}
  :root:not([data-theme="light"]) .cmp-box:not(.on):hover{border-color:rgba(242,233,75,.42)}
  :root:not([data-theme="light"]) .cmp-box:focus-visible{
    border-color:var(--yellow);box-shadow:0 0 0 3px rgba(242,233,75,.5);
  }
  :root:not([data-theme="light"]) .dt-pay .pay{background:var(--tint-2);border-color:var(--line);color:var(--ink-2)}
  :root:not([data-theme="light"]) .dt-meta .tg{background:rgba(255,255,255,.08)}
  :root:not([data-theme="light"]) #lpList .row:hover{border-color:rgba(242,233,75,.4)}
  :root:not([data-theme="light"]) #lpList .row:active{
    border-color:var(--yellow);box-shadow:0 0 0 3px rgba(242,233,75,.18);
  }
  :root:not([data-theme="light"]) #lpList .row:active::before,
  :root:not([data-theme="light"]) #lpList .row:focus-visible::before{background:var(--yellow)}
  :root:not([data-theme="light"]) #lpList .row:focus-visible{
    border-color:var(--yellow);box-shadow:0 0 0 3px rgba(242,233,75,.5);
  }
}
/* ============================================================
   Scroll reveal (progressive enhancement)
   ============================================================ */
.js .reveal{opacity:0;translate:0 16px;transition:opacity .6s ease, translate .7s var(--ease)}
.js .reveal.in{opacity:1;translate:0 0}
/* the hero is above the fold — it plays its own entrance, never the reveal */
.js .hero,.js .hero.reveal{opacity:1;translate:0 0}
/* ---------- component stagger ----------
   A section arriving as one block reads as a slab; its parts arriving a beat
   apart reads as a list being laid down. backwards (not both) means the
   animation stops applying once it is over, so each card's own hover lift and
   press still work afterwards. */
.js .st{opacity:0}
.js .st.st-in{opacity:1;animation:stIn .5s var(--ease) backwards}
@keyframes stIn{from{opacity:0;translate:0 14px}to{opacity:1;translate:0 0}}
@media (prefers-reduced-motion:reduce){
  .js .st,.js .st.st-in{opacity:1;animation:none}
}
@media (prefers-reduced-motion: reduce){
  .js .reveal,.js .reveal.in{opacity:1;translate:0 0;transition:none}
  *,*::before,*::after{animation:none !important;transition-duration:.01ms !important}
  html{scroll-behavior:auto}
  .lyr{translate:none !important}
}
/* ============================================================
   Wider screens
   Everything above this line is the H5 layout and stays exactly as it was —
   the file is mobile-first, so a phone never reads a rule from here. Two steps:
   768px, where a second column starts to pay for itself, and 1080px, where the
   page can afford a real desktop measure.
   ============================================================ */

/* On a phone the item page is one flow, and these wrappers must not exist as
   far as layout is concerned. */
.dt-part{display:contents}

@media (min-width:768px){
  :root{--pad:24px}
  .shell{max-width:768px}
  .section{margin-top:34px}

  /* ---------- hero ----------
     It stops being a card with the art tucked in behind the words and becomes
     two columns, so neither has to give way to the other. Explicit placement
     rather than order, because the art comes first in the markup and belongs
     on the right. */
  .hero{
    display:grid;grid-template-columns:minmax(0,1fr) auto;
    align-items:center;column-gap:22px;
    padding:30px 28px;
  }
  .hero-copy{grid-column:1;grid-row:1;max-width:none}
  .hero .art{grid-column:2;grid-row:1;position:static;width:258px;top:auto;right:auto}
  .hero h2{font-size:34px;letter-spacing:-1.2px}
  .hero .lede{font-size:13.5px;max-width:38ch}

  /* ---------- the lists become cards, two across ----------
     One tall column of full-width rows is what a phone wants; on a wide page it
     is a stretched table. The slab drops away and each row takes its own edge,
     the same treatment the section listing already uses. */
  .list{
    display:grid;grid-template-columns:repeat(2,1fr);gap:12px;
    background:none;border:0;border-radius:0;box-shadow:none;overflow:visible;
  }
  .list .row{
    background:var(--card);border:1px solid var(--line);border-radius:18px;
    box-shadow:var(--shadow-s);
    transition:translate .2s var(--pop), border-color .16s ease, box-shadow .16s ease;
  }
  .list .row:hover{translate:0 -3px;border-color:rgba(12,12,12,.22);box-shadow:var(--shadow-m);z-index:2}
  .list .row:active{translate:0 1px}
  /* Two-up cards are narrower than a phone's full-width row, so the pack size
     that fitted on one line at 390px stops fitting. Same answer the section
     listing already gives: let it wrap. A taller card costs nothing in a grid,
     where the row levels them anyway, and an ellipsis in the middle of
     "(130 eFootball Coins)" tells the reader nothing. */
  .list .row-info em{white-space:normal;text-overflow:clip;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
  #lpList:not([hidden]){display:grid;grid-template-columns:repeat(2,1fr);gap:14px}

  .why-grid{grid-template-columns:repeat(4,1fr)}
  .why-item{padding:20px 16px}
  .why-item .wi{width:36px;height:36px}

  .promo{padding:30px 28px}
  .promo h4{font-size:21px;max-width:56%}
  .promo .lede{font-size:12px;max-width:50%}
  .promo .btn{margin-top:15px;padding:11px 17px;font-size:12.5px}
  /* Centred rather than pinned to a top offset: the art is now taller than the
     text beside it, and .promo clips its overflow, so a fixed top was shaving
     the bottom off the gift cards. */
  .promo{min-height:242px;display:flex;flex-direction:column;
         justify-content:center;align-items:flex-start}
  /* Every piece inside .promo-art is positioned from its TOP edge — the deck at
     top:0, the four chips at top:2/40/82/84 — so the box's height was never
     doing anything. 178px of box held ~124px of artwork clustered at the top,
     which is why centring the box still left the gift cards riding high.
     Sized to its content, the box can be centred and actually centre what is
     in it; scale grows the deck, the chips and the card's own type together. */
  .promo-art{width:196px;height:124px;right:16px;top:calc(50% + 6px);
             translate:0 -50%;scale:1.15;transform-origin:100% 50%}

  .quick a{padding:24px 10px 20px}
  .qi{width:42px;height:42px}
  .quick b{font-size:12.5px}

  .sec-head h3{font-size:19px}
  .sec-head p{font-size:11.5px}

  .list .row,#lpList .row{padding:15px 13px;column-gap:11px}
  .row-ico,.gico{width:44px;height:44px;border-radius:14px}
  .row-info b{font-size:14.5px}

  /* ---------- the item page gets a side column ----------
     The purchase card follows you down the page, because on a tall desktop
     window the thing you came to do should not scroll away. align-items:start
     is what makes that possible: a stretched grid item fills its row and has
     nothing left to stick inside. */
  /* :not([hidden]) is load-bearing, not decoration. An id selector outweighs
     the .view[hidden]{display:none} that hides an inactive view, so a bare
     #v-detail{display:grid} put the item page back on screen on every route —
     it was showing, empty, under the home page. Same reason #lpList is guarded:
     the script sets its hidden when a search matches nothing. */
  /* Both columns reach the same depth. The third row is 1fr so that whatever
     extra height the side column asks for lands there rather than being shared
     out across the rows above — sharing it would open a gap between the plan
     chips and "Why buy from us" instead of closing the one at the bottom.
     align-items is left at its default stretch for the same reason. */
  #v-detail:not([hidden]){
    display:grid;grid-template-columns:minmax(0,1fr) minmax(0,320px);
    /* 1 head, 2 hero, 3 the card, 4 guide and alert, 5 slack.
       The left column carries the argument in order; the right holds the
       reassurance beside it and ends on the same line. */
    grid-template-rows:auto auto auto auto 1fr;
    column-gap:26px;
  }
  /* The plan chips were an auto-fit grid of minmax(0,1fr) columns, which may be
     narrower than the text in them, and "1300 eFootball Coins" ran straight out
     of its pill in this narrower column. A fixed floor fixed that but broke the
     other way: "60 UC" was forced to wrap 2+1 when all three fitted easily.
     Flex sizes each chip to its own label and wraps only when they really do
     not fit, which is right for both. */
  #dtPlans{display:flex;flex-wrap:wrap;gap:8px}
  /* Stretched to the full column, a 10.5px label sits in the middle of a 400px
     pill with nothing near it and reads as a caption rather than a choice the
     row is asking you to make. The type grows with the pill; the phone keeps
     the size it was drawn at. */
  #dtPlans .chip-b{flex:1 1 auto;font-size:13.5px;padding:14px 10px;border-radius:15px}
  #dtPlans .chip-b .ct{font-size:11px;padding:2px 7px;margin-left:7px}

  /* The trust tiles are sized by their padding, so a wider column made them
     wider without making them taller: 115x121 on a phone, a squat 164x108 here.
     Giving the padding back the height keeps them close to the upright
     proportion they were drawn at. */
  .dt-trust{gap:11px}
  .dt-t{padding:17px 14px}
  .dt-t .wi{width:46px;height:46px;border-radius:15px;margin-bottom:14px}
  .dt-t .wi svg{width:22px;height:22px}
  .dt-guide{padding:18px}
  /* The bar is three tiles wide on a phone and three banners wide here, but
     its type never changed. One step is enough - the bar only grows from 233px
     to 413px across the whole desktop range. */
  /* 9px was drawn for a 150px card on a phone. Beside figures twice that size
     in an 830px card it reads as fine print rather than a label. */
  .cmp-lbl{font-size:9.5px;letter-spacing:.6px}
  .cmp-r i{font-size:10.5px}
  .cmp-more{font-size:10.5px}
  #v-detail > .lp-top{grid-column:1 / -1}
  .dt-part{display:block;min-width:0}
  /* Rows are placed by hand. Left to auto-placement the side column lands in
     the same row as the first left wrapper, and a grid row is as tall as its
     tallest item — so the purchase card was propping that row open and leaving
     a ~330px hole in the left column before "Why buy from us". Spanning it
     across both left rows lets the left column close up and flow normally. */
  .dt-p-item{grid-column:1;grid-row:2}
  /* The trust tiles take the slack: they are the one block here that can grow
     without looking stretched, and the difference is 13-30px. Sticky is gone
     from the side column — equal columns leave it nothing to travel through. */
  /* space-between is what pins the tiles to the foot of this row, which is the
     row the purchase card ends on — so the tiles and the card finish on the
     same line whatever slack there is above them. */
  /* space-between put the column's slack between the label and the tiles, so
     the title sat 158px off its own cards while every other label on the page
     sits 9px off. The slack goes under the tiles instead. */
  /* The card takes the wide column: it is what the page is for, and it was
     sitting in the 400px gutter while three reassurance tiles had the 830px. */
  .dt-p-buy{grid-column:1;grid-row:3}
  /* The transaction runs down the left, the reference material down the
     right. The right side is one column of its own so the guide can sit
     directly under the tiles - two grid siblings in separate rows never
     could, because the rows are sized by the left column. */
  .dt-p-side{grid-column:2;grid-row:2 / span 3;display:flex;flex-direction:column;
             justify-content:flex-start;min-width:0}
  .dt-p-guide{display:block}
  /* Stacked in a narrow column the tiles stop being cards and become rows -
     mark beside the words, not above them. Three centred blocks in a 320px
     gutter would spend 800px of column on nine words. */
  .dt-p-trust{display:flex;flex-direction:column;justify-content:flex-start}
  .dt-p-trust .dt-trust{grid-template-columns:1fr;gap:9px;max-height:none;flex:0 0 auto}
  .dt-p-trust .dt-t{
    display:grid;grid-template-columns:auto minmax(0,1fr);
    grid-template-areas:"ico title" "ico sub";
    column-gap:13px;align-items:center;align-content:center;text-align:left;
    padding:14px 15px;
  }
  .dt-p-trust .dt-t .wi{grid-area:ico;align-self:center;margin-bottom:0}
  .dt-p-trust .dt-t b{grid-area:title;align-self:end}
  .dt-p-trust .dt-t span:not(.wi){grid-area:sub;align-self:start}
  .dt-p-alert{grid-column:1;grid-row:4;align-self:start}
  .dt-p-alert{display:grid;margin-top:14px}
  .dt-p-alert > *{height:100%;margin-top:0}
  /* the bar's own 14px is for following a section; under a label it takes the
     same 9px every other label on the page gives its content */
  .dt-p-guide .dt-guide{margin-top:9px}
  .dt-p-guide .lbl{display:block}
  /* Both columns start on the same line. The bottoms were already level, but
     the card had its top margin zeroed while the hero kept 18px, so the right
     column began 18px higher — which is the mismatch you actually see. */
  .dt-p-item > :first-child,.dt-p-side > * > :first-child{margin-top:18px}
  @media (prefers-reduced-motion:reduce){.list .row{transition:none}}
}

@media (min-width:1080px){
  :root{--pad:28px}
  .shell{max-width:1200px}
  .dock{width:min(600px,100vw)}
  .section{margin-top:40px}

  .hero{padding:48px 44px;column-gap:40px}
  .hero .art{width:490px;margin-right:34px}
  /* The orbits are drawn at a fixed radius and the globe is scaled inside them,
     so shrinking the globe is what opens the gap between it and the icons
     riding the paths. The CSS transform replaces the element's own attribute,
     which is why this is desktop-only and H5 still reads 1.3 from the markup. */
  .hero .globe{transform-box:view-box;transform-origin:115px 100px;transform:scale(1.14)}
  .hero h2{font-size:46px;letter-spacing:-1.8px}
  .hero .lede{font-size:16px}

  .brand h1{font-size:24px}
  .brand p{font-size:12.5px}
  .topbar{padding:20px 0 16px}

  .list,#lpList{gap:16px}

  /* The promo is the widest card on the page and was the flattest: 944x194.
     The art and every line of type grow with the box, or it just gets emptier. */
  .promo{padding:54px 46px}
  .promo .tag{font-size:11px}
  .promo h4{margin-top:15px;font-size:31px;letter-spacing:-1.1px;max-width:54%}
  .promo .lede{margin-top:12px;font-size:14.5px;max-width:48%}
  .promo .btn{margin-top:26px;padding:16px 26px;font-size:14.5px;border-radius:15px}
  .promo .btn svg{width:16px;height:16px}
  .promo{min-height:382px}
  .promo h4{max-width:47%}
  .promo .lede{max-width:44%}
  /* A touch below centre rather than dead on it, so the deck sits on the card
     like an object on a shelf. The copy's max-width comes in to make the room. */
  /* The box's width is the gap: the deck is anchored to its left edge and the
     four logos to its right, so 336px was holding them ~170px apart and they
     read as two things. Narrowed, they read as one group. */
  .promo-art{width:220px;height:124px;right:30px;top:calc(50% + 18px);
             translate:0 -50%;scale:1.75;transform-origin:100% 50%}

  .quick a{padding:32px 14px 26px;gap:10px}
  .qi{width:48px;height:48px;border-radius:14px}
  .qi svg{width:22px;height:22px}
  .quick b{font-size:14px}
  .quick .sub{font-size:11px}

  .why-item{padding:26px 22px}
  .why-item .wi{width:42px;height:42px;border-radius:13px}
  .why-item .wi svg{width:21px;height:21px}
  .why-item b{font-size:16.5px}
  .why-item > span:last-child{font-size:11px}

  .sec-head{gap:14px;margin-bottom:14px}
  .sec-ico{width:42px;height:42px;border-radius:14px}
  .sec-head h3{font-size:22px;letter-spacing:-.6px}
  .sec-head p{font-size:12.5px}

  /* the list cards carry the same step: mark, name, prices and saving together */
  .list .row,#lpList .row{padding:19px 17px;column-gap:14px}
  .row-ico,.gico{width:52px;height:52px;border-radius:16px}
  .gico{font-size:15px}
  .row-info b{font-size:16px}
  .row-info em{font-size:11.5px}
  .price .amt{font-size:15px}
  .price .flag{width:16px;height:11px}
  .price{min-width:72px}
  .save{padding:9px 12px;border-radius:15px;min-width:76px}
  .save b{font-size:15.5px}
  .save > i{font-size:9.5px}

  .search{padding:9px 9px 9px 20px}
  .search input{font-size:15.5px}
  .search .icon{width:22px;height:22px}

  #v-detail:not([hidden]){grid-template-columns:minmax(0,1fr) minmax(0,400px);column-gap:34px}
}

/* Wide enough that a third column stops squeezing the rows: 1224px of content
   makes each card 397px, which is more room than a 390px phone gives one. */
@media (min-width:1440px){
  .shell{max-width:1320px}
  .dock{width:min(660px,100vw)}
  .list,#lpList:not([hidden]){grid-template-columns:repeat(3,1fr)}
  /* Three across leaves 411px a card, and the fixed price columns and the
     saving chip take all but 39px of it, which is not a name. The prices move
     under the name here, exactly as they do on a narrow phone, and the name
     takes one line again. */
  .list .row,#lpList .row{
    grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-areas:"ico info save" "ico prices save";
    row-gap:9px;
  }
  .list .prices,#lpList .prices{justify-content:flex-start;margin-left:0}
  .list .row-info b,#lpList .row-info b{-webkit-line-clamp:1}
  .list .row-info,#lpList .row-info{min-height:0}
  .hero{padding:54px 50px}
  .hero .art{width:540px;margin-right:44px}
  .hero .globe{transform:scale(1.10)}
  .hero h2{font-size:50px}
  .promo{min-height:400px;padding:58px 50px}
  .promo-art{scale:1.95}

  .dt-trust{gap:13px}
  /* These sized a mark to fill a wide three-across tile. In a stacked sidebar
     the tile is as tall as its two lines, so the mark is sized to the text it
     sits beside rather than to a box it has to fill. */
  .dt-p-trust .dt-t{padding:15px 16px;column-gap:14px}
  .dt-p-trust .dt-t .wi{width:46px;height:46px;border-radius:15px;margin-bottom:0}
  .dt-p-trust .dt-t .wi svg{width:22px;height:22px}
  .dt-t b{font-size:15px;letter-spacing:-.3px}
  .dt-t span:not(.wi){font-size:11px;margin-top:3px;line-height:1.45}
  .dt-guide{padding:20px}
  .dt-gico{width:36px;height:36px}
  .dt-gico svg{width:17px;height:17px}
  .dt-gtx b{font-size:12.5px}
  .dt-gtx span{font-size:10.5px}
}
