/* Макет «Треугольник ISS»: строгий первый экран. В центре — треугольник: три стороны — три направления, тело — кнопка заявки
   со значком-зовом; слова говорит строка состояния сверху. Верхней панели нет; внизу тихая строка: язык, подпись платформы,
   контакты, звук. После первого экрана — контакты. */

/* Onest (переменный, wght 100–900): латиница с узбекскими ʻ и ‘ — и кириллица, по одному файлу на набор. */
@font-face {
  font-family: "Onest";
  src: url("vendor/onest/onest-latin-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
    U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Onest";
  src: url("vendor/onest/onest-cyrillic-wght-normal.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

/* Угол бегущего света по рамке контактов: зарегистрированное свойство, чтобы угол плавно анимировался. */
@property --c-a {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

:root {
  color-scheme: dark;
  --bg: #000;
  --fg: #ededed;
  --fg-2: #a1a1a1;     /* вторичный текст: подписи строк контактов, кнопки подвала */
  --fg-panel: #bdbdbd; /* пункты панели и строка состояния стоят в свете — светлее вторичного, чтобы держать 4.5:1 */
  --credit: #777;      /* подпись платформы — самая тихая строка (≈ 4.7:1 на чёрном) */
  --hair: rgb(255 255 255 / 0.1);        /* тонкие линейки: разделители пунктов, рамка контактов */
  --grid-line: rgb(255 255 255 / 0.05);  /* инженерная сетка */
  /* Цвета сторон — по образцам Отабека: зал синий, поддержка розовая, бездиск зелёный, вершина фиолетовая. */
  --hall: #6a9cff;
  --support: #ff4f8b;
  --diskless: #6fd4a0;
  --apex: #b07ae8;
  --radius: 8px;
  --status-top: 12px;
  --status-h: 44px;
  --gutter: 40px;
  --maxw: 1440px;
  /* Треугольник и всё внутри него — в единицах рисунка (сторона = 280): знак ISS, волосяная линия, подпись, значок-зов.
     Места и кегли — по ширинам (шагами): так знак и значок стоят на месте и без JS. На экране: знак ≈ 25–30 px, подпись
     8.5–9 px, кольцо значка 28–32 px, его линия 1.5 px. */
  --tri: 250px;
  --u: calc(var(--tri) / 280); /* одна единица рисунка в CSS-пикселях */
  --mark: 34px;       /* кегль ISS */
  --mark-y: -12.56px; /* базовая линия ISS */
  --rule-y: -4.72px;  /* волосяная линия: верх, высота (1 CSS-px), ширина */
  --rule-h: 1.12px;
  --rule-w: 83.6px;
  --cap-fs: 10px;     /* «iT SOFT SERVICE»: кегль, разрядка (доля em), базовая линия */
  --cap-t: 0.2;
  --cap-y: 10.19px;
  --call-y: 42.67px;  /* центр значка-зова, масштаб сетки 24×24 и толщина линии в её единицах (= 1.5 CSS-px) */
  --call-k: 1.792;
  --call-sw: 0.938;
  --cell: 64px;                /* клетка сетки */
  --grid-w: 1680px;
  --grid-h: 1040px;
  --ease: cubic-bezier(0.215, 0.61, 0.355, 1);  /* как power2.out у GSAP — свет и панель */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);    /* отклик кнопки, значки */
}

/* ── Поверхности браузера: выделение, фокус, полоса прокрутки, подчёркивания — из палитры ── */
html {
  background: var(--bg);
  color: var(--fg);
  accent-color: var(--fg);
  caret-color: var(--fg);
  scrollbar-color: #2e2e2e var(--bg);
  scrollbar-width: thin;
  -webkit-tap-highlight-color: transparent;
}
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; } /* «Aloqa» в подвале плавно ведёт к контактам */
}
::selection { background: rgb(106 156 255 / 0.42); color: #fff; }
::-webkit-scrollbar { width: 10px; height: 10px; background: var(--bg); }
::-webkit-scrollbar-thumb { background: #2e2e2e; border: 2px solid var(--bg); border-radius: 8px; }
:focus-visible { outline: 2px solid var(--fg); outline-offset: 3px; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "Onest", ui-sans-serif, system-ui, sans-serif;
  font-size: 15px; /* рабочий текст — пункты панели. Ниже — 12 (подпись платформы), 13–14 (строка состояния, подвал,
                      подписи контактов); выше — 18 / 20 (название направления), 24 (номер), 28 (заголовок контактов) */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
}
/* Первый экран — вся высота окна: строка состояния сверху, треугольник с панелью по центру, строка подвала внизу. */
.screen {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Первый экран: треугольник и под ним место панели, всё по центру ── */
.hero {
  --st-c: var(--apex);   /* цвет точки строки состояния: покой — вершина, сторона — её цвет */
  --st-glyph: #d9c6ff;   /* цвет знаков во время расшифровки строки */
  position: relative;
  isolation: isolate;
  overflow: clip;
  box-sizing: border-box;
  flex: 1 0 auto;
  /* Сверху — место строки состояния; снизу столько же: блок по центру стоит там же, где стоял без неё. */
  padding: calc(var(--status-top) + var(--status-h) + 8px) var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  align-content: center; /* блок «треугольник + место панели» по центру — сам треугольник выше середины */
  row-gap: calc(var(--u) * 11); /* панель начинается на 80 единиц ниже основания: там свет основания уже спал */
  background: var(--bg);
}
.hero[data-emph="hall"] { --st-c: var(--hall); --st-glyph: #b3cbff; }
.hero[data-emph="support"] { --st-c: var(--support); --st-glyph: #ffa3c2; }
.hero[data-emph="diskless"] { --st-c: var(--diskless); --st-glyph: #b3ebce; }

/* ── Строка состояния: живая точка и текст, сверху по центру — не панель: без подложки, рамки и кнопок. Ссылка на бота.
   Коробка текста занята всеми четырьмя строками языка сразу (невидимыми) — при смене ничего не сдвигается; видимая
   строка — слева в этой коробке, точка стоит на месте. ── */
.status {
  position: absolute;
  z-index: 3;
  /* Слева и справа — поля страницы, ширина по содержимому, поля auto — по центру (с left: 50% ширина сжималась бы до
     половины экрана и строка ломалась на телефоне). */
  top: var(--status-top);
  left: calc(var(--gutter) - 12px);
  right: calc(var(--gutter) - 12px);
  width: fit-content;
  margin: 0 auto;
  box-sizing: border-box;
  min-height: var(--status-h);
  padding: 0 12px;
  display: flex;
  align-items: center;
  gap: 10px;
  border-radius: var(--radius);
  color: var(--fg-panel);
  font-size: 13px;
  line-height: 18px;
  font-weight: 450;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: color 150ms var(--ease);
}
.st-dot {
  position: relative;
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--st-c);
  transition: background-color 300ms var(--ease);
}
/* «Живая» точка: от неё расходится и гаснет кольцо, раз в 2.4 с. */
.st-dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--st-c);
  animation: st-pulse 2.4s var(--ease-out) infinite;
}
@keyframes st-pulse {
  0% { transform: scale(1); opacity: 0.6; }
  70%, 100% { transform: scale(3.4); opacity: 0; }
}
.st-text { display: grid; text-align: left; }
.st-text > * { grid-area: 1 / 1; }
.st-size { visibility: hidden; }
.st-scr { color: var(--st-glyph); }  /* знаки на фронте расшифровки */
.st-old { opacity: 0.4; }            /* остаток прежней строки, который фронт ещё не прошёл */
.status:hover { color: var(--fg); }
.status:hover .st-live {
  text-decoration: underline 1px rgb(237 237 237 / 0.45);
  text-underline-offset: 5px;
}

/* Слои: свет (0) → сетка (1, осветлением поверх света) → треугольник и панель (2). .stage слоя не создаёт. */
.stage {
  position: relative;
  width: calc(var(--u) * 400);
  display: grid;
  place-items: center;
}
.tri {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* Коробка света: x −430…430, y −440…330 в единицах рисунка; центр — на 30 единиц выше центра рисунка. */
.light {
  position: absolute;
  z-index: 0;
  left: 50%;
  top: 50%;
  width: calc(var(--u) * 860);
  height: calc(var(--u) * 770);
  translate: -50% calc(-50% - var(--u) * 30);
  isolation: isolate;
  background: #000; /* зерно смешивается с чёрным, а не с пустотой: вне света остаётся чистый чёрный */
  pointer-events: none;
}
.light-img, .light-side, .grain, .light-gl { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
/* Зерно не доходит до краёв коробки (там свет уже чёрный): край слоя с наложением не даёт полоски в 1px. */
.grain { inset: 4px; width: calc(100% - 8px); height: calc(100% - 8px); opacity: 0.4; mix-blend-mode: soft-light; }
/* Шейдер проявляется поверх запасного кадра, когда отрисовал первый кадр (кадр покоя совпадает с растром — перехода не
   видно); после проявления растр и зерно снимаются совсем (hero.js ставит gl-done). */
.light-gl { opacity: 0; transition: opacity 700ms linear; }
.hero.gl-on .light-gl { opacity: 1; }
.hero.gl-done .light-img,
.hero.gl-done .grain { display: none; }
/* Без WebGL (hero.js ставит gl-off) свет — растры: кадр покоя внизу, над ним проявляется кадр выбранной стороны (кадр
   покоя остаётся под ним — переход без провала яркости). Картинки сторон грузятся только в этом случае. */
.light-img { transition: filter 320ms var(--ease-out); }
.light-side {
  background: center / 100% 100% no-repeat;
  opacity: 0;
  transition: opacity 420ms var(--ease), filter 320ms var(--ease-out);
}
.hero.gl-off .light-side[data-dir="hall"] { background-image: url("light-hall.webp"); }
.hero.gl-off .light-side[data-dir="support"] { background-image: url("light-support.webp"); }
.hero.gl-off .light-side[data-dir="diskless"] { background-image: url("light-diskless.webp"); }
.hero.gl-off[data-light="hall"] .light-side[data-dir="hall"],
.hero.gl-off[data-light="support"] .light-side[data-dir="support"],
.hero.gl-off[data-light="diskless"] .light-side[data-dir="diskless"] { opacity: 1; }
/* Наведение на тело треугольника поднимает свет и здесь (как шейдер: заметно, а не на пару уровней). */
.hero:has(.cta:hover) :is(.light-img, .light-side),
.hero:has(.cta:focus-visible) :is(.light-img, .light-side) { filter: brightness(1.8); }

/* «Дыхание» вершины: мягкое фиолетовое свечение над остриём, период ≈ 4.6 с туда и обратно; блик на стекле (.sheen)
   дышит в той же фазе. Только в покое: выбрана сторона — гаснет. Отдельный слой с одной прозрачностью — шейдер ради
   него не перерисовывается. */
.apex-breath {
  position: absolute;
  left: 50%;
  top: 36.15%; /* вершина: y −161.66 в коробке −440…330 */
  width: calc(var(--u) * 210);
  height: calc(var(--u) * 210);
  translate: -50% -50%;
  mix-blend-mode: screen;
  transition: opacity 420ms var(--ease);
}
.apex-breath::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgb(176 122 232 / 0.42), rgb(176 122 232 / 0.12) 45%, transparent 100%);
  opacity: 0.5;
  animation: apex-breath 2.3s ease-in-out infinite alternate;
}
@keyframes apex-breath {
  from { opacity: 0.3; }
  to { opacity: 0.75; }
}
.hero:not([data-light="none"]) .apex-breath { opacity: 0; }

/* Блик на стекле: мягкая косая полоса по верхней трети тела, дышит вместе с вершиной. Слой над рисунком, обрезан по
   треугольнику (вершины — в долях коробки рисунка 400×350) и маской гаснет ниже верхней трети; до знака ISS не доходит. */
.sheen {
  position: absolute;
  z-index: 3;
  inset: 0;
  pointer-events: none;
  clip-path: polygon(50% 10.95%, 85% 80.24%, 15% 80.24%);
  /* Полоса наклонена на 20° («/»), середина проходит через (50%, 24%) коробки — это 31.6% длины линии перехода при 160°. */
  background: linear-gradient(160deg, transparent 26%, rgb(230 220 255 / 0.24) 31%, rgb(230 220 255 / 0.07) 34.5%, transparent 38.5%);
  -webkit-mask-image: linear-gradient(to bottom, #000 30%, transparent 38%);
  mask-image: linear-gradient(to bottom, #000 30%, transparent 38%);
  mix-blend-mode: screen;
  opacity: 0.5;
  animation: apex-breath 2.3s ease-in-out infinite alternate;
}

/* Инженерная сетка: линии в 1px через клетку, одна линия проходит через центр тяжести треугольника.
   Маска гасит её от треугольника к краям; осветление (screen) не даёт ей спорить со светом. */
.grid-lines {
  position: absolute;
  z-index: 1;
  left: 50%;
  top: 50%;
  width: var(--grid-w);
  height: var(--grid-h);
  translate: -50% calc(-50% + var(--u) * 25);
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: var(--cell) var(--cell);
  background-position: calc(50% + var(--cell) / 2) calc(50% + var(--cell) / 2);
  -webkit-mask-image: radial-gradient(closest-side, #000, rgb(0 0 0 / 0.7) 35%, transparent);
  mask-image: radial-gradient(closest-side, #000, rgb(0 0 0 / 0.7) 35%, transparent);
  mix-blend-mode: screen;
  pointer-events: none;
}

/* ── Тело треугольника — кнопка заявки. Материал — обсидиан: свет из-за спины входит внутрь от каждой стороны широкой
   мягкой полосой (линия 40 единиц, размытие 11), к середине стекло темнеет (тёмный треугольник, отступивший от сторон
   на 30 единиц и размытый — ровно по расстоянию до ближайшей стороны; там знак и значок — контраст ≥ 4.5), блик от
   вершины, тонкая цветная кромка изнутри. Выбранная сторона светит внутрь сильнее, две другие тише. ── */
.tri .cta {
  cursor: pointer;
  outline: none;
  transform-box: view-box;
  transform-origin: 0 0; /* центр тяжести */
  transition: transform 220ms var(--ease-out);
}
.body { fill: url(#obs-fill); }
.spec { opacity: 0.8; transition: opacity 320ms var(--ease-out); }
.core { fill: #000; opacity: 0.85; }
/* Свет внутри: в покое ≈ 0.5 (0.85 × 0.6), выбранная сторона ≈ 0.85, две другие ≈ 0.2. */
.glows { opacity: 0.85; transition: opacity 320ms var(--ease-out); }
.glow { fill: none; stroke-width: 40; stroke-linecap: round; opacity: 0.6; transition: opacity 420ms var(--ease); }
.rim { fill: none; stroke-width: 1; vector-effect: non-scaling-stroke; opacity: 0.5; transition: opacity 420ms var(--ease); }
.hero:not([data-light="none"]) .glow { opacity: 0.24; }
.hero:not([data-light="none"]) .rim { opacity: 0.2; }
.hero[data-light="hall"] .glow[data-dir="hall"],
.hero[data-light="support"] .glow[data-dir="support"],
.hero[data-light="diskless"] .glow[data-dir="diskless"] { opacity: 1; }
.hero[data-light="hall"] .rim[data-dir="hall"],
.hero[data-light="support"] .rim[data-dir="support"],
.hero[data-light="diskless"] .rim[data-dir="diskless"] { opacity: 0.95; }

/* Знак: ISS полужирным с широкой разрядкой (S–S на 0.03 em плотнее: у двух округлых букв просвет кажется шире), под ним
   волосяная линия, гаснущая к концам, и мелкая подпись с разрядкой тонким начертанием — контраст веса и кегля вместо
   украшений. Разрядка добавляет место и после последней буквы — сдвиг на её половину возвращает знак в центр. */
.mark {
  font-family: "Onest", ui-sans-serif, system-ui, sans-serif;
  font-size: var(--mark);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-anchor: middle;
  fill: #f4f4f4;
  transform: translate(calc(var(--mark) * 0.085), var(--mark-y));
}
.mark-s1 { letter-spacing: 0.17em; }
.mark-rule {
  x: calc(var(--rule-w) / -2);
  y: var(--rule-y);
  width: var(--rule-w);
  height: var(--rule-h);
}
.mark-cap {
  font-family: "Onest", ui-sans-serif, system-ui, sans-serif;
  font-size: var(--cap-fs);
  font-weight: 450;
  letter-spacing: calc(var(--cap-t) * 1em);
  text-anchor: middle;
  fill: var(--fg-panel);
  transform: translate(calc(var(--cap-fs) * var(--cap-t) / 2), var(--cap-y));
}

/* ── Значок-зов: кольцо в волосяную линию (1.5 CSS-px), по нему бежит точка света с коротким хвостом — оборот 6.4 с; её
   цвет следует за гранью, мимо которой она проходит (сверху — фиолетовый вершины, справа — синий зала, снизу — зелёный
   основания, слева — розовый поддержки). Внутри стрелка. Наведение и фокус (у мыши — после 120 мс намерения): кольцо
   наливается светом, стрелка темнеет и уходит на 3 px вправо, под кольцом загорается мягкое пятно, свет за треугольником
   поднимается (hero.js). Нажатие — волна от кольца. «Уменьшить движение» — точка стоит сверху, фиолетовая. ── */
.call-pos { transform: translate(0, var(--call-y)) scale(var(--call-k)); }
.call-bloom { opacity: 0; transition: opacity 320ms var(--ease-out); }
.call-fill { fill: #ededed; fill-opacity: 0.03; transition: fill-opacity 220ms var(--ease-out); }
.call-ring {
  fill: none;
  stroke: rgb(237 237 237 / 0.45);
  stroke-width: var(--call-sw);
  transition: stroke 220ms var(--ease-out);
}
.call-hue {
  color: #cdb8ff;
  animation: call-hue 6.4s linear infinite;
  transition: opacity 180ms var(--ease-out);
}
.call-head, .call-tail {
  fill: none;
  stroke: currentColor;
  stroke-width: calc(var(--call-sw) * 1.35);
  stroke-linecap: round;
}
.call-head { stroke-dasharray: 0.035 0.965; animation: call-run 6.4s linear infinite; }
.call-tail { stroke-dasharray: 0.14 0.86; stroke-dashoffset: 0.105; opacity: 0.4; animation: call-run-tail 6.4s linear infinite; }
@keyframes call-run { from { stroke-dashoffset: 0; } to { stroke-dashoffset: -1; } }
@keyframes call-run-tail { from { stroke-dashoffset: 0.105; } to { stroke-dashoffset: -0.895; } }
@keyframes call-hue {
  0%, 100% { color: #cdb8ff; }
  16.7% { color: #a9c3ff; }
  50% { color: #a4e6c3; }
  83.3% { color: #ff93b8; }
}
.call-arrow {
  fill: none;
  stroke: var(--fg);
  stroke-width: var(--call-sw);
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 220ms var(--ease-out), stroke 180ms var(--ease-out);
}
.call-ripple {
  fill: none;
  stroke: #ededed;
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}
.cta.is-press .call-ripple,
.cta:active .call-ripple { animation: call-ripple 520ms var(--ease-out) both; }
@keyframes call-ripple {
  from { opacity: 0.8; transform: scale(1); }
  to { opacity: 0; transform: scale(2.2); }
}

/* Наведение и фокус на теле: тело чуть растёт (×1.02), свет за ним заметно поднимается (hero.js: сила сторон шейдера
   ×2.2, без WebGL — яркость растров ×1.8), три кромки в полную силу, значок-зов наливается светом. У мыши — задержка
   намерения 120 мс, как у сторон: пролёт через тело к панели ничего не зажигает; фокус — сразу. */
@media (hover: hover) {
  .tri .cta:hover, .cta:hover :is(.glows, .spec, .rim, .call-bloom, .call-fill, .call-ring, .call-hue, .call-arrow),
  .hero:has(.cta:hover) :is(.light-img, .light-side) { transition-delay: 120ms; }
  .tri .cta:hover { transform: scale(1.02); }
  .cta:hover :is(.glows, .spec) { opacity: 1; }
  .hero .tri .cta:hover .rim { opacity: 1; }
  .cta:hover .call-bloom { opacity: 1; }
  .cta:hover .call-fill { fill-opacity: 0.94; }
  .cta:hover .call-ring { stroke: #ededed; }
  .cta:hover .call-hue { opacity: 0; }
  .cta:hover .call-arrow { stroke: #0a0a0a; transform: translateX(1.9px); }
}
.tri .cta:focus-visible { transform: scale(1.02); }
.cta:focus-visible :is(.glows, .spec) { opacity: 1; }
.hero .tri .cta:focus-visible .rim { opacity: 1; }
.cta:focus-visible .call-bloom { opacity: 1; }
.cta:focus-visible .call-fill { fill-opacity: 0.94; }
.cta:focus-visible .call-ring { stroke: #ededed; }
.cta:focus-visible .call-hue { opacity: 0; }
.cta:focus-visible .call-arrow { stroke: #0a0a0a; transform: translateX(1.9px); }
/* Нажатие — короткий «провал» на 120 мс. */
.tri .cta:active { transform: scale(0.985); transition-duration: 120ms; transition-delay: 0s; }
.cta:active .glows { opacity: 0.6; transition-duration: 120ms; transition-delay: 0s; }

/* Широкая невидимая полоса стороны (8 единиц внутрь, 68 наружу) — цель наведения, нажатия и Tab.
   Внутренность треугольника остаётся за кнопкой заявки. */
.tri .hit {
  fill: transparent;
  stroke: none;
  pointer-events: fill;
  cursor: pointer;
  outline: none;
}
.ring, .cta-ring {
  fill: none;
  stroke: var(--fg);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  opacity: 0;
  pointer-events: none;
}
.hit:focus-visible + .ring,
.cta:focus-visible .cta-ring { opacity: 1; }

/* ── Панель направления под треугольником. Не карточка: значок цветом стороны, название, три пункта. В покое пусто;
   все три панели лежат в одной ячейке — место занято самой длинной, ничего не прыгает. ── */
.dirs {
  position: relative;
  z-index: 2;
  width: min(100%, 696px);
  /* Место под панель занято заранее и одинаково в обоих языках: значок 40 + отступ 12 + название 28 + отступ 18 + три
     строки по 22 (колонки по 232px держат любой пункт в три строки и по-узбекски, и по-русски). */
  min-height: calc(52px + 28px + 18px + 3 * 22px);
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
}
.dir {
  grid-area: 1 / 1;
  text-align: center;
  opacity: 0;
  visibility: hidden;
  translate: 0 6px;
  transition: opacity 180ms var(--ease), translate 180ms var(--ease), visibility 0s linear 180ms;
}
.dir.is-emph {
  opacity: 1;
  visibility: visible;
  translate: 0 0;
  transition: opacity 260ms var(--ease) 60ms, translate 260ms var(--ease) 60ms, visibility 0s;
}
.dir[data-dir="hall"] { --c: var(--hall); }
.dir[data-dir="support"] { --c: var(--support); }
.dir[data-dir="diskless"] { --c: var(--diskless); }

/* Значок направления: сетка 24×24, линии 1.5px (0.9 единицы при 40px), скруглённые концы, цвет стороны. При появлении
   панели линии рисуются по очереди и значок «садится» на место — не дольше 700 мс, один раз за показ; пока панель видна,
   у зала мигает огонёк сервера, у поддержки — микрофон. При «уменьшить движение» — сразу последний кадр. */
.dir-icon {
  display: block;
  width: 40px;
  height: 40px;
  margin: 0 auto 12px;
  overflow: visible;
}
.dir-icon .ln {
  fill: none;
  stroke: var(--c);
  stroke-width: 0.9;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1 1;
}
.dir-icon .live { fill: var(--c); }
.dir.is-emph .dir-icon { animation: icon-settle 680ms var(--ease-out) both; }
.dir.is-emph .dir-icon .ln { animation: stroke-draw 560ms var(--ease-out) calc(var(--i) * 70ms) both; }
.dir.is-emph .dir-icon .live { animation: live-in 160ms linear 520ms both, live-pulse 2.4s ease-in-out 1.4s infinite; }
@keyframes stroke-draw {
  from { stroke-dashoffset: 1; opacity: 0; }
  10% { opacity: 1; }
  to { stroke-dashoffset: 0; opacity: 1; }
}
@keyframes icon-settle {
  from { transform: translateY(3px) scale(0.94); }
  to { transform: none; }
}
@keyframes live-in {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes live-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

.dir-title {
  margin: 0 0 18px;
  font-size: 20px;
  line-height: 28px;
  font-weight: 600;
  letter-spacing: -0.015em;
  text-wrap: balance;
  color: var(--fg);
}
.dir-points {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.dir-points li {
  padding: 0 24px;
  font-size: 15px;
  line-height: 22px;
  text-align: left; /* колонки по верхнему краю, текст в колонке — по левому; название над ними — по центру */
  text-wrap: pretty;
  color: var(--fg-panel);
}
.dir-points li + li { box-shadow: inset 1px 0 0 var(--hair); }

/* ── Подвал первого экрана: язык слева, подпись платформы по центру — самая тихая строка (12 px, #777), справа ссылка
   на контакты и звук — выше её по весу и кеглю (13 px, 500, #a1a1a1) ── */
.foot {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  grid-template-areas: "lang credit end";
  align-items: center;
  column-gap: 12px;
  box-sizing: border-box;
  width: 100%;
  max-width: var(--maxw);
  min-height: 56px;
  margin: 0 auto;
  padding: 0 calc(var(--gutter) - 12px) env(safe-area-inset-bottom, 0px);
  font-size: 13px;
  line-height: 16px;
  color: var(--fg-2);
}
/* Язык — сегментированный переключатель: в дорожке с волосяной линией два сегмента равной ширины (переключение ничего
   не сдвигает), в каждом флаг и название языка на нём самом. Выбранный стоит на светлой плашке (::before) — виден не
   только цветом; плашка переезжает к нажатому, но не при старте (класс is-ready ставит hero.js) и не при «уменьшить
   движение». Видимая дорожка 36 px, цель нажатия 44 px: кнопки выходят за дорожку на 5 px вверх и вниз. Левый край
   дорожки — на поле страницы, как правый край значка звука. Скругления вложены: дорожка 8, плашка и фокус 8 − 1 − 3 = 4. */
.lang {
  grid-area: lang;
  justify-self: start;
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  box-sizing: border-box;
  height: 36px;
  margin-inline-start: 12px;
  padding: 0 3px;
  border: 1px solid var(--hair);
  border-radius: var(--radius);
}
.lang::before {
  content: "";
  position: absolute;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: calc(50% - 3px);
  border-radius: 4px;
  background: rgb(255 255 255 / 0.1);
}
.lang:has(.lang-opt[data-lang="ru"][aria-pressed="true"])::before { translate: 100% 0; }
.lang.is-ready::before { transition: translate 260ms var(--ease-out); }
.lang-opt {
  position: relative; /* над плашкой */
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 44px;
  margin-block: -5px;
  padding: 0 12px;
  border: 0;
  border-radius: 4px;
  background: none;
  color: var(--fg-2);
  font: inherit;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: color 150ms var(--ease);
}
.lang-opt:hover, .lang-opt[aria-pressed="true"] { color: var(--fg); }
/* Фокус с клавиатуры — обводка по сегменту (высота плашки 28 px), а не по всей цели нажатия; утоплена на 1 px, чтобы
   у краёв дорожки между ней и волосяной линией оставалось 2 px. */
.lang-opt:focus-visible { outline: none; }
.lang-opt:focus-visible::after {
  content: "";
  position: absolute;
  inset: 8px 0;
  border-radius: 4px;
  outline: 2px solid var(--fg);
  outline-offset: -1px;
}
/* Флаг: скругление 2 px; невыбранный приглушён, при наведении и выборе — в полный цвет. Кольцо 10 % белого держит край
   флага на чёрном. Красные каймы Узбекистана — 1 px при 1x, на плотных экранах тоньше и всё так же по пикселям
   устройства: 0,5 px при 2x, ⅓ px при 3x (сжатие вокруг середины — белая полоса и эмблема стоят на месте). */
.flag {
  display: block;
  flex: none;
  translate: 0 -1px; /* центр флага — на середине прописных (замер: без сдвига ниже на 0,67 px); целый пиксель — чётко */
  border-radius: 2px;
  opacity: 0.6;
  transition: opacity 150ms var(--ease);
}
.lang-opt:hover .flag, .lang-opt[aria-pressed="true"] .flag { opacity: 1; }
.flag-ring { stroke: var(--hair); }
.flag-fimb { transform-box: fill-box; transform-origin: center; }
@media (min-resolution: 2dppx) { .flag-fimb { transform: scaleY(calc(5 / 6)); } }
@media (min-resolution: 3dppx) { .flag-fimb { transform: scaleY(calc(7 / 9)); } }
.lang-code { display: none; letter-spacing: 0.08em; }
.powered {
  grid-area: credit;
  justify-self: center;
  margin: 0;
  font-size: 12px; /* «прям мелким шрифтом» (Отабек) */
  font-weight: 400;
  letter-spacing: 0.02em;
  white-space: nowrap;
  color: var(--credit);
}
.foot-end { grid-area: end; justify-self: end; display: flex; align-items: center; gap: 2px; }
.foot-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 10px;
  border-radius: 4px;
  color: var(--fg-2);
  font-weight: 500;
  text-decoration: underline 1px transparent;
  text-underline-offset: 6px;
  transition: color 150ms var(--ease), text-decoration-color 150ms var(--ease);
}
.foot-link:hover { color: var(--fg); text-decoration-color: currentColor; }
/* Звук: значок-динамик (линия 1.5px). Включён — волны; выключен — крестик; смена рисуется. */
.sound {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: none;
  color: var(--fg-2);
  cursor: pointer;
  transition: color 150ms var(--ease);
}
.sound:hover, .sound[aria-pressed="true"] { color: var(--fg); }
.sound svg {
  width: 20px;
  height: 20px;
  overflow: visible;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.sp-on, .sp-off { stroke-dasharray: 1 1; transition: stroke-dashoffset 260ms var(--ease-out), opacity 140ms linear; }
.sound[aria-pressed="true"] .sp-off,
.sound[aria-pressed="false"] .sp-on { stroke-dashoffset: 1; opacity: 0; }

/* ── Контакты: сразу после первого экрана. Рамка в волосяную линию на инженерной сетке; по рамке бежит свет цветов
   граней (оборот 10 с); при появлении — линия сканирования сверху вниз и вспышка строк их цветом (всё ≤ 700 мс, один раз),
   цифры номера «расшифровываются» (hero.js). Строка загорается своим цветом при наведении и фокусе: номер Руслана —
   розовым (поддержка, работа с клиентами), бот — фиолетовым (вершина, цвет действия). Не карточки: одна рамка, две
   строки через линейку. ── */
.contacts {
  position: relative;
  isolation: isolate;
  overflow: clip;
  display: grid;
  justify-items: center;
  row-gap: 28px;
  padding: 104px var(--gutter) 120px;
  scroll-margin-top: 0;
}
.c-grid {
  position: absolute;
  z-index: -1;
  inset: 0;
  background-image:
    linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
    linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
  background-size: var(--cell) var(--cell);
  background-position: calc(50% + var(--cell) / 2) 0;
  -webkit-mask-image: radial-gradient(closest-side at 50% 55%, #000, rgb(0 0 0 / 0.6) 45%, transparent);
  mask-image: radial-gradient(closest-side at 50% 55%, #000, rgb(0 0 0 / 0.6) 45%, transparent);
  pointer-events: none;
}
.c-title {
  margin: 0;
  font-size: 28px;
  line-height: 34px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--fg);
}
/* Обёртка рамки несёт метки углов — как на инженерном чертеже: по два штриха 10 px у каждого угла, в 8 px от рамки. */
.c-wrap {
  --tick: rgb(255 255 255 / 0.3);
  position: relative;
  width: min(100%, 620px);
}
.c-wrap::before {
  content: "";
  position: absolute;
  inset: -9px;
  background:
    linear-gradient(var(--tick) 0 0) left top / 10px 1px no-repeat,
    linear-gradient(var(--tick) 0 0) left top / 1px 10px no-repeat,
    linear-gradient(var(--tick) 0 0) right top / 10px 1px no-repeat,
    linear-gradient(var(--tick) 0 0) right top / 1px 10px no-repeat,
    linear-gradient(var(--tick) 0 0) left bottom / 10px 1px no-repeat,
    linear-gradient(var(--tick) 0 0) left bottom / 1px 10px no-repeat,
    linear-gradient(var(--tick) 0 0) right bottom / 10px 1px no-repeat,
    linear-gradient(var(--tick) 0 0) right bottom / 1px 10px no-repeat;
  pointer-events: none;
}
/* Строки стоят внутри рамки с отступом 8 px: свет строки не упирается в линию рамки. */
.c-frame {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  padding: 8px;
  border-radius: var(--radius);
  background: #050506;
  box-shadow: inset 0 0 0 1px var(--hair);
  overflow: clip;
}
/* Бегущий свет по рамке: коническая заливка, от которой маска оставляет только линию в 1px по краю. */
.c-frame::before {
  content: "";
  position: absolute;
  z-index: 2;
  inset: 0;
  padding: 1px;
  border-radius: inherit;
  background: conic-gradient(from var(--c-a), transparent 0deg 262deg, rgb(176 122 232 / 0.9) 292deg, rgb(106 156 255 / 0.9) 316deg,
    rgb(111 212 160 / 0.9) 334deg, rgb(255 79 139 / 0.9) 350deg, transparent 360deg);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0.75;
  animation: c-run 10s linear infinite;
  pointer-events: none;
}
@keyframes c-run { to { --c-a: 360deg; } }
/* Линия сканирования: слой во всю рамку, линия у его нижнего края со светлым следом над ней; при появлении слой
   проезжает сверху вниз (hero.js ставит is-revealed). */
.c-frame::after {
  content: "";
  position: absolute;
  z-index: 3;
  inset: 0;
  background: linear-gradient(to top, rgb(237 237 237 / 0.75) 0 1px, rgb(176 122 232 / 0.16) 1px, transparent 36px);
  opacity: 0;
  transform: translateY(-100%);
  pointer-events: none;
}
.contacts.is-revealed .c-frame::after { animation: c-scan 600ms var(--ease-out) both; }
@keyframes c-scan {
  0% { opacity: 0; transform: translateY(-100%); }
  12% { opacity: 1; }
  82% { opacity: 1; }
  100% { opacity: 0; transform: translateY(0); }
}
.c-row {
  --rc: 255 79 139; /* цвет строки (r g b): номер — розовый */
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  min-height: 88px;
  border-radius: 6px;
}
.c-row[data-row="bot"] { --rc: 176 122 232; }
/* Линейка между строками — с отступами от краёв, как разделители пунктов панели. */
.c-row + .c-row::after {
  content: "";
  position: absolute;
  left: 16px;
  right: 16px;
  top: 0;
  height: 1px;
  background: var(--hair);
  pointer-events: none;
}
/* Свет строки: цвет слева, гаснет к правому краю. Наведение и фокус — зажигают; появление секции — вспышка по очереди. */
.c-row::before {
  content: "";
  position: absolute;
  z-index: 0;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, rgb(var(--rc) / 0.16), rgb(var(--rc) / 0.05) 45%, transparent 80%);
  opacity: 0;
  transition: opacity 240ms var(--ease-out);
  pointer-events: none;
}
.c-row:hover::before, .c-row:focus-within::before { opacity: 1; }
.contacts.is-revealed .c-row::before { animation: c-wash 460ms var(--ease-out) backwards; }
.contacts.is-revealed .c-row[data-row="phone"]::before { animation-delay: 100ms; }
.contacts.is-revealed .c-row[data-row="bot"]::before { animation-delay: 220ms; }
@keyframes c-wash {
  0% { opacity: 0; }
  35% { opacity: 1; }
  100% { opacity: 0; }
}
.c-link {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: 28px minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 20px;
  min-height: 88px;
  box-sizing: border-box;
  padding: 18px 20px;
  border-radius: 6px;
  color: inherit;
  text-decoration: none;
  outline-offset: -2px;
}
.c-row[data-row="bot"] .c-link { grid-column: 1 / -1; }
.c-icon, .c-go {
  display: block;
  width: 28px;
  height: 28px;
  fill: none;
  stroke: var(--fg-2);
  stroke-width: 1.3; /* 1.5 CSS-px при 28 px */
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: stroke 200ms var(--ease-out), transform 220ms var(--ease-out);
}
.c-go { width: 22px; height: 22px; stroke-width: 1.64; }
.c-row:is(:hover, :focus-within) .c-icon { stroke: rgb(var(--rc)); }
.c-row:is(:hover, :focus-within) .c-go { stroke: var(--fg); transform: translateX(3px); }
.c-text { display: grid; row-gap: 4px; justify-items: start; min-width: 0; }
.c-label { font-size: 14px; line-height: 20px; color: var(--fg-2); text-wrap: balance; transition: color 200ms var(--ease-out); }
.c-row:is(:hover, :focus-within) .c-label { color: var(--fg-panel); }
/* Номер — цифры одной ширины (tnum у Onest): «расшифровка» при появлении не двигает строку. Слой эффекта лежит поверх
   настоящего номера; для чтеца и копирования всегда настоящий номер. */
.c-num {
  display: grid;
  font-size: 24px;
  line-height: 32px;
  font-weight: 500;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--fg);
}
.c-num > * { grid-area: 1 / 1; }
.c-num.is-fx .c-num-real { color: transparent; }
.c-num-fx .fx-b { color: #ffb3cc; } /* ещё не вставшие цифры — розовым строки */
/* «tez orada»: честная пометка — у бота ещё нет имени. */
.c-chip {
  display: inline-block;
  padding: 3px 8px;
  border-radius: 6px;
  box-shadow: inset 0 0 0 1px rgb(176 122 232 / 0.5);
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: #d4c0f6;
}
/* Скопировать: два листа → галочка на 1.5 с (hero.js ставит is-done) и рядом «Nusxalandi». */
.c-copy {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-right: 16px;
  padding: 0;
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--fg-2);
  cursor: pointer;
  transition: color 150ms var(--ease), background-color 150ms var(--ease);
}
.c-copy:hover { color: var(--fg); background: rgb(255 255 255 / 0.06); }
.c-copy svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.64; /* 1.5 CSS-px при 22 px */
  stroke-linecap: round;
  stroke-linejoin: round;
}
.cp-back, .cp-front, .cp-check { stroke-dasharray: 1 1; transition: stroke-dashoffset 260ms var(--ease-out), opacity 160ms linear; }
.cp-check { stroke-dashoffset: 1; opacity: 0; stroke: rgb(var(--rc)); }
.c-copy.is-done .cp-back, .c-copy.is-done .cp-front { stroke-dashoffset: 1; opacity: 0; }
.c-copy.is-done .cp-check { stroke-dashoffset: 0; opacity: 1; transition-delay: 90ms; }
.c-toast {
  position: absolute;
  z-index: 1;
  right: 68px;
  top: 50%;
  translate: 0 -50%;
  font-size: 13px;
  line-height: 18px;
  color: var(--fg-panel);
  opacity: 0;
  transition: opacity 180ms var(--ease-out), translate 180ms var(--ease-out);
  pointer-events: none;
}
.c-toast.is-on { opacity: 1; translate: -4px -50%; }

/* Узкий компьютер: треугольник меньше. */
@media (min-width: 1024px) and (max-width: 1279.98px) {
  :root {
    --tri: 190px;
    --mark: 38px; --mark-y: -20.04px;
    --rule-y: -9.72px; --rule-h: 1.474px; --rule-w: 93.5px;
    --cap-fs: 12.5px; --cap-y: 9.43px;
    --call-y: 46.27px; --call-k: 2.063; --call-sw: 1.071;
  }
}

/* ── Планшет (481–1023) ───────────────────────────────── */
@media (max-width: 1023.98px) {
  :root {
    --gutter: 32px;
    --tri: 205px;
    --mark: 37px; --mark-y: -19.41px;
    --rule-y: -9.85px; --rule-h: 1.366px; --rule-w: 91px;
    --cap-fs: 12px; --cap-y: 8.2px;
    --call-y: 45.08px; --call-k: 2.049; --call-sw: 1;
  }
  /* Панель стоит прямо в свете основания (шейдер здесь выбирает основание мягче); тёмный ореол вокруг букв держит
     контраст. */
  .dir { text-shadow: 0 0 2px #000, 0 0 10px #000, 0 0 22px rgb(0 0 0 / 0.9); }
  .dir-points li { color: #cfcfcf; }
  .hero.gl-off .light-side[data-dir="diskless"] { background-image: url("light-diskless-soft.webp"); }
}

/* Три колонки уже не помещаются: панель по центру — значок, название и пункты друг под другом, выровнены по центру,
   разделены линейками в блоке 300px. Место — значок 52 + название 26 + отступ 6 + три пункта по две строки (11 + 44 + 11). */
@media (max-width: 759.98px) {
  .dirs { width: min(100%, 300px); min-height: calc(52px + 26px + 6px + 3 * (22px + 2 * 22px)); }
  .dir-title { margin-bottom: 6px; font-size: 18px; line-height: 26px; }
  .dir-points { grid-template-columns: minmax(0, 1fr); }
  .dir-points li { padding: 11px 0; text-align: center; text-wrap: balance; }
  .dir-points li + li { box-shadow: inset 0 1px 0 var(--hair); }
  /* Язык: на виду флаг и код, название остаётся именем кнопки для чтеца. Колонке языка при 481 px остаётся 130 px —
     дорожка (≈ 129 px) встаёт от поля подвала (20 px), без отступа до поля страницы. */
  .lang { margin-inline-start: 0; }
  .lang-opt { gap: 5px; padding: 0 6px; }
  .lang-name {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
  .lang-code { display: inline; }
}

/* ── Телефон (≤ 480) ───────────────────────────────────── */
@media (max-width: 480px) {
  :root {
    --gutter: 16px;
    --tri: min(170px, calc((100vw - 2 * var(--gutter)) * 280 / 400));
    /* Капсулы нет — «iT SOFT SERVICE» вернулась: 9 px, разрядка плотнее (0.12 em), чтобы встать в тело шириной 170 px. */
    --mark: 41px; --mark-y: -23.91px;
    --rule-y: -14.03px; --rule-h: 1.647px; --rule-w: 100.9px;
    --cap-fs: 14.8px; --cap-t: 0.12; --cap-y: 6.31px;
    --call-y: 45.84px; --call-k: 2.306; --call-sw: 1.071;
    --cell: 48px;
    --grid-w: 720px;
    --grid-h: 960px;
  }
  /* Подвал в две строки: сверху управление (язык слева, контакты и звук справа), под ним по центру — подпись
     платформы, самая тихая. */
  .foot {
    grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-areas: "lang . end" "credit credit credit";
    padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px));
  }
  .powered { margin-top: -2px; }
  .lang { margin-inline-start: 12px; } /* подвал в две строки, места хватает: дорожка снова на поле страницы */
  .contacts { row-gap: 20px; padding-block: 72px 88px; }
  .c-title { font-size: 24px; line-height: 30px; }
  .c-frame { padding: 6px; }
  .c-link { column-gap: 14px; padding: 16px 12px; grid-template-columns: 24px minmax(0, 1fr) auto; }
  .c-icon { width: 24px; height: 24px; stroke-width: 1.5; }
  .c-num { font-size: 22px; line-height: 30px; }
  .c-label { font-size: 13px; line-height: 18px; }
  .c-copy { margin-right: 8px; }
  /* «Nusxalandi» — под кнопкой, у правого края: слева от неё места нет, там номер. */
  .c-toast { right: 8px; top: auto; bottom: 4px; translate: 0 0; font-size: 12px; line-height: 16px; }
  .c-toast.is-on { translate: 0 0; }
}
/* Узкий телефон: русская строка покоя в 13 px (≈ 367 px с точкой) не встаёт в 360 — 12 px и поля плотнее держат её
   в одну строку до ширины ≈ 336 px; уже — переносится (коробка занята заранее, ничего не прыгает). */
@media (max-width: 400px) {
  .status { padding-inline: 6px; gap: 8px; font-size: 12px; left: 6px; right: 6px; }
}

/* ── «Уменьшить движение»: всё видно сразу, ничего не движется ── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 0s !important;
    transition-delay: 0s !important;
    animation: none !important;
  }
  /* Свет — покой: все три стороны светят; «дыхания» вершины нет; панель на компьютере — по наведению или фокусу;
     значки нарисованы сразу; точка значка-зова стоит сверху (фиолетовая), рамка контактов — с неподвижной дугой света;
     строка состояния меняется без расшифровки, цифры номера — сразу настоящие. */
}
/* На узком экране без движения цикла нет — страница полная сразу: все три направления списком. */
@media (prefers-reduced-motion: reduce) and (max-width: 1023.98px) {
  .dirs { gap: 32px; }
  .dir { grid-area: auto; opacity: 1; visibility: visible; translate: none; }
}
