* { box-sizing: border-box; margin: 0; -webkit-tap-highlight-color: transparent; }
:root {
  /* brand */
  /* Back to blue at his call, one step deeper than the original #1565d8. A royal blue holds
     its own against a photo without going black on it, and at 7:1 on white a price stays
     legible in daylight on a phone — the old bright blue sat at 4.6:1 and greyed out in sun.
     The dark step is for pressed states, the light step for tints. Token names stay --blue*:
     150-odd rules reference them. */
  --blue: #1B4FA8; --blue-d: #123A80; --blue-l: #3B72D9; --blue-soft: #E7EEFB; --accent: #3B72D9;
  /* surfaces — a faintly cool paper now that the ink is blue again; pure grey next to blue
     reads dirty */
  --bg: #F4F6FA; --card: #ffffff;
  --glass: rgba(255,255,255,.78); --glass-brd: rgba(27,79,168,.12);
  /* text */
  --text: #101B2B; --muted: #5A6B84; --line: #DDE3EC;
  /* Gold is مريم's and only hers: it marks what she points at or says. Spent on an ordinary
     button it stops meaning anything. The cart bar was already reaching for var(--gold) with a
     hard-coded fallback — declared here so there is one gold instead of two that drift apart. */
  --gold: #C9A24A; --gold-soft: #E7CE8E;
  /* #C9A24A on white is 2.40:1 — under AA on any text, and under 3:1 even as an icon. Gold is
     مريم's and stays hers, so the SIGNAL is unchanged: the ring, the fill and the glow are still
     --gold. Only glyphs sitting on white move to this darker step of the same hue (4.76:1), so
     her tab and her drawer row can actually be read. Two tokens, one colour. */
  --gold-text: #8F6E1C;
  /* مريم's ONE look. The pointing ring, the spotlight ring and the orb's collar were each
     styled on a different day — 16px vs 14px radius, an outline vs a border, three unrelated
     glows — so she read as three plugins instead of one character. Every surface that is her
     reads from these four, and her surface on a dark scrim is --gold-soft: same hue, the tint
     that still clears contrast on navy where #C9A24A does not. */
  --gold-ring: 2px; --gold-r: 16px;
  --gold-glow: 0 0 0 4px rgba(201,162,74,.28), 0 10px 28px -10px rgba(201,162,74,.5);
  --gold-ink: #08192C;   /* the navy she speaks on — float scrim, spotlight tip, her doors */
  /* Her LIGHT surfaces (2026-08-25, his call: «الوان تشبه ستايل المتجر … افتح»). The navy
     blocks read as a different app dropped inside a bright shop. Same gold, spent as a tint
     and an edge instead of a fill, so she is still unmistakably hers on a white page. */
  --her-surface: #FDF6E6;  /* gold at ~8% over paper */
  --her-edge: rgba(201,162,74,.42);
  /* ONE motion vocabulary: slide for a screen, pulse for a point, dim for cinema. Anything of
     hers that moves is one of the three, at these durations and this easing. */
  --ease: cubic-bezier(.4,0,.2,1); --t-slide: .28s; --t-dim: .28s; --t-pulse: 1.3s;
  /* shape + depth (soft, light from top-left) */
  --radius: 22px; --radius-sm: 14px;
  --shadow: 0 12px 30px rgba(27,79,168,.10), 0 3px 10px rgba(27,79,168,.06);
  --shadow-sm: 0 4px 14px rgba(27,79,168,.08);
  --glow: 0 0 22px rgba(27,79,168,.22);
  /* The bottom belongs to مريم now: the tab bar was removed and its four destinations moved
     into the drawer, so every calculation that used to clear it clears nothing. Kept as a
     token rather than deleted from ~30 rules — restoring the bar is one number. */
  --tab-h: 82px;   /* floating bar 62 + 10 gap + 10 breathing */
}
html { overflow-x: hidden; }
body { font-family: 'Tajawal', 'Cairo', system-ui, -apple-system, sans-serif; color: var(--text);
  background: linear-gradient(160deg, #FAF8F4 0%, #EDEAE3 100%); background-attachment: fixed;
  min-height: 100vh; overflow-x: hidden; max-width: 100%; padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom)); }
#view, .nav-wrap { max-width: 100%; }

/* ---- top bar + chips ---- */
.topbar { position: sticky; top: 0; z-index: 10; display: flex; flex-direction: column; gap: 10px;
  background: var(--card); padding: 10px 14px; }
.brand { height: 40px; width: auto; display: block; }
.p-rate { display: flex; align-items: center; gap: 7px; margin: 4px 0 2px; }
.p-rate .stars { display: inline-flex; gap: 1px; }
.p-rate .star svg { width: 17px; height: 17px; fill: #d7dbe2; display: block; }
.p-rate .star.on svg { fill: #f7b500; }
.p-rate .rate-num { font-weight: 700; font-size: .9rem; }
.p-rate .rate-count { color: var(--muted); font-size: .82rem; }

/* interactive "your rating" widget */
.my-rate { display: flex; align-items: center; gap: 9px; margin: 6px 0 2px; }
.my-rate.muted, .my-rate-label { color: var(--muted); font-size: .85rem; }
.my-rate .stars { display: inline-flex; gap: 2px; }
.my-rate .rate-input .star { cursor: pointer; padding: 2px; }
.my-rate .rate-input .star svg { width: 26px; height: 26px; fill: #d7dbe2; display: block; transition: fill .12s, transform .12s; }
.my-rate .rate-input .star.on svg { fill: #f7b500; }
.my-rate .rate-input:hover .star svg { fill: #f7b500; }
.my-rate .rate-input .star:hover ~ .star svg { fill: #d7dbe2; }
.my-rate .rate-input .star:active svg { transform: scale(1.25); }

/* compact rating on product cards */
.card-rate { display: flex; align-items: center; gap: 4px; margin: 2px 0; font-size: .78rem; }
.card-rate .stars { display: inline-flex; gap: 1px; }
.card-rate .star svg { width: 13px; height: 13px; fill: #d7dbe2; display: block; }
.card-rate .star.on svg { fill: #f7b500; }
.card-rate .cr-a { font-weight: 700; }
.card-rate .cr-n { color: var(--muted); }
.card-rate .cr-like { display: inline-flex; align-items: center; gap: 3px; color: var(--muted); }
.card-rate .cr-like svg { width: 13px; height: 13px; stroke: var(--blue); fill: none; }

/* prominent like count on the product page */
.like-count { display: flex; align-items: center; gap: 5px; color: var(--muted); font-size: .9rem; margin: 4px 0 2px; }
.like-count b { color: var(--ink, #222); }
.like-count .lc-thumb svg { width: 16px; height: 16px; stroke: var(--blue); fill: none; display: block; }

/* transient toast */
.toast { position: fixed; left: 50%; bottom: 84px; transform: translateX(-50%);
  background: #222; color: #fff; padding: 10px 18px; border-radius: 22px; font-size: .9rem;
  z-index: 999; box-shadow: 0 4px 16px rgba(0,0,0,.25); animation: toastIn .2s ease; }
@keyframes toastIn { from { opacity: 0; transform: translate(-50%, 8px); } }
.ai-fab .ai-spark { transform-origin: 12px 11.4px; animation: aiTwinkle 3.2s ease-in-out infinite; }
@keyframes aiFloat { 50% { transform: translateY(-4px); } }
@keyframes aiHalo { 0% { transform: scale(1); opacity: .5; } 70%, 100% { transform: scale(1.35); opacity: 0; } }
@keyframes aiTwinkle {
  0%, 60%, 100% { transform: scale(1) rotate(0deg); opacity: 1; }
  30% { transform: scale(1.35) rotate(90deg); opacity: .75; }
}
/* a floating, pulsing button is exactly what vestibular-sensitive users ask to stop */
@media (prefers-reduced-motion: reduce) {
  .ai-fab, .ai-fab::before, .ai-fab .ai-spark { animation: none; }
  .ai-fab::before { opacity: 0; }
}
.ai-back { position: fixed; inset: 0; background: rgba(10,15,25,.5); z-index: 1000; display: flex; align-items: flex-end; }
/* On Android the keyboard shrinks only the VISUAL viewport, so a sheet sized in vh kept
   its full height and pushed its own header — the call button included — above the top
   of what the customer could see. dvh tracks the keyboard; the vh line is the fallback. */
.ai-back { height: 100vh; height: 100dvh; }
.ai-sheet { --ai-accent: var(--blue); width: 100%; height: 82vh; height: 82dvh; max-height: 100%; background: var(--bg); border-radius: 22px 22px 0 0; display: flex; flex-direction: column;
  overflow: hidden; animation: dpUp .28s ease; }
/* The half-height «mini» sheet that used to live here is gone: while مريم drives the screen the
   conversation collapses all the way to the floating text (.ai-float, bottom of this file)
   instead of a bar with hard edges parked over the third of the screen she is pointing at. */
.ai-head { display: flex; justify-content: space-between; align-items: center; padding: 14px 16px; background: var(--card); border-bottom: 1px solid var(--line); }
.ai-title { display: flex; align-items: center; gap: 8px; font-weight: 800; font-size: 1.05rem; }
.ai-title svg { width: 22px; height: 22px; stroke: var(--gold); }
.ai-close { background: var(--bg); border: none; width: 34px; height: 34px; border-radius: 50%; font-size: 1rem; cursor: pointer; color: var(--text); }
.ai-msgs { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 10px; scroll-behavior: smooth; }
/* flex children shrink by default — without this the bubbles and cards squash to
   fit instead of overflowing, so the box never scrolls to a new message */
.ai-msgs > * { flex: none; }
.ai-msg { max-width: 84%; padding: 11px 14px; border-radius: 16px; font-size: .95rem; line-height: 1.6; white-space: normal; }
/* her bubbles carry her gold edge — inside her own sheet she was the only surface in the store
   with no mark on her at all, an anonymous grey card answering in her name */
.ai-msg.bot { align-self: flex-start; background: var(--card); border: 1px solid var(--line);
  border-inline-start: var(--gold-ring) solid var(--gold); border-start-start-radius: 4px; }
.ai-msg.me { align-self: flex-end; background: var(--ai-accent, var(--blue)); color: #fff; border-end-end-radius: 4px; }
.ai-msg.typing { display: flex; gap: 4px; align-items: center; }
.ai-msg.typing span { width: 7px; height: 7px; border-radius: 50%; background: var(--muted); animation: aiBlink 1s infinite; }
.ai-msg.typing span:nth-child(2) { animation-delay: .2s; }
.ai-msg.typing span:nth-child(3) { animation-delay: .4s; }
@keyframes aiBlink { 0%,60%,100% { opacity: .3; } 30% { opacity: 1; } }
.ai-inp { position: relative; display: flex; gap: 8px; padding: 12px 14px calc(12px + env(safe-area-inset-bottom)); background: var(--card); border-top: 1px solid var(--line); }
.ai-inp input { flex: 1; padding: 12px 14px; border: 1.5px solid var(--line); border-radius: 999px; font-family: inherit; font-size: 1rem; background: var(--bg); }
.ai-inp input:focus { outline: none; border-color: var(--ai-accent, var(--blue)); background: #fff; }
.ai-send { flex: none; width: 46px; height: 46px; border: none; border-radius: 50%; background: var(--ai-accent, var(--blue)); color: #fff; cursor: pointer; display: grid; place-items: center; }
.ai-send svg { width: 20px; height: 20px; transform: scaleX(-1); }

/* ---- assistant header actions + role picker + mic ---- */
.ai-head-act { display: flex; align-items: center; gap: 8px; }
.ai-call-btn { display: inline-flex; align-items: center; gap: 6px; border: none; cursor: pointer; font-family: inherit;
  font-weight: 800; font-size: .85rem; padding: 7px 13px; border-radius: 999px; color: #fff;
  background: linear-gradient(135deg, var(--ai-accent, var(--blue)), var(--blue-l)); box-shadow: 0 3px 10px rgba(16,48,78,.35); }
.ai-call-btn svg { width: 16px; height: 16px; }
.ai-tabs { display: flex; gap: 6px; padding: 10px 12px; background: var(--card); border-bottom: 1px solid var(--line); }
.ai-tab { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; border: 1.5px solid var(--line);
  background: var(--bg); color: var(--muted); font-family: inherit; font-weight: 700; font-size: .82rem; padding: 9px 6px;
  border-radius: 12px; cursor: pointer; transition: all .18s; }
.ai-tab svg { width: 17px; height: 17px; }
.ai-tab > * { pointer-events: none; }  /* taps always land on the button, not its icon/label */
.ai-tab.on { color: #fff; background: var(--tab); border-color: var(--tab); box-shadow: 0 4px 12px color-mix(in srgb, var(--tab) 40%, transparent); }
.ai-mic { position: relative; z-index: 3; flex: none; width: 46px; height: 46px; border: 1.5px solid var(--line); border-radius: 50%; background: var(--bg);
  color: var(--ai-accent, var(--blue)); cursor: pointer; display: grid; place-items: center; touch-action: none; }
.ai-mic svg { width: 20px; height: 20px; }
/* attach/snap a photo for the assistant */
.ai-imgprev { padding: 8px 12px 0; }
.ai-imgprev[hidden] { display: none; }
.ai-imgprev { position: relative; display: inline-flex; }
.ai-imgprev img { width: 62px; height: 62px; object-fit: cover; border-radius: 12px; border: 1.5px solid var(--line); }
.ai-img-x { position: absolute; top: 2px; inset-inline-end: 6px; width: 22px; height: 22px; border: none; border-radius: 50%;
  background: rgba(0,0,0,.6); color: #fff; font-size: .8rem; cursor: pointer; display: grid; place-items: center; }
.ai-msg-img { display: block; max-width: 190px; width: 100%; border-radius: 12px; margin-bottom: 6px; }
.ai-file-chip { display: inline-flex; align-items: center; max-width: 240px; padding: 7px 12px; border-radius: 12px;
  background: var(--card, #f2f4f7); border: 1.5px solid var(--line); font-size: .82rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.ai-msg-file { display: inline-block; margin-bottom: 6px; padding: 5px 9px; border-radius: 9px;
  background: rgba(0,0,0,.06); font-size: .78rem; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ai-mic.listening { background: var(--ai-accent, var(--blue)); color: #fff; border-color: transparent; animation: micPulse 1.1s infinite; }
@keyframes micPulse { 0%,100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--ai-accent, #10304E) 55%, transparent); } 50% { box-shadow: 0 0 0 9px transparent; } }

/* ---- push-to-talk voice message (WhatsApp-style) ---- */
.ai-mic.recording { background: #e5484d; color: #fff; border-color: transparent; transform-origin: center;
  box-shadow: 0 0 0 0 rgba(229,72,77,.5); animation: pttPulse 1.2s infinite; }
.ai-mic.recording.dragging { animation: none; transition: transform .04s linear; }
@keyframes pttPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(229,72,77,.5); } 50% { box-shadow: 0 0 0 12px rgba(229,72,77,0); } }
.ai-inp.ptt-on input, .ai-inp.ptt-on .ai-send { visibility: hidden; }
.ptt-bar { position: absolute; inset: 8px 8px calc(8px + env(safe-area-inset-bottom)); z-index: 2; pointer-events: none;
  display: flex; align-items: center; gap: 8px; padding: 0 14px; border-radius: 999px; background: var(--card);
  color: var(--text); font-size: .9rem; }
.ptt-bar.locked { pointer-events: auto; }
.ptt-dot { flex: none; width: 11px; height: 11px; border-radius: 50%; background: #e5484d; animation: pttBlink 1s infinite; }
@keyframes pttBlink { 0%,100% { opacity: 1; } 50% { opacity: .25; } }
.ptt-time { font-variant-numeric: tabular-nums; font-weight: 700; color: var(--muted); min-width: 38px; }
.ptt-hint { margin-inline-start: auto; color: var(--muted); font-size: .85rem; white-space: nowrap; opacity: .9;
  animation: pttSlide 1.6s ease-in-out infinite; }
@keyframes pttSlide { 0%,100% { transform: translateX(0); opacity: .5; } 50% { transform: translateX(-6px); opacity: 1; } }
.ptt-trash { flex: none; margin-inline-start: 12px; width: 38px; height: 38px; border: none; border-radius: 50%;
  background: transparent; color: var(--muted); display: grid; place-items: center; cursor: pointer; transition: all .12s; }
.ptt-trash svg { width: 19px; height: 19px; }
.ptt-bar.near-cancel .ptt-trash { background: #e5484d; color: #fff; transform: scale(1.15); }
.ptt-bar.near-cancel .ptt-hint { color: #e5484d; }
.ptt-send { display: none; flex: none; margin-inline-start: 8px; width: 42px; height: 42px; border: none; border-radius: 50%;
  background: var(--ai-accent, var(--blue)); color: #fff; place-items: center; cursor: pointer; }
.ptt-send svg { width: 19px; height: 19px; transform: scaleX(-1); }
.ptt-bar.locked .ptt-hint { display: none; }
.ptt-bar.locked .ptt-send { display: grid; }
.ptt-bar.locked .ptt-trash { margin-inline-start: auto; }
/* lock chevron floating above the mic */
.ptt-lock { position: absolute; z-index: 4; inset-inline-start: 20px; bottom: calc(100% - 4px); pointer-events: none;
  width: 30px; height: 44px; border-radius: 16px; background: var(--card); border: 1px solid var(--line);
  color: var(--muted); display: grid; place-items: center; box-shadow: 0 2px 8px rgba(0,0,0,.12);
  animation: pttLockBob 1.4s ease-in-out infinite; }
.ptt-lock svg { width: 16px; height: 16px; }
.ptt-lock.near { background: var(--ai-accent, var(--blue)); border-color: transparent; color: #fff; animation: none; }
@keyframes pttLockBob { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }

/* listening — soft breathing rings */

@keyframes orbRing { 0% { transform: scale(1); opacity: .7; } 100% { transform: scale(1.5); opacity: 0; } }
/* thinking — slow spin */

@keyframes orbSpin { to { transform: rotate(360deg); } }
/* speaking — pulsing waveform */

@keyframes orbBeat { 0%,100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@keyframes waveBeat { 0%,100% { opacity: .7; transform: scaleY(.8); } 50% { opacity: 1; transform: scaleY(1.15); } }
.call-ctrl.on > svg, .call-ctrl.off > svg { background: #fff; color: #1e293b; }  /* active mute/speaker-off state */
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes ccRing { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tab) 55%, transparent); } 100% { box-shadow: 0 0 0 26px transparent; } }
@keyframes ccShake { 0%,100% { transform: rotate(-9deg); } 50% { transform: rotate(9deg); } }
.cc-depts { width: 100%; max-width: 440px; display: flex; flex-direction: column; gap: 12px; margin-top: 22px; }
.cc-depts.picked { opacity: .5; pointer-events: none; }
.cc-dept { display: flex; align-items: center; gap: 14px; width: 100%; padding: 14px 16px; border: none; border-radius: 18px;
  background: rgba(255,255,255,.1); backdrop-filter: blur(6px); color: #fff; font-family: inherit; cursor: pointer;
  border-inline-start: 4px solid var(--tab); transition: transform .12s, background .12s; }
.cc-dept:active { transform: scale(.98); background: rgba(255,255,255,.18); }

/* offers — merchant-ticked in Odoo */
.promo-badge { position: absolute; inset-inline-start: 8px; top: 8px; z-index: 2; background: #e0245e; color: #fff;
  font-size: .68rem; font-weight: 800; padding: 3px 8px; border-radius: 999px; box-shadow: 0 2px 8px rgba(224,36,94,.4); }
.promo-badge.sm { position: static; display: inline-block; margin-inline-start: 5px; padding: 1px 6px; font-size: .62rem; box-shadow: none; }
.old-price { color: var(--muted); font-weight: 600; font-size: .8em; margin-inline-start: 6px; text-decoration: line-through; }
.save-tag { display: inline-block; margin-inline-start: 8px; background: #fdeaf0; color: #e0245e; font-size: .72rem;
  font-weight: 800; padding: 3px 9px; border-radius: 999px; vertical-align: middle; }
.promo-line { display: flex; align-items: center; gap: 6px; margin-top: 8px; color: #e0245e; font-weight: 700; font-size: .85rem; }
.promo-line svg { width: 15px; height: 15px; }

/* product card the AI attaches to its reply */
.ai-card { align-self: flex-start; max-width: 84%; width: 260px; background: var(--card); border: 1px solid var(--line);
  border-radius: 16px; overflow: hidden; }
.ai-c-top { display: flex; gap: 10px; padding: 10px; cursor: pointer; }
.ai-c-img, .ai-c-top .noimg { flex: none; width: 64px; height: 64px; border-radius: 10px; object-fit: contain; background: var(--bg); }
.ai-c-top .noimg { display: grid; place-items: center; }
.ai-c-top .noimg svg { width: 24px; height: 24px; color: var(--muted); }
.ai-c-info { min-width: 0; }
.ai-c-name { font-weight: 700; font-size: .9rem; line-height: 1.35; }
.ai-c-det { color: var(--muted); font-size: .76rem; line-height: 1.4; margin-top: 2px; }
.ai-c-price { color: var(--blue); font-weight: 800; font-size: .9rem; margin-top: 4px; }
.ai-c-act { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border-top: 1px solid var(--line); }
.ai-c-qty { display: flex; align-items: center; gap: 2px; border: 1.5px solid var(--line); border-radius: 999px; }
.ai-c-qty button { width: 26px; height: 26px; border: none; background: none; font-size: 1rem; color: var(--text); cursor: pointer; }
.ai-c-qty b { min-width: 18px; text-align: center; font-size: .85rem; }
.ai-c-add { flex: 1; display: flex; align-items: center; justify-content: center; gap: 5px; border: none; border-radius: 999px;
  background: var(--blue); color: #fff; font-family: inherit; font-weight: 700; font-size: .8rem; padding: 8px; cursor: pointer; }
.ai-c-add svg { width: 15px; height: 15px; }
.ai-cart-link { align-self: flex-start; background: var(--blue-soft); color: var(--blue); border: none; border-radius: 12px;
  padding: 10px 14px; font-family: inherit; font-weight: 800; font-size: .9rem; cursor: pointer; }

/* ================= ACCOUNT PAGE ================= */
.acc-page { display: flex; flex-direction: column; gap: 18px; padding-bottom: 8px; }
.acc-hero { text-align: center; padding: 6px 0 2px; }
.acc-avatar { width: 88px; height: 88px; margin: 0 auto 10px; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--blue), var(--blue-l)); color: #fff; font-size: 2.1rem; font-weight: 800;
  box-shadow: 0 10px 26px rgba(16,48,78,.34); }
.acc-hero .acc-name { font-size: 1.3rem; font-weight: 800; }
.info-card, .addr-card, .pay-card, .settings { background: var(--card); border: 1px solid var(--line); border-radius: 16px; }

.settings { padding: 2px 14px; }
.set-row { display: flex; justify-content: space-between; align-items: center; gap: 12px; padding: 13px 0;
  border: none; border-bottom: 1px solid var(--line); width: 100%; background: none;
  font-family: inherit; font-size: .92rem; font-weight: 600; color: var(--text); text-align: right; }
.set-row:last-child { border-bottom: none; }
.set-row.link { cursor: pointer; }
.set-row > span:first-child { display: inline-flex; align-items: center; gap: 9px; }
.set-row span svg { width: 18px; height: 18px; stroke: var(--muted); fill: none; }
.set-row .chev { color: var(--muted); font-size: 1.3rem; line-height: 1; }

.toggle { width: 46px; height: 27px; border-radius: 999px; background: var(--line); border: none; position: relative;
  cursor: pointer; transition: background .2s; flex: none; }
.toggle i { position: absolute; top: 3px; right: 3px; width: 21px; height: 21px; border-radius: 50%; background: #fff;
  transition: transform .2s; box-shadow: 0 1px 3px rgba(0,0,0,.2); }
.toggle.on { background: var(--blue); }
.toggle.on i { transform: translateX(-19px); }

.acc-sec .logout { color: #e0245e; margin-top: 8px; }
.acc-sec .logout svg { stroke: #e0245e; }
.top-actions { display: flex; align-items: center; gap: 4px; }
.icon-btn { position: relative; background: none; border: none; color: var(--text); cursor: pointer;
  width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; }
.icon-btn:hover { background: var(--bg); }
.icon-btn svg { width: 23px; height: 23px; }
.cart-chip { background: var(--blue-soft); color: var(--blue); }
.count { position: absolute; top: 0; inset-inline-start: 0; min-width: 17px; height: 17px; padding: 0 4px;
  background: var(--blue); color: #fff; font-size: .68rem; font-weight: 700; border-radius: 9px;
  display: grid; place-items: center; opacity: 0; transform: scale(.4); transition: .18s; }
.count.has { opacity: 1; transform: scale(1); }
.chips { position: sticky; top: 62px; z-index: 9; display: none;
  background: var(--card); padding: 4px 14px 8px; border-bottom: 1px solid var(--line); }
.chips-row, .chips-sub { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.chips-row::-webkit-scrollbar, .chips-sub::-webkit-scrollbar { display: none; }
.chip { flex: 0 0 auto; background: none; border: none; font: inherit; font-weight: 700; color: var(--muted);
  padding: 7px 12px; border-radius: 12px; cursor: pointer; border-bottom: 2.5px solid transparent; }
/* top-level chips carry the whole catalogue — they're the main thing to hit on this
   screen, so they get the size. 44px tall clears the minimum touch target too. */
.chip.has-ic { font-size: 1.02rem; padding: 8px 14px; }
.chip.on { color: var(--text); border-bottom-color: var(--blue); }
/* icon rides beside the name: the mark for the glance, the word so «NVR» and «كامرة كت»
   can't be confused for each other */
.chip.has-ic { display: inline-flex; align-items: center; gap: 6px; }
.chip-ic { display: inline-grid; place-items: center; width: 34px; height: 34px; border-radius: 10px;
  background: var(--bg); color: var(--muted); transition: background .15s, color .15s; }
.chip-ic svg { width: 21px; height: 21px; }
.chip.on .chip-ic { background: var(--blue-soft); color: var(--blue); }
/* sub-categories: pills, so a drill-down level never reads as another top-level tab */
.chips-sub { padding-top: 6px; }
.chips-sub .chip { padding: 5px 11px; font-size: 13px; border-bottom: none;
  background: var(--bg); border-radius: 999px; }
.chips-sub .chip.on { background: var(--blue); color: #fff; }

main { max-width: 720px; margin: 0 auto; padding: 8px 16px 24px; }
.page-title { font-size: 1.5rem; font-weight: 800; margin: 14px 4px 16px; }
/* Section headings carry a brand accent bar instead of an emoji — emoji render differently
   on every platform and read as clip-art next to real product photography. */
.sec-title { font-size: 1.15rem; font-weight: 800; margin: 22px 4px 12px;
  display: flex; align-items: center; gap: 9px; }
.sec-title::before { content: ''; flex: none; width: 4px; height: 1.05em; border-radius: 2px;
  background: linear-gradient(180deg, var(--blue), var(--accent)); }
.offers-banner { display: flex; align-items: center; gap: 8px; margin: 14px 2px 4px; padding: 14px 16px;
  border-radius: 16px; background: linear-gradient(100deg, #ff5a5f, #ff8a3d); color: #fff; font-size: 1.05rem;
  font-weight: 700; text-decoration: none; box-shadow: 0 6px 18px rgba(255,90,95,.28); }
.offers-banner b { font-weight: 900; }
.offers-banner .ob-go { margin-inline-start: auto; font-size: .9rem; font-weight: 800; white-space: nowrap; }

/* ---- welcome ---- */
.welcome { text-align: center; padding-top: 10px; }
.w-head { font-size: 1.45rem; font-weight: 800; line-height: 1.6; margin: 14px 8px 6px; }
.w-sub { color: var(--muted); line-height: 1.7; margin: 8px 12px 16px; }
.w-btn { width: 100%; }
.w-brand { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 6px; }
.w-featured { text-align: right; margin-top: 22px; }
/* .welcome centres the hero; the rails under it are normal RTL content, not centred copy */
.w-rails { text-align: right; margin-top: 26px; }

/* ---- recent searches: a dropdown under the field, like Google/YouTube ---- */
.search-wrap { position: relative; }        /* anchor for .sug */
.sug { position: absolute; z-index: 40; inset-inline: -1.5px; top: calc(100% + 6px);
  background: var(--card); border: 1.5px solid var(--line); border-radius: 14px;
  box-shadow: 0 14px 38px rgba(20,40,80,.16); overflow: hidden; max-height: 46vh;
  overflow-y: auto; overscroll-behavior: contain; }
.sug-row { display: flex; align-items: center; gap: 10px; padding: 12px 14px; cursor: pointer; }
.sug-row + .sug-row { border-top: 1px solid var(--line); }
.sug-row:active { background: var(--blue-soft); }
.sug-row svg { width: 17px; height: 17px; color: var(--muted); flex: 0 0 auto; }
.sug-q { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .93rem; color: var(--text); }
.sug-x { background: none; border: 0; color: var(--muted); font-size: 1rem; line-height: 1;
  padding: 4px 6px; cursor: pointer; flex: 0 0 auto; }
.sug-clear { display: block; width: 100%; background: none; border: 0;
  border-top: 1px solid var(--line); color: var(--blue); font: inherit; font-size: .86rem;
  font-weight: 700; padding: 11px; cursor: pointer; }

/* ---- server-rendered fallback (crawlers + the seconds before app.js has the catalog).
   app.js assigns #view.innerHTML on boot, so this is replaced, never merged. ---- */
.ssr { padding: 16px 4px; line-height: 1.8; }
.ssr-h1 { font-size: 1.3rem; font-weight: 800; margin: 6px 0 10px; }
.ssr-h2 { font-size: 1.05rem; font-weight: 800; margin: 22px 0 8px; }
.ssr-crumbs { color: var(--muted); font-size: .85rem; margin: 0 0 6px; }
.ssr-brand { color: var(--blue); font-weight: 700; margin: 0 0 6px; }
.ssr-price { font-size: 1.25rem; font-weight: 800; margin: 6px 0 12px; }
.ssr-desc { color: var(--muted); margin: 0 0 12px; }
.ssr-trust { color: var(--muted); font-size: .88rem; }
.ssr-list { margin: 0; padding-inline-start: 18px; }
.ssr-list li { margin-bottom: 6px; }
.ssr-list a { color: var(--blue); text-decoration: none; font-weight: 600; }
.slide { flex: 0 0 100%; scroll-snap-align: center; padding: 2px; }
.hero-card { position: relative; background: var(--card); border-radius: 26px; padding: 10px;
  box-shadow: 0 10px 34px rgba(20,40,80,.10); overflow: hidden; }
.hero-card .stage { position: relative; width: 100%; }
.hero-card model-viewer { width: 100%; height: clamp(280px, 42vh, 400px); background: transparent; }
.hero-card .parts-grid model-viewer { height: clamp(140px, 22vh, 195px); }
.badge3d { position: absolute; top: 16px; inset-inline-start: 16px; z-index: 3; background: var(--blue); color: #fff;
  font-size: .72rem; font-weight: 800; padding: 5px 12px; border-radius: 12px; box-shadow: 0 3px 10px rgba(16,48,78,.4); }
.badge3d.sm { top: 8px; inset-inline-start: 8px; font-size: .62rem; padding: 3px 8px; border-radius: 9px; }
.hint { position: absolute; bottom: 10px; inset-inline-start: 50%; transform: translateX(50%); z-index: 3;
  background: rgba(16,21,31,.72); color: #fff; font-size: .74rem; padding: 5px 12px; border-radius: 14px;
  pointer-events: none; white-space: nowrap; }
.part .pname { text-align: center; font-size: .82rem; font-weight: 600; padding: 4px 0; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: #cfd6e0; transition: .2s; }
.dot.on { width: 22px; border-radius: 4px; background: var(--blue); }
.p-name { font-size: 1.2rem; font-weight: 800; line-height: 1.5; }
.p-price { font-size: 1.35rem; font-weight: 800; color: var(--blue); margin: 8px 0 6px; }
.p-price .cur { font-size: .95rem; font-weight: 700; }
.p-trust { color: var(--muted); font-size: .85rem; margin-bottom: 16px; }
/* external "buy the hardware at the vendor" link — deliberately NOT styled like the
   primary add-to-cart, so it reads as leaving the store, not as our checkout */
.buy-ext { display: flex; flex-direction: column; gap: 3px; text-align: center;
  padding: 12px 14px; margin: 0 0 12px; border: 1.5px solid var(--blue);
  border-radius: 12px; color: var(--blue); font-weight: 800; text-decoration: none; }
.buy-ext .buy-ext-note { font-size: .76rem; font-weight: 600; color: var(--muted); line-height: 1.5; }

/* option picker (variants: plan, size…) — one chip per choice, price under the label */
.var-row { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.var-chip { display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  padding: 9px 13px; border: 1.5px solid var(--line); border-radius: 12px;
  background: var(--card); cursor: pointer; font: inherit; color: inherit;
  text-align: start; transition: border-color .15s, background .15s; }
.var-chip .var-l { font-weight: 700; font-size: .92rem; }
.var-chip .var-p { font-size: .82rem; color: var(--muted); }
.var-chip.on { border-color: var(--blue); background: rgba(16,48,78,.07); }
.var-chip.on .var-p { color: var(--blue); font-weight: 700; }

/* everything in one line: quantity + add-to-cart + like + favorite + share */
.buy-row { display: flex; align-items: stretch; gap: 7px; margin: 12px 0; }
.buy-row .qty-step { flex: none; height: 50px; }
.buy-row .add-cart { flex: 1; min-width: 0; height: 50px; margin: 0; display: flex; align-items: center;
  justify-content: center; gap: 6px; box-shadow: 0 6px 18px rgba(16,48,78,.28); }
.buy-row .add-cart { position: relative; }
.buy-row .add-cart svg { width: 24px; height: 24px; }
.buy-row .round-btn { width: 48px; height: 50px; flex: none; }
.buy-row .qbtn { height: 100%; width: 38px; font-size: 1.3rem; }
.buy-row .qval { min-width: 32px; }
.qty-step { display: flex; align-items: center; border: 1.5px solid var(--line); border-radius: 12px; overflow: hidden; }
.qbtn { width: 44px; height: 44px; border: none; background: var(--bg); font-size: 1.4rem; font-weight: 700; color: var(--blue); cursor: pointer; }
.qbtn:active { background: var(--blue-soft); }
.qval { min-width: 44px; text-align: center; font-weight: 800; font-size: 1.05rem; }
.wish-btn { width: 100%; margin-top: 10px; display: flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--blue-soft); color: var(--blue); border: 1.5px solid transparent; border-radius: 14px; padding: 13px;
  font-family: inherit; font-weight: 800; font-size: .95rem; cursor: pointer; }
.wish-btn svg { width: 20px; height: 20px; }
.wish-btn.on { background: #fff2f6; border-color: #f6c9d6; color: #e0245e; }
.wish-btn.on svg { fill: #e0245e; stroke: #e0245e; }
.round-btn { width: 52px; height: 52px; flex: 0 0 auto; border: 1.5px solid var(--line); background: var(--card);
  border-radius: 16px; display: grid; place-items: center; cursor: pointer; color: var(--text); }
.round-btn svg { width: 22px; height: 22px; }
.round-btn.fav.on { color: #e0245e; border-color: #f6c9d6; background: #fff2f6; }
.round-btn.like.on { color: var(--blue); border-color: #bcd3f5; background: var(--blue-soft); }
.round-btn.copied { color: var(--blue); border-color: var(--blue); }
.btn-primary { flex: 1; background: var(--blue); color: #fff; border: none; padding: 15px; border-radius: 16px;
  font-size: 1.02rem; font-weight: 800; cursor: pointer; font-family: inherit; box-shadow: 0 6px 18px rgba(16,48,78,.28); }
.btn-primary:hover { background: var(--blue-d); }
.btn-primary:disabled { opacity: .5; }
.btn-primary.added, .grid-add.added { background: #1e9e4a; box-shadow: none; }
.btn-link { background: none; border: none; color: var(--blue); cursor: pointer; font-family: inherit;
  padding: 12px 0; font-weight: 700; width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px; }
.btn-link svg { width: 18px; height: 18px; }

/* ---- account: guest auth landing ---- */
.auth-landing { text-align: center; padding: 26px 20px 22px; }
.auth-hero { margin-bottom: 6px; }
.auth-badge { width: 74px; height: 74px; margin: 0 auto 14px; border-radius: 50%; display: grid; place-items: center;
  background: linear-gradient(135deg, var(--blue), var(--blue-l)); box-shadow: 0 10px 24px rgba(16,48,78,.34); }
.auth-badge svg { width: 36px; height: 36px; stroke: #fff; }
.auth-h { font-size: 1.35rem; font-weight: 800; margin: 0 0 6px; }
.auth-p { color: var(--muted); font-size: .92rem; line-height: 1.65; margin: 0 auto; max-width: 340px; }
.auth-btn { width: 100%; flex: none; margin-top: 10px; }

/* ---- redesigned signup form ---- */
.auth-form .auth-hero { margin-bottom: 8px; }
/* social links */
.socials { display: flex; gap: 12px; justify-content: center; margin: 8px 0; }
.social { width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center; color: #fff; }
.social svg { width: 24px; height: 24px; }
.social.fb { background: #1877f2; }
.social.ig { background: linear-gradient(45deg, #f09433, #e6683c, #dc2743, #cc2366, #bc1888); }
.social.tt { background: #000; }
.social-handle { text-align: center; color: var(--muted); font-weight: 700; margin-top: 4px; }

/* biometric login button */
.bio-btn { width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 4px;
  background: var(--card); color: var(--text); border: 1.5px solid var(--line); border-radius: 14px; padding: 13px;
  font-family: inherit; font-weight: 800; font-size: .95rem; cursor: pointer; }
.bio-btn svg { width: 20px; height: 20px; stroke: var(--blue); }

/* small phone/email toggle, sits above the contact field */
.mode-switch { display: inline-block; margin: 2px 0 8px; padding: 6px 12px; background: var(--blue-soft);
  color: var(--blue); border: none; border-radius: 999px; font-family: inherit; font-weight: 700;
  font-size: .82rem; cursor: pointer; }
.mode-switch:active { opacity: .8; }
/* two fields per row (first / last name) */
.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.row2 .field { margin: 0; }
/* phone input with +964 prefix */
.phone-in { display: flex; align-items: stretch; gap: 8px; direction: ltr; }
.phone-in .cc { display: flex; align-items: center; padding: 0 12px; background: var(--blue-soft); color: var(--blue);
  font-weight: 800; border-radius: 12px; direction: ltr; }
.phone-in input { flex: 1; text-align: left; direction: ltr; }
/* password strength meter */
.pw-meter { height: 6px; background: var(--line); border-radius: 4px; overflow: hidden; margin: 8px 0 4px; }
.pw-bar { height: 100%; width: 0; border-radius: 4px; transition: width .2s, background .2s; }
.pw-label { font-size: .8rem; font-weight: 700; min-height: 1em; margin-bottom: 4px; }
/* live confirm-password match feedback */
.match-hint { font-size: .82rem; font-weight: 700; min-height: 1em; margin: -4px 0 8px; }
#sPass2.ok { box-shadow: 0 0 0 1.6px #1e9e4a; }
#sPass2.bad { box-shadow: 0 0 0 1.6px #e0245e; }
/* OTP: phone + edit link, then 6 digit boxes */
.otp-phone { display: flex; align-items: center; justify-content: center; gap: 10px; margin-top: 6px; }
.edit-phone { background: none; border: none; color: var(--blue); font-family: inherit; font-weight: 700;
  font-size: .84rem; cursor: pointer; text-decoration: underline; }
.otp-boxes { display: flex; gap: 8px; justify-content: center; margin: 10px 0 16px; }
.otp-box { width: 46px; height: 56px; text-align: center; font-size: 1.5rem; font-weight: 800;
  border: 1.5px solid var(--line); border-radius: 12px; background: var(--bg); }
.otp-box:focus { border-color: var(--blue); outline: none; background: #fff; }
/* invisible reCAPTCHA host (renders nothing inline; Google shows a corner badge) */
#recaptcha-container { min-height: 0; }

/* date-of-birth field → opens the wheel picker */
.date-field { width: 100%; text-align: right; padding: 12px; border: 1.5px solid var(--line); border-radius: 12px;
  font-family: inherit; font-size: 1rem; background: var(--bg); color: var(--text); cursor: pointer; }
.date-field.ph { color: var(--muted); }
/* gender segmented selector (ذكر / أنثى) */
.gender-seg { display: flex; gap: 8px; }
.gseg { flex: 1; padding: 12px; border: 1.5px solid var(--line); background: var(--bg); border-radius: 12px;
  font-family: inherit; font-weight: 700; font-size: .95rem; color: var(--muted); cursor: pointer; }
.gseg.on { border-color: var(--blue); background: var(--blue-soft); color: var(--blue); }
/* iOS-style wheel picker */
.dp-back { position: fixed; inset: 0; background: rgba(0,0,0,.35); z-index: 1000; display: flex; align-items: flex-end; }
.dp-sheet { width: 100%; background: var(--card); border-radius: 20px 20px 0 0; padding: 12px 14px calc(16px + env(safe-area-inset-bottom));
  box-shadow: 0 -8px 30px rgba(0,0,0,.2); animation: dpUp .25s ease; }
@keyframes dpUp { from { transform: translateY(100%); } }
.dp-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
.dp-head b { font-weight: 800; }
.dp-head button { background: none; border: none; font-family: inherit; font-weight: 800; font-size: 1rem; color: var(--blue); cursor: pointer; padding: 6px; }
.dp-wheels { display: flex; gap: 6px; position: relative; height: 200px; }
.dp-band { position: absolute; left: 0; right: 0; top: 80px; height: 40px; background: var(--blue-soft); border-radius: 10px; pointer-events: none; }
.wheel { flex: 1; height: 200px; overflow-y: scroll; scroll-snap-type: y mandatory; text-align: center;
  scrollbar-width: none; -ms-overflow-style: none; position: relative; z-index: 1; }
.wheel::-webkit-scrollbar { display: none; }
.wheel-item { height: 40px; line-height: 40px; scroll-snap-align: center; font-weight: 700; font-size: 1.05rem; color: var(--text); }
.wheel-pad { height: 80px; }
.btn-outline { width: 100%; background: transparent; color: var(--blue); border: 1.6px solid var(--blue);
  border-radius: 16px; padding: 14px; font-size: 1.02rem; font-weight: 800; cursor: pointer; font-family: inherit; }
.btn-outline:active { background: var(--blue-soft); }
.auth-landing .or-sep { margin: 16px auto; }

/* ---- home sections ---- */
.h-scroll { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 2px 16px 6px;
  scroll-snap-type: x proximity; scroll-padding-inline: 16px; overscroll-behavior-x: contain; }
.h-scroll > * { scroll-snap-align: start; }
.h-scroll::-webkit-scrollbar { display: none; }
.mini-card { flex: 0 0 150px; background: var(--card); border-radius: 16px; overflow: hidden;
  box-shadow: 0 4px 14px rgba(20,40,80,.06); cursor: pointer; }
.mini-card .media { position: relative; }
.mini-card img, .mini-card .noimg { width: 100%; aspect-ratio: 1.15; object-fit: contain; background: #eef2f7;
  display: flex; align-items: center; justify-content: center; font-size: 1.6rem; color: #b3c2d1; }
.mini-card .media { position: relative; }
/* Two lines is 46px, and the supplier titles are spec sheets: the Cudy router had 173px of name
   in that box, so two variants of the same router were indistinguishable on a rail card. Three
   lines at a slightly tighter step shows the part that separates them (model + the first spec)
   and costs 20px of rail height. It will still truncate the longest names — that is the source
   data, not the box; the fix there is a shorter name in Odoo. */
.mini-name { font-size: .78rem; font-weight: 700; padding: 8px 9px 2px; line-height: 1.38;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; min-height: 4.14em; }
.mini-price { color: var(--blue); font-weight: 800; font-size: .85rem; padding: 0 9px 8px; }
/* the rail card follows the grid card: price on the row, control as a circle beside it */
.mini-add { width: 32px; height: 32px; padding: 0; font-size: 1.15rem; margin: 0; }
.mini-card .buy-line { padding: 0 9px 9px; }
.mini-card .mini-price { margin: 0; }
.sec-title.first { margin-top: 10px; }

/* ---- product detail page ---- */
.back-btn { background: none; border: none; color: var(--blue); font: inherit; font-weight: 700;
  cursor: pointer; padding: 10px 2px; margin-top: 6px; }
.prod-card { margin-bottom: 10px; }

/* ---- product gallery + 3D modal ---- */
.gal { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.gal::-webkit-scrollbar { display: none; }
.gal-img { flex: 0 0 100%; width: 100%; height: clamp(280px, 42vh, 400px); object-fit: contain;
  scroll-snap-align: center; }
.btn3d { position: absolute; bottom: 12px; inset-inline-end: 12px; z-index: 3; display: inline-flex;
  align-items: center; gap: 6px; background: var(--blue); color: #fff; border: none; cursor: pointer;
  font-family: inherit; font-size: .82rem; font-weight: 800; padding: 9px 14px; border-radius: 16px;
  box-shadow: 0 4px 14px rgba(16,48,78,.4); }
.btn3d svg { width: 17px; height: 17px; }
.thumbs { display: flex; gap: 8px; overflow-x: auto; padding: 2px 2px 4px; margin-bottom: 16px;
  scrollbar-width: none; }
.thumbs::-webkit-scrollbar { display: none; }
.th { flex: 0 0 auto; width: 62px; height: 62px; padding: 4px; background: var(--card); border: 2px solid var(--line);
  border-radius: 14px; cursor: pointer; overflow: hidden; }
.th.on { border-color: var(--blue); }
.th img { width: 100%; height: 100%; object-fit: contain; display: block; }
.th3d { display: grid; place-items: center; gap: 1px; color: var(--blue); background: var(--blue-soft);
  border-color: var(--blue-soft); font-family: inherit; font-size: .62rem; font-weight: 800; }
.th3d svg { width: 20px; height: 20px; }
.modal3d { position: fixed; inset: 0; z-index: 60; background: #fff;
  display: flex; flex-direction: column; padding: env(safe-area-inset-top) 10px 10px; }
.m3d-bar { display: flex; justify-content: space-between; align-items: center; padding: 10px 4px; }
.m3d-bar .interact-tag { position: static; }
.m3d-close { width: 40px; height: 40px; border: none; border-radius: 50%; cursor: pointer;
  background: var(--bg); color: var(--text); font-size: 1.1rem; }
.m3d-stage { position: relative; flex: 1; display: flex; flex-direction: column; justify-content: center; }
.m3d-stage model-viewer { width: 100%; height: 62vh; background: #fff; }
.m3d-stage .parts-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.m3d-stage .parts-grid model-viewer { height: 28vh; }
.m3d-stage .pname { color: var(--text); }
body.noscroll { overflow: hidden; }

.prod-info { padding: 0 2px; }
.prod-info .p-name { font-size: 1.25rem; font-weight: 800; line-height: 1.5; }
.prod-info .p-code { display: inline-flex; align-items: center; gap: 5px; color: var(--muted); font-size: .78rem;
  font-weight: 600; margin-top: 6px; direction: ltr; }
.prod-info .p-code svg { width: 14px; height: 14px; }
.prod-info .p-price { font-size: 1.4rem; font-weight: 800; color: var(--blue); margin: 8px 0 6px; }
/* pre-line: the merchant writes the description in Odoo, line breaks are theirs */
.prod-info .p-desc { color: var(--muted); font-size: .92rem; line-height: 1.8; margin: 8px 0; white-space: pre-line; }
.prod-info .p-trust { color: var(--muted); font-size: .85rem; margin: 6px 0 16px; }
.wide-img, .wide-card .noimg { width: 108px; height: 108px; flex: 0 0 auto; object-fit: contain; border-radius: 14px;
  background: #eef2f7; display: flex; align-items: center; justify-content: center; font-size: 2rem; color: #b3c2d1; }
.wide-info .name { font-weight: 700; font-size: .95rem; line-height: 1.5; }
.wide-info .price { color: var(--blue); font-weight: 800; margin-top: 6px; }

/* ---- brands ---- */
.brand-row { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 2px 16px 6px; }
.brand-row::-webkit-scrollbar { display: none; }
.brand-logo { width: 34px; height: 34px; border-radius: 10px; background: var(--blue-soft); color: var(--blue);
  display: grid; place-items: center; font-size: 1.1rem; font-weight: 800; overflow: hidden; }
.brand-logo img { width: 100%; height: 100%; object-fit: contain; }
/* brand page: category drill-down (breadcrumb + section cards) */
.bc-trail { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 2px 2px 12px; }
.bc-seg { background: none; border: none; font: inherit; font-weight: 700; font-size: .9rem; color: var(--blue); cursor: pointer; padding: 2px 4px; }
.bc-seg.on { color: var(--text); cursor: default; }
.bc-sep { color: var(--muted); }
.bcat-label { font-size: .9rem; font-weight: 800; color: var(--muted); margin: 4px 2px 8px; }
.bcat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 10px; margin: 2px 2px 16px; }
.bcat-card { display: flex; flex-direction: column; align-items: center; gap: 6px; background: var(--card); border: 1.5px solid var(--line);
  border-radius: 14px; padding: 16px 10px; font: inherit; font-weight: 700; font-size: .9rem; color: var(--text); cursor: pointer; }
.bcat-card:hover { border-color: var(--blue); color: var(--blue); }
.bcat-ic svg { width: 26px; height: 26px; }
.bcat-t { text-align: center; line-height: 1.2; }
.brand-pill { display: inline-flex; align-items: center; gap: 5px; background: var(--card); border: 1.5px solid var(--line);
  border-radius: 12px; padding: 8px 13px; font: inherit; font-weight: 700; font-size: .85rem; color: var(--text); cursor: pointer; }
.brand-pill svg { width: 15px; height: 15px; color: var(--muted); }
.pill-logo { width: 18px; height: 18px; object-fit: contain; border-radius: 3px; }
.brand-pill:hover { border-color: var(--blue); color: var(--blue); }
.brand-pill:hover svg { color: var(--blue); }
.brand-pill.on { background: var(--blue); color: #fff; border-color: var(--blue); }
.brand-pill.on svg { color: #fff; }

.menu-sec { color: var(--muted); font-size: .78rem; font-weight: 800; padding: 16px 4px 6px; }
.menu-row.sub { padding-inline-start: 8px; font-weight: 700; }
.menu-row.sub .m-ic svg { width: 18px; height: 18px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }
.card { background: var(--card); border-radius: 18px; overflow: hidden; box-shadow: 0 4px 16px rgba(20,40,80,.06);
  display: flex; flex-direction: column; cursor: pointer; }
.card .media { position: relative; }
/* contain, not cover: product shots have mixed aspect ratios (wide 16:9 camera
   renders next to square boxes) — cover cropped each one differently */
.card img, .card .noimg { width: 100%; aspect-ratio: 4 / 3; object-fit: contain; padding: 10px; background: #fff;
  display: flex; align-items: center; justify-content: center; font-size: 2rem; color: #b3c2d1; transition: transform .25s; }
.card:hover img { transform: scale(1.04); }
.heart-btn, .like-btn { position: absolute; bottom: 8px; inset-inline-end: 8px; width: 36px; height: 36px; border: none;
  background: rgba(255,255,255,.92); border-radius: 50%; display: grid; place-items: center; cursor: pointer;
  color: var(--muted); box-shadow: 0 2px 8px rgba(0,0,0,.12); }
.heart-btn svg, .like-btn svg { width: 18px; height: 18px; }
.heart-btn.on { color: #e0245e; }
.like-btn.on { color: var(--blue); }
.card .body { padding: 11px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
/* Clamp to 2 lines like .mini-name already did. Without this, one long spec-sheet name
   (e.g. "MSI B650M GAMING WIFI DDR5 Micro-ATX Motherboard — AMD B650 Chipset, AM5…")
   renders in full and stretches its card to ~10x the height of its neighbours. */
.card .name { font-weight: 700; font-size: .9rem; line-height: 1.4; text-align: start;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  min-height: 2.8em; }
.card .price { color: var(--blue); font-weight: 800; }
/* Six product cards used to mean six full-width navy slabs, each as loud as the product above
   it — the grid read as a wall of buttons. The price is what a customer scans, so the price
   gets the row and the control shrinks to a circle beside it. The card also lost ~40px of
   height, which is one more product per screen. */
.buy-line { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.buy-line .price { font-size: 1.02rem; }
.grid-add { flex: none; width: 36px; height: 36px; display: grid; place-items: center;
  background: var(--card); color: var(--blue); border: 1.5px solid var(--blue); border-radius: 50%;
  cursor: pointer; font-family: inherit; font-weight: 700; font-size: 1.25rem; line-height: 1;
  transition: transform .12s ease, background .15s ease, color .15s ease; }
.grid-add:active { transform: scale(.88); }
/* already in the basket: the circle carries the count, so the customer never wonders whether
   the first tap landed */
.grid-add:has(.ga-n) { background: var(--blue); color: #fff; }
.ga-n { font-size: .95rem; font-weight: 800; }
.grid-add.added { background: #1e9e4a; border-color: #1e9e4a; color: #fff; }
.grid-add svg { width: 18px; height: 18px; }
/* the ghost that flies to the cart chip — above everything, catching no taps */
.fly-ghost { position: fixed; z-index: 3000; pointer-events: none; object-fit: contain;
  border-radius: 12px; background: #fff; }
.grid-add.added, .add-cart.added { display: inline-flex; align-items: center; justify-content: center; gap: 5px; }
.grid-add.added svg, .add-cart.added svg { width: 1.05em; height: 1.05em; }

/* ---- search ---- */
.search-wrap { display: flex; align-items: center; gap: 8px; background: var(--card); border: 1.5px solid var(--line);
  border-radius: 14px; padding: 10px 14px; margin-bottom: 16px; }
.search-wrap svg { width: 20px; height: 20px; color: var(--muted); flex: 0 0 auto; }
.search-wrap input { flex: 1; border: none; outline: none; font: inherit; background: none; min-width: 0; }

/* ---- cart page ---- */
.cart-row { display: flex; gap: 12px; align-items: center; background: var(--card); border-radius: 18px;
  padding: 10px; margin-bottom: 10px; box-shadow: 0 4px 14px rgba(20,40,80,.05); }
.c-media { position: relative; width: 96px; flex: 0 0 auto; border-radius: 14px; overflow: hidden; cursor: pointer; }
.c-media img, .c-media .noimg { width: 96px; height: 96px; object-fit: contain; background: #eef2f7;
  display: flex; align-items: center; justify-content: center; font-size: 1.6rem; color: #b3c2d1; }
.c-info { flex: 1; min-width: 0; }
.c-name { font-weight: 700; font-size: .88rem; line-height: 1.45; }
.c-price { color: var(--muted); font-size: .82rem; margin: 3px 0 8px; }
.c-controls { display: flex; align-items: center; gap: 12px; }
.qty { display: flex; align-items: center; gap: 8px; }
.qty button { width: 30px; height: 30px; border: 1.5px solid var(--line); background: #fff; border-radius: 9px;
  cursor: pointer; font-size: 1.05rem; }
.rm-btn { display: flex; align-items: center; gap: 4px; background: none; border: none; color: #c0392b;
  font: inherit; font-size: .8rem; font-weight: 700; cursor: pointer; }
.rm-btn svg { width: 16px; height: 16px; }
.c-line-total { font-weight: 800; white-space: nowrap; }
.summary { margin-top: 14px; }
.summary .btn-primary { width: 100%; margin-top: 8px; }
.s-row { display: flex; justify-content: space-between; padding: 8px 0; color: var(--muted); font-weight: 600; }
.s-row.total-row { color: var(--text); font-weight: 800; font-size: 1.1rem; border-top: 1px solid var(--line); margin-top: 4px; padding-top: 12px; }
.free { color: #1e9e4a; font-weight: 800; }
.empty-cart { text-align: center; padding: 30px 16px; }
.empty-cart .big { font-size: 3rem; margin-bottom: 6px; }
.empty-cart .big svg { width: 52px; height: 52px; color: var(--muted); }
.empty-cart .btn-primary { width: 100%; margin-top: 14px; }

/* ---- panels / forms ---- */
.panel { background: var(--card); border-radius: 20px; padding: 18px; box-shadow: 0 4px 16px rgba(20,40,80,.06); }
.panel h2 { margin-bottom: 10px; font-size: 1.05rem; }
.co-title { font-size: 1.35rem; font-weight: 800; margin-bottom: 14px; }
.field { margin-bottom: 12px; }
.field label { display: block; font-size: .85rem; color: var(--muted); margin-bottom: 5px; font-weight: 600; }
.field input, .field textarea, .field select { width: 100%; padding: 12px; border: 1.5px solid var(--line); border-radius: 12px;
  font-family: inherit; font-size: 1rem; background: var(--bg); }
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--blue); background: #fff; }
#fAreaOther { margin-top: 8px; }
.zone-note { background: var(--bg); border: 1.5px solid var(--line); border-radius: 12px;
  padding: 12px; margin-top: 14px; font-weight: 700; line-height: 1.7; }
.zone-note small { display: block; color: var(--muted); font-weight: 600; }
.checkout-panel .btn-primary { width: 100%; margin-top: 6px; }
.err { color: #c0392b; font-size: .9rem; margin: 8px 0; }
.total { display: flex; justify-content: space-between; font-weight: 800; padding: 14px 0 4px; font-size: 1.1rem; }
.pay-line { color: var(--muted); font-weight: 700; margin-bottom: 12px; }

/* ---- auth ---- */
.google-btn { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%;
  background: #fff; color: #3c4043; border: 1.5px solid var(--line); border-radius: 14px; padding: 13px;
  font: inherit; font-weight: 700; cursor: pointer; }
.google-btn:hover { background: #f8f9fb; }
.fb-btn, .apple-btn { display: flex; align-items: center; justify-content: center; gap: 10px; width: 100%;
  border: none; border-radius: 14px; padding: 13px; font: inherit; font-weight: 700; cursor: pointer;
  margin-top: 10px; color: #fff; }
.fb-btn { background: #1877F2; } .fb-btn:hover { background: #1568da; }
.apple-btn { background: #000; } .apple-btn:hover { background: #1a1a1a; }
.or-sep { display: flex; align-items: center; gap: 12px; color: var(--muted); font-size: .85rem; margin: 14px 0; }
.or-sep::before, .or-sep::after { content: ''; flex: 1; height: 1px; background: var(--line); }
.checkout-panel .btn-link { margin-top: 2px; }

/* ---- map ---- */
.map-block { margin: 14px 0; }
.map-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; font-weight: 700; margin-bottom: 8px; flex-wrap: wrap; }
.loc-btn { display: flex; align-items: center; gap: 6px; background: var(--blue-soft); color: var(--blue); border: none;
  border-radius: 12px; padding: 9px 12px; font: inherit; font-size: .85rem; font-weight: 800; cursor: pointer; }
.loc-btn svg { width: 17px; height: 17px; }
.map-box { border-radius: 16px; overflow: hidden; background: #e8edf3; min-height: 170px; }
.map-box iframe { width: 100%; height: 220px; border: 0; display: block; }
.map-empty { display: grid; place-items: center; min-height: 170px; color: var(--muted); font-size: .9rem; padding: 12px; text-align: center; }

/* ---- success ---- */
.success { text-align: center; padding-top: 18px; }
.success .shield { width: 110px; height: 110px; margin: 0 auto 10px; filter: drop-shadow(0 10px 22px rgba(216,165,32,.35)); }
.success h1 { font-size: 1.35rem; margin-bottom: 20px; }
.steps { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 20px; }
.step { display: flex; flex-direction: column; align-items: center; gap: 5px; color: var(--muted); font-size: .82rem; font-weight: 700; }
.step .s-ic { width: 44px; height: 44px; border-radius: 50%; background: var(--card); display: grid; place-items: center;
  box-shadow: 0 3px 12px rgba(20,40,80,.08); }
.step .s-ic svg { width: 21px; height: 21px; }
.step.done { color: var(--blue); }
.step.done .s-ic { background: var(--blue-soft); }
.s-bar { width: 34px; height: 3px; border-radius: 2px; background: var(--line); margin-bottom: 22px; }
.o-meta { text-align: center; margin-bottom: 14px; line-height: 2; }
.o-meta span { color: var(--muted); }
.pay-summary { text-align: start; margin-bottom: 16px; }
.success .btn-primary { width: 100%; }
#eSave, #aSave, .af-save { width: 100%; margin-top: 10px; }
.o-ic { width: 42px; height: 42px; flex: 0 0 auto; border-radius: 12px; background: var(--blue-soft); color: var(--blue);
  display: grid; place-items: center; }
.o-ic svg { width: 20px; height: 20px; }
.o-body { flex: 1; display: flex; flex-direction: column; }
.o-body small { color: var(--muted); }
/* notifications: same row as an order, unread gets a blue rail */
.notif-row { display: flex; align-items: center; gap: 12px; width: 100%; background: var(--card); border: none;
  border-radius: 16px; padding: 13px; margin-bottom: 9px; box-shadow: 0 4px 14px rgba(20,40,80,.05);
  cursor: pointer; font: inherit; text-align: start; }
.notif-row.unread { border-inline-start: 4px solid var(--blue); background: #fbfcff; }
.notif-row .o-body b { font-weight: 700; font-size: .95rem; }
.track-panel { margin-bottom: 18px; }
.timeline { padding: 4px 6px; }
.t-step { position: relative; display: flex; align-items: center; gap: 12px; padding: 12px 0; color: var(--muted); }
.t-step::before { content: ''; position: absolute; top: 44px; inset-inline-start: 15px; width: 2px; height: calc(100% - 40px); background: var(--line); }
.t-step:last-child::before { display: none; }
.t-ic { width: 32px; height: 32px; flex: 0 0 auto; border-radius: 50%; background: var(--bg); display: grid; place-items: center; z-index: 1; }
.t-ic svg { width: 16px; height: 16px; }
.t-step.done { color: var(--text); font-weight: 700; }
.t-step.done .t-ic { background: var(--blue); color: #fff; }
.t-now { margin-inline-start: auto; background: var(--blue-soft); color: var(--blue); font-size: .72rem; font-weight: 800;
  padding: 4px 10px; border-radius: 10px; }
.cancelled { text-align: center; color: #c0392b; font-weight: 800; padding: 14px; }
.cancel-why { display: block; margin-top: 6px; font-weight: 600; font-size: .92rem; color: var(--muted); }

/* ---- account ---- */
.account { text-align: center; }
.avatar { width: 72px; height: 72px; margin: 4px auto 10px; border-radius: 50%; background: var(--blue-soft);
  color: var(--blue); font-size: 1.7rem; font-weight: 800; display: grid; place-items: center; }
.acc-name { font-weight: 800; font-size: 1.15rem; }
.dash { display: flex; gap: 8px; }
.addr { margin-bottom: 4px; }
.logout { color: #c0392b; margin-top: 18px; }
.about p { line-height: 1.9; margin-bottom: 10px; }

/* ---- drawer (menu) ---- */
#backdrop { position: fixed; inset: 0; background: rgba(10,15,25,.42); opacity: 0; visibility: hidden; z-index: 65;
  transition: opacity .25s, visibility .25s; z-index: 20; }
#backdrop.show { opacity: 1; visibility: visible; }
#drawer { position: fixed; top: 0; bottom: 0; right: 0; left: auto; width: min(340px, 86vw);
  /* was 21 — under the announcement strip's 60, so the strip swallowed the tap on the drawer's
     own «×». The backdrop still closed it, which is why it read as «the × is dead» rather than
     as «the menu is stuck». A panel that covers the screen has to sit above the chrome it covers. */
  background: var(--card); z-index: 70; padding: 18px; overflow-y: auto;
  transform: translateX(105%); transition: transform .3s cubic-bezier(.4,0,.2,1); box-shadow: 0 0 30px rgba(0,0,0,.2);
  border-radius: 18px 0 0 18px; }
#drawer.open { transform: none; }
/* absolute, so the brand block that follows it in the flow painted straight over it — a real
   finger landed on the logo. It also sat under the announcement strip until the drawer's own
   z-index was raised. Both fixed: it stacks above its siblings and clears the strip. */
.close-x { position: absolute; z-index: 3; top: calc(env(safe-area-inset-top, 0px) + 14px); left: 14px; right: auto;
  background: none; border: none; font-size: 1.3rem;
  cursor: pointer; color: var(--text); width: 44px; height: 44px; border-radius: 50%; }
.close-x:hover { background: var(--bg); }
.menu-brand { text-align: center; padding: 20px 0 22px; border-bottom: 1px solid var(--line); margin-bottom: 8px; }
.m-name { font-weight: 800; font-size: 1.05rem; }
.menu-row { display: flex; align-items: center; gap: 12px; width: 100%; text-align: start; background: none; border: none;
  border-bottom: 1px solid var(--line); padding: 15px 4px; font: inherit; font-weight: 700; cursor: pointer; color: var(--text); }
.menu-row .m-ic { color: var(--muted); display: grid; place-items: center; }
.menu-row .m-ic svg { width: 21px; height: 21px; }
.menu-row:hover { color: var(--blue); }
.menu-row:hover .m-ic { color: var(--blue); }

/* ---- bottom tabs ---- */
/* ===== the floating tab bar (2026-08-16) =====
   Modelled on the shop we measured against: a white pill that hovers over the content with a
   soft shadow, three destinations, the active one in the brand colour with a filled glyph. It
   was `display:none !important` here, which is why the header had to carry five controls. */
.tabbar { display: flex !important; position: fixed; z-index: 60;
  inset-inline: 14px; bottom: max(14px, calc(10px + env(safe-area-inset-bottom)));
  height: 62px; padding: 0 6px; align-items: center;
  /* env(safe-area-inset-bottom) is 0 on Android 11 with the classic three-button bar, so the
     floating pill sat directly on top of the system buttons on a Redmi 9A. max() keeps a real
     gap there without adding a second one on phones that do report an inset. */
  background: var(--card); border: none; border-radius: 31px;
  box-shadow: 0 6px 28px rgba(16,48,78,.16), 0 1px 3px rgba(16,48,78,.10); }
body.mode-maryam .tabbar,            /* her surface is the interface; nothing floats over it */
body.agent-live .tabbar { display: none !important; }
.tab { flex: 1; background: none; border: none; cursor: pointer; color: var(--muted);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; font-family: inherit; }
.tab svg { width: 24px; height: 24px; }
.tab .tl { font-size: .68rem; font-weight: 700; }
.tab.on { color: var(--blue); }
.tab.on .ti { background: none; padding: 0; }
.tab.on .tl { font-weight: 800; }

/* ---- motion / misc ---- */
.fade-in { animation: fadein .3s ease; }
@keyframes fadein { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .28s; }
button { transition: transform .12s ease, background .15s ease, color .15s ease; }
button:active { transform: scale(.95); }
/* Inline SVG icons embedded in text (replace old emoji).
   An ICON dropped into a text node has no intrinsic size and fills its box — ~300px.
   Forgetting to extend this list has now shipped a giant icon three times (.zone-note,
   .svc-note, .io-txt small), so it ends with a floor: an svg directly inside <small> or
   <p> is text-inline by definition and gets sized whether or not anyone remembered.
   Dedicated icon tiles (.io-ic, .sb-ic, .chip-ic …) set their own w/h and out-specify. */
.p-trust svg, .pay-line svg, .interact-tag svg, .map-empty svg, .hint svg, .about p svg,
.zone-note svg, .svc-note svg,
.prod-info .p-trust svg,
small > svg, p > svg { width: 1.05em; height: 1.05em; vertical-align: -0.18em; display: inline-block; flex: 0 0 auto; }

/* ---- services: banner (home) + attach offer (cart) ---- */
.svc-banner, .inst-offer { width: 100%; display: flex; align-items: center; gap: 12px; text-align: right;
  background: var(--card); border: 1.5px solid var(--line); border-radius: 16px; padding: 14px; margin: 4px 0 14px;
  font-family: inherit; cursor: pointer; }
@media (max-width: 380px) { .sb-txt { width: 68%; } .sb-txt b { font-size: .97rem; } }
.io-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.sb-txt b, .io-txt b { font-size: 1rem; font-weight: 800; }
.sb-txt small, .io-txt small { color: var(--muted); font-weight: 600; line-height: 1.5; }
/* install tickbox (cart) */
.inst-offer { border-color: var(--line); }
.inst-offer.on { border-color: var(--blue); background: var(--blue-soft); }
.io-box { flex: 0 0 auto; display: grid; place-items: center; width: 26px; height: 26px; border-radius: 8px;
  border: 2px solid var(--line); background: var(--card); color: #fff; }
.inst-offer.on .io-box { background: var(--blue); border-color: var(--blue); }
.io-box svg { width: 15px; height: 15px; }
.io-amt { flex: 0 0 auto; font-weight: 800; color: var(--blue); white-space: nowrap; }
.svc-price .cur { font-size: .75rem; }
.svc-lede { color: var(--muted); font-weight: 600; line-height: 1.7; margin: -6px 0 14px; }
@media (max-width: 380px) { .io-go { font-size: .78rem; padding: 8px 9px; } }
.hint { display: flex; align-items: center; gap: 5px; }
.map-empty svg { width: 1.2em; height: 1.2em; }
.noimg svg { width: 40%; height: 40%; opacity: .38; color: var(--muted); }
/* photo-less products name their brand instead of showing a bare glyph — placeholder() in app.js */
.noimg { flex-direction: column; gap: 6px; }
.noimg svg { width: 26%; height: 26%; }
.noimg-b { font-size: .82rem; font-weight: 700; color: var(--muted); letter-spacing: .3px;
  max-width: 90%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* a service isn't missing a photo, so tint it instead of leaving it looking broken */
.noimg-svc { background: linear-gradient(150deg, var(--blue-soft), #f6f9ff) !important; }
.noimg-svc svg { opacity: .75; color: var(--blue); }
.empty-cart .big svg { width: 54px; height: 54px; color: var(--muted); }

.notice { text-align: center; color: var(--muted); padding: 36px 0; }

/* ---- appointment (booked, not billed) ---- */
.s-appt, .appt-card { display: flex; align-items: flex-start; gap: 10px; background: #fff8e8;
  border: 1.5px solid #f0dfae; border-radius: 12px; padding: 12px; margin-top: 12px;
  font-weight: 600; line-height: 1.7; text-align: right; }
.s-appt b, .appt-card b { color: var(--text); }
.s-appt svg, .ap-ic svg { width: 1.05em; height: 1.05em; vertical-align: -.18em; }
.ap-ic { flex: 0 0 auto; display: grid; place-items: center; width: 36px; height: 36px;
  border-radius: 10px; background: #f0dfae; color: #7a5c14; }
.ap-ic svg { width: 19px; height: 19px; }
.ap-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.ap-body small { color: #7a6a3e; font-weight: 600; font-size: .84rem; line-height: 1.65; }
.brand-link::after, .drawer-brand::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255,255,255,.85), transparent);
  animation: brandSheen 5.5s ease-in-out infinite; }
.drawer-brand { position: relative; overflow: hidden; border-radius: 8px; }
/* keyframes drive `left`, not transform — the sheen crosses a container of unknown width
   and a % translate would resolve against the sheen's own width, not the wordmark's */
@keyframes brandSheen { 0% { left: -50%; } 22%, 100% { left: 105%; } }
@media (prefers-reduced-motion: reduce) { .brand-link::after, .drawer-brand::after { animation: none; opacity: 0; } }
/* welcome screen: the real wordmark, not a "3D" tile from the old name */
.w-lockup { height: 46px; width: auto; display: block; margin: 0 auto; }

/* ---- estimate warning: red, because "تقديري" is the one word a customer must not skim.
   Everything else on this screen is a firm number; this one isn't, and finding that out
   from the technician instead of from here is exactly the surprise we're avoiding. ---- */
.est-warn { display: flex; align-items: flex-start; gap: 9px; background: #fdf0f0;
  border: 1.5px solid #f3c9c9; border-radius: 12px; padding: 12px; margin-top: -4px;
  color: #a12727; font-weight: 600; font-size: .85rem; line-height: 1.7; }
/* installation → AI-scheduling note (friendly, assistant-violet) */
.ai-appt-note { display: flex; align-items: center; gap: 9px; background: #f3ecff;
  border: 1.5px solid #e0d1ff; border-radius: 12px; padding: 12px; margin-top: -4px;
  color: #6d28d9; font-weight: 700; font-size: .88rem; line-height: 1.6; }
.ai-appt-note > svg { width: 1.25em; height: 1.25em; flex: 0 0 auto; }
.est-warn b { color: #8b1d1d; font-weight: 800; }
.est-warn > svg { width: 1.15em; height: 1.15em; flex: 0 0 auto; margin-top: .28em; }

/* ---- booking (service order) ---- */
.bk-panel { margin-bottom: 12px; }
.bk-h { display: flex; align-items: center; gap: 8px; font-size: 1rem; font-weight: 800; margin-bottom: 10px; }
.bk-h svg { width: 18px; height: 18px; color: var(--blue); }
.bk-row { display: flex; justify-content: space-between; gap: 10px; padding: 7px 0; font-weight: 600; }
.bk-p { color: var(--blue); font-weight: 800; white-space: nowrap; }
.bk-tot { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 10px; font-weight: 800; font-size: 1.05rem; }
.bk-tot span:last-child { color: var(--blue); }
.bk-note { display: flex; align-items: flex-start; gap: 6px; color: var(--muted); font-weight: 600; font-size: .82rem; line-height: 1.6; }
.slots { display: flex; gap: 8px; flex-wrap: wrap; }
.slot { flex: 1; min-width: 96px; background: var(--bg); border: 1.5px solid var(--line); border-radius: 11px;
  padding: 12px 8px; font-family: inherit; font-weight: 700; font-size: .88rem; color: var(--text); cursor: pointer;
  transition: background .15s, border-color .15s, color .15s; }
.slot.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.bk-add { display: flex; flex-wrap: wrap; gap: 8px; }
.bk-chip { background: var(--card); border: 1.5px dashed var(--line); border-radius: 11px; padding: 9px 13px;
  font-family: inherit; font-weight: 700; font-size: .85rem; color: var(--blue); cursor: pointer; }
.bk-chip:hover { border-style: solid; background: var(--blue-soft); }
.bk-chip b { font-weight: 800; }
.checkout-panel .btn-primary, #bkGo { width: 100%; margin-top: 6px; }
.slot { display: flex; flex-direction: column; gap: 2px; align-items: center; }
.slot b { font-size: .9rem; font-weight: 800; }
.slot span { font-size: .78rem; opacity: .8; font-weight: 700; }

/* persistent brand facet under the category chips — second filter axis */
.chips-brands { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none;
  padding: 8px 16px 2px; margin: 0 -16px; border-top: 1px solid var(--line); }
.chips-brands::-webkit-scrollbar { display: none; }
.chips-brands .brand-pill { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  background: var(--bg); border: 1.5px solid var(--line); border-radius: 999px; padding: 6px 13px;
  font-family: inherit; font-weight: 700; font-size: .82rem; color: var(--text); cursor: pointer; white-space: nowrap; }
.chips-brands .brand-pill.on { background: var(--blue); border-color: var(--blue); color: #fff; }
.chips-brands .brand-pill svg { width: 13px; height: 13px; }

/* tag-based category tunnel (redesign) — reuses chip/card styles, native look */
.nav-wrap { padding: 8px 7px calc(var(--tab-h) + 20px); }
.nav-wrap .chips-row, .nav-wrap .chips-sub { margin-bottom: 5px; }
.nav-cnt { opacity: .5; font-size: 11px; margin-inline-start: 4px; font-weight: 600; }
#navBody { margin-top: 6px; }
#navBody .chips-brands { margin-bottom: 12px; }

/* new 12-category home grid (redesign) */
.navhome { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; padding: 16px; }
@media (max-width: 360px) { .navhome { grid-template-columns: repeat(2, 1fr); } }
.navhome-cat { background: var(--card); border: 1px solid var(--line); border-radius: 16px; padding: 18px 8px; text-align: center; cursor: pointer; font: inherit; display: flex; flex-direction: column; align-items: center; gap: 8px; box-shadow: 0 2px 10px rgba(16,21,31,.04); transition: transform .12s; }
.navhome-cat:active { transform: scale(.96); }
.nhc-e { font-size: 30px; line-height: 1; }
.nhc-n { font-size: 12.5px; font-weight: 700; color: var(--text); line-height: 1.35; }
@media (min-width: 420px) { .brand-grid { grid-template-columns: repeat(3, 1fr); } }
.brand-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px 4px; }
.back-chip { background: var(--blue-soft); color: var(--blue-d); border: 0; border-radius: 16px; padding: 6px 13px; font: inherit; font-weight: 700; font-size: 13px; cursor: pointer; }
.navcats .chip.navcat { display: flex; flex-direction: column; align-items: center; gap: 4px; border-bottom: none; padding: 6px 10px; }
.navcats .chip .cc-ic { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 11px; background: var(--bg); color: var(--muted); transition: background .15s, color .15s; }
.navcats .chip .cc-ic svg { width: 21px; height: 21px; }
.navcats .chip .cc-t { font-size: 11px; font-weight: 700; white-space: nowrap; color: var(--muted); }
.navcats .chip.on .cc-ic { background: var(--blue); color: #fff; }
.navcats .chip.on .cc-t { color: var(--blue-d); }
/* home grid: SVG mark instead of emoji */
.navhome-cat .nhc-e { display: grid; place-items: center; height: 34px; }
.navhome-cat .nhc-e svg { width: 32px; height: 32px; color: var(--blue); }

/* search-tab filter & sort bar */
.sf-bar { display: grid; grid-template-columns: 1fr 1fr; gap: 9px; padding: 6px 14px 10px; align-items: center; }
.sf-sel, .sf-price { min-width: 0; width: 100%; box-sizing: border-box; height: 44px; border: 1px solid #e6ebf3; border-radius: 14px; background: #fff;
  color: var(--text); font-family: inherit; font-weight: 600; font-size: .92rem; padding: 0 14px; outline: none;
  box-shadow: 0 2px 8px rgba(30,41,59,.05); transition: border-color .15s, box-shadow .15s; }
.sf-sel { appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%238a94a3' stroke-width='2'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat; background-position: left 12px center; padding-left: 32px; }
.sf-price { text-align: center; }
.sf-sel:focus, .sf-price:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(16,48,78,.12); }

/* store location page */
.loc-panel .loc-addr { color: var(--muted); margin: 2px 0 10px; }
.loc-map { position: relative; width: 100%; aspect-ratio: 16 / 10; border-radius: 14px; overflow: hidden;
  border: 1px solid var(--line); background: var(--bg); }
.loc-map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.loc-dir { display: inline-flex; align-items: center; gap: 8px; margin-top: 12px; padding: 11px 18px;
  background: var(--blue); color: #fff; border-radius: 12px; font-weight: 700; text-decoration: none; }
.loc-dir svg { stroke: #fff; }
.loc-note { color: var(--muted); margin-top: 12px; }

/* ===== redesigned header: delivery-to + actions, then a full-width search ===== */
.top-row { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.deliver-to { flex: 1; min-width: 0; display: flex; align-items: center; gap: 5px; background: none; border: none;
  cursor: pointer; color: var(--text); font-family: inherit; padding: 2px 0; text-align: start; }
.deliver-to .dt-label { color: var(--muted); font-size: .9rem; flex: none; }
.deliver-to .dt-area { font-weight: 800; font-size: .98rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.deliver-to .dt-caret { color: var(--blue); flex: none; }
.cart-chip { border-radius: 50%; display: inline-flex; }
.header-search { display: flex; align-items: center; gap: 9px; width: 100%; height: 44px; padding: 0 14px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 13px; cursor: text; font-family: inherit; }
.header-search svg { width: 20px; height: 20px; color: var(--muted); flex: none; }
.header-search .hs-text { color: var(--muted); font-size: .95rem; }
@media (min-width: 900px) {
  .topbar { flex-direction: row; align-items: center; gap: 18px; padding: 12px 28px; }
  .top-row { flex: none; gap: 14px; }
  .header-search { flex: 1; max-width: 620px; margin: 0 auto; height: 46px; order: 1; }
  .deliver-to { flex: none; }
}

/* ===== saved-addresses bottom sheet ===== */
.sheet-wrap { position: fixed; inset: 0; z-index: 60; background: rgba(0,0,0,.45); display: flex; align-items: flex-end;
  opacity: 0; transition: opacity .2s; }
.sheet-wrap.show { opacity: 1; }
.addr-sheet { position: relative; width: 100%; max-height: 86vh; overflow-y: auto; background: var(--card);
  border-radius: 22px 22px 0 0; padding: 22px 20px calc(22px + env(safe-area-inset-bottom));
  transform: translateY(100%); transition: transform .22s ease; box-shadow: 0 -8px 30px rgba(0,0,0,.18); }
.sheet-wrap.show .addr-sheet { transform: translateY(0); }
@media (min-width: 900px) { .sheet-wrap { align-items: center; } .addr-sheet { max-width: 520px; margin: auto; border-radius: 22px; } }
.sheet-close { position: absolute; inset-inline-end: 18px; top: 16px; width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--card); color: var(--text); font-size: 1.05rem; cursor: pointer; }
.as-title { font-size: 1.5rem; font-weight: 800; margin: 6px 0 18px; }
.as-sub { font-size: 1.1rem; font-weight: 800; margin: 0 0 10px; }
.as-list { display: flex; flex-direction: column; }
.as-item { display: flex; align-items: flex-start; gap: 12px; padding: 14px 2px; background: none; border: none;
  border-bottom: 1px solid var(--line); cursor: pointer; text-align: start; font-family: inherit; color: var(--text); width: 100%; }
.as-item .as-pin { color: var(--text); flex: none; margin-top: 2px; }
.as-item .as-pin svg { width: 22px; height: 22px; }
.as-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.as-body b { font-size: 1.05rem; }
.as-body span { color: var(--muted); font-size: .9rem; }
.as-big { display: flex; align-items: center; gap: 13px; width: 100%; margin-top: 12px; padding: 15px 16px;
  background: var(--card); border: 1px solid var(--line); border-radius: 14px; cursor: pointer; text-align: start;
  font-family: inherit; color: var(--text); }
.as-big .asb-ic { color: var(--blue); flex: none; display: inline-flex; }
.as-big .asb-body { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.as-big .asb-body b { font-size: 1.02rem; }
.as-big .asb-body span { color: var(--muted); font-size: .88rem; }
.as-big .asb-arrow { color: var(--muted); font-size: 1.2rem; }

/* ===== account hero strip (tap → settings) ===== */
.acc-hero { display: flex; align-items: center; gap: 12px; width: 100%; background: none; border: none;
  cursor: pointer; padding: 8px 2px 14px; text-align: start; font-family: inherit; color: var(--text); }
.acc-hero .acc-gear { color: var(--text); flex: none; display: inline-flex; }
.acc-hero .acc-id { flex: 1; display: flex; flex-direction: column; align-items: flex-end; gap: 2px; text-align: end; }
.acc-hero .acc-name { font-size: 1.25rem; font-weight: 800; }
.acc-hero .acc-country { color: var(--muted); font-size: .9rem; }
.acc-hero .acc-avatar { width: 52px; height: 52px; border-radius: 50%; background: var(--blue-soft); color: var(--blue);
  display: flex; align-items: center; justify-content: center; font-size: 1.3rem; font-weight: 800; flex: none; margin: 0; }

/* ===== settings page ===== */
.set-page { padding: 4px 2px 20px; }
.set-head { display: flex; align-items: center; gap: 10px; justify-content: flex-end; margin-bottom: 8px; }
.set-head .page-title { margin: 0; }
.set-head .back-chip { order: 2; }
.set-list { display: flex; flex-direction: column; }
.set-row2 { display: flex; align-items: center; justify-content: space-between; gap: 12px; width: 100%;
  background: none; border: none; border-bottom: 1px solid var(--line); padding: 18px 2px; cursor: pointer;
  font-family: inherit; color: var(--text); }
.set-row2 .sr2-label { font-size: 1.08rem; font-weight: 600; }
.set-row2 .sr2-end { display: flex; align-items: center; gap: 8px; color: var(--muted); }
.set-row2 .sr2-val { color: var(--muted); font-size: .95rem; }
.set-row2 .sr-chev { color: var(--muted); flex: none; }
.set-row2:active { background: var(--bg); }

/* ===== account-info (معلومات الحساب) extras ===== */
.acc-info .field { margin-top: 14px; }
.ai-check { display: flex; align-items: center; gap: 10px; margin-top: 16px; cursor: pointer; font-size: .98rem; }
.ai-check input { width: 20px; height: 20px; accent-color: var(--blue); flex: none; }
.ai-danger { display: block; width: 100%; margin-top: 22px; padding: 14px; background: none; color: #d33;
  border: 1.5px solid #f0b4b4; border-radius: 13px; font-family: inherit; font-weight: 700; font-size: 1rem; cursor: pointer; }
.ai-danger:active { background: #fff2f2; }

/* ===== address book list (العناوين) ===== */
.set-head .add-link { order: 3; margin-inline-start: auto; background: none; border: none; color: var(--blue);
  font-family: inherit; font-weight: 700; font-size: 1rem; cursor: pointer; }
.addr-list { display: flex; flex-direction: column; }
.addr-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 16px 2px; background: none;
  border: none; border-bottom: 1px solid var(--line); cursor: pointer; text-align: start; font-family: inherit; color: var(--text); }
.addr-item .ai-chev { color: var(--muted); flex: none; display: inline-flex; }
.addr-item .ai-body { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.addr-item .ai-body > b { font-size: 1.1rem; font-weight: 800; }
.addr-item .ai-area { color: var(--muted); font-weight: 600; font-size: .95rem; }
.addr-item .ai-line, .addr-item .ai-phone { color: var(--muted); font-size: .92rem; }

/* ===== the mode switch: «المتجر» ⇄ «مريم» (replaced the corner «Ai» chip) ===== */
/* Two halves of one control, so browsing and مريم read as the same size of choice. The
   selected half is the raised one — she never gets gold here, because gold is what she
   POINTS with, and a permanently gold tab would burn the signal before she says a word. */
/* Sized to the millimetre: the top row also carries «التوصيل إلى», whose area name is the
   one thing here that can't be abbreviated. Wider padding pushed it past its ellipsis. */
/* Equal halves, 2026-08-16. «المتجر» is six letters and «Ai» is two, so sizing each to its own
   text made one a wide slab and the other a tight circle — two different objects, not two halves
   of one switch. Grid with equal columns sizes both to the wider text; the padding drops from 9
   to 6 to pay for most of the growth, because the note above still holds: the row also carries
   «التوصيل إلى» and it must not lose its area name to an ellipsis. */
/* A visible frame, 2026-08-17. The track was var(--bg) with no edge, which reads as one unit on
   the store's own grey ground but disappears on مريم's cream surface — «المتجر» floated there
   with no container, so the pair looked like two loose words instead of one switch. */
.mode-seg { display: inline-grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  gap: 2px; padding: 2px; border-radius: 19px; background: var(--bg);
  border: 1px solid var(--line, #e6e9f0); }
/* on her surface the ground is warmer and lighter, so the same hairline needs a touch more ink */
body.mode-maryam .mode-seg { background: rgba(255,255,255,.72); border-color: rgba(16,48,78,.16); }
/* three segments now, so each gets less room — the label still must not wrap or clip */
.ms-b { height: 32px; padding: 0 5px; text-decoration: none; border: none; border-radius: 16px; background: none; color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  font-family: inherit; font-weight: 800; font-size: .78rem; line-height: 1; cursor: pointer; white-space: nowrap; }
.ms-b.on { background: var(--card); color: var(--blue); box-shadow: var(--shadow-sm); }
/* Revised: her half stays quiet while she is off — the note above still holds, a permanently
   gold tab burns the signal before she speaks. But once she IS on, the half is her, so it wears
   her gold and her ring like everything else of hers. Gold appears exactly when مريم appears. */
/* the RING stays --gold (that is the signal, and a ring is not text); the word «مريم» takes the
   readable step, because gold-on-white was 2.40:1 on a tab a customer is meant to tap. */
/* the ring is INSET: an outer ring grows the half by 2px on every side, so her side sat proud of
   «المتجر» and the switch looked lopsided again the moment she was selected. Drawn inside, the
   silhouette of both halves stays identical and the gold still reads. */
.ms-b[data-mode="maryam"].on { color: var(--gold-text); box-shadow: var(--shadow-sm), inset 0 0 0 var(--gold-ring) var(--gold); }

/* ===== order-notification badge on the «الطلبات» bottom tab ===== */
.tab .ti { position: relative; }
.tab-badge { position: absolute; top: -6px; inset-inline-start: 58%; min-width: 16px; height: 16px; padding: 0 4px;
  border-radius: 9px; background: #e8342f; color: #fff; font-size: .68rem; font-weight: 700; line-height: 1;
  display: none; align-items: center; justify-content: center; }
.tab-badge.has { display: inline-flex; }

/* ===== collapsing header search on scroll ===== */
.topbar { transition: gap .25s ease; }
.header-search { transition: height .25s ease, opacity .2s ease, margin .25s ease, border-width .2s ease; overflow: hidden; }
@media (max-width: 899px) {
  .topbar.collapsed { gap: 0; }
  .topbar.collapsed .header-search { height: 0; opacity: 0; margin: 0; border-width: 0; pointer-events: none; }
}
.order-cards { display: flex; flex-direction: column; gap: 14px; }
.order-card { background: var(--card); border: 1px solid var(--line); border-radius: 16px; overflow: hidden; }
.oc-head { display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-bottom: 1px solid var(--line); }
.oc-status { background: #eef2f7; color: #64748b; font-weight: 700; font-size: .82rem; padding: 4px 10px; border-radius: 999px; }
.oc-status.active { background: var(--blue-soft); color: var(--blue); }
.oc-status.done { background: #e9f7ec; color: #1c8b3b; }
.oc-status.cancel { background: #fdecec; color: #dc2626; }
/* The five real stages, each its own colour so the state reads before the words do — amber is
   «nobody has touched it yet», navy «we are packing», violet «it is moving», green «it arrived».
   Same hues the rest of the store already uses; only «wait» and «ship» are new. */
.oc-status.wait { background: #FFF3E0; color: #B26A00; }
.oc-status.prep { background: var(--blue-soft); color: var(--blue); }
.oc-status.ship { background: #EDE9FE; color: #5B21B6; }
/* orders-page status filter row */
.order-filter { padding: 4px 14px 2px; gap: 8px; overflow-x: auto; }
.oc-date { color: var(--muted); font-size: .9rem; }
.oc-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 14px; }
.oc-code { display: flex; flex-direction: column; gap: 2px; }
.oc-code b { font-size: .82rem; color: var(--muted); font-weight: 600; }
.oc-code span { font-weight: 800; font-size: 1.02rem; }
.oc-toggle { display: inline-flex; align-items: center; gap: 5px; background: none; border: none; cursor: pointer;
  color: var(--text); font-family: inherit; font-weight: 700; font-size: .95rem; }
.oc-toggle .oc-chev { transition: transform .2s; color: var(--muted); }
.oc-toggle.open .oc-chev { transform: rotate(180deg); }
.oc-items { display: flex; flex-direction: column; gap: 10px; padding: 0 14px 12px; }
.oc-item { display: flex; align-items: center; gap: 10px; }
.oc-item img, .oc-item .oc-noimg { width: 46px; height: 46px; border-radius: 10px; object-fit: contain; background: var(--bg); flex: none;
  display: flex; align-items: center; justify-content: center; color: var(--muted); }
.oc-iname { font-size: .95rem; }
.oc-pay { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px; border-top: 1px solid var(--line); }
.oc-total { font-weight: 800; font-size: 1.08rem; }
.oc-total span { font-weight: 600; font-size: .85rem; color: var(--muted); }
.oc-rate { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 12px 14px; border-top: 1px solid var(--line); }
.oc-rate > span { color: var(--muted); font-size: .95rem; }
.oc-stars { display: inline-flex; gap: 3px; }
.oc-star { background: none; border: none; padding: 0; cursor: pointer; color: #d6d9df; line-height: 0; }
.oc-star svg { width: 24px; height: 24px; }
.oc-star.on { color: #f6b100; }
.oc-star.on svg { fill: #f6b100; }
.orders-end { text-align: center; color: var(--muted); font-size: .92rem; margin: 20px 8px; }

/* ===== clean account menu (row list) ===== */
.acc-menu { display: flex; flex-direction: column; margin-top: 8px; }
.acc-row { display: flex; align-items: center; gap: 14px; width: 100%; padding: 17px 4px; background: none;
  border: none; border-bottom: 1px solid var(--line); cursor: pointer; text-align: start; font-family: inherit; color: var(--text); }
.acc-row.static { cursor: default; }
.acc-row .ar-ic { color: var(--text); flex: none; display: inline-flex; }
.acc-row .ar-ic svg { width: 23px; height: 23px; }
.acc-row .ar-label { flex: 1; font-size: 1.05rem; font-weight: 600; }
.acc-row .ar-val { color: var(--muted); font-size: .92rem; }
.acc-row .ar-chev { color: var(--muted); flex: none; }
.acc-row:not(.static):active { background: var(--bg); }

/* ===== inline order tracking (chevron expander, matches the items arrow) ===== */
.oc-track-btn { color: var(--blue); }
.oc-track { padding: 8px 14px 14px; }
.oc-track:not([hidden]) { border-top: 1px solid var(--line); }

/* ===== real category artwork on the home grid tiles ===== */
.navhome { overflow: visible; gap: 16px 10px; }
/* glassmorphism category card: frosted glass, soft shadow, glossy top sheen */
.navhome-cat.has-art { position: relative; overflow: hidden; gap: 8px;
  background: var(--glass); border: 1px solid var(--glass-brd); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 14px 8px 12px;
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  transition: transform .22s ease, box-shadow .22s ease; }
.navhome-cat.has-art::before { content: ''; position: absolute; inset: 0 0 auto; height: 46%; pointer-events: none;
  border-radius: var(--radius) var(--radius) 0 0;
  background: linear-gradient(180deg, rgba(255,255,255,.55), rgba(255,255,255,0)); }
.navhome-cat.has-art .nhc-e { position: relative; z-index: 1; height: auto; width: 100%; }
.nhc-img { display: block; width: 100%; height: 88px; object-fit: contain; margin: 0 auto; transition: transform .22s ease; }
.navhome-cat.has-art .nhc-n { position: relative; z-index: 1; display: block; font-size: 12.5px; font-weight: 800; color: var(--text); }
/* hover: lift + blue glow + icon zoom (mobile gets the :active press) */
.navhome-cat.has-art:hover { transform: translateY(-4px);
  box-shadow: var(--shadow), 0 0 0 1px rgba(16,48,78,.28), 0 12px 28px rgba(16,48,78,.24); }
.navhome-cat.has-art:hover .nhc-img { transform: scale(1.09); }
.navhome-cat.has-art:active { transform: scale(.97); }
/* category chips (browse strip): big artwork, no box behind it */
.navcats .chip .cc-ic { width: auto; height: auto; background: none; border-radius: 0; }
.navcats .chip.on .cc-ic { background: none; }

/* ===== «الكاتلوكات» tab (2026-08 redesign) =====
   The old screen was three identical white 3×2 grids under three banners: every tile the
   same size, the same empty white box, nothing to look at first. Everything below is scoped
   to .cat-screen so the welcome landing's copy of .navhome is untouched.
   Layout maths (3 cols): lead tile = 2×2 cells, so a 6-tile group fills 3 rows exactly and a
   7-tile group closes on a full-width tile — no ragged half-rows either way. */
.cat-screen { padding: 6px 0 calc(var(--tab-h) + 22px); }
.cat-group { margin: 16px 12px 0; border-radius: var(--radius); overflow: hidden;
  background: linear-gradient(180deg, color-mix(in srgb, var(--blue-soft) 75%, #fff), #fff 62%);
  border: 1px solid var(--glass-brd); box-shadow: var(--shadow); }

/* banner becomes the card's header strip: shorter, titled, with a count pill */
.cat-screen .sec-banner { margin: 0; aspect-ratio: 16/6; border-radius: 0; box-shadow: none;
  align-items: flex-end; justify-content: space-between; padding-inline-end: 14px; }
.cat-screen .sec-banner-t { font-size: 1.1rem; padding: 12px 16px; }
.cat-count { position: relative; z-index: 1; margin-bottom: 14px; flex: none;
  font-size: 11.5px; font-weight: 700; color: #fff; padding: 4px 11px; border-radius: 999px;
  background: rgba(255,255,255,.18); border: 1px solid rgba(255,255,255,.34);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }

.cat-screen .navhome { padding: 14px 12px 16px; gap: 11px 10px; }
.cat-screen .navhome-cat.has-art { justify-content: center; padding: 10px 8px; gap: 6px;
  background: linear-gradient(168deg, #fff 42%, color-mix(in srgb, var(--blue-l) 26%, #fff) 100%);
  border-color: #fff; border-radius: 18px; box-shadow: var(--shadow-sm);
  -webkit-backdrop-filter: none; backdrop-filter: none; }
/* the flat white sheen becomes a brand halo sitting *behind* the cut-out, so the artwork
   lands on colour instead of floating in an empty white box */
.cat-screen .navhome-cat.has-art::before { inset: 8px 10px auto; height: 72px; border-radius: 50%;
  background: radial-gradient(58% 58% at 50% 52%, color-mix(in srgb, var(--accent) 45%, transparent), transparent 72%);
  filter: blur(7px); }
.cat-screen .nhc-img { height: 78px; }
.cat-screen .navhome-cat.has-art .nhc-n { display: flex; align-items: center; justify-content: center;
  min-height: 2.5em; font-size: 12px; }

/* lead tile: wide, deep-brand, the thing the eye lands on first in each department */
.cat-screen .navhome-cat.has-art:first-child { grid-column: span 2; grid-row: span 2;
  flex-direction: column; justify-content: space-between; align-items: stretch;
  gap: 8px; padding: 16px 18px 15px; text-align: start; border-color: transparent;
  background: linear-gradient(150deg, var(--blue-d) 0%, var(--blue) 55%, var(--blue-l) 100%);
  box-shadow: 0 10px 24px rgba(21,101,216,.30); }
.cat-screen .navhome-cat.has-art:first-child::before { inset: 0; height: 100%; border-radius: 18px;
  background: radial-gradient(52% 42% at 50% 42%, rgba(255,255,255,.30), transparent 72%); filter: blur(2px); }
.cat-screen .navhome-cat.has-art:first-child .nhc-e { flex: 1 1 auto; min-height: 0; display: grid; place-items: center; }
.cat-screen .navhome-cat.has-art:first-child .nhc-img { height: 100%; max-height: 175px; }
.cat-screen .navhome-cat.has-art:first-child .nhc-n { display: block; min-height: 0; flex: none;
  color: #fff; font-size: 18px; text-align: start; text-shadow: 0 1px 8px rgba(3,12,45,.35); }
.cat-screen .navhome-cat.has-art:first-child .nhc-n::after { content: 'تصفّح القسم ←';
  display: block; margin-top: 5px; font-size: 11.5px; font-weight: 600; opacity: .88; }
/* a 7th tile closes the row as a full-width strip (see layout maths above) */
.cat-screen .navhome-cat.has-art:nth-child(7):last-child { grid-column: span 3;
  flex-direction: row-reverse; align-items: center; gap: 12px; padding: 8px 16px; text-align: start; }
.cat-screen .navhome-cat.has-art:nth-child(7):last-child .nhc-e { flex: 0 0 34%; }
.cat-screen .navhome-cat.has-art:nth-child(7):last-child .nhc-img { height: 74px; }
.cat-screen .navhome-cat.has-art:nth-child(7):last-child .nhc-n { display: block; flex: 1; min-height: 0;
  font-size: 14px; }
.cat-screen .navhome-cat.has-art:nth-child(7):last-child .nhc-n::after { content: 'تصفّح القسم ←';
  display: block; margin-top: 4px; font-size: 11.5px; font-weight: 600; color: var(--blue-d); opacity: .8; }
.cat-screen .navhome-cat.has-art:nth-child(7):last-child::before { inset: 8px auto 8px 10px; width: 34%; height: auto; }

/* arrival: each department lifts in, tiles a beat behind their banner */
@keyframes catRise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
.cat-screen .cat-group { animation: catRise .44s cubic-bezier(.2,.8,.3,1) both; }
.cat-screen .cat-group:nth-child(2) { animation-delay: .07s; }
.cat-screen .cat-group:nth-child(3) { animation-delay: .14s; }
.cat-screen .navhome-cat { animation: catRise .38s cubic-bezier(.2,.8,.3,1) both; animation-delay: .10s; }
.cat-screen .navhome-cat:nth-child(2) { animation-delay: .15s; }
.cat-screen .navhome-cat:nth-child(3) { animation-delay: .20s; }
.cat-screen .navhome-cat:nth-child(4) { animation-delay: .25s; }
.cat-screen .navhome-cat:nth-child(5) { animation-delay: .30s; }
.cat-screen .navhome-cat:nth-child(6) { animation-delay: .35s; }
.cat-screen .navhome-cat:nth-child(7) { animation-delay: .40s; }
@media (prefers-reduced-motion: reduce) {
  .cat-screen .cat-group, .cat-screen .navhome-cat { animation: none; }
  .cat-screen .navhome-cat, .cat-screen .nhc-img { transition: none; }
}
/* narrow phones: 2 columns, so the lead tile drops its span and the 7th goes full width */
@media (max-width: 360px) {
  .cat-group { margin-inline: 8px; }
  .cat-screen .navhome { padding: 12px 10px 14px; }
  .cat-screen .navhome-cat.has-art:first-child { grid-column: auto; grid-row: auto;
    flex-direction: column; text-align: center; padding: 10px 8px; }
  .cat-screen .navhome-cat.has-art:first-child .nhc-e { flex: none; width: 100%; }
  .cat-screen .navhome-cat.has-art:first-child .nhc-img { height: 78px; }
  .cat-screen .navhome-cat.has-art:first-child .nhc-n { text-align: center; font-size: 12.5px; }
  .cat-screen .navhome-cat.has-art:first-child .nhc-n::after { font-size: 10.5px; }
  .cat-screen .navhome-cat.has-art:nth-child(7):last-child { grid-column: span 2; }
}

.topbar .ms-b:active { transform: scale(.94); }

/* ===== Google Maps location picker ===== */
.map-box { height: 300px; min-height: 300px; }
.map-box > div { width: 100%; height: 100%; }
.map-search { width: 100%; height: 44px; padding: 0 14px; margin-bottom: 8px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--card); color: var(--text); font-family: inherit; font-size: .95rem; outline: none; }
.map-search:focus { border-color: var(--blue); }
.map-hint { color: var(--muted); font-size: .85rem; margin: 8px 2px 0; }

/* ===== full-screen map picker (عنوان التوصيل) ===== */
.map-picker { position: fixed; inset: 0; z-index: 70; background: var(--card); display: flex; flex-direction: column; }
.mp-head { display: flex; align-items: center; gap: 12px; padding: 12px 16px; border-bottom: 1px solid var(--line); }
.mp-head .mp-title { flex: 1; text-align: center; font-size: 1.15rem; font-weight: 800; margin: 0; }
.mp-x { width: 38px; height: 38px; border-radius: 50%; border: 1px solid var(--line); background: var(--card);
  color: var(--text); font-size: 1.05rem; cursor: pointer; flex: none; }
.mp-search { margin: 10px 16px 0; height: 46px; padding: 0 14px; border: 1px solid var(--line); border-radius: 13px;
  background: var(--bg); font-family: inherit; font-size: .95rem; outline: none; }
.mp-search:focus { border-color: var(--blue); background: var(--card); }
.mp-mapwrap { position: relative; flex: 1; margin: 10px 0 0; }
.mp-map { position: absolute; inset: 0; }
.mp-map > div { width: 100%; height: 100%; }
/* centre pin: fixed over the map middle, the map pans under it */
.mp-pin { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -100%); pointer-events: none;
  display: flex; flex-direction: column; align-items: center; z-index: 2; }
.mp-pin svg { width: 44px; height: 44px; color: #e8342f; filter: drop-shadow(0 6px 8px rgba(0,0,0,.3)); }
.mp-tip { background: #1f2430; color: #fff; font-size: .82rem; font-weight: 700; padding: 7px 12px; border-radius: 12px;
  white-space: nowrap; margin-bottom: 8px; box-shadow: 0 4px 12px rgba(0,0,0,.25); }
.mp-locate { position: absolute; inset-inline-start: 14px; bottom: 16px; width: 46px; height: 46px; border-radius: 50%;
  background: var(--card); border: 1px solid var(--line); color: var(--blue); box-shadow: 0 3px 12px rgba(0,0,0,.18);
  display: grid; place-items: center; cursor: pointer; z-index: 2; }
.mp-foot { padding: 14px 16px calc(16px + env(safe-area-inset-bottom)); border-top: 1px solid var(--line); }
.mp-addr { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.mp-addr-ic svg { width: 20px; height: 20px; color: var(--text); }
.mp-addr b { font-size: 1rem; font-weight: 700; }
.mp-foot .btn-primary { width: 100%; }

/* ===== new-address details form (Talabat-style) ===== */
.addr-form2 { padding: 4px 2px 24px; }
.af-map { height: 150px; border-radius: 16px; overflow: hidden; background: var(--bg); margin-bottom: 14px; }
.af-map > div { width: 100%; height: 100%; }
.af-area { display: flex; align-items: center; justify-content: space-between; gap: 10px; border: 1px solid var(--line);
  border-radius: 14px; padding: 12px 14px; margin-bottom: 16px; }
.af-area-body { display: flex; align-items: center; gap: 10px; }
.af-area-ic svg { width: 22px; height: 22px; color: var(--text); }
.af-area-body b { display: block; font-size: 1.02rem; }
.af-area-body span { color: var(--muted); font-size: .9rem; }
.af-edit { background: none; border: none; color: var(--blue); font-family: inherit; font-weight: 800; font-size: .98rem; cursor: pointer; }
.af-types { display: flex; gap: 10px; justify-content: center; margin-bottom: 16px; }
.af-type { flex: 0 0 auto; padding: 9px 20px; border-radius: 22px; border: 1.5px solid var(--line); background: var(--card);
  color: var(--text); font-family: inherit; font-weight: 700; font-size: .95rem; cursor: pointer; }
.af-type.on { background: #1f2430; color: #fff; border-color: #1f2430; }
.af-in { width: 100%; height: 54px; padding: 0 16px; margin-bottom: 12px; border: 1px solid var(--line);
  border-radius: 14px; background: var(--card); color: var(--text); font-family: inherit; font-size: 1rem; outline: none; }
.af-in:focus { border-color: var(--blue); }
.af-row2 { display: flex; gap: 12px; }
.af-row2 .af-in { flex: 1; }
.af-phone { display: flex; align-items: center; gap: 8px; direction: rtl; }
.af-phone .af-flag { display: inline-flex; align-items: center; gap: 4px; height: 54px; padding: 0 12px; margin-bottom: 12px;
  border: 1px solid var(--line); border-radius: 14px; font-size: 1rem; white-space: nowrap; }
.af-phone .af-in { flex: 1; }
.af-hint { color: var(--muted); font-size: .85rem; margin: 2px 2px 16px; text-align: center; }
.af-save { width: 100%; }

/* ============ Phase 3 — glossy / glass identity across components ============ */
/* unified button identity: solid blue pill, matching the active filter chips */
.btn-primary { background: var(--blue); color: #fff; border: none; border-radius: 999px;
  box-shadow: 0 6px 16px rgba(16,48,78,.35);
  transition: transform .2s ease, box-shadow .2s ease; }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 9px 22px rgba(16,48,78,.42); }
.btn-primary:active { transform: scale(.97); }

/* frosted glass search bar in the header */
.header-search { background: var(--glass); border: 1px solid var(--glass-brd); border-radius: var(--radius-sm);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); box-shadow: var(--shadow-sm); }

/* content + product cards: soft diffused shadow, rounded, subtle glass edge */
.card, .panel { box-shadow: var(--shadow); border: 1px solid var(--glass-brd); }
.card { border-radius: var(--radius); transition: transform .2s ease, box-shadow .2s ease; }
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow), 0 12px 26px rgba(16,48,78,.16); }

/* frosted bottom tab bar */
.tabbar { background: var(--glass); border-top: 1px solid var(--glass-brd);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px); }

/* glass icon buttons in the header */
.topbar .icon-btn { background: var(--glass); border: 1px solid var(--glass-brd); }
.topbar .icon-btn:hover { background: #fff; }

/* order cards + address/settings rows: unify to the soft shadow */
.order-card { box-shadow: var(--shadow); border: 1px solid var(--glass-brd); border-radius: var(--radius); }
/* group banners: full-width themed image with title over a bottom scrim */
.sec-banner { position: relative; overflow: hidden; margin: 22px 0 12px; aspect-ratio: 3/1;
  border-radius: var(--radius); background-size: cover; background-position: center;
  box-shadow: 0 10px 24px rgba(16,21,31,.13); display: flex; align-items: flex-end; }
.sec-banner::before { content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(0deg, rgba(3,12,45,.84) 0%, rgba(3,12,45,.30) 34%, transparent 62%); }
.sec-banner-t { position: relative; z-index: 1; color: #fff; font-weight: 900; font-size: 1.25rem;
  padding: 14px 20px; text-shadow: 0 2px 12px rgba(0,0,0,.45); }

/* product card: the price is the loud element. This block used to repaint .grid-add solid navy
   with a heavy shadow — it sits 800 lines below the card rules and silently undid them, which
   is why the new circle rendered filled. .add-cart (the product PAGE's full-width button) keeps
   the filled treatment; there it is the only action on screen and it should be loud. */
.price { font-weight: 800; font-size: 1.05rem; color: var(--blue-d); }
.add-cart { background: var(--blue); color: #fff; border: none; border-radius: 999px; font-weight: 800;
  box-shadow: 0 6px 16px rgba(16,48,78,.35); transition: transform .2s ease, box-shadow .2s ease; }
.add-cart:hover { transform: translateY(-2px); box-shadow: 0 9px 22px rgba(16,48,78,.42); }
.add-cart:active { transform: scale(.97); }

/* ==================== improve-filters: category strip + facet pills ==================== */
:root { --badge: #eef2f7; }

/* (أ) result count → separated round badge */
/* colour was #64748b on the #eef2f7 pill: 4.23:1, just under AA. --muted is the same grey-blue
   one step deeper (4.83:1) and is already the store's secondary-text token — no third grey. */
.nav-cnt { display: inline-flex; align-items: center; justify-content: center; min-width: 21px; height: 21px;
  padding: 0 7px; margin-inline-start: 6px; border-radius: 999px; background: var(--badge);
  color: var(--muted); font-size: 13px; font-weight: 700; line-height: 1; opacity: 1; }
.chips-sub .chip.on .nav-cnt { background: rgba(255,255,255,.25); color: #fff; }

/* current-category header (top of a browse page) — tap to go back to the home grid */
.cat-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; width: 100%;
  background: none; border: none; padding: 0; cursor: pointer; text-align: start; }
.cat-head .ch-img { width: 60px; height: 60px; object-fit: contain; flex: none; transition: transform .18s ease; }
.cat-head:active .ch-img { transform: scale(.94); }
.cat-head .ch-name { font-size: 1.35rem; font-weight: 800; color: #1e293b; margin: 0; }

/* first-row filter chip icon (emoji or generated cutout image) */
.chip-ic { margin-inline-end: 5px; font-size: 1em; line-height: 1; display: inline-flex; align-items: center; }
.chip-ic img { width: 20px; height: 20px; object-fit: contain; vertical-align: middle; }
/* first filter row = bare cutout icons, uniform fixed box so nothing overflows/overlaps */
.chips-sub .chip.icontile,
.chips-sub .chip.icontile.on { flex-direction: column; align-items: center; justify-content: center; gap: 0;
  padding: 0; min-width: 74px; background: none; border: none; box-shadow: none; border-radius: 0; }
.chips-sub .chip.icontile:hover { transform: translateY(-2px); box-shadow: none; border: none; }
/* bare icon by default; a light tint tile appears ONLY on the selected one */
.chip.icontile .chip-ic { margin: 0; width: 74px; height: 74px; display: grid; place-items: center; font-size: 50px;
  background: transparent; border-radius: 18px; transition: background .15s ease, box-shadow .15s ease, transform .18s ease; }
.chip.icontile .chip-ic img { width: 74px; height: 74px; object-fit: contain; }
.chip.icontile:hover .chip-ic { transform: scale(1.05); }
.chip.icontile.on .chip-ic { background: #dce8ff; box-shadow: inset 0 0 0 1.5px #b9d0ff; }
.leaf-fly { position: fixed; z-index: 1500; font-size: 26px; line-height: 1; pointer-events: none;
  will-change: transform, opacity; filter: drop-shadow(0 2px 4px rgba(22,140,74,.4)); }
.chip.icontile .chip-tx { display: none; }  /* icon-only; the selected name shows in the first-row title tile */
.chip.icontile .nav-cnt { display: none; }
.facet-rows .chips-sub:has(.chip.icontile) { gap: 6px; padding: 6px 2px; margin: 0; }
/* wrap the whole first-row icon strip (icons + label) in ONE unified card/tile */
.facet-group:has(.chip.icontile) { margin-bottom: 10px; background: #fff; border: 1px solid #eef2f7;
  border-radius: 18px; box-shadow: 0 4px 14px rgba(30,41,59,.06); padding: 3px 10px; align-items: stretch; }
.facet-group:has(.chip.icontile) .facet-title { background: none; border: none; box-shadow: none; border-radius: 0;
  border-left: 1px solid #eef2f7; width: 38px; padding-left: 6px; }   /* clipped at 30 — see .facet-title */

/* (ب) facet groups: one vertical white tile per title, spanning the levels it covers */
.facet-group { display: flex; align-items: stretch; gap: 10px; margin-bottom: 1px; }
.facet-title { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  /* vertical-rl: `width` is the LINE BOX, not the label length — 32px minus 6px of padding left
     29px for a 33px glyph run, so every letter of «كاميرات» lost ~4px off its side. */
  writing-mode: vertical-rl; flex: 0 0 auto; align-self: stretch; width: 38px; box-sizing: border-box;
  background: #fff; border: 1px solid #eef2f7; border-radius: 10px; padding: 6px 3px;
  box-shadow: 0 1px 3px rgba(30,41,59,.05); overflow: hidden; position: relative;
  font-size: 15px; font-weight: 800; letter-spacing: .2px; color: #64748b; margin: 0; }
.ft-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); flex: none; margin: 0; }
/* stacked chip rows to the side of a single spanning title */
.facet-rows { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* one tidy row with horizontal scroll — no tall wrapping gaps */
.facet-rows .chips-sub { flex: none; min-width: 0; flex-wrap: nowrap; overflow-x: auto; gap: 7px; padding: 9px 1px; margin: -7px 0; align-items: center; }

/* (ج) unified facet pills — two states only */
.chips-sub .chip { background: #fff; border: 1px solid #e2e8f0; color: #334155; padding: 6px 12px; font-size: 15px;
  border-radius: 999px; box-shadow: 0 1px 3px rgba(30,41,59,.05); transition: all .2s ease; border-bottom-width: 1px; }
.chips-sub .chip:hover { transform: translateY(-2px); border-color: #c7d2e0; box-shadow: 0 6px 14px rgba(30,41,59,.10); }
.chips-sub .chip.on { background: var(--blue); border-color: var(--blue); color: #fff; box-shadow: 0 6px 16px rgba(16,48,78,.35); }
.navcats .chip.navcat { flex-direction: column; align-items: center; gap: 2px; background: #fff; border: 1px solid #eef2f7;
  border-radius: 12px; padding: 5px 8px 4px; box-shadow: 0 3px 9px rgba(30,41,59,.06); transition: all .2s ease; }
.navcats .chip.navcat .cc-ic { width: auto; height: auto; background: none; }
.navcats .chip.navcat .cc-img { width: 96px; height: 96px; object-fit: contain; transition: transform .2s ease; }
.navcats .chip.navcat .cc-t { font-size: 11px; font-weight: 700; color: #64748b; white-space: nowrap; transition: color .2s ease; }
.navcats .chip.navcat:hover { transform: translateY(-3px); box-shadow: 0 10px 22px rgba(16,48,78,.18); }
.navcats .chip.navcat:hover .cc-img { transform: scale(1.05); }
.navcats .chip.navcat:hover .cc-t { color: #1e293b; }
.navcats .chip.navcat.on { border-color: var(--blue); box-shadow: 0 8px 18px rgba(16,48,78,.22); }
.navcats .chip.navcat.on .cc-ic { background: none; }
.navcats .chip.navcat.on .cc-t { color: var(--blue); }

/* announcement strip — server-driven, shares /api/app-config with the native app */
/* It wrapped to two lines on a 360px phone and ate 72px of the screen before the customer saw
   anything — a delivery promise printed as a paragraph. One line, one size smaller, and the
   promise itself shortened at the source (/etc/store/app-config.json). If it ever overflows
   again the ellipsis is the signal to shorten the text, not to let it wrap. */
.ann-bar { display: flex; align-items: center; justify-content: center; gap: 8px;
  padding: 7px 12px; font-size: .78rem; font-weight: 700; color: #fff; text-align: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  background: linear-gradient(100deg, var(--blue-d), var(--blue) 65%, var(--blue-l));
  position: sticky; top: 0; z-index: 60; }
.ann-bar span { overflow: hidden; text-overflow: ellipsis; }
.ann-bar[hidden] { display: none; }
.ann-bar svg { width: 1.1em; height: 1.1em; flex: none; }

/* «اطلب أي منتج» — request form */
.req-lead { color: var(--muted); line-height: 1.7; margin-bottom: 14px; }
.panel textarea { width: 100%; padding: 12px; border: 1.5px solid var(--line); border-radius: 12px;
  background: var(--card); color: inherit; font: inherit; resize: vertical; }
.req-msg { margin-top: 10px; font-size: .9rem; color: var(--muted); min-height: 20px; }
.req-msg.bad { color: #d33; font-weight: 700; }
.req-done { text-align: center; padding: 30px 20px; }
.req-done h2 { margin: 12px 0 6px; }
.req-done p { color: var(--muted); line-height: 1.8; margin-bottom: 18px; }
.req-tick svg { width: 56px; height: 56px; color: var(--blue); }

/* the agent pointing at something — a ring that pulses three times then gets out of the way.
   GOLD, and gold is spent nowhere else: after two days the customer's eye learns that anything
   gold means مريم is talking about THIS, without anyone explaining the rule to him. */
/* PULSE — the one motion she uses to point, shared by the ring on a product and the ring a
   spotlight cuts. They used to be two animations (one of them none at all). */
@keyframes goldPulse {
  0%   { box-shadow: var(--gold-glow), 0 0 0 0 rgba(201,162,74,.6); }
  70%  { box-shadow: var(--gold-glow), 0 0 0 14px rgba(201,162,74,0); }
  100% { box-shadow: var(--gold-glow), 0 0 0 0 rgba(201,162,74,0); }
}
.rt-point { animation: goldPulse var(--t-pulse) ease-out 3; border-radius: var(--gold-r);
  outline: var(--gold-ring) solid var(--gold); box-shadow: var(--gold-glow); }

/* ---- spotlight: dim the screen, cut a hole over one element, explain it ----
   The hole is a giant box-shadow spread on a transparent box — no canvas, no clip-path,
   no library, and it survives scrolling because the box is re-positioned on scroll. */
/* DIM — the cinema move, one duration and one easing with everything else of hers. */
.spot-hole { position: fixed; z-index: 998; border-radius: var(--gold-r); pointer-events: none;
  box-shadow: 0 0 0 9999px rgba(8,25,44,.72); transition: all var(--t-dim) var(--ease); }
/* the same ring she points at a product with — same weight, same radius, same glow, same pulse */
.spot-ring { position: fixed; z-index: 999; border-radius: var(--gold-r); pointer-events: none;
  border: var(--gold-ring) solid var(--gold); box-shadow: var(--gold-glow);
  animation: goldPulse var(--t-pulse) ease-out 3;
  transition: top var(--t-dim) var(--ease), left var(--t-dim) var(--ease),
              width var(--t-dim) var(--ease), height var(--t-dim) var(--ease); }
/* Her words look the same wherever she says them: the float speaks in gold on her navy, so the
   coach mark does too. It used to be a white card with blue bold — a system tooltip, not مريم.
   Horizontal centring lives here, not in spotlight(), so there is one rule for where she sits. */
/* one width as well as one place — a bubble that resizes to its sentence moves the anchor */
.spot-tip { position: fixed; z-index: 1000; width: min(88vw, 360px);
  left: 50%; transform: translateX(-50%);
  background: var(--gold-ink); color: var(--gold-soft); border-radius: var(--gold-r);
  border: 1px solid rgba(201,162,74,.34); padding: 14px 16px;
  box-shadow: 0 18px 48px rgba(8,20,40,.44); font-size: .95rem; line-height: 1.65; font-weight: 700;
  transition: top var(--t-dim) var(--ease); }
.spot-tip b { color: #fff; }
.spot-tip .spot-x { position: absolute; inset-inline-end: 8px; top: 6px; background: none;
  border: 0; color: rgba(255,255,255,.55); font-size: 1.1rem; cursor: pointer; padding: 4px 8px; }
.spot-catch { position: fixed; inset: 0; z-index: 997; }

/* tour button inside the coach-mark bubble — gold, because it is hers and it is standing on
   her navy; a var(--blue) button on that surface was two dark colours fighting */
.spot-next { margin-top: 12px; width: 100%; padding: 10px; font-size: .92rem; pointer-events: auto; }
.spot-tip .spot-next { background: var(--gold); color: var(--gold-ink); box-shadow: none; }
.spot-tip { pointer-events: auto; }

/* ---- the header orb: the voice agent's only entry point ---- */
.orb-btn { width: 40px; height: 40px; padding: 0; border: 0; background: none; border-radius: 50%;
  cursor: pointer; display: grid; place-items: center; flex: 0 0 auto; }
/* The canvas is deliberately wider than its button. The sphere is drawn at half the canvas,
   so a 76px canvas paints a 38px sphere while the tap target stays 40px — and the speak
   rings have room to travel instead of being clipped square against the edge. */
.orb-btn canvas { width: 76px; height: 76px; display: block; margin: -18px; }
.orb-btn:active { transform: scale(.92); }

/* ---- a live call has NO window, NO bar and NO text. The orb is the entire interface ----
   Huthaifa: «ليش تسوي بب اب… خلي الكرة التي بالمنتصف تكبر ٥٠٪ وتتفاعل مع كلامه وفقط بدون
   نص». The store's own chrome folds away, a green frame pulses around what's left, and the
   orb grows and breathes with his voice. Tapping it hangs up. */
#callModal { display: none; }

/* the store's chrome gets out of the way */
.ann-bar, .topbar, .chips { transition: opacity .28s ease, transform .34s ease; }
.tabbar { transition: transform .34s cubic-bezier(.4,0,.2,1), opacity .24s ease; }
body.agent-live .ann-bar,
body.agent-live .topbar,
body.agent-live .chips { opacity: 0; transform: translateY(-16px);
  pointer-events: none; max-height: 0 !important; padding-block: 0 !important;
  margin-block: 0 !important; overflow: hidden; }
body.agent-live .tabbar { transform: translateY(115%); opacity: 0; pointer-events: none; }
/* nothing is pinned to the top any more, so the store just moves up into the freed space */
body.agent-live main { padding-top: 14px; }

/* the pulsing green frame: the visible edge of "Jarvis is driving this screen" */
.agent-frame { position: fixed; inset: 0; z-index: 988;
  pointer-events: none; border: 2.5px solid rgba(34,197,94,.6); border-radius: 22px;
  animation: agentPulse 2.4s ease-in-out infinite; }
@keyframes agentPulse {
  0%, 100% { border-color: rgba(34,197,94,.42); box-shadow: inset 0 0 18px -6px rgba(34,197,94,.35); }
  50%      { border-color: rgba(34,197,94,.98); box-shadow: inset 0 0 34px 0 rgba(34,197,94,.30); }
}
@media (prefers-reduced-motion: reduce) {
  .agent-frame { animation: none; border-color: rgba(34,197,94,.8); }
  .live-orb { transition: none !important; }
  .rt-focus { transform: none; }
}

/* ---- the camera: while Jarvis is on one product, the rest of the page steps back ---- */
#view.rt-camera .card, #view.rt-camera .mini-card { transition: opacity .35s ease, filter .35s ease; }
#view.rt-camera .card:not(.rt-focus),
#view.rt-camera .mini-card:not(.rt-focus) { opacity: .38; filter: saturate(.55); }
.rt-focus { position: relative; z-index: 2; transform: scale(1.035);
  transition: transform .35s cubic-bezier(.2,.9,.25,1.2);
  box-shadow: 0 18px 44px rgba(20,60,140,.24) !important; }

/* ---- adding to the cart, performed: ghost cursor → press → fly → mini-cart ---- */
.rt-cursor { position: fixed; left: 0; top: 0; z-index: 995; width: 26px; height: 26px;
  margin: -13px 0 0 -13px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle at 35% 32%, rgba(255,255,255,.9), rgba(34,197,94,.55) 60%, rgba(34,197,94,.15));
  box-shadow: 0 0 0 2px rgba(34,197,94,.5), 0 6px 18px rgba(20,60,40,.3);
  transition: transform .55s cubic-bezier(.3,.85,.3,1); }
.rt-cursor.tap { animation: rtTap .3s ease-out; }
@keyframes rtTap {
  0%   { box-shadow: 0 0 0 2px rgba(34,197,94,.5); }
  55%  { box-shadow: 0 0 0 14px rgba(34,197,94,0); }
  100% { box-shadow: 0 0 0 2px rgba(34,197,94,.5); }
}
.rt-press { transform: scale(.93); filter: brightness(1.15);
  transition: transform .12s ease, filter .12s ease; }
.rt-fly { position: fixed; z-index: 994; width: 60px; height: 60px; object-fit: contain;
  border-radius: 12px; background: #fff; padding: 4px; pointer-events: none;
  box-shadow: 0 10px 26px rgba(20,40,80,.24);
  transition: left .62s cubic-bezier(.5,-0.2,.7,1), top .62s cubic-bezier(.3,.9,.4,1),
              transform .62s ease-in, opacity .62s ease-in; }
.rt-minicart { position: fixed; z-index: 996; top: calc(env(safe-area-inset-top, 0px) + 14px);
  inset-inline-end: 14px; max-width: min(340px, calc(100vw - 28px));
  display: flex; align-items: center; gap: 10px; padding: 9px 12px 9px 9px;
  background: var(--card, #fff); border-radius: 16px; cursor: pointer;
  box-shadow: 0 14px 38px rgba(15,35,70,.22); border: 1.5px solid rgba(34,197,94,.55);
  animation: mcIn .34s cubic-bezier(.2,.9,.25,1.25) both; }
@keyframes mcIn { from { opacity: 0; transform: translateY(-14px) scale(.94); }
                  to   { opacity: 1; transform: none; } }
.rt-minicart.out { opacity: 0; transform: translateY(-10px); transition: opacity .3s, transform .3s; }
.rt-minicart .mc-img { width: 46px; height: 46px; object-fit: contain; border-radius: 10px;
  background: #fff; flex: 0 0 auto; }
.rt-minicart .mc-mid { min-width: 0; flex: 1; }
.rt-minicart .mc-t { font-size: .84rem; font-weight: 700; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.rt-minicart .mc-s { font-size: .76rem; color: var(--muted); margin-top: 2px; }
.rt-minicart .mc-tot { text-align: center; flex: 0 0 auto; padding-inline-start: 8px;
  border-inline-start: 1px solid rgba(0,0,0,.08); }
.rt-minicart .mc-tot span { display: block; font-size: .64rem; color: var(--muted); }
.rt-minicart .mc-tot b { font-size: .84rem; color: var(--blue); }

/* ---- read-along: the sentence he is saying, lit up inside the product's own description ---- */
.ra-s { transition: background-color .25s ease, color .25s ease; border-radius: 5px;
  padding: 1px 2px; }
.ra-s.on { background: rgba(34,197,94,.22); color: var(--text);
  box-shadow: 0 0 0 3px rgba(34,197,94,.22); }

body.agent-live .orb-btn { opacity: 0; transform: scale(.4); }

/* The orb that follows him around the rest of the store. It only appears once the welcome
   card's orb is gone — otherwise there would be two of the same thing on one screen. */
.live-orb { position: fixed; z-index: 993; inset-inline: 0; margin-inline: auto;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 18px);
  width: 132px; height: 132px; padding: 0; border: 0; background: none; cursor: pointer;
  display: grid; place-items: center; border-radius: 50%;
  animation: orbAdvance .5s cubic-bezier(.2,.9,.25,1.35) both; }
.live-orb canvas { width: 132px; height: 132px; display: block; grid-area: 1/1; }
.live-orb:active { transform: scale(.93); }
/* running cart total, because the header counter is folded away during a call */
.live-cart { grid-area: 1/1; justify-self: end; align-self: start; margin: 26px 24px 0 0;
  min-width: 24px; height: 24px; padding: 0 6px; border-radius: 12px;
  background: #22c55e; color: #fff; font-weight: 800; font-size: .78rem;
  display: grid; place-items: center; pointer-events: none;
  box-shadow: 0 4px 12px rgba(20,80,50,.35); }
.live-cart[hidden] { display: none; }
body:has(#landOrb) .live-orb { display: none; }
@keyframes orbAdvance {
  from { transform: scale(.3) translateY(14px); opacity: 0; }
  to   { transform: scale(1) translateY(0); opacity: 1; }
}

/* ---- replay the tour: a glasses chip on the welcome screen, and the ?tour=1 link ---- */
.tour-btn { display: inline-flex; align-items: center; gap: 8px; margin: 14px auto 0;
  padding: 9px 18px; border-radius: 999px; cursor: pointer;
  background: var(--glass, rgba(255,255,255,.7)); color: var(--blue);
  border: 1.5px solid var(--glass-brd, rgba(20,60,140,.14));
  font-family: inherit; font-size: .9rem; font-weight: 700; }
.tour-btn svg { width: 21px; height: 21px; stroke: currentColor; fill: none; stroke-width: 1.9;
  stroke-linecap: round; stroke-linejoin: round; }
.tour-btn:active { transform: scale(.96); }

/* ============ welcome landing: rhythm, one hierarchy, store above the fold ============
   The landing used to spend a whole screen on brand + headline + orb + four pill badges +
   three stacked CTAs before the first product. Everything here is spacing and grouping:
   the badges become one info bar (they were reading as tappable filter chips), the two
   secondary actions share a row, and the rails get chunked so four identical headings
   stop reading as one long list. Scoped to .welcome so the catalog screen is untouched. */
.welcome { padding-top: 4px; }
.welcome .w-lockup { height: 42px; }
.welcome .w-head { font-size: 1.58rem; line-height: 1.42; margin: 12px 6px 4px; }
.welcome .w-sub { font-size: .95rem; margin: 0 14px; }
.welcome .w-btn { margin-top: 14px; }
.w-alt { display: flex; gap: 10px; margin-top: 10px; }
.w-alt > * { flex: 1 1 0; min-width: 0; margin: 0; justify-content: center; }
.w-alt .tour-btn { padding: 11px 10px; font-size: .88rem; }
.w-alt .btn-link { padding: 11px 10px; border-radius: 999px; font-size: .88rem; font-weight: 700;
  background: var(--glass, rgba(255,255,255,.7)); border: 1.5px solid var(--line); }

/* rails: the category grid uses the full width, and each product rail is its own block */
.welcome .w-rails { margin-top: 6px; }
.welcome .w-rails .sec-title { margin-top: 24px; font-size: 1.18rem; }
.welcome .navhome { padding: 14px 0 0; }
/* the bestsellers rail is filled asynchronously — hide its shell until the heading lands */
.w-rail:not(:has(.sec-title)) { display: none; }
/* The 3D rail is the one that is not like the others, so it gets its own band. The band is
   white, not blue: --blue-soft is a shade off the page background and vanished against it. */
.w-rail.tinted { margin: 22px -16px 0; padding: 2px 16px 14px; background: var(--card);
  box-shadow: inset 0 1px 0 var(--line), inset 0 -1px 0 var(--line); }
.w-rail.tinted .sec-title { margin-top: 16px; }

@media (max-width: 380px) {
  /* the shared .navhome drops to two columns under 360px, which turned six departments into
     three rows of scrolling — the landing's six tiles fit three across at this size */
  .welcome .navhome { grid-template-columns: repeat(3, 1fr); gap: 14px 8px; }
  .welcome .w-head { font-size: 1.34rem; }
  .welcome .w-sub { font-size: .9rem; }
  .w-trust span { font-size: .63rem; }
  .w-alt .tour-btn, .w-alt .btn-link { font-size: .8rem; padding: 11px 6px; }
}
/* ---- the ask bar: مريم in the thumb zone ---- */
/* The bottom of the screen is a STACK, not a pile: tabbar (0) → ask bar → cart bar. Each
   layer is pushed up by the height of the one under it, so the three never overlap. --ask-h
   is written by syncAskBar() from the bar's measured height — the openers row makes the bar
   taller on the home screen, and a guessed constant would put the cart bar through it. */
:root { --ask-h: 0px; }
.ask-bar { position: fixed; inset-inline: 12px; z-index: 14; display: flex; flex-direction: column; gap: 8px;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 8px); }
.ask-bar[hidden] { display: none; }
body.agent-live .ask-bar { display: none; }   /* a live call is the interface; nothing floats over it */
body.has-askbar { padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--ask-h) + 12px); }
/* openers: requests he'd actually make, one scrollable line so they offer مريم without
   pushing the products he came to see off the screen.
   At 360px a long opener used to be sliced off at both edges of the row, so the customer read
   «أريد لابتوب بحدود 1,250,000 دينا…». Three things stop that now: the openers themselves are
   short (see ASK_OPENERS), no chip may be wider than the row (max-width + ellipsis, so a long
   one truncates INSIDE its pill instead of running past it), and the row fades at its end so a
   half-visible chip reads as «there is more, scroll» rather than as a broken layout. */
/* Correction to the note above: the end fade was worse than the problem. Over a grid of white
   product photos a half-faded pill doesn't read as «there is more» — it reads as a chip that
   broke. The row still scrolls; the fade is gone, and the pills carry the card surface instead
   of glass, because a translucent pill sitting on a product photo is unreadable. */
.ask-sugs { display: flex; gap: 7px; overflow-x: auto; scrollbar-width: none; padding-inline: 1px; }
.ask-sugs::-webkit-scrollbar { display: none; }
.ask-sugs:empty { display: none; }
.ask-sug { flex: none; max-width: 100%; overflow: hidden; text-overflow: ellipsis;
  padding: 7px 13px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--card);
  box-shadow: var(--shadow-sm); color: var(--text); font-family: inherit; font-size: .84rem;
  font-weight: 700; white-space: nowrap; cursor: pointer; }
/* while the keyboard is up the openers are noise — the bar and her last two lines are enough */
body.ask-typing .ask-sugs { display: none; }
.ask-row { position: relative; display: flex; align-items: center; gap: 8px; padding: 7px 8px 7px 12px;
  border-radius: 999px; background: var(--card); border: 1px solid var(--line); box-shadow: var(--shadow); }
.ask-plus { flex: none; width: 34px; height: 34px; border: none; border-radius: 50%; background: var(--bg);
  color: var(--muted); font-size: 1.35rem; line-height: 1; font-family: inherit; cursor: pointer; }
/* a real input now, not a button that opened a sheet over the shop (see mountAskBar) */
.ask-field { flex: 1; min-width: 0; background: none; border: none; padding: 0; text-align: start;
  font-family: inherit; font-size: .95rem; color: var(--text); outline: none; }
.ask-field::placeholder { color: var(--muted); }
/* Dictation and a live call are two different things, so they are two different shapes: a
   plain outline glyph that types for him, and مريم's own orb that answers out loud. */
.ask-mic { flex: none; width: 38px; height: 38px; border: 1px solid var(--line); border-radius: 50%;
  background: var(--card); color: var(--text); display: grid; place-items: center; cursor: pointer; }
.ask-mic svg { width: 20px; height: 20px; }
.ask-mic.recording { background: #e5484d; color: #fff; border-color: transparent;
  box-shadow: 0 0 0 0 rgba(229,72,77,.5); animation: pttPulse 1.2s infinite; }
.ask-mic.recording.dragging { animation: none; transition: transform .04s linear; }
/* The orb stays navy — it is the same sphere painted everywhere and that colour was chosen
   deliberately. The gold is the ring around it, which is the part that says «this is مريم». */
.ask-row .orb-btn { box-shadow: 0 0 0 var(--gold-ring) var(--gold), var(--gold-glow); }
.ask-row.ptt-on .ask-field, .ask-row.ptt-on .ask-plus, .ask-row.ptt-on .orb-btn { visibility: hidden; }
/* the swipe-up-to-lock chevron floats above the mic. In the chat row the mic is the first
   child (rightmost in RTL) so inline-start put it there; here the mic is second from the
   end, and an unmoved chevron pointed at empty air on the other side of the bar. */
.ask-row .ptt-lock { inset-inline-start: auto; inset-inline-end: 74px; }
.ask-bar:has(.ptt-on) .ask-sugs { visibility: hidden; }   /* the chevron travels over them */
/* the recording bar, live: the bars move with what the mic is hearing (see pttWave) */
.ptt-wave { flex: 1; min-width: 0; display: flex; align-items: center; gap: 2px; height: 22px; }
.ptt-wave i { flex: 1; height: 22%; border-radius: 2px; background: var(--gold);
  transition: height .07s linear; }

/* ---- sticky cart bar ---- */
/* Sits above the tabbar, not over it: the tabs stay reachable, so the bar adds a route to
   checkout instead of taking one away. z-index is below .tabbar (15) for the same reason. */
.cart-bar { position: fixed; inset-inline: 12px; z-index: 14; display: flex; align-items: center; gap: 10px;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--ask-h) + 16px);
  padding: 11px 14px; border: none; border-radius: 14px; cursor: pointer; font-family: inherit;
  background: var(--blue, #10304E); color: #fff; box-shadow: 0 6px 20px rgba(0,0,0,.28);
  animation: cartBarIn .26s cubic-bezier(.4,0,.2,1); }
@keyframes cartBarIn { from { transform: translateY(16px); opacity: 0; } to { transform: none; opacity: 1; } }
.cart-bar .cb-n { min-width: 24px; height: 24px; border-radius: 50%; background: rgba(255,255,255,.22);
  display: grid; place-items: center; font-weight: 800; font-size: .85rem; }
.cart-bar .cb-t { font-weight: 800; font-size: .98rem; }
/* white, not gold: this is an ordinary checkout button. Gold here would compete with مريم's
   pointing on the same screen and cost the ring its meaning. */
.cart-bar .cb-go { margin-inline-start: auto; font-weight: 800; font-size: .95rem; color: #fff; }
/* the bar overlaps the last row of any list unless the page grows by its height */
body.has-cartbar { padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--ask-h) + 74px); }
body.agent-live .cart-bar { display: none; }
@media (prefers-reduced-motion: reduce) { .cart-bar { animation: none; } }

/* ---- the floating exchange: مريم talks OVER the store, never in front of it ---- */
/* The old behaviour: tap the chat input, a sheet covers the shop, and the customer can no
   longer see the thing she is doing for him. Default state is now the last exchange as text
   on a bottom-up scrim — no panel, no card, no edges — with the sheet one tap away.
   LEGIBILITY: text with no background is unreadable over a white product photo, and a blur
   does not help (white behind white). The scrim is her navy, opaque where the words are and
   gone by the top, plus a dark halo on the glyphs themselves — so it holds over the brightest
   image in the catalogue and still reads as «no background» rather than as a box. */
/* Below the tabbar (15) and the ask bar (14) on purpose: the scrim runs past the bottom of the
   screen so it has no lower edge, and the only thing that may stop it is a real bar with its
   own surface. At z-999 it washed over the ask bar and the tabs and made every control look
   switched off. */
.ai-float { position: fixed; inset-inline: 0; z-index: 13; pointer-events: none;
  padding: 40px 16px 14px; display: flex; flex-direction: column; justify-content: flex-end;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--ask-h) + 6px); }
.ai-float[hidden] { display: none; }
/* checkout hides the ask bar and owns its own bottom of the screen — she goes quiet there too */
body:not(.has-askbar) .ai-float { display: none; }
/* the cart bar occupies exactly this slot when it is out; float above it, never through it */
body.has-cartbar .ai-float { bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + var(--ask-h) + 78px); }
/* Second attempt, from his phone: fading at BOTH ends drew a navy band across the middle of
   the screen with two visible edges, slicing the category tiles in half — a box by another
   name. The screen has a bottom, so the darkness should have one direction: it starts under
   the ask bar and dissolves upward, and it runs PAST the bottom of the viewport so there is
   no lower edge to see at all. Only the top ever fades. */
.ai-float::before { content: ''; position: absolute; inset: -70px 0 -320px; pointer-events: none;
  background: linear-gradient(to top,
    rgba(8,25,44,.96) 0%, rgba(8,25,44,.94) 48%, rgba(8,25,44,.78) 72%,
    rgba(8,25,44,.38) 88%, rgba(8,25,44,0) 100%); }
/* pointer-events live on the WORDS only: the customer keeps tapping the products underneath */
.ai-float .af-body { position: relative; pointer-events: auto; cursor: pointer;
  text-shadow: 0 1px 6px rgba(4,14,24,.9); }
.ai-float .af-you { color: #9DB3C6; font-size: .84rem; font-weight: 700; line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-bottom: 2px; }
/* gold, because this is مريم speaking — the same signal as the ring she points with */
.ai-float .af-her { color: var(--gold-soft); font-size: .97rem; font-weight: 700; line-height: 1.6;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 4; overflow: hidden; }
/* ~3 lines in practice, 5 at the ceiling (his one + four of hers); longer replies are read in
   the sheet, which is one tap on this text away */
.ai-float.waiting .af-her { color: #9DB3C6; }
/* typing: the keyboard already takes half the screen, so she shrinks to a single line */
body.ask-typing .ai-float .af-her { -webkit-line-clamp: 1; }
body.agent-live .ai-float { display: none; }   /* a live call is the interface */
/* the coach mark speaks from this exact slot — she does not talk over herself */
body.spot-on .ai-float { display: none; }

/* ---- the chat sheet's input row: «+ · field · mic · send» ---- */
/* Camera and gallery used to sit here as well, while the «+» sheet already owned both — one
   place for capabilities, not two that drift apart. */
.ai-plus { flex: none; width: 46px; height: 46px; border: 1.5px solid var(--line); border-radius: 50%;
  background: var(--bg); color: var(--muted); font-size: 1.5rem; line-height: 1; font-family: inherit; cursor: pointer; }
/* the greeting screen's openers: the same requests the ask bar offers, as tappable rows in
   the empty room under her one-line hello */
/* `margin-top: auto` parked them on the floor of the flex column: at 360px that left ~320px of
   empty grey between her one-line hello and the only things on screen to tap, and the openers
   fell below the fold on a taller phone. They belong under the sentence they answer. */
.ai-openers { display: flex; flex-direction: column; gap: 8px; padding-top: 10px; }
.ai-opener { text-align: start; padding: 13px 15px; border-radius: 15px; border: 1px solid var(--line);
  background: var(--card); color: var(--text); font-family: inherit; font-size: .95rem; font-weight: 700;
  cursor: pointer; box-shadow: var(--shadow-sm); }
.ai-opener:active { transform: scale(.98); }

/* مريم owns gold everywhere else, so her row in the drawer carries it too — it is the one
   row that is not navigation but a conversation. */
.menu-row-gold { color: var(--gold-text); font-weight: 700; }
.menu-row-gold .m-ic { color: var(--gold-text); }
/* the drawer opener sits before the address; keep it from eating the address label width */
.menu-btn { flex: none; }

/* With the menu button in the row, «التوصيل إلى» squeezed the address down to «حـ…».
   The label is decoration; the area name is the information. Drop it on narrow phones. */
@media (max-width: 400px) { .dt-label { display: none; } }
/* The switch grew to three segments on 2026-08-17 and took the row's spare width with it, so
   «حدّد موقعك» started arriving as «حدّد موق…». The area name is the one thing here that must
   never be cut — it is what tells the customer we know where to deliver — so the switch gives
   the width back instead: tighter track, smaller label, and the location keeps its own line. */
.mode-seg { padding: 2px 1px; }
.ms-b { padding: 0 4px; font-size: .74rem; }
@media (max-width: 400px) {
  .deliver-to { min-width: 0; flex: 1 1 auto; }
  .deliver-to .dt-area { font-size: .92rem; }
  .ms-b { padding: 0 3px; font-size: .7rem; }
}

/* ---- home departments: compact ----
   Six tiles at 88px of artwork each pushed «الأكثر مبيعاً» a full screen down, so the page a
   customer lands on from an ad showed him departments and no prices. Same tiles, two thirds of
   the height: the artwork is what identifies a department, the padding around it was decoration. */
.navhome-tight { padding: 10px 12px 4px; gap: 9px; }
.navhome-tight .navhome-cat { padding: 10px 6px; gap: 4px; border-radius: 14px; }
.navhome-tight .nhc-img { height: 58px; }
.navhome-tight .nhc-n { font-size: 12px; }
.dept-head { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 14px 16px 0; }
.dept-head .sec-title { margin: 0; }
/* «الكل» belongs beside the heading it belongs to, not as a second full-width button under a
   block that already links everywhere */
/* Back to a plain floating link at his call — the chip was solving the wrong problem: it
   looked dead because it WAS dead (data-browse sent him to the screen he was already on), not
   because it lacked a shape. The padding stays for the thumb; it costs nothing visually. */
.dept-all { display: inline-flex; align-items: center; gap: 6px; background: none; border: none;
  font: inherit; font-size: .86rem; font-weight: 700; color: var(--blue); cursor: pointer;
  padding: 8px 6px; white-space: nowrap; }
.dept-all:active { opacity: .55; }
.da-a { font-size: .9em; }

/* The drawer header carried the app icon — a rounded tile lifted off a home screen and pasted
   into a menu. A menu wants a wordmark: the monogram he uses as the icon, set as type, with the
   full name under it so the short form is always tied to what it stands for. */
/* A menu header, not a splash screen. It used to be a centred column — a 2.6rem monogram over
   the name, 38px of padding — which pushed the first row of the menu below the fold and left the
   «×» stranded in its own empty band. One row, panel-start aligned, tall enough that the 44px
   «×» sits across from it in the far corner. (The two `body:has(#annBar…)` offsets that used to
   shove this block 86px down are gone with it: the drawer is z-index 70 and covers the strip.) */
.drawer-brand { display: flex; flex-direction: row; align-items: center; justify-content: flex-start;
  gap: 9px; padding: 0 0 12px; min-height: 44px; text-align: start; }
.dm-ho { font-family: inherit; font-weight: 700; font-size: 1.75rem; line-height: 1; letter-spacing: .06em;
  color: var(--blue); }
.dm-name { font-size: 1.35rem; font-weight: 900; color: var(--blue); line-height: 1.15; } /* ponytail: text wordmark until GeoStore has a logo */

/* ---- conversation history in the drawer ----
   The rows are his own first questions, so the question gets the room and the time sits at the
   end, muted: he scans titles, and the age only tells him which of two similar ones he wants. */
.chat-sec { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.chat-clear { background: none; border: none; font: inherit; font-size: .78rem; font-weight: 700;
  color: var(--muted); cursor: pointer; padding: 2px 4px; }
.chat-clear:active { color: var(--blue); }
.chat-list { display: flex; flex-direction: column; }
.chat-row { display: flex; align-items: baseline; gap: 10px; width: 100%; background: none; border: none;
  font: inherit; text-align: start; padding: 11px 16px; cursor: pointer; color: var(--text); }
.chat-row + .chat-row { border-top: 1px solid var(--line); }
.chat-row:active { background: var(--blue-soft); }
.cr-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: .92rem; font-weight: 700; }
.cr-w { flex: none; font-size: .72rem; color: var(--muted); font-weight: 700; }

/* ---- product page buy row ----
   One decision owns the row and carries its own price; the stepper only exists once there is
   something to step. Like and share stay outlined and quiet — they are not what the page is for. */
.buy-row .add-cart { flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center;
  gap: 8px; height: 52px; padding: 0 14px; border-radius: 16px; font-size: .98rem; }
.buy-row .add-cart .ac-t { font-weight: 800; }
.buy-row .add-cart .ac-p { font-weight: 800; opacity: .92; border-inline-start: 1px solid rgba(255,255,255,.35);
  padding-inline-start: 10px; }
.buy-row .add-cart.in-cart { background: #1e9e4a; box-shadow: 0 6px 16px rgba(30,158,74,.3); }
.buy-row .qty-step[hidden] { display: none; }
.buy-row .round-btn { border: 1.5px solid var(--line); background: var(--card); color: var(--muted);
  box-shadow: none; }
.buy-row .round-btn.on { color: var(--blue); border-color: var(--blue); }

.buy-row .add-cart.in-cart { flex: 0 1 auto; padding: 0 18px; }

/* ---- categories screen, built to scale ----
   A department used to open with a 16:6 banner — beautiful once, exhausting by the third.
   Slim it to a strip that still carries the artwork, and give the screen a sticky rail so
   «الأمان» is one tap away instead of three thumb-scrolls. */
.cat-screen .sec-banner.slim { aspect-ratio: auto; height: 84px; display: flex; align-items: center;
  justify-content: space-between; padding: 0 16px; background-size: cover; background-position: center; }
.cat-screen .sec-banner.slim .sec-banner-t { font-size: 1.05rem; }
.dep-rail { position: sticky; top: 0; z-index: 12; display: flex; gap: 8px; overflow-x: auto;
  scrollbar-width: none; padding: 10px 12px; background: var(--bg); }
.dep-rail::-webkit-scrollbar { display: none; }
.dep-chip { flex: none; padding: 7px 14px; border-radius: 999px; border: 1.5px solid var(--line);
  background: var(--card); color: var(--text); font: inherit; font-size: .84rem; font-weight: 700;
  cursor: pointer; white-space: nowrap; }
.dep-chip.on { background: var(--blue); border-color: var(--blue); color: #fff; }

/* COMPACT TILES — the actual fix for «a department still costs a screen».
   .navhome-tight was already on these grids and did nothing: every one of its declarations is
   a single class, and the block above overrides them with .cat-screen .navhome-cat.has-art
   (0,2,1). Re-stating them at the same specificity is what makes them land — and the lead tile
   loses its 2×2 span here, because one tile the height of three is the other half of the cost.
   Artwork checked at 58px: the cut-outs still read (they are the same 58px the home page ships). */
.cat-screen .navhome.navhome-tight { padding: 10px 12px 12px; gap: 9px; }
/* The shared .navhome drops to two columns under 360px — the exact rule the welcome landing
   already had to override for the same reason. Two columns is what kept these tiles enormous
   on the phone this screen exists for; six departments must fit in two rows, not three. */
@media (max-width: 360px) { .cat-screen .navhome.navhome-tight { grid-template-columns: repeat(3, 1fr); gap: 8px; padding: 10px 10px 12px; } }
.cat-screen .navhome-tight .navhome-cat.has-art { padding: 10px 6px; gap: 4px; border-radius: 14px; }
.cat-screen .navhome-tight .navhome-cat.has-art .nhc-img { height: 58px; }
.cat-screen .navhome-tight .navhome-cat.has-art .nhc-n { font-size: 12px; min-height: 2.4em; }
.cat-screen .navhome-tight .navhome-cat.has-art::before { inset: 6px 8px auto; height: 52px; }
/* the lead tile keeps its deep-brand look but not its size: same cell as its neighbours */
.cat-screen .navhome-tight .navhome-cat.has-art:first-child { grid-column: auto; grid-row: auto;
  padding: 10px 6px; text-align: center; align-items: center; justify-content: center; }
.cat-screen .navhome-tight .navhome-cat.has-art:first-child .nhc-e { flex: none; width: 100%; }
.cat-screen .navhome-tight .navhome-cat.has-art:first-child .nhc-img { height: 58px; max-height: 58px; }
.cat-screen .navhome-tight .navhome-cat.has-art:first-child .nhc-n { font-size: 12px; text-align: center; }
.cat-screen .navhome-tight .navhome-cat.has-art:first-child .nhc-n::after { content: none; }
/* a 7th tile still closes the row full-width, just at the compact height */
.cat-screen .navhome-tight .navhome-cat.has-art:nth-child(7):last-child .nhc-img { height: 52px; }
.cat-screen .navhome-tight .navhome-cat.has-art:nth-child(7):last-child .nhc-n { font-size: 13px; min-height: 0; }

/* ---- مريم's door: the way out of a dead end ----
   Same gold, same ring weight, same radius, same navy she speaks on everywhere else — this is
   her talking, not a «chat with us» button, so it must look like her float and her coach mark
   and nothing like a store control. */
.maryam-door { display: flex; align-items: center; gap: 10px; width: calc(100% - 24px);
  margin: 4px 12px 10px; padding: 11px 14px; text-align: start; cursor: pointer;
  font: inherit; font-size: .88rem; font-weight: 700; line-height: 1.5;
  background: var(--her-surface); color: var(--text);
  border: 1px solid var(--her-edge); border-radius: var(--gold-r);
  box-shadow: 0 8px 22px -12px rgba(8,25,44,.6); }
.maryam-door:active { transform: scale(.99); }
/* her mark. Static on purpose: pulse is the POINT gesture and it belongs to the ring — a dot
   pulsing on every empty screen would spend the signal on nothing being pointed at. */
.maryam-door .md-dot { flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--gold); box-shadow: 0 0 0 3px rgba(201,162,74,.26); }
.maryam-door .md-t { flex: 1; min-width: 0; }
.notice + .maryam-door { margin-inline: auto; max-width: 420px; }

/* account/orders screens: the header stays for navigation, minus the two controls that only
   make sense while shopping */
body.bare-head #deliverTo,
body.bare-head .header-search { display: none; }
body.bare-head .topbar { padding-bottom: 8px; }

/* ==================== audit fixes: touch targets, prices, the delivery control ============ */

/* ---- 40×40 touch, without moving a pixel ----
   Measured: #askPlus 34, .ai-close 34, #askMic 38, .sheet-close 38, .ask-sug 33 tall, a facet
   .chip 35 tall, #open3d 156×35. All of them are drawn small on purpose — a 40px ✕ shouts and a
   40px facet pill breaks the row — so the VISUAL size is left alone and only the hit area grows.
   The pseudo-element is a child of the button, so a tap that lands on it targets the button;
   max() means anything already ≥40 is untouched. */
#askPlus, .ai-close, #askMic, .sheet-close, .ask-sug, .chips-sub .chip, .btn3d { position: relative; }
#askPlus::after, .ai-close::after, #askMic::after, .sheet-close::after,
.ask-sug::after, .chips-sub .chip::after, .btn3d::after {
  content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: max(100%, 40px); height: max(100%, 40px); border-radius: inherit; }
/* Two boxes clip the openers' pad and both have to let it out: the chip clips its own overflow
   for the ellipsis (`clip` keeps the ellipsis and takes a margin, which `hidden` does not), and
   the row is an overflow-x:auto scroller, which the spec turns into a vertical clip too. The
   row gets the 4px it needs and gives it straight back as a negative margin, so the ask bar is
   exactly as tall as it was — this stack is measured into --ask-h. */
.ask-sug { overflow: clip; overflow-clip-margin: 6px; }
.ask-sugs { padding-block: 4px; margin-block: -4px; }

/* ---- seven-digit prices ----
   .price is a flex item next to the round add button, so «1,293,000 د.ع» ran out of room and
   broke after the number, orphaning «د.ع» on a second line — every product over a million
   looked like a rendering fault. nowrap keeps the amount and its currency as one word; the
   currency drops a step so the pair fits the row it has (the product page already does this,
   see .svc-price .cur). */
.price, .ai-c-price, .mini-price, .c-line-total { white-space: nowrap; }
.cur { font-size: .82em; font-weight: 700; margin-inline-start: 3px; }

/* ---- the delivery control at 360 ----
   «التوصيل إلى» is already dropped under 400px, and it still was not enough: once the cart
   badge appears the row's other children take 280 of the 332px available and «حدّد موقعك» is
   ellipsised to «حدّد …» — 40% of the one control that decides a 5,000 vs 10,000 delivery fee.
   The three things it competes with each give back what they can afford to: the mode switch
   loses its side padding, the icon buttons lose 4px, and the caret shrinks. */
@media (max-width: 430px) {
  .top-row { gap: 6px; }
  .ms-b { padding: 0 5px; font-size: .8rem; }
  .top-actions .icon-btn { width: 38px; height: 38px; }
  .deliver-to { gap: 2px; }
  .deliver-to .dt-caret { width: 13px; height: 13px; }
}

/* ---- the one tap out of a rejected order ----
   Every rejection used to be a sentence and a dead end. When the cause is a cart line the
   message now comes with the fix attached, so it has to look like something to press — full
   width under the reason, in the store's blue, at the size the submit button above it is. */
.err:has(.err-fix) { display: flex; flex-direction: column; align-items: stretch; gap: 8px; }
.err-fix { width: 100%; min-height: 44px; padding: 11px 14px; border: 1.5px solid var(--blue);
  border-radius: 14px; background: var(--card); color: var(--blue);
  font-family: inherit; font-size: .95rem; font-weight: 800; cursor: pointer; }
.err-fix:active { transform: scale(.98); }

/* ==================== المنظومة: يكمّل هذا المنتج ====================
   Not «مشابهة» in a second coat of paint: these are the parts that make the thing WORK, so the
   rail reads as one kit — each card wears the role it fills («جهاز التسجيل»، «الهارد») above the
   product, because the role is the reason it is there and the customer is buying a job done, not
   a second camera. Her gold marks the rail the way it marks everything else she chose. */
.sys-title { margin-bottom: 2px; }
.sys-note { color: var(--muted); font-size: .82rem; font-weight: 600; margin: 0 0 10px; }
.sys-rail { display: flex; gap: 10px; overflow-x: auto; scrollbar-width: none;
  padding: 2px 2px 6px; scroll-snap-type: x proximity; }
.sys-rail::-webkit-scrollbar { display: none; }
.sys-card { flex: 0 0 44%; max-width: 190px; scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 6px; padding: 10px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--gold-r);
  box-shadow: var(--shadow-sm); font-family: inherit; text-align: start; cursor: pointer; }
.sys-card:active { transform: scale(.985); }
/* the role is the headline — it is what he is missing, the product is only how we fill it */
.sys-role { align-self: flex-start; background: var(--gold-ink); color: var(--gold-soft);
  font-size: .72rem; font-weight: 800; padding: 3px 9px; border-radius: 999px; }
.sys-img { width: 100%; aspect-ratio: 1; object-fit: contain; background: #fff; border-radius: 11px; }
.sys-img.noimg { display: block; background: var(--line); }
.sys-name { color: var(--text); font-size: .84rem; font-weight: 700; line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sys-price { font-size: .92rem; font-weight: 800; }

/* the narrowing chips are HER question, not the store's shortcuts — so they carry her gold
   edge, and sit in the same strip the openers use (one row, one behaviour, one measurement) */
.ask-sug.narrow { border-color: var(--her-edge); background: var(--her-surface); color: var(--text); }

/* ==================== عرض مريم: المسرح ====================
   The store's other show. The grid answers «شنو عندكم» by putting sixteen things in front of a
   scanning thumb; this answers «وريني» by putting ONE thing in front of a watching eye — big
   enough to judge, with the price where the decision is made and the next move under the thumb.
   Her navy frames the scene the way it frames everything she is responsible for. */
.stage { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 6px 2px 4px;
  animation: dpUp .22s ease; }
.st-count { align-self: flex-start; background: var(--gold-ink); color: var(--gold-soft);
  font-weight: 800; font-size: .8rem; padding: 4px 11px; border-radius: 999px;
  font-variant-numeric: tabular-nums; }
.st-count b { color: #fff; }
.st-card { width: 100%; display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 18px 14px 20px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--gold-r); box-shadow: var(--shadow-sm); cursor: pointer; text-align: center; }
.st-card.in { border-color: var(--gold); box-shadow: 0 0 0 var(--gold-ring) var(--gold), var(--shadow-sm); }
.st-meta { display: flex; align-items: center; gap: 8px; color: var(--muted);
  font-size: .84rem; font-weight: 700; min-height: 1.2em; }
.st-in { color: var(--gold-ink); background: var(--gold); padding: 2px 9px; border-radius: 999px; font-size: .78rem; }
.ex-in { align-self: flex-start; background: var(--gold); color: var(--gold-ink);
  font-weight: 800; font-size: .86rem; padding: 6px 13px; border-radius: 999px; }
.st-card:active { transform: scale(.995); }
/* the whole point of this show: the product is big enough to actually judge */
.st-img { width: 100%; max-width: 300px; aspect-ratio: 1; object-fit: contain;
  background: #fff; border-radius: 14px; }
.st-img.noimg { display: block; background: var(--line); }
.st-name { color: var(--text); font-weight: 800; font-size: 1.02rem; line-height: 1.55;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.st-price { font-size: 1.25rem; font-weight: 900; }
/* the two decisions, both inside thumb reach, with the commit in her gold */
/* where he is in the row — a scene with no map is a corridor */
.st-strip { display: flex; gap: 6px; width: 100%; overflow-x: auto; scrollbar-width: none;
  padding-bottom: 2px; }
.st-strip::-webkit-scrollbar { display: none; }
.st-dot { flex: none; width: 46px; height: 46px; padding: 0; border-radius: 11px;
  border: 1px solid var(--line); background: #fff; overflow: hidden; cursor: pointer; opacity: .55; }
.st-dot img { width: 100%; height: 100%; object-fit: contain; }
.st-dot.on { opacity: 1; border-color: var(--gold); box-shadow: 0 0 0 var(--gold-ring) var(--gold); }

/* ==================== عرض مريم: المشهد الافتتاحي ====================
   Not a smaller home. A different question: the shop asks the customer what he came for instead
   of handing him shelves. Her navy fills the screen because this is HER moment — the only place
   in the store that is hers alone — and the doors under it are real departments with real
   counts, so a tap can never open on nothing. */
.opening { display: flex; flex-direction: column; align-items: center; gap: 10px;
  padding: 18px 4px 8px; text-align: center; }
.op-orb { width: 118px; height: 118px; }
.op-ask { color: var(--text); font-size: 1.45rem; font-weight: 900; line-height: 1.5;
  margin: 2px 0 0; text-wrap: balance; }
.op-sub { color: var(--muted); font-size: .93rem; font-weight: 600; margin: 0 0 6px; }
/* ==================== عرض مريم: شرح المنتج ====================
   The spec sheet answers «شنو هذا». This answers «ليش هذا» — placement inside its own shelf,
   the merchant's own words, and what it needs to work at all. Every line is computed; there is
   no sentence here that the code cannot justify from SHOP. */
.explain { display: flex; flex-direction: column; gap: 14px; padding: 4px 2px 10px; }
.ex-back { align-self: flex-start; background: none; border: none; color: var(--muted);
  font-family: inherit; font-size: .95rem; font-weight: 800; cursor: pointer; padding: 4px 2px; }
.ex-hero { display: flex; flex-direction: column; align-items: center; gap: 8px; text-align: center; }
.ex-img { width: 100%; max-width: 300px; aspect-ratio: 1; object-fit: contain;
  background: #fff; border-radius: 16px; }
.ex-img.noimg { display: block; background: var(--line); }
.ex-name { color: var(--text); font-size: 1.12rem; font-weight: 900; line-height: 1.55; margin: 0;
  text-wrap: balance; }
.ex-price { font-size: 1.35rem; font-weight: 900; }
/* the reasons, as a short list — a paragraph here reads as marketing, a list reads as facts */
.ex-why { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.ex-why li { position: relative; padding-inline-start: 20px; color: var(--text);
  font-size: .95rem; font-weight: 700; line-height: 1.7; }
.ex-why li::before { content: ''; position: absolute; inset-inline-start: 4px; top: .62em;
  width: 7px; height: 7px; border-radius: 50%; background: var(--gold); }
.ex-desc { color: var(--muted); font-size: .92rem; font-weight: 600; line-height: 1.9; margin: 0; }
.ex-sys { display: flex; flex-direction: column; gap: 8px; }
.ex-h2 { font-size: 1rem; font-weight: 900; margin: 4px 0 0; }
.ex-part { display: flex; align-items: center; gap: 10px; padding: 11px 12px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--card);
  font-family: inherit; cursor: pointer; text-align: start; }
.ep-role { flex: none; background: var(--gold-ink); color: var(--gold-soft); font-size: .74rem;
  font-weight: 800; padding: 3px 9px; border-radius: 999px; }
.ep-name { flex: 1; min-width: 0; color: var(--text); font-size: .88rem; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ep-price { flex: none; font-weight: 800; font-size: .88rem; }

/* the parts list stays tappable — opening a product is movement, not an action on it */
.ex-part:active { transform: scale(.985); }

/* ==================== متجر مريم: سطح منفصل ====================
   Not a skin over the shop — its own root, shown while the shop's root is hidden. So the
   chrome that belongs to HIS store (chips, tabs, the search button, the cart bar) is not
   restyled here, it is simply absent: there is nothing of his on screen to restyle. */
#agentView { padding: 0 14px calc(var(--ask-h) + 26px); }
/* «الهيدر والفوتر وكلشي إله علاقة بالمتجر البشري شيله — هذا متجر ذكاء صناعي، أي معلومة
   ياخذها من الزبون بالصوت أو النص.»  So the shop's furniture is not restyled here, it is
   GONE: no tab bar, no chips, no cart bar, no delivery-address picker, no bell, no cart
   icon, no search button. Those are how a human store asks for things by form; she asks by
   talking. Exactly two things survive on screen, and each is a door, not a control:
     · the switch back to his store — leaving must never require knowing a gesture
     · her own input bar — the one place the store still takes anything from him
   The announcement strip goes too: it is the shop shouting, and she does the talking here. */
body.mode-maryam #chips,
body.mode-maryam .tabbar,
body.mode-maryam .cart-bar,
body.mode-maryam .ann-bar,
body.mode-maryam .header-search,
body.mode-maryam .deliver-to,
body.mode-maryam .menu-btn,
body.mode-maryam #bellBtn { display: none; }
/* The cart chip STAYS in her mode (2026-08-25): the header shows state, the stage shows
   content, and «كم عندي بالسلة» is state. Tapping it swaps the board to the cart scene —
   it never throws him out of her. */
/* what is left of the header is the door back, centred and quiet */
body.mode-maryam .topbar { box-shadow: none; background: transparent; border: none; }
body.mode-maryam .top-row { justify-content: center; padding-bottom: 2px; }
body.mode-maryam .top-actions { flex: 0 1 auto; }

/* ==================== متجرها: السلة والفاتورة ====================
   Neither is a form. The basket is what a man at a counter would be TOLD he is taking; the bill
   is the receipt of a conversation — what she already knows about him, and what she is still
   missing. Nothing on either is editable by hand, because in this store you change things by
   saying so. */
.ag-h { font-size: 1.15rem; font-weight: 900; margin: 6px 0 12px; }
.ag-lines { display: flex; flex-direction: column; gap: 8px; }
.ag-line { display: flex; align-items: center; gap: 10px; padding: 10px 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: 13px; }
.ag-l-img { width: 44px; height: 44px; flex: none; object-fit: contain; background: #fff; border-radius: 9px; }
.ag-l-img.noimg { display: block; background: var(--line); }
.ag-l-n { flex: 1; min-width: 0; font-size: .89rem; font-weight: 700; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ag-l-q { flex: none; color: var(--muted); font-weight: 800; font-size: .85rem; font-variant-numeric: tabular-nums; }
.ag-l-p { flex: none; font-weight: 800; font-size: .9rem; font-variant-numeric: tabular-nums; }
/* The bill is the store's card, not her dark block — it is the same money the checkout screen
   shows, and it should look like the same shop said it. */
.ag-sum { margin-top: 14px; padding: 12px 14px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--gold-r); display: flex; flex-direction: column; gap: 7px; }
.ag-s-row { display: flex; justify-content: space-between; color: var(--muted);
  font-size: .9rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.ag-s-row.total { color: var(--blue); font-size: 1.05rem; font-weight: 900;
  border-top: 1px solid var(--line); padding-top: 9px; margin-top: 2px; }
.ag-miss { margin-top: 16px; display: flex; flex-direction: column; gap: 8px; }
.ag-m-h { font-size: .95rem; font-weight: 800; }
/* what she knows about him, gathered by talking — not a form he filled */
.ag-who { margin-top: 14px; display: flex; flex-direction: column; gap: 8px; }
.ag-w-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 10px 12px; background: var(--card); border: 1px solid var(--line); border-radius: 12px; }
.ag-w-row span { color: var(--muted); font-size: .85rem; font-weight: 700; }
.ag-w-row b { font-size: .92rem; font-weight: 800; text-align: end; }
.ag-need { margin-top: 14px; padding: 12px 14px; border-radius: 13px; background: var(--blue-soft);
  color: var(--blue-d); font-size: .92rem; font-weight: 800; line-height: 1.7; }
.ag-ready { margin-top: 14px; padding: 12px 14px; border-radius: 13px; background: var(--gold);
  color: var(--gold-ink); font-size: .95rem; font-weight: 800; }
/* the commit window: the only touch target in her whole store, and it UNDOES */
.ag-commit { position: fixed; inset-inline: 12px; bottom: calc(var(--ask-h) + 18px); z-index: 30;
  display: flex; align-items: center; gap: 10px; padding: 12px 14px; border-radius: 15px;
  background: var(--card); border: 1px solid var(--her-edge);
  box-shadow: 0 18px 40px -16px rgba(8,25,44,.35); animation: dpUp .2s ease; }
.agc-t { flex: 1; color: var(--text); font-weight: 800; font-size: .95rem; }
.agc-t b { color: var(--gold-text); font-variant-numeric: tabular-nums; }
.agc-x { flex: none; min-height: 42px; padding: 0 16px; border: 1px solid rgba(201,162,74,.5);
  border-radius: 11px; background: none; color: var(--gold-soft); font-family: inherit;
  font-weight: 800; font-size: .9rem; cursor: pointer; }
.ag-empty, .ag-done { text-align: center; padding: 18vh 10px; }
.ag-e-t, .ag-d-t { font-size: 1.15rem; font-weight: 900; }
.ag-e-s, .ag-d-s { color: var(--muted); font-size: .93rem; font-weight: 600; margin-top: 6px; line-height: 1.8; }
.ag-d-tick { width: 64px; height: 64px; margin: 0 auto 12px; border-radius: 50%; display: grid;
  place-items: center; background: var(--gold); color: var(--gold-ink); font-size: 2rem; font-weight: 900; }
.ag-d-n { color: var(--muted); font-weight: 800; margin-top: 4px; }

/* ==================== الأوامر: أزرار تُقال ====================
   Shaped like speech, not like controls: full sentences, wrapping, no icons, no chevrons — the
   difference between «أضفه للسلة» as a button and as a thing you say out loud is that the
   second one is allowed to be a sentence. Gold marks the ones that move the sale. */
.ag-cmds { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.ag-cmd { max-width: 100%; padding: 10px 15px; border-radius: 16px; border: 1px solid var(--line);
  background: var(--card); color: var(--blue); font-family: inherit; font-size: .88rem;
  font-weight: 700; line-height: 1.6; cursor: pointer; text-align: start;
  box-shadow: var(--shadow-sm);
  /* a named command runs long («أضف Imou Ranger 2 3MP #2621 للسلة») — one line and it would be
     an ellipsis he cannot read, so it wraps and the pill becomes a rounded rectangle */
  white-space: normal; overflow-wrap: anywhere; }
.ag-cmd:active { transform: scale(.97); }
.ag-cmd.running { opacity: .5; }
.opening .ag-cmds { flex-direction: column; align-items: stretch; width: 100%; margin-top: 18px; }
.opening .ag-cmd { text-align: center; padding: 14px 16px; font-size: .95rem;
  background: var(--blue-soft); border-color: transparent; color: var(--blue-d); }
/* the one command that moves the sale keeps her gold — that is the whole point of the colour */
.ag-cmd.go { background: var(--gold); border-color: var(--gold); color: var(--gold-ink); font-weight: 800; }

/* the float and the ask-bar's own chips are HIS store's furniture: over here they printed on
   top of her commands, and offered the same narrowing twice in two different shapes */
body.mode-maryam #aiFloat,
body.mode-maryam .ask-sugs { display: none !important; }
/* her sentence, inside the scene it is about */
.ag-say { margin: 0 0 12px; padding: 12px 14px; border-radius: 15px; background: var(--her-surface);
  border: 1px solid var(--her-edge); color: var(--text); font-size: .93rem; font-weight: 700; line-height: 1.85; }

/* ==================== متجرها: خيط المحادثة ====================
   One conversation growing downward. His turn is a small bubble; hers is not a bubble at all —
   it is merchandise, because her answer IS the goods. Cards are wide, images are big enough to
   judge, and every card carries the sentences he can say about it. */
.ag-thread { display: flex; flex-direction: column; gap: 18px; padding: 8px 0 10px; }
.ag-me { align-self: flex-end; max-width: 82%; padding: 11px 15px; border-radius: 17px 17px 4px 17px;
  background: var(--gold); color: var(--gold-ink); font-size: .94rem; font-weight: 700; line-height: 1.7; }
.ag-her { display: flex; flex-direction: column; gap: 10px; }
.ag-card { display: flex; flex-direction: column; gap: 9px; padding: 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--gold-r);
  box-shadow: var(--shadow-sm); }
.ag-card.in { border-color: var(--gold); }
.agc-face { display: flex; align-items: center; gap: 12px; width: 100%; padding: 0; border: none;
  background: none; font-family: inherit; text-align: start; cursor: pointer; }
.agc-img { width: 96px; height: 96px; flex: none; object-fit: contain; background: #fff; border-radius: 12px; }
.agc-img.noimg { display: block; background: var(--line); }
.agc-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.agc-name { color: var(--text); font-size: .95rem; font-weight: 800; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.agc-price { font-size: 1.06rem; font-weight: 900; }
.agc-in { align-self: flex-start; background: var(--gold); color: var(--gold-ink);
  font-size: .74rem; font-weight: 800; padding: 2px 9px; border-radius: 999px; }
.ag-card .ag-cmds { margin-top: 0; }
.ag-card .ag-cmd { padding: 8px 13px; font-size: .84rem; }
.ag-explain { display: flex; flex-direction: column; gap: 11px; padding: 14px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--gold-r); }
.ag-explain .ex-img { width: 100%; max-width: 260px; align-self: center; aspect-ratio: 1;
  object-fit: contain; background: #fff; border-radius: 14px; }
.ag-explain .ex-name { font-size: 1.05rem; font-weight: 900; margin: 0; line-height: 1.55; }
.ag-more { color: var(--muted); font-size: .87rem; font-weight: 700; text-align: center; padding: 4px; }

/* ==================== عرض السعر · المقارنة · العرض · المعرض ==================== */
/* an offer has to read at a glance or it is not an offer */
.ag-card.deal, .ag-explain.deal { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold), var(--shadow-sm); }
.ag-deal { align-self: flex-start; background: var(--gold); color: var(--gold-ink);
  font-size: .76rem; font-weight: 900; padding: 3px 10px; border-radius: 999px; }
/* the quotation: a document he can decide with, so it reads like one */
.ag-quote, .ag-cmp { background: var(--card); border: 1px solid var(--line);
  border-radius: var(--gold-r); padding: 12px; overflow-x: auto; }
.agq-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.agq-t { font-weight: 900; font-size: 1rem; }
.agq-d { color: var(--muted); font-size: .82rem; font-weight: 700; }
.agq-tbl { width: 100%; border-collapse: collapse; font-size: .86rem; }
.agq-tbl th, .agq-tbl td { padding: 8px 6px; text-align: start; border-bottom: 1px solid var(--line);
  font-variant-numeric: tabular-nums; }
.agq-tbl thead th { color: var(--muted); font-weight: 800; font-size: .8rem; }
.agq-n { font-weight: 700; line-height: 1.5; }
.agq-tbl tbody tr { cursor: pointer; }
.agq-tbl tfoot td { font-weight: 800; border-bottom: none; padding-top: 10px; }
.agq-total td { color: var(--text); font-size: 1rem; font-weight: 900; border-top: 2px solid var(--line); }
.agq-best { color: var(--gold-ink); background: var(--gold); padding: 1px 7px; border-radius: 999px; font-size: .72rem; }
.agc-tbl th { text-align: center; }
.agcmp-img { width: 54px; height: 54px; object-fit: contain; background: #fff; border-radius: 9px; display: block; margin: 0 auto 4px; }
.agcmp-n { display: block; font-size: .76rem; font-weight: 700; line-height: 1.4; text-align: center; }
.agc-tbl td { text-align: center; }
/* the gallery inside the product block: swipe the photos, stay in the conversation */
.ag-gal { align-self: center; width: 100%; max-width: 300px; }
.agg-track { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none;
  border-radius: 14px; background: #fff; }
.agg-track::-webkit-scrollbar { display: none; }
.agg-img { flex: 0 0 100%; width: 100%; aspect-ratio: 1; object-fit: contain; scroll-snap-align: center; }
.agg-dots { display: flex; justify-content: center; gap: 5px; margin-top: 7px; }
.agg-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--line); }
.agg-dot.on { background: var(--gold); }

/* ==================== نافذة المنتج ====================
   Looking at a product is not something you SAY, so it does not become a message. It opens over
   the conversation and closes back onto the exact line he was reading — which is also what stops
   a thread from filling with four near-identical blocks a curious customer made himself. */
.ag-sheet-wrap { position: fixed; inset: 0; z-index: 40; display: flex; align-items: flex-end;
  background: rgba(8,25,44,.5); opacity: 0; transition: opacity .2s ease; }
.ag-sheet-wrap.show { opacity: 1; }
.ag-sheet { width: 100%; max-height: 92vh; overflow-y: auto; background: var(--bg);
  border-radius: 22px 22px 0 0; padding: 14px 14px calc(18px + env(safe-area-inset-bottom));
  transform: translateY(14px); transition: transform .22s ease; position: relative; }
.ag-sheet-wrap.show .ag-sheet { transform: none; }
.ag-sh-x { position: sticky; top: 0; margin-inline-start: auto; display: block; width: 38px; height: 38px;
  border: none; border-radius: 50%; background: var(--card); box-shadow: var(--shadow-sm);
  color: var(--muted); font-size: 1rem; font-weight: 800; cursor: pointer; z-index: 1; }
/* an older shelf, kept as a line so the conversation still reads back without repeating itself */
.ag-past { color: var(--muted); font-size: .85rem; font-weight: 700; padding: 8px 12px;
  background: var(--card); border: 1px dashed var(--line); border-radius: 12px; }

/* The tour + sign-up pair moved BELOW the products when the landing hero was removed
   (2026-08-16). They are still reachable, they just no longer compete with the aisles for the
   first screen — so they get air above them and read as a footer, not as a call to action. */
.w-alt-end { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line, #e6e9f0); }

/* The cart chip is chrome on demand: hidden until something is in it, the same rule the
   reference shop applies to its cart strip. `.has` is toggled wherever the badge updates, so
   the element stays in the DOM for the fly-to-cart animation and for مريم to point at. */
/* Always on screen, in one of two states — see .cart-chip rules at the end of this file. */
.cart-chip { display: inline-flex; }

/* `hidden` is an attribute, not a rule — and `.icon-btn { display:flex }` outranks the UA
   sheet, so the bell kept painting after it was marked hidden. Say it once, for everything. */
[hidden] { display: none !important; }

/* ===== product screen, shaped like the reference shop (2026-08-16) ===== */
/* Round ✕ on the photo instead of a «→ رجوع للمتجر» text link: closing a product should feel
   like dismissing a card, not travelling somewhere else. */
.sheet-x { position: absolute; z-index: 6; inset-block-start: 12px; inset-inline-end: 12px;
  width: 40px; height: 40px; border: none; border-radius: 50%;
  background: var(--card); color: var(--ink, #10304E);
  box-shadow: 0 2px 10px rgba(16,48,78,.18);
  font-size: 1.5rem; line-height: 1; cursor: pointer; font-family: inherit; }
.sheet-x:active { transform: scale(.92); }
main#view { position: relative; }   /* the ✕ anchors to the screen, not the document */

/* The specs — the one thing a grocery-shaped competitor cannot show. Directly under the price,
   because that is where «is this the right one» gets decided. */
.p-specs { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 2px; }
.spec-chip { padding: 4px 10px; border-radius: 999px; font-size: .78rem; font-weight: 700;
  color: var(--blue); background: var(--blue-soft); }

/* Their buy bar never scrolls away: price and «add» stay under the thumb the whole time. It
   floats ABOVE the tab bar, and the page reserves room so the last line is never covered. */
/* FIXED, not sticky: sticky only holds while its own container is on screen, and the system
   rail + similar rail come after .prod-info — so the bar slid away at the exact moment the
   customer was comparing and most likely to buy. Theirs never leaves. */
.buy-row-stick { position: fixed; z-index: 55;
  inset-inline: 14px; bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 4px);
  margin: 0; padding: 8px; border-radius: 22px;
  background: var(--card); box-shadow: 0 6px 26px rgba(16,48,78,.18), 0 1px 4px rgba(16,48,78,.10); }
/* room for it, so the last rail is never hidden underneath */
body.on-product { padding-bottom: calc(var(--tab-h) + env(safe-area-inset-bottom) + 96px); }

/* ===== checkout rules (2026-08-16) ===== */
/* The refusal sits where the error is, not in a toast that outlives nothing. */
.co-rule { margin: 10px 0; padding: 12px 14px; border-radius: 14px;
  background: #FDECEC; color: #A32020; font-weight: 700; font-size: .9rem; line-height: 1.5; }
/* Two waits, side by side: packed, then delivered. */
.co-eta { display: flex; flex-wrap: wrap; gap: 8px 18px; margin: 10px 0;
  padding: 12px 14px; border-radius: 14px; background: var(--blue-soft); color: var(--blue);
  font-size: .88rem; font-weight: 600; }
.co-eta b { font-weight: 800; }
/* Asked once here instead of a phone call to a customer who is at work. */
.co-sub { display: flex; align-items: flex-start; gap: 10px; margin: 10px 0;
  padding: 12px 14px; border-radius: 14px; background: var(--card);
  border: 1px solid var(--line, #e6e9f0); cursor: pointer; }
.co-sub input { width: 20px; height: 20px; accent-color: var(--blue); margin-top: 2px; flex: none; }
.co-sub small { display: block; color: var(--muted); font-weight: 500; font-size: .8rem; margin-top: 2px; }

/* ===== two-pane department browser (2026-08-16) =====
   The reference shop shows the whole map at once: departments down one side, the chosen one's
   aisles beside them. Each column scrolls on its own, so picking a department never loses your
   place in the list of departments. In RTL the department column comes FIRST in source, so it
   lands on the right where the thumb is. */
/* --head-h was never a real variable, so the fallback 148px decided the height and the columns
   ended under the floating bar. Measure from the header's actual bottom instead: the panes take
   whatever is left between it and the tab bar, whatever the announcement strip is doing. */
.cat-two { display: grid; grid-template-columns: 132px 1fr; gap: 10px;
  height: calc(100dvh - var(--cat-top, 210px) - var(--tab-h) - env(safe-area-inset-bottom) - 8px);
  padding: 8px 10px 0; }
.dep-col { overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 2px;
  background: var(--bg); border-radius: 16px; padding: 6px 4px; }
.dep-row { padding: 14px 8px; border: none; border-radius: 12px; background: none;
  color: var(--muted); font-family: inherit; font-size: .82rem; font-weight: 700; line-height: 1.45;
  text-align: center; cursor: pointer; }
/* the selected department is the one the aisles belong to — it reads as connected to them */
.dep-row.on { background: var(--card); color: var(--blue); font-weight: 800;
  box-shadow: 0 1px 4px rgba(16,48,78,.10); }
/* grid-auto-rows: max-content is not decoration. Inside a parent with a definite height the
   rows were being squeezed to fit — every tile came out 107px tall for 139px of content, and
   `overflow:hidden` on the artwork variant sliced the department name in half. Let the rows be
   the size of what is in them and let the PANE scroll instead. */
.cat-pane { overflow-y: auto; overscroll-behavior: contain;
  display: grid; grid-template-columns: repeat(2, 1fr); grid-auto-rows: max-content; gap: 10px;
  align-content: start; padding-bottom: 14px; }
/* the tiles are the same component the landing uses, just narrower here */
.cat-pane .navhome-cat { width: 100%; margin: 0; }
@media (max-width: 360px) { .cat-two { grid-template-columns: 108px 1fr; } }

/* the folded chat history (2026-08-17) — one row that opens the rest in place */
.chat-all { width: 100%; margin-top: 4px; padding: 11px 8px; border: none; border-radius: 12px;
  background: var(--blue-soft); color: var(--blue); font: inherit; font-weight: 700;
  font-size: .84rem; cursor: pointer; }
.chat-all:active { transform: scale(.98); }
.chat-more { display: contents; }

.social.wa { background: #25D366; color: #fff; }   /* WhatsApp green — the one contact that answers */
.social.tel { background: var(--blue); color: #fff; }   /* same number, forwarded to his phone */

/* ===== the phone identity sheet (2026-08-17) ===== */
.ph-wrap { position: fixed; inset: 0; z-index: 999; display: flex; align-items: flex-end;
  background: rgba(10,20,35,.42); animation: phFade .18s ease; }
@keyframes phFade { from { opacity: 0 } }
.ph-sheet { width: 100%; background: var(--card); border-radius: 22px 22px 0 0;
  padding: 10px 18px calc(22px + env(safe-area-inset-bottom));
  animation: phUp .22s cubic-bezier(.2,.8,.3,1); text-align: center; }
@keyframes phUp { from { transform: translateY(14%) } }
.ph-grip { width: 42px; height: 4px; margin: 0 auto 14px; border-radius: 2px; background: #d7dde6; }
.ph-logo { height: 46px; margin: 6px auto 12px; display: block; }
.ph-word { height: auto; text-align: center; font-size: 1.7rem; font-weight: 900; color: var(--blue); }
.ph-sub { color: var(--muted); font-size: .92rem; margin-bottom: 18px; }
.ph-lab { display: block; text-align: start; font-size: .86rem; color: var(--muted); margin-bottom: 6px; }
/* the field and its action are ONE control, the way the reference sheet draws it */
.ph-row { display: flex; align-items: center; gap: 8px; padding: 6px;
  border: 1px solid var(--line, #e6e9f0); border-radius: 16px; }
.ph-in { flex: 1; border: none; outline: none; background: none; font: inherit; font-size: 1.05rem;
  text-align: start; direction: ltr; padding: 8px; }
.ph-send { border: none; border-radius: 12px; padding: 11px 14px; background: var(--blue); color: #fff;
  font: inherit; font-weight: 700; font-size: .88rem; cursor: pointer; white-space: nowrap; }
.ph-boxes { display: flex; gap: 8px; justify-content: center; margin: 16px 0 4px; }
.ph-err { min-height: 20px; margin-top: 10px; font-size: .86rem; color: var(--blue); }
.ph-skip { margin-top: 6px; border: none; background: none; color: var(--muted);
  font: inherit; font-size: .86rem; text-decoration: underline; cursor: pointer; }

/* ===== services screen (2026-08-17) ===== */
.svc-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; padding: 4px 14px 20px; }
.svc-card { display: flex; flex-direction: column; gap: 8px; padding: 10px;
  background: var(--card); border-radius: 18px; box-shadow: 0 2px 12px rgba(16,48,78,.07); }
.svc-media { border-radius: 12px; overflow: hidden; background: #f5f7fa; }
.svc-media img, .svc-media .noimg { width: 100%; aspect-ratio: 4/3; object-fit: contain; }
.svc-body { flex: 1; }
.svc-name { font-weight: 800; font-size: .9rem; line-height: 1.4; }
/* «من X د.ع» — the number is a floor, not a quote. Saying so in the price stops the estimate
   from reading as a promise the technician then has to break at the door. */
.svc-price { margin-top: 4px; color: var(--blue); font-weight: 800; font-size: 1rem; }
/* the promise that replaced the number: quieter than a price, because it is not one */
.svc-quote { display: flex; align-items: center; gap: 5px; margin-top: 4px;
  color: var(--muted); font-weight: 700; font-size: .8rem; }
.svc-quote svg { width: 14px; height: 14px; flex: none; }
.svc-price span { font-size: .74rem; font-weight: 600; }
.svc-book { width: 100%; padding: 10px; font-size: .86rem; border-radius: 14px;
  display: flex; align-items: center; justify-content: center; gap: 7px; }
/* the glyph had no size of its own, so it inherited the SVG's own 24-unit box scaled to the
   button's width — a wrench taller than the card it sits in */
.svc-book svg { width: 17px; height: 17px; flex: none; }
/* Two columns even on a 360px phone. Twelve services in one column is twelve swipes, and the
   customer is scanning for the one he needs, not reading them. */
.svc-media { display: grid; place-items: center; min-height: 92px; }
.svc-media img { max-height: 92px; }
/* none of the twelve services carries a photo in Odoo, and an empty 4:3 box was eating the
   card — a wrench on the shop's own tint says «service» faster than a grey rectangle. */
.svc-media .noimg { aspect-ratio: auto; height: 92px; display: grid; place-items: center;
  background: var(--blue-soft); color: var(--blue); }
.svc-media .noimg svg { width: 34px; height: 34px; }

/* ===== the مريم switch (2026-08-17) =====
   A real on/off, drawn like a dark-mode toggle: track, knob, and the knob travels. Gold only
   while she is on — gold is her signal everywhere else in the store, and a permanently gold
   control would burn it before she says a word. */
/* ---- مريم's presence switch, redesigned 2026-08-25 -------------------------------------
   It was a grey iOS knob with «Ai» in Latin next to it: a generic OS control wearing no part
   of this brand, in a header where everything else is a navy/gold pill. It is now the same
   pill as its neighbours, and it says her NAME. Gold is the whole signal — his rule that gold
   means مريم and nothing else is what makes the on-state readable at a glance, so the switch
   needs no knob to say which way it is thrown. */
.ai-sw { position: relative; display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 11px 0 9px; border-radius: 17px; cursor: pointer;
  border: 1px solid var(--line, #e6e9f0); background: var(--bg); font-family: inherit;
  transition: background .2s ease, border-color .2s ease, box-shadow .2s ease; }
.ai-sw-i { display: grid; place-items: center; color: var(--muted); transition: color .2s ease; }
.ai-sw-i svg { width: 18px; height: 18px; display: block; }
.ai-sw-t { font-size: .8rem; font-weight: 800; color: var(--muted); letter-spacing: -.01em;
  transition: color .2s ease; }
/* ON: her gold, filled — the same «she is here» the pointing ring uses elsewhere. */
.ai-sw[aria-checked="true"] { background: linear-gradient(180deg, #F6E4B4, var(--gold-soft, #E7CE8E));
  border-color: var(--gold, #C9A24A); box-shadow: 0 0 0 3px rgba(201,162,74,.18); }
.ai-sw[aria-checked="true"] .ai-sw-i { color: var(--gold-text, #8F6E1C); }
.ai-sw[aria-checked="true"] .ai-sw-t { color: var(--gold-text, #8F6E1C); }
/* the small spark twinkles only while she is on — an idle animation on an OFF control is noise */
.ai-sw .ai-spark { opacity: 0; transition: opacity .2s ease; transform-origin: 18.5px 18.2px; }
.ai-sw[aria-checked="true"] .ai-spark { opacity: 1; animation: aiTwinkle 3.2s ease-in-out infinite; }
.ai-sw:active { transform: scale(.95); }
@media (prefers-reduced-motion: reduce) { .ai-sw[aria-checked="true"] .ai-spark { animation: none; } }
@media (max-width: 400px) { .ai-sw { height: 32px; padding: 0 9px 0 7px; gap: 5px; }
  .ai-sw-t { font-size: .75rem; } .ai-sw-i svg { width: 16px; height: 16px; } }

/* the verified phone on the checkout form: a fact with a way out, not an empty box */
.ph-fixed { display: flex; align-items: center; gap: 8px; }
.ph-fixed input { flex: 1; }
.ph-fixed input[readonly] { background: var(--bg); color: var(--muted); font-weight: 700; }
.ph-change { flex: none; padding: 10px 14px; border: 1px solid var(--line, #e6e9f0);
  border-radius: 12px; background: var(--card); color: var(--blue);
  font: inherit; font-weight: 700; font-size: .84rem; cursor: pointer; }

/* Google inside the phone gate: available, but visually secondary to the number — it fills the
   name and the email, it does not replace the thing the delivery depends on. */
.ph-goog { display: flex; align-items: center; justify-content: center; gap: 9px;
  width: 100%; margin-top: 16px; padding: 12px; border-radius: 14px;
  border: 1px solid var(--line, #e6e9f0); background: var(--card);
  font: inherit; font-weight: 700; font-size: .9rem; cursor: pointer; }
.ph-goog:active { transform: scale(.98); }
.ph-note { margin: 8px 0 0; color: var(--muted); font-size: .8rem; line-height: 1.6; }

/* the returning-customer summary: facts to read, not fields to fill */
.co-sum { margin: 4px 0 14px; padding: 14px 16px; border-radius: 16px;
  background: var(--card); border: 1px solid var(--line, #e6e9f0); }
.cs-row { display: flex; gap: 12px; padding: 7px 0; font-size: .93rem; }
.cs-row + .cs-row { border-top: 1px solid var(--line, #e6e9f0); }
.cs-k { flex: none; min-width: 84px; color: var(--muted); }
.cs-v { font-weight: 700; }
.cs-addr .cs-v { line-height: 1.6; }
.cs-edit { margin-top: 10px; padding: 9px 14px; border-radius: 12px;
  border: 1px solid var(--blue); background: none; color: var(--blue);
  font: inherit; font-weight: 700; font-size: .84rem; cursor: pointer; }

/* a second line inside an account row: what the row is FOR, when the label alone is a verb */
.ar-sub { display: block; margin-top: 2px; color: var(--muted); font-weight: 500;
  font-size: .74rem; line-height: 1.5; }

/* signup progress — three dots, so «كم باقي؟» is answered before it is asked */
.su-dots { display: flex; gap: 6px; justify-content: center; margin: 4px 0 18px; }
.su-dot { width: 26px; height: 4px; border-radius: 2px; background: var(--line, #e6e9f0);
  transition: background .2s; }
.su-dot.done { background: var(--blue-l, #3B72D9); }
.su-dot.on { background: var(--blue); width: 34px; }

/* The floating cart bar sat on top of «احجز فنّي» on the services grid: two calls to action in
   the same 60px, and the one the customer came for was underneath. Booking a technician has
   nothing to do with the goods cart, so on this screen the page gives it room instead. */
body.on-services .svc-grid { padding-bottom: 96px; }

/* ---- Checkout: folded review sections (2026-08-25) ---------------------------------------
   The customer already gave us all of this at signup, so the default state is «read», not
   «type». Native <details>, so the folding costs no JS. */
.co-hint { margin: -6px 0 12px; font-size: .86rem; color: var(--muted, #64748b); }
.co-sec { margin: 0 0 10px; border: 1px solid var(--line, #e6e9f0); border-radius: 14px;
  background: var(--card, #fff); overflow: hidden; }
.co-sec > summary { display: flex; align-items: center; gap: 10px; padding: 13px 14px;
  cursor: pointer; list-style: none; font-size: .95rem; }
.co-sec > summary::-webkit-details-marker { display: none; }
.co-sec > summary::after { content: '⌄'; margin-inline-start: auto; font-size: 1.1rem;
  color: var(--muted, #64748b); transition: transform .18s ease; }
.co-sec[open] > summary::after { transform: rotate(180deg); }
.co-sec > summary b { flex: 0 0 auto; font-weight: 700; }
.co-sec-v { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-size: .86rem; color: var(--muted, #64748b); }
.co-sec-v.miss { color: #c2410c; font-weight: 600; }
.co-sec[open] > summary { border-bottom: 1px solid var(--line, #e6e9f0); }
.co-sec > *:not(summary) { padding: 0 14px; }
.co-sec > *:not(summary):last-child { padding-bottom: 12px; }
.co-sec .field:first-of-type { margin-top: 12px; }

/* Name + number: identity, shown for review only, edited where they live (2026-08-25) */
.co-who { display: flex; align-items: center; gap: 12px; margin: 0 0 10px; padding: 12px 14px;
  border: 1px solid var(--line, #e6e9f0); border-radius: 14px; background: var(--card, #fff); }
.cw-lines { flex: 1 1 auto; min-width: 0; }
.cw-name { font-weight: 700; font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cw-phone { font-size: .86rem; color: var(--muted, #64748b); margin-top: 2px; }
.cw-edit { flex: 0 0 auto; display: inline-flex; align-items: center; gap: 5px;
  border: 0; background: var(--blue-soft, #eaf1fb); color: var(--blue, #1a5fd4);
  font: inherit; font-size: .8rem; font-weight: 800; letter-spacing: -.01em;
  padding: 7px 12px 7px 10px; border-radius: 999px; cursor: pointer;
  transition: background .15s ease, transform .12s ease; }
.cw-edit svg { flex: 0 0 auto; opacity: .85; }
.cw-edit:hover { background: var(--blue, #1a5fd4); color: #fff; }
.cw-edit:active { transform: scale(.96); }

.lbl-opt { font-weight: 400; font-size: .78rem; color: var(--muted, #64748b); }
.map-head .req { color: #c2410c; }

/* «استخدام الموقع الحالي» sits under the map it acts on */
.map-block > .loc-btn { width: 100%; justify-content: center; margin-top: 10px; padding: 12px; font-size: .9rem; }

/* the fold's own «تعديل» pill replaces the chevron — same control as the identity row */
.co-sec > summary:has(.sec-edit)::after { content: none; }
.sec-edit { flex: 0 0 auto; pointer-events: none; }   /* the summary owns the click */
/* open = «you are editing now», so the chip inverts instead of just sitting there */
.co-sec[open] .sec-edit { background: var(--blue, #1a5fd4); color: #fff; }
.co-notes { margin-top: 12px; }
.co-notes > label { display: block; font-weight: 700; font-size: .95rem; margin-bottom: 6px; }

.w-note { color: var(--muted, #64748b); font-size: .85rem; margin: -4px 0 14px; line-height: 1.6; }
.verified-line { color: #1e9e4a; font-weight: 700; }
.err a { color: var(--blue, #1a5fd4); font-weight: 700; }

/* ---- the header bag says whether the cart has anything in it (2026-08-25) ----------------
   Two states, never absent: empty is a quiet outline, full is the brand blue with a live count.
   It used to vanish when the cart was empty, which answered «هل بالسلة شي؟» by removing the
   thing you look at to find out. */
.cart-chip { position: relative; background: transparent; color: var(--muted, #64748b);
  border: 1px solid var(--line, #e6e9f0); transition: background .18s ease, color .18s ease, border-color .18s ease; }
.cart-chip.has { background: var(--blue-soft, #eaf1fb); color: var(--blue, #1a5fd4); border-color: transparent; }
.cart-chip.has svg { transform: scale(1.04); }
/* the count rides on the bag itself — a number is the only unambiguous «how many» */
#cartCount { position: absolute; top: -3px; inset-inline-start: -3px; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: 9px; background: var(--blue, #1a5fd4); color: #fff;
  font-size: .7rem; font-weight: 800; display: grid; place-items: center;
  border: 2px solid var(--card, #fff); opacity: 0; transform: scale(.4); transition: .18s; }
#cartCount.has { opacity: 1; transform: scale(1); }

.forgot-link { margin-top: 2px; font-size: .88rem; }
#fgBoxes { margin: 6px 0 14px; }

/* ================= order confirmation, redesigned 2026-08-25 =====================
   The old screen gave a fist-sized shield, an empty payment card and a cash glyph with no
   size constraint that ate a third of the page — and never said what was bought, where it
   was going or when it lands. Compact hero, then the three answers. */
.success { padding: 18px 14px 28px; }
.success h1 { font-size: 1.35rem; font-weight: 800; margin: 0 0 4px; text-align: center; }
.ok-hero { display: grid; justify-items: center; gap: 2px; margin-bottom: 18px; }
.ok-badge { width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center;
  background: rgba(30,158,74,.12); color: #1e9e4a; margin-bottom: 10px;
  animation: okPop .38s cubic-bezier(.2,1.4,.4,1); }
.ok-badge svg { width: 30px; height: 30px; stroke-width: 3; }
@keyframes okPop { from { transform: scale(.5); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .ok-badge { animation: none; } }
.ok-sub { color: var(--muted, #64748b); font-size: .9rem; margin: 0 0 12px; text-align: center; }
/* the number is a control: he may have to quote it back to us on WhatsApp */
.ok-num { display: inline-flex; align-items: center; gap: 7px; border: 1px dashed var(--line, #e6e9f0);
  background: var(--card, #fff); color: var(--text, #0f172a); font: inherit; font-weight: 800;
  letter-spacing: .04em; padding: 8px 14px; border-radius: 999px; cursor: pointer; }
.ok-num svg { width: 15px; height: 15px; color: var(--muted, #64748b); }
.ok-num:active { transform: scale(.97); }

.ok-card { padding: 14px 16px; margin: 0 0 12px; }
.ok-card h2 { font-size: .95rem; font-weight: 800; margin: 0 0 10px; }
.ok-items { display: grid; gap: 10px; }
.ok-item { display: flex; align-items: center; gap: 10px; }
.oi-img { width: 42px; height: 42px; flex: 0 0 auto; border-radius: 10px; object-fit: contain;
  background: var(--bg, #f5f7fa); }
.oi-none { display: grid; place-items: center; color: var(--muted, #64748b); }
.oi-none svg { width: 20px; height: 20px; }
.oi-name { flex: 1 1 auto; min-width: 0; font-size: .88rem; line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.oi-qty { flex: 0 0 auto; font-weight: 800; font-size: .85rem; color: var(--muted, #64748b); }

.ok-row { display: flex; align-items: flex-start; gap: 12px; padding: 9px 0; font-size: .9rem; }
.ok-row + .ok-row { border-top: 1px solid var(--line, #e6e9f0); }
.ok-k { display: inline-flex; align-items: center; gap: 6px; flex: 0 0 auto;
  color: var(--muted, #64748b); }
/* THE bug this redesign fixes: an inline icon with no box grows to fill the row. */
.ok-k svg { width: 16px; height: 16px; flex: 0 0 auto; }
.ok-v { flex: 1 1 auto; text-align: end; font-weight: 600; line-height: 1.5; }
.ok-total { font-size: 1.02rem; font-weight: 800; padding-top: 12px; }
.ok-total span:last-child { color: var(--blue, #1a5fd4); }
.success .btn-primary { width: 100%; margin-top: 4px; }
.success .btn-link { width: 100%; margin-top: 2px; }
/* nothing else on this screen may render an unbounded glyph again */
.success .steps svg, .success .ap-ic svg { width: 20px; height: 20px; }

/* ================= مريم's stage — a camera that does not move (2026-08-25) ==============
   His design: «ملعب ثابت وتتحرك فيه اللاعبون». The four regions below each hold their place
   whether or not they have content; only .ag-board changes, and only .ag-board scrolls. The
   page itself never grows, so the frame the customer learned in his first turn is the frame
   he still has in his tenth. */
body.mode-maryam #agentView.ag-fixed {
  position: fixed; inset-inline: 0;
  top: var(--stage-top, 64px);
  bottom: var(--stage-bottom, 78px);
  display: flex; flex-direction: column; gap: 8px;
  padding: 6px 12px 0; overflow: hidden; }
/* the page must not also scroll behind a fixed frame */
body.mode-maryam { overflow: hidden; padding-bottom: 0 !important; }

.ag-stage { display: flex; flex-direction: column; gap: 8px; min-height: 0; flex: 1; }
/* what he just asked — one line, so the answer above it has context without a transcript */
.ag-echo { flex: 0 0 auto; min-height: 22px; display: flex; align-items: center; gap: 10px;
  color: var(--muted); font-size: .8rem; }
.ag-echo > :first-child { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ag-past-btn { flex: 0 0 auto; border: 1px solid var(--line); background: var(--card);
  color: var(--muted); font: inherit; font-size: .72rem; font-weight: 700;
  padding: 3px 10px; border-radius: 999px; cursor: pointer; }
/* her sentence: two lines, always the same box — a wall of text is what made the old bubble
   unreadable, and a box that grows is a camera that pans */
.ag-stage .ag-say { flex: 0 0 auto; margin: 0; min-height: 2.9em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  background: var(--her-surface, #FDF6E6); color: var(--text, #101B2B);
  border: 1px solid var(--her-edge, rgba(201,162,74,.42));
  border-radius: 14px; padding: 9px 13px; font-size: .92rem; font-weight: 700; line-height: 1.55; }
.ag-stage .ag-say:empty { visibility: hidden; }
/* THE stage: the only region that changes, the only one that scrolls */
.ag-board { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 9px; padding-bottom: 2px;
  scrollbar-width: none; }
.ag-board::-webkit-scrollbar { display: none; }
.ag-board > .ag-card { margin: 0; }
/* the decision row keeps its height when empty — that is what stops the frame from jumping */
.ag-row { flex: 0 0 auto; min-height: 40px; display: flex; align-items: center; }
/* ONE line, scrolled sideways — wrapping to a second row costs the board 50px and makes the
   row's height depend on its content, which is the one thing a fixed frame cannot allow. */
.ag-row .ag-cmds { margin: 0; width: 100%; overflow-x: auto; scrollbar-width: none;
  flex-wrap: nowrap; }
.ag-row .ag-cmd { flex: 0 0 auto; white-space: nowrap; }
.ag-row .ag-cmds::-webkit-scrollbar { display: none; }
/* one action per shelf card: the extra two moved to the single-product scene */
.ag-board .ag-card .ag-cmds { margin-top: 6px; }

/* «الي فات» — the past as a layer over the stage, never stacked above it */
.ag-hist { position: fixed; inset: 0; z-index: 70; background: rgba(8,25,44,.55);
  display: flex; align-items: flex-end; }
.agh-sheet { width: 100%; max-height: 78dvh; background: var(--bg); border-radius: 20px 20px 0 0;
  display: flex; flex-direction: column; animation: dpUp .26s var(--ease, ease); }
.agh-head { display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--line); font-size: 1rem; }
.agh-x { border: 0; background: none; font: inherit; font-size: 1.1rem; color: var(--muted); cursor: pointer; }
.agh-body { overflow-y: auto; padding: 12px 14px 24px; }
@media (prefers-reduced-motion: reduce) { .agh-sheet { animation: none; } }

/* Gold says «مريم هنا»; blue says «اضغط». Her action chips were gold, so on a shelf of four
   cards the colour that means her presence appeared eight times as an ordinary button and
   stopped meaning anything (2026-08-25). One line to revert if he wants the gold back. */
.ag-cmd.go { background: var(--blue, #1a5fd4); border-color: var(--blue, #1a5fd4); color: #fff; }
.ag-cmd.go:active { filter: brightness(.94); }

/* ===== services home: three families, not twelve cards (2026-08-25) =====================
   The colour on each family is a stripe, not a fill — the section still belongs to the store's
   blue, and the stripe only says «these three are different kinds of work». */
.fam-grid { display: grid; gap: 12px; margin: 4px 0 18px; }
.fam-card { display: flex; align-items: stretch; gap: 12px; width: 100%; padding: 0;
  background: var(--card); border: 1px solid var(--line); border-radius: 18px;
  font: inherit; text-align: start; cursor: pointer; overflow: hidden;
  transition: border-color .18s ease, transform .12s ease; }
.fam-card:active { transform: scale(.99); }
.fam-bar { flex: 0 0 5px; background: var(--muted); }
.fam-field .fam-bar { background: #2F9E6B; }
.fam-remote .fam-bar { background: #4C7BE0; }
.fam-project .fam-bar { background: #9B59C7; }
.fam-build .fam-bar { background: #C4762F; }
.fam-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 3px;
  padding: 14px 0 14px 4px; }
.fam-body b { font-size: 1rem; font-weight: 800; }
.fam-sub { color: var(--muted); font-size: .84rem; line-height: 1.5; }
.fam-price { color: var(--gold-text); font-size: .8rem; font-weight: 700; margin-top: 3px; }
.fam-n { flex: 0 0 auto; align-self: center; margin-inline-end: 14px;
  min-width: 26px; height: 26px; padding: 0 7px; border-radius: 999px;
  background: var(--bg); color: var(--muted); font-size: .8rem; font-weight: 800;
  display: grid; place-items: center; }
.fam-card:hover { border-color: var(--blue); }

/* the live-call orb is hidden for now — the ask row keeps text + the voice-note mic */
body.no-live-call .orb-btn, body.no-live-call .live-orb { display: none; }

/* payment method choice (card via Stripe Checkout, 2026-10-01) */
.co-pay { margin: 4px 0 14px; padding: 12px 14px; border: 1px solid var(--line, #e3e7ef); border-radius: 14px; }
.co-pay .cp-title { font-weight: 700; margin-bottom: 6px; }
.co-pay .cp-opt { display: flex; align-items: center; gap: 8px; padding: 8px 0; cursor: pointer; font-weight: 600; }
.co-pay .cp-opt input { width: 18px; height: 18px; margin: 0; accent-color: var(--brand, #14213d); }
.co-pay .cp-usd { display: block; color: var(--muted); line-height: 1.6; margin-top: 4px; }
