/* «Зимняя школа» — schools.mipt.ru/winter и корень winter.mipt.ru.

   Палитра и шкала из UI Kit макета: три яруса — 1600 / 768 / 360, пороги
   те же, что у главной (1100 и 720), чтобы страницы не разъезжались на
   промежуточных ширинах. */

:root {
    --bg: #d9f2ff;
    --alice: #eaf4fc;
    --light: #f4f8ff;
    --text: #0072c3;
    --second: #005ea8;
    --deep: #0b3e81;
    --dark: #052043;
    --sky: #57a5db;
    --baby: #b7e3ff;
    --turquoise: #4fbfad;
    --soft-70: rgba(127, 201, 255, 0.7);
    --steel-45: rgba(69, 138, 188, 0.45);
    --pastel-75: rgba(194, 215, 230, 0.75);
    --main: #0069b4;
    --orange: #ee6e5b;
    --btn-blue: #dcecf8;
    --very-dark: #002138;
    /* Подложка липкой шапки: тот же --bg, но сквозь него виден скролл. */
    --bg-88: rgba(217, 242, 255, 0.88);
    --white-20: rgba(255, 255, 255, 0.2);
    --white-40: rgba(255, 255, 255, 0.4);
    --white-60: rgba(255, 255, 255, 0.6);
    /* Единственный градиент кита: выделенный тариф и водяные заголовки. */
    --gradient: linear-gradient(232.72deg, #1c9ffe 0%, #1f67b0 104.12%);
}

* { box-sizing: border-box; }

/* Якорь останавливается ниже шапки, иначе заголовок раздела оказывается
   под ней ровно тогда, когда по ссылке к нему и пришли. */
html { scroll-behavior: smooth; scroll-padding-top: 120px; }

body {
    margin: 0;
    background: var(--bg);
    color: var(--text);
    font-family: 'Montserrat', 'Segoe UI', Arial, sans-serif;
    font-size: 18px;
    line-height: 1.3;
    letter-spacing: -0.03em;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: inherit; text-decoration: none; }

button { font: inherit; letter-spacing: inherit; color: inherit; }

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.wrap { max-width: 1520px; margin: 0 auto; padding: 0 40px; }

@media (max-width: 1100px) { .wrap { padding: 0 24px; } }
@media (max-width: 720px) { .wrap { padding: 0 10px; } }

/* ---------- типографика из кита ---------- */

.h2 { font-size: clamp(30px, 3vw, 45px); font-weight: 500; line-height: 1; margin: 0; }
.h3 { font-size: clamp(25px, 2.6vw, 40px); font-weight: 500; line-height: 1; margin: 0; }
.h4 { font-size: clamp(20px, 2.3vw, 35px); font-weight: 500; line-height: 1; margin: 0; }
.h5 { font-size: 20px; font-weight: 500; line-height: 1.2; margin: 0; }
.text-1 { font-size: 25px; font-weight: 500; line-height: 1; }
.text-2 { font-size: 18px; font-weight: 400; line-height: 1.3; }
.descriptor { font-size: 20px; font-weight: 500; line-height: 1.2; margin: 0; }
.tag { font-size: 14px; font-weight: 500; line-height: 1.2; margin: 0; }

/* Ярусы 768 и 360 из своих китов: clamp() по vw давал промежуточные размеры,
   которых в макете нет. */
@media (max-width: 1100px) {
    .hero-title { font-size: 115px; }
    .h2 { font-size: 30px; }
    .h3 { font-size: 25px; }
    .h4 { font-size: 20px; line-height: 1.2; }
    .h5 { font-size: 16px; }
    .text-1 { font-size: 18px; }
    .text-2 { font-size: 14px; line-height: 1.2; }
    .descriptor { font-size: 14px; }
}

@media (max-width: 720px) {
    .hero-title { font-size: 54px; }
    .h2 { font-size: 25px; }
}

/* Зазор между секциями — 180 из макета, он там одинаковый по всей странице. */
.section { padding-top: 180px; }
.section-title { text-align: center; }

/* «Программа» идёт вплотную за горами: у макета отступ считался от сплошной
   россыпи, а у нас она внизу растворяется — при общих 180 пикселях между
   последними точками и заголовком зияет пустая полоса. */
.section.program { padding-top: 60px; }

@media (max-width: 1100px) {
    .section { padding-top: 80px; }
    .section.program { padding-top: 30px; }
}

@media (max-width: 720px) {
    .section { padding-top: 60px; }
    .section.program { padding-top: 20px; }
}

/* Пунктирная линейка-разделитель. Градиент, а не dotted-рамка: у рамки шаг
   точек задаёт браузер, и он разный в Safari и Chrome. */
.rule {
    height: 1px;
    margin: 26px 0 20px;
    background: repeating-linear-gradient(to right, var(--sky) 0 2px, transparent 2px 8px);
}

/* ---------- кнопки ---------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    border: 0;
    border-radius: 12px;
    background: var(--orange);
    color: #fff;
    font-size: 18px;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background 0.15s;
}

.btn:hover { background: #e35c48; }

.btn--ghost { background: var(--btn-blue); color: var(--second); }
.btn--ghost:hover { background: #cbe2f4; }

@media (max-width: 1100px) { .btn { font-size: 14px; padding: 16px 20px; } }
/* В ките 360 кнопка выше десктопной по полям: 57 пикселей при мелком кегле. */
@media (max-width: 720px) { .btn { padding: 20px; } }

.round-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: 50px;
    height: 50px;
    padding: 8px;
    border: 0;
    border-radius: 100px;
    background: #fff;
    cursor: pointer;
}

/* Шеврон нарисован «влево», поэтому +90° — это вверх. Направления как в
   макете: у свёрнутой карточки он смотрит вверх, у раскрытой — вниз. */
.round-btn img { transform: rotate(90deg); transition: transform 0.2s; }
.subject.is-open .round-btn img { transform: rotate(-90deg); }

.arrow {
    flex: none;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

/* Стрелка одна на все карусели: влево и вправо — её же повороты, как и в
   макете, где это два состояния одного компонента. */
.arrow img { width: 50px; height: 50px; }
.arrow--sm img { width: 40px; height: 40px; }
.arrow--prev img { transform: rotate(-90deg); }
.arrow--next img { transform: rotate(90deg); }
.arrow[disabled] { opacity: 0.35; cursor: default; }

.carousel-arrows { display: flex; gap: 6px; }

.dots { display: flex; gap: 0; justify-content: center; padding-top: 16px; }

.dots button {
    width: 18px;
    height: 28px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.dots span {
    display: block;
    width: 8px;
    height: 8px;
    margin: 10px auto;
    border-radius: 100px;
    background: var(--main);
}

.dots .is-active span { background: var(--orange); }

/* ---------- шапка ---------- */

/* Шапка едет со страницей: «Подать заявку» нужна на любом экране, а не
   только на первом. fixed, а не sticky: первый экран рассчитан на шапку
   поверх снимка, и вставь её в поток — герой съедет вниз на её высоту. */
.header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
    /* 20px, а не 25: с ними шапка ровно 102 пикселя, как на schools.mipt.ru, и
       логотип стоит на той же высоте. Переход с главной на страницу школы не
       должен дёргать шапку. */
    padding: 20px 0;
    transition: background-color 0.2s, box-shadow 0.2s;
}

/* Подложка появляется только после прокрутки: на первом экране шапка лежит
   прямо на точках фона, а над снимками и текстом прозрачная не читается.
   Открытое меню — тот же случай: под ним страница, а не фон героя. */
.header.is-stuck,
.header.is-open {
    background: var(--bg-88);
    backdrop-filter: blur(10px);
    box-shadow: 0 1px 0 var(--pastel-75);
}

.header > .wrap { display: flex; align-items: center; gap: 20px; }

.brand {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 25px;
    font-weight: 600;
    line-height: 1.2;
}

.brand img { width: 49px; height: 54px; }

.nav {
    display: flex;
    align-items: center;
    gap: 20px;
    margin: 0 auto;
    font-size: 20px;
    font-weight: 500;
    line-height: 1.2;
}

.nav > a, .nav-schools > a { padding-bottom: 10px; }

.nav-schools { position: relative; }
.nav-schools > a { display: flex; align-items: center; gap: 2px; }
/* Стрелка нарисована «вправо» и в макете повёрнута: держим её так же, иначе
   пункт меню читается как «Наши школы >». */
.nav-schools > a img { width: 12px; height: 24px; transform: rotate(90deg); }

.nav-schools-menu {
    position: absolute;
    top: 100%;
    left: 0;
    display: none;
    flex-direction: column;
    gap: 10px;
    padding: 16px 20px;
    border-radius: 12px;
    background: #fff;
    box-shadow: 0 12px 30px rgba(5, 32, 67, 0.15);
    white-space: nowrap;
}

.nav-schools:hover .nav-schools-menu, .nav-schools:focus-within .nav-schools-menu { display: flex; }

.burger {
    display: none;
    flex-direction: column;
    justify-content: space-between;
    width: 24px;
    height: 16px;
    padding: 0;
    border: 0;
    background: none;
    cursor: pointer;
}

.burger span { display: block; height: 2px; border-radius: 2px; background: var(--text); }

.mobile-menu {
    display: none;
    padding: 20px 0 24px;
}

.mobile-menu ul { display: flex; flex-direction: column; gap: 14px; margin: 0 0 20px; padding: 0; list-style: none; }
.mobile-menu .btn { width: 100%; }

.header.is-open .mobile-menu { display: block; background: var(--alice); }

@media (max-width: 1100px) {
    html { scroll-padding-top: 70px; }
    .header { padding: 10px 0; }
    .nav, .header > .wrap > .btn { display: none; }
    /* Вправо бургер отжимала навигация своим margin: 0 auto. Её тут нет, и
       без собственного отступа кнопка липла к логотипу, а половина шапки
       стояла пустой. */
    .burger { display: flex; margin-left: auto; }
    .brand { font-size: 18px; }
    .brand img { width: 32px; height: 35px; }
    .nav { margin: 0; }
}

@media (max-width: 720px) {
    .brand { font-size: 16px; }
}

/* ---------- первый экран ---------- */

.hero { position: relative; padding: 279px 0 35px; }

.hero-bg {
    position: absolute;
    inset: 0;
    background: url('img/hero-mountains.webp') no-repeat center bottom / cover;
}

.hero .wrap { position: relative; }

.hero-title { font-size: clamp(54px, 14.4vw, 230px); font-weight: 700; line-height: 0.77; text-transform: uppercase; margin: 0; }
.hero-title__line { display: flex; align-items: center; gap: 0; }

/* Кадр стоит на месте первого слога «школы»: в макете он ровно той ширины,
   с которой начинается слово, поэтому размеры заданы в em и держатся сами. */
.hero-photo {
    flex: none;
    width: 2.12em;
    height: 0.69em;
    border-radius: 0.06em;
    object-fit: cover;
}

.hero-meta {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 30px;
    margin-top: 26px;
    padding-top: 30px;
    border-top: 1px dotted var(--sky);
}

.hero-facts {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.hero-facts li { display: flex; align-items: center; gap: 5px; }

.hero-facts li::before {
    content: '';
    flex: none;
    width: 8px;
    height: 8px;
    border-radius: 100px;
    background: var(--text);
}

.hero-pitch {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 25px;
    padding-left: 30px;
    border-left: 1px dotted var(--sky);
}

.hero-pitch .btn { width: 374px; max-width: 100%; }

@media (max-width: 1100px) {
    .hero { padding: 200px 0 30px; }
    .hero-facts li::before { width: 6px; height: 6px; }
    .hero-pitch .btn { width: 350px; }
    /* Своя ступень: в ките 768 и 360 подзаголовок героя мельче, чем H4. */
    .hero-pitch p { font-size: 18px; }
}

@media (max-width: 720px) {
    .hero { padding: 333px 0 24px; }
    .hero-meta { margin-top: 18px; padding-top: 12px; gap: 0 12px; }
    .hero-pitch { padding-left: 12px; gap: 16px; }
    .hero-pitch .btn { width: 100%; }
    .hero-facts { font-size: 14px; }
    .hero-facts li { align-items: flex-start; }
    .hero-facts li::before { margin-top: 5px; }
    .hero-pitch p { font-size: 14px; }

    /* На узком экране кнопка уезжает под обе колонки: в макете она во всю
       ширину, а не в правой половине. Считаем от колонки: 38px — это поле с
       линейкой у каждой из двух (12+1) и зазор между ними. max-width снимаем:
       он остался от десктопных 374px и обрезал бы растяжку обратно. */
    .hero-pitch .btn { position: relative; left: calc(-100% - 38px); width: calc(200% + 38px); max-width: none; }
}

/* ---------- о школе ---------- */

/* Секция ровно той высоты, что в макете: текст сверху, под ним 474 из 1600
   ширины — горы. Проценты снизу, потому что они считаются от ширины и
   держат пропорцию на любом экране. */
.intro { position: relative; padding: 180px 0 29.6%; }

/* Не прячем переполнение: затухающий хвост гор нарочно свисает ниже секции.
   По горизонтали слои ровно по её ширине, так что прятать нечего. */
.intro-bg { position: absolute; inset: 0; pointer-events: none; }

/* Поле точек встаёт на место картинок, когда скрипт их разобрал. До этого
   момента — и навсегда при выключенном JS — видны сами картинки. */
/* Каждый слой — своя канва, прижатая к низу секции: так параллакс делается
   сдвигом канвы, без пересчёта точек на каждый кадр прокрутки. */
.intro-bg__canvas { position: absolute; left: 0; bottom: 0; will-change: transform; }
.intro-bg.is-live .intro-bg__back,
.intro-bg.is-live .intro-bg__front { display: none; }

/* Два слоя гор, оба прижаты к низу секции — как в макете.

   Вектором: выгрузка из Figma весит 7,5 МБ на слой, потому что плагин
   пиксель-арта выдаёт каждую точку отдельным кругом из четырёх дуг и своей
   копией одного и того же градиента. Мы оставили круги кругами, градиент —
   один на слой, и обрезали по кадру макета: вышло 235 и 249 КБ, а по сети,
   сжатыми, — по два десятка. */
.intro-bg__back,
.intro-bg__front {
    position: absolute;
    left: 0;
    bottom: 0;
    display: block;
    width: 100%;
    background-repeat: no-repeat;
    background-size: 100% 100%;
    /* Низ растворяется: кадр обрывает россыпь на полутоне, и ровный срез
       читается как край картинки. В макете точки сходят на нет — здесь то же,
       только прозрачностью. */
    mask-image: linear-gradient(to bottom, #000 78%, transparent);
}

.intro-bg__back {
    aspect-ratio: 1600 / 709;
    background-image: url('img/intro-mountains-back.svg');
}

.intro-bg__front {
    aspect-ratio: 1600 / 575;
    background-image: url('img/intro-mountains-front.svg');
}

/* На узком экране макет берёт то же полотно, но приближает его: точки те же
   самые, только кадр вдвое уже, и слои разъезжаются — задний уходит вправо,
   передний влево. Растяни сюда широкие — и от гор осталась бы сплюснутая
   полоса, поэтому кадр вырезан заранее: те же круги широкого слоя, отобраны
   по окну макета и подписаны своим viewBox. */
/* Кадры макета — 381 и 317 пикселей высотой, но россыпь в выгрузке кончается
   раньше: у широких слоёв свой низ, ниже него точек просто нет. Поэтому слой
   ровно по россыпи и приподнят на разницу — иначе внутри него оставался бы
   ровный срез, который маска не достаёт. Передний вдобавок не доходит до низа
   секции 13 пикселей, как в макете. */
@media (max-width: 720px) {
    /* Россыпь обрывается там, где кончилась выгрузка, и на этой высоте она
       ещё густая: узкой маски не хватало — низ гор упирался в ровную черту.
       Растворяем длинно, до нуля ровно на срезе. Задний слой кончается на 28
       пикселей ниже переднего, поэтому гаснет позже и тянет хвост за него. */
    .intro-bg__back { mask-image: linear-gradient(to bottom, #000 88%, transparent); }
    .intro-bg__front { mask-image: linear-gradient(to bottom, #000 78%, transparent); }

    /* Подъём — долей, а не пикселями: высота слоя считается от ширины блока,
       и на экране шире 360 фиксированный отступ отстал бы от неё. Проценты в
       отступе абсолютного блока тоже считаются от ширины, поэтому едут вместе.
       60 и 88 из макета — это 16.6667% и 24.4444% его 360 пикселей. */
    .intro-bg__back {
        aspect-ratio: 360 / 321;
        margin-bottom: 16.6667%;
        background-image: url('img/intro-mountains-back-narrow.svg');
    }

    .intro-bg__front {
        aspect-ratio: 360 / 242;
        margin-bottom: 24.4444%;
        background-image: url('img/intro-mountains-front-narrow.svg');
    }
}


.intro .wrap { position: relative; text-align: center; }
.intro .h2 { max-width: 1040px; margin: 0 auto; }

.intro-text {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 699px;
    margin: 20px auto 0;
}

.intro-text p { margin: 0; }

/* Чем уже экран, тем больше места под текстом занимают горы — доли из
   макетов 768 и 360. */
@media (max-width: 1100px) { .intro { padding: 100px 0 40%; } }
/* На узком экране горы крупнее и занимают под текстом 344 из 360 ширины —
   доля из макета. */
@media (max-width: 720px) {
    .intro { padding: 60px 0 96%; }
    .intro-text { margin-top: 10px; }
}

/* ---------- программа ---------- */

.program-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; align-items: start; }

.subject {
    display: flex;
    flex-direction: column;
    gap: 28px;
    padding: 20px;
    border: 1px solid var(--white-20);
    border-radius: 18px;
    background: var(--deep);
    color: #fff;
}

.subject__head { display: flex; align-items: center; justify-content: space-between; gap: 20px; margin: 0; font-weight: 500; }
.subject__body { display: flex; flex-direction: column; gap: 10px; }
.subject:not(.is-open) .subject__body { display: none; }

.topic { border-radius: 12px; background: var(--second); overflow: hidden; }

.topic__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    width: 100%;
    min-height: 80px;
    padding: 15px;
    border: 0;
    background: none;
    color: #fff;
    text-align: left;
    cursor: pointer;
}

.topic__sign { flex: none; }
.topic__sign img { width: 40px; height: 40px; }
.topic__minus, .topic.is-open .topic__plus { display: none; }
.topic.is-open .topic__minus { display: block; }
.topic.is-open { background: var(--turquoise); }

.topic__list {
    display: none;
    flex-direction: column;
    gap: 5px;
    margin: 0;
    padding: 0 15px 15px;
    list-style: none;
}

.topic.is-open .topic__list { display: flex; }

.topic__list li { display: flex; align-items: baseline; gap: 5px; }

.topic__list li::before {
    content: '';
    flex: none;
    width: 5px;
    height: 5px;
    border-radius: 100px;
    background: #fff;
}

@media (max-width: 1100px) {
    .program-grid { grid-template-columns: 1fr; }
    .subject { gap: 20px; }
    .topic__head { min-height: 60px; }
    .topic__sign img { width: 30px; height: 30px; }
}

/* ---------- карусели ---------- */

.carousel-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
/* min-width: 0 — чтобы заголовок переносился, а не распирал строку: без него
   флекс не даёт ему стать уже самого длинного слова, и стрелки уезжают за
   край экрана. */
.carousel-head .section-title { flex: 1; min-width: 0; }

/* Заголовок по центру всей строки, а не остатка слева от стрелок: там он
   съезжал влево на половину их ширины. Боковые колонки равны, стрелки встают
   в правую. На узких экранах стрелки и так уходят под заголовок. */
@media (min-width: 1101px) {
    .carousel-head { display: grid; grid-template-columns: 1fr auto 1fr; }
    .carousel-head .section-title { grid-column: 2; }
    .carousel-head .carousel-arrows { grid-column: 3; justify-self: end; }
}

.carousel { margin-top: 25px; }

.carousel__track {
    display: flex;
    gap: 24px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    scroll-behavior: smooth;
}

.carousel__track::-webkit-scrollbar { display: none; }
.carousel__track > * { scroll-snap-align: start; }

/* На узких экранах стрелки уходят под заголовок и расходятся по краям —
   как в макетах 768 и 360. */
@media (max-width: 1100px) {
    .carousel__track { gap: 10px; }
    /* stretch: с flex-start заголовок в колонке сжимался до своего текста и
       прижимался влево, мимо центровки остальных заголовков. */
    .carousel-head { flex-direction: column; align-items: stretch; gap: 20px; }
    .carousel-head .carousel-arrows { width: 100%; justify-content: space-between; }
}

/* ---------- преподаватели ---------- */

.teacher {
    display: flex;
    flex: none;
    flex-direction: column;
    gap: 20px;
    width: 464px;
    padding: 20px;
    border: 1px solid var(--white-20);
    border-radius: 18px;
    background: var(--second);
    color: #fff;
}

.teacher__photo { width: 100%; height: auto; }
.teacher p { margin: 0; }

@media (max-width: 1100px) { .teacher { width: 353px; gap: 12px; padding: 16px; } }
@media (max-width: 720px) { .teacher { width: 100%; } }

/* ---------- распорядок дня ---------- */

/* Водяной заголовок шире секции и обязан обрезаться ею: иначе он растягивает
   страницу и на телефоне появляется горизонтальная прокрутка. */
.schedule, .tariffs { position: relative; overflow: hidden; }

/* Водяной заголовок: в макете он крупнее секции и обрезан её краями. */
.watermark {
    position: absolute;
    top: 90px;
    left: 50%;
    transform: translateX(-50%);
    margin: 0;
    font-size: clamp(62px, 16.3vw, 260px);
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    background: linear-gradient(180deg, rgba(48, 158, 237, 0.2) 45%, rgba(217, 242, 255, 0.2) 80%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    pointer-events: none;
    user-select: none;
}

.schedule .wrap, .tariffs .wrap { position: relative; }

.timeline { margin-top: 72px; text-align: center; }

.timeline__time { margin: 0; font-size: clamp(45px, 7.5vw, 120px); font-weight: 600; line-height: 1; }

.timeline__rail { display: flex; align-items: flex-end; gap: 20px; margin-top: 25px; }

/* Активная точка всегда посередине, остальные разъезжаются от неё — как в
   макете, где лента показывает окрестность выбранного часа. Сдвиг считает
   скрипт, потому что зависит от ширины подписей. */
/* Края окна растворяются: подписи соседних часов обрезаются на ходу, и
   ровный срез посреди цифры читается как поломка, а не как продолжение. */
.timeline__viewport {
    position: relative;
    flex: 1;
    overflow: hidden;
    mask-image: linear-gradient(to right, transparent, #000 40px, #000 calc(100% - 40px), transparent);
}

/* Лента проходит через центры точек, поэтому это фон окна, а не рамка списка:
   у активной точки диаметр вдвое больше, и рамкой линия поехала бы. */
.timeline__viewport::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 10px;
    height: 1px;
    background: repeating-linear-gradient(to right, var(--sky) 0 2px, transparent 2px 8px);
}

.timeline__points {
    display: flex;
    align-items: flex-end;
    gap: 12%;
    margin: 0;
    padding: 0;
    list-style: none;
    transition: transform 0.3s;
}

.timeline__points li { position: relative; flex: none; }

.timeline__points button {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--sky);
    cursor: pointer;
}

.timeline__points button::after {
    content: '';
    width: 20px;
    height: 20px;
    border-radius: 100px;
    background: var(--baby);
}

.timeline__points .is-active { color: var(--text); }

/* Ободок активной точки — цвет фона страницы, а не белый: он «прожигает»
   ленту, и линия не просвечивает сквозь неё. */
.timeline__points .is-active::after {
    width: 40px;
    height: 40px;
    margin: 0 -10px -10px;
    border: 10px solid var(--bg);
    background: var(--text);
    background-clip: padding-box;
}

.timeline__points .is-active .timeline__label { visibility: hidden; }

.timeline .h4 { margin-top: 25px; }
.timeline p:last-child { margin: 8px 0 0; }
.timeline .h4:empty, .timeline p:empty { display: none; }

@media (max-width: 1100px) { .timeline { margin-top: 40px; } .watermark { top: 56px; } }

/* Нижний порог clamp() взят из кита 1600 и на узком экране шире колонки:
   «Расписание» вылезало за оба края. Держим кегль от ширины — в макете
   водяной заголовок ровно по колонке. */
@media (max-width: 720px) { .watermark { font-size: 14.7vw; } }
/* В ките 360 у ленты одни точки. Время соседних часов не подписано: крупное
   время над лентой и так называет выбранный час, а подписи в 360 пикселей не
   помещаются — окно резало бы их посреди цифр. */
@media (max-width: 720px) {
    .timeline__rail { gap: 8px; }

    .timeline__label { display: none; }

    /* Шаг точек — 82 пикселя из макета: активная в середине окна, следующая
       у правой стрелки. Поля кнопки добирают палец до 30 пикселей, не трогая
       ни размер точки, ни шаг: в зазоре они уже учтены. */
    .timeline__points { gap: 52px; }
    .timeline__points button { padding: 10px 10px 0; }
    .timeline__points button::after { width: 10px; height: 10px; }
    /* Псевдоэлементы мимо глобального box-sizing, поэтому размер тут —
       внутренняя точка, а ободок ложится поверх: 16 и 7 дают те самые 30
       пикселей активной точки из макета. */
    .timeline__points .is-active::after { width: 16px; height: 16px; border-width: 7px; }

    /* Ободок активной точки свисает ниже ленты, а окно режет всё, что вышло
       за его край: подкладываем поле ровно на свес и опускаем линию туда же,
       иначе у точки срезано донце. Резать посреди цифры больше нечего, и
       широкое затухание у краёв только гасило бы соседнюю точку. */
    .timeline__viewport {
        padding-bottom: 10px;
        mask-image: linear-gradient(to right, transparent, #000 12px, #000 calc(100% - 12px), transparent);
    }

    .timeline__viewport::before { bottom: 15px; }
}

/* ---------- комфорт ---------- */

.comfort-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px; margin-top: 30px; }

.comfort-card {
    display: flex;
    flex-direction: column;
    gap: 20px;
    min-height: 383px;
    padding: 20px;
    border: 1px solid var(--white-20);
    border-radius: 18px;
    background: var(--second);
    color: #fff;
}

.comfort-card__shape { width: 95px; height: 95px; margin-left: auto; }

/* Под заголовок отведены две строки, даже когда он в одну: «Медицинская
   помощь» переносится, и без этого запаса текст в соседних карточках
   начинался бы выше — четыре разных высоты в одном ряду. */
.comfort-card h3 { min-height: 2em; }

/* Текст идёт сразу под заголовком, а не прижат к низу карточки: прижатый
   начинался у каждой карточки на своей высоте — по длине самого текста. */
.comfort-card p { margin: 0; }

@media (max-width: 1100px) {
    .comfort-grid { grid-template-columns: 1fr 1fr; gap: 10px; }
    .comfort-card { min-height: 310px; }
    .comfort-card__shape { width: 80px; height: 80px; }
}

@media (max-width: 720px) {
    .comfort-grid { grid-template-columns: 1fr; }
    .comfort-card { min-height: 0; gap: 12px; }
    /* Карточки идут одна под другой, равнять не с чем — пустая строка под
       коротким заголовком была бы просто дырой. */
    .comfort-card h3 { min-height: 0; }
}

/* ---------- атмосфера ---------- */

.gallery .wrap { position: relative; }
.gallery-head { position: absolute; left: 0; right: 0; top: 0; z-index: 1; }
.gallery-label { text-align: center; }
.gallery .section-title { margin-top: 14px; }
.carousel-arrows--gallery { display: none; justify-content: space-between; margin-top: 20px; }

.gallery-mosaic { margin-top: 0; }

.gallery-mosaic__track { position: relative; display: block; aspect-ratio: 1440 / 666; overflow: visible; }

.gallery-mosaic__track img {
    position: absolute;
    width: 18.68%;
    height: 38.14%;
    border-radius: 14px;
    object-fit: cover;
}

.gallery-mosaic__track img:nth-child(1) { left: 0; top: 0; height: 58.26%; }
.gallery-mosaic__track img:nth-child(2) { left: 20.42%; top: 18.77%; width: 18.61%; height: 39.49%; }
.gallery-mosaic__track img:nth-child(3) { left: 40.69%; top: 28.53%; width: 18.61%; height: 29.73%; }
.gallery-mosaic__track img:nth-child(4) { left: 60.97%; top: 16.67%; height: 41.59%; }
.gallery-mosaic__track img:nth-child(5) { left: 81.32%; top: 0.15%; height: 39.49%; }
.gallery-mosaic__track img:nth-child(6) { left: 0; top: 61.86%; }
.gallery-mosaic__track img:nth-child(7) { left: 20.35%; top: 61.86%; width: 18.61%; }
.gallery-mosaic__track img:nth-child(8) { left: 40.69%; top: 61.86%; width: 38.96%; }
.gallery-mosaic__track img:nth-child(9) { left: 81.32%; top: 43.09%; height: 56.91%; }

@media (max-width: 1100px) {
    /* Ниже десктопа мозаика становится сеткой, и заголовок встаёт над ней
       обычной строкой — как в макетах 768 и 360. */
    .gallery-head { position: static; }
    .gallery-mosaic { margin-top: 30px; }

    .gallery-mosaic__track {
        position: static;
        display: grid;
        grid-template-columns: repeat(3, 1fr);
        gap: 10px;
        aspect-ratio: auto;
    }

    /* :nth-child(n) — не украшение: размеры мозаики заданы правилами
       :nth-child(2), (3)… и перебивают простой селектор. Без него часть снимков
       оставалась шириной в пятую долю ряда — сетка и лента разъезжались. */
    .gallery-mosaic__track img:nth-child(n) {
        position: static;
        width: 100%;
        height: auto;
        aspect-ratio: 1;
    }
}

@media (max-width: 720px) {
    .carousel-arrows--gallery { display: flex; }

    /* Обратно к прокручиваемой ленте: overflow из десктопной раскладки
       перебивает .carousel__track, и без этого снимки растягивают страницу. */
    .gallery-mosaic__track { display: flex; overflow-x: auto; }
    .gallery-mosaic__track img:nth-child(n) { flex: none; width: 100%; aspect-ratio: 341 / 300; }
}

/* ---------- стоимость ---------- */

.tariffs .section-title { margin-top: 107px; }
.tariff-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 30px; }

.tariff {
    display: flex;
    flex-direction: column;
    gap: 20px;
    padding: 20px;
    border: 1px solid var(--white-20);
    border-radius: 18px;
    background: var(--deep);
    color: #fff;
}

.tariff--featured { background: var(--gradient); }
.tariff__body { display: flex; flex-direction: column; gap: 5px; }
.tariff__name { text-align: center; }
.tariff__price { margin-top: 10px; text-align: center; }
.tariff__per { color: var(--white-60); text-align: center; }
.tariff .btn { margin-top: auto; width: 100%; }

.tariff__list { display: flex; flex-direction: column; gap: 5px; margin: 15px 0 0; padding: 0; list-style: none; }
.tariff__list li { display: flex; align-items: flex-start; gap: 5px; }
.tariff__list img { flex: none; width: 24px; height: 24px; }

@media (max-width: 1100px) {
    .tariffs .section-title { margin-top: 79px; }
    .tariff-grid { grid-template-columns: 1fr; gap: 10px; }
}

/* ---------- отзывы ---------- */

.review {
    display: flex;
    flex: none;
    flex-direction: column;
    gap: 20px;
    width: 464px;
    margin: 0;
    padding: 20px;
    border-radius: 20px;
    background: var(--main);
    color: #fff;
}

.review__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.review__head > span { display: flex; flex-direction: column; gap: 8px; }
.review__head img { flex: none; width: 88px; height: 88px; }
.review__role { color: var(--white-60); }
.review__text { margin: 0; }
.review__date { margin: auto 0 0; color: var(--white-60); }

@media (max-width: 1100px) { .review { width: 349px; padding: 16px; } .review__head img { width: 64px; height: 64px; } }
@media (max-width: 720px) { .review { width: 100%; } }

/* ---------- FAQ ---------- */

.faq { position: relative; padding-bottom: 90px; overflow: hidden; }

.faq-bg {
    position: absolute;
    inset: 0;
    background: url('img/faq-bg.webp') no-repeat center / cover;
    pointer-events: none;
}

.faq .wrap { position: relative; }

.faq-list { display: flex; flex-direction: column; gap: 10px; max-width: 851px; margin: 30px auto 0; }

.topic--faq { border-radius: 18px; }
.topic--faq .topic__head { padding: 20px; }
.topic--faq .topic__sign img { width: 50px; height: 50px; }

.topic__answer { display: none; margin: 0; padding: 0 20px 30px; color: #fff; }
.topic--faq.is-open .topic__answer { display: block; }

@media (max-width: 1100px) {
    .faq { padding-bottom: 56px; }
    .topic--faq .topic__head { padding: 15px; }
    .topic--faq .topic__sign img { width: 30px; height: 30px; }
    .topic__answer { padding: 0 15px 20px; }
}

/* ---------- адрес и контакты ---------- */

.contacts-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 678px;
    gap: 30px;
    margin-top: 30px;
    padding: 30px;
    border-radius: 24px;
    background: var(--deep);
    color: #fff;
}

.contacts-title { max-width: 651px; }

.contacts-list {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 40px 24px;
    margin: 116px 0 0;
}

.contacts-list dt { color: var(--white-40); }
.contacts-list dd { margin: 10px 0 0; }

.socials { display: flex; gap: 10px; }

.socials a {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 50px;
    height: 50px;
    border-radius: 100px;
    background: #fff;
}

.contacts-map { position: relative; display: block; }
.contacts-map img { width: 100%; height: 100%; border-radius: 12px; object-fit: cover; }

.contacts-map__pin {
    position: absolute;
    top: 31%;
    left: 45%;
    width: 63px;
    height: 102px;
}

.contacts-map__pin img { position: absolute; inset: 0; width: 100%; height: 100%; border-radius: 0; object-fit: contain; }

/* Значок школы внутри булавки — отдельный слой, как в макете. */
.contacts-map__pin img:last-child { inset: 18px auto auto 19.5px; width: 24px; height: 27px; }

@media (max-width: 1100px) {
    .contacts-card { grid-template-columns: 1fr; padding: 20px; gap: 20px; }
    .contacts-list { margin-top: 40px; gap: 24px; }
    .contacts-map { aspect-ratio: 678 / 439; }
    .contacts-map__pin { width: 44px; height: 71px; }
}

@media (max-width: 720px) {
    .contacts-list { grid-template-columns: 1fr; gap: 16px; }
    .socials a { width: 40px; height: 40px; }
}

/* ---------- подвал ---------- */

.footer {
    margin-top: 80px;
    padding: 30px 0;
    border-radius: 40px 40px 0 0;
    background: var(--dark);
    color: var(--bg);
}

/* Доли колонок из макета: логотипы занимают половину полосы, и на равных
   третях «Физтех-центр» наезжает на навигацию. */
.footer .wrap {
    display: grid;
    grid-template-columns: 50.8% 25.4% auto;
    gap: 30px 0;
    align-items: start;
}

.footer-logos { display: flex; align-items: center; gap: 60px; }
.footer-logos img:first-child { width: 306px; height: auto; }
.footer-logos img:last-child { width: 151px; height: auto; }

.footer-nav p { margin: 0 0 10px; }
.footer-nav ul { display: flex; flex-direction: column; gap: 5px; margin: 0; padding: 0; list-style: none; }

.footer-legal { grid-column: 1; margin: 0; color: var(--soft-70); }
.footer-legal--right { grid-column: 3; grid-row: 1; margin: 0; }

.footer-links { grid-column: 1; display: flex; gap: 40px; margin: 26px 0 0; }
.footer-links a { border-bottom: 1px solid currentcolor; }

.footer-copy { grid-column: 3; margin: 26px 0 0; color: var(--soft-70); }

@media (max-width: 1100px) {
    .footer { margin-top: 56px; border-radius: 30px 30px 0 0; }
    .footer .wrap { grid-template-columns: 1fr 1fr; }
    .footer-logos { grid-column: 1 / -1; justify-content: center; gap: 30px; }
    .footer-logos img:first-child { width: 200px; }
    .footer-logos img:last-child { width: 100px; }
    .footer-legal { grid-column: 1 / -1; }
    .footer-legal--right { grid-column: 2; grid-row: auto; }
    .footer-nav { grid-column: 1; }
    .footer-copy { grid-column: 1 / -1; margin-top: 12px; }
    .footer-links { grid-column: 1 / -1; margin-top: 12px; }
}

@media (max-width: 720px) {
    .footer .wrap { grid-template-columns: 1fr; }
    .footer-legal--right, .footer-nav, .footer-copy, .footer-links { grid-column: 1; }
    /* Столбиком ссылки растягивались на всю ширину, и подчёркивание тянулось
       до правого края. Подчёркнут только текст, как на широких экранах. */
    .footer-links { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* ---------- модальное окно заявки ---------- */

.modal { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal[hidden] { display: none; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(5, 32, 67, 0.55); }

/* Высота окна из макета и не меняется от шага к шагу: иначе кнопки прыгают
   под курсором, когда шагов становится меньше полей. */
.apply-dialog {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 840px;
    max-width: 100%;
    min-height: 708px;
    max-height: 100%;
    padding: 30px;
    border-radius: 24px;
    background: var(--light);
    color: var(--very-dark);
    overflow-y: auto;
}

.apply-dialog form { display: flex; flex: 1; flex-direction: column; }

.modal__close { position: absolute; top: 30px; right: 30px; padding: 0; border: 0; background: none; cursor: pointer; }
.modal__close img { width: 40px; height: 40px; }

/* Снизу отступ до заголовка шага: вплотную к полоскам «Выберите формат»
   читался подписью к ним, а не заголовком. */
.steps { display: flex; gap: 13px; margin: 48px 0 32px; padding: 0; list-style: none; }
.steps li { flex: 1; color: var(--pastel-75); }
.steps li.is-current, .steps li.is-done { color: var(--second); }

.steps span { display: flex; align-items: center; gap: 5px; height: 24px; font-size: 16px; }
.steps img { display: none; width: 24px; height: 24px; }
.steps li.is-done img { display: block; }

.steps li::after { content: ''; display: block; height: 4px; margin-top: 8px; border-radius: 100px; background: currentcolor; }

.step { display: flex; flex: 1; flex-direction: column; min-width: 0; margin: 0; padding: 0; border: 0; }
.step[hidden] { display: none; }
.step legend { padding: 0; margin-bottom: 32px; color: var(--very-dark); }

.field { display: flex; flex-direction: column; gap: 8px; margin: 0 0 24px; }
.field label { color: var(--second); }

.field input, .field select {
    width: 100%;
    height: 49px;
    padding: 15px 10px;
    border: 1px solid var(--steel-45);
    border-radius: 8px;
    background: var(--alice);
    color: var(--very-dark);
    font: inherit;
    font-size: 16px;
    line-height: 1.2;
    letter-spacing: inherit;
}

.field input::placeholder { color: var(--steel-45); }

/* Красная рамка появляется только после нажатия «Продолжить»: подсветить
   пустое поле раньше, чем человек начал его заполнять, — значит отчитать
   его за то, что он ещё не сделал. Подсказку браузер говорит сам, но
   всплывающее окно гаснет через секунду, а рамка остаётся. */
.step.is-checked .field :invalid { border-color: var(--orange); }
.field select { appearance: none; background-image: url('img/select-arrow.svg'); background-repeat: no-repeat; background-position: right 12px center; background-size: 24px 12px; }
.field select:invalid { color: var(--steel-45); }

.consent { display: flex; align-items: center; gap: 5px; margin: 0 0 8px; font-size: 14px; line-height: 1.4; letter-spacing: 0; }
.consent input { flex: none; width: 16px; height: 16px; margin: 0; accent-color: var(--second); }
.consent a { border-bottom: 1px solid rgba(0, 33, 56, 0.6); }

/* Кнопки прижаты к низу и занимают правую половину: на первом шаге «Назад»
   нет, и одна кнопка не должна растягиваться на всю ширину. */
.step__actions { display: flex; justify-content: flex-end; gap: 20px; margin-top: auto; padding-top: 32px; }
.step__actions .btn { flex: 0 1 calc(50% - 10px); }

.consult-error { display: none; margin: 16px 0 0; color: var(--orange); }

.apply-done { display: none; flex-direction: column; align-items: center; gap: 20px; padding: 40px 0 0; text-align: center; }
/* Галочка в круге с ореолом. Собирается из той же галочки, что и в шагах:
   отдельный экспорт тащил бы за собой подложку холста Figma. */
.apply-done__mark {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 257px;
    height: 257px;
    border: 30px solid var(--alice);
    border-radius: 100%;
    background: var(--main);
}

.apply-done__mark::before {
    content: '';
    width: 110px;
    height: 110px;
    background: #fff;
    mask: url('img/icon-done.svg') no-repeat center / contain;
    -webkit-mask: url('img/icon-done.svg') no-repeat center / contain;
}
.apply-done p { max-width: 560px; margin: 0; }
.apply-done .btn { width: 100%; margin-top: 20px; }

.apply-dialog.is-done .steps,
.apply-dialog.is-done form { display: none; }
.apply-dialog.is-done .apply-done { display: flex; }

@media (max-width: 720px) {
    .modal { padding: 10px; }
    .apply-dialog { min-height: 0; padding: 20px; }
    .step__actions .btn { flex: 1; }
    .modal__close { top: 20px; right: 20px; }
    .modal__close img { width: 30px; height: 30px; }
    .steps { gap: 6px; margin-top: 36px; margin-bottom: 24px; }
    .steps span { font-size: 12px; }
    .step legend { margin-bottom: 24px; }
    .step__actions { flex-direction: column-reverse; gap: 10px; }
    .apply-done__mark { width: 160px; height: 160px; border-width: 18px; }
    .apply-done__mark::before { width: 70px; height: 70px; }
}
