@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');

:root {
  --accent: #c1121f;
  --bg-dark-start: #050505;
  --bg-dark-end: #141418;
  --text-light: #f1f1f1;
  --text-muted: #9a9aa3;
  --font-family: "Inter", "Segoe UI", Arial, sans-serif;
  --font-heading: "Playfair Display", Georgia, serif;
  --font-mono: "Courier New", monospace;
}

/* Тема "hacker" (подход 2, Theme Engine) — референс дизайна Resend
   (DESIGN.md): чистый чёрный холст, графитовые 1px рамки, строгая
   типографика без засечек. Переключается через
   document.documentElement[data-theme], см. nav.js initTheme(). Точечные
   переопределения конкретных компонентов (карточки/модалки/кнопки/инпуты,
   терминальный режим компьютера/телефона) — в конце файла, см. секцию
   "HACKER THEME — Component Overrides". */
[data-theme="hacker"] {
  --font-family: "Inter", sans-serif;
  --font-heading: "Inter", sans-serif;
  --font-mono: "JetBrains Mono", monospace;

  --bg-dark-start: #000000;
  --bg-dark-end: #000000;
  --text-light: #ffffff;
  --text-muted: #8a8f98;
  --accent: #ff3333;

  --border-color: #292d30;
  --border-color-hover: #3f4448;
  --card-radius: 8px;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html {
  height: 100%;
  background: linear-gradient(160deg, var(--bg-dark-start), var(--bg-dark-end));
  overscroll-behavior-y: none;
}

body {
  min-height: 100vh;
  min-height: 100dvh;
  font-family: var(--font-family);
  color: var(--text-light);
  background: linear-gradient(160deg, var(--bg-dark-start), var(--bg-dark-end));
  overscroll-behavior-y: none;
  overflow-x: hidden;
}

/* Глобальный «киноплёночный» шум поверх всего сайта. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 180px 180px;
}

/* В hacker-теме плёночного шума не будет (см. подход 2) — отключаем эффект
   заранее, чтобы правки styles.css под конкретный визуал не пришлось
   переплетать с этим селектором позже. */
[data-theme="hacker"] body::after {
  content: none;
}

/* Блокировка скролла страницы при открытой модалке — класс переключается
   в nav.js (setupModalScrollLock()) через MutationObserver за всеми
   backdrop-элементами сайта. Оба селектора (html и html body) нужны, т.к. в
   разных браузерах скроллящимся элементом может быть либо <html>, либо
   <body>. */
html.modal-open,
html.modal-open body {
  overflow: hidden;
}

/* Верхняя панель с кнопкой входа */
.top-bar {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 10;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  padding: 1.5rem;
  box-sizing: border-box;
}

.login-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6rem 1.2rem;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--text-light);
  text-decoration: none;
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease;
}

.login-btn i {
  font-size: 0.85rem;
}

.login-btn:hover,
.login-btn:focus-visible {
  background-color: var(--accent);
  color: var(--bg-dark-start);
}

/* Hero-секция */
.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 2rem;
  background:
    radial-gradient(ellipse 80% 60% at 50% 40%, rgba(193, 18, 31, 0.12), transparent 55%),
    linear-gradient(180deg, #0a0a0c 0%, #050505 45%, #121218 100%);
  overflow: hidden;
}

.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse at center, transparent 35%, rgba(0, 0, 0, 0.65) 100%);
}

.hero__content {
  position: relative;
  z-index: 1;
  max-width: 960px;
}

.hero__title {
  font-family: var(--font-heading);
  font-size: clamp(2.1rem, 8vw, 5.5rem);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.15;
  white-space: nowrap;
}

.hero__title .accent {
  color: var(--accent);
}

.hero__subtitle {
  margin-top: 1rem;
  font-size: clamp(1rem, 2vw, 1.25rem);
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.hero__description {
  margin-top: 1.5rem;
  margin-left: auto;
  margin-right: auto;
  max-width: 42rem;
  font-size: clamp(0.95rem, 1.5vw, 1.1rem);
  line-height: 1.7;
  color: var(--text-muted);
}

/* Контейнер 3D-куба (Three.js, hero-3d.js) — премиальный элемент темы
   "hacker" (DESIGN.md/Resend). В noir скрыт: hero остаётся тем же
   центрированным одноколоночным блоком, что и раньше. Видимость и
   двухколоночный layout переопределены в секции "HACKER THEME —
   Component Overrides" в конце файла. */
.hero-3d-container {
  display: none;
}

/* Динамический лендинг (блоки из /api/site/active) */
.landing-container {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
}

/* Зебра-чередование фона блоков по позиции, независимо от типа блока. */
.landing-container > section {
  width: 100%;
}

.landing-container > section:nth-child(even) {
  background: rgba(0, 0, 0, 0.25);
}

.landing-section__inner {
  max-width: 960px;
  margin: 0 auto;
}

.landing-hero__cta,
a.auth-submit.landing-hero__cta {
  display: inline-block;
  margin-top: 2.5rem;
  width: auto;
  padding: 0.75rem 1.5rem;
  text-decoration: none;
  text-align: center;
}

.landing-cases {
  padding: 2.5rem 1.5rem 4rem;
  text-align: center;
}

.landing-cases__grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 1.25rem;
  margin-top: 1.5rem;
  text-align: left;
}

.landing-cases__all,
a.auth-submit.landing-cases__all {
  display: inline-block;
  width: auto;
  margin-top: 2.5rem;
  padding: 0.75rem 1.5rem;
  text-decoration: none;
  text-align: center;
}

.landing-section__title {
  font-family: var(--font-heading);
  font-size: clamp(1.4rem, 3vw, 2rem);
  font-weight: 600;
  letter-spacing: 0.02em;
  margin-bottom: 1.25rem;
  text-align: center;
}

.landing-features,
.landing-text-image-section,
.landing-faq-section {
  padding: 2.5rem 1.5rem;
}

.landing-features__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.25rem;
}

.landing-features__item {
  text-align: center;
  padding: 1.25rem 1rem;
  border: 1px solid rgba(241, 241, 241, 0.12);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.03);
}

.landing-features__icon {
  font-size: 1.75rem;
  color: var(--accent);
  margin-bottom: 0.75rem;
}

.landing-features__item-title {
  font-size: 1.05rem;
  margin-bottom: 0.5rem;
  color: var(--text-light);
}

.landing-features__item-text {
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.landing-text-image {
  display: flex;
  gap: 2rem;
  align-items: center;
}

.landing-text-image.align-right {
  flex-direction: row-reverse;
}

.landing-text-image__content {
  flex: 1;
  min-width: 0;
}

.landing-text-image__content .landing-section__title {
  text-align: left;
}

.landing-text-image__text {
  color: var(--text-muted);
  line-height: 1.65;
  white-space: pre-wrap;
}

.landing-text-image__media {
  flex: 1;
  min-width: 0;
}

.landing-text-image__media img {
  display: block;
  width: 100%;
  max-width: 100%;
  border-radius: 8px;
  object-fit: cover;
}

.landing-text-image__media--empty {
  min-height: 12rem;
  border: 1px dashed rgba(241, 241, 241, 0.2);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
}

.landing-faq__list {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.landing-faq__item {
  border: 1px solid rgba(241, 241, 241, 0.12);
  border-radius: 8px;
  padding: 0.85rem 1rem;
  background: rgba(255, 255, 255, 0.03);
}

.landing-faq__question {
  cursor: pointer;
  list-style: none;
  color: var(--text-light);
  font-weight: 500;
  text-align: center;
}

.landing-faq__question::-webkit-details-marker {
  display: none;
}

.landing-faq__answer {
  margin-top: 0.75rem;
  color: var(--text-muted);
  line-height: 1.55;
}

.landing-cta {
  text-align: center;
  padding: 3rem 1.5rem;
}

.landing-cta__subtitle {
  color: var(--text-muted);
  margin: 0.75rem auto 0;
  max-width: 36rem;
  line-height: 1.5;
}

.landing-cta__btn,
a.auth-submit.landing-cta__btn {
  display: inline-block;
  width: auto;
  margin-top: 2rem;
  padding: 0.75rem 1.5rem;
  text-decoration: none;
}

@media (max-width: 768px) {
  .landing-text-image,
  .landing-text-image.align-right {
    flex-direction: column;
  }

  .landing-text-image__content .landing-section__title {
    text-align: center;
  }
}

@media (max-width: 480px) {
  .landing-cases {
    padding: 1.5rem 1rem 3rem;
  }

  .landing-features,
  .landing-text-image-section,
  .landing-faq-section,
  .landing-cta {
    padding: 2rem 1rem;
  }
}

/* Редактор лендинга (site-editor) */
.site-editor-page {
  overflow: hidden;
  height: 100vh;
  height: 100dvh;
}

.site-editor {
  display: flex;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  width: 100%;
}

.site-editor-sidebar {
  width: 350px;
  flex-shrink: 0;
  overflow-y: auto;
  padding: 1rem 1.1rem 2rem;
  background: var(--bg-dark-start);
  border-right: 1px solid rgba(241, 241, 241, 0.08);
}

.site-editor-sidebar__header {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

.site-editor-sidebar__actions {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.site-editor-sidebar__actions .auth-submit {
  width: 100%;
}

.site-editor-section {
  margin-bottom: 1.5rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid rgba(241, 241, 241, 0.08);
}

.site-editor-section__title {
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-bottom: 0.85rem;
}

.site-editor-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-bottom: 0.75rem;
}

.site-editor-field--row {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

.site-editor-field__label {
  font-size: 0.85rem;
  color: var(--text-muted);
}

/* Визуально отделяет "Загрузку новой модели" от "Параметров текущей
   модели" (#hero-model-section) — разные по смыслу действия (файл vs.
   трансформация) не должны выглядеть одной формой. */
.site-editor-subsection {
  border: 1px solid rgba(241, 241, 241, 0.1);
  border-radius: 8px;
  padding: 0.85rem;
  margin-bottom: 0.85rem;
  background: rgba(255, 255, 255, 0.02);
}

.site-editor-subsection__title {
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin: 0 0 0.75rem;
}

/* <details>/<summary> используются для аккордеонов анимации (левитация,
   вращение, качение, интерактив) — только <summary> должен показывать
   курсор-подсказку сворачивания, обычные <h3> с этим же классом (upload
   секция) остаются как есть. */
summary.site-editor-subsection__title {
  cursor: pointer;
}

.site-editor-subsection .auth-submit {
  width: 100%;
}

.site-editor-notice {
  color: var(--accent);
  border: 1px solid rgba(230, 57, 70, 0.35);
  border-radius: 6px;
  padding: 0.6rem 0.75rem;
  background: rgba(230, 57, 70, 0.08);
}

.site-editor-notice a {
  color: inherit;
  text-decoration: underline;
}

.site-editor-input,
.site-editor-select {
  width: 100%;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(241, 241, 241, 0.15);
  color: var(--text-light);
  border-radius: 6px;
  padding: 0.55rem 0.7rem;
  font: inherit;
}

.site-editor-textarea {
  resize: vertical;
  min-height: 5rem;
}

.site-editor-field input[type="color"] {
  width: 2.5rem;
  height: 2rem;
  padding: 0;
  border: 1px solid rgba(241, 241, 241, 0.2);
  background: transparent;
  cursor: pointer;
}

.site-editor-btn-block {
  display: flex;
  width: 100%;
  justify-content: center;
}

.site-editor-color-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex: 1;
  justify-content: flex-end;
}

.site-editor-hex-input {
  width: 6.5rem;
  text-align: center;
  font-family: monospace;
  text-transform: lowercase;
}

.site-editor-blocks {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  margin-bottom: 1rem;
}

.site-editor-blocks__empty {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.site-editor-block {
  border: 1px solid rgba(241, 241, 241, 0.12);
  border-radius: 8px;
  padding: 0.75rem;
  background: rgba(255, 255, 255, 0.03);
}

.site-editor-block__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.site-editor-block__title {
  font-size: 0.9rem;
  font-weight: 500;
  letter-spacing: 0.03em;
}

.site-editor-block__actions {
  display: flex;
  gap: 0.25rem;
}

.site-editor-block__btn {
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid rgba(241, 241, 241, 0.18);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-light);
  cursor: pointer;
  font-size: 0.85rem;
  line-height: 1;
}

.site-editor-block__btn:hover:not(:disabled) {
  border-color: rgba(241, 241, 241, 0.4);
}

.site-editor-block__btn:disabled {
  opacity: 0.35;
  cursor: default;
}

.site-editor-block__btn--danger:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

.site-editor-add-block .auth-submit {
  width: 100%;
  margin-top: 0.35rem;
}

.site-editor-items {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin-top: 0.5rem;
}

.site-editor-item {
  border: 1px solid rgba(241, 241, 241, 0.1);
  border-radius: 6px;
  padding: 0.65rem;
  background: rgba(0, 0, 0, 0.2);
}

.site-editor-item__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.site-editor-add-item {
  width: 100%;
  justify-content: center;
}

.site-editor-case-pick {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin-top: 0.35rem;
}

.site-editor-case-pick__list {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-height: 14rem;
  overflow-y: auto;
  padding: 0.35rem 0;
}

.site-editor-case-pick__row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.35rem 0.45rem;
  border-radius: 4px;
  cursor: pointer;
  font-size: 0.85rem;
}

.site-editor-case-pick__row:hover {
  background: rgba(255, 255, 255, 0.04);
}

.site-editor-case-pick__title {
  flex: 1;
  min-width: 0;
  color: var(--text-light);
}

.site-editor-case-pick__status {
  color: var(--text-muted);
  font-size: 0.75rem;
  flex-shrink: 0;
}

.site-editor-preview {
  flex: 1;
  min-width: 0;
  background: #2a2a32;
}

.site-editor-preview iframe {
  width: 100%;
  height: 100%;
  border: none;
  display: block;
  background: var(--bg-dark-start);
}

@media (max-width: 900px) {
  .site-editor {
    flex-direction: column;
  }

  .site-editor-sidebar {
    width: 100%;
    max-height: 45vh;
    border-right: none;
    border-bottom: 1px solid rgba(241, 241, 241, 0.08);
  }
}

/* Анимация появления текста */
.fade-in {
  opacity: 0;
  transform: translateY(20px);
  animation: fadeInUp 0.8s ease forwards;
  animation-delay: var(--delay, 0s);
}

@keyframes fadeInUp {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Адаптивность */
@media (max-width: 768px) {
  .hero {
    padding: 1.5rem;
  }

  .hero__description {
    line-height: 1.5;
  }
}

/* .top-bar и .account-widget — два независимых fixed-элемента без общего
   родителя (см. case-editor.html/admin.html/cases.html/...). На мобильных
   ширинах кнопки шапки при переносе (flex-wrap) могут растянуться под правый
   верхний угол, где висит виджет аккаунта и открывается его dropdown —
   поэтому явно резервируем справа зону под .account-widget через max-width,
   вместо того чтобы позволять кнопкам расти на всю ширину экрана. Виджет
   теперь — просто иконка+шеврон (без текста email), поэтому резерв заметно
   меньше, чем раньше. */
@media (max-width: 700px) {
  .top-bar {
    max-width: calc(100% - 7rem);
  }
}

@media (max-width: 480px) {
  .top-bar {
    padding: 1rem;
    gap: 0.5rem;
    max-width: calc(100% - 5.5rem);
  }

  .login-btn {
    padding: 0.5rem 1rem;
    font-size: 0.8rem;
  }

  .hero__content {
    max-width: 100%;
  }

  .hero__title {
    letter-spacing: 0.02em;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fade-in {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* Карточка авторизации (login.html) */
.auth-card {
  width: 100%;
  max-width: 380px;
  padding: 2rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  backdrop-filter: blur(6px);
}

.auth-tabs {
  display: flex;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.auth-tab {
  flex: 1;
  padding: 0.75rem;
  background: none;
  border: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 1rem;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.25s ease, border-color 0.25s ease;
}

.auth-tab.is-active {
  color: var(--text-light);
  border-bottom-color: var(--accent);
}

.auth-form {
  display: none;
  flex-direction: column;
  gap: 1rem;
}

.auth-form.is-active {
  display: flex;
}

.auth-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  text-align: left;
}

.auth-field label {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.auth-field input {
  padding: 0.65rem 0.8rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-light);
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  outline: none;
  transition: border-color 0.2s ease;
}

.auth-field input:focus {
  border-color: var(--accent);
}

.auth-field input[readonly] {
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.02);
  cursor: default;
}

.auth-field textarea {
  padding: 0.65rem 0.8rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-light);
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  outline: none;
  resize: vertical;
  transition: border-color 0.2s ease;
}

.auth-field textarea:focus {
  border-color: var(--accent);
}

/* .auth-field { display: flex; } задан без условия на класс — без этого фикса
   элемент с атрибутом hidden не спрячется, т.к. авторский display перекрывает
   правило браузера [hidden] { display: none } (та же история была с .auth-form). */
.auth-field[hidden] {
  display: none;
}

/* Карточка вопроса финального квиза (game.html #quiz-questions) — строка
   ввода растёт, кнопка «Ответить» по ширине контента; решённое состояние
   красится в зелёный, как .toast.is-success. */
.quiz-question__row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.quiz-question__row input {
  flex: 1;
  min-width: 0;
}

.quiz-question--solved label {
  color: var(--text-light);
}

.quiz-question__solved-answer {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.65rem 0.8rem;
  color: #7fdba0;
  background: rgba(127, 219, 160, 0.08);
  border: 1px solid #7fdba0;
  border-radius: 6px;
}

/* Неверный ответ (после общей проверки checkAllQuizAnswers) — красная
   подсветка инпута, тот же принцип, что у зелёного .quiz-question__solved-answer,
   но по цвету как .toast.is-error. */
.quiz-question--incorrect .quiz-question__row input {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.08);
  color: var(--accent);
}

.admin-checkbox-field {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.9rem;
  color: var(--text-light);
  cursor: pointer;
}

.admin-checkbox-field input[type="checkbox"] {
  width: 1.1rem;
  height: 1.1rem;
  accent-color: var(--accent);
  cursor: pointer;
}

.password-input {
  position: relative;
}

.password-input input {
  width: 100%;
  padding-right: 2.5rem;
}

.toggle-password {
  position: absolute;
  top: 50%;
  right: 0.6rem;
  transform: translateY(-50%);
  padding: 0.25rem;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.2s ease;
}

.toggle-password:hover {
  color: var(--accent);
}

.auth-submit {
  margin-top: 0.5rem;
  padding: 0.7rem;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--bg-dark-start);
  background: var(--accent);
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.auth-submit:hover {
  opacity: 0.9;
}

/* Второстепенное действие рядом с залитой основной кнопкой: обводка акцентом,
   заливка на наведении. Рамка задаётся вместо `border: none` базовой кнопки,
   поэтому высота обеих кнопок отличается на 2px — компенсируем паддингом. */
.auth-submit--outline {
  padding: calc(0.7rem - 1px);
  color: var(--text-light);
  background: transparent;
  border: 1px solid var(--accent);
  transition: color 0.2s ease, background-color 0.2s ease;
}

.auth-submit--outline:hover {
  color: var(--bg-dark-start);
  background: var(--accent);
  opacity: 1;
}

/* Досье персонажа/жертвы — бумажный светлый фон, на нём светлый текст
   outline-кнопки нечитаем. */
.game-modal--dossier .auth-submit--outline {
  color: #2b2620;
}

.game-modal--dossier .auth-submit--outline:hover {
  color: var(--text-light);
}

.auth-link {
  align-self: center;
  padding: 0;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--accent);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: none;
  transition: text-decoration-color 0.2s ease;
}

.auth-link:hover {
  text-decoration: underline;
}

/* Всплывающие уведомления */
.toast-container {
  position: fixed;
  top: 1.5rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  width: 100%;
  max-width: 90%;
  pointer-events: none;
}

.toast {
  pointer-events: auto;
  padding: 0.75rem 1.25rem;
  font-size: 0.9rem;
  color: var(--text-light);
  background: rgba(20, 18, 22, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  opacity: 0;
  transform: translateY(-12px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.toast.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.toast.is-error {
  border-color: var(--accent);
  color: var(--accent);
}

.toast.is-success {
  border-color: #7fdba0;
  color: #7fdba0;
}

.toast.is-warning {
  border-color: #e6b34d;
  color: #e6b34d;
}

/* Виджет аккаунта (кнопка пользователя + выпадающее меню) */
.account-widget {
  position: fixed;
  top: 1.5rem;
  right: 1.5rem;
  z-index: 20;
}

.account-widget__wrapper {
  position: relative;
}

.account-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.75rem;
  height: 2.75rem;
  font-size: 1rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.account-btn:hover,
.account-btn[aria-expanded="true"] {
  border-color: var(--accent);
}

.account-dropdown {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  min-width: 200px;
  max-width: calc(100vw - 2rem);
  padding: 0.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  background: rgba(20, 18, 22, 0.98);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}

.account-dropdown.is-open {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.account-dropdown__header {
  padding: 0.4rem 0.7rem 0.6rem;
  margin-bottom: 0.25rem;
  font-size: 0.85rem;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.account-dropdown__item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--text-light);
  text-decoration: none;
  text-align: left;
  background: none;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.account-dropdown__item:hover {
  color: var(--accent);
  background: rgba(255, 255, 255, 0.06);
}

.account-dropdown__item--logout {
  margin-top: 0.25rem;
  padding-top: 0.65rem;
  color: var(--accent);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

@media (max-width: 480px) {
  .account-widget {
    top: 1rem;
    right: 1rem;
  }

  .account-btn {
    width: 2.5rem;
    height: 2.5rem;
  }
}

/* Личный кабинет (dashboard.html) */
.dashboard-card {
  max-width: 480px;
  padding: 2rem;
  text-align: center;
}

.dashboard-email {
  color: var(--accent);
  font-weight: 500;
}

.logout-btn {
  margin-top: 1.5rem;
  padding: 0.6rem 1.2rem;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--text-light);
  background: transparent;
  border: 1px solid var(--text-muted);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.logout-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}

.dashboard-section {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.dashboard-section__title {
  margin-bottom: 0.5rem;
  font-family: var(--font-heading);
  font-size: 1.25rem;
  letter-spacing: 0.03em;
}

.settings-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1.25rem;
  text-align: left;
}

.settings-form + .settings-form {
  margin-top: 1.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

/* Компактная модалка личного кабинета (сейчас — смена никнейма). Визуально
   повторяет .game-modal, но без привязки к игровому контексту — используется
   на dashboard.html. */
.account-modal-backdrop {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.account-modal-backdrop[hidden] {
  display: none;
}

.account-modal {
  position: relative;
  width: 100%;
  max-width: 360px;
  /* Тот же фикс переполнения, что и у .game-modal — см. комментарий там. */
  max-height: calc(100vh - 3rem);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  text-align: left;
  background: rgba(20, 18, 22, 0.98);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}

.account-modal__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  padding: 0.4rem;
  font-size: 1.2rem;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}

.account-modal__close:hover {
  color: var(--accent);
}

.account-modal__title {
  font-family: var(--font-heading);
  font-size: 1.3rem;
  letter-spacing: 0.03em;
}

.account-modal__input {
  padding: 0.65rem 0.8rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-light);
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  outline: none;
  transition: border-color 0.2s ease;
}

.account-modal__input:focus {
  border-color: var(--accent);
}

.account-modal__text {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.account-modal__error {
  margin: 0;
  font-size: 0.85rem;
  color: #ff6b6b;
}

.account-modal__error[hidden] {
  display: none;
}

/* Pre-game модалка выбора сложности/режима (public/cases.js,
   openPregameModal) — расширяет базовый .account-modal, поэтому цвета/рамки
   наследуются от него и от CSS-переменных темы, отдельных
   [data-theme="hacker"]-переопределений не требуется. */
.pregame-modal {
  max-width: 560px;
}

.pregame-modal__header {
  display: flex;
  gap: 1rem;
}

.pregame-modal__cover {
  width: 120px;
  height: 120px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.04);
}

.pregame-modal__info {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.pregame-modal__description {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.pregame-modal__badges {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 0.4rem;
}

.pregame-modal__section-title {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-muted);
}

.pregame-modal__options {
  display: flex;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.pregame-option-btn {
  padding: 0.5rem 0.9rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.pregame-option-btn:hover:not(:disabled) {
  border-color: var(--accent);
}

.pregame-option-btn.is-active {
  color: var(--text-light);
  background: rgba(230, 57, 70, 0.12);
  border-color: var(--accent);
}

.pregame-option-btn:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

@media (max-width: 768px) {
  .pregame-modal__header {
    flex-direction: column;
  }
}

/* Страница лобби (public/lobby.html, public/lobby.js) — комната ожидания
   перед стартом кооперативного дела. Использует общие .auth-card/
   .dashboard-card/.dashboard-section/.account-modal__input/.auth-submit,
   поэтому наследует цвета/рамки текущей темы без отдельных переопределений
   для [data-theme="hacker"] — только сами lobby-* классы ниже нейтральны
   к теме через CSS-переменные. */
.lobby-header {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.lobby-header__cover {
  width: 96px;
  height: 96px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.04);
}

.lobby-header__info {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.lobby-invite {
  display: flex;
  gap: 0.6rem;
}

.lobby-invite__input {
  flex: 1;
  min-width: 0;
}

.lobby-invite__copy {
  flex-shrink: 0;
  width: auto;
  margin-top: 0;
  white-space: nowrap;
}

.lobby-players {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lobby-player {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.8rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
}

.lobby-player i {
  color: var(--text-muted);
}

.lobby-player__name {
  flex: 1;
}

.lobby-player__host-badge {
  padding: 0.15rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--bg-dark-start);
  background: var(--accent);
  border-radius: 4px;
}

.lobby-start-btn {
  margin-top: 1.5rem;
}

@media (max-width: 600px) {
  .lobby-header {
    flex-direction: column;
    text-align: center;
  }

  .lobby-invite {
    flex-direction: column;
  }

  .lobby-invite__copy {
    width: 100%;
  }
}

/* Кнопка обратной связи тестеров (public/nav.js, setupFeedbackWidget) —
   фиксирована в левом нижнем углу на всех страницах сайта. z-index ниже
   модалки (200), но выше игровых fixed-элементов (game-menu-toggle/
   game-bottom-bar — 30), чтобы не перекрывалась ими. */
.feedback-fab {
  position: fixed;
  left: 1.25rem;
  bottom: 1.25rem;
  z-index: 150;
  width: 3rem;
  height: 3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  color: #fff;
  background: var(--accent);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  transition: background-color 0.2s ease, transform 0.2s ease;
}

.feedback-fab:hover {
  background: #ff5a64;
}

.feedback-fab:active {
  background: #c62d39;
  transform: scale(0.95);
}

/* Сетка дел (cases.html) */
.case-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 1.25rem;
  margin-top: 1.5rem;
  text-align: left;
}

.case-tile {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  color: var(--text-light);
  text-decoration: none;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  transition: border-color 0.25s ease, background-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.case-tile:hover {
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.06);
  transform: scale(1.03);
  box-shadow: 0 12px 32px rgba(193, 18, 31, 0.35), 0 0 20px rgba(193, 18, 31, 0.2);
}

.case-tile__cover {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: rgba(0, 0, 0, 0.25);
}

.case-tile__cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  font-size: 2rem;
}

.case-tile__body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.9rem 1rem 1.1rem;
}

.case-tile__title {
  font-weight: 500;
}

.case-tile__status {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.case-tile__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.case-tile__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.5rem;
  font-size: 0.72rem;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 999px;
}

.case-tile__action {
  align-self: flex-start;
  margin-top: 0.4rem;
  padding: 0.45rem 0.9rem;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--bg-dark-start);
  background: var(--accent);
  border-radius: 6px;
}

.case-tile.is-disabled {
  cursor: default;
  opacity: 0.6;
}

.case-tile.is-disabled:hover {
  border-color: rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.03);
  transform: none;
  box-shadow: none;
}

/* Достижения (achievements.html) */
.achievements-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}

.achievement-card {
  padding: 1.25rem 1rem;
  text-align: center;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  opacity: 0.5;
  transition: opacity 0.25s ease, border-color 0.25s ease;
}

.achievement-card.is-granted {
  color: var(--text-light);
  border-color: var(--accent);
  opacity: 1;
}

.achievement-card i {
  font-size: 1.6rem;
  color: var(--accent);
}

.achievement-card__title {
  margin-top: 0.6rem;
  font-weight: 500;
  font-size: 0.9rem;
}

.achievement-card__description {
  margin-top: 0.35rem;
  font-size: 0.75rem;
}

/* Страница игры (game.html) */

/* Кнопка-гамбургер шапки + выезжающая слева панель — заменяет старую строку
   из 4 кнопок ("К списку дел"/"Адресная книга"/"Завершить дело"/"Начать
   заново"), которые раньше стояли прямо в .top-bar. Открытие/закрытие —
   setupSideMenu() в game.js; сами кнопки не изменились (те же ID), просто
   физически лежат внутри панели. */
.game-menu-toggle {
  position: fixed;
  top: 1.5rem;
  left: 1.5rem;
  z-index: 30;
  width: 2.75rem;
  height: 2.75rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.game-menu-toggle:hover,
.game-menu-toggle[aria-expanded="true"] {
  border-color: var(--accent);
}

/* Фиксированная панель кнопок «Адресная книга»/«Телефон» по центру низа
   экрана (раньше — плавающая иконка телефона справа снизу + пункт бокового
   меню). pointer-events: none на контейнере + auto на кнопках — чтобы
   пустые зоны панели по краям не перехватывали клики по контенту под ней. */
.game-bottom-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 1.5rem;
  z-index: 30;
  display: flex;
  justify-content: center;
  gap: 0.75rem;
  padding: 0 1rem;
  pointer-events: none;
}

.game-bottom-bar__btn {
  position: relative;
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  width: 11rem;
  height: 2.75rem;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--text-light);
  background: rgba(13, 13, 13, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 6px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: border-color 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

.game-bottom-bar__btn i {
  font-size: 0.85rem;
}

.game-bottom-bar__btn span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.game-bottom-bar__btn:hover {
  border-color: var(--accent);
}

.game-bottom-bar__btn:active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg-dark-start);
}

.game-bottom-bar__btn[hidden] {
  display: none;
}

.game-phone-toggle__badge {
  position: absolute;
  top: -0.35rem;
  right: -0.35rem;
  min-width: 1.2rem;
  height: 1.2rem;
  padding: 0 0.3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  background: #e5484d;
  border-radius: 999px;
  box-shadow: 0 0 0 2px var(--bg-dark);
}

.game-phone-toggle__badge[hidden] {
  display: none;
}

/* Экран телефона (React-остров phone-app.js) — плавающее окно над кнопкой
   #game-phone-toggle, сама кнопка сидит на bottom:1.5rem/2.75rem высотой,
   поэтому здесь оставлен зазор в bottom, чтобы окно не перекрывало её. */
.game-phone-root {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 5rem;
  z-index: 1000;
  width: 320px;
  height: 550px;
  max-height: calc(100vh - 7rem);
  max-height: calc(100dvh - 7rem);
}

.game-phone-root[hidden] {
  display: none;
}

.phone-container {
  width: 100%;
  height: 100%;
  padding: 0.6rem;
  background: linear-gradient(160deg, #2a2a2e, #111113);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 34px;
  box-shadow: 0 20px 48px rgba(0, 0, 0, 0.5);
}

/* "Режим улики" (evidenceMode в phone-app.js) — телефон подозреваемого,
   найденный как улика, а не собственный телефон детектива: красная рамка
   вместо обычной серой, чтобы визуально отличать чужое устройство. */
.phone-container--evidence {
  border-color: #e05252;
  box-shadow: 0 20px 48px rgba(224, 82, 82, 0.35), 0 0 0 2px rgba(224, 82, 82, 0.5);
}

.phone-screen {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: #f4f4f6;
  border-radius: 26px;
  color: #1b1b1f;
}

.phone-header {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.85rem 0.6rem;
  background: #ffffff;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
}

.phone-header__title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 600;
  font-size: 0.95rem;
  text-align: center;
}

.phone-header__spacer {
  width: 1.9rem;
  flex-shrink: 0;
}

.phone-back-btn,
.phone-close-btn {
  flex-shrink: 0;
  width: 1.9rem;
  height: 1.9rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: #1b1b1f;
  background: rgba(0, 0, 0, 0.06);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.phone-back-btn:hover,
.phone-close-btn:hover {
  background: rgba(0, 0, 0, 0.12);
}

.phone-screen__body {
  flex: 1;
  overflow-y: auto;
  padding: 1rem;
}

.phone-empty-state {
  margin: 2rem 0;
  text-align: center;
  color: #8a8a92;
  font-size: 0.9rem;
}

/* Главный экран */
.phone-home-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1rem;
}

.phone-app-icon {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.4rem;
  padding: 0.75rem 0.5rem;
  background: none;
  border: none;
  cursor: pointer;
  color: #1b1b1f;
}

.phone-app-icon__glyph {
  width: 3.25rem;
  height: 3.25rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  color: #fff;
  background: linear-gradient(160deg, var(--accent), #b32330);
  border-radius: 16px;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
}

.phone-app-icon:nth-child(2) .phone-app-icon__glyph {
  background: linear-gradient(160deg, #4b8bf4, #2f5fc4);
}

.phone-app-icon__label {
  font-size: 0.8rem;
}

.phone-app-icon__badge {
  position: absolute;
  top: 0.35rem;
  right: 0.9rem;
  min-width: 1.2rem;
  height: 1.2rem;
  padding: 0 0.3rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  background: #e5484d;
  border-radius: 999px;
  box-shadow: 0 0 0 2px #f4f4f6;
}

/* Экран сообщений */
.phone-sms-list {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.phone-sms-item {
  display: grid;
  grid-template-columns: 0.6rem 1fr;
  row-gap: 0.2rem;
  column-gap: 0.5rem;
  padding: 0.65rem 0.75rem;
  text-align: left;
  background: #ffffff;
  border: none;
  border-radius: 12px;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.phone-sms-item:hover {
  background: #ececee;
}

.phone-sms-item__sender {
  grid-column: 2;
  font-size: 0.88rem;
  color: #1b1b1f;
}

.phone-sms-item--unread .phone-sms-item__sender {
  font-weight: 700;
}

.phone-sms-item__dot {
  grid-column: 1;
  grid-row: 1 / 3;
  width: 0.4rem;
  height: 0.4rem;
  margin-top: 0.35rem;
  background: var(--accent);
  border-radius: 50%;
}

.phone-sms-item__preview {
  grid-column: 2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 100%;
  font-size: 0.8rem;
  color: #6b6b72;
}

.phone-sms-detail__sender {
  margin-bottom: 0.5rem;
  font-weight: 700;
  font-size: 0.95rem;
}

.phone-sms-detail__text {
  font-size: 0.9rem;
  line-height: 1.5;
  white-space: pre-wrap;
}

/* Экран галереи */
.phone-gallery-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.75rem;
}

.phone-gallery-item {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.phone-gallery-item__img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  background: #dcdce0;
  border-radius: 12px;
}

.phone-gallery-item__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 0.8rem;
  text-align: center;
  color: #4a4a50;
}

@media (max-width: 480px) {
  .game-phone-root {
    right: 0.75rem;
    bottom: 4rem;
    left: 0.75rem;
    width: auto;
    transform: none;
    height: min(550px, calc(100vh - 6rem));
    height: min(550px, calc(100dvh - 6rem));
  }
}

.game-side-menu__backdrop {
  position: fixed;
  inset: 0;
  z-index: 35;
  background: rgba(0, 0, 0, 0.6);
}

.game-side-menu__backdrop[hidden] {
  display: none;
}

.game-side-menu {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 40;
  width: 280px;
  max-width: 85vw;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 4.5rem 1.25rem 1.5rem;
  background: rgba(20, 18, 22, 0.98);
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 12px 0 32px rgba(0, 0, 0, 0.4);
  transform: translateX(-100%);
  transition: transform 0.25s ease;
}

.game-side-menu.is-open {
  transform: translateX(0);
}

.game-side-menu .login-btn {
  width: 100%;
  justify-content: flex-start;
}

.game-side-menu__close {
  position: absolute;
  top: 1rem;
  right: 1rem;
  padding: 0.4rem;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}

.game-side-menu__close:hover {
  color: var(--accent);
}

/* Аккордеон "Сложность" внутри бокового меню — кнопка-заголовок с шевроном
   (поворачивается на 180deg при раскрытии) + скрытый по умолчанию список
   вариантов, слегка сдвинутый вправо для визуальной иерархии. */
.game-side-menu__accordion-btn {
  justify-content: space-between;
}

.game-side-menu__accordion-chevron {
  margin-left: auto;
  font-size: 0.8rem;
  transition: transform 0.2s ease;
}

.game-side-menu__accordion-btn.is-expanded .game-side-menu__accordion-chevron {
  transform: rotate(180deg);
}

.game-side-menu__accordion-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding-left: 1.5rem;
}

.game-side-menu__accordion-body[hidden] {
  display: none;
}

.game-side-menu__option-btn {
  padding: 0.5rem 0.9rem;
  font-family: inherit;
  font-size: 0.85rem;
  text-align: left;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease, background-color 0.2s ease;
}

.game-side-menu__option-btn:hover {
  border-color: var(--accent);
}

.game-side-menu__option-btn.is-active {
  color: var(--text-light);
  background: rgba(230, 57, 70, 0.12);
  border-color: var(--accent);
}

/* Выезжающая слева панель "Подсказки" — независимая от .game-side-menu,
   та же геометрия открытия/закрытия (backdrop + translateX). */
.game-hints-menu__backdrop {
  position: fixed;
  inset: 0;
  z-index: 35;
  background: rgba(0, 0, 0, 0.6);
}

.game-hints-menu__backdrop[hidden] {
  display: none;
}

.game-hints-menu {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  z-index: 40;
  width: 280px;
  max-width: 85vw;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 4.5rem 1.25rem 1.5rem;
  background: rgba(20, 18, 22, 0.98);
  border-right: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 12px 0 32px rgba(0, 0, 0, 0.4);
  transform: translateX(-100%);
  transition: transform 0.25s ease;
}

.game-hints-menu.is-open {
  transform: translateX(0);
}

.game-hints-menu__title {
  font-family: var(--font-heading);
  font-size: 1.4rem;
  letter-spacing: 0.03em;
  color: var(--text-light);
}

.game-hints-menu__list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  overflow-y: auto;
}

.game-hints-menu__placeholder {
  font-size: 0.9rem;
  color: var(--text-muted);
}

@media (max-width: 480px) {
  .game-menu-toggle {
    top: 1rem;
    left: 1rem;
    width: 2.5rem;
    height: 2.5rem;
  }

  .game-bottom-bar {
    bottom: 1rem;
    gap: 0.5rem;
    padding: 0 0.75rem;
  }

  .game-bottom-bar__btn {
    flex: 1 1 0;
    width: auto;
    max-width: 11rem;
    height: 2.5rem;
    padding: 0 0.6rem;
    gap: 0.35rem;
    font-size: 0.75rem;
  }

  .game-bottom-bar__btn span {
    min-width: 0;
  }
}

.game {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: 5.5rem 1.5rem 6.5rem;
  gap: 1.5rem;
}

/* Карта игры — React-остров (game-map-viewer.js) с zoom/pan через
   react-zoom-pan-pinch, тот же подход, что и в редакторе (.map-viewer*).
   #game-scene — фиксированная по высоте "рамка" (нужна для TransformWrapper:
   без определённой высоты контейнера подгонка картинки под размер работать
   не может); высота min(55vh, 520px), чтобы под картой сразу было видно
   инвентарь/известных/дневник; .game-scene__viewport — корень React-дерева,
   замеряется ResizeObserver'ом внутри game-map-viewer.js; .game-scene__inner
   — контент натурального пиксельного размера внутри TransformComponent,
   аналог .map-viewer__scene. */
.game-scene {
  position: relative;
  width: 100%;
  max-width: 960px;
  height: min(55vh, 520px);
  border-radius: 12px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.02);
}

.game-scene__viewport {
  width: 100%;
  height: 100%;
}

.game-scene__inner {
  position: relative;
}

.game-scene__image {
  display: block;
  user-select: none;
}

.game-scene__controls {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 2;
  display: flex;
  gap: 0.4rem;
}

.game-scene__control-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  color: var(--text-light);
  background: rgba(13, 13, 13, 0.75);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.game-scene__control-btn:hover {
  border-color: var(--accent);
}

.game-hotspot {
  position: absolute;
  width: 2.25rem;
  height: 2.25rem;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: rgba(230, 57, 70, 0.55);
  border: 3px solid var(--accent);
  cursor: pointer;
  animation: hotspotPulse 1.8s ease-in-out infinite;
}

@keyframes hotspotPulse {
  0%, 100% {
    box-shadow: 0 0 0 0 rgba(230, 57, 70, 0.65);
  }
  50% {
    box-shadow: 0 0 0 8px rgba(230, 57, 70, 0);
  }
}

/* Круглая зона видимости на карте (content.mapZones) — рендерится и в
   редакторе (map-viewer.js), и в игре (game-map-viewer.js) до хотспотов, чтобы
   у обоих не задан z-index (auto) и порядок в DOM гарантировал отрисовку
   хотспотов поверх зон. */
.map-zone {
  position: absolute;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-color: rgba(46, 204, 113, 0.35);
  border: 2px dashed rgba(46, 204, 113, 0.8);
  aspect-ratio: 1;
  pointer-events: none;
}

.map-zone--selected {
  border-style: solid;
  border-color: #fff;
  box-shadow: 0 0 15px rgba(46, 204, 113, 1);
}

.game-inventory {
  width: 100%;
  max-width: 960px;
  padding: 1.25rem;
  text-align: center;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.game-inventory__title {
  margin-bottom: 0.75rem;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  letter-spacing: 0.03em;
}

.game-inventory__empty {
  color: var(--text-muted);
  font-size: 0.9rem;
}

.game-inventory__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}

.game-inventory__item {
  padding: 0.5rem 0.9rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.game-inventory__item:hover {
  border-color: var(--accent);
}

/* У улики есть непрочитанное доп. описание (см. hasUnseenAdditions в
   game.js) — снимается при открытии карточки улики.
   position: relative нужен только для абсолютного позиционирования точки
   .game-inventory__item-dot внутри кнопки. */
.game-inventory__item--updated {
  position: relative;
}

/* Тот же зелёный, что и у подсветки additionalDescriptions в записной
   книжке (.game-notebook__entry-addition) — зелёный = новая/доп.
   информация, по аналогии с .game-known-characters__new-dot. */
.game-inventory__item-dot {
  position: absolute;
  top: -0.25rem;
  right: -0.25rem;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background: #7fdba0;
  box-shadow: 0 0 0 2px var(--bg-dark-start);
}

.game-modal__backdrop {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.game-modal__backdrop[hidden] {
  display: none;
}

.game-modal {
  position: relative;
  width: 100%;
  max-width: 420px;
  /* 1.5rem паддинга backdrop сверху и снизу — без этого длинные модалки
     (много полей формы/вопросов квиза) обрезаются экраном на мобильных без
     возможности скролла (см. HANDOFF "Фикс переполнения модалок"). */
  max-height: calc(100vh - 3rem);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  text-align: center;
  background: rgba(20, 18, 22, 0.98);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.4);
}

.game-modal__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  padding: 0.4rem;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}

.game-modal__close:hover {
  color: var(--accent);
}

.game-modal__image {
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: 8px;
}

.game-modal__title {
  font-family: var(--font-heading);
  font-size: 1.3rem;
  letter-spacing: 0.03em;
}

/* Плеер комикс-вступления (#comic-modal-backdrop, см. game.js) — осознанно
   не .game-modal__backdrop: занимает весь экран, не центрирует небольшую
   карточку, а главное — клик по фону здесь листает кадры, а не закрывает
   модалку (закрытия по фону/Esc у неё нет вообще, см. setupComicPlayer). */
.comic-player-backdrop {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  padding: 2rem 1.5rem;
  background: #050505;
  cursor: pointer;
}

.comic-player-backdrop[hidden] {
  display: none;
}

.comic-player__frames {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
  width: 100%;
  max-width: 720px;
  max-height: 85vh;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0.5rem;
}

/* Плавное появление кадра (opacity/translate 0 -> 1) — класс is-visible
   навешивается через requestAnimationFrame сразу после вставки в DOM,
   см. revealNextComicFrame() в game.js. */
.comic-player__frame {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.comic-player__frame.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.comic-player__frame img {
  display: block;
  width: 100%;
  max-height: 70vh;
  object-fit: contain;
  border-radius: 10px;
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.55);
}

.comic-player__subtitle {
  max-width: 90%;
  padding: 0.6rem 1.2rem;
  font-family: var(--font-heading);
  font-size: 1.05rem;
  text-align: center;
  color: var(--text-light);
  background: rgba(0, 0, 0, 0.55);
  border-radius: 8px;
}

.comic-player__start-btn {
  position: relative;
  flex-shrink: 0;
  cursor: pointer;
}

/* Модалка предмета/здания в стиле фото-полароида (#game-modal). */
.polaroid-frame {
  width: 100%;
  padding: 0.5rem 0.5rem 1.25rem;
  margin-bottom: 0.5rem;
  background: #fdfdfa;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.4);
  transform: rotate(-1.5deg);
}

.polaroid-frame .game-modal__image {
  width: 100%;
  max-height: 220px;
  object-fit: cover;
  border-radius: 0;
}

/* Модалка персонажа/жертвы в стиле личного дела: бумага, тёмный текст,
   фото в углу со скрепкой. Обёртка .dossier-photo плавает справа, поэтому
   элементы после фото (список фактов, кнопки) сбрасывают float через
   clear: both — иначе при коротком описании они наезжают на фото. */
.game-modal--dossier {
  text-align: left;
  color: #2b2620;
  background:
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.02) 0 1px, transparent 1px 26px),
    linear-gradient(135deg, #f2e9d4, #e6d8b8);
  border: 1px solid rgba(60, 45, 20, 0.25);
}

.game-modal--dossier .game-modal__close {
  color: rgba(43, 38, 32, 0.6);
}

.game-modal--dossier .game-modal__close:hover {
  color: var(--accent);
}

.game-modal--dossier .game-modal__title {
  color: #221d17;
}

.game-modal--dossier .game-modal__description,
.game-modal--dossier .character-fact__text {
  color: #4a423a;
}

.game-modal--dossier .character-fact {
  background: rgba(0, 0, 0, 0.04);
  border-color: rgba(60, 45, 20, 0.2);
}

.dossier-photo {
  position: relative;
  float: right;
  width: 6.5rem;
  margin: 0 0 0.75rem 1rem;
  background: #fff;
  padding: 0.3rem 0.3rem 0.5rem;
  box-shadow: 0 6px 14px rgba(0, 0, 0, 0.35);
  transform: rotate(3deg);
}

.dossier-photo .game-modal__image {
  width: 100%;
  height: 8rem;
  max-height: none;
  object-fit: cover;
  border-radius: 0;
}

.dossier-photo__clip {
  position: absolute;
  top: -0.6rem;
  left: 50%;
  transform: translateX(-50%) rotate(-8deg);
  font-size: 1.4rem;
  color: #8a8f98;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
}

.game-modal--dossier .character-fact-list,
.game-modal--dossier .game-modal__audio,
.game-modal--dossier > .auth-submit,
.game-modal--dossier > .auth-link,
.game-modal--dossier > div[id$="-bank-btn-container"] {
  clear: both;
}

/* Текст брифинга дела (#intro-modal-text) — сохраняем переносы строк из
   textarea редактора и позволяем скроллить длинный текст без раздувания
   модалки на весь экран. */
.game-modal__intro-text {
  max-height: 50vh;
  overflow-y: auto;
  text-align: left;
  white-space: pre-wrap;
  color: var(--text-muted);
  line-height: 1.5;
}

/* Переключатель «Художественные описания» (модалка перед обыском,
   #game-search-flavor-modal) — нативный checkbox спрятан, вместо него пилюля
   с ползунком, включено — заливка var(--accent) и сдвиг ползунка вправо. */
.game-flavor-toggle {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0.5rem 0;
  cursor: pointer;
  user-select: none;
}

.game-flavor-toggle input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.game-flavor-toggle__track {
  position: relative;
  flex-shrink: 0;
  width: 2.6rem;
  height: 1.5rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.2);
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.game-flavor-toggle__thumb {
  position: absolute;
  top: 0.15rem;
  left: 0.15rem;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 50%;
  background: var(--text-light);
  transition: transform 0.2s ease;
}

.game-flavor-toggle input[type="checkbox"]:checked ~ .game-flavor-toggle__track {
  background: var(--accent);
  border-color: var(--accent);
}

.game-flavor-toggle input[type="checkbox"]:checked ~ .game-flavor-toggle__track .game-flavor-toggle__thumb {
  transform: translateX(1.1rem);
}

.game-flavor-toggle__label {
  font-size: 0.9rem;
  color: var(--text-muted);
}

/* Модалка «Проверить логику» (валидатор дела) — список может быть длинным,
   поэтому шире и без центрирования текста в отличие от базовой .game-modal. */
.validator-modal {
  max-width: 640px;
  text-align: left;
}

.validator-results {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-height: 60vh;
  overflow-y: auto;
}

.validator-results__group-title {
  margin-bottom: 0.5rem;
  font-family: var(--font-heading);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

.validator-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.validator-list__item {
  padding: 0.6rem 0.8rem;
  font-size: 0.92rem;
  border-radius: 8px;
  border: 1px solid currentColor;
  background: rgba(255, 255, 255, 0.03);
}

.validator-list__item--error {
  color: var(--accent);
}

.validator-list__item--warning {
  color: #e6b800;
}

/* Чип триггера внутри сообщения валидатора: техническое имя, подсказка с
   описанием по title, клик уводит на сам триггер. Цвет наследуется от
   сообщения, поэтому чип выглядит частью ошибки/предупреждения. */
.validator-trigger-chip {
  display: inline-block;
  padding: 0.05rem 0.4rem;
  color: inherit;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.85rem;
  vertical-align: baseline;
  border: 1px solid currentColor;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.06);
  cursor: pointer;
  transition: background 0.2s ease;
}

.validator-trigger-chip:hover {
  background: rgba(255, 255, 255, 0.16);
}

.validator-trigger-chip--missing {
  cursor: help;
  opacity: 0.75;
  text-decoration: line-through;
}

.validator-trigger-chip--missing:hover {
  background: rgba(255, 255, 255, 0.06);
}

.validator-success {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.9rem 1rem;
  color: #7fdba0;
  border: 1px solid #7fdba0;
  border-radius: 8px;
  background: rgba(127, 219, 160, 0.08);
}

.game-modal__description {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* Тот же повторяющийся паттерн, что у .auth-field[hidden]/.game-modal__backdrop[hidden]
   и т.д. — без этого переопределения [hidden] проигрывает каскад безусловному
   display: flex выше (нужно для #police-modal-welcome, скрываемого на
   под-экранах участка, см. showPoliceDepartment() в game.js). */
.game-modal__description[hidden] {
  display: none;
}

.game-modal__description-main {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.game-modal__description-addition {
  padding: 0.5rem 0.75rem;
  border-left: 2px solid #7fdba0;
  border-radius: 0 6px 6px 0;
  background: rgba(127, 219, 160, 0.08);
  font-size: 0.88rem;
  color: var(--text-light);
}

/* Ввод ПИН-кода/пароля улики-устройства (openItemModal в game.js) — строка
   инпут+кнопка внутри модалки улики, вместо отдельного .auth-field. */
.game-modal__device-unlock {
  display: flex;
  width: 100%;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.game-modal__device-unlock[hidden] {
  display: none;
}

.game-modal__device-unlock input {
  flex: 1;
  min-width: 0;
  padding: 0.65rem 0.8rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-light);
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  outline: none;
  transition: border-color 0.2s ease;
}

.game-modal__device-unlock input:focus {
  border-color: var(--accent);
}

.game-modal__device-unlock .auth-submit {
  flex: 0 0 auto;
  width: auto;
  margin-top: 0;
}

/* Модалка оценки дела ("шляпы детектива", #review-modal-backdrop) */
.hats-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem;
  margin: 1rem 0;
}

.detective-hat {
  font-size: 1.8rem;
  color: #3a3a42;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.15s ease;
}

.detective-hat:hover,
.detective-hat.active {
  color: var(--accent);
  transform: scale(1.1);
}

/* Текст отзыва в модалке завершения дела — необязательный, поэтому кнопка
   «Отправить» на него не смотрит, а счётчик просто показывает остаток до
   maxlength (см. setupReviewModal в game.js). */
.review-modal__comment-field {
  margin-bottom: 1rem;
}

.review-modal__counter {
  margin: 0;
  font-size: 0.75rem;
  color: var(--text-muted);
  text-align: right;
}

.game-modal__audio {
  width: 100%;
}

/* Записная книжка (game.html) */
.game-notebook {
  width: 100%;
  max-width: 960px;
  padding: 1.25rem;
  text-align: center;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.game-notebook__title {
  margin-bottom: 0.75rem;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  letter-spacing: 0.03em;
}

.game-notebook__empty {
  color: var(--text-muted);
  font-size: 0.9rem;
}

.game-notebook__entry {
  padding: 0.75rem 0;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.game-notebook__entry:first-child {
  border-top: none;
}

.game-notebook__entry-title {
  margin-bottom: 0.25rem;
  font-weight: 500;
}

.game-notebook__entry-text {
  font-size: 0.9rem;
  color: var(--text-muted);
}

.game-notebook__entry-addition {
  margin-top: 0.4rem;
  padding: 0.4rem 0.6rem;
  border-left: 2px solid #7fdba0;
  border-radius: 0 6px 6px 0;
  background: rgba(127, 219, 160, 0.08);
  font-size: 0.85rem;
  color: var(--text-light);
}

/* У улики есть непрочитанное доп. описание (см. hasUnseenAdditions в
   game.js) — снимается при открытии карточки улики. */
.game-notebook__entry--updated .game-notebook__entry-title {
  color: var(--accent);
}

.game-notebook__entry-badge {
  display: inline-block;
  margin-left: 0.5rem;
  padding: 0.1rem 0.5rem;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #fff;
  background: var(--accent);
  border-radius: 4px;
  vertical-align: middle;
}

.game-known-characters {
  width: 100%;
  max-width: 960px;
  padding: 1.25rem;
  text-align: center;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.game-known-characters__title {
  margin-bottom: 0.75rem;
  font-family: var(--font-heading);
  font-size: 1.15rem;
  letter-spacing: 0.03em;
}

.game-known-characters__empty {
  color: var(--text-muted);
  font-size: 0.9rem;
}

.game-known-characters__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6rem;
}

.game-known-characters__item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.4rem 0.8rem 0.4rem 0.4rem;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--text-light);
  text-align: left;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.game-known-characters__item:hover {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
}

.game-known-characters__item-photo {
  flex-shrink: 0;
  width: 2rem;
  height: 2rem;
  object-fit: cover;
  border-radius: 50%;
}

.game-known-characters__item-photo--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
}

/* Индикаторы "новый ответ" (облегчённая сложность) — не меняют размеры
   фото/плейсхолдера, только оборачивают их для абсолютного позиционирования
   точек. Жёлтая (диалог) и красная (допрос) точки могут показываться
   одновременно — разнесены по разным углам, чтобы не перекрываться. */
.game-known-characters__item-photo-wrap {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
}

.game-known-characters__new-dot {
  position: absolute;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--bg-dark-start);
}

.game-known-characters__new-dot--dialogue {
  top: -0.1rem;
  right: -0.1rem;
  background: #f4c430;
}

/* Тот же зелёный, что и у .game-inventory__item-dot — "впервые доступен
   диалог" при самой первой встрече, заменяет жёлтую точку выше (см.
   isFirstMeeting в renderKnownEntityPhoto, game.js), поэтому позиция та же. */
.game-known-characters__new-dot--first-meeting {
  top: -0.1rem;
  right: -0.1rem;
  background: #7fdba0;
}

.game-known-characters__new-dot--interrogation {
  bottom: -0.1rem;
  right: -0.1rem;
  background: var(--accent);
}

.game-complete {
  max-width: 640px;
  margin: 0 auto;
  padding: 6rem 1.5rem 2rem;
  text-align: center;
}

.game-complete__answers {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 2rem;
  text-align: left;
}

.game-complete__return-btn {
  display: inline-block;
  margin-top: 2rem;
  text-decoration: none;
}

/* Админка (admin.html) */
.admin-page {
  max-width: 1100px;
  margin: 0 auto;
  padding: 6rem 1.5rem 2rem;
}

.admin-tabs {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}

.admin-tabs::-webkit-scrollbar {
  display: none;
}

.admin-tab {
  padding: 0.75rem 1.25rem;
  background: none;
  border: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 1rem;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  transition: color 0.25s ease, border-color 0.25s ease;
  flex-shrink: 0;
  white-space: nowrap;
}

.admin-tab.is-active {
  color: var(--text-light);
  border-bottom-color: var(--accent);
}

.admin-tab-panel {
  display: none;
  text-align: left;
}

.admin-tab-panel.is-active {
  display: block;
}

/* Бейджик числа новых записей на вкладке админки (сейчас — «Обратная связь»,
   см. admin.js loadDashboard) — по образцу .game-phone-toggle__badge, но
   инлайново рядом с текстом вкладки, а не абсолютно поверх иконки. */
.admin-tab__badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.2rem;
  height: 1.2rem;
  margin-left: 0.4rem;
  padding: 0 0.3rem;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1;
  color: #fff;
  background: #e5484d;
  border-radius: 999px;
}

.admin-tab__badge[hidden] {
  display: none;
}

/* Пилюли-подвкладки внутри вкладок «Сущности» и «Общение» */
.admin-subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.25rem;
}

.admin-subtab {
  padding: 0.45rem 1rem;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 999px;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 0.9rem;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease, background-color 0.2s ease;
}

.admin-subtab:hover {
  color: var(--text-light);
}

.admin-subtab.is-active {
  color: var(--text-light);
  background: var(--accent);
  border-color: var(--accent);
}

.admin-subtab-panel {
  display: none;
}

.admin-subtab-panel.is-active {
  display: block;
}

.admin-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.admin-stat-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1.25rem;
  text-align: left;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-stat-card__value {
  font-family: var(--font-heading);
  font-size: 2rem;
  color: var(--text-light);
}

.admin-stat-card__label {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.admin-users-table {
  width: 100%;
  margin-top: 1rem;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.admin-users-table th,
.admin-users-table td {
  padding: 0.6rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.admin-users-table th {
  color: var(--text-muted);
  font-weight: 500;
}

.admin-status-dot {
  display: inline-block;
  width: 0.55rem;
  height: 0.55rem;
  margin-right: 0.4rem;
  border-radius: 50%;
  background: var(--text-muted);
}

.admin-status-dot.is-online {
  background: #4caf50;
}

.admin-status-dot.is-offline {
  background: var(--text-muted);
}

.admin-period-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 1rem;
}

.admin-period-card {
  padding: 1rem 1.1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-period-card__title {
  margin-bottom: 0.6rem;
  font-size: 0.95rem;
  color: var(--text-light);
}

.admin-period-card__row {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.25rem 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.admin-period-card__row strong {
  color: var(--text-light);
}

.admin-activity-feed {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 1rem;
}

.admin-activity-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.9rem;
  font-size: 0.85rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
}

.admin-activity-item i {
  color: var(--accent);
}

.admin-activity-item--clickable {
  cursor: pointer;
  transition: background 0.2s ease;
}

.admin-activity-item--clickable:hover {
  background: rgba(255, 255, 255, 0.06);
}

.admin-activity-item__time {
  margin-left: auto;
  color: var(--text-muted);
  white-space: nowrap;
}

.admin-user-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1rem;
}

.admin-user-card {
  padding: 1rem 1.1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-user-card.is-banned {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.08);
}

.admin-user-card.is-highlighted {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.14);
}

.admin-user-card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}

.admin-user-card__header-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
}

/* На узких экранах роль-селект + кнопка бана не помещаются рядом с именем
   пользователя (justify-content: space-between их выталкивает за карточку) —
   переносим блок действий на новую строку на всю ширину. */
@media (max-width: 560px) {
  .admin-user-card__header-actions {
    flex-basis: 100%;
    width: 100%;
  }

  .admin-user-card__header-actions .admin-badge-select {
    flex: 1 1 auto;
    min-width: 0;
  }
}

.admin-user-card__email {
  margin-top: 0.2rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.admin-user-card__meta {
  margin-top: 0.2rem;
  font-size: 0.8rem;
  color: var(--text-muted);
}

.admin-user-card__ban-btn {
  flex-shrink: 0;
  padding: 0.4rem 0.8rem;
  font-size: 0.8rem;
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 6px;
  color: var(--text-light);
  cursor: pointer;
}

/* Всегда акцентно-красная (в отличие от обратимого бана) — самое
   разрушительное действие в админке должно быть визуально выделено сильнее. */
.admin-user-card__delete-btn {
  flex-shrink: 0;
  padding: 0.4rem 0.8rem;
  font-size: 0.8rem;
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 6px;
  color: var(--accent);
  cursor: pointer;
}

.admin-user-card__delete-btn:hover {
  background: rgba(230, 57, 70, 0.14);
}

.admin-user-card__progress {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-top: 0.85rem;
}

.admin-user-progress-item {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.admin-user-progress-item--empty {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.admin-user-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.admin-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.6rem;
  font-size: 0.75rem;
  background: rgba(230, 57, 70, 0.12);
  border: 1px solid var(--accent);
  border-radius: 20px;
}

.admin-badge__revoke {
  display: inline-flex;
  align-items: center;
  padding: 0;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
}

.admin-user-card__grant {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.admin-badge-select {
  flex: 1;
  padding: 0.5rem 0.6rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
}

/* Раскрытый список <option> рендерится браузером отдельным непрозрачным
   слоем и игнорирует полупрозрачный background селекта — без явного
   непрозрачного фона текст (светлый) оказывается невидимым на белом. */
.admin-badge-select option {
  color: var(--text-light);
  background-color: var(--bg-dark-end);
}

.admin-user-card__grant-btn {
  padding: 0.5rem 1rem;
  font-size: 0.85rem;
}

.admin-achievement-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.admin-achievement-item {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-achievement-item__icon {
  flex-shrink: 0;
  width: 1.6rem;
  padding-top: 0.15rem;
  font-size: 1.3rem;
  color: var(--accent);
  text-align: center;
}

.admin-achievement-item__info {
  flex: 1;
  min-width: 0;
}

.admin-achievement-item__info p {
  margin-top: 0.25rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.admin-achievement-item__holders {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.5rem;
  font-size: 0.75rem;
  color: var(--text-muted);
}

.admin-achievement-item__actions {
  display: flex;
  flex-shrink: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.admin-achievement-item__move {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  color: var(--text-light);
  cursor: pointer;
}

.admin-achievement-item__move:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.admin-achievement-item__hidden-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  color: var(--text-muted);
  white-space: nowrap;
}

.admin-achievement-item__edit {
  padding: 0.5rem 0.9rem;
  font-size: 0.8rem;
}

/* .admin-achievement-item__actions с flex-shrink: 0 не сжимается, поэтому
   на узкой карточке (иконка + текст + блок действий в одну строку) блок
   действий выталкивается за пределы контейнера — на мобильных переходим на
   вертикальную раскладку и отдаём действиям всю ширину. */
@media (max-width: 600px) {
  .admin-achievement-item {
    flex-wrap: wrap;
  }

  .admin-achievement-item__actions {
    flex-basis: 100%;
    width: 100%;
    padding-left: 2.6rem;
    box-sizing: border-box;
  }
}

.admin-shop-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.admin-shop-item {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-shop-item__cover {
  flex-shrink: 0;
  width: 3.2rem;
  height: 3.2rem;
  object-fit: cover;
  border-radius: 8px;
}

.admin-shop-item__cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed rgba(255, 255, 255, 0.2);
  color: var(--text-muted);
  font-size: 1.1rem;
}

.admin-shop-item__info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.admin-shop-item__badge {
  display: inline-flex;
  align-self: flex-start;
  padding: 0.15rem 0.55rem;
  font-size: 0.7rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: var(--text-muted);
}

.admin-shop-item__badge--draft {
  color: var(--text-muted);
  border-color: rgba(255, 255, 255, 0.2);
}

.admin-shop-item__badge--testing {
  color: #8a7ffb;
  border-color: rgba(138, 127, 251, 0.4);
}

.admin-shop-item__badge--coming_soon {
  color: #e0b34d;
  border-color: rgba(224, 179, 77, 0.4);
}

.admin-shop-item__badge--available {
  color: #4caf6f;
  border-color: rgba(76, 175, 111, 0.4);
}

.admin-shop-item__price {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.admin-shop-item__price-old {
  margin-right: 0.35rem;
  text-decoration: line-through;
}

.admin-shop-item__actions {
  display: flex;
  flex-shrink: 0;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.admin-shop-item__move {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  color: var(--text-light);
  cursor: pointer;
}

.admin-shop-item__move:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.admin-shop-item__edit {
  padding: 0.5rem 0.9rem;
  font-size: 0.8rem;
}

/* Обложка + инфо + 3 кнопки действий в одну строку не помещаются на узком
   экране — переносим блок действий на отдельную строку на всю ширину
   карточки (сама карточка при этом переходит на flex-wrap). */
@media (max-width: 600px) {
  .admin-shop-item {
    flex-wrap: wrap;
  }

  .admin-shop-item__actions {
    flex-basis: 100%;
    width: 100%;
    padding-left: calc(3.2rem + 1rem);
    box-sizing: border-box;
  }

  .admin-shop-item__edit {
    flex: 1;
  }
}

.admin-shop-cover-preview {
  margin-bottom: 0.5rem;
}

.admin-shop-cover-preview img {
  max-width: 100%;
  max-height: 140px;
  border-radius: 8px;
  object-fit: cover;
}

/* Вкладка «Обратная связь» — фильтры и список карточек, по образцу
   .admin-user-list/.admin-user-card выше в файле. */
.admin-feedback-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 1rem 0;
}

.admin-feedback-filters .admin-badge-select {
  flex: 0 1 200px;
}

.admin-feedback-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.admin-feedback-card {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1rem 1.1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-feedback-card--new {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.06);
}

.admin-feedback-card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.admin-feedback-card__meta {
  font-size: 0.8rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

.admin-feedback-card__message {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.admin-feedback-card__details {
  font-size: 0.8rem;
  color: var(--text-muted);
}

.admin-feedback-card__details summary {
  cursor: pointer;
  color: var(--text-light);
}

.admin-feedback-card__details pre {
  margin: 0.5rem 0 0;
  padding: 0.6rem 0.75rem;
  overflow-x: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  background: rgba(0, 0, 0, 0.3);
  border-radius: 6px;
}

.admin-feedback-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.admin-feedback-card__status-btn {
  padding: 0.5rem 0.9rem;
  font-size: 0.8rem;
}

/* Вкладка «Отзывы (Оценки)» — те же .admin-feedback-list/-filters, что и у
   «Обратной связи», карточка своя (оценка + две раздельные кнопки статуса,
   а не один тоггл). */
.admin-review-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 1rem 1.1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-review-card--accepted {
  border-color: rgba(56, 176, 0, 0.4);
}

.admin-review-card--rejected {
  opacity: 0.7;
}

.admin-review-card__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
}

.admin-review-card__score {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-weight: 600;
  color: var(--accent);
}

/* Текст отзыва игрока (case_reviews.comment) — необязателен, поэтому блок
   рендерится только когда он есть. */
.admin-review-card__text {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.admin-review-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.admin-review-card__accept-btn,
.admin-review-card__reject-btn {
  padding: 0.5rem 0.9rem;
  font-size: 0.8rem;
}

.admin-case-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.admin-case-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  width: 100%;
  padding: 0.9rem 1.1rem;
  text-align: left;
  font-family: inherit;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.admin-case-card:hover {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.08);
}

.admin-case-card__cover {
  flex-shrink: 0;
  width: 3.2rem;
  height: 3.2rem;
  object-fit: cover;
  border-radius: 8px;
}

.admin-case-card__cover--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px dashed rgba(255, 255, 255, 0.2);
  color: var(--text-muted);
  font-size: 1.1rem;
}

.admin-case-card__info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}

.admin-case-card__description {
  font-size: 0.85rem;
  color: var(--text-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.admin-editor {
  text-align: left;
}

.map-viewer {
  position: relative;
  width: 100%;
  max-width: 720px;
  height: 480px;
  margin: 1rem 0;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.02);
}

.map-viewer__scene {
  position: relative;
  display: inline-block;
}

.map-viewer__image {
  display: block;
  max-width: none;
  user-select: none;
}

.map-viewer__controls {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
  z-index: 2;
  display: flex;
  gap: 0.4rem;
}

.map-viewer__control-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  color: var(--text-light);
  background: rgba(13, 13, 13, 0.75);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease;
}

.map-viewer__control-btn:hover {
  border-color: var(--accent);
}

.admin-hotspot-marker {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.6rem;
  height: 1.6rem;
  transform: translate(-50%, -50%);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--bg-dark-start);
  background: var(--accent);
  border: 2px solid var(--text-light);
  border-radius: 50%;
  pointer-events: none;
}

.admin-hotspot-marker--clickable {
  pointer-events: auto;
  cursor: pointer;
}

.admin-hotspot-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 1rem;
}

.admin-hotspot-item {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 0.9rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 8px;
}

.admin-hotspot-item--clickable {
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.admin-hotspot-item--clickable:hover {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.08);
}

.admin-hotspot-item__info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.3rem;
}

.admin-hotspot-item__info p {
  margin-top: 0.25rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.admin-hotspot-item__delete {
  padding: 0.4rem 0.6rem;
  color: var(--text-muted);
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.admin-hotspot-item__delete:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* Карточка вопроса дела — мини-форма (текст + эталонный ответ для ИИ),
   в отличие от статичных строк-хотспотов переиспользует .admin-hotspot-item
   только для внешней рамки/отступов. */
.admin-question-item {
  align-items: stretch;
}

.admin-question-item__fields {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  flex: 1;
  min-width: 0;
}

.admin-question-item__actions {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  flex-shrink: 0;
}

.hotspot-type-badge {
  display: inline-flex;
  align-self: flex-start;
  padding: 0.15rem 0.55rem;
  font-size: 0.7rem;
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: var(--text-muted);
}

.hotspot-type-badge--clue {
  color: #4caf6f;
  border-color: rgba(76, 175, 111, 0.4);
}

.hotspot-type-badge--character {
  color: #e0b34d;
  border-color: rgba(224, 179, 77, 0.4);
}

.hotspot-type-badge--building {
  color: #5da9e0;
  border-color: rgba(93, 169, 224, 0.4);
}

.admin-entity-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  margin-top: 1rem;
}

.admin-case-card__actions {
  flex-shrink: 0;
  margin-left: auto;
}

.admin-case-card__delete {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.4rem 0.6rem;
  color: var(--text-muted);
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.admin-case-card__delete:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.admin-case-card.is-highlighted {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.14);
}

.hotspot-entity-delete-btn {
  margin-top: 0.5rem;
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
}

/* Аккордеон «список + деталь» (вкладки Персонажи/Здания/Триггеры/Диалоги/
   Улики редактора дела). Раньше это был боковой сплит-вид (список слева,
   форма справа) — теперь единая колонка: `.admin-split__detail` физически
   переезжает через JS (`mountDetailInline()` в case-editor.js) прямо внутрь
   `.admin-split__list` — в слот `.admin-entity-detail-slot`, вставленный
   сразу после выбранной карточки — а не регенерируется, чтобы не терять
   навешанные на форму обработчики событий. Когда выбора нет — форма
   возвращается сюда, в `.admin-split` (этот узел не затрагивается
   перезаписью `innerHTML` списка). Раскладка одинакова на всех экранах. */
.admin-split {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  margin-top: 1rem;
}

.admin-split__list {
  width: 100%;
  min-width: 0;
}

.admin-split__detail {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding: 1.1rem 1.25rem;
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-left: 2px solid var(--accent);
  border-radius: 10px;
}

/* Точка монтирования формы внутри списка — сама по себе невидима, всю
   визуальную «выпадающую панель» даёт .admin-split__detail внутри неё. */
.admin-entity-detail-slot {
  width: 100%;
}

.admin-entity-list--compact {
  gap: 0.5rem;
}

.admin-entity-card--row {
  padding: 0.65rem 0.85rem;
  cursor: pointer;
}

.admin-entity-card--row.is-active {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
}

.admin-entity-card__icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 2.2rem;
  height: 2.2rem;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.04);
  border-radius: 50%;
}

.admin-entity-card--row.is-active .admin-entity-card__icon {
  color: var(--accent);
}

.admin-building-detail__triggers {
  padding: 0.9rem 1rem;
  margin: 0.5rem 0;
  background: rgba(255, 255, 255, 0.02);
  border: 1px dashed rgba(255, 255, 255, 0.15);
  border-radius: 8px;
}

.admin-building-detail__triggers-title {
  margin: 0 0 0.35rem;
  font-family: var(--font-heading);
  font-size: 1.1rem;
  letter-spacing: 0.03em;
  color: var(--text-light);
}

.admin-rule-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0.75rem 0;
}

.admin-rule-card {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.65rem 0.75rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 8px;
}

.admin-rule-card--full {
  flex-direction: column;
  align-items: stretch;
  position: relative;
  padding-right: 2.75rem;
}

.admin-rule-card__section {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
}

.admin-rule-card--full > .admin-rule-card__delete {
  position: absolute;
  top: 0.6rem;
  right: 0.6rem;
}

.admin-rule-card__label {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.admin-rule-card__field {
  flex: 1 1 150px;
  min-width: 130px;
}

/* На узком экране несколько полей (например select "Триггер" + select
   "Включен/Выключен") не помещаются рядом даже после переноса строки —
   у каждого есть свой min-width: 130px, который не даёт им сжаться.
   min-width: 0 разрешает полю ужаться и перенестись на новую строку
   вместо того, чтобы вылезать за карточку; flex-basis: auto оставляет
   природный (компактный) размер поля вместо растягивания на всю ширину
   карточки, а max-width: 100% — просто страховка, чтобы даже самое широкое
   поле (например превью картинки с file-инпутом) не могло вылезти за
   пределы карточки. */
@media (max-width: 600px) {
  .admin-rule-card__field {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 100%;
  }
}

.admin-rule-card__delete {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.4rem 0.6rem;
  color: var(--text-muted);
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.admin-rule-card__delete:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* Строка "текущий файл" под file-инпутом (пока только у банковской выписки,
   см. HANDOFF.md) — ссылка на уже загруженный файл + кнопка удаления. */
.admin-file-current {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

/* Единый виджет для стандартных полей image/audio/pdf (персонажи, жертвы,
   здания, улики, головоломки, модалка создания точки на карте) — кнопка
   выбора файла + имя текущего/выбранного файла вместо нативной надписи
   "Файл не выбран" + кнопка-мусорка удаления (см. HANDOFF.md). */
.admin-file-field {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}

.admin-file-field__browse {
  margin-top: 0;
  padding: 0.5rem 0.9rem;
  font-size: 0.85rem;
  white-space: nowrap;
}

.admin-file-field__name {
  font-size: 0.85rem;
  color: var(--text-muted);
  overflow-wrap: anywhere;
}

/* Единая подсветка невалидного поля для форм без нативной required-валидации
   (см. HANDOFF "Фикс валидации точки на карте") — переключается JS-классом
   на произвольном .auth-field, тот же принцип (красный через var(--accent)),
   что у .quiz-question--incorrect выше в файле. */
.auth-field--invalid input,
.auth-field--invalid select {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.08);
}

.auth-field--invalid .admin-file-field {
  padding: 0.4rem;
  background: rgba(230, 57, 70, 0.08);
  border: 1px solid var(--accent);
  border-radius: 6px;
}

/* Конструктор комикс-вступления дела (case-editor.js: renderComicPagesList) —
   карточка страницы содержит вложенный список карточек кадров, визуально
   выделенный отступом и левой рамкой, чтобы вложенность была видна сразу. */
.admin-comic-page-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}

.admin-comic-frames-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding-left: 0.75rem;
  border-left: 2px solid rgba(255, 255, 255, 0.12);
}

.admin-comic-frame-card__preview {
  display: block;
  max-width: 160px;
  max-height: 120px;
  margin-top: 0.5rem;
  border-radius: 6px;
  object-fit: cover;
}

.admin-rule-card__trigger-link {
  padding: 0.3rem 0.5rem;
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--accent);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: transparent;
  transition: text-decoration-color 0.2s ease;
}

.admin-rule-card__trigger-link:hover {
  text-decoration-color: var(--accent);
}

/* Группы условий: И внутри группы, ИЛИ между группами — переиспользуется
   правилами персонажей/зданий и условиями запуска диалога. */
.admin-condition-groups {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  flex: 1 1 100%;
}

.admin-condition-groups__empty {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.admin-condition-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  padding: 0.5rem;
  background: rgba(255, 255, 255, 0.04);
  border: 1px dashed rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  width: 100%;
}

.admin-condition-group__row {
  display: flex;
  align-items: center;
  gap: 0.35rem;
}

.admin-condition-group__row select {
  min-width: 130px;
}

.admin-condition-group__row-delete {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.3rem 0.5rem;
  color: var(--text-muted);
  background: none;
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.admin-condition-group__row-delete:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.admin-condition-group__add-and {
  padding: 0.25rem 0.55rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.admin-condition-group__add-and:hover {
  color: var(--accent);
  border-color: var(--accent);
}

.admin-condition-groups__or {
  align-self: center;
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}

.admin-condition-groups__add-or {
  padding: 0.3rem 0.65rem;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-light);
  background: none;
  border: 1px dashed rgba(255, 255, 255, 0.25);
  border-radius: 6px;
  cursor: pointer;
  transition: border-color 0.2s ease, color 0.2s ease;
}

.admin-condition-groups__add-or:hover {
  color: var(--accent);
  border-color: var(--accent);
}

/* Диалоги: граф блоков на React Flow (см. dialogue-flow-editor.js) */
.dialogue-flow-editor {
  position: relative;
  height: 560px;
  margin: 0.75rem 0;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 10px;
  overflow: hidden;
}

.dialogue-flow-editor__inner {
  position: relative;
  width: 100%;
  height: 100%;
}

.dialogue-flow-editor .react-flow {
  background: transparent;
}

/* Дефолтные кнопки Controls (zoom in/out/fit view/toggle interactivity)
   React Flow берут --xy-controls-button-color по умолчанию как `inherit` —
   на сайте это наследует почти белый цвет текста (--text-light) от body, а
   фон кнопки у библиотеки светлый (#fefefe) — иконка (fill: currentColor)
   становится почти невидимой (белое на белом). Переопределяем переменные
   темы React Flow под тёмную палитру сайта, в духе .dialogue-flow-editor__fullscreen-btn. */
.dialogue-flow-editor .react-flow__controls {
  --xy-controls-button-background-color: rgba(20, 20, 20, 0.92);
  --xy-controls-button-background-color-hover: rgba(40, 40, 40, 0.95);
  --xy-controls-button-color: var(--text-muted);
  --xy-controls-button-color-hover: var(--text-light);
  --xy-controls-button-border-color: rgba(255, 255, 255, 0.18);
}

.dialogue-flow-editor__add-block {
  position: absolute;
  top: 0.6rem;
  left: 0.6rem;
  z-index: 5;
  width: auto !important;
}

/* Полноэкранный режим графа диалогов — .dialogue-flow-editor__inner получает
   этот класс при isFullscreen === true (см. dialogue-flow-editor.js).
   В проекте нет переменной --bg-dark, поэтому фон повторяет градиент body. */
.react-flow-fullscreen {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 9999;
  background: linear-gradient(160deg, var(--bg-dark-start), var(--bg-dark-end));
}

.dialogue-flow-editor__fullscreen-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  color: var(--text-muted);
  background: rgba(20, 20, 20, 0.9);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.dialogue-flow-editor__fullscreen-btn:hover {
  color: var(--text-light);
  border-color: var(--accent);
}

.dialogue-flow-node {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  width: 260px;
  padding: 0.75rem 0.85rem;
  background: rgba(20, 20, 20, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
}

.dialogue-flow-node__badge {
  align-self: flex-start;
  padding: 0.1rem 0.5rem;
  font-family: var(--font-heading);
  font-size: 0.7rem;
  letter-spacing: 0.05em;
  color: #0d0d0d;
  background: var(--accent);
  border-radius: 4px;
}

.dialogue-flow-node__header {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.dialogue-flow-node__title {
  flex: 1;
  font-family: var(--font-heading);
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  color: var(--text-muted);
}

.dialogue-flow-node__icon-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.06);
  border: none;
  border-radius: 6px;
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
}

.dialogue-flow-node__icon-btn:hover {
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.12);
}

.dialogue-flow-node__icon-btn--danger:hover {
  color: var(--accent);
}

.dialogue-flow-node__line {
  padding: 0.5rem 0.6rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text-light);
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 6px;
  outline: none;
  resize: vertical;
}

.dialogue-flow-node__line:focus {
  border-color: var(--accent);
}

.dialogue-flow-node__condition {
  padding: 0.35rem 0.5rem;
  font-size: 0.78rem;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.04);
  border-radius: 6px;
}

.dialogue-flow-node__responses {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding-top: 0.4rem;
  border-top: 1px dashed rgba(255, 255, 255, 0.12);
}

.dialogue-flow-node__response {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  padding: 0.4rem 1.1rem 0.4rem 0.6rem;
  font-size: 0.82rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.05);
  border-radius: 6px;
}

.dialogue-flow-node__response-condition-icon {
  flex-shrink: 0;
  font-size: 0.72rem;
  color: var(--accent);
}

.dialogue-flow-node__no-responses {
  font-size: 0.78rem;
  font-style: italic;
  color: var(--text-muted);
}

.dialogue-flow-node__handle-target {
  width: 10px;
  height: 10px;
  background: var(--text-muted);
  border: 2px solid rgba(0, 0, 0, 0.5);
}

.dialogue-flow-node__handle-source {
  width: 10px;
  height: 10px;
  background: var(--accent);
  border: 2px solid rgba(0, 0, 0, 0.5);
}

/* Диалоги: боковая панель редактирования выбранного блока */
.dialogue-flow-panel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  width: 320px;
  padding: 1rem;
  overflow-y: auto;
  background: rgba(10, 10, 10, 0.97);
  border-left: 1px solid rgba(255, 255, 255, 0.15);
}

/* Фиксированные 320px оставляют канвасу графа почти нулевую ширину на
   телефоне — на мобильных панель раскрывается на всю ширину канваса
   (канвас снова виден после закрытия панели). */
@media (max-width: 700px) {
  .dialogue-flow-panel {
    width: 100%;
    border-left: none;
  }
}

.dialogue-flow-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.dialogue-flow-panel__header h4 {
  margin: 0;
  font-family: var(--font-heading);
  letter-spacing: 0.03em;
  color: var(--text-light);
}

.dialogue-flow-panel__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 1.8rem;
  height: 1.8rem;
  color: var(--text-muted);
  background: rgba(255, 255, 255, 0.06);
  border: none;
  border-radius: 6px;
  cursor: pointer;
}

.dialogue-flow-panel__close:hover {
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.12);
}

.dialogue-flow-panel__section h5 {
  margin: 0 0 0.5rem;
  font-family: var(--font-heading);
  font-size: 0.9rem;
  letter-spacing: 0.03em;
  color: var(--text-muted);
}

.dialogue-flow-panel__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0.4rem 0;
}

.dialogue-flow-panel__response {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.6rem;
  margin-bottom: 0.6rem;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 8px;
}

.dialogue-flow-panel__response-condition {
  padding: 0.4rem;
  background: rgba(255, 255, 255, 0.03);
  border-radius: 6px;
}

.admin-building-detail__actions {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-top: 0.5rem;
}

.admin-building-detail__actions .auth-submit {
  width: auto;
}

/* Адресная книга (игровой интерфейс) */
.address-book__list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 1rem;
  max-height: 60vh;
  overflow-y: auto;
}

.address-book__entry {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.75rem 0.9rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.address-book__entry-icon {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
  border-radius: 50%;
}

.address-book__entry-info {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.35rem;
  min-width: 0;
}

.address-book__entry-name {
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  font-weight: 700;
  color: var(--text-light);
  text-align: left;
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}

.address-book__entry-name:hover {
  color: var(--accent);
}

.address-book__entry-crime-scene {
  font-size: 0.8rem;
  color: var(--accent);
}

.address-book__entry-noaddress {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.address-book__entry-address {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.25rem 0.7rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.address-book__entry-address:hover {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
}

.address-book__entry-address.is-revealed {
  color: #4caf6f;
  border-color: rgba(76, 175, 111, 0.4);
  cursor: default;
}

.game-residents__list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 1rem;
  max-height: 60vh;
  overflow-y: auto;
}

.game-residents__item {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.75rem 0.9rem;
  font-family: inherit;
  font-size: 1rem;
  color: var(--text-light);
  text-align: left;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease;
}

.game-residents__item:hover {
  border-color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
}

.game-residents__item-photo {
  flex-shrink: 0;
  width: 2.4rem;
  height: 2.4rem;
  object-fit: cover;
  border-radius: 50%;
}

.game-residents__item-photo--placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--accent);
  background: rgba(230, 57, 70, 0.1);
}

.game-police__dossier-block {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0.5rem 0;
}

/* Полицейский участок — стартовый экран "кабинетов" (#game-police-modal) и
   его под-экраны, см. openPoliceStationModal()/setupPoliceStationModal() в
   game.js. Классы .facility-* названы обобщённо (не .police-*), так как
   когда-то делились с больницей — та с этой итерации переехала на
   полноэкранный React-компьютер (см. openHospitalModal() в game.js) и эти
   классы больше не использует, но переименовывать обратно в .police-*
   незачем: они по-прежнему могут понадобиться будущим учреждениям
   (см. #editor-tab-computer в case-editor.html). */
.game-modal--facility {
  max-width: 480px;
}

.facility-departments {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 0.9rem;
  margin: 0.5rem 0;
}

.facility-department-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 1.1rem 0.75rem;
  font-family: inherit;
  color: var(--text-light);
  text-align: center;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.25s ease, background-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.facility-department-card:hover {
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.06);
  transform: scale(1.03);
  box-shadow: 0 10px 26px rgba(193, 18, 31, 0.3), 0 0 18px rgba(193, 18, 31, 0.18);
}

.facility-department-card__icon {
  font-size: 1.6rem;
  color: var(--accent);
}

.facility-department-card__label {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  letter-spacing: 0.02em;
}

.facility-department-card__badge {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  padding: 0.15rem 0.45rem;
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--bg-dark-start);
  background: var(--text-muted);
  border-radius: 4px;
}

.facility-department-view {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  animation: facilityViewIn 0.25s ease;
}

.facility-department-view__title {
  margin: 0;
  font-family: var(--font-heading);
  font-size: 1.05rem;
  letter-spacing: 0.02em;
}

/* Без этого переопределения [hidden] у .facility-departments/.facility-department-view
   проигрывает каскад безусловному display выше (та же специфичность 0,1,0,
   но авторский класс идёт позже UA-стиля [hidden] { display: none }) — грид
   кабинетов и все под-экраны оставались бы видимы одновременно, а клики по
   карточкам/"Назад" визуально ничего не меняли бы. Тот же паттерн, что
   .game-modal__backdrop[hidden] выше. */
.facility-departments[hidden],
.facility-department-view[hidden] {
  display: none;
}

@keyframes facilityViewIn {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.facility-back-btn {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.35rem 0.2rem;
  font-family: inherit;
  font-size: 0.85rem;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  transition: color 0.2s ease;
}

.facility-back-btn:hover {
  color: var(--accent);
}

/* Динамическое досье персонажа (character.facts) — строки, открытые игроку
   по текущему прогрессу, в модалке персонажа (#game-character-modal-facts). */
.character-fact-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0.5rem 0;
  text-align: left;
}

.character-fact {
  padding: 0.65rem 0.9rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.character-fact__title {
  margin-right: 0.4rem;
  font-weight: 600;
  color: var(--accent);
}

.character-fact__text {
  white-space: pre-wrap;
}

/* «Рабочий компьютер» (полицейский участок) — стиль защищённой служебной ОС:
   тёмно-синяя палитра, стальные рамки, голубой акцент вместо зелёного
   ретро-терминала (7 приложений-баз, см. APPS в computer-app.js). Отдельный
   полноэкранный оверлей (аналог .game-modal__backdrop), а не floating-окно,
   как у .game-phone-root — по требованию задачи. */
.game-computer-root {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: rgba(0, 0, 0, 0.85);
}

.game-computer-root[hidden] {
  display: none;
}

.computer-window {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  height: 520px;
  max-height: calc(100vh - 3rem);
  max-height: calc(100dvh - 3rem);
  overflow: hidden;
  color: #dbe6f5;
  background: linear-gradient(165deg, #0b1220, #101c30);
  border: 1px solid #2c3e58;
  border-radius: 8px;
  box-shadow: 0 0 0 1px rgba(79, 163, 255, 0.12), 0 0 32px rgba(79, 163, 255, 0.18), inset 0 0 40px rgba(79, 163, 255, 0.03);
}

.computer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  background: rgba(79, 163, 255, 0.05);
  border-bottom: 1px solid rgba(79, 163, 255, 0.25);
}

.computer-header__dots {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 0.4rem;
}

.computer-header__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  opacity: 0.7;
}

/* Красная точка — единственная из трёх кликабельная (закрывает компьютер,
   см. onClick={onClose} в ComputerHeader), поэтому она <button>, а не
   <span> — нужен сброс браузерного chrome кнопки поверх общих правил
   .computer-header__dot выше. */
.computer-header__dot--red {
  padding: 0;
  border: none;
  background: #e05252;
  cursor: pointer;
  transition: opacity 0.2s ease, box-shadow 0.2s ease;
}

.computer-header__dot--red:hover {
  opacity: 1;
  box-shadow: 0 0 6px rgba(224, 82, 82, 0.6);
}

.computer-header__dot--yellow {
  background: #e0b552;
}

.computer-header__dot--green {
  background: #52c98a;
}

/* Заменяет крестик справа на рабочем столе (см. ComputerHeader) — то же
   flex: 1, что у .computer-header__dots слева, чтобы .computer-header__title
   между ними остался визуально по центру, а не только внутри своего flex:1. */
.computer-header__spacer {
  flex: 1;
}

.computer-header__title {
  flex: 1;
  overflow: hidden;
  font-size: 0.95rem;
  font-weight: 700;
  text-align: center;
  text-overflow: ellipsis;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.computer-back-btn,
.computer-close-btn {
  flex: 0 0 auto;
  padding: 0.3rem 0.5rem;
  font-family: inherit;
  font-size: 0.8rem;
  color: #9fc3f2;
  background: transparent;
  border: 1px solid rgba(79, 163, 255, 0.35);
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s ease, box-shadow 0.2s ease;
}

.computer-back-btn:hover,
.computer-close-btn:hover {
  background: rgba(79, 163, 255, 0.12);
  box-shadow: 0 0 8px rgba(79, 163, 255, 0.35);
}

.computer-screen-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  padding: 1.5rem;
  overflow-y: auto;
}

.computer-desktop {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 1rem;
}

.computer-desktop-grid {
  display: grid;
  flex: 1;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 1rem 0.9rem;
  align-content: center;
  justify-content: center;
  padding: 0.5rem 0;
}

.computer-app-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  padding: 1.1rem 0.75rem;
  font-family: inherit;
  color: #dbe6f5;
  background: rgba(79, 163, 255, 0.05);
  border: 1px solid rgba(79, 163, 255, 0.25);
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.computer-app-icon:hover {
  background: rgba(79, 163, 255, 0.12);
  border-color: rgba(79, 163, 255, 0.5);
  box-shadow: 0 0 16px rgba(79, 163, 255, 0.3);
  transform: translateY(-2px);
}

.computer-app-icon--disabled {
  opacity: 0.4;
  filter: grayscale(100%);
  cursor: not-allowed;
}

.computer-app-icon--disabled:hover {
  background: rgba(79, 163, 255, 0.05);
  border-color: rgba(79, 163, 255, 0.25);
  box-shadow: none;
  transform: none;
}

.computer-app-icon__glyph {
  font-size: 1.6rem;
  color: #4fa3ff;
}

.computer-app-icon__label {
  font-size: 0.8rem;
  text-align: center;
  letter-spacing: 0.02em;
  color: #b8c7de;
}

.computer-taskbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(79, 163, 255, 0.2);
}

.computer-taskbar__status {
  font-size: 0.78rem;
  color: #7c8ba5;
  letter-spacing: 0.02em;
}

.computer-logout-btn {
  flex: 0 0 auto;
  padding: 0.4rem 0.75rem;
  font-family: inherit;
  font-size: 0.8rem;
  color: #f2b8b8;
  background: rgba(224, 82, 82, 0.08);
  border: 1px solid rgba(224, 82, 82, 0.35);
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.2s ease, box-shadow 0.2s ease;
}

.computer-logout-btn:hover {
  background: rgba(224, 82, 82, 0.18);
  box-shadow: 0 0 10px rgba(224, 82, 82, 0.35);
}

.computer-app-screen {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 1rem;
}

.computer-input-form {
  display: flex;
  gap: 0.6rem;
}

.computer-input {
  flex: 1;
  padding: 0.6rem 0.75rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: #dbe6f5;
  background: #060c17;
  border: 1px solid #2c3e58;
  border-radius: 4px;
  caret-color: #4fa3ff;
}

.computer-input:focus {
  outline: none;
  border-color: #4fa3ff;
  box-shadow: 0 0 10px rgba(79, 163, 255, 0.4);
}

.computer-input::placeholder {
  color: rgba(219, 230, 245, 0.35);
}

.computer-submit-btn {
  flex: 0 0 auto;
  padding: 0.6rem 1.1rem;
  font-family: inherit;
  font-weight: 700;
  color: #05101f;
  letter-spacing: 0.03em;
  background: #4fa3ff;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  box-shadow: 0 0 12px rgba(79, 163, 255, 0.4);
  transition: filter 0.2s ease;
}

.computer-submit-btn:hover {
  filter: brightness(1.1);
}

.computer-result {
  padding: 0.75rem 0.9rem;
  font-family: 'Courier New', Courier, monospace;
  font-size: 0.9rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  background: rgba(79, 163, 255, 0.05);
  border: 1px solid rgba(79, 163, 255, 0.2);
  border-radius: 6px;
}

.computer-result--error {
  color: #ff8a8a;
  background: rgba(224, 82, 82, 0.08);
  border-color: rgba(224, 82, 82, 0.3);
}

/* Успешный результат приложения компьютера — "печатный отчёт" в стиле
   личного дела (.game-modal--dossier/.dossier-photo выше), только в
   масштабе инлайн-карточки внутри тёмного окна компьютера, а не полноэкранной
   модалки. Фото (.computer-dossier-card__photo) рендерится только если у
   ключа задано поле "Фото/скан" в редакторе — иначе карточка остаётся чистым
   листом текста без скрепки. */
.computer-dossier-list {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.computer-dossier-card {
  position: relative;
  padding: 0.9rem 1rem;
  color: #2b2620;
  background:
    repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.02) 0 1px, transparent 1px 26px),
    linear-gradient(135deg, #f2e9d4, #e6d8b8);
  border: 1px solid rgba(60, 45, 20, 0.25);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.computer-dossier-card__photo {
  position: relative;
  float: right;
  width: 5rem;
  margin: 0 0 0.5rem 0.8rem;
  background: #fff;
  padding: 0.25rem 0.25rem 0.4rem;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.35);
  transform: rotate(3deg);
}

.computer-dossier-card__photo img {
  width: 100%;
  height: 5.5rem;
  object-fit: cover;
}

.computer-dossier-card__clip {
  position: absolute;
  top: -0.5rem;
  left: 50%;
  transform: translateX(-50%) rotate(-8deg);
  font-size: 1.1rem;
  color: #8a8f98;
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.4);
}

/* Заголовок с искомым значением (код/адрес/имя) — без clear, поэтому
   занимает свободное место слева от .computer-dossier-card__photo, а не
   пропадает пустым зря; если фото нет, просто обычная строка над текстом. */
.computer-dossier-card__title {
  margin: 0 0 0.4rem;
  font-size: 0.85rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #6b5a35;
}

.computer-dossier-card__text {
  margin: 0;
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  word-break: break-word;
  clear: both;
}

/* Рамка экрана ноутбука-улики (facility: 'laptop', класс .laptop-frame на
   #game-laptop-computer-root) — толстая чёрная рамка со скруглёнными углами
   и более выраженной тенью поверх обычного .computer-window, имитация
   бордера экрана ноутбука. */
.laptop-frame .computer-window {
  border: 10px solid #050608;
  border-radius: 18px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55), 0 0 0 1px rgba(255, 255, 255, 0.05);
}

/* Галерея ноутбука-улики (LaptopAppScreen, appId 'gallery') — по образцу
   .phone-gallery-grid, но без подписи под фото (у устройства-улики фото не
   привязаны к отдельным именованным уликам). */
.computer-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 0.75rem;
}

.computer-gallery-grid__img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 6px;
  border: 1px solid rgba(79, 163, 255, 0.25);
}

/* "Дешифратор" (полицейский компьютер, DecrypterScreen) — список устройств
   переиспользует сетку/карточку .computer-app-icon (см. DesktopScreen), а
   состояние расшифровки/результата — свои небольшие блоки. */
.computer-decrypt-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
  gap: 1rem 0.9rem;
}

.computer-decrypt-progress {
  padding: 1.75rem 0.9rem;
  font-family: 'Courier New', Courier, monospace;
  font-size: 0.95rem;
  text-align: center;
  color: #b8c7de;
}

.computer-decrypt-result {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  padding: 1.75rem 0.9rem;
  text-align: center;
}

.computer-decrypt-result strong {
  font-family: 'Courier New', Courier, monospace;
  font-size: 1.3rem;
  color: #4fa3ff;
  letter-spacing: 0.08em;
}

.computer-decrypt-result .computer-submit-btn {
  margin-top: 0;
}

.game-search-item {
  display: flex;
  align-items: center;
  width: 100%;
  padding: 0.75rem 0.9rem;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 500;
  text-align: left;
  color: var(--text-light);
  border: 1px solid var(--accent);
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
  transition: color 0.2s ease, background-color 0.2s ease;
}

.game-search-item:hover {
  color: var(--bg-dark-start);
  background: var(--accent);
}

.game-search-item__name {
  color: inherit;
}

.game-dialogue-modal {
  max-width: 460px;
}

.game-dialogue-modal__portrait {
  width: 5rem;
  height: 5rem;
  margin: 0 auto;
  object-fit: cover;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.1);
}

.game-dialogue-modal__name {
  font-family: var(--font-heading);
  font-size: 1.2rem;
  letter-spacing: 0.03em;
}

.game-dialogue-modal__line {
  color: var(--text-light);
  line-height: 1.5;
}

.game-dialogue-modal__responses {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin-top: 0.5rem;
}

/* Варианты ответа — контурная акцентная кнопка, на hover заливается целиком
   (тот же приём, что у .game-bottom-bar__btn:active и hacker-варианта
   .auth-submit). position: relative — для точки "новый ответ" ниже. */
.game-dialogue-modal__response-btn {
  position: relative;
  padding: 0.75rem 0.9rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--text-light);
  text-align: left;
  background: transparent;
  border: 1px solid var(--accent);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.2s ease, background-color 0.2s ease, color 0.2s ease;
}

.game-dialogue-modal__response-btn:hover {
  color: var(--bg-dark-start);
  background: var(--accent);
  border-color: var(--accent);
}

.game-dialogue-modal__response-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

/* Точка "этот ответ игрок ещё не выбирал" (только в облегчённой сложности,
   см. renderDialogueBlock() в game.js) — те же размеры/цвета, что у точек на
   фото персонажей: жёлтая в обычном диалоге, акцентная в допросе. */
.game-dialogue-modal__response-dot {
  position: absolute;
  top: -0.2rem;
  right: -0.2rem;
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  box-shadow: 0 0 0 2px var(--bg-dark-start);
}

.game-dialogue-modal__response-dot--dialogue {
  background: #f4c430;
}

.game-dialogue-modal__response-dot--interrogation {
  background: var(--accent);
}

/* Головоломки (сейфы): модалка кодовой панели — см. openPuzzleModal() в
   game.js. background-image ставится инлайном, только если у пазла есть
   картинка (puzzle.image); иначе модалка выглядит как обычная .game-modal. */
.game-puzzle-modal {
  max-width: 420px;
  background-size: cover;
  background-position: center;
}

.game-puzzle-keypad__screen {
  padding: 0.75rem 1rem;
  font-family: var(--font-heading), monospace;
  font-size: 1.6rem;
  letter-spacing: 0.3em;
  text-align: center;
  color: var(--accent);
  background: rgba(0, 0, 0, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  min-height: 2.4rem;
}

@keyframes error-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}

.game-puzzle-keypad__screen.error-shake {
  color: #ff5c5c;
  border-color: #ff5c5c;
  animation: error-shake 0.4s ease;
}

.game-puzzle-keypad__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.6rem;
}

/* Тот же фикс, что у .auth-field[hidden] выше в файле: авторский
   display: grid перекрывает правило браузера [hidden] { display: none },
   а без этого переключение keypad/dial в openPuzzleModal() (game.js) не
   скрывало бы сетку кнопок при открытии головоломки-лимба. */
.game-puzzle-keypad__grid[hidden] {
  display: none;
}

/* Попап "Открыто" — короткое подтверждение после решения головоломки (см.
   showPuzzleSolvedPopup() в game.js), заменяет собой уголковый toast. */
@keyframes puzzle-success-pop {
  from {
    transform: scale(0.7);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

.game-puzzle-success-modal {
  align-items: center;
  animation: puzzle-success-pop 0.25s ease;
}

.game-puzzle-success-modal i {
  font-size: 3rem;
  color: var(--accent);
}

.game-puzzle-success-modal h2 {
  margin: 0;
}

/* Мультиплеер, Этап 3: grace-period хоста — z-index выше .game-computer-root
   (70), чтобы перекрыть даже открытый компьютерный терминал учреждения. */
.game-host-disconnected-backdrop {
  z-index: 2000;
}

.game-host-disconnected-modal {
  align-items: center;
  text-align: center;
  gap: 0.75rem;
}

.game-host-disconnected-modal i {
  font-size: 2.5rem;
  color: var(--accent);
  animation: hostSignalPulse 1.6s ease-in-out infinite;
}

@keyframes hostSignalPulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

.game-host-disconnected-modal h2 {
  margin: 0;
}

.game-host-disconnected-modal p {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.9rem;
}

.game-puzzle-keypad__btn {
  padding: 0.75rem 0;
  font-family: var(--font-heading);
  font-size: 1.1rem;
  color: var(--text-light);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease;
}

.game-puzzle-keypad__btn:hover {
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.12);
}

.game-puzzle-keypad__btn--reset {
  font-size: 0.85rem;
  letter-spacing: 0.03em;
  color: var(--text-muted);
}

/* Механический лимб (сейф) — вращаемый SVG-диск на pointer-событиях, см.
   openDialPuzzle()/onDialPointerMove() в game.js. Метка сверху неподвижна,
   вращается только сам диск внутри контейнера. Размер — clamp(220px, 70vw,
   300px): растёт до 300px на широких экранах, плавно уменьшается на узких,
   не переполняя .game-puzzle-modal (max-width увеличен до 420px). */
.game-puzzle-dial-container {
  position: relative;
  width: clamp(220px, 70vw, 300px);
  height: clamp(220px, 70vw, 300px);
  margin: 1rem auto;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, #4a4a4a, #101010 70%);
  box-shadow: inset 0 4px 14px rgba(0, 0, 0, 0.65), 0 6px 18px rgba(0, 0, 0, 0.5);
  touch-action: none;
}

.game-puzzle-dial-marker {
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 0;
  height: 0;
  border-left: 8px solid transparent;
  border-right: 8px solid transparent;
  border-top: 14px solid #ff5c5c;
  z-index: 2;
}

.game-puzzle-dial {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  color: var(--text-light);
  cursor: grab;
  user-select: none;
  transform: rotate(0deg);
}

.game-puzzle-dial:active {
  cursor: grabbing;
}

.game-puzzle-dial svg {
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
}

/* ====================================================================
   HACKER THEME — Component Overrides (Подход 2, DESIGN.md / Resend)
   Точечные переопределения для мест, где фон/рамки захардкожены
   (rgba(255,255,255,.03..15)), а не заданы через переменные — поэтому
   переменные из [data-theme="hacker"] выше их не перекрывают. Секция
   умышленно в конце файла: при равной специфичности с базовыми правилами
   более поздние по порядку выигрывают, что гарантирует применение темы
   независимо от того, где определён базовый селектор.
   ==================================================================== */

/* --- Кнопки-призраки (вторичные действия, close-кнопки) --- */
[data-theme="hacker"] .login-btn {
  color: var(--text-light);
  border-color: var(--border-color);
}

[data-theme="hacker"] .login-btn:hover,
[data-theme="hacker"] .login-btn:focus-visible {
  color: var(--text-light);
  background-color: #1a1a1a;
  border-color: var(--border-color-hover);
}

[data-theme="hacker"] .game-modal__close:hover,
[data-theme="hacker"] .account-modal__close:hover {
  color: var(--accent);
}

/* --- Кнопки-действия (Auth Submit / основной CTA) — без заливки-градиента,
   акцент только в рамке/тексте, инверсия на hover. --- */
[data-theme="hacker"] .auth-submit {
  color: var(--accent);
  background: transparent;
  border: 1px solid var(--accent);
  box-shadow: none;
}

[data-theme="hacker"] .auth-submit:hover {
  color: #000000;
  background: var(--accent);
  opacity: 1;
}

/* --- Карточки: дела, инвентарь --- */
[data-theme="hacker"] .case-tile,
[data-theme="hacker"] .game-inventory__item {
  background: #000000;
  border: 1px solid var(--border-color);
  border-radius: var(--card-radius);
}

[data-theme="hacker"] .case-tile:hover {
  background: #0a0a0a;
  border-color: var(--accent);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}

[data-theme="hacker"] .case-tile.is-disabled:hover {
  background: #000000;
  border-color: var(--border-color);
  box-shadow: none;
}

[data-theme="hacker"] .game-inventory__item:hover {
  border-color: var(--accent);
}

/* --- Модалки --- */
[data-theme="hacker"] .game-modal,
[data-theme="hacker"] .account-modal {
  background: #000000;
  border: 1px solid var(--border-color);
  border-radius: var(--card-radius);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
}

/* --- Инпуты --- */
[data-theme="hacker"] .auth-field input,
[data-theme="hacker"] .auth-field textarea,
[data-theme="hacker"] .account-modal__input {
  background: #000000;
  border: 1px solid var(--border-color);
  color: var(--text-light);
}

[data-theme="hacker"] .auth-field input:focus,
[data-theme="hacker"] .auth-field textarea:focus,
[data-theme="hacker"] .account-modal__input:focus {
  border-color: var(--accent);
}

/* --- Терминальный режим: компьютер и телефон в игре целиком на
   моноширинном шрифте (текст, инпуты, кнопки внутри). Иконки Font
   Awesome не страдают — их font-family задаётся с !important в самом
   FA-стиле и всегда выигрывает у этого правила. --- */
[data-theme="hacker"] .game-computer-root,
[data-theme="hacker"] .game-computer-root *,
[data-theme="hacker"] .game-phone-root,
[data-theme="hacker"] .game-phone-root * {
  font-family: var(--font-mono);
}

/* --- Hero: 3D-модель (hero-3d.js) как полноэкранный фоновый слой на
   всю секцию, только для hacker — в noir hero остаётся центрированным
   одноколоночным блоком. Модель лежит позади текста (z-index: 0 у
   контейнера vs. z-index: 1 у .hero__content, см. базовое правило
   .hero__content выше) и не перехватывает клики (pointer-events: none),
   поэтому кнопка "Начать расследование" остаётся кликабельной даже
   визуально поверх модели.

   ВАЖНО: .hero/.hero__content/.hero__title/.hero__description —
   переиспользуемые классы. Кроме лендинга (index.html, внутри
   .landing-container) их используют dashboard/login/cases/achievements/
   support как fullscreen flex-контейнер для центрирования .auth-card.
   Без скоупа предком .landing-container правило justify-content:
   flex-start ломало центрирование карточек на всех этих страницах
   (баг: "сайт сдвинут влево" при активной теме hacker). --- */
[data-theme="hacker"] .landing-container .hero {
  justify-content: flex-start;
  text-align: left;
}

[data-theme="hacker"] .landing-container .hero__content {
  text-align: left;
}

[data-theme="hacker"] .landing-container .hero__title {
  white-space: normal;
}

[data-theme="hacker"] .landing-container .hero__description {
  margin-left: 0;
  margin-right: 0;
}

/* Инсеты -2rem (а не 0) компенсируют .hero { padding: 2rem } — offset
   position:absolute считается от padding-box родителя, поэтому 0 оставил
   бы видимый зазор в 2rem от реального края секции. -2rem дотягивает
   бокс до border-box .hero, т.е. до самых верхней/нижней/боковых границ
   блока. Единственный брейкпоинт, где контейнер виден (>768px) — там
   .hero всегда padding: 2rem, ниже 768px контейнер и так display:none. */
[data-theme="hacker"] .landing-container .hero-3d-container {
  display: flex;
  position: absolute;
  top: -2rem;
  right: -2rem;
  bottom: -2rem;
  left: -2rem;
  justify-content: center;
  align-items: center;
  z-index: 0;
  pointer-events: none;
}

@media (max-width: 768px) {
  [data-theme="hacker"] .landing-container .hero-3d-container {
    display: none;
  }
}
