:root {
  --bg: #0d1117; --card: #161b22; --card2: #1c2230; --border: #30363d; --text: #e6edf3; --muted: #8b949e;
  --accent: #2f81f7; --green: #3fb950; --red: #f85149; --yellow: #d29922; --purple: #a371f7;
}
* { box-sizing: border-box; }
body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: var(--bg); color: var(--text); line-height: 1.55; }
a { color: var(--accent); }
/* position: relative — точка отсчёта для переключателя языка в углу */
.wrap { max-width: 980px; margin: 0 auto; padding: 40px 20px 80px; position: relative; }
h1 { margin: 0 0 6px; font-size: 27px; }
h1 a { color: var(--text); text-decoration: none; }
/* Шапка сайта: одна и та же на всех страницах — бренд, меню, поиск.
   Меню выше строки ввода нарочно: на страницу чаще приходят за разделом, чем
   за словом. Раньше логотип был отдельной строкой в каждом шаблоне, а поиск жил
   только на главной; собранные по-разному, они расходились */
/* Верхняя строка шапки: логотип и меню в одну линию, поиск — во всю ширину
   под ней. Меню больше не отдельная полоса с рамками: рамка осталась одна,
   под всей строкой, и шапка читается как одна шапка, а не как три блока */
.site-head { margin: 0 0 18px; }
.head-top { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 10px 26px; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
.brand { margin: 0; }
.brand-a { display: inline-flex; flex-direction: column; line-height: 1.15; text-decoration: none; }
.brand-name { font-size: 17px; font-weight: 700; color: var(--text); letter-spacing: .2px; }
.brand-name::first-letter { color: var(--accent); }
.brand-tag { font-size: 11.5px; color: var(--muted); letter-spacing: .3px; }
.brand-a:hover .brand-tag { color: var(--accent); }
/* Поиск во всю ширину макета: он главный вход на сайт, и половина колонки
   под него — это половина подсказок, которых человек не видит */
.hsearch { margin: 14px 0 0; max-width: none; }
.hsearch input { padding: 10px 16px; font-size: 15.5px; border-radius: 10px; }
.qa-h1, .post-h1 { font-size: 24px; line-height: 1.32; margin: 0 0 6px; max-width: 46em; }
.sub { color: var(--muted); margin: 0 0 26px; font-size: 15px; }
.sub b { color: var(--text); font-weight: 600; }

.search { position: relative; }
.search input { width: 100%; padding: 14px 18px; font-size: 17px; border-radius: 12px; border: 1px solid var(--border); background: var(--card); color: var(--text); outline: none; transition: border-color .15s; }
.search input:focus { border-color: var(--accent); }
.dd { position: absolute; top: calc(100% + 6px); left: 0; right: 0; background: var(--card); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; z-index: 20; display: none; box-shadow: 0 12px 32px rgba(0,0,0,.45); }
.dd.open { display: block; }
.opt { display: flex; align-items: center; gap: 12px; padding: 10px 16px; cursor: pointer; }
.opt:hover, .opt.active { background: #1f2630; }
.opt .sym { font-weight: 700; min-width: 76px; font-variant-numeric: tabular-nums; }
.opt .nm { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); }
.tag { font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.tag.CRYPTO { color: var(--yellow); border-color: rgba(210,153,34,.5); }
.tag.RU { color: var(--green); border-color: rgba(63,185,80,.5); }
.tag.US { color: var(--accent); border-color: rgba(47,129,247,.5); }
.hint { padding: 10px 16px; color: var(--muted); font-size: 14px; }

.recent { margin: 16px 0 0; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; color: var(--muted); font-size: 13px; }
.chip { padding: 4px 12px; border-radius: 999px; background: var(--card); border: 1px solid var(--border); color: var(--text); cursor: pointer; font-size: 13px; text-decoration: none; }
.chip:hover { border-color: var(--accent); }

.card { background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 22px; margin-top: 22px; }
.head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.head h2 { margin: 0; font-size: 21px; }
.head h2 span { color: var(--muted); font-weight: 500; }
.meta { color: var(--muted); font-size: 12.5px; margin-top: 8px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.meta .dot { opacity: .4; }
.sent { font-weight: 600; font-size: 11.5px; padding: 3px 10px; border-radius: 999px; text-transform: uppercase; letter-spacing: .5px; }
.sent.bullish { background: rgba(63,185,80,.15); color: var(--green); }
.sent.bearish { background: rgba(248,81,73,.15); color: var(--red); }
.sent.neutral { background: rgba(139,148,158,.15); color: var(--muted); }
.sent.mixed { background: rgba(210,153,34,.15); color: var(--yellow); }
.pill { font-size: 11.5px; padding: 2px 9px; border-radius: 6px; }
.pill.hit { background: rgba(163,113,247,.15); color: var(--purple); }
.pill.miss { background: rgba(47,129,247,.15); color: var(--accent); }

.headline { font-size: 18px; font-weight: 600; margin: 18px 0 10px; }
p { margin: 0 0 10px; }
h3 { font-size: 12.5px; text-transform: uppercase; letter-spacing: .7px; color: var(--muted); margin: 24px 0 8px; }
ul { margin: 0; padding-left: 20px; }
li { margin: 6px 0; }
.ref { font-size: 11px; color: var(--accent); text-decoration: none; margin-left: 2px; vertical-align: super; }
.ref:hover { text-decoration: underline; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
.cols ul li::marker { color: var(--red); }
.cols .cats li::marker { color: var(--green); }
@media (max-width: 640px) { .cols { grid-template-columns: 1fr; } h1 { font-size: 22px; } .qa-h1, .post-h1 { font-size: 20px; } }

.community { background: var(--card2); border-left: 2px solid var(--purple); border-radius: 0 8px 8px 0; padding: 10px 14px; margin-top: 8px; font-size: 14.5px; }
.warn { margin-top: 18px; font-size: 12.5px; color: var(--muted); }
.warn code { color: var(--yellow); font-size: 11.5px; }

.news { list-style: none; padding: 0; margin: 8px 0 0; }
.news li { padding: 11px 0; border-top: 1px solid var(--border); margin: 0; }
.news li:target { background: rgba(47,129,247,.07); }
.news a.t { color: var(--text); text-decoration: none; }
.news a.t:hover { color: var(--accent); }
.news .src { color: var(--muted); font-size: 12px; margin-top: 2px; }
.news .snp { color: var(--muted); font-size: 13px; margin-top: 4px; }
/* Строка источников над списком публикаций: чипы-фильтры. Кликабельны они
   только при живом скрипте — без него это подпись с числом публикаций */
.srcf-wrap { color: var(--muted); line-height: 1.6; }
.srcf { display: flex; flex-wrap: wrap; gap: 6px; }
.srcf-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 999px; background: var(--card2); border: 1px solid var(--border); color: var(--text); font: inherit; font-size: 12.5px; line-height: 1.5; }
html.js .srcf-chip { cursor: pointer; }
html.js .srcf-chip:hover { border-color: var(--accent); color: var(--accent); }
.srcf-chip .c { color: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.srcf-chip.on { border-color: var(--accent); color: var(--accent); }
.srcf-chip.on .c { color: var(--accent); opacity: .75; }
/* Скрытая фильтром строка: атрибут hidden ставит скрипт, правило страхует
   от будущего display у .news li, который его перебил бы */
.news li[hidden] { display: none; }
.num { color: var(--muted); font-size: 12px; margin-right: 6px; font-variant-numeric: tabular-nums; }
details summary { cursor: pointer; color: var(--muted); font-size: 12.5px; text-transform: uppercase; letter-spacing: .7px; margin-top: 24px; }
details summary:hover { color: var(--text); }

.notice { margin-top: 14px; padding: 9px 13px; border-radius: 8px; background: rgba(210,153,34,.12); color: var(--yellow); font-size: 13.5px; }
.loader { display: flex; align-items: center; gap: 12px; color: var(--muted); }
.spin { flex: none; width: 18px; height: 18px; border: 2px solid var(--border); border-top-color: var(--accent); border-radius: 50%; animation: s .8s linear infinite; }
@keyframes s { to { transform: rotate(360deg); } }
.err { color: var(--red); }

/* каталог тикеров */
.cat { margin-top: 34px; }
.cat h2 { font-size: 19px; margin: 0 0 4px; display: flex; align-items: baseline; gap: 10px; }
.cat h2 .cnt { font-size: 13px; color: var(--muted); font-weight: 400; }
.cat .lead { color: var(--muted); font-size: 13.5px; margin: 0 0 14px; }
details.cat > summary { list-style: none; cursor: pointer; margin-top: 0; text-transform: none; letter-spacing: 0; }
details.cat > summary::-webkit-details-marker { display: none; }
details.cat > summary::before { content: '▸'; color: var(--muted); margin-right: 8px; display: inline-block; }
details.cat[open] > summary::before { content: '▾'; }
details.cat > summary h2 { display: inline-flex; }
details.cat > summary:hover h2 { color: var(--accent); }
.letters { margin-top: 14px; }
.letters .lt { font-size: 11.5px; color: var(--muted); text-transform: uppercase; letter-spacing: .8px; margin: 16px 0 6px; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 2px 16px; }
.tl { display: flex; gap: 8px; align-items: baseline; padding: 4px 0; text-decoration: none; color: var(--text); font-size: 14px; border-bottom: 1px solid transparent; }
.tl:hover { border-bottom-color: var(--accent); }
.tl .s { font-weight: 700; font-variant-numeric: tabular-nums; min-width: 62px; color: var(--accent); }
.tl .n { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tl:hover .n { color: var(--text); }
.nav { display: flex; flex-wrap: wrap; gap: 6px 20px; margin: 0; font-size: 14.5px; padding: 0; }
/* Подчёркивания у пунктов меню нет: это навигация, а не текст в абзаце.
   Строка меню и без него читается как меню — рамки сверху и снизу */
.nav a { margin: 0; text-decoration: none; }
.nav a:hover { color: #7cb0ff; }
/* Текущий раздел не выглядит ссылкой, но и не исчезает: человек видит, где он */
.nav a.on { color: var(--text); font-weight: 600; }
/* Меню переносится по строкам, а не уезжает за край: пять пунктов на узком
   экране в одну строку не влезают, и горизонтальная прокрутка прятала бы
   «Наш токен» целиком */
/* На телефоне верхней строке логотип и пять пунктов не уживаются в линию:
   меню уходит под логотип, но остаётся тем же блоком */
@media (max-width: 700px) {
  .head-top { gap: 8px 16px; }
  .nav { font-size: 14px; gap: 6px 16px; }
}
/* Личный кабинет в правом верхнем углу. Стоит справа от меню в одну строку
   с ним и отделён чертой: это не раздел сайта, а состояние входа */
.head-right { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 18px; }
.uenter {
  padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px;
  text-decoration: none; font-size: 13.5px; color: var(--text); white-space: nowrap;
}
.uenter:hover { border-color: var(--accent); color: var(--accent); }
.ume { position: relative; }
/* Список <details> сам умеет открываться без скрипта: тот же приём, что у
   выбора интервала, и по той же причине — лишнего кода на клиенте нет */
.ume > summary {
  display: flex; align-items: center; gap: 7px; cursor: pointer; list-style: none;
  padding: 4px 10px 4px 4px; border: 1px solid var(--border); border-radius: 999px; font-size: 13.5px;
  /* Общее правило details summary рассчитано на подписи секций: отступ сверху
     в 24px и капс. Здесь это кнопка в строке меню — без сброса она съезжала
     вниз на 12px и шапка выглядела разъехавшейся */
  margin: 0; text-transform: none; letter-spacing: 0;
}
.ume > summary::-webkit-details-marker { display: none; }
.ume > summary:hover, .ume[open] > summary { border-color: var(--accent); }
/* Значок — первая буква ника: аватаров у нас нет, а буква читается быстрее
   пустого круга и не требует загрузки картинки. Имени рядом нет нарочно:
   в шапке оно занимало место на каждой странице, а внутри меню читается
   там, где нужно — при нажатии */
.uava {
  width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center;
  background: var(--accent); color: #fff; font-size: 12.5px; font-weight: 700; flex: none;
}
/* Ник в открытом меню, над ссылками. Это подпись, а не действие: без наведения
   и без рамки, чтобы не читался как ещё один пункт */
.uhead {
  padding: 4px 10px 8px; margin-bottom: 2px; border-bottom: 1px solid var(--border);
  color: var(--muted); font-size: 12.5px; letter-spacing: .2px;
  max-width: 200px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ucar { color: var(--muted); font-size: 11px; }
.umenu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 30; min-width: 190px;
  display: flex; flex-direction: column; gap: 2px; padding: 6px;
  background: var(--card); border: 1px solid var(--border); border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0,0,0,.35);
}
.umenu a, .umenu button {
  padding: 8px 10px; border-radius: 7px; text-decoration: none; font: inherit; font-size: 13.5px;
  color: var(--text); background: transparent; border: 0; text-align: left; cursor: pointer;
}
.umenu a:hover, .umenu button:hover { background: rgba(255,255,255,.07); }
.umenu form { margin: 0; }
/* На телефоне меню открывается вправо от значка: он стоит у левого края
   строки, и список, прижатый к его правому ребру, уезжал бы за край окна */
@media (max-width: 700px) {
  .head-right { width: 100%; justify-content: space-between; }
  .umenu { right: auto; left: 0; min-width: 170px; }
}
/* Переключение интервала идёт запросом: без пометки блок кажется зависшим */
[data-live].loading { opacity: .55; transition: opacity .12s; }
.foot { margin-top: 50px; padding-top: 22px; border-top: 1px solid var(--border); color: var(--muted); font-size: 12.5px; }
.foot a { color: var(--muted); text-decoration: none; }
.foot a:hover { color: var(--accent); }
/* Четыре колонки: о сервисе шире, ссылки — по одной в строку, как в подвалах
   биржевых сайтов. Раньше это был один абзац через точки, и «Правила
   обсуждений» стояли в той же строке, что и источники данных */
.fgrid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 22px; }
.fabout p { margin: 6px 0 0; line-height: 1.5; max-width: 42em; }
.fbrand { font-size: 15px; font-weight: 700; color: var(--text); }
.fbrand span { display: block; font-size: 11.5px; font-weight: 400; color: var(--muted); letter-spacing: .3px; }
.fcol { display: flex; flex-direction: column; gap: 6px; }
.fcol h4 { margin: 0 0 2px; font-size: 11.5px; text-transform: uppercase; letter-spacing: .7px; color: var(--text); }
.flang { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; margin: 22px 0 0; }
.flang span { font-size: 11.5px; text-transform: uppercase; letter-spacing: .7px; color: var(--text); }
/* Свой язык не ссылка на себя, но и не исчезает: видно, где ты */
.flang a.on { color: var(--text); cursor: default; }
.flang a.on::after { content: ' ✓'; color: var(--accent); }
.flegal { margin: 20px 0 0; padding-top: 14px; border-top: 1px solid var(--border); }
@media (max-width: 700px) { .fgrid { grid-template-columns: 1fr 1fr; } .fabout { grid-column: 1 / -1; } }

/* вопросы к ИИ-аналитику */
.qa { margin-top: 34px; background: var(--card); border: 1px solid var(--border); border-radius: 14px; padding: 22px; }
.qa h2 { font-size: 19px; margin: 0 0 4px; }
.qa h2 span { color: var(--muted); font-weight: 500; font-size: 15px; }
.qa .lead { color: var(--muted); font-size: 13.5px; margin: 0 0 16px; }
.qa-form textarea { width: 100%; padding: 12px 14px; font: inherit; font-size: 15px; line-height: 1.5; color: var(--text); background: var(--card2); border: 1px solid var(--border); border-radius: 10px; outline: none; resize: vertical; min-height: 78px; }
.qa-form textarea:focus { border-color: var(--accent); }
.qa-form textarea::placeholder { color: var(--muted); }
.qa-actions { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; flex-wrap: wrap; }
.qa-hint { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.btn { background: var(--accent); color: #fff; border: 0; padding: 9px 20px; border-radius: 9px; cursor: pointer; font-size: 14px; font-weight: 600; }
.btn:hover { filter: brightness(1.1); }
.btn:disabled { opacity: .55; cursor: default; }
.qa-list { margin-top: 20px; display: flex; flex-direction: column; gap: 2px; }
.qa-item { display: block; padding: 12px 0; border-top: 1px solid var(--border); text-decoration: none; color: var(--text); }
.qa-item:hover .qa-q { color: var(--accent); }
.qa-q { display: block; font-weight: 600; font-size: 15px; }
.qa-a { display: block; color: var(--muted); font-size: 13.5px; margin-top: 4px; }
.qa-empty { color: var(--muted); font-size: 13.5px; margin: 18px 0 0; }
.qa-page .qa-question { font-size: 22px; line-height: 1.35; margin: 16px 0 14px; }
.qa-asked { color: var(--muted); font-size: 13.5px; margin: -8px 0 18px; font-style: italic; }
.qa-answer p { margin: 0 0 12px; font-size: 15.5px; }
.qa-refs { font-size: 13px; color: var(--muted); }
.qa-page .news li a { color: var(--text); text-decoration: none; }
.qa-page .news li a:hover { color: var(--accent); }
.qa-page .news .src { color: var(--muted); font-size: 12px; }

/* ---------------------------------------------------------------- обсуждения по тикеру */
.post-title { font-size: 21px; line-height: 1.35; margin: 14px 0 10px; }
.post-body { font-size: 15.5px; margin: 10px 0 12px; word-wrap: break-word; overflow-wrap: break-word; }
.post-body p { margin: 0 0 10px; }
.post-body p:last-child { margin-bottom: 0; }
/* Картинка к сообщению: график с Imgur. Ширину не задаём жёстко — она бывает
   разной, а панель поста узкая, поэтому потолок по контейнеру и высота в долю
   экрана: длинный скриншот иначе занимает всю ленту */
.post-media { margin: 12px 0; padding: 0; }
.post-media img { display: block; max-width: 100%; max-height: 70vh; width: auto; height: auto; border: 1px solid var(--border); border-radius: 10px; background: var(--card2); }
.post-media a { display: inline-block; max-width: 100%; }

.post-meta { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); }
.post-nick { font-weight: 600; color: var(--text); }
.post-host { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11.5px; color: var(--muted); }
.post-host::before { content: '('; }
.post-host::after { content: ')'; }
.post-date { font-variant-numeric: tabular-nums; }
.post-reply { margin-left: auto; }

.meta-nick { margin-left: auto; font-size: 13px; color: var(--muted); }
.meta-nick::before { content: 'вы вошли как '; }
.meta-nick::after { content: ' · '; }

.post-list { margin-top: 4px; }
.post { padding: 14px 0; border-top: 1px solid var(--border); }
.post-nest { border-left: 2px solid var(--border); padding-left: 12px; margin-top: 10px; margin-left: calc(var(--d, 1) * 22px); }
.post-cnt { color: var(--muted); font-variant-numeric: tabular-nums; }
.post-target { font-size: 12px; color: var(--muted); margin-bottom: 6px; }

.forum-new { margin-top: 18px; }
.forum-new > summary {
  list-style: none; cursor: pointer; display: inline-block; text-transform: none; letter-spacing: 0;
  font-size: 13.5px; color: var(--text); padding: 7px 15px; border: 1px solid var(--border);
  border-radius: 8px; margin-top: 0;
}
.forum-new > summary::-webkit-details-marker { display: none; }
.forum-new > summary::before { content: '+ '; color: var(--accent); }
.forum-new[open] > summary::before { content: '− '; }
.forum-new > summary:hover { border-color: var(--accent); }

.forum-form { margin-top: 14px; }
.forum-form label { display: block; margin-bottom: 14px; }
.field-label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.forum-form input[type="text"], .forum-form textarea, .forum-form .phrase {
  width: 100%; padding: 11px 13px; font: inherit; font-size: 15px; line-height: 1.5; color: var(--text);
  background: var(--card2); border: 1px solid var(--border); border-radius: 10px; outline: none; resize: vertical;
}
.forum-form input[type="text"]:focus, .forum-form textarea:focus { border-color: var(--accent); }
.forum-form .phrase {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13.5px; line-height: 1.7; word-spacing: 2px;
}
.forum-form .check { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--muted); }
.forum-form .check input { accent-color: var(--accent); }
/* Список-выбор на доске объявлений: та же рамка и фон, что у поля ввода */
.forum-form select {
  width: 100%; padding: 11px 13px; font: inherit; font-size: 15px; color: var(--text);
  background: var(--card2); border: 1px solid var(--border); border-radius: 10px; outline: none;
}
.forum-form select:focus { border-color: var(--accent); }

/* ------------------------------------------------ флудилка и доска объявлений
   Обе страницы — плоские ленты, а не дерево веток: у каждой записи своя
   карточка, свежее снизу (чат) или сверху (объявления) */
/* Вкладки разделов форума стоят сразу под заголовком, до вводного абзаца */
.ftabs { margin: 4px 0 16px; }
.flood-log { margin-top: 20px; display: flex; flex-direction: column; gap: 10px; }
.flood-log:empty { display: none; }
.flood-msg {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 12px 16px; max-width: 78ch;
}
.flood-msg .post-body { margin: 6px 0 0; }
.flood-form { margin-top: 22px; }
/* Поле ввода прилипает к низу окна: в чате пишут последним, и искать поле
   после длинной ленты — лишний шаг. На узком экране липкость мешала бы
   листать, поэтому там она выключена */
.flood-form textarea { min-height: 74px; }

.board-list { margin-top: 6px; display: flex; flex-direction: column; gap: 12px; }
.board-item { background: var(--card); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; }
.board-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.board-head h3 { margin: 0; font-size: 16.5px; line-height: 1.35; }
.board-cat { flex: none; }
.board-item .post-body { margin: 8px 0 10px; }
.board-contact { color: var(--text); }
.bboard-tabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 18px; }
.btab {
  padding: 5px 12px; border: 1px solid var(--border); border-radius: 999px;
  font-size: 13px; color: var(--muted); text-decoration: none;
}
.btab:hover { color: var(--text); border-color: var(--accent); }
.btab.on { color: var(--text); border-color: var(--accent); background: var(--card2); }
/* ханипот: человек поле не видит, автозаполнение ботов — заполняет */
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

.msg { margin: 14px 0; padding: 12px 15px; border-radius: 10px; background: var(--card2); border: 1px solid var(--border); font-size: 14px; }
.msg.ok { border-color: rgba(63,185,80,.45); color: var(--green); }
.msg.err { border-color: rgba(248,81,73,.45); color: var(--red); }

/* Запросы на возможности: статус красится как метка раздела — цветом, а не
   словом «новый», которое читается одинаково со всеми остальными */
.feat-new { color: var(--accent); border-color: rgba(47,129,247,.5); }
.feat-planned { color: var(--yellow); border-color: rgba(210,153,34,.5); }
.feat-done { color: var(--green); border-color: rgba(63,185,80,.5); }
.feat-declined { color: var(--muted); }
.feat-h2 { margin: 26px 0 0; font-size: 19px; }
/* Смена статуса стоит под записью, а не в её шапке: так список читается
   сверху вниз и не распадается на две колонки на узком экране */
.feat-status { display: flex; gap: 8px; align-items: center; margin-top: 10px; }
.feat-status select {
  padding: 6px 10px; border-radius: 8px; font: inherit; font-size: 13px;
  color: var(--text); background: var(--card2); border: 1px solid var(--border);
}
.seed {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 14px; line-height: 1.8; word-spacing: 4px;
  background: var(--bg); border: 1px dashed var(--border); border-radius: 10px; padding: 12px 14px;
  margin: 12px 0; color: var(--text); word-break: break-word;
}

.kv { display: grid; gap: 8px; font-size: 14px; margin: 14px 0; }
.kv > div { display: flex; gap: 14px; align-items: baseline; flex-wrap: wrap; }
.kv span { color: var(--muted); min-width: 110px; }
.kv b { font-weight: 500; }
.kv code { color: var(--yellow); font-size: 13px; }

.rules { margin: 12px 0; padding-left: 22px; }
.rules li { margin: 8px 0; font-size: 14.5px; }

.logout { margin-top: 16px; }
.btn.ghost { background: transparent; border: 1px solid var(--border); color: var(--text); font-weight: 500; }
.btn.ghost:hover { border-color: var(--accent); }
.linkish { background: none; border: 0; padding: 0; font: inherit; color: var(--muted); cursor: pointer; text-decoration: underline; }
.linkish:hover { color: var(--text); }

/* Дивиденды: цифры — главное на блоке, поэтому сумма выплаты крупнее прочего текста */
.div-card h2 { display: flex; align-items: baseline; gap: 10px; font-size: 19px; margin: 0 0 4px; }
.div-card h2 span { color: var(--muted); font-weight: 500; font-size: 15px; }
.div-next { display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap; margin: 14px 0 4px; }
.div-amount { font-size: 30px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--green); }
.div-when { display: flex; flex-direction: column; font-size: 13px; color: var(--muted); }
.div-when b { color: var(--text); font-size: 15px; font-weight: 600; }
.div-yield { font-size: 13px; color: var(--muted); border-left: 1px solid var(--border); padding-left: 18px; }
.div-facts { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); margin: 14px 0 6px; }
.div-table { width: 100%; border-collapse: collapse; font-size: 14px; margin-top: 6px; }
.div-table th {
  text-align: left; color: var(--muted); font-weight: 500; font-size: 12.5px;
  border-bottom: 1px solid var(--border); padding: 7px 10px 7px 0;
}
.div-table td { padding: 7px 10px 7px 0; border-bottom: 1px solid rgba(48,54,61,.55); }
.div-table .num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.div-table th.num { text-align: right; padding-right: 14px; }
.div-table td.num { text-align: right; padding-right: 14px; }
.div-kind { font-size: 11.5px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); white-space: nowrap; }
.div-kind.rec { color: var(--green); border-color: rgba(63,185,80,.45); }
.div-kind.fc { color: var(--yellow); border-color: rgba(210,153,34,.45); }
.div-src { color: var(--muted); font-size: 12px; margin: 14px 0 0; }

/* Календарь дивидендов: тикер рядом с названием — как в поиске, узнаваемо */
.div-table .sym { color: var(--muted); font-size: 12.5px; margin-left: 4px; }
@media (max-width: 640px) {
  .div-table { font-size: 13px; }
  /* На узком экране убираем последнюю колонку: статус и «изм. к году» —
     пояснения, а дата и сумма должны остаться целиком */
  .div-table th:last-child, .div-table td:last-child { display: none; }
  .div-amount { font-size: 25px; }
}

/* Индексы: значение крупно, график — свой SVG, таблицы те же, что у дивидендов */
.idx-value { display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap; margin-bottom: 6px; }
.idx-num { font-size: 40px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.5px; }
.idx-num span { font-size: 17px; font-weight: 400; color: var(--muted); margin-left: 6px; }
/* Само значение — тоже span (его подменяет живая котировка), но крупное.
   Без этого правила оно попадало под селектор выше и печаталось серым
   семнадцатым кеглем рядом с единицей измерения */
.idx-num span.n { font-size: inherit; font-weight: inherit; color: inherit; margin-left: 0; letter-spacing: inherit; }
.idx-delta { font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--muted); }
.idx-delta.up, .idx-table .up { color: var(--green); }
.idx-delta.down, .idx-table .down { color: var(--red); }
.idx-chart { margin-top: 18px; }
.idx-chart svg { width: 100%; height: 190px; display: block; }
.idx-chart-axis { display: flex; justify-content: space-between; color: var(--muted); font-size: 12px; margin-top: 6px; font-variant-numeric: tabular-nums; }
/* У индексных таблиц последняя колонка — смысловая (вес бумаги), её не прячем
   на узком экране, в отличие от календаря дивидендов */
.idx-table th:last-child, .idx-table td:last-child { display: table-cell; }
@media (max-width: 640px) {
  .idx-num { font-size: 30px; }
  .idx-chart svg { height: 140px; }
  .idx-table th:last-child, .idx-table td:last-child { display: table-cell; }
}

/* График цены на странице тикера: тот же принцип, что у индексов —
   серверный SVG, переключение периодов обычными ссылками */
.chart-card .meta-stamp { color: var(--muted); font-size: 12.5px; }
/* ---------------------------------------------------------- перекрестие
   Показателей над графиком больше нет: они повторяли то, что видно по
   свечам. Вместо блока — строка, которая появляется при наведении и
   рассказывает про одну свечу. Место под неё не резервируется, поэтому без
   курсора карточка на столько же короче */
.plot { position: relative; }
/* Отступ сверху у самого блока, а не у SVG: строка параметров лежит поверх
   графика, и отступ внутри SVG отодвинул бы её от свечей */
.chart .plot { margin-top: 10px; }
/* Прямые линии перекрестия. Толщина в 1 px и полупрозрачный цвет: линия
   должна показывать, какую свечу читают, и не спорить с самими свечами */
/* Линии и строка появляются по классу .on, а не по :hover: до первого
   движения курсора у них нет координат, и :hover показал бы линии в левом
   верхнем углу и пустую подложку строки */
.xh { position: absolute; opacity: 0; pointer-events: none; transition: opacity .1s; }
.xh-v { top: 0; bottom: 0; width: 1px; background: rgba(230,237,243,.35); }
.xh-h { left: 0; right: 0; height: 1px; background: rgba(230,237,243,.22); }
.plot.on .xh { opacity: 1; }
/* Строка параметров: поверх графика справа, одной строкой в один шрифт.
   Подложка нужна, чтобы числа читались поверх свечей */
.chart-read { position: absolute; top: 0; right: 0; display: none; gap: 10px; align-items: baseline; padding: 3px 8px; border-radius: 7px; background: rgba(13,17,23,.88); font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; white-space: nowrap; pointer-events: none; }
.plot.on .chart-read { display: flex; }
.chart-read .v { color: var(--text); }
.chart-read .rd.up { color: var(--green); }
.chart-read .rd.down { color: var(--red); }
.chart-read .rd.flat { color: var(--muted); }
.periods { display: flex; gap: 6px; flex-wrap: wrap; margin: 14px 0 6px; }
.periods a { padding: 5px 12px; border-radius: 999px; border: 1px solid var(--border); color: var(--muted); font-size: 13px; text-decoration: none; }
.periods a:hover { color: var(--text); border-color: var(--accent); }
.periods a.on { background: rgba(47,129,247,.15); border-color: rgba(47,129,247,.6); color: var(--text); }
.chart svg { width: 100%; height: 210px; display: block; }
/* В блоке с перекрестием отступ задаёт .plot, и второй, у SVG, сдвинул бы
   строку параметров вместе с ним */
.chart .plot svg { margin-top: 0; }
/* Переключатель интервалов: до восьми пунктов, поэтому на узком экране он переносится */
/* Заголовок графика и выбор интервала в одну строку: подпись времени уходит
   влево, выпадающий список — к правому краю. На узком экране инструменты
   переносятся под заголовок, но остаются одним блоком */
.chart-head { justify-content: space-between; }
.chart-tools { display: flex; align-items: center; gap: 10px; margin-left: auto; }
.chart-tools .tfdd > summary { font-size: 13px; padding: 5px 12px; }
.chart-tools .tfmenu { min-width: 150px; }
@media (max-width: 560px) {
  .chart-tools { margin-left: 0; }
}
.chart-empty { color: var(--muted); margin: 12px 0 0; }
@media (max-width: 640px) {
  .chart svg { height: 150px; }
  /* На узком экране шесть величин в строку не влезают: строка переносится,
     а не уезжает за край. Курсора там нет, зато есть нажатие — оно тоже
     показывает свечу */
  .chart-read { flex-wrap: wrap; gap: 2px 10px; font-size: 11.5px; white-space: normal; max-width: calc(100% - 8px); }
}

/* Строка индексов на главной: шесть значений в одну линию, без графиков */
.idx-strip { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 2px; margin-top: 12px; }
.idx-cell { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: 10px; text-decoration: none; color: var(--text); border: 1px solid transparent; }
.idx-cell:hover { background: var(--card2); border-color: var(--border); }
.idx-cell-name { color: var(--muted); font-size: 12.5px; }
.idx-cell-val { font-size: 19px; font-weight: 600; font-variant-numeric: tabular-nums; }
.idx-cell-chg { font-size: 12.5px; font-variant-numeric: tabular-nums; color: var(--muted); }
.idx-cell-chg.up { color: var(--green); }
.idx-cell-chg.down { color: var(--red); }
.idx-home h2 .cnt { font-size: 13px; color: var(--muted); font-weight: 400; }

/* Быстрые ссылки по странице тикера: страница длинная, без них нужна прокрутка.
   Верхнее меню (.nav) ведёт по сайту, это — внутри самой страницы */
.jump { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0 0; }
.jump a {
  padding: 5px 13px; border-radius: 999px; font-size: 13px; text-decoration: none;
  color: var(--text); background: var(--card); border: 1px solid var(--border);
}
.jump a:hover { border-color: var(--accent); color: var(--accent); }
/* Якорь не должен уезжать под верх экрана: отступ сверху даёт воздух */
.card[id], .qa[id], .cat[id] { scroll-margin-top: 16px; }

/* Плавный переход по якорям: иначе прыжок к дивидендам выглядит как перезагрузка */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

/* Возврат наверх: после прыжка к дивидендам или к обсуждению до меню
   приходится крутить страницу обратно. Ссылка-якорь, без скрипта —
   так она работает и при отключённом JS, и в индексе не мешает */
.totop {
  position: fixed; right: 18px; bottom: 18px; z-index: 20;
  padding: 9px 14px; border-radius: 999px; font-size: 13.5px; text-decoration: none;
  color: var(--text); background: var(--card2); border: 1px solid var(--border);
  box-shadow: 0 4px 14px rgba(0,0,0,.35);
  /* Наверху страницы кнопка не нужна: она закрывает текст, а возвращаться
     некуда. Класс .on вешает скрипт по прокрутке, а при отключённом JS
     видимость возвращает <noscript> в разметке страницы */
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity .2s ease, transform .2s ease, visibility .2s;
}
.totop.on { opacity: 1; visibility: visible; transform: none; }
/* Клавиатура: кнопка не должна исчезать из-под фокуса, если человек
   добрался до неё табом, а страница при этом наверху */
.totop:focus-visible { opacity: 1; visibility: visible; transform: none; }
.totop:hover { border-color: var(--accent); color: var(--accent); }
@media (prefers-reduced-motion: reduce) {
  .totop { transition: none; }
}
@media (max-width: 640px) {
  /* На телефоне кнопка не должна закрывать текст — остаётся один знак */
  .totop { right: 12px; bottom: 12px; padding: 10px 13px; font-size: 15px; }
  .totop span { display: none; }
}

/* Счётчик рядом с заголовком в списках — как на старых досках: по нему видно,
   насколько длинный ответ или сколько ответов в ветке, не открывая её */
.qa-cnt { color: var(--muted); font-weight: 400; font-variant-numeric: tabular-nums; font-size: 13px; }
.qa-item:hover .qa-cnt { color: var(--muted); }

/* Дерево обсуждения на странице тикера: строка темы, под ней с отступом
   ответы, ответ на ответ — глубже. Плотная сетка, как на старых досках:
   в одну строку умещается заголовок, просмотры и автор */
.ftree { margin-top: 16px; border-top: 1px solid var(--border); }
.ftree-row {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 5px 0; font-size: 14px; line-height: 1.45;
  color: var(--text); text-decoration: none; border-bottom: 1px solid rgba(48,54,61,.5);
}
a.ftree-row:hover { background: var(--card2); }
a.ftree-row:hover .ft-text { color: var(--accent); }
.ftree-row.root { font-weight: 600; }
/* Шаг отступа задаёт разметка (--d), ширину шага — здесь: на телефоне он меньше */
.ftree-row[style] { margin-left: calc(var(--d, 0) * 18px); }
/* Прочерк вместо текста: сообщение пустое, открывать нечего — и ссылки нет */
.ftree-row.empty { color: var(--muted); }
.ft-empty { font-style: normal; color: var(--muted); }
/* Текст не растягивается: пометка тикера стоит сразу за ним, а не уезжает
   к правому краю строки, где читается как отдельная колонка */
.ft-text { flex: 0 1 auto; min-width: 0; overflow-wrap: break-word; }
.ft-cnt { color: var(--muted); font-size: 12.5px; font-variant-numeric: tabular-nums; }
.ft-by { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.ft-nick { color: var(--text); font-weight: 500; }
.ft-date { font-variant-numeric: tabular-nums; }
/* Пометка тикера у корня ветки на общем форуме: на странице тикера она не
   нужна — там все ветки про одно и та же подпись повторялась бы в каждой строке */
.ft-main { flex: 1 1 320px; min-width: 0; display: flex; align-items: baseline; gap: 8px; }
.ft-tk { flex: none; }
.ftree-all { margin-top: 22px; }

@media (max-width: 640px) {
  /* На телефоне отступ в 18px на глубине съедает ширину: уменьшаем вдвое */
  .ftree-row { font-size: 13.5px; padding: 6px 0; }
  .ftree-row[style] { margin-left: calc(var(--d, 0) * 11px); }
  .ft-by { white-space: normal; }
}

/* Таблица на главной: тикеры по капитализации, как на биржевых витринах.
   Числа справа моноширинными цифрами — иначе столбцы прыгают при прокрутке */
.rank { margin-top: 24px; }
.tabs { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.tabs .tab {
  padding: 6px 14px; border-radius: 999px; font-size: 13.5px; text-decoration: none;
  color: var(--text); background: var(--card); border: 1px solid var(--border);
}
.tabs .tab span { color: var(--muted); font-size: 12px; margin-left: 2px; }
.tabs .tab:hover { border-color: var(--accent); color: var(--accent); }
.tabs .tab.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.tabs .tab.on span { color: rgba(255,255,255,.75); }
/* Шесть колонок в 390 px не влезают: без прокрутки таблица растягивала
   документ шире экрана, и вся страница ехала вбок вместе с ней */
.rank-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.rank-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.rank-table th {
  text-align: left; color: var(--muted); font-weight: 500; font-size: 12.5px;
  border-bottom: 1px solid var(--border); padding: 8px 10px 8px 0;
}
.rank-table td { padding: 8px 10px 8px 0; border-bottom: 1px solid rgba(48,54,61,.55); }
.rank-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; padding-right: 14px; }
.rank-table th.num { padding-right: 14px; }
.rank-table .rk { color: var(--muted); font-size: 12.5px; width: 34px; font-variant-numeric: tabular-nums; }
.rank-table th.rk { padding-right: 0; }
.rank-table .nm a { color: var(--text); text-decoration: none; }
.rank-table tr:hover .nm a { color: var(--accent); }
.rank-table .sym { color: var(--muted); font-size: 12.5px; margin-left: 4px; }
.rank-table .mk { width: 76px; }
.rank-table .up { color: var(--green); }
.rank-table .down { color: var(--red); }
.rank-table .flat { color: var(--muted); }
.rank-src { color: var(--muted); font-size: 12px; margin: 14px 0 0; }
@media (max-width: 640px) {
  /* На телефоне капитализация важнее рынка: колонку с тегом убираем,
     а цену и изменение оставляем — они и есть смысл таблицы */
  .rank-table { font-size: 13px; }
  .rank-table .mk, .rank-table th.mk { display: none; }
  .rank-table .cap { padding-right: 0; }
}

/* ---------------------------------------------- страница «Графики»
   Сетка карточек вместо одного большого графика: задача страницы — увидеть
   весь рынок разом, а не разглядывать одну бумагу. Ширина у неё теперь общая,
   ровно как у капитализации и тикера: своя, более широкая колонка сдвигала
   левый край на 60 px, и раздел выглядел чужим на фоне остальных страниц.
   Трём карточкам по 300 px хватает и 940 px содержимого */
/* Меню «Графиков» стоит на обеих страницах сразу под меню сайта и с одинаковым
   отступом: при переходе между сеткой и инструментом кнопки не сдвигаются */
/* Одна строка: категории слева, справа интервал выпадающим списком и
   настройка доски. Раньше это были три полосы друг под другом — наборы,
   категории, восемь кнопок интервала, — и до карточек приходилось листать */
.gnav { margin: 18px 0 22px; display: flex; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; gap: 10px 16px; }
.gnav-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.gtabs { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; }
/* На узком экране зазор между категориями меньше: они и так делят строку */
/* Отступ по бокам меньше прежнего: восемь категорий вместе с интервалом и
   шестерёнкой должны укладываться в одну строку даже на 1280 px. При 18 px
   строка переносилась, и интервал уезжал под категории */
.gtab {
  padding: 8px 14px; border-radius: 999px; font-size: 14.5px; text-decoration: none;
  color: var(--text); background: var(--card); border: 1px solid var(--border);
}
.gtab:hover { border-color: var(--accent); color: var(--accent); }
.gtab.on { background: var(--accent); border-color: var(--accent); color: #fff; }
/* Интервал: <details> с обычными ссылками внутри. Настоящий <option> без
   скрипта не переходит по адресу, а ссылка работает и с выключенным JS,
   и для поисковика */
.tfdd { position: relative; }
.tfdd > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
  padding: 8px 14px; border-radius: 999px; font-size: 14px; color: var(--text);
  background: var(--card); border: 1px solid var(--border); white-space: nowrap;
  /* Общее правило details summary делает подписи капсом: здесь это кнопка,
     а не заголовок секции */
  text-transform: none; letter-spacing: 0; margin: 0;
}
.tfdd > summary::-webkit-details-marker { display: none; }
.tfdd > summary:hover { border-color: var(--accent); }
.tfdd[open] > summary { border-color: var(--accent); }
.tfcar { color: var(--muted); font-size: 11px; }
.tfmenu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 25; min-width: 148px;
  display: flex; flex-direction: column; padding: 6px; border-radius: 12px;
  background: var(--card); border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
.tfopt { padding: 7px 12px; border-radius: 8px; font-size: 14px; color: var(--text); text-decoration: none; display: flex; justify-content: space-between; gap: 10px; }
.tfopt:hover { background: #1f2630; }
.tfopt.on { color: var(--accent); font-weight: 600; }
.tfchk { font-size: 12px; }

.ggrid {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
}
/* Карточка — ссылка целиком: нажатие на любую её точку открывает страницу
   инструмента, как в списках котировок. Подчёркивания нет: оно превратило бы
   сетку в набор ссылок вместо таблицы цен */
a.gcard { text-decoration: none; color: inherit; transition: border-color .12s; }
a.gcard:hover { border-color: var(--accent); }
a.gcard:hover .gname { color: var(--accent); }
a.gcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.gcard {
  background: var(--card); border: 1px solid var(--border); border-radius: 12px;
  padding: 14px 14px 10px; display: flex; flex-direction: column; min-width: 0;
}
/* Две строки под название оставлены всегда, даже если оно короткое: иначе
   цена в соседних карточках ряда стояла бы на разной высоте, и сравнение
   значений — то, ради чего эта сетка существует, — разваливалось */
.ghead { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-height: 3.1em; }
/* Название переносится на вторую строку, а не обрезается: в колонке 940 px
   карточка уже 304 px, и «Индекс гособлигаций RGBI» многоточием терял именно
   то слово, по которому его ищут. Высота карточек в ряду выравнивается сеткой */
.gname { font-size: 14.5px; font-weight: 600; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.gsym { color: var(--muted); font-size: 12px; white-space: nowrap; padding-top: 3px; }
.gvals { display: flex; align-items: baseline; gap: 10px; margin: 6px 0 2px; }
.gprice { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; }
.gchg { font-size: 13px; font-variant-numeric: tabular-nums; }
.gchg.up { color: var(--green); }
.gchg.down { color: var(--red); }
/* Нулевое изменение серым, а не зелёным: цвет заявляет направление,
   которого у нуля нет */
.gchg.flat { color: var(--muted); }
.gchart { margin-top: 6px; }
.gchart svg { width: 100%; height: 150px; display: block; }
.gempty { color: var(--muted); font-size: 13px; padding: 40px 0; text-align: center; }
.gaxis { display: flex; justify-content: space-between; color: var(--muted); font-size: 11.5px; margin-top: 2px; font-variant-numeric: tabular-nums; }
.gfoot { display: flex; justify-content: space-between; gap: 8px; color: var(--muted); font-size: 11.5px; margin-top: 6px; min-height: 16px; }
/* Точка «идёт обновление»: без неё подмена разметки выглядит как мигание */
.ggrid[data-poll] .gtime::before {
  content: ''; display: inline-block; width: 5px; height: 5px; border-radius: 50%;
  background: var(--green); margin-right: 5px; vertical-align: middle;
}
/* Крестик лежит поверх угла карточки, но в разметке стоит рядом с ней:
   карточка — ссылка, и кнопка внутри неё открывала бы инструмент. Справа в
   шапке оставлено место, чтобы крестик не наезжал на короткое имя */
.gcell { position: relative; min-width: 0; display: flex; }
.gcell > .gcard { flex: 1; }
.gcell .ghead { padding-right: 22px; }
/* Перетаскивание: ручка — вся плитка, но курсор обещает перенос только на
   самой карточке, а не на крестике в её углу. Ссылку внутри тащить нельзя —
   иначе браузер потащил бы адрес инструмента вместо плитки */
.gcell[draggable] { cursor: grab; }
.gcell .gcard { cursor: inherit; }
/* Крестик — кнопка, и курсор у него свой: «схватить» над ним обещало бы
   перенос, которого не будет */
.gcell .ghide { cursor: pointer; }
.gcell.gdragging { opacity: .45; cursor: grabbing; }
.gcell.gdragging .gcard { border-style: dashed; border-color: var(--accent); }
/* Куда встанет плитка, показывает сам сдвиг соседей: подсвечивать ещё и
   пустое место значило бы рисовать рамку вокруг того, чего нет */
.ggrid.gdnd .gcell { transition: none; }
/* Стрелки переноса. Скрыты по умолчанию: без скрипта они ничего не делают,
   а место занимали бы. Класс js на <html> ставит сам скрипт — по нему и
   показываем. Лежат поверх нижнего правого угла, а не в потоке: ячейка —
   флекс из одной карточки, и третьим столбцом стрелки отняли бы у графика
   ширину. Верхний правый угол уже занят крестиком */
.gmove { display: none; position: absolute; right: 8px; bottom: 5px; gap: 4px; }
html.js .gmove { display: flex; }
/* Под стрелки оставлено место в подписи: иначе они наезжали бы на время */
html.js .gcell .gfoot { padding-right: 56px; }
.gmove button {
  width: 24px; height: 22px; padding: 0; border: 1px solid var(--border); border-radius: 6px;
  background: var(--card); color: var(--muted); cursor: pointer; font: inherit; font-size: 14px;
  line-height: 1; opacity: 0; pointer-events: none;
}
/* Наведение на карточку показывает стрелки: постоянно видимые, они спорили бы
   с ценой за внимание, а на тачскрине наведения нет — там они видны всегда.
   Клик невидимая стрелка не перехватывает: иначе угол карточки, где ничего не
   видно, открывал бы перенос вместо инструмента */
.gcell:hover .gmove button, .gmove button:focus-visible, .gcell:focus-within .gmove button { opacity: 1; pointer-events: auto; }
@media (hover: none) { .gmove button { opacity: .7; pointer-events: auto; } }
.gmove button:hover { color: var(--text); border-color: var(--accent); }
.gmove button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Кнопка сброса — та же пилюля, что у «вернуть скрытые»: появляется, когда
   сбрасывать есть что — скрытые карточки или свой порядок */
.greset { margin: 10px 0 0; }
.greset button {
  padding: 3px 10px; border-radius: 999px; font: inherit; font-size: 12.5px; cursor: pointer;
  color: var(--muted); background: transparent; border: 1px solid var(--border);
}
.greset button:hover { color: var(--text); border-color: var(--accent); }
.ghide { position: absolute; top: 9px; right: 8px; margin: 0; }
.ghide button {
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: 6px; cursor: pointer;
  background: transparent; color: var(--muted); font-size: 17px; line-height: 22px; opacity: .55;
}
.gcell:hover .ghide button, .ghide button:focus-visible { opacity: 1; }
.ghide button:hover { color: var(--text); background: rgba(255,255,255,.07); }
.ghide button:focus-visible { outline: 2px solid var(--accent); }
/* Полоса «Скрыто»: кнопки вернуть — те же пилюли, что у наборов */
.ghidden { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 14px 0 0; font-size: 12.5px; color: var(--muted); }
.ghidden form { margin: 0; }
.ghidden button {
  padding: 3px 10px; border-radius: 999px; font: inherit; cursor: pointer;
  color: var(--text); background: transparent; border: 1px solid var(--border);
}
.ghidden button:hover { border-color: var(--accent); }
.ghidden a { margin-left: 4px; }
/* Настройка доски — та же пилюля, что была в полосе наборов, только теперь
   стоит справа от интервала */
.gset {
  padding: 8px 14px; border-radius: 999px; font-size: 13px; text-decoration: none;
  color: var(--muted); background: transparent; border: 1px solid var(--border); white-space: nowrap;
}
.gset:hover { color: var(--text); border-color: var(--accent); }
/* Шестерёнка настройки — круглая и без подписи: слов в полосе и так много,
   а значок узнают. Размер тот же, что у пилюль рядом, чтобы строка не ехала */
.gcfg { padding: 0; width: 34px; height: 34px; display: inline-flex; align-items: center; justify-content: center; font-size: 15px; line-height: 1; }
/* «Добавить» — та же пилюля, что и шестерёнка, но с подписью: это главное
   действие вкладки «Мои», и значок «＋» без слов читался бы как что угодно */
.gadd { display: inline-flex; align-items: center; gap: 6px; padding: 0 14px; height: 34px; color: var(--text); font-size: 13.5px; }
.gadd:hover { color: var(--accent); }
/* Счётчик на вкладке «Мои»: у остальных вкладок числа нет, и лишний кружок
   рядом с подписью был бы шумом — поэтому он только здесь */
.gnum {
  margin-left: 6px; padding: 0 6px; border-radius: 999px; font-size: 11.5px; line-height: 17px;
  background: rgba(255,255,255,.1); color: inherit;
}
.gtab.on .gnum { background: rgba(255,255,255,.25); }
/* Пустая вкладка «Мои»: объяснение и кнопка по центру сетки. Ряд прочерков
   или пустое место человек прочитал бы как поломку */
.gempty-mine { max-width: 620px; padding: 22px; border: 1px dashed var(--border); border-radius: 14px; }
.gempty-mine p { margin: 0 0 14px; color: var(--muted); }
.gmine-lead { margin: 0 0 12px; }
/* Поиск на странице добавления: поле и кнопка в одну строку */
.vsearch { display: flex; gap: 8px; margin: 10px 0 0; }
.vsearch input {
  flex: 1; min-width: 0; padding: 9px 12px; border-radius: 10px; font: inherit; font-size: 15px;
  color: var(--text); background: var(--card); border: 1px solid var(--border);
}
.vsearch input:focus { outline: 2px solid var(--accent); outline-offset: 1px; border-color: var(--accent); }
.vcounter { margin: 4px 0 0; }
/* Живые подсказки под полем: список того, что нашлось, с кнопкой добавить.
   Показывается только когда есть что показать — пустая рамка под полем
   выглядела бы как недогруженная страница */
.vadd-dd { position: relative; }
.vadd-dd .vdd {
  margin: 8px 0 0; padding: 6px; border-radius: 12px; background: var(--card);
  border: 1px solid var(--border); box-shadow: 0 12px 32px rgba(0,0,0,.35);
}
.vadd-dd .vopt { padding: 6px 8px; border-radius: 8px; }
.vadd-dd .vopt:hover { background: #1f2630; }
.vdd-add { display: flex; justify-content: flex-end; margin-top: 6px; }
.gnone { margin: 6px 0 0; }
/* Страница настройки: группы по категориям, внутри — столбцы галочек */
.vform { margin-top: 10px; }
.vset { border: 1px solid var(--border); border-radius: 12px; padding: 10px 16px 14px; margin: 0 0 14px; background: var(--card); }
.vset legend { padding: 0 6px; font-weight: 600; }
.vgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 4px 18px; }
.vopt { display: flex; align-items: baseline; gap: 8px; padding: 5px 0; cursor: pointer; }
.vopt input { flex: none; accent-color: var(--accent); }
.vname { flex: 1; }
.vsrc { color: var(--muted); font-size: 12px; white-space: nowrap; }
.vbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 6px; }
/* Сброс стоит отдельно от «Сохранить»: между ним и формой выбора — черта,
   чтобы кнопка не читалась как ещё один способ применить галочки */
.vreset { margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--border); }
.vreset p { margin: 0 0 12px; }

@media (max-width: 640px) {
  .ggrid { grid-template-columns: 1fr; }
  /* На телефоне категории и интервал не делят строку: интервал уходит под
     них и занимает свой край, настройка остаётся рядом с ним */
  .gnav-right { margin-left: 0; }
  .gchart svg { height: 165px; }
  .gnav { margin-bottom: 16px; }
  .inst-chart .chart svg { height: 200px; }
}
/* График инструмента на широкой странице: та же ширина, что у сетки, поэтому
   свечи получают больше места по горизонтали, а не растягиваются в ленту */
.inst-chart .chart svg { height: 320px; }

/* ------------------------------------------------ сводные страницы: форум и FAQ
   Строка = одна ветка или один вопрос. Это список ссылок, а не карточки с
   текстом: сам разговор живёт на странице тикера, и второй полный текст здесь
   развёл бы один ответ по двум адресам */
.findex, .qalist { display: flex; flex-direction: column; gap: 2px; margin-top: 6px; }
.frow, .qarow {
  display: flex; flex-direction: column; gap: 4px; padding: 13px 16px;
  border-radius: 10px; text-decoration: none; color: var(--text);
  border: 1px solid transparent; transition: background .12s, border-color .12s;
}
.frow:hover, .qarow:hover { background: var(--card); border-color: var(--border); }
.frow + .frow, .qarow + .qarow { border-top: 1px solid var(--border); border-radius: 0; }
.ftitle, .qahead { font-weight: 600; font-size: 15.5px; line-height: 1.35; }
.qaprev { color: var(--muted); font-size: 13.5px; line-height: 1.45; }
.fmeta, .qameta {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  color: var(--muted); font-size: 12.5px; margin-top: 2px;
}
.fmeta .dot, .qameta .dot { opacity: .4; }
.fasset { color: var(--accent); }

/* ---------------------------------------------------------- карта рынка (3D)
   Карта живёт в той же колонке, что и остальные карточки: вынос за её пределы
   давал крупные плитки, но страница становилась непохожей на себя — заголовок
   и текст в 980 пикселях, карта во всё окно. Крупнее карту делают переключатель
   2D/3D и кнопка «на весь экран», а не постоянная ширина */
/* Переключатель рынков: общая карта и три отдельных. Он стоит над карточкой,
   а не внутри неё: это выбор страницы, а не вида карты, и рядом с кнопками
   2D/3D он читался бы как ещё один режим того же полотна */
.mm3d-markets { margin-bottom: 12px; }
.mm3d-lead { color: var(--muted); margin: -6px 0 14px; font-size: 14.5px; }
.mm3d-card { position: relative; }
.mm3d-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; font-size: 12.5px; color: var(--muted); margin-bottom: 8px; }
/* Точка перед подписью: зелёная — котировки живые, серая — из вечерней выгрузки.
   Это единственное место, где видно, свежие ли числа на карте */
.mm3d-live::before { content: '●'; margin-right: 6px; color: var(--muted); }
.mm3d-live.on::before { color: var(--green); }
.mm3d-ctl { display: inline-flex; align-items: center; gap: 10px; }
.mm3d-btns { display: inline-flex; gap: 4px; }
.mm3d-btns button {
  width: 30px; height: 28px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card2); color: var(--text); font-size: 14px; line-height: 1; cursor: pointer;
}
.mm3d-btns button:hover { border-color: var(--accent); }
.mm3d-btns button:active { background: #252c3a; }
/* Переключатель режима: две кнопки в общей рамке, нажатая залита. Отдельные
   кнопки-переключатели читались бы как ещё две команды, а это выбор вида */
.mm3d-mode { display: inline-flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; }
.mm3d-mode button {
  padding: 5px 9px; border: 0; background: var(--card2); color: var(--muted);
  font-size: 11.5px; font-weight: 600; letter-spacing: .02em; cursor: pointer;
}
.mm3d-mode button + button { border-left: 1px solid var(--border); }
.mm3d-mode button:hover { color: var(--text); }
.mm3d-mode button.on { background: rgba(47,129,247,.18); color: var(--text); }
/* В плоском виде поворачивать нечего: стрелки остались бы кнопками, которые
   нажимаются и ничего не делают */
.mm3d-card.flat .mm3d-btns [data-mm="left"],
.mm3d-card.flat .mm3d-btns [data-mm="right"],
.mm3d-card.flat .mm3d-btns [data-mm="up"],
.mm3d-card.flat .mm3d-btns [data-mm="down"] { display: none; }
/* На весь экран: карточка раскрывается поверх страницы, страница под ней не
   прокручивается. Крестик в правом верхнем углу закрывает этот вид */
.mm3d-card.full {
  position: fixed; inset: 0; z-index: 60; width: 100vw; height: 100vh;
  max-width: none; margin: 0; border-radius: 0; border: 0;
  padding: 10px 14px 12px; background: var(--card); overflow: auto;
}
html.mm3d-noscroll, html.mm3d-noscroll body { overflow: hidden; }
.mm3d-close {
  display: none; position: absolute; top: 6px; right: 6px; z-index: 7;
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--card2); color: var(--text); font-size: 18px; line-height: 1; cursor: pointer;
}
.mm3d-close:hover { border-color: var(--accent); }
.mm3d-card.full .mm3d-close { display: block; position: fixed; top: 10px; right: 12px; }
.mm3d-card.full .mm3d-bar { padding-right: 38px; }
/* Раскрывать то, что уже раскрыто, нечего: кнопка уступает место крестику */
.mm3d-card.full .mm3d-expand { display: none; }
.mm3d { position: relative; width: 100%; }
.mm3d canvas { display: block; width: 100%; margin: 0 auto; touch-action: none; cursor: default; }
.mm3d canvas.grab { cursor: grabbing; }
/* В плоском виде поворачивать нельзя, зато клик по плитке — единственное
   действие, поэтому курсор подсказывает клик, а не перетаскивание */
.mm3d-card.flat canvas { cursor: pointer; }
/* Подсказка следует за курсором и не перехватывает мышь: иначе она сама
   становится препятствием для наведения на соседнюю плитку */
.mm3d-tip {
  position: absolute; pointer-events: none; opacity: 0; transition: opacity .1s;
  background: rgba(22,27,34,.97); border: 1px solid var(--border); border-radius: 9px;
  padding: 7px 10px; font-size: 12px; line-height: 1.45; max-width: 220px;
  box-shadow: 0 8px 24px rgba(0,0,0,.5); z-index: 5;
}
.mm3d-tip.on { opacity: 1; }
.mm3d-tip b { font-variant-numeric: tabular-nums; }
.mm3d-tip .up { color: var(--green); font-weight: 600; }
/* Сектор подсказки — только на общей карте: на экране сектора он и так
   написан на нажатой кнопке */
.mm3d-tip .mm3d-tsec { color: var(--muted); }
.mm3d-tip .down { color: var(--red); font-weight: 600; }
/* Кнопки экранов: общая карта и каждый сектор отдельно. Строкой с переносом,
   а не выпадающим списком — так видно, из чего рынок состоит и сколько в
   каждом секторе веса, ещё до нажатия */
.mm3d-tabs { display: flex; flex-wrap: wrap; gap: 5px; margin: 0 0 8px; }
/* На телефоне двенадцать кнопок в перенос дают четыре строки над картой,
   поэтому там они едут одной полосой вбок */
@media (max-width: 760px) {
  .mm3d-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
  .mm3d-tabs::-webkit-scrollbar { display: none; }
}
.mm3d-tab {
  padding: 4px 10px; border-radius: 999px; border: 1px solid var(--border);
  background: var(--card2); color: var(--muted); font-size: 12px; text-decoration: none;
  white-space: nowrap;
}
.mm3d-tab:hover { border-color: var(--accent); color: var(--text); }
.mm3d-tab.on { background: rgba(47,129,247,.16); border-color: var(--accent); color: var(--text); }
.mm3d-tab span { color: var(--muted); font-variant-numeric: tabular-nums; margin-left: 3px; }
.mm3d-tab.on span { color: var(--text); }
/* Подпись экрана: что именно сейчас на карте. Показывается одна, остальные
   лежат в разметке готовыми — скрипт только переключает видимую */
.mm3d-cap { color: var(--muted); font-size: 12.5px; margin: -2px 0 8px; font-variant-numeric: tabular-nums; }
.mm3d-cap > span { display: none; }
.mm3d-cap > span.on { display: inline; }
/* Пояснение под картой: что означают площадь, цвет и высота. Без него высота
   читается как капитализация — площадь уже занята ею */
.mm3d-hint { color: var(--muted); font-size: 12.5px; margin: 10px 2px 0; max-width: 70em; line-height: 1.5; }
/* Про высоту сказано только в объёмном виде: в плоском её нет, и упоминать
   её значило бы обещать на карте то, чего на ней не видно */
.mm3d-hint-2d { display: none; }
.mm3d-card.flat .mm3d-hint-3d { display: none; }
.mm3d-card.flat .mm3d-hint-2d { display: block; }
.mm3d-noscript { color: var(--muted); font-size: 13px; padding: 20px 0; }
/* Пока скрипт не построил полотно, держим высоту: иначе страница прыгает,
   когда карта появляется, и человек теряет место чтения */
.mm3d:not(.ready) canvas { min-height: 380px; }
@media (max-width: 760px) {
  .mm3d:not(.ready) canvas { min-height: 300px; }
  .mm3d-hint { font-size: 12px; }
}

.mm3d-breadth { margin: 4px 0 14px; }
.mm3d-gauge { height: 10px; border-radius: 999px; background: rgba(248,81,73,.55); overflow: hidden; }
.mm3d-gauge .mm3d-up { display: block; height: 100%; background: var(--green); }
.mm3d-breadth p { color: var(--muted); font-size: 13.5px; margin: 8px 0 0; }
.mm3d-movers { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; }
@media (max-width: 640px) { .mm3d-movers { grid-template-columns: 1fr; gap: 8px; } }
.mm3d-movers h3 { margin: 8px 0 6px; }
.mm3d-movers ul { margin: 0; padding: 0; list-style: none; font-size: 13.5px; }
.mm3d-movers li { padding: 5px 0; border-bottom: 1px solid rgba(48,54,61,.5); display: flex; gap: 8px; justify-content: space-between; }
.mm3d-movers li b { font-variant-numeric: tabular-nums; white-space: nowrap; }
.mm3d-name { color: var(--muted); }
.mm3d-sym { font-weight: 700; }
.mm3d-sym, .mm3d-movers a { font-variant-numeric: tabular-nums; }
.mm3d-table td.num, .mm3d-table th.num { text-align: right; }
.mm3d-table .up { color: var(--green); }
.mm3d-table .down { color: var(--red); }
.mm3d-secs { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 26px; }
@media (max-width: 700px) { .mm3d-secs { grid-template-columns: 1fr; } }
.mm3d-sec { border-top: 1px solid rgba(48,54,61,.7); padding-top: 10px; }
.mm3d-sec h3 { margin: 0 0 4px; font-size: 13px; text-transform: none; letter-spacing: 0; color: var(--text); }
.mm3d-sec h3 .mm3d-share { color: var(--muted); font-weight: 500; margin-left: 4px; }
.mm3d-sec h3 b { float: right; font-variant-numeric: tabular-nums; }
.mm3d-meta { color: var(--muted); font-size: 12.5px; margin: 4px 0; }
.mm3d-ind { list-style: none; margin: 8px 0; padding: 0; font-size: 12.5px; }
.mm3d-ind li { display: flex; gap: 8px; padding: 3px 0; border-bottom: 1px solid rgba(48,54,61,.35); }
.mm3d-ind li span:first-child { flex: 1; color: var(--text); }
.mm3d-ind .mm3d-ic { color: var(--muted); font-variant-numeric: tabular-nums; }
.mm3d-ind b { font-variant-numeric: tabular-nums; min-width: 58px; text-align: right; }
.mm3d .up, .mm3d-movers .up, .mm3d-sec .up, .mm3d-meta .up { color: var(--green); }
.mm3d .down, .mm3d-movers .down, .mm3d-sec .down, .mm3d-meta .down { color: var(--red); }
.mm3d .flat, .mm3d-movers .flat, .mm3d-sec .flat { color: var(--muted); }
