/* ============================================================================
   КОНСТРУКТ · ОБЩИЕ ПОВЕРХНОСТИ САЙТА
   ----------------------------------------------------------------------------
   Подключается после /products/product.css. Шаблон продукта даёт холст, шапку,
   кнопки и сетку; здесь живёт то, чего у одной витрины не было: ссылки
   разделов в шапке, общий подвал с правовой строкой, текстовый документ,
   каталог, карточки и списки.

   Геометрия — тессерактовая: прямой угол, тонкая линия, узел на пересечении.
   Радиуса нет нигде (--kn-radius: 0), глубина набирается толщиной линии, а не
   скруглением и не заливкой. Закруглённая карточка спорит со знаком студии,
   который стоит на том же экране и состоит из одних прямых рёбер.
   ========================================================================== */

/* --- пропуск к содержанию ------------------------------------------------- */
/* Первое, на что попадает Tab. До этой ссылки человек, идущий с клавиатуры,
   проходил знак, четыре раздела, язык и тему — семь остановок, и так на каждой
   из тридцати страниц. Ссылка не видна, пока её не взяли фокусом: тогда она
   выезжает в левый верхний угол поверх шапки. */
.kn-skip{
  position:fixed; z-index:100; top:0; inset-inline-start:0;
  transform:translateY(-120%);
  display:inline-flex; align-items:center; height:44px; padding:0 1.1rem;
  background:var(--kn-ink); color:var(--kn-ink-invert);
  font-family:var(--font-display); font-size:.86rem; letter-spacing:.02em;
  text-decoration:none;
  transition:transform .18s var(--kn-ease);
}
.kn-skip:focus{ transform:none }
/* У цели ссылки стоит tabindex="-1", иначе в половине браузеров переход по
   якорю только прокручивает страницу, а Tab возвращается в шапку — то есть
   ссылка как бы есть, а пропуска нет. Кольцо у самого полотна не рисуется:
   полотно не орган управления, и обводка вокруг всей страницы читалась бы
   как ошибка. Признак перехода — прокрутка и то, что следующий Tab попадает
   уже внутрь содержания. */
#kn-content:focus, #root:focus, .r-content:focus{ outline:none }

/* --- страница без сценария ------------------------------------------------ */
/* .kp-rise прячет блок до того, как его покажет IntersectionObserver. Если
   сценарий не пришёл — не загрузился, отключён, заблокирован в корпоративной
   сети, — блок остаётся с opacity:0 навсегда, и витрина DRIFT показывает
   пустое полотно вместо одиннадцати блоков текста. Класс js ставит тот же
   встроенный сценарий в голове, что ставит тему: он выполняется до первой
   отрисовки, поэтому мигания нет. Нет сценария — нет класса — виден текст. */
html:not(.js) .kp-rise{ opacity:1 !important; transform:none !important }

/* --- шапка: ссылки разделов ---------------------------------------------- */
/* У витрины продукта в шапке стояли только знак и кнопка загрузки. Сайту нужны
   разделы, поэтому ссылки вставляются между знаком и утилитами и забирают
   свободное место на себя. */
.kn-nav__links{
  display:flex; align-items:center; gap:clamp(.9rem,2vw,1.8rem);
  margin-inline:auto; min-width:0;
}
.kn-nav__link{
  position:relative; padding:.35rem 0;
  font-family:var(--font-display); font-weight:400; font-size:.88rem;
  color:var(--kn-ink-secondary); text-decoration:none; white-space:nowrap;
  transition:color .2s;
}
.kn-nav__link:hover{ color:var(--kn-ink) }
/* Текущий раздел отмечен чертой под словом, а не заливкой: подчёркивание —
   то же ребро каркаса, только короткое. */
.kn-nav__link.is-current{ color:var(--kn-ink) }
.kn-nav__link.is-current::after{
  content:''; position:absolute; left:0; right:0; bottom:-1px;
  height:var(--kn-edge); background:currentColor;
}
.kn-nav__link:focus-visible{ outline:2px solid var(--kn-focus-ring); outline-offset:3px }

@media (max-width:860px){
  /* Слово «КОНСТРУКТ» рядом со знаком уходит первым: знак узнаётся и без него,
     а четыре раздела без подписи узнать нельзя. */
  .kp-brand-name{ display:none }
  .kn-nav__links{ gap:1rem; font-size:.82rem; overflow-x:auto; scrollbar-width:none }
  .kn-nav__links::-webkit-scrollbar{ display:none }
}

/* --- полотно страницы ----------------------------------------------------- */
.kn-main{ position:relative; z-index:1 }

/* Длинный адрес — один неразрывный кусок, и на узкой колонке он распирает
   страницу: на витрине ENDLESS строка с пятью параметрами в адресе уводила
   содержимое до 443 пикселей при экране в 375, а html с overflow-x:hidden
   срезал хвост молча. Разрешаем перенос внутри слова там, где иначе не
   влезает; обычные слова это правило не трогает. */
.kn-main p, .kn-main li, .kn-main td, .kn-main th,
.kn-main h1, .kn-main h2, .kn-main h3,
.kn-card__desc, .kn-list__desc, .kn-foot__col a{ overflow-wrap:anywhere }
/* Заголовки раньше в этот список не входили, а зря: .kn-hero__title набран
   кеглем до 3.8rem, и одно длинное слово в нём распирает страницу вчетверо
   охотнее, чем то же слово в абзаце. */

/* --- шапка раздела -------------------------------------------------------- */
.kn-hero{
  position:relative; z-index:1;
  width:var(--kn-shell); margin:0 auto;
  padding:clamp(3.5rem,8vw,6.5rem) 0 clamp(2rem,4vw,3.2rem);
  border-bottom:var(--kn-hair) solid var(--kn-line);
}
.kn-hero__kicker{
  margin:0 0 1.1rem;
  font-family:var(--font-display); font-weight:200;
  font-size:.69rem; letter-spacing:.38em; text-transform:uppercase;
  color:var(--kn-ink-muted);
}
/* Начертание 200 и положительное межбуквенное — типографика Образа. Прежняя
   шкала сайта жала заголовок отрицательным трекингом; на тонком начертании это
   слипается в пятно. */
.kn-hero__title{
  margin:0; max-width:27ch;
  font-family:var(--font-display); font-weight:200;
  font-size:clamp(2.1rem,3.7vw,3.8rem); line-height:1.08; letter-spacing:.045em;
  text-wrap:balance; color:var(--kn-ink);
}
.kn-hero__lead{
  margin:1.4rem 0 0; max-width:62ch;
  font-weight:300; font-size:clamp(1rem,1.5vw,1.14rem); line-height:1.7;
  color:var(--kn-ink-secondary);
}

/* --- секция --------------------------------------------------------------- */
.kn-section{
  width:var(--kn-shell); margin:0 auto;
  padding:clamp(2.6rem,5vw,4.4rem) 0;
}
.kn-section + .kn-section{ border-top:var(--kn-hair) solid var(--kn-line) }
.kn-h2{
  margin:0 0 1.6rem;
  font-family:var(--font-display); font-weight:300;
  font-size:clamp(1.3rem,2.2vw,1.85rem); line-height:1.25; letter-spacing:.01em;
  color:var(--kn-ink);
}

/* --- текстовый документ --------------------------------------------------- */
/* Правовые страницы читают, а не разглядывают. Колонка меряется --kn-measure:
   строка шире семидесяти пяти знаков теряет глаз на переносе. */
.kn-doc{
  width:var(--kn-measure); margin:0 auto;
  padding:clamp(3rem,7vw,5rem) 0 clamp(4rem,8vw,6rem);
}
.kn-doc h1{
  margin:0 0 .6rem;
  font-family:var(--font-display); font-weight:200;
  font-size:clamp(1.8rem,3.2vw,2.8rem); line-height:1.14; letter-spacing:.03em;
  color:var(--kn-ink);
}
.kn-doc h2{
  margin:2.8rem 0 .9rem;
  font-family:var(--font-display); font-weight:400;
  font-size:1.06rem; line-height:1.4; letter-spacing:.01em; color:var(--kn-ink);
}
.kn-doc h3{
  margin:2rem 0 .7rem;
  font-family:var(--font-display); font-weight:400; font-size:.95rem; color:var(--kn-ink);
}
.kn-doc p, .kn-doc li{
  font-size:.97rem; line-height:1.78; color:var(--kn-ink-primary);
}
.kn-doc p{ margin:0 0 1.05rem }
.kn-doc ul, .kn-doc ol{ margin:0 0 1.2rem; padding-inline-start:1.3rem }
.kn-doc li{ margin:0 0 .5rem }
.kn-doc strong{ font-weight:600; color:var(--kn-ink) }
/* Ссылка в документе не красится: цвет здесь занят смыслом, а не навигацией.
   Отличает её подчёркивание — и оно же становится плотнее под курсором. */
.kn-doc a{
  color:inherit; text-decoration:underline;
  text-decoration-color:var(--kn-line-strong); text-underline-offset:.22em;
  transition:text-decoration-color .2s;
}
.kn-doc a:hover{ text-decoration-color:currentColor }
.kn-updated{
  margin:0 0 2.6rem !important;
  font-size:.8rem !important; color:var(--kn-ink-secondary) !important;
}

/* --- таблица -------------------------------------------------------------- */
.kn-table{
  width:100%; border-collapse:collapse; margin:0 0 1.6rem;
  font-size:.93rem; line-height:1.6;
}
.kn-table th, .kn-table td{
  padding:.8rem 0; text-align:start; vertical-align:top;
  border-bottom:var(--kn-hair) solid var(--kn-line);
}
.kn-table th{
  width:32%; font-weight:400; color:var(--kn-ink-secondary);
  padding-inline-end:1.4rem;
}
.kn-table td{ color:var(--kn-ink-primary) }

/* На телефоне таблица «что — что» встаёт двумя строками вместо двух колонок.
   Прежде она держала колонку в 32 % и распирала страницу: на витрине ENDLESS
   содержимое уезжало до 443 пикселей при ширине экрана 375, а html с
   overflow-x:hidden просто срезал хвост — молча, без полосы прокрутки, так что
   часть таблицы было не прочитать вовсе. */
@media (max-width:560px){
  .kn-table, .kn-table tbody, .kn-table tr, .kn-table th, .kn-table td{ display:block }
  .kn-table tr{ padding:.9rem 0; border-bottom:var(--kn-hair) solid var(--kn-line) }
  .kn-table th, .kn-table td{ width:auto; padding:0; border:0 }
  .kn-table th{ margin-bottom:.3rem }
}

/* Всё, что шире полосы по своей природе, прокручивается внутри себя, а не
   растягивает страницу. Обёртку ставит сборщик (_сборка/build_pages.py). */
.kn-scroll{ overflow-x:auto; max-width:100%; -webkit-overflow-scrolling:touch }

/* --- сетка карточек ------------------------------------------------------- */
.kn-grid{
  display:grid; gap:var(--kn-hair);
  grid-template-columns:repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
  /* Зазор в один пиксель и линия по контуру: карточки стоят сеткой каркаса, а
     не отдельными плитками. Фон зазора даёт линию без двойных границ. */
  background:var(--kn-line);
  border:var(--kn-hair) solid var(--kn-line);
}
.kn-card{
  position:relative; display:flex; flex-direction:column; gap:.55rem;
  padding:clamp(1.3rem,2.4vw,1.9rem);
  background:var(--kn-canvas); color:inherit; text-decoration:none;
  transition:background .18s;
}
a.kn-card:hover{ background:var(--kn-state-hover) }
a.kn-card:focus-visible{ outline:2px solid var(--kn-focus-ring); outline-offset:-4px }
/* Узел каркаса в углу выбранной карточки: четыре точки читаются как вершины
   тессеракта, и это дешевле любой подсветки. */
a.kn-card::after{
  content:''; position:absolute; inset:.55rem auto auto .55rem;
  width:var(--kn-node); height:var(--kn-node); background:var(--kn-ink);
  opacity:0; transition:opacity .18s;
}
a.kn-card:hover::after{ opacity:1 }
.kn-card__name{
  font-family:var(--font-display); font-weight:500; font-size:1rem;
  letter-spacing:.02em; color:var(--kn-ink);
}
.kn-card__desc{ font-size:.88rem; line-height:1.6; color:var(--kn-ink-secondary) }
.kn-card__meta{
  margin-top:auto; padding-top:.9rem;
  font-family:var(--font-display); font-size:.68rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--kn-ink-secondary);
}

/* --- список строк --------------------------------------------------------- */
.kn-list{ list-style:none; margin:0; padding:0 }
.kn-list li{
  display:grid; gap:.3rem;
  grid-template-columns:minmax(0,15rem) minmax(0,1fr);
  padding:1rem 0; border-bottom:var(--kn-hair) solid var(--kn-line);
}
.kn-list li:first-child{ border-top:var(--kn-hair) solid var(--kn-line) }
.kn-list__name{
  font-family:var(--font-display); font-weight:500; font-size:.94rem;
  letter-spacing:.04em; color:var(--kn-ink);
}
.kn-list__desc{ font-size:.92rem; line-height:1.66; color:var(--kn-ink-secondary) }
@media (max-width:640px){
  .kn-list li{ grid-template-columns:1fr }
}

/* --- врезка --------------------------------------------------------------- */
/* Срезанный угол — тот же угол в сорок пять градусов, по которому тессеракт
   складывается в ромб на первом экране. Единственное место, где форма говорит
   вслух; в остальном она держится прямого угла. */
.kn-note{
  margin:1.6rem 0; padding:1.1rem 1.3rem;
  border:var(--kn-hair) solid var(--kn-line-strong);
  clip-path:polygon(0 0, 100% 0, 100% calc(100% - var(--kn-bevel)),
                    calc(100% - var(--kn-bevel)) 100%, 0 100%);
  font-size:.92rem; line-height:1.7; color:var(--kn-ink-primary);
}
.kn-note p:last-child{ margin-bottom:0 }

/* --- строка действий ------------------------------------------------------ */
.kn-actions{ display:flex; flex-wrap:wrap; gap:.7rem; margin-top:1.8rem }

/* --- подвал --------------------------------------------------------------- */
/* Заливки нет: в языке Образа светлая тема — абсолютно белый холст, и подвал
   отделяется линией, а не серой плашкой. Зерно поверх — общий материал сайта. */
.kn-foot{
  position:relative; z-index:1; margin-top:clamp(4rem,8vw,7rem);
  border-top:var(--kn-hair) solid var(--kn-line);
  padding:clamp(2.8rem,6vw,4.5rem) 0 2.4rem;
}
.kn-foot__in{
  display:grid; gap:clamp(2rem,4vw,3.4rem);
  grid-template-columns:minmax(0,12rem) minmax(0,1fr); align-items:start;
}
.kn-foot__brand{
  display:flex; align-items:center; gap:.6rem;
  color:var(--kn-ink); text-decoration:none;
}
.kn-foot__brand .kp-mark{ width:26px; height:26px }
.kn-foot__word{
  font-family:var(--font-display); font-weight:500;
  font-size:.92rem; letter-spacing:.14em;
}
.kn-foot__cols{
  display:grid; gap:clamp(1.6rem,3vw,2.6rem);
  grid-template-columns:repeat(auto-fit, minmax(min(100%,11rem), 1fr));
}
.kn-foot__col ul{ list-style:none; margin:0; padding:0 }
.kn-foot__col li{ margin:0 0 .6rem }
.kn-foot__title{
  display:block; margin-bottom:1rem;
  font-family:var(--font-display); font-weight:500; font-size:.82rem;
  letter-spacing:.02em; color:var(--kn-ink);
}
.kn-foot__col a{
  font-size:.86rem; color:var(--kn-ink-secondary);
  text-decoration:none; transition:color .2s;
}
.kn-foot__col a:hover{ color:var(--kn-ink) }
.kn-foot__col a:focus-visible{ outline:2px solid var(--kn-focus-ring); outline-offset:3px }

.kn-foot__law{
  margin-top:clamp(2.4rem,5vw,3.6rem); padding-top:1.4rem;
  border-top:var(--kn-hair) solid var(--kn-line);
}
.kn-foot__org{
  margin:0 0 .9rem; font-size:.76rem; line-height:1.7; color:var(--kn-ink-secondary);
}
.kn-foot__line{
  margin:0; display:flex; flex-wrap:wrap; gap:.4rem 1.4rem;
  font-size:.76rem; color:var(--kn-ink-secondary);
}
.kn-foot__line a{ color:inherit; text-decoration:none; transition:color .2s }
.kn-foot__line a:hover{ color:var(--kn-ink) }

@media (max-width:760px){
  .kn-foot__in{ grid-template-columns:1fr }
}

/* --- каталог -------------------------------------------------------------- */
.kn-cat__state{
  display:inline-flex; align-items:center; gap:.4rem;
  font-family:var(--font-display); font-size:.62rem; letter-spacing:.18em;
  text-transform:uppercase; color:var(--kn-ink-secondary);
}
/* Точка состояния — тот же узел каркаса. Готовое горит чернилами, ожидающее
   остаётся контуром: разница видна, но цветом не кричит. */
.kn-cat__dot{
  width:var(--kn-node); height:var(--kn-node);
  background:var(--kn-ink); flex:none;
}
.kn-cat__dot--soon{ background:none; box-shadow:inset 0 0 0 1px var(--kn-ink-muted) }
.kn-cat__plat{
  display:flex; gap:.5rem; flex-wrap:wrap;
  font-size:.74rem; color:var(--kn-ink-secondary);
}

/* --- кнопки в разделах ---------------------------------------------------- */
/* Шаблон продукта называет вид кнопки через одно тире (.kp-btn-primary), а
   разделы сайта пишутся по словарю классов, где модификатор стоит через два, и
   вторичная кнопка обходится одним .kp-btn. Без этих четырёх правил обе
   остаются прозрачной коробкой: у голого .kp-btn нет ни заливки, ни обводки —
   он задаёт только размер. Одно оформление под двумя именами дешевле, чем
   разметка, разошедшаяся со словарём. */
.kn-main .kp-btn{
  background:var(--surface); color:var(--fg);
  border-color:var(--border); box-shadow:var(--shadow-soft);
}
.kn-main .kp-btn:hover{ border-color:var(--border-strong); box-shadow:var(--shadow) }
.kn-main .kp-btn--primary{
  background:var(--fg); color:var(--invert-fg);
  border-color:transparent; box-shadow:var(--shadow);
}
.kn-main .kp-btn--primary:hover{ box-shadow:var(--shadow-hover) }

/* --- каталог внутри рассказа на главной ----------------------------------- */
/* Рассказ на главной объясняет правило студии; за ним человек вправе спросить,
   что из этого можно взять. До сих пор ответа не было: на главной не стояло ни
   одной ссылки на продукт. Блок живёт по правилам рассказа — та же полоса, тот
   же ритм, — но внутри у него сетка каталога. */
.kn-block--catalog{ display:block }
.kn-block--catalog .kn-grid{ margin-top:1.6rem }
.kn-block__more{ margin:1.4rem 0 0 }
.kn-block__more a{
  font-family:var(--font-display); font-size:.86rem; letter-spacing:.02em;
  color:var(--kn-ink); text-decoration:underline;
  text-decoration-color:var(--kn-line-strong); text-underline-offset:.24em;
  transition:text-decoration-color .2s;
}
.kn-block__more a:hover{ text-decoration-color:currentColor }

/* --- размер цели нажатия --------------------------------------------------- */
/* Палец — не курсор. Значки языка и темы стоят 1.85rem (29.6px) по рисунку, и
   рисунок правильный: крупная плашка в шапке спорит со знаком. Поэтому растёт
   не значок, а область нажатия — прозрачным прямоугольником поверх него.
   29.6 + 2×7.2 = 44px, ровно порог. Видимая часть не меняется. */
.kp-icon-btn{ position:relative }
.kp-icon-btn::after{
  content:''; position:absolute; inset:-.45rem;
}
/* Ссылки подвала стояли строкой в 21–22 пикселя: меньше порога в 24, который
   WCAG считает минимумом даже с поправкой на разрежение. Поле сверху и снизу
   доводит строку до 27 и ничего не двигает — отступ между пунктами уменьшен
   на ту же величину. */
.kn-foot__col li{ margin:0 0 .25rem }
.kn-foot__col a{ display:inline-block; padding:.18rem 0 }
.kn-foot__line{ gap:.2rem 1.4rem }
.kn-foot__line a, .kn-foot__line span{ display:inline-block; padding:.18rem 0 }

/* --- одна полоса на шапку и на содержание --------------------------------- */
/* На экранах уже 620px шаблон продукта переводит --shell на «100% − 2rem», а
   --kn-shell оставался на 92%: шапка мерила одну полосу, герой и секции —
   другую. На 375px расхождение — по пикселю с каждой стороны, и знак в шапке
   переставал стоять на одной вертикали с заголовком под ним. Ровно то, от
   чего --kn-shell и заводился. */
@media (max-width:620px){
  :root{ --kn-shell:min(1120px, 100% - 2rem) }
}

/* --- движение отключено по просьбе системы -------------------------------- */
@media (prefers-reduced-motion: reduce){
  .kn-nav__link, a.kn-card, a.kn-card::after, .kn-foot__col a{ transition:none }
}
