/* ============================================================
   Fbenz — design system (reference: Fineapp).
   Clean rounded cards · racing red accent · deep-navy dark + light.
   ============================================================ */
:root{
  --red:#EF0C3B; --red-2:#FF2E56; --red-soft:rgba(239,12,59,.14);
  /* status semantics (distinct from brand red; always paired with icon+label) */
  --st-yes:#25D07A; --st-queue:#FF9F2E; --st-low:#FFCE3A; --st-no:#C9455C; --st-nodata:#565B72;
  --st-yes-bg:rgba(37,208,122,.15); --st-queue-bg:rgba(255,159,46,.12);
  --st-low-bg:rgba(255,206,58,.16); --st-no-bg:rgba(201,69,92,.15); --st-nodata-bg:rgba(86,91,114,.14);
  --r:20px; --r-sm:14px; --r-lg:26px; --r-pill:999px;
  --f:"Onest",system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  --sheet-max:520px; --panel-w:392px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --safe-b:env(safe-area-inset-bottom,0px);
  --maint-h:0px;   /* height of the tech-works banner, measured live (0 when hidden) */
}
html[data-theme="dark"]{
  --bg:#14151E; --surface:#1F2230; --surface-2:#252839; --surface-3:#2F3348;
  --text:#EEF0F8; --text-2:#A4A9C6; --text-3:#71769A;
  --line:rgba(255,255,255,.08); --line-2:rgba(255,255,255,.13);
  --btn-fill:#DFE2EF; --btn-fill-text:#15172A;   /* soft off-white CTA (pure white was too bright) */
  --shadow:0 18px 50px rgba(0,0,0,.45); --shadow-sm:0 6px 20px rgba(0,0,0,.35);
  --glow:radial-gradient(120% 90% at 100% 0%, rgba(232,19,43,.14), transparent 55%);
  /* darken the light "voyager" tiles into a clean dark map (no dark_all tile-edge banding) */
  --tile-filter:invert(1) hue-rotate(180deg) brightness(.92) contrast(.9) saturate(.85);
}
html[data-theme="light"]{
  --bg:#F1F2F5; --surface:#FFFFFF; --surface-2:#F6F7F9; --surface-3:#ECEEF2;
  --text:#181B2B; --text-2:#5A5F76; --text-3:#9499AE;
  --line:rgba(20,22,45,.09); --line-2:rgba(20,22,45,.14);
  --btn-fill:#23263C; --btn-fill-text:#FFFFFF;
  --shadow:0 18px 50px rgba(60,64,90,.20); --shadow-sm:0 6px 18px rgba(60,64,90,.14);
  --glow:radial-gradient(120% 90% at 100% 0%, rgba(232,19,43,.07), transparent 55%);
  --tile-filter:none;
  /* darker status hues for WCAG-AA contrast on the light surface */
  --st-yes:#0F8F53; --st-queue:#A85C0C; --st-low:#846800; --st-no:#B03047; --st-nodata:#767C90;
}
*{box-sizing:border-box}
/* No pinch / double-tap zoom of the UI — only the Leaflet map zooms. touch-action must sit on the
   element actually under the fingers, so disable zoom-gestures broadly, then hand the map back its
   own (none = Leaflet drives pan+pinch itself). */
*{touch-action:pan-x pan-y}
.leaflet-container,.leaflet-container *{touch-action:none}
html,body{height:100%;margin:0;overscroll-behavior:none}
body{
  font-family:var(--f); background:var(--bg); color:var(--text);
  overflow:hidden; -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  font-size:15px; line-height:1.45;
  position:fixed; width:100%;   /* pin the layout so the keyboard can't drag the whole page (iOS) */
}
button{font-family:inherit;cursor:pointer;color:inherit;border:0;background:none}
a{color:inherit;text-decoration:none}
:focus-visible{outline:2.5px solid var(--red);outline-offset:2px;border-radius:8px}
::-webkit-scrollbar{width:8px;height:8px}
::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:8px}

/* ---------------- MAP ---------------- */
#map{position:fixed;inset:0;z-index:1;background:var(--bg)}
.leaflet-container{background:var(--bg);font-family:var(--f)}
.leaflet-tile-pane{filter:var(--tile-filter)}
.leaflet-control-zoom{display:none}   /* mobile zooms by pinch; desktop gets styled +/- buttons below */
@media (min-width:1024px){
  /* «.leaflet-bottom .leaflet-control-zoom» beats Leaflet's own margin rule so it clears FAB+tabbar */
  .leaflet-bottom .leaflet-control-zoom{display:flex;flex-direction:column;margin:0 24px 150px 0;border:0;
    border-radius:12px;overflow:hidden;box-shadow:var(--shadow-sm)}
  .leaflet-control-zoom a{width:40px;height:40px;line-height:40px;font-size:20px;font-weight:700;
    background:var(--surface);color:var(--text);border:1px solid var(--line)}
  .leaflet-control-zoom a:first-child{border-bottom:0}
  .leaflet-control-zoom a:hover{background:var(--surface-2);color:var(--red)}
  .leaflet-control-zoom a.leaflet-disabled{color:var(--text-3)}
}
.leaflet-control-attribution{
  background:transparent!important;color:var(--text-3)!important;font-size:10px;
  padding:2px 6px;backdrop-filter:blur(4px);
}
.leaflet-control-attribution a{color:var(--text-3)!important}

/* marker pin (status colored) */
.pin{
  width:30px;height:30px;border-radius:50% 50% 50% 0;transform:rotate(-45deg);
  display:grid;place-items:center;border:2.5px solid #fff;
  box-shadow:0 4px 10px rgba(0,0,0,.4);
}
.pin svg{width:15px;height:15px;transform:rotate(45deg);fill:#fff}
.pin.s-yes{background:var(--st-yes)} .pin.s-queue{background:var(--st-queue)}
.pin.s-low{background:var(--st-low)} .pin.s-no{background:var(--st-no)}
.pin.s-nodata{background:var(--st-nodata)}
.pin.s-low svg{fill:#3a2f00}
/* ===== gdebenz-style pump pin (unbranded АЗС) — teardrop + fuel-pump glyph + status glow ===== */
.gpin{position:relative;width:34px;height:40px}
.gpin-body{position:absolute;left:50%;top:1px;width:30px;height:30px;margin-left:-15px;z-index:2;
  border-radius:50% 50% 50% 0;transform:rotate(-45deg);display:grid;place-items:center;
  border:2.5px solid #fff;box-shadow:0 4px 9px rgba(0,0,0,.42);background:var(--st-nodata)}
.gpin-body svg{width:16px;height:16px;transform:rotate(45deg);fill:#fff}
.gpin.s-yes .gpin-body{background:var(--st-yes)} .gpin.s-queue .gpin-body{background:var(--st-queue)}
.gpin.s-low .gpin-body{background:var(--st-low)} .gpin.s-no .gpin-body{background:var(--st-no)}
.gpin.s-nodata .gpin-body{background:var(--st-nodata)}
.gpin.s-low .gpin-body svg{fill:#3a2f00}
/* soft status glow behind the pin head (the gdebenz "halo" look) */
.gpin-glow{position:absolute;left:50%;top:4px;width:32px;height:32px;margin-left:-16px;z-index:1;
  border-radius:50%;background:var(--st-nodata);filter:blur(8px);opacity:.75}
.gpin.s-yes .gpin-glow{background:var(--st-yes)} .gpin.s-queue .gpin-glow{background:var(--st-queue)}
.gpin.s-no .gpin-glow{background:var(--st-no);opacity:.9} .gpin.s-low .gpin-glow{background:var(--st-low)}
.gpin.s-nodata .gpin-glow{opacity:.4}
.gpin.match .gpin-body{box-shadow:0 0 0 3px #FFC83A,0 4px 9px rgba(0,0,0,.5)}
.gpin.is-active{z-index:1000}
.gpin.is-active .gpin-body{transform:rotate(-45deg) scale(1.12)}
.gpin-just .gpin-body{animation:gpin-pop .55s var(--ease)}
@keyframes gpin-pop{0%{transform:rotate(-45deg) scale(.55)}55%{transform:rotate(-45deg) scale(1.18)}100%{transform:rotate(-45deg) scale(1)}}
/* user "you are here" dot */
.user-dot{width:16px;height:16px;border-radius:50%;background:#2b8cff;border:3px solid #fff;
  box-shadow:0 0 0 1.5px rgba(43,140,255,.5),0 2px 7px rgba(0,0,0,.45);position:relative}
.user-dot::before{content:"";position:absolute;left:50%;top:50%;width:16px;height:16px;
  margin:-8px 0 0 -8px;border-radius:50%;background:rgba(43,140,255,.45);
  animation:userPulse 2.2s ease-out infinite}
@keyframes userPulse{0%{transform:scale(1);opacity:.7}100%{transform:scale(3);opacity:0}}
/* cluster bubble */
.cl{
  width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  font-weight:800;font-size:14px;color:#fff;border:3px solid rgba(255,255,255,.85);
  background:#3a3f63;box-shadow:0 6px 16px rgba(0,0,0,.4)}
.cl.big{width:50px;height:50px;font-size:16px}
/* cluster tinted by best status inside (visible when zoomed out) */
.cl.s-yes{background:var(--st-yes)} .cl.s-queue{background:var(--st-queue)}
.cl.s-low{background:var(--st-low);color:#3a2f00} .cl.s-no{background:var(--st-no)}
/* cluster pie ring: a conic-gradient of the status mix inside + a dark centre with the count */
.clp{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;position:relative;
  box-shadow:0 6px 16px rgba(0,0,0,.42)}
.clp::before{content:"";position:absolute;inset:5px;border-radius:50%;background:#1c1e30}
.clp span{position:relative;z-index:1;font-weight:800;font-size:14px;color:#fff}
.clp.big{width:54px;height:54px}.clp.big::before{inset:6px}.clp.big span{font-size:16px}

/* ===== FBENZ MARKER SYSTEM — "Living-Drop" (brand coin + status halo) =====
   brand = the COIN's fill (static). status = animated HALO + a static ring baked into the
   coin's box-shadow (so status reads even paused / reduced-motion / mid-pan). */
.leaflet-div-icon{background:transparent;border:0}
.fmk{position:relative;width:36px;height:36px;--sc:var(--st-nodata)}
.fmk i{position:absolute;top:50%;left:50%;border-radius:50%}
/* static status glow behind brand coins (gdebenz colored-halo look; separate from the sonar halo) */
.fmk::after{content:"";position:absolute;top:50%;left:50%;width:26px;height:26px;margin:-13px 0 0 -13px;
  border-radius:50%;background:var(--sc);filter:blur(8px);opacity:.55;z-index:0;pointer-events:none}
.fmk.s-nodata::after{opacity:.3}
.fmk.s-no::after{opacity:.8}
.fmk-coin{width:26px;height:26px;margin:-13px 0 0 -13px;display:grid;place-items:center;
  background:var(--bc,#3a3f63);color:var(--bf,#fff);font:800 12.5px/1 var(--f);letter-spacing:-.3px;
  box-shadow:0 0 0 2px #fff,0 0 0 4.5px var(--sc),0 3px 8px rgba(0,0,0,.45);z-index:3;user-select:none}
.fmk-coin svg{display:block;width:15px;height:15px;fill:currentColor}
.fmk-halo{width:26px;height:26px;margin:-13px 0 0 -13px;box-shadow:0 0 0 3px var(--sc);
  opacity:0;z-index:1;pointer-events:none}
.fmk.s-yes{--sc:var(--st-yes)} .fmk.s-queue{--sc:var(--st-queue)} .fmk.s-low{--sc:var(--st-low)}
.fmk.s-no{--sc:var(--st-no)} .fmk.s-nodata{--sc:var(--st-nodata)}
.fmk.s-nodata .fmk-coin{box-shadow:0 0 0 2px #fff,0 0 0 4px var(--sc),0 3px 8px rgba(0,0,0,.45)}
.fmk.b-generic{--bc:var(--surface-3);--bf:var(--text-2)}
html[data-theme="dark"] .fmk.b-generic{--bf:#fff}   /* white pump on the dark generic coin */
.fmk-drop{width:17px;height:17px}.fmk-drop .body{fill:var(--red)}.fmk-drop .hl{fill:#fff}
/* gold ring = "this АЗС has the fuel you filtered for" */
.fmk.match .fmk-coin{box-shadow:0 0 0 2px #fff,0 0 0 4.5px var(--sc),0 0 0 7px #FFC83A,0 4px 9px rgba(0,0,0,.5)}
.fmk.is-active{z-index:1000}
.fmk.is-active .fmk-coin{transform:scale(1.1);transition:transform .14s var(--ease)}

/* ----- alive sonar halo: animate ONLY transform+opacity (GPU); runs only while map idle ----- */
.fmk.s-yes   .fmk-halo{animation:fb-sonar   2.6s var(--ease)  var(--d,0s) infinite}
.fmk.s-low   .fmk-halo{animation:fb-sonar   3.3s var(--ease)  var(--d,0s) infinite}
.fmk.s-queue .fmk-halo{animation:fb-shimmer 2.1s ease-in-out  var(--d,0s) infinite}
/* «нет» — не учащённый соннар, а маячок: два быстрых кольца подряд и тишина.
   Ритм отличает статус на слух глаза, даже когда цвет уже примелькался. */
.fmk.s-no    .fmk-halo{animation:fb-alert   2.2s var(--ease)  var(--d,0s) infinite}
.fmk.s-nodata .fmk-halo{animation:none;opacity:0}
.fmk-halo{animation-play-state:paused}
.leaflet-container.fb-live .fmk-halo{animation-play-state:running}
.leaflet-dragging .fmk-halo,.leaflet-zoom-anim .fmk-halo{animation-play-state:paused}
@keyframes fb-sonar{0%{transform:scale(1);opacity:.5}70%{opacity:0}100%{transform:scale(2.1);opacity:0}}
@keyframes fb-shimmer{0%,100%{transform:scale(1);opacity:.18}50%{transform:scale(1.22);opacity:.48}}
@keyframes fb-alert{
  0%{transform:scale(1);opacity:.62}
  18%{transform:scale(1.95);opacity:0}
  20%{transform:scale(1);opacity:.62}
  38%{transform:scale(1.95);opacity:0}
  100%{transform:scale(1.95);opacity:0}
}

/* ----- дыхание статусного пятна -----
   Пятно .fmk::after уже существует и уже имеет свой композиторный слой от filter:blur.
   Анимируем у него ТОЛЬКО opacity: новых слоёв ноль, стоимость кадра не меняется.
   Второй filter на маркер добавлять нельзя — блюр на каждой монете и так самая
   дорогая статья на карте. Периоды держим в полосе проекта 1.25-3.3 с,
   стартовая фаза берётся из того же --d, что у соннара, поэтому сотня маркеров
   дышит вразнобой, а не марширует. */
.fmk::after{animation:fb-glow-yes 3.2s ease-in-out var(--d,0s) infinite;animation-play-state:paused}
.fmk.s-no::after{animation:fb-glow-no 2.2s ease-in-out var(--d,0s) infinite}
.fmk.s-nodata::after{animation:fb-glow-dim 3.2s ease-in-out var(--d,0s) infinite}
.leaflet-container.fb-live .fmk::after{animation-play-state:running}
.leaflet-dragging .fmk::after,.leaflet-zoom-anim .fmk::after{animation-play-state:paused}
@keyframes fb-glow-yes{0%,100%{opacity:.45}50%{opacity:.72}}
/* у «нет» вспышка совпадает с кольцами маячка, а не живёт своим ритмом */
@keyframes fb-glow-no{0%,100%{opacity:.62}9%{opacity:.95}19%{opacity:.62}29%{opacity:.95}45%{opacity:.62}}
@keyframes fb-glow-dim{0%,100%{opacity:.22}50%{opacity:.36}}
/* "1 голос засчитан" — a real one-shot spring+ping, not a checkmark */
.fmk.fb-just .fmk-coin{animation:fb-pop .6s var(--ease)}
.fmk.fb-just .fmk-halo{animation:fb-ping .66s var(--ease);animation-play-state:running!important}
@keyframes fb-pop{0%{transform:scale(.5)}55%{transform:scale(1.16)}100%{transform:scale(1)}}
@keyframes fb-ping{0%{transform:scale(1);opacity:.85}100%{transform:scale(2.5);opacity:0}}

/* ----- подпись под маркером: какие марки есть на этой АЗС -----
   Позиционная сетка: пять ячеек 92/95/98/100/ДТ всегда на своих местах и одной ширины.
   Доступная марка горит зелёным, недоступная гаснет. Ширина подписи постоянная, поэтому
   ряды монет не «дышат», а глаз читает рисунок, а не текст: одинаковые АЗС дают
   одинаковый паттерн, и различия выпрыгивают сами.
   Живёт вне габарита иконки (36x36) — overflow у .fmk не скрыт. pointer-events:none
   обязателен: Leaflet кладёт маркеры по широте, и подпись перехватывала бы клики соседей. */
.fmk-fuels{position:absolute;top:calc(50% + 16px);left:50%;transform:translateX(-50%);
  display:flex;gap:1px;padding:2px 5px;border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm);
  pointer-events:none;z-index:2;white-space:nowrap;
  opacity:0;transition:opacity .18s var(--ease)}
.fmk-fuels s{text-decoration:none;display:block;width:17px;text-align:center;
  font:800 8.5px/1.5 var(--f);color:var(--st-yes);letter-spacing:-.2px}
.fmk-fuels s.off{color:var(--text-3);opacity:.4}
/* Подпись чужой сети печатает её собственные названия («G-95», «ДТл»), а они длиннее
   наших двух-трёх знаков. Фиксированная ячейка их обрежет, поэтому здесь ширина по
   содержимому и разделители между марками. Позиционной сетки тут нет и быть не может:
   набор марок у сети свой и меняется от станции к станции. */
.fmk-fuels.exact{gap:0}
.fmk-fuels.exact s{width:auto;padding:0 3px}
.fmk-fuels.exact s + s{border-left:1px solid var(--line)}
/* капля безбрендовой АЗС якорится остриём, подпись отсчитываем от него, а не от центра */
.gpin .fmk-fuels{top:34px}
/* показываем только вблизи и только на неподвижной карте — механизм тот же, что у соннара */
.leaflet-container.fb-lbl.fb-live .fmk-fuels{opacity:1}

/* ---------- отметки водителей: список + «спасибо»/«не так» ---------- */
.rep-list{display:flex;flex-direction:column;gap:8px}
/* строки отметок v104: слева статусное «ребро» (быстрый скан столбца цветом), капсула с
   каплей-глифом, stagger-появление. Ребро — inset-тень, чтобы не трогать границу строки. */
.rep-row{display:flex;align-items:center;gap:10px;background:var(--surface);
  border:1px solid var(--line);border-radius:12px;padding:9px 12px 9px 14px;
  box-shadow:inset 3px 0 0 var(--line-2);
  animation:rep-in .26s var(--ease) both;animation-delay:var(--d,0s)}
.rep-row.s-yes{box-shadow:inset 3px 0 0 var(--st-yes)}
.rep-row.s-queue{box-shadow:inset 3px 0 0 var(--st-queue)}
.rep-row.s-low{box-shadow:inset 3px 0 0 var(--st-low)}
.rep-row.s-no{box-shadow:inset 3px 0 0 var(--st-no)}
@keyframes rep-in{from{opacity:0;transform:translateY(8px)}}
.rep-old{opacity:.72}
.rep-st{flex:0 0 auto;width:34px;height:34px;border-radius:11px;display:flex;align-items:center;
  justify-content:center;color:#fff}
.rep-st svg{width:19px;height:19px;fill:currentColor;
  animation:glyph-in .32s var(--ease) both;animation-delay:calc(var(--d,0s) + 60ms)}
@keyframes glyph-in{0%{transform:scale(.5);opacity:0}70%{transform:scale(1.08)}100%{transform:scale(1);opacity:1}}
.rep-st.s-yes{background:var(--st-yes)} .rep-st.s-queue{background:var(--st-queue)}
.rep-st.s-low{background:var(--st-low);color:#3a2f00} .rep-st.s-no{background:var(--st-no)}
.rep-st.s-nodata{background:var(--st-nodata)}
/* современные браузеры: капля в цвет статуса на мягкой подложке-линзе (обе темы) */
@supports (background:color-mix(in srgb,red 14%,transparent)){
  .rep-st{background:color-mix(in srgb,var(--stc,var(--st-nodata)) 14%,transparent);color:var(--stc,var(--st-nodata))}
  .rep-st.s-yes{--stc:var(--st-yes);background:color-mix(in srgb,var(--st-yes) 14%,transparent);color:var(--st-yes)}
  .rep-st.s-queue{--stc:var(--st-queue);background:color-mix(in srgb,var(--st-queue) 16%,transparent);color:var(--st-queue)}
  .rep-st.s-low{--stc:var(--st-low);background:color-mix(in srgb,var(--st-low) 18%,transparent);color:var(--st-low)}
  .rep-st.s-no{--stc:var(--st-no);background:color-mix(in srgb,var(--st-no) 14%,transparent);color:var(--st-no)}
  .rep-st.s-nodata{background:color-mix(in srgb,var(--st-nodata) 16%,transparent);color:var(--st-nodata)}
  /* белая галка внутри полной капли «есть» остаётся белой на заливке самой капли */
}
.rep-fuels{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}
.rf{font-style:normal;font-size:10.5px;font-weight:800;padding:1px 6px;border-radius:var(--r-pill);
  border:1px solid var(--line);color:var(--text-3)}
.rf.on{color:var(--st-yes);border-color:var(--st-yes)}
.rf.off{text-decoration:line-through;opacity:.7}
.rep-at.is-old{display:inline-flex;align-items:center;gap:3px;color:var(--text-3);
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 7px}
.rep-at.is-old svg{width:10px;height:10px;fill:currentColor;opacity:.85}
.vote-pop svg{animation:vote-pop .45s var(--ease)}
@keyframes vote-pop{0%{transform:scale(1)}35%{transform:scale(1.35) rotate(-9deg)}70%{transform:scale(.94)}100%{transform:scale(1)}}
@media (prefers-reduced-motion:reduce){
  .rep-row,.ff-row,.rep-st svg,.vote-pop svg{animation:none}
}
.rep-main{flex:1;min-width:0}
.rep-head{display:flex;align-items:center;justify-content:space-between;gap:8px}
.rep-author{font-size:11.5px;font-weight:800;color:var(--red)}
.rep-at{font-size:10.5px;color:var(--text-3);font-weight:600;flex:0 0 auto}
.rep-status{font-size:13.5px;color:var(--text);line-height:1.3;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.rep-votes{display:flex;gap:6px;flex:0 0 auto}
.rep-vote{display:flex;align-items:center;gap:4px;height:32px;padding:0 9px;border-radius:var(--r-pill);
  border:1px solid var(--line);background:var(--surface-2);color:var(--text-2);cursor:pointer;
  font:inherit;font-size:12px;font-weight:700;transition:transform .1s var(--ease),border-color .12s}
.rep-vote svg{width:14px;height:14px;fill:currentColor}
.rep-vote b{font-weight:800;min-width:0}
.rep-vote:active{transform:scale(.93)}
.rep-vote.up.on{background:var(--st-yes);border-color:var(--st-yes);color:#fff}
.rep-vote.down.on{background:var(--st-no);border-color:var(--st-no);color:#fff}
.rep-own{font-size:10.5px;font-weight:700;color:var(--text-3);border:1px dashed var(--line);
  border-radius:var(--r-pill);padding:4px 9px}

/* ---------- Fineapp promo modal ---------- */
.fpromo-backdrop{position:fixed;inset:0;z-index:60;display:flex;align-items:center;justify-content:center;
  background:rgba(8,9,20,.55);backdrop-filter:blur(3px);opacity:0;transition:opacity .22s var(--ease);
  padding:24px}
.fpromo-backdrop.show{opacity:1}
/* min(340px,100%) вместо 92vw: модалка остаётся внутри 24px-полей бэкдропа на узких экранах */
.fpromo{width:min(340px,100%);background:var(--surface);border:1px solid var(--line);
  border-radius:20px;padding:22px 20px 16px;text-align:center;
  box-shadow:0 18px 60px rgba(0,0,0,.45);transform:translateY(14px) scale(.97);
  transition:transform .22s var(--ease)}
.fpromo-backdrop.show .fpromo{transform:none}
.fpromo-coin{width:58px;height:58px;margin:0 auto 12px;border-radius:17px;background:var(--surface-2);
  border:1px solid var(--line);display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 4px var(--red-soft)}
.fpromo-coin img{width:36px;height:36px;object-fit:contain}
.fpromo h3{font-size:16.5px;font-weight:800;margin:0 0 7px;color:var(--text)}
.fpromo p{font-size:13.5px;line-height:1.45;color:var(--text-2);margin:0 0 15px}
.fpromo .btn{width:100%}
.fpromo .btn.btn-ghost{margin-top:8px}


/* ---------- плашка сети: офлайн / очередь отметок ---------- */
.net-chip{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(76px + var(--safe-b,0px));
  z-index:55;border:1px solid var(--line);background:var(--surface);color:var(--text-2);
  font:inherit;font-size:12.5px;font-weight:700;border-radius:var(--r-pill);padding:8px 14px;
  box-shadow:0 6px 24px rgba(0,0,0,.25);cursor:pointer}
.net-chip.q{border-color:var(--red);color:var(--red);box-shadow:0 0 0 3px var(--red-soft)}


/* ---------- умный поиск в «Ситуации» ---------- */
.list-search{display:flex;align-items:center;gap:9px;margin:10px 0 2px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:12px;padding:0 12px;height:42px}
.list-search svg{width:17px;height:17px;fill:var(--text-3);flex:0 0 auto}
.list-search input{flex:1;min-width:0;border:0;background:none;font:inherit;font-size:16px;
  color:var(--text);height:100%}
.list-search input:focus{outline:none}
.list-search input::placeholder{color:var(--text-3)}
#listSearchClear{width:26px;height:26px;border-radius:50%;border:0;background:var(--surface-3);
  display:grid;place-items:center;cursor:pointer;flex:0 0 auto}
#listSearchClear svg{width:12px;height:12px}
.list-sug{display:flex;flex-direction:column;gap:4px;margin:6px 0 2px}
.sug-item{display:flex;align-items:center;gap:9px;border:1px solid var(--line);background:var(--surface);
  border-radius:11px;padding:8px 11px;font:inherit;font-size:13.5px;font-weight:700;color:var(--text);
  cursor:pointer;text-align:left}
.sug-item svg{width:15px;height:15px;fill:var(--red);flex:0 0 auto}
.sug-item small{margin-left:auto;color:var(--text-3);font-weight:600;font-size:11px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:45%}
.sug-item:hover{border-color:var(--red)}
.sug-cat{font-size:10.5px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text-3);margin:4px 2px 0}
.pill-trust svg{width:13px;height:13px;fill:currentColor;margin-right:4px}
.card-trust{display:flex;align-items:center;gap:6px;margin:7px 0 0;font-size:11.5px;font-weight:700;
  color:var(--st-yes)}
.card-trust svg{width:13px;height:13px;fill:currentColor}
/* карточка «Нет данных»: вместо серых пилюль всех топлив — приглашение отметить */
.card-invite{margin:12px 0 0;font-size:12.5px;line-height:1.4;color:var(--text-3)}
/* вместо «Да, подтверждаю», когда свежая отметка — ваша (самоподтверждение запрещено) */
.own-note{display:flex;align-items:center;gap:8px;font-size:12.5px;font-weight:650;
  color:var(--text-3);line-height:1.35;padding:3px 2px}
.own-note svg{width:15px;height:15px;fill:currentColor;flex:0 0 auto}


/* FAQ-аккордеон в «О сервисе» */
.faq-list{display:flex;flex-direction:column;gap:8px}
.faq-item{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:11px 14px}
.faq-item summary{font-weight:800;font-size:14px;cursor:pointer;list-style:none;position:relative;padding-right:22px}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::after{content:"+";position:absolute;right:0;top:-2px;font-size:18px;color:var(--red);font-weight:800}
.faq-item[open] summary::after{content:"–"}
.faq-item p{color:var(--text-2);font-size:13.5px;line-height:1.5;margin:8px 0 0}

@media (prefers-reduced-motion:reduce){
  .fmk-halo{animation:none!important;opacity:0!important}
  .fmk:not(.s-nodata) .fmk-coin{box-shadow:0 0 0 2px #fff,0 0 0 5px var(--sc),0 0 9px -1px var(--sc),0 3px 8px rgba(0,0,0,.45)}
  .fmk.fb-just .fmk-coin{animation:none!important}
  /* дыхание пятна тоже выключаем и фиксируем на среднем уровне: статус читается
     статичным свечением в тени монеты (строка выше), пульсация не нужна */
  .fmk::after{animation:none!important;opacity:.55}
  .fmk.s-nodata::after{opacity:.3} .fmk.s-no::after{opacity:.8}
  .chip .dot{animation:none!important}
}

/* ---------------- TOP BAR ---------------- */
.topbar{
  position:fixed;z-index:20;top:var(--maint-h);left:0;right:0;height:64px;
  display:flex;align-items:center;gap:10px;padding:10px 14px;
  pointer-events:none;
  /* ландшафт телефона с вырезом: логотип и кнопки не залезают под чёлку */
  padding-left:max(14px,env(safe-area-inset-left,0px));
  padding-right:max(14px,env(safe-area-inset-right,0px));
}
.topbar>*{pointer-events:auto}
.brand{display:flex;align-items:center;gap:9px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);
  padding:8px 15px 8px 12px;box-shadow:var(--shadow-sm);color:var(--text)}
.brand-mark{width:30px;height:24px}
/* speed-F glyph (Fine brand) + "benz" in the Fine wordmark face */
.brand{gap:7px;padding-left:13px}
/* full designer lockup (F gradient + «benz»); color drives the currentColor «benz» letters per theme */
.brand-logo{height:27px;width:auto;display:block;flex:0 0 auto;color:var(--text)}
.fine-f{height:27px;width:auto;display:block;flex:0 0 auto}
/* Questrial ≈ the geometric monoline face of the Fine wordmark (square terminals, regular weight) */
.brand-word{font-family:"Questrial",var(--f);font-weight:400;font-size:24px;letter-spacing:0;color:var(--text);line-height:1}
.fbenz-logo{height:30px;width:auto;display:block}
.city-btn{display:inline-flex;align-items:center;gap:5px;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);
  padding:9px 12px;font-weight:700;font-size:14px;box-shadow:var(--shadow-sm);max-width:42vw}
.city-btn .ic{width:17px;height:17px;fill:var(--red);flex:0 0 auto}
.city-btn .ic-chev{width:16px;height:16px;fill:var(--text-3);flex:0 0 auto}
.city-btn #cityName{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.top-actions{margin-left:auto;display:flex;gap:8px}
.icon-btn{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm)}
.icon-btn svg{width:21px;height:21px;fill:var(--text)}
.icon-btn.add-desktop svg{fill:var(--red)}
#themeBtn .ic-sun{display:none;stroke:var(--text);fill:none;stroke-width:2;stroke-linecap:round}
html[data-theme="light"] #themeBtn .ic-moon{display:none}
html[data-theme="light"] #themeBtn .ic-sun{display:block}

/* Fine cross-promo chip (top-right) → opens the fines-payment app */
.fine-chip{display:inline-flex;align-items:center;gap:6px;height:44px;padding:0 13px;border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm);color:var(--text)}
.fine-chip img{height:18px;width:auto;display:block}
.fine-chip span{font-family:"Questrial",var(--f);font-weight:400;font-size:15px}
.fine-chip .fc-arr{width:13px;height:13px;fill:var(--text-3)}
.fine-chip:hover{border-color:var(--red)}
/* tight phone widths: the top row (logo + city + Fine) overflows → Fine becomes an icon-only chip */
@media (max-width:560px){
  .fine-chip{width:44px;padding:0;justify-content:center}
  .fine-chip span,.fine-chip .fc-arr{display:none}
  .fine-chip img{height:20px}
}

/* floating action row under the header: Поиск / Поделиться / Поддержать / тема (gdebenz-style) */
.actionbar{position:fixed;z-index:18;top:calc(var(--maint-h) + 62px);left:14px;right:14px;
  display:flex;gap:8px;justify-content:space-between;pointer-events:none;   /* раскидать по ширине (не липнуть влево) */
  left:max(14px,env(safe-area-inset-left,0px));right:max(14px,env(safe-area-inset-right,0px))}
.actionbar>*{pointer-events:auto}
.act-pill{display:inline-flex;align-items:center;gap:6px;height:38px;padding:0 14px;border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm);
  font-weight:700;font-size:13px;color:var(--text);white-space:nowrap}
.act-pill svg{width:18px;height:18px;fill:currentColor}
.act-pill.act-ico{width:38px;padding:0;justify-content:center;flex:0 0 auto}
.act-support{color:var(--red)} .act-support svg{fill:var(--red)}
@media (max-width:1023px){ body[data-view="list"] .actionbar{opacity:0;pointer-events:none} }
/* «Есть бензин» (тумблер карты): показывать только АЗС с живым статусом yes.
   Активация = упругий pop + капля «подпрыгивает» + зелёное пульс-гало — тот же язык,
   что у живых пинов карты (halo), 99% траффа мобильный → анимация на тапе, не hover */
.act-avail svg{transition:transform .25s var(--ease)}
.act-avail[aria-pressed="true"]{color:#fff;border-color:var(--st-yes);
  background:linear-gradient(135deg,#25d184,#149d61);
  animation:avail-pop .5s var(--ease),avail-halo 2.4s ease-out .5s infinite}
.act-avail[aria-pressed="true"] svg{animation:avail-drip 1.9s ease-in-out .55s infinite}
@keyframes avail-pop{0%{transform:scale(1)}35%{transform:scale(.88)}68%{transform:scale(1.08)}100%{transform:scale(1)}}
@keyframes avail-halo{0%{box-shadow:0 0 0 0 rgba(31,191,117,.55)}70%{box-shadow:0 0 0 11px rgba(31,191,117,0)}100%{box-shadow:0 0 0 0 rgba(31,191,117,0)}}
@keyframes avail-drip{0%,100%{transform:translateY(0) scale(1)}50%{transform:translateY(-1.5px) scale(1.12)}}

/* Пары в ряду: слева «поиск + Есть бензин», справа «Газпром + тема». Одна auto-margin съедает
   свободное место ДО того, как justify-content:space-between начнёт раскидывать четыре кнопки
   равными промежутками (иначе «Газпром» повиснет отдельным островом посреди ряда). */
#availBtn{margin-right:auto}
/* «Газпром» — тумблер режима официальных статусов сети. Тот же язык активации, что у «Есть бензин»
   (pop + пульс-гало), но в синем: зелёный уже занят смыслом «топливо есть». */
.act-gpn img{width:20px;height:20px;flex:0 0 auto;object-fit:contain;border-radius:50%;
  background:#fff;padding:2.5px;box-shadow:0 0 0 1px rgba(20,22,45,.10)}
.act-gpn[aria-pressed="true"]{color:#fff;border-color:#0066B3;
  background:linear-gradient(135deg,#1E8FD6,#0066B3);
  animation:avail-pop .5s var(--ease),gpn-halo 2.4s ease-out .5s infinite}
@keyframes gpn-halo{0%{box-shadow:0 0 0 0 rgba(0,102,179,.55)}70%{box-shadow:0 0 0 11px rgba(0,102,179,0)}100%{box-shadow:0 0 0 0 rgba(0,102,179,0)}}
/* very narrow phones: «Есть бензин» collapses to an icon so the search/avail/theme row never overflows
   right (adaptive под все ширины — кнопки не «улетают» за экран) */
@media (max-width:360px){
  #availBtn{width:38px;padding:0;justify-content:center}
  #availBtn .lbl{display:none}
}
/* Четвёртая кнопка: без свёртки ряд переполняется на 361-368px (сумма 340.2px против 333-340
   доступных). Порог 368, чтобы на самых ходовых 390px подпись осталась; от системного
   увеличения шрифта страхует ellipsis ниже, а не запас по ширине. */
@media (max-width:368px){
  #gpnBtn{width:38px;padding:0;justify-content:center}
  #gpnBtn .lbl{display:none}
}
@media (max-width:1023px){
  .act-pill{min-width:0}
  .act-pill .lbl{overflow:hidden;text-overflow:ellipsis;min-width:0}
  .actionbar{flex-wrap:nowrap}
}
@media (min-width:1024px){
  /* десктопная сетка полей 24px (топбар, FAB, зум, футер): держим её и здесь */
  .actionbar{right:auto;width:auto;left:24px}
  body[data-view="list"] .actionbar{left:calc(var(--panel-w) + 24px)}   /* clear the sidebar */
}

/* ===== РЕЖИМ «ГАЗПРОМ» =====================================================
   На карте лежит официальный слой сети, а не наши краудсорс-отметки. Инструменты
   про отметки в этот момент врут, поэтому их не показываем: поиск ищет по нашим
   станциям, «Есть бензин» фильтрует наши статусы, список рядом — тоже наш.
   Всё гасится атрибутом на body, JS про эти правила не знает. */
body[data-mode="gpn"] #searchBtn,
body[data-mode="gpn"] #availBtn,
body[data-mode="gpn"] .install-banner{display:none}
body[data-mode="gpn"] #gpnBtn{margin-left:auto}   /* авто-отступ уехал вместе с «Есть бензин» */
body[data-mode="gpn"] .panel{display:none}

/* марки топлива режима — плавающий ряд под кнопками, прокручивается вбок на узких экранах */
.gpn-chips{position:fixed;z-index:17;top:calc(var(--maint-h) + 108px);
  left:max(14px,env(safe-area-inset-left,0px));right:max(14px,env(safe-area-inset-right,0px));
  display:flex;gap:6px;overflow-x:auto;scrollbar-width:none;pointer-events:none}
.gpn-chips::-webkit-scrollbar{display:none}
.gpn-chip{pointer-events:auto;flex:0 0 auto;height:32px;padding:0 13px;border-radius:var(--r-pill);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm);
  font:800 12.5px/1 var(--f);color:var(--text);cursor:pointer;
  transition:background .18s var(--ease),color .18s var(--ease),border-color .18s var(--ease)}
.gpn-chip.on{background:var(--red);border-color:var(--red);color:#fff}
@media (min-width:1024px){ .gpn-chips{right:auto;width:auto;left:24px} }

/* Строка марки в карточке сети. Сетка, а не флекс: колонка статуса фиксирована, поэтому
   «В наличии» и «Отсутствует» у всех строк стоят на одной вертикали и глаз читает столбец,
   а не рваный край. Время источника прижато к статусу, цена — к правому краю. */
.gpn-rows{display:flex;flex-direction:column;gap:8px}
.gpn-row{display:grid;grid-template-columns:52px minmax(92px,auto) 1fr auto;align-items:center;
  gap:10px;padding:10px 12px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid var(--line)}
.gpn-badge{text-align:center;padding:5px 6px;border-radius:8px;
  background:var(--surface-3);font:800 13px/1 var(--f);color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gpn-since{font-size:11.5px;color:var(--text-3);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.gpn-price{font:800 15px/1 var(--f);color:var(--text);white-space:nowrap;text-align:right}
.gpn-price span{font-weight:700;font-size:11.5px;color:var(--text-3)}
.gpn-noprice{font-weight:700;font-size:11.5px;color:var(--text-3)}
.gpn-pill{display:inline-block;padding:4px 10px;border-radius:var(--r-pill);font:800 11.5px/1 var(--f);
  white-space:nowrap}
.gpn-pill.yes{background:var(--st-yes-bg);color:var(--st-yes)}
.gpn-pill.no{background:var(--st-no-bg);color:var(--st-no)}
.gpn-pill.nodata{background:var(--st-nodata-bg);color:var(--st-nodata)}
.gpn-empty{padding:14px;border-radius:var(--r-sm);background:var(--surface-2);
  border:1px solid var(--line);color:var(--text-2);font-size:13.5px}
/* узкие телефоны: время съезжает под статус, иначе цена и время дерутся за одну строку.
   Колонка бейджа 56px — под самую длинную марку сети «G-100», она не должна резаться. */
@media (max-width:400px){
  .gpn-row{grid-template-columns:56px 1fr auto;row-gap:4px;gap:8px;padding:10px}
  .gpn-badge{font-size:12px;padding:5px 4px}
  .gpn-since{grid-column:2/3;font-size:11px}
  .gpn-price{grid-row:1/3;grid-column:3/4}
}

/* PWA install nudge — floats just under the action row */
.install-banner{position:fixed;z-index:17;top:calc(var(--maint-h) + 110px);left:14px;right:14px;
  left:max(14px,env(safe-area-inset-left,0px));right:max(14px,env(safe-area-inset-right,0px));
  display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:16px;
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow);animation:ib-in .3s var(--ease)}
@keyframes ib-in{from{opacity:0;transform:translateY(-8px)}}
.install-banner[hidden]{display:none}
.ib-logo{width:34px;height:auto;flex:0 0 auto}
.ib-text{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.2}
.ib-text b{font-size:14px;font-weight:800}
.ib-text span{font-size:11.5px;color:var(--text-3);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ib-add{flex:0 0 auto;background:var(--red);color:#fff;border:0;border-radius:var(--r-pill);
  padding:9px 15px;font-weight:800;font-size:13px;font-family:inherit}
.ib-close{flex:0 0 auto;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface-2);border:0}
.ib-close svg{width:15px;height:15px;fill:var(--text-3)}
.install-steps{margin:14px 0 4px;padding-left:20px;color:var(--text);font-size:14.5px;line-height:1.7}
.install-steps li{margin-bottom:6px}
.ish-ic{display:inline-grid;place-items:center;width:20px;height:20px;vertical-align:-5px}
.ish-ic svg{width:17px;height:17px;fill:var(--red)}
/* hide the floating install nudge whenever the list/sidebar is open (it overlapped the filter on
   desktop, and the «Ещё» → «Добавить на экран» item keeps install reachable) */
body[data-view="list"] .install-banner{display:none}
@media (min-width:1024px){ .install-banner{left:24px;right:auto;width:360px} }

/* ---------------- LIST PANEL ---------------- */
.panel{
  position:fixed;z-index:15;background:var(--surface);
  display:flex;flex-direction:column;background-image:var(--glow);
}
.panel-grip{display:none}
.panel-head{padding:10px 16px 4px;flex:0 0 auto;
  padding-left:max(16px,env(safe-area-inset-left,0px));
  padding-right:max(16px,env(safe-area-inset-right,0px))}
/* mini FineApp logo above the centered situation summary (просили вернуть на главную) */
.panel-fine{display:flex;align-items:center;justify-content:center;gap:5px;padding:0 0 8px}
.panel-fine img{height:16px;width:auto;display:block}
.panel-fine span{font-family:"Questrial",var(--f);font-weight:400;font-size:13px;color:var(--text-2)}
/* центрируем чипы теми же margin:auto, что и .filter-bar: justify-content:center на скроллере
   прячет первый чип за левым краем, как только сводка перестаёт помещаться (узкие телефоны) */
.summary{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;padding-bottom:10px}
.summary>:first-child{margin-left:auto}
.summary>:last-child{margin-right:auto}
.summary::-webkit-scrollbar{display:none}
.chip{display:inline-flex;align-items:center;gap:7px;flex:0 0 auto;
  background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-pill);
  padding:7px 13px;font-weight:700;font-size:13px}
.chip .dot{width:9px;height:9px;border-radius:50%}
.chip b{font-weight:800}
/* Точки сводки живут тем же ритмом, что маркеры на карте: «есть» ровно дышит,
   «нет» бьётся двойным маячком. Так подпись становится не только цветовым, но и
   поведенческим ключом — связь «частое мигание = нет» считывается без чтения.
   Здесь точек три, а не три сотни, поэтому box-shadow анимировать не жалко. */
.chip .d-yes{animation:dot-yes 3.2s ease-in-out infinite}
.chip .d-queue{animation:dot-queue 2.1s ease-in-out infinite}
.chip .d-no{animation:dot-no 2.2s var(--ease) infinite}
@keyframes dot-yes{0%,100%{box-shadow:0 0 0 0 rgba(31,191,117,.5)}50%{box-shadow:0 0 0 4px rgba(31,191,117,0)}}
@keyframes dot-queue{0%,100%{transform:scale(1);opacity:1}50%{transform:scale(1.18);opacity:.75}}
@keyframes dot-no{
  0%{box-shadow:0 0 0 0 rgba(255,59,92,.62)}
  18%{box-shadow:0 0 0 5px rgba(255,59,92,0)}
  20%{box-shadow:0 0 0 0 rgba(255,59,92,.62)}
  38%{box-shadow:0 0 0 5px rgba(255,59,92,0)}
  100%{box-shadow:0 0 0 5px rgba(255,59,92,0)}
}
.filter{padding-bottom:13px;border-bottom:1px solid var(--line)}
/* ОДНА строка: «Фильтры (N)» + токены активных фильтров (тап = снять). По центру, с воздухом.
   margin:auto на краях центрирует группу, но не ломает скролл при переполнении (в отличие от
   justify-content:center, который прячет левый край). Параметры — в шите filterSheet. */
.filter-bar{display:flex;gap:8px;overflow-x:auto;scrollbar-width:none;padding:6px 0 2px}
.filter-bar::-webkit-scrollbar{display:none}
.filter-bar>:first-child{margin-left:auto}
.filter-bar>:last-child{margin-right:auto}
.filter-bar .pill{flex:0 0 auto;padding:7px 12px;font-size:12.5px}
.pill-more{display:inline-flex;align-items:center;gap:5px}
.pill-more svg{width:14px;height:14px;fill:currentColor}
.pill-more .pm-n{display:inline-grid;place-items:center;min-width:17px;height:17px;border-radius:9px;
  background:#fff;color:var(--red);font-size:11px;font-weight:800;padding:0 4px}
.pill-more[aria-pressed="true"] .pm-n{background:#fff;color:var(--red)}
/* токен активного фильтра: залит красным, крестик для снятия */
.tok{display:inline-flex;align-items:center;gap:6px;background:var(--red);border-color:var(--red);color:#fff}
.tok svg{width:11px;height:11px;fill:currentColor;opacity:.85}
/* кнопка «Последние отметки» рядом с «Фильтрами» */
.pill-feed{display:inline-flex;align-items:center;gap:5px}
.pill-feed svg{width:13px;height:13px;fill:currentColor}
/* шит «Последние отметки»: полный список */
.feed-full{display:flex;flex-direction:column;gap:8px}
.ff-row{animation:rep-in .26s var(--ease) both;animation-delay:var(--d,0s);
  display:flex;align-items:center;gap:11px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:13px;padding:10px 12px;font:inherit;color:var(--text);cursor:pointer;
  text-align:left;transition:.15s}
.ff-row:hover{border-color:var(--red);transform:translateY(-1px)}
.ff-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.ff-main b{font-weight:800;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ff-main small{font-weight:700;font-size:11.5px}
.ff-main small.s-yes{color:var(--st-yes)} .ff-main small.s-queue{color:var(--st-queue)}
.ff-main small.s-low{color:#9a7b06} .ff-main small.s-no{color:var(--st-no)}
.ff-main small.s-nodata{color:var(--st-nodata)}
.ff-at{flex:0 0 auto;color:var(--text-3);font-size:11px;font-weight:600;white-space:nowrap}
.ff-arr{flex:0 0 auto;width:16px;height:16px;fill:var(--text-3)}
/* шит «Фильтры»: топливо-соты, тумблер «точно есть», группы пилюль, футер */
.fs-fuel{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin-bottom:10px}
.fs-fbtn{height:46px;border-radius:13px;background:var(--surface-2);border:1px solid var(--line);
  font:inherit;font-weight:800;font-size:15px;color:var(--text-2);cursor:pointer;transition:.15s}
.fs-fbtn[aria-pressed="true"]{background:var(--red);border-color:var(--red);color:#fff;
  box-shadow:0 4px 14px -4px var(--red)}
.fs-avail{display:flex;align-items:center;gap:11px;width:100%;padding:12px 14px;margin:0 0 8px;
  border-radius:14px;background:var(--surface-2);border:1px solid var(--line);cursor:pointer;
  font:inherit;text-align:left;color:var(--text);transition:.15s}
.fs-avail>svg{width:18px;height:18px;fill:var(--st-yes);flex:0 0 auto}
.fs-avail span{flex:1;font-weight:800;font-size:14px}
.fs-avail small{display:block;font-weight:600;font-size:11.5px;color:var(--text-3);margin-top:1px}
.fs-sw{flex:0 0 auto;width:44px;height:26px;border-radius:13px;background:var(--surface-3);
  border:1px solid var(--line);position:relative;transition:.2s}
.fs-sw::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;
  background:#fff;box-shadow:0 1px 4px rgba(0,0,0,.3);transition:.2s}
.fs-avail[aria-pressed="true"]{border-color:var(--st-yes)}
.fs-avail[aria-pressed="true"] .fs-sw{background:var(--st-yes);border-color:var(--st-yes)}
.fs-avail[aria-pressed="true"] .fs-sw::after{left:20px}
/* заголовки секций и ряды пилюль в шите — по центру (просьба владельца) */
#filterSheet .section-label{text-align:center}
#filterSheet h2{text-align:center}
.fs-row{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:6px;justify-content:center}
.fs-row .pill{display:inline-flex;align-items:center;gap:5px}
.fs-row .pill svg{width:13px;height:13px;fill:currentColor}
.fs-foot{display:flex;gap:10px;margin-top:16px}
.fs-foot .btn{flex:1;margin:0}
.pill-cash{display:inline-flex;align-items:center;gap:5px}
.pill-cash svg{fill:currentColor}
.pill-cash[aria-pressed="true"]{background:var(--st-yes);border-color:var(--st-yes);color:#fff}
.pill{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-pill);
  padding:7px 14px;font-weight:700;font-size:13px;color:var(--text-2);transition:.15s}
.pill[aria-pressed="true"]{background:var(--red);border-color:var(--red);color:#fff}
.pill-avail{display:inline-flex;align-items:center;gap:5px}
.pill-avail svg{width:14px;height:14px;fill:currentColor}
.pill-avail[aria-pressed="true"]{background:var(--st-yes);border-color:var(--st-yes);color:#fff}
/* About: status colour legend */
.legend{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px;
  color:var(--text-2);font-size:13.5px;line-height:1.4}
.legend li{display:flex;align-items:flex-start;gap:9px}
.legend b{color:var(--text)}
.lg-dot{flex:0 0 auto;width:14px;height:14px;border-radius:50%;margin-top:1px;border:2px solid var(--surface)}
.list{flex:1;overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:12px 16px calc(20px + var(--safe-b));display:flex;flex-direction:column;gap:12px;
  padding-left:max(16px,env(safe-area-inset-left,0px));
  padding-right:max(16px,env(safe-area-inset-right,0px))}

/* station card (Fineapp) */
.card{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r);
  padding:14px;transition:transform .12s var(--ease),box-shadow .15s;cursor:pointer}
.card:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
.card:active{transform:scale(.99)}
.card-top{display:flex;align-items:flex-start;gap:11px}
.logo{width:42px;height:42px;border-radius:12px;flex:0 0 auto;display:grid;place-items:center;
  font-weight:800;font-size:15px;color:#fff;letter-spacing:-.5px;position:relative;overflow:hidden}
/* real brand logo in a clean circular white badge (like company app icons) — logo.dev gives a
   crisp 128px transparent mark that sits centred; the brand-colour coin ring frames it. */
.blogo{position:absolute;inset:8%;width:84%;height:84%;border-radius:50%;background:#fff;
  object-fit:contain;padding:13%;box-shadow:0 0 0 1px rgba(0,0,0,.07)}
.card-name{flex:1;min-width:0}
.card-name h3{margin:0;font-size:15.5px;font-weight:800;letter-spacing:-.2px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card-name .addr{color:var(--text-3);font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.badge{display:inline-flex;align-items:center;gap:5px;flex:0 0 auto;
  border-radius:var(--r-pill);padding:5px 10px;font-weight:800;font-size:12px}
.badge svg{width:13px;height:13px}
.badge.s-yes{color:var(--st-yes);background:var(--st-yes-bg)}
.badge.s-queue{color:var(--st-queue);background:var(--st-queue-bg)}
.badge.s-low{color:#9a7b06;background:var(--st-low-bg)}
.badge.s-no{color:var(--st-no);background:var(--st-no-bg)}
.badge.s-nodata{color:var(--st-nodata);background:var(--st-nodata-bg)}
.fuels{display:flex;gap:6px;flex-wrap:wrap;margin:12px 0 0}
.fuel{font-weight:800;font-size:11.5px;padding:4px 9px;border-radius:8px;
  background:var(--surface-3);color:var(--text-2);border:1px solid var(--line)}
.fuel.on{background:var(--st-yes-bg);color:var(--st-yes);border-color:transparent}
.fuel.no{background:var(--st-no-bg);color:var(--st-no);border-color:transparent;text-decoration:line-through;text-decoration-thickness:1.5px}
.fuel-empty{font-size:13px;font-weight:700;color:var(--text-3);padding:5px 0}
/* инфо-группа (км/время) слева, кнопки справа; при нехватке ширины кнопки переносятся
   вниз ЦЕЛОЙ группой и жмутся вправо — «Отметить» больше не подрезается краем карточки */
.card-foot{display:flex;align-items:center;justify-content:space-between;gap:8px 10px;
  margin-top:13px;flex-wrap:wrap}
.card-info{display:flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0}
.card-acts{display:flex;align-items:center;gap:8px;flex:0 0 auto;margin-left:auto}
.meta{display:flex;align-items:center;gap:5px;color:var(--text-3);font-size:12px;font-weight:600;white-space:nowrap}
.meta .km{color:var(--text);font-weight:800}
.mini-btn{display:inline-flex;align-items:center;gap:5px;border-radius:var(--r-pill);
  padding:8px 13px;font-weight:800;font-size:12.5px;background:var(--surface-3);border:1px solid var(--line)}
.mini-btn svg{width:14px;height:14px;fill:currentColor}
.mini-btn.red{background:var(--red);color:#fff;border-color:var(--red)}

/* ad / cross-promo card in the situation list (currently Fine) — единый нейтральный стиль
   с tg-card: обычная рамка, бренд-цвет только в иконке (красная рамка+кольцо кричали в списке) */
/* поля и колонка иконки те же 14/11, что у .card: заголовки промо и АЗС стоят на одной линии */
.ad-card{display:flex;align-items:center;gap:11px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r);padding:12px 14px;transition:transform .12s var(--ease)}
.ad-card:hover{transform:translateY(-2px)}
.ad-logo{width:42px;height:42px;border-radius:12px;background:#fff;display:grid;place-items:center;flex:0 0 auto;
  box-shadow:0 0 0 1px var(--line)}
.ad-logo img{width:30px;height:auto;display:block}
.ad-main{flex:1;min-width:0}
.ad-h{font-weight:800;font-size:14.5px;letter-spacing:-.2px}
.ad-s{color:var(--text-3);font-size:12.5px;margin-top:2px;line-height:1.3}
.ad-chev{width:18px;height:18px;fill:var(--text-3);flex:0 0 auto}
/* «Наш канал в Telegram» promo card — clean neutral card (no blue outline), blue только в иконке.
   Живёт внутри списка «Ситуация» → виден ТОЛЬКО при открытии раздела, не в свёрнутом пике (правило ниже). */
.tg-card{display:flex;align-items:center;gap:11px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:var(--r);padding:12px 14px;
  transition:transform .12s var(--ease)}
.tg-card:hover{transform:translateY(-2px)}
@media (max-width:1023px){ body[data-view="map"] .tg-card{display:none} }   /* не показывать в свёрнутом пике */
.tg-ic{width:42px;height:42px;border-radius:12px;flex:0 0 auto;display:grid;place-items:center;
  background:linear-gradient(160deg,#37BBFE,#1E96C8)}
.tg-ic svg{width:23px;height:23px;fill:#fff;margin-left:-1px}
.tg-main{flex:1;min-width:0}
.tg-tag{display:inline-block;font-size:10px;font-weight:800;letter-spacing:.6px;text-transform:uppercase;
  color:#1E96C8;background:rgba(41,171,226,.15);border-radius:var(--r-pill);padding:2px 8px;margin-bottom:3px}
.tg-h{font-weight:800;font-size:14.5px;letter-spacing:-.2px}
.tg-s{color:var(--text-3);font-size:12.5px;margin-top:2px;line-height:1.3}
.tg-arr{width:18px;height:18px;fill:var(--text-3);flex:0 0 auto}
/* cheapest-price sort pill */
.pill-cheap{display:inline-flex;align-items:center;gap:5px}
.pill-cheap svg{width:14px;height:14px;fill:currentColor}
.pill-cheap[aria-pressed="true"]{background:var(--st-queue);border-color:var(--st-queue);color:#fff}
/* «Показать все» toggle */
.show-all{width:100%;padding:12px;border-radius:var(--r);background:var(--surface-2);border:1px solid var(--line);
  font-weight:800;font-size:13.5px;color:var(--text-2);transition:.15s}
.show-all:hover{color:var(--red);border-color:var(--red)}
/* full Fine wordmark at the list bottom (white badge so the black "ine" reads on dark too) */
.list-fine{display:flex;flex-direction:column;align-items:center;gap:7px;margin:6px 0 2px;padding:2px}
.list-fine span{font-size:11px;color:var(--text-3);font-weight:700;letter-spacing:.3px}
.list-fine a{display:inline-flex;align-items:center;gap:7px;background:#fff;border-radius:12px;
  padding:8px 16px;box-shadow:0 0 0 1px var(--line),var(--shadow-sm)}
.list-fine img{height:22px;width:auto;display:block}
.list-fine b{font-family:"Questrial",var(--f);font-weight:400;font-size:18px;color:#141414;letter-spacing:-.3px}

/* ---------------- FAB + TABBAR ---------------- */
.fab{position:fixed;z-index:16;width:50px;height:50px;border-radius:16px;
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow);
  display:grid;place-items:center}
.fab svg{width:23px;height:23px;fill:var(--red)}
.fab.on svg{fill:#fff}.fab.on{background:var(--red);border-color:var(--red)}
/* вертикальная «ПОДЕЛИТЬСЯ»: при загрузке разворачивается со столбиком букв (заметность),
   через ~4с плавно сворачивается в компактную иконку 50×50 (место).
   ПК: ЛЕВЫЙ нижний угол карты — правый занят зум-контролом (right:24/bottom:150 накладывались). */
.share-fab{position:fixed;z-index:16;left:24px;bottom:150px;width:50px;padding:15px 0;
  border-radius:16px;background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow);
  display:flex;flex-direction:column;align-items:center;cursor:pointer;overflow:hidden;
  transition:border-color .2s,padding .45s var(--ease)}
/* translateX(-1.5px): оптическая центровка — у share-глифа «чернила» тяжелее справа */
.share-fab svg{width:19px;height:19px;fill:var(--red);flex:0 0 auto;transform:translateX(-1.5px)}
.share-fab span{writing-mode:vertical-rl;text-orientation:upright;font-size:10px;font-weight:800;
  letter-spacing:2px;color:var(--text-2);max-height:0;max-width:0;opacity:0;margin-top:0;overflow:hidden;
  transition:max-height .5s var(--ease),opacity .3s,margin-top .5s var(--ease)}
.share-fab.exp span{max-height:150px;max-width:20px;opacity:1;margin-top:9px}
.share-fab:hover{border-color:var(--red)}
/* max-width обязателен: база 0 — без него столбик букв при hover-раскрытии оставался невидимым */
@media (hover:hover){.share-fab:hover span{max-height:150px;max-width:20px;opacity:1;margin-top:9px}}
/* ПК, открыт сайдбар «Рядом» — уехать за его правый край, чтобы не лечь под список */
@media (min-width:1024px){body[data-view="list"] .share-fab{left:calc(var(--panel-w) + 24px)}}
/* bottom tab bar — shown on BOTH mobile (full width) and desktop (over the map, right of sidebar) */
.tabbar{display:flex;position:fixed;z-index:25;left:0;right:0;bottom:0;
  background:var(--surface);border-top:1px solid var(--line);
  padding:8px 6px calc(8px + var(--safe-b));justify-content:space-around;box-shadow:0 -6px 24px rgba(0,0,0,.18);
  padding-left:max(6px,env(safe-area-inset-left,0px));
  padding-right:max(6px,env(safe-area-inset-right,0px))}
.tab{display:flex;flex-direction:column;align-items:center;gap:3px;color:var(--text-3);background:none;border:0;
  cursor:pointer;font-size:10.5px;font-weight:700;flex:1;min-width:0;padding:3px;font-family:inherit}
.tab span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.tab svg{width:24px;height:24px;fill:currentColor}
@media (max-width:400px){.tab{font-size:9.5px}}
.tab[aria-current="true"]{color:var(--text)}
.tab.tab-add svg{fill:var(--red)}
.tab.tab-add[aria-current="true"]{color:var(--red)}
/* light theme: the heavy dark drop-shadow reads as a dirty band — soften it */
html[data-theme="light"] .tabbar{box-shadow:0 -2px 14px rgba(20,22,45,.05)}

/* ---------------- SHEETS / MODALS ---------------- */
.backdrop{position:fixed;inset:0;z-index:30;background:rgba(8,9,20,.55);
  backdrop-filter:blur(3px);animation:fade .2s}
@keyframes fade{from{opacity:0}}
.sheet{position:fixed;z-index:31;background:var(--surface);background-image:var(--glow);
  box-shadow:var(--shadow);display:flex;flex-direction:column;
  left:50%;bottom:0;width:100%;max-width:var(--sheet-max);transform:translateX(-50%);
  border-radius:var(--r-lg) var(--r-lg) 0 0;max-height:88vh;max-height:88dvh;
  padding-bottom:var(--safe-b);animation:slideUp .28s var(--ease)}
@keyframes slideUp{from{transform:translate(-50%,100%)}to{transform:translate(-50%,0)}}
.sheet-grip{width:42px;height:5px;border-radius:3px;background:var(--line-2);margin:10px auto 4px;flex:0 0 auto}
.sheet-body{overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch;padding:6px 20px 22px;min-height:0;
  padding-left:max(20px,env(safe-area-inset-left,0px));
  padding-right:max(20px,env(safe-area-inset-right,0px))}
.sheet h2{font-size:20px;font-weight:800;letter-spacing:-.4px;margin:.2em 0 .1em;overflow-wrap:break-word}
.sheet .sub{color:var(--text-3);font-size:13px;margin:0 0 4px}
.sheet-close{position:absolute;top:12px;right:14px;width:34px;height:34px;border-radius:50%;
  background:var(--surface-2);display:grid;place-items:center;z-index:2}
.sheet-close svg{width:18px;height:18px;fill:var(--text-2)}
/* light theme: grey-on-light was washed out — darken the icon + outline the circle for contrast */
html[data-theme="light"] .sheet-close{background:#EDEFF5;border:1px solid var(--line-2)}
html[data-theme="light"] .sheet-close svg{fill:var(--text)}

/* station detail */
.st-head{display:flex;align-items:flex-start;gap:13px;padding-top:8px}
.st-head .logo{width:50px;height:50px;font-size:17px}
/* min-width:0, иначе длинный адрес распирает flex-колонку и вылезает за край шита */
.st-title{flex:1;min-width:0}
/* заголовок отбит под кнопку закрытия (34px справа), поля самого шита остаются 20/20 */
.st-title h2{margin:0;padding-right:34px}
.st-row{display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin:14px 0}
.st-stat{display:flex;align-items:center;gap:8px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:var(--r);padding:12px 14px;flex:1;min-width:130px}
.st-stat .n{font-size:19px;font-weight:800;line-height:1}
.st-stat .l{color:var(--text-3);font-size:11.5px;font-weight:600}
/* distance under the station name (gdebenz «X км от вас») */
.st-dist{margin:6px 0 0;font-size:13px;font-weight:700;color:var(--text-2)}

/* gdebenz-style status card: status-tinted panel with title + freshness + actions */
.st-card{margin:16px 0 2px;padding:16px;border-radius:18px;background:var(--st-nodata-bg);
  border:1px solid var(--line);box-shadow:inset 0 1px 0 rgba(255,255,255,.04)}
.st-card.s-yes{background:linear-gradient(135deg, rgba(31,191,117,.16), rgba(31,191,117,.08))}
.st-card.s-queue{background:linear-gradient(135deg, rgba(240,169,58,.13), rgba(240,169,58,.055));border-color:rgba(240,169,58,.24)}
.st-card.s-low{background:var(--st-low-bg)} .st-card.s-no{background:var(--st-no-bg)}
.st-card-head{display:flex;align-items:flex-start;gap:14px}
.sts-icon{width:52px;height:52px;border-radius:15px;flex:0 0 auto;display:grid;place-items:center;
  background:rgba(12,15,34,.42);color:var(--st-nodata);box-shadow:inset 0 0 0 1px var(--line)}
html[data-theme="light"] .sts-icon{background:rgba(255,255,255,.72)}
.sts-icon svg{width:27px;height:27px;fill:currentColor}
.st-card.s-yes .sts-icon{color:var(--st-yes)} .st-card.s-queue .sts-icon{color:var(--st-queue)}
.st-card.s-low .sts-icon{color:var(--st-low)} .st-card.s-no .sts-icon{color:var(--st-no)}
.sts-info{min-width:0;padding-top:2px}
.sts-title{font-size:21px;font-weight:800;letter-spacing:-.4px;line-height:1.1;color:var(--st-nodata)}
.st-card.s-yes .sts-title{color:var(--st-yes)} .st-card.s-queue .sts-title{color:var(--st-queue)}
.st-card.s-low .sts-title{color:#9a7b06} .st-card.s-no .sts-title{color:var(--st-no)}
.sts-lead{color:var(--text);font-size:13.5px;font-weight:750;margin-top:6px;line-height:1.35;opacity:.9}
.sts-meta{color:var(--text-2);font-size:12.5px;font-weight:700;margin-top:4px;line-height:1.35}
.stale-badge{display:inline-flex;align-items:center;gap:6px;margin-top:10px;
  background:var(--surface);color:var(--text-3);font-size:12px;font-weight:700;
  padding:5px 11px;border-radius:var(--r-pill);border:1px solid var(--line)}
.stale-badge svg{width:13px;height:13px;fill:currentColor}
.st-card-actual{margin-top:15px;padding-top:14px;border-top:1px solid rgba(255,255,255,.10)}
html[data-theme="light"] .st-card-actual{border-top-color:var(--line)}
.actual-q{font-weight:800;font-size:14px;margin:0}
.actual-hint{margin:4px 0 10px;color:var(--text-2);font-size:12.5px;font-weight:700;line-height:1.35}
.actual-btns{display:flex;gap:9px}
.actual-btns .btn{margin:0;flex:1;font-size:13.5px;padding:12px 10px}
.btn-confirm{background:var(--st-yes);color:#fff}
.btn-changed{background:rgba(18,22,44,.68);color:var(--text);border:1px solid var(--line-2)}
html[data-theme="light"] .btn-changed{background:rgba(255,255,255,.72)}
.btn-share-sit{margin-top:9px;background:rgba(18,22,44,.62);color:var(--text);border:1px solid var(--line-2)}
html[data-theme="light"] .btn-share-sit{background:rgba(255,255,255,.72)}
.btn-share-sit svg{fill:currentColor;opacity:.9}
.section-label{font-size:11.5px;font-weight:800;letter-spacing:1.2px;text-transform:uppercase;
  color:var(--text-3);margin:18px 0 9px}

/* buttons */
.btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;
  border-radius:14px;padding:15px;font-weight:800;font-size:15px;transition:.15s}
.btn svg{width:19px;height:19px;fill:currentColor}
.btn-red{background:var(--red);color:#fff}
.btn-red:active{background:var(--red-2)}
.btn-fill{background:var(--btn-fill);color:var(--btn-fill-text)}
.btn-ghost{background:var(--surface-2);color:var(--text);border:1px solid var(--line)}
.btn-row{display:flex;gap:10px;margin-top:10px}
.btn-row .btn{margin:0}

/* route app picker */
.route-sub{line-height:1.35}
.route-options{display:flex;flex-direction:column;gap:10px;margin-top:16px}
.route-opt{display:flex;align-items:center;gap:13px;width:100%;padding:14px;
  border-radius:16px;background:var(--surface-2);border:1px solid var(--line);
  text-align:left;transition:.14s var(--ease)}
.route-opt:active{transform:translateY(1px);background:var(--surface-3)}
.route-opt b{display:block;font-size:15px;font-weight:850;color:var(--text);line-height:1.2}
.route-opt small{display:block;margin-top:3px;font-size:12px;font-weight:650;color:var(--text-2);line-height:1.3}
.route-ico{width:42px;height:42px;border-radius:14px;display:grid;place-items:center;flex:0 0 auto;
  background:linear-gradient(145deg, rgba(255,255,255,.08), rgba(255,255,255,.02));
  border:1px solid var(--line);box-shadow:inset 0 1px 0 rgba(255,255,255,.05)}
.route-ico svg{width:30px;height:30px;display:block}
.route-ico .ri-bg{fill:rgba(255,255,255,.12)}
.route-ico .ri-main{fill:var(--text-2)}
html[data-theme="light"] .route-ico{background:#F1F3F8;border-color:rgba(20,22,45,.08);box-shadow:none}
html[data-theme="light"] .route-ico .ri-bg{fill:#fff}
html[data-theme="light"] .route-ico .ri-main{fill:#5b6378}

/* vote: status grid + fuel select */
.status-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.status-opt{display:flex;align-items:center;gap:11px;background:var(--surface-2);
  border:2px solid var(--line);border-radius:var(--r);padding:14px;font-weight:800;font-size:15px;transition:.12s}
.status-opt .si{width:34px;height:34px;border-radius:10px;display:grid;place-items:center;flex:0 0 auto}
.status-opt .si svg{width:18px;height:18px;fill:#fff}
.status-opt[aria-pressed="true"]{border-color:currentColor;transform:translateY(-1px)}
.status-opt.s-yes[aria-pressed="true"]{color:var(--st-yes)} .status-opt.s-yes .si{background:var(--st-yes)}
.status-opt.s-queue[aria-pressed="true"]{color:var(--st-queue)} .status-opt.s-queue .si{background:var(--st-queue)}
.status-opt.s-low[aria-pressed="true"]{color:#9a7b06} .status-opt.s-low .si{background:var(--st-low)}
.status-opt.s-low .si svg{fill:#3a2f00}
.status-opt.s-no[aria-pressed="true"]{color:var(--st-no)} .status-opt.s-no .si{background:var(--st-no)}
.fuel-select{display:flex;gap:8px;flex-wrap:wrap}
.fuel-opt{font-weight:800;font-size:14px;padding:11px 16px;border-radius:12px;
  background:var(--surface-2);border:2px solid var(--line);color:var(--text-2)}
.fuel-opt[aria-pressed="true"]{background:var(--st-yes-bg);border-color:var(--st-yes);color:var(--st-yes)}
.presence-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.presence-opt{display:flex;flex-direction:column;align-items:flex-start;justify-content:center;gap:4px;min-height:74px;
  background:var(--surface-2);border:2px solid var(--line);border-radius:var(--r);padding:14px 15px;
  color:var(--text-2);font-family:inherit;text-align:left;transition:.12s}
.presence-opt span{font-size:18px;font-weight:900;color:var(--text)}
.presence-opt small{font-size:12.5px;font-weight:700;line-height:1.25;color:var(--text-2)}
.presence-opt[aria-pressed="true"]{transform:translateY(-1px)}
.presence-opt.p-yes[aria-pressed="true"]{background:var(--st-yes-bg);border-color:var(--st-yes)}
.presence-opt.p-yes[aria-pressed="true"] span,.presence-opt.p-yes[aria-pressed="true"] small{color:var(--st-yes)}
.presence-opt.p-no[aria-pressed="true"]{background:var(--st-no-bg);border-color:var(--st-no)}
.presence-opt.p-no[aria-pressed="true"] span,.presence-opt.p-no[aria-pressed="true"] small{color:var(--st-no)}
.vote-details{margin-top:6px}
/* per-fuel vote marks (Есть/Нет per grade) */
.fmarks{display:flex;flex-direction:column;gap:8px}
.fmark{display:flex;align-items:center;gap:12px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r);padding:8px 8px 8px 16px}
.fmark-label{font-weight:800;font-size:16px;flex:1}
.fmark-btns{display:flex;gap:6px}
.fm-btn{font-weight:800;font-size:13.5px;padding:9px 16px;border-radius:10px;
  background:var(--surface-3);border:2px solid var(--line);color:var(--text-2);transition:.12s}
.fm-btn.fm-yes[aria-pressed="true"]{background:var(--st-yes);border-color:var(--st-yes);color:#fff}
.fm-btn.fm-no[aria-pressed="true"]{background:var(--st-no);border-color:var(--st-no);color:#fff}
/* vote: optional price field shown next to «Есть/Нет» when fuel is present */
.fmark-right{display:flex;align-items:center;gap:8px}
/* iOS Safari auto-zooms the whole page on focus of any input whose font-size is < 16px, and since the
   viewport no longer locks user-scalable it doesn't reliably zoom back out. Keep every form control at
   >= 16px so focus never triggers the zoom (pinch-zoom stays available for accessibility). This base
   rule covers unstyled/future inputs (e.g. #addUrl); the class rules below are bumped to 16px too. */
input, textarea, select { font-size: 16px; }
.fm-price{width:66px;height:38px;border-radius:10px;border:2px solid var(--line);background:var(--surface-3);
  color:var(--text);font-family:inherit;font-weight:700;font-size:16px;text-align:center;outline:none;padding:0 6px}
.fm-price::placeholder{color:var(--text-3);font-weight:600}
.fm-price:focus-visible{border-color:var(--st-yes);outline:none}
/* per-fuel prices on card + detail */
.prices{display:flex;gap:6px;flex-wrap:wrap;margin:10px 0 0}
.price{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:700;padding:4px 9px;
  border-radius:8px;background:var(--surface-3);color:var(--text-2);border:1px solid var(--line)}
.price b{font-weight:800;color:var(--text);font-size:11.5px}
.price.hit{background:var(--st-yes-bg);color:var(--st-yes);border-color:transparent}
.price.hit b{color:var(--st-yes)}
/* vote: per-car limit field + «нет налички» toggle */
.extra-row{display:flex;gap:8px;align-items:stretch;flex-wrap:wrap}
.limit-field{display:flex;align-items:center;gap:8px;background:var(--surface-2);border:2px solid var(--line);
  border-radius:12px;padding:0 6px 0 14px;font-weight:800;font-size:13.5px;color:var(--text-2);height:46px}
.limit-field input{width:54px;height:38px;border:0;background:none;text-align:center;font-family:inherit;
  font-weight:800;font-size:16px;color:var(--text);outline:none}
.cash-toggle{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:7px;background:var(--surface-2);
  border:2px solid var(--line);border-radius:12px;padding:10px 14px;font-weight:800;font-size:13.5px;
  color:var(--text-2);min-height:46px;height:auto;line-height:1.2;text-align:center}
.cash-toggle svg{width:18px;height:18px;fill:currentColor}
.cash-toggle[aria-pressed="true"]{background:var(--st-no-bg);border-color:var(--st-no);color:var(--st-no)}
/* station info badges (limit / no-cash) on cards + detail */
.itags{display:flex;gap:6px;flex-wrap:wrap;margin:10px 0 0}
.itag{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:800;padding:4px 9px;border-radius:8px}
.itag svg{width:13px;height:13px;fill:currentColor}
.itag-limit{background:var(--st-queue-bg);color:var(--st-queue)}
.itag-cash{background:var(--st-no-bg);color:var(--st-no)}
.itag-fuelcard{background:rgba(79,141,255,.14);color:#73a6ff}
html[data-theme="light"] .itag-fuelcard{background:rgba(47,112,217,.12);color:#2f70d9}
.cond-row{display:flex;gap:8px;flex-wrap:wrap}
.cond{flex:1 1 54px;text-align:center;font-weight:800;font-size:14px;padding:11px 10px;border-radius:12px;
  background:var(--surface-2);border:2px solid var(--line);color:var(--text-2)}
.cond[aria-pressed="true"]{border-color:var(--st-queue);color:var(--st-queue);background:var(--st-queue-bg)}
.data-source{margin:6px 0 0;color:var(--text-2);font-size:12px;font-weight:700}
.notif-list{display:flex;flex-direction:column;gap:10px;margin-top:6px}
.notif-item{display:flex;gap:12px;align-items:flex-start;background:var(--surface-2);border:1px solid var(--line);
  border-radius:14px;padding:14px 15px}
.notif-item>svg{width:22px;height:22px;fill:var(--red);flex:0 0 auto;margin-top:1px}
.notif-body{font-size:14.5px;font-weight:600;line-height:1.4;color:var(--text)}
.notif-time{display:block;color:var(--text-3);font-size:11.5px;font-weight:600;margin-top:5px}

/* search sheet */
.sheet-search{top:var(--maint-h);bottom:auto;border-radius:0 0 var(--r-lg) var(--r-lg);max-height:80vh;max-height:80dvh;
  animation:slideDown .26s var(--ease)}
@keyframes slideDown{from{transform:translate(-50%,-100%)}to{transform:translate(-50%,0)}}
.search-field{display:flex;align-items:center;gap:10px;background:var(--surface-2);
  border:1px solid var(--line);border-radius:14px;padding:13px 15px;margin:6px 0 4px}
.search-field svg{width:20px;height:20px;fill:var(--text-3);flex:0 0 auto}
.search-field input{flex:1;border:0;background:none;color:var(--text);font-size:16px;font-family:inherit;outline:none}
.res{display:flex;flex-direction:column;gap:2px;margin-top:8px}
.res-item{display:flex;align-items:center;gap:12px;padding:13px 8px;border-radius:12px;border-bottom:1px solid var(--line)}
.res-item:hover{background:var(--surface-2)}
.res-item .logo{width:38px;height:38px;font-size:14px}
.res-item .ri-main{flex:1;min-width:0}
.res-item h4{margin:0;font-size:15px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.res-item .ri-sub{color:var(--text-3);font-size:12.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* me sheet */
.me-link{display:flex;align-items:center;gap:13px;padding:15px 6px;border-bottom:1px solid var(--line);font-weight:700}
.me-link svg{width:22px;height:22px;fill:var(--red);flex:0 0 auto}
.me-link .arr{margin-left:auto;fill:var(--text-3);width:18px;height:18px}
.me-link small{display:block;color:var(--text-3);font-weight:500;font-size:12.5px}

/* achievements / badges grid (our brand: red coin when earned, muted + progress while locked) */
.ach-label{display:flex;align-items:center;gap:8px}
.ach-label #badgesCount{color:var(--red);font-weight:800}
.ach-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin:2px 0 6px}
.ach-load,.ach-err{grid-column:1/-1;text-align:center;color:var(--text-3);font-size:13px;padding:16px}
.ach{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;
  background:var(--surface-2);border:1px solid var(--line);border-radius:14px;padding:13px 8px 11px}
.ach-ic{position:relative;width:46px;height:46px;border-radius:50%;display:grid;place-items:center;
  background:var(--surface-3);color:var(--text-3)}
.ach-ic svg{width:25px;height:25px;fill:currentColor}
.ach.done .ach-ic{background:linear-gradient(150deg,var(--red),var(--red-2));color:#fff;
  box-shadow:0 5px 13px -3px rgba(232,19,43,.55)}
.ach-check{position:absolute;right:-3px;bottom:-3px;width:19px;height:19px;border-radius:50%;
  background:var(--st-yes);display:grid;place-items:center;border:2.5px solid var(--surface-2)}
.ach-check svg{width:11px;height:11px;fill:#fff}
.ach-t{font-size:11.5px;font-weight:800;line-height:1.2;color:var(--text-2);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:2.4em}
.ach.done .ach-t{color:var(--text)}
.ach-sub{font-size:10.5px;font-weight:700;color:var(--text-3)}
.ach.done .ach-sub{color:var(--st-yes)}
.ach-bar{width:100%;height:4px;border-radius:2px;background:var(--surface-3);overflow:hidden;margin-top:1px}
.ach-bar i{display:block;height:100%;background:var(--red);border-radius:2px}

/* trust-rating card (Phase 2) — tier-tinted: Новичок=muted, Надёжный=red, Эксперт=gold→red */
.rating-card{display:flex;align-items:center;gap:13px;padding:14px;border-radius:16px;margin:6px 0 2px;
  background:var(--surface-2);border:1px solid var(--line)}
.rating-load{padding:0;border:0;background:none;min-height:0}
.rating-card .rc-ic{width:46px;height:46px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;
  background:var(--surface-3);color:var(--text-3)}
.rating-card .rc-ic svg{width:26px;height:26px;fill:currentColor}
.rating-card.t-trusted{background:var(--red-soft);border-color:transparent}
.rating-card.t-trusted .rc-ic{background:linear-gradient(150deg,var(--red),var(--red-2));color:#fff}
.rating-card.t-expert{background:linear-gradient(135deg,rgba(245,170,30,.18),rgba(232,19,43,.13));border-color:transparent}
.rating-card.t-expert .rc-ic{background:linear-gradient(150deg,#F5AA1E,#E8132B);color:#fff}
.rc-body{flex:1;min-width:0}
.rc-tier{font-size:14.5px;font-weight:700}
.rc-tier b{font-weight:800}
.rc-sub{font-size:12px;color:var(--text-3);font-weight:600;margin-top:2px}
.rc-bar{height:5px;border-radius:3px;background:var(--surface-3);overflow:hidden;margin:8px 0 4px}
.rc-bar i{display:block;height:100%;background:var(--red);border-radius:3px}
.rc-next{font-size:11px;color:var(--text-3);font-weight:700}

/* per-station chat */
/* dedicated, framed scroll box — stays put even with 1000+ messages (no chaining to the card) */
.chat-list{display:flex;flex-direction:column;gap:8px;height:260px;overflow-y:auto;
  overscroll-behavior:contain;-webkit-overflow-scrolling:touch;touch-action:pan-y;
  padding:10px;margin-top:4px;background:var(--bg);border:1px solid var(--line);border-radius:14px}
.chat-empty{margin:auto 0;color:var(--text-3);font-size:13px;text-align:center;padding:8px;line-height:1.45}
.chat-msg{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:9px 12px;flex:0 0 auto}
.chat-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:3px}
.chat-tag{font-size:11.5px;font-weight:800;color:var(--red)}
.chat-at{font-size:10.5px;color:var(--text-3);font-weight:600;flex:0 0 auto}
.chat-text{font-size:14px;color:var(--text);line-height:1.35;word-break:break-word}
.chat-box{display:flex;gap:8px;margin-top:10px}
.chat-box input{flex:1;min-width:0;height:44px;border-radius:12px;border:1px solid var(--line);
  background:var(--surface-2);padding:0 14px;font-size:16px;font-family:inherit;color:var(--text)}
.chat-box input:focus-visible{outline:2px solid var(--red);outline-offset:1px}
.chat-send{position:relative;flex:0 0 auto;width:44px;height:44px;border-radius:12px;background:var(--red);
  border:0;display:grid;place-items:center;overflow:hidden}
.chat-send .cs-ic{width:20px;height:20px;fill:#fff}
.chat-send .cs-timer{display:none;position:relative;z-index:1;font-weight:800;font-size:14px;
  color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.45)}
.chat-send:disabled:not(.cooling){opacity:.5}
/* rate-limited: send icon → animated depleting countdown ring + seconds left */
.chat-send.cooling{background:var(--surface-3)}
.chat-send.cooling .cs-ic{display:none}
.chat-send.cooling .cs-timer{display:block}
.chat-send.cooling::before{content:"";position:absolute;inset:0;z-index:0;
  background:conic-gradient(var(--red) calc(100% - var(--p,0%)), transparent 0)}

/* profile + Telegram login (me sheet) */
.profile-card{display:flex;align-items:center;gap:13px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r);padding:14px;margin:6px 0 4px}
.profile-card.guest{flex-direction:column;align-items:stretch;text-align:center;gap:12px}
.pf-av{width:48px;height:48px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;overflow:hidden;
  background:var(--red);color:#fff;font-weight:800;font-size:20px}
.pf-av img{width:100%;height:100%;object-fit:cover}
.pf-main{flex:1;min-width:0}
.pf-name{font-weight:800;font-size:16px;display:flex;align-items:center;gap:8px;flex-wrap:wrap;justify-content:center}
.profile-card:not(.guest) .pf-name{justify-content:flex-start}
.pf-stats{color:var(--text-3);font-size:12.5px;margin-top:2px;font-weight:600}
.vbadge{font-size:11px;font-weight:800;color:var(--st-yes);background:var(--st-yes-bg);
  border-radius:var(--r-pill);padding:3px 9px}
.tg-login{display:flex;justify-content:center;min-height:42px}
/* feedback */
.fb-area{width:100%;min-height:110px;resize:vertical;background:var(--surface-2);border:1px solid var(--line);
  border-radius:14px;padding:13px 15px;color:var(--text);font-family:inherit;font-size:15px;outline:none}
.fb-area:focus-visible{outline:2.5px solid var(--red);outline-offset:2px}

/* geo prime */
.geo-prime{position:fixed;inset:0;z-index:40;display:grid;place-items:end center;
  background:linear-gradient(0deg,rgba(8,9,20,.75),rgba(8,9,20,.35));backdrop-filter:blur(2px)}
.geo-card{background:var(--surface);background-image:var(--glow);width:100%;max-width:var(--sheet-max);
  border-radius:var(--r-lg) var(--r-lg) 0 0;padding:30px 24px calc(26px + var(--safe-b));text-align:center;
  box-shadow:var(--shadow);animation:slideUp .3s var(--ease);
  /* ландшафт (высота ~390): карточка выше экрана, скроллим её, а не срезаем заголовок */
  max-height:100dvh;overflow-y:auto}
.geo-emoji{font-size:46px}
.geo-card h2{font-size:23px;font-weight:800;letter-spacing:-.5px;margin:10px 0 6px}
.geo-card p{color:var(--text-2);font-size:14.5px;margin:0 auto 20px;max-width:330px}
.geo-card .btn{margin-top:10px}

/* safety / anti-fraud notice — slides up above the tab bar; pops every visit until «больше не показывать» */
.safety-pop{position:fixed;z-index:35;left:12px;right:12px;bottom:calc(80px + var(--safe-b));
  max-width:var(--sheet-max);margin:0 auto;background:var(--surface);background-image:var(--glow);
  border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow);
  padding:16px 16px 14px;animation:sp-in .34s var(--ease)}
@keyframes sp-in{from{opacity:0;transform:translateY(18px)}}
.safety-pop[hidden]{display:none}
.sp-close{position:absolute;top:10px;right:10px;width:30px;height:30px;border-radius:50%;
  display:grid;place-items:center;background:var(--surface-2);border:0}
.sp-close svg{width:15px;height:15px;fill:var(--text-3)}
.sp-head{display:flex;align-items:center;justify-content:center;gap:10px;padding:0 28px}
.sp-ic{width:36px;height:36px;border-radius:11px;flex:0 0 auto;display:grid;place-items:center;background:var(--st-yes-bg)}
.sp-ic svg{width:21px;height:21px;fill:var(--st-yes)}
.sp-head b{font-size:16px;font-weight:800;letter-spacing:-.2px}
.sp-text{color:var(--text-2);font-size:13.5px;line-height:1.45;margin:11px 0 0;text-align:center}
.sp-never{width:100%;margin-top:14px;padding:12px;border-radius:12px;background:var(--surface-2);
  border:1px solid var(--line);color:var(--text-2);font-weight:800;font-size:13.5px;font-family:inherit}
.sp-never:hover{color:var(--text);border-color:var(--text-3)}
@media (min-width:1024px){.safety-pop{left:50%;right:auto;width:400px;margin-left:-200px;bottom:calc(96px + var(--safe-b))}}

/* toast */
.toast{position:fixed;z-index:50;left:50%;bottom:calc(26px + var(--safe-b));transform:translateX(-50%);
  background:#1b1d2e;color:#fff;border:1px solid rgba(255,255,255,.12);
  padding:13px 18px;border-radius:14px;font-weight:700;font-size:14px;max-width:90vw;text-align:center;
  box-shadow:var(--shadow);animation:toastIn .25s var(--ease)}
.toast.err{background:#3a1420;border-color:rgba(255,59,92,.4)}
.toast.ok{background:#0f2e22;border-color:rgba(31,191,117,.4)}
@keyframes toastIn{from{opacity:0;transform:translate(-50%,12px)}}

/* station detail: address + copy */
.addr-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.addr-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
.copy-addr{flex:0 0 auto;display:inline-flex;align-items:center;gap:6px;height:30px;padding:0 12px;
  border-radius:9px;background:var(--surface-2);border:1px solid var(--line-2);
  color:var(--text-2);font-weight:700;font-size:12.5px;font-family:inherit}
.copy-addr svg{width:14px;height:14px;fill:var(--text-3)}
.copy-addr:hover{color:var(--text);border-color:var(--text-3)}
.copy-addr:active{background:var(--surface-3);transform:scale(.97)}
/* "не подтверждено" warning + confirm */
.pending-warn{display:flex;align-items:center;gap:10px;background:var(--st-no-bg);
  border:1px solid var(--st-no);border-radius:var(--r);padding:11px 13px;margin:14px 0 0}
.pending-warn>svg{width:22px;height:22px;fill:var(--st-no);flex:0 0 auto}
.pending-warn .pw-text{flex:1;font-size:13px;font-weight:600;line-height:1.35}
.pending-warn .pw-btn{flex:0 0 auto;background:var(--st-no);color:#fff;font-weight:800;font-size:12.5px;
  padding:9px 14px;border-radius:var(--r-pill)}
.pending-warn.conflict-warn{background:var(--st-queue-bg);border-color:var(--st-queue)}
.pending-warn.conflict-warn>svg{fill:var(--st-queue)}
.pending-warn.conflict-warn .pw-btn{background:var(--st-queue);color:#211600}
/* maintenance banner (set from /admin) */
.maint-banner{position:fixed;z-index:45;left:0;right:0;top:0;background:var(--st-queue);color:#1a1200;
  font-weight:800;font-size:13.5px;text-align:center;padding:9px 16px;line-height:1.3;
  box-shadow:0 4px 14px rgba(0,0,0,.25)}
.maint-banner svg{width:16px;height:16px;fill:#1a1200;vertical-align:-3px;margin-right:6px}
@media (min-width:1024px){body.has-maint .panel{padding-top:calc(76px + var(--maint-h))}}

/* add-station pick mode */
.pick-mode{position:fixed;inset:0;z-index:28;pointer-events:none}
.pick-cross{position:absolute;left:50%;top:50%;transform:translate(-50%,-100%);z-index:2}
.pick-cross svg{width:46px;height:46px;fill:var(--red);filter:drop-shadow(0 6px 10px rgba(0,0,0,.5))}
.pick-cross::after{content:"";position:absolute;left:50%;bottom:-3px;transform:translateX(-50%);
  width:10px;height:5px;border-radius:50%;background:rgba(0,0,0,.35)}
.pick-bar{position:absolute;left:50%;bottom:calc(24px + var(--safe-b));transform:translateX(-50%);
  width:calc(100% - 32px);max-width:var(--sheet-max);pointer-events:auto;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:var(--shadow);padding:14px 16px;text-align:center}
.pick-bar>span{display:block;font-weight:700;font-size:14px;margin-bottom:10px}
.pick-btns{display:flex;gap:10px}
.pick-btns .btn{margin:0}
/* pick-mode runs in map view (sidebar hidden → map is full screen), so centre on the whole viewport */

.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
[hidden]{display:none!important}

/* ============================================================
   RESPONSIVE
   ============================================================ */
/* DESKTOP: left sidebar + right map */
@media (min-width:1024px){
  .panel{left:0;top:0;bottom:0;width:var(--panel-w);border-right:1px solid var(--line);
    box-shadow:var(--shadow);padding-top:76px;transition:transform .28s var(--ease)}
  /* «Карта» → sidebar hidden, map full screen. «Рядом» → sidebar slides in, map shifts over. */
  body[data-view="map"] .panel{transform:translateX(-100%);box-shadow:none}
  body[data-view="list"] .panel{transform:translateX(0)}
  #map{left:0;transition:left .28s var(--ease)}
  body[data-view="list"] #map{left:var(--panel-w)}
  /* list view: Fbenz logo floats over the MAP (top-left), FineApp rises to the top-centre of the sidebar */
  body[data-view="list"] .brand{margin-left:calc(var(--panel-w) + 4px);transition:margin-left .28s var(--ease)}
  body[data-view="list"] .panel{padding-top:calc(var(--maint-h) + 14px)}
  /* было 14 слева и 24 справа: логотип стоял ближе к краю, чем кнопка города */
  .topbar{left:0;width:100%;padding-left:24px;padding-right:24px}      /* full width so actions have room */
  .topbar .top-actions{margin-left:auto}
  .city-btn{max-width:150px}
  .fab{right:24px;bottom:88px}                        /* sit above the desktop tab bar */
  .tabbar{left:0;right:0}                             /* full width when the map is full screen */
  body[data-view="list"] .tabbar{left:var(--panel-w)}/* over the map only when the sidebar is open */
  .tab{font-size:11.5px;max-width:120px}             /* roomier targets on a wide screen */
  /* sheets become centered modals over the WHOLE screen (not just the map area) */
  .sheet,.sheet-search{
    left:50%;
    top:50%;bottom:auto;transform:translate(-50%,-50%);
    border-radius:var(--r-lg);max-height:86vh;max-height:86dvh;animation:modalIn .24s var(--ease);
  }
  .sheet .sheet-grip{display:none}
  .panel-foot{display:block}
}
@keyframes modalIn{from{opacity:0;transform:translate(-50%,-46%)}}

/* sidebar footer: contacts + ad (desktop only) */
/* поля 16px, как у .panel-head и .list, иначе футер визуально уже списка */
.panel-foot{display:none;flex:0 0 auto;border-top:1px solid var(--line);
  padding:14px 16px calc(16px + var(--safe-b));background:var(--surface)}
/* ad slot → a real CTA card linking to Telegram (was a dashed placeholder) */
.ad-slot{display:flex;align-items:center;gap:11px;border:1px solid var(--line-2);border-radius:var(--r);
  padding:12px 14px;margin-bottom:14px;background:var(--surface-2);transition:border-color .15s,transform .12s var(--ease)}
.ad-slot:hover{border-color:var(--red);transform:translateY(-1px)}
.ad-slot>svg{width:22px;height:22px;fill:var(--red);flex:0 0 auto}
.ad-slot .ad-txt{flex:1;min-width:0;display:flex;flex-direction:column;line-height:1.25}
.ad-slot .ad-txt b{font-weight:800;font-size:13.5px;color:var(--text)}
.ad-slot .ad-txt small{font-weight:600;font-size:11.5px;color:var(--text-3);margin-top:2px}
.ad-slot .ad-arr{width:16px;height:16px;fill:var(--text-3);flex:0 0 auto}
.foot-links{display:flex;align-items:center;justify-content:center;gap:8px 4px;flex-wrap:wrap;font-weight:700;font-size:13px}
.foot-links a{color:var(--text-2);padding:3px 0;transition:color .12s}
.foot-links a:not(:last-child)::after{content:"·";color:var(--text-3);margin-left:8px;font-weight:700}
.foot-links a:hover{color:var(--red)}
.foot-copy{color:var(--text-3);font-size:11px;line-height:1.4;margin-top:11px;text-align:center}
/* footer is desktop-only — this wins over the base display:none above (source order) */
@media (min-width:1024px){.panel-foot{display:block}}
html[data-theme="light"] .badge.s-low{color:#6a5c00}
.search-field input:focus-visible{outline:2.5px solid var(--red);outline-offset:2px;border-radius:8px}

/* MOBILE: full map + floating panel(bottom sheet) + tab bar */
@media (max-width:1023px){
  /* Constant-height sheet anchored at the bottom; map↔list is a PURE transform slide (no top/height
     jump → smooth). Collapsed = peek 132px; «Рядом» = slide fully up. dvh dodges the iOS vh quirk. */
  /* collapsed peek height: content (grip + Fineapp + summary chips) + the tab-bar + the device
     safe-area, so the «Есть/Очередь/Нет» chips ALWAYS clear the bottom tab bar on every device
     (was clipped on iPhone with a home-indicator → «границы съехали»). 170px matches JS PEEK. */
  .panel{left:0;right:0;bottom:0;height:calc(100dvh - 72px - var(--maint-h));
    border-radius:var(--r-lg) var(--r-lg) 0 0;
    box-shadow:0 -10px 40px rgba(0,0,0,.4);transition:transform .34s var(--ease);
    transform:translateY(calc(100% - 170px - var(--safe-b)));padding-bottom:calc(70px + var(--safe-b))}
  html[data-theme="light"] .panel{box-shadow:0 -8px 30px rgba(20,22,45,.08)}
  body[data-view="list"] .panel{transform:translateY(0)}
  .panel-grip{display:block;width:100%;padding:11px 0 4px;background:none;touch-action:none}
  .panel-grip span{display:block;width:42px;height:5px;border-radius:3px;background:var(--line-2);margin:0 auto}
  .panel-head{padding-top:2px;touch-action:none}
  .list{overscroll-behavior:contain;transform:translateZ(0)}   /* GPU layer → smoother scroll (фикс подёргиваний) */
  #map{bottom:0}
  .fab{right:16px;bottom:calc(192px + var(--safe-b))}   /* clear the collapsed panel peek */
  .share-fab{left:auto;right:16px;bottom:calc(254px + var(--safe-b))}   /* мобила: справа над геолокацией, как было */
  body[data-view="list"] .fab,
  body[data-view="list"] .share-fab{opacity:0;pointer-events:none}
  /* collapsed peek shows ONLY grip+Fineapp+summary; поиск и фильтр — строго по свайпу
     (на iPhone строка с лупой выглядывала из-под таббара на пару пикселей) */
  body[data-view="map"] .filter,
  body[data-view="map"] .list-search,
  body[data-view="map"] .list-sug{display:none}
  .status-grid{grid-template-columns:1fr 1fr}
  /* extra bottom room so the last line of a scrolled sheet clears the iOS Safari toolbar (dvh caps height) */
  .sheet-body{padding-bottom:calc(34px + var(--safe-b))}
}
@media (max-width:1023px){.add-desktop{display:none}}
@media (max-width:380px){.city-btn{max-width:38vw}}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
}

/* Запомненные марки топлива. Визуально приглушены и подписаны возрастом, чтобы их нельзя
   было спутать с текущими: источник обнуляет разбивку через ~8 часов, и это ПАМЯТЬ. */
.fuel-memo{display:flex;flex-direction:column;gap:6px}
.fuel-memo-pills{display:flex;flex-wrap:wrap;gap:6px}
.fuel.was{opacity:.55;border-style:dashed}
.fuel-memo-note{font-size:12px;line-height:1.3;color:var(--muted)}

/* ==== маркеры и кластеры ==== */

/* ---------- 1. ТИШИНА В ПОКОЕ ----------
   На маркерах крутились ЧЕТЫРЕ бесконечные анимации разом: соннар «есть», мерцание
   «очереди», маячок «нет» и дыхание блюр-пятна. На сотне точек это не «живая карта»,
   а мельтешение, в котором глаз не находит ответа. Гасим всё; чужие правила не
   удаляем — перебиваем той же специфичностью ниже по каскаду (так правка обратима
   одним удалением этого блока).
   Остаётся РОВНО ОДИН момент движения на карте — появление свежей отметки. */
.fmk.s-yes .fmk-halo,.fmk.s-queue .fmk-halo,.fmk.s-low .fmk-halo,
.fmk.s-no .fmk-halo,.fmk.s-nodata .fmk-halo{animation:none;opacity:0}
.fmk::after,.fmk.s-no::after,.fmk.s-nodata::after{animation:none}
/* ...и возвращаем праздник обратно: он объявлен ВЫШЕ по файлу, наши глушилки его
   перекрыли бы (одинаковая специфичность, побеждает последний). */
.fmk.fb-just .fmk-coin{animation:fb-pop .6s var(--ease)}
.fmk.fb-just .fmk-halo{animation:fb-ping .66s var(--ease);animation-play-state:running!important}

/* ---------- 2. ИЕРАРХИЯ ПО СТАТУСУ ----------
   Раньше «нет данных» весил ровно столько же, сколько «есть», и экран читался как
   поле одинаковых точек. Теперь вес монеты = ценность ответа:
     есть        — крупнее и ярче всех, к нему тянется глаз;
     очередь/мало— заметны, но тише;
     нет         — ПОЛОЕ кольцо без заливки: читается, не кричит;
     нет данных  — мелкая приглушённая точка без логотипа. Это не ответ, а его отсутствие.
   Габарит иконки (36x36) и её якорь не трогаем: цель тапа остаётся 36px при любом
   размере монеты — монета центрируется отрицательными полями от 50%/50%. */
.fmk{
  --coin-b:25px;              /* базовый диаметр монеты — задаёт статус */
  --fr:1;                     /* коэффициент свежести — задаёт класс a-* */
  --coin:calc(var(--coin-b) * var(--fr) * var(--zf,1));
  --ring:4.5px;               /* толщина статусного кольца */
  --edge:#fff; --edge-w:2px;  /* белая отбивка монеты от пёстрой карты */
  --fill:var(--sc);           /* заливка: вдали статус, вблизи бренд (см. п.4) */
  --drop:0 3px 8px rgba(0,0,0,.38);
  --gold:0 0 0 0 transparent; /* кольцо «совпало с выбранной маркой» */
}
.fmk.match{--gold:0 0 0 calc(var(--ring) + 2.5px) #FFC83A}
.fmk.s-yes{--coin-b:27px;--ring:5px}
.fmk.s-queue,.fmk.s-low{--coin-b:25px;--ring:4.5px}
.fmk.s-no{--coin-b:23px;--ring:2.5px;--edge-w:0px;--fill:var(--surface)}
.fmk.s-nodata{--coin-b:16px;--ring:0px;--edge-w:1.5px;--edge:rgba(255,255,255,.82);
  --drop:0 1px 3px rgba(0,0,0,.3);opacity:.55}
/* Размер/фон/тени монеты собраны в ОДНО место: иначе три старых правила
   (.fmk-coin, .s-nodata .fmk-coin, .match .fmk-coin) дерутся за box-shadow. */
.fmk.s-yes .fmk-coin,.fmk.s-queue .fmk-coin,.fmk.s-low .fmk-coin,
.fmk.s-no .fmk-coin,.fmk.s-nodata .fmk-coin{
  width:var(--coin);height:var(--coin);
  margin:calc(var(--coin) / -2) 0 0 calc(var(--coin) / -2);
  background:var(--fill);
  box-shadow:0 0 0 var(--edge-w) var(--edge),0 0 0 var(--ring) var(--sc),
             var(--gold),var(--drop);
}
/* «нет» = полая монета. Глиф перекрашиваем в статус: белый на светлой теме пропал бы,
   потому что заливки под ним больше нет. Логотип сети приглушаем opacity, не filter. */
.fmk.s-no .fmk-coin{color:var(--st-no)}
/* «нет данных» = просто точка. Вместе с лицом бренда уходит и САМЫЙ дорогой слой карты:
   blur-пятно у 90% маркеров (на стенде 675 из 748 станций — nodata). */
.fmk.s-nodata .fmk-coin > *{display:none}
.fmk.s-nodata::after{display:none}
/* статусное пятно: размер по монете, вес по статусу */
.fmk::after{width:var(--coin);height:var(--coin);
  margin:calc(var(--coin) / -2) 0 0 calc(var(--coin) / -2);opacity:.5}
.fmk.s-yes::after{opacity:.6}
.fmk.s-queue::after,.fmk.s-low::after{opacity:.4}
.fmk.s-no::after{opacity:.3}
/* подпись марок отсчитываем от КРАЯ монеты, а не от фиксированных 16px:
   монета теперь плавает по размеру, и «есть» иначе налезло бы на подпись */
.fmk-fuels{top:calc(50% + var(--coin) / 2 + var(--ring) + 3px)}

/* ---------- 3. ИЕРАРХИЯ ПО СВЕЖЕСТИ ----------
   Отметка трёхминутной давности и вчерашняя стоили глазу одинаково, хотя это
   принципиально разная ценность. Ступени: до часа / до 6 ч / до 24 ч / старше суток.
   Свежее — крупнее и ярче, старше — мельче и глуше; возраст читается ДО чтения текста.
   Класс вешает JS только там, где есть чему стареть (статус != nodata): у «нет данных»
   last_at — это возраст точки в базе, а не возраст ответа, врать им нельзя. */
.fmk.a-hot{--fr:1.08}
.fmk.a-warm{--fr:1}
.fmk.a-cool{--fr:.9;opacity:.8}
.fmk.a-cold{--fr:.82;opacity:.6}
/* самое свежее «есть» добирает вес ещё и кольцом — это громкость номер один на карте */
.fmk.a-hot.s-yes{--ring:6px}
/* безбрендовая капля живёт по тем же ступеням; размер у неё завязан на rotate-трансформ
   (.is-active), поэтому её не масштабируем — только приглушаем */
.gpin.a-cool{opacity:.82}
.gpin.a-cold{opacity:.62}
.gpin.s-nodata{opacity:.5}
.gpin.s-nodata .gpin-glow{display:none}
.gpin.s-no .gpin-body{background:var(--surface);border-color:var(--st-no)}
.gpin.s-no .gpin-body svg{fill:var(--st-no)}
.gpin.s-no .gpin-glow{opacity:.35}

/* ---------- 4. БРЕНД — ТОЛЬКО ВБЛИЗИ ----------
   На дальнем зуме логотип нечитаем, а фирменная заливка монеты (красный Лукойл,
   синяя Газпромнефть, жёлтая Роснефть) прямо конкурирует со статусным цветом:
   человек ищет зелёное, а спотыкается о бренд. Поэтому вдали монета = чистый статус,
   с z14 (≈1.5 км по ширине экрана мобилы, на виду единицы АЗС) возвращаются и заливка,
   и логотип. Класс fb-brand ставит JS на контейнер карты по zoomend — тем же
   механизмом, что и существующий fb-lbl. */
.fmk-coin > *{opacity:0;transition:opacity .14s var(--ease)}
.leaflet-container.fb-brand .fmk-coin > *{opacity:1}
.leaflet-container.fb-brand .fmk{--fill:var(--bc,var(--surface-3))}
.leaflet-container.fb-brand .fmk.s-no{--fill:var(--surface)}
.leaflet-container.fb-brand .fmk.s-nodata{--fill:var(--st-nodata)}
/* логотип «нет» приглушаем только там, где он вообще виден: иначе это правило
   специфичнее зум-гейта и вытаскивало бы логотип обратно на дальнем зуме */
.leaflet-container.fb-brand .fmk.s-no .fmk-coin .blogo{opacity:.42}
/* Вдали заливка и кольцо — один и тот же статусный цвет, и белая отбивка между ними
   читалась мишенью. Схлопываем кольцо в отбивку: получается сплошной статусный диск.
   Потерянный кольцом вес возвращаем множителем --zf, чтобы габарит маркера не прыгал
   на пороге зума. У «нет» кольцо остаётся: полая монета — это и есть кольцо. */
.leaflet-container:not(.fb-brand) .fmk{--ring:var(--edge-w);--zf:1.16}
.leaflet-container:not(.fb-brand) .fmk.s-no{--ring:2.5px}
.leaflet-container:not(.fb-brand) .fmk.s-nodata{--zf:.95}

/* ---------- 5. КЛАСТЕР ОТВЕЧАЕТ, А НЕ СЧИТАЕТ ----------
   Пончик сообщал «двадцать чего-то»: число в центре и пирог по краю, где серый сегмент
   «нет данных» весил столько же, сколько зелёный «есть». Теперь:
     · сегмент «нет данных» почти прозрачен → длина цветной дуги = доля РЕАЛЬНОГО знания;
     · внутри есть бензин → число зелёное, подложка с зелёным подмесом;
     · внутри нет ни одного «есть/очередь/мало» → кольцо гаснет, пончик мельчает
       и уходит на задний план.
   Стена одинаковых кружков сама собой разрешается в «где зелено».
   Гасим НЕ через opacity на всём пончике (число ушло бы за порог контраста), а
   отдельной вуалью .clp::after под подложкой — цифра остаётся читаемой. */
:root{--cl-void:rgba(120,126,155,.16)}
html[data-theme="light"]{--cl-void:rgba(20,22,45,.10)}
.clp{box-shadow:var(--shadow-sm)}
.clp::before{background:var(--surface);z-index:1}
.clp span{color:var(--text-2);font-weight:600;font-size:13.5px;z-index:2}
.clp.has-yes::before{background:linear-gradient(var(--st-yes-bg),var(--st-yes-bg)),var(--surface)}
.clp.has-yes span{color:var(--st-yes)}
.clp.is-quiet{transform:scale(.82)}
.clp.is-quiet::after{content:"";position:absolute;inset:0;border-radius:50%;
  background:var(--bg);opacity:.6;z-index:0}

/* ---------- 6. ДОСТУПНОСТЬ ----------
   Глобальный reduced-motion в файле уже режет длительности, но своё правило держим
   явным: единственная оставшаяся анимация и единственный transition должны исчезать
   гарантированно, а не «стать 0.01мс». */
@media (prefers-reduced-motion:reduce){
  .fmk.fb-just .fmk-coin,.fmk.fb-just .fmk-halo,.gpin-just .gpin-body{animation:none}
  .fmk-coin > *{transition:none}   /* зум-гейт бренда остаётся: это информация, а не движение */
}

/* ==== бюджет экрана и хром (верх / низ / десктоп / safe-area) ==== */

/* Вертикальная лесенка верха отсчитывалась только от --maint-h, вырез не учитывался вовсе:
   в standalone-PWA с viewport-fit=cover шапка заезжала под чёлку. Считаем через max(),
   а не сумму: баннер техработ сам получил отступ выреза, а setMaintOffset() меряет его
   offsetHeight уже вместе с этим отступом — сложение дало бы двойной сдвиг. */
:root{
  --top-safe:env(safe-area-inset-top,0px);
  --chrome-top:max(var(--maint-h), var(--top-safe));
}
.maint-banner{padding-top:calc(9px + var(--top-safe))}
.topbar{top:var(--chrome-top)}
.actionbar{top:calc(var(--chrome-top) + 62px)}
.gpn-chips{top:calc(var(--chrome-top) + 108px)}
.install-banner{top:calc(var(--chrome-top) + 110px)}

/* Баннер установки — подсказка, а не контент: одна строка вместо карточки в три этажа.
   Высота была 69px из-за .ib-logo{width:34px;height:auto} — картинка вертикальная,
   поэтому размер задаём по ВЫСОТЕ, а ширину отдаём пропорции. */
.install-banner{padding:3px 6px 3px 10px;gap:8px;border-radius:14px}
.ib-logo{width:auto;height:20px}
.ib-text{flex-direction:row;align-items:center;gap:6px;overflow:hidden}
.ib-text b{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ib-text span{display:none}
.ib-add{padding:6px 12px;font-size:12px;font-weight:600}
.ib-close{width:26px;height:26px}
.ib-close svg{width:14px;height:14px}

/* ---------------------------------------------------------------------------
   МОБИЛА. Было три плавающие полосы, стало две плотные (одна смысловая зона)
   плюс строка-подсказка. Замер 390x844: верх 179px -> 115px, свёрнутая панель
   170px -> 142px, живой карты 495px -> 587px (58% -> 70% экрана).
   --------------------------------------------------------------------------- */
@media (max-width:1023px){
  /* citySheet прибит к верху экрана — его тоже надо опустить из-под выреза.
     Если автор шитов переписывает .sheet-search, эту строку можно выкинуть. */
  .sheet-search{top:var(--chrome-top)}

  /* --- строка 1: бренд + город + лупа + тема --- */
  .topbar{height:44px;padding:5px 12px;
    padding-left:max(12px,env(safe-area-inset-left,0px));
    padding-right:max(12px,env(safe-area-inset-right,0px))}
  .brand{padding:6px 12px 6px 10px;gap:6px}
  .brand-logo{height:21px}
  .top-actions{gap:6px;margin-right:80px}   /* место под вынесенные сюда лупу и тему */
  .city-btn{padding:7px 11px;font-size:13.5px;font-weight:600;max-width:34vw}
  .city-btn .ic{width:16px;height:16px}
  .city-btn .ic-chev{width:15px;height:15px}

  /* Лупа и тема — про приложение, а не про карту, поэтому им место в строке бренда.
     Вынимаем их из потока .actionbar через position:fixed и НЕ трогаем разметку:
     контейнер остаётся их родителем, значит гашение в списке (opacity), pointer-events
     и режим «Газпром» продолжают ими управлять ровно как раньше. */
  #searchBtn,#themeBtn{position:fixed;top:calc(var(--chrome-top) + 5px);
    width:34px;height:34px;padding:0}
  #themeBtn{right:max(12px,env(safe-area-inset-right,0px))}
  #searchBtn{right:calc(max(12px,env(safe-area-inset-right,0px)) + 40px)}

  /* --- строка 2: только тумблеры карты, прижаты влево под бренд --- */
  .actionbar{top:calc(var(--chrome-top) + 43px);gap:8px;justify-content:flex-start;
    left:max(12px,env(safe-area-inset-left,0px));
    right:max(12px,env(safe-area-inset-right,0px))}
  #availBtn{margin-right:0}                       /* auto-отступ разгонял пару по краям */
  body[data-mode="gpn"] #gpnBtn{margin-left:0}
  .act-pill{height:34px;padding:0 12px;font-size:12.5px}
  .act-pill svg{width:17px;height:17px}
  .act-pill.act-ico{width:34px}
  .act-gpn img{width:18px;height:18px}

  /* --- строка 3: тонкая подсказка установки --- */
  .install-banner{top:calc(var(--chrome-top) + 81px)}
  .gpn-chips{top:calc(var(--chrome-top) + 82px)}  /* в режиме ГПН баннера нет — занимаем его место */

  /* --- НИЗ: свёрнутая панель --- */
  /* Плашка Fineapp переезжает в строку грипа отдельным чипом: видимость и клик те же
     (чип даже заметнее прежней строки), но собственная строка в 27px из пика уходит.
     Грип раньше был 20px пустоты — теперь он несёт плашку. */
  .panel{transform:translateY(calc(100% - 142px - var(--safe-b)))}
  .panel-grip{padding:12px 0 13px}
  .panel-fine{position:absolute;top:5px;right:max(14px,env(safe-area-inset-right,0px));
    height:24px;padding:0 10px;gap:5px;border-radius:var(--r-pill);
    background:var(--surface-2);border:1px solid var(--line);z-index:2}
  .panel-fine img{height:13px}
  .panel-fine span{font-size:12px}
  .panel-head{padding-top:0}
  .summary{padding-bottom:6px}
  .chip{padding:6px 11px;font-size:12.5px}
  .fab{bottom:calc(164px + var(--safe-b))}        /* пик 142 + 22, как было 170 + 22 */
  .share-fab{bottom:calc(226px + var(--safe-b))}

  /* В списке гасли ВСЕ действия разом. Теперь в этой строке живут лупа и тема — они
     в списке как раз к месту (лупа ставит курсор в поле поиска), а прятать надо только
     тумблеры карты: фильтровать нечего, карта под панелью. */
  body[data-view="list"] .actionbar{opacity:1}
  body[data-view="list"] #availBtn,
  body[data-view="list"] #gpnBtn{opacity:0;pointer-events:none}

  /* Цели тапа. Пилюли ужались до 34px ради высоты карты, но палец меряет не пиксели
     краски: прозрачный ::after растягивает область нажатия до 44px, ничего не двигая. */
  .act-pill,.city-btn,.ib-add,.ib-close{position:relative}
  .act-pill::after,.city-btn::after,.ib-add::after,.ib-close::after,.panel-fine::after{
    content:"";position:absolute;left:0;right:0;top:50%;height:44px;transform:translateY(-50%)}
  .ib-close::after,.panel-fine::after{left:-9px;right:-9px}
}
/* иконочные свёртки узких экранов — под новую высоту пилюли */
@media (max-width:360px){ .act-pill.act-ico,#availBtn{width:34px} }
@media (max-width:368px){ #gpnBtn{width:34px} }

/* ---------------------------------------------------------------------------
   ДЕСКТОП. Карта и список тут ОДИН экран, а не два режима (applyView приводит вид
   к list), поэтому мобильный таббар во всю ширину внизу — лишняя полоса: JS переносит
   его внутрь панели (блок в конце app.js), а здесь он становится рядом действий.
   --------------------------------------------------------------------------- */
@media (min-width:1024px){
  .panel>.tabbar{position:static;flex:0 0 auto;justify-content:stretch;gap:10px;
    padding:10px 16px;border-top:1px solid var(--line);background:transparent}
  html[data-theme] .panel>.tabbar{box-shadow:none}
  /* «Карта» и «Ситуация» на ПК — переключатели в никуда: обе панели уже на экране */
  .panel>.tabbar .tab[data-tab="map"],
  .panel>.tabbar .tab[data-tab="list"]{display:none}
  .panel>.tabbar .tab{flex:1 1 0;flex-direction:row;justify-content:center;gap:8px;
    min-height:44px;padding:0 12px;max-width:none;border-radius:var(--r-sm);
    background:var(--surface-2);border:1px solid var(--line);
    font-size:13.5px;font-weight:600;color:var(--text-2);
    transition:border-color .15s var(--ease),color .15s var(--ease)}
  .panel>.tabbar .tab:hover{border-color:var(--red);color:var(--text)}
  .panel>.tabbar .tab svg{width:19px;height:19px;flex:0 0 auto}
  .panel>.tabbar .tab span{max-width:none}
  .panel>.tabbar .tab.tab-add{background:var(--red);border-color:var(--red);color:#fff}
  .panel>.tabbar .tab.tab-add svg{fill:#fff}
  .panel>.tabbar .tab.tab-add:hover{color:#fff;border-color:var(--red)}

  /* панель на ПК всегда на месте — верхний отступ считаем и от выреза тоже */
  body[data-view="list"] .panel{padding-top:calc(var(--chrome-top) + 14px)}

  /* низ карты освободился от таббара — опускаем всё, что стояло над ним */
  .fab{bottom:calc(24px + var(--safe-b))}
  .share-fab{bottom:calc(24px + var(--safe-b))}
  .leaflet-bottom .leaflet-control-zoom{margin:0 24px 88px 0}
  .safety-pop{bottom:calc(28px + var(--safe-b))}
  .net-chip{bottom:calc(24px + var(--safe-b))}

  /* баннер установки больше не накрывает фильтр — он уехал на сторону карты.
     :not([hidden]) обязателен: без него display:flex переиграл бы .install-banner[hidden] */
  .install-banner{left:calc(var(--panel-w) + 24px);right:auto;width:360px}
  body[data-view="list"] .install-banner:not([hidden]){display:flex}

  /* Выбор точки для новой АЗС: endPick() берёт S.map.getCenter(), а прицел рисуется
     по центру своего слоя. Раньше сайдбар в этот момент уезжал и центры совпадали;
     теперь панель на месте, поэтому слой прицела обязан начинаться от края карты. */
  .pick-mode{left:var(--panel-w)}

  /* режим «Газпром» прячет панель целиком — карта обязана занять её место,
     иначе слева остаётся мёртвая полоса в 392px */
  body[data-mode="gpn"] #map{left:0}
  body[data-mode="gpn"] .pick-mode{left:0}
  body[data-mode="gpn"] .actionbar{left:24px}
  body[data-mode="gpn"] .gpn-chips{left:24px}
  body[data-mode="gpn"] .install-banner{left:24px}
  body[data-mode="gpn"] .brand{margin-left:0}
  body[data-mode="gpn"] .share-fab{left:24px}
}

@media (prefers-reduced-motion:reduce){
  .panel>.tabbar .tab{transition:none}
}

/* ==== карточки, типографика, провенанс ====
   Автор области: карточка списка .card, карточка станции .st-card, типографическая
   шкала, возраст отметки, подтверждения, марки топлива, кризисные признаки.
   Ни одного нового цвета — только переменные из :root. Ни одной бесконечной анимации:
   бюджет движения по дизайн-тезису отдан переходам интерфейса, не покою. */

/* ---- A. ШКАЛА ВЕСОВ FINEAPP -------------------------------------------------
   В файле почти весь текст набран 700-850. Из-за этого в карточке нет иерархии:
   бренд, статус, марки и километры кричат одинаково громко, и глазу не за что
   зацепиться. Fineapp говорит тише: заголовок 600, тело 400-500, акцент 600.
   Ниже — только веса и кегли, структура и цвета не трогаются. */
.card-name h3{font-size:17px;font-weight:600;letter-spacing:-.1px}
.card-name .addr{font-size:13px;font-weight:400;color:var(--text-3);margin-top:3px}
.badge{font-weight:600;font-size:12.5px;padding:6px 11px}
.logo{font-weight:600}
.fuel{font-weight:500;font-size:12px}
.fuel-empty{font-weight:400;font-size:13px}
.meta{font-weight:400;font-size:12.5px}
.meta .km{font-weight:600;color:var(--text)}
.mini-btn{font-weight:600;font-size:13px}
.price{font-weight:400}
.price b{font-weight:600}
.show-all{font-weight:600}
.card-invite{font-size:13px;font-weight:400;line-height:1.45;color:var(--text-3)}
.card-trust{font-weight:600}
/* соседи заправок в списке. Если промо оставить на 800, оно перекричит сами карточки —
   а это ровно та ошибка, из-за которой список читается как рекламная лента */
.ad-h,.tg-h{font-weight:600;font-size:15px;letter-spacing:-.1px}
.ad-s,.tg-s{font-weight:400;font-size:13px}
.tg-tag{font-weight:600}
.list-fine span{font-weight:500}
/* шиты и кнопки — тот же шаг вниз, иначе карточка тихая, а деталка всё ещё орёт */
.sheet h2{font-weight:600;letter-spacing:-.3px}
.sheet .sub{font-weight:400}
.section-label{font-weight:600;font-size:11px;letter-spacing:.09em}
.btn{font-weight:600}

/* ---- B. КАРТОЧКА СПИСКА ------------------------------------------------------
   Плитка 48, поле 16, воздух между блоками — ритм Fineapp: иконка, заголовок,
   приглушённый адрес, дальше содержимое.
   Фон карточки СОЗНАТЕЛЬНО оставлен --surface-2, хотя тезис называет --surface:
   у Fineapp карточка лежит на --bg, а у нас — внутри .panel, которая сама --surface.
   Перекрасив карточку в --surface, мы бы слили её с панелью в одно полотно. */
.card{padding:16px;border-radius:var(--r)}
.card-top{gap:12px;align-items:center}
.logo{width:48px;height:48px;border-radius:14px;font-size:16px}
.ad-logo,.tg-ic{width:48px;height:48px;border-radius:14px}
.ad-logo img{width:32px}
.ad-card,.tg-card{padding:13px 14px;gap:12px;border-radius:var(--r)}
.fuels{margin-top:14px}
.card-foot{margin-top:14px}
.card-info{gap:10px}
/* цель тапа 44px без раздувания самой кнопки: видимая пилюля остаётся компактной,
   а невидимый ::after добирает недостающие миллиметры до пальца */
.mini-btn{position:relative;min-height:38px;padding:9px 14px}
.mini-btn::after{content:"";position:absolute;inset:-3px -2px;border-radius:inherit}

/* ---- C. ПРОВЕНАНС: ВОЗРАСТ ОТМЕТКИ И ПОДТВЕРЖДЕНИЯ ---------------------------
   Это единственное, чего нет ни у Яндекса, ни у Сбера, ни у Альфы: у нас видно,
   КОГДА и СКОЛЬКО живых людей это видели. Раньше «3 мин назад» и «36 дн назад»
   были одинаковым серым 12px — самое ценное поле выглядело как сноска.
   Теперь возраст считывается за один взгляд по четырём ступеням (час / 6 часов /
   сутки / протухло): свежее темнее, весомее, точка залита; старое — тише и точка
   полая. Ступени намеренно те же, что у маркеров на карте, чтобы список и карта
   говорили об одном и том же одним языком. */
.age{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;
  font-size:12.5px;line-height:1.2;font-variant-numeric:tabular-nums}
.age-dot{width:7px;height:7px;border-radius:50%;flex:0 0 auto;background:currentColor}
/* до часа — данные, ради которых стоит ехать */
.age-now{color:var(--st-yes);font-weight:600}
.age-now .age-dot{box-shadow:0 0 0 3px var(--st-yes-bg)}
/* до 6 часов — ещё рабочие, но уже не «прямо сейчас» */
.age-warm{color:var(--text);font-weight:500}
.age-warm .age-dot{background:var(--st-low)}
/* до суток — справочные */
.age-day{color:var(--text-2);font-weight:400}
.age-day .age-dot{background:var(--st-nodata)}
/* старше суток и «никто не отмечал» — полая точка: форма, а не только цвет,
   чтобы разница читалась и при дальтонизме, и в ч/б скриншоте */
.age-old,.age-none{color:var(--text-3);font-weight:400}
.age-old .age-dot,.age-none .age-dot{background:none;box-shadow:inset 0 0 0 1.5px currentColor}
/* подтверждение — это второй человек, который доехал и увидел то же самое.
   Одинокая отметка такого веса не имеет, поэтому у чипа есть подложка. */
.conf-chip{display:inline-flex;align-items:center;gap:5px;white-space:nowrap;
  font-size:12px;font-weight:500;line-height:1.2;color:var(--st-yes);
  background:var(--st-yes-bg);border-radius:var(--r-pill);padding:4px 10px 4px 8px}
.conf-chip svg{width:13px;height:13px;fill:currentColor;flex:0 0 auto}
.conf-chip b{font-weight:600;font-variant-numeric:tabular-nums}
/* подтверждённое «топлива нет» — такая же ценность, но зелёный тут соврал бы */
.conf-chip.conf-neg{color:var(--st-no);background:var(--st-no-bg)}
/* в деталке чипы стоят в строке .sts-meta вперемешку с текстовыми ветками —
   поэтому они inline, а не flex-элементы: текстовые ветки не должны ломаться */
.sts-meta .age,.sts-meta .conf-chip{vertical-align:middle;margin:2px 8px 2px 0}

/* ---- D. МАРКА, ПО КОТОРОЙ ФИЛЬТРУЮТ ------------------------------------------
   Водитель с выбранной маркой смотрит карточку ради одной пилюли из пяти, а ровный
   ряд одинакового веса заставляет искать её глазами. Кольцо снимает этот шаг.
   Класс .hit переиспользован от .price.hit — одна и та же идея «это твоё». */
.fuel.hit{font-weight:600;border-color:transparent;box-shadow:0 0 0 1.5px currentColor}
.fuel.hit:not(.on):not(.no){color:var(--text);box-shadow:0 0 0 1.5px var(--text-3)}

/* ---- E. КРИЗИСНЫЕ ПРИЗНАКИ: ЛИМИТ, ТОЛЬКО КАРТЫ, НЕТ НАЛИЧКИ -----------------
   В дефицит это и решает, ехать или нет: приедешь с наличкой на «только карты» —
   зря сжёг бензин. Тремя цветными плашками подряд оно читалось как декор и терялось
   среди цен. Собираем в одну спокойную полку: цвет остаётся ТОЛЬКО в иконке, текст
   обычный, а заметность даёт подложка и то, что блок стоит отдельной строкой. */
.itags{gap:8px 16px;margin-top:12px;padding:10px 12px;align-items:center;
  background:var(--surface-3);border-radius:var(--r-sm)}
.itag{padding:0;border-radius:0;background:none;gap:7px;
  font-size:12.5px;font-weight:500;color:var(--text)}
.itag svg{width:16px;height:16px}
.itag b{font-weight:600;font-variant-numeric:tabular-nums}
.itag-limit{background:none;color:var(--text)}
.itag-limit svg{fill:var(--st-queue)}
.itag-cash{background:none;color:var(--text)}
.itag-cash svg{fill:var(--st-no)}
.itag-fuelcard{background:none;color:var(--text)}
.itag-fuelcard svg{fill:#73a6ff}
html[data-theme="light"] .itag-fuelcard{background:none;color:var(--text)}
html[data-theme="light"] .itag-fuelcard svg{fill:#2f70d9}

/* ---- F. КАРТОЧКА СТАНЦИИ В ДЕТАЛКЕ ------------------------------------------
   Тот же язык, что и в списке: плитка 48/14, радиус 20, заголовок 600, подпись
   приглушена. 21px/800 в .sts-title смотрелось баннером, а не карточкой. */
.st-card{padding:18px;border-radius:var(--r)}
.st-card-head{gap:14px;align-items:center}
.sts-icon{width:48px;height:48px;border-radius:14px}
.sts-icon svg{width:26px;height:26px}
.sts-info{padding-top:0}
.sts-title{font-size:20px;font-weight:600;letter-spacing:-.3px}
.sts-lead{font-size:14px;font-weight:400;color:var(--text-2);opacity:1;margin-top:5px}
.sts-meta{font-size:12.5px;font-weight:400;margin-top:9px;line-height:1.5}
.stale-badge{font-weight:500}
.actual-q{font-weight:600;font-size:14.5px}
.actual-hint{font-weight:400;font-size:13px;color:var(--text-3)}
.st-stat .n{font-weight:600}
.st-stat .l{font-weight:400}
.st-dist{font-weight:500;font-size:13px;color:var(--text-2)}
.data-source{font-weight:400;font-size:12px;color:var(--text-3)}

/* ---- G. ТАБЛИЧНЫЕ ЦИФРЫ ------------------------------------------------------
   renderList перерисовывает список на каждой букве поиска и после каждой отметки.
   Пропорциональные цифры при этом дёргают строку по горизонтали — «1.4 км» и
   «11.4 км» имеют разную ширину. Таблица держит колонку на месте. */
.card,.st-card,.st-head,.prices,.itags,.age,.conf-chip,.meta,.fuel,.st-dist,.st-stat{
  font-variant-numeric:tabular-nums}

/* ---- H. ДОСТУПНОСТЬ И ДОЛГИ --------------------------------------------------
   В этой области нет ни одной бесконечной анимации: ступени возраста держатся на
   цвете, весе и ФОРМЕ точки, а не на движении — значит при reduced-motion картинка
   не теряет ни бита смысла. Правило ниже — страховка на случай, если кто-то из
   соседних областей повесит переход на эти же классы. */
@media (prefers-reduced-motion:reduce){
  .age,.age-dot,.conf-chip,.fuel.hit,.itag,.card{animation:none!important;transition:none!important}
}
/* долг из строки 1307: переменной --muted нет ни в одной теме, подпись памяти марок
   падала в inherit и красилась цветом родителя */
.fuel-memo-note{color:var(--text-3);font-weight:400;font-size:12px}
.fuel-memo{gap:7px}
.fuel.was{opacity:.5}

/* ==== ОТВЕТ ПЕРВОГО ЭКРАНА (.fbans) ==== */
/* Конкуренты открываются полем точек и заставляют человека самому добывать ответ.
   Этот блок отвечает сразу: куда ехать, далеко ли, насколько свежие данные.
   В ПОКОЕ не двигается вообще (ни одной бесконечной анимации), весь бюджет движения
   потрачен на вход: подъём карточки + короткий каскад строк. */
.fbans{
  flex:0 0 auto;                      /* десктоп: обычный блок в колонке .panel, не сжимается */
  margin:12px 16px 2px;
  position:relative;
  padding:12px 14px 13px;
  background:var(--surface-2);background-image:var(--glow);
  border:1px solid var(--line-2);border-radius:var(--r);
  box-shadow:var(--shadow-sm);
  opacity:0;transform:translateY(-10px);
  transition:opacity .3s var(--ease),transform .36s var(--ease);
}
.fbans.is-in{opacity:1;transform:none}
/* режим «Газпром» ведёт свой контур официальных статусов, наш ответ там врал бы */
body[data-mode="gpn"] .fbans{display:none}

/* строки карточки: каскад только на ПЕРВОМ показе (.is-intro снимается через 1.5с),
   иначе он переигрывался бы на каждой букве в поиске */
.fbans.is-intro .fbans-row{animation:fbans-row .34s var(--ease) both;animation-delay:calc(var(--i,0) * 60ms + 90ms)}
@keyframes fbans-row{from{opacity:0;transform:translateY(7px)}}

.fbans-eyebrow{display:block;margin:0 34px 9px 0;
  font-size:11px;font-weight:600;letter-spacing:1.1px;text-transform:uppercase;color:var(--text-3)}

/* крестик: визуально 32px, зона тапа расширена до 44px через ::after */
.fbans-x{position:absolute;top:7px;right:7px;width:32px;height:32px;border-radius:50%;
  display:grid;place-items:center;color:var(--text-3);background:none;transition:background .15s,color .15s}
.fbans-x::after{content:"";position:absolute;inset:-6px}
.fbans-x svg{width:15px;height:15px;fill:currentColor}
.fbans-x:hover{background:var(--surface-3);color:var(--text)}

.fbans-head{display:flex;align-items:center;gap:11px;width:100%;padding:0;
  background:none;border:0;color:inherit;text-align:left;font-family:inherit;
  transition:transform .12s var(--ease)}
.fbans-head:active{transform:scale(.99)}
.fbans-logo{width:42px;height:42px;border-radius:12px;flex:0 0 auto;position:relative;overflow:hidden;
  display:grid;place-items:center;color:#fff;font-weight:600;font-size:14px;letter-spacing:-.3px}
.fbans-logo svg{width:22px;height:22px;fill:currentColor}
.fbans-name{flex:1;min-width:0;display:block}
.fbans-title{display:block;margin:0;font-size:16.5px;font-weight:600;letter-spacing:-.2px;line-height:1.25;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fbans-meta{display:block;margin:2px 0 0;font-size:12.5px;line-height:1.3;color:var(--text-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fbans-meta b{color:var(--text);font-weight:600}
/* пустые состояния: в заголовке не имя бренда, а фраза, её нельзя резать многоточием */
.fbans-head.is-text{align-items:flex-start}
.fbans-head.is-text .fbans-title{white-space:normal;font-size:15.5px;line-height:1.28;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

.fbans-badge{display:inline-flex;align-items:center;gap:5px;flex:0 0 auto;
  border-radius:var(--r-pill);padding:5px 10px;font-weight:600;font-size:12px}
.fbans-badge svg{width:13px;height:13px;fill:currentColor}
.fbans-badge.s-yes{color:var(--st-yes);background:var(--st-yes-bg)}
.fbans-badge.s-queue{color:var(--st-queue);background:var(--st-queue-bg)}
.fbans-badge.s-low{color:var(--st-low);background:var(--st-low-bg)}
.fbans-badge.s-no{color:var(--st-no);background:var(--st-no-bg)}
.fbans-badge.s-nodata{color:var(--st-nodata);background:var(--st-nodata-bg)}

.fbans-fuels{display:flex;gap:6px;flex-wrap:wrap;margin-top:10px}
.fbans-f{font-weight:600;font-size:11.5px;padding:4px 9px;border-radius:8px;
  background:var(--st-yes-bg);color:var(--st-yes)}

/* строка честности: возраст данных и подтверждения. Точка красится статусом, не мигает. */
.fbans-note{display:flex;align-items:flex-start;gap:8px;margin:10px 0 0;
  font-size:12.5px;line-height:1.35;color:var(--text-2)}
.fbans-dot{width:7px;height:7px;border-radius:50%;flex:0 0 auto;margin-top:5px;background:var(--st-yes)}
.fbans-note.is-warn{color:var(--st-queue)}
.fbans-note.is-warn .fbans-dot{background:var(--st-queue)}

.fbans-text{margin:9px 0 0;font-size:13px;line-height:1.45;color:var(--text-2)}
.fbans-text b{color:var(--text);font-weight:600}

.fbans-acts{display:flex;gap:8px;margin-top:12px}
.fbans-btn{flex:1;min-height:44px;padding:11px 12px;border-radius:14px;
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  font-family:inherit;font-weight:600;font-size:13.5px;
  background:var(--surface-3);color:var(--text);border:1px solid var(--line);
  transition:transform .12s var(--ease),background .15s,border-color .15s}
.fbans-btn svg{width:16px;height:16px;fill:currentColor;flex:0 0 auto}
.fbans-btn:hover{border-color:var(--line-2)}
.fbans-btn:active{transform:scale(.98)}
/* главная кнопка шире второстепенной, чтобы её подпись жила в одну строку на 360px */
.fbans-btn-red{flex:1.7;background:var(--red);border-color:var(--red);color:#fff}
.fbans-btn-red:active{background:var(--red-2)}

/* ссылка-хвост: 34px по виду, 46px по зоне тапа (::after), иначе карточка растёт впустую */
.fbans-link{position:relative;display:inline-flex;align-items:center;gap:6px;min-height:34px;margin-top:4px;
  background:none;border:0;padding:0;font-family:inherit;font-weight:600;font-size:12.5px;
  color:var(--text-2);transition:color .12s}
.fbans-link::after{content:"";position:absolute;inset:-6px -8px}
.fbans-link svg{width:13px;height:13px;fill:currentColor}
.fbans-link:hover{color:var(--red)}
.fbans-link.is-accent{color:var(--red)}

/* МОБИЛА: карточка плавает над картой, ровно под строкой действий.
   В body фиксируем её намеренно: .panel трансформирован, а transform у предка ломает
   position:fixed у потомков, внутри панели она уехала бы вместе с ней.
   СБОРКА: полка пересчитана под уплотнённый хром (topbar 44 + ряд действий до 77),
   было 106/110 от --maint-h — стало 85/81 от --chrome-top. */
@media (max-width:1023px){
  .fbans{position:fixed;z-index:19;margin:0;
    left:max(12px,env(safe-area-inset-left,0px));
    right:max(12px,env(safe-area-inset-right,0px));
    top:calc(var(--chrome-top) + var(--fbans-top,85px));
    background-color:var(--surface);box-shadow:var(--shadow)}
  /* список открыт на весь экран: ответ уже виден в нём, карточка только закрыла бы поиск */
  body[data-view="list"] .fbans{opacity:0;transform:translateY(-10px);pointer-events:none}
}
/* режим «поставить точку на карте»: убираем себя с дороги (класс ставится из JS) */
.fbans.is-off{opacity:0;transform:translateY(-8px);pointer-events:none}

@media (prefers-reduced-motion:reduce){
  .fbans{transition:none}
  .fbans.is-intro .fbans-row{animation:none}
  .fbans-head:active,.fbans-btn:active{transform:none}
}

/* ============================================================
   ==== motion-system ====
   Единый язык движения. Одна шкала длительностей, две кривые.
   Вход мягче и длиннее, выход резче и короче — так интерфейс ощущается
   отзывчивым, а не медленным. В покое НИЧЕГО не двигается: каждая анимация
   ниже — реакция на действие пользователя или на приход данных.
   Анимируются только transform и opacity.
   ============================================================ */
:root{
  --mo-fast:140ms;      /* пресс, микро-реакция на палец */
  --mo-base:260ms;      /* основное: карточки, панель, тост, тема */
  --mo-scene:420ms;     /* сцена: шит, онбординг — самая большая поверхность */
  --mo-exit:170ms;      /* выход ВСЕГДА короче входа */
  --mo-step:30ms;       /* шаг лесенки в списке */
  --mo-in:cubic-bezier(.16,.84,.34,1);      /* вход: быстрый старт, мягкое приземление */
  --mo-out:cubic-bezier(.45,0,.85,.4);      /* выход: мягкий старт, резкий уход */
  --mo-spring:cubic-bezier(.22,1.2,.36,1);  /* возврат после нажатия: лёгкая пружина */
}

/* ---------- 1. ШИТЫ ----------
   Выезд снизу с перелётом на 9px и мягким возвратом. Перелёт задан КЛЮЧЕВЫМ КАДРОМ,
   а не пружинной кривой: у bezier с y>1 амплитуда перелёта пропорциональна пути
   (100% высоты шита = десятки пикселей), а нам нужен ровно один и тот же перелёт
   на любой высоте контента. */
.sheet{animation:fbSheetIn var(--mo-scene)}
@keyframes fbSheetIn{
  0%{opacity:.35;transform:translate(-50%,100%);animation-timing-function:cubic-bezier(.17,.72,.26,1)}
  68%{opacity:1;transform:translate(-50%,-9px);animation-timing-function:cubic-bezier(.4,0,.25,1)}
  100%{transform:translate(-50%,0)}
}
.sheet-search{animation:fbSearchIn var(--mo-scene)}
@keyframes fbSearchIn{
  0%{opacity:.35;transform:translate(-50%,-100%);animation-timing-function:cubic-bezier(.17,.72,.26,1)}
  68%{opacity:1;transform:translate(-50%,9px);animation-timing-function:cubic-bezier(.4,0,.25,1)}
  100%{transform:translate(-50%,0)}
}
/* Выход. forwards обязателен: шит физически остаётся в DOM ещё --mo-exit, пока JS не снимет
   hidden — без forwards он моргнёт обратно в исходное состояние на последнем кадре.
   На входе fill НЕ ставим: залитая forwards анимация переигрывает inline-стиль, а свайп-
   роспуск (setupSheetDrag) двигает шит именно через inline transform. */
.sheet.fb-out{pointer-events:none;animation:fbSheetOut var(--mo-exit) var(--mo-out) forwards}
.sheet-search.fb-out{animation-name:fbSearchOut}
/* --sheet-dy — точка, где палец оставил шит при свайпе. Выезд продолжается оттуда,
   а не от нуля, поэтому шит не дёргается назад перед уходом. */
@keyframes fbSheetOut{
  from{opacity:1;transform:translate(-50%,var(--sheet-dy,0px))}
  to{opacity:0;transform:translate(-50%,calc(var(--sheet-dy,0px) + 34px))}
}
@keyframes fbSearchOut{
  from{opacity:1;transform:translate(-50%,var(--sheet-dy,0px))}
  to{opacity:0;transform:translate(-50%,calc(var(--sheet-dy,0px) - 34px))}
}
/* Затемнение нарастает ровно столько же, сколько едет шит (было .2s против .28s — фон
   «доезжал» раньше и читался отдельной вспышкой). Уходит вместе с шитом. */
.backdrop{animation:fbFadeIn var(--mo-scene) var(--mo-in)}
@keyframes fbFadeIn{from{opacity:0}}
.backdrop.fb-out{pointer-events:none;animation:fbFadeOut var(--mo-exit) var(--mo-out) forwards}
@keyframes fbFadeOut{to{opacity:0}}
/* Мобила: «юбка» под шитом цветом поверхности. Во время перелёта шит поднимается на 9px
   выше нижнего края экрана, и без неё в щель видно затемнённую карту. Тень нулевого
   размытия дешевле псевдоэлемента и не трогает вёрстку. */
@media (max-width:1023px){
  .sheet{box-shadow:var(--shadow),0 44px 0 0 var(--surface)}
  .sheet-search{box-shadow:var(--shadow),0 -44px 0 0 var(--surface)}
}
/* Содержимое шита въезжает следом за ним короткой лесенкой — «богатство в переходе».
   backwards (без forwards) держит стартовое состояние только на время задержки, после
   анимации элемент возвращается под обычные правила и hover внутри шита не ломается.
   .feed-full и .rep-list пропущены: их строки уже каскадируют своим rep-in. */
.sheet-body>*{animation:fbRise var(--mo-base) var(--mo-in) backwards;animation-delay:.22s}
.sheet-body>.feed-full,.sheet-body>.rep-list{animation:none}
.sheet-body>*:nth-child(1){animation-delay:.1s}
.sheet-body>*:nth-child(2){animation-delay:.14s}
.sheet-body>*:nth-child(3){animation-delay:.18s}
@keyframes fbRise{from{opacity:0;transform:translateY(10px)}}
/* ПК: шит — центр-модалка (боковую роль тут играет сайдбар .panel, он и так выезжает сбоку). */
@media (min-width:1024px){
  .sheet,.sheet-search{animation:fbModalIn var(--mo-base)}
  .sheet.fb-out,.sheet-search.fb-out{animation:fbModalOut var(--mo-exit) var(--mo-out) forwards}
}
@keyframes fbModalIn{
  0%{opacity:0;transform:translate(-50%,-46%) scale(.96);animation-timing-function:cubic-bezier(.17,.72,.26,1)}
  62%{opacity:1;transform:translate(-50%,-50%) scale(1.008);animation-timing-function:cubic-bezier(.4,0,.25,1)}
  100%{transform:translate(-50%,-50%) scale(1)}
}
@keyframes fbModalOut{to{opacity:0;transform:translate(-50%,-50%) scale(.97)}}

/* ---------- 2. ПАНЕЛЬ (карта ↔ список) ----------
   Только шкала и кривая. Значение transform НЕ трогаем: его считает CSS-позиция пика
   и перетирает драг-жест, любое вмешательство сломает свайп. Мобила была .34s —
   260мс с тормозящей кривой ощущается заметно отзывчивее на отпускании пальца.
   На ПК держим 260 против 280 у #map{left} — рассинхрон 20мс глазом не ловится. */
.panel{transition:transform var(--mo-base) var(--mo-in)}

/* ---------- 3. КАСКАД СПИСКА ----------
   Класс .fb-cascade вешает JS и ТОЛЬКО когда сменился набор станций (новый фильтр,
   поиск, город). Перерисовка тем же составом (обновление данных, возврат после
   голосования) идёт молча — иначе список дёргается на каждой букве в поиске.
   Лесенка максимум на 10 первых элементах, дальше экран всё равно кончился. */
.list.fb-cascade>.fb-casc{
  animation:fbRise var(--mo-base) var(--mo-in) backwards;
  animation-delay:calc(var(--i,0) * var(--mo-step));
}

/* ---------- 4. СМЕНА СОСТОЯНИЯ ----------
   Карточка, у которой ПРИШЁЛ новый статус, коротко «дышит», а бейдж мягко проявляет
   свой цвет: подсветка сделана заливкой currentColor на opacity — это тот же цвет,
   что у нового статуса, но анимируется прозрачность, а не сам цвет. */
.card.fb-restat{animation:fbBump var(--mo-base) var(--mo-spring)}
@keyframes fbBump{0%{transform:scale(1)}34%{transform:scale(1.022)}100%{transform:scale(1)}}
.card.fb-restat .badge{position:relative;isolation:isolate}
.card.fb-restat .badge::after{
  content:"";position:absolute;inset:0;border-radius:inherit;z-index:-1;pointer-events:none;
  background:currentColor;opacity:0;animation:fbTint var(--mo-scene) var(--mo-in);
}
@keyframes fbTint{from{opacity:.42}}
/* Сводка в пике панели видна прямо на карте — цифра, которая изменилась, коротко подпрыгивает.
   Это и есть «свежая отметка заметна» без единой фоновой анимации. */
.chip.fb-bump{animation:fbPop var(--mo-base) var(--mo-spring)}
@keyframes fbPop{0%{transform:scale(1)}32%{transform:scale(1.09)}100%{transform:scale(1)}}

/* ---------- 5. МИКРОВЗАИМОДЕЙСТВИЯ ----------
   Группа А — у элементов transition УЖЕ стоял (часто как `all .15s`). Подменяем только
   шкалу и кривую, список свойств не объявляем: иначе они потеряют плавную заливку. */
.btn,.pill,.fs-fbtn,.fs-avail,.fs-sw,.route-opt,.status-opt,.presence-opt,.fm-btn,
.show-all,.card,.ad-card,.tg-card,.ad-slot,.rep-vote,.ff-row{
  transition-duration:var(--mo-fast);
  transition-timing-function:var(--mo-spring);
}
/* Группа Б — перехода не было вовсе, добавляем строго transform. */
.mini-btn,.icon-btn,.act-pill,.tab,.fab,.sheet-close,.chip,.res-item,.me-link,.sp-never,.copy-addr{
  transition-property:transform;
  transition-duration:var(--mo-fast);
  transition-timing-function:var(--mo-spring);
}
/* Сжатие на палец. Отпускание идёт по пружинной кривой — кнопка чуть «выстреливает» обратно. */
.btn:active,.mini-btn:active,.pill:active,.fs-fbtn:active,.route-opt:active,.status-opt:active,
.presence-opt:active,.fm-btn:active,.show-all:active,.icon-btn:active,.act-pill:active,
.sheet-close:active,.tab:active,.res-item:active,.me-link:active,.sp-never:active{transform:scale(.955)}
.fab:active{transform:scale(.92)}
/* Тумблер: бегунок ехал через left (переливка макета на каждом кадре) — переводим на transform
   с пружинкой. Ход тот же: было left:2px → left:20px, стало сдвиг на 18px. */
.fs-sw::after{
  left:2px;
  transition-property:transform;
  transition-duration:var(--mo-base);
  transition-timing-function:var(--mo-spring);
}
.fs-avail[aria-pressed="true"] .fs-sw::after{left:2px;transform:translateX(18px)}
/* Смена темы. Цвет анимировать нельзя, поэтому кладём поверх вуаль цвета УХОДЯЩЕЙ темы и
   гасим её прозрачностью: заодно прячет перерисовку тайлов карты, которая раньше моргала. */
.fb-veil{position:fixed;inset:0;z-index:70;pointer-events:none;opacity:.85;
  transition:opacity var(--mo-base) var(--mo-out)}
.fb-veil.fb-veil-out{opacity:0}

/* ---------- 6. ОСТАЛЬНОЙ ХРОМ НА ТУ ЖЕ ШКАЛУ ---------- */
.toast{animation:toastIn var(--mo-base) var(--mo-in)}
.toast.fb-out{animation:fbToastOut var(--mo-exit) var(--mo-out) forwards}
@keyframes fbToastOut{to{opacity:0;transform:translate(-50%,10px)}}
.safety-pop{animation:sp-in var(--mo-base) var(--mo-in)}
.install-banner{animation:ib-in var(--mo-base) var(--mo-in)}
/* Онбординг гео ехал общими keyframes slideUp, а они тянут translate(-50%) по X ради центровки
   шита. Карточка гео центрируется гридом, поэтому весь въезд она делала боком и в конце
   прыгала на место. Свои кадры без сдвига по X. */
.geo-card{animation:fbGeoIn var(--mo-scene)}
@keyframes fbGeoIn{
  0%{opacity:.35;transform:translateY(100%);animation-timing-function:cubic-bezier(.17,.72,.26,1)}
  68%{opacity:1;transform:translateY(-9px);animation-timing-function:cubic-bezier(.4,0,.25,1)}
  100%{transform:translateY(0)}
}

/* ---------- 7. ДОСТУПНОСТЬ ----------
   Глобальный блок выше уже жмёт все длительности до .01ms, но своё явное правило нужно:
   оно снимает анимации целиком, а не ускоряет их (ускоренный перелёт всё ещё дёргает кадр). */
@media (prefers-reduced-motion:reduce){
  .sheet,.sheet-search,.sheet.fb-out,.sheet-search.fb-out,.backdrop,.backdrop.fb-out,
  .sheet-body>*,.list.fb-cascade>.fb-casc,.card.fb-restat,.card.fb-restat .badge::after,
  .chip.fb-bump,.toast,.toast.fb-out,.geo-card,.safety-pop,.install-banner{
    animation:none!important;
  }
  .panel,.fs-sw::after,.btn,.pill,.fs-fbtn,.fs-avail,.fs-sw,.route-opt,.status-opt,
  .presence-opt,.fm-btn,.show-all,.card,.ad-card,.tg-card,.ad-slot,.rep-vote,.ff-row,
  .mini-btn,.icon-btn,.act-pill,.tab,.fab,.sheet-close,.chip,.res-item,.me-link,
  .sp-never,.copy-addr,.fb-veil{transition:none!important}
  .btn:active,.mini-btn:active,.pill:active,.fs-fbtn:active,.route-opt:active,.status-opt:active,
  .presence-opt:active,.fm-btn:active,.show-all:active,.icon-btn:active,.act-pill:active,
  .sheet-close:active,.tab:active,.res-item:active,.me-link:active,.sp-never:active,
  .fab:active{transform:none}
  .fb-veil{display:none!important}
}

/* ==== сборка: разрешение конфликтов между областями ==== */
/* Точки в чипах сводки (app.css:595-597, dot-yes/dot-queue/dot-no) были задуманы
   «поведенческим эхом» пульсирующих маркеров (комментарий 591-594). Область markers
   маркерный амбиент погасила — эхо стало эхом тишины и осталось ЕДИНСТВЕННЫМ, что
   двигается в покое, прямо против дизайн-тезиса №2. Оба автора (markers и motion)
   это пометили и не тронули, потому что чип — чужая зона; решение сборщика.
   Импульс на изменившейся цифре (.chip.fb-bump из motion) продолжает работать:
   он реакция на приход данных, а не фон. Откат = удалить эти две строки. */
.chip .d-yes,.chip .d-queue,.chip .d-no{animation:none}

/* ==== правки по итогам приёмки (2026-08-07) ====================================
   Восемь находок визуальной приёмки и техаудита. Блок последний в файле — бьёт
   всё предыдущее при равной специфичности. Откат = удалить блок целиком.
   ============================================================================ */

/* 1. БЛОКЕР: на десктопе в сайдбаре было НОЛЬ целых карточек станций.
      Причина: .panel это флекс-колонка, и карточка-ответ, ряд действий и футер
      забирали фиксированную высоту, а списку доставался остаток в 32-190px.
      Лечим не подрезкой содержимого, а сменой того, ЧТО скроллится: скроллит
      теперь вся панель, шапка липнет сверху, ряд действий снизу, а карточка-ответ
      и футер спокойно уезжают вверх. Список получает всю высоту. */
@media (min-width:1024px){
  .panel{overflow-y:auto;overscroll-behavior:contain}
  .panel-head{position:sticky;top:0;z-index:4;background:var(--surface)}
  .list{overflow:visible;flex:0 0 auto;min-height:0}
  .panel>.tabbar{position:sticky;bottom:0;z-index:4;background:var(--surface)}
  .fbans{flex:0 0 auto}
  .panel-foot{flex:0 0 auto}
}

/* 2. Обрезка названий («Кремлёвская А…»): заголовок вырос 15.5/800 → 17/600,
      а колонку под него не расширили — её съел бейдж статуса. Возвращаем место. */
.card-name{min-width:0;flex:1 1 auto}
.card-top>.badge{padding:5px 9px;font-size:12px}
.card-name h3{letter-spacing:-.2px}

/* 3. Контраст. --text-3 не проходил AA НИ В ОДНОЙ теме (тёмная 3.58, светлая 2.83
      при пороге 4.5), а это ~30 мест: подписи таббара, адреса АЗС, возраст отметки. */
html[data-theme=dark]{ --text-3:#8E94B4; }
html[data-theme=light]{ --text-3:#6B7086; }

/* 3б. Хардкод #9a7b06 вместо токена — проваливал обе темы (2.64 и 3.77). */
.badge.s-low{color:var(--st-low)}
.status-opt.s-low[aria-pressed=true]{color:var(--st-low)}
.ff-main small.s-low{color:var(--st-low)}
.st-card.s-low .sts-title{color:var(--st-low)}

/* 3в. Статусный текст на своих подложках. Маркеру «нет данных» тусклость нужна,
       ТЕКСТУ — нет: 2.12 это худшая пара в файле. Разводим роли. */
.badge.s-nodata,.gpn-pill.nodata{color:var(--text-2)}
html[data-theme=dark] .badge.s-no{color:#E8798C}
html[data-theme=light] .badge.s-yes{color:#0B7A46}
html[data-theme=light] .fuel.on{color:#0B7A46}

/* 4. «Уменьшить движение» гасило не всё. Псевдоэлементы селектор * не берёт,
      а бесконечной анимации мало обнулить длительность: она гоняет итерацию
      каждый кадр вечно, пока не ограничить число повторов. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-iteration-count:1!important}
  .user-dot::before{animation:none!important}
  .act-avail[aria-pressed=true],
  .act-avail[aria-pressed=true] svg,
  .act-gpn[aria-pressed=true]{animation:none!important}
}

/* 5. На 360px пилюли теряли подписи и оставались двумя безымянными кружками,
      хотя рядом 260px пустоты: редизайн унёс лупу и тему наверх, а старый
      брейкпоинт этого не заметил. */
@media (max-width:360px){
  #availBtn .lbl,#gpnBtn .lbl{display:inline}
}

/* ==== правки по замечаниям (2026-08-07, второй заход) ======================== */

/* 1. Плашка Fineapp на ДЕСКТОПЕ. На мобиле ей сделали аккуратный чип в строке грипа,
      а на широком экране она откатывалась к исходному виду: мелкий центрированный текст
      без подложки, висящий сам по себе посреди пустоты. Даём тот же чип и прижимаем
      вправо, чтобы у него был якорь, а не «где-то сверху по центру». */
@media (min-width:1024px){
  .panel-fine{
    display:flex;width:fit-content;margin:0 0 10px auto;
    height:26px;padding:0 11px;gap:6px;
    border-radius:var(--r-pill);background:var(--surface-2);border:1px solid var(--line);
  }
  .panel-fine img{height:14px}
  .panel-fine span{font-size:12.5px}
  .panel-fine:hover{border-color:var(--red)}
}

/* 2. Воздух в шапке сайдбара. 194px уходило на плашку, сводку, поиск и фильтры
      ДО первой карточки. Поджимаем, не ломая ритм. */
@media (min-width:1024px){
  .panel{padding-top:10px}
  .panel-head{padding:6px 16px 2px}
  .summary{padding-bottom:8px}
  .list-search{margin:8px 0 2px}
  .fbans{margin-top:8px}
  .list{padding-top:8px}
}

/* 3. Карточка-ответ на ДЕСКТОПЕ занимала 215px и оставляла в сайдбаре одну целую
      карточку станции. На мобиле она хозяйка первого экрана и такой размер оправдан,
      а на широком экране список рядом и она должна быть компактнее: тот же смысл,
      меньше воздуха. */
@media (min-width:1024px){
  .fbans{padding:10px 12px 11px;margin-top:6px}
  .fbans-eyebrow{margin-bottom:7px;font-size:10.5px}
  .fbans-logo{width:36px;height:36px;border-radius:11px}
  .fbans-logo svg{width:19px;height:19px}
  .fbans-title{font-size:15.5px}
  .fbans-head.is-text .fbans-title{font-size:14.5px}
  .fbans-meta{font-size:12px}
  .fbans-x{top:5px;right:5px;width:28px;height:28px}
}

/* ==== правки по замечаниям (2026-08-07, третий заход) ======================= */

/* 1. ЛОГОТИП. На десктопе панель теперь всегда открыта, а старое правило
      «в режиме списка отодвинуть лого за панель» осталось — и лого уехало на карту,
      за 420px от края. Раньше оно стояло у левого края, потому что панель по умолчанию
      была спрятана. Возвращаем на место: лого — шапка сайдбара, а не наклейка на карте.
      Панели даём отступ сверху, чтобы содержимое не лезло под лого. */
@media (min-width:1024px){
  body[data-view="list"] .brand{margin-left:0}
  .panel{padding-top:58px}
  body[data-view="list"] .panel{padding-top:58px}
  body.has-maint .panel{padding-top:calc(58px + var(--maint-h))}
}

/* 2. КАРТОЧКА-ОТВЕТ на десктопе уезжала вниз вместе со списком: большой тёмный блок,
      который катается. Прибиваем её к шапке и делаем компактной — тогда она и всегда
      на виду, и не отжирает список. */
@media (min-width:1024px){
  .fbans{
    position:sticky;top:0;z-index:3;
    margin:0 16px 10px;padding:9px 11px 10px;
  }
  .fbans-eyebrow{margin:0 30px 6px 0;font-size:10px;letter-spacing:.10em}
  .fbans-logo{width:32px;height:32px;border-radius:10px}
  .fbans-logo svg{width:17px;height:17px}
  .fbans-head{gap:9px}
  .fbans-title{font-size:14.5px}
  .fbans-head.is-text .fbans-title{font-size:13.5px}
  .fbans-meta{font-size:11.5px;margin-top:1px}
  .fbans-x{top:4px;right:4px;width:26px;height:26px}
}

/* 2б. Десктопная карточка-ответ живёт внутри шапки (её кладёт туда fbAnsHome) и потому
       обязана быть компактной: рядом список, ей не нужен весь набор мобильного экрана.
       Убираем надзаголовок и подсказку про геопозицию, ужимаем кнопки. Смысл остаётся:
       кто, как далеко, насколько свежо и что нажать. */
@media (min-width:1024px){
  .fbans{position:static;margin:8px 0 2px;padding:10px 12px 11px}
  .fbans .fbans-eyebrow{display:none}
  .fbans .fbans-link{display:none}
  .fbans .fbans-acts{gap:8px;margin-top:9px}
  .fbans .fbans-btn{height:36px;font-size:13px}
  .fbans .fbans-note{margin-top:7px}
}

/* 4. Прозрачная полоса над шапкой. Отступ под плавающее лого висел на .panel,
      а шапка липла к его внутреннему краю — значит верхние 58px оставались
      прозрачными, и в них просвечивал уезжающий список. Отступ переезжает
      ВНУТРЬ шапки: теперь она перекрывает всю верхнюю зону, включая полосу под лого. */
@media (min-width:1024px){
  .panel{padding-top:0}
  body[data-view="list"] .panel{padding-top:0}
  body.has-maint .panel{padding-top:var(--maint-h)}
  .panel-head{padding-top:58px}
  body.has-maint .panel-head{padding-top:calc(58px + var(--maint-h))}
}

/* 5. Невысокие ноутбуки (700-800px): шапка с карточкой-ответом забирала почти половину
      экрана. Там карточка теряет кнопки — она сама по себе кликабельна и ведёт на АЗС,
      а маршрут строится уже из карточки станции. */
@media (min-width:1024px) and (max-height:820px){
  .panel-head{padding-top:52px}
  .fbans .fbans-acts{display:none}
  .fbans{padding-bottom:9px}
  .summary{padding-bottom:6px}
  .list-search{margin:6px 0 2px}
}

/* 6. Крестик карточки-ответа абсолютный, а я в прошлой правке снял с карточки
      position:relative — крестик потерял якорь и улетел в угол панели. Возвращаем. */
@media (min-width:1024px){ .fbans{position:relative} }

/* 7. Липкая шапка обрезала карточку под собой без всякой границы — глаз читал это
      как наложение, а не как прокрутку под шапкой. Даём ей явный край. */
@media (min-width:1024px){
  .panel-head{border-bottom:1px solid var(--line);box-shadow:0 6px 14px -10px rgba(0,0,0,.45)}
}

/* ==== угол сайдбара (2026-08-07) ==========================================
   Лого — плашка с фоном, рамкой и тенью, придуманная чтобы висеть НАД КАРТОЙ.
   На десктопе панель теперь всегда открыта, и плашка легла на белое: белый
   прямоугольник на белом с лишней обводкой. Плюс Fineapp сидел отдельной строкой
   ниже и правее — три разных выравнивания в первых ста пикселях.
   Собираем угол в одну строку: слева лого без подложки, справа чип Fineapp.
   ========================================================================= */
@media (min-width:1024px){
  .brand{background:none;border:0;box-shadow:none;padding:0}
  .topbar{padding-left:16px}

  /* чип едет вместе с липкой шапкой, потому что позиционируется от неё */
  .panel-head{padding-top:64px}
  body.has-maint .panel-head{padding-top:calc(64px + var(--maint-h))}
  .panel-fine{position:absolute;top:19px;right:16px;margin:0}
}

@media (min-width:1024px) and (max-height:820px){
  .panel-head{padding-top:58px}
  .panel-fine{top:16px}
}

/* ==== мягкие края липких зон (2026-08-07) ==================================
   Шапка и нижний ряд действий обрезали список гильотиной: жёсткая линия, под ней
   срезанная посреди строки карточка. Плюс на плавной прокрутке в шве между липким
   блоком и содержимым проскакивала пиксельная полоска (субпиксельное округление).
   Меняем жёсткие границы на растворение: содержимое уходит под шапку и под нижний
   ряд плавно, а градиент заодно перекрывает шов.
   ========================================================================= */
@media (min-width:1024px){
  /* жёсткую линию и тень убираем — их работу берёт градиент */
  .panel-head{border-bottom:0;box-shadow:none}

  .panel-head::after{
    content:"";position:absolute;left:0;right:0;top:100%;height:22px;
    background:linear-gradient(to bottom,var(--surface) 0%,rgba(0,0,0,0) 100%);
    pointer-events:none;z-index:1;
    /* -1px вверх: перекрывает субпиксельный шов, из-за которого при прокрутке
       мелькала полоска содержимого */
    margin-top:-1px;
  }

  .panel>.tabbar{box-shadow:none}
  .panel>.tabbar::before{
    content:"";position:absolute;left:0;right:0;bottom:100%;height:26px;
    background:linear-gradient(to top,var(--surface) 0%,rgba(0,0,0,0) 100%);
    pointer-events:none;margin-bottom:-1px;
  }
}

/* ==== доводка краёв (2026-08-07) ==========================================
   1) Дорожка полосы прокрутки была ПРОЗРАЧНОЙ (в проекте покрашен только
      ползунок). Из-за этого справа оставалась щель в 8px, через которую
      уезжающее содержимое просвечивало МИМО липкой шапки — те самые
      «торчащие пиксели». Красим дорожку в цвет панели.
   2) Градиенты в 22 и 26px были короче строки текста, поэтому строка не успевала
      раствориться и край всё равно читался как обрез. Удлиняем.
   ========================================================================= */
@media (min-width:1024px){
  .panel::-webkit-scrollbar{width:8px}
  .panel::-webkit-scrollbar-track{background:var(--surface)}
  .panel::-webkit-scrollbar-thumb{background:var(--line-2);border-radius:8px;
    border:2px solid var(--surface);background-clip:padding-box}
  .panel{scrollbar-color:var(--line-2) var(--surface)}

  .panel-head::after{height:36px}
  .panel>.tabbar::before{height:52px}
}

/* ==== правки по замечаниям (2026-08-07, четвёртый заход) ==================== */

/* 1. ЦИФРЫ РАЗЪЕЗЖАЛИСЬ. Табличные знаки я включил, чтобы числа не дёргались при
      обновлении. Но в Onest табличная единица вдвое шире обычной (8.4px против 4.5),
      и она болтается в широком боксе — «13 ч» читалось как «1 3 ч», «1.7» как «1 7».
      Табличные оставляем ТОЛЬКО в сводке, где счётчики реально тикают на месте. */
.card,.st-card,.st-head,.prices,.itags,.age,.conf-chip,.meta,.fuel,.st-dist,.st-stat,
.age b,.conf-chip b,.itag b,.meta .km{font-variant-numeric:normal}
.summary .chip,.summary .chip b{font-variant-numeric:tabular-nums}

@media (min-width:1024px){
  /* 2. СВОРАЧИВАНИЕ КАРТОЧКИ-ОТВЕТА — стрелка по центру нижнего края вместо
        крестика в углу. Тот же обработчик, другой облик: шеврон нарисован
        border'ами, никакой новой графики. */
  .fbans-x{
    top:auto;bottom:0;right:auto;left:50%;transform:translateX(-50%);
    width:52px;height:18px;border-radius:0 0 12px 12px;
    display:grid;place-items:center;color:var(--text-3);background:none;
  }
  .fbans-x:hover{background:var(--surface-3);color:var(--text)}
  .fbans-x svg{display:none}
  .fbans-x::before{
    content:"";width:8px;height:8px;
    border-top:1.7px solid currentColor;border-left:1.7px solid currentColor;
    transform:rotate(45deg);margin-top:3px;
  }
  .fbans-x::after{content:"";position:absolute;inset:-4px -10px}
  .fbans{padding-bottom:20px}

  /* 3. FINEAPP — по центру и крупнее: это благодарность спонсору, ей уместнее
        быть заметной, а не жаться в угол. */
  .panel-fine{
    left:50%;right:auto;transform:translateX(-50%);
    height:32px;padding:0 14px;gap:7px;
  }
  .panel-fine img{height:17px}
  .panel-fine span{font-size:14px}

  /* 4. FBENZ — мельче и в ряд с лупой над картой (переезд делает fbAnsHome).
        Плашка ему там нужна: под ним карта. */
  .actionbar>.brand{
    order:-1;flex:0 0 auto;height:38px;padding:0 13px 0 11px;gap:6px;
    background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);
    box-shadow:var(--shadow-sm);margin:0;
  }
  .actionbar>.brand .brand-logo,.actionbar>.brand .fine-f{height:19px}
  .actionbar>.brand .brand-word{font-size:17px}
  .topbar{padding-left:24px}
}

/* ==== правки по замечаниям (2026-08-07, пятый заход) ======================= */

@media (min-width:1024px){
  /* 1. FBENZ вернулся в верхнюю строку: в одном ряду с лупой и тумблерами
        над картой скапливалось слишком много, карта читалась перегруженной.
        Размер оставляем уменьшенный. */
  .topbar>.brand{
    height:auto;padding:6px 13px 6px 11px;gap:6px;
    background:var(--surface);border:1px solid var(--line);border-radius:var(--r-pill);
    box-shadow:var(--shadow-sm);margin-left:calc(var(--panel-w) + 24px);
  }
  .topbar>.brand .brand-logo,.topbar>.brand .fine-f{height:20px}
  .topbar>.brand .brand-word{font-size:18px}

  /* 2. СТРЕЛКУ СВОРАЧИВАНИЯ не находили: тонкий серый шеврон без подложки
        не читался как кнопка. Делаем явный язычок с рамкой и фоном. */
  .fbans-x{
    bottom:-11px;width:64px;height:22px;border-radius:var(--r-pill);
    background:var(--surface-2);border:1px solid var(--line);
    color:var(--text-2);box-shadow:var(--shadow-sm);
  }
  .fbans-x:hover{background:var(--surface-3);color:var(--text);border-color:var(--line-2)}
  .fbans-x::before{width:9px;height:9px;border-width:2px;margin-top:2px}
  .fbans{padding-bottom:14px;margin-bottom:16px}
}

/* 3. Лого в ВЕРХНЮЮ строку и над картой. Прошлое правило
      body[data-view="list"] .brand{margin-left:0} перебивало новое по специфичности
      (0,2,1 против 0,2,0), поэтому лого садилось на панель. Бьём тем же весом. */
@media (min-width:1024px){
  body[data-view="list"] .topbar>.brand{margin-left:calc(var(--panel-w) + 24px)}
  .topbar{padding-left:0}
}

/* ==== марки топлива: заливка вместо перечёркивания (2026-08-07) =============
   Было: у отсутствующей марки красная подложка И перечёркивание поверх текста —
   статус кричал дважды, а помарка поверх букв выглядела грубо.
   Стало: состояние несёт ЗАЛИВКА, ровно как у новых иконок-капель.
     залито зелёным  — есть
     пусто, контур   — нет
     плоское серое   — неизвестно
   ========================================================================= */
.fuel.no{
  background:none;
  color:var(--st-no);
  border:1px solid var(--st-no);
  text-decoration:none;
}
html[data-theme=dark] .fuel.no{border-color:color-mix(in srgb,var(--st-no) 62%,transparent)}

/* та же логика в ленте последних отметок */
.rf.off{
  text-decoration:none;
  color:var(--st-no);
  border-color:color-mix(in srgb,var(--st-no) 55%,transparent);
  opacity:1;
}

/* ==== язычок сворачивания сайдбара (2026-08-07) ============================
   Кнопка живёт на кромке панели и едет вместе с ней: панель открыта — язычок
   у её правого края со стрелкой влево, панель убрана — язычок у края экрана
   со стрелкой вправо. Один элемент вместо двух, поэтому глазу не надо искать,
   куда делась кнопка.
   ========================================================================= */
.panel-toggle{display:none}

@media (min-width:1024px){
  .panel-toggle{
    display:grid;place-items:center;position:fixed;z-index:19;
    left:var(--panel-w);top:50%;transform:translateY(-50%);
    width:22px;height:64px;padding:0;
    background:var(--surface);color:var(--text-3);
    border:1px solid var(--line);border-left:0;border-radius:0 10px 10px 0;
    box-shadow:var(--shadow-sm);cursor:pointer;
    transition:left .28s var(--ease),background .15s,color .15s;
  }
  .panel-toggle::before{
    content:"";width:7px;height:7px;
    border-top:1.8px solid currentColor;border-right:1.8px solid currentColor;
    transform:rotate(-135deg);margin-left:3px;   /* «‹» — убрать панель */
  }
  .panel-toggle:hover{background:var(--surface-2);color:var(--text)}
  .panel-toggle:focus-visible{outline:2.5px solid var(--red);outline-offset:2px}

  /* панель убрана: карта на всю ширину, хром прижимается к левому краю */
  body[data-panel="off"] .panel{transform:translateX(-100%);box-shadow:none}
  body[data-panel="off"] #map{left:0}
  body[data-panel="off"] .panel-toggle{left:0;border-left:1px solid var(--line);border-radius:0 10px 10px 0}
  body[data-panel="off"] .panel-toggle::before{transform:rotate(45deg);margin-left:-3px}  /* «›» — вернуть */
  body[data-panel="off"] .topbar>.brand{margin-left:24px}
  body[data-panel="off"] .actionbar{left:24px}
  body[data-panel="off"] .share-fab{left:24px}
  body[data-panel="off"] .gpn-chips{left:24px}
}

/* ==== свёрнутая панель: полоса-сводка и нативный Fineapp (мобила) ============
   Fineapp уходит из строки грипа в поток, в одну строку со сводкой, правым
   хвостом той же полосы. Грип снова чистая ручка (до правки его правые 113px
   по elementFromPoint возвращали ссылку на fineapp.ru).
   Сводка: три одинаковые пилюли врали иерархией. Теперь одна полоса, ведущая
   цифра «Есть», нулевая категория остаётся (ноль — тоже ответ), но гасит точку.
   Всё внутри мобильных медиазапросов; единственная глобальная строка — --peek,
   её читают только мобильные правила и peek() в app.js.
   ========================================================================= */

/* Высота пика теперь ОДНА на проект: раньше 142 жило и в CSS, и в app.js, и в
   отступах FAB. Правка одной стороны роняла драг. */
:root{--peek:134px}

@media (max-width:1023px){
  /* Шапка панели — сетка: первая строка держит сводку и Fineapp одной полосой,
     поиск/подсказки/фильтры остаются во всю ширину, как были.
     БЕЗ position:relative — иначе .panel-fine (offsetParent = #panel) уедет. */
  .panel-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:stretch;padding-top:0}
  .summary{grid-row:1;grid-column:1}
  .panel-fine{grid-row:1;grid-column:2}
  .list-search,.list-sug,.filter{grid-column:1 / -1}

  /* Полоса вместо трёх пилюль: минус шесть границ, минус две подложки, минус
     16px межпилюльных зазоров. Центрирование группы оставляем базовым трюком
     margin:auto на крайних детях. */
  .summary{display:flex;align-items:center;gap:0;height:34px;padding:0;
    background:var(--surface-2);border:1px solid var(--line);border-right:0;
    border-radius:var(--r-pill) 0 0 var(--r-pill)}
  /* до первого /api/nearby #summary пуст — не показываем голую капсулу */
  .summary:empty{background:none;border-color:transparent}
  .panel-head:has(.summary:empty) .panel-fine{border-radius:var(--r-pill)}

  .summary .chip{background:none;border:0;border-radius:0;padding:0 7px;gap:5px;
    font-size:12px;font-weight:500;color:var(--text-2)}
  .summary .chip .dot{width:8px;height:8px}
  .summary .chip b{font-weight:600;font-size:13px;color:var(--text)}
  /* ведущая цифра: человек смотрит сюда за одним ответом. Цвет держит точка:
     --st-yes на светлой теме не проходит по контрасту как текст. */
  .summary .chip[data-k="yes"] b{font-size:14.5px}
  /* Ноль не прячем — «очередей нет» это информация. Но он перестаёт весить как
     факт: точка гаснет (цветная точка = «состояние есть»), кегль и цвет тише. */
  .summary .chip.is-zero{padding:0 6px;font-size:11.5px;color:var(--text-3)}
  .summary .chip.is-zero .dot{display:none}
  .summary .chip.is-zero b{font-size:11.5px;font-weight:500;color:var(--text-3)}

  /* Ступени сжатия ставит замером fbSumFit() в app.js, а не брейкпоинтом:
     полоса лежит в .panel-head с touch-action:none, пальцем её не проскроллить. */
  .summary.is-tight .chip{padding:0 5px;gap:4px;font-size:11px}
  .summary.is-tight .chip b{font-size:12px}
  .summary.is-tight .chip[data-k="yes"] b{font-size:12.5px}
  .summary.is-tight .chip.is-zero{display:none}
  .summary.is-tighter .chip .chip-l{display:none}

  /* Fineapp — правый хвост той же полосы. inset:auto обязателен: базовое правило
     задаёт top/right под absolute, при position:relative они стали бы сдвигом. */
  .panel-fine{position:relative;inset:auto;z-index:1;align-self:stretch;margin:0;
    height:auto;padding:0 9px;gap:5px;
    background:var(--surface-2);border:1px solid var(--line);
    border-radius:0 var(--r-pill) var(--r-pill) 0}
  .panel-fine img{height:13px}
  .panel-fine span{font-size:11.5px;color:var(--text-2)}
  /* Тап-зона 44px растёт ВНИЗ и ВПРАВО, а не по центру: центрированная лезла бы
     обратно на грип. */
  .panel-fine::after{top:auto;bottom:-10px;height:44px;left:0;right:-10px;transform:none}

  /* грип снова чистая ручка — плашка с него ушла */
  .panel-grip{padding:11px 0 10px}

  /* Пик 142 -> 134 и всё, что от него считалось. Запас над таббаром прежний 8px. */
  .panel{transform:translateY(calc(100% - var(--peek) - var(--safe-b)))}
  .fab{bottom:calc(var(--peek) + 22px + var(--safe-b))}
  .share-fab{bottom:calc(var(--peek) + 84px + var(--safe-b))}
}

/* Узкие телефоны. Порог 380 намеренно мимо 360/368 — там уже дерутся четыре
   правила про #availBtn/#gpnBtn, мои селекторы с ними не пересекаются. */
@media (max-width:380px){
  .summary .chip{padding:0 5px;gap:4px;font-size:11.5px}
  .summary .chip b{font-size:12.5px}
  .summary .chip[data-k="yes"] b{font-size:13.5px}
  .summary .chip.is-zero{padding:0 5px;font-size:11px}
  .summary .chip.is-zero b{font-size:11px}
  .panel-fine{padding:0 8px;gap:4px}
  .panel-fine span{font-size:11px}
}

/* ==== верхний ряд кнопок на мобиле ====
   ДО: [лого]--дырка 92px--[город][лупа][тема] / [Только где есть][Газпром]--пусто 110px--
   Дырка не случайна: .top-actions{margin-left:auto} прижимает город вправо, а
   margin-right:80px резервирует место под лупу и тему, вынесенные в эту строку
   через position:fixed. 6+34+6+34 = ровно 80 — весь люфт собирается в ОДНО место.
   Но проблема не в пикселях, а в группировке: город (ГДЕ смотрим) стоял в одной
   пачке с лупой и темой (КАК выглядит приложение).
   СТАЛО, две строки, каждую можно назвать словом:
     строка 1 — приложение и место: лого + город слева, тема справа;
     строка 2 — инструменты карты: лупа + «Только где есть» + «Газпром».
   Лупа ищет станции НА КАРТЕ, значит её место рядом с фильтрами карты — ровно
   так же, как на принятом десктопе. Тема остаётся наверху: вторая строка целиком
   гаснет в списке, а тему надо уметь сменить из любого вида. */
@media (max-width:1023px){

  /* Город встаёт вплотную к логотипу: вместе читаются как «Fbenz, Химки» —
     заголовок экрана, а не набор кнопок. Снимаем margin-left:auto и резерв 80px:
     под правым краем теперь одна иконка, и та вынута из потока. */
  .top-actions{margin-left:0;margin-right:auto;gap:6px}

  /* Освободившееся место отдаём названию города: потолок 34vw резал «Нижний
     Новгород» на полуслове, пока справа стояли ещё две кнопки. */
  .city-btn{max-width:min(46vw,240px)}

  /* Лупа возвращается в поток ряда тумблеров. Разметку не трогаем: #searchBtn и
     так первый ребёнок .actionbar, порядок в строке получается сам собой. */
  #searchBtn{position:static;top:auto;right:auto}

  /* Подписи тумблеров. Свёртка в безымянные кружки была нужна ряду из ЧЕТЫРЁХ
     кнопок; кнопок снова три, ширины хватает с запасом. Возвращаем слова и
     авто-ширину ОДНИМ местом, чтобы четыре конфликтующих правила больше не
     спорили: 2161 возвращал подпись, но не ширину, и на 360px подписи резались
     в «· Т…» и «Г.». */
  #availBtn,#gpnBtn{width:auto;padding:0 12px;justify-content:flex-start}
  #availBtn .lbl,#gpnBtn .lbl{display:inline}

  /* В списке карта закрыта панелью — гаснет вся вторая строка, включая лупу:
     прямо под ней стоит настоящее поле поиска, а кнопка была лишь вторым входом
     в него. Тема живёт вне потока этой строки и остаётся доступной. */
  body[data-view="list"] #searchBtn{opacity:0;pointer-events:none}
}

/* Узкие экраны: поджимаем поля и зазор, а не выкидываем слова. Зона тапа всё
   равно растянута до 44px через ::after. */
@media (max-width:360px){
  .actionbar{gap:6px}
  #availBtn,#gpnBtn{padding:0 10px}
}

/* ==== лист «Ещё» (личный кабинет) ====
   Область: иконки ЛК, плотность листа, кнопка «Идея» в ряду действий «Ситуации».
   Верхний ряд, сводку, чип Fineapp, поиск и карточку-ответ не трогаем. */

/* --- иконки одним набором: глифы несут обводку сами, здесь только размер и цвет --- */
.me-link .me-ic{width:22px;height:22px;color:var(--red)}
.me-link .arr{width:16px;height:16px}

/* --- меню одной карточкой: было шесть строк по 71px, стало четыре одной группой --- */
.me-menu{margin:2px 0 4px;background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r);overflow:hidden}
.me-menu .me-link{padding:0 14px;min-height:54px;gap:12px;font-size:14.5px;font-weight:500;
  border-bottom:1px solid var(--line)}
.me-menu .me-link:last-child{border-bottom:0}
@media (hover:hover){.me-menu .me-link:hover{background:var(--surface-3)}}

/* --- достижения --- */
.ach{padding:11px 7px 10px;border-radius:var(--r-sm)}
.ach-ic{width:42px;height:42px}
.ach-ic svg{width:25px;height:25px}
.ach-t{font-weight:600}
.ach-sub{font-weight:500}
.ach-label #badgesCount{font-weight:600}
.ach-more{display:block;width:100%;margin:0 0 6px;padding:11px;border-radius:var(--r-sm);
  background:var(--surface-2);border:1px solid var(--line);color:var(--text-2);
  font:inherit;font-size:13px;font-weight:600}
.ach-more[hidden]{display:none}
@media (hover:hover){.ach-more:hover{color:var(--text);border-color:var(--line-2)}}
/* движение только на приход данных по тапу: раскрытые плитки въезжают один раз */
.ach.is-new{animation:meAchIn .26s var(--ease) both;animation-delay:var(--d,0s)}
@keyframes meAchIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}

/* --- рейтинг доверия: тот же блок, но тише и ниже --- */
.rating-card{padding:12px;gap:11px;border-radius:var(--r-sm)}
.rating-card .rc-ic{width:38px;height:38px}
.rating-card .rc-ic svg{width:21px;height:21px}
.rc-tier{font-size:14px;font-weight:500}
.rc-tier b{font-weight:600}
.rc-sub,.rc-next{font-weight:500}
.pf-name{font-weight:600}
.pf-stats{font-weight:500}

/* --- «Идея» в ряду действий «Ситуации» --------------------------------------
   Добавляем ровно одну пилюлю. Сам ряд (.filter-bar, .pill-more, .pill-feed) —
   чужая область, к нему не притрагиваемся.
   Пилюля без подписи не из экономии, а по замерам: с подписью «Идея» ряд
   становится 358.6px при 358 доступных на мобиле и 361 при 359 в десктопном
   сайдбаре. Хвост уезжал бы за край, а вбок ряд пальцем не крутится — на
   .panel-head стоит touch-action:none. Смысл несут aria-label и title. */
.filter-bar .pill-idea{position:relative;display:inline-flex;align-items:center;
  justify-content:center;width:34px;padding:0;
  background:var(--red-soft);border-color:transparent;color:var(--red)}
.filter-bar .pill-idea svg{width:16px;height:16px}
/* цель тапа 44px без раздувания самой пилюли — тем же приёмом, что у .act-pill */
.filter-bar .pill-idea::after{content:"";position:absolute;left:0;right:0;top:50%;height:44px;
  transform:translateY(-50%)}

@media (max-width:1023px){
  /* в покое видна одна строка достижений, остальные 11 плиток — по кнопке */
  .ach-grid.is-clip>.ach:nth-child(n+4){display:none}
}
@media (min-width:1024px){
  /* десктоп: сетка достижений остаётся полной, кнопка раскрытия не нужна */
  .ach-more{display:none}
}
@media (prefers-reduced-motion:reduce){
  .ach.is-new{animation:none}
}

/* ==== поле поиска и карточка-ответ на мобиле ====
   Парные вставки «десктоп / мобила» внутри ОДНОЙ разметки: JS рисует обе половины,
   а нужную показывает CSS. По умолчанию мобильная половина спрятана — значит на
   1024+ карточка собирается ровно из тех же кусков, что и до правок. */
.fbans-m-mob{display:none}
.fbans-btn-m{display:none}

/* Подсказка про марки топлива. Из плейсхолдера она ушла (он должен называть, что
   искать, а не перечислять варианты), но сама подсказка нужна — поэтому живёт в
   выпадашке поиска и появляется, когда человек ткнул в пустое поле. */
.sug-hint{margin:2px 2px 0;font-size:12.5px;line-height:1.45;color:var(--text-3)}
.sug-hint b{color:var(--text-2);font-weight:600}

@media (max-width:1023px){
  /* КАРТОЧКА-ОТВЕТ.
     ДО: 215px обычно / 266px с марками. Живой карты между рядом действий (кончается
     на y=77) и пиком панели всего ~625px — ответ съедал 34% карты, ради которой
     человек и пришёл. СТАЛО: 132 / 161 / 184px.
     Смысл не выброшен, он переставлен: возраст отметки уехал в строку под названием,
     счётчик альтернатив — в надзаголовок, «включить геопозицию» — во вторую кнопку. */
  .fbans{padding:10px 12px 11px}

  .fbans .fbans-m-desk{display:none}
  .fbans .fbans-m-mob{display:inline}
  .fbans .fbans-btn-m{display:inline-flex}
  .fbans .fbans-btn-d{display:none}

  .fbans .fbans-eyebrow{margin:0 34px 6px 0;font-size:10px;letter-spacing:.07em;line-height:1.4}
  .fbans .fbans-x{top:5px;right:5px;width:30px;height:30px}
  .fbans .fbans-x svg{width:14px;height:14px}

  .fbans .fbans-head{gap:10px}
  .fbans .fbans-logo{width:36px;height:36px;border-radius:11px}
  .fbans .fbans-logo svg{width:19px;height:19px}
  .fbans .fbans-title{font-size:15.5px}
  .fbans .fbans-meta{font-size:12px;margin-top:1px}
  .fbans .fbans-head.is-text .fbans-title{font-size:14.5px}
  .fbans .fbans-badge{padding:4px 9px;font-size:11.5px}
  /* протухшая отметка красится там же, где про неё теперь написано */
  .fbans .fbans-when.is-warn{color:var(--st-queue)}
  /* ...а сама строка честности на мобиле возраста уже не содержит, поэтому красить
     её текст в оранжевый нечестно: там остались подтверждения и очередь. Точку
     оставляем статусной — она и есть сигнал. */
  .fbans .fbans-note.is-warn{color:var(--text-2)}

  /* Марки топлива. Перенос НЕ запрещаем: пять марок влезают в строку даже на 320px,
     но если шрифт отрисуется чуть шире, перенос честнее обрезанной «ДТ». */
  .fbans .fbans-fuels{margin-top:7px}
  .fbans .fbans-f{font-size:11px;padding:3px 8px;border-radius:7px}

  /* Строка честности: возраст ушёл наверх, здесь остаются подтверждения и очередь.
     Не осталось ничего — строки нет вовсе (класс is-mobempty вешает JS). */
  .fbans .fbans-note{margin-top:7px;font-size:12px;gap:7px}
  .fbans .fbans-note .fbans-dot{margin-top:4px}
  .fbans .fbans-note.is-mobempty{display:none}

  /* Абзац-пояснение в пустых состояниях повторяет три вещи, которые уже сказаны
     рядом: надзаголовок, заголовок карточки и подпись на красной кнопке.
     Сам ЧЕСТНЫЙ ответ остаётся: «Рядом никто не отмечался N часов» и «Ближайшая: X». */
  .fbans .fbans-text{display:none}

  .fbans .fbans-acts{margin-top:9px;gap:8px}
  .fbans .fbans-btn{min-height:44px;padding:10px 12px;font-size:13px;border-radius:13px}
  .fbans .fbans-btn svg{width:15px;height:15px}
}

/* ==== сборка: разрешение конфликта между областями ==========================
   Ряд действий «Ситуации» общий у двух областей: раскладку строки держит «пик
   панели», а третью пилюлю «Идея» добавила область личного кабинета. По
   отдельности каждая правка мерилась на 390 и 360 и влезала, но вместе на 320px
   ряд стал 317px при 288 доступных.
   Прокрутить его пальцем НЕЛЬЗЯ: на .panel-head стоит touch-action:none, вся
   шапка отдана драгу панели. Значит переполнение здесь не «уедет под палец», а
   просто отрежет «Идею» — единственный вход в пожелания после того, как пункт
   убрали из листа «Ещё».
   Лечим полями, а не удалением слова: подписи «Фильтры» и «Последние отметки»
   остаются целыми. Порог 380 взят тот же, что у сводки, — намеренно мимо 360/368,
   где уже дерутся четыре правила про #availBtn/#gpnBtn.
   Замер после: 320px -> 277 из 288 (запас 11), 360px -> 308 из 328. */
@media (max-width:380px){
  .filter-bar{gap:6px}
  .filter-bar .pill{padding:7px 7px}
  /* у «Идеи» ширина фиксированная (34px) и padding:0 — её поля не трогаем,
     иначе кружок перестанет быть кружком */
  .filter-bar .pill-idea{padding:0}
}
/* Самые узкие телефоны: одних полей не хватило (на 320 оставалось 293 из 288).
   Снимаем ВЕДУЩИЕ ГЛИФЫ у «Фильтров» и «Последних отметок» — они декоративные,
   смысл несут слова, и слова остаются целиком. Счётчик активных фильтров .pm-n
   не трогаем: он единственный источник информации в этой пилюле.
   Замер: 320px -> 256 из 288. */
@media (max-width:340px){
  .filter-bar .pill-more>svg,.filter-bar .pill-feed>svg{display:none}
}

/* ==== контраст и цели тапа по итогам техаудита (2026-08-07) =================
   Аудит замерил контраст по WCAG с реальными композитными подложками и нашёл,
   что бейджи мы подчинили, а несколько мест с теми же цветами пропустили.
   Правим цвет ТЕКСТА, геометрию не трогаем.
   ========================================================================= */

/* 1. .sts-title — главный заголовок статуса в карточке станции. Валился в обеих
      темах (тёмная 2.12 и 2.97, светлая 3.39 и 3.69 при пороге 4.5), а это ровно
      тот элемент, ради которого карточку открывают. */
.st-card .sts-title{color:var(--text)}
html[data-theme=dark] .st-card.s-yes .sts-title{color:#4FE09A}
html[data-theme=dark] .st-card.s-queue .sts-title{color:#FFB25C}
html[data-theme=dark] .st-card.s-low .sts-title{color:var(--st-low)}
html[data-theme=dark] .st-card.s-no .sts-title{color:#E8798C}
html[data-theme=dark] .st-card.s-nodata .sts-title{color:var(--text-2)}
html[data-theme=light] .st-card.s-yes .sts-title{color:#0B7A46}
html[data-theme=light] .st-card.s-queue .sts-title{color:#8F4D06}
html[data-theme=light] .st-card.s-low .sts-title{color:#6E5600}
html[data-theme=light] .st-card.s-no .sts-title{color:var(--st-no)}
html[data-theme=light] .st-card.s-nodata .sts-title{color:var(--text-2)}

/* 2. Тёмная тема: --st-no и --st-nodata как ТЕКСТ прямо на surface читались
      от 2.36 до 3.38. Для маркера на карте тусклость нужна, для текста нет. */
html[data-theme=dark] .ff-main small.s-nodata{color:var(--text-2)}
html[data-theme=dark] .ff-main small.s-no{color:#E8798C}
html[data-theme=dark] .fuel.no{color:#E8798C}
html[data-theme=dark] .itag-cash{color:#E8798C}

/* 3. Чип подтверждений: 12px/500, тёмная 2.97, светлая 3.69. */
html[data-theme=dark] .conf-chip.conf-neg{color:#E8798C}
html[data-theme=light] .conf-chip{color:#0B7A46}

/* 4. Цели тапа меньше 44px. Расширяем ЗОНУ прозрачным ::after, видимую геометрию
      не меняем — приём уже применён в этой сессии у .fbans-x. */
/* .sheet-close НЕ трогаем: он position:absolute в углу шита (строка 833), и relative
   выбивал крестик из угла в поток на всех девяти шитах. Абсолют сам по себе
   годится якорем для ::after-расширителя. */
.act-pill,.rep-vote,.copy-addr{position:relative}
.sheet-close::after,.rep-vote::after,.copy-addr::after,.pill-idea::after{
  content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:max(100%,44px);height:44px;
}
@media (max-width:1023px){
  .act-pill::after{
    content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
    width:max(100%,44px);height:44px;
  }
}

/* ==== кнопка пожеланий: подпись вместо голой иконки (2026-08-07) ============
   Была кружком 34px без текста — единственный вход в пожелания после того, как
   пункт убрали из «Ещё», и угадать его назначение нельзя. Плюс брендовый красный
   спорил с «Отметить», хотя это не главное действие экрана.
   Место в забитом ряду освободили, сократив «Последние отметки» до «Отметки».
   ========================================================================= */
.filter-bar .pill-idea{
  width:auto;padding:7px 12px 7px 10px;gap:6px;
  background:var(--surface-3);border-color:var(--line);color:var(--text-2);
}
.filter-bar .pill-idea svg{fill:var(--red);flex:0 0 auto}
.filter-bar .pill-idea:hover{border-color:var(--line-2);color:var(--text)}

/* на самых узких подпись уходит, остаётся иконка — но это уже 320px, где выбора нет */
@media (max-width:340px){
  .filter-bar .pill-idea{width:34px;padding:0;gap:0;font-size:0}
  .filter-bar .pill-idea svg{font-size:16px}
}

/* ==== достижения: контурный набор (2026-08-07) =============================
   Иконки перерисованы в один контур толщиной 1.7 и живут в тех же плитках.
   Поэтому у svg снимаем заливку: она красила бы внутренности контуров.
   Полученное достижение по-прежнему заливается брендовым красным — это ровно
   наш принцип «заливка = состояние», только теперь он работает и здесь.
   ========================================================================= */
.ach-ic svg{fill:none}
.ach-ic svg path{vector-effect:non-scaling-stroke}
/* контур на 25px читался тоньше, чем у иконок меню рядом — выравниваем оптику */
.ach-ic svg{width:23px;height:23px}
.ach.done .ach-ic{box-shadow:0 5px 13px -3px rgba(239,12,59,.5)}

/* ==== достижения: спокойная оправа (2026-08-07) =============================
   Плитка полученного достижения была красным ГРАДИЕНТОМ с цветной тенью, и сверху
   на неё вешался отдельный кружок с галкой. Три сигнала об одном и том же, и вместе
   они дают язык мобильной игрушки, а не наш минимализм.
   Оставляем один сигнал — заливку. Ровно тот принцип, что уже работает у марок
   топлива и у иконок статуса: залито = есть, контур = нет.
   ========================================================================= */
.ach-ic{border-radius:14px}                     /* плитка, как у карточек, а не медаль */
.ach.done .ach-ic{background:var(--red);box-shadow:none}
.ach-check{display:none}                        /* заливка уже сказала «получено» */
.ach:not(.done) .ach-ic{background:var(--surface-3);color:var(--text-3)}
.ach-t{font-weight:600}
.ach.done .ach-t{color:var(--text)}

/* ==== ряд действий не ездит, сводка не уезжает (2026-08-07) =================

   1. РЯД «Фильтры / Отметки / Идея» ездил, потому что у него overflow-x:auto —
      это горизонтальная прокрутка, её смахивает палец. Ряд замерен и влезает
      на 320, 360 и 390, значит прокрутка ему не нужна: выключаем совсем.
      На всякий случай оставляем возможность ужаться, а не переноситься.

   2. ПОЛОСА СВОДКИ уезжала вниз у части юзеров. Три причины разом:
      перенос флекса при нехватке ширины, рост первой строки при системном
      увеличении шрифта, и запоздалый замер до загрузки Onest (лечится в JS).
      Здесь запрещаем перенос и фиксируем высоту строки.
   ========================================================================= */
@media (max-width:1023px){
  .filter-bar{overflow-x:hidden;flex-wrap:nowrap}
  .filter-bar .pill{flex:0 1 auto;min-width:0}
  /* подписи ужимаются многоточием прежде, чем ряд начнёт что-то выталкивать */
  .filter-bar .pill>span,.filter-bar .pill{white-space:nowrap;text-overflow:ellipsis;overflow:hidden}

  .summary{flex-wrap:nowrap;overflow:hidden;min-width:0;flex:1 1 auto}
  .summary .chip{flex:0 0 auto;white-space:nowrap}
  /* первая строка шапки держит ровно одну высоту независимо от системного кегля,
     иначе на крупном шрифте она выпирает за пик и полоса «улетает вниз» */
  .panel-head{grid-auto-rows:min-content}
  .summary,.panel-fine{height:34px;align-self:start}
  .panel-fine{flex:0 0 auto}
}


/* ---- оплаченный рекламный слот: партнёрская кампания в ротации с Fineapp ------
   Плитка тёмная: у карты «Архангел Михаил» арт чёрно-золотой, на белой подложке
   Fineapp он выглядел бы вырезанным из чужого макета. */
.ad-logo-dark{background:#17140f;border:1px solid rgba(214,178,116,.3);box-shadow:none;padding:0;overflow:hidden}
.ad-logo-dark img{width:100%;height:100%;object-fit:cover;display:block;border-radius:inherit}
.ad-mark{margin-top:5px;font-size:10.5px;font-weight:400;line-height:1.25;color:var(--text-3);opacity:.6}
.fpromo-ad .fpromo-art{margin:0 0 14px;border-radius:14px;overflow:hidden;
  border:1px solid rgba(214,178,116,.22);box-shadow:0 12px 30px rgba(0,0,0,.45)}
.fpromo-ad .fpromo-art img{display:block;width:100%;height:auto}
.fpromo-ad .ad-mark{margin-top:12px;text-align:center}
