/* ═══════════════════════════════════════════════════════════════════════════
   «ВЬЕТНАМ НАВИГАТОР» — ДИЗАЙН-СИСТЕМА
   ═══════════════════════════════════════════════════════════════════════════

   ИДЕЯ. Сайт — справочник, и выглядит он как хорошо набранный печатный путеводитель:
   сильная типографика, волосяные линейки вместо теней, нумерованный указатель,
   крупные табличные цифры как графика. Не «лендинг с карточками».

   ЧЕГО ЗДЕСЬ НЕТ И ПОЧЕМУ. Первая версия этого файла была написана по инерции и
   содержала полный набор признаков шаблонной вёрстки: размытые градиентные пятна в
   герое, логотип-квадрат с диагональным градиентом, `fade-in` на каждом блоке, эмодзи
   вместо иконок. Всё это выброшено осознанно — по таким деталям типовую генерацию
   отличают от осмысленной работы, и tools/inspect_site.py теперь ловит их автоматически.
     · нет декоративных градиентов — цвет работает функцией, а не украшением;
     · нет теней в роли границ — разделяют линейки в 1px, как в книге;
     · нет эмодзи в интерфейсе — только SVG (эмодзи рисуются по-разному в каждой ОС
       и читаются скринридером вслух: «дерево пальма» посреди заголовка);
     · анимация только там, где отвечает на действие человека: наведение и фокус.

   ЦВЕТ. Один акцент — глубокий красный. Он наследует фирменный красный сети (#fe3059),
   но приглушён до печатного: на белом даёт контраст 5.9:1, то есть проходит WCAG AA
   как обычный текст, а не только как крупный. Второго акцента нет намеренно: два
   акцента — это отсутствие акцента.

   ШРИФТЫ. Unbounded (заголовки) и Golos Text (текст), оба под SIL Open Font License,
   лежат у нас на сервере. Circe из панели убран: он коммерческий (ParaType), и
   самохостинг без веб-лицензии — прямое нарушение.
   ═══════════════════════════════════════════════════════════════════════════ */

/* fonts.css подключается ОТДЕЛЬНЫМ <link> в разметке, а не через @import.
   @import внутри CSS браузер обрабатывает последовательно: он узнаёт о втором файле
   только разобрав первый, и это лишний круг до отрисовки текста. Два <link> рядом
   грузятся параллельно. */

:root{
  /* ── ЦВЕТ. Имена по роли, а не по оттенку: --accent можно перекрасить, не переименовывая. */
  --bg:#ffffff;
  --paper:#faf9f6;          /* тёплая подложка секций */
  --card:#ffffff;
  --ink:#1a1a17;            /* заголовки и основной текст */
  --ink2:#45443d;           /* текст статей */
  --muted:#6b6a61;          /* подписи, метаданные */
  /* Приглушённый второй уровень: номера в указателе, разделители. Раньше на него
     ссылались как на var(--muted2,#9aa1bb) — переменной не было, и цвет брался из
     запасного значения СТАРОЙ палитры: контраст 2.44:1 при норме 4.5. Инспектор
     отрисовки это поймал, разметочный не мог — в CSS всё выглядело корректно. */
  --muted2:#727166;        /* 4.92:1 на белом, 4.67:1 на бумаге — обе выше AA */
  --rule:#e4e1d9;           /* волосяная линейка */
  --rule-strong:#c9c5b8;
  --accent:#c8102e;
  --accent-ink:#a30d26;
  --accent-wash:#fdf2f3;    /* заливка под акцентом, очень светлая */
  --ok:#1f7a3d;
  /* ── ПОДВАЛ. Отдельные токены, и это не прихоть. Раньше он заливался var(--ink) —
     токеном цвета ТЕКСТА. В тёмной теме --ink переворачивается в светлый, подвал
     становился светлым, а текст в нём остался жёстко заданным светло-серым: белым
     по белому. Токен, названный по роли «чернила», нельзя использовать как фон —
     у роли есть смысл, и он меняется вместе с темой. */
  --ftr-bg:#1a1a17;
  --ftr-fg:#cfccc3;
  --ftr-dim:#8a877e;
  --ftr-line:rgba(255,255,255,.14);

  /* ── РАЗМЕРЫ. Радиусы намеренно разные по роли: у карточки крупнее, у плашки почти
        нет. Одинаковый радиус на всём — примета плоского шаблона. */
  --r-card:4px;
  --r-pill:2px;
  --r-btn:3px;
  --wrap:1180px;
  --read:66ch;
  --ease:cubic-bezier(.2,.6,.35,1);
}

/* ── ОДНА ГАММА НА ВСЕ УСТРОЙСТВА ────────────────────────────────────────────
   Тёмной темы у сайта нет, и это решение, а не упущение.

   ПОЧЕМУ. Дизайн построен на метафоре печатного путеводителя: тёплая бумага,
   волосяные линейки, один печатный красный. В тёмном исполнении метафора
   рассыпается — получается просто другой сайт. Плюс вторая тема удваивает
   поверхность для ошибок, и мы это уже проверили на себе: подвал заливался
   токеном var(--ink), в тёмной теме он переворачивался в светлый, и текст
   становился белым по белому. Баг нашёл человек, а не инспектор.

   `color-scheme: light` обязателен. Без него браузер на устройстве с тёмной
   системной темой сам перекрашивает то, что рисует он: полосы прокрутки, поля
   ввода, подложку под страницей. Получилась бы светлая вёрстка в тёмной оправе.
   Инспектор проверяет страницы и в тёмном контексте — и требует, чтобы результат
   был ТАКИМ ЖЕ, как в светлом. */
:root{color-scheme:light}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--bg);color:var(--ink);
  font:400 17px/1.65 "Golos Text",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;
  font-feature-settings:"liga" 1,"kern" 1;
  -webkit-font-smoothing:antialiased;
  display:flex;flex-direction:column;min-height:100vh;
}
img,svg{max-width:100%;display:block}

/* Все цифры — табличные. В списке чатов и в полосе статистики числа стоят друг под
   другом, и пропорциональные цифры делают колонку рваной. */
.num,.stat-n,.count{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* ── ФОКУС И КЛАВИАТУРА ──────────────────────────────────────────────────── */
.skip{position:absolute;left:-9999px;top:0;z-index:100;background:var(--accent);
  color:#fff;padding:14px 22px;font-weight:600}
.skip:focus{left:0}
a:focus-visible,button:focus-visible,summary:focus-visible,details:focus-visible{
  outline:2px solid var(--accent);outline-offset:3px}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px;width:100%}

/* ── ТИПОГРАФИКА ─────────────────────────────────────────────────────────── */
h1,h2,h3,h4{font-family:Unbounded,Impact,sans-serif;font-weight:800;color:var(--ink);
  margin:0;line-height:1.1;letter-spacing:-.035em}
h1{font-size:clamp(32px,5.6vw,60px)}
h2{font-size:clamp(23px,3.2vw,34px);letter-spacing:-.03em}
h3{font-size:clamp(17px,2vw,20px);letter-spacing:-.02em}
p{margin:0 0 1.05em}
a{color:var(--accent);text-decoration:none}
a:hover{color:var(--accent-ink)}
.lead{font-size:clamp(17px,1.9vw,20px);line-height:1.6;color:var(--ink2)}
.muted{color:var(--muted)}
.small{font-size:14.5px;line-height:1.55}

/* Надзаголовок секции: капитель с линейкой на всю ширину — приём книжного указателя. */
.eyebrow{display:flex;align-items:center;gap:14px;margin:0 0 22px;
  font-family:"Golos Text",sans-serif;font-weight:600;font-size:12px;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.eyebrow::after{content:"";flex:1;height:1px;background:var(--rule)}

/* ── ШАПКА ───────────────────────────────────────────────────────────────── */
.hdr{position:sticky;top:0;z-index:50;background:var(--bg);border-bottom:1px solid var(--rule)}
/* На телефоне шапка НЕ липкая. Причина простая: 64px — это заметная доля экрана
   высотой 740px, и она висит перед глазами всё время чтения, ничего при этом не
   давая: разделов пять, и все они есть в подвале. На десктопе места достаточно,
   там липкость полезна. */
@media(max-width:760px){.hdr{position:static}}
.hdr .wrap{display:flex;align-items:center;gap:28px;height:64px}
/* Логотип — словесный знак, а не квадрат с градиентом. Точка акцентом вместо иконки:
   мелкая деталь, которая читается как типографский знак, а не как «иконка приложения». */
.logo{font-family:Unbounded,sans-serif;font-weight:800;font-size:17px;color:var(--ink);
  letter-spacing:-.04em;white-space:nowrap}
.logo:hover{color:var(--ink)}
.logo i{color:var(--accent);font-style:normal}
.hdr nav{display:flex;gap:26px;margin-left:auto;align-items:center}
.hdr nav a{color:var(--ink2);font-weight:500;font-size:15.5px;
  padding:4px 0;border-bottom:2px solid transparent;transition:border-color .18s var(--ease)}
.hdr nav a:hover{color:var(--ink);border-bottom-color:var(--accent)}
.hdr nav a[aria-current]{color:var(--ink);border-bottom-color:var(--accent)}
/* Телефон: в шапке остаются только «Гиды» и «Все чаты». Семь пунктов в 390px не
   помещаются, и раньше список просто обрезался на «Нячанг Дан…» — выглядело как
   сломанная вёрстка, а горизонтальная прокрутка внутри шапки неочевидна. Города
   никуда не делись: они на главной первым же блоком и в подвале целиком. */
@media(max-width:860px){
  .hdr nav{gap:18px;font-size:15px}
  .hdr nav a[data-city]{display:none}
}
/* Узкий экран: шапка в две строки. Логотип и три пункта меню в 360px в одну
   строку не помещаются — документ становился шире экрана на 79px, и появлялась
   горизонтальная прокрутка на КАЖДОЙ странице. Прятать пункты дальше нельзя,
   их и так осталось три; значит переносим. */
@media(max-width:560px){
  .hdr .wrap{flex-wrap:wrap;height:auto;gap:0;padding-block:10px}
  .hdr .logo{font-size:16px}
  .hdr nav{margin-left:0;width:100%;justify-content:space-between;
    gap:10px;padding-top:8px;font-size:14.5px}
}

/* ── КНОПКИ ──────────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;
  font-family:"Golos Text",sans-serif;font-weight:600;font-size:16px;line-height:1;
  padding:15px 26px;border-radius:var(--r-btn);border:1px solid transparent;cursor:pointer;
  transition:background-color .18s var(--ease),color .18s var(--ease),
             border-color .18s var(--ease)}
.btn-primary{background:var(--accent);color:#fff;border-color:var(--accent)}
.btn-primary:hover{background:var(--accent-ink);border-color:var(--accent-ink);color:#fff}
.btn-ghost{background:transparent;color:var(--ink);border-color:var(--rule-strong)}
.btn-ghost:hover{border-color:var(--ink);color:var(--ink)}
.btn svg{width:17px;height:17px;flex-shrink:0}

/* ── ГЕРОЙ ───────────────────────────────────────────────────────────────── */
/* Никакой заливки и никаких пятен: разворот книги. Заголовок прижат влево, справа —
   колонка цифр. Асимметрия здесь работает лучше центровки: глаз входит в текст. */
.hero{padding:clamp(48px,7vw,88px) 0 clamp(34px,4vw,52px);border-bottom:1px solid var(--rule)}
.hero-grid{display:grid;gap:clamp(28px,4vw,56px);grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  align-items:end}
@media(max-width:900px){.hero-grid{grid-template-columns:1fr;align-items:start}}
.hero h1{max-width:15ch}
.hero .lead{margin:22px 0 0;max-width:52ch}
.hero .cta{display:flex;flex-wrap:wrap;gap:12px;margin-top:30px}
.kicker{display:inline-flex;align-items:center;gap:9px;margin-bottom:20px;
  font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--muted)}
.kicker .live{width:7px;height:7px;border-radius:50%;background:var(--ok);flex-shrink:0}

/* Колонка цифр. Крупные табличные числа с линейками — единственная «графика» на
   первом экране, и она не декоративная: это настоящие данные о сети. */
.figures{display:grid;gap:0;border-top:1px solid var(--ink)}
.figure{display:flex;align-items:baseline;justify-content:space-between;gap:16px;
  padding:14px 0;border-bottom:1px solid var(--rule)}
.figure .stat-n{font-family:Unbounded,sans-serif;font-weight:800;
  font-size:clamp(26px,3.6vw,36px);letter-spacing:-.045em;color:var(--ink);line-height:1}
.figure .stat-l{font-size:14px;color:var(--muted);text-align:right;max-width:15ch;line-height:1.35}

/* ── СЕКЦИИ ──────────────────────────────────────────────────────────────── */
.sec{padding:clamp(48px,6.5vw,80px) 0}
.sec-paper{background:var(--paper);border-block:1px solid var(--rule)}
.sec-head{max-width:58ch;margin-bottom:34px}
.sec-head h2+p{margin-top:14px;color:var(--ink2)}

/* ── УКАЗАТЕЛЬ ГОРОДОВ ───────────────────────────────────────────────────── */
/* Нумерованный указатель. На узком экране строка СВЁРНУТА: видно номер, город и
   цифры, описание с перечнем тем раскрывается нажатием. На широком раскрыто всегда.

   ПОЧЕМУ ТАК. Пять городов с описаниями и списками тем занимали на телефоне почти
   три экрана прокрутки — ради выбора из пяти пунктов. Человек не читает пять
   абзацев, чтобы ткнуть в свой город: ему нужен список, а подробности по запросу.
   На десктопе места достаточно, и там прятать нечего — поэтому раскрытие принудительно
   включено медиазапросом, а не атрибутом open: атрибут не умеет зависеть от ширины.

   ПОЧЕМУ КНОПКА ВНЕ <summary>. Интерактивный элемент внутри summary — спорная
   разметка: нажатие на него одновременно сворачивает блок, а скринридеры читают
   такую конструкцию по-разному. Кнопка вынесена соседом по флексу. */
.index{border-top:1px solid var(--ink)}
.city-row{display:flex;align-items:flex-start;gap:clamp(12px,2vw,24px);
  padding:clamp(14px,2vw,20px) 0;border-bottom:1px solid var(--rule);position:relative}
.city-row::before{content:"";position:absolute;left:-14px;top:0;bottom:-1px;width:3px;
  background:var(--accent);transform:scaleY(0);transform-origin:top;
  transition:transform .22s var(--ease)}
.city-row:hover::before{transform:scaleY(1)}
.city{flex:1;min-width:0}
.city>summary{cursor:pointer;list-style:none;display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;align-items:baseline;
  gap:clamp(10px,2vw,18px);padding:6px 0;min-height:24px;user-select:none}
.city>summary::-webkit-details-marker{display:none}
.city .no{font-family:Unbounded,sans-serif;font-weight:800;font-size:13px;
  color:var(--muted2);font-variant-numeric:tabular-nums}
.city .nm{font-family:Unbounded,sans-serif;font-weight:800;
  font-size:clamp(20px,3vw,30px);letter-spacing:-.035em;color:var(--ink);line-height:1.1}
.city-row:hover .nm{color:var(--accent)}
.city .cnt{font-size:14px;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums;justify-self:end}
/* Стрелка-указатель. Только там, где блок действительно сворачивается. */
.city .chev{width:9px;height:9px;border-right:2px solid var(--muted2);
  border-bottom:2px solid var(--muted2);transform:rotate(45deg) translateY(-3px);
  transition:transform .2s var(--ease);flex-shrink:0;justify-self:end}
.city[open] .chev{transform:rotate(225deg) translateY(-1px)}
.city-body{padding:10px 0 4px}
.city-body p{color:var(--muted);font-size:15.5px;margin:0;max-width:56ch}
/* Компактный список чатов города внутри раскрытой строки.
   ПОЧЕМУ НЕ ОДНА КНОПКА НА ГОРОД. Раньше в строке стояла единственная кнопка
   «Вступить», ведущая в общий чат, а остальные четыре были тонкой строкой ссылок.
   Это и непонятно (в какой именно чат я вступаю?), и несправедливо: чат
   недвижимости Нячанга вдвое крупнее общего. Теперь все чаты города равноправны,
   у каждого свой счётчик и своя кнопка — но показываются они только по раскрытию,
   а не вываливаются на страницу все четырнадцать сразу. */
.mini{display:grid;gap:0;margin-top:14px;border-top:1px solid var(--rule)}
.mini-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;
  gap:12px;align-items:center;padding:9px 0;border-bottom:1px solid var(--rule)}
.mini-row:last-child{border-bottom:0}
.mini-row .t{font-weight:600;font-size:15.5px;color:var(--ink);
  display:inline-flex;align-items:center;min-height:24px}
.mini-row .t:hover{color:var(--accent)}
.mini-row .c{font-size:13.5px;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums}
.mini-row .join{display:inline-flex;align-items:center;gap:6px;font-weight:600;
  font-size:13.5px;line-height:1;padding:7px 12px;border-radius:var(--r-btn);
  border:1px solid var(--rule-strong);color:var(--ink);white-space:nowrap;min-height:24px;
  transition:background-color .18s var(--ease),color .18s var(--ease),
             border-color .18s var(--ease)}
.mini-row .join:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.mini-row .join svg{width:13px;height:13px;flex-shrink:0}
.city-more{display:inline-flex;align-items:center;min-height:24px;margin-top:12px;
  font-size:14.5px}
@media(max-width:430px){
  .mini-row{grid-template-columns:minmax(0,1fr) auto;grid-template-rows:auto auto;
    row-gap:1px;column-gap:10px;padding:8px 0}
  .mini-row .t{grid-column:1;grid-row:1}
  .mini-row .c{grid-column:1;grid-row:2;font-size:13px}
  .mini-row .join{grid-column:2;grid-row:1/3;align-self:center}
}

/* Широкий экран: прятать нечего, раскрываем всё и убираем стрелку. */
@media(min-width:900px){
  .city>*:not(summary){display:block}
  .city .chev{display:none}
  .city>summary{cursor:default}
}
/* Узкий экран: счётчик уходит под название, чтобы не жать заголовок. */
@media(max-width:520px){
  .city>summary{grid-template-columns:auto minmax(0,1fr) auto;row-gap:2px}
  .city .cnt{grid-column:2;justify-self:start;font-size:13px}
}

/* ── ПРОСТОЙ НУМЕРОВАННЫЙ РЯД ────────────────────────────────────────────── */
/* Общая строка указателя без раскрытия: «Три шага» на главной, список гидов,
   перечень городов на странице 404. Отдельно от .city-row намеренно — у той своя
   механика с <details>, и смешивать их значит чинить одно, ломая другое.
   ⚠️ Эти стили однажды уже пропали: при переписывании указателя городов блок
   удалился целиком, а три шаблона продолжали ссылаться на класс — страницы
   молча остались без вёрстки. Поймал инспектор отрисовки, замерив у ссылок
   высоту 21px вместо положенных 24. */
.index-row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;
  gap:clamp(14px,2.4vw,32px);align-items:start;padding:clamp(18px,2.4vw,26px) 0;
  border-bottom:1px solid var(--rule);position:relative}
.index-row::before{content:"";position:absolute;left:-14px;top:0;bottom:-1px;width:3px;
  background:var(--accent);transform:scaleY(0);transform-origin:top;
  transition:transform .22s var(--ease)}
.index-row:hover::before{transform:scaleY(1)}
.index-row .no{font-family:Unbounded,sans-serif;font-weight:800;font-size:13px;
  color:var(--muted2);font-variant-numeric:tabular-nums;padding-top:5px}
.index-row h3{font-size:clamp(18px,2.4vw,24px);margin-bottom:7px}
.index-row h3 a{color:var(--ink);display:inline-flex;align-items:center;min-height:24px}
.index-row h3 a:hover{color:var(--accent)}
.index-row p{color:var(--muted);font-size:15.5px;margin:0;max-width:60ch}
.index-row .meta{text-align:right;white-space:nowrap;font-size:14px;color:var(--muted);
  font-variant-numeric:tabular-nums;padding-top:4px}
.index-row .meta b{font-family:Unbounded,sans-serif;font-weight:800;font-size:18px;
  color:var(--ink);letter-spacing:-.03em;display:block}
@media(max-width:640px){
  .index-row{grid-template-columns:auto minmax(0,1fr);row-gap:8px}
  .index-row .meta{grid-column:2;text-align:left;padding-top:0}
  .index-row .meta b{display:inline;font-size:15px;margin-right:6px}
}

/* ── СПИСОК ЧАТОВ ────────────────────────────────────────────────────────── */
/* У строки ДВЕ разные цели, и это главное в её устройстве. Вся строка ведёт на
   страницу чата (там правила, примеры сообщений, соседние чаты), а отдельная
   кнопка справа — сразу в Telegram.

   ЗАЧЕМ ТАК. Человек, пришедший по запросу «чат Нячанга», хочет вступить, а не
   читать о чате: раньше до кнопки было три клика, и это ровно та лишняя работа,
   на которой люди уходят обратно в выдачу. Теперь вступление — один клик с любого
   списка на сайте. При этом внутренние страницы не обесценились: по ним по-прежнему
   ходят и люди, и робот, им нужен вес ссылок.

   ПОЧЕМУ НЕ ССЫЛКА ВНУТРИ ССЫЛКИ. Вложенные <a> — невалидная разметка, браузеры
   раскрывают их непредсказуемо, а клавиатура и скринридер получают кашу. Поэтому
   строка — это div, кликабельную область даёт псевдоэлемент у заголовка, а кнопка
   поднята над ним z-index'ом. Инспектор проверяет отсутствие вложенных ссылок. */
.chats{display:grid;gap:0;border-top:1px solid var(--rule)}
.chat{display:grid;grid-template-columns:20px minmax(0,1fr) auto auto;gap:16px;
  align-items:center;padding:14px 12px 14px 0;border-bottom:1px solid var(--rule);
  position:relative;transition:background-color .18s var(--ease)}
.chat:hover{background:var(--accent-wash)}
.chat .ico{width:20px;height:20px;color:var(--muted2);flex-shrink:0;opacity:.75}
.chat:hover .ico{color:var(--accent)}
.chat .name{font-weight:600;font-size:16.5px;color:var(--ink);display:block}
/* Растянутая ссылка: заголовок накрывает всю строку, кроме того, что поднято выше. */
.chat .name::after{content:"";position:absolute;inset:0}
.chat:hover .name{color:var(--accent)}
.chat .desc{font-size:14.5px;color:var(--muted);margin-top:2px;line-height:1.45}
.chat .side{text-align:right;font-size:14px;color:var(--muted);white-space:nowrap;
  font-variant-numeric:tabular-nums}
/* Кнопка вступления. z-index поднимает её над растянутой ссылкой заголовка —
   без этого клик по кнопке уходил бы на страницу чата вместо Telegram. */
.chat .join{position:relative;z-index:1;display:inline-flex;align-items:center;gap:7px;
  font-weight:600;font-size:14.5px;line-height:1;white-space:nowrap;
  padding:10px 15px;border-radius:var(--r-btn);
  border:1px solid var(--rule-strong);color:var(--ink);background:var(--bg);
  transition:background-color .18s var(--ease),color .18s var(--ease),
             border-color .18s var(--ease)}
.chat .join:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.chat .join svg{width:15px;height:15px;flex-shrink:0}
/* Телефон: строка чата в ДВЕ короткие строки с кнопкой справа, а не в две строки
   с кнопкой под ними. Раньше пять чатов города занимали пол-экрана пустотой:
   кнопка каждый раз уезжала на отдельную строку. Теперь иконка и кнопка тянутся
   на обе строки, между ними название и счётчик — высота падает примерно на треть. */
@media(max-width:760px){
  .chat{grid-template-columns:20px minmax(0,1fr) auto;grid-template-rows:auto auto;
    row-gap:1px;column-gap:12px;padding:11px 0}
  .chat .ico{grid-row:1/3;align-self:center}
  .chat .body{grid-column:2;grid-row:1;min-width:0}
  .chat .desc{display:none}
  .chat .side{grid-column:2;grid-row:2;text-align:left;font-size:13px}
  .chat .join{grid-column:3;grid-row:1/3;align-self:center;padding:9px 13px}
}

/* ── ЗАМЕТКИ: КАРТОЧКИ И ЛЕНТА ───────────────────────────────────────────── */
/* Сетка карточек, а не список строк: у заметок есть иллюстрации, и картинка —
   главный способ выбрать глазами. Тот же язык, что везде: волосяные линейки
   вместо теней, акцент только при наведении.

   ⚠️ У каждой картинки в разметке ЖЁСТКО заданы width и height, а здесь
   aspect-ratio. Без этого браузер не знает место под изображение до загрузки,
   и вёрстка прыгает — это ровно то, что измеряет CLS в Core Web Vitals.
   Все иллюстрации квадратные 1:1, поэтому соотношение одно на всех. */
.ngrid{display:grid;gap:clamp(18px,2.4vw,28px);
  grid-template-columns:repeat(auto-fill,minmax(260px,1fr))}
.ncard{display:flex;flex-direction:column;min-width:0;color:var(--ink)}
.ncard .nbody{display:flex;flex-direction:column;min-width:0}
.ncard .pic{width:100%;aspect-ratio:1;overflow:hidden;background:var(--paper);
  border:1px solid var(--rule);border-radius:var(--r-card);margin-bottom:12px}
.ncard img{width:100%;height:100%;object-fit:cover;
  transition:transform .5s var(--ease)}
/* Заглушка вместо отсутствующей иллюстрации: тот же размер, чтобы ряд не ехал,
   и название темы вместо пустоты. */
.ncard .pic.empty{display:grid;place-items:center;background:var(--paper);
  padding:10px;text-align:center}
.ncard .pic.empty span{font-family:Unbounded,sans-serif;font-weight:800;
  font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted2);
  line-height:1.25}
.ncard:hover .pic.empty span{color:var(--accent)}
.ncard:hover img{transform:scale(1.03)}
.ncard .nmeta{font-size:12.5px;color:var(--muted);letter-spacing:.02em;
  text-transform:uppercase;font-weight:600;margin-bottom:6px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.ncard .nmeta .d{font-variant-numeric:tabular-nums}
.ncard .ntitle{font-weight:600;font-size:16.5px;line-height:1.35;color:var(--ink);
  margin-bottom:6px}
.ncard:hover .ntitle{color:var(--accent)}
/* overflow-wrap обязателен: в выжимках попадаются длинные неразрывные куски —
   адреса, названия вроде «ConCung», склейки с двоеточиями, — и без переноса они
   вылезают за колонку карточки. Инспектор ловит это как обрезку текста. */
.ncard .nexc{font-size:14.5px;line-height:1.5;color:var(--muted);
  overflow-wrap:anywhere}
.ncard .ntitle{overflow-wrap:anywhere}
@media(max-width:520px){
  /* На узком экране сетка вырождается в один столбец, и квадратная картинка
     на всю ширину занимает пол-экрана. Кладём её слева от текста — но текст
     обязан оставаться ОДНИМ блоком (.nbody), иначе его части разъедутся по
     колонкам и дата обрежется многоточием. */
  .ngrid{grid-template-columns:1fr;gap:0}
  .ncard{flex-direction:row;gap:14px;align-items:flex-start;
    padding:14px 0;border-bottom:1px solid var(--rule)}
  .ncard .pic{width:84px;flex-shrink:0;margin-bottom:0}
  .ncard .nbody{flex:1;min-width:0}
  .ncard .nexc{display:none}
  .ncard .ntitle{font-size:15.5px;line-height:1.32}
}

/* Иллюстрация на самой странице заметки. */
.nhero{margin:0 0 28px;border:1px solid var(--rule);border-radius:var(--r-card);
  overflow:hidden;max-width:var(--read)}
.nhero img{width:100%;height:auto;display:block}

/* Строка «дата · тема · город» над заголовком. */
.nline{display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center;
  font-size:13.5px;color:var(--muted);margin-bottom:16px}
.nline a{color:var(--muted)}
.nline a:hover{color:var(--accent)}
.nline time{font-variant-numeric:tabular-nums}

/* Перечень тем и городов на витрине раздела. */
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}
.chips a{display:inline-flex;align-items:center;gap:7px;min-height:24px;
  padding:7px 13px;border:1px solid var(--rule-strong);border-radius:var(--r-btn);
  font-size:14.5px;font-weight:600;color:var(--ink);
  transition:background-color .18s var(--ease),color .18s var(--ease),
             border-color .18s var(--ease)}
.chips a:hover{background:var(--accent);border-color:var(--accent);color:#fff}
.chips a b{font-weight:400;color:var(--muted);font-variant-numeric:tabular-nums}
.chips a:hover b{color:#fff}

/* ── ПЛАШКИ ──────────────────────────────────────────────────────────────── */
.pill{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;
  padding:4px 9px;border-radius:var(--r-pill);border:1px solid var(--rule-strong);
  color:var(--muted);white-space:nowrap;letter-spacing:.01em}
.pill-new{border-color:var(--ok);color:var(--ok)}
.pill-accent{border-color:var(--accent);color:var(--accent)}

/* ── ХЛЕБНЫЕ КРОШКИ ─────────────────────────────────────────────────────── */
.crumbs{display:flex;flex-wrap:wrap;gap:9px;align-items:center;font-size:14px;
  color:var(--muted);padding:18px 0 0}
.crumbs a{color:var(--muted)}
.crumbs a:hover{color:var(--accent)}

/* ── ТЕКСТ СТАТЬИ ───────────────────────────────────────────────────────── */
/* Гиды — половина всего SEO, поэтому набору длинного текста здесь отдельное внимание:
   мера строки 66 знаков, крупный интерлиньяж, заголовки с большим верхним отступом. */
.prose{max-width:var(--read);font-size:18px;line-height:1.72;color:var(--ink2)}
@media(max-width:640px){.prose{font-size:16.5px;line-height:1.62}
  .prose h2{margin:34px 0 12px}.prose h3{margin:26px 0 9px}}
.prose h2{margin:46px 0 16px;color:var(--ink)}
.prose h3{margin:34px 0 12px;color:var(--ink)}
.prose>:first-child{margin-top:0}
.prose ul,.prose ol{margin:0 0 1.1em;padding:0;list-style:none}
.prose ol{counter-reset:n}
.prose li{position:relative;padding-left:28px;margin:.55em 0}
.prose ul li::before{content:"";position:absolute;left:8px;top:.72em;width:6px;height:1px;
  background:var(--accent)}
.prose ol li{counter-increment:n}
.prose ol li::before{content:counter(n) ".";position:absolute;left:0;top:0;
  font-variant-numeric:tabular-nums;font-weight:600;color:var(--accent)}
.prose b,.prose strong{color:var(--ink);font-weight:600}
.prose a{text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:3px;
  text-decoration-color:var(--rule-strong)}
.prose a:hover{text-decoration-color:var(--accent)}
.prose figure{margin:28px 0}
.prose figcaption{font-size:14px;color:var(--muted);margin-top:8px}

/* Врезка. Отбита слева акцентной линейкой — книжный приём, без заливки-«плашки». */
.note{border-left:2px solid var(--accent);padding:2px 0 2px 20px;margin:26px 0;
  font-size:16.5px;line-height:1.6;color:var(--ink2)}
.note b{color:var(--ink)}

/* ── FAQ ─────────────────────────────────────────────────────────────────── */
/* Нативный <details>: раскрывается без JS, работает с клавиатуры, доступен
   скринридеру из коробки. Своя стрелка вместо браузерного маркера. */
.faq{border-bottom:1px solid var(--rule)}
.faq summary{cursor:pointer;list-style:none;padding:20px 40px 20px 0;position:relative;
  font-weight:600;font-size:17.5px;color:var(--ink);user-select:none}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:6px;top:27px;width:11px;height:1px;
  background:var(--accent)}
.faq summary::before{content:"";position:absolute;right:11px;top:22px;width:1px;height:11px;
  background:var(--accent);transition:transform .2s var(--ease)}
.faq[open] summary::before{transform:scaleY(0)}
.faq .ans{padding:0 0 22px;color:var(--ink2);font-size:16.5px;line-height:1.68;
  max-width:var(--read)}
.faq .ans>:last-child{margin-bottom:0}

/* ── ПОДВАЛ ──────────────────────────────────────────────────────────────── */
/* Со ВСЕМИ чатами — это не украшение, а сквозная перелинковка: с любой страницы
   робот и человек в один клик попадают на любую другую. Для маленького сайта это
   самый дешёвый способ добиться полной индексации. */
.ftr{margin-top:auto;background:var(--ftr-bg);color:var(--ftr-fg);padding:56px 0 26px}
.ftr a{color:var(--ftr-fg)}
.ftr a:hover{color:#fff}
/* Подписи колонок подвала — НЕ заголовки. Раньше здесь стоял <h4> после <h2>
   страницы, и это ломало иерархию заголовков на КАЖДОЙ странице сайта: скринридер
   в режиме навигации по заголовкам показывал «Нячанг, Дананг…» как разделы документа,
   которыми они не являются. Внешний вид тот же, семантика честная. */
.ftr .col-h{font-family:"Golos Text",sans-serif;font-size:12px;font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--ftr-dim);margin:0 0 14px}
.ftr-cols{display:grid;gap:32px;grid-template-columns:repeat(auto-fit,minmax(180px,1fr))}
.ftr-cols ul{list-style:none;margin:0;padding:0;display:grid;gap:8px;font-size:15px}
.ftr-bot{margin-top:40px;padding-top:22px;border-top:1px solid var(--ftr-line);
  display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;
  font-size:14px;color:var(--ftr-dim)}

/* ── ПОЛОСА ПРИЗЫВА ─────────────────────────────────────────────────────── */
.cta-band{border:1px solid var(--ink);padding:clamp(28px,4.5vw,48px);
  display:grid;gap:24px;grid-template-columns:minmax(0,1fr) auto;align-items:center}
@media(max-width:760px){.cta-band{grid-template-columns:1fr}}
.cta-band h2{margin-bottom:10px}
.cta-band p{color:var(--ink2);margin:0;max-width:54ch}

/* ── ДВИЖЕНИЕ ────────────────────────────────────────────────────────────── */
/* Единственная анимация появления на сайте — на полосе цифр в герое, и та мягкая.
   Всё остальное движение отвечает на действие человека (наведение, фокус, раскрытие).
   Стартовое состояние ставит скрипт: если JS выключен, текст обязан остаться видимым. */
.js-on .fade-seq>*{opacity:0;transform:translateY(8px)}
.js-on .fade-seq.in>*{opacity:1;transform:none;
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.js-on .fade-seq.in>*:nth-child(2){transition-delay:.06s}
.js-on .fade-seq.in>*:nth-child(3){transition-delay:.12s}
.js-on .fade-seq.in>*:nth-child(4){transition-delay:.18s}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important}
  .js-on .fade-seq>*{opacity:1!important;transform:none!important}
}

/* ── ПЕЧАТЬ ──────────────────────────────────────────────────────────────── */
@media print{
  .hdr,.ftr,.cta-band,.btn,.skip{display:none}
  body{font-size:11pt;color:#000;background:#fff}
  .prose a::after{content:" (" attr(href) ")";font-size:9pt;color:#555}
}

/* ── СЛУЖЕБНЫЕ КЛАССЫ ─────────────────────────────────────────────────────
   Заменяют инлайновые style= в шаблонах. Дело не в чистоте разметки: пока в
   HTML есть хоть один атрибут style, политика безопасности (CSP) обязана
   разрешать unsafe-inline, а это снимает главную защиту от внедрения чужого
   кода. Пять классов здесь — цена строгого CSP на всём сайте. */
.sprite{display:none}
.faq-wrap{max-width:78ch}
.ico-sm{width:18px;height:18px}
.stat-n-sm{font-size:19px}
.lead-wide{margin-top:22px;max-width:56ch}

/* ── РАЗМЕР КЛИКАБЕЛЬНЫХ ЦЕЛЕЙ ───────────────────────────────────────────────
   WCAG 2.5.8 (уровень AA) требует минимум 24×24 CSS-пикселя для любой цели, кроме
   ссылок внутри строки текста — у тех размер задан набором, и трогать его нельзя.
   Крошки, подвал, надзаголовки и перечни тем под это исключение НЕ подпадают:
   это отдельно стоящие ссылки. Инспектор отрисовки замерял у них 17-23px. */
/* min-WIDTH тоже обязателен, не только высота. Короткое слово даёт цель 23×24px —
   на пиксель уже минимума WCAG 2.5.8. Поймал инспектор отрисовки на крошке «Гид». */
.crumbs a,.eyebrow a,.ftr a,.hdr nav a,.topics a,.ftr-bot a{
  display:inline-flex;align-items:center;justify-content:center;
  min-height:24px;min-width:24px}

/* Длинные строки без пробелов — @имена чатов, адреса — не должны растягивать
   страницу. На странице чата «@arenda_nhatrang_dzen» делал документ шире экрана
   на 36px, и на телефоне появлялась горизонтальная прокрутка. */
.stat-n-sm,.chat .name,.prose a{overflow-wrap:anywhere}
.figure{min-width:0}
.figure .stat-l{min-width:0;overflow-wrap:anywhere}

/* ── ТЁМНАЯ ТЕМА: ТЕКСТ НА АКЦЕНТЕ ───────────────────────────────────────────
   В светлой теме акцент тёмно-красный (#c8102e) и белый текст на нём даёт 5.9:1.
   В тёмной акцент осветлён до #ff4d63, чтобы читаться на тёмном фоне, — ибелый
   текст на нём падает до 3.23:1, ниже нормы AA. Решение не «вернуть тёмный
   красный» (он потеряется на тёмном фоне), а перевернуть текст: тёмный по
   светло-красному даёт 5.8:1. Поймал инспектор отрисовки, когда научился
   проверять обе темы. */
