/* ============================================================
   Greenlight — лендинг Proposal Pre-Send Check. Палитра брендборда.
   Порядок: токены → база → утилиты → секции → демо → модалка → баннер →
            липкая полоса → длинный текст → адаптив → reduced-motion

   Внешних шрифтов нет намеренно: блокирующая загрузка бьёт по CR.
   Ни одного hex-а внутри правил — только переменные из :root.
   Полоса сканирования 1.2s === PRESEND_CONFIG.scanDurationMs.
   ============================================================ */

:root {
  /* --- Поверхности и текст --- */
  --surface:        #ffffff;
  --surface-sunken: #fcfdfe;
  --paper:          #f8fafc;
  --paper-deep:     #eef2f6;
  --dark:           #111827;
  /* Две ступени поверх --dark: карточка показа продукта и блоки внутри неё.
     Проверено на --text-on-dark: 6.2:1 на raised, 6.7:1 на sunken. */
  --dark-raised:    #171f2f;
  --dark-sunken:    #0d1320;
  --dark-border:    #252f42;

  --text:       #111827;
  --text-soft:  #6b7280;
  --text-faint: #6b7280;
  --text-invert:#f8fafc;
  /* Только для текста на тёмной заливке: на белом даёт 2.5:1 и там запрещён. */
  --text-on-dark: #9ca3af;

  --border:      #e2e8f0;
  --border-soft: #eff3f7;
  --border-firm: #cbd5e1;

  /* --- Брендовый зелёный. Работает заливкой, но НЕ цветом текста на светлом:
     #22c55e на белом даёт 2.3:1. Для текста и ссылок — --accent-link. --- */
  --accent:      #22c55e;
  --accent-dark: #16a34a;
  --accent-ink:  #052e16;   /* краска поверх зелёной заливки */
  --accent-link: #15803d;   /* зелёный, пригодный для текста на светлом */
  --accent-soft: #f1f5f9;
  --accent-dim:  #86efac;   /* только на тёмном */

  /* --- Светофор. Зарезервированная семантика, вне вердикта не используется. --- */
  --red:    #ef4444;
  --yellow: #eab308;
  --green:  #22c55e;

  /* Тексты сигналов — отдельные токены: на белом нужен контраст ≥ 4.5:1. */
  --red-text:    #dc2626;
  --yellow-text: #a16207;
  --green-text:  #15803d;

  --dot-off: #e5e7eb;

  /* Подложка карточки вердикта — тонкий фон сигнала, текст поверх остаётся контрастным. */
  --red-tint:    #fef2f2;
  --red-edge:    #fecaca;
  --yellow-tint: #fefce8;
  --yellow-edge: #fde68a;
  --green-tint:  #f0fdf4;
  --green-edge:  #bbf7d0;

  /* --- Подсветка фрагментов. Читаемость важнее заметности: по ним читают. --- */
  --hl-placeholder-bg:   #fef3c7;
  --hl-placeholder-text: #78350f;
  --hl-placeholder-line: #b45309;

  --hl-ai-bg:   #e5e7eb;
  --hl-ai-text: #111827;
  --hl-ai-line: #94a3b8;

  --hl-tos-bg:   #fee2e2;
  --hl-tos-text: #7f1d1d;
  --hl-tos-line: #ef4444;

  /* Применённое исправление. Зелёный здесь — тот же сигнал, что и у зелёного вердикта. */
  --hl-fixed-bg:   #dcfce7;
  --hl-fixed-text: #14532d;
  --hl-fixed-line: #16a34a;

  /* --- Форма --- */
  --radius-sm: 7px;
  --radius:    10px;
  --radius-lg: 16px;
  --radius-pill: 999px;

  --shadow-sm:   0 1px 2px rgba(17, 24, 39, .06);
  --shadow:      0 1px 2px rgba(17, 24, 39, .05), 0 10px 26px rgba(17, 24, 39, .07);
  --shadow-modal:0 20px 56px rgba(17, 24, 39, .28);
  --shadow-up:   0 -6px 22px rgba(17, 24, 39, .09);

  --focus: 0 0 0 3px rgba(34, 197, 94, .35);

  /* Ореолы и полоса сканирования: те же цвета, что у токенов выше, но с альфой. */
  --halo-red:    rgba(239, 68, 68, .18);
  --halo-yellow: rgba(234, 179, 8, .2);
  --halo-green:  rgba(34, 197, 94, .18);
  --scan-soft:   rgba(34, 197, 94, .14);
  --scan-firm:   rgba(34, 197, 94, .55);
  --tint-red:    rgba(239, 68, 68, .14);

  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
  /* Inter — из брендборда. Подключать только самохостом: woff2 + font-display: swap.
     Пока файла нет, стек падает на системный шрифт и страница не ждёт загрузки. */
  --sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  /* Высота липкой полосы: на неё же отодвигается футер, чтобы ссылки не закрывались. */
  --sticky-h: 104px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--surface);
  color: var(--text);
  font: 16px/1.65 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
}

body.is-locked { overflow: hidden; }

h1, h2, h3 { line-height: 1.18; margin: 0 0 .5em; letter-spacing: -.02em; }
h3 { letter-spacing: -.01em; }
p { margin: 0 0 1em; }

a { color: var(--accent-link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent-dark); }

/* Один общий фокус на всё интерактивное, включая крестик модалки. */
:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

code {
  font: .88em/1 var(--mono);
  background: var(--paper);
  border: 1px solid var(--border-soft);
  padding: .15em .35em;
  border-radius: 5px;
}

.container {
  max-width: 1120px;
  margin: 0 auto;
  padding: 0 24px;
}

/* --- Кнопки ------------------------------------------------ */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5em;
  font: 600 15px/1 var(--sans);
  padding: 13px 20px;
  min-height: 44px;
  border: 1px solid transparent;
  border-radius: var(--radius);
  cursor: pointer;
  transition: background-color .15s, box-shadow .15s, color .15s;
}

.button:disabled { cursor: default; }

.button--primary {
  background: var(--accent);
  color: var(--accent-ink);
  box-shadow: var(--shadow-sm);
}
.button--primary:hover:not(:disabled) { background: var(--accent-dark); }
.button--primary:disabled {
  background: var(--paper-deep);
  color: var(--text-faint);
  box-shadow: none;
}

.button--ghost {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border-firm);
}
.button--ghost:hover { background: var(--paper); }

.button--lg { padding: 16px 28px; font-size: 17px; min-height: 52px; }
.button--full { width: 100%; }

/* --- Секции ------------------------------------------------ */

.eyebrow {
  font: 700 11.5px/1 var(--sans);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin: 0 0 18px;
}

/* Hero держим компактным: верх демо обязан попадать на первый экран.
   Hero и финальный CTA — тёмная заливка бренда, страница закрывается тем же фоном. */
.hero {
  padding: clamp(40px, 5vw, 64px) 0 clamp(48px, 6vw, 72px);
  background: var(--dark);
  color: var(--text-invert);
}
.hero .eyebrow { color: var(--accent); }
/* На тёмном только --text-on-dark: --text-soft/--text-faint дают здесь 3.6:1. */
.hero__subtitle, .hero__note { color: var(--text-on-dark); }
/* Две колонки: текст и показ продукта. Ограничена колонка, а не сам .container —
   max-width на контейнере вместе с его margin: 0 auto центрировал hero и уводил
   его от левого края страницы. */
.hero__inner {
  max-width: 1120px;
  display: grid;
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
}
.hero__copy { max-width: 720px; }
.hero__title { font-size: clamp(34px, 5.2vw, 56px); margin-bottom: .35em; }
.hero__subtitle {
  font-size: clamp(17px, 1.5vw, 19px);
  max-width: 62ch;
  margin-bottom: 26px;
}
.hero__note { font-size: 14px; margin: 14px 0 0; }

/* Правая колонка hero: строка из черновика → вердикт → готовая замена.
   Тот же разбор, что даёт демо ниже, — только статичный и на один случай. */
@media (min-width: 900px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr) minmax(0, .9fr); }
}

/* Карточка и светофор — два отдельных предмета в ряд. Светофор тянется на всю высоту
   карточки (align-items по умолчанию stretch), поэтому высоту ему не задаём. */
.showcase {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px;
}

/* Сама карточка. Три состояния наложены в одну ячейку: её высота равна самому высокому
   из них, поэтому переключение не двигает ни кнопку hero, ни границу первого экрана. */
.showcase__body {
  display: grid;
  padding: 18px;
  background: var(--dark-raised);
  border: 1px solid var(--dark-border);
  border-radius: var(--radius-lg);
}
.showcase__state {
  grid-area: 1 / 1;
  display: grid;
  gap: 14px;
  align-content: start;
  opacity: 0;
  visibility: hidden;
  transition: opacity .35s ease-out;
}
.showcase__state.is-active { opacity: 1; visibility: visible; }

.showcase__block {
  padding: 15px 17px;
  background: var(--dark-sunken);
  border: 1px solid var(--dark-border);
  border-radius: var(--radius);
}

/* Моноширинный лейбл — единственное место на странице, где он несёт роль подписи к блоку. */
.showcase__label {
  margin: 0 0 9px;
  font: 500 10.5px/1 var(--mono);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--text-on-dark);
}

.showcase__text { margin: 0; font-size: 14.5px; line-height: 1.6; color: var(--text-on-dark); }
/* Замена — то, ради чего смотрят карточку: она ярче исходной строки. */
.showcase__text--bright { color: var(--text-invert); }

/* Цвет вердикта идёт от состояния. На тёмном берутся заливочные --red/--yellow/--accent,
   а не текстовые --*-text: те затемнены под белый фон и здесь дают меньше контраста.
   19px/680 — крупный текст по WCAG, порог 3:1; худшая пара (--red) даёт 4.4:1. */
.showcase__verdict {
  margin: 0;
  font: 680 19px/1.25 var(--sans);
  letter-spacing: -.01em;
}
.showcase[data-verdict="red"]    .showcase__verdict { color: var(--red); }
.showcase[data-verdict="yellow"] .showcase__verdict { color: var(--yellow); }
.showcase[data-verdict="green"]  .showcase__verdict { color: var(--accent); }

/* Светофор справа. Вертикальный и мелкий: это указатель состояния, а не орган управления —
   кликать по нему нечего, весь интерактив живёт в демо ниже. */
/* Корпус по размеру ламп, а не по высоте карточки: растянутый на всю высоту, он давал
   три мелкие точки на большом расстоянии — это читалось как индикаторы, а не как светофор.
   Пропорция примерно 1:2.6 и лампы почти во всю ширину корпуса — как у настоящего.
   Поверхность та же, что у карточки: стоя на --dark рядом с ней, он должен читаться
   предметом того же ряда. */
.showcase__light {
  align-self: center;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 16px;
  background: var(--dark-raised);
  border: 1px solid var(--dark-border);
  border-radius: var(--radius-lg);
}
/* Лампа — кнопка. Область нажатия 44px, сама лампа 38px: отрицательный margin съедает
   разницу, поэтому шаг ламп и ширина корпуса остаются прежними. */
.showcase__dot {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: -3px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
}
.showcase__lamp {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: var(--dark-border);
  transition: background-color .35s, box-shadow .35s;
}

/* Наведение подкрашивает лампу её собственным цветом вполсилы — тем же токеном ореола.
   Без этого погашенная лампа никак не показывает, что по ней вообще можно нажать. */
.showcase__dot--red:hover    .showcase__lamp { background: var(--halo-red); }
.showcase__dot--yellow:hover .showcase__lamp { background: var(--halo-yellow); }
.showcase__dot--green:hover  .showcase__lamp { background: var(--halo-green); }

.showcase[data-verdict="red"] .showcase__dot--red .showcase__lamp {
  background: var(--red);
  box-shadow: 0 0 0 7px var(--halo-red);
}
.showcase[data-verdict="yellow"] .showcase__dot--yellow .showcase__lamp {
  background: var(--yellow);
  box-shadow: 0 0 0 7px var(--halo-yellow);
}
.showcase[data-verdict="green"] .showcase__dot--green .showcase__lamp {
  background: var(--green);
  box-shadow: 0 0 0 7px var(--halo-green);
}

.showcase__note { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--text-on-dark); }

.section { padding: clamp(40px, 5vw, 64px) 0; }

/* Фоновых заливок две на всю страницу: белая и --paper.
   Paper отдан демо, финальный CTA закрывает страницу тёмным. */
.demo { background: var(--paper); border-block: 1px solid var(--border); }
.section--muted { background: var(--surface-sunken); }
.section--cta {
  text-align: center;
  padding: clamp(56px, 6vw, 84px) 0;
  background: var(--dark);
  color: var(--text-invert);
  border-block: 0;
}
.section__title { font-size: clamp(25px, 3vw, 34px); }
.section__lead { color: var(--text-soft); max-width: 66ch; font-size: 16.5px; }
.section__lead--wide { max-width: 72ch; font-size: 18px; }

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
  margin-top: 30px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 22px 24px;
}
.card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-ink);
  font-size: 17px;
}
.card__title { font-size: 17.5px; margin: 14px 0 6px; }
.card__text { color: var(--text-soft); font-size: 14.5px; margin: 0; max-width: 44ch; }

.steps {
  list-style: none;
  padding: 0;
  margin: 30px 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 20px;
}
.step {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 20px 22px 22px;
}
.step__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-ink);
  font: 650 13px/1 var(--sans);
}
.step__title { font-size: 17px; margin: 13px 0 5px; }
.step__text { color: var(--text-soft); font-size: 14.5px; margin: 0; max-width: 40ch; }

.footer {
  border-top: 1px solid var(--border);
  padding: 26px 0;
  /* Место под липкую полосу: её крестик не должен быть единственным способом дойти до Terms. */
  padding-bottom: calc(26px + var(--sticky-h));
}
.footer__inner { display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.footer__brand { font-weight: 650; margin: 0; }
.footer__links { display: flex; gap: 20px; font-size: 15px; }

/* ============================================================
   ДЕМО — главный блок страницы, весь визуальный акцент здесь
   ============================================================ */

.demo__tabs {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  width: fit-content;
  margin: 22px 0 14px;
  padding: 4px;
  background: var(--paper-deep);
  border-radius: var(--radius);
}

.demo__tab {
  font: 500 13px/1 var(--sans);
  padding: 9px 14px;
  min-height: 38px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-soft);
  cursor: pointer;
  transition: background-color .15s, color .15s;
}
.demo__tab:hover { color: var(--text); }
.demo__tab.is-active {
  background: var(--surface);
  color: var(--text);
  font-weight: 650;
  box-shadow: var(--shadow-sm);
}

.demo__window {
  display: grid;
  grid-template-columns: 1.22fr .78fr;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.demo__pane { min-width: 0; padding: 0 0 20px; }
.demo__pane--panel {
  background: var(--paper);
  border-left: 1px solid var(--border);
}

.demo__pane-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 11px 18px;
  margin-bottom: 18px;
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--border-soft);
}
.demo__pane--panel .demo__pane-head { background: var(--surface); }

.demo__pane-title {
  font: 650 12.5px/1 var(--sans);
  color: var(--text);
  letter-spacing: .01em;
}
/* Точка перед «Pre-Send Check» — это единственная декорация в блоке. */
.demo__pane-title::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 8px;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
}

/* Карточка-интро над текстом предложения: бейдж + пояснение, что это за текст. */
.demo__pane--text .demo__pane-head {
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
  margin: 18px 18px 16px;
  padding: 18px;
  background: var(--accent-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
}
.demo__pane-note {
  margin: 0;
  max-width: 56ch;
  font-size: 13.5px;
  line-height: 1.6;
  color: var(--text-soft);
}

.demo__badge {
  font-size: 10.5px;
  font-weight: 700;
  line-height: 1;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-ink);
  background: var(--accent);
  border: 0;
  border-radius: var(--radius-pill);
  padding: 7px 12px;
}

.demo__text-wrap { position: relative; overflow: hidden; padding: 0 22px; }

.demo__text {
  margin: 0;
  font: 13.5px/1.9 var(--mono);
  color: var(--text);
  white-space: pre-wrap;
  word-break: break-word;
  max-width: 68ch;
}

/* Полоса сканирования: 1.2 с сверху вниз, синхронно с config.scanDurationMs */
.demo__scanline {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 44px;
  opacity: 0;
  pointer-events: none;
  background: linear-gradient(180deg,
              transparent,
              var(--scan-soft) 55%,
              var(--scan-firm) 96%,
              transparent);
}
.demo.is-scanning .demo__scanline {
  opacity: 1;
  animation: scan 1.2s linear;
}
@keyframes scan {
  from { transform: translateY(-44px); }
  to   { transform: translateY(100%); }
}

/* --- Подсветка фрагментов. Строится в demo.js по полю match.
   Три категории отличаются не только цветом: разный стиль подчёркивания. --- */
.hl {
  border-radius: 3px;
  padding: 1px 2px;
  cursor: pointer;
}
.hl--placeholder {
  background: var(--hl-placeholder-bg);
  color: var(--hl-placeholder-text);
  border-bottom: 2px dotted var(--hl-placeholder-line);
}
.hl--ai_cliche {
  background: var(--hl-ai-bg);
  color: var(--hl-ai-text);
  border-bottom: 2px solid var(--hl-ai-line);
}
.hl--tos_risk {
  background: var(--hl-tos-bg);
  color: var(--hl-tos-text);
  border-bottom: 2px solid var(--hl-tos-line);
}
/* Применённая замена остаётся отмеченной до сброса: видно, что именно поменялось. */
.hl--fixed {
  background: var(--hl-fixed-bg);
  color: var(--hl-fixed-text);
  border-bottom: 2px solid var(--hl-fixed-line);
  cursor: default;
}
/* Анимируется только последняя замена — иначе при «Fix errors» мигает весь текст. */
.hl--fixed.is-new { animation: fix-in .5s ease-out; }

@keyframes fix-in {
  from { background: var(--hl-fixed-line); color: var(--text-invert); }
  to   { background: var(--hl-fixed-bg); color: var(--hl-fixed-text); }
}

/* Активная подсветка: обводка акцентом, а не сменой фона — текст остаётся читаемым. */
.hl.is-active {
  box-shadow: 0 0 0 2px var(--accent);
  border-radius: 4px;
}

/* --- Светофор. Светофор и подпись — одна карточка: .light верх, .light__caption низ. --- */
.light {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 18px;
  padding: 16px 16px 0;
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom: 0;
  border-radius: 14px 14px 0 0;
}
.light__dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--dot-off);
  box-shadow: inset 0 0 0 1px var(--border-firm);
  transition: background-color .2s, box-shadow .2s;
}
/* Активная точка: цвет + ореол, чтобы неактивное состояние читалось однозначно. */
.light[data-verdict="red"] .light__dot--red {
  background: var(--red);
  box-shadow: 0 0 0 4px var(--halo-red);
}
.light[data-verdict="yellow"] .light__dot--yellow {
  background: var(--yellow);
  box-shadow: 0 0 0 4px var(--halo-yellow);
}
.light[data-verdict="green"] .light__dot--green {
  background: var(--green);
  box-shadow: 0 0 0 4px var(--halo-green);
}

.light__caption {
  margin: 0 18px 14px;
  padding: 12px 16px 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-top: 0;
  border-radius: 0 0 14px 14px;
  font-size: 20px;
  font-weight: 680;
  line-height: 1.25;
  letter-spacing: -.02em;
  color: var(--text);
}
/* idle: demo.js ставит пустую строку. Заполняем через CSS, чтобы не трогать разметку. */
.light__caption:empty::before {
  content: "Not checked yet";
  color: var(--text-faint);
}

/* Тон карточки идёт от вердикта — единственное место, где сигнал заливает площадь. */
.light[data-verdict="red"],
.light[data-verdict="red"] ~ .light__caption {
  background: var(--red-tint);
  border-color: var(--red-edge);
}
.light[data-verdict="yellow"],
.light[data-verdict="yellow"] ~ .light__caption {
  background: var(--yellow-tint);
  border-color: var(--yellow-edge);
}
.light[data-verdict="green"],
.light[data-verdict="green"] ~ .light__caption {
  background: var(--green-tint);
  border-color: var(--green-edge);
}
.light[data-verdict="red"] ~ .light__caption { color: var(--red-text); }
.light[data-verdict="yellow"] ~ .light__caption { color: var(--yellow-text); }
.light[data-verdict="green"] ~ .light__caption { color: var(--green-text); }

/* Кнопки панели одной колонкой: они читаются как одна группа действий над результатом. */
.demo__actions {
  display: grid;
  gap: 8px;
  margin: 14px 18px 0;
}
.demo__actions .button { width: 100%; }
/* display у .button перебивает браузерное [hidden] — гасим явно, как у остальных скрытых блоков. */
.demo__fix-errors[hidden] { display: none; }

/* Сброс — не кнопка по весу: это выход из сценария, а не следующий шаг в нём. */
.demo__reset {
  justify-self: start;
  padding: 4px 0;
  background: none;
  border: 0;
  color: var(--text-soft);
  font: 500 13px/1.4 var(--sans);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.demo__reset:hover { color: var(--text); }

.demo__hint { font-size: 12.5px; color: var(--text-faint); margin: 12px 18px 0; }

/* --- Карточки проблем. Разметка — issueCardHtml() в demo.js. --- */
.issues {
  list-style: none;
  padding: 0;
  margin: 18px 18px 0;
  display: grid;
  gap: 8px;
}
/* Заголовок списка появляется вместе с карточками — в idle список пуст. */
.issues:not(:empty)::before {
  content: "What to fix";
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 2px;
}
/* Чинить нечего — заголовок «What to fix» над строкой «всё чисто» противоречил бы ей. */
.issues:has(.issue--clear)::before { content: none; }

.issue {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border-firm);
  border-radius: var(--radius);
  overflow: hidden;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity .2s, transform .2s;
}
.issue.is-visible { opacity: 1; transform: none; }
.issue--critical { border-left-color: var(--red); }
.issue--warning  { border-left-color: var(--yellow); }
.issue--note     { border-left-color: var(--border-firm); }

/* Исправленная карточка не исчезает: список проблем — это ещё и отчёт о том, что сделано. */
.issue.is-fixed {
  border-left-color: var(--green);
  background: var(--surface-sunken);
}
.issue.is-fixed .issue__icon    { color: var(--green-text); }
.issue.is-fixed .issue__category{ color: var(--green-text); }
.issue.is-fixed .issue__title   { color: var(--text-soft); }

/* Строка вместо списка, когда чинить больше нечего. */
.issue--clear {
  display: flex;
  align-items: baseline;
  gap: 11px;
  padding: 12px 13px;
  border-left-color: var(--green);
  font-size: 13.5px;
  color: var(--green-text);
}
.issue--clear .issue__icon { color: var(--green-text); }

.issue__head {
  display: flex;
  color: inherit;
  align-items: flex-start;
  gap: 11px;
  width: 100%;
  padding: 12px 13px;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
}
.issue__head:hover { background: var(--surface-sunken); }
.issue__head:focus-visible { outline-offset: -2px; }

.issue__icon {
  width: 20px;
  flex: none;
  text-align: center;
  font-size: 14px;
  line-height: 1.35;
  color: var(--text-soft);
}
.issue--critical .issue__icon { color: var(--red-text); }
.issue--warning  .issue__icon { color: var(--yellow-text); }

.issue__titles { flex: 1; min-width: 0; }
.issue__category {
  display: block;
  font: 700 10px/1.4 var(--sans);
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.issue__title {
  display: block;
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  margin-top: 3px;
}
.issue__chevron {
  flex: none;
  font-size: 12px;
  padding-top: 3px;
  color: var(--text-faint);
  transition: transform .15s;
}
.issue.is-open .issue__chevron { transform: rotate(180deg); }

.issue__body { padding: 0 14px 14px 44px; }
.issue__detail { font-size: 13px; color: var(--text-soft); margin: 0 0 9px; max-width: 60ch; }

/* Fix — единственное место, где акцент появляется внутри карточки проблемы.
   Кант и метка тёмные, а не зелёные: --accent как текст на светлом даёт 2.3:1. */
.issue__fix {
  font-size: 13px;
  margin: 0;
  background: var(--accent-soft);
  border-left: 2px solid var(--text);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 9px 11px;
  max-width: 60ch;
}
.issue__fix-label {
  display: block;
  font: 700 10.5px/1 var(--sans);
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--text);
  margin-bottom: 4px;
}
.issue__fix-text { margin: 0; }

/* Кнопка исправления — внутри блока Fix: действие стоит там же, где написано, что оно сделает. */
.issue__fix-btn {
  margin-top: 10px;
  padding: 8px 12px;
  min-height: 34px;
  background: var(--accent);
  color: var(--accent-ink);
  border: 1px solid var(--accent);
  border-radius: var(--radius-sm);
  font: 650 12.5px/1 var(--sans);
  cursor: pointer;
  transition: background-color .15s, color .15s, border-color .15s;
}
.issue__fix-btn:hover:not(:disabled) {
  background: var(--accent-dark);
  border-color: var(--accent-dark);
}
/* Применённое — не выключенная кнопка, а отметка о результате: зелёная, читаемая. */
.issue__fix-btn:disabled {
  background: transparent;
  color: var(--green-text);
  border-color: var(--green);
  cursor: default;
}

/* Блок без кнопки: акцент убран, потому что действия здесь нет — есть работа для автора. */
.issue__fix--manual {
  background: var(--paper);
  border-left-color: var(--border-firm);
}
.issue__fix--manual .issue__fix-label { color: var(--text-soft); }

.issue__fix-manual {
  display: flex;
  gap: 7px;
  margin: 9px 0 0;
  padding-top: 9px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
  color: var(--text-soft);
}
.issue__fix-manual-icon { flex: none; }

/* ============================================================
   МОДАЛКА
   ============================================================ */

.modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  place-items: center;
  padding: 20px;
  overflow-y: auto;
}
.modal[hidden] { display: none; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(17, 24, 39, .58); }

.modal__dialog {
  position: relative;
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 26px;
  box-shadow: var(--shadow-modal);
}

.modal__close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 30px;
  height: 30px;
  font-size: 17px;
  line-height: 1;
  background: var(--paper);
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-soft);
  cursor: pointer;
}
.modal__close:hover { background: var(--paper-deep); color: var(--text); }

.modal__title { font-size: 21px; max-width: 20ch; margin-bottom: .4em; }
.modal__text { color: var(--text-soft); font-size: 14px; margin-bottom: 18px; }

.lead__label {
  display: block;
  font: 650 11.5px/1 var(--sans);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-soft);
  margin-bottom: 7px;
}
.lead__input {
  width: 100%;
  font: 15px/1.2 var(--sans);
  color: var(--text);
  padding: 12px 13px;
  min-height: 46px;
  background: var(--surface);
  border: 1px solid var(--border-firm);
  border-radius: var(--radius);
  margin-bottom: 12px;
}
.lead__input::placeholder { color: var(--text-faint); }
.lead__input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--focus);
}
.lead__input[aria-invalid="true"] {
  border-color: var(--red);
  box-shadow: 0 0 0 3px var(--tint-red);
}

/* Ошибка живёт под полем; иконка на случай, если цвет не различается. */
.lead__error {
  display: flex;
  gap: 7px;
  color: var(--red-text);
  font-size: 12.5px;
  line-height: 1.5;
  margin: -6px 0 12px;
}
.lead__error[hidden] { display: none; }
.lead__error::before { content: "⚠"; flex: none; }

.lead__legal { font-size: 11.5px; color: var(--text-faint); margin: 12px 0 0; line-height: 1.55; }

.price__amount {
  font: 680 44px/1 var(--sans);
  letter-spacing: -.035em;
  margin: 14px 0 12px;
}
.price__period { font-size: 15px; font-weight: 500; color: var(--text-soft); letter-spacing: 0; }
.price__done {
  display: flex;
  gap: 9px;
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--text);
  line-height: 1.55;
}
.price__done[hidden] { display: none; }
.price__done::before {
  content: "✓";
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 19px;
  height: 19px;
  border-radius: 50%;
  background: var(--green);
  color: var(--accent-ink);
  font-size: 11px;
}

/* ============================================================
   COOKIE-БАННЕР — тёмный, чтобы не конкурировать с демо
   ============================================================ */

.cookie {
  position: fixed;
  bottom: 16px;
  left: 16px;
  right: 16px;
  z-index: 55;
  max-width: 620px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  padding: 14px 16px;
  background: var(--dark);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-modal);
}
.cookie[hidden] { display: none; }
.cookie__text {
  flex: 1;
  min-width: 220px;
  font-size: 13.5px;
  line-height: 1.55;
  margin: 0;
  color: var(--paper);
}
.cookie__text a { color: var(--accent-dim); }
.cookie .button--primary { color: var(--accent-ink); }
.cookie__actions { display: flex; gap: 8px; }
.cookie .button { padding: 9px 14px; font-size: 13px; min-height: 38px; }
.cookie .button--ghost {
  background: transparent;
  color: var(--paper-deep);
  border-color: rgba(255, 255, 255, .22);
}
.cookie .button--ghost:hover { background: rgba(255, 255, 255, .08); color: var(--surface); }

/* ============================================================
   ЛИПКАЯ ПОЛОСА (раздел 10 брифа)

   Разметка вставлена в index.html перед </body>, логика — assets/js/sticky.js.

   Классы состояний, которые переключает JS:
     .sticky.is-visible  — всплыла (после 40% скролла, если решение по cookie принято)
     .sticky.is-sent     — успех: остаётся одна строка «спасибо»
   ============================================================ */

.sticky {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 45;
  background: var(--surface);
  border-top: 1px solid var(--border);
  box-shadow: var(--shadow-up);
  transform: translateY(100%);
  transition: transform .28s ease-out;
}
.sticky[hidden] { display: none; }
.sticky.is-visible { transform: none; }

.sticky__inner {
  position: relative;
  display: flex;
  align-items: center;
  gap: 20px;
  flex-wrap: wrap;
  padding-block: 14px;
}
.sticky__copy { flex: 1; min-width: 220px; }
.sticky__title { font: 650 14.5px/1.3 var(--sans); margin: 0; }
.sticky__note { font-size: 12.5px; color: var(--text-faint); margin: 3px 0 0; }

.sticky__form { display: flex; gap: 8px; flex: 0 1 420px; }
.sticky__input {
  flex: 1;
  min-width: 0;
  font: 14px/1.2 var(--sans);
  color: var(--text);
  padding: 11px 13px;
  min-height: 44px;
  background: var(--surface-sunken);
  border: 1px solid var(--border-firm);
  border-radius: var(--radius);
}
.sticky__input::placeholder { color: var(--text-faint); }
.sticky__input:focus { outline: none; border-color: var(--accent); box-shadow: var(--focus); }
.sticky__input[aria-invalid="true"] { border-color: var(--red); }

.sticky__error {
  flex: 1 0 100%;
  order: 3;
  display: flex;
  gap: 7px;
  font-size: 12.5px;
  color: var(--red-text);
  margin: 0;
}
.sticky__error[hidden] { display: none; }
.sticky__error::before { content: "⚠"; flex: none; }

/* Крестик — обычный элемент строки: абсолютный ложился поверх кнопки отправки. */
.sticky__close {
  flex: none;
  align-self: center;
  width: 28px;
  height: 28px;
  font-size: 15px;
  line-height: 1;
  background: none;
  border: 0;
  color: var(--text-faint);
  cursor: pointer;
}
.sticky__close:hover { color: var(--text); }

/* Успех: полоса сжимается в одну строку, форма и подпись уходят. */
.sticky.is-sent .sticky__form,
.sticky.is-sent .sticky__note { display: none; }
.sticky.is-sent .sticky__title::before {
  content: "✓ ";
  color: var(--green-text);
}

/* ============================================================
   ДЛИННЫЙ ТЕКСТ — privacy.html / terms.html
   ============================================================ */

.legal { padding-top: clamp(28px, 4vw, 44px); }
.legal h1 { font-size: clamp(28px, 3.4vw, 38px); margin-bottom: .4em; }
.legal h2 {
  font-size: 19px;
  margin: 2em 0 .5em;
  padding-top: 1.1em;
  border-top: 1px solid var(--border);
}
.legal p, .legal li { font-size: 15.5px; color: var(--text-soft); max-width: 70ch; }
.legal ul { padding-left: 20px; margin: 0 0 1em; }
.legal li { margin-bottom: .4em; }
.legal strong { color: var(--text); }

/* ============================================================
   АДАПТИВ — две колонки не помещаются ниже 900px
   ============================================================ */

@media (max-width: 899px) {
  /* Показ продукта уходит: на узком экране он вытолкнул бы верх демо за фолд,
     а демо обязано попадать на первый экран (BUSINESS-LOGIC.md §3). Тот же разбор
     доступен ниже в самом демо, поэтому ничего уникального не теряется. */
  .showcase { display: none; }

  .demo__window { grid-template-columns: 1fr; }
  .demo__pane--panel { border-left: 0; border-top: 1px solid var(--border); }
  .demo__text-wrap { max-height: 44vh; overflow-y: auto; }
  .demo__tabs { width: 100%; }
  .demo__tab { flex: 1; text-align: center; padding-inline: 8px; }

  /* Демо скроллит к подписи под светофором: она не должна попадать под полосу. */
  .demo__pane--panel { scroll-padding-bottom: var(--sticky-h); }
}

@media (max-width: 599px) {
  :root { --sticky-h: 132px; }

  .container { padding: 0 16px; }
  .hero__title { font-size: clamp(30px, 8vw, 38px); }
  .modal { padding: 12px; align-items: start; }
  .modal__dialog { padding: 22px 20px; }
  .price__amount { font-size: 38px; }
  .light__caption { font-size: 18px; }

  .cookie { left: 10px; right: 10px; bottom: 10px; padding: 13px 14px; }
  .cookie__actions { width: 100%; }
  .cookie .button { flex: 1; }

  /* Мобильная полоса: подпись скрыта, поле и кнопка на всю ширину.
     Крестик здесь снова абсолютный — в потоке он занял бы отдельную строку,
     а место под него уже зарезервировано отступом .sticky__copy. */
  .sticky__inner { gap: 10px; padding-block: 12px 14px; }
  .sticky__note { display: none; }
  .sticky__copy { flex: 1 0 100%; padding-right: 30px; }
  .sticky__close { position: absolute; top: 10px; right: 0; }
  .sticky__form { flex: 1 0 100%; flex-wrap: wrap; }
  .sticky__input { flex: 1 0 100%; }
  .sticky__form .button { width: 100%; }
}

/* ============================================================
   REDUCED MOTION
   Убираются полоса и стаггер. Пауза 1.2 с живёт в JS и остаётся.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  .demo.is-scanning .demo__scanline { opacity: 0; }
  .issue { opacity: 1; transform: none; }
  .sticky { transform: none; }
}
