/* eink.css — единственная таблица стилей оболочки. Реализует DESIGN.md дословно:
   палитра из шести токенов, serif + mono (T8), шкала 4 px, линии 1 px, радиус ≤ 2 px,
   без теней/градиентов/иконок, color-scheme: light only, движение ≥ 200 мс, reduced-motion.
   Классы = компоненты словаря (masthead · banner · frame · tree · rows · field · button · slot ·
   panel · toast · collapsible · textpage). Соответствие — DESIGN.md «Компоненты — реализация». */

:root {
  color-scheme: light only;
  --paper: #f4f3ee;
  --paper-sunk: #eae8e2;
  --ink: #1a1a1a;
  --ink-mid: #6b6b6b;
  --ink-faint: #a8a5a0;
  --alert: #a63d40;
  --serif: Charter, "Iowan Old Style", "Palatino Linotype", Georgia, serif;
  --mono: ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 32px;
  --s7: 48px;
  --page: 1120px;
  --text: 68ch;
  --tap: 44px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  background: var(--paper);
  color: var(--ink);
  font: 16px / 1.5 var(--serif);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  padding-block: 0 var(--s7);
  padding-inline: var(--s4);
  min-height: 100vh;
}

a {
  color: var(--ink);
  text-underline-offset: 2px;
}
a:visited {
  color: var(--ink-mid);
}
a[aria-current="page"] {
  text-decoration: none;
  border-bottom: 1px solid var(--ink);
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

h1,
h2,
h3 {
  font-weight: normal;
  margin: 0;
}
h1 {
  font-size: 18px;
}
h2 {
  font-size: 14px;
  letter-spacing: 0.04em;
  color: var(--ink-mid);
  margin: var(--s6) 0 var(--s3);
}
h2 a {
  color: inherit;
}
h3 {
  font-size: 16px;
  margin-bottom: var(--s3);
}

p {
  margin: 0 0 var(--s3);
  max-width: var(--text);
}
hr {
  border: 0;
  border-top: 1px solid var(--ink-faint);
  margin: var(--s6) 0;
}
code,
.mono {
  font-family: var(--mono);
  font-size: 14px;
}
.meta {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-mid);
}
.alert {
  color: var(--alert);
}
.faint {
  color: var(--ink-mid);
}
[hidden] {
  display: none;
}

.wrap {
  max-width: var(--page);
  margin: 0 auto;
}

/* Скрыто визуально, доступно screen reader */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* skip-link: невидим, пока не в фокусе */
.skip {
  position: absolute;
  left: -9999px;
  top: var(--s2);
  background: var(--paper);
  padding: var(--s2) var(--s3);
  border: 1px solid var(--ink);
  z-index: 3;
}
.skip:focus {
  left: var(--s4);
}

/* Мигающая каретка загрузки, 1 Гц */
.caret::after {
  content: "▌";
  animation: caret 1s steps(1) infinite;
}
@keyframes caret {
  50% {
    opacity: 0;
  }
}

/* ---------- masthead ---------- */
.masthead {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s5);
  align-items: baseline;
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--ink);
}
.masthead .name {
  font-size: 18px;
  white-space: nowrap;
}
.masthead .name a {
  text-decoration: none;
}
.masthead .tagline {
  flex: 1 1 320px;
  margin: 0;
  max-width: var(--text);
}
.masthead .meta {
  display: flex;
  gap: var(--s2) var(--s4);
  flex-wrap: wrap;
  flex-basis: 100%;
}
.masthead .meta b {
  font-weight: normal;
  color: var(--ink);
}
.masthead .meta .stale {
  color: var(--ink-mid);
}
.masthead .meta .over {
  color: var(--alert);
}
.masthead .logout {
  font: inherit;
  color: var(--ink);
  background: none;
  border: 0;
  padding: 0;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
  min-height: 0;
}

nav.anchors {
  display: flex;
  gap: var(--s4);
  overflow-x: auto;
  font-size: 14px;
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--ink-faint);
  scrollbar-width: none;
}
nav.anchors a {
  white-space: nowrap;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding: var(--s2) 0;
}
nav.anchors a:hover {
  border-bottom-color: var(--ink);
}

/* ---------- banner (ровно один) ---------- */
.banner {
  display: flex;
  gap: var(--s3);
  align-items: baseline;
  border: 1px solid var(--ink);
  padding: var(--s2) var(--s3);
  margin: var(--s4) 0 0;
  font-size: 14px;
}
.banner.is-alert {
  border-color: var(--alert);
  color: var(--alert);
}
.banner .text {
  flex: 1 1 auto;
}
.banner .close {
  min-height: 0;
  padding: 0 var(--s2);
  font-size: 14px;
  border: 0;
  background: none;
}

/* ---------- frame (песочница) ---------- */
section {
  scroll-margin-top: var(--s4);
}
.frame {
  border: 1px solid var(--ink);
  background: var(--paper);
}
.frame .cap,
.frame .foot {
  display: flex;
  justify-content: space-between;
  gap: var(--s2) var(--s3);
  flex-wrap: wrap;
  padding: var(--s2) var(--s3);
  font-size: 14px;
}
.frame .cap {
  border-bottom: 1px solid var(--ink);
  min-height: var(--tap);
  align-items: center;
}
.frame .cap .r {
  display: flex;
  gap: var(--s3);
  align-items: center;
  color: var(--ink-mid);
  font-family: var(--mono);
  font-size: 13px;
}
.frame .cap b {
  font-weight: normal;
}
.frame .foot {
  border-top: 1px solid var(--ink-faint);
  font-size: 13px;
  color: var(--ink-mid);
}
.frame .body {
  position: relative;
  height: auto;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  background: var(--paper);
}
.frame iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
  background: var(--paper);
}
.frame .state {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: var(--s4);
  text-align: center;
  color: var(--ink-mid);
  background: var(--paper);
}
.frame .state p {
  margin: 0;
  max-width: 40ch;
}
/* e-ink flash (T9): инверсия → бумага, 300 мс, только при смене sha */
.frame.flash {
  animation: eink-flash 300ms steps(2, end) 1;
}
@keyframes eink-flash {
  0% {
    background: var(--ink);
  }
  50% {
    background: var(--ink);
  }
  100% {
    background: var(--paper);
  }
}
.frame.flash iframe,
.frame.flash .state {
  animation: eink-hide 300ms steps(2, end) 1;
}
@keyframes eink-hide {
  0%,
  50% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

/* полноэкранная песочница — единственная модалка */
dialog.fullscreen {
  width: 100vw;
  height: 100dvh;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--paper);
  color: var(--ink);
  display: none;
  flex-direction: column;
}
dialog.fullscreen[open] {
  display: flex;
}
dialog.fullscreen::backdrop {
  background: var(--paper);
}
dialog.fullscreen .cap {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) var(--s4);
  border-bottom: 1px solid var(--ink);
  font-size: 14px;
  min-height: var(--tap);
}
dialog.fullscreen iframe {
  flex: 1 1 auto;
  width: 100%;
  border: 0;
  background: var(--paper);
}

/* ---------- tree (карта) ---------- */
.tree {
  border-top: 1px solid var(--ink-faint);
  border-bottom: 1px solid var(--ink-faint);
  padding: var(--s3) 0;
  position: relative;
}
.tree .tools {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
  margin-bottom: var(--s3);
}
.tree .canvas {
  position: relative;
  width: 100%;
  height: 100vw;
  min-height: 320px;
  max-height: 520px;
  overflow: hidden;
  touch-action: pan-y pinch-zoom;
  background: var(--paper);
}
.tree .canvas.grab {
  touch-action: none;
  cursor: grab;
}
.tree .canvas.grab:active {
  cursor: grabbing;
}
.tree svg {
  display: block;
  width: 100%;
  height: 100%;
  user-select: none;
}
.tree svg text {
  font-family: var(--mono);
  font-size: 13px;
  fill: var(--ink);
  pointer-events: none;
}
.tree svg text.dim {
  fill: var(--ink-mid);
}
.tree svg text.me {
  fill: var(--ink);
}
.tree svg .edge {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.2;
  stroke-linecap: round;
}
.tree svg .node {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 1.4;
}
.tree svg .node.root {
  stroke-width: 1.8;
}
.tree svg .node.banned {
  fill: var(--paper);
  stroke: var(--ink-faint);
}
.tree svg .hit {
  fill: transparent;
  stroke: none;
  cursor: pointer;
  pointer-events: all;
}
.tree svg .ring {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.2;
  stroke-dasharray: 3 3;
}
.tree svg.has-me .edge {
  stroke: var(--ink-faint);
}
.tree svg.has-me .edge.path {
  stroke: var(--ink);
  stroke-width: 2;
}
.tree svg.has-me .node {
  stroke: var(--ink-faint);
}
.tree svg.has-me .node.path {
  stroke: var(--ink);
}
.tree svg.has-me .node.me {
  fill: var(--ink);
  stroke: var(--ink);
}
.tree svg.has-me text {
  fill: var(--ink-mid);
}
.tree svg.has-me text.path,
.tree svg.has-me text.me {
  fill: var(--ink);
}
.tree .state {
  padding: var(--s4);
  color: var(--ink-mid);
  font-size: 14px;
}
.tree .shown {
  margin: var(--s2) 0 0;
}
/* поповер узла */
.tree .pop {
  position: absolute;
  z-index: 2;
  max-width: 280px;
  background: var(--paper);
  border: 1px solid var(--ink);
  padding: var(--s2) var(--s3);
  font-size: 14px;
}
.tree .pop p {
  margin: 0 0 var(--s1);
}
.tree .pop .actions {
  margin-top: var(--s2);
}
.tree .pop .banned {
  color: var(--ink-mid);
  text-decoration: line-through;
}
/* список участников (SR-версия и мобильный основной вид) */
.tree .list ul {
  list-style: none;
  margin: 0;
  padding: 0;
}
.tree .list ul ul {
  padding-left: var(--s4);
  border-left: 1px solid var(--ink-faint);
  margin-left: var(--s1);
}
.tree .list li {
  font-size: 14px;
  line-height: 1.4;
}
.tree .list .row {
  display: flex;
  align-items: stretch;
  gap: var(--s2);
}
.tree .list button {
  font: inherit;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink);
  background: none;
  border: 0;
  padding: var(--s2) 0;
  min-height: var(--tap);
  text-align: left;
  cursor: pointer;
  flex: 1 1 auto;
}
.tree .list button.toggle,
.tree .list .toggle-gap {
  flex: 0 0 var(--tap);
  width: var(--tap);
  text-align: center;
  color: var(--ink-mid);
}
.tree .list ul ul {
  padding-left: var(--s2);
}
.tree .list button .k {
  color: var(--ink-mid);
}
.tree .list button.banned span.h {
  color: var(--ink-mid);
  text-decoration: line-through;
}
.tree .list button.me {
  background: var(--paper-sunk);
}
.tree .canvas[hidden] {
  display: none;
}

/* ---------- rows ---------- */
.rows {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--ink-faint);
}
.rows li {
  display: flex;
  gap: var(--s3);
  align-items: baseline;
  min-height: var(--tap);
  padding: var(--s2) 0;
  border-bottom: 1px solid var(--ink-faint);
  font-size: 14px;
}
.rows .k {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-mid);
  flex: 0 0 auto;
  white-space: nowrap;
}
.rows .sym {
  flex: 0 0 1.2em;
  font-family: var(--mono);
  color: var(--ink);
}
.rows .sym.bad {
  color: var(--alert);
}
.rows .sym.dim {
  color: var(--ink-mid);
}
.rows .txt {
  flex: 1 1 12em;
  min-width: 0;
  overflow-wrap: anywhere;
}
.rows li {
  flex-wrap: wrap;
}
.rows li > .k:last-child {
  margin-left: auto;
}
.rows .txt.dim {
  color: var(--ink-mid);
}
.rows li.me {
  background: var(--paper-sunk);
  margin: 0 calc(-1 * var(--s2));
  padding-inline: var(--s2);
}
.rows li.placeholder {
  min-height: var(--tap);
}
.rows li.placeholder .txt {
  height: 1px;
  background: var(--ink-faint);
  align-self: center;
}
.rows li.new {
  animation: row-in 200ms ease-out 1;
}
@keyframes row-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
.rows details {
  flex: 1 1 12em;
  min-width: 0;
}
.rows details summary {
  cursor: pointer;
  list-style: none;
}
.rows details summary::-webkit-details-marker {
  display: none;
}
.rows details summary::after {
  content: " ▸";
  color: var(--ink-mid);
}
.rows details[open] summary::after {
  content: " ▾";
}
.rows details .reason {
  margin: var(--s1) 0 0;
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-mid);
}
.more {
  color: var(--ink-mid);
  font-size: 14px;
  margin: var(--s2) 0 0;
}
.more button {
  min-height: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.empty {
  color: var(--ink-mid);
  font-size: 14px;
  padding: var(--s3) 0;
  border-top: 1px solid var(--ink-faint);
  border-bottom: 1px solid var(--ink-faint);
}
/* очередь на мобиле: текущий + 3, остальное за «ещё N» */
.queue-rows li[data-extra] {
  display: none;
}
.queue-rows.expanded li[data-extra] {
  display: flex;
}
.two {
  display: grid;
  gap: var(--s5);
}
#live {
  margin: 0;
}

/* ---------- field ---------- */
.field {
  display: block;
  margin-top: var(--s3);
}
.field > span,
.field-label {
  display: block;
  font-size: 14px;
  margin-bottom: var(--s1);
}
input[type="text"],
input[type="url"],
textarea {
  display: block;
  width: 100%;
  font: 16px / 1.5 var(--serif);
  color: var(--ink);
  background: var(--paper-sunk);
  border: 1px solid var(--ink-mid);
  border-radius: 2px;
  padding: var(--s2) var(--s3);
  min-height: var(--tap);
  margin: 0;
}
input[type="url"] {
  font-family: var(--mono);
  font-size: 16px;
}
textarea {
  resize: vertical;
}
input:disabled,
textarea:disabled {
  color: var(--ink-mid);
}
.hint {
  font-size: 13px;
  color: var(--ink-mid);
  margin: var(--s1) 0 0;
  max-width: var(--text);
}
.hint.counter {
  font-family: var(--mono);
}
.err {
  font-size: 14px;
  color: var(--alert);
  margin: var(--s1) 0 0;
}
.err:empty {
  display: none;
}
.ok {
  font-size: 14px;
  color: var(--ink);
  margin: var(--s3) 0 0;
}
.ok:empty {
  display: none;
}
.tweet {
  font-family: var(--mono);
  font-size: 14px;
  background: var(--paper-sunk);
  border: 1px solid var(--ink-mid);
  padding: var(--s2) var(--s3);
  margin: var(--s1) 0 0;
  overflow-wrap: anywhere;
  user-select: all;
}

/* ---------- button ---------- */
button,
.button {
  font: 14px / 1.2 var(--serif);
  background: var(--paper);
  color: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 2px;
  padding: 0 var(--s3);
  min-height: var(--tap);
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
}
.button {
  color: var(--ink);
}
button.primary,
.button.primary {
  background: var(--ink);
  color: var(--paper);
}
button:disabled,
button[aria-disabled="true"] {
  color: var(--ink-mid);
  border-color: var(--ink-mid);
  background: var(--paper);
  cursor: default;
}
.actions {
  display: flex;
  gap: var(--s2);
  flex-wrap: wrap;
  margin-top: var(--s3);
}

/* ---------- slot (одна из панелей) ---------- */
.slot {
  border: 1px solid var(--ink);
  padding: var(--s4);
  max-width: var(--text);
}
.slot h3 {
  margin-bottom: var(--s2);
}
.slot .steps {
  counter-reset: s;
  padding: 0;
  margin: 0;
  list-style: none;
}
.slot .steps li {
  counter-increment: s;
  margin-top: var(--s3);
}
.slot .steps li::before {
  content: counter(s) ". ";
  color: var(--ink-mid);
}
.slot .permalink {
  border-bottom: 1px solid var(--ink-faint);
  padding-bottom: var(--s3);
  margin-bottom: var(--s3);
}

/* ---------- panel («твоя ветка») ---------- */
.panel {
  border-top: 1px solid var(--ink-faint);
  padding-top: var(--s3);
  font-size: 14px;
  max-width: var(--text);
}
.panel .kv {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-mid);
}
.panel > p.meta,
.panel #invite-result .field-label {
  margin-top: var(--s3);
}

/* ---------- toast ---------- */
.toast {
  position: fixed;
  left: var(--s4);
  right: var(--s4);
  bottom: var(--s4);
  margin: 0 auto;
  max-width: 480px;
  display: flex;
  gap: var(--s3);
  align-items: center;
  justify-content: space-between;
  background: var(--paper);
  border: 1px solid var(--ink);
  padding: var(--s2) var(--s3);
  font-size: 14px;
  z-index: 4;
}
.toast .close {
  min-height: 0;
  border: 0;
  padding: 0 var(--s1);
  background: none;
}

/* ---------- collapsible ---------- */
details.collapsible summary {
  cursor: pointer;
  font-size: 16px;
  min-height: var(--tap);
  display: flex;
  align-items: center;
}
details.collapsible .body {
  max-width: var(--text);
  padding-top: var(--s3);
}
details.list summary {
  cursor: pointer;
  color: var(--ink-mid);
  font-size: 14px;
  margin-top: var(--s2);
  min-height: var(--tap);
  display: flex;
  align-items: center;
}

/* ---------- textpage ---------- */
.textpage {
  max-width: var(--text);
}
.textpage h2 {
  font-size: 16px;
  color: var(--ink);
  letter-spacing: 0;
  margin-top: var(--s6);
}
.textpage h3 {
  margin-top: var(--s5);
}
.textpage ul,
.textpage ol {
  padding-left: var(--s5);
  margin: 0 0 var(--s3);
}
.textpage li {
  margin-bottom: var(--s1);
}
.textpage pre {
  font-family: var(--mono);
  font-size: 13px;
  background: var(--paper-sunk);
  border: 1px solid var(--ink-mid);
  padding: var(--s2) var(--s3);
  overflow-x: auto;
  margin: 0 0 var(--s3);
}
.textpage blockquote {
  margin: 0 0 var(--s3);
  padding-left: var(--s3);
  border-left: 1px solid var(--ink-faint);
  color: var(--ink-mid);
}
.textpage table,
.status-table {
  border-collapse: collapse;
  width: 100%;
  font-family: var(--mono);
  font-size: 13px;
}
.status-table th,
.status-table td,
.textpage th,
.textpage td {
  text-align: left;
  padding: var(--s2) var(--s3) var(--s2) 0;
  border-bottom: 1px solid var(--ink-faint);
  vertical-align: top;
  font-weight: normal;
}
.status-table th {
  color: var(--ink-mid);
}
.status-table tr.is-alert td {
  color: var(--alert);
}
.scroll-x {
  overflow-x: auto;
}

footer {
  margin-top: var(--s7);
  padding-top: var(--s3);
  border-top: 1px solid var(--ink);
  font-size: 13px;
  color: var(--ink-mid);
  display: flex;
  gap: var(--s2) var(--s4);
  flex-wrap: wrap;
}

/* ---------- раскладка ---------- */
@media (min-width: 641px) {
  .tree .canvas {
    height: 520px;
  }
  .tree .list-toggle {
    display: none;
  }
}
@media (min-width: 768px) {
  .frame .body {
    aspect-ratio: auto;
    height: min(70vh, 720px);
  }
  .two {
    grid-template-columns: 1fr 2fr;
  }
  .queue-rows li[data-extra] {
    display: flex;
  }
  .more.mobile-only {
    display: none;
  }
}
@media (min-width: 1024px) {
  .masthead .meta {
    flex-basis: auto;
    margin-left: auto;
  }
}

/* ---------- движение ---------- */
@media (prefers-reduced-motion: reduce) {
  .frame.flash,
  .frame.flash iframe,
  .frame.flash .state,
  .rows li.new,
  .caret::after {
    animation: none;
  }
  .caret::after {
    opacity: 1;
  }
}
