/*!
 * dokanseba.com — stylesheet
 * Author : MD Noyon Ali
 * Updated: 2026-08-13
 *
 * Token gulo :root e. Dark ta default, light ta html[data-theme="light"].
 * Notun color add korle DUI jaygay e add korte hobe, na hole ek theme e bhange.
 * Responsive: 1080 / 768 / 480 — file er sesh e ek jaygay.
 */

  /* ============ DARK (default, posboi-style) ============ */
  :root{
    --gold:#6FCBA4;
    --gold-2:#0F9D6A;
    --gold-ink:#043724;
    --gold-soft:rgba(22,168,111,.14);
    --gold-line:rgba(22,168,111,.26);
    --pink:#F87171;
    --ok:#6FCBA4;
    --neg:#F87171;
    --grad:linear-gradient(90deg,#6FCBA4 0%,#34B483 45%,#16A86F 100%);
    --btn-grad:linear-gradient(135deg,#6FCBA4,#34B483);
    --ink:#FFFFFF;
    --body:#96A29A;
    --muted:#838F87;
    --bg:#111512;
    --bg-alt:#151A16;
    --card:#181D19;
    --card-2:#1E251F;
    --line:#28302A;
    --header-bg:rgba(17,21,18,.88);
    --footer-bg:#0B0F0C;
    --cream:#E5F5EE;
    --hero-top:#0E1712;
    --radius:16px;
    --shadow-md:0 10px 34px rgba(0,0,0,.45);
    --shadow-lg:0 24px 70px rgba(0,0,0,.55);
    --glow:0 6px 26px rgba(15,157,106,.34);
    --max:1390px;
  }
  /* ============ LIGHT ============ */
  html[data-theme="light"]{
    --gold:#0A6F4B;
    --gold-2:#08573B;
    --gold-ink:#FFFFFF;
    --btn-grad:linear-gradient(135deg,#0A6F4B,#08573B);
    --gold-soft:rgba(15,157,106,.10);
    --gold-line:rgba(15,157,106,.28);
    --pink:#DC2626;
    --ok:#0A6F4B;
    --neg:#DC2626;
    --grad:linear-gradient(90deg,#0F9D6A 0%,#0C8A5D 45%,#0A6F4B 100%);
    --ink:#121713;
    --body:#525D55;
    --muted:#5F6B65;
    --bg:#F0F2F0;
    --bg-alt:#E7EBE8;
    --card:#FFFFFF;
    --card-2:#FAFCFB;
    --line:#E5E8E5;
    --header-bg:rgba(240,242,240,.86);
    --footer-bg:#111512;
    --hero-top:#E5F5EE;
    --shadow-md:0 8px 30px rgba(10,40,28,.08);
    --shadow-lg:0 24px 60px rgba(10,40,28,.12);
    --glow:0 6px 22px rgba(15,157,106,.28);
  }


/* ============================================================================
   FONTS — self-hosted, was fonts.googleapis.com
   ============================================================================

   Ager ta chilo <link href="fonts.googleapis.com/css2?..."> head er moddhe.
   Sheta 3-ta alada khoroch chilo, tinta e render block kore:

     1. fonts.googleapis.com — notun DNS + TCP + TLS handshake, tarpor 16 KB
        CSS. Ei CSS ta render-blocking, mane eta na ashle kono text e ase na.
     2. sei CSS er bhitor theke fonts.gstatic.com — ARO ekta DNS + TCP + TLS,
        ebong ei chain ta serial: HTML → googleapis CSS → gstatic woff2.
        Bangladeshi 4G te protita handshake ~150-300ms.
     3. cross-site HTTP cache 2020 sal theke partitioned. Mane "onno site
        theke already cached thakbe" — eta ekhon mitthe. Kono lav nai.

   Ekhon shob nijeder origin e. HTML jei connection e ashe, font o shei
   connection e ashe — kono notun handshake nai, kono blocking CSS nai.

   Files: assets/fonts/. Google Fonts OFL, self-host kora allowed.
   unicode-range gulo Google er css2 output theke hubohu copy kora — eta
   chara browser bengali page er jonno latin file o namabe.

   Notun weight lagle: fonts.googleapis.com/css2?family=... khule woff2 URL
   ta nao, assets/fonts/ e rakho, niche ekta @font-face add koro. `300` ta
   icche kore nai — style.css e font-weight:300 ekbar o nai. */

/* --- Hind Siliguri : bengali --- */
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/hind-400-bengali.woff2) format('woff2');unicode-range:U+0951-0952,U+0964-0965,U+0980-09FE,U+1CD0,U+1CD2,U+1CD5-1CD6,U+1CD8,U+1CE1,U+1CEA,U+1CED,U+1CF2,U+1CF5-1CF7,U+200C-200D,U+20B9,U+25CC,U+A8F1}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/hind-500-bengali.woff2) format('woff2');unicode-range:U+0951-0952,U+0964-0965,U+0980-09FE,U+1CD0,U+1CD2,U+1CD5-1CD6,U+1CD8,U+1CE1,U+1CEA,U+1CED,U+1CF2,U+1CF5-1CF7,U+200C-200D,U+20B9,U+25CC,U+A8F1}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:600;font-display:swap;src:url(fonts/hind-600-bengali.woff2) format('woff2');unicode-range:U+0951-0952,U+0964-0965,U+0980-09FE,U+1CD0,U+1CD2,U+1CD5-1CD6,U+1CD8,U+1CE1,U+1CEA,U+1CED,U+1CF2,U+1CF5-1CF7,U+200C-200D,U+20B9,U+25CC,U+A8F1}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:700;font-display:swap;src:url(fonts/hind-700-bengali.woff2) format('woff2');unicode-range:U+0951-0952,U+0964-0965,U+0980-09FE,U+1CD0,U+1CD2,U+1CD5-1CD6,U+1CD8,U+1CE1,U+1CEA,U+1CED,U+1CF2,U+1CF5-1CF7,U+200C-200D,U+20B9,U+25CC,U+A8F1}

/* --- Hind Siliguri : latin --- */
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:400;font-display:optional;src:url(fonts/hind-400-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:500;font-display:optional;src:url(fonts/hind-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:600;font-display:optional;src:url(fonts/hind-600-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:700;font-display:optional;src:url(fonts/hind-700-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* --- Hind Siliguri : latin-ext --- */
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:400;font-display:swap;src:url(fonts/hind-400-latinext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:500;font-display:swap;src:url(fonts/hind-500-latinext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:600;font-display:swap;src:url(fonts/hind-600-latinext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Hind Siliguri';font-style:normal;font-weight:700;font-display:swap;src:url(fonts/hind-700-latinext.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* ── EKTA MAPA, BATIL BIKOLPO: latin er jonno alada `swap` family ─────

   Cheshta kora hoyechilo, jate English e Latin ta ASHOL Hind Siliguri pay,
   Bangla er moto. font-display ekta @font-face descriptor — selector diye
   bodlano jay na — tai ek e char-ta latin woff2 DUITIYO ek-ta family name e
   ('Hind Latin') `font-display:swap` diye bola hoyechilo, ar stack e sheta
   dhukto shudhu `html[data-lang="en"] body` e. Notun kono byte lagto na.

   KAJ KORTO: English heading gulo `HindSiliguri-Bold` e rasterise hocchilo,
   protita page e, ar Bangla page ek chuler o bodlato na (selector-gated).

   TOBU BATIL, karon CLS. 390px e, 300ms latency / 400kbps throttle e — niche
   .count er docblock e jei poddhoti lekha ache, hubohu sheta — before -> after:

       /offer     en   0.0302 -> 0.2511
       /blog      en   0      -> 0.1682
       /features  en   0      -> 0.0315
       /          en   0      -> 0.0101
       /offer     bn   0.0302 -> 0.0294   <- Bangla thik e chilo

   Mane trade ta ulte gelo: Bangla bachate `optional` boshano hoyechilo, ar
   ei bikolpo ta thik oi CLS ta ENGLISH page er ghare tule dito. 0.2511 Google
   er "poor" band e. Malik er ovijog chilo text BOLD hocche na — sheta uporer
   'HS Fallback' er bold face diye MITE JAY, kono CLS kharap na kore. Tai
   typeface milanor jonno CLS deya holo na.

   Ei bikolpo ta mapte giye 'HS Fallback' er latin-range face duita (96.5% /
   96.3%) beriye eshechilo, ar SEGULO thake geche — uporer 'HS Fallback' block
   dekhun. Segulo eka eka /blog en 0.1682 -> 0.0033 ar /features en 0.0315 ->
   0.0024 kore, mane 'Hind Latin' er khoti-r beshir bhag e mite jeto — kintu
   /offer en 0.2534 e e reheto, karon lp-hero er px line-pin gulo Bangla text
   er jonno mapa, English er jonno noy. Oi ek-ta page e e puro bikolpo ta
   ATKE jay. */

/* ── Inter shorano hoyeche ───────────────────────────────────────────────
   Inter er latin file ta 48,432 byte — ekta variable font, 400 theke 700
   ek file e. Puro site e eta lagto TINTA rule e: .plogo (payment badge),
   .ilogo .ib (integration badge), ar .crd code. Tinta e choto, decorative,
   ek-duita Latin shobdo — "bKash", "Card".

   Mane page er 48 KB, mane home page er 13%, tinta badge label er jonno.
   Ar Hind Siliguri er latin subset (8 KB, already namche) oi shobdo gulo
   dekhatei pare. Tai oi tinta rule ekhon `font-family:inherit` (mane Hind
   Siliguri), ar .crd code system monospace e.

   390px e dui version er screenshot milano hoyeche — badge gulo chara ar
   kothao kono parthokko nai, ar badge gulo teo chokhe pore na. */

/* Hind Siliguri te bangla digit gulo, bishesh kore ১, choto size e boja jay na.
   Tai shudhu digit gulor jonno Noto Sans Bengali. unicode-range diye deya
   ache, tai baki text agher font e e thake — font ta shudhu number er jonno load hoy.

   ── File ta 107 KB chilo, ekhon 8 KB ────────────────────────────────────
   unicode-range shudhu bole KON glyph er jonno font ta LAGBE — file er
   bhitor ki ache sheta bodlay na. Tai puro Noto Sans Bengali (107,720 byte,
   shob juktakkhor shoho) namto, 16-ta digit ke dekhanor jonno. Ekhon file
   tai oi 16-ta codepoint e subset kora (Google Fonts `&text=` diye), 8,316
   byte — hubohu ekoi glyph, 400/600/700 tinta weight e screenshot mile. */

/* ── Font swap er jonno je layout jump hoto, sheta bondho ────────────────
   Font ashar AGE browser system font e text dekhay, tar por Hind Siliguri
   ashle SHOB text abar mapa hoy. Hind Siliguri system font gulor cheye
   SORU — mapa hoyeche, ekoi lead-paragraph 100px e:

       Hind Siliguri 400   14,942 px
       Noto Sans Bengali   15,722 px   (Android er bangla fallback)  → 95.0%
       Nirmala UI          16,937 px   (Windows)                     → 88.2%

   Mane fallback e paragraph ta 5-12% CHOWRA, tai ek-duita line BESHI ney.
   Font ashar por line kome jay ar niche-r shob kichu upore lafay — home
   page e etai chilo CLS er 0.149, mane pura layout shift er 85%.

   size-adjust die fallback ta ke ekoi choura banano hoy, tai line count
   bodlay na, tai kichu nore na. Duita @font-face ekoi name e: browser jeta
   PAY sheta ney, ar pore-r ta age. Android e Noto Sans Bengali pabe (95%),
   Windows e Nirmala UI (88.2%).

   Eta stack e 'Hind Siliguri' er thik PORE bosano — tai fallback ta ar
   platform er upor chhara nai, amra e thik kore dilam kon ta hobe.

   ── 🔴 `font-weight:400 700` EK-TA REGULAR FACE ER UPORE = BOLD MARA JAY ──

   Malik er kotha, 2026-08-27: "dokanseba website er all page e Bangla verison
   e text gula bold hoye thik thak show korche kintu english e switch korle sei
   text gula are bold hocce na, cikon hoye show korche."

   `font-weight:400 700` ekta RANGE. Ei descriptor browser ke bole: ei face ta
   400 theke 700 porjonto SHOB weight nijei dey. Kintu `local('Nirmala UI')`
   ekta static REGULAR face — er bhitore kono bold nai, kono wght axis nai. Tai
   browser weight 700 chaile ei face-take e "match" pay, aro mota kono face
   khoje na, ebong — ei tuku e asol khoti — SYNTHETIC BOLD o banay na. Synthesis
   tokhon i hoy jokhon browser jei face ta beche niyeche tar weight chawa weight
   er cheye KOM; ekhane descriptor mithye bole diyeche je kom na.

   ── 🔴 `document.fonts.check()` DIYE EITA DHORA JAY NA ──────────────────

   Ei bug ta mapte gele shobar age jei jinish tay haat jay — `document.fonts
   .check('700 16px "Hind Siliguri"', 'E')` — sheta TRUE ferot dilo, thik oi
   page e jekhane heading gulo Times New Roman e rasterise hocchilo. API ta
   "ei face ta ki LOAD hoyeche" er uttor dey; "ei face ta ki EKECHE" er noy.
   Duita alada proshno, ar chhoto tar uttor diye boro tar dabi kora jay na.
   Ek e bhabe computed `font-weight:700` o mithye bole — weight ta 700 e
   COMPUTE hoy, bold face na thakleo.

   Jei jinish ta mithye bolte pare na: CDP `CSS.getPlatformFontsForNode`, ja
   ASHOL rasterise howa postScriptName ferot dey (`NirmalaUI` bonam
   `NirmalaUI-Bold` bonam `HindSiliguri-Bold`). Ar tar pashe width — ekoi
   string 400 e ar 700 e mepe. Ei duita chara ei file er kono font-weight
   dabi biswas korben na.

   MAPA HOYECHE, headless Chrome, ek e string 32px e, site er nijer stack e:

       weight 400  ->  346.20 px
       weight 600  ->  346.20 px      <- ek chuler o parthokko nai
       weight 700  ->  346.20 px

   Bangla te eta dhora pore na, karon Bangla glyph gulo 'Hind Siliguri' er
   bengali face gulo theke ashe ar shekhane ashol 400/500/600/700 file ache
   (236.81 / 233.61 / 228.36 — weight response ache). English er Latin glyph
   `HS Fallback` porjonto neme ashe (CSS.getPlatformFontsForNode: `Nirmala UI
   [NirmalaUI]` — REGULAR postscript name, protita page e, protita heading e),
   ar shekhane weight ta more jay. Tai bug ta "English e" — asole "Latin e".

   KENO Latin ta `HS Fallback` porjonto name, jodio hind-*-latin.woff2 char-tai
   download hoy: uporer `font-display:optional`. `optional` bole — 100ms er
   moddhe na pele ei page load er jonno fallback e e thako. Prothom baar asha
   pathok (mane protita advertisement click) tai kokhono Hind er Latin pay na.
   Prod e `.htaccess` 30 din immutable cache dey, tai DUITIYO baar theke Hind
   ashe — mane bug ta "kokhono kokhono" noy, "PROTHOM baar-e", ar setai beshi
   guruttopurno.

   TAI 400-700 range ta bhenge duita ashol face kora holo: regular ta 400 500 e,
   ar 600 700 er jonno platform er ASHOL bold face. Chrome e mapa — `src` er
   bhitore `local('Nirmala UI Bold')` KHUJE PAY (postscript `NirmalaUI-Bold`
   rasterise hoy), jodio `font-family:'Nirmala UI Bold'` diye direct dile pay na.
   Ar ekta bikolpo je kaj kore NA, ta likhe rakha holo jate keu abar na cheshta
   kore: range ta shudhu `400` kore dile Chrome synthetic bold banay na — mapa
   holo, tinta weight e 432.81 px, ek e.

   ── size-adjust 80.3%, ar keno 88.2% NOY ────────────────────────────────

   size-adjust er ek matro kaj: fallback ta ke Hind er SAMAN CHOURA kora, jate
   line count na bodlay, jate kichu na nore. 88.2% ta mapa hoyechilo Nirmala
   REGULAR er upore. Bold face beshi choura, tai tar nijer number lage. 10-ta
   ashol Bangla string 100px e mapa:

       Hind bengali 700  /  Nirmala UI Bold   = 80.28%   <- ekhane eta
       Hind bengali 400  /  Nirmala UI        = 85.21%   (tulonar jonno)

   Ar eta CLS er dik theke SHUDHU RAKKHA kore, bhange na. Aj ke bold Bangla
   heading er fallback = Nirmala REGULAR x 88.2% = Hind bold er 98.93% —
   dorkar-er cheye bhalo, kaka-taliyo. Bold face ke 88.2% e rakhle seta hoto
   109.9% (10% choura), mane heading re-wrap, mane notun CLS. 80.3% e width
   ta ajker moto e thake.

   Noto Sans Bengali er bold number ta MAPA NOY — ei machine e (Windows) font
   ta install nai, `document.fonts` e face ta `error` dekhay. Nirmala er
   bold/regular anupat (80.28/85.21 = 0.942) Noto er 95.0% er upore boshano
   holo -> 89.5%. Uporer comment o ek e kotha shikar kore: mapar machine
   Windows, tai Noto er dhap ta kokhono o mapa hoy nai.

   Jodi `local()` ta kono platform e na pay (Android e 'Noto Sans Bengali Bold'
   thaka na thakate pare), face ta error hoy ar family te 600-700 e kichu thake
   na — tokhon browser 400 500 face ta ney, mane AJKER behaviour, mane kono
   regression noy. */
@font-face{font-family:'HS Fallback';font-style:normal;font-weight:400 500;src:local('Nirmala UI');size-adjust:88.2%}
@font-face{font-family:'HS Fallback';font-style:normal;font-weight:600 700;src:local('Nirmala UI Bold'),local('NirmalaUI-Bold');size-adjust:80.3%}

/* ── EK-TA size-adjust DUI-TA LIPI-KE SEBA DITE PARE NA ──────────────

   Uporer 88.2% ar 80.3% — duita e BANGLA string diye mapa, karon ei fallback
   ta Bangla er jonno e banano hoyechilo. Kintu 'HS Fallback' er kono
   unicode-range nai, tai Latin glyph gulo O oi ek e number pay. Latin er
   ashol anupat puro alada — 10-ta ashol string 100px e mapa:

       Hind latin 400 / Nirmala UI       = 96.53%     (Bangla e 85.21%)
       Hind latin 700 / Nirmala UI Bold  = 96.29%     (Bangla e 80.28%)

   Bangla er number Latin e boshale ki hoy, ta bold face ta bosanor SATHE
   SATHE chokhe porlo: English e regular 346.20 px, bold 336.09 px — bold ta
   regular er CHEYE CHOTO. Mane ekta English anucched e `<strong>` shobdo gulo
   pasher shobdo theke 9% choto hoye rendered hoto. Bold ta thik korte giye
   notun ekta chokhe-pora bhul toiri hoto.

   Tai Latin range er jonno alada duita face, tader nijer mapa number e. Pore
   bola hoyeche, tai ek e weight e Latin codepoint er jonno EGULO jete — CSS
   font matching e shomo-match er kkhetre SHESH declaration ta jete. Ekhon
   English e 378.83 -> 403.08 px (regular -> bold), thik dik e.

   ── AR EITA /offer ER CLS 75x KOMAY, dhar hishebe noy ─────────────────

   Niche .count er docblock e /offer er CLS er bekkha ache, ar tar ek-ta line
   thik na: "the `HS Fallback` metric match above covers the BENGALI range
   only". Coverage ta thik e chilo (U+0-10FFFF); bhul ta chilo ANUPAT — Bangla
   er 88.2% Latin em-dash ar middot er jonno 9% shoru. Oi 9% e e line re-wrap
   hoto. Ekhon anupat ta thik, tai:

       /offer  bn   0.0302 -> 0.0004        /pricing bn  0.0217 -> 0.0207
       /offer  en   0.0302 -> 0.0004        /help    bn  0.0200 -> 0.0204
       /       bn   0.0002 -> 0.0028        /blog, /features  — obodolito

   390px, 300ms/400kbps, duibar kore — .count er nijer poddhoti. `/ bn` er
   0.0026 barti "good" band er (0.1) onek bhitore, ar /offer — jei page e
   protita advertisement name — kaachakachi shunno. */
@font-face{font-family:'HS Fallback';font-style:normal;font-weight:400 500;src:local('Nirmala UI');size-adjust:96.5%;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'HS Fallback';font-style:normal;font-weight:600 700;src:local('Nirmala UI Bold'),local('NirmalaUI-Bold');size-adjust:96.3%;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

/* ── lp-hero: line boxes pinned in PIXELS, so a late font cannot move the CTA ──

   MEASURED 2026-08-25 on the live /offer, in a phone-sized browser:

       /        CLS 0.002   ← the size-adjust fallback above does its job
       /offer   CLS 0.239   ← it does not, here

   Isolated by blocking one font file at a time:

       nothing blocked      0.2388
       bn-digits blocked    0.1752
       hind-*.woff2 blocked 0        ← the whole of it is the webfont swap

   And read off the LayoutShift entries themselves rather than guessed: each
   `li` grew 53px -> 55px, `.cta-btns` moved 569 -> 581 and back 29ms later.
   Two pixels per line, six lines, and the button a visitor is reaching for
   jumps twelve pixels down and then back up. On the page every advertisement
   lands on, that is the difference between a tap and a mis-tap.

   WHY THE FALLBACK ABOVE WAS NOT ENOUGH. `size-adjust` matches the fallback's
   WIDTH so a paragraph keeps its line COUNT — which is exactly the home
   page's problem and exactly what it fixed there. It does not pin line
   HEIGHT, and this hero's line-height is a ratio (1.7), so the box grows with
   whatever metrics the active face reports. A ratio is the right default
   everywhere text can reflow freely; it is the wrong one directly above a
   button.

   So only this hero is pinned, in px, and only the two things that were
   measured moving. Everything else keeps the ratio. */
.lp-hero .lp-points li{line-height:26.5px}
.lp-hero .lead,.lp-hero .lp-lead,.lp-hero h1{line-height:1.38}

/* ── The animated counters, and the REAL cause of /offer's CLS ──────────

   SOLVED 2026-08-25. It was `hind-*-latin.woff2`, and the two guesses
   recorded above — the line-height pin and `.count` — were both wrong. Both
   rules are kept, because each is right on its own merits, but neither moved
   the number and the next person should not repeat either experiment.

   HOW IT WAS ISOLATED. Not on the live site, where a measurement varies with
   whatever the network did that second, but against a local server with the
   transport throttled (300ms latency, 400kbps) so the swap always lands after
   first paint. That harness returns the SAME number five runs out of five,
   which is what made a one-file-at-a-time matrix worth trusting:

       nothing blocked            0.2553
       hind-*-bengali blocked     0.2532   <- the Bangla text face: not it
       bn-digits blocked          0.2553   <- the counters: not it either
       hind-*-latinext blocked    0.2553
       hind-*-latin BLOCKED       0.0302   <- 88% of the whole number
       all images blocked         0.2553   <- not images
       all woff2 blocked          0        <- a font, definitively

   WHY THE LATIN FACE, ON A PAGE WITH NO ENGLISH ON IT. Because the Bangla
   copy is full of Latin-range codepoints. Every bullet on this page reads
   "নেট ছাড়াই চলে — লাইন গেলেও…": that em-dash is U+2014, and U+2000-206F is
   the LATIN face's unicode-range, not the Bengali one. So does the middot in
   "কার্ড লাগবে না · এখন টাকা লাগবে না". The `HS Fallback` metric match above
   covers the BENGALI range only — for these characters the browser fell
   through to an untuned system font, and their width changed on swap. One
   punctuation mark per line, in the middle of the line, is enough to re-wrap
   the line and re-flow every block under it.

   THE FIX is `font-display:optional` on the four latin faces. `optional`
   gives the file a ~100ms window and then commits to the fallback FOR THAT
   PAGE LOAD — so there is no swap to shift anything. A visitor who already
   has the file cached still gets Hind from the first paint; a first-time
   visitor on mobile data gets the system font for their punctuation, which
   is a dash and a middot.

   That trade is deliberate, and it is the right way round for THIS site:
   /offer is where every Facebook advertisement lands, its visitors are
   first-time and on mobile data by definition, and 0.2553 is deep in
   Google's "poor" band while 0.0302 is inside "good".

   MEASURED ACROSS THE WHOLE SITE, before -> after. Thirteen pages, every one
   improved, none regressed:

       /             0.0019 -> 0.0002      /terms         0.0030 -> 0.0005
       /offer        0.2553 -> 0.0302      /privacy       0.0022 -> 0.0002
       /pricing      0.0237 -> 0.0217      /blog          0.0029 -> 0.0002
       /features     0.0033 -> 0.0005      /videos        0.0443 -> 0.0381
       /faq          0.0032 -> 0.0009      /stories       0.0184 -> 0.0086
       /about        0.0038 -> 0.0008      /integrations  0.0062 -> 0.0011
       /contact      0.0162 -> 0.0122

   ONE THING THIS DOES NOT COVER, said plainly rather than left to be found:
   the measurement machine is Windows, so its fallback is Nirmala UI and the
   88.2% branch. Bangladeshi ad traffic is overwhelmingly Android, where the
   fallback is Noto Sans Bengali and the 95.0% branch. `optional` removes the
   swap on BOTH — that part is not platform-dependent — but the residual
   0.0302 was only ever measured against Nirmala.

   A REJECTED FIX, recorded so it is not retried: splitting `HS Fallback`
   into per-weight size-adjust (85.8/89.1/89.3, measured off 14 real strings
   per weight) made things WORSE — /offer 0.2553 -> 0.358 and the home page
   0.0019 -> 0.177. The home page was the control that caught it. Width
   matching was already good; it was never the lever. */
.count{font-variant-numeric:tabular-nums;font-feature-settings:'tnum' 1;
  display:inline-block;min-width:2.4ch;text-align:inherit}

/* Android er dhap. Uporer Nirmala jora-r hubohu shape — regular 400 500 e,
   bold 600 700 e — noile Android e English abar cikon hoye jabe. 89.5% er
   hishab ar tar shikarokti uporer docblock e.

   ── EI DHAP E LATIN-RANGE FACE NAI, ar seta icche kore ─────────────────

   Nirmala er jonno Latin er alada 96.5%/96.3% face duita ache (upore), ar oi
   number duita MAPA. Noto er jonno oi rokom number mapa jay na — ei machine e
   font ta install e nai. Bar kora jeto: Nirmala er Latin/Bangla anupat (96.53
   /85.21 = 1.133) Noto er 95.0% e boshale 107.6% hoy. Kintu seta ekta anuman
   er upore ar-ekta anuman, ar bhul hole seta Android e — mane BD er beshir
   bhag traffic e, mane /offer e — fallback ta bhul chourai kore, jeta thik oi
   jinish ja .count er docblock er puro campaign ta thamate cheyechilo. Tai
   bosano holo na.

   Fol: Android e Latin bold 89.5% e ashe ar Latin regular 95.0% e, mane bold
   ta regular er cheye 5.8% choto. Windows e ei 9% er problem tai thik kora
   hoyeche (upore), kintu Android er jonno mapa noy bole thik kora holo na.
   Ajker obostha — Android e bold BOLDI HOY NA — er cheye eta shob dik theke
   bhalo, tai eta niye ship kora holo, lukiye noy.

   `local()` gulo Android e na milleo kono khoti nai: face ta error hoy, family
   te 600-700 e kichu thake na, browser 400 500 face tai ney — mane ajker
   behaviour. Regression noy, shudhu fix ta oi platform e pouchay na. */
@font-face{font-family:'HS Fallback';font-style:normal;font-weight:400 500;src:local('Noto Sans Bengali');size-adjust:95.0%}
@font-face{font-family:'HS Fallback';font-style:normal;font-weight:600 700;src:local('Noto Sans Bengali Bold'),local('NotoSansBengali-Bold');size-adjust:89.5%}

@font-face{
  font-family:'BN Numerals';
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url(bn-digits.woff2) format('woff2');
  unicode-range:U+09E6-09EF, U+09F2-09F9;
}
  *{margin:0;padding:0;box-sizing:border-box}
  html{scroll-behavior:smooth}
  body{
    font-family:'BN Numerals','Hind Siliguri','HS Fallback',system-ui,-apple-system,'Segoe UI',sans-serif;
    background:var(--bg);color:var(--body);line-height:1.75;
    transition:background .25s ease,color .25s ease;-webkit-font-smoothing:antialiased;
  }
  /* Ei jaygay `html[data-lang="en"] body{...}` diye 'Hind Latin' stack e
     dhokano hoyechilo. Batil — karon ar mapa number gulo uporer 'Hind Latin'
     block e. */
  h1,h2,h3,h4{color:var(--ink);line-height:1.38;font-weight:700}
  a{text-decoration:none;color:inherit}
  svg{display:block}
  .wrap{max-width:var(--max);margin:0 auto;padding:0 22px}
  .section{padding:92px 0;position:relative}
  .section.alt{background:var(--bg-alt)}
  .gtext{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

  /* ---------- Buttons (pill) ---------- */
  .btn{display:inline-flex;align-items:center;justify-content:center;gap:9px;
    padding:13px 30px;border-radius:999px;font-weight:600;font-size:15.5px;
    border:1px solid transparent;cursor:pointer;transition:.22s ease;white-space:nowrap;font-family:inherit}
  .btn-gold{background:var(--btn-grad);color:var(--gold-ink);box-shadow:var(--glow)}
  .btn-gold:hover{transform:translateY(-2px);box-shadow:0 10px 32px rgba(22,168,111,.46)}
  .btn-line{background:transparent;color:var(--ink);border-color:var(--line)}
  .btn-line:hover{border-color:var(--gold);color:var(--gold)}
  .btn-dark{background:#043724;color:#B9E2CF}
  .btn-sm{padding:10px 24px;font-size:14.5px}

  /* ---------- Announcement bar ---------- */
  .topbar{background:linear-gradient(90deg,rgba(22,168,111,.10),rgba(15,157,106,.08) 55%,rgba(22,168,111,.10));
    border-bottom:1px solid var(--line);font-size:13.5px;overflow:hidden}
  /* `min-height`, not `height`. Every taller state this bar has — the wrapped
     two-row phone layout below 768px, and the reduced-motion fallback that
     lets the sentence run onto a second line — grows out of this one word.
     Nothing moves today: the row's tallest child is the 24px hotline link, so
     42px is still exactly 42px, and the 44px tiers below are still 44px. */
  .tb{display:flex;align-items:center;justify-content:space-between;gap:18px;min-height:42px}
  .tb-left{display:flex;align-items:center;gap:10px;color:var(--ink);font-weight:500;min-width:0}

  /* ── The announcement ticker ──────────────────────────────────────────────
   *
   * Owner: *"mobile screen e ei text ta breaking news er moto ek pas theke text
   * onno pase jabe seta kore daw jate full text ta porte pare."* The markup is
   * two boxes and the reason for each is in partials/header.php.
   *
   * `data-tick` on #topbar is written by assets/app.js and has three values.
   * The SPLIT matters: the script answers only "does this sentence fit", and
   * this stylesheet decides what to do about it. That is what keeps the
   * reduced-motion branch below purely declarative — no script has to know
   * about the preference for the strip to obey it.
   *
   *   (absent)  not measured yet, or nothing to say. Clipped, as before.
   *   off       it fits. IT MUST THEN SIT PERFECTLY STILL. A strip that
   *             scrolls a sentence with 400px of room to spare is decoration,
   *             and decoration that moves is the thing readers ask to be
   *             turned off. This is why app.js measures instead of keying off
   *             a breakpoint: the Bangla and English sentences are different
   *             lengths, so one width is "fits" in one language and "overflows"
   *             in the other at the very same screen size.
   *   on        it overflows. --tb-run and --tb-dur come with it.
   *   wrap      the reader has asked for no motion. See the block after next.
   *
   * ── The travel, and why --tb-run is in PIXELS ────────────────────────────
   *
   * `translateX(100%)` on the track would be 100% OF THE TRACK, which is the
   * sentence's own width and has nothing to do with the window it is being
   * read through — a 400px sentence in a 290px viewport would start 110px past
   * the right edge and the reader would watch an empty bar for a second and a
   * half before anything arrived. So app.js hands over the VIEWPORT's width in
   * px as --tb-run: the sentence starts flush with the right edge and ends
   * flush with the left, and the cycle is exactly `viewport + sentence` long.
   * The 100% fallback only ever applies for one frame if a var goes missing.
   *
   * ── Speed is px/sec, and it is a number, not a duration ──────────────────
   *
   * A fixed `animation-duration` is the classic marquee mistake: it makes a
   * long sentence move fast and a short one crawl, so the only line that
   * actually needed help is the one nobody can read. app.js divides the travel
   * by a constant 72 px/sec instead, so every announcement — any length, either
   * language — passes the eye at one steady pace. The arithmetic and the choice
   * of 72 are argued where they are applied, in assets/app.js.
   *
   * `will-change` is scoped to [data-tick="on"] on purpose. It asks the
   * compositor for a layer, and a layer held permanently for a strip that is
   * NOT animating is memory rented for nothing on a 2GB Android phone.
   */
  .tb-msg{flex:1 1 auto;min-width:0;overflow:hidden}
  .tb-msg>span{display:inline-block;white-space:nowrap}
  /* ── THE EDGES FADE, AND ONLY WHILE IT IS MOVING ──────────────────────────
   *
   * `overflow:hidden` cuts a glyph in half at whichever pixel the box ends on,
   * which on a moving line reads as damage rather than as a boundary — a
   * sliced Bangla conjunct against the call button looks like something has
   * gone wrong with the button. A 14px ramp at each end lets the sentence
   * arrive and leave instead of appearing and vanishing.
   *
   * ON THE VIEWPORT, NEVER ON THE TRACK. The mask is painted in the masked
   * element's own box, so a mask on the track would travel with the text and
   * fade the same two words for the whole cycle — the same trap that makes
   * `overflow` belong here and not one element in. This box does not move.
   *
   * Scoped to [data-tick="on"] because a sentence that FITS has no edge to
   * soften: fading the last 14px of a line that ends 200px early would dim
   * real words for no reason. `-webkit-` first for the Android WebViews that
   * shipped the prefixed property only; a browser with neither simply gets the
   * hard clip it got before, which is not a broken layout. */
  .topbar[data-tick="on"] .tb-msg{
    -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
    mask-image:linear-gradient(90deg,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%)}
  .topbar[data-tick="on"] .tb-msg>span{
    will-change:transform;animation:tbtick var(--tb-dur,14s) linear infinite}
  @keyframes tbtick{from{transform:translateX(var(--tb-run,100%))}to{transform:translateX(-100%)}}

  /* Three ways to stop it and finish the line. Hover is the mouse; :focus-within
     is the keyboard, and it works because the strip already contains focusable
     things — tabbing to the hotline link parks the sentence, which is what a
     keyboard reader trying to read it would do anyway. `data-hold` is the touch
     one: a tap on the message toggles it in app.js, because a phone has no
     hover and would otherwise be the only device that cannot pause. */
  .topbar[data-tick="on"]:hover .tb-msg>span,
  .topbar[data-tick="on"]:focus-within .tb-msg>span,
  .topbar[data-tick="on"][data-hold] .tb-msg>span{animation-play-state:paused}

  /* ── prefers-reduced-motion: STILL, AND STILL READABLE ────────────────────
   *
   * A strip of text sliding across the top of every page is a textbook
   * vestibular trigger, so this has to be a full stop and not a slow-down.
   *
   * But `animation:none` alone would hand a reader who cannot tolerate motion
   * the WORSE of the two originals — a sentence clipped mid-word — which is
   * not an accommodation. So the fallback is the other readable shape: the
   * sentence wraps onto as many lines as it needs and the bar grows to hold
   * them. That is what `min-height` on .tb bought, and it is why nothing here
   * has to name 42 or 44: whichever floor this width tier set still applies.
   *
   * Both the media query and the `wrap` attribute exist, and they are not
   * redundant. The query is the GUARANTEE — it holds before app.js has run, on
   * a page where the script failed, and the instant the preference is toggled.
   * The attribute is how app.js skips measuring entirely for such a reader,
   * because a duration nobody will see is not worth a layout pass.
   */
  /* ── `padding-block`, and the shorthand it replaces was a REAL BUG ────────
   *
   * These two rules read `padding:5px 0` and that zeroes the LEFT AND RIGHT
   * padding too — on `.tb`, which is also `.wrap`, the element that carries the
   * page gutter (22px, 16px at 480, 14px at 380). So a reader with
   * prefers-reduced-motion got a strip with no gutter at all: measured before
   * the fix, at 1280 the dismiss × sat at x=1260.77 and is 19.23px wide, so its
   * right edge landed on 1280.00 — flush with the window, while every other row
   * on the page stopped 24px short. At 390 the message viewport measured
   * 325.72px against 293.72px in the motion path: the same 32px, which is the
   * two 16px gutters, arriving as extra width nobody asked for.
   *
   * It is only ever seen by a reader who has asked for no motion, which is why
   * it survived: the state is not the default one and the screenshots taken of
   * this strip were all taken in the default one. `padding-block` says the one
   * axis these rules were always about. */
  .topbar[data-tick="wrap"] .tb-msg>span{white-space:normal}
  .topbar[data-tick="wrap"] .tb{height:auto;padding-block:5px}
  @media(prefers-reduced-motion:reduce){
    .topbar .tb-msg>span{animation:none!important;transform:none!important;white-space:normal}
    .topbar[data-tick] .tb{height:auto;padding-block:5px}
  }

  .tb-left em{font-style:normal;background:var(--btn-grad);color:var(--gold-ink);font-weight:700;
    padding:2px 10px;border-radius:999px;font-size:12px;flex:none}
  .pulse{width:8px;height:8px;border-radius:50%;background:#34B483;flex:none;
    box-shadow:0 0 0 0 rgba(52,180,131,.6);animation:pulse 2s infinite}
  @keyframes pulse{70%{box-shadow:0 0 0 8px rgba(52,180,131,0)}100%{box-shadow:0 0 0 0 rgba(52,180,131,0)}}
  .tb-right{display:flex;align-items:center;gap:16px;color:var(--body);flex:none}
  .tb-right a{display:flex;align-items:center;gap:7px;transition:.2s}
  .tb-right a:hover{color:var(--gold)}
  /* The digits are a single token and must never break across two lines: this
     is a one-line strip and a wrapped phone number is the shape the owner
     photographed, one element to the left. */
  .tb-call .tb-num{white-space:nowrap}
  .tb-x{background:none;border:0;color:var(--muted);cursor:pointer;font-size:17px;line-height:1;padding:2px 4px;font-family:inherit;
    border-radius:10px;transition:.2s}
  .tb-x:hover{color:var(--gold)}

  /* ---------- Floating glass navbar ---------- */
  header{position:sticky;top:0;z-index:70;padding:16px 0;transition:padding .3s ease}
  header.stuck{padding:10px 0}
  .navshell{display:flex;align-items:center;justify-content:space-between;gap:18px;
    padding:9px 9px 9px 20px;border-radius:18px;border:1px solid var(--line);
    background:var(--header-bg);backdrop-filter:saturate(180%) blur(18px);transition:.3s ease}
  header.stuck .navshell{box-shadow:var(--shadow-lg);border-color:var(--gold-line)}

  /* logo */
  .logo{display:flex;align-items:center;gap:11px;font-weight:700;font-size:21px;color:var(--ink)}
  .logo .mark{width:42px;height:42px;border-radius:13px;background:var(--btn-grad);
    display:grid;place-items:center;color:var(--gold-ink);font-size:20px;box-shadow:var(--glow);flex:none;
    transition:.3s ease}
  .logo:hover .mark{transform:rotate(-8deg) scale(1.05)}
  /* The uploaded branding logo, drawn INSTEAD of .mark + the wordmark text when
     an operator has set one on the platform panel. Height-constrained rather
     than width-constrained because a wordmark's width is whatever its words
     need and its height is what has to line up with the bar; max-width is the
     guard against somebody uploading a banner. `width:auto` overrides the
     intrinsic width attribute, which is there for the aspect hint only. */
  .logo .brandlogo{height:34px;width:auto;max-width:190px;object-fit:contain;flex:none}
  .logo b{color:var(--gold)}
  .wm{display:flex;flex-direction:column;line-height:1.05}
  .wm em{font-style:normal;font-size:9.5px;letter-spacing:1.7px;color:var(--muted);
    font-weight:600;margin-top:4px}

  /* links */
  .nav-links{display:flex;align-items:center;gap:4px}
  .nav-item{position:relative}
  .nav-item > a{display:flex;align-items:center;gap:5px;font-size:15px;font-weight:500;color:var(--body);
    padding:9px 15px;border-radius:11px;transition:.2s}
  .nav-item > a:hover{color:var(--ink);background:var(--card-2)}
  .nav-item > a.on{color:var(--gold);background:var(--gold-soft)}
  .nav-item > a .cv{transition:.25s}
  .nav-item:hover > a .cv{transform:rotate(180deg)}

  /* mega dropdown */
  .mega{position:absolute;top:calc(100% + 14px);left:50%;transform:translateX(-50%) translateY(10px);
    width:660px;background:var(--card);border:1px solid var(--line);border-radius:20px;
    box-shadow:var(--shadow-lg);padding:18px;opacity:0;visibility:hidden;transition:.24s ease;z-index:90}
  /* :focus-within as well as :hover. Hover alone meant the six feature
     anchors, the ten trade pages, the three resources and the six company
     links — twenty-five destinations — could not be reached by keyboard AT
     ALL: `visibility:hidden` takes them out of the tab order, so a reader
     tabbing the bar went Home → Features → Solutions → Pricing and never saw
     what was under any of them. */
  .nav-item:hover .mega,.nav-item:focus-within .mega{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0)}
  .nav-item:focus-within > a .cv{transform:rotate(180deg)}
  .mega::before{content:"";position:absolute;top:-14px;left:0;right:0;height:14px}
  .mega-grid{display:grid;grid-template-columns:1fr 1fr;gap:6px}
  .mega-grid a{display:flex;gap:13px;padding:12px;border-radius:13px;transition:.2s}
  .mega-grid a:hover{background:var(--card-2)}
  /* the trade you are reading, inside the সমাধান panel. `b` as well as the
     row, because the row's tint alone is close to `:hover` and says "under the
     cursor" rather than "where you are". */
  .mega-grid a.on{background:var(--gold-soft)}
  .mega-grid a.on b{color:var(--gold)}
  .mega-grid .mi{width:38px;height:38px;border-radius:11px;background:var(--gold-soft);
    border:1px solid var(--gold-line);color:var(--gold);display:grid;place-items:center;flex:none}
  .mega-grid b{display:block;color:var(--ink);font-size:14.8px;font-weight:600;line-height:1.5}
  .mega-grid small{font-size:12.8px;color:var(--muted);line-height:1.5}
  .mega-foot{display:flex;align-items:center;gap:14px;margin-top:12px;padding:14px 16px;
    border-radius:14px;background:linear-gradient(100deg,rgba(22,168,111,.12),rgba(15,157,106,.07));
    border:1px solid var(--gold-line)}
  .mega-foot .mi{width:38px;height:38px;border-radius:11px;background:var(--btn-grad);color:var(--gold-ink);
    display:grid;place-items:center;flex:none}
  .mega-foot b{display:block;color:var(--ink);font-size:14.5px}
  .mega-foot small{font-size:12.8px;color:var(--body)}
  .mega-foot .btn{margin-left:auto}

  /* right cluster */
  .nav-right{display:flex;align-items:center;gap:9px}
  /* ---------- Language switch — ONE dropdown, 320px to 1920px ---------------
     One control at every width, a panel at every width. The owner asked for a
     dropdown on mobile AND desktop after seeing the segmented pair this
     replaces; what did NOT change is that there is exactly one of these in the
     document — see the note above $langSwitch in partials/header.php.

     What a panel buys back, besides being what was asked for: the trigger is
     ~54px at the narrow end against the segmented control's 80, and those 26
     pixels are the difference between the burger fitting on a 320px screen and
     hanging 44px off the edge of it. The panel itself is `position:absolute`
     inside `.lang`, so it is not in the bar's flex row and costs the row
     nothing.

     No `overflow` anywhere up the chain — `.navshell` and `.wrap` are both
     `visible` — so the panel is not clipped by the bar it hangs from. Checked,
     not assumed: `.navshell` has a `backdrop-filter`, which makes a stacking
     context and would have made a z-index fight out of a clipping problem. */
  .lang{position:relative;flex:none}
  .langbtn{display:inline-flex;align-items:center;gap:4px;padding:7px 8px 7px 9px;
    border:1px solid var(--line);border-radius:999px;background:var(--card-2);color:var(--ink);
    font:inherit;font-size:12.5px;font-weight:700;letter-spacing:.5px;line-height:1;
    cursor:pointer;transition:border-color .2s,background .2s}
  .langbtn:hover{border-color:var(--gold-line)}
  .langbtn[aria-expanded="true"]{border-color:var(--gold);background:var(--card)}
  .lang-globe{flex:none;color:var(--muted);transition:color .2s}
  .langbtn:hover .lang-globe,.langbtn[aria-expanded="true"] .lang-globe{color:var(--gold)}
  .langcode{flex:none}
  .langcv{flex:none;color:var(--muted);transition:transform .25s}
  .langbtn[aria-expanded="true"] .langcv{transform:rotate(180deg)}

  /* The panel. `visibility` rather than `opacity` alone is what keeps the two
     links out of the tab order while it is shut — an `opacity:0` panel is
     invisible and still focusable, which is a keyboard reader tabbing into
     nothing. The delayed `visibility` step lets the fade out finish first. */
  .langpop{position:absolute;top:calc(100% + 9px);right:0;z-index:5;min-width:152px;
    display:grid;gap:3px;padding:6px;border:1px solid var(--line);border-radius:14px;
    background:var(--card);box-shadow:var(--shadow-lg);
    opacity:0;visibility:hidden;transform:translateY(-6px);
    transition:opacity .18s ease,transform .18s ease,visibility 0s .18s}
  .lang[data-open="1"] .langpop{opacity:1;visibility:visible;transform:none;
    transition:opacity .18s ease,transform .18s ease,visibility 0s 0s}
  .langpop a{display:flex;align-items:center;gap:9px;padding:9px 11px;border-radius:10px;
    color:var(--body);font-size:14.5px;font-weight:600;white-space:nowrap;
    /* NAMED properties, never the `all` this said first. `all` transitions the
       INHERITED visibility coming down from the panel too, and for the 180ms it
       took to arrive the row was still `visibility:hidden` — which is not
       focusable, so the focus() that puts the caret on the open panel silently
       did nothing and the caret stayed on the trigger. Seen in all sixteen
       captures; the row looked perfect and the keyboard was standing outside. */
    transition:background .18s ease,color .18s ease}
  .langpop a .lc{font-size:11px;font-weight:800;letter-spacing:.6px;opacity:.7;min-width:19px}
  .langpop a:hover{background:var(--card-2);color:var(--ink)}
  /* The language you are IN. `aria-current="true"` says the same thing to a
     reader who cannot see the fill; before both existed this was conveyed by
     BACKGROUND COLOUR AND NOTHING ELSE. partials/head.php keeps the class and
     the attribute together on a client-side switch. */
  .langpop a.on,.langpop a.on:hover{background:var(--btn-grad);color:var(--gold-ink)}
  .langpop a.on .lc{opacity:.85}
  @media(prefers-reduced-motion:reduce){
    .langpop,.langcv{transition:none}
    .lang[data-open="1"] .langpop{transition:none}
  }
  .theme-btn{width:38px;height:38px;border-radius:50%;border:1px solid var(--line);background:var(--card-2);
    color:var(--ink);display:grid;place-items:center;cursor:pointer;transition:.25s;flex:none}
  .theme-btn:hover{border-color:var(--gold);color:var(--gold);transform:rotate(20deg)}
  .theme-btn .i-moon{display:block}.theme-btn .i-sun{display:none}
  html[data-theme="light"] .theme-btn .i-moon{display:none}
  html[data-theme="light"] .theme-btn .i-sun{display:block}
  .divider{width:1px;height:26px;background:var(--line);margin:0 3px}
  .login{display:flex;align-items:center;gap:7px;font-size:15px;font-weight:500;color:var(--body);
    padding:9px 15px;border-radius:11px;transition:.2s}
  .login:hover{color:var(--ink);background:var(--card-2)}
  .nav-right .btn{padding:11px 22px}
  .nav-right .btn svg{transition:.25s}
  .nav-right .btn:hover svg{transform:translateX(3px)}

  /* scroll progress */
  .prog{position:absolute;left:0;bottom:0;height:2px;width:0;background:var(--btn-grad);
    border-radius:2px;transition:width .1s linear}

  /* mobile */
  .burger{display:none;background:var(--card-2);border:1px solid var(--line);border-radius:11px;
    cursor:pointer;color:var(--ink);width:40px;height:40px;place-items:center}
  .mobile-menu{display:none;margin-top:10px;border:1px solid var(--line);border-radius:18px;
    background:var(--card);padding:10px 18px 20px;box-shadow:var(--shadow-lg)}
  .mobile-menu a{display:block;padding:13px 2px;font-weight:500;border-bottom:1px solid var(--line)}
  .mobile-menu a:last-of-type{border-bottom:0}
  .mobile-menu .m-lang{display:flex;gap:10px;align-items:center;padding-top:14px}
  .mobile-menu .btn{width:100%;margin-top:14px}

  /* ---------- Hero ---------- */
  .hero{position:relative;overflow:hidden;padding:70px 0 86px}
  .hero::before{content:"";position:absolute;width:760px;height:760px;right:-240px;top:-320px;
    background:radial-gradient(circle,rgba(22,168,111,.13),transparent 62%);border-radius:50%;pointer-events:none}
  .hero::after{content:"";position:absolute;width:560px;height:560px;left:-260px;bottom:-300px;
    background:radial-gradient(circle,rgba(15,157,106,.08),transparent 62%);border-radius:50%;pointer-events:none}
  .hero .wrap{position:relative;z-index:2;display:grid;grid-template-columns:1fr 1fr;gap:54px;align-items:center}
  .badge{display:inline-flex;align-items:center;gap:9px;background:var(--card);border:1px solid var(--line);
    padding:9px 20px;border-radius:999px;font-size:14.5px;font-weight:600;color:var(--ink);margin-bottom:26px}
  .badge svg{color:var(--gold)}
  .hero h1{font-size:52px;line-height:1.3;margin-bottom:22px;letter-spacing:-.5px}
  .hero p.lead{font-size:17px;max-width:520px;margin-bottom:32px;line-height:1.85}
  .hero-cta{display:flex;gap:14px;flex-wrap:wrap;margin-bottom:44px}
  .hstats{display:grid;grid-template-columns:repeat(3,max-content);gap:44px;
    padding-top:30px;border-top:1px solid var(--line)}
  .hstats b{display:block;font-size:27px;color:var(--gold);line-height:1.25;font-weight:700}
  .hstats small{font-size:14px;color:var(--muted)}

  /* hero visual: cream panel + dark dashboard */
  .cream-panel{background:var(--cream);border-radius:22px;padding:30px;position:relative;
    box-shadow:var(--shadow-lg);overflow:hidden}
  .cream-panel::before{content:"";position:absolute;width:230px;height:230px;right:-70px;top:-90px;
    background:rgba(22,168,111,.30);border-radius:50%}
  .cp-head{position:relative;z-index:2;margin-bottom:20px}
  .cp-head small{color:#0A6F4B;font-size:14.5px;font-weight:600}
  .cp-head h2{color:#043724;font-size:25px;line-height:1.35;margin:4px 0 8px}
  .cp-head h2 span{color:#0A6F4B}
  .cp-head p{color:#525D55;font-size:14px;line-height:1.6}
  .mock{background:#111512;border:1px solid #28302A;border-radius:14px;overflow:hidden;position:relative;z-index:2}
  .mock-bar{display:flex;align-items:center;gap:7px;padding:11px 15px;background:#181D19;border-bottom:1px solid #28302A}
  .dot{width:9px;height:9px;border-radius:50%}
  .mock-bar span{margin-left:8px;font-size:12px;color:#838F87}
  .mock-body{padding:16px;display:grid;gap:12px}
  .mock-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}
  .mstat{background:#181D19;border:1px solid #28302A;border-radius:10px;padding:11px}
  .mstat small{display:block;font-size:11.5px;color:#838F87}
  .mstat b{font-size:16px;color:#fff}
  .mstat i{font-style:normal;font-size:11.5px;color:#6FCBA4;font-weight:600}
  .chart{background:#181D19;border:1px solid #28302A;border-radius:10px;padding:14px}
  .chart-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}
  .chart-head b{font-size:13.5px;color:#fff}.chart-head small{color:#838F87;font-size:11.5px}
  .bars{display:flex;align-items:flex-end;gap:8px;height:86px}
  .bars i{flex:1;border-radius:5px 5px 0 0;background:linear-gradient(180deg,#34B483,#0C8A5D)}
  .bars i.dim{background:linear-gradient(180deg,#3A473F,#28302A)}
  .play{position:absolute;left:50%;top:56%;transform:translate(-50%,-50%);width:70px;height:70px;
    border-radius:50%;background:var(--btn-grad);display:grid;place-items:center;color:var(--gold-ink);
    box-shadow:0 8px 30px rgba(15,157,106,.5);z-index:5;cursor:pointer;transition:.2s}
  .play:hover{transform:translate(-50%,-50%) scale(1.07)}
  .float-card{position:absolute;background:var(--card);border:1px solid var(--line);border-radius:12px;
    padding:11px 16px;box-shadow:var(--shadow-md);display:flex;align-items:center;gap:10px;
    font-size:13.5px;font-weight:600;color:var(--ink);z-index:6}
  .float-card svg{color:var(--gold)}
  .visual{position:relative}
  .float-card.a{left:-24px;bottom:64px}
  .float-card.b{right:-16px;top:-14px}

  /* ---------- Section head ---------- */
  .shead{text-align:center;max-width:820px;margin:0 auto 56px}
  .over{display:inline-flex;align-items:center;gap:8px;color:var(--gold);font-size:14.5px;
    font-weight:600;margin-bottom:18px;letter-spacing:.2px}
  .shead h2{font-size:38px;line-height:1.42;margin-bottom:16px;letter-spacing:-.5px}
  .shead p{font-size:16.5px;max-width:640px;margin:0 auto}

  /* ---------- Cards ---------- */
  .grid-4{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
  .grid-3{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  .grid-2{display:grid;grid-template-columns:1fr 1fr;gap:22px}
  .grid-6{display:grid;grid-template-columns:repeat(6,1fr);gap:16px}
  /*
   * .grid-5 — for a TEN-item strip, which .grid-6 renders as 6 + a ragged 4.
   *
   * The industries strip is ds_industries(), and that list is ten because the
   * site has ten trade landing pages. Six columns left four tiles alone on the
   * second row with two empty cells beside them; five gives 5 + 5.
   *
   * Purely additive — .grid-6 keeps every one of its own users and none of its
   * rules change. It steps down on the SAME breakpoints as .grid-6 rather than
   * inventing its own, so a strip that moved from one class to the other
   * behaves identically on a phone, where both are two-up.
   */
  .grid-5{display:grid;grid-template-columns:repeat(5,1fr);gap:16px}
  .card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
    padding:30px 26px;transition:.25s ease}
  .card:hover{transform:translateY(-5px);border-color:var(--gold-line);box-shadow:var(--shadow-md)}
  .icon{width:56px;height:56px;border-radius:14px;background:var(--gold-soft);border:1px solid var(--gold-line);
    display:grid;place-items:center;color:var(--gold);margin-bottom:20px}
  .card h3{font-size:18.5px;margin-bottom:10px;line-height:1.5}
  .card p{font-size:14.8px;line-height:1.8}

  /* ---------- Split ---------- */
  .split{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center}
  .split h2{font-size:36px;line-height:1.42;margin-bottom:18px;letter-spacing:-.5px}
  .split p.lead{font-size:16.5px;margin-bottom:28px;line-height:1.85}
  .nlist{display:grid;grid-template-columns:1fr 1fr;gap:26px 24px;list-style:none}
  .nlist li{display:flex;gap:14px}
  .nlist .num{width:38px;height:38px;border-radius:10px;background:var(--gold-soft);border:1px solid var(--gold-line);
    color:var(--gold);display:grid;place-items:center;font-weight:700;font-size:14px;flex:none}
  .nlist b{display:block;color:var(--ink);font-size:16px;margin-bottom:5px}
  .nlist small{font-size:14.2px;color:var(--body);line-height:1.75}

  .sync-box{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:32px;box-shadow:var(--shadow-md)}
  .sync-box h3{font-size:19px;margin-bottom:6px}
  .sync-box > p{font-size:14.5px;margin-bottom:24px}
  .sync-row{display:flex;align-items:center;gap:14px;background:var(--card-2);border:1px solid var(--line);
    border-radius:12px;padding:14px 16px;margin-bottom:12px}
  .sync-row .si{width:36px;height:36px;border-radius:10px;background:var(--gold-soft);color:var(--gold);
    display:grid;place-items:center;flex:none}
  .sync-row b{display:block;font-size:14.5px;color:var(--ink)}
  .sync-row small{font-size:12.5px;color:var(--muted)}
  .chip{margin-left:auto;background:var(--gold-soft);color:var(--gold);padding:4px 13px;
    border-radius:999px;font-size:12px;font-weight:600;white-space:nowrap}

  /* ---------- Industries ---------- */
  .ind{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:26px 16px;
    text-align:center;transition:.25s}
  .ind:hover{border-color:var(--gold);transform:translateY(-4px);box-shadow:var(--shadow-md)}
  .ind .icon{margin:0 auto 15px}
  .ind b{display:block;color:var(--ink);font-size:15.5px;margin-bottom:2px}
  .ind small{font-size:13px;color:var(--muted)}

  /* ---------- Pricing ---------- */
  .price{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:34px 30px;
    position:relative;transition:.25s}
  .price:hover{box-shadow:var(--shadow-md)}
  .price.pop{border:1px solid var(--gold);box-shadow:0 0 0 4px var(--gold-soft),var(--shadow-lg)}
  .pop-tag{position:absolute;top:-15px;left:50%;transform:translateX(-50%);background:var(--btn-grad);
    color:var(--gold-ink);padding:6px 20px;border-radius:999px;font-size:13px;font-weight:700;white-space:nowrap}
  .price h2{font-size:19px;margin-bottom:5px}
  .price .sub{font-size:14px;color:var(--muted);margin-bottom:22px}
  .amount{display:flex;align-items:flex-end;gap:7px;margin-bottom:24px;padding-bottom:24px;border-bottom:1px solid var(--line)}
  .amount b{font-size:42px;color:var(--gold);line-height:1;font-weight:700}
  .amount small{color:var(--muted);font-size:15px;padding-bottom:6px}
  .price ul{list-style:none;display:grid;gap:13px;margin-bottom:28px}
  .price li{display:flex;gap:11px;align-items:flex-start;font-size:14.8px}
  .price li svg{color:var(--gold);flex:none;margin-top:5px}
  .price .btn{width:100%}

  /* ---------- CTA ---------- */
  .cta{border-radius:26px;padding:60px 46px;text-align:center;position:relative;overflow:hidden;
    background:linear-gradient(120deg,#062A1C,#043724 40%,#121713);border:1px solid var(--gold-line)}
  .cta::before{content:"";position:absolute;width:420px;height:420px;right:-120px;top:-190px;
    background:radial-gradient(circle,rgba(22,168,111,.22),transparent 65%);border-radius:50%}
  .cta > *{position:relative;z-index:2}
  .cta h2{font-size:36px;color:#fff;margin-bottom:14px;line-height:1.4}
  .cta p{color:#96A29A;font-size:16.5px;max-width:580px;margin:0 auto 30px}
  .cta-btns{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}
  .cta .btn-line{color:#fff;border-color:rgba(255,255,255,.28)}
  .cta .btn-line:hover{border-color:var(--gold);color:var(--gold)}

  /* ---------- FAQ ---------- */
  .faq-list{max-width:830px;margin:0 auto;display:grid;gap:14px}
  .faq{background:var(--card);border:1px solid var(--line);border-radius:14px;overflow:hidden;transition:.2s}
  .faq.open{border-color:var(--gold-line)}
  .faq button{width:100%;display:flex;justify-content:space-between;align-items:center;gap:18px;
    padding:20px 24px;background:none;border:0;cursor:pointer;text-align:left;
    font-family:inherit;font-size:16.5px;font-weight:600;color:var(--ink)}
  .faq .chev{width:28px;height:28px;border-radius:50%;background:var(--gold-soft);color:var(--gold);
    display:grid;place-items:center;flex:none;transition:.25s}
  .faq.open .chev{background:var(--btn-grad);color:var(--gold-ink);transform:rotate(180deg)}
  .faq .ans{max-height:0;overflow:hidden;transition:max-height .3s ease}
  .faq.open .ans{max-height:260px}
  .faq .ans p{padding:0 24px 22px;font-size:15.2px;line-height:1.85}

  /* ---------- Contact ---------- */
  .contact-card{display:flex;gap:16px;align-items:center;background:var(--card);border:1px solid var(--line);
    border-radius:14px;padding:24px;transition:.25s}
  .contact-card:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md)}
  .contact-card .icon{margin:0;width:48px;height:48px;border-radius:12px}
  .contact-card b{display:block;color:var(--ink);font-size:16px}
  .contact-card small{font-size:14.2px;color:var(--body)}

  /* ---------- Footer ---------- */
  footer{background:var(--footer-bg);color:#96A29A;padding:70px 0 0;--gold:#6FCBA4;--gold-ink:#043724;--btn-grad:linear-gradient(135deg,#6FCBA4,#34B483)}
  .fgrid{display:grid;grid-template-columns:1.7fr 1fr 1fr 1fr;gap:44px;padding-bottom:48px}
  footer h2{color:#fff;font-size:16px;margin-bottom:20px}
  footer .logo{color:#fff;margin-bottom:18px}
  footer p{font-size:14.5px;line-height:1.85;max-width:330px}
  footer ul{list-style:none;display:grid;gap:12px}
  footer ul a{font-size:14.5px;transition:.2s}
  footer ul a:hover{color:var(--gold);padding-left:4px}
  .socials{display:flex;gap:10px;margin-top:22px}
  .socials a{width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,.06);
    display:grid;place-items:center;color:#fff;transition:.2s}
  .socials a:hover{background:var(--btn-grad);color:var(--gold-ink)}
  .fbot{border-top:1px solid rgba(255,255,255,.08);padding:22px 0;display:flex;
    justify-content:space-between;gap:14px;flex-wrap:wrap;font-size:14px}
  .fbot a:hover{color:var(--gold)}

  /* ── Footer links, made big enough to actually hit ────────────────────

     MEASURED 2026-08-25 on a 390px phone. Every page carried six to ten tap
     targets under 40px, and the smallest were these:

         20 x 23   "দাম"            <- twenty pixels wide
         41 x 23   "প্রশ্নোত্তর"
         51 x 23   "যোগাযোগ"
         75 x 23   "মূল ওয়েবসাইট"

     Google asks for 48x48 and Apple for 44x44. Twenty-three pixels tall is
     about four millimetres on a handset — a fingertip is eight to ten. This
     product is sold to shopkeepers, plenty of them middle-aged and reading
     in daylight with one hand on a counter, so this is not a rounding error
     on an accessibility checklist; it is the footer of the page every
     advertisement lands on.

     Padding rather than font-size: the type stays exactly as designed and
     only the hit area grows. `inline-block` because padding on an inline
     element does not extend the box a finger has to land in — which is the
     failure this rule would otherwise still have, invisibly. The negative
     margin keeps the row looking the same height as before. */
  .fbot a{display:inline-block;padding:11px 8px;margin:-11px 0;min-width:44px;text-align:center}


  /* ---------- Hero chips ---------- */
  .chips{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:30px}
  .chip-i{display:inline-flex;align-items:center;gap:8px;background:var(--card);border:1px solid var(--line);
    padding:8px 15px;border-radius:999px;font-size:13.8px;font-weight:600;color:var(--ink);transition:.2s}
  .chip-i:hover{border-color:var(--gold-line);transform:translateY(-2px)}
  .chip-i svg{color:var(--gold)}

  /* ---------- Counters ---------- */
  .counters{display:grid;grid-template-columns:repeat(4,1fr);gap:22px}
  /* A four-column row with one tile in it leaves three quarters of the section
     empty, which is what /offer renders whenever `stats.districts.value` is
     unset — and unset is what the live payload says. The row is told to fit
     what it has rather than being filled with a second figure, because the only
     available second figure would be an invented one and that is the defect
     that emptied this row to begin with. Modifier class: nothing that does not
     ask for it is affected. */
  .counters.counters-1{grid-template-columns:minmax(0,320px);justify-content:center}

  /* ---------- The free-trial band (/offer, under the package grid) ----------
     The sentence it carries was already on the page as a `<p class="small">`
     caption and it was the ONLY mention of the trial anywhere on /offer — the
     single most persuasive fact available to a reader who has just read three
     yearly prices, set in the smallest type on the page and not a link.

     So it is given the weight of the thing it is: the row after the prices,
     tinted rather than boxed so it reads as a continuation of the grid above
     and not as another card competing with it. Text left, button right on a
     desktop; stacked and full-width on a phone, where a button beside a
     paragraph is a button nobody's thumb reaches. The 640px breakpoint is
     where the two-column form drops to one on this page already.
     ------------------------------------------------------------------- */
  .trialband{display:flex;align-items:center;justify-content:space-between;gap:26px;flex-wrap:wrap;
    margin-top:26px;padding:26px 30px;border-radius:20px;
    background:var(--gold-soft);border:1px solid var(--gold-line)}
  .trialband h3{font-size:19px;color:var(--ink);margin-bottom:7px;line-height:1.45}
  .trialband p{font-size:14.6px;line-height:1.8;color:var(--body);margin:0;max-width:620px}
  .trialband .btn{flex:none}
  @media(max-width:640px){
    .trialband{padding:22px 20px;gap:18px}
    .trialband h3{font-size:17.5px}
    .trialband .btn{width:100%;flex:auto}
  }
  .cnt{background:var(--card);border:1px solid var(--line);border-radius:18px;padding:30px 24px;text-align:center;transition:.25s}
  .cnt:hover{border-color:var(--gold-line);transform:translateY(-4px)}
  .cnt .icon{margin:0 auto 16px;width:50px;height:50px;border-radius:13px}
  .cnt b{display:block;font-size:35px;line-height:1.2;background:var(--grad);
    -webkit-background-clip:text;background-clip:text;color:transparent;font-weight:700}
  .cnt small{font-size:14.5px;color:var(--body)}

  /* ---------- "Data from 42 minutes ago" ----------
     Sits under any block of live ERP figures. Muted and small on purpose: it
     is a timestamp, not a warning, and styling a normal cache age as a problem
     would teach visitors to doubt prices that are perfectly correct. */
  .dataage{margin-top:14px;text-align:center;font-size:13px;color:var(--muted)}

  /* ---------- Detailed feature cards ---------- */
  .fcard{background:var(--card);border:1px solid var(--line);border-radius:18px;padding:28px 26px;transition:.25s}
  .fcard:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md);transform:translateY(-4px)}
  .fcard .fhead{display:flex;align-items:center;gap:14px;margin-bottom:18px}
  .fcard .icon{margin:0;width:48px;height:48px;border-radius:13px}
  .fcard h3{font-size:17.5px;line-height:1.45}
  .fcard ul{list-style:none;display:grid;gap:11px}
  .fcard li{display:flex;gap:10px;align-items:flex-start;font-size:14.5px;line-height:1.7}
  .fcard li svg{color:var(--gold);flex:none;margin-top:5px}

  .why-strip{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:26px;
    background:linear-gradient(100deg,rgba(22,168,111,.09),rgba(15,157,106,.05));
    border:1px solid var(--gold-line);border-radius:20px;padding:30px}
  .why-strip .w{display:flex;gap:14px;align-items:flex-start}
  .why-strip .wi{width:42px;height:42px;border-radius:12px;background:var(--btn-grad);color:var(--gold-ink);
    display:grid;place-items:center;flex:none}
  .why-strip b{display:block;color:var(--ink);font-size:16px;margin-bottom:4px}
  .why-strip small{font-size:14px;color:var(--body);line-height:1.7}

  /* ---------- Screenshot showcase ---------- */
  .tabs{display:flex;flex-wrap:wrap;gap:9px;justify-content:center;margin-bottom:34px}
  .tab{padding:10px 22px;border-radius:999px;border:1px solid var(--line);background:var(--card);
    color:var(--body);font-family:inherit;font-size:14.5px;font-weight:600;cursor:pointer;transition:.2s}
  .tab:hover{border-color:var(--gold-line);color:var(--ink)}
  .tab.on{background:var(--btn-grad);color:var(--gold-ink);border-color:transparent;box-shadow:var(--glow)}
  .frame{background:#111512;border:1px solid #28302A;border-radius:18px;overflow:hidden;box-shadow:var(--shadow-lg)}
  .frame-bar{display:flex;align-items:center;gap:7px;padding:12px 16px;background:#181D19;border-bottom:1px solid #28302A}
  .frame-bar span{margin-left:8px;font-size:12px;color:#838F87}
  .app{display:grid;grid-template-columns:190px 1fr;min-height:400px}
  .side{background:#141A15;border-right:1px solid #28302A;padding:16px 12px}
  .side a{display:flex;align-items:center;gap:10px;padding:9px 12px;border-radius:9px;
    font-size:13.5px;color:#96A29A;margin-bottom:3px}
  .side a.on{background:rgba(22,168,111,.14);color:#6FCBA4;font-weight:600}
  .side a svg{opacity:.9}
  .pane{padding:20px;display:none}
  .pane.on{display:block}
  .pane .pane-title{color:#fff;font-size:16px;margin-bottom:16px;display:flex;align-items:center;gap:10px}
  .pane .pane-title span{margin-left:auto;font-size:12px;font-weight:600;color:#6FCBA4;
    background:rgba(22,168,111,.14);padding:4px 12px;border-radius:999px}
  .tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:11px;margin-bottom:16px}
  .tile{background:#181D19;border:1px solid #28302A;border-radius:11px;padding:13px}
  .tile small{display:block;font-size:11.5px;color:#838F87;margin-bottom:3px}
  .tile b{font-size:17px;color:#fff}
  .tbl{width:100%;border-collapse:collapse;font-size:13px}
  .tbl th{text-align:left;color:#838F87;font-weight:600;padding:9px 12px;border-bottom:1px solid #28302A;font-size:12px}
  .tbl td{padding:11px 12px;border-bottom:1px solid #212823;color:#B8C2BB}
  .tbl td b{color:#fff;font-weight:600}
  .tbl tr:last-child td{border-bottom:0}
  .pg{padding:3px 11px;border-radius:999px;font-size:11.5px;font-weight:600;display:inline-block}
  .pg.ok{background:rgba(22,168,111,.16);color:#6FCBA4}
  .pg.warn{background:rgba(251,191,36,.14);color:#FBBF24}
  .pg.due{background:rgba(248,113,113,.13);color:#F87171}
  .pos-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:14px}
  .pitem{background:#181D19;border:1px solid #28302A;border-radius:11px;padding:13px;text-align:center}
  .pitem b{display:block;color:#fff;font-size:13px;margin-bottom:3px}
  .pitem small{color:#6FCBA4;font-size:12.5px;font-weight:600}
  .cartline{display:flex;justify-content:space-between;padding:9px 13px;background:#181D19;
    border:1px solid #28302A;border-radius:9px;margin-bottom:7px;font-size:13px;color:#B8C2BB}
  .cartline b{color:#fff}
  .total{display:flex;justify-content:space-between;padding:13px;background:rgba(22,168,111,.10);
    border:1px solid rgba(22,168,111,.26);border-radius:10px;font-size:15px;color:#6FCBA4;font-weight:700}

  /* ---------- Pricing extras ---------- */
  .ptoggle{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--line);background:var(--card);
    padding:5px;border-radius:999px;margin:0 auto 40px;justify-self:center}
  .ptoggle button{padding:9px 22px;border:0;border-radius:999px;background:none;color:var(--body);
    font-family:inherit;font-size:14.5px;font-weight:600;cursor:pointer;transition:.2s;display:flex;align-items:center;gap:8px}
  .ptoggle button.on{background:var(--btn-grad);color:var(--gold-ink)}
  .ptoggle .save{background:rgba(22,168,111,.15);color:var(--ok);font-size:11.5px;padding:2px 9px;border-radius:999px}
  .ptoggle button.on .save{background:rgba(0,0,0,.16);color:var(--gold-ink)}
  .install{display:flex;align-items:center;gap:9px;font-size:13.2px;color:var(--muted);
    margin-top:-10px;margin-bottom:22px;padding-bottom:20px;border-bottom:1px dashed var(--line)}
  .install svg{color:var(--gold);flex:none}
  .yr{display:none}
  .price.year .mo{display:none}
  .price.year .yr{display:flex}

  /* ---------- Offices ---------- */
  .office{background:var(--card);border:1px solid var(--line);border-radius:18px;padding:28px;transition:.25s}
  .office:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md)}
  .office .ohead{display:flex;align-items:center;gap:12px;margin-bottom:16px}
  .office .oi{width:44px;height:44px;border-radius:12px;background:var(--gold-soft);border:1px solid var(--gold-line);
    color:var(--gold);display:grid;place-items:center;flex:none}
  .office h3{font-size:17px}
  .office .obadge{margin-left:auto;font-size:11.5px;font-weight:600;color:var(--gold);
    background:var(--gold-soft);padding:4px 12px;border-radius:999px}
  .office p{font-size:14.5px;line-height:1.8;margin-bottom:16px}
  .office .orow{display:flex;align-items:center;gap:10px;font-size:14.5px;color:var(--ink);
    padding:11px 14px;background:var(--card-2);border:1px solid var(--line);border-radius:11px;margin-bottom:9px}
  .office .orow:last-child{margin-bottom:0}
  .office .orow svg{color:var(--gold);flex:none}

  /* ---------- Trust badges ---------- */
  .trustbar{border-top:1px solid var(--line);border-bottom:1px solid var(--line);background:var(--bg-alt);padding:22px 0}
  .tbadges{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:14px 34px}
  .tbadge{display:flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:var(--body)}
  .tbadge svg{color:var(--gold);flex:none}
  .tbadge b{color:var(--ink);font-weight:600}
  .paylogos{display:flex;gap:9px;align-items:center}
  .plogo{padding:5px 12px;border-radius:8px;font-size:12px;font-weight:700;color:#fff;font-family:inherit}
  /* ── w-pay: payment marks on white tiles ──────────────────────────────
     Every brand here is drawn FOR white — bKash magenta, Rocket purple,
     Dutch-Bangla blue. On this page's near-black ground they lose contrast
     against each other rather than against the page, which is why one shared
     white tile beats tinting each mark: it treats every brand identically and
     it works in BOTH themes without a second rule. */
  .tbadge-pay{gap:12px}
  .paylabel{font-weight:600;color:var(--body);white-space:nowrap}
  .paytile{display:inline-flex;align-items:center;justify-content:center;
    background:#fff;border-radius:8px;padding:7px 11px;min-height:38px;
    box-shadow:0 1px 2px rgba(4,55,36,.10);flex:none}
  /* The wordmark tiles carry no artwork, so they need their own type scale to
     sit at the same optical weight as a drawn logo beside them. */
  .paytile-wm{padding:8px 12px}
  .wm{font-size:13px;font-weight:800;letter-spacing:-.01em;line-height:1;white-space:nowrap}
  .wm i{font-style:normal;font-weight:600;font-size:9.5px;opacity:.72;margin-left:3px;
    vertical-align:.12em;letter-spacing:.04em}
  @media (max-width:640px){
    .paytile{padding:6px 9px;min-height:34px}
    .wm{font-size:12px}
  }

  /* ---------- Steps ---------- */
  .steps{display:grid;grid-template-columns:repeat(3,1fr);gap:24px;position:relative}
  .steps::before{content:"";position:absolute;top:36px;left:16%;right:16%;height:2px;
    background:linear-gradient(90deg,var(--gold-line),var(--gold),var(--gold-line));opacity:.5}
  .step{text-align:center;position:relative;z-index:2}
  .step .sn{width:72px;height:72px;border-radius:22px;background:var(--btn-grad);color:var(--gold-ink);
    display:grid;place-items:center;margin:0 auto 20px;font-size:26px;font-weight:700;
    box-shadow:var(--glow);border:4px solid var(--bg)}
  .step h3{font-size:19px;margin-bottom:9px}
  .step p{font-size:14.8px;max-width:290px;margin:0 auto}

  /* ---------- Calculator ---------- */
  .calc{display:grid;grid-template-columns:1fr 1fr;gap:34px;background:var(--card);
    border:1px solid var(--line);border-radius:24px;padding:38px;box-shadow:var(--shadow-md)}
  .calc-in label{display:block;font-size:14.5px;font-weight:600;color:var(--ink);margin-bottom:12px}
  .calc-in .val{color:var(--gold);font-weight:700;font-size:19px}
  .calc-in .fld{margin-bottom:28px}
  input[type=range]{-webkit-appearance:none;appearance:none;width:100%;height:6px;border-radius:999px;
    background:var(--card-2);border:1px solid var(--line);outline:none}
  input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:24px;height:24px;border-radius:50%;
    background:var(--btn-grad);cursor:pointer;box-shadow:var(--glow);border:3px solid var(--bg)}
  input[type=range]::-moz-range-thumb{width:22px;height:22px;border-radius:50%;background:var(--gold);
    cursor:pointer;border:3px solid var(--bg)}
  .rng-note{display:flex;justify-content:space-between;font-size:12.5px;color:var(--muted);margin-top:8px}
  .calc-out{background:linear-gradient(140deg,rgba(22,168,111,.12),rgba(15,157,106,.06));
    border:1px solid var(--gold-line);border-radius:18px;padding:28px;display:flex;flex-direction:column;justify-content:center}
  .calc-out .big{font-size:44px;line-height:1.15;font-weight:700;background:var(--grad);
    -webkit-background-clip:text;background-clip:text;color:transparent;margin-bottom:4px}
  .calc-out .cap{font-size:14.5px;color:var(--body);margin-bottom:22px}
  .crow{display:flex;justify-content:space-between;align-items:center;padding:11px 0;
    border-bottom:1px dashed var(--line);font-size:14.5px}
  .crow:last-of-type{border-bottom:0}
  .crow b{color:var(--ink)}
  .crow.net{margin-top:10px;padding:14px 16px;background:var(--card);border:1px solid var(--gold-line);
    border-radius:12px;border-bottom:1px solid var(--gold-line)}
  .crow.net b{color:var(--gold);font-size:17px}

  /* ---------- Comparison table ---------- */
  .cmp-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:20px;background:var(--card)}
  .cmp{width:100%;border-collapse:collapse;min-width:640px}
  .cmp th,.cmp td{padding:16px 20px;text-align:left;border-bottom:1px solid var(--line);font-size:14.8px}
  .cmp thead th{background:var(--card-2);color:var(--muted);font-size:14px;font-weight:600}
  .cmp thead th.us{color:var(--gold);background:var(--gold-soft);font-size:15.5px;font-weight:700}
  .cmp tbody td:first-child{color:var(--ink);font-weight:600}
  .cmp td.us{background:var(--gold-soft)}
  .cmp tr:last-child td{border-bottom:0}
  .yes{color:var(--ok)}.no{color:var(--neg)}.mid{color:var(--muted)}

  /* ---------- Testimonials ---------- */
  .tst-track{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  .tst{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:28px;transition:.25s;display:none}
  .tst.show{display:block}
  .tst:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md);transform:translateY(-4px)}
  .stars{display:flex;gap:3px;color:var(--gold);margin-bottom:16px}
  .tst q{display:block;font-size:15.2px;line-height:1.85;color:var(--body);margin-bottom:22px;quotes:none}
  .tst-who{display:flex;align-items:center;gap:13px;padding-top:18px;border-top:1px solid var(--line)}
  .av{width:48px;height:48px;border-radius:50%;background:var(--btn-grad);color:var(--gold-ink);
    display:grid;place-items:center;font-weight:700;font-size:18px;flex:none}
  .tst-who b{display:block;color:var(--ink);font-size:15.5px}
  .tst-who small{font-size:13.2px;color:var(--muted)}
  .tst-nav{display:flex;justify-content:center;gap:9px;margin-top:30px}
  .tdot{width:9px;height:9px;border-radius:50%;background:var(--line);border:0;cursor:pointer;transition:.2s;padding:0}
  .tdot.on{width:28px;border-radius:999px;background:var(--btn-grad)}

  /* ---------- Testimonials that swipe on a phone ----------
     Owner: "review ta mobile screen er jonno sliding system kore daw."

     `.tst-swipe` is a MODIFIER and that is the whole point of it. `.tst-track`
     is drawn by eight pages — index, pricing, compare, grocery, pharmacy,
     stories, offer and the case studies — and the instruction was for /offer,
     which is the page he is looking at and the one being bought traffic for.
     A bare `.tst-track` rule here would have silently restyled seven other
     pages nobody asked about. Only markup that asks for the class gets it, so
     lifting this to another page later is one class on one div and no CSS
     change at all.

     ── Why scroll-snap and not a carousel script ─────────────────────────
     This site has no carousel dependency and must not grow one for three
     quotes. An `overflow-x:auto` track with scroll-snap swipes natively with a
     finger, scrolls with a trackpad, moves with the arrow keys once focused,
     and — this is the part a script cannot match — WORKS WITH JAVASCRIPT OFF,
     which on a Facebook in-app browser on a cheap Android is not a hypothetical
     audience. The `.tdot` group-switcher above is JS and is a different
     mechanism for a different thing; /offer draws no dots and none is added.

     ── The specificity is deliberate, not decorative ─────────────────────
     `.tst-track.tst-swipe` is (0,2,0) against `.tst-track`'s (0,1,0), so it
     beats the `grid-template-columns:1fr` that the <=768 block sets on
     `.dl,.vids,.blogs,.tst-track` several hundred lines below this one. Written
     as a single class it would have tied on specificity and lost on source
     order, and it would have lost SILENTLY — the track would simply have gone
     on stacking and looked like the feature had not been asked for.

     ── No full-bleed, on purpose ─────────────────────────────────────────
     The obvious way to make cards run to the screen edge is a negative inline
     margin cancelling `.wrap`'s 22px padding. It is also the classic way to
     give a document a horizontal scrollbar, and horizontal overflow at 320-414
     is a live failure mode on this site rather than a theoretical one — it was
     found on the nav drawer earlier today. So the track stays inside the
     padding it was given, the 88% card width is what makes the next card peek,
     and the page's own scrollWidth is untouched. Asserted at 320, 360, 390 and
     414.

     ── Where the snap points are, and why `start` with a trailing margin ──
     `scroll-snap-align:start`, cards one gutter narrower than the track, and a
     gutter of trailing margin on the last card. Each of those three exists to
     stop a specific failure, and the third one is the subtle one.

     Under `snap-type:mandatory` a card whose snap position lies beyond the
     container's maximum scroll offset can never be brought fully into view —
     the browser clamps the scroll and the card stays permanently short. With
     `start` on all three, the third card wants to BEGIN at 2×(card+gap) while
     the furthest the track can scroll is scrollWidth−clientWidth, and with
     cards one gutter narrower than the track those two do not meet: the third
     card lands a gutter shy and no amount of swiping finishes the job.

     Writing `end` on the last card is what closes it, and it closes exactly.
     For a card of width C−34 with 14px gaps, the last card's END-aligned snap
     position works out to 2C−74, which IS scrollWidth−clientWidth — so the
     furthest the track can go is precisely where that card sits flush against
     the right edge, with card two's tail peeking on the left to say where you
     came from. The first two keep `start`, so their snap positions are 0 and
     C−20, both comfortably inside the range.

     A trailing MARGIN on the last card also makes it reachable and was tried
     first; it leaves the card flush left at the end with 34px of empty track to
     its right, which reads as a fourth card that failed to load. Measured at
     320/360/390/414: settled end-scroll equals maxScroll and the third card's
     left and right gaps are both zero.

     `calc(100% - 34px)` and the 34px margin are ONE number written twice and
     they have to stay in step. The 34px is also the affordance: it is what of
     card two is visible at rest, which is how a reader knows the row moves.

     Percentages were tried here and are a trap worth naming, because it cost a
     round: a percentage flex-basis resolves against the flex container's
     CONTENT box, so trailing padding on the track shrinks the very width the
     cards are a percentage of. Cards specified at 88% measured 77% and the row
     came up short of the right edge by the padding. `calc(100% - 34px)` on the
     item and a margin on the item have no such feedback.

     ── No track padding and no negative margins, deliberately ────────────
     An earlier version padded the track and cancelled the padding with negative
     margins so the hover shadow would not clip. At 360px that produced a
     document scrollWidth of 361 against a clientWidth of 360 — one pixel of
     horizontal page scroll, which is the exact failure this whole block is
     supposed to avoid and which nobody would ever see in a screenshot. The
     hover lift is switched off on touch below instead, which is what should
     have happened first, and the focus ring is an `outline` — outlines are not
     clipped by an element's own overflow, so it never needed the room.

     ── A note on the first card, and on trusting a harness ───────────────
     The browser check reported the first card clipped by 5-19px at all four
     widths and it was WRONG — it was reading scrollLeft while a `scroll-
     behavior:smooth` animation started by the check itself was still running.
     The page was fine. It is recorded here because the failure was convincing:
     four widths, a width-dependent offset, a plausible mechanism. The harness
     now polls until scrollLeft stops changing before it measures anything, and
     the settled rest position is 0 at every width with the first card flush. */
  @media(max-width:768px){
    .tst-track.tst-swipe{
      display:flex;
      gap:14px;
      overflow-x:auto;
      /* The page must not rubber-band sideways when the track hits its end. */
      overscroll-behavior-x:contain;
      scroll-snap-type:x mandatory;
      scroll-behavior:smooth;
      -webkit-overflow-scrolling:touch;
      scrollbar-width:none;
    }
    .tst-track.tst-swipe::-webkit-scrollbar{display:none}
    .tst-track.tst-swipe > .tst{
      flex:0 0 calc(100% - 34px);
      /* Without this a flex item refuses to shrink below its longest
         unbreakable run of text, and a Bangla quote gives a browser very few
         places it is willing to break — that is how a track like this ends up
         wider than it thinks it is. */
      min-width:0;
      scroll-snap-align:start;
    }
    /* See the note above: this is what makes the third card reachable, and it
       is the whole of the mechanism — no trailing margin, no spacer element. */
    .tst-track.tst-swipe > .tst:last-child{scroll-snap-align:end}
    /* :hover sticks after a tap on touch, and a card left lifted inside a
       scroll container reads as a rendering fault rather than as a hover. */
    .tst-track.tst-swipe > .tst:hover{transform:none;box-shadow:none;border-color:var(--line)}
    /* The track is a tab stop (tabindex="0" in the markup) because the cards
       hold no focusable children — without it a keyboard or switch user can
       reach the first quote and never the second or third. A tab stop with no
       visible ring is its own defect, so it gets one. */
    .tst-track.tst-swipe:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:22px}
  }
  @media(prefers-reduced-motion:reduce){
    .tst-track.tst-swipe{scroll-behavior:auto}
  }

  /* ---------- Case study ---------- */
  .case{display:grid;grid-template-columns:1.15fr .85fr;gap:36px;align-items:center;margin-top:34px;
    background:linear-gradient(120deg,rgba(22,168,111,.10),rgba(15,157,106,.05));
    border:1px solid var(--gold-line);border-radius:24px;padding:38px}
  .case .over{margin-bottom:14px}
  .case h3{font-size:26px;line-height:1.45;margin-bottom:14px}
  .case p{font-size:15.2px;line-height:1.85;margin-bottom:22px}
  .case-stats{display:grid;grid-template-columns:repeat(2,1fr);gap:14px}
  .cs{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:20px}
  .cs b{display:block;font-size:28px;color:var(--gold);line-height:1.2}
  .cs small{font-size:13.5px;color:var(--body)}

  /* ---------- Integrations ---------- */
  .integ{display:grid;grid-template-columns:repeat(7,1fr);gap:14px}
  .ilogo{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:22px 10px;
    text-align:center;transition:.25s}
  .ilogo:hover{border-color:var(--gold-line);transform:translateY(-4px)}
  .ilogo .ib{width:44px;height:44px;border-radius:12px;display:grid;place-items:center;margin:0 auto 11px;
    color:#fff;font-weight:700;font-size:17px;font-family:inherit}
  .ilogo b{display:block;font-size:13.5px;color:var(--ink);font-weight:600}
  .ilogo small{font-size:11.5px;color:var(--muted)}

  /* ---------- Download ---------- */
  .dl{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  .dcard{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:30px;transition:.25s}
  .dcard:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md);transform:translateY(-4px)}
  .dcard .icon{margin-bottom:18px}
  .dcard h3{font-size:18.5px;margin-bottom:8px}
  .dcard p{font-size:14.5px;margin-bottom:12px}
  .dmeta{display:flex;gap:14px;font-size:12.5px;color:var(--muted);margin-bottom:20px;flex-wrap:wrap}
  .dmeta span{display:flex;align-items:center;gap:6px}
  .dcard .btn{width:100%}
  /* Coming soon: present, legible, and plainly not pressable. It keeps the
     card's shape so the row still reads as three offers, and loses the hover
     lift so a finger learns there is nothing under it. */
  .dcard.dsoon{border-style:dashed}
  .dcard.dsoon:hover{border-color:var(--line);box-shadow:none;transform:none}
  .dcard.dsoon .icon{opacity:.55}
  .btn-soon{display:flex;align-items:center;justify-content:center;
    background:transparent;border:1px dashed var(--line);color:var(--muted);cursor:default}
  .btn-soon:hover{background:transparent;border-color:var(--line);color:var(--muted);transform:none;box-shadow:none}

  /* ---------- Plan table ---------- */
  .ptable{margin-top:44px}
  .ptable .cmp thead th:nth-child(3){color:var(--gold);background:var(--gold-soft)}
  .ptable .cmp td:nth-child(3){background:var(--gold-soft)}
  .ptable .cmp th:not(:first-child),.ptable .cmp td:not(:first-child){text-align:center}

  /* ---------- Demo access ---------- */
  .demo{display:grid;grid-template-columns:1fr 1fr;gap:36px;align-items:center;
    background:linear-gradient(120deg,#062A1C,#043724 45%,#121713);border:1px solid var(--gold-line);
    border-radius:24px;padding:42px;position:relative;overflow:hidden}
  .demo::before{content:"";position:absolute;width:380px;height:380px;right:-130px;top:-170px;
    background:radial-gradient(circle,rgba(22,168,111,.20),transparent 65%);border-radius:50%}
  .demo > *{position:relative;z-index:2}
  .demo h2{color:#fff;font-size:31px;line-height:1.42;margin-bottom:14px}
  .demo p{color:#96A29A;font-size:15.5px;margin-bottom:24px}
  .demo .btn-line{color:#fff;border-color:rgba(255,255,255,.28)}
  .cred{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12);border-radius:18px;padding:26px}
  .cred h3{color:#fff;font-size:16px;margin-bottom:18px;display:flex;align-items:center;gap:9px}
  .cred h3 svg{color:var(--gold)}
  .crd{display:flex;align-items:center;gap:12px;background:rgba(0,0,0,.28);border:1px solid rgba(255,255,255,.10);
    border-radius:12px;padding:13px 16px;margin-bottom:11px}
  .crd small{font-size:12.5px;color:#96A29A;width:74px;flex:none}
  .crd code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14.5px;color:#B9E2CF;letter-spacing:.4px;flex:1}
  .copy{background:rgba(22,168,111,.16);border:0;color:#6FCBA4;border-radius:8px;padding:6px 12px;
    font-size:12px;font-weight:600;cursor:pointer;font-family:inherit;transition:.2s}
  .copy:hover{background:var(--btn-grad);color:var(--gold-ink)}
  .cred .btn{width:100%;margin-top:8px}

  /* ---------- Videos ---------- */
  .vids{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  .vid{background:var(--card);border:1px solid var(--line);border-radius:18px;overflow:hidden;transition:.25s;display:block}
  .vid:hover{border-color:var(--gold-line);transform:translateY(-4px);box-shadow:var(--shadow-md)}
  .thumb{height:170px;position:relative;display:grid;place-items:center;
    background:linear-gradient(135deg,#043724,#08573B 50%,#121713)}
  .thumb .vp{width:56px;height:56px;border-radius:50%;background:var(--btn-grad);color:var(--gold-ink);
    display:grid;place-items:center;box-shadow:0 6px 22px rgba(15,157,106,.45);transition:.25s}
  .vid:hover .thumb .vp{transform:scale(1.12)}
  .thumb .dur{position:absolute;right:12px;bottom:12px;background:rgba(0,0,0,.65);color:#fff;
    padding:3px 10px;border-radius:6px;font-size:12px;font-weight:600}
  .vid .vb{padding:20px}
  .vid b{display:block;color:var(--ink);font-size:16px;margin-bottom:6px;line-height:1.5}
  .vid small{font-size:13.5px;color:var(--muted)}

  /* ---------- Blog ---------- */
  .blogs{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
  .bcard{background:var(--card);border:1px solid var(--line);border-radius:18px;padding:26px;transition:.25s;display:block}
  .bcard:hover{border-color:var(--gold-line);transform:translateY(-4px);box-shadow:var(--shadow-md)}
  .bcat{display:inline-block;background:var(--gold-soft);color:var(--gold);padding:4px 13px;
    border-radius:999px;font-size:12px;font-weight:600;margin-bottom:14px}
  .bcard h3{font-size:17.5px;line-height:1.55;margin-bottom:10px}
  .bcard p{font-size:14.2px;line-height:1.75;margin-bottom:16px}
  .bmeta{display:flex;align-items:center;gap:14px;font-size:12.8px;color:var(--muted);
    padding-top:14px;border-top:1px solid var(--line)}
  .bmeta span{display:flex;align-items:center;gap:6px}

  /* ---------- sp1: staff-published entries (/blog, /videos, /stories) ------
     The three pages are rendered from data/cache/site.json now rather than
     from cards typed into the markup. These are the four rules that needed
     adding; everything else reuses .bcard, .bcat, .vid and .prose exactly as
     they were, which is why a published article looks like the page it landed
     on rather than like a new section of the site.
     ------------------------------------------------------------------------ */
  /* The cover. `aspect-ratio` and not a fixed height: a reserved box of the
     right SHAPE means nothing jumps when the bytes land, at any column width,
     including the single column the <=768 block collapses .blogs to.

     Inset inside the card's padding rather than bled to its edge with a
     negative margin. Full-bleed needs `overflow:hidden` on .bcard to keep the
     corners, and .bcard is a SHARED class — adding it there would clip
     something on a page nobody looked at. Eighteen pixels of border is not
     worth that. */
  .pcover{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;
    border-radius:12px;margin-bottom:18px;background:var(--gold-soft)}
  .pdate{display:block;font-size:12.8px;color:var(--muted);padding-top:14px;border-top:1px solid var(--line)}
  .vid .pdate{padding-top:12px;margin-top:12px}
  /* The player box. Sized by ratio for the same reason as the cover — an iframe
     with no height is a zero-pixel element until YouTube answers. */
  .vembed{position:relative;aspect-ratio:16/9;background:#000;border-radius:18px 18px 0 0;overflow:hidden}
  .vembed iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
  /* A published article's own page: the body paragraphs, and the cover above
     them. `.prose` already sets the measure and the rhythm. */
  .postcover{display:block;width:100%;aspect-ratio:16/9;object-fit:cover;
    border-radius:18px;margin-bottom:28px;background:var(--gold-soft)}

  /* ---------- Floating WhatsApp + toast + mobile bar ---------- */
  .fab{position:fixed;right:22px;bottom:24px;z-index:90;display:flex;flex-direction:column;gap:12px}
  .fab a,.fab button{width:56px;height:56px;border-radius:50%;font:inherit;padding:0;cursor:pointer;display:grid;place-items:center;color:#fff;
    box-shadow:0 8px 26px rgba(0,0,0,.35);transition:.25s;position:relative}
  .fab a:hover,.fab button:hover{transform:translateY(-3px) scale(1.05)}
  .fab .up{background:var(--card);border:1px solid var(--line);color:var(--ink);width:46px;height:46px;
    margin-left:5px;opacity:0;visibility:hidden}
  .fab .up.show{opacity:1;visibility:visible}

  .toast{position:fixed;left:22px;bottom:24px;z-index:88;display:flex;align-items:center;gap:13px;
    background:var(--card);border:1px solid var(--line);border-radius:14px;padding:13px 18px 13px 14px;
    box-shadow:var(--shadow-lg);max-width:330px;transform:translateY(140%);transition:.45s cubic-bezier(.2,.8,.3,1)}
  .toast.show{transform:translateY(0)}
  .toast .ta{width:38px;height:38px;border-radius:50%;background:var(--gold-soft);color:var(--gold);
    display:grid;place-items:center;flex:none}
  .toast b{display:block;color:var(--ink);font-size:14px;line-height:1.5}
  .toast small{font-size:12.2px;color:var(--muted)}

  .mbar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:92;gap:10px;padding:11px 14px;
    background:var(--header-bg);backdrop-filter:blur(16px);border-top:1px solid var(--line)}
  .mbar .btn{flex:1;padding:12px 10px;font-size:14.5px}

  /* ---------- Responsive ----------
     All media queries now live in one consolidated block at the end of
     this file (1080px / 768px / 480px). Nothing responsive here. */

/* ===================================================================
   PAGE-LEVEL STYLES (inner pages)
   =================================================================== */
.phero{position:relative;overflow:hidden;padding:64px 0 58px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,var(--hero-top) 0%,var(--bg) 100%)}
.phero::before{content:"";position:absolute;width:640px;height:640px;right:-220px;top:-300px;
  background:radial-gradient(circle,rgba(22,168,111,.12),transparent 62%);border-radius:50%;pointer-events:none}
.phero .wrap{position:relative;z-index:2;text-align:center;max-width:860px}
.phero h1{font-size:42px;line-height:1.35;margin-bottom:16px;letter-spacing:-.5px}
.phero p{font-size:17px;max-width:640px;margin:0 auto;line-height:1.85}
.crumb{display:flex;align-items:center;justify-content:center;gap:9px;font-size:13.5px;
  color:var(--muted);margin-bottom:20px;flex-wrap:wrap}
.crumb a:hover{color:var(--gold)}
.crumb span{opacity:.5}

/* Article / long-form SEO copy */
.prose{max-width:820px;margin:0 auto}
.prose h2{font-size:29px;line-height:1.45;margin:44px 0 16px}
.prose h2:first-child{margin-top:0}
.prose h3{font-size:20px;margin:30px 0 12px}
.prose p{font-size:16px;line-height:1.95;margin-bottom:18px}
.prose ul,.prose ol{margin:0 0 22px 0;padding-left:0;list-style:none;display:grid;gap:12px}
.prose ul li{display:flex;gap:11px;align-items:flex-start;font-size:15.8px;line-height:1.8}
.prose ul li::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--btn-grad);
  flex:none;margin-top:11px}
.prose ol{counter-reset:n}
.prose ol li{display:flex;gap:13px;align-items:flex-start;font-size:15.8px;line-height:1.8;counter-increment:n}
.prose ol li::before{content:counter(n);width:26px;height:26px;border-radius:8px;background:var(--gold-soft);
  border:1px solid var(--gold-line);color:var(--gold);font-size:13px;font-weight:700;
  display:grid;place-items:center;flex:none;margin-top:3px}
.prose strong{color:var(--ink);font-weight:600}
.prose a{color:var(--gold);text-decoration:underline;text-underline-offset:3px}
.callout{background:linear-gradient(100deg,rgba(22,168,111,.10),rgba(15,157,106,.05));
  border:1px solid var(--gold-line);border-radius:18px;padding:26px 28px;margin:28px 0}
.callout b{color:var(--ink)}
.callout p:last-child{margin-bottom:0}

/* Contact form */
.form-wrap{display:grid;grid-template-columns:1.05fr .95fr;gap:34px;align-items:start}
.formcard{background:var(--card);border:1px solid var(--line);border-radius:22px;padding:34px;box-shadow:var(--shadow-md)}
.formcard h2{font-size:21px;margin-bottom:8px}
.formcard > p{font-size:14.8px;margin-bottom:26px}
.f2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.field{margin-bottom:18px}
.field label{display:block;font-size:14px;font-weight:600;color:var(--ink);margin-bottom:8px}
.field label i{color:var(--pink);font-style:normal}
/* su1 — the mirror of the pink asterisk: this box is OPTIONAL and says so.
   Muted and lighter than the label, because it qualifies the label rather than
   competing with it. Without a marker of its own, an unstarred box on a form
   where required boxes ARE starred reads as "we forgot the star". */
.field label .opt{color:var(--muted);font-weight:500}
.field input,.field select,.field textarea{width:100%;padding:13px 16px;border-radius:12px;
  border:1px solid var(--line);background:var(--card-2);color:var(--ink);font-family:inherit;
  font-size:15px;transition:.2s;outline:none}
.field textarea{min-height:110px;resize:vertical}
.field input:focus,.field select:focus,.field textarea:focus{border-color:var(--gold);
  box-shadow:0 0 0 3px var(--gold-soft)}
.field input.err,.field select.err,.field textarea.err{border-color:var(--pink)}
.field small{display:block;font-size:12.5px;color:var(--muted);margin-top:7px}
.fmsg{margin-top:16px;padding:13px 16px;border-radius:12px;font-size:14.5px;display:none}
.fmsg.ok{display:block;background:rgba(22,168,111,.12);border:1px solid rgba(22,168,111,.30);color:var(--ok)}
.fmsg.bad{display:block;background:rgba(220,38,38,.10);border:1px solid rgba(220,38,38,.30);color:var(--neg)}

/* Blog list */
.blist{display:grid;gap:22px}
.bwide{display:grid;grid-template-columns:.85fr 1.15fr;gap:0;background:var(--card);
  border:1px solid var(--line);border-radius:20px;overflow:hidden;transition:.25s}
.bwide:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md)}
.bwide .bimg{min-height:210px;display:grid;place-items:center;
  background:linear-gradient(135deg,#043724,#08573B 50%,#121713);color:var(--gold)}
.bwide .bbody{padding:30px}
.bwide h2{font-size:23px;line-height:1.5;margin:12px 0 10px}
.bwide p{font-size:15px;line-height:1.8;margin-bottom:16px}

/* Feature detail rows */
.frow{display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center;padding:56px 0;
  border-bottom:1px solid var(--line)}
.frow:last-child{border-bottom:0}
.frow.rev .fimg{order:-1}
.frow h2{font-size:31px;line-height:1.45;margin-bottom:16px}
.frow p{font-size:16px;line-height:1.9;margin-bottom:22px}
.frow ul{list-style:none;display:grid;gap:13px}
.frow li{display:flex;gap:11px;align-items:flex-start;font-size:15.2px;line-height:1.75}
.frow li svg{color:var(--gold);flex:none;margin-top:5px}
.frow li b{color:var(--ink);font-weight:600}

/* The language switch's own rules live with the rest of the header, above.
   They used to be split across two places — the container up there, the links
   down here — which is how `.lang button` came to survive as a dead rule after
   the markup became anchors. One block now. */

/* Skip link (a11y + SEO) */
.skip{position:absolute;left:-9999px;top:0;background:var(--gold);color:var(--gold-ink);padding:12px 20px;
  border-radius:0 0 10px 0;z-index:200;font-weight:600}
.skip:focus{left:0}

/* (inner-page responsive rules moved to the consolidated block at end of file) */

/* ===================================================================
   PRICING PAGE EXTRAS
   =================================================================== */
.rec{background:var(--card);border:1px solid var(--line);border-radius:20px;padding:28px;transition:.25s;position:relative}
.rec:hover{border-color:var(--gold-line);box-shadow:var(--shadow-md);transform:translateY(-4px)}
.rec .icon{margin-bottom:18px}
.rec h3{font-size:18.5px;margin-bottom:8px}
.rec > p{font-size:14.6px;line-height:1.8;margin-bottom:18px}
.rec ul{list-style:none;display:grid;gap:10px;margin-bottom:20px}
.rec li{display:flex;gap:10px;align-items:flex-start;font-size:14.4px;line-height:1.7}
.rec li svg{color:var(--gold);flex:none;margin-top:5px}
.rec-pick{display:flex;align-items:center;gap:10px;padding:14px 16px;border-radius:12px;
  background:var(--gold-soft);border:1px solid var(--gold-line);font-size:14.5px;color:var(--ink);font-weight:600}
.rec-pick b{color:var(--gold)}

.gbox{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.gitem{text-align:center;background:var(--card);border:1px solid var(--line);border-radius:20px;padding:32px 24px;transition:.25s}
.gitem:hover{border-color:var(--gold-line)}
.gitem .gi{width:60px;height:60px;border-radius:18px;background:var(--btn-grad);color:var(--gold-ink);
  display:grid;place-items:center;margin:0 auto 18px;box-shadow:var(--glow)}
.gitem h3{font-size:18px;margin-bottom:9px}
.gitem p{font-size:14.5px;line-height:1.8}

.payrow{display:flex;flex-wrap:wrap;gap:12px;justify-content:center;margin-top:26px}
.paycard{display:flex;align-items:center;gap:10px;background:var(--card);border:1px solid var(--line);
  border-radius:12px;padding:12px 18px;font-size:14.2px;font-weight:600;color:var(--ink);transition:.2s}
.paycard:hover{border-color:var(--gold-line)}
.paycard i{width:10px;height:10px;border-radius:50%;flex:none}

/* (.gbox responsive rule moved to the consolidated block at end of file) */

/* ===================================================================
   AD LANDING PAGE
   =================================================================== */
.lp-bar{position:sticky;top:0;z-index:70;background:var(--header-bg);backdrop-filter:blur(16px);
  border-bottom:1px solid var(--line)}
.lp-bar .wrap{display:flex;align-items:center;justify-content:space-between;height:70px;gap:16px}
.lp-hero{position:relative;overflow:hidden;padding:56px 0 66px;
  background:linear-gradient(180deg,var(--hero-top) 0%,var(--bg) 100%)}
.lp-hero::before{content:"";position:absolute;width:720px;height:720px;right:-240px;top:-320px;
  background:radial-gradient(circle,rgba(22,168,111,.15),transparent 62%);border-radius:50%;pointer-events:none}
.lp-hero .wrap{position:relative;z-index:2;display:grid;grid-template-columns:1.08fr .92fr;gap:46px;align-items:start}
.lp-hero h1{font-size:44px;line-height:1.32;margin-bottom:18px;letter-spacing:-.5px}
.lp-hero p.lead{font-size:17px;line-height:1.85;margin-bottom:26px}
.lp-points{display:grid;gap:13px;list-style:none;margin-bottom:28px}
.lp-points li{display:flex;gap:12px;align-items:flex-start;font-size:15.6px;line-height:1.7}
.lp-points li svg{color:var(--gold);flex:none;margin-top:5px}
.lp-points b{color:var(--ink)}

.offerbox{background:var(--card);border:2px solid var(--gold);border-radius:22px;padding:30px;
  box-shadow:0 0 0 5px var(--gold-soft),var(--shadow-lg);position:relative}
.offerbox .rib{position:absolute;top:-15px;left:50%;transform:translateX(-50%);background:var(--btn-grad);
  color:var(--gold-ink);font-weight:700;font-size:13px;padding:6px 20px;border-radius:999px;white-space:nowrap}
.offerbox h2{font-size:20px;text-align:center;margin:6px 0 6px}
.offerbox .sub{text-align:center;font-size:14px;color:var(--muted);margin-bottom:20px}
.oprice{display:flex;align-items:flex-end;justify-content:center;gap:10px;margin-bottom:6px}
.oprice .was{font-size:19px;color:var(--muted);text-decoration:line-through;padding-bottom:8px}
.oprice .now{font-size:46px;font-weight:700;line-height:1;background:var(--grad);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.oprice small{color:var(--muted);font-size:15px;padding-bottom:6px}
.osave{text-align:center;font-size:13.5px;color:var(--ok);font-weight:600;margin-bottom:20px}
.oincl{display:grid;gap:10px;list-style:none;padding:18px 0;margin-bottom:18px;
  border-top:1px dashed var(--line);border-bottom:1px dashed var(--line)}
.oincl li{display:flex;gap:10px;align-items:flex-start;font-size:14.3px;line-height:1.7}
.oincl li svg{color:var(--gold);flex:none;margin-top:5px}
.otimer{display:flex;justify-content:center;gap:9px;margin-bottom:18px}
.tcell{background:var(--card-2);border:1px solid var(--line);border-radius:11px;padding:9px 13px;text-align:center;min-width:60px}
.tcell b{display:block;font-size:21px;color:var(--gold);line-height:1.2}
.tcell small{font-size:11px;color:var(--muted)}

.problem{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
.pbad,.pgood{border-radius:18px;padding:28px;border:1px solid var(--line)}
.pbad{background:rgba(220,38,38,.05);border-color:rgba(220,38,38,.22)}
.pgood{background:rgba(22,168,111,.06);border-color:rgba(22,168,111,.24)}
.pbad h3,.pgood h3{font-size:18px;margin-bottom:18px;display:flex;align-items:center;gap:10px}
.pbad ul,.pgood ul{list-style:none;display:grid;gap:13px}
.pbad li,.pgood li{display:flex;gap:11px;align-items:flex-start;font-size:15px;line-height:1.75}
.pbad li::before{content:"✕";color:var(--neg);font-weight:700;flex:none}
.pgood li::before{content:"✓";color:var(--ok);font-weight:700;flex:none}

.orderwrap{display:grid;grid-template-columns:1fr 1fr;gap:34px;align-items:start}
.ordercard{background:var(--card);border:1px solid var(--gold-line);border-radius:22px;padding:34px;
  box-shadow:var(--shadow-lg)}
.ordercard h2{font-size:22px;margin-bottom:8px}
.ordercard > p{font-size:14.6px;margin-bottom:24px}
.trustline{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:18px;font-size:13px;color:var(--muted)}
.trustline span{display:flex;align-items:center;gap:7px}
.trustline svg{color:var(--gold)}

/* ===================================================================
   CONSOLIDATED RESPONSIVE LAYER
   Three tiers only:
     1080px — small laptop / tablet landscape / tablet portrait
      768px — large phone landscape & tablet portrait edge
      480px — phones (covers 414px and 360px)
   Nothing above 1080px is touched; desktop layout is unchanged.
   Tiers are additive (each narrower tier only overrides what breaks).
   =================================================================== */

/* -------------------------------------------------------------------
   <= 1080px
   Fixes: navbar (.navshell/.nav-links/.nav-right/.mega/.burger) —
   the inline nav's min-content width (~1010px) overflowed the page
   between 769px and 1080px, so the whole bar collapses to the burger
   here and the 660px-wide .mega dropdown stops existing at all.
   Also: .hero, .grid-4, .grid-6, .split, .fgrid, .float-card,
   .counters, .why-strip, .integ, .dl/.vids/.blogs/.tst-track, .steps,
   .calc, .case, .demo, .app/.side/.pane (dashboard mock),
   .form-wrap, .frow, .bwide, .gbox, .lp-hero, .orderwrap, .problem.
   ------------------------------------------------------------------- */
@media(max-width:1080px){
  /* --- navbar collapses to burger --- */
  /* `.lang` is deliberately NOT in this list. It used to be hidden here and
     replaced by the `.langdd` dropdown; there is one control now and it stays
     in the bar at every width. */
  .nav-links,.nav-right .login,.nav-right .divider{display:none}
  .mobile-menu .login{display:flex}
  .burger{display:grid}
  /* 7px rather than 9px between the three round controls. The bar now carries
     one more of them and the two saved pixels are what a 360px screen has. */
  .nav-right{gap:7px}
  .navshell{gap:12px}
  .tb-right a:last-of-type{display:none}

  /* --- hero + generic grids --- */
  .hero .wrap{grid-template-columns:1fr;gap:52px}
  .hero h1{font-size:41px}
  .grid-4{grid-template-columns:repeat(2,1fr)}
  .grid-6,.grid-5{grid-template-columns:repeat(3,1fr)}
  .split{grid-template-columns:1fr;gap:44px}
  .fgrid{grid-template-columns:1fr 1fr;gap:36px}
  .float-card.a{left:0}
  .float-card.b{right:0}
  .counters{grid-template-columns:repeat(2,1fr)}
  .why-strip{grid-template-columns:1fr;gap:20px}
  .integ{grid-template-columns:repeat(4,1fr)}
  .dl,.vids,.blogs,.tst-track{grid-template-columns:repeat(2,1fr)}
  .steps{grid-template-columns:1fr;gap:34px}
  .steps::before{display:none}
  .calc{grid-template-columns:1fr;gap:26px;padding:28px}
  .case{grid-template-columns:1fr;gap:26px;padding:28px}
  .demo{grid-template-columns:1fr;gap:28px;padding:30px}

  /* --- dashboard mock: sidebar scrolls sideways, .pane (not the page)
         owns the .tbl overflow. min-width:0 stops the grid items from
         being sized by their content and bursting .frame. --- */
  .app{grid-template-columns:1fr;min-width:0}
  .app > *{min-width:0}
  .side{display:flex;gap:6px;overflow-x:auto;-webkit-overflow-scrolling:touch;
    border-right:0;border-bottom:1px solid #28302A;padding:12px;min-width:0}
  .side a{white-space:nowrap;margin:0;flex:none}
  .pane{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .cmp-wrap{-webkit-overflow-scrolling:touch}

  /* --- inner pages --- */
  .form-wrap{grid-template-columns:1fr}
  .frow{grid-template-columns:1fr;gap:32px;padding:44px 0}
  .frow.rev .fimg{order:0}
  .bwide{grid-template-columns:1fr}
  .bwide .bimg{min-height:150px}
  .gbox{grid-template-columns:1fr}

  /* --- ad landing page --- */
  .lp-hero .wrap{grid-template-columns:1fr;gap:36px}
  .lp-hero h1{font-size:34px}
  .orderwrap{grid-template-columns:1fr}
  .problem{grid-template-columns:1fr}
}

/* -------------------------------------------------------------------
   <= 768px
   Fixes: header/topbar sizing + 44px tap targets (.tb-x, .theme-btn,
   .burger, .lang, .copy, .tdot, .socials, footer links, form inputs),
   heading scale, .grid-2/3/4/6, .counters, .nlist, .hstats,
   .tiles/.pos-grid/.tbl inside the dashboard, .integ, .case-stats,
   .dl/.vids/.blogs/.tst-track, .f2, .fgrid, .float-card,
   .mbar/.fab/.toast stacking, .faq answer clipping, long-string wrap.
   ------------------------------------------------------------------- */
@media(max-width:768px){
  /* --- header + announcement bar --- */
  header{padding:12px 0}
  .navshell{padding:8px 8px 8px 14px;border-radius:16px}
  .logo{font-size:18.5px}
  .logo .mark{width:38px;height:38px}
  /* Same step down as .mark, and a tighter max-width: the phone bar carries the
     burger and the trial button beside this, so an unbounded wordmark pushes
     one of them off the row. */
  .logo .brandlogo{height:30px;max-width:150px}
  .nav-right .btn{padding:10px 16px;font-size:13.5px}
  /* ── The announcement strip goes to TWO ROWS here, and gains the sentence ──
   *
   * `.tb-left span{display:none}` used to be this line, and it is what the
   * owner was looking at: on a phone the announcement had no text at all.
   *
   * Measured at 390px, which is why it is two rows and not a ticker on one —
   * and measured properly only on the second pass. The first version of this
   * note DERIVED the number by subtracting parts (358px of row, a 130px hotline,
   * a 44px close button, the gaps) and then called it measured. It was close by
   * luck. The real figures, taken by reconstructing the one-row geometry in the
   * browser and reading the box: the message had 85.281px in English and
   * 105.594px in Bangla, against sentences of 391.719px and 373.891px.
   *
   * 85px at this bar's 5.68px per character is about fifteen characters of a
   * sixty-nine character sentence. A ticker through that is not reading, it is a
   * slot machine, and it would have been a fair answer to the words of the
   * request and a wrong answer to the point of it.
   *
   * Given the whole row instead, the sentence gets ~290px and overflows by
   * about a third rather than by four hundred percent — so most of it is on
   * screen at any moment and the travel is short. The cost is honest and worth
   * stating: the strip is taller on a phone than it was. It is a dismissible
   * band with its own close button, and it now carries the sentence it exists
   * to carry.
   *
   * The DOM order is the visual order — message first, then hotline and close
   * — so no `order` property is involved, which keeps what a screen reader
   * hears identical to what a sighted reader sees. `row-gap:0` because the
   * bar's `gap:18px` is both axes, and 18px of nothing between the two rows
   * would undo the space this just spent. `margin-left:auto` keeps the
   * controls on the right of their own row, where they already were. */
  /* ── AND THEN IT WENT BACK TO ONE ROW, AS A GRID ─────────────────────────
   *
   * Owner, on the two-row strip the note above describes: *"number and text ta
   * alda line e hoye gece jar karone dekhte kharap lageche ei bugs ta fix kore
   * daw. are ei design ta aro batter koro daw."*
   *
   * The two-row strip answered the READING problem and created a COMPOSITION
   * one. Measured on the shipped build at 390px before this change: row one was
   * the pill and the sentence, row two was a 44px band holding a 129.92px
   * tap-to-call and a 44px close button pushed right by `margin-left:auto` —
   * with 187.88px of empty bar between the gutter and the phone icon, and
   * nothing above them to line up with. Read as a spill, because it was one:
   * two floated groups that had wrapped, not a layout designed to be two rows.
   *
   * So: one row again, and the space is found by changing the HOTLINE rather
   * than the sentence. Below 769px the digits are hidden and the `tel:` link
   * becomes a 44x44 icon button (see partials/header.php for why the digits are
   * the right thing to give up on this device and only on this device). That
   * turns ~130px of text into a 44px control and puts the number back on the
   * sentence's own line, which is what he asked for.
   *
   * The rest is arithmetic, all of it read off the browser at 390px:
   *
   *              two rows (before)      one row (after)
   *   bar height        71.00px               49.00px
   *   message view     293.72px              211.72px  (bn)
   *                    289.20px              207.20px  (en)
   *   hotline       129.92px of text      44x44 button
   *
   * ── THE OPTION THIS REJECTS, AND ITS NUMBER ──────────────────────────────
   *
   * Keeping the digits and putting everything on one row anyway was measured on
   * this very grid, by un-hiding `.tb-num`: the hotline grows to 155.92px in
   * English and the message viewport falls to 95.28px (115.59px in Bangla).
   * That is within four pixels of the 85.28px the two-row note above rejected
   * as "not reading, a slot machine", and it would have been the same mistake
   * with a nicer grid under it.
   *
   * ── AND THE NOTE ABOVE VERIFIES ──────────────────────────────────────────
   *
   * Its 85.281px / 105.594px are not taken on trust: reconstructed here at 390px
   * by forcing this strip back to the pre-change one-row flex geometry — pulse
   * shown, `gap:18px`, `.tb-right` at 12px, the hotline as text with its 14px
   * icon — the message viewport reads 85.281px in English and 105.594px in
   * Bangla, and the hotline 129.922px. Three figures, to three decimals, from a
   * note that had already been caught inventing one. They were measured.
   *
   * The sentence loses 82px against the two-row strip and is still 2.43x what
   * it had before either change in English and 2.00x in Bangla — the two
   * languages differ and the ratio is written for both rather than for the
   * flattering one — so the ticker is still reading rather than the slot
   * machine that note rejects. The strip loses 22px of height and every element
   * on it now sits on one baseline.
   *
   * ── WHY GRID AND NOT THE FLEX ROW IT REPLACES ────────────────────────────
   *
   * `minmax(0,1fr)` on the middle track is the whole reason. A flex row needs
   * `min-width:0` on the message to stop its content from setting its width,
   * and `.tb-msg` has it — but the two side items then still size themselves
   * from content, so the pill and the control cluster silently take whatever
   * they want and the sentence gets the remainder in whatever order the browser
   * resolved them. Named tracks say it once: the pill is `auto`, the controls
   * are `auto`, the sentence is EVERYTHING ELSE and never less than zero.
   *
   * `.tb-left{display:contents}` promotes the pill and the message into that
   * grid without a second wrapper. It is a plain <div> with no role and no
   * label, which is the case where `display:contents` is safe — the elements
   * that matter (the <em> and the message) keep their own boxes.
   *
   * The grid PLACES rather than reorders: DOM order is pill, message, controls
   * and so is column order, so nothing here changes what a screen reader hears
   * relative to what a sighted reader sees.
   *
   * ── `.topbar .tb`, NOT `.tb`, AND THAT IS DELIBERATE ─────────────────────
   *
   * There is a SECOND `@media(max-width:1080px)` block much further down this
   * file — the tap-target one — and it also sets `.tb{min-height:44px}`. It is
   * later in the source, so at 390px, where both queries match, a bare `.tb`
   * here would lose the cascade to it and this strip's height would be decided
   * by a rule written for a different tier. `.topbar .tb` outranks it whatever
   * the order. The two agreed on 44px before, which is exactly why nobody had
   * noticed the hazard.
   *
   * 48px is a chosen number and not the tallest child: the controls are 44px,
   * so this is 2px of air above and below them. The strip had no deliberate
   * height on a phone at all before — it was 71px because that is what two
   * wrapped rows happened to add up to. */
  .topbar .tb{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
    align-items:center;column-gap:10px;row-gap:0;min-height:48px}
  .tb-left{display:contents}
  .tb-left em{grid-column:1;grid-row:1}
  .tb-msg{grid-column:2;grid-row:1}
  .tb-right{grid-column:3;grid-row:1;gap:2px;margin:0}
  /* The pulsing dot is the one thing on this strip that says nothing. The pill
     beside it already reads নতুন / NEW, so on the device where its 8px and the
     10px column gap after it come straight out of the sentence, the word keeps
     the meaning and the dot goes. It stays from 769px up, where the space is
     free — and it is also one fewer thing moving on a strip that is already
     asking a phone to composite a scrolling line. */
  .topbar .pulse{display:none}
  /* Two 44px controls, 2px apart, as one cluster. The call carries the tint
     because it is the action; the dismiss stays plain because it is not. */
  .tb-call,.tb-x{width:44px;height:44px;padding:0;display:grid;place-items:center;
    border-radius:999px;flex:none}
  .tb-call{gap:0;background:var(--gold-soft);color:var(--gold);border:1px solid var(--gold-line)}
  .tb-call .tb-num{display:none}
  .tb-call svg{width:18px;height:18px}
  /* The × is a glyph, not a chip: one tinted control on this cluster is the
     action and a second would compete with it. It keeps the same 44px circle
     for the thumb and for the focus ring, and gains two points of size because
     at 17px beside an 18px handset it read as smaller than it is. */
  .tb-x{font-size:19px}
  /* ── THE STILL PATH IS THE ONE SHAPE THAT IS STILL TWO ROWS ───────────────
   *
   * A reader who has asked for no motion gets no ticker, so their sentence has
   * to fit where it is printed — and where it is printed on this grid is a
   * ~200px column, which sets 69 characters of English as four short lines
   * with a pill and two buttons floating in the middle of them. That is the
   * layout this change exists to remove, arrived at from the other direction.
   *
   * So for that reader, and ONLY that reader, the grid goes to TWO columns: the
   * pill and the sentence stack in the left one, and the controls move into the
   * right one spanning both rows, centred against the block they sit beside.
   *
   * The first shape tried here was the obvious one — leave three columns and
   * let the sentence span the full width of a second row — and it was rejected
   * by looking at it: the pill then sits alone on the left of row one with the
   * controls on the right and ~190px of empty bar between them, which is the
   * exact composition the owner photographed, arrived at from the other
   * direction. Measured at 390px, it was also the taller of the two — 104.25px
   * against 84.50px, in both languages — because the sentence gained a row of
   * its own that it did not need.
   *
   * Both selectors, for the reason the base block already gives: the media
   * query is the GUARANTEE (it holds before app.js has measured, and on a page
   * where the script never ran), the attribute is how app.js records it. */
  .topbar[data-tick="wrap"] .tb{grid-template-columns:minmax(0,1fr) auto;row-gap:3px}
  .topbar[data-tick="wrap"] .tb-left em{grid-column:1;grid-row:1;justify-self:start}
  .topbar[data-tick="wrap"] .tb-msg{grid-column:1;grid-row:2}
  .topbar[data-tick="wrap"] .tb-right{grid-column:2;grid-row:1/span 2;align-self:center}
  /* tap targets. The close button was 44x40 and is now square: it sits beside a
     44px call button in the same cluster, so the four pixels are free — the row
     was already that tall and the bar's floor is a `min-height`. It is the same
     44x44 the React port of this strip gives its own X, and the two agreeing is
     worth more than the four pixels ever were. */
  .tb-x{min-width:44px;min-height:44px;padding:0;display:grid;place-items:center}
  .theme-btn{width:44px;height:44px}
  .burger{width:44px;height:44px}
  /* The control keeps a 44px-tall row on touch, but the segments narrow to
     32px so the whole switch stays ~76px and still clears the wordmark at
     360px. Mis-tapping the wrong half is a no-op when it is the half you are
     already on, and is the thing you wanted when it is not — which is why a
     narrow segment is an acceptable trade here and would not be on a menu. */
  /* 44px of touch height, from a control that is only 54–60px WIDE. The panel
     rows are the generous half of this control on a phone: 40px tall and the
     full width of the panel, which is the target a thumb actually gets. */
  .langbtn{min-height:44px;padding:0 8px 0 9px}
  .langpop a{padding:11px 12px}
  .mobile-menu a{padding:14px 2px}
  .btn{min-height:46px}
  .btn-sm{min-height:44px}
  .tab{min-height:44px}
  .copy{padding:11px 15px;min-height:44px;font-size:12.5px}
  .socials a{width:44px;height:44px}
  footer ul{gap:4px}
  footer ul a{display:inline-block;padding-top:8px;padding-bottom:8px}

  /* --- rhythm + typography --- */
  .section{padding:64px 0}
  .hero{padding:48px 0 66px}
  .hero h1{font-size:32px}
  .hero p.lead{font-size:16px}
  .shead{margin-bottom:40px}
  .shead h2{font-size:27px}
  .split h2{font-size:26px}
  .cta{padding:42px 22px}
  .cta h2{font-size:26px}
  .demo h2{font-size:24px}
  .case h3{font-size:23px}
  .phero{padding:44px 0 40px}
  .phero h1{font-size:29px}
  .phero p{font-size:15.5px}
  .prose h2{font-size:23px}
  .frow h2{font-size:24px}
  .lp-hero{padding:36px 0 46px}
  .lp-hero h1{font-size:27px}
  .lp-hero p.lead{font-size:15.5px}
  .lp-bar .wrap{height:62px}

  /* --- grids --- */
  .grid-4,.grid-3,.grid-2{grid-template-columns:1fr}
  .grid-6,.grid-5{grid-template-columns:repeat(2,1fr)}
  .counters{grid-template-columns:1fr 1fr;gap:14px}
  .cnt{padding:22px 14px}
  .cnt b{font-size:26px}
  .nlist{grid-template-columns:1fr}
  .hstats{grid-template-columns:repeat(3,1fr);gap:18px}
  .hstats b{font-size:21px}
  .chips{gap:7px}
  .chip-i{font-size:12.8px;padding:7px 13px}
  .dl,.vids,.blogs,.tst-track{grid-template-columns:1fr}
  .integ{grid-template-columns:repeat(3,1fr)}
  .case-stats{grid-template-columns:1fr 1fr}
  .calc-out .big{font-size:33px}
  .tbadges{gap:12px 20px}
  .tbadge{font-size:13px}
  .fgrid{grid-template-columns:1fr}
  .fbot{justify-content:center;text-align:center}
  .float-card{display:none}
  .price.pop{transform:none}
  .cta-btns{justify-content:center !important}

  /* --- dashboard mock: table scrolls inside .pane, never the page --- */
  .tiles{grid-template-columns:repeat(2,1fr)}
  .pos-grid{grid-template-columns:1fr 1fr}
  .pane{padding:14px}
  .tbl{min-width:520px}
  .side a{padding:10px 12px}
  .frame-bar span,.mock-bar span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}

  /* --- forms: 16px inputs so iOS Safari does not zoom on focus --- */
  .f2{grid-template-columns:1fr}
  .formcard{padding:24px}
  .ordercard{padding:24px 20px}
  .offerbox{padding:24px 20px}
  .oprice .now{font-size:38px}
  .field input,.field select,.field textarea{font-size:16px;min-height:48px;padding:12px 14px}
  .field textarea{min-height:120px}
  input[type=range]{height:20px}

  /* --- FAQ answers were clipped at 260px; phone text is much taller --- */
  .faq.open .ans{max-height:760px}

  /* --- testimonial dots: 9px dot, ~33x45px invisible tap area. The
         pseudo fills the gap exactly so neighbouring dots never steal
         each other's taps. --- */
  .tst-nav{gap:24px}
  .tdot{position:relative}
  .tdot::after{content:"";position:absolute;top:-18px;bottom:-18px;left:-12px;right:-12px}

  /* --- long unbroken strings (IMEI, emails, URLs) --- */
  .crd code,.tbl td,.tbl th,.orow,.contact-card small,.contact-card b,
  .office p,.prose p,.prose li,.fbot,.mstat b,.tile b{overflow-wrap:anywhere}

  /* --- sticky bottom bar / FAB / toast: mbar is ~69px tall, body is
         padded 78px so the last CTA is never hidden under it. The FAB
         column starts above the bar; the toast is off on phones so the
         two can never collide. --- */
  body{padding-bottom:78px}
  .mbar{display:flex}
  .mbar .btn{flex:1;min-width:0;min-height:46px;line-height:1.25;padding:10px 12px;font-size:14.5px}
  .fab{right:16px;bottom:88px}
  .fab a,.fab button{width:50px;height:50px}
  .fab .up{width:46px;height:46px;margin-left:0;align-self:flex-end}
  .toast{display:none}
}

/* The still-path twin of `.topbar[data-tick="wrap"] .tb-msg` in the block
   above, and the reason for two of them is argued there. A top-level combined
   query rather than a `@media` nested inside the 768px one: nested queries are
   CSS Nesting, which the cheap Android browsers this strip is designed for do
   not all have, and a layout rule that silently does not parse on the oldest
   device in the room is the wrong place to spend a modern feature.

   `.topbar .tb-msg` carries the same 0-2-0 specificity as its twin, so this
   wins over the single-class grid placement no matter where it sits in the
   file. That is not an accident of ordering and should not become one. */
@media(max-width:768px) and (prefers-reduced-motion:reduce){
  .topbar .tb{grid-template-columns:minmax(0,1fr) auto;row-gap:3px}
  .topbar .tb-left em{grid-column:1;grid-row:1;justify-self:start}
  .topbar .tb-msg{grid-column:1;grid-row:2}
  .topbar .tb-right{grid-column:2;grid-row:1/span 2;align-self:center}
}

/* -------------------------------------------------------------------
   <= 520px  the nav CTA leaves the bar

   This rule used to live in the 480px tier, and 480 was the right number
   while the bar held three things. It now holds four — the language
   dropdown joined the theme toggle, the trial CTA and the burger — and
   measured at 481px the flex row had run out: the trial button was
   squeezed from 109px to 100px and the burger from 44px to 39px, which
   is a tap target quietly dropping below the minimum the 1080px block
   sets for it. The row needs 502px to hold all four at full size, so the
   CTA leaves at 520 with a margin rather than at 481 with none.

   Nothing is lost by dropping it: the trial button is still in the
   mobile menu and in the sticky .mbar, which is the same reasoning that
   put this rule at 480 in the first place.
   ------------------------------------------------------------------- */
@media(max-width:520px){
  .nav-right .btn{display:none}
}

/* -------------------------------------------------------------------
   <= 480px  (360px and 414px phones)
   Fixes: .wrap gutters, header CTA overflow, heading scale,
   .mock-stats, .integ, .otimer/.tcell, .oprice, .rib/.pop-tag,
   .crd, .sync-row, .case-stats, .tabs, .hstats, card padding,
   full-width hero/CTA buttons.
   ------------------------------------------------------------------- */
@media(max-width:480px){
  /* tighter page gutter buys 12px of usable width on a 360px screen */
  .wrap{padding:0 16px}
  .section{padding:48px 0}

  /* --- header: the logo tagline does not fit next to a 44px burger at
         360px, and is still reachable nowhere it matters — it is a
         tagline, not a control. The nav CTA used to be dropped here too;
         it now goes at 520px instead, see the block below this one. --- */
  .wm em{display:none}
  .navshell{gap:10px;padding:7px 7px 7px 12px}
  .tb-left em{font-size:11px;padding:2px 8px}

  /* --- /offer sticky bar: logo wordmark + a 42px mark + theme
         toggle + the phone CTA together measured ~396px at 360px and
         pushed the page sideways. Keep the gold mark as the brand and
         give the phone CTA the room. --- */
  .lp-bar .wrap{height:56px;gap:10px}
  .lp-bar .logo .wm{display:none}
  .lp-bar .logo .mark{width:38px;height:38px}
  .lp-bar .btn{padding:9px 14px;font-size:13.5px;min-height:44px}

  /* --- ...and the same bar was STILL pushing the page sideways at 360px,
         because the fix above never touched the path that ships.

         `.wm` and `.mark` are the FALLBACK lockup — the wordmark and the
         gold square drawn when no logo has been uploaded. An uploaded logo
         renders `<img class="brandlogo">` instead, `.wm` is empty and
         `.mark` is not in the DOM at all, so hiding them moves nothing.
         A logo has been uploaded. Measured on PRODUCTION with DNS pinned,
         not locally and not from the source: https://dokanseba.com/offer at
         360x700 reports documentElement.scrollWidth 361 against clientWidth
         360, with `a.btn.btn-gold.btn-sm` — the phone CTA — ending at
         361.17. 320, 375, 390 and 414 are all clean; 360 alone is not, and
         360 is the single most common Android viewport in this market.

         The arithmetic: 14px gutter + a 150px logo image + a 10px gap + a
         187px control group + 14px gutter is 375, in 360. The image is
         150px because `.logo .brandlogo` caps at 190px, tightened to 150px
         at 768 and to 104px only below 340 — a ladder written for the site
         header, which has different neighbours.

         Rather than add a fourth magic number for one viewport width, the
         logo is simply made the thing that yields. `flex:0 1 auto` with
         `min-width:0` lets the flex algorithm take the space back out of
         the mark, `max-width:100%` makes the image follow its box, and
         `object-fit:contain` (already on `.brandlogo`) keeps the aspect
         ratio while it does. The control group is pinned with `flex:none`
         so the shrinking can only ever come out of the logo: a wordmark
         eight pixels narrower is legible, a phone button that has lost its
         last digit is not.

         This holds at any width rather than at the ones that were tested,
         which is the point — the 340px cap above exists because somebody
         checked 320, and 360 was still broken underneath it. --- */
  .lp-bar .logo{min-width:0;flex:0 1 auto}
  .lp-bar .logo .brandlogo{flex:0 1 auto;min-width:0;max-width:100%}
  .lp-bar .wrap > div{flex:none}

  /* --- typography (nothing below 14px for body copy) --- */
  .hero{padding:36px 0 48px}
  .hero h1{font-size:26px;line-height:1.35}
  .hero p.lead{font-size:15.5px}
  .badge{font-size:13.5px;padding:8px 16px;margin-bottom:20px}
  .shead{margin-bottom:32px}
  .shead h2{font-size:24px}
  .shead p{font-size:15.5px}
  .over{font-size:13.5px;margin-bottom:14px}
  .split h2{font-size:22px}
  .split p.lead{font-size:15.5px}
  .cta{padding:34px 18px;border-radius:20px}
  .cta h2{font-size:22px}
  .cta p{font-size:15.5px}
  .phero h1{font-size:24px}
  .phero p{font-size:15px}
  .prose h2{font-size:20px}
  .prose h3{font-size:18px}
  .prose p{font-size:15.5px}
  .prose ul li,.prose ol li{font-size:15px}
  .frow h2{font-size:21px}
  .frow p{font-size:15.5px}
  .demo h2{font-size:21px}
  .case h3{font-size:20px}
  .bwide h2{font-size:19px}
  .lp-hero h1{font-size:23px;line-height:1.38}
  .lp-hero p.lead{font-size:15px}
  .amount b{font-size:34px}
  .calc-out .big{font-size:28px}
  .cnt b{font-size:24px}
  .hstats{gap:10px}
  .hstats b{font-size:19px}
  .hstats small{font-size:12.5px}

  /* --- card / panel padding so content is not squeezed --- */
  .card{padding:24px 20px}
  .fcard{padding:22px 18px}
  .dcard{padding:22px 20px}
  .bcard{padding:20px}
  .tst{padding:22px 20px}
  .office{padding:22px 20px}
  .rec{padding:22px 20px}
  .gitem{padding:26px 18px}
  .price{padding:28px 20px}
  .sync-box{padding:22px 18px}
  .why-strip{padding:22px 18px}
  .calc{padding:20px}
  .calc-out{padding:20px}
  .case{padding:22px 18px}
  .demo{padding:22px 18px}
  .cred{padding:18px 16px}
  .callout{padding:20px 18px}
  .formcard{padding:20px 16px}
  .ordercard{padding:22px 18px}
  .offerbox{padding:22px 18px}
  .pbad,.pgood{padding:20px 18px}
  .bwide .bbody{padding:20px}
  .contact-card{padding:18px 16px;gap:12px}
  .frow{padding:32px 0;gap:26px}
  .split{gap:32px}

  /* --- hero dashboard mock: 3 stat tiles do not fit in ~220px --- */
  .cream-panel{padding:18px;border-radius:18px}
  .cp-head h2{font-size:21px}
  .mock-body{padding:12px;gap:10px}
  .mock-stats{grid-template-columns:repeat(2,1fr)}
  .mock-stats .mstat:last-child{grid-column:span 2}
  .mstat b{font-size:15px}
  .play{width:58px;height:58px}

  /* --- showcase: tabs scroll sideways instead of stacking 4 rows --- */
  .tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;
    justify-content:flex-start;margin-bottom:22px;padding-bottom:4px;
    scrollbar-width:none}
  .tabs::-webkit-scrollbar{display:none}
  .tab{flex:none;padding:10px 18px;font-size:14px}
  .pane{padding:12px}
  .tiles{gap:8px}
  .tile{padding:11px}
  .pos-grid{gap:8px}

  /* --- comparison table: less padding = less sideways scrolling --- */
  .cmp{min-width:560px}
  .cmp th,.cmp td{padding:12px 12px;font-size:14px}

  /* --- 2-up grids that are too tight at 360px --- */
  .integ{grid-template-columns:repeat(2,1fr)}
  .grid-6,.grid-5{grid-template-columns:repeat(2,1fr)}
  .case-stats{gap:10px}
  .cs{padding:16px 14px}
  .cs b{font-size:22px}

  /* --- demo credentials: code gets its own full-width line --- */
  .crd{flex-wrap:wrap;gap:8px 10px;padding:12px 14px}
  .crd small{width:auto;flex:none}
  .crd code{flex:1 0 100%;order:3;min-width:0;font-size:13.8px;overflow-wrap:anywhere}
  .crd .copy{margin-left:auto}

  /* --- sync rows: chip must be allowed to drop to a second line --- */
  .sync-row{flex-wrap:wrap;padding:12px 14px}
  .sync-row > div{min-width:0;flex:1 1 60%}
  .chip{margin-left:auto}

  /* --- offer box (conversion element): must read as deliberate --- */
  .offerbox{margin-top:14px}
  .offerbox .rib,.pop-tag{white-space:normal;text-align:center;line-height:1.35;
    max-width:calc(100% - 28px);font-size:12px;padding:5px 14px}
  .oprice{flex-wrap:wrap;gap:6px 8px}
  .oprice .now{font-size:34px}
  .oprice .was{font-size:16px;padding-bottom:5px}
  .oprice small{font-size:13.5px}
  .otimer{gap:6px}
  .tcell{min-width:0;flex:1 1 0;padding:8px 4px;border-radius:9px}
  .tcell b{font-size:18px}
  .tcell small{font-size:10.5px}

  /* --- full-width primary actions read better than half-width pills --- */
  .hero-cta{gap:10px;margin-bottom:34px}
  .hero-cta .btn,.cta-btns .btn{width:100%}

  /* --- pricing toggle must not burst its centring wrapper --- */
  .ptoggle{max-width:100%;margin-bottom:30px}
  .ptoggle button{padding:9px 12px;font-size:13.5px;gap:6px}

  /* --- FAQ --- */
  .faq button{padding:16px 16px;font-size:15.5px;gap:12px}
  .faq .ans p{padding:0 16px 18px;font-size:15px}
  .faq.open .ans{max-height:1000px}

  /* --- footer / bottom bar --- */
  footer{padding-top:52px}
  .fgrid{gap:28px;padding-bottom:34px}
  .mbar{padding:10px 12px;gap:8px}
  .mbar .btn{padding:10px 8px;font-size:13.8px}
  .fab{right:12px;bottom:84px}
  .fab a,.fab button{width:48px;height:48px}
  .fab .up{width:44px;height:44px}
}

/* mobile menu is class-driven (JS toggles .open) — no inline styles.
   The burger now appears at <=1080px, so the desktop guard matches. */
.mobile-menu{display:none}
.mobile-menu.open{display:block}
@media(min-width:1081px){ .mobile-menu,.mobile-menu.open{display:none} }


/* blog e ekhono sob lekha ready na — card gulo link kora jabe na, tai plain article */
.bcard.soon{cursor:default}
.bcard.soon:hover{transform:none;border-color:var(--line);box-shadow:none}
.soon-tag{background:var(--card-2);color:var(--muted);margin-left:7px}
/* --- lead form: honeypot and per-field errors (w253) ---------------------
   .hp is the bot trap. It must be invisible to people and to screen readers
   but still fillable by something that parses the DOM, so it is moved off
   canvas rather than display:none — some bots skip hidden fields. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.field .ferr{display:block;margin-top:6px;color:var(--neg);font-size:13px;line-height:1.5}
.field input.err,.field select.err,.field textarea.err{border-color:var(--neg)}
.fmsg.bad a,.fmsg.ok a{color:inherit;text-decoration:underline}

/* choto dropdown — feature er mega ta boro, solutions/resources er jonno eta */
.mega.sm{width:280px;padding:10px}
.mega.sm .mega-grid{grid-template-columns:1fr;gap:2px}
.mega.sm .mega-grid a{padding:10px 12px;align-items:center}
.mega.sm .mega-grid .mi{width:32px;height:32px;border-radius:9px}
.mega.sm .mega-grid b{font-size:14.2px}
.mega.sm .sep{height:1px;background:var(--line);margin:6px 10px}
.mega.sm .all{display:block;padding:9px 12px;border-radius:10px;font-size:13.5px;
  color:var(--gold);font-weight:600}
.mega.sm .all:hover{background:var(--gold-soft)}
/* mobile menu e sub-link gulo indent kore alada bojha jay */
.mobile-menu .sub{display:block;padding:9px 0 9px 16px;font-size:14.5px;color:var(--body);border-bottom:0}
.mobile-menu .grp{display:block;padding:12px 0 4px;font-size:12.5px;font-weight:700;
  letter-spacing:.6px;color:var(--muted);border-bottom:0}

/* ═══ The mobile drawer: current item, height, and the two buttons ═══════
   Three separate defects, all measured at 390x844 on the build before this.

   ── 1. The active row was marked and never painted ───────────────────
   partials/header.php marks the current row `.on` (and the group heading of
   the section it belongs to). There was NO rule for `.mobile-menu a.on`
   anywhere in this file — the old JavaScript added that class in the drawer
   and nothing styled it, so on EVERY page, at every phone width, the drawer's
   current item was pixel-identical to the twenty rows around it. Confirmed by
   screenshot on /pharmacy: "ফার্মেসি" carried `class="sub on"` and looked like
   every other trade.

   The leaf gets a gold bar in the 16px indent `.sub` already reserves — colour
   alone is what this menu had a moment ago and it is not enough on a list of
   twenty-one identical rows. */
.mobile-menu a.on{color:var(--gold);font-weight:700}
.mobile-menu .sub{position:relative}
.mobile-menu .sub.on::before{content:"";position:absolute;left:2px;top:8px;bottom:8px;
  width:3px;border-radius:2px;background:var(--btn-grad)}
.mobile-menu .grp.on{color:var(--gold)}

/* ── 2. The bottom of the drawer could not be reached AT ALL ──────────
   `header` is `position:sticky;top:0` and the drawer is inside it. The drawer
   is 1261px tall — twenty-one links in four groups — and the viewport is 844.
   A sticky box pinned at the top does not scroll, so the tail hung off the
   bottom of the screen and stayed there at every scroll offset. Measured by
   stepping scrollY across the whole 10712px document and taking the best case:
   the account button's bottom was 476px below the fold at 390x844, 580px at
   360x740 and 424px at 414x896 — i.e. "রিসোর্স", "কোম্পানি", the login link and
   the green button were unreachable on every common phone. That is the whole
   of the owner's "my account section is not showing properly": it was not
   drawn wrong, it was off-screen.

   So the drawer scrolls inside itself. The exact height is set by
   assets/app.js when it opens, from the drawer's own measured top, because
   only the browser knows whether the announcement bar is still there; this is
   the floor for the frame before that runs and for any resize it misses.
   `dvh` first with `vh` under it: on iOS Safari `100vh` is the LARGER,
   address-bar-hidden viewport, which would put the tail back under the chrome. */
.mobile-menu.open{max-height:calc(100vh - 150px);max-height:calc(100dvh - 150px);
  overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}

/* ── 3. `.mobile-menu a` was winning the buttons' own geometry ────────
   `.mobile-menu a` (0,1,1) outranks `.btn` (0,1,0), so the free-trial button
   and the "আমার একাউন্ট" button were taking `display:block` and — the part
   nobody had noticed — `padding:13px 2px` from it as well. Measured: a 320px
   wide button, `text-align:start`, label sitting 2px from its left edge, which
   is the crowding in the owner's screenshot. `justify-content:center` was
   already on them from `.btn` and was inert on a block box.

   This selector is (0,2,0) and takes the geometry back. Restoring `flex` also
   makes an icon possible again — see the note in partials/header.php, which
   had dropped one because an <svg> inside `display:block` became its own line.
   Stated as its own rule rather than by raising `.btn`'s specificity, because
   `.mobile-menu a`'s block/padding IS right for the twenty-one links. */
.mobile-menu .btn{display:flex;align-items:center;justify-content:center;gap:9px;
  padding:13px 22px;text-align:center}
@media(max-width:480px){ .mobile-menu .btn{padding:13px 20px} }
/* callback strip — footer er thik agey. onek dokandar form vore na, shudhu number dey */
.cbstrip{background:linear-gradient(100deg,rgba(22,168,111,.10),rgba(15,157,106,.05));
  border-top:1px solid var(--gold-line);border-bottom:1px solid var(--gold-line);padding:34px 0}
.cbstrip .in{display:flex;align-items:center;gap:26px;flex-wrap:wrap;justify-content:space-between}
.cbstrip h2{font-size:22px;margin-bottom:6px}
.cbstrip p{font-size:14.5px;margin:0}
.cbform{display:flex;gap:10px;flex-wrap:wrap}
.cbform input{padding:13px 18px;border-radius:999px;border:1px solid var(--line);
  background:var(--card);color:var(--ink);font-family:inherit;font-size:16px;min-width:220px;outline:none}
.cbform input:focus{border-color:var(--gold);box-shadow:0 0 0 3px var(--gold-soft)}
.cbform input.err{border-color:var(--pink)}
.cbnote{width:100%;font-size:13px;color:var(--muted);margin-top:4px}
.cbnote.ok{color:var(--ok)}

/* exit-intent — chole jawar agey ek bar */
.exit{position:fixed;inset:0;z-index:120;display:none;place-items:center;padding:20px;
  background:rgba(0,0,0,.72);backdrop-filter:blur(4px)}
.exit.show{display:grid}
.exitbox{background:var(--card);border:1px solid var(--gold-line);border-radius:22px;
  padding:38px 34px;max-width:520px;width:100%;text-align:center;position:relative;box-shadow:var(--shadow-lg)}
.exitbox h2{font-size:26px;line-height:1.45;margin-bottom:12px}
.exitbox p{font-size:15.5px;margin-bottom:24px}
.exitbox .btn{width:100%;margin-bottom:10px}
.exitbox .x{position:absolute;right:14px;top:14px;width:36px;height:36px;border-radius:50%;
  border:1px solid var(--line);background:var(--card-2);color:var(--ink);font-size:19px;
  cursor:pointer;font-family:inherit;line-height:1}
.exitbox .x:hover{border-color:var(--gold);color:var(--gold)}
.exitbox .small{font-size:13px;color:var(--muted);margin:0}
@media(max-width:768px){
  .cbstrip .in{flex-direction:column;align-items:stretch;gap:18px}
  .cbform input{min-width:0;flex:1}
  .exitbox{padding:28px 22px}
  .exitbox h2{font-size:21px}
}

/* ===================================================================
   NARROW-SCREEN HARDENING

   The tiers above stop at 480px and treat 360px as the floor. The cheap
   Android phones still being sold here report 320px, and a layout that
   survives 360px is not automatically safe at 320px — the page gutter
   alone is 32px of the 320.

   Everything in this section is a root-cause fix rather than a per-page
   nudge, because the copy on these pages moves: a longer product name, a
   longer Bengali compound or a bigger price must not be able to push the
   document sideways again the next time someone edits a sentence.
   =================================================================== */

/* --- media is never wider than its box ------------------------------
   The site ships no oversized bitmap today, so nothing here moves; the
   rule exists so that the first <img> someone drops in at its natural
   size cannot scroll the whole page sideways. */
img,svg,video,iframe,canvas{max-width:100%}
img,video{height:auto}

/* --- layout grids may not be sized by their own content --------------
   `1fr` is `minmax(auto,1fr)`, and that `auto` floor is the grid item's
   min-content width. So one unbreakable thing inside a card — a
   20-character default <input>, a nowrap CTA, a long Bengali compound —
   makes the TRACK wider than the page and the entire document scrolls
   sideways. Measured before this rule: /contact?lang=en at 320px reported
   documentElement.scrollWidth 346 against innerWidth 320, because
   .formcard's min-content is the intrinsic width of the name field; and
   /signup pushed 1024 to 1038 for the same reason at desktop width.

   min-width:0 drops that floor to zero, so the track is the container
   and the content wraps inside it instead. Keyed to the layout grids by
   name and deliberately NOT to `*`, so that the scrolling containers
   (.pane, .cmp-wrap) and the intentionally-wide .tbl/.cmp keep the
   min-widths they are supposed to have. */
.grid-2>*,.grid-3>*,.grid-4>*,.grid-5>*,.grid-6>*,.f2>*,.form-wrap>*,.orderwrap>*,
.counters>*,.integ>*,.tiles>*,.hstats>*,.case-stats>*,.mock-stats>*,
.gbox>*,.fgrid>*,.dl>*,.vids>*,.blogs>*,.nlist>*,.steps>*,.pos-grid>*,
.split>*,.frow>*,.bwide>*,.calc>*,.case>*,.demo>*,.problem>*,
.why-strip>*,.hero .wrap>*,.lp-hero .wrap>*{min-width:0}

/* --- flex rows that have to be allowed a second line -----------------
   Each of these is display:flex at the default nowrap, so its
   min-content width is the SUM of its children: it cannot shrink, it can
   only stick out of the card it lives in. On /en/ the trust badge
   "Payments: bKash Nagad Rocket Card" measured 337px inside a 288px
   column. Wrapping is the natural reading of all three (a price line, a
   trust badge, a payment-logo strip) so they wrap at every width rather
   than only on phones — a longer payment list then costs a line instead
   of the page. */
.rec-pick{flex-wrap:wrap}
.tbadge{flex-wrap:wrap;justify-content:center}
.paylogos{flex-wrap:wrap}

/* --- long unbroken strings, at every width ---------------------------
   The 768px tier already does this for the elements that were known to
   carry emails and IMEIs. Hoisting it out of the media query covers the
   tablet range too, where a card column is only ~230px wide. */
.crd code,.tbl td,.tbl th,.orow,.contact-card small,.contact-card b,
.office p,.prose p,.prose li,.fbot,.mstat b,.tile b{overflow-wrap:anywhere}

/* -------------------------------------------------------------------
   <= 1080px  tap targets

   The tap-target sizes live in the 768px tier, but the navbar collapses
   to the burger at 1080px — so between 769px and 1080px the site serves
   a touch layout with pointer-sized controls on it. iPad landscape is
   1024px and lands squarely in that band. Measured there before this
   block: the announcement-bar close button was 16x21, the hotline link
   24px tall, the theme toggle 38x38, the burger 40x40, and the
   testimonial dots lost the invisible ::after that gives them a
   thumb-sized hit area.

   The values are the ones the 768px tier already uses, so nothing at or
   below 768px moves; this only widens the band they apply to. .tb is
   pinned to 44px for the same reason it is at 768px — the bar has to be
   as tall as the target inside it.
   ------------------------------------------------------------------- */
@media(max-width:1080px){
  /* `min-height` for the same reason the base rule is — see the announcement
     block. This tier is one row: between 769 and 1080 the sentence has the
     best part of 700px and the ticker measures it as fitting, so it sits still
     there and only the tap targets below are doing any work. */
  .tb{min-height:44px}
  .tb-right a{min-height:44px}
  .tb-x{min-width:44px;min-height:44px;padding:0;display:grid;place-items:center}
  .theme-btn{width:44px;height:44px}
  .burger{width:44px;height:44px}
  .tdot{position:relative}
  .tdot::after{content:"";position:absolute;top:-18px;bottom:-18px;left:-12px;right:-12px}
}

/* -------------------------------------------------------------------
   <= 480px additions
   ------------------------------------------------------------------- */
@media(max-width:480px){
  /* CTA labels wrap instead of leaving the screen. .btn is
     white-space:nowrap, which is right on desktop and wrong at 320px:
     the contact form's "পাঠিয়ে দিন — কল পাবেন এক ঘন্টায়" is 276px of
     unbreakable text plus 60px of pill padding inside a 256px card.
     Wrapping keeps the button inside its card whatever the label ends
     up saying, which is the part that has to keep holding. */
  .btn{white-space:normal;line-height:1.3;max-width:100%;padding:13px 20px}
  .btn-sm{padding:10px 16px}

  /* The form controls are the widest intrinsic thing on the site (a bare
     <input> is 20 characters plus padding). They already have
     width:100%; min-width:0 stops them setting a floor when they are a
     flex or grid item. */
  .field input,.field select,.field textarea,.cbform input{min-width:0}
}

/* -------------------------------------------------------------------
   <= 380px  (320px and 360px phones)
   Only the things that measured broken at 320px, not a new tier of
   design decisions.
   ------------------------------------------------------------------- */
@media(max-width:380px){
  /* 14px gutter buys back 4px a side without the text touching glass */
  .wrap{padding:0 14px}

  /* three stat tiles across a 292px content box give each one ~88px,
     which is narrower than a single Bengali label. Two up, last one
     full width — the same shape .mock-stats already uses at 480. */
  .hstats{grid-template-columns:repeat(2,1fr);gap:10px}
  .hstats > *:last-child:nth-child(odd){grid-column:span 2}
}

/* -------------------------------------------------------------------
   <= 359px  (320px phones — the SE-sized ones, and cheap Androids)

   ONE rule, and it is here rather than in the 380px tier above because
   360px does not need it. Measured with the language dropdown in the
   bar: at 360px the row has 20px to spare, at 320px it is 22px OVER and
   the navshell's content spills past its own padding.

   Twenty-two pixels cannot be found by shaving. The alternatives were
   measured too — logo to 17px, gaps to 5px, the shell's padding down
   three more pixels — and together they came to 21px, one pixel short,
   for a bar in which the wordmark touches the language button and is
   set smaller than any other text on the site. Illegible and still
   broken is not a trade.

   So the wordmark goes and the gold mark stays, which is exactly what
   .lp-bar already does at 480px and for the same reason. The mark IS the
   brand — it is the favicon and the app icon — the link keeps its
   bilingual aria-label so it is still "DokanSeba — home" to a screen
   reader, and the name is on the page in the hero and the footer. The
   language switcher the owner asked for is worth more at this width than
   a second rendering of a name the reader just tapped to get here.
   ------------------------------------------------------------------- */
@media(max-width:359px){
  .navshell .logo .wm{display:none}
}
/* ===================================================================
   PAYMENT BRAND LOGOS
   -------------------------------------------------------------------
   Every payment method on this site used to be its NAME painted into a
   box of the brand's colour (.plogo), a 44px square holding the brand's
   first letter (.ilogo .ib), or a 10px coloured dot (.paycard i). Three
   different ways of saying "this is roughly bKash-ish" and none of them
   a logo — which is the whole point of a payment strip. A shopkeeper
   deciding whether we take the wallet they actually use recognises the
   bird in about half the time it takes to read the word.

   bKash, Nagad and Rocket now carry their real artwork, out of #pay-*
   in partials/sprite.php. Card, Bank transfer and Cash keep the old
   treatment on purpose — see the note in that sprite file; none of the
   three is a brand, so none has a logo to show and a dot is the honest
   thing to draw.

   Pathao's mark is in the same sprite but under #cour-*, deliberately.
   It is a courier, not a wallet, and the only place it appears is the
   integrations grid — never the payment strip, where it would read as
   a fourth way to pay.
   =================================================================== */

/* Visually hidden, but present for a screen reader AND for the browser's
   own Ctrl+F. This site had no such helper, and it is needed the moment
   a logo REPLACES a word: an <svg><title> is announced but is not
   findable, so a visitor searching the page for "bKash" would miss the
   strip that exists to tell them we take bKash. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* The lockup in a trust strip. No pill: the artwork has its own shape and
   boxing it in a rounded rectangle is what made the old ones read as
   home-made. `flex:none` because .paylogos wraps and a logo must not be
   squeezed narrower than its own aspect. */
.paylogo{display:inline-flex;align-items:center;flex:none}
.paylogo svg{display:block}

/* The bare mark where a dot used to be. Same 10px slot's job, 18px of it,
   because a bird at 10px is a smudge. */
.paymark{display:block;flex:none}

/* bKash's wordmark is #231F20. THIS SITE IS DARK BY DEFAULT (see the token
   block at the top of this file: light is the html[data-theme="light"]
   override), so near-black is the wrong way round here — "Kash" would sit
   at about 1.2:1 on our dark ground and simply not be there. White is the
   default and the dark ink is the override, which is the mirror of how the
   panel does it, because the panel's default theme is the other one.
   bKash publish a white-wordmark lockup for dark grounds; this is that.

   IT HAS TO BE A CUSTOM PROPERTY, and this is not a style preference.
   `<use href="#pay-bkash">` clones the symbol into a SHADOW TREE, and a
   document selector cannot reach across that boundary: `.bk-ink` matches
   (it is wholly inside the tree) but `html[data-theme="light"] .bk-ink`
   does not, because the combinator has to walk out through the shadow host
   to find <html>. Written that way the rule silently never fires — the
   first attempt here did exactly that and put a white "Kash" on the light
   theme's cream background, invisible, with the page otherwise perfect.
   Custom properties DO inherit through the boundary, so the theme switch
   happens outside the shadow tree and only the resolved value crosses.

   ⚠ THIS PAIR IS FOR THE LOCKUP ON A PAGE GROUND, which is the ground it was
   written for. The one place #pay-bkash actually renders today is `.paytile`,
   which is WHITE IN BOTH THEMES — and there the dark-theme default is white on
   white at 1.00:1. The tile hands the property back to a fixed value; see "the
   permanently-WHITE plate" at the end of this file. Anywhere this lockup is
   put on a fixed ground in future needs the same treatment. */
:root{--bk-ink:#fff}
html[data-theme="light"]{--bk-ink:#231F20}
.bk-ink{fill:var(--bk-ink)}

/* The integrations grid: a neutral tile instead of a brand-coloured square.
   The square was the brand's colour with a white letter on it; putting the
   real mark on top of that would be a bKash logo on a bKash-pink field,
   which is the one background the mark is not drawn for. */
.ilogo .ib.ib-brand{background:var(--bg-alt);border:1px solid var(--line)}

/* ═══════════════════════════════════════════════════════════════════════════
   HEADER: keyboard focus, and the two fixed things that sat ON the open menu
   ═══════════════════════════════════════════════════════════════════════════

   ── Focus was effectively invisible in the bar ──────────────────────────
   There was no :focus-visible rule anywhere in this file except .skip and the
   form fields, so every control in the header fell back to the user agent's
   own ring. Measured in the dark theme that came out as `outline: auto 1px
   rgb(16,16,16)` on a #111512 header — a near-black hairline on a near-black
   bar. A keyboard reader could tab the whole navigation without ever seeing
   where they were.

   :focus-visible rather than :focus, so a mouse click does not leave a ring
   behind on a control that was just pressed. The halo is the same --gold-soft
   the active states already use, so it reads as this site's own colour in both
   themes rather than as a browser default. */
.nav-item > a:focus-visible,
.mega a:focus-visible,
.mobile-menu a:focus-visible,
.langpop a:focus-visible,
.langbtn:focus-visible,
.burger:focus-visible,
.theme-btn:focus-visible,
.logo:focus-visible,
.tb-right a:focus-visible,
.tb-x:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:11px}
/* The ring on a panel row must sit OUTSIDE it. Inset — which is where this
   started, to keep clear of the panel edge — drew a --gold ring on the row that
   is FILLED with --gold, which is the row focus lands on when the panel opens:
   green on green, invisible, photographed and checked. The panel's own 6px of
   padding is enough room for a 2px ring at 2px offset, so the shared rule above
   is right for these and this only rounds the corner to match the row. */
.langpop a:focus-visible{border-radius:10px}

/* ── The floating CTA and the sticky bottom bar rendered OVER the open menu ──
   `header` is z-index 70; `.fab` is 90 and `.mbar` is 92, and both are
   `position:fixed`, so neither is inside the header's stacking context and
   both painted on top of the mobile menu's links. Measured at 393×850 with the
   menu open: .fab sat at y=722–766 and .mbar covered y=783–850, squarely over
   the menu, which runs to y=1399.

   They are HIDDEN while the menu is open rather than out-stacked. Raising the
   header's z-index would win the paint and lose the argument: a floating
   "order now" button and a sticky action bar are navigation shortcuts, and
   they have nothing to offer while the navigation itself is open on top of
   them. assets/app.js sets the attribute in the same place it toggles the
   menu, so the two cannot disagree.

   The language panel gets the SAME treatment for the same reason — it is the
   other thing in this header that opens over the page, and on a short screen (a
   landscape phone) it reaches the band the .fab occupies. Same attribute shape,
   set in the same block of assets/app.js that owns whether the panel is open,
   so the attribute and the state cannot disagree.

   `html` rather than `body` because that is where the site's other two global
   states — data-theme and data-lang — already live. */
html[data-menu="open"] .fab,
html[data-menu="open"] .mbar,
html[data-langdd="open"] .fab,
html[data-langdd="open"] .mbar{display:none!important}

/* ── The switch at the narrow end ────────────────────────────────────────
   The segmented control is wider than the 46px `.langdd` trigger it replaced,
   and at 360px — a Galaxy-A width, not an edge case — that extra pushed the
   burger 19px off the right of the screen. Measured against the previous
   build on a second port rather than guessed: 360px was clean before this
   change and overflowing after, so it is this control's bill to pay.

   The dropdown pays that bill twice over — its trigger is ~54px here against
   the segmented control's 80 — and it still tightens itself rather than hiding
   the globe or collapsing the wordmark beside it. The globe is the part that makes this
   legible as a language control to a reader who cannot read either code, and
   dropping it on phones would remove it exactly where most of this site's
   readers are. So the padding, the gap and the segment width give up the
   pixels instead, and the row keeps its 44px touch height throughout. */
@media(max-width:400px){
  .nav-right{gap:5px}
  .langbtn{gap:3px;padding:0 6px 0 7px;font-size:12px}
  .lang-globe{width:13px;height:13px}
}

/* ── The English nav did not fit just above the burger breakpoint ────────
   Between 1081px (one pixel past the switch to the desktop bar) and roughly
   1200px, the English navigation overflowed the window: six labels, the
   language switch, the login link and the "Free trial" button came to 1068px
   of content in a 1037px shell at 1081, and the page scrolled sideways with
   the CTA hanging off the right edge. Measured docW 1153 against a 1081
   window.

   Bangla fits at the same widths — its labels are shorter — which is why this
   survived: the site's own language is the one that renders correctly, and
   the failure only appears in the language nobody browsing internally reads.
   It was there before this lane's changes; verified by serving the previous
   build on a second port and measuring both.

   The band is closed by tightening the bar rather than by moving the
   breakpoint to ~1200px. Sending a 1100px laptop to the hamburger to fix an
   English-only overflow would take the whole navigation away from a window
   that has room for it in either language once the padding is sane. */
/* ── 340px and below: the bar fits, at the price of 27px of wordmark ─────

   At 320 the header still ran 28px off the right of the screen after the
   dropdown had given back the 26 the segmented control was costing: 131px of
   logo image + 10 gap + 161 of controls + 19 of shell padding is 321 inside a
   292px shell. Measured on this build, not estimated, and measured on the
   PREVIOUS one too — it was 44px over there, so this band was broken before
   the dropdown and is merely less broken by it.

   The remaining 28 come out of the logo, and deliberately not out of the three
   controls beside it: the language switch, the theme button and the burger are
   the only things in this bar a reader can DO anything with at this width, and
   all three are already at the 44px touch floor. A wordmark rendered at 104px
   instead of 131 is still legible and still the brand; a 38px burger is a
   mis-tap. The band is capped at 340px so no common Android width sees it —
   360 fits without any of this.

   Everything here is a tightening of the header alone. `.wrap` is untouched:
   its 14px is the page gutter every section on the site is aligned to. */
@media(max-width:340px){
  .navshell{padding:9px 5px 9px 9px;gap:8px}
  .logo .brandlogo{max-width:104px}
  .nav-right{gap:4px}
}

@media(min-width:1081px) and (max-width:1200px){
  .nav-links{gap:0}
  .nav-item > a{padding:9px 10px;font-size:14.5px}
  .nav-right{gap:7px}
  .nav-right .login{padding-left:2px}
}

/* ══════════════════════════════════════════════════════════════════════
   REGIONS THAT DO NOT FOLLOW THE THEME
   ══════════════════════════════════════════════════════════════════════

   Most of this site has two grounds — page-dark and page-light — and one set
   of ink tokens that flips with them. A handful of regions have only ONE
   ground: they are dark in BOTH themes (`.cta`, `.bwide .bimg`, `.mock`,
   `.thumb`, the footer) or light in both (`.cream-panel`, `.paytile`). Ink
   inside those regions must be a FIXED value chosen for that one ground. If it
   takes a theme token instead, it is correct in one theme by luck and
   invisible in the other.

   Amber hid this for years because amber is mid-lightness and reads on either
   ground. Financial Green has no such step: `--gold` is #6FCBA4 in dark and
   #0A6F4B in light, and #0A6F4B on this band's #043724 is 2.15:1.

   The owner photographed the result — the three tick lines under
   "মাসে ৳৩০০ থেকে শুরু" measured 1.24:1 to 2.20:1 in light mode, dark ink on
   dark green. The footer already got this treatment (see `footer{...--gold:
   #6FCBA4...}` above); the pricing band did not.

   These live at the END of the file and win on SPECIFICITY, not on order —
   `.cta .tbadge` (0,2,0) beats `.tbadge` (0,1,0) wherever it sits, including
   inside the responsive tiers. Nothing above needed editing, which keeps this
   block off every line range the other lanes are working in.

   ── The nested exception ────────────────────────────────────────────────
   `.rec` is a WHITE card sitting inside the dark `.cta` band, so the rule
   inverts inside it: there, the theme tokens are RIGHT and the band's fixed
   values are wrong. That is what made "এই প্যাকেজটি অর্ডার করুন" white on
   white at 1:1 — `.cta .btn-line{color:#fff}` reached into a card it was never
   written for. So `.rec` hands the theme back.
   ------------------------------------------------------------------------ */

/* ---- the permanently-dark bands ----
   `.demo` is carried here for consistency but is NOT verified: no page in this
   site renders `class="demo"` any more (the live-demo section was removed —
   see the note in pages/index/page.php), so the rule is unreachable today and
   the 264-capture run could not exercise it. It is written the same way as
   `.cta` so that if the band ever comes back it comes back correct, not so
   that anyone can claim it was tested. */
.cta .over,
.demo .over,
.demo .cred h3 svg{color:#6FCBA4}               /* 6.82:1 on #043724 */
.cta .tbadge{color:#96A29A}                     /* 5.03:1 — same ink as `.cta p` */
.cta .tbadge b{color:#fff}                      /* 13.32:1 — same ink as `.cta h2` */
.cta .tbadge svg{color:#6FCBA4}                 /* the tick itself, 6.82:1 */

/* The figure in the headline is gradient-clipped text, so its colour is a
   gradient and no single ratio describes it. In light mode it took the LIGHT
   `--grad` (#0F9D6A → #0A6F4B) onto this dark band: the left end held 3.84:1
   but the right end fell to 2.15:1 against a 3.0 requirement, so "৳৩০০" faded
   out from left to right. Pinned to the dark-ground ramp, the WORST stop is
   4.35:1. */
.cta .gtext{background:linear-gradient(90deg,#6FCBA4 0%,#34B483 45%,#16A86F 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}

/* Blog list thumbnails carry the same fixed dark gradient as `.cta`, and the
   same theme-following icon: 2.15:1 down to 1.60:1 in light mode. */
.bwide .bimg{color:#6FCBA4}

/* ---- the light card nested inside the dark band ---- */
.cta .rec .btn-line{color:var(--ink);border-color:var(--line)}
.cta .rec .btn-line:hover{border-color:var(--gold);color:var(--gold)}
.cta .rec > p{color:var(--body)}

/* ---- the permanently-WHITE plate: the payments row ----

   `.paytile` is `background:#fff` in both themes — the block above already
   names it as one of the light-in-both regions, and partials/pay-strip.php
   gives the reason: bKash magenta, Rocket purple and Dutch-Bangla blue are
   each drawn FOR white, so one white tile per mark treats every brand alike.

   Six of the seven marks on that row are fixed paint and were measured on the
   tile, identical in both themes: bKash's bird #E2136E 4.61:1 and #D12053
   5.19:1, Nagad #EC1C24 4.41:1 / #F16522 3.17:1 / #F6921E 2.32:1, Rocket
   #8B3392 7.03:1, and the four inline wordmark hexes in pay-strip.php —
   City #E4002B 4.85:1, BRAC #00427A 10.19:1, DBBL #0067B2 5.86:1, Card
   #1A73E8 4.51:1. (Those are logotypes, which WCAG 1.4.3 exempts; they are
   recorded so the next reader can see they were checked and are NOT tokens.)

   The seventh still followed the theme, and that is the whole bug. bKash's
   WORDMARK — the "Kash" — is painted through `--bk-ink`, which is #fff by
   default and #231F20 only under [data-theme="light"], because this site is
   dark-first and the token was written for the lockup sitting on the PAGE
   ground. On a white tile the default is white on white:

       dark theme   #FFFFFF on #FFFFFF =  1.00:1   ← not drawn at all
       light theme  #231F20 on #FFFFFF = 16.30:1

   Nothing looked broken, which is why it survived: the "b" and the bird are
   fixed magenta and rendered normally, so the dark-theme tile read as a
   slightly odd bKash mark rather than a missing one.

   IT MUST BE THE CUSTOM PROPERTY, not a fill. The wordmark is a <use> clone
   living in a SHADOW TREE, so `.paytile .bk-ink` cannot match it — the
   combinator would have to walk out through the shadow host to reach the
   tile. Only inherited custom properties cross that boundary, so the value
   has to be handed IN from the host side. That is the same trap the token's
   own note (search `--bk-ink` above) records for the light-theme rule.

   And it is pinned HERE rather than by changing the `:root` default, because
   the theme-following pair is still correct for the lockup on a page ground,
   which is what it was drawn for. The tile is the exception, and exceptions
   to the theme live in this block. */
.paytile{--bk-ink:#231F20}                      /* 16.30:1 on the tile, both themes */

/* ══════════════════════════════════════════════════════════════════════
   ONE CLASS, TWO GROUNDS — `.pg`
   ══════════════════════════════════════════════════════════════════════
   `.pg.ok` is used in two places that are not the same kind of place: the
   app mockups (`.mock`, `.frame`) which are dark in both themes, and the
   `/status` service table which follows the theme. #6FCBA4 is right for the
   first and 1.65:1 for the second, and no single value satisfies both — the
   class has to split. The theme-following case takes the light accent
   (5.23:1 on the pill's #DAF1E8) and the mockups keep the mint they had.

   `.pg.warn` and `.pg.due` are deliberately NOT given light values: they
   occur ONLY inside the mockups (verified across all 33 pages), so a light
   rule for them would be a rule no page can render and no run can check. */
html[data-theme="light"] .pg.ok{color:#0A6F4B}
html[data-theme="light"] .mock .pg.ok,
html[data-theme="light"] .frame .pg.ok{color:#6FCBA4}

/* ---- plain contrast misses, not region bugs ----
   The top bar's dismiss "×" took `--muted` and landed at 4.46:1 against a
   4.5 requirement — a 0.04 miss, but on 32 of 33 pages. `--body` is the same
   family one step darker and clears it at 5.52:1. Light only: the dark
   theme's pairing was never in question. */
html[data-theme="light"] .tb-x{color:var(--body)}

/* ---- the brand mark, which is an ASSET that does not follow the theme ----
   Same defect as the rest of this block, one layer out: the header drew
   `/api/branding/logo-dark` in BOTH themes. 49% of that file's ink is #FFFFFF,
   which is 1.13:1 on the light bar — "DOKAN" was not visible in light mode,
   while "SEBA" (#2FF77A, the other 51%) read as a shape at 1.27:1. The
   light-ground twin already existed at `/api/branding/logo` with the same
   artwork in #01262F: 14.14:1.

   PHP cannot choose between them — the theme is localStorage plus an inline
   script, with no cookie — so both marks are emitted and this picks. Each
   theme hides exactly one, and neither needs an explicit display value for the
   one it shows, so the flex layout of `.logo` is untouched.

   `:not([data-theme="light"])` rather than `[data-theme="dark"]` on purpose:
   if scripting is off the attribute is never set at all, and the page renders
   with the dark `:root` defaults — so the dark mark is the correct one to
   leave showing in that case, and this selector is the one that does it.

   `#2FF77A` is unchanged and deliberately so. WCAG 1.4.3 exempts logotypes,
   so 1.27:1 on a brand mark is not a conformance failure, and how saturated
   that mark sits on white is the owner's decision rather than a defect to fix
   underneath him. */
html:not([data-theme="light"]) .brandlogo-l{display:none}
html[data-theme="light"] .brandlogo-d{display:none}

/* ── The complete per-trade feature list (partials/trade-features.php) ──────
 *
 * Every colour is a token, so light and dark both follow the page rather than
 * needing a second block. Nothing is declared only inside a media query or a
 * [data-theme] rule — that is the bug that renders one theme's text on the
 * other theme's ground, and this site has three theme states, not two.
 *
 * ── The badge colour, measured ────────────────────────────────────────────
 *
 * `--gold-ink` is the ON-GOLD text colour: #FFFFFF in light, #043724 in dark.
 * Used on `--gold-soft` — which is a 10–14% tint of that same green — it
 * measured 1.12:1 in light and 1.05:1 in dark. Invisible in BOTH themes, and
 * the screenshot looked plausible in each. `--gold` is the token for green
 * text on a page background, which `.over` already proves at this size.
 *
 * The grid is deliberately NOT .grid-3's equal thirds: these groups hold
 * between two and fourteen items, so equal columns leave a page of white space
 * beside "কর্মচারী". auto-fit lets a short group sit beside a tall one.
 */
.ftgrid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr));align-items:start;gap:20px}
.ftgroup{padding:24px 22px}
.ftgroup:hover{transform:none;border-color:var(--line);box-shadow:none}
.ftgroup h3{display:flex;align-items:center;gap:9px;font-size:16.5px;margin-bottom:14px;
  padding-bottom:12px;border-bottom:1px solid var(--line)}
.ftn{margin-left:auto;font-size:12.5px;font-weight:600;color:var(--gold);background:var(--gold-soft);
  border:1px solid var(--gold-line);border-radius:999px;padding:2px 9px;font-variant-numeric:tabular-nums}
.ftlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:13px}
.ftlist li{display:flex;flex-direction:column;gap:3px}
.ftt{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px}
.ftlist b{font-size:14.5px;font-weight:600;color:var(--ink);line-height:1.5}
.ftb{font-size:13px;color:var(--muted);line-height:1.65}
.ftplan{display:inline-block;font-size:11px;font-weight:600;color:var(--gold);
  background:var(--gold-soft);border:1px solid var(--gold-line);border-radius:5px;
  padding:1px 6px;white-space:nowrap}
@media(max-width:640px){.ftgrid{grid-template-columns:1fr}.ftgroup{padding:20px 18px}}

/* ── The footer's contact lines: email, address, opening hours ─────────────
 *
 * Added with them (partials/footer.php). The footer already carried a phone
 * icon and the social row; these three facts lived in lib/content.php and on
 * /contact and were named nowhere in the block a reader scrolls to for exactly
 * them.
 *
 * Colours are the footer's own, inherited — no hardcoded white. The wordmark
 * beside these was `style="color:#fff"` and that is how the header's mark ended
 * up at 1.13:1 the day a light bar arrived.
 */
.fmeta{list-style:none;margin:18px 0 0;padding:0;display:flex;flex-direction:column;gap:9px}
.fmeta li{display:flex;align-items:flex-start;gap:9px;font-size:13.5px;line-height:1.6;opacity:.85}
.fmeta svg{flex:0 0 auto;margin-top:3px;opacity:.75}
.fmeta a{color:inherit;text-decoration:none;border-bottom:1px solid rgba(255,255,255,.22)}
.fmeta a:hover{border-bottom-color:currentColor}

/* tr1 — the consent notice. Bottom strip, never a wall. */
.consent{position:fixed;left:16px;right:16px;bottom:16px;z-index:60;display:flex;gap:14px;align-items:center;justify-content:space-between;flex-wrap:wrap;
  padding:14px 18px;border-radius:14px;background:var(--card,#fff);border:1px solid var(--line);box-shadow:0 12px 40px rgba(0,0,0,.14);font-size:14px;color:var(--ink)}
.consent[hidden]{display:none}
.consent p{margin:0;flex:1 1 320px;line-height:1.5}
.consent p a{margin-left:6px;text-decoration:underline}
.consent-actions{display:flex;gap:8px;flex-wrap:wrap}
.consent .btn{padding:9px 16px;border-radius:999px;font-size:14px}
@media(max-width:480px){.consent{left:8px;right:8px;bottom:8px;padding:12px 14px}}
