/* Вход в Nexo.
   ================================================================
   Движение здесь работает, а не украшает. Три правила, из которых
   следует всё остальное:

   1. У всего одна кривая — пружина без отскока. Разные кривые на одном
      экране читаются как разные приложения.
   2. Появление лесенкой: элементы приходят с задержкой в 60 мс друг за
      другом. Одновременное появление выглядит перерисовкой, а не
      открытием.
   3. Шаги двигаются вбок. Направление показывает, куда идёт человек, и
      «назад» становится очевидным без объяснений.

   И всё это выключается при prefers-reduced-motion: анимация, от которой
   человеку плохо, не стоит ни одного вау. */

:root {
  --e-page: #f7f8fc;
  --e-ink: #101014;
  --e-soft: #6b6d78;
  --e-line: rgb(16 16 20 / .09);
  --e-card: rgb(255 255 255 / .82);
  --e-tint: rgb(16 16 20 / .03);
  /* ПОЛЕ, В КОТОРОЕ ПИШУТ ИЛИ КОТОРОЕ ВЫБИРАЮТ.
     Был жёсткий #fff в четырёх местах, и тёмная тема переопределяла три
     из них. Забытым оказалось четвёртое — плитки «что делает клиент»: в
     тёмной теме на белой плитке стоял почти белый текст, контраст 1.10
     при нужных 4.5, то есть выбор был не «блёклым», а невидимым. Ровно
     это владелец и прислал снимком.
     Токен затем и заведён: забыть переопределить его нельзя — он один. */
  --e-solid: #fff;
  --e-spring: cubic-bezier(.2, .9, .25, 1);
  --e-r: 26px;
  color-scheme: light;
}

* , *::before, *::after { box-sizing: border-box; }
html { height: 100%; }
/* Именно min-height: страница должна занимать экран, когда шаг короткий, и
   становиться выше него, когда шаг длинный. Процент считается от высоты
   html — без height: 100% выше он не работает вовсе. */
body { min-height: 100%; margin: 0; }

body.enter {
  /* Шаг с созданием бизнеса выше телефона, и запретить прокрутку значит
     спрятать кнопку «Создать кабинет» под краем экрана — экран, с которого
     нельзя уйти. По горизонтали прокрутки нет: её дало бы только фоновое
     пятно.

     Центрирование сделано полями (`margin: auto` на .enter-main), а не
     `place-items`: выравнивание по центру в переполненном контейнере
     срезает верх — вместе с первым полем формы и кнопкой «назад». */
  display: flex;
  padding: 24px max(18px, env(safe-area-inset-left)) calc(24px + env(safe-area-inset-bottom));
  color: var(--e-ink);
  background: var(--e-page);
  font-family: var(--n-font, -apple-system, BlinkMacSystemFont, "SF Pro Display", system-ui, sans-serif);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  overflow-y: auto;
}

/* ── Фон ──────────────────────────────────────────────────────────
   Три пятна, медленно расходящиеся по своим орбитам. Период у каждого
   свой и некратный соседям — иначе через минуту они сходятся в исходное
   положение, и глаз ловит повтор. */

.enter-wall { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }
.enter-orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(72px);
  opacity: .55;
  will-change: transform;
}
.enter-orb--one {
  top: -18vmin; left: -10vmin; width: 62vmin; height: 62vmin;
  background: radial-gradient(circle at 40% 40%, #2f5bff 0%, rgb(47 91 255 / 0) 70%);
  animation: orb-one 26s var(--e-spring) infinite alternate;
}
.enter-orb--two {
  right: -16vmin; top: 8vmin; width: 54vmin; height: 54vmin;
  background: radial-gradient(circle at 60% 40%, #6a2fd6 0%, rgb(106 47 214 / 0) 70%);
  animation: orb-two 31s var(--e-spring) infinite alternate;
}
.enter-orb--three {
  left: 18vmin; bottom: -22vmin; width: 66vmin; height: 66vmin;
  background: radial-gradient(circle at 50% 50%, #ff6b4a 0%, rgb(255 107 74 / 0) 68%);
  animation: orb-three 37s var(--e-spring) infinite alternate;
}
@keyframes orb-one   { to { transform: translate3d(14vmin, 10vmin, 0) scale(1.15); } }
@keyframes orb-two   { to { transform: translate3d(-12vmin, 16vmin, 0) scale(1.1); } }
@keyframes orb-three { to { transform: translate3d(10vmin, -14vmin, 0) scale(1.18); } }

/* ── Герой ────────────────────────────────────────────────────────
   Знак собирается: сначала прорези закрыты и квадрат сплошной, потом
   они прорезаются, и в знаке проявляется N. Это ровно то, чем он
   является, — и потому не выглядит эффектом ради эффекта. */

.enter-main {
  position: relative; z-index: 1;
  width: min(420px, 100%);
  margin: auto;
  display: grid; gap: 22px;
}
.enter-head { display: grid; justify-items: center; gap: 10px; text-align: center; }

.enter-mark {
  width: 76px; height: 76px;
  filter: drop-shadow(0 14px 30px rgb(47 91 255 / .28));
  animation: mark-in 1.1s var(--e-spring) both;
}
.enter-mark svg { width: 100%; height: 100%; display: block; }
@keyframes mark-in {
  from { opacity: 0; transform: translateY(14px) scale(.82) rotate(-8deg); }
  to   { opacity: 1; transform: none; }
}

/* Прорези «режутся» штрихом: длина линии анимируется от нуля. Пока они
   закрыты, знак — сплошной квадрат; к концу появляется N. */
.enter-slit {
  stroke-dasharray: 62;
  stroke-dashoffset: 62;
  animation: slit 900ms var(--e-spring) 420ms both;
}
.enter-slit--bottom { animation-delay: 560ms; }
@keyframes slit { to { stroke-dashoffset: 0; } }

.enter-title {
  margin: 0;
  font-size: clamp(30px, 8vw, 38px); font-weight: 300; letter-spacing: -.045em;
  animation: rise 700ms var(--e-spring) 240ms both;
}
.enter-sub {
  margin: 0; color: var(--e-soft); font-size: 15px;
  animation: rise 700ms var(--e-spring) 320ms both;
}
@keyframes rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* ── Карточка ─────────────────────────────────────────────────────
   Стекло на цветном фоне: пятна просвечивают, но текст остаётся на
   белом. Карточка — единственная плоскость, на которой читают. */

.enter-card {
  position: relative;
  padding: 22px 20px 18px;
  border-radius: var(--e-r);
  background: var(--e-card);
  box-shadow:
    0 1px 0 rgb(255 255 255 / .9) inset,
    0 10px 24px rgb(16 16 20 / .07),
    0 40px 80px -40px rgb(16 16 20 / .32);
  backdrop-filter: saturate(1.7) blur(24px);
  -webkit-backdrop-filter: saturate(1.7) blur(24px);
  overflow: hidden;
  animation: rise 800ms var(--e-spring) 400ms both;
  transition: height 420ms var(--e-spring);
}

/* Шаги лежат стопкой и сдвигаются вбок: вперёд — влево, назад — вправо.
   Так человек видит направление и не ищет кнопку «назад» глазами. */
.enter-step {
  display: grid; gap: 14px;
  opacity: 0;
  transform: translateX(24px);
  transition: opacity 300ms var(--e-spring), transform 420ms var(--e-spring);
  pointer-events: none;
}
.enter-step:not(.is-on) { position: absolute; inset: 22px 20px auto; }
.enter-step.is-on { opacity: 1; transform: none; pointer-events: auto; position: relative; }
.enter-step.is-left { transform: translateX(-24px); }

.enter-toggle {
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px;
  padding: 4px; border-radius: 999px; background: rgb(16 16 20 / .05);
}
.enter-toggle button {
  min-height: 38px; border: 0; border-radius: 999px; background: transparent;
  color: var(--e-soft); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer;
  transition: transform 220ms var(--e-spring), background 200ms ease, color 200ms ease;
}
.enter-toggle button.is-on {
  background: #fff; color: var(--e-ink);
  box-shadow: 0 2px 8px rgb(16 16 20 / .1);
}
.enter-toggle button:active { transform: scale(.97); }

/* ЧАСЫ РАБОТЫ — ВЫБОРОМ, А НЕ ТЕКСТОМ.
   Замер: из 174 бизнесов свои часы при регистрации назвали 34 — это
   самое редко заполняемое поле формы и единственное, без которого нельзя
   принять ни одной записи. Кнопки переносятся строкой: названий пять, и
   горизонтальной прокрутки в форме регистрации быть не должно. */
.hours-pick { display: flex; flex-wrap: wrap; gap: 8px; }
.hours-pick button {
  flex: 1 1 45%; min-width: 140px;
  appearance: none; border: none; cursor: pointer; font: inherit;
  font-size: 14px; font-weight: 500; padding: 11px 12px;
  border-radius: 12px; text-align: center;
  color: var(--e-ink, #18181b);
  background: color-mix(in srgb, currentColor 8%, transparent);
}
.hours-pick button.on { color: #fff; background: var(--e-ink, #18181b); }
.hours-pick button:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.enter-field { display: grid; gap: 7px; }
.enter-field > span { color: var(--e-soft); font-size: 13px; font-weight: 500; }
/* ВЫБОР — НЕ ПОЛЕ ВВОДА.
   Правило ниже красит ЛЮБОЙ input в наборе: белое поле во всю ширину,
   высотой 52 пикселя, со скруглением. Радио-кнопке это дало белый
   прямоугольник во весь экран с чёрной точкой внутри, а подпись выехала
   за край — так выглядела форма создания кабинета на живом сайте.
   Поэтому правило прямо говорит, к чему оно НЕ относится. */
.enter-field input:not([type="radio"]):not([type="checkbox"]) {
  width: 100%; min-height: 52px;
  border: 0; border-radius: 16px; padding: 0 16px;
  background: var(--e-solid); box-shadow: inset 0 0 0 1px var(--e-line);
  color: var(--e-ink); font: inherit; font-size: 17px;
  transition: box-shadow 220ms var(--e-spring), transform 220ms var(--e-spring);
}
.enter-field input:not([type="radio"]):not([type="checkbox"]):focus {
  outline: 0;
  box-shadow: inset 0 0 0 2px var(--e-ink);
}
.enter-caption { margin: -4px 0 0; color: var(--e-soft); font-size: 13px; line-height: 1.4; }
.enter-code-head { display: grid; gap: 5px; }
.enter-code-head h2 { margin: 0; font-size: 23px; letter-spacing: -.035em; }
.enter-code-head p { margin: 0; color: var(--e-soft); font-size: 14px; line-height: 1.35; overflow-wrap: anywhere; }
.enter-code-head strong { color: var(--e-ink); font-weight: 600; }
.enter-field input.enter-code {
  padding-left: .24em; text-align: center; letter-spacing: .32em;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 24px; font-weight: 700;
}
.enter-field select {
  width: 100%; min-height: 52px;
  border: 0; border-radius: 16px; padding: 0 42px 0 16px;
  appearance: none;
  background: var(--e-solid) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='m1 1 6 6 6-6' fill='none' stroke='%236b6d78' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E") calc(100% - 17px) center/14px 9px no-repeat;
  box-shadow: inset 0 0 0 1px var(--e-line);
  color: var(--e-ink); font: inherit; font-size: 16px;
}
.enter-field select:focus { outline: 0; box-shadow: inset 0 0 0 2px var(--e-ink); }
/* Прайс вставляют целиком, поэтому поле сразу многострочное: одна строка
   заставила бы человека набирать услуги по одной, а именно этого шага он и
   не сделает. */
.enter-field textarea {
  width: 100%; min-height: 104px; resize: vertical;
  border: 0; border-radius: 16px; padding: 14px 16px;
  background: var(--e-solid); box-shadow: inset 0 0 0 1px var(--e-line);
  color: var(--e-ink); font: inherit; font-size: 16px; line-height: 1.4;
  transition: box-shadow 220ms var(--e-spring);
}
.enter-field textarea:focus { outline: 0; box-shadow: inset 0 0 0 2px var(--e-ink); }
.enter-field small { color: var(--e-soft); font-size: 11px; font-weight: 400; }
.enter-business-head { display: grid; gap: 5px; }
.enter-business-head h2 { margin: 0; font-size: 23px; letter-spacing: -.035em; }
.enter-business-head p { margin: 0; color: var(--e-soft); font-size: 14px; line-height: 1.35; }
.enter-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }

.enter-go {
  min-height: 52px; border: 0; border-radius: 16px;
  background: var(--e-ink); color: #fff;
  font: inherit; font-size: 16px; font-weight: 600; letter-spacing: -.01em; cursor: pointer;
  transition: transform 260ms var(--e-spring), opacity 200ms ease;
}
.enter-go:active { transform: scale(.98); }
.enter-go[disabled] { opacity: .5; cursor: default; }

.enter-back, .enter-swap {
  justify-self: start;
  border: 0; padding: 4px 0; background: none;
  color: var(--e-soft); font: inherit; font-size: 14px; cursor: pointer;
}
.enter-back { font-weight: 500; }
.enter-swap { justify-self: center; }
.enter-back:hover, .enter-swap:hover { color: var(--e-ink); }

.enter-consent {
  display: flex; gap: 9px; align-items: flex-start;
  color: var(--e-soft); font-size: 12.5px; line-height: 1.4;
}
.enter-consent a { color: var(--e-ink); }

.enter-note { margin: 0; min-height: 18px; color: var(--e-soft); font-size: 13px; line-height: 1.4; }
.enter-note.err { color: #ac2b41; }

/* Ошибка вздрагивает один раз и коротко. Красная рамка без движения
   замечается не всегда, а трясущееся полминуты поле раздражает. */
.enter-shake { animation: shake 420ms var(--e-spring); }
@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  30%, 70% { transform: translateX(4px); }
  50%      { transform: translateX(-4px); }
}

/* ── Готово ───────────────────────────────────────────────────────
   Галочка рисуется, а не появляется: линия, которую провели, читается
   как завершённое действие. */
.enter-done { justify-items: center; text-align: center; padding: 10px 0 4px; }
.enter-done h2 { margin: 0; font-size: 22px; font-weight: 600; letter-spacing: -.03em; }
.enter-done p { margin: 0; color: var(--e-soft); font-size: 14px; }
.enter-tick {
  width: 54px; height: 54px; border-radius: 50%;
  background: linear-gradient(140deg, #2f5bff, #6a2fd6);
  box-shadow: 0 12px 26px rgb(47 91 255 / .3);
  position: relative;
}
.enter-tick::after {
  content: ""; position: absolute; left: 18px; top: 15px;
  width: 12px; height: 22px;
  border: solid #fff; border-width: 0 3px 3px 0;
  transform: rotate(45deg) scale(0);
  transform-origin: center;
  animation: tick 520ms var(--e-spring) 120ms forwards;
}
@keyframes tick { to { transform: rotate(45deg) scale(1); } }

/* Разобранный прайс. Строки проявляются по одной сверху вниз — в том же
   порядке, в каком их читали, — и человек видит работу, а не итог из
   ниоткуда. Задержка своя у каждой: их не больше восьми. */
.enter-understood {
  display: grid; gap: 6px; margin: 4px 0 0; padding: 0; list-style: none;
  justify-items: center; text-align: center;
}
.enter-understood li {
  color: var(--e-ink); font-size: 14px; line-height: 1.35;
  opacity: 0; transform: translateY(6px);
  animation: rise 520ms var(--e-spring) both;
}
.enter-understood li:nth-child(1) { animation-delay: 260ms; }
.enter-understood li:nth-child(2) { animation-delay: 340ms; }
.enter-understood li:nth-child(3) { animation-delay: 420ms; }
.enter-understood li:nth-child(4) { animation-delay: 500ms; }
.enter-understood li:nth-child(5) { animation-delay: 580ms; }
.enter-understood li:nth-child(6) { animation-delay: 660ms; }
.enter-understood li:nth-child(7) { animation-delay: 740ms; }
.enter-understood li:nth-child(8) { animation-delay: 820ms; }

.enter-foot {
  display: flex; gap: 10px; justify-content: center;
  color: var(--e-soft); font-size: 13px;
  animation: rise 700ms var(--e-spring) 520ms both;
}
.enter-foot a { color: var(--e-soft); text-decoration: none; }
.enter-foot a:hover { color: var(--e-ink); }

/* ── Тёмная тема ──────────────────────────────────────────────────
   Ночью белый экран в лицо — это не «стильно», а больно. */
@media (prefers-color-scheme: dark) {
  :root {
    --e-page: #0b0b0f;
    --e-ink: #f4f4f7;
    --e-soft: #9a9ba6;
    --e-line: rgb(255 255 255 / .12);
    --e-card: rgb(28 28 34 / .72);
    --e-tint: rgb(255 255 255 / .05);
    --e-solid: rgb(255 255 255 / .06);
    color-scheme: dark;
  }
  .enter-card {
    box-shadow:
      0 1px 0 rgb(255 255 255 / .06) inset,
      0 10px 24px rgb(0 0 0 / .4),
      0 40px 80px -40px rgb(0 0 0 / .8);
  }
  /* Поля берут тот же токен, что и плитки выбора: отдельное правило
     здесь и было тем местом, где про плитки забыли. */
  .enter-toggle { background: rgb(255 255 255 / .07); }
  .enter-toggle button.is-on { background: rgb(255 255 255 / .14); }
  .enter-go { background: #fff; color: #101014; }
  .enter-orb { opacity: .42; }
}

@media (max-width: 390px) {
  .enter-pair { grid-template-columns: 1fr; }
}

/* ── Движение, от которого не тошнит ──────────────────────────────
   Обещание, а не оговорка: при этом флаге не остаётся ни одной
   анимации, включая фоновые пятна, — они самые заметные. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    /* Без сброса задержки строки разбора всё равно выступали бы по
       очереди — то самое движение, от которого человек и отказался. */
    animation-delay: 0ms !important;
    transition-duration: .01ms !important;
  }
  .enter-orb { animation: none; }
  .enter-slit { stroke-dashoffset: 0; }
}

/* Выход с экрана «Ваш бизнес». Тихая строка, а не вторая кнопка: главное
   действие здесь одно, а это — дверь для того, кто пришёл не туда. */
.enter-quiet{display:block;width:100%;margin:14px 0 0;padding:10px;border:0;
  background:none;color:var(--e-soft,rgba(255,255,255,.55));font:inherit;
  font-size:14px;cursor:pointer;text-decoration:underline;
  text-underline-offset:3px}
.enter-quiet:hover{color:inherit}

/* РАЗВИЛКА НА ЭКРАНЕ СОЗДАНИЯ.
   Тихой строкой её здесь мало: человек с обрезанной ссылкой уже прошёл
   мимо такой же на первом шаге и дошёл до формы, которая выглядит как
   единственный путь. Рамка и отступ поднимают её из фона ровно настолько,
   чтобы прочитать до того, как начнёшь заполнять поля, — но она остаётся
   подсказкой, а не вторым главным действием. */
.enter-fork{margin:0 0 4px;padding:12px 14px;border-radius:12px;
  border:1px solid var(--e-line,rgba(255,255,255,.14));
  background:var(--e-tint)}
.enter-fork p{margin:0;color:var(--e-soft);font-size:13px;line-height:1.4}
.enter-fork .enter-quiet{margin:6px 0 0;padding:4px 0;text-align:left;
  width:auto;color:inherit}

/* ── ЧТО ДЕЛАЕТ КЛИЕНТ НА ВИТРИНЕ ─────────────────────────────────────
   Два ответа, и оба видны сразу: выпадающим списком этот вопрос задавать
   нельзя — половина людей не открывает список и оставляет первое
   значение, не прочитав второго. А второе для части мастеров и есть
   причина остаться: они договариваются лично, и продукт, требующий
   расписание, для них «не про меня». */
.enter-mode { display: grid; gap: 9px; border: 0; padding: 0; margin: 0; }
.enter-mode > legend {
  padding: 0; margin-bottom: 2px;
  color: var(--e-soft); font-size: 13px; font-weight: 500;
}
.enter-radio {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 13px 15px; border-radius: 16px; cursor: pointer;
  background: var(--e-solid); box-shadow: inset 0 0 0 1px var(--e-line);
  transition: box-shadow 220ms var(--e-spring);
}
.enter-radio:has(input:checked) { box-shadow: inset 0 0 0 2px var(--e-ink); }
.enter-radio input { flex: 0 0 auto; margin-top: 3px; accent-color: var(--e-ink); }
.enter-radio > span { display: grid; gap: 2px; }
.enter-radio b { font-size: 15px; font-weight: 600; }
.enter-radio small { color: var(--e-soft); font-size: 13px; line-height: 1.35; }

/* ── КАБИНЕТ, КОТОРЫЙ У ЧЕЛОВЕКА УЖЕ БЫЛ ──────────────────────────────
   Развилка стоит ДО формы: раньше человек заполнял её целиком и узнавал
   о своём кабинете только отказом при отправке. Половина на этом заводила
   пустышку-двойник, а настоящий салон с услугами и клиентами оставался
   стоять ничей. */
/* Та же ошибка, что и у плиток выбора: белая карточка без
   переопределения в тёмной теме. Разбор по всему файлу нашёл её рядом —
   в тёмной теме здесь стоял почти белый текст на белом, и человек,
   у которого УЖЕ есть кабинет, не видел об этом ни слова. */
.enter-had { display: grid; gap: 10px; padding: 18px; border-radius: 20px;
  background: var(--e-solid); box-shadow: inset 0 0 0 1px var(--e-line); }
.enter-had-t { margin: 0; font-size: 17px; font-weight: 600; }
.enter-had-t b { font-weight: 700; }
.enter-had-s { margin: 0; color: var(--e-soft); font-size: 14px; line-height: 1.4; }
.enter-had .enter-go { margin-top: 4px; text-align: center; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center; }

/* ВХОД ЧЕРЕЗ TELEGRAM И РАЗДЕЛИТЕЛЬ «ИЛИ».
   Ссылка, а не кнопка: она уводит в мессенджер. Выглядеть при этом
   обязана ровно как кнопка рядом — иначе читается как второстепенная,
   хотя это самый короткий путь из всех. */
a.enter-go.tg {
  display: flex; align-items: center; justify-content: center;
  text-decoration: none; text-align: center;
}
.enter-or {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  gap: 10px; margin: 2px 0; color: var(--e-soft); font-size: 13px;
}
.enter-or::before, .enter-or::after {
  content: ""; height: 1px; background: currentColor; opacity: .22;
}
