/* Western Setup — «Wanted Poster» design system.
   Источник стиля: mockups/v1-wanted-poster.html (пункт 1 roadmap).
   Правило проекта: поведение Bootstrap не трогаем — только визуальные
   переменные и оформительские overrides. */

:root {
  /* Сцена: доски салунного стола, на них разложена бумага. Фон страницы —
     тёмный орех со швами между досками; всё содержательное живёт на карточках
     цвета --card-paper. Отсюда две пары «фон + текст», их нельзя путать:
       на дереве  — --on-wood / --on-wood-soft / --brass-light / --link-wood;
       на бумаге  — --ink / --ink-soft / --stamp / --brass.
     Карточка непрозрачна нарочно: полупрозрачная ловила бы свой участок
     градиента, и плашки шагов различались бы по цвету. */
  --wood-top: #5A3821;
  --wood: #412818;
  --wood-deep: #2E1B10;
  --on-wood: #F2E2C4;
  --on-wood-soft: #DDC8A6;
  --brass-light: #B98F4E;
  --link-wood: #F3B45F;
  /* мелкие буквы Special Elite тонкие: половина пикселей штриха уходит в
     сглаживание, и на них контраст падает вчетверо. Для набора мельче основного
     берём светлую латунь, а не --link-wood */
  --brass-bright: #FFE0AC;

  --card-paper: #F7EBD6;
  --card-deep: #E9D6B4;  /* поля контролов на карточке */
  /* зерно старой бумаги: одна текстура на доски и на карточки */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2'/%3E%3CfeColorMatrix values='0 0 0 0 .24 0 0 0 0 .16 0 0 0 0 .07 0 0 0 .05 0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  --ink: #33261A;
  --ink-soft: #5C4832;
  --stamp: #8E2F1C;
  --stamp-deep: #742515;
  --brass: #7A5B22;
  --cream: #FFF8EC;
  /* обводка фокуса: наследуется, поэтому на карточках её перебивает печать */
  --focus: var(--link-wood);

  --bs-body-bg: var(--wood);
  --bs-body-color: var(--on-wood);
  --bs-body-font-family: "Crimson Pro", Georgia, serif;
  /* кегль меряем по росту строчных, а не по формальному размеру: у Crimson Pro
     x-height 0.42 em — на 13% ниже Georgia и на 6% ниже системного шрифта iOS.
     18.4px дают рост 7.7px, то есть кегль основного текста из Apple HIG (17 pt).
     Ниже этого проза в приложении не опускается. */
  --bs-body-font-size: 1.15rem;
  --bs-border-radius: .25rem;
  /* Bootstrap красит <a> через *-rgb-переменные; без них ссылка остаётся синей.
     Базовая ссылка — на дереве; на карточках её перебивает .card ниже. */
  --bs-link-color: var(--link-wood);
  --bs-link-hover-color: var(--on-wood);
  --bs-link-color-rgb: 243, 180, 95;
  --bs-link-hover-color-rgb: 242, 226, 196;
}

body {
  background-color: var(--wood);
  /* доски: зерно + швы между планками + заливка вглубь, всё на чистом CSS.
     Заливка тянется на всю высоту документа (не 100vh и не fixed:
     background-attachment: fixed на мобильных webkit ведёт себя непредсказуемо),
     поэтому на длинной странице стол темнеет к дальнему краю. */
  background-image:
    var(--grain),
    repeating-linear-gradient(90deg, rgba(0, 0, 0, 0) 0 84px, rgba(0, 0, 0, .22) 84px 88px),
    linear-gradient(180deg, var(--wood-top) 0%, var(--wood) 55%, var(--wood-deep) 100%);
  background-repeat: repeat, repeat, no-repeat;
  min-height: 100vh;
}

/* Возврат к «бумажным» токенам внутри любой карточки: цвет текста, ссылок и
   обводки фокуса наследуются, поэтому достаточно перекрыть их на контейнере. */
.card, .poster, .alert-expansions {
  color: var(--ink);
  --focus: var(--stamp);
  --bs-link-color-rgb: 142, 47, 28;
  --bs-link-hover-color-rgb: 116, 37, 21;
}

.display-font { font-family: "Rye", "Crimson Pro", serif; font-weight: 400; }
.label-font { font-family: "Special Elite", "Courier New", monospace; letter-spacing: .04em; }

/* ——— poster frame: фирменный элемент стиля ——— */
.poster {
  border: 3px solid var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: 5px;
  background: var(--card-paper) var(--grain);
  position: relative;
}
.poster-stars::before, .poster-stars::after {
  content: "★";
  position: absolute;
  top: .4rem;
  color: var(--brass);
  font-size: 1.1rem;
}
.poster-stars::before { left: .75rem; }
.poster-stars::after { right: .75rem; }

.eyebrow {
  font-family: "Special Elite", monospace;
  font-size: 1rem;
  color: var(--stamp);
  text-transform: uppercase;
  letter-spacing: .35em;
}

.brand-title {
  font-family: "Rye", serif;
  text-transform: uppercase;
  line-height: 1.05;
}

h2.section-title, .section-title {
  font-family: "Rye", serif;
  font-size: 1.25rem;
  text-transform: uppercase;
  letter-spacing: .06em;
}

.rule-ornament {
  display: flex;
  align-items: center;
  gap: .6rem;
  color: var(--brass-light);
  margin: 1.4rem 0 .9rem;
}
.rule-ornament::before, .rule-ornament::after {
  content: "";
  flex: 1;
  border-top: 2px solid var(--brass-light);
}

/* ——— Bootstrap components: только визуальные переменные ——— */
.btn-primary {
  --bs-btn-bg: var(--stamp);
  --bs-btn-border-color: var(--stamp-deep);
  --bs-btn-color: var(--cream);
  --bs-btn-hover-bg: var(--stamp-deep);
  --bs-btn-hover-border-color: var(--stamp-deep);
  --bs-btn-hover-color: var(--cream);
  --bs-btn-active-bg: var(--stamp-deep);
  --bs-btn-active-border-color: var(--ink);
  --bs-btn-active-color: var(--cream);
  --bs-btn-focus-shadow-rgb: 142, 47, 28;
  --bs-btn-padding-y: .8rem;
  --bs-btn-padding-x: 1.6rem;
  --bs-btn-font-size: 1.2rem;
  font-family: "Special Elite", monospace;
  text-transform: uppercase;
  letter-spacing: .08em;
  box-shadow: 3px 3px 0 var(--ink);
}
/* стоит и на дереве (футер), и на бумаге (финальный постер) — токены берём
   контекстные: .card/.poster переопределяют их на себе */
.btn-outline-secondary {
  --bs-btn-color: var(--on-wood);
  --bs-btn-border-color: var(--brass-light);
  --bs-btn-hover-bg: var(--on-wood);
  --bs-btn-hover-border-color: var(--on-wood);
  --bs-btn-hover-color: var(--wood-deep);
  --bs-btn-active-bg: var(--on-wood);
  --bs-btn-active-border-color: var(--on-wood);
  --bs-btn-active-color: var(--wood-deep);
  font-family: "Special Elite", monospace;
}
.card .btn-outline-secondary, .poster .btn-outline-secondary {
  --bs-btn-color: var(--ink);
  --bs-btn-border-color: var(--brass);
  --bs-btn-hover-bg: var(--ink);
  --bs-btn-hover-border-color: var(--ink);
  --bs-btn-hover-color: var(--cream);
  --bs-btn-active-bg: var(--ink);
  --bs-btn-active-border-color: var(--ink);
  --bs-btn-active-color: var(--cream);
}

.card {
  --bs-card-bg: var(--card-paper);
  --bs-card-border-color: var(--ink);
  --bs-card-border-width: 2px;
  background-image: var(--grain);
  /* бумага лежит на столе: тень плотнее, чем была на светлом фоне */
  box-shadow: 4px 5px 0 rgba(0, 0, 0, .35);
}
.list-group {
  --bs-list-group-bg: transparent;
  --bs-list-group-border-color: rgba(51, 38, 26, .35);
  --bs-list-group-color: var(--ink);
}

/* табличка с латунными буквами: ореховое поле и золотой кант — та же пара,
   что у надписей на досках. Заодно не спорит с красной печатью кнопок. */
.badge-brass {
  background: var(--wood);
  color: var(--brass-bright);
  box-shadow: inset 0 0 0 1px rgba(255, 224, 172, .5);
  font-family: "Special Elite", monospace;
  font-weight: 400;
  /* .75em по умолчанию давало 12.75px — на таком кегле штрих не закрывает
     пиксель целиком; фиксируем размер, чтобы он не зависел от контекста */
  font-size: .9rem;
  letter-spacing: .02em;
  /* по умолчанию бейдж сидит на базовой линии и свисает ниже соседнего текста */
  vertical-align: .18em;
}

/* ——— form controls: только визуальные переменные/оформление ——— */
.form-check-input {
  width: 1.3em;
  height: 1.3em;
  margin-top: .18em;
  background-color: var(--card-deep);
  border: 2px solid var(--ink);
}
.form-check-input:checked {
  background-color: var(--stamp);
  border-color: var(--stamp-deep);
}
.form-check-input:focus { border-color: var(--ink); }
.form-switch .form-check-input {
  width: 2.9em;
  height: 1.55em;
  --bs-form-switch-bg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%2333261A'/%3E%3C/svg%3E");
}
.form-switch .form-check-input:checked {
  --bs-form-switch-bg: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23FFF8EC'/%3E%3C/svg%3E");
}

.list-group-item { padding: .8rem 1rem; }
/* название опции держит ту же долю над пояснением, что и до укрупнения прозы
   (1.22): иначе бы они сравнялись и список перестал читаться списком */
.form-check-label { font-size: 1.4rem; }
/* пояснение под названием опции — тот же кегль, что и вся проза: собственного
   размера у него больше нет, «чуть мельче основного» и делало его нечитаемым */
.item-note { color: var(--ink-soft); }

/* ——— экран раскладки (steps.html): прогрессивный чеклист ——— */
/* заголовок фазы стоит на досках — печать там не читается, берём латунь */
h2.step-phase { font-size: .85rem; letter-spacing: .25em; color: var(--link-wood); }
.step-card .step-count { font-size: .8rem; color: var(--ink-soft); }
/* заголовок держится вровень с текстом по кеглю — Rye при том же размере выше
   на глаз (x-height 0.566 против 0.42), иерархию даёт шрифт, а не размер */
.step-card .step-title { font-size: 1.15rem; }
.step-diagram { width: 100%; max-width: 240px; }
.step-diagram svg { width: 100%; height: auto; display: block; }
/* пройденный шаг: приглушаем цветом (не opacity — контраст остаётся AA) */
.step-done { --bs-card-border-color: rgba(51, 38, 26, .45); box-shadow: none; }
.step-done .step-title, .step-done .step-text { color: var(--ink-soft); }
.progress {
  /* дорога впереди — светлая колея: на тёмной рейке чёрный трек сливался с ней
     и путь обрывался там, где стоит повозка */
  --bs-progress-bg: rgba(255, 224, 172, .16);
  --bs-progress-bar-bg: var(--link-wood);
}

/* ——— дорога с повозкой: рейка, прибитая к верху экрана ——— */
.trail-dock {
  position: sticky;
  top: 0;
  z-index: 20;
  /* фон шире колонки на гуттеры контейнера: иначе тень карточки,
     уезжающей под рейку, просвечивает в боковом поле */
  margin-inline: -.75rem;
  padding: .5rem .75rem .6rem;
  background: var(--wood-deep);
  border-bottom: 2px solid var(--brass-light);
  box-shadow: 0 6px 12px rgba(0, 0, 0, .4);
}
.trail { position: relative; padding-top: 26px; }  /* место повозке над дорогой */
.trail .progress { height: .125rem; }  /* колея, а не полоса: тонкая линия под колёсами */
/* Упряжка: ::before — фургон «Old wagon» (Delapouite, game-icons.net, CC BY 3.0),
   ::after — лошадь собственной генерации (Stability AI → векторизация, порядок в
   docs/illustration-pipeline.md). Готовой лошади в профиль в свободных наборах нет:
   в game-icons только всадники, голова, единорог и пегас, у Phosphor тоже голова,
   у Tabler и Line Awesome контурный стиль, у mdi ноги в пиксель толщиной. Обе маской,
   а не картинкой: красятся палитрой и не добавляют файлов в прекеш. viewBox у обеих
   обрезан по bbox пути, поэтому коробка совпадает с рисунком и упряжка встаёт на
   дорогу колёсами и копытами. */
.wagon {
  position: absolute;
  bottom: .125rem;  /* высота дороги: колёса стоят на её поверхности, а не в ней */
  width: 60px;      /* фургон 34 + сцепка 3 + лошадь 23 */
  height: 27px;
  /* упряжка не свисает за края: на 0 стоит у левого конца, на 1 — у правого */
  left: calc(30px + (100% - 60px) * var(--p, 0));
  transform: translateX(-50%);
  transition: left .6s ease;  /* тот же тайминг, что у .progress-bar в Bootstrap */
}
.wagon::before, .wagon::after {
  content: "";
  position: absolute;
  bottom: 0;
  background-color: var(--brass-bright);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: contain;
  mask-size: contain;
}
.wagon::before {
  left: 0;
  width: 34px;
  height: 27px;  /* пропорция пути 465:368 */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='24 118 465 368'%3E%3Cpath d='M425 118c-9 0-17 3-25 6c-9 4-18 9-28 12c-7 2-14 4-22 3c-23 71-28 149-29 220h68c-1-6-2-12-2-20c0-19 4-43 11-70c12-49 34-105 61-140c-11-7-21-11-30-11a48 48 0 0 0-4 0zM331 140c-12 4-24 8-38 11c-18 3-39 2-67-10V359h78c1-69 5-147 27-219m-124 5c-18 12-34 19-51 19c-16 0-33-6-54-17c19 69 25 145 26 212h78zM85 147c-11 12-23 19-35 22c-9 3-18 3-26 2c12 29 22 63 25 96c4 33 2 65-9 91h72c-1-68-7-144-26-212zM409 309c0 0 0 1 0 1l-3 28c0 1 0 1 0 2c0 8 1 14 2 18c0 1 1 2 1 2h40v16h18v-34h-44v-32zM33 377v46H48c2-18 11-34 25-46zm135 0c13 12 22 28 25 46h47c2-18 11-34 25-46zm192 0c13 12 22 28 25 46h47v-14h57v-18h-57v-14h-71zm-249 1a55 55 0 0 0-23 10l23 23zm18 0v33l23-23a55 55 0 0 0-23-10m174 0a55 55 0 0 0-23 10l23 23zm18 0v33l23-23a55 55 0 0 0-23-10m-246 22A55 55 0 0 0 66 423h33l-23-23zm90 0L142 423h33a55 55 0 0 0-10-23zm102 0A55 55 0 0 0 258 423h33l-23-23zm90 0L334 423h33a55 55 0 0 0-10-23zM66 441a55 55 0 0 0 10 23L99 441zm76 0l23 23A55 55 0 0 0 175 441zm116 0a55 55 0 0 0 10 23L291 441zm76 0l23 23A55 55 0 0 0 367 441zm-223 13L88 477a55 55 0 0 0 23 10zm18 0v33a55 55 0 0 0 23-10zm174 0l-23 23a55 55 0 0 0 23 10zm18 0v33a55 55 0 0 0 23-10z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='24 118 465 368'%3E%3Cpath d='M425 118c-9 0-17 3-25 6c-9 4-18 9-28 12c-7 2-14 4-22 3c-23 71-28 149-29 220h68c-1-6-2-12-2-20c0-19 4-43 11-70c12-49 34-105 61-140c-11-7-21-11-30-11a48 48 0 0 0-4 0zM331 140c-12 4-24 8-38 11c-18 3-39 2-67-10V359h78c1-69 5-147 27-219m-124 5c-18 12-34 19-51 19c-16 0-33-6-54-17c19 69 25 145 26 212h78zM85 147c-11 12-23 19-35 22c-9 3-18 3-26 2c12 29 22 63 25 96c4 33 2 65-9 91h72c-1-68-7-144-26-212zM409 309c0 0 0 1 0 1l-3 28c0 1 0 1 0 2c0 8 1 14 2 18c0 1 1 2 1 2h40v16h18v-34h-44v-32zM33 377v46H48c2-18 11-34 25-46zm135 0c13 12 22 28 25 46h47c2-18 11-34 25-46zm192 0c13 12 22 28 25 46h47v-14h57v-18h-57v-14h-71zm-249 1a55 55 0 0 0-23 10l23 23zm18 0v33l23-23a55 55 0 0 0-23-10m174 0a55 55 0 0 0-23 10l23 23zm18 0v33l23-23a55 55 0 0 0-23-10m-246 22A55 55 0 0 0 66 423h33l-23-23zm90 0L142 423h33a55 55 0 0 0-10-23zm102 0A55 55 0 0 0 258 423h33l-23-23zm90 0L334 423h33a55 55 0 0 0-10-23zM66 441a55 55 0 0 0 10 23L99 441zm76 0l23 23A55 55 0 0 0 175 441zm116 0a55 55 0 0 0 10 23L291 441zm76 0l23 23A55 55 0 0 0 367 441zm-223 13L88 477a55 55 0 0 0 23 10zm18 0v33a55 55 0 0 0 23-10zm174 0l-23 23a55 55 0 0 0 23 10zm18 0v33a55 55 0 0 0 23-10z'/%3E%3C/svg%3E");
}
.wagon::after {
  right: 0;
  width: 23px;
  height: 20px;  /* пропорция пути 589:512; к фургону 0.73 — как в жизни */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 589 512'%3E%3Cpath d='M550 0 535 17 524 15 525 0 520 2 512 13 498 11 496 8 483 11 461 8 450 13 445 20 426 20 412 30 398 35 408 34 408 38 394 46 386 44 386 48 374 55 382 50 388 50 388 54 361 73 362 77 354 86 357 82 362 83 357 93 340 96 344 102 341 113 334 117 324 115 337 119 338 124 323 124 321 128 336 130 337 134 331 137 320 136 321 140 316 145 318 148 324 148 324 153 316 156 321 156 322 160 313 166 281 170 223 157 186 157 165 163 140 178 109 188 89 202 77 219 60 254 60 288 51 310 55 301 60 302 55 323 48 331 35 336 40 337 37 342 23 346 9 343 32 347 31 352 16 351 29 353 29 357 23 363 12 367 0 365 11 368 31 366 31 371 21 377 0 377 16 382 16 387 0 392 20 390 16 399 5 398 17 400 15 405 3 407 15 408 15 412 9 417 19 412 16 423 21 422 21 426 24 421 31 419 31 426 38 412 43 413 42 419 48 410 52 410 48 424 55 412 60 414 81 374 85 374 86 377 93 357 98 357 109 299 115 300 113 291 116 290 113 281 114 277 119 278 131 317 132 331 128 341 119 356 92 379 83 427 74 453 63 470 63 485 76 491 72 511 109 512 92 484 93 461 104 424 117 408 123 397 150 375 173 353 178 353 177 359 151 398 150 404 179 465 186 498 194 490 199 490 202 493 203 503 208 505 208 512 248 512 233 494 227 492 202 466 185 431 186 416 190 416 237 447 251 472 258 465 265 466 267 491 287 499 303 500 295 476 286 467 273 446 228 415 214 399 214 386 229 341 231 328 244 313 275 327 297 333 324 336 363 333 372 338 378 433 372 444 352 464 336 457 333 466 320 472 315 481 315 490 325 508 327 508 347 485 354 487 368 479 379 461 403 436 406 425 405 390 412 350 416 350 455 387 485 422 494 443 490 454 495 454 492 478 494 473 498 473 502 483 502 480 506 478 514 480 517 483 515 497 520 500 522 507 556 503 544 485 527 471 505 425 500 402 477 369 455 315 456 307 470 281 475 261 475 245 465 211 474 186 484 129 491 124 512 129 518 136 544 152 550 166 555 170 579 166 589 146 586 136 571 115 568 107 570 102 561 85 560 61 565 60 564 56 558 53 556 43 546 30 551 13z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 589 512'%3E%3Cpath d='M550 0 535 17 524 15 525 0 520 2 512 13 498 11 496 8 483 11 461 8 450 13 445 20 426 20 412 30 398 35 408 34 408 38 394 46 386 44 386 48 374 55 382 50 388 50 388 54 361 73 362 77 354 86 357 82 362 83 357 93 340 96 344 102 341 113 334 117 324 115 337 119 338 124 323 124 321 128 336 130 337 134 331 137 320 136 321 140 316 145 318 148 324 148 324 153 316 156 321 156 322 160 313 166 281 170 223 157 186 157 165 163 140 178 109 188 89 202 77 219 60 254 60 288 51 310 55 301 60 302 55 323 48 331 35 336 40 337 37 342 23 346 9 343 32 347 31 352 16 351 29 353 29 357 23 363 12 367 0 365 11 368 31 366 31 371 21 377 0 377 16 382 16 387 0 392 20 390 16 399 5 398 17 400 15 405 3 407 15 408 15 412 9 417 19 412 16 423 21 422 21 426 24 421 31 419 31 426 38 412 43 413 42 419 48 410 52 410 48 424 55 412 60 414 81 374 85 374 86 377 93 357 98 357 109 299 115 300 113 291 116 290 113 281 114 277 119 278 131 317 132 331 128 341 119 356 92 379 83 427 74 453 63 470 63 485 76 491 72 511 109 512 92 484 93 461 104 424 117 408 123 397 150 375 173 353 178 353 177 359 151 398 150 404 179 465 186 498 194 490 199 490 202 493 203 503 208 505 208 512 248 512 233 494 227 492 202 466 185 431 186 416 190 416 237 447 251 472 258 465 265 466 267 491 287 499 303 500 295 476 286 467 273 446 228 415 214 399 214 386 229 341 231 328 244 313 275 327 297 333 324 336 363 333 372 338 378 433 372 444 352 464 336 457 333 466 320 472 315 481 315 490 325 508 327 508 347 485 354 487 368 479 379 461 403 436 406 425 405 390 412 350 416 350 455 387 485 422 494 443 490 454 495 454 492 478 494 473 498 473 502 483 502 480 506 478 514 480 517 483 515 497 520 500 522 507 556 503 544 485 527 471 505 425 500 402 477 369 455 315 456 307 470 281 475 261 475 245 465 211 474 186 484 129 491 124 512 129 518 136 544 152 550 166 555 170 579 166 589 146 586 136 571 115 568 107 570 102 561 85 560 61 565 60 564 56 558 53 556 43 546 30 551 13z'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) {
  .wagon { transition: none; }
}
/* scrollIntoView в goToActive() иначе прячет верх карточки под рейкой */
.step-card, #final-poster { scroll-margin-top: 4.5rem; }
.alert-expansions {
  --bs-alert-bg: var(--card-paper);
  --bs-alert-border-color: var(--brass);
  --bs-alert-color: var(--ink-soft);
  border-width: 2px;
}

.step-stamp {
  font-family: "Special Elite", monospace;
  color: var(--stamp);
  border: 2px solid var(--stamp);
  border-radius: .25rem;
  display: inline-block;
  padding: .1rem .55rem;
  transform: rotate(-2deg);
  text-transform: uppercase;
  font-size: .95rem;
}

/* ——— hub tiles: карточка-раздел целиком кликабельна ——— */
a.hub-tile {
  display: block;
  color: var(--ink);
  text-decoration: none;
  height: 100%;
  padding: 1.5rem 1.25rem;
}
a.hub-tile .tile-note { color: var(--ink-soft); }
a.hub-tile:hover, a.hub-tile:focus-visible {
  background: rgba(255, 248, 236, .75);
}
@media (prefers-reduced-motion: no-preference) {
  .card-tile { transition: transform .12s ease; }
  .card-tile:has(.hub-tile:hover) { transform: translate(-2px, -2px); }
}
.card-tile { height: 100%; }

.text-soft { color: var(--ink-soft); }  /* только внутри карточек */

/* ——— back link: постоянная навигация в шапке внутренних страниц ——— */
.back-link {
  display: inline-block;
  font-family: "Special Elite", "Courier New", monospace;
  font-size: .95rem;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--on-wood);
  text-decoration: underline;
  text-decoration-color: var(--brass-light);
  text-decoration-thickness: 2px;
  text-underline-offset: .28em;
  padding: .35rem 0;
}
.back-link::before {
  /* стрелка своя: в latin-сабсете Special Elite нет «←», системная выглядит чужой */
  content: "";
  display: inline-block;
  width: .85em;
  height: .85em;
  margin-right: .4em;
  vertical-align: -.06em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.5 1.5 8 8 14.5 M1.5 8 H15' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 1.5 1.5 8 8 14.5 M1.5 8 H15' fill='none' stroke='black' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center / contain;
}
.back-link:hover, .back-link:focus-visible {
  color: var(--link-wood);
  text-decoration-color: var(--link-wood);
}

/* ——— вывеска Buy Me a Coffee: старый щит, прибитый к доскам подвала ———
   Собрано на превью app/_signs.html (в git не входило) из четырёх вариантов;
   владелец выбрал щит на гвоздях. Фактура — старая кремовая эмаль по дереву,
   своя генерация (Stability AI, docs/illustration-pipeline.md), приведена
   к палитре: app/img/sign-board.png. */
.coffee-sign {
  /* Шляпка гвоздя — картинкой, а не радиальным градиентом: у градиента центр
     смещён в угол, радиус считается до дальнего угла тайла, и круг вылезал
     за свою коробку, шляпка обрезалась в полуквадрат. В SVG круг с полями. */
  --nail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cdefs%3E%3CradialGradient id='n' cx='36%25' cy='30%25' r='78%25'%3E%3Cstop offset='0' stop-color='%234A443B'/%3E%3Cstop offset='.42' stop-color='%23231E18'/%3E%3Cstop offset='1' stop-color='%23090706'/%3E%3C/radialGradient%3E%3C/defs%3E%3Ccircle cx='6' cy='6' r='5.4' fill='url(%23n)' stroke='%23000' stroke-opacity='.55' stroke-width='.7'/%3E%3Ccircle cx='4.3' cy='3.9' r='1.35' fill='%23FFF' fill-opacity='.3'/%3E%3C/svg%3E");
  --paint: #B4643C;   /* свинцовый сурик: тем и красили вывески; красная печать палитры читалась кровью */
  display: inline-block;
  position: relative;
  text-decoration: none;
  text-align: center;
  line-height: 1.1;
  padding: .8rem 1.9rem .85rem;
  color: var(--ink);
  background:
    var(--nail) 9px 8px / 8px 8px no-repeat,
    var(--nail) calc(100% - 9px) 8px / 8px 8px no-repeat,
    var(--nail) 9px calc(100% - 8px) / 8px 8px no-repeat,
    var(--nail) calc(100% - 9px) calc(100% - 8px) / 8px 8px no-repeat,
    url("../img/sign-board.png") center / cover,
    var(--card-paper);
  border: 3px solid var(--ink);
  /* внешний кант кольцом тени, а не outline: outline занят обводкой фокуса */
  box-shadow: 0 0 0 4px rgba(0, 0, 0, 0), 0 0 0 5px var(--ink), 4px 5px 0 rgba(0, 0, 0, .35);
  transform: rotate(-1.2deg);
}
/* Rye идёт одним начертанием, жирного у него нет: вес добавляем обводкой по
   контуру глифа — штрих набирает толщину, а форма буквы не плывёт */
.coffee-sign__top {
  display: block;
  font-family: "Rye", serif;
  font-size: .92rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  margin-bottom: .18rem;
  -webkit-text-stroke: .4px currentColor;
}
.coffee-sign__main {
  display: block;
  font-family: "Rye", serif;
  font-size: 1.32rem;
  letter-spacing: .02em;
  white-space: nowrap;
  -webkit-text-stroke: .5px currentColor;
}
/* буквы выбиты в эмали: тёмная кромка сверху, кремовый блик снизу — свет
   падает сверху, поэтому дно углубления в тени, а нижняя фаска подсвечена */
.coffee-sign__top, .coffee-sign__main {
  text-shadow: 0 -1px 0 rgba(51, 38, 26, .45), 0 1px 0 rgba(255, 248, 236, .95), 0 2px 1px rgba(51, 38, 26, .18);
}
/* «Whiskey» замазано двумя широкими мазками по дуге. Форму задаёт маска из
   SVG-дуг: клип-путём кривую не нарисовать, а маска ещё и оставляет цвет за
   краской. Каждый мазок — несколько лент разной толщины с просветами между
   ними, как от подсохшей кисти. */
.coffee-sign s {
  text-decoration: none;
  position: relative;
  margin-right: .15em;
}
.coffee-sign s::before, .coffee-sign s::after {
  content: "";
  position: absolute;
  left: -6%;
  right: -8%;
  top: -10%;
  bottom: -12%;
  pointer-events: none;
  background: var(--paint);
  opacity: .8;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%;
  mask-size: 100% 100%;
}
.coffee-sign s::before {   /* обратный проход кисти: дуга прогибается вниз */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cg fill='none' stroke='%23fff' stroke-linecap='round'%3E%3Cpath d='M12 24 C 62 44 138 46 188 31' stroke-width='7'/%3E%3Cpath d='M24 38 C 74 55 126 56 176 44' stroke-width='4'/%3E%3Cpath d='M46 16 C 86 30 118 31 158 23' stroke-width='2.5'/%3E%3C/g%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cg fill='none' stroke='%23fff' stroke-linecap='round'%3E%3Cpath d='M12 24 C 62 44 138 46 188 31' stroke-width='7'/%3E%3Cpath d='M24 38 C 74 55 126 56 176 44' stroke-width='4'/%3E%3Cpath d='M46 16 C 86 30 118 31 158 23' stroke-width='2.5'/%3E%3C/g%3E%3C/svg%3E");
}
.coffee-sign s::after {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cg fill='none' stroke='%23fff' stroke-linecap='round'%3E%3Cpath d='M6 44 C 55 26 140 24 194 32' stroke-width='9'/%3E%3Cpath d='M10 32 C 60 15 136 13 192 20' stroke-width='7'/%3E%3Cpath d='M18 54 C 68 38 132 36 182 42' stroke-width='5'/%3E%3Cpath d='M40 22 C 84 9 122 8 164 12' stroke-width='2.5'/%3E%3C/g%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 60' preserveAspectRatio='none'%3E%3Cg fill='none' stroke='%23fff' stroke-linecap='round'%3E%3Cpath d='M6 44 C 55 26 140 24 194 32' stroke-width='9'/%3E%3Cpath d='M10 32 C 60 15 136 13 192 20' stroke-width='7'/%3E%3Cpath d='M18 54 C 68 38 132 36 182 42' stroke-width='5'/%3E%3Cpath d='M40 22 C 84 9 122 8 164 12' stroke-width='2.5'/%3E%3C/g%3E%3C/svg%3E");
}
.coffee-sign:hover, .coffee-sign:focus-visible { color: var(--stamp-deep); }

footer { color: var(--on-wood-soft); font-size: .95rem; }
/* Внутренние страницы: в подвале только номер версии, орнамент там отделял бы
   карточки от одной строки. Держим полосу узкой — на мобильном прежний подвал
   съедал под последней карточкой ~140 px пустых досок. */
.page-foot { padding-bottom: 1rem; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--card-paper);
  color: var(--ink);
  padding: .5rem 1rem;
  z-index: 100;
}
.skip-link:focus-visible { left: .5rem; top: .5rem; }

/* --focus наследуется: латунь на досках, печать внутри карточек */
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }

@media (prefers-reduced-motion: no-preference) {
  .btn-primary { transition: transform .12s ease; }
  .btn-primary:hover { transform: translate(-1px, -1px); }
}
