/* ==========================================================================
   launch.css — стартовый экран, выбор демо-роли и прелоудер.

   Экран живёт над приложением как отдельный слой и снимается сразу после
   выбора роли. Вся анимация — CSS: медленный дрейф градиента, мягкий
   параллакс архитектурных слоёв и плавный blur-переход между фотографиями.
   Ни видео, ни canvas, ни сторонних библиотек: слой должен появляться
   мгновенно и не мешать первому кадру приложения.
   ========================================================================== */

.launch {
  position: fixed;
  inset: 0;
  z-index: 900;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.86fr);
  background: var(--color-background);
  overflow: hidden;
  opacity: 1;
  transition: opacity var(--dur-slower) var(--ease-out);
}

.launch[hidden] { display: none; }

/* Снятие слоя: сначала уводим в прозрачность, затем скрываем из потока */
.launch.is-leaving { opacity: 0; pointer-events: none; }

/* --------------------------------------------------------------------------
   Фон: архитектурные слои
   -------------------------------------------------------------------------- */

.launch__bg {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* Медленный дрейф тёплого градиента — движение на грани заметности */
.launch__wash {
  position: absolute;
  inset: -20%;
  background:
    radial-gradient(60% 50% at 20% 25%, rgba(147, 31, 43, 0.07), transparent 70%),
    radial-gradient(55% 45% at 80% 75%, rgba(23, 22, 20, 0.06), transparent 72%);
  animation: launch-drift 46s var(--ease-inout) infinite alternate;
}

@keyframes launch-drift {
  from { transform: translate3d(-1.5%, -1%, 0) scale(1.02); }
  to   { transform: translate3d(1.5%, 1.5%, 0) scale(1.06); }
}

/* Контуры зданий: тонкая линейная графика, проявляется один раз */
.launch__lines {
  position: absolute;
  right: 0;
  bottom: 0;
  width: min(58vw, 720px);
  height: auto;
  color: rgba(23, 22, 20, 0.16);
  animation: launch-lines-in 1600ms var(--ease-soft) both;
}

.launch__lines path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Второй слой контуров идёт с иным темпом — получается мягкий параллакс */
.launch__lines--far {
  width: min(72vw, 900px);
  color: rgba(23, 22, 20, 0.08);
  animation: launch-lines-in 2000ms var(--ease-soft) both,
             launch-parallax 38s var(--ease-inout) infinite alternate;
}

@keyframes launch-lines-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes launch-parallax {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-22px, -8px, 0); }
}

/* --------------------------------------------------------------------------
   Правая колонка: blur-переход между архитектурными фотографиями
   -------------------------------------------------------------------------- */

.launch__media {
  position: relative;
  overflow: hidden;
  background: var(--color-surface-ink);
}

.launch__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transform: scale(1.06);
  filter: blur(10px);
  animation: launch-photo 24s var(--ease-inout) infinite;
}

.launch__photo:nth-of-type(1) { animation-delay: 0s; }
.launch__photo:nth-of-type(2) { animation-delay: 8s; }
.launch__photo:nth-of-type(3) { animation-delay: 16s; }

@keyframes launch-photo {
  0%   { opacity: 0; filter: blur(12px); transform: scale(1.10); }
  8%   { opacity: 1; filter: blur(0);    transform: scale(1.06); }
  30%  { opacity: 1; filter: blur(0);    transform: scale(1.01); }
  38%  { opacity: 0; filter: blur(12px); transform: scale(1.00); }
  100% { opacity: 0; filter: blur(12px); transform: scale(1.10); }
}

.launch__media-veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--color-background) 0%, rgba(244, 242, 239, 0) 22%),
    linear-gradient(180deg, rgba(23, 22, 20, 0.10), rgba(23, 22, 20, 0.36));
}

.launch__media-caption {
  position: absolute;
  left: var(--space-7);
  right: var(--space-7);
  bottom: var(--space-7);
  color: var(--color-text-inverse);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-text-inverse-dim);
}

/* --------------------------------------------------------------------------
   Контент
   -------------------------------------------------------------------------- */

.launch__inner {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  padding: clamp(1.5rem, 1rem + 3vw, 4.5rem);
  overflow-y: auto;
}

.launch__stage {
  width: 100%;
  max-width: 640px;
  animation: launch-stage-in var(--dur-slower) var(--ease-soft) both;
}

@keyframes launch-stage-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.launch__logo { display: block; height: 22px; width: auto; }

.launch__eyebrow {
  margin-top: var(--space-6);
  font-size: var(--text-2xs);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

.launch__title {
  margin-top: var(--space-3);
  font-family: var(--font-display);
  font-size: var(--text-display);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tighter);
  color: var(--color-text-primary);
  text-wrap: balance;
}

.launch__lede {
  margin-top: var(--space-5);
  max-width: 46ch;
  font-size: var(--text-body);
  line-height: var(--leading-relaxed);
  color: var(--color-text-secondary);
}

.launch__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-8);
}

/* Кнопка «Войти» остаётся видимой, но недоступной: она объясняет, что
   рабочий контур ещё не запущен, а не притворяется рабочей. */
.launch__signin[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.55;
}

.launch__hint {
  margin-top: var(--space-4);
  min-height: 1.4em;
  font-size: var(--text-xs);
  color: var(--color-text-tertiary);
  opacity: 0;
  transition: opacity var(--t-fast);
}

.launch__hint.is-visible { opacity: 1; }

.launch__foot {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border-hairline);
  font-size: var(--text-micro);
  line-height: var(--leading-relaxed);
  color: var(--color-text-tertiary);
}

/* --------------------------------------------------------------------------
   Карточки демо-ролей
   -------------------------------------------------------------------------- */

.launch__back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--text-xs);
  color: var(--color-text-secondary);
  cursor: pointer;
}

.launch__back:hover { color: var(--color-brand); }

.role-cards {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.role-card {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-5);
  text-align: left;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
}

.role-card:hover,
.role-card:focus-visible {
  border-color: var(--color-border-strong);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}

/* Две строки: «имя — должность» и отдельной строкой описание доступа.
   Раскладку задаёт flex, а не отступы у строчных элементов: подписи
   внутри карточки — <span>, и без явного контекста они текли бы одной
   строкой, слипаясь друг с другом. */
.role-card__body {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* Имя и должность стоят на одной строке через заметный горизонтальный
   зазор. Если строка не помещается — должность переносится под имя,
   и это же поведение работает на телефоне. */
.role-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-3);
  /* При переносе должности под имя строки не должны соприкасаться */
  row-gap: 2px;
}

.role-card__name {
  font-size: var(--text-h3);
  font-weight: var(--weight-semibold);
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-snug);
  color: var(--color-text-primary);
}

/* Вторичный уровень: заметно мельче имени, но ещё в основном цвете текста */
.role-card__position {
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
  color: var(--color-text-secondary);
}

/* Третий уровень: описание области доступа не конкурирует с именем */
.role-card__scope {
  font-size: var(--text-2xs);
  line-height: var(--leading-normal);
  color: var(--color-text-tertiary);
}

.role-card__go {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 0 var(--space-4);
  height: 36px;
  white-space: nowrap;
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  color: var(--color-brand);
  background: var(--color-brand-soft);
  border-radius: var(--radius-pill);
}

.role-card:hover .role-card__go { background: var(--color-brand); color: var(--color-text-inverse); }

/* --------------------------------------------------------------------------
   Прелоудер

   Используется и на старте, и при смене роли внутри кабинета: одна разметка,
   разная длительность. Слой сообщает о ходе загрузки через aria-live.
   -------------------------------------------------------------------------- */

.preloader {
  position: fixed;
  inset: 0;
  z-index: 950;
  display: grid;
  place-items: center;
  background: var(--color-background);
  opacity: 1;
  transition: opacity var(--dur-slow) var(--ease-out);
}

.preloader[hidden] { display: none; }
.preloader.is-leaving { opacity: 0; pointer-events: none; }

.preloader__inner {
  width: min(420px, calc(100vw - 3rem));
  text-align: center;
}

.preloader__logo { height: 24px; width: auto; }

/* Тонкая архитектурная линия под знаком */
.preloader__rule {
  width: 100%;
  height: 1px;
  margin: var(--space-7) 0 var(--space-5);
  background: var(--color-border);
  position: relative;
  overflow: hidden;
}

.preloader__rule::after {
  content: '';
  position: absolute;
  inset: 0;
  transform-origin: left center;
  transform: scaleX(0);
  background: var(--color-brand);
  animation: preloader-fill var(--preloader-duration, 2000ms) var(--ease-soft) forwards;
}

@keyframes preloader-fill {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.preloader__caption {
  min-height: 1.4em;
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-normal);
  color: var(--color-text-secondary);
  transition: opacity var(--t-fast);
}

.preloader__caption.is-swapping { opacity: 0; }

.preloader__role {
  margin-top: var(--space-3);
  font-size: var(--text-micro);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--color-text-tertiary);
}

/* --------------------------------------------------------------------------
   Планшет и мобильные
   -------------------------------------------------------------------------- */

@media (max-width: 1024px) {
  .launch { grid-template-columns: 1fr; }

  .launch__media { display: none; }

  .launch__inner {
    align-items: flex-start;
    padding-top: clamp(2rem, 6vh, 4rem);
    padding-bottom: clamp(2rem, 6vh, 4rem);
    /* Экран не обрезается: контент прокручивается внутри слоя */
    min-height: 100%;
  }

  .launch__lines { width: 120vw; opacity: 0.7; }
  .launch__lines--far { width: 150vw; }
}

@media (max-width: 640px) {
  .launch__stage { max-width: none; }

  .launch__actions { flex-direction: column; align-items: stretch; }
  .launch__actions .btn { width: 100%; justify-content: center; }

  .role-card {
    grid-template-columns: auto minmax(0, 1fr);
    padding: var(--space-4);
    gap: var(--space-3);
  }

  .role-card__go {
    grid-column: 1 / -1;
    justify-content: center;
    height: 40px;
  }
}

/* --------------------------------------------------------------------------
   Пониженная подвижность: движение выключается, смысл остаётся
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .launch__wash,
  .launch__lines,
  .launch__lines--far,
  .launch__photo,
  .launch__stage {
    animation: none;
  }

  .launch__photo:nth-of-type(1) { opacity: 1; filter: none; transform: none; }

  .preloader__rule::after { animation-duration: 1ms; transform: scaleX(1); }

  .launch,
  .preloader,
  .preloader__caption { transition: none; }
}
