

:root {
  /* ── Ядро палитры ─────────────────────────────────────────────────────
     Тёмная тема — база. Нейтральные тона уведены в синеву акцента, чтобы
     серый не читался как «непродуманный». Уровни поверхностей разнесены
     по светлоте, а не только по прозрачности: так карточки видно и без
     backdrop-filter (Telegram WebView его местами глушит). */
  --bg:          #0a0b12;
  --bg-2:        #0e1019;
  --bg-card:     #141726;
  --s1:          #171a2b;
  --s2:          #1e2136;
  --s3:          #262a42;
  --ln:          rgba(255, 255, 255, 0.09);
  --ln2:         rgba(255, 255, 255, 0.16);
  --ln-strong:   rgba(124, 109, 250, 0.42);

  --p:           #7c6dfa;
  --pd:          #6355d8;
  --p-soft:      rgba(124, 109, 250, 0.16);
  --p-ring:      rgba(124, 109, 250, 0.34);
  --glow:        rgba(124, 109, 250, 0.35);

  --t1:          #f2f4fb;
  --t2:          #9aa3bd;
  --t3:          #6b7391;
  --price-color: #c9c2ff;
  --price-bg:    rgba(124, 109, 250, 0.13);
  --gr:          #34d399;
  --gr-soft:     rgba(52, 211, 153, 0.14);
  --rd:          #f87171;
  --brand:       #7c6dfa;
  --hdr-bg:      rgba(10, 11, 18, 0.88);

  /* Тени: две штуки — контактная и рассеянная, иначе карточки «висят» */
  --sh-1:        0 1px 2px rgba(0,0,0,.5);
  --sh-2:        0 2px 6px rgba(0,0,0,.45), 0 10px 24px rgba(0,0,0,.35);
  --sh-pop:      0 8px 28px rgba(0,0,0,.55);

  --r-sm: 10px; --r-md: 14px; --r-lg: 18px; --r-xl: 24px;
}

.theme-light {
  /* Светлая тема: фон уведён в холодный сиреневый, границы реально видно.
     Раньше здесь было #fff на #f4f6fb с рамкой 0.08 — карточки сливались. */
  --bg:          #eef0f8;
  --bg-2:        #f6f7fc;
  --bg-card:     #ffffff;
  --s1:          #ffffff;
  --s2:          #f2f4fb;
  --s3:          #e8ebf6;
  --ln:          rgba(23, 27, 56, 0.11);
  --ln2:         rgba(23, 27, 56, 0.18);
  --ln-strong:   rgba(99, 102, 241, 0.45);

  --p:           #6366f1;
  --pd:          #4f46e5;
  --p-soft:      rgba(99, 102, 241, 0.10);
  --p-ring:      rgba(99, 102, 241, 0.30);
  --glow:        rgba(99, 102, 241, 0.22);

  --t1:          #12162a;
  --t2:          #545c78;
  --t3:          #7a829c;
  --price-color: #4338ca;
  --price-bg:    rgba(99, 102, 241, 0.09);
  --gr:          #059669;
  --gr-soft:     rgba(5, 150, 105, 0.11);
  --rd:          #dc2626;
  --brand:       #6366f1;
  --hdr-bg:      rgba(246, 247, 252, 0.92);

  --sh-1:        0 1px 2px rgba(23, 27, 56, .07);
  --sh-2:        0 1px 3px rgba(23, 27, 56, .07), 0 6px 18px rgba(23, 27, 56, .07);
  --sh-pop:      0 10px 34px rgba(23, 27, 56, .16);
}

*,*::before,*::after { box-sizing:border-box; -webkit-tap-highlight-color:transparent; user-select:none; margin:0; padding:0; }

body {
  font-family: 'Outfit', sans-serif;
  background-color: var(--bg);
  background-image: radial-gradient(circle at 15% 50%, rgba(124, 109, 250, 0.06) 0%, transparent 40%), radial-gradient(circle at 85% 30%, rgba(99, 102, 241, 0.07) 0%, transparent 40%);
  background-attachment: fixed;
  color: var(--t1);
  min-height: 100vh;
  /* --dock-h выставляет syncDockHeight() по реальной высоте дока */
  padding-bottom: calc(var(--dock-h, 76px) + 12px);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

@keyframes fadeUp {
  0% { opacity: 0; transform: translateY(20px) scale(0.95); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

/* ── Header ─────────────────────────────────────── */
.hdr {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--ln);
  background: var(--hdr-bg);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  position: sticky; top: 0; z-index: 50;
  transition: background .2s, border-color .2s;
}
.hdr-ico {
  width: 44px; height: 44px; border-radius: 14px; flex-shrink: 0;
  background: linear-gradient(135deg, rgba(124, 109, 250, 0.25), rgba(99, 102, 241, 0.45));
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; color: #fff;
  border: 1px solid rgba(255,255,255,0.15);
  box-shadow: 0 4px 16px var(--glow);
}
.theme-light .hdr-ico {
  background: linear-gradient(135deg, #6366f1, #4f46e5);
  color: #fff;
  border: none;
  box-shadow: 0 4px 16px rgba(99, 102, 241, 0.35);
}
.hdr-h {
  font-size: 19px; font-weight: 800; letter-spacing: -0.2px; text-transform: uppercase;
  background: linear-gradient(90deg, #ffffff, #cbd5e1);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.theme-light .hdr-h {
  background: linear-gradient(90deg, #0f172a, #334155);
  -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
.hdr-s { font-size: 13px; color: var(--t2); margin-top: 2px; font-weight: 500; letter-spacing: 0.5px; }
.theme-toggle {
  margin-left:auto; width:36px; height:36px; border-radius:10px;
  background:var(--s2); border:1px solid var(--ln); color:var(--t1);
  display:flex; align-items:center; justify-content:center;
  font-size:18px; cursor:pointer; transition:transform .1s;
}
.theme-toggle:active { transform:scale(.92); }

/* ── Tabs ───────────────────────────────────────── */
.tabwrap {
  overflow-x:auto; scrollbar-width:none; border-bottom:1px solid var(--ln);
  position:sticky; top:76px; z-index:45;
  /* Плотный фон, а не полупрозрачный: в Telegram WebView backdrop-filter
     местами не применяется, и текст секций просвечивал сквозь вкладки. */
  background:var(--bg);
  /* Затухание у правого края — подсказка, что вкладки скроллятся.
     Раньше последняя вкладка просто обрезалась. */
  -webkit-mask-image:linear-gradient(90deg, #000 0, #000 calc(100% - 26px), transparent 100%);
          mask-image:linear-gradient(90deg, #000 0, #000 calc(100% - 26px), transparent 100%);
}
.tabwrap::-webkit-scrollbar { display:none; }
.tabs { display:flex; padding:0 14px; width:max-content; min-width:100%; gap:2px; }
.tab {
  padding:11px 11px 10px;
  font-size:13px; font-weight:600; color:var(--t3);
  border-bottom:2px solid transparent;
  cursor:pointer; white-space:nowrap;
  transition:color .18s, border-color .18s;
  margin-bottom:-1px; letter-spacing:-.01em;
  display:flex; align-items:center; gap:6px;
}
.tab.on { color:var(--t1); border-bottom-color:var(--p); font-weight:700; }
.tab-ico { font-size:14px; opacity:.9; }

/* ── Pages ──────────────────────────────────────── */
.page { display:none; padding-bottom:8px; }
.page.on { display:block; animation:pg .22s ease both; }
@keyframes pg { from{opacity:0;transform:translateY(5px)} to{opacity:1;transform:translateY(0)} }

/* ── Section ────────────────────────────────────── */
.sec { margin:22px 12px 0; }
/* Заголовок раздела — именно заголовок, а не ещё одна карточка:
   раньше он был боксом с рамкой и читался наравне с услугами. */
.sec-hd {
  background:transparent; border:none;
  border-radius:0;
  padding:0 4px 2px;
  display:flex; flex-direction:column; gap:3px;
}
.sec-hd-t {
  font-size:12px; font-weight:700; letter-spacing:.09em;
  text-transform:uppercase; color:var(--t2);
}
.sec-hd-s { font-size:12.5px; color:var(--t3); margin-top:0; line-height:1.4; }

.sec-rows {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  background: transparent;
  border: none;
  padding: 10px 0 0;
}
.sec-rows.standalone { border-radius:14px; }

/* ── Row (карточка услуги) ──────────────────────── */
.row {
  display:flex; flex-direction:column; align-items:stretch; justify-content:space-between;
  padding:14px;
  background:var(--s1);
  border-radius:var(--r-lg);
  border:1px solid var(--ln);
  gap:10px;
  box-shadow:var(--sh-1);
  transition:border-color .18s, box-shadow .18s, transform .12s;
  position:relative;
  overflow:hidden;
}
.theme-light .row { background:#fff; border-color:var(--ln); box-shadow:var(--sh-1); }
.row:active { transform:scale(.975); }
.row::before { content:none; }

/* Позиция уже в корзине — видно на уровне карточки, а не только по значку */
.row.in-cart {
  border-color:var(--ln-strong);
  box-shadow:0 0 0 1px var(--p-ring), var(--sh-1);
}
.row.in-cart .row-ico { background:var(--p-soft); border-color:var(--ln-strong); }

.row-l { display:flex; flex-direction:column; align-items:flex-start; gap:9px; width:100%; margin-bottom:auto; }
.row-ico {
  font-size:20px; flex-shrink:0; line-height:1;
  width:38px; height:38px;
  background:var(--s2);
  border-radius:var(--r-sm);
  display:flex; align-items:center; justify-content:center;
  border:1px solid var(--ln);
  transition:background .18s, border-color .18s;
}
.theme-light .row-ico { background:var(--s2); border-color:var(--ln); }
.row-info { width:100%; margin-top:0; }
/* Название ведёт, цена — вторична. Раньше было наоборот: цена 900/16px
   перекрикивала название 800/15px, и каталог читался как прайс-лист. */
.row-name { font-size:14.5px; font-weight:700; letter-spacing:-.01em; line-height:1.3; color:var(--t1); }
.row-sub  { font-size:12px; color:var(--t3); margin-top:4px; font-weight:400; line-height:1.35; }

/* Цена слева, действие справа — под большой палец, как принято */
.row-r {
  display:flex; flex-direction:row; justify-content:space-between; align-items:center;
  gap:8px; width:100%; margin-top:2px;
}
.row-pricing { text-align:left; min-width:0; }
.row-price {
  font-size:15px; font-weight:700; letter-spacing:-.02em; color:var(--price-color);
  font-variant-numeric:tabular-nums;
}
.row-alt {
  font-size:10.5px; color:var(--t3); margin-top:2px; font-weight:500;
  font-variant-numeric:tabular-nums; letter-spacing:.01em;
}

/* ── Add button / Stepper ───────────────────────── */
/* Основное действие карточки — заливка акцентом. Раньше кнопка была
   такой же серой плиткой, как иконка сверху, и не читалась как кнопка. */
.add-btn {
  width:38px; height:38px; border-radius:12px; cursor:pointer;
  background:var(--p); color:#fff;
  font-size:19px; font-weight:600; line-height:1;
  display:flex; align-items:center; justify-content:center;
  transition:transform .12s, background .18s, box-shadow .18s;
  flex-shrink:0;
  border:none;
  box-shadow:0 2px 8px var(--glow);
}
.theme-light .add-btn { background:var(--p); color:#fff; border:none; }
.add-btn:active { transform:scale(.88); background:var(--pd); }

/* Состояния задаются классами, а не инлайн-стилями: так их видно в CSS
   и можно менять тему, не трогая JS. */
.add-btn.is-added {
  background:var(--gr-soft); color:var(--gr);
  box-shadow:inset 0 0 0 1px currentColor; font-size:17px;
}
.add-btn.is-qty {
  background:var(--p-soft); color:var(--p);
  box-shadow:inset 0 0 0 1px var(--ln-strong);
  font-size:14px; font-weight:800; font-variant-numeric:tabular-nums;
}

.stepper {
  display:flex; align-items:center; gap:0;
  background:var(--s2); border:1px solid var(--ln); border-radius:12px;
  overflow:hidden; flex-shrink:0;
}
.step-dec, .step-inc {
  width:34px; height:34px; border:none; cursor:pointer;
  background:transparent; color:var(--t1);
  font-size:18px; font-weight:500; line-height:1;
  display:flex; align-items:center; justify-content:center;
  transition:background .12s;
}
.step-dec:active, .step-inc:active { background:var(--p-soft); }
.step-val {
  min-width:30px; text-align:center;
  font-size:14px; font-weight:800;
  padding:0 2px; color:var(--t1); font-variant-numeric:tabular-nums;
}

/* ── Rules page ─────────────────────────────────── */
.rb-num {
  width:22px; height:22px; border-radius:7px;
  background:rgba(123,108,246,.14); color:#b0a2ff;
  font-size:11px; font-weight:700;
  display:flex; align-items:center; justify-content:center;
  flex-shrink:0; margin-top:1px;
}
.theme-light .rb-num {
  background: #e0e7ff; color: #4338ca;
}
.fq-q { font-size:13.5px; font-weight:600; color: var(--t1); }
.fq-a { font-size:12.5px; color:var(--t2); margin-top:4px; line-height:1.45; }

/* ── Sheet overlay ──────────────────────────────── */
.overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.75);
  z-index: 150;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}
.overlay.on { display: block; animation: fdi .2s ease; }
@keyframes fdi { from{opacity:0} to{opacity:1} }

.sheet {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  background: #13151f;
  border-top: 1px solid var(--ln2);
  box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.85);
  border-radius: 24px 24px 0 0;
  padding: 0 18px calc(24px + env(safe-area-inset-bottom, 0px));
  z-index: 200;
  max-height: 88vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  transform: translateY(100%);
  transition: transform .3s cubic-bezier(.32,.72,0,1);
}
.theme-light .sheet {
  background: #ffffff;
  box-shadow: 0 -10px 40px rgba(0, 0, 0, 0.15);
  border-top: 1px solid rgba(0,0,0,0.08);
}
.sheet.on { transform: translateY(0); }

.sh-drag { width:36px; height:4px; background:var(--t3); border-radius:2px; margin:12px auto 18px; }
.sh-title { font-size:19px; font-weight:800; letter-spacing:-.4px; margin-bottom:16px; color:var(--t1); }

/* Cart item in sheet */
.ci {
  display:flex; align-items:center; justify-content:space-between;
  gap:10px;
  padding:11px 0;
  border-bottom:1px solid var(--ln);
}
.ci:last-child { border-bottom:none; }
.ci-name { font-size:14px; font-weight:600; color:var(--t1); flex:1; }
.ci-r { display:flex; align-items:center; gap:8px; flex-shrink:0; }
.ci-price { font-size:14px; font-weight:700; color:var(--price-color); min-width:56px; text-align:right; }
.ci-del {
  width:26px; height:26px; border-radius:7px; border:none; cursor:pointer;
  background:rgba(239,68,68,.12); color:var(--rd);
  font-size:14px; display:flex; align-items:center; justify-content:center;
  transition:background .12s;
}
.ci-del:active { background:rgba(239,68,68,.24); }

.total-row {
  display:flex; justify-content:space-between; align-items:center;
  padding:14px 0 0;
  font-size:15px; font-weight:700;
  color:var(--t1);
}
.total-sub { font-size:11.5px; color:var(--t2); margin-top:3px; }
.cart-total { font-size:19px; font-weight:800; letter-spacing:-.4px; color: var(--price-color); }

.field-lbl {
  font-size:12px; font-weight:700; letter-spacing:.8px;
  text-transform:uppercase; color:var(--t2);
  margin:16px 0 8px;
}

textarea {
  width:100%; background: var(--s1);
  border:1px solid var(--ln2); border-radius:12px;
  color:var(--t1); font-family:'Outfit',sans-serif;
  font-size:16px; padding:12px 14px;
  resize:none; min-height:80px; outline:none;
  line-height:1.5; margin-bottom:14px;
  user-select:text; -webkit-user-select:text;
  transition:border-color .15s;
}
.theme-light textarea {
  background: #f8fafc; border-color: #cbd5e1; color: #0f172a;
}
textarea::placeholder { color: var(--t3); }
textarea:focus { border-color: var(--p); }

.sh-btn {
  width:100%; padding:16px;
  background: linear-gradient(135deg, #7c6dfa, #6366f1);
  color: #ffffff; border:none; border-radius:14px;
  font-family: 'Outfit', sans-serif; font-size:16px; font-weight:800;
  cursor:pointer; box-shadow: 0 6px 22px rgba(124, 109, 250, 0.35);
  transition: opacity .15s, transform .1s; letter-spacing: 0.5px;
  text-transform: uppercase;
  margin-top: 14px;
  margin-bottom: 24px;
}
.theme-light .sh-btn {
  background: linear-gradient(135deg, #6366f1, #4f46e5);
  color: #ffffff;
  box-shadow: 0 6px 22px rgba(99, 102, 241, 0.35);
}
.sh-btn:active { opacity:.88; transform:scale(.98); }
.sh-btn:disabled { opacity:.45; }

.empty-cart {
  text-align:center; padding:28px 0 16px;
  color:var(--t3); font-size:14px; font-weight:500;
}

/* ── Success screen ─────────────────────────────── */
.success { display:none; flex-direction:column; align-items:center; text-align:center; padding:24px 0 8px; }
.success.on { display:flex; }
.s-ico {
  width:62px; height:62px; border-radius:50%;
  background:rgba(16,185,129,.12); border:1.5px solid rgba(16,185,129,.3);
  display:flex; align-items:center; justify-content:center;
  font-size:26px; margin-bottom:14px; color:var(--gr);
  animation:pop .35s cubic-bezier(.34,1.56,.64,1);
}
@keyframes pop { from{transform:scale(0);opacity:0} to{transform:scale(1);opacity:1} }
.s-title { font-size:19px; font-weight:800; letter-spacing:-.4px; margin-bottom:6px; color:var(--t1); }
.s-sub   { font-size:13.5px; color:var(--t2); line-height:1.5; margin-bottom:20px; }
.s-close {
  width:100%; padding:13px;
  background:var(--s2); border:1px solid var(--ln2);
  color:var(--t1); border-radius:13px;
  font-family:'Outfit',sans-serif; font-size:14px; font-weight:600; cursor:pointer;
}

.search-input { width:100%; padding:14px 16px; border:1px solid var(--ln); border-radius:14px; background:var(--bg-card); color:var(--t1); font-family:Outfit,sans-serif; font-size:16px; outline:none; transition:.2s; }
.theme-light .search-input { background: #ffffff; border-color: #cbd5e1; color: #0f172a; }
.search-input:focus { border-color:var(--p); box-shadow:0 0 0 2px var(--glow); }

.field-row { display:flex; gap:12px; margin-bottom:16px; }
.field-col { flex:1; display:flex; flex-direction:column; gap:6px; }
.form-input, .form-select { width:100%; padding:14px; border:1px solid var(--ln2); border-radius:12px; background:var(--s1); color:var(--t1); font-family:Outfit,sans-serif; font-size:16px; outline:none; }
.theme-light .form-input, .theme-light .form-select { background: #f8fafc; border-color: #cbd5e1; color: #0f172a; }
.form-select option { background: #13151f; color: #ffffff; }
.theme-light .form-select option { background: #ffffff; color: #0f172a; }
.form-input::placeholder { color:var(--t3); }
.form-input:focus, .form-select:focus { border-color:var(--p); }

.promo-row { display:flex; gap:8px; margin-bottom:4px; }
.promo-btn { padding:0 20px; border:none; border-radius:12px; background:var(--p); color:#ffffff; font-family:Outfit,sans-serif; font-size:15px; font-weight:700; cursor:pointer; border:1px solid var(--ln2); }
.promo-btn:active { transform:scale(0.96); }

/* ── Нижний док: корзина + навигация ──────────────────────────────────────
   Кнопка и навигация живут в одном фиксированном контейнере, поэтому не
   налезают друг на друга и не требуют угадывать отступ у body. */
.dock {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 100;
  background: var(--bg);
  border-top: 1px solid var(--ln);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}

.dock-cta-wrap { display: none; padding: 10px 12px 4px; }
body.has-cart .dock-cta-wrap { display: block; }

#cta {
  width: 100%;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px;
  background: linear-gradient(135deg, var(--p), var(--pd));
  color: #fff;
  border: none; border-radius: 16px;
  font-family: 'Outfit', sans-serif;
  cursor: pointer;
  text-align: left;
  box-shadow: 0 4px 18px var(--glow), inset 0 1px 0 rgba(255,255,255,.2);
  transition: transform .14s cubic-bezier(.16,1,.3,1), box-shadow .18s;
  animation: ctaIn .28s cubic-bezier(.34,1.35,.64,1) both;
}
@keyframes ctaIn { from{opacity:0; transform:translateY(12px)} to{opacity:1; transform:none} }
#cta:active { transform: scale(.985); box-shadow: 0 2px 10px var(--glow); }
#cta:disabled { display: none; }

.cta-l { display: flex; align-items: center; gap: 9px; min-width: 0; }
.cta-ico { font-size: 17px; line-height: 1; flex-shrink: 0; }
/* Подпись усекается, сумма — никогда: цену важнее видеть целиком. */
.cta-txt {
  font-size: 14px; font-weight: 700; letter-spacing: -.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cta-sum {
  flex-shrink: 0; text-align: right; line-height: 1.2;
  font-variant-numeric: tabular-nums;
}
.cta-sum b { display: block; font-size: 15px; font-weight: 800; letter-spacing: -.02em; }
.cta-sum i { display: block; font-size: 10.5px; font-style: normal; opacity: .82; margin-top: 1px; }

.bottom-nav {
  position: static;
  height: 58px;
  background: transparent;
  border-top: 1px solid var(--ln);
  display: flex; justify-content: space-around; align-items: center;
}
body.has-cart .bottom-nav { border-top-color: transparent; }
.theme-light .bottom-nav { background: transparent; }
.bnav-item {
  flex: 1;
  background: none; border: none;
  color: var(--t3);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  cursor: pointer; padding: 6px 0;
  transition: color .18s;
  font-family: inherit;
}
.bnav-item.active { color: var(--p); }
.theme-light .bnav-item.active { color: var(--p); }
.bnav-ico { font-size: 19px; line-height: 1; }
.bnav-lbl { font-size: 11px; font-weight: 700; letter-spacing: -.01em; }
.bnav-item.active .bnav-lbl { color: inherit; text-shadow: none; }
.theme-light .bnav-item.active .bnav-lbl { color: inherit; text-shadow: none; }

/* ── Main Screens ── */
.main-screen {
  display: none;
  animation: pg .22s ease both;
  padding-bottom: 20px;
}
.main-screen.active {
  display: block;
}

/* ── Realtime Dynamic Calculator Box ── */
.calc-card {
  margin: 14px 12px 16px;
  background: var(--s1);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border-radius: 20px;
  border: 1px solid var(--ln);
  padding: 16px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  position: relative;
  overflow: hidden;
}
.theme-light .calc-card {
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.08);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.04);
}
.calc-card::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 100%;
  background: radial-gradient(circle at top right, rgba(255,255,255,0.05), transparent 70%);
  pointer-events: none;
}
.calc-hd {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px;
}
.calc-title {
  font-size: 16px; font-weight: 800; display: flex; align-items: center; gap: 6px; color: var(--t1);
}
.calc-badge {
  font-size: 11px; font-weight: 700; background: var(--s2); padding: 3px 8px; border-radius: 8px; color: var(--p);
}
.theme-light .calc-badge {
  background: #eef2ff; color: #6366f1;
}
.calc-row {
  margin-bottom: 12px;
}
.calc-label {
  display: flex; justify-content: space-between; font-size: 13px; font-weight: 600; color: var(--t2); margin-bottom: 6px;
}
.calc-label-val {
  color: var(--t1); font-weight: 700;
}
.calc-range {
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  height: 6px;
  border-radius: 3px;
  background: var(--s2);
  border: 1px solid var(--ln);
  outline: none;
  margin: 10px 0;
}
.calc-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--p);
  cursor: pointer;
  box-shadow: 0 2px 8px var(--glow);
  border: 2px solid #ffffff;
}
.theme-light .calc-range {
  background: #e2e8f0;
  border-color: #cbd5e1;
}
.theme-light .calc-range::-webkit-slider-thumb {
  background: #6366f1;
  border: 2px solid #ffffff;
  box-shadow: 0 2px 8px rgba(99, 102, 241, 0.4);
}
.calc-options {
  display: flex; flex-direction: column; gap: 8px; margin: 12px 0;
}
.calc-opt {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 12px; border-radius: 12px;
  background: var(--s2); border: 1px solid var(--ln);
  font-size: 13px; font-weight: 600; cursor: pointer; color: var(--t1);
}
.theme-light .calc-opt {
  background: #f8fafc;
  border-color: #e2e8f0;
}
.calc-opt input {
  accent-color: var(--p); transform: scale(1.15); cursor: pointer;
}
.calc-footer {
  display: flex; align-items: center; justify-content: space-between; margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--ln);
}
.calc-price-wrap {
  display: flex; flex-direction: column;
}
.calc-price-lbl { font-size: 11px; color: var(--t2); text-transform: uppercase; font-weight: 700; }
.calc-price-num { font-size: 22px; font-weight: 900; color: var(--price-color); }
.calc-add-btn {
  padding: 10px 18px; border-radius: 12px; background: linear-gradient(135deg, var(--p), var(--pd)); color: #ffffff; font-size: 13px; font-weight: 800; border: none; cursor: pointer;
  box-shadow: 0 4px 14px var(--glow);
  transition: transform .1s;
}
.theme-light .calc-add-btn {
  background: linear-gradient(135deg, #6366f1, #4f46e5);
  box-shadow: 0 4px 14px rgba(99, 102, 241, 0.3);
}
.calc-add-btn:active { transform: scale(0.94); }

/* ── Screen: Orders ── */

.order-badge {
  font-size: 11px; font-weight: 700; padding: 4px 10px; border-radius: 10px;
}
.badge-pending { background: rgba(234, 179, 8, 0.15); color: #facc15; border: 1px solid rgba(234, 179, 8, 0.3); }
.badge-progress { background: rgba(59, 130, 246, 0.15); color: #60a5fa; border: 1px solid rgba(59, 130, 246, 0.3); }
.badge-completed { background: rgba(34, 197, 94, 0.15); color: #4ade80; border: 1px solid rgba(34, 197, 94, 0.3); }
.badge-closed { background: rgba(148, 163, 184, 0.15); color: #cbd5e1; border: 1px solid rgba(148, 163, 184, 0.3); }
.badge-disputed { background: rgba(239, 68, 68, 0.15); color: #f87171; border: 1px solid rgba(239, 68, 68, 0.3); }

.timeline-tracker::before {
  content: ''; position: absolute; top: 11px; left: 16px; right: 16px; height: 2px;
  background: var(--ln); z-index: 1;
}
/* ── Screen: Profile ── */
.profile-tier-card {
  margin: 14px 14px 16px; padding: 20px; border-radius: 20px;
  background: var(--s1);
  border: 1px solid var(--ln);
  box-shadow: 0 8px 24px rgba(0,0,0,0.4);
  display: flex; flex-direction: column; gap: 14px;
}
.theme-light .profile-tier-card {
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.08);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
}
.profile-tier-hd {
  display: flex; align-items: center; justify-content: space-between;
}
.profile-tier-badge {
  font-size: 13px; font-weight: 800; padding: 4px 12px; border-radius: 12px;
  background: var(--s2); color: var(--t1); border: 1px solid var(--ln2);
}
.theme-light .profile-tier-badge {
  background: #e0e7ff; color: #4338ca; border-color: #c7d2fe;
}
.profile-stats-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px;
}
.pstat-box {
  background: var(--s2); border: 1px solid var(--ln); border-radius: 14px; padding: 12px;
}
.theme-light .pstat-box {
  background: #f8fafc; border-color: #e2e8f0;
}
.pstat-val { font-size: 17px; font-weight: 800; color: var(--t1); }
.theme-light .pstat-val { color: #0f172a; }
.pstat-lbl { font-size: 11px; color: var(--t2); margin-top: 2px; }

.ref-box {
  background: var(--s2); border: 1px solid var(--ln); border-radius: 16px; padding: 16px; margin: 0 14px 16px;
}
.theme-light .ref-box {
  background: #f8fafc; border-color: #e2e8f0;
}
.ref-title { font-size: 14px; font-weight: 700; margin-bottom: 6px; color: var(--t1); }
.ref-desc { font-size: 12px; color: var(--t2); line-height: 1.4; margin-bottom: 12px; }
.ref-actions { display: flex; gap: 8px; }
.ref-btn {
  flex: 1; padding: 10px; border-radius: 12px; border: 1px solid var(--ln2);
  background: var(--s2); color: var(--t1); font-size: 12px; font-weight: 700; cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 5px;
}
.theme-light .ref-btn {
  background: #eef2ff; color: #4338ca; border-color: #c7d2fe;
}
.ref-btn:active { transform: scale(0.96); }

/* ── Переключатели опций калькулятора ───────────────────────────────────
   Нативный чекбокс выбивался из остального интерфейса и на мобильном
   имел слишком маленькую зону нажатия. */
.calc-opt input[type="checkbox"] {
  appearance:none; -webkit-appearance:none;
  width:42px; height:25px; border-radius:999px;
  background:var(--s3); border:1px solid var(--ln);
  position:relative; cursor:pointer; flex-shrink:0; margin:0;
  transition:background .2s, border-color .2s;
}
.calc-opt input[type="checkbox"]::after {
  content:''; position:absolute; top:2px; left:2px;
  width:19px; height:19px; border-radius:50%;
  background:var(--t2);
  transition:transform .2s cubic-bezier(.34,1.4,.64,1), background .2s;
}
.calc-opt input[type="checkbox"]:checked { background:var(--p); border-color:var(--p); }
.calc-opt input[type="checkbox"]:checked::after { transform:translateX(17px); background:#fff; }
.calc-opt input[type="checkbox"]:focus-visible { outline:2px solid var(--p); outline-offset:2px; }

/* ── Доступность ────────────────────────────────────────────────────── */
:focus-visible { outline:2px solid var(--p); outline-offset:2px; }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important; scroll-behavior:auto !important;
  }
}

.total-was { font-size:12px; color:var(--t2); margin-right:7px; font-weight:600; }
.cart-total { text-align:right; }
.cart-total b { font-weight:800; letter-spacing:-.02em; }
.total-row { align-items:flex-start; gap:14px; }

/* ── Поиск: счётчик и пустое состояние ────────────────────────────────────
   Раньше при нуле совпадений оставался просто пустой экран. */
.search-note {
  margin: 10px 12px 0; padding: 0 4px;
  font-size: 12px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--t3);
}
.search-empty {
  margin: 20px 12px; padding: 30px 22px;
  background: var(--s1); border: 1px solid var(--ln);
  border-radius: var(--r-lg); text-align: center;
}
.search-empty-ico { font-size: 30px; line-height: 1; margin-bottom: 12px; opacity: .55; }
.search-empty-t { font-size: 15.5px; font-weight: 700; color: var(--t1); margin-bottom: 7px; }
.search-empty-s { font-size: 13px; color: var(--t3); line-height: 1.5; }
.search-empty-s span { color: var(--t2); font-weight: 600; }
.search-empty-btn {
  margin-top: 16px; padding: 10px 20px;
  background: var(--p-soft); color: var(--p);
  border: 1px solid var(--ln-strong); border-radius: 12px;
  font-family: inherit; font-size: 13.5px; font-weight: 700; cursor: pointer;
}
.search-empty-btn:active { transform: scale(.97); }

/* Во время поиска вкладки категорий не нужны: показываются все совпадения. */
body.is-searching .tabwrap { display: none; }

/* ── Списание бонусов в корзине ───────────────────────────────────────── */
.bonus-row { margin: 14px 0 4px; }
.bonus-toggle {
  display: flex; align-items: center; gap: 11px;
  padding: 12px 14px; cursor: pointer;
  background: var(--s2); border: 1px solid var(--ln); border-radius: var(--r-md);
}
.bonus-toggle input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 22px; height: 22px; flex-shrink: 0; margin: 0;
  border: 2px solid var(--ln2); border-radius: 7px;
  background: transparent; position: relative; cursor: pointer;
  transition: background .18s, border-color .18s;
}
.bonus-toggle input[type="checkbox"]:checked { background: var(--p); border-color: var(--p); }
.bonus-toggle input[type="checkbox"]:checked::after {
  content: '¹3'; position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-size: 14px; font-weight: 800;
}
.bonus-txt { font-size: 14px; font-weight: 600; color: var(--t1); }
.bonus-txt b { color: var(--price-color); }
.bonus-hint { font-size: 11.5px; color: var(--t3); margin: 6px 4px 0; }

/* ── Экран «Мои заказы» ───────────────────────────────────────────────────
   Карточка строится вокруг статуса: он определяет цвет полоски слева,
   поэтому список читается взглядом, без вчитывания в текст. */
.order-card {
  margin: 10px 12px; padding: 14px 16px;
  border-radius: var(--r-lg);
  background: var(--s1);
  border: 1px solid var(--ln);
  box-shadow: var(--sh-1);
  position: relative; overflow: hidden;
}
.order-card::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--t3);
}
.order-card.st-pending::before  { background: #eab308; }
.order-card.st-progress::before { background: var(--p); }
.order-card.st-completed::before{ background: #38bdf8; }
.order-card.st-closed::before   { background: var(--gr); }
.order-card.st-disputed::before { background: var(--rd); }
.order-card.st-cancelled::before{ background: var(--t3); }

.order-card-hd {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin-bottom: 8px;
}
.order-card-id {
  font-size: 14.5px; font-weight: 800; letter-spacing: -.01em; color: var(--t1);
  font-variant-numeric: tabular-nums;
}
.order-badge {
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em;
  padding: 4px 9px; border-radius: 999px; white-space: nowrap;
}
.badge-pending   { background: rgba(234,179,8,.14);  color: #eab308; border: 1px solid rgba(234,179,8,.28); }
.badge-progress  { background: var(--p-soft);        color: var(--p); border: 1px solid var(--ln-strong); }
.badge-completed { background: rgba(56,189,248,.14); color: #38bdf8; border: 1px solid rgba(56,189,248,.28); }
.badge-closed    { background: var(--gr-soft);       color: var(--gr); border: 1px solid currentColor; }
.badge-disputed  { background: rgba(248,113,113,.14);color: var(--rd); border: 1px solid rgba(248,113,113,.28); }

.order-desc {
  font-size: 12.5px; color: var(--t3); line-height: 1.45;
  margin-bottom: 10px; word-break: break-word;
}
.order-meta {
  display: flex; flex-wrap: wrap; gap: 6px 14px;
  font-size: 12px; color: var(--t2); font-variant-numeric: tabular-nums;
}
.order-meta b { color: var(--price-color); font-weight: 700; }

/* Прогресс и срок — то, ради чего клиент сюда заходит. */
.order-progress { margin: 10px 0 4px; }
.order-progress-bar {
  height: 6px; border-radius: 999px; background: var(--s3); overflow: hidden;
}
.order-progress-fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--p), var(--pd));
  transition: width .4s cubic-bezier(.16,1,.3,1);
}
.order-progress-lbl {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--t3); margin-top: 5px;
  font-variant-numeric: tabular-nums;
}
.order-note { font-size: 12px; color: var(--t2); font-style: italic; margin-top: 6px; }

/* ── Экран «Профиль» ──────────────────────────────────────────────────────
   Ранг — главное на экране, поэтому он и получает единственный акцент. */
.profile-tier-card {
  margin: 12px 12px 14px; padding: 18px;
  border-radius: var(--r-xl);
  background: linear-gradient(150deg, var(--p-soft), transparent 62%), var(--s1);
  border: 1px solid var(--ln);
  box-shadow: var(--sh-1);
}
.profile-tier-hd { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.profile-tier-badge {
  font-size: 12px; font-weight: 800; letter-spacing: .02em;
  padding: 7px 13px; border-radius: 999px; white-space: nowrap;
  background: var(--p); color: #fff;
  box-shadow: 0 2px 10px var(--glow);
}
.profile-stats-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: 9px; margin-top: 16px;
}
.pstat-box {
  background: var(--s2); border: 1px solid var(--ln);
  border-radius: var(--r-md); padding: 12px 13px;
}
.pstat-val {
  font-size: 19px; font-weight: 800; letter-spacing: -.02em; color: var(--t1);
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.pstat-lbl {
  font-size: 10.5px; font-weight: 600; letter-spacing: .05em;
  text-transform: uppercase; color: var(--t3); margin-top: 5px;
}

.ref-box {
  background: var(--s1); border: 1px solid var(--ln);
  border-radius: var(--r-lg); padding: 16px; margin: 0 12px 14px;
}
.ref-title { font-size: 14.5px; font-weight: 700; color: var(--t1); margin-bottom: 5px; }
.ref-desc { font-size: 12.5px; color: var(--t3); line-height: 1.45; margin-bottom: 13px; }
.ref-actions { display: flex; gap: 9px; }
.ref-btn {
  flex: 1; padding: 11px 8px;
  background: var(--s2); border: 1px solid var(--ln); border-radius: var(--r-md);
  color: var(--t1); font-family: inherit; font-size: 13px; font-weight: 700;
  cursor: pointer; transition: background .16s, transform .12s;
}
.ref-btn:active { transform: scale(.97); background: var(--s3); }

/* Бонусы: строка с балансом и подсказкой, что с ним делать. */
.bonus-card {
  margin: 0 12px 14px; padding: 14px 16px;
  background: var(--price-bg); border: 1px solid var(--ln-strong);
  border-radius: var(--r-lg);
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.bonus-card-l { min-width: 0; }
.bonus-card-t { font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; color: var(--t3); }
.bonus-card-v { font-size: 22px; font-weight: 800; color: var(--price-color); font-variant-numeric: tabular-nums; margin-top: 3px; }
.bonus-card-hint { font-size: 11.5px; color: var(--t3); text-align: right; max-width: 46%; line-height: 1.35; }

/* ── Пустые состояния ─────────────────────────────────────────────────── */
.screen-empty { text-align: center; padding: 46px 26px; }
.screen-empty-ico { font-size: 34px; opacity: .5; margin-bottom: 12px; }
.screen-empty-t { font-size: 15.5px; font-weight: 700; color: var(--t1); margin-bottom: 6px; }
.screen-empty-s { font-size: 13px; color: var(--t3); line-height: 1.5; }

/* Кнопка повтора живёт в подвале карточки заказа, рядом с суммой. */
.order-actions {
  display: flex; gap: 8px; margin-top: 12px;
  padding-top: 12px; border-top: 1px solid var(--ln);
}
.order-btn {
  flex: 1; padding: 9px 12px;
  background: var(--s2); border: 1px solid var(--ln); border-radius: var(--r-md);
  color: var(--t1); font-family: inherit; font-size: 12.5px; font-weight: 700;
  cursor: pointer; transition: background .16s, transform .12s, border-color .16s;
}
.order-btn:active { transform: scale(.97); }
.order-btn-primary {
  background: var(--p-soft); border-color: var(--ln-strong);
  /* На тёмной карточке сам --p даёт контраст 4.45 — чуть ниже нормы
     для 12.5px. Осветляем ровно настолько, чтобы её перешагнуть. */
  color: #9b90ff;
}
body.theme-light .order-btn-primary { color: var(--pd); }
.order-btn:disabled { opacity: .55; cursor: default; transform: none; }

/* ══════════════════════════════════════════════════════════════════════════
   ОФОРМЛЕНИЕ v2

   Слой поверх базовых правил, а не замена им: базовая раскладка выверена,
   переделывать нужно было подачу. Что изменилось и почему — по пунктам ниже,
   развёрнуто это же лежит в ДИЗАЙН.md.

   1. Глубина. У поверхностей появилась грань света по верхнему краю и
      двойная тень: контактная и рассеянная. Одна тень читается как наклейка,
      две — как предмет. Фон перестал быть заливкой.
   2. Деньги отдельным цветом. Цена была фиолетовой, как кнопки, вкладки и
      слайдеры: выделено всё — значит ничего. Теперь янтарь, и это
      единственный тёплый цвет в интерфейсе. Название по-прежнему ведёт
      размером и позицией — решение из базовых правил не отменяю, цена
      находится температурой, а не крикливостью.
   3. Иконки. Эмодзи каждая система рисует своим набором, и цветом их не
      возьмёшь. Хром и часть каталога переведены на векторный спрайт;
      остальные эмодзи убраны в тайл-подложку, чтобы список держал ритм.
   4. Отклик. Нажатие отвечает всегда, добавление в корзину — заметно.

   Всё цветное — через переменные, обе темы обязаны работать.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  --gold:       #f5c15a;
  --gold-2:     #ffd98a;
  --gold-soft:  rgba(245, 193, 90, .13);
  --gold-ring:  rgba(245, 193, 90, .34);
  /* Грань света по верхнему краю: имитирует источник сверху, из-за неё
     карточка перестаёт быть прямоугольной заливкой. */
  --rim:        rgba(255, 255, 255, .085);
  --rim-strong: rgba(255, 255, 255, .16);
  --sh-card:    0 1px 2px rgba(0,0,0,.55), 0 14px 30px -16px rgba(0,0,0,.9);
  --sh-lift:    0 2px 4px rgba(0,0,0,.5), 0 22px 44px -20px rgba(0,0,0,.95);
  --ease:       cubic-bezier(.4, 0, .2, 1);
}

.theme-light {
  /* Золото на белом — отдельная задача. Тот же #f5c15a на светлом выцветает
     до бежевого, а если его затемнить до «читаемого» коричневого, получается
     грязь. Поэтому на свету деньги подаются не цветом текста, а плашкой:
     тёплая подложка + густой охристый текст. Плашка выглядит намеренной,
     одинокий коричневый текст — нет. */
  --gold:       #7a4e02;
  --gold-2:     #5f3c01;
  --gold-soft:  rgba(245, 193, 90, .30);
  --gold-ring:  rgba(158, 108, 12, .30);
  --rim:        rgba(255, 255, 255, .95);
  --rim-strong: #ffffff;
  /* Тени подкрашены в фиолетовый, а не серые: нейтрально-серая тень на
     светлом фоне читается как грязь под карточкой, цветная — как воздух. */
  --sh-card:    0 1px 2px rgba(40, 35, 90, .05), 0 10px 24px -12px rgba(76, 62, 160, .26);
  --sh-lift:    0 2px 6px rgba(40, 35, 90, .07), 0 22px 44px -18px rgba(76, 62, 160, .34);
}

/* ── Фон ──────────────────────────────────────────────────────────────────
   Холодное свечение сверху и уплотнение к низу. Градиент прибит к вьюпорту,
   поэтому при прокрутке экран не «едет» полосами. */
body {
  background-color: #07080f;
  background-image:
    radial-gradient(115% 55% at 50% -8%,  rgba(124,109,250,.22), transparent 62%),
    radial-gradient(70%  40% at 100% 4%,  rgba(56,189,248,.09),  transparent 60%),
    radial-gradient(60%  35% at 0%   12%, rgba(245,193,90,.05),  transparent 60%),
    linear-gradient(180deg, #0b0d1a 0%, #07080f 55%);
  background-attachment: fixed;
}
/* Светлая тема — не «тёмная наоборот». Плоская лавандовая заливка и белые
   карточки на ней сливались в одно молочное пятно: границ не видно, глубины
   нет. Фон уводится в тёплую бумагу к низу и держит холодное свечение
   сверху — так белая карточка снова становится белой на чём-то. */
body.theme-light {
  background-color: #e9ebf6;
  background-image:
    radial-gradient(120% 58% at 50% -10%, rgba(110, 96, 240, .22), transparent 64%),
    radial-gradient(75%  42% at 100% 2%,  rgba(56, 189, 248, .16), transparent 62%),
    radial-gradient(65%  45% at 0%   22%, rgba(245, 193, 90, .13), transparent 64%),
    linear-gradient(180deg, #fbfbfe 0%, #eceef8 45%, #e3e6f4 100%);
}

/* ── Шапка ─────────────────────────────────────────────────────────────── */
.hdr {
  padding: 14px 16px;
  border-bottom: 1px solid transparent;
  box-shadow: 0 1px 0 var(--ln), 0 8px 24px -18px rgba(0,0,0,.9);
}
.hdr-ico {
  width: 42px; height: 42px; border-radius: 13px;
  background: linear-gradient(150deg, #8b7cff, #5b4bd6);
  border: none;
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.34),
    0 6px 18px -6px var(--glow);
}
.hdr-ico .ic { width: 21px; height: 21px; stroke-width: 1.9; }
.hdr-h {
  font-size: 18px; font-weight: 800; letter-spacing: .01em;
  background: linear-gradient(92deg, var(--t1) 30%, #b9b0ff 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
}
.theme-light .hdr-h {
  background: linear-gradient(92deg, #12162a 30%, #4f46e5 100%);
  -webkit-background-clip: text; background-clip: text;
}
.hdr-s { font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--t3); }
.theme-toggle {
  width: 36px; height: 36px; border-radius: 11px;
  display: flex; align-items: center; justify-content: center;
  background: var(--s2); border: 1px solid var(--ln); color: var(--t2);
  box-shadow: inset 0 1px 0 var(--rim);
  transition: transform .12s var(--ease), color .18s;
}
.theme-toggle:active { transform: scale(.9) rotate(-12deg); color: var(--p); }
.theme-toggle .ic { width: 18px; height: 18px; }

/* ── Вкладки ───────────────────────────────────────────────────────────── */
.tab {
  border-bottom: none !important;
  border-radius: 999px;
  padding: 8px 13px;
  color: var(--t3);
  transition: color .18s, background .18s, box-shadow .18s;
}
.tab.on {
  color: var(--t1);
  background: linear-gradient(180deg, var(--s3), var(--s2));
  box-shadow: inset 0 1px 0 var(--rim), 0 4px 14px -8px var(--glow);
}
.tab .ic { width: 15px; height: 15px; }
.tab.on .ic { color: var(--p); }
.tabs { gap: 4px; padding: 4px 12px 8px; }
.tabwrap { border-bottom: 1px solid var(--ln); }

/* ── Поиск ─────────────────────────────────────────────────────────────── */
.search-wrap-v2 { position: relative; }
.search-wrap-v2 .ic {
  position: absolute; left: 15px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; color: var(--t3); pointer-events: none;
}
.search-input {
  padding: 13px 16px 13px 42px;
  background: linear-gradient(180deg, rgba(30, 33, 54, .82), rgba(20, 23, 38, .88));
  box-shadow: inset 0 1px 0 var(--rim), var(--sh-1);
  transition: border-color .18s, box-shadow .18s;
}
.search-input:focus {
  box-shadow: inset 0 1px 0 var(--rim), 0 0 0 3px var(--p-soft), 0 8px 20px -12px var(--glow);
}

/* ── Заголовок раздела ─────────────────────────────────────────────────── */
.sec-hd-t {
  letter-spacing: .11em;
  color: var(--t2);
  display: flex; align-items: center; gap: 9px;
}
/* Короткая черта перед заголовком: раздел начинается, а не просто набегает */
.sec-hd-t::before {
  content: ""; width: 14px; height: 2px; border-radius: 2px; flex-shrink: 0;
  background: linear-gradient(90deg, var(--p), transparent);
}

/* ── Карточка услуги ───────────────────────────────────────────────────── */
/* Поверхности тёмной темы намеренно НЕ глухие. Свечение фона живёт под
   ними и подкрашивает карточки: вверху экрана они холоднее, внизу теплее.
   С непрозрачной заливкой атмосферу было видно только в зазорах между
   карточками, то есть почти никогда — каталог закрывает экран целиком.
   Прозрачность без блюра: backdrop-filter в Telegram WebView местами не
   работает, а держаться на нём дизайн не имеет права. */
.row {
  background: linear-gradient(178deg, rgba(30, 33, 54, .84) 0%, rgba(20, 23, 38, .90) 100%);
  border-color: var(--ln);
  box-shadow: inset 0 1px 0 var(--rim), var(--sh-card);
  transition: transform .13s var(--ease), box-shadow .22s, border-color .22s;
}
.theme-light .row {
  background: linear-gradient(178deg, #fff 0%, #fbfcff 100%);
  box-shadow: inset 0 1px 0 var(--rim), var(--sh-card);
}
.row:active { transform: scale(.972); box-shadow: inset 0 1px 0 var(--rim), var(--sh-1); }

/* В корзине — тёплая грань слева, а не только рамка по периметру:
   видно боковым зрением при прокрутке. */
.row.in-cart {
  border-color: var(--ln-strong);
  box-shadow: inset 3px 0 0 var(--p), inset 0 1px 0 var(--rim), var(--sh-lift);
}

/* ── Тайл иконки ───────────────────────────────────────────────────────── */
.row-ico {
  width: 40px; height: 40px; border-radius: 13px;
  background:
    radial-gradient(130% 130% at 28% 18%, rgba(124,109,250,.30), rgba(124,109,250,.06) 70%),
    var(--s2);
  border: 1px solid var(--ln);
  box-shadow: inset 0 1px 0 var(--rim), 0 5px 14px -10px var(--glow);
  color: var(--p);
  transition: background .2s, box-shadow .2s, color .2s;
}
.theme-light .row-ico {
  background: radial-gradient(130% 130% at 28% 18%, rgba(99,102,241,.16), rgba(99,102,241,.04) 70%), #fff;
}
.row-ico .ic { width: 21px; height: 21px; }
/* Эмодзи без векторной пары: приглушаем и сажаем на ту же подложку,
   чтобы строка всё равно начиналась с пятна одного веса. */
.row-ico.is-emoji {
  font-size: 19px;
  filter: saturate(.92) contrast(1.04) drop-shadow(0 1px 2px rgba(0,0,0,.45));
}
.row.in-cart .row-ico {
  color: var(--p);
  box-shadow: inset 0 1px 0 var(--rim-strong), 0 6px 16px -8px var(--glow);
}

/* ── Текст карточки ────────────────────────────────────────────────────── */
.row-name { font-size: 15px; font-weight: 700; letter-spacing: -.015em; }
.row-price {
  font-size: 16px; font-weight: 800; letter-spacing: -.02em;
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.row-alt { color: var(--t3); opacity: .85; }

/* ── Кнопка добавления ─────────────────────────────────────────────────── */
.add-btn {
  width: 40px; height: 40px; border-radius: 13px;
  background: linear-gradient(160deg, #8b7cff, #6152d9);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.3),
    0 6px 16px -8px var(--glow);
  transition: transform .13s var(--ease), box-shadow .2s, background .2s;
}
.add-btn:active { transform: scale(.87); }
.add-btn.is-added {
  background: var(--gr-soft); color: var(--gr);
  box-shadow: inset 0 0 0 1px currentColor;
  animation: popGlow .5s var(--ease);
}
.add-btn.is-qty {
  background: linear-gradient(160deg, var(--s3), var(--s2));
  color: var(--p);
  box-shadow: inset 0 1px 0 var(--rim), inset 0 0 0 1px var(--ln-strong);
}

/* Момент, ради которого приложение и открыли, — он обязан ощущаться. */
@keyframes popGlow {
  0%   { box-shadow: inset 0 0 0 1px currentColor, 0 0 0 0 var(--gr-soft); }
  55%  { box-shadow: inset 0 0 0 1px currentColor, 0 0 0 10px transparent; }
  100% { box-shadow: inset 0 0 0 1px currentColor, 0 0 0 0 transparent; }
}

/* ── Калькулятор ───────────────────────────────────────────────────────── */
.calc-card {
  background: linear-gradient(168deg, rgba(30, 33, 54, .86) 0%, rgba(20, 23, 38, .92) 92%);
  box-shadow: inset 0 1px 0 var(--rim-strong), var(--sh-lift);
  border-color: var(--ln2);
}
.calc-title { letter-spacing: -.01em; }
.calc-badge {
  background: var(--gold-soft); color: var(--gold);
  box-shadow: inset 0 0 0 1px var(--gold-ring);
}
.calc-range::-webkit-slider-thumb {
  box-shadow: 0 0 0 4px var(--p-soft), 0 4px 12px -4px var(--glow);
}

/* ── Нижнее меню ───────────────────────────────────────────────────────── */
.bottom-nav { height: 60px; }
.bnav-item { position: relative; gap: 4px; }
.bnav-ico { display: flex; align-items: center; justify-content: center; height: 22px; }
.bnav-ico .ic { width: 22px; height: 22px; }
.bnav-item.active { color: var(--p); }
/* Точка под активным разделом вместо только цвета: понятно и боковым зрением */
.bnav-item.active::after {
  content: ""; position: absolute; bottom: 2px; left: 50%;
  width: 4px; height: 4px; margin-left: -2px; border-radius: 50%;
  background: var(--p); box-shadow: 0 0 8px var(--p);
}
.bnav-lbl { font-size: 11px; font-weight: 600; letter-spacing: .01em; }

/* ── Появление ─────────────────────────────────────────────────────────── */
/* Лесенкой и только на первых карточках раздела: анимировать весь каталог —
   значит заставить ждать. */
@keyframes riseIn {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}
.sec-rows > .row { animation: riseIn .34s var(--ease) both; }
.sec-rows > .row:nth-child(1) { animation-delay: .02s }
.sec-rows > .row:nth-child(2) { animation-delay: .05s }
.sec-rows > .row:nth-child(3) { animation-delay: .08s }
.sec-rows > .row:nth-child(4) { animation-delay: .11s }
.sec-rows > .row:nth-child(5) { animation-delay: .14s }
.sec-rows > .row:nth-child(6) { animation-delay: .17s }
.sec-rows > .row:nth-child(n+7) { animation-delay: .19s }

@media (prefers-reduced-motion: reduce) {
  .sec-rows > .row { animation: none; }
  .add-btn.is-added { animation: none; }
  * { transition-duration: .01ms !important; }
}

/* ── Цена плашкой ─────────────────────────────────────────────────────────
   Не просто цветной текст: плашка одинаково работает в обеих темах и
   становится опознавательным знаком — глаз ищет тёплый прямоугольник, а не
   читает строку целиком. На светлой теме без неё золото не живёт вовсе. */
.row-price {
  display: inline-block;
  padding: 2px 8px 3px;
  border-radius: 9px;
  background: var(--gold-soft);
  box-shadow: inset 0 0 0 1px var(--gold-ring);
  color: var(--gold);
}

/* ── Светлая тема: глубина тенью, а не рамкой ─────────────────────────── */
body.theme-light .row {
  background: #fff;
  border-color: rgba(30, 34, 78, .05);
  box-shadow: inset 0 1px 0 var(--rim), var(--sh-card);
}
body.theme-light .row:active { box-shadow: inset 0 1px 0 var(--rim), 0 1px 2px rgba(40,35,90,.08); }
body.theme-light .hdr {
  background: rgba(252, 252, 255, .88);
  box-shadow: 0 1px 0 rgba(30, 34, 78, .07), 0 10px 26px -20px rgba(76, 62, 160, .55);
}
body.theme-light .search-input {
  background: #fff;
  border-color: rgba(30, 34, 78, .09);
  box-shadow: inset 0 1px 0 var(--rim), 0 4px 12px -8px rgba(76, 62, 160, .35);
}
body.theme-light .calc-card {
  background: linear-gradient(168deg, #fff 0%, #fafbff 92%);
  border-color: rgba(30, 34, 78, .07);
}
body.theme-light .tab.on {
  background: #fff;
  box-shadow: 0 1px 0 rgba(30,34,78,.05), 0 6px 16px -10px rgba(76, 62, 160, .5);
}
body.theme-light .bottom-nav { border-top-color: rgba(30, 34, 78, .08); }

/* ── Оттенок раздела ──────────────────────────────────────────────────────
   Тринадцать разделов подряд одним фиолетовым сливались в одну ленту: на
   прокрутке непонятно, сменился раздел или нет. Теперь у каждого свой тон —
   его берут тайл иконки, черта перед заголовком и подсветка карточки.

   Тёплый янтарь в набор не входит намеренно: он означает деньги, и если
   им покрасить ещё и раздел, значение потеряется. Кнопка добавления тоже
   остаётся фирменной фиолетовой — действие должно узнаваться одинаково
   в любом разделе, разнообразие тут только мешало бы.

   Переменные проставляет скрипт по порядку разделов; если он не отработал,
   всё падает обратно на --p и выглядит как раньше. */
.sec { --acc: var(--p); --acc-lt: var(--p); }
.row-ico { color: var(--acc); }
body.theme-light .row-ico { color: var(--acc-lt); }
.row-ico {
  background:
    radial-gradient(130% 130% at 28% 18%, color-mix(in srgb, var(--acc) 30%, transparent), transparent 72%),
    var(--s2);
}
/* color-mix есть не везде: подстраховка через currentColor и прозрачность */
@supports not (background: color-mix(in srgb, red 30%, transparent)) {
  .row-ico { background: var(--s2); box-shadow: inset 0 1px 0 var(--rim), inset 0 0 0 1px currentColor; }
}
body.theme-light .row-ico {
  background:
    radial-gradient(130% 130% at 28% 18%, color-mix(in srgb, var(--acc-lt) 16%, transparent), transparent 72%),
    #fff;
  border-color: color-mix(in srgb, var(--acc-lt) 26%, transparent);
}
.sec-hd-t::before { background: linear-gradient(90deg, var(--acc), transparent); }
body.theme-light .sec-hd-t::before { background: linear-gradient(90deg, var(--acc-lt), transparent); }
.row.in-cart { box-shadow: inset 3px 0 0 var(--acc), inset 0 1px 0 var(--rim), var(--sh-lift); }
body.theme-light .row.in-cart { box-shadow: inset 3px 0 0 var(--acc-lt), inset 0 1px 0 var(--rim), var(--sh-lift); }

/* ══════════════════════════════════════════════════════════════════════════
   ТЕМА «ГЕРАЛЬДИКА» — только для администраторов

   Отсылка к Fate сделана НЕ кадрами из игры: это чужие работы Type-Moon и
   Aniplex, а страница коммерческая. Взято то, из чего Fate сама выросла —
   артурианская и жанновская геральдика: лилия, золото по чернильному синему,
   витраж, капительный шрифт. Всё нарисовано вектором здесь же, отсюда и вес
   в килобайтах вместо мегабайтов.

   Три тинктуры вместо привычной пары: золото держит структуру (рамки,
   орнамент, заголовки), червлень — действие, лазурь и прочие — разделы.
   Деньги остаются золотыми, но ЯРКИМИ и в плотной рамке: структурное золото
   приглушено до 16-30% прозрачности, поэтому цена всё равно выигрывает —
   не оттенком, так силой.

   Доступ косметический. Флаг is_admin приходит с сервера, но подделать его
   у себя в браузере может кто угодно: это выбор оформления, а не право.
   Ни один запрос к данным на него не смотрит.
   ══════════════════════════════════════════════════════════════════════════ */

body.theme-fate {
  --bg:          #070915;
  --bg-2:        #0b0e1f;
  --bg-card:     #10142b;
  --s1:          #141a35;
  --s2:          #191f42;
  --s3:          #232a55;

  --ln:          rgba(212, 175, 55, .17);
  --ln2:         rgba(212, 175, 55, .30);
  --ln-strong:   rgba(212, 175, 55, .55);
  --rim:         rgba(240, 208, 120, .16);
  --rim-strong:  rgba(240, 208, 120, .30);

  /* Действие — червлень. Красный тут цвет приказа, и на золоте он читается
     мгновенно; фиолетовый рядом с золотом выглядел бы случайным. */
  --p:           #b8253c;
  --pd:          #8e1a2e;
  --p-soft:      rgba(184, 37, 60, .18);
  --p-ring:      rgba(184, 37, 60, .40);
  --glow:        rgba(184, 37, 60, .40);

  --t1:          #f2ecd9;
  --t2:          #b5ab8d;
  --t3:          #7e7660;

  --gold:        #f0d078;
  --gold-2:      #d4af37;
  --gold-soft:   rgba(212, 175, 55, .16);
  --gold-ring:   rgba(240, 208, 120, .55);

  --gr:          #7fb069;
  --rd:          #e05263;
  --hdr-bg:      rgba(7, 9, 21, .90);

  --sh-card:     0 1px 2px rgba(0,0,0,.65), 0 16px 34px -18px rgba(0,0,0,.95);
  --sh-lift:     0 2px 5px rgba(0,0,0,.6), 0 24px 48px -20px rgba(0,0,0,1);

  --fleur: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M12 2c-1.4 1.9-1.8 3.5-1.1 5 .3.7 1.1 1.6 1.1 1.6s.8-.9 1.1-1.6c.7-1.5.3-3.1-1.1-5z'/%3E%3Cpath d='M10.8 9.6C9.2 8.2 7.3 8 6.1 9.1c-1.2 1.1-.9 3 .6 3.9.8.5 1.7.5 2.4.1-.9-.1-1.4-.9-1.1-1.7.3-.8 1.3-1.1 2.1-.6zM13.2 9.6c1.6-1.4 3.5-1.6 4.7-.5 1.2 1.1.9 3-.6 3.9-.8.5-1.7.5-2.4.1.9-.1 1.4-.9 1.1-1.7-.3-.8-1.3-1.1-2.1-.6z'/%3E%3Cpath d='M8.4 13h7.2v1.4H8.4zM11.3 14.4h1.4V19h-1.4zM9.8 19h4.4v1.4H9.8z'/%3E%3C/svg%3E");

  background-color: #070915;
  /* Витраж сверху, дамаск по всему полю. Дамаск — та же лилия, залитая и в
     5% прозрачности: узор должен угадываться, а не лезть в глаза. */
  background-image:
    radial-gradient(105% 46% at 50% -6%, rgba(212,175,55,.20), transparent 60%),
    radial-gradient(70% 38% at 50% 0%,   rgba(184,37,60,.16),  transparent 62%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='104' height='104'%3E%3Cg fill='%23d4af37' fill-opacity='.05'%3E%3Cpath d='M52 18c-4 5.4-5 9.8-2.6 13.9.9 1.6 2.6 3.4 2.6 3.4s1.7-1.8 2.6-3.4C57 27.8 56 23.4 52 18z'/%3E%3Cpath d='M47.6 36c-4.6-4.2-9.9-4.9-13.4-1.6-3.4 3.2-2.6 8.8 1.7 11.4 2.4 1.5 5.1 1.5 6.9.2-2.7-.3-4-2.6-3.2-5 .8-2.4 3.8-3.2 6.1-1.6z'/%3E%3Cpath d='M56.4 36c4.6-4.2 9.9-4.9 13.4-1.6 3.4 3.2 2.6 8.8-1.7 11.4-2.4 1.5-5.1 1.5-6.9.2 2.7-.3 4-2.6 3.2-5-.8-2.4-3.8-3.2-6.1-1.6z'/%3E%3Cpath d='M39 47h26v3H39zM50 50h4v22h-4zM44 72h16v3H44z'/%3E%3C/g%3E%3C/svg%3E"),
    linear-gradient(180deg, #0a0d20 0%, #070915 60%);
  background-attachment: fixed, fixed, fixed, fixed;
}

/* Звёзды тут не нужны — их место занял дамаск. Остаются зерно и виньетка. */
body.theme-fate::after {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.20'/%3E%3C/svg%3E"),
    radial-gradient(120% 80% at 50% 38%, transparent 52%, rgba(0,0,0,.55) 100%);
  background-size: 160px 160px, 100% 100%;
  opacity: .9;
}
body.theme-fate::before {
  background:
    radial-gradient(36% 26% at 22% 14%, rgba(212,175,55,.16), transparent 66%),
    radial-gradient(32% 24% at 78% 26%, rgba(184,37,60,.16),  transparent 64%);
}

/* Капитель на заголовках. Шрифт подгружается только при включении темы:
   грузить его всем ради оформления, которое видят двое, незачем. */
body.theme-fate .hdr-h,
body.theme-fate .sec-hd-t,
body.theme-fate .calc-title,
body.theme-fate .row-name {
  font-family: 'Cinzel', 'Outfit', Georgia, serif;
}
body.theme-fate .hdr-h {
  background: linear-gradient(96deg, #f0d078 20%, #fff3cd 55%, #d4af37 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent;
  letter-spacing: .06em;
}
body.theme-fate .sec-hd-t { letter-spacing: .16em; color: var(--gold); }
body.theme-fate .row-name { font-size: 14.5px; letter-spacing: .01em; }

/* Лилия вместо черты перед заголовком раздела */
body.theme-fate .sec-hd-t::before {
  width: 13px; height: 13px; background: none;
  -webkit-mask: var(--fleur) center/contain no-repeat;
  mask: var(--fleur) center/contain no-repeat;
  background-color: var(--acc-ft, var(--gold));
}

/* Поверхности: золотая нить по краю вместо белой */
body.theme-fate .row {
  background: linear-gradient(178deg, rgba(25, 31, 66, .82) 0%, rgba(16, 20, 43, .90) 100%);
  border-color: var(--ln);
  box-shadow: inset 0 1px 0 var(--rim), var(--sh-card);
}
body.theme-fate .calc-card {
  background: linear-gradient(168deg, rgba(25, 31, 66, .86) 0%, rgba(16, 20, 43, .92) 92%);
  border-color: var(--ln2);
  box-shadow: inset 0 1px 0 var(--rim-strong), var(--sh-lift);
}
body.theme-fate .search-input {
  background: linear-gradient(180deg, rgba(25,31,66,.8), rgba(16,20,43,.88));
  border-color: var(--ln);
}
body.theme-fate .hdr-ico {
  background: linear-gradient(150deg, #d4af37, #8a6d1a);
  box-shadow: inset 0 1px 0 rgba(255,240,200,.45), 0 6px 18px -6px rgba(212,175,55,.5);
  color: #14101f;
}
body.theme-fate .theme-toggle { color: var(--gold); border-color: var(--ln2); }

/* Цена: яркое золото в плотной рамке. */
body.theme-fate .row-price {
  color: #14101f;
  background: linear-gradient(180deg, #f0d078, #d4af37);
  box-shadow: inset 0 0 0 1px rgba(255,245,214,.6), 0 2px 8px -4px rgba(212,175,55,.7);
  font-weight: 800;
}
body.theme-fate .add-btn {
  background: linear-gradient(160deg, #c9293f, #8e1a2e);
  box-shadow: inset 0 1px 0 rgba(255,200,200,.28), 0 6px 16px -8px rgba(184,37,60,.8);
}
body.theme-fate .add-btn.is-qty {
  background: linear-gradient(160deg, var(--s3), var(--s2));
  color: var(--gold);
  box-shadow: inset 0 1px 0 var(--rim), inset 0 0 0 1px var(--ln-strong);
}
body.theme-fate .tab.on {
  background: linear-gradient(180deg, rgba(35,42,85,.9), rgba(25,31,66,.9));
  box-shadow: inset 0 1px 0 var(--rim), 0 4px 14px -8px rgba(212,175,55,.45);
  color: var(--gold);
}
body.theme-fate .tab.on .ic { color: var(--gold); }
body.theme-fate .bnav-item.active { color: var(--gold); }
body.theme-fate .bnav-item.active::after { background: var(--gold); box-shadow: 0 0 8px var(--gold); }
body.theme-fate .calc-badge {
  background: rgba(184,37,60,.18); color: #f0a6b2;
  box-shadow: inset 0 0 0 1px rgba(184,37,60,.45);
}

/* Тинктуры разделам: золото, червлень, лазурь, серебро, зелень, пурпур */
body.theme-fate .row-ico {
  color: var(--acc-ft, var(--gold));
  background:
    radial-gradient(130% 130% at 28% 18%, color-mix(in srgb, var(--acc-ft, #d4af37) 26%, transparent), transparent 72%),
    var(--s2);
  border-color: var(--ln);
}
body.theme-fate .row.in-cart {
  box-shadow: inset 3px 0 0 var(--acc-ft, var(--gold)), inset 0 1px 0 var(--rim), var(--sh-lift);
  border-color: var(--ln-strong);
}

/* ── Деньги на всех экранах, а не только в каталоге ───────────────────────
   Правило «тёплый цвет означает деньги» держалось ровно на одном экране из
   трёх. В корзине — там, где на суммы и смотрят, — цена и итог были обычным
   белым текстом, неотличимым от названия услуги. Это не придирка к оттенку:
   приём, который работает не везде, не работает вовсе.

   Плашку здесь не вешаем: в чеке числа стоят столбцом, и подложка под
   каждым превратила бы его в лоскутное одеяло. Хватает цвета и цифр
   одинаковой ширины. */
.ci-price,
.cart-total,
.is-money {
  color: var(--gold);
  font-variant-numeric: tabular-nums;
}
.cart-total { font-weight: 800; letter-spacing: -.02em; }
body.theme-light .ci-price,
body.theme-light .cart-total,
body.theme-light .is-money { color: var(--gold); }

/* Итог в чеке — главное число экрана, ему и вес. */
.total-row { align-items: baseline; }

/* ── Иерархия действий в чеке ─────────────────────────────────────────────
   «Применить» у промокода была залита тем же акцентом, что и «Оформить
   заказ», и одинаково с ней кричала. Две главные кнопки на экране — это ни
   одной главной: глаз выбирает между ними вместо того, чтобы идти к оплате.
   Промокод — вспомогательное действие, и выглядеть должен вспомогательно. */
.promo-btn {
  background: linear-gradient(180deg, var(--s3), var(--s2));
  color: var(--t1);
  box-shadow: inset 0 1px 0 var(--rim), inset 0 0 0 1px var(--ln2);
}
.promo-btn:active { transform: scale(.96); }
body.theme-light .promo-btn {
  background: #fff;
  color: var(--p);
  box-shadow: inset 0 0 0 1px var(--ln2), var(--sh-1);
}
body.theme-fate .promo-btn { color: var(--gold); }

/* ── Выпадающий список ────────────────────────────────────────────────────
   Родной select рисуется системой: своя стрелка, свой шрифт, свои поля. На
   тёмной теме он читался чужим элементом, случайно попавшим в интерфейс.
   Снимаем системную отделку и рисуем стрелку сами — тем же вектором, что
   и остальные значки. */
.form-select {
  -webkit-appearance: none; appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239aa3bd' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  background-size: 17px 17px;
  box-shadow: inset 0 1px 0 var(--rim), var(--sh-1);
}
body.theme-light .form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23545c78' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
body.theme-fate .form-select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23f0d078' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
/* Раскрытый список рисует система, и тёмного фона он не знает — задаём
   цвета пунктам явно, иначе на Android они белые на белом. */
.form-select option { background: var(--bg-card); color: var(--t1); }

/* ── Плотность чека ───────────────────────────────────────────────────────
   Лист корзины занимал 621 пиксель из 812 — три четверти экрана ради одной
   позиции. Итог уезжал под сгиб, и человек оформлял заказ, не видя суммы.

   Мерил по блокам, а не на глаз. Тридцать пикселей тратили блоки, которых
   на экране НЕТ: пустой контейнер и строка списания бонусов при нулевом
   балансе сохраняли свои внешние отступы. Ещё восемьдесят — поле
   комментария, пустое по умолчанию, и поля высотой 52–55 пикселей, набранные
   подряд.

   Ничего не выброшено, всё на месте — просто перестало занимать место
   впустую. */

/* Скрытого блока на экране нет, значит и отступов у него быть не должно. */
#cart-form > div:empty { margin: 0 !important; }
.bonus-row:not(.on) { margin: 0 !important; }

/* Поля и кнопки: 52–55 → 46–50. Палец попадает и в 46. */
#cart-form .form-select,
#cart-form input[type="text"],
#cart-form .promo-btn { height: 46px; }
#cart-form .sh-btn { height: 50px; margin: 12px 0 16px; }

/* Метка над полем: 16 сверху и 8 снизу — это полторы строки воздуха
   на каждую подпись из одного слова. */
#cart-form .field-lbl { margin: 10px 0 6px; }
#cart-form .sh-title { margin-bottom: 12px; }
#cart-form .field-row { margin-bottom: 10px; }
#cart-form .promo-row { margin-bottom: 2px; }

/* Комментарий пустой у большинства заказов: начинаем с двух строк и растём
   по мере ввода. Восемьдесят пикселей под пустое поле — расточительство. */
#cart-form textarea {
  min-height: 52px;
  height: 52px;
  margin-bottom: 10px;
  resize: none;
  transition: height .15s var(--ease);
}
#cart-form textarea:focus { height: 88px; }

/* Комментарий нужен меньшинству заказов, а место занимал у всех.
   Прячем за ссылку: нужен — раскрывается по нажатию и сразу получает
   курсор; не нужен — не отнимает восемьдесят пикселей у итога. */
.comment-toggle {
  display: flex; align-items: center; gap: 7px;
  margin: 4px 0 12px;
  padding: 9px 12px;
  border: 1px dashed var(--ln2);
  border-radius: 12px;
  background: transparent;
  color: var(--t2);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
  transition: transform .12s var(--ease), border-color .18s, color .18s;
}
.comment-toggle:active { transform: scale(.97); }
.comment-toggle .ic { width: 15px; height: 15px; }
.comment-hidden { display: none !important; }

/* Подписи полей повторяют то, что и так написано внутри поля
   («Введите UID», «Введите код…»), поэтому им хватает одной строки без
   воздуха вокруг. */
#cart-form .field-lbl { margin: 8px 0 5px; font-size: 10.5px; }

/* ── Второй проход по плотности чека ──────────────────────────────────────
   После первого прохода лист занимал 479 пикселей. Промерил остаток по
   блокам — и снова нашёл места, где пиксели уходят ни на что:

   * 34 пикселя на полоску-хватку высотой ЧЕТЫРЕ пикселя (поля 12 и 18);
   * 27 — на подпись «Промокод» над полем, внутри которого написано
     «Введите код…». Подпись повторяет плейсхолдер слово в слово;
   * 28 — поля вокруг кнопки, при том что снизу у листа есть своё поле;
   * 57 — итог, где заголовок, пояснение и сумма стоят с запасом.

   Подпись убираем из виду, но не из разметки: экранный диктор её читает,
   а глазу она не нужна — поле само себя объясняет. */
#cart-form .sh-drag, .sheet .sh-drag { margin: 8px auto 10px; }

/* Подпись, дублирующая плейсхолдер, прячется от глаз и остаётся для
   озвучки. display:none тут нельзя — диктор пропустит её вместе с полем. */
#cart-form .field-lbl.dup-lbl {
  position: absolute;
  width: 1px; height: 1px;
  margin: 0; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

#cart-form .sh-btn { margin: 10px 0 4px; }
#cart-form .comment-toggle { margin: 2px 0 8px; }

/* Итог: строка и пояснение ближе друг к другу, сумма крупнее. */
.total-row { padding: 2px 0 6px; }
.total-sub { margin-top: 1px; line-height: 1.25; }

/* ── Устаревшая сессия ────────────────────────────────────────────────────
   Подпись Telegram (initData) живёт час — это защита от повторного
   проигрывания запросов, и трогать её нельзя. Проблема в другом: Telegram
   восстанавливает мини-приложение из своего кэша вместе со вчерашней
   подписью, страница об этом молчит, и человек узнаёт правду на кнопке
   «Оформить» — собрав корзину, выбрав сервер, введя UID.

   Поэтому предупреждение показывается сразу: сверху, поперёк экрана, с
   кнопкой, которая закрывает приложение. Следующее открытие через бота
   выдаст свежую подпись. */
.stale-bar {
  position: fixed; left: 0; right: 0; top: 0; z-index: 200;
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px calc(11px + env(safe-area-inset-top, 0px));
  background: linear-gradient(180deg, #b8253c, #8e1a2e);
  color: #fff5f5;
  box-shadow: 0 10px 26px -14px rgba(0,0,0,.9);
  font-size: 13px; line-height: 1.35;
  animation: riseIn .3s var(--ease) both;
}
.stale-bar .ic { width: 19px; height: 19px; flex-shrink: 0; }
.stale-bar b { display: block; font-size: 13.5px; }
.stale-bar span { display: block; opacity: .85; font-size: 12px; margin-top: 1px; }
.stale-bar button {
  margin-left: auto; flex-shrink: 0;
  border: none; border-radius: 10px; cursor: pointer;
  padding: 9px 13px;
  background: rgba(255,255,255,.16);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.28);
  color: #fff; font-family: inherit; font-size: 12.5px; font-weight: 700;
  transition: transform .12s var(--ease), background .18s;
}
.stale-bar button:active { transform: scale(.94); background: rgba(255,255,255,.26); }
body.has-stale { padding-top: 58px; }

/* ── Атмосфера ────────────────────────────────────────────────────────────
   Два слоя за контентом, ни одной картинки: страница идёт через Funnel,
   и каждый лишний килобайт платится трафиком на каждом открытии.

   Оба слоя прибиты к вьюпорту и вынесены из потока, поэтому прокрутка
   списка их не трогает. Движется только нижний и только через transform —
   анимировать background-position значит перерисовывать весь экран каждый
   кадр, на телефоне это видно сразу. */
body::before {
  content: ""; position: fixed; inset: -20%; z-index: -2; pointer-events: none;
  background:
    radial-gradient(38% 30% at 20% 16%, rgba(124,109,250,.34), transparent 68%),
    radial-gradient(34% 26% at 80% 28%, rgba(56,189,248,.20), transparent 66%),
    radial-gradient(30% 26% at 58% 74%, rgba(245,193,90,.11), transparent 66%);
  animation: drift 52s ease-in-out infinite alternate;
  will-change: transform;
}
@keyframes drift {
  from { transform: translate3d(-2%, -1%, 0) scale(1); }
  to   { transform: translate3d(3%, 2%, 0) scale(1.09); }
}

/* Звёзды и зерно одним слоем.
   Звёзды — одна плитка 320×320, которая повторяется: двенадцать точек в
   разметке вместо тысячи элементов. Зерно — SVG-турбулентность в data-URI,
   пара сотен байт; без него большие градиенты на дешёвых экранах идут
   ступеньками. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background-image:
    radial-gradient(1.1px 1.1px at 24px 38px,  rgba(255,255,255,.55), transparent),
    radial-gradient(1px 1px   at 118px 92px,   rgba(255,255,255,.40), transparent),
    radial-gradient(1.4px 1.4px at 210px 46px, rgba(201,194,255,.50), transparent),
    radial-gradient(1px 1px   at 286px 150px,  rgba(255,255,255,.35), transparent),
    radial-gradient(1.2px 1.2px at 62px 188px, rgba(255,255,255,.45), transparent),
    radial-gradient(1px 1px   at 168px 246px,  rgba(245,193,90,.40),  transparent),
    radial-gradient(1.3px 1.3px at 252px 292px, rgba(255,255,255,.42), transparent),
    radial-gradient(1px 1px   at 12px 268px,   rgba(255,255,255,.30), transparent),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.22'/%3E%3C/svg%3E"),
    radial-gradient(120% 80% at 50% 40%, transparent 55%, rgba(0,0,0,.42) 100%);
  background-size: 320px 320px, 320px 320px, 320px 320px, 320px 320px,
                   320px 320px, 320px 320px, 320px 320px, 320px 320px,
                   160px 160px, 100% 100%;
  opacity: .85;
}
/* В светлой теме звёзд быть не должно, а зерно и виньетка остаются:
   первое убирает ступеньки градиента, вторая держит края экрана. */
.theme-light::after, body.theme-light::after {
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='.16'/%3E%3C/svg%3E"),
    radial-gradient(120% 80% at 50% 40%, transparent 62%, rgba(23,27,56,.10) 100%);
  background-size: 160px 160px, 100% 100%;
  opacity: .5;
}
.theme-light::before, body.theme-light::before {
  background:
    radial-gradient(38% 30% at 20% 16%, rgba(99,102,241,.20), transparent 68%),
    radial-gradient(34% 26% at 80% 28%, rgba(56,189,248,.14), transparent 66%);
}

@media (prefers-reduced-motion: reduce) {
  body::before { animation: none; }
}

/* Строка, начинающаяся с иконки: калькулятор и его переключатели */
.lead-ic { display: flex; align-items: center; gap: 8px; }
.lead-ic .ic { width: 17px; height: 17px; color: var(--p); }
.calc-title.lead-ic .ic { width: 19px; height: 19px; }
body.theme-fate .lead-ic .ic { color: var(--gold); }

/* Итог калькулятора — те же деньги, что и в карточках, значит тот же цвет.
   Плашку тут не вешаем: число крупное, и подложка под ним выглядит ценником
   на витрине, а не итогом расчёта. */
.calc-price-num {
  color: var(--gold);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
body.theme-fate .calc-price-num { color: var(--gold); }

/* Общее для всех иконок спрайта.
   Обводка задаётся здесь, а не атрибутами на корне спрайта: через <use>
   presentation-атрибуты родителя не наследуются, и иконка приезжает с
   fill:black / stroke:none — то есть чёрным пятном вместо контура. */
.ic {
  display: block; flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Размер по умолчанию — страховка, а не оформление.
     У <svg> без width/height и без intrinsic-размера браузер подставляет
     СВОЙ умолчательный: 300×150. Ровно это и случилось с кнопкой корзины —
     значок раздулся до 300×150, кнопка выросла со стандартных 56 до 174
     пикселей, и снаружи это выглядело как «огромная корзина». Причина была
     не в вёрстке корзины, а в одном ненаписанном правиле.
     Теперь забытое правило даёт значок нормального размера, а не монстра. */
  width: 18px;
  height: 18px;
}

/* Кнопка корзины: значок крупнее прочих, это главное действие экрана. */
.cta-ico .ic { width: 22px; height: 22px; }

