/* Bubbli landing page — all styles.
   Split out of index.html so the browser can cache it separately from the
   markup, and so a strict CSP no longer needs to allow inline styles. */

*{margin:0;padding:0;box-sizing:border-box}

  /* ==========================================================
     Bubbli v2
     ========================================================== */
  #bb-root{
    /* official brand colours, taken from the logo lockup */
    --brand-orange:#fc4631;
    --brand-navy:#10276b;

    /* neutrals: cool grey-blue */
    --paper:#f9fafd;
    --card:#ffffff;
    --ink:#232833;
    --muted:#727a88;
    --line:#e0e5ee;
    --wash:#f4f6fa;        /* subtle inset panels (meter, notes, receipt) */

    /* service tints lifted from the app's New Order screen */
    --svc-core:#f6f7fa;
    --svc-luxe:#fdeeeb;
    --svc-express:#fbfbe3;
    --svc-core-line:#b4c1e2;  /* chosen-card border: each tint's own hue, deepened */
    --svc-luxe-line:#f2b6a4;

    --accent:var(--brand-orange);
    --accent-deep:#d8341f;
    --foam:#ffeae4;
    --mint:#0e7d3a;
    --mint-soft:#e7f4ea;
    --danger:#b3261e;
    --r-lg:24px;
    --r-md:16px;
    --shadow:0 10px 30px rgba(35,45,70,.08);

    color-scheme: light;
    background:var(--paper);
    color:var(--ink);
    font-family:Tajawal,-apple-system,"SF Arabic",BlinkMacSystemFont,"Segoe UI","Noto Sans Arabic",sans-serif;
    line-height:1.7;
    min-height:100vh;
    overflow-x:hidden;
    position:relative;
  }
  /* Base layer wrapped in :where() so it carries ZERO specificity — otherwise
     `#bb-root *` (1,0,1) silently beats every component class (0,1,0) and wipes
     out margins, button fills and borders across the whole page. */
  :where(#bb-root) *{box-sizing:border-box;margin:0;font-family:inherit}
  #bb-root ::selection{background:var(--foam)}
  :where(#bb-root) :is(img,svg){max-width:100%;display:block}
  :where(#bb-root) button{cursor:pointer;border:0;background:none;color:inherit;font:inherit}
  :where(#bb-root) :is(input,textarea){font-size:inherit;color:var(--ink)}
  :where(#bb-root) a{color:inherit}
  #bb-root :focus-visible{outline:3px solid rgba(252,70,49,.4);outline-offset:2px;border-radius:6px}
  /* `hidden` must always win. Any component class that sets `display` (e.g.
     .bb-verified{display:flex}) otherwise beats the UA's [hidden]{display:none},
     because author styles outrank UA styles — the element stays visible while
     el.hidden reads true. */
  #bb-root [hidden]{display:none !important}

  /* ---------- ambient bubbles (the one flourish) ---------- */
  .bb-bubbles{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:0}
  .bb-bubble{
    position:absolute;border-radius:50%;
    background:radial-gradient(circle at 32% 28%, rgba(255,255,255,.98), rgba(255,255,255,.30) 42%, rgba(252,70,49,.07) 100%);
    box-shadow:inset 0 0 0 1px rgba(252,70,49,.10);
    opacity:.4;
    animation:bbFloat linear infinite;
  }
  @keyframes bbFloat{
    from{transform:translateY(12vh) translateX(0)}
    to{transform:translateY(-110vh) translateX(24px)}
  }
  @media (prefers-reduced-motion:reduce){ .bb-bubble{animation:none;opacity:.18} }
  /* Nine continuously-animating gradient circles are pure decoration and cost
     real paint work on a phone. Half of them are hidden on small screens. */
  @media (max-width:640px){ .bb-bubble:nth-child(n+5){display:none} }

  .bb-shell{position:relative;z-index:1;max-width:1100px;margin:0 auto;padding:0 18px 90px}

  /* ---------- header ---------- */
  /* The header is the one place that does NOT mirror with the page direction:
     the lockup stays on the left and the language switch on the right in both
     languages. `direction:ltr` fixes the flex axis to left→right so the pair
     keeps its physical sides; everything else on the page still flows with dir.
     The switcher carries its own dir attribute, so its label renders correctly
     inside this LTR box. */
  .bb-header{display:flex;align-items:center;padding:20px 2px 4px;direction:ltr}
  .bb-logo{display:flex;align-items:center}
  /* official lockup, inlined: mark in brand orange, wordmark in brand navy */
  .bb-logo-mark{
    width:132px;height:auto;display:block;
    animation:bbLogoFloat 5s ease-in-out infinite;will-change:transform;
  }
  @media(max-width:400px){ .bb-logo-mark{width:118px} }
  @keyframes bbLogoFloat{
    0%,100%{transform:translateY(0)}
    50%    {transform:translateY(-7px)}
  }
  @media (prefers-reduced-motion:reduce){ .bb-logo-mark{animation:none} }

  /* Language switch. First child in the header, so the logo's auto margin still
     pushes the lockup to the inline-end and this sits at the inline-start — the
     pair mirrors itself between the Arabic and English pages with no override.
     A real <a> to the other URL, never an in-page toggle: the two languages are
     separate documents so each one can be indexed on its own. */
  .bb-lang{
    display:inline-flex;align-items:center;gap:6px;margin-left:auto;
    padding:6px 13px;border-radius:999px;
    border:1.5px solid var(--line);background:var(--card);
    color:var(--muted);font-size:.8rem;font-weight:700;
    text-decoration:none;white-space:nowrap;
    transition:border-color .15s,color .15s;
  }
  .bb-lang svg{width:15px;height:15px;flex:none}
  /* Flexbox centres the LINE box, and Tajawal's descent is deeper than its
     ascender overshoot, so the label's ink lands ~0.115em above the pill's
     centre while the icon sits exactly on it — measured at 1.43px for "English"
     and 1.53px for "العربية", hence one value for both. Nudging only the label
     brings the ink onto the same centre line as the icon. Same correction the
     quantity digit needs. */
  .bb-lang > span{display:inline-block;transform:translateY(0.115em)}
  .bb-lang:hover,.bb-lang:focus-visible{border-color:var(--accent);color:var(--accent)}

  /* ---------- hero: welcome + order ---------- */
  .bb-hero{display:grid;gap:22px;padding:44px 0 10px;align-items:start}
  @media(min-width:980px){
    .bb-hero{grid-template-columns:1fr 1fr;gap:44px;padding-top:56px}
    .bb-hero-copy{position:sticky;top:24px}
  }
  .bb-h1{
    font-size:clamp(2.1rem,6.5vw,3.3rem);font-weight:800;line-height:1.25;
    text-wrap:balance;margin-bottom:10px;margin-top:8px;color:var(--brand-navy);
  }
  .bb-h1 em{font-style:normal;color:var(--accent)}

  /* The real <h1>: the target keyword, set as an eyebrow above the display
     line. Kept smaller so the animated hook stays the visual hero — Google
     weighs the H1's text, not its font-size. Swap the sizes here if the
     keyword should be the big line instead. */
  .bb-h1-seo{
    font-size:clamp(.95rem,2.6vw,1.1rem);font-weight:700;
    color:var(--muted);letter-spacing:.005em;
    margin-top:8px;margin-bottom:2px;
  }

  /* rotating headline — "الكشف بالمسح".
     No overflow:hidden here: the clip-path does the masking, and clipping the box
     would cut Arabic diacritics (the shadda in معطّر / مغلّف sits above the line).
     The word is never split per-letter — that severs Arabic cursive joining. */
  .bb-h1-slot{
    position:relative;display:inline-block;vertical-align:top;
    color:var(--accent);white-space:nowrap;
  }
  .bb-h1-slot i{
    position:absolute;inset-inline-start:0;top:0;
    font-style:normal;white-space:nowrap;opacity:0;
  }
  .bb-h1-slot i.in {animation:bbWipeIn .62s cubic-bezier(.65,0,.35,1) forwards}
  .bb-h1-slot i.out{animation:bbWipeOut .40s cubic-bezier(.65,0,.35,1) forwards}
  @keyframes bbWipeIn {from{opacity:1;clip-path:inset(0 0 0 100%)} to{opacity:1;clip-path:inset(0 0 0 0)}}
  @keyframes bbWipeOut{from{opacity:1;clip-path:inset(0 0 0 0)}    to{opacity:1;clip-path:inset(0 100% 0 0)}}
  @media (prefers-reduced-motion:reduce){
    .bb-h1-slot{width:auto !important}
    .bb-h1-slot i{position:static;animation:none !important;opacity:1;clip-path:none}
    .bb-h1-slot i.out{display:none}
  }
  /* readable by screen readers, invisible on screen */
  .bb-sr{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;
         clip:rect(0 0 0 0);white-space:nowrap;border:0}
  .bb-sub{font-size:clamp(1rem,2.6vw,1.15rem);color:var(--muted);max-width:34ch;margin-bottom:18px}
  .bb-trust-row{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px;margin-top:26px}
  .bb-trust{
    display:inline-flex;align-items:center;gap:6px;font-size:1rem;font-weight:400;
    background:var(--card);border:1px solid var(--line);padding:6px 12px;border-radius:999px;
  }
  .bb-trust svg{width:15px;height:15px;flex:none}
  /* the certification sits in the same row but stays green so it reads as a credential */
  .bb-cert{
    color:var(--mint);background:var(--mint-soft);border-color:transparent;
    text-decoration:none;transition:transform .15s;
  }
  .bb-cert:hover{transform:translateY(-1px)}

  /* ---------- certification popup ---------- */
  /* The chip is a <button> now, so it inherits the :where() button reset; these
     just restore the pill it shares with .bb-trust. */
  .bb-cert{font:inherit;font-size:1rem;text-align:inherit}

  /* `display` MUST stay scoped to [open]. An unscoped display on <dialog> beats
     the UA's `dialog:not([open]){display:none}` and the popup renders
     permanently — the same trap that left the OTP "verified" note visible. */
  .bb-cert-modal{border:0;padding:0;background:transparent;max-width:none;color:var(--ink)}
  .bb-cert-modal[open]{
    display:flex;flex-direction:column;align-items:center;text-align:center;
    /* The global `*{margin:0}` reset kills the UA's `margin:auto`, which is what
       centres a modal dialog inside its `inset:0`. Without this it sticks to the
       top-left corner. */
    margin:auto;
    width:min(340px,calc(100vw - 32px));
    max-height:calc(100dvh - 32px);overflow:auto;
    padding:28px 24px 24px;
    background:var(--card);border-radius:var(--r-lg);
    box-shadow:0 24px 60px rgba(16,39,107,.22);
    animation:bbCertIn .22s ease-out;
  }
  .bb-cert-modal::backdrop{background:rgba(16,39,107,.45)}
  @keyframes bbCertIn{from{opacity:0;transform:translateY(8px) scale(.97)}to{opacity:1;transform:none}}
  @media (prefers-reduced-motion:reduce){ .bb-cert-modal[open]{animation:none} }

  .bb-cert-x{
    position:absolute;top:10px;inset-inline-start:10px;
    width:34px;height:34px;border-radius:50%;color:var(--muted);
    display:flex;align-items:center;justify-content:center;
  }
  .bb-cert-x:hover{background:var(--wash);color:var(--ink)}
  .bb-cert-x svg{width:17px;height:17px}

  .bb-cert-badge{width:168px;height:auto;display:block;margin-bottom:18px}
  .bb-cert-line{font-size:1rem;font-weight:700;line-height:1.65}
  .bb-cert-no{margin-top:8px;font-size:.95rem;color:var(--muted)}
  .bb-cert-no b{color:var(--ink);font-weight:700;unicode-bidi:isolate}
  .bb-cert-verify{
    margin-top:20px;display:inline-flex;align-items:center;gap:7px;
    padding:9px 17px;border-radius:999px;text-decoration:none;
    font-size:.9rem;font-weight:700;
    color:var(--mint);background:var(--mint-soft);transition:transform .15s;
  }
  .bb-cert-verify:hover{transform:translateY(-1px)}
  .bb-cert-verify svg{width:15px;height:15px;flex:none}

  /* social proof + store badge, directly under the order card */
  .bb-app{display:flex;flex-direction:column;align-items:center;gap:12px;margin-top:18px}
  .bb-rating{display:flex;align-items:center;gap:8px;font-size:.85rem;color:var(--muted)}
  .bb-stars{color:#eaa53f;letter-spacing:2px;font-size:.95rem}
  .bb-appstore{display:block;transition:transform .15s}
  .bb-appstore:hover{transform:translateY(-2px)}
  .bb-appstore img{width:200px;height:auto;display:block}

  /* ---------- order card ---------- */
  .bb-order{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow);overflow:hidden}
  .bb-order-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:16px 20px 0}
  .bb-order-title{font-weight:800;font-size:1.1rem}
  .bb-steps-dots{display:flex;gap:6px}
  .bb-dot{width:22px;height:5px;border-radius:99px;background:var(--line);transition:background .25s}
  .bb-dot.on{background:var(--accent)}
  .bb-order-body{padding:16px 20px 20px}

  .bb-step{animation:stepIn .32s ease both}
  @keyframes stepIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
  @media (prefers-reduced-motion:reduce){.bb-step{animation:none}}
  .bb-step[hidden]{display:none}

  .bb-label{font-size:.95rem;font-weight:800;margin:14px 0 8px;display:flex;align-items:center;gap:8px}
  /* step-1 labels sit above centred content (the service grid, the stepper),
     so they centre too rather than hugging the right edge */
  .bb-label--center{justify-content:center}
  .bb-label small{font-weight:500;color:var(--muted)}

  /* service cards — now carrying the real app icons */
  .bb-services{display:grid;grid-template-columns:1fr 1fr;gap:10px}
  /* tinted fills instead of outlined white cards, matching the app's New Order screen */
  .bb-svc{
    position:relative;text-align:center;border:2px solid transparent;border-radius:var(--r-md);
    padding:18px 10px 13px;background:var(--svc-core);
    transition:border-color .2s,transform .12s;
    /* Column + auto margin on the stepper pins both steppers to the bottom of
       their cards. Without it the core card's extra "لفترة محدودة" line pushes
       its stepper ~34px lower than the luxe one. */
    display:flex;flex-direction:column;
  }
  .bb-svc[data-svc="luxe"]{background:var(--svc-luxe)}
  .bb-svc:active{transform:scale(.98)}
  /* Selected = a border in the card's OWN colour family, not the orange accent.
     The accent border plus its 3px ring read as an alert beside two already
     tinted cards; an on-tone border marks the choice without shouting. The
     background never changes, and the 2px transparent border is always there so
     nothing shifts size when a card is picked. */
  .bb-svc.on{border-color:var(--svc-core-line)}
  .bb-svc[data-svc="luxe"].on{border-color:var(--svc-luxe-line)}
  /* The wrapper owns the selected-state scale and the icon owns the idle
     animation. They must be separate elements: a running animation outranks a
     normal declaration, so putting both on one element means the animation
     silently eats the .on scale. */
  .bb-svc-ico{
    display:block;width:54px;height:54px;margin:0 auto 8px;pointer-events:none;
    perspective:420px;                 /* gives the core flip real depth */
    transition:transform .25s ease;
  }
  /* the luxe orbital has more rings, so it needs a touch more room to read */
  .bb-svc[data-svc="luxe"] .bb-svc-ico{width:64px;height:64px;margin-bottom:2px}
  .bb-svc.on .bb-svc-ico{transform:scale(1.08)}
  .bb-svc-icon{width:100%;height:100%;object-fit:contain;display:block}

  /* core: a slow flip that rests, rather than spinning constantly — it should
     catch the eye on a glance, not compete with the price. Held flat for the
     first 55% of the cycle, then one full turn. transform only, so it stays on
     the compositor and costs no layout or paint. */
  .bb-svc[data-svc="core"] .bb-svc-icon{
    animation:bbCoreFlip 7s cubic-bezier(.55,0,.45,1) infinite;
    backface-visibility:visible;
  }
  @keyframes bbCoreFlip{
    0%,55% { transform:rotateY(0deg) }
    100%   { transform:rotateY(360deg) }
  }

  /* luxe: brand-orange gradient drifting through the glyph. The PNG becomes a
     mask so the gradient shows only inside the orbital strokes.
     Guarded by @supports: without mask support the wrapper would paint as a
     solid gradient rectangle, so in that case we leave the plain image alone. */
  @supports ((-webkit-mask-image:url(#m)) or (mask-image:url(#m))){
    .bb-svc[data-svc="luxe"] .bb-svc-ico{
      -webkit-mask:url(/images/service-luxe.png) center/contain no-repeat;
              mask:url(/images/service-luxe.png) center/contain no-repeat;
      /* A highlight sweeping across a solid brand base. Two things were tuned
         by eye and matter: broad orange-to-orange stops are invisible on
         strokes this thin, but a near-white peak washed the whole 64px glyph
         out at mid-sweep. A light-coral peak in a narrow window reads as
         movement while the icon stays legible at every phase. */
      background-image:linear-gradient(105deg,
        var(--accent-deep) 0%,   var(--accent) 38%,
        #ffb08c 47%,             #ffc9b0 50%,   #ffb08c 53%,
        var(--accent) 62%,       var(--accent-deep) 100%);
      background-size:300% 100%;
      animation:bbLuxeShimmer 5s linear infinite;
    }
    /* hidden, not removed — the <img> still reserves the box and still loads,
       which is what the mask is sized against. */
    .bb-svc[data-svc="luxe"] .bb-svc-icon{visibility:hidden}
  }
  @keyframes bbLuxeShimmer{
    from { background-position:0% 50% }
    to   { background-position:-300% 50% }
  }

  @media (prefers-reduced-motion:reduce){
    .bb-svc[data-svc="core"] .bb-svc-icon,
    .bb-svc[data-svc="luxe"] .bb-svc-ico{animation:none}
  }
  .bb-svc-name{font-weight:800;font-size:1.5rem}
  .bb-svc-desc{font-size:.74rem;color:var(--muted);line-height:1.55;margin-top:3px;min-height:2.4em}
  /* flex + gap so the struck-out price never merges with the new one
     (inline margins let "35" and "29" read as one number "3529" in RTL) */
  .bb-svc-price{
    margin-top:7px;font-weight:800;font-size:1.35rem;font-variant-numeric:tabular-nums;
    display:flex;align-items:baseline;justify-content:center;gap:8px;
  }
  .bb-svc-price .now{color:var(--ink)}
  /* The card price is 800-weight, which makes the default .bb-sar (sized for
     body text) read light beside it. A larger ratio here only — the totals and
     receipt keep the global size. */
  .bb-svc-price .bb-sar{height:.82em;width:.734em}

  /* Official Saudi Riyal symbol, replacing the "ر.س" abbreviation everywhere a
     price is shown. Inherits currentColor via <use>, so the same markup works
     on the ink service prices, the orange grand total and the green discount
     row. Width is derived from the 1124.14×1256.39 viewBox (ratio .895) so the
     glyph never distorts. */
  .bb-sar{
    /* Must beat `:where(#bb-root) :is(img,svg){display:block}` above, or the
       glyph becomes a block and drops onto its own line under the number. */
    display:inline-block;
    /* Tajawal's digits carry ~.64em of ink, so .72em makes the symbol read a
       touch larger than the numerals — the usual proportion for a currency
       mark. Width follows the viewBox ratio (.8947) so it never distorts. */
    height:.72em;width:.644em;
    fill:currentColor;
    /* A replaced element's baseline is its bottom edge, and the glyph fills the
       viewBox to the bottom, so `baseline` lands it exactly on the digits'. */
    vertical-align:baseline;
    flex:none;
  }
  .bb-badge{
    position:absolute;top:-9px;inset-inline-start:12px;background:var(--accent);color:#fff;
    font-size:.68rem;font-weight:800;padding:3px 10px;border-radius:999px;box-shadow:0 4px 10px rgba(252,70,49,.35);
  }

  /* per-service qty stepper, inside each card.
     The order carries a quantity per service, so a single shared stepper has no
     meaning any more — each card owns its own count and a card reads as chosen
     when that count is above zero. */
  .bb-svc-qty{
    display:flex;align-items:center;justify-content:center;gap:6px;
    margin-top:auto;background:var(--card);border:1.5px solid var(--line);
    border-radius:999px;padding:4px;
  }
  /* SVG icons, not "+" and "−" text. A glyph is centred on its LINE BOX, not on
     its ink, and Tajawal puts the ink of both symbols ~4.2px above the baseline
     — so the plus visibly sat low inside its circle. An SVG is centred
     geometrically, and both symbols get an identical stroke weight. */
  .bb-svc-qty button{
    width:40px;height:40px;border-radius:50%;border:1.5px solid var(--line);background:#fff;
    color:var(--ink);flex:none;
    display:grid;place-items:center;transition:transform .1s,border-color .2s,opacity .2s;
  }
  .bb-svc-qty button svg{width:18px;height:18px;display:block}
  .bb-svc-qty button:active{transform:scale(.9)}
  .bb-svc-qty button:disabled{opacity:.3;cursor:not-allowed}
  .bb-svc-qty .n{
    min-width:2ch;text-align:center;font-size:1.15rem;font-weight:800;
    font-variant-numeric:tabular-nums;color:var(--ink);
    /* Tajawal reserves a deep descender, so even with line-height:1 the digit's
       ink sits at the TOP of its line box — measured 3.53px above the pill's
       centre at this size. Flexbox centres the box, not the ink, so the only
       fix is to shift the glyph itself. 3.53/18.4 = 0.19em, expressed in em so
       it tracks the font size. transform, so it costs no layout. */
    line-height:1;
    transform:translateY(0.19em);
  }
  /* The pill keeps the neutral border in both states — the card's own accent
     border already signals "chosen", so repeating it inside was one highlight
     too many. A zero stays muted so an untouched card still reads as empty. */
  .bb-svc:not(.on) .bb-svc-qty .n{color:var(--muted)}

  /* free-delivery meter */
  /* No panel around it — the bar and its line of text carry the message, and a
     bordered box competed with the service cards directly above. */
  .bb-meter{margin-top:14px;padding:0 2px}
  .bb-meter-track{height:8px;border-radius:99px;background:var(--line);overflow:hidden}
  .bb-meter-fill{height:100%;border-radius:99px;background:var(--accent);transition:width .35s ease,background .35s}
  .bb-meter.done .bb-meter-fill{background:var(--mint)}
  .bb-meter-txt{font-size:.8rem;font-weight:700;margin-top:7px;color:var(--muted)}
  .bb-meter.done .bb-meter-txt{color:var(--mint)}

  /* express row — light yellow + running glyph, mirroring the app's "Sarie" card */
  /* unlike the service cards this row never takes an accent border — the toggle
     alone carries the on/off state, so the row stays calm either way */
  .bb-express{
    display:flex;align-items:center;gap:12px;margin-top:12px;padding:12px 14px;
    border-radius:var(--r-md);background:var(--svc-express);
  }
  .bb-express-ico{flex:none;width:50px;height:50px;display:grid;place-items:center}
  .bb-express-ico img{width:44px;height:44px;object-fit:contain;pointer-events:none}
  .bb-express-info{flex:1;min-width:0}
  .bb-express-info b{font-size:1rem}
  .bb-express-info small{display:block;color:var(--muted);font-size:.74rem}
  /* Track 48px, knob 22px, resting 3px from the inline-start edge, so the knob
     crosses 48-3-22-3 = 20px to reach the far end. */
  .bb-switch{position:relative;width:48px;height:28px;flex:none;--knob-travel:20px}
  /* translateX is PHYSICAL while the knob's resting edge (inset-inline-start)
     is LOGICAL, so the travel has to be flipped by hand. A fixed -20px worked
     in RTL and slid the knob straight out of the left edge of the track under
     dir="ltr" instead of across it. */
  [dir="rtl"] .bb-switch{--knob-travel:-20px}
  .bb-switch input{position:absolute;inset:0;opacity:0;cursor:pointer;margin:0}
  .bb-switch-ui{position:absolute;inset:0;border-radius:99px;background:var(--line);transition:background .2s;pointer-events:none}
  .bb-switch-ui::after{content:"";position:absolute;top:3px;inset-inline-start:3px;width:22px;height:22px;border-radius:50%;background:#fff;box-shadow:0 2px 6px rgba(0,0,0,.2);transition:transform .2s}
  .bb-switch input:checked + .bb-switch-ui{background:var(--accent)}
  .bb-switch input:checked + .bb-switch-ui::after{transform:translateX(var(--knob-travel))}

  /* totals */
  .bb-total{margin-top:16px;border-top:2px dashed var(--line);padding-top:12px;display:flex;flex-direction:column;gap:5px;font-size:.9rem}
  .bb-row{display:flex;justify-content:space-between;gap:10px}
  .bb-row .v{font-variant-numeric:tabular-nums;font-weight:700}
  .bb-row.muted{color:var(--muted);font-weight:400}
  .bb-row.muted .v{font-weight:500}
  .bb-row.free .v{color:var(--mint)}
  .bb-row.grand{font-size:1.15rem;font-weight:800;margin-top:3px}
  .bb-row.grand .v{color:var(--accent-deep)}
  .bb-row.disc .v{color:var(--mint)}

  /* buttons */
  .bb-cta{
    width:100%;margin-top:16px;padding:15px;border-radius:var(--r-md);
    background:var(--accent);color:#fff;font-weight:800;font-size:1.05rem;
    box-shadow:0 8px 20px rgba(252,70,49,.32);transition:transform .12s,box-shadow .2s,opacity .2s;
  }
  .bb-cta:active{transform:scale(.98)}
  .bb-cta:disabled{opacity:.45;box-shadow:none;cursor:not-allowed}
  .bb-cta.secondary{background:#fff;color:var(--ink);border:1.5px solid var(--line);box-shadow:none}
  .bb-back{margin-top:10px;width:100%;padding:10px;font-weight:700;color:var(--muted);font-size:.9rem}
  .bb-back::before{content:"→ ";font-weight:400}

  /* inputs */
  .bb-input{width:100%;border:1.5px solid var(--line);border-radius:var(--r-md);padding:13px 15px;background:#fff;transition:border-color .2s,box-shadow .2s}
  .bb-input:focus{outline:none;border-color:var(--accent);box-shadow:0 0 0 3px rgba(252,70,49,.14)}
  .bb-input.ltr{direction:ltr;text-align:center;letter-spacing:1px}
  .bb-hint{font-size:.74rem;color:var(--muted);margin-top:5px}
  .bb-or{display:flex;align-items:center;gap:12px;color:var(--muted);font-size:.8rem;margin:13px 0}
  .bb-or::before,.bb-or::after{content:"";flex:1;height:1px;background:var(--line)}

  .bb-locate{width:100%;display:flex;align-items:center;justify-content:center;gap:9px;padding:13px;border:1.5px solid var(--accent);border-radius:var(--r-md);color:var(--accent);font-weight:800;background:#fff;transition:background .2s}
  .bb-locate:hover{background:var(--foam)}

  /* interactive pin, loaded lazily; the fallback overlays it if Maps JS fails to load */
  .bb-map{position:relative;height:200px;border-radius:var(--r-md);overflow:hidden;margin-top:12px;background:var(--wash);border:1px solid var(--line)}
  .bb-map-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:16px;text-align:center;font-size:.82rem;color:var(--muted)}

  /* flex-start + line-height: a geocoded address can wrap to two lines */
  .bb-located{display:flex;align-items:flex-start;gap:9px;background:var(--mint-soft);color:var(--mint);font-weight:700;font-size:.88rem;border-radius:var(--r-md);padding:12px 14px;margin-top:10px;line-height:1.6}
  .bb-located svg{flex:none;margin-top:2px}
  .bb-spin{width:16px;height:16px;border:2px solid currentColor;border-inline-end-color:transparent;border-radius:50%;animation:bbSpin .7s linear infinite;flex:none}
  @keyframes bbSpin{to{transform:rotate(360deg)}}

  /* chips */
  .bb-chips{display:flex;gap:8px;flex-wrap:wrap}
  .bb-chip{padding:9px 16px;border:1.5px solid var(--line);border-radius:999px;background:#fff;font-weight:700;font-size:.85rem;transition:border-color .2s,background .2s}
  .bb-chip.on{border-color:var(--accent);background:var(--foam);color:var(--accent-deep)}
  .bb-note{display:flex;gap:8px;align-items:flex-start;font-size:.78rem;color:var(--muted);background:var(--wash);border-radius:var(--r-md);padding:10px 13px;margin-top:13px}

  /* OTP */
  /* two classes so it outranks `.bb-input.ltr`'s letter-spacing */
  .bb-input.bb-otp-input{font-size:1.5rem;letter-spacing:12px;font-weight:800;font-variant-numeric:tabular-nums;padding-inline-start:27px}
  .bb-verified{display:flex;align-items:center;gap:9px;background:var(--mint-soft);color:var(--mint);font-weight:800;border-radius:var(--r-md);padding:12px 14px}
  .bb-verified svg{flex:none}
  /* escape hatch: locking the number outright would trap anyone who wants to
     order on a different phone */
  .bb-change-phone{
    margin-inline-start:auto;flex:none;background:none;border:0;padding:4px 2px;
    color:var(--mint);font-weight:700;font-size:.78rem;text-decoration:underline;
    text-underline-offset:3px;cursor:pointer;
  }
  /* a verified number is locked — readonly rather than disabled so it stays
     readable and selectable, and still submits with the form */
  .bb-input[readonly]{background:var(--wash);color:var(--muted);cursor:not-allowed}
  .bb-input[readonly]:focus{border-color:var(--line);box-shadow:none}
  .bb-err{color:var(--danger);font-size:.82rem;font-weight:700;margin-top:7px}
  .bb-shake{animation:bbShake .4s}
  @keyframes bbShake{0%,100%{transform:none}25%{transform:translateX(6px)}50%{transform:translateX(-6px)}75%{transform:translateX(4px)}}

  /* fake SMS toast */
  /* Hidden by translating off-screen, but the shadow is offset 16px DOWN with a
     40px blur — so it still painted a dark band across the top of the viewport
     (centred, 380px wide, matching this box). Opacity kills the shadow too;

  /* review receipt */
  .bb-receipt{border:1.5px dashed var(--line);border-radius:var(--r-md);padding:14px 16px;background:var(--wash)}
  .bb-receipt .bb-row{padding:3px 0}
  .bb-edit{font-size:.72rem;color:var(--accent);font-weight:700;text-decoration:underline;text-underline-offset:3px}
  /* Centred, with a ticket glyph — as a bare underlined line of text pushed to
     one edge it read as fine print and got missed. */
  .bb-coupon-toggle{
    display:flex;align-items:center;justify-content:center;gap:7px;
    width:100%;margin-top:14px;
    font-size:.92rem;font-weight:700;color:var(--accent);
  }
  .bb-coupon-toggle svg{width:18px;height:18px;flex:none}
  .bb-coupon-toggle span{text-decoration:underline;text-underline-offset:3px}
  .bb-coupon-row{display:flex;gap:8px;margin-top:10px}
  .bb-coupon-row .bb-input{flex:1}
  .bb-coupon-row button{
    padding:0 20px;border-radius:var(--r-md);border:1.5px solid var(--ink);
    font-weight:700;background:var(--ink);color:#fff;flex:none;
    transition:opacity .15s;
  }
  .bb-coupon-row button:disabled{opacity:.45;cursor:not-allowed}
  .bb-coupon-msg{font-size:.8rem;font-weight:700;margin-top:6px}
  .bb-cod-line{display:flex;align-items:center;justify-content:center;gap:7px;font-size:.8rem;color:var(--muted);margin-top:10px}

  /* success */
  .bb-success{text-align:center;padding:10px 0 6px;position:relative}
  .bb-check{width:86px;height:86px;margin:0 auto 14px}
  .bb-check circle{stroke:var(--mint);stroke-width:2.5;fill:var(--mint-soft);stroke-dasharray:290;stroke-dashoffset:290;animation:draw .7s ease forwards}
  .bb-check path{stroke:var(--mint);stroke-width:5;fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:60;stroke-dashoffset:60;animation:draw .5s .5s ease forwards}
  @keyframes draw{to{stroke-dashoffset:0}}
  @media (prefers-reduced-motion:reduce){.bb-check circle,.bb-check path{animation:none;stroke-dashoffset:0}}
  .bb-order-no{display:inline-block;font-variant-numeric:tabular-nums;background:var(--wash);border:1px solid var(--line);border-radius:999px;padding:5px 16px;font-weight:800;margin-top:8px;direction:ltr}
  .bb-success h3{font-size:1.35rem;font-weight:800}
  .bb-success p{color:var(--muted);font-size:.9rem;max-width:30ch;margin:8px auto 0}
  .bb-confetti{position:absolute;width:8px;height:14px;border-radius:2px;opacity:0;animation:conf 1.6s ease-out forwards;pointer-events:none}
  @keyframes conf{0%{opacity:1;transform:translateY(0) rotate(0)}100%{opacity:0;transform:translateY(130px) rotate(300deg)}}

  /* ---------- sections ---------- */
  .bb-section{margin-top:56px}
  .bb-h2{font-size:clamp(1.4rem,4vw,1.9rem);font-weight:800;text-wrap:balance;margin-bottom:6px}
  .bb-section-sub{color:var(--muted);font-size:.92rem;margin-bottom:22px}

  /* ---------- تجارب عملائنا : YouTube Shorts (live players) ---------- */
  /* Mobile: horizontal swipe strip — full-width 9:16 tiles stacked would add
     ~600px of scrolling each to a page whose whole point is a short path to
     order. Desktop: plain 3-up grid. */
  .bb-yt-grid{
    display:grid;gap:14px;
    grid-auto-flow:column;
    grid-auto-columns:min(62vw,240px);
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;
    padding-bottom:10px;margin-inline:-18px;padding-inline:18px;
    -webkit-overflow-scrolling:touch;
  }
  .bb-yt-grid::-webkit-scrollbar{height:6px}
  .bb-yt-grid::-webkit-scrollbar-thumb{background:var(--line);border-radius:99px}
  @media(min-width:760px){
    .bb-yt-grid{
      grid-auto-flow:row;grid-template-columns:repeat(3,1fr);
      overflow:visible;margin-inline:0;padding-inline:0;
    }
  }
  .bb-yt{
    position:relative;aspect-ratio:9/16;border-radius:var(--r-lg);overflow:hidden;
    background:#12151c;border:1px solid var(--line);box-shadow:var(--shadow);
    scroll-snap-align:start;
  }
  .bb-yt iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
  /* file:// only — YouTube rejects a null origin (error 153), so the tile links
     out instead of embedding a player that could only render an error. */
  .bb-yt-link{
    position:absolute;inset:0;display:grid;place-items:center;padding:16px;
    color:#fff;font-weight:800;font-size:.9rem;text-align:center;text-decoration:none;
    background:linear-gradient(150deg,#1c2130,#8a2f1c 55%,#fc4631);
  }
  .bb-yt-note{font-size:.78rem;color:var(--muted);margin-top:12px;text-align:center}
  .bb-swipe-hint{color:var(--accent);font-weight:700;white-space:nowrap}
  @media(min-width:760px){ .bb-swipe-hint{display:none} }

  /* ---------- how it works ---------- */
  .bb-how{display:grid;gap:12px}
  @media(min-width:760px){.bb-how{grid-template-columns:repeat(3,1fr)}}
  .bb-how-card{background:var(--card);border:1px solid var(--line);border-radius:var(--r-lg);padding:20px;display:flex;flex-direction:column;gap:9px}
  .bb-how-ico{width:46px;height:46px;border-radius:14px;background:var(--foam);display:grid;place-items:center;color:var(--accent)}
  .bb-how-ico svg{width:24px;height:24px}
  .bb-how-card b{font-size:1rem}
  .bb-how-card p{font-size:.94rem;color:var(--muted)}

  /* ---------- FAQ ---------- */
  .bb-faq details{background:var(--card);border:1px solid var(--line);border-radius:var(--r-md);padding:0 18px;margin-bottom:9px}
  .bb-faq summary{list-style:none;cursor:pointer;font-weight:800;font-size:1rem;padding:14px 0;display:flex;justify-content:space-between;align-items:center;gap:10px}
  .bb-faq summary::-webkit-details-marker{display:none}
  .bb-faq summary::after{content:"+";font-size:1.5rem;color:var(--accent);font-weight:400;transition:transform .2s}
  .bb-faq details[open] summary::after{transform:rotate(45deg)}
  .bb-faq details p{padding:0 0 15px;font-size:.86rem;color:var(--muted)}

  /* ---------- footer ---------- */
  .bb-footer{margin-top:60px;border-top:1px solid var(--line);padding:26px 2px 10px;display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;font-size:.9rem;color:var(--muted)}
  /* flex-basis:100% keeps the links on their own row above the copyright and
     socials, so the existing two-item space-between layout is untouched. */
  .bb-footer-nav{flex:0 0 100%;display:flex;flex-wrap:wrap;gap:8px 20px;margin-bottom:2px}
  .bb-footer-nav a{color:var(--muted);text-decoration:none;transition:color .18s}
  .bb-footer-nav a:hover{color:var(--accent)}

  .bb-socials{display:flex;gap:10px;align-items:center}
  .bb-socials a{
    width:38px;height:38px;border-radius:50%;display:grid;place-items:center;
    background:var(--card);border:1px solid var(--line);color:var(--brand-navy);
    text-decoration:none;transition:color .18s,border-color .18s,transform .15s;
  }
  .bb-socials a:hover{color:var(--accent);border-color:var(--accent);transform:translateY(-2px)}
  .bb-socials svg{width:18px;height:18px;display:block}

  /* WhatsApp FAB */
  .bb-wa{position:fixed;bottom:18px;inset-inline-end:16px;z-index:50;width:54px;height:54px;border-radius:50%;background:#25D366;display:grid;place-items:center;box-shadow:0 10px 26px rgba(0,0,0,.22);transition:transform .15s}
  .bb-wa:hover{transform:translateY(-2px)}
  .bb-wa svg{width:28px;height:28px;fill:#fff}
