/* Страница «Архитектор»: /workbench/architect/.

   Здесь только раскладка холста и панели модели. Цвета подсветки исходника
   приходят из css/fts.css — второй таблицы цветов у одного языка быть не
   должно, — а оформление самого редактора приезжает вместе с редактором.

   Приём с наложением textarea на подсвеченный <pre> требует, чтобы у обоих
   совпали ВСЕ метрики текста: шрифт, кегль, межстрочный интервал, отступы и
   перенос. Расхождение в любой из них разъезжает курсор с цветами — поэтому
   метрики заданы один раз общим селектором, а не по отдельности каждому. */

.architect-page .workbench-shell {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

.architect__kicker {
  margin: 0;
  color: var(--course-muted);
  font-size: 0.85rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.architect__head h1 {
  margin: 0.3rem 0 0.6rem;
}

.architect__lead {
  margin: 0;
  max-width: 62ch;
  color: var(--course-muted);
}

.architect__dictionary table {
  width: 100%;
  border-collapse: collapse;
}

.architect__dictionary th,
.architect__dictionary td {
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--course-line);
  text-align: left;
  vertical-align: top;
}

.architect__dictionary th {
  color: var(--course-muted);
  font-weight: 600;
}

.architect__note {
  margin: 0.8rem 0 0;
  max-width: 68ch;
  color: var(--course-muted);
  font-size: 0.92rem;
}

.architect__section-title {
  margin: 0 0 0.8rem;
}

.architect__grid {
  display: grid;
  gap: 1.2rem;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
}

@media (max-width: 900px) {
  .architect__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

.architect__controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0 0 0.6rem;
}

.architect__button {
  padding: 0.45rem 1rem;
  border: 1px solid var(--course-line-strong);
  border-radius: var(--digitable-radius-sm, 6px);
  background: var(--course-control);
  color: var(--course-text);
  font: inherit;
  cursor: pointer;
}

.architect__button:hover:not(:disabled) {
  border-color: var(--wb-accent, var(--course-line-strong));
}

.architect__button:disabled {
  cursor: default;
  opacity: 0.55;
}

.architect__button--ghost {
  background: transparent;
}

.architect__status,
.architect__verdict {
  margin: 0.6rem 0 0;
  color: var(--course-muted);
  font-size: 0.9rem;
}

.architect__verdict[data-architect-verdict-state='ok'] {
  color: var(--course-text);
}

.architect__verdict ul {
  margin: 0;
  padding-left: 1.1rem;
}

/* Жалоба перевода и диагностика компилятора — разные вещи, и путать их нельзя:
   первая говорит «на рисунке чего-то не хватает», вторая — «язык отверг». */
.architect__verdict li[data-architect-problem='flang'] {
  font-family: var(--course-mono);
  font-size: 0.85rem;
}

.architect__canvas {
  min-height: 24rem;
  height: 60vh;
  border: 1px solid var(--course-line);
  border-radius: var(--digitable-radius-sm, 6px);
  background: var(--course-panel);
}

/* Пока редактор не смонтирован, пустая рамка занимала бы экран ни за чем. */
.architect__canvas:not([data-architect-mounted]) {
  min-height: 0;
  height: 0;
  border: 0;
}

.architect__label {
  display: block;
  margin-bottom: 0.4rem;
  color: var(--course-muted);
  font-size: 0.9rem;
}

.architect__editor {
  position: relative;
  border: 1px solid var(--course-line);
  border-radius: var(--digitable-radius-sm, 6px);
  background: var(--course-panel);
  overflow: hidden;
}

.architect__painted,
.architect__source {
  margin: 0;
  padding: 0.8rem;
  border: 0;
  font-family: var(--course-mono);
  font-size: 0.88rem;
  line-height: 1.55;
  tab-size: 2;
  white-space: pre-wrap;
  overflow-wrap: break-word;
}

/*
  НАЛОЖЕНИЕ ВКЛЮЧАЕТСЯ ТОЛЬКО ПОСЛЕ УДАЧНОЙ ПОКРАСКИ

  Здесь была ошибка, которая стоила страницы целиком, и её стоит запомнить.

  Раньше поле ввода было прозрачным всегда, а видимым его возвращало правило
  `html:not(.js)`. Это защищает ровно от одного случая — «JavaScript выключен»,
  — и не защищает от другого, куда более частого: скрипт есть, но НЕ ДОЕХАЛ.
  Именно так и вышло на боевом сайте: граф импортов упал на MIME-типе (см.
  scripts/sync-flang-vendor.mjs), класс `js` на <html> стоял, подсветка не
  легла, <pre> остался пустым — и восемь строк модели оказались прозрачным
  текстом на пустой рамке. Владелец увидел пустое место и написал, что страница
  «отсутствует». Он описал ровно то, что было.

  Поэтому признак теперь не «есть ли JavaScript вообще», а «легла ли подсветка
  на самом деле»: атрибут data-architect-painted-ready ставит скрипт ПОСЛЕ
  первой удачной покраски. Любая поломка — сеть, тип MIME, исключение в модуле —
  оставляет обычное текстовое поле с читаемым текстом.
*/
.architect__painted {
  display: none;
  min-height: 14rem;
  background: transparent;
  pointer-events: none;
}

.architect__source {
  display: block;
  width: 100%;
  min-height: 14rem;
  resize: vertical;
  background: transparent;
  color: var(--course-text);
}

.architect__editor[data-architect-painted-ready] .architect__painted {
  display: block;
}

.architect__editor[data-architect-painted-ready] .architect__source {
  position: absolute;
  inset: 0;
  height: 100%;
  min-height: 0;
  resize: none;
  /* Текст поля прозрачен: видны цвета из <pre> под ним, а курсор и выделение
     остаются настоящими — их рисует само поле. */
  color: transparent;
  caret-color: var(--course-text);
}

.architect__source:focus {
  outline: 2px solid var(--wb-accent, var(--course-line-strong));
  outline-offset: -2px;
}

.architect__limits ul {
  margin: 0;
  padding-left: 1.1rem;
  max-width: 72ch;
}

.architect__limits li + li {
  margin-top: 0.7rem;
}

/* ------------------------------------------------------------------ рельс

   Разделы страницы. Разметка — обычные ссылки в <nav>; роли, hidden и roving
   tabindex навешивает js/portal-tabs.js. Без скрипта это остаётся оглавлением
   с якорями, а все три раздела видны подряд. */

.architect__rail {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  border-bottom: 1px solid var(--course-line);
}

.architect__rail a {
  padding: 0.5rem 0.9rem;
  border-bottom: 2px solid transparent;
  color: var(--course-muted);
  text-decoration: none;
}

.architect__rail a:hover {
  color: var(--course-text);
}

.architect__rail a[aria-selected='true'] {
  border-bottom-color: var(--wb-accent, var(--course-text));
  color: var(--course-text);
  font-weight: 600;
}

.architect__panels {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

/* До инициализации скрипт ещё не проставил hidden. Без этого правила все три
   панели успевают мелькнуть разом — тот же приём и та же причина, что у шагов
   визарда на /fts/ (static/css/fts.css). */
.js .architect__panels:not([data-portal-panels-ready]) > [data-architect-panel]:not(:first-child) {
  display: none;
}

/* ---------------------------------------------------------------- ожидание */

.architect__loading {
  display: none;
  align-items: center;
  gap: 0.6rem;
  margin: 0.6rem 0 0;
  color: var(--course-muted);
  font-size: 0.9rem;
}

.architect[data-architect-loading] .architect__loading {
  display: flex;
}

.architect__loading > span {
  width: 1rem;
  height: 1rem;
  border: 2px solid var(--course-line-strong);
  border-top-color: var(--wb-accent, var(--course-text));
  border-radius: 50%;
  animation: architect-spin 0.9s linear infinite;
}

@keyframes architect-spin {
  to { transform: rotate(360deg); }
}

/* Крутящийся индикатор — украшение, а не сообщение: тому, кто просил убрать
   анимацию, оно не нужно, а текст рядом говорит то же самое словами. */
@media (prefers-reduced-motion: reduce) {
  .architect__loading > span { animation: none; }
}

/* Пока редактор грузится, место под холст занято рамкой: иначе страница
   прыгает в момент, когда React наконец смонтировался. */
.architect[data-architect-loading] .architect__canvas {
  min-height: 24rem;
  height: 60vh;
  border: 1px dashed var(--course-line);
}
