/* ===========================================================================
   Front site - direction A (clean light).
   Taken from mockups/front-a.html; the mockup stays as the visual reference.
   --brand is overwritten per site from the theme colour in Settings.
   =========================================================================== */
*,*::before,*::after{box-sizing:border-box}
/* A `display` in a rule beats the hidden attribute, and several below
   set one - so say outright that hidden means hidden. */
[hidden]{display:none!important}
:root{
  --brand:#6c4df6; --brand-2:#a06bff; --brand-soft:#f1ecff;
  --ink:#15152a; --ink-2:#43435c; --muted:#767690;
  /* The page is tinted and a surface is white. A white card on a white
     page is only its 1.5px border, which on a phone is nothing at all -
     the eye cannot find where one card ends and the next begins. */
  --bg:#f2f2f9; --surface:#ffffff; --bg-soft:#f8f8fc; --line:#eceaf4;
  --ok:#16a34a; --warn:#f59e0b; --radius:20px;
  --shadow:0 2px 4px rgba(21,21,42,.04), 0 12px 32px rgba(21,21,42,.06);
  /* The glow a brand-coloured thing casts: under a card, under a button at
     rest, and under one the pointer has lifted. Mixed from --brand like
     every other tint, because a purple shadow under a button the admin has
     just turned blue is the one place the colour they chose visibly does
     not reach. */
  --glow-soft:rgba(108,77,246,.10);
  --glow-soft:color-mix(in srgb, var(--brand) 10%, transparent);
  --glow:rgba(108,77,246,.32);
  --glow:color-mix(in srgb, var(--brand) 32%, transparent);
  --glow-lift:rgba(108,77,246,.42);
  --glow-lift:color-mix(in srgb, var(--brand) 42%, transparent);
  --shadow-lg:0 8px 24px rgba(108,77,246,.10), 0 24px 60px rgba(21,21,42,.10);
  --shadow-lg:0 8px 24px var(--glow-soft), 0 24px 60px rgba(21,21,42,.10);
  /* The hero band. Mixed from --brand so the theme colour in Settings
     re-tints it, rather than a hard-coded gradient that ignores the one
     field an admin is given. Each one declares a plain value first, so a
     browser with no color-mix() keeps a sensible colour instead of an
     invalid declaration. */
  --brand-deep:#30187a;
  --brand-deep:color-mix(in oklab, var(--brand) 60%, #0d0526);
  --brand-warm:#ff6f91;
  --brand-warm:color-mix(in oklab, var(--brand) 38%, #ff7a4b);
  --grad:linear-gradient(135deg,var(--brand),var(--brand-2));
  --grad-deep:linear-gradient(125deg,var(--brand-deep) 0%,var(--brand) 40%,
              var(--brand-2) 70%,var(--brand-warm) 100%);
}
html{-webkit-text-size-adjust:100%}
body{margin:0;font-family:'Plus Jakarta Sans',system-ui,-apple-system,Segoe UI,sans-serif;
  color:var(--ink);background:var(--bg);line-height:1.6;overflow-x:hidden}
img,svg{max-width:100%}
a{color:inherit;text-decoration:none}
h1,h2,h3,h4{margin:0;line-height:1.2;letter-spacing:-.02em}
p{margin:0}
button,input,select{font:inherit;color:inherit}
.wrap{width:100%;max-width:1200px;margin:0 auto;padding:0 20px}
.icon{width:1em;height:1em;display:inline-block;vertical-align:-.125em;fill:currentColor;flex:none}

/* ---------- scrollbars ----------
   The browser default is a wide grey slab with arrow buttons, and inside a
   rounded modal it sits right on the corner. This is the one piece of
   browser chrome a page is allowed to restyle, so it is worth doing. */
*{scrollbar-width:thin;scrollbar-color:var(--line) transparent}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--line);border-radius:999px;
  border:3px solid transparent;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:var(--muted);background-clip:padding-box;border-width:2px}
::-webkit-scrollbar-button{display:none}
::-webkit-scrollbar-corner{background:transparent}
/* Keep the modal's bar clear of its rounded corner. */
.modal{scrollbar-gutter:stable}
/* The panel is given the focus on a touch screen, so the keyboard does not
   come up with it. It is a box, not a control, so it is not drawn as one. */
.modal:focus{outline:none}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  border:0;border-radius:999px;padding:12px 22px;font-weight:700;font-size:15px;
  cursor:pointer;transition:transform .15s ease, box-shadow .15s ease, background .15s ease;white-space:nowrap}
.btn:active{transform:translateY(1px)}
.btn-primary{background:linear-gradient(135deg,var(--brand),var(--brand-2));color:#fff;
  box-shadow:0 6px 18px var(--glow)}
.btn-primary:hover{box-shadow:0 10px 26px var(--glow-lift)}
.btn-ghost{background:#fff;color:var(--ink);border:1.5px solid var(--line)}
.btn-ghost:hover{border-color:#d9d4ee;background:var(--bg-soft)}
.btn-tg{background:#229ed9;color:#fff;box-shadow:0 6px 18px rgba(34,158,217,.3)}
.btn-wa{background:#25d366;color:#fff;box-shadow:0 6px 18px rgba(37,211,102,.3)}
.btn-lg{padding:16px 30px;font-size:17px}
.btn-block{width:100%}
/* ---------- a button that is working ----------
   Placing the order now also begins the payment, so the wait between the
   press and the next screen can be a second or two. A word alone does not
   read as "busy" - a button that looks pressed but idle gets pressed again -
   so it spins, stops taking clicks, and keeps its size so the panel under it
   does not jump. */
.btn-wait{pointer-events:none;opacity:.92}
.btn-wait::before{content:"";width:1.05em;height:1.05em;flex:none;border-radius:50%;
  border:2px solid currentColor;border-top-color:transparent;animation:btnspin .6s linear infinite}
@keyframes btnspin{to{transform:rotate(1turn)}}
.btn:disabled{cursor:default}
/* A button whose whole content is its icon has no word to sit beside, so
   the gap meant for one would read as the button being off-centre. */
.btn:has(> svg:only-child){gap:0;padding-left:20px;padding-right:20px}

/* ---------- rows of channel buttons ----------
   The contact page and the home band can each offer more than one way to
   reach us, so both need a row that wraps rather than a pair of buttons
   that assume there are two. */
.chatrow{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-bottom:28px}
.bandrow{display:flex;gap:12px;flex-wrap:wrap;justify-content:center}

/* ---------- header ---------- */
header{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.88);
  backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}
/* A page that opens on the hero band gives the header to the band: no bar,
   no line, white type straight on the colour. :has() asks the question the
   layout cannot - it renders the header before it knows what the page is -
   and a browser without it simply keeps the white bar. */
body:has(.hero) > header{position:absolute;left:0;right:0;background:none;
  backdrop-filter:none;border-bottom:0}
body:has(.hero) > header .logo{color:#fff}
body:has(.hero) > header .logo-mark{background:rgba(255,255,255,.18);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.3)}
body:has(.hero) > header .nav-links a{color:rgba(255,255,255,.88)}
body:has(.hero) > header .nav-links a:hover,
body:has(.hero) > header .nav-links a.active{background:rgba(255,255,255,.16);color:#fff}
body:has(.hero) > header .chat-link{color:#fff}
body:has(.hero) > header .btn-ghost{background:rgba(255,255,255,.12);color:#fff;
  border-color:rgba(255,255,255,.45)}
body:has(.hero) > header .btn-ghost:hover{background:rgba(255,255,255,.22);border-color:#fff}
body:has(.hero) > header .burger{color:#fff;border-color:rgba(255,255,255,.45)}
/* The drawer drops out of a transparent header, so it carries its own
   surface rather than borrowing the bar's. */
body:has(.hero) > header .drawer{border-radius:0 0 18px 18px;box-shadow:var(--shadow)}
.nav{display:flex;align-items:center;gap:18px;height:72px}
.logo{display:flex;align-items:center;gap:10px;font-weight:800;font-size:20px;letter-spacing:-.03em}
.logo-mark{width:36px;height:36px;border-radius:11px;flex:none;
  background:linear-gradient(135deg,var(--brand),var(--brand-2));color:#fff;
  display:grid;place-items:center;font-size:19px;box-shadow:0 4px 12px var(--glow)}
.nav-links{display:flex;gap:4px;margin-left:12px}
.nav-links a{padding:9px 14px;border-radius:10px;font-weight:600;font-size:15px;color:var(--ink-2)}
.nav-links a:hover,.nav-links a.active{background:var(--brand-soft);color:var(--brand)}
.nav-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.chat-link{display:inline-flex;align-items:center;gap:7px;font-weight:700;font-size:14px;color:#128c7e}
.chat-link:hover{text-decoration:underline}
.burger{display:none;background:none;border:1.5px solid var(--line);border-radius:10px;padding:9px 11px;cursor:pointer}

/* ---------- hero ----------
   A coloured band with the page curving up into it. The headline sits on
   colour, the only white things on it are the ones to act on - the button
   and the platform bar riding the curve - and the picture beside it is a
   phone rather than a card, which is what the reference site does and what
   a customer recognises.

   Everything is mixed from --brand, so the band follows the theme colour
   instead of contradicting it. */
.hero{position:relative;isolation:isolate;overflow:hidden;color:#fff;
  padding:138px 0 124px;background:var(--brand);background:var(--grad-deep)}

/* Decoration, both of it: a soft disc behind the phone and one diagonal
   sheen across the band. Marked aria-hidden in the markup. */
.hero-orb{position:absolute;z-index:-1;top:50%;right:4%;width:600px;height:600px;margin-top:-300px;
  border-radius:50%;background:rgba(255,255,255,.08);box-shadow:inset 0 0 0 1px rgba(255,255,255,.14)}
.hero-ray{position:absolute;z-index:-1;top:-30%;left:40%;width:30%;height:170%;transform:rotate(16deg);
  background:linear-gradient(90deg,rgba(255,255,255,.085),rgba(255,255,255,0))}

/* The light page rising into the band: a box whose top corners are half an
   ellipse. Wider than the hero so the arc is shallow rather than a dome. */
.hero-edge{position:absolute;left:-8%;right:-8%;bottom:-1px;height:78px;background:var(--bg);
  border-radius:50% 50% 0 0 / 78px 78px 0 0}

/* minmax(0,...) rather than a bare 1fr: `1fr` is `minmax(auto,1fr)`, and
   that auto floor is the item's min-content width - a column then refuses
   to go narrower than the widest unbreakable thing inside it and the item
   spills out of the grid, where nothing can scroll to reach it. */
.hero-grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:40px;align-items:center}
.hero-copy{min-width:0}

h1{font-size:clamp(28px,4.2vw,42px);font-weight:800;margin:20px 0 16px}
/* Only the hero's. Every other h1 on the site keeps the heavy weight the
   rest of the headings are set in. */
.hero h1{font-size:clamp(31px,4.3vw,47px);font-weight:600;letter-spacing:-.032em;
  line-height:1.1;margin:0}
/* On the band the headline is white throughout and weight is what separates
   the words, not colour - a gradient fill would be invisible here. */
.hero h1 b{font-weight:800;color:#fff;background:none;-webkit-text-fill-color:#fff}

/* ---------- the four points under the headline ----------
   Two words each, on one row. White icons by default: on a band this
   saturated a mid-tone tint goes muddy rather than bright, and four
   competing colours read as decoration instead of as four points. The warm
   pair is kept because amber and yellow are the two that gain contrast
   against the band rather than losing it. */
.hero-points{list-style:none;display:flex;flex-wrap:wrap;gap:12px 22px;margin:22px 0 0;padding:0}
.hero-points li{display:flex;align-items:center;gap:9px;min-width:0}
.hero-points .icon{font-size:19px;flex:none;color:#fff}
.hero-points li:nth-child(1) .icon{color:#ffb84d}
.hero-points li:nth-child(2) .icon{color:#ffe169}
.hero-points b{display:block;font-size:14px;font-weight:800;color:#fff;line-height:1.2}
.hero-points small{display:block;font-size:11.5px;font-weight:600;color:rgba(255,255,255,.72);line-height:1.2}


/* ---------- the phone and its chips ----------
   Drawn, not photographed: it re-colours with the theme, weighs nothing and
   there is no image to ship with a release. */
.hero-art{position:relative;display:grid;place-items:center;min-height:470px}
.phone{width:300px;background:#fff;border-radius:34px;padding:22px 18px;transform:rotate(-3deg);
  box-shadow:0 30px 70px -20px rgba(10,6,30,.45), 0 0 0 1px rgba(255,255,255,.5)}
.ph-head{display:flex;align-items:center;gap:12px}
.ph-av{width:46px;height:46px;border-radius:50%;flex:none;background:var(--brand-soft);
  box-shadow:inset 0 0 0 2px var(--brand)}
.ph-say{color:var(--muted);font-size:12.5px;font-weight:600}
.ph-nums{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;margin:18px 0 12px;
  text-align:center;color:var(--muted);font-size:10.5px;font-weight:700}
.ph-follow{background:var(--grad);color:#fff;border-radius:999px;text-align:center;
  padding:11px;font-weight:800;font-size:14px}
.ph-bars{margin:16px 0 14px}
.ph-bars i{display:block;height:8px;border-radius:999px;background:var(--bg);margin-bottom:7px}
.ph-bars i:nth-child(1){width:86%}
.ph-bars i:nth-child(2){width:68%}
.ph-bars i:nth-child(3){width:77%}
.ph-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
.ph-grid i{aspect-ratio:1;border-radius:7px;background:var(--brand-soft)}

.chip{position:absolute;display:inline-flex;align-items:center;gap:10px;background:#fff;color:var(--ink);
  border-radius:15px;padding:11px 16px;box-shadow:0 14px 34px -10px rgba(10,6,30,.38);
  animation:bob 3.4s ease-in-out infinite}
.chip .icon{font-size:18px;color:var(--brand)}
.chip b{display:block;font-size:14px;font-weight:800;line-height:1.2}
.chip small{display:block;font-size:11px;font-weight:600;color:var(--muted)}
.chip-1{left:0;top:16%}
.chip-2{right:0;top:44%;animation-delay:.6s}
.chip-3{right:6%;bottom:14%;animation-delay:1.2s}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}

/* ---------- platform switcher ----------
   One floating bar sitting on the curve at the foot of the hero. It is the
   first choice on the page and the first white thing under the band, so it
   is where the eye lands coming off the headline. */
.psec{position:relative;z-index:3;margin-top:-34px;padding:0 0 6px}
.plat-bar{background:var(--surface);border:1px solid var(--line);border-radius:999px;padding:0;
  box-shadow:0 10px 30px -12px rgba(21,21,42,.3), 0 2px 6px rgba(21,21,42,.05);
  width:max-content;max-width:100%;margin:0 auto}
/* The bar's white frame lives here: a scroll container clips at its
   padding box, so the active tile's shadow needs the room inside it. */
.plat-scroll{overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;padding:6px}
.plat-scroll::-webkit-scrollbar{display:none}
.plats{display:flex;gap:4px;min-width:max-content;justify-content:center}
.plat{display:flex;align-items:center;gap:9px;background:none;border:0;
  border-radius:999px;padding:11px 24px;font-weight:700;font-size:14.5px;cursor:pointer;
  transition:background .18s ease, color .18s ease, box-shadow .18s ease;color:var(--ink-2)}
/* A platform that has a logo is only its logo: the mark is the name, and the
   card underneath says it in words anyway. One that has none keeps the text,
   because a row of identical default glyphs chooses nothing. */
.plat-icon{padding:11px;width:46px;height:46px;justify-content:center}
.plat .icon{font-size:19px}
.plat-icon .icon{font-size:23px}
/* Only where a pointer can hover: on a touch screen the state sticks to
   whatever was last tapped, and the strip is a scroll container that clips,
   so a hover that moved the tile would slice it. */
@media (hover:hover){
  .plat:hover{background:var(--bg-soft);color:var(--ink)}
}
.plat.active{color:#fff;background:var(--pc,var(--brand));
  box-shadow:0 8px 20px -6px var(--pc,var(--brand))}

/* ---------- services ---------- */
.section{padding:56px 0}
.section-head{text-align:center;max-width:680px;margin:0 auto 32px}
.eyebrow{display:inline-block;background:var(--brand-soft);color:var(--brand);font-weight:800;
  font-size:12px;letter-spacing:.09em;text-transform:uppercase;padding:6px 14px;border-radius:999px;margin-bottom:14px}
h2{font-size:clamp(25px,3.4vw,36px);font-weight:800}
.section-head p{color:var(--ink-2);margin-top:12px}
/* The one line under the services heading. A pill rather than a paragraph,
   because it is an instruction and not a description - and the link icon
   says which link it means before the sentence is read. */
/* .section-head .svc-note, not .svc-note: `.section-head p` above is one
   specificity point heavier than a bare class and was winning the colour. */
/* Small on purpose: it is a note under the heading, not a second heading.
   At this size the whole sentence still sits on one line inside a 390px
   phone, which is what keeps it reading as one instruction. */
.section-head .svc-note{display:inline-flex;align-items:center;gap:8px;margin-top:12px;
  background:var(--brand-soft);color:var(--brand);border:1px solid var(--brand-line,transparent);
  border-radius:999px;padding:8px 16px;font-size:12.5px;font-weight:800;
  text-align:center;line-height:1.3}
.section-head .svc-note .icon{font-size:1.15em;flex:none}
.tabs{display:flex;gap:6px;justify-content:center;background:var(--surface);border:1px solid var(--line);
  border-radius:999px;padding:6px;width:max-content;max-width:100%;margin:0 auto 34px;overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tab{display:inline-flex;align-items:center;gap:9px;border:0;background:none;border-radius:999px;
  padding:10px 22px;font-weight:700;font-size:14.5px;
  cursor:pointer;color:var(--ink-2);white-space:nowrap;transition:all .18s}
/* The icon says what the tab sells at a glance; the word still has to be
   there, because a picture of a heart is not the word Likes. */
.tab .icon{font-size:17px;opacity:.75}
.tab.active{background:#fff;color:var(--brand);box-shadow:var(--shadow)}
.tab.active .icon{opacity:1}
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:22px}
.card{container-type:inline-size;min-width:0;background:#fff;border:1.5px solid var(--line);border-radius:var(--radius);padding:24px;
  display:flex;flex-direction:column;position:relative;box-shadow:var(--shadow);
  transition:transform .2s, box-shadow .2s, border-color .2s}
/* The lifted border is the brand at a fifth, not a lilac that stays lilac
   whatever Settings says. */
.card:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg);border-color:#ddd6f8;
  border-color:color-mix(in srgb, var(--brand) 20%, #fff)}
.card.featured{border-color:var(--brand);box-shadow:var(--shadow-lg)}
.cbadge{position:absolute;top:-12px;left:22px;background:linear-gradient(135deg,var(--brand),var(--brand-2));
  color:#fff;font-size:11.5px;font-weight:800;padding:6px 14px;border-radius:999px;letter-spacing:.03em;
  box-shadow:0 5px 14px var(--glow)}
.card h3{font-size:19px;margin:8px 0 7px;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.cdesc{color:var(--muted);font-size:13.5px;font-weight:500;min-height:40px}
/* ---- quantity + amount (kept deliberately plain) ---- */
.qp{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;margin:20px 0 0;min-width:0}
/* Side by side only where the amount actually fits; stacked otherwise,
   because a cut-off price is worse than a tall card. A browser without
   container queries keeps the stacked default, which is never wrong. */
@container (min-width: 300px){ .qp{grid-template-columns:minmax(0,1fr) minmax(0,1fr)} }
.qp-f>span{display:block;font-size:12.5px;font-weight:700;color:var(--ink-2);margin-bottom:8px}
.qp input,.qp .price{width:100%;height:56px;border:1.5px solid var(--line);border-radius:13px;padding:0 16px;
  font-size:21px;font-weight:800;letter-spacing:-.02em;outline:none;background:var(--bg-soft);
  display:flex;align-items:center;font-family:inherit}
.qp input{-moz-appearance:textfield}
.qp input::-webkit-outer-spin-button,.qp input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.qp input:focus{border-color:var(--brand);background:#fff}
.qp .price{background:var(--brand-soft);border-color:transparent;color:var(--brand)}
.qp-note{font-size:12.5px;color:var(--muted);font-weight:600;margin-top:10px}
.qp-err{color:#dc2626;font-size:12.5px;font-weight:700;margin-top:7px;display:none}
.qp-err.show{display:block}
.qp-del{display:flex;align-items:center;gap:6px;font-size:13px;font-weight:700;color:var(--ok);margin-top:14px}
.feats{list-style:none;padding:0;margin:18px 0;display:grid;gap:9px}
.feats li{display:flex;align-items:center;gap:9px;font-size:13.5px;font-weight:600;color:var(--ink-2)}
.tick{width:19px;height:19px;border-radius:50%;background:#e8f8ee;color:var(--ok);display:grid;place-items:center;font-size:11px;flex:none}
.card .btn{margin-top:auto}
.empty{text-align:center;padding:50px 20px;color:var(--muted);font-weight:600;grid-column:1/-1}

/* ---------- preset packages ----------
   The gradient head is the card: the name and the quantity sit on it, so the
   tiers read as a row of price tags rather than a row of paragraphs. */
.card.pkg{padding:0;overflow:hidden}
.pkg-head{background:linear-gradient(135deg,var(--brand),var(--brand-2));color:#fff;padding:22px 18px;text-align:center;position:relative}
.pkg-head b{display:block;font-size:17px;font-weight:800;line-height:1.25}
.pkg-qty{display:block;font-size:31px;font-weight:800;font-style:italic;letter-spacing:-.02em;margin-top:4px}
.pkg-badge{position:absolute;top:0;right:0;background:var(--ok);color:#fff;font-size:11px;font-weight:800;
  padding:5px 11px;border-bottom-left-radius:10px;z-index:2}
.card.pkg-badged .pkg-head{padding-top:28px}
.pkg-body{padding:20px 18px 22px;display:flex;flex-direction:column;flex:1;text-align:center}
.pkg-line{display:inline-block;font-size:11.5px;font-weight:800;letter-spacing:.02em;
  color:var(--ok);background:rgba(22,163,74,.12);border-radius:999px;padding:4px 11px;
  margin-bottom:8px}
.pkg-price{font-size:27px;font-weight:800;letter-spacing:-.025em;margin:8px 0 16px}
.pkg-body .feats{text-align:left;margin:0 0 18px}
.pkg-body .qp-del{justify-content:center;margin:0 0 14px}
.pkg-body .btn{margin-top:auto}

/* ---------- the custom-quantity panel ----------
   Full width under the tiers, and never as wide as the page: a single form
   centred under a row of cards reads as the alternative to them. */
.customwrap{grid-column:1/-1;display:flex;justify-content:center;margin-top:6px}
.card.custom{width:100%;max-width:470px;text-align:left}
.card.custom h3{justify-content:flex-start}
.pickf{display:block;margin:16px 0 0}
.pickf>span{display:block;font-size:12.5px;font-weight:700;color:var(--ink-2);margin-bottom:8px}
.pickf select{width:100%;height:50px;border:1.5px solid var(--line);border-radius:14px;
  padding:0 40px 0 13px;font-size:14.5px;font-weight:700;background:var(--bg-soft);color:inherit;
  outline:none;cursor:pointer;appearance:none;font-family:inherit;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23838aa0'%3E%3Cpath d='M7 10l5 5 5-5z'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center;background-size:20px}
.pickf select:focus{border-color:var(--brand);background-color:#fff}
.qp-range{font-size:12.5px;font-weight:600;color:var(--muted);margin:8px 0 18px}

/* ---------- how it works ---------- */
.steps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:22px;counter-reset:s}
.step{background:#fff;border:1.5px solid var(--line);border-radius:var(--radius);padding:28px 24px;position:relative;box-shadow:var(--shadow)}
.step-n{width:46px;height:46px;border-radius:14px;background:linear-gradient(135deg,var(--brand),var(--brand-2));
  color:#fff;display:grid;place-items:center;font-weight:800;font-size:20px;margin-bottom:16px;
  box-shadow:0 6px 16px var(--glow)}
.step h3{font-size:18px;margin-bottom:8px}
.step p{color:var(--muted);font-size:14px;font-weight:500}

/* ---------- faq ---------- */
.faq{max-width:780px;margin:0 auto;display:grid;gap:12px}
.fitem{background:#fff;border:1.5px solid var(--line);border-radius:15px;overflow:hidden;transition:border-color .2s}
.fitem.open{border-color:var(--brand)}
.fq{width:100%;text-align:left;background:none;border:0;padding:18px 22px;font-weight:700;font-size:15.5px;
  cursor:pointer;display:flex;justify-content:space-between;align-items:center;gap:14px}
.fq i{font-style:normal;font-size:20px;color:var(--brand);transition:transform .25s;flex:none}
.fitem.open .fq i{transform:rotate(45deg)}
.fa{max-height:0;overflow:hidden;transition:max-height .3s ease}
.fa p{padding:0 22px 20px;color:var(--ink-2);font-size:14.5px}

/* ---------- cta band ---------- */
.band{background:linear-gradient(135deg,var(--brand),var(--brand-2));border-radius:28px;padding:48px 36px;
  text-align:center;color:#fff;box-shadow:var(--shadow-lg)}
.band h2{margin-bottom:12px}
.band p{opacity:.9;max-width:50ch;margin:0 auto 26px}
.band .btn-ghost{background:#fff;color:var(--brand);border-color:#fff}

/* ---------- footer ---------- */
footer{background:var(--surface);border-top:1px solid var(--line);padding:52px 0 28px;margin-top:56px}
.fgrid{display:grid;grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr));gap:36px}
.fgrid h4{font-size:13px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:16px}
.fgrid ul{list-style:none;padding:0;margin:0;display:grid;gap:11px}
.fgrid a{font-size:14.5px;font-weight:600;color:var(--ink-2)}
.fgrid a:hover{color:var(--brand)}
.fabout p{color:var(--muted);font-size:14px;margin-top:14px;max-width:34ch}
.pays{display:flex;gap:8px;margin-top:18px;flex-wrap:wrap}
.pay{background:#fff;border:1px solid var(--line);border-radius:9px;padding:7px 12px;font-size:11.5px;font-weight:800;color:var(--ink-2)}
.fbottom{border-top:1px solid var(--line);margin-top:40px;padding-top:22px;display:flex;
  justify-content:space-between;gap:16px;flex-wrap:wrap;color:var(--muted);font-size:13.5px;font-weight:600}

/* ---------- modal ---------- */
.overlay{position:fixed;inset:0;background:rgba(21,21,42,.55);backdrop-filter:blur(5px);z-index:90;
  display:none;align-items:flex-start;justify-content:center;padding:20px;overflow-y:auto}
.overlay.show{display:flex}
/* margin:auto with a flex-start overlay centres the panel while it fits and
   lets the whole of it be reached once it does not - centring alone clips
   the top beyond scrolling. */
.modal{background:var(--surface);border-radius:24px;width:100%;max-width:460px;margin:auto;
  box-shadow:0 30px 70px rgba(0,0,0,.3);
  animation:pop .25s cubic-bezier(.2,.9,.3,1.2);max-height:calc(100vh - 40px);
  max-height:calc(100dvh - 40px);overflow-y:auto}
@keyframes pop{from{opacity:0;transform:translateY(16px) scale(.97)}to{opacity:1;transform:none}}
.mhead{display:flex;align-items:flex-start;gap:14px;padding:24px 24px 0}
.mhead h3{font-size:20px}
.mhead p{color:var(--muted);font-size:13.5px;font-weight:600;margin-top:4px}
.mclose{margin-left:auto;background:var(--bg-soft);border:0;width:34px;height:34px;border-radius:50%;
  font-size:19px;cursor:pointer;color:var(--ink-2);flex:none;line-height:1}
.mclose:hover{background:#eceaf4}
.mbody{padding:22px 24px 24px}
/* ---------- the modal's pay step ----------
   It renders the order page's own panel, which is a card in its own right.
   Inside the modal that would be a box in a box, so the panel gives up its
   frame and padding and the modal's own body provides them. */
.ompay .panel{background:none;border:0;border-radius:0;padding:0;box-shadow:none}
.ompay .panel + .panel{margin-top:16px}
/* One line, reading as a sentence: how many, of what, and what it costs.
   Only the money is heavy. The name is the part the customer already chose
   and is here to be recognised, not read again - the amount is the part
   they are agreeing to, so that is what the weight points at. */
.summary{display:flex;align-items:baseline;flex-wrap:wrap;gap:0 8px;background:var(--brand-soft);
  border-radius:14px;padding:14px 16px;margin-bottom:20px;
  font-size:15.5px;font-weight:600;color:var(--ink);line-height:1.4}
.summary .sep{font-weight:800}
/* Two lines at most. The card the customer just pressed is still behind
   this box and carries the whole name; letting it wrap to four lines here
   pushes the button that places the order off a phone screen. */
.summary b{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;font-weight:600}
.summary .amt{font-weight:800;white-space:nowrap}
/* The tracked order's block. It was sharing .summary with the order modal
   until that became a single line - but this one is showing a status and a
   delivered count beside the name, which is two lines by nature. */
.osum{display:flex;align-items:center;gap:13px;background:var(--brand-soft);
  border-radius:15px;padding:15px}
.osum .si{width:44px;height:44px;border-radius:12px;background:#fff;display:grid;
  place-items:center;font-size:21px;flex:none;color:var(--brand)}
.osum b{display:block;font-size:15px;line-height:1.35}
.osum small{color:var(--muted);font-size:12.5px;font-weight:700}
.field{margin-bottom:16px}
.field label{display:block;font-size:13px;font-weight:700;margin-bottom:7px}
.field input{width:100%;border:1.5px solid var(--line);border-radius:13px;padding:13px 15px;font-size:15px;
  font-weight:600;outline:none;transition:border-color .15s;background:var(--bg-soft)}
.field input:focus{border-color:var(--brand);background:#fff}
/* A placeholder is an example, not an answer. Held well back from the
   value so the box never reads as already filled in. */
.field input::placeholder,.field textarea::placeholder{color:var(--muted);opacity:.45}
/* The lock beside "not private" - the hint's own size, so it sits on
   the line rather than on top of it. */
.hint .icon{font-size:1.05em;vertical-align:-.15em;margin-left:3px}
.field small{display:block;color:var(--muted);font-size:12px;font-weight:600;margin-top:6px}
.field label .opt-tag{font-weight:600;color:var(--muted);font-size:11px;text-transform:uppercase;letter-spacing:.06em;margin-left:5px}
/* A line under the button, not a panel above it. It settles a worry at
   the moment of pressing; as a green box in the flow it was one more
   thing to read on the way to the button. */
.safe-note{display:block;text-align:center;margin:12px 0 0;
  font-size:11.5px;font-weight:600;color:var(--muted);line-height:1.45}

/* ---------- modal: fit the screen it opens on ----------
   A customer who has to scroll to find the button has not found the button.
   The panel is drawn tighter as the viewport gets shorter rather than being
   clipped, and dvh is used because a phone's 100vh counts the URL bar that
   is covering the bottom of the page. */
@media (max-width: 440px){
  /* One size for the whole line, so the quantity, the name and the price
     stay a single sentence rather than three sizes sitting together. */
  .summary{font-size:14.5px;padding:12px 14px}
}
@media (max-height: 780px){
  .overlay{padding:12px}
  .mhead{padding:16px 18px 0}
  .mhead h3{font-size:18px}
  .mhead p{display:none}
  .mclose{width:30px;height:30px;font-size:17px}
  .mbody{padding:14px 18px 18px}
  .summary{padding:11px 12px;margin-bottom:12px}
  .field{margin-bottom:9px}
  .field label{margin-bottom:5px}
  .field input{padding:11px 14px}
  .field small{margin-top:3px;font-size:11.5px}
  .safe-note{margin-top:10px;font-size:11px}
  .form-err{padding:10px 13px;margin-bottom:12px}
  .btn-lg{padding:13px 24px;font-size:16px}
  .om-done{padding:0}
  .om-done-head{margin-bottom:12px}
  .om-done-rows>div{padding:10px 13px}
  .om-done-note{margin-bottom:11px}
}
@media (max-height: 660px){
  /* The reassurance line stays. It used to be a padded green panel above
     the button, and on a short screen that panel was the difference between
     reaching the button and not - so it was the first thing dropped. As one
     small line under the button it costs about sixteen pixels and takes
     nothing from the button, so there is no longer a reason to hide it. */
  .mhead{padding:13px 16px 0}
  .mbody{padding:12px 16px 16px}
  .summary{margin-bottom:10px}
  .field{margin-bottom:8px}
}

/* The hints go only where the room is genuinely not there: a phone. They
   help, but not as much as a button the thumb can reach. A desktop window
   that happens to be under 660px tall is not that case - it has a mouse, a
   scrollbar and the width to say "make sure your account is public" on one
   line - and hiding it there dropped the one line that stops an order being
   placed against a private account. An error still appears whatever the
   size, because .err is a different element from .hint. */
@media (max-height: 660px) and (max-width: 560px){
  .mbody .field .hint{display:none}
}

/* ---------- the floating chat bubbles ----------
   A stack, because Settings may put more than one channel here. The column
   is what is pinned to the corner; each bubble is ordinary flow inside it,
   so adding a second one cannot land on top of the first. */
.fabs{position:fixed;right:20px;bottom:20px;z-index:60;display:grid;gap:10px;justify-items:end}
/* A circle, at every width. The bubble is an icon and nothing else: a word
   beside it is a word the customer has to read before they can press the
   thing they were already going to press, and the stack has to stay a stack
   of equal shapes once there is more than one channel in it. */
.fab{position:relative;display:grid;place-items:center;width:54px;height:54px;
  background:#25d366;color:#fff;border:0;border-radius:50%;
  cursor:pointer;box-shadow:0 10px 30px rgba(37,211,102,.45)}
.fab:hover{transform:translateY(-2px)}
.fab .icon{font-size:22px}
.fab::after{content:"";position:absolute;inset:0;border-radius:50%;border:2px solid #25d366;
  animation:ring 2s ease-out infinite}
/* Only the first bubble rings. Two things pulsing at the corner of every
   page is not twice the invitation, it is a fairground. */
.fab:not(:first-child)::after{display:none}
.fab-telegram{background:#229ed9;box-shadow:0 10px 30px rgba(34,158,217,.45)}
.fab-telegram::after{border-color:#229ed9}
.fab-email{background:var(--brand);box-shadow:var(--shadow-lg)}
.fab-email::after{border-color:var(--brand)}
@keyframes ring{0%{transform:scale(1);opacity:.7}100%{transform:scale(1.35);opacity:0}}

/* ---------- responsive ---------- */
@media (max-width:1000px){
  /* One column, centred: the copy reads as a block rather than a column
     with a hole beside it. */
  .hero{padding:124px 0 104px}
  .hero-grid{grid-template-columns:minmax(0,1fr);gap:34px;text-align:center}
  .hero-points{justify-content:center;gap:12px 18px}
  /* The art moves under the copy, so it gets a width of its own and the
     chips hang off that rather than off the far edges of the page. The
     disc is centred on the hero, which once the art is below the copy
     means a ring behind the headline - so it goes. */
  .hero-art{min-height:430px;max-width:560px;margin:0 auto;width:100%}
  .hero-orb{display:none}
  .chip-1{left:0}
  .chip-3{right:0;bottom:16%}
  .steps{grid-template-columns:minmax(0,1fr)}
  .fgrid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:28px}
}
@media (max-width:760px){
  .nav-links,.nav-right .chat-link{display:none}
  .burger{display:block}
  /* All four stay on one row, and the icon moves above its words to buy
     the room for it. Beside them, each item needs its icon plus its widest
     word on one line, which four of does not fit a 360px screen - the row
     either reflowed into a ragged three-and-one or shrank the type past
     reading. Stacked, an item is only as wide as its text, so the four fit
     with the words intact. */
  .hero-points{flex-wrap:nowrap;justify-content:space-between;gap:0 8px;
    max-width:420px;margin:20px auto 0}
  .hero-points li{flex:1 1 0;min-width:0;flex-direction:column;align-items:center;
    gap:5px;text-align:center}
  .hero-points .icon{font-size:17px}
  .hero-points b{font-size:11.5px}
  .hero-points small{font-size:10px;line-height:1.25}
  /* Track Order stays in the bar: it is where someone who has already
     paid is heading, and a burger hides it behind a guess. */
  .nav-right{margin-left:auto;gap:8px}
  .nav-right .btn-ghost{padding:9px 14px;font-size:13.5px}
  .nav-right .btn-ghost .icon{display:none}
  /* The phone is decoration, and on a phone screen it is a whole
     screenful of it between the headline and the thing to tap. */
  .hero-art{display:none}
  /* The disc is only there to sit behind the phone. With the phone gone it
     is a ring across the headline. */
  .hero-orb{display:none}
  .nav{height:64px}
  .hero{padding:96px 0 86px}
  .hero-edge{height:54px;border-radius:50% 50% 0 0 / 54px 54px 0 0}
  .hero h1{line-height:1.14}
  .plats{justify-content:flex-start}
  .plat{padding:11px 18px}
  .plat-icon{padding:10px;width:42px;height:42px}
  .psec{margin-top:-26px}
  .section{padding:40px 0}
  /* Three tabs with an icon each stopped fitting a 320px bar, and a bar
     that scrolls leaves the chosen one half under its own rounded edge -
     which is what it did. Full width, tighter, and the tabs share the row
     between them; past four of them it scrolls, and the script keeps the
     chosen one in the middle of what can be seen. */
  .tabs{width:100%;max-width:100%;padding:5px;gap:4px;justify-content:flex-start;
    scroll-padding-inline:5px}
  /* Grow to share the row, never shrink: a shrinking tab goes under its own
     min-content width and the label ends up printed over the icon. Past what
     fits, the strip scrolls instead. */
  .tab{flex:1 0 auto;justify-content:center;padding:9px 10px;font-size:13px;gap:6px}
  .tab .icon{font-size:15px}
  .cards{grid-template-columns:minmax(0,1fr)}
  .band{padding:34px 22px;border-radius:22px}
  .fgrid{grid-template-columns:minmax(0,1fr)}
}
/* mobile drawer */
.drawer{display:none;border-top:1px solid var(--line);background:#fff;padding:12px 20px 18px}
.drawer.show{display:block}
/* :not(.btn) because .drawer a outranks .btn and would otherwise turn any
   button dropped in here into a left-aligned block with no side padding. */
.drawer a:not(.btn){display:block;padding:12px 0;font-weight:700;border-bottom:1px solid var(--line)}
.drawer a:not(.btn):last-child{border-bottom:0}
.drawer .btn{margin-top:14px}

/* ---- order / tracking page ---- */
:root{ --page:var(--bg-soft); --acc:var(--brand); --acc-on:#fff; }
/* ============ order page additions (uses the direction's own tokens) ============ */
body{padding-bottom:40px}
.opage{padding:30px 0 10px}
.obar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:22px}
.ocode{font-size:clamp(21px,3vw,28px);font-weight:800;letter-spacing:-.02em}
.ocode small{display:block;font-size:12px;font-weight:700;color:var(--muted);letter-spacing:.12em;
  text-transform:uppercase;margin-bottom:4px;letter-spacing:.1em}
.sbadge{display:inline-flex;align-items:center;gap:8px;border-radius:999px;padding:8px 16px;font-size:13px;font-weight:800}
.sbadge .d{width:8px;height:8px;border-radius:50%;background:currentColor}
.sb-pending{background:rgba(245,158,11,.14);color:#b45309}
.sb-paid{background:rgba(37,99,235,.14);color:#1d4ed8}
.sb-processing{background:rgba(168,116,58,.16);color:#8a5d2a}
.sb-completed{background:rgba(22,163,74,.15);color:#15803d}
.ogrid{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,.9fr);gap:22px;align-items:start}
.panel{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:24px}
.panel + .panel{margin-top:18px}
.ptitle{font-size:17px;font-weight:800;margin-bottom:4px;display:flex;align-items:center;gap:9px}
.ptitle .icon{color:var(--acc)}
.psubtitle{color:var(--muted);font-size:13.5px;font-weight:600;margin-bottom:18px}

/* summary rows */
.orow{display:flex;justify-content:space-between;gap:16px;padding:13px 0;border-bottom:1px solid var(--line);
  font-size:14.5px;font-weight:600}
.orow:last-of-type{border-bottom:0}
.orow span{color:var(--muted);font-weight:700}
.orow b{text-align:right;word-break:break-all;font-weight:800}
.ototal{display:flex;justify-content:space-between;align-items:center;gap:14px;background:var(--acc);
  color:var(--acc-on);border-radius:14px;padding:17px 20px;margin-top:16px;font-weight:800}
.ototal .big{font-size:26px;letter-spacing:-.02em}

/* timeline */
.tl{list-style:none;padding:0;margin:4px 0 0}
.tl li{display:flex;gap:15px;padding-bottom:22px;position:relative}
.tl li:last-child{padding-bottom:0}
.tl li::before{content:"";position:absolute;left:13px;top:28px;bottom:2px;width:2px;background:var(--line)}
.tl li:last-child::before{display:none}
.tl li.done::before{background:var(--acc)}
.tl .dot{width:28px;height:28px;border-radius:50%;border:2px solid var(--line);flex:none;display:grid;
  place-items:center;font-size:12px;color:var(--muted);background:var(--surface);z-index:1}
.tl li.done .dot{background:var(--acc);border-color:var(--acc);color:var(--acc-on)}
.tl li.now .dot{border-color:var(--acc);color:var(--acc)}
.tl b{display:block;font-size:14.5px;font-weight:800}
.tl small{color:var(--muted);font-size:12.5px;font-weight:600}
.counts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;margin-top:20px}
.count{background:var(--page);border:1px solid var(--line);border-radius:13px;padding:13px;text-align:center}
.count b{display:block;font-size:19px;font-weight:800}
.count small{color:var(--muted);font-size:11.5px;font-weight:700}
.progress{height:9px;border-radius:999px;background:var(--line);overflow:hidden;margin-top:16px}
.progress i{display:block;height:100%;border-radius:999px;background:var(--acc);width:64%;transition:width .4s}

/* payment methods */
/* ---------- choosing how to pay ----------
   Logos and names, two across where they fit. A customer is looking for the
   app they recognise, so the logo leads and nothing else competes with it -
   what a method needs is shown once it is chosen, not all at once. */
/* How many fit on a line is decided by the names, not by a column count:
   equal columns cut "Raast QR" down to "Raast..." while a shorter name sat
   in the same width with room to spare. Each tile is as wide as its own
   name needs, they share out what is left over, and whatever does not fit
   goes to the next line. */
.paypick{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:16px}
.payopt{flex:1 1 auto;display:flex;align-items:center;gap:10px;cursor:pointer;min-width:0;
  max-width:100%;border:2px solid var(--line);border-radius:14px;padding:12px 13px;
  background:var(--surface);transition:border-color .15s,background .15s}
.payopt input{position:absolute;opacity:0;width:0;height:0}
.payopt:has(input:checked),.payopt.on{border-color:var(--acc);background:var(--page)}
.paylogo{width:38px;height:38px;border-radius:10px;flex:none;display:grid;place-items:center;
  background:var(--acc);color:var(--acc-on);font-size:12.5px;font-weight:800;overflow:hidden}
.paylogo img{width:100%;height:100%;object-fit:contain;background:#fff}
.payname{font-size:14px;font-weight:700;min-width:0;line-height:1.3;
  overflow-wrap:anywhere}

/* What the chosen method needs. Hidden only once the script runs, so without
   it every panel is open and the server still reads only the chosen one. */
.paystep{display:none}
.paystep.on{display:block}
/* The questions a manual method asks. They sit under the account details
   inside the method's own block, so they need the gap that tells them apart
   from it - and the last field must not add one before the button. */
.pf-ask{margin-top:14px}
.pf-ask .field:last-child{margin-bottom:0}
.acct{display:flex;align-items:center;gap:12px;background:var(--page);border-radius:12px;padding:13px 15px;margin-bottom:9px}
.acct div{flex:1;min-width:0}
.acct small{display:block;color:var(--muted);font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.acct b{font-size:15.5px;font-weight:800;word-break:break-all}
.copy{background:var(--acc);color:var(--acc-on);border:0;border-radius:9px;padding:9px 13px;font-size:12.5px;
  font-weight:800;cursor:pointer;flex:none}
.copy:active{transform:scale(.96)}
.note{display:flex;gap:10px;background:var(--page);border-radius:12px;padding:13px 15px;font-size:13px;
  font-weight:600;color:var(--ink-2);margin-top:12px}
.note .icon{color:var(--acc);font-size:17px;flex:none}
.err{color:#dc2626;font-size:13px;font-weight:800;margin-top:9px;display:none}
.err.show{display:block}
.okmsg{display:none;gap:11px;background:rgba(22,163,74,.12);color:#15803d;border-radius:13px;padding:15px 17px;
  font-size:13.5px;font-weight:800;margin-top:14px}
.okmsg.show{display:flex}
.okmsg .icon{font-size:18px;flex:none}
.stack{display:grid;gap:10px;margin-top:16px}
.help{text-align:center;font-size:13px;font-weight:600;color:var(--muted);margin-top:16px}
.help a{color:var(--acc);font-weight:800}

/* ---------- paying by QR ----------
   One column, because the whole page is the code and the amount: a phone is
   held up to the screen, or the link under it is tapped, and there is nothing
   else to be done while that happens. */
.qrpay{max-width:520px;margin:0 auto}
.qrwait{display:flex;align-items:center;gap:9px;background:var(--page);border-radius:999px;
  padding:9px 16px;font-size:13px;font-weight:800;color:var(--ink-2);margin-bottom:18px}
.qrwait .d{width:8px;height:8px;border-radius:50%;background:var(--acc);flex:none;
  animation:qrpulse 1.4s ease-in-out infinite}
@keyframes qrpulse{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.6);opacity:.45}}
/* Once there is an answer the dot has nothing left to say, so it stops. */
.qrwait-ok{background:rgba(22,163,74,.12);color:#15803d}
.qrwait-ok .d{background:#16a34a;animation:none}
.qrwait-bad{background:#fdeaea;color:#b91c1c}
.qrwait-bad .d{background:#dc2626;animation:none}
.qrwait-idle .d{background:var(--muted);animation:none}
.qrbox{display:grid;place-items:center;background:#fff;border:1px solid var(--line);
  border-radius:16px;padding:14px;box-shadow:var(--shadow)}
/* A QR scaled past legibility is not a QR, so it keeps the size it was drawn
   at and only gives way on a screen narrower than itself. */
.qr{display:block;width:230px;height:auto;max-width:100%}
.qramt{display:flex;align-items:center;justify-content:space-between;gap:14px;background:var(--acc);
  color:var(--acc-on);border-radius:14px;padding:14px 18px;margin:16px 0 12px}
.qramt small{font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;opacity:.85}
.qramt b{font-size:24px;font-weight:800;letter-spacing:-.02em}
.qrcap{text-align:center;font-size:13px;font-weight:600;color:var(--muted);margin:0 0 14px}

@media (max-width:900px){
  .ogrid{grid-template-columns:minmax(0,1fr)}
  /* One column puts the right-hand column last, which on a phone
     buried "how do I pay" under the summary and the whole delivery
     timeline. An order that is waiting to be paid leads with the
     paying; everything else about it is already known. */
  .ogrid-pay > div:last-child{order:-1}
}
@media (max-width:760px){
  .opage{padding:20px 0 6px}
  .panel{padding:20px 17px}
  .counts{grid-template-columns:minmax(0,1fr);gap:8px}
  .count{display:flex;align-items:baseline;gap:9px;text-align:left}
  .ototal{flex-direction:column;align-items:flex-start;gap:4px}
}

/* ===========================================================================
   Additions beyond the mockup: flash messages, inline form errors, the
   tracking page and the empty states a real site needs.
   =========================================================================== */

.alert{border-radius:14px;padding:14px 18px;font-size:14.5px;font-weight:600;margin-bottom:18px;
  border:1px solid transparent}
.alert a{text-decoration:underline;font-weight:700}
.alert-success{background:#e8f8ee;border-color:#bfe9cf;color:#146c3a}
.alert-error{background:#fdeaea;border-color:#f6caca;color:#b91c1c}
.alert-warning{background:#fff7e6;border-color:#f6e2b8;color:#8a5d2a}
.alert-info{background:var(--brand-soft);border-color:#ddd4fb;color:#4a32c0}

.field .err{display:block;color:#dc2626;font-size:12.5px;font-weight:700;margin-top:6px}
.field input[aria-invalid="true"]{border-color:#dc2626}
.form-err{display:none;background:#fdeaea;border:1px solid #f6caca;color:#b91c1c;border-radius:13px;
  padding:12px 15px;font-size:13.5px;font-weight:700;margin-bottom:16px}
.form-err.show{display:block}

/* honeypot: a real person never sees this, a bot fills it in */
.hp{position:absolute!important;left:-9999px!important;width:1px;height:1px;overflow:hidden}

.page-head{padding:60px 0 10px;text-align:center}
.page-head h1{font-size:clamp(28px,4.4vw,42px);margin-bottom:12px}
.page-head p{color:var(--ink-2);max-width:58ch;margin:0 auto}
.prose{max-width:72ch;margin:0 auto;color:var(--ink-2);font-size:16px}
.prose h2{font-size:24px;margin:28px 0 12px;color:var(--ink)}
.prose h3{font-size:19px;margin:22px 0 10px;color:var(--ink)}
.prose p{margin:0 0 1em}
.prose ul,.prose ol{margin:0 0 1em;padding-left:22px}
.prose li{margin-bottom:6px}
.prose a{color:var(--brand);font-weight:600}

/* tracking */
.track-wrap{max-width:560px;margin:0 auto}
.track-card{background:#fff;border:1px solid var(--line);border-radius:var(--radius);padding:28px;
  box-shadow:var(--shadow)}
.track-form{display:flex;gap:10px;flex-wrap:wrap}
.track-form input{flex:1;min-width:180px;border:1.5px solid var(--line);border-radius:13px;
  padding:14px 16px;font-size:16px;font-weight:700;outline:none;background:var(--bg-soft);
  text-transform:uppercase;letter-spacing:.06em}
.track-form input:focus{border-color:var(--brand);background:#fff}

.empty-state{text-align:center;padding:56px 24px;background:var(--surface);border:1px dashed var(--line);
  border-radius:var(--radius);color:var(--muted);font-weight:600;grid-column:1/-1}
.empty-state b{display:block;color:var(--ink);font-size:17px;margin-bottom:6px}

/* the platform strip and tabs are real links, so they need link resets */
.plat,.tab{text-decoration:none}
a.plat,a.tab{display:inline-flex}
a.tab{align-items:center}

/* The payment panel follows the checked radio even before the script runs,
   so the details are reachable with JavaScript blocked. */

/* ===========================================================================
   Skeleton shown while a platform or category is being fetched. The cards are
   replaced in place, so the page never jumps.
   =========================================================================== */
.cards.is-loading{opacity:.9}
.card-skeleton{pointer-events:none;border-color:var(--line)}
.sk{display:block;border-radius:8px;background:linear-gradient(90deg,
    var(--bg-soft) 25%, #eceaf4 37%, var(--bg-soft) 63%);
  background-size:400% 100%;animation:sk 1.3s ease-in-out infinite}
@keyframes sk{0%{background-position:100% 50%}100%{background-position:0 50%}}
.sk-badge{width:84px;height:18px;border-radius:999px;margin-bottom:14px}
.sk-title{width:78%;height:22px;margin-bottom:12px}
.sk-line{width:100%;height:12px;margin-bottom:8px}
.sk-line.short{width:62%}
.sk-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;margin:20px 0 14px}
.sk-box{height:56px;border-radius:13px}
.sk-button{width:100%;height:52px;border-radius:999px;margin-top:18px}

@media (prefers-reduced-motion: reduce){
  .sk,.chip,.fab::after,.btn-wait::before{animation:none}
}

/* --- the order, once it exists --------------------------------------------
   The customer reads their code and amount here before anything navigates. */
.om-tick{width:34px;height:34px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:#e8f8ee;color:var(--ok);font-size:17px}
/* The order code is the one string a customer has to read back or type,
   so it gets a face where 0 and O are not the same shape. */

/* --- the order code, and saying the order happened ------------------------ */
/* The moment after a manual payment is sent. Green, because the customer
   has finished their part and the next move is ours. */
.othanks{display:flex;align-items:flex-start;gap:13px;background:#e8f8ee;border-radius:14px;
  padding:14px 16px;margin-bottom:16px}
.othanks b{display:block;font-size:15.5px;font-weight:800;color:#146c3a;line-height:1.3}
.othanks small{display:block;color:#1a7a44;font-size:13px;font-weight:600;margin-top:3px}
.othanks .om-tick{margin-top:1px}
.oplaced{display:flex;align-items:center;gap:13px;background:#e8f8ee;border-radius:14px;
  padding:14px 17px;margin-bottom:18px}
.oplaced b{display:block;font-size:15.5px;font-weight:800;color:#146c3a}
.oplaced small{color:#1a7a44;font-size:13px;font-weight:600}
.ocode-row{display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap}
.ocode-copy{background:var(--brand-soft);color:var(--brand);border:0;border-radius:999px;
  padding:5px 13px;font-size:12px;font-weight:800;cursor:pointer;letter-spacing:.02em}
.ocode-copy:hover{background:var(--brand);color:#fff}

/* ============ TRACK ORDER MODAL ============ */
.tk-modal-box {
  max-width: 430px !important;
  width: 92% !important;
  border-radius: 20px !important;
  background: #ffffff !important;
  box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
  padding: 22px 22px 20px !important;
  box-sizing: border-box;
}

.tk-mhead {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding-bottom: 12px !important;
  border-bottom: none !important;
  margin-bottom: 0 !important;
}

.tk-title {
  margin: 0 !important;
  font-size: 20px !important;
  font-weight: 700 !important;
  color: #1e1b4b !important;
  letter-spacing: -0.01em;
}

.tk-mclose {
  background: transparent !important;
  border: none !important;
  font-size: 26px !important;
  color: var(--brand, #3b82f6) !important;
  line-height: 1 !important;
  padding: 0 4px !important;
  cursor: pointer !important;
  transition: opacity 0.15s ease;
}
.tk-mclose:hover {
  opacity: 0.7;
}

.tk-mbody {
  padding: 0 !important;
}

.tk-search-row {
  display: flex !important;
  gap: 10px !important;
  align-items: stretch !important;
  margin-top: 6px !important;
  margin-bottom: 6px !important;
}

.tk-input {
  flex: 1 1 auto !important;
  min-width: 0 !important;
  height: 48px !important;
  background: #ffffff !important;
  border: 1.5px solid #e2e8f0 !important;
  border-radius: 12px !important;
  padding: 0 14px !important;
  font-size: 15px !important;
  color: #0f172a !important;
  font-weight: 500 !important;
  transition: all 0.2s ease !important;
  box-sizing: border-box !important;
}
.tk-input:focus {
  border-color: var(--brand, #6366f1) !important;
  outline: none !important;
  box-shadow: 0 0 0 3px var(--glow-soft, rgba(99, 102, 241, 0.15)) !important;
}
.tk-input::placeholder {
  color: #94a3b8 !important;
}

.tk-submit-btn {
  flex: 0 0 auto !important;
  height: 48px !important;
  padding: 0 18px !important;
  background: var(--grad, var(--brand, #6366f1)) !important;
  color: #ffffff !important;
  font-size: 14.5px !important;
  font-weight: 700 !important;
  border: none !important;
  border-radius: 12px !important;
  cursor: pointer !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  box-shadow: 0 2px 8px var(--glow, rgba(0, 0, 0, 0.12)) !important;
  transition: all 0.2s ease !important;
  white-space: nowrap !important;
}
.tk-submit-btn:hover {
  filter: brightness(0.92) !important;
  transform: translateY(-1px);
}
.tk-submit-btn:active {
  transform: translateY(0);
}
.tk-submit-btn:disabled {
  opacity: 0.75;
  cursor: not-allowed;
  transform: none;
}

.tk-loader {
  display: none !important;
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.35);
  border-top-color: #ffffff;
  border-radius: 50%;
  animation: tkSpin 0.7s linear infinite;
  vertical-align: middle;
}
.tk-submit-btn.loading .tk-loader,
.tk-loader.show {
  display: inline-block !important;
}

@keyframes tkSpin {
  to { transform: rotate(360deg); }
}

.tk-alert-error {
  margin-top: 14px;
  padding: 10px 14px;
  background: #fef2f2;
  border: 1px solid #fecaca;
  color: #b91c1c;
  border-radius: 10px;
  font-size: 13.5px;
  font-weight: 500;
  text-align: center;
}

.tk-card {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid #f1f5f9;
}

.tk-card-header {
  font-size: 15px;
  font-weight: 700;
  color: #0f172a;
  margin-bottom: 6px;
}

.tk-detail-row {
  display: flex !important;
  align-items: center !important;
  justify-content: space-between !important;
  padding: 10px 0 !important;
  border-bottom: 1px solid #f1f5f9 !important;
  font-size: 14px !important;
}
.tk-detail-row:last-child {
  border-bottom: none !important;
}

.tk-label {
  color: #475569 !important;
  font-weight: 500 !important;
}

.tk-value {
  color: #0f172a !important;
  font-weight: 600 !important;
  text-align: right !important;
}

.tk-bold {
  font-weight: 700 !important;
}

.tk-val-status {
  font-weight: 700 !important;
  letter-spacing: 0.02em !important;
  color: #dc2626 !important;
}
.tk-val-status.is-completed {
  color: #dc2626 !important;
}
.tk-val-status.is-processing,
.tk-val-status.is-paid {
  color: #2563eb !important;
}
.tk-val-status.is-pending {
  color: #d97706 !important;
}

.tk-val-payment {
  color: #16a34a !important;
  font-weight: 700 !important;
}
.tk-val-payment.is-pending {
  color: #d97706 !important;
}

