/* 2base key public patterns: shell, navigation, constructor and company. */
/* ============================================================================
   Redesign 2026-07 components (source: docs/design/ offline mockup) —
   wordmark, marker highlight, header search, light footer, bottom status bar.
   ============================================================================ */

/* Wordmark: "2base" + lime dot. The mockup sets the word in Onest 800; the
   design bundle ships no Onest file, so Inter 800 with identical tracking
   stands in until the owner okays downloading the Onest subset. */
.brand-word {
  /* Onest — brand-only face (brand book): wordmark + 404 figure. */
  font-family: 'Onest', 'Inter', ui-sans-serif, system-ui, sans-serif;
  font-weight: 800;
  font-size: 1.3125rem;   /* 21px */
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--ink);
}

.brand-dot {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-left: 3px;
  border-radius: 99px;
  background: var(--marker-dot);
}

/* Marker highlight — lime wash behind the lower half of key words */
.hl {
  background: linear-gradient(transparent 58%, var(--marker) 58%);
}

/* Header search (every page except home; mockup hides it under 1120px) */
.hdr-search {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  max-width: 420px;
  height: 40px;
  padding: 0 6px 0 14px;
  border-radius: 11px;
  background: var(--tint);
}

.hdr-search input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  padding: 0;
  font-size: 0.875rem;
  color: var(--ink);
}

.hdr-search input:focus {
  box-shadow: none;
}

/* Product home: one concise working hero with a single visual anchor. */
.home-hero {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 296px;
  overflow: hidden;
  isolation: isolate;
  border-radius: 18px;
  background: var(--tint);
  padding: 32px 40px;
}

.home-hero__visual {
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: url('/static/images/hero-data-cards-3d-v1.webp');
  background-repeat: no-repeat;
  background-position: right center;
  background-size: auto 126%;
  filter: contrast(1.1) saturate(1.04);
  transition: transform 420ms cubic-bezier(0.22, 1, 0.36, 1);
}

.home-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(90deg, rgba(240, 240, 243, 1) 0%, rgba(240, 240, 243, 0.98) 38%, rgba(240, 240, 243, 0.68) 53%, rgba(240, 240, 243, 0.12) 70%, rgba(240, 240, 243, 0) 82%);
  pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
  .home-hero:hover .home-hero__visual {
    transform: translate3d(5px, -3px, 0) scale(1.008);
  }
}

.home-hero__content {
  width: min(100%, 590px);
}

.home-hero__title {
  max-width: 540px;
  margin: 0;
  color: var(--ink);
  font-size: clamp(2.125rem, 3vw, 2.75rem);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.035em;
}

.home-hero__lead {
  margin-top: 8px;
  color: var(--color-text-secondary);
  font-size: 0.9375rem;
  line-height: 1.4;
}

.home-hero__search {
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: 560px;
  margin-top: 20px;
  border-radius: 14px;
  background: #fff;
  padding: 7px;
}

.home-hero__search .hero-intent-search__input {
  padding: 10px 4px 10px 12px;
  font-size: 1rem;
}

.home-hero__presets {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  max-width: 600px;
  margin-top: 12px;
}

.home-hero__preset {
  min-height: 32px;
  border: 1px solid rgba(126, 130, 135, 0.24);
  border-radius: 99px;
  background: rgba(255, 255, 255, 0.82);
  padding: 6px 10px;
  color: var(--ink);
  font-size: 0.75rem;
  line-height: 1.2;
  white-space: nowrap;
  transition: border-color var(--transition-fast), background-color var(--transition-fast), transform var(--transition-fast);
}

.home-hero__preset:hover {
  border-color: var(--ink);
  background: #fff;
  transform: translateY(-1px);
}

.home-hero__preset:active {
  transform: translateY(0);
}

.home-hero__preset:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* The focus belongs to the rounded compound control, not to the square text
   input inside it. */
.hero-intent-search {
  border: 1px solid transparent;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.hero-intent-search:hover {
  border-color: var(--color-border-hover);
}

.hero-intent-search:focus-within {
  border-color: var(--ink);
  box-shadow: var(--ring-focus);
}

.hero-intent-search__input:focus,
.hero-intent-search__input:focus-visible {
  outline: none;
  box-shadow: none;
}

@media (max-width: 1120px) {
  .hdr-search { display: none; }
  .hero-cards { display: none; }
}

@media (max-width: 760px) {
  .home-hero {
    min-height: 0;
    padding: 24px 16px 18px;
  }

  .home-hero__visual {
    background-position: 54% center;
    background-size: auto 110%;
    opacity: 0.58;
  }

  .home-hero::after {
    background: linear-gradient(90deg, rgba(240, 240, 243, 1) 0%, rgba(240, 240, 243, 0.98) 62%, rgba(240, 240, 243, 0.88) 78%, rgba(240, 240, 243, 0.62) 100%);
  }

  .home-hero__title {
    max-width: 330px;
    font-size: 2rem;
  }

  .home-hero__lead {
    max-width: 290px;
    font-size: 0.875rem;
  }

  .home-hero__search {
    flex-direction: column;
    align-items: stretch;
    margin-top: 16px;
  }

  .home-hero__presets {
    flex-wrap: nowrap;
    max-width: none;
    margin-top: 10px;
    margin-right: -16px;
    overflow-x: auto;
    padding: 2px 16px 4px 0;
    scrollbar-width: none;
  }

  .home-hero__presets::-webkit-scrollbar {
    display: none;
  }

  .home-hero__preset {
    min-height: 36px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .home-hero__visual,
  .home-hero__preset {
    transition: none;
  }
}

/* Full-width variant survives the <=1120px hide — used inside the mobile
   drawer where the search must stay visible. */
.hdr-search--full,
.hdr-search.hdr-search--full {
  display: flex;
  max-width: none;
}

/* Micro-label: JetBrains Mono caps (counters, eyebrows, table meta) */
.mono-label {
  font-family: var(--font-mono);
  font-size: 0.625rem;      /* 10px */
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Light footer: mono-caps column heads, quiet links, 34px icon buttons */
.foot-h {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 0.75rem;
}

.foot-link {
  display: block;
  padding: 0.3125rem 0;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--muted);
  text-decoration: none;
}

.foot-link:hover {
  color: var(--ink);
}

.foot-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--gray-200);
  border-radius: 9px;
  background: #fff;
  color: var(--ink);
  transition: border-color var(--transition-fast), background-color var(--transition-fast);
}

.foot-icon-btn:hover {
  border-color: var(--color-border-hover);
  background: var(--tint);
}

/* Bottom status bar — sticky ink strip with the live-update ticker.
   Rendered by partials/status_bar.html only when the handler provides
   .StatusBar; the cookie banner (z-60) intentionally stacks above it. */
/* In normal document flow right above the footer (mockup): the strip is a
   provenance fact, not a toolbar — pinning it to the viewport covered content
   on every page and forced hiding it on phones. */
.status-bar {
  background: var(--ink);
  color: #fff;
}

.status-bar__inner {
  max-width: var(--container-wide);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.status-bar__pulse {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  border-radius: 99px;
  background: var(--marker);
  box-shadow: 0 0 0 3px rgba(233, 251, 78, 0.18);
}

.status-bar__text {
  font-size: 0.78125rem;    /* 12.5px */
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.status-bar__text b {
  color: #fff;
  font-weight: 600;
}

.status-bar__meta {
  display: flex;
  align-items: center;
  gap: 22px;
  flex-shrink: 0;
  font-size: 0.71875rem;    /* 11.5px */
  color: var(--muted);
}

.status-bar__meta b {
  font-size: 0.8125rem;
  font-weight: 600;
  color: #fff;
}

.status-bar__sep {
  width: 1px;
  height: 14px;
  background: rgba(255, 255, 255, 0.14);
}

@media (max-width: 1100px) {
  .status-bar__meta { display: none; }
}

/* Phones keep the strip (mockup «Главная mobile»): now that it scrolls in
   flow above the footer it no longer fights the constructor's fixed order
   bar for the bottom edge. Only the right meta column is dropped (rule
   above) so the left provenance phrase fits one line. */

/* ============================================================
   Constructor wave 1b — filter pills, filter modal, sample table
   (mockup «База (дашборд)», rows 63-274)
   ============================================================ */

/* ============================================================
   Header «Каталог» mega-menu (mockup rows 32-59)
   <details>-driven: opens without JS, Alpine only adds escape/outside-click.
   ============================================================ */
.mega {
  position: static;   /* panel spans the full header width, not the summary */
}

/* «Каталог» reads as a control, not a link — a tint pill, per the mockup */
.mega__trigger {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.875rem;
  border-radius: 10px;
  background: var(--tint);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  list-style: none;
  user-select: none;
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

/* Top-level header links: quiet until current, then ink with a lime underline */
.nav-top {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0.5rem 0;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--muted);
  transition: color var(--transition-fast);
}

.nav-top:hover {
  color: var(--ink);
}

.nav-top.is-active {
  color: var(--ink);
}

.nav-top.is-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 2px;
  background: var(--marker);
}

/* Icon-only header button (orders/cart) */
.hdr-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex-shrink: 0;
  border-radius: 10px;
  color: var(--ink);
  transition: background-color var(--transition-fast);
}

.hdr-icon-btn:hover {
  background: var(--tint);
}

.mega__trigger::-webkit-details-marker { display: none; }

.mega__trigger:hover {
  background: var(--gray-200);
}

/* Open state reads as a pressed control — ink pill, as in the mockup */
.mega[open] .mega__trigger {
  background: var(--ink);
  color: #fff;
}

.mega__burger {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 14px;
}

.mega__burger > span {
  height: 1.8px;
  background: currentColor;
}

.mega__panel {
  position: absolute;
  left: 0;
  right: 0;
  top: 64px;
  z-index: 61;
  background: #fff;
  border-top: 1px solid var(--tint);
  box-shadow: 0 26px 60px -22px rgba(20, 19, 17, 0.4);
  max-height: calc(100vh - 64px);
  overflow: hidden;
}

.mega__inner {
  padding-top: 20px;
  padding-bottom: 28px;
}

.mega__top {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--tint);
}

.mega__top p {
  margin-top: 4px;
  color: var(--ink);
  font-size: 0.9375rem;
  font-weight: 600;
}

.mega__top a {
  flex-shrink: 0;
  color: var(--ink);
  font-size: 0.8125rem;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: var(--color-border-hover);
  text-underline-offset: 3px;
}

/* Two panes, per the mockup: a 300px industry rail on the left, the niches of
   the hovered industry on the right. Fixed left track → flex, not an
   arbitrary grid template (safelist guard). */
.mega__grid {
  display: flex;
  align-items: stretch;
  gap: 28px;
}

.mega__rail {
  width: 300px;
  flex: 0 0 300px;
  max-height: min(52vh, 460px);
  overflow-y: auto;
  overscroll-behavior: contain;
  border-right: 1px solid var(--tint);
  padding-right: 16px;
  scrollbar-width: thin;
  scrollbar-color: var(--color-border-hover) transparent;
}

/* The mockup dims the page behind the open panel. Sits under the panel
   (z-index 61) and over everything else. */
.mega__scrim {
  display: none;
  position: fixed;
  left: 0;
  right: 0;
  top: 64px;
  bottom: 0;
  z-index: 60;
  background: var(--overlay);
}

.mega[open] .mega__scrim {
  display: block;
}

.mega__pane {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 350px;
  padding-top: 2px;
}

.mega__item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 9px 10px;
  border-radius: 8px;
  font-size: 0.875rem;
  color: var(--ink);
  transition: background-color var(--transition-fast);
}

.mega__item:hover,
.mega__item.is-on {
  background: var(--tint);
}

/* 3×3 grid of niches — the mockup's right pane */
.mega__subs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 2px 20px;
}

.mega__sub {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.625rem;
  padding: 7px 8px;
  border-radius: 8px;
  font-size: 0.8125rem;
  color: var(--color-text-secondary);
  transition: background-color var(--transition-fast), color var(--transition-fast);
}

.mega__sub:hover {
  background: var(--tint);
  color: var(--ink);
}

.mega__sub-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mega__item:focus-visible,
.mega__sub:focus-visible,
.mega__top a:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

/* «также» — inside the right pane, its rule spanning that pane only */
.mega__foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin-top: 22px;
  padding-top: 16px;
  padding-left: 8px;
  border-top: 1px solid var(--tint);
}

/* Pill bar: wraps on desktop, one swipeable row on phones (four stacked
   rows ate 178px of a 812px screen before the table even started).
   Sticks under the 64px header — tokens: «панель выборки на главной липнет
   под шапкой: top: 64px». */
.fp-pillbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  position: sticky;
  top: 64px;
  z-index: 30;
  background: var(--paper);
  padding-block: 0.625rem;
}

.fp-pills {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  min-width: 0;
}

.fp-pills-actions {
  display: flex;
  align-items: center;
  gap: 0.625rem;
  flex-shrink: 0;
}

@media (max-width: 1023.98px) {
  .fp-pillbar { gap: 0.5rem; flex-wrap: wrap; }
  .fp-pill,
  .pg-btn,
  .ctab-dots {
    min-height: 2.75rem;
  }
  /* Бейдж со «Сбросом» стоял в одной строке с лентой и съедал 159px из 390 —
     на телефон влезало полтора пилла. Отдаём ленте всю ширину, действия
     переносим строкой ниже (появляются только когда фильтр уже выбран). */
  .fp-pills { flex: 1 1 100%; }
  .fp-pills-actions { margin-left: auto; }
  .fp-pills {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 2px;
  }
  .fp-pills::-webkit-scrollbar { display: none; }
  .fp-pills > * { flex-shrink: 0; }
}

/* Filter pill — one per modal section; active = the section narrows the set */
.fp-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 38px;
  padding: 0 0.875rem;
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  background: #fff;
  font-size: 0.84375rem;   /* 13.5px */
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.fp-pill:hover {
  background: var(--tint);
}

.fp-pill.is-active {
  border-color: var(--ink);
}

.fp-pill__caret {
  font-size: 9px;
  color: var(--muted);
}

.fp-pill__label {
  max-width: 230px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Lime counter of active filters next to the reset button */
.fp-count-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 24px;
  height: 24px;
  padding: 0 7px;
  border-radius: 99px;
  background: var(--marker);
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  font-weight: 700;
  color: var(--ink);
}

/* Filter modal: fixed sheet under the header, rail on the left */
.fp-overlay {
  position: fixed;
  inset: 0;
  background: var(--overlay);
  z-index: 80;
}

.fp-modal {
  position: fixed;
  left: 50%;
  top: 74px;
  transform: translateX(-50%);
  width: min(940px, calc(100vw - 40px));
  max-height: calc(100vh - 110px);
  max-height: calc(100dvh - 110px);
  background: #fff;
  border-radius: 16px;
  box-shadow: var(--shadow-mega);
  z-index: 81;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.fp-modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 16px 22px;
  border-bottom: 1px solid var(--tint);
}

.fp-modal__close {
  width: 32px;
  height: 32px;
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  background: #fff;
  cursor: pointer;
  font-size: 14px;
  color: var(--ink);
}

.fp-modal__close:hover {
  background: var(--tint);
}

.fp-modal__body {
  display: flex;
  flex: 1;
  min-height: 0;
}

.fp-modal__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 14px 22px;
  border-top: 1px solid var(--tint);
}

.fp-rail {
  width: 236px;
  flex-shrink: 0;
  border-right: 1px solid var(--gray-200);
  padding: 12px;
  overflow-y: auto;
  background: var(--tint);
}

.fp-rail-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-radius: 9px;
  background: transparent;
  font-size: 0.84375rem;
  font-weight: 500;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}

.fp-rail-item:hover {
  background: rgba(255, 255, 255, 0.7);
}

.fp-rail-item.is-active {
  background: #fff;
  font-weight: 600;
}

/* Dot marking a section that currently narrows the selection */
.fp-dot {
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  border-radius: 99px;
  background: var(--marker-dot);
}

.fp-section-pane {
  flex: 1;
  min-width: 0;
  padding: 20px 24px;
  overflow-y: auto;
}

/* Phone: the modal becomes a full-screen sheet, the rail a horizontal strip */
@media (max-width: 1023.98px) {
  .fp-modal {
    top: 0;
    left: 0;
    transform: none;
    width: 100vw;
    max-height: 100vh;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
  }
  .fp-modal__body { flex-direction: column; }
  .fp-rail {
    display: flex;
    gap: 4px;
    width: auto;
    border-right: none;
    border-bottom: 1px solid var(--gray-200);
    overflow-x: auto;
    overflow-y: hidden;
    padding: 10px 12px;
  }
  .fp-rail-item { white-space: nowrap; width: auto; }
  /* Полоса прокрутки рельса: на телефонах она оверлейная и невидимая, а в
     десктопном браузере с узким окном рисуется толстой серой плашкой поперёк
     листа. Прячем — активная вкладка и так подскроливается сама. */
  .fp-rail { scrollbar-width: none; }
  .fp-rail::-webkit-scrollbar { display: none; }
  .fp-modal__foot { padding: 12px 16px; gap: 12px; }
  /* Иначе «Сбросить всё» ломается на две строки и подпирает кнопку. */
  .fp-modal__foot > button:first-child { white-space: nowrap; }
}

/* Modal search + checkable two-column list (mockup «Фильтры выборки»: one
   search box над сеткой 1fr 1fr, строка = [✓] имя … моно-счётчик). Replaces
   the dropdowns that used to sit here — a 85-region <select> hid the counts
   and made «сочи» unfindable. */
.fp-search {
  width: 100%;
  background: var(--tint);
  border: 1px solid transparent;
  border-radius: 10px;
  padding: 11px 13px;
  font-size: 0.84375rem;   /* 13.5px */
  color: var(--ink);
  outline: none;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast), background-color var(--transition-fast);
}

.fp-search::placeholder { color: var(--muted); }

.fp-search:focus {
  border-color: var(--ink);
  box-shadow: var(--ring-focus);
  background: #fff;
}

.fp-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2px 18px;
  max-height: 344px;
  overflow-y: auto;
  padding-right: 4px;
}

@media (min-width: 640px) {
  .fp-list { grid-template-columns: 1fr 1fr; }
}

/* Телефон: модалка и так лист во весь экран со своим скроллом — вложенный
   скроллер списка на тач-устройстве только мешает (палец скроллит не то, что
   ожидаешь). Правило обязано стоять ПОСЛЕ базового `.fp-list`: специфичность
   одинаковая, побеждает то, что ниже в файле. */
@media (max-width: 1023.98px) {
  .fp-list {
    max-height: none;
    overflow-y: visible;
    padding-right: 0;
  }
}

.fp-list-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  /* Grid-элементы по умолчанию не сжимаются ниже своего контента: без этого
     длинное название ниши распирало колонку 1fr и весь список получал
     горизонтальный скролл. */
  min-width: 0;
  padding: 7px 9px;
  border: none;
  border-radius: 8px;
  background: none;
  font-size: 0.84375rem;
  line-height: 1.35;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
  transition: background 0.14s ease;
}

.fp-list-row:hover { background: var(--tint); }

.fp-list-row.is-selected {
  background: var(--tint);
  font-weight: 600;
}

.fp-list-row__check {
  display: inline-block;
  flex-shrink: 0;
  width: 16px;
  font-weight: 700;
  color: var(--ink);
}

/* Одна строка на позицию: названия ниш из ЕГРЮЛ бывают под 90 символов и
   ломали двухколоночную сетку макета. */
.fp-list-row__name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.fp-list-row__sub {
  font-size: 0.71875rem;   /* 11.5px */
  color: var(--muted);
  font-weight: 400;
}

.fp-list-row__count {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 0.71875rem;
  font-weight: 400;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.fp-list-empty {
  grid-column: 1 / -1;
  padding: 14px 9px;
  font-size: 0.8125rem;
  color: var(--muted);
}

.fp-hint {
  margin-top: 10px;
  font-size: 0.71875rem;
  color: var(--muted);
}

/* Alpine-dead fallback: the modal opens via vanilla listeners and every
   section is shown stacked (no rail switching without Alpine). */
.fp-fallback .fp-rail { display: none; }
.fp-fallback .fp-section { display: block !important; margin-bottom: 1.75rem; }

/* The native <select>s stay in the DOM as the vanilla path's real controls
   (deep links, form submit, the fallback filter UI). Once Alpine boots, the
   mockup lists above take over and the selects are hidden — the class lands on
   <html> from the alpine:initialized listener, so a dead Alpine leaves them
   visible and usable. */
.js-alpine .fp-native { display: none; }

/* Sample table — mono-caps head, dashed row separators, tint hover */
.ctab {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
  font-size: 0.84375rem;   /* 13.5px */
}

/* Keep the preview columns stable while async rows arrive. Auto table layout
   used the skeleton/header widths first and then recomputed from real names,
   which produced a visible late shift on the main conversion screen. */
.ctab th:nth-child(1), .ctab th:nth-child(2), .ctab th:nth-child(8) { width: 32px; }
.ctab th:nth-child(4) { width: 118px; }
.ctab th:nth-child(5) { width: 110px; }
.ctab th:nth-child(6) { width: 165px; }
.ctab th:nth-child(7) { width: 62px; }

.ctab thead th {
  padding: 12px 9px 8px;
  border-bottom: 1px solid var(--gray-200);
  font-family: var(--font-mono);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--muted);
  text-align: left;
  white-space: nowrap;
}

.ctab tbody td {
  padding: 11px 9px;
  border-bottom: 1px dashed var(--gray-200);
  vertical-align: top;
}

.ctab tbody tr:hover {
  background: var(--tint);
}

.ctab .ctab-num {
  font-family: var(--font-mono);
  font-size: 0.78125rem;
  color: var(--muted);
}

/* «Готовые базы»: search + sort sitting inside the hero (mockup). Fixed-width
   sort next to a fluid search field → flex, not an arbitrary grid track. */
.bases-hero-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}

.bases-hero-controls__q {
  flex: 1 1 320px;
  min-width: 0;
  max-width: 460px;
  background: #fff;
}

.bases-hero-controls__sort {
  flex: 0 0 auto;
  width: 210px;
}

/* Masked emails are long and unbreakable; wrapping them turned every row into
   three lines once the pick/★/⋯ columns joined. Clip instead — the full value
   is in the title attribute, and the real one ships in the XLSX anyway. */
.ctab .ctab-email,
.ctab .ctab-cat {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ctab .ctab-email { max-width: 145px; }
.ctab .ctab-cat { max-width: 150px; }

/* Row controls from the mockup: pick column, ★ shortlist, ⋯ menu, ⇅ headers */
.ctab .ctab-pick {
  width: 1%;
  padding-left: 6px;
  padding-right: 6px;
  white-space: nowrap;
}

.ctab-check {
  width: 15px;
  height: 15px;
  accent-color: var(--ink);
  cursor: pointer;
  vertical-align: middle;
}

.ctab-star {
  border: 0;
  background: none;
  padding: 0 2px;
  font-size: 14px;
  line-height: 1;
  color: var(--gray-300);
  cursor: pointer;
  transition: color var(--transition-fast);
}

.ctab-star:hover { color: var(--muted); }
.ctab-star.is-on { color: var(--marker-dot); }

.ctab-sort {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 0;
  background: none;
  padding: 0;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  color: inherit;
  cursor: pointer;
}

.ctab-sort--end { justify-content: flex-end; width: 100%; }
.ctab-sort:hover { color: var(--ink); }
.ctab-sort.is-on { color: var(--ink); }

.ctab tbody tr.is-picked { background: var(--tint); }

.ctab-menu { position: relative; }

.ctab-dots {
  border: 0;
  background: none;
  padding: 0 4px;
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  cursor: pointer;
}

.ctab-dots:hover { color: var(--ink); }

.ctab-menu__pop {
  position: absolute;
  right: 0;
  top: 100%;
  z-index: 30;
  min-width: 190px;
  padding: 4px;
  background: #fff;
  border: 1px solid var(--tint);
  border-radius: 12px;
  box-shadow: var(--shadow-mega);
}

.ctab-menu__item {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: none;
  text-align: left;
  font-size: 0.8125rem;
  color: var(--ink);
  white-space: nowrap;
  cursor: pointer;
}

.ctab-menu__item:hover { background: var(--tint); }

/* Bar above the table: what is selected / shortlisted right now */
.ctab-bar {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 8px;
  padding: 10px 12px;
  border-radius: 10px;
  background: var(--tint);
}

.ctab-bar__act {
  border: 0;
  background: none;
  padding: 0;
  font-size: 0.8125rem;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--color-border-hover);
  cursor: pointer;
}

.ctab-bar__act:hover { text-decoration-color: var(--ink); }

/* Pagination buttons under the table */
.pg-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 32px;
  height: 32px;
  padding: 0 6px;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  font-size: 0.8125rem;
  color: var(--ink);
  cursor: pointer;
}

.pg-btn:hover {
  background: var(--tint);
}

.pg-btn.is-current {
  background: var(--ink);
  color: #fff;
  font-weight: 600;
  cursor: default;
}

.pg-btn:disabled {
  color: var(--gray-300);
  cursor: default;
  background: transparent;
}

/* Contact-coverage toggle rows in the order panel */
.cov-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--gray-200);
  border-radius: 9px;
  background: #fff;
  font-size: 0.8125rem;
  color: var(--ink);
  cursor: pointer;
  text-align: left;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.cov-row:hover {
  background: var(--tint);
}

/* Active channel = lime frame + wash. Mockup uses the accent here precisely
   because it is the one place a filter changes what the buyer pays for. */
.cov-row.is-on {
  border-color: var(--marker);
  background: rgba(233, 251, 78, 0.28);
}

.cov-row.is-on:hover {
  background: rgba(233, 251, 78, 0.28);
}

/* Mono count + share of the matched set, right-aligned */
.cov-row__num {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink);
  white-space: pre;
  flex-shrink: 0;
}

.cov-row__box {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  border: 1.5px solid var(--gray-300);
  border-radius: 5px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  color: #fff;
  background: #fff;
}

.cov-row.is-on .cov-row__box {
  border-color: var(--ink);
  background: var(--ink);
}

/* Quantity presets (1K / 5K / 10K / Все) in the order panel */
.qp-btn {
  flex: 1;
  height: 32px;
  border: 1px solid var(--gray-200);
  border-radius: 8px;
  background: #fff;
  font-size: 0.78125rem;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}

.qp-btn:hover {
  background: var(--tint);
}

.qp-btn.is-on {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

/* ===== Company card (redesign wave 1c) =====
   Mockup screen «Карточка компании»: white blocks on paper, mono for every
   machine-readable value (ИНН/ОГРН, contacts, dates), tint chips for the
   at-a-glance facts, one ink CTA in the contacts block. */

.cc-block {
  background: #fff;
  border: 1px solid var(--tint);
  border-radius: 14px;
  padding: 1.375rem 1.625rem;
}

@media (max-width: 639.98px) {
  .cc-block {
    padding: 1.125rem 1.125rem;
  }
}

.cc-name {
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.15;
  color: var(--ink);
  margin: 0;
}

@media (max-width: 639.98px) {
  .cc-name {
    font-size: 1.375rem;
  }
}

/* ИНН · ОГРН — mono so the digits stay scannable and copy cleanly */
.cc-ids {
  font-family: var(--font-mono);
  font-size: 0.78125rem;
  color: var(--muted);
  margin-top: 0.5rem;
  overflow-wrap: anywhere;
}

.cc-copy {
  font-family: inherit;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--ink);
  background: none;
  border: none;
  padding: 0 0 0 0.375rem;
  cursor: pointer;
}

.cc-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1rem;
}

.cc-chip {
  font-size: 0.78125rem;
  color: var(--muted);
  background: var(--tint);
  border-radius: 6px;
  padding: 0.3125rem 0.625rem;
}

.cc-chip a,
a.cc-chip {
  color: inherit;
  text-decoration: none;
}

.cc-chip a:hover,
a.cc-chip:hover {
  color: var(--ink);
}

.cc-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.625rem;
  margin-top: 1.125rem;
  padding-top: 1rem;
  border-top: 1px solid var(--tint);
}

.cc-action {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  background: none;
  border: 1px solid var(--tint);
  border-radius: 8px;
  padding: 0.5rem 0.875rem;
  font-size: 0.78125rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--transition-fast);
}

.cc-action:hover {
  background: var(--tint);
}

/* Contacts money block: masked values are masked SERVER-side (mask.go), so
   they render as plain mono text — the mockup shows the shape of the number
   on purpose, it is what makes the unlock worth 25 ₽. */
.cc-mono-contacts {
  font-family: var(--font-mono);
  font-size: 0.9375rem;
  line-height: 1.8;
  color: var(--muted);
  overflow-wrap: anywhere;
}

.cc-mono-contacts--open {
  font-size: 1rem;
  line-height: 1.85;
  color: var(--ink);
}

.cc-mono-contacts a {
  color: inherit;
  text-decoration: none;
  border-bottom: 1px solid var(--color-border-hover);
}

.cc-mono-contacts a:hover {
  color: var(--ink);
}

/* Key/value rows — two columns on desktop, one on narrow screens */
.cc-rows {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 2rem;
  font-size: 0.875rem;
}

@media (max-width: 767.98px) {
  .cc-rows {
    grid-template-columns: 1fr;
    gap: 0;
  }
}

.cc-rows--single {
  grid-template-columns: 1fr;
}

.cc-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.6875rem 0;
  border-bottom: 1px solid var(--tint);
  min-width: 0;
}

.cc-row__k {
  color: var(--muted);
  white-space: nowrap;
}

.cc-row__v {
  font-weight: 600;
  text-align: right;
  color: var(--ink);
  min-width: 0;
  overflow-wrap: anywhere;
}

.cc-row__v a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--color-border-hover);
}

.cc-row__v--num {
  font-variant-numeric: tabular-nums;
}

/* Wide rows (address, ОКВЭД, руководитель) span both columns */
.cc-row--wide {
  grid-column: 1 / -1;
}

/* Timeline-ish rows: mono date + event text */
.cc-fact {
  display: flex;
  gap: 0.75rem;
  padding: 0.5625rem 0;
  border-bottom: 1px solid var(--tint);
  font-size: 0.84375rem;
  color: var(--ink);
}

.cc-fact:last-child {
  border-bottom: none;
}

.cc-fact__date {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--muted);
  white-space: nowrap;
}

/* Label + value variant of the same row, used by the «Реквизиты» block on
   /contacts (the mockup's separate requisites screen lives there — /requisites
   301s to it). Same dashed rhythm as the company card's facts. */
.cc-facts {
  margin: 0;
}

.cc-fact__k {
  flex: 0 0 190px;
  color: var(--muted);
}

.cc-fact__v {
  flex: 1;
  min-width: 0;
  font-weight: 500;
  overflow-wrap: anywhere;
}

@media (max-width: 640px) {
  .cc-fact {
    flex-direction: column;
    gap: 0.2rem;
  }

  .cc-fact__k {
    flex: none;
  }
}

/* Outlined status pill — the mockup's «Действует». Ink outline, no fill:
   an active company is the default state and should not shout. */
.cc-status {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink);
  border: 1px solid var(--ink);
  padding: 0.3125rem 0.6875rem;
  border-radius: 99px;
  white-space: nowrap;
}
/* Key public interaction contract: every dense control remains operable by keyboard. */
.fp-pill:focus-visible,
.fp-modal__close:focus-visible,
.fp-rail-item:focus-visible,
.fp-list-row:focus-visible,
.ctab-star:focus-visible,
.ctab-sort:focus-visible,
.ctab-dots:focus-visible,
.ctab-menu__item:focus-visible,
.ctab-bar__act:focus-visible,
.cc-copy:focus-visible,
.cc-action:focus-visible,
.cc-chip a:focus-visible,
a.cc-chip:focus-visible,
.cc-mono-contacts a:focus-visible {
  outline: none;
  box-shadow: var(--ring-focus);
}

.fp-search--okved { width: 10rem; }
.fp-search--revenue { width: 12.5rem; }
.fp-search--year { width: 8.75rem; }
.fp-selection-chip { background: var(--tint); }
.ctab-th--end,
.ctab-num--end { text-align: right; }
.ctab-num--ink { color: var(--ink); }
.ctab-row--open { cursor: pointer; }
.constructor-quantity-range { accent-color: var(--ink); }

@media (max-width: 639.98px) {
  .fp-search--okved,
  .fp-search--revenue,
  .fp-search--year {
    width: 100%;
  }
}
/* Company record details keep their fact-first hierarchy without inline styling. */
.cc-contact-state--open,
.cc-contact-access-note,
.cc-report-status { color: var(--ink); }

.cc-contact-state--masked,
.cc-contact-type,
.cc-map-meta { color: var(--muted); }

.cc-inline-link { text-decoration-color: var(--color-border-hover); }
.cc-inline-link:hover { text-decoration-color: currentColor; }
.cc-inline-link:focus-visible {
  outline: none;
  border-radius: var(--radius-xs);
  box-shadow: var(--ring-focus);
}

.company-map {
  height: 18.75rem;
  border: 1px solid var(--tint);
}
/* Site shell uses shared tokens instead of static inline declarations. */
.app-site-header {
  background: var(--paper);
  border-color: var(--tint);
}

.app-site-header__inner { height: 4rem; }
.app-text-muted { color: var(--muted); }
.app-underline-link { text-decoration-color: var(--color-border-hover); }
.app-underline-link:hover { text-decoration-color: currentColor; }
.app-underline-link:focus-visible {
  outline: none;
  border-radius: var(--radius-xs);
  box-shadow: var(--ring-focus);
}

.hdr-summary,
.hdr-mobile-summary { list-style: none; }
.hdr-account-menu {
  border: 1px solid var(--tint);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-mega);
}
.hdr-search__symbol {
  color: var(--muted);
  font-size: 0.9375rem;
  line-height: 1;
}
.hdr-mobile-overlay { background: var(--overlay); }

/* Панель заказа: при переходе на шаг 2 мобильный скролл ведёт к её верху.
   Отступ — под ДВЕ липкие полосы: шапку и панель фильтров-пиллов; при 76px
   они накрывали «← к сегменту». */
#constructor-step3 {
  scroll-margin-top: 128px;
}

/* The count, coverage and preview arrive asynchronously. Reserve the desktop
   working surface so the footer never enters the first viewport and then gets
   pushed away; this removes the largest measured layout shift on the home
   constructor without making the compact hero taller. */
@media (min-width: 1024px) {
  #constructor-results { min-height: 660px; }
  #constructor-step3 { min-height: 454px; }
}
/* Footer shell shares the same paper and quiet-link treatment as the header. */
.app-site-footer {
  background: var(--paper);
  border-color: var(--tint);
}
.app-site-footer__legal { border-color: var(--tint); }
.app-footer-link { text-decoration-color: var(--muted); }
.app-footer-link:hover { text-decoration-color: currentColor; }
.app-footer-link:focus-visible {
  outline: none;
  border-radius: var(--radius-xs);
  box-shadow: var(--ring-focus);
}
