/* ==========================================================================
   IMKONIYAT design system — Bootstrap 5 re-skinned to the brand.
   Deep Navy #14213D · Dark Navy #000A24 · Gold #FCA311 / #FFA515
   Montserrat (headlines) · Manrope (body)
   ========================================================================== */

:root {
  --im-navy: #14213D;
  --im-navy-dark: #000A24;
  --im-gold: #FCA311;
  --im-gold-ui: #FFA515;
  --im-white: #FFFFFF;
  --im-silver: #E5E5E5;
  --im-surface: #F9F9F9;
  --im-text: #1A1C1C;
  --im-text-soft: #45464D;
  --im-error: #BA1A1A;
  --im-radius-card: 18px;
  --im-radius-input: 12px;
  --im-section-y: 96px;
  --im-section-y-mobile: 52px;
  --im-container: 1280px;

  --bs-primary: #14213D;
  --bs-primary-rgb: 20, 33, 61;
  --bs-body-font-family: "Manrope", system-ui, sans-serif;
  --bs-body-color: #1A1C1C;
  --bs-body-bg: #F9F9F9;
  --bs-link-color: #14213D;
  --bs-link-hover-color: #000A24;
  --bs-border-radius: 12px;
  --bs-danger: #BA1A1A;
}

body { font-family: "Manrope", system-ui, sans-serif; background: var(--im-surface); color: var(--im-text); }
.container { max-width: var(--im-container); }

h1, h2, h3, h4, .h1, .h2, .h3, .h4, .font-display {
  font-family: "Montserrat", sans-serif;
  font-weight: 800;
  color: var(--im-navy);
  letter-spacing: -0.01em;
}
/* Пятый и шестой уровни раньше сюда не входили и рисовались Manrope, поэтому
   `<h6>` и `<h2 class="h6">` — соседние заголовки в подвале — были набраны
   разными шрифтами. Вес 600, а не 500: из Montserrat загружены 600/800/900,
   и запрошенный Bootstrap'ом 500 браузер всё равно подменял шестисотым. */
h5, h6, .h5, .h6 { font-family: "Montserrat", sans-serif; font-weight: 600; }
/* Семейство задаёт сам класс, а не тег. Второй и следующие заголовки слайдера
   — это `<p class="display-title">` (на страницу приходится один H1), и без
   этой строки они наследовали Manrope от body: первый слайд был набран
   Montserrat, остальные — другим шрифтом. */
.display-title {
  font-family: "Montserrat", sans-serif;
  font-weight: 900; font-size: clamp(2.4rem, 6vw, 4.6rem); line-height: 1.08;
  letter-spacing: -0.02em;
}
.headline-xl {
  font-family: "Montserrat", sans-serif;
  font-weight: 800; font-size: clamp(1.7rem, 3.4vw, 3.1rem); line-height: 1.2;
}
.big-number { font-family: "Montserrat", sans-serif; font-weight: 900; font-size: clamp(3rem, 8vw, 6.5rem); line-height: 1; }
.lead-im { font-size: 1.2rem; line-height: 1.65; color: var(--im-text-soft); }
.text-gold { color: var(--im-gold) !important; }
.text-navy { color: var(--im-navy) !important; }
.text-soft { color: var(--im-text-soft) !important; }

/* --- Sections & bands ------------------------------------------------- */
.section { padding-top: var(--im-section-y); padding-bottom: var(--im-section-y); }
@media (max-width: 767px) {
  .section { padding-top: var(--im-section-y-mobile); padding-bottom: var(--im-section-y-mobile); }
}
.band-navy { background: var(--im-navy); color: var(--im-white); }
.band-navy h1, .band-navy h2, .band-navy h3, .band-navy h4 { color: var(--im-white); }
.band-navy .text-soft { color: #B9C6EA !important; }
.band-navy .lead-im { color: #cdd5e6; }
.band-navy p:not([class]) { color: #cdd5e6; }
.band-dark { background: var(--im-navy-dark); color: var(--im-white); }
.band-white { background: var(--im-white); }

/* Compact artwork belongs only to the short header of the About page. */
.about-hero {
  position: relative;
  overflow: hidden;
  padding-block: 56px;
  background-color: var(--im-navy);
  background-image: url("../img/about/imkoniyat-education-background.svg");
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
.about-hero > * { position: relative; z-index: 1; }
.about-hero .editorial-divider { height: 42px; }
@media (max-width: 575.98px) {
  .about-hero {
    padding-block: 44px;
    background-image: url("../img/about/imkoniyat-education-background-mobile.svg");
  }
}

/* Section background image (admin-managed) with a brand overlay for contrast. */
.section.has-bg, .band-navy.has-bg { position: relative; background-image: var(--section-bg);
  background-size: cover; background-position: center; }
.has-bg::after { content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, rgba(20,33,61,.86), rgba(0,10,36,.92)); }
.has-bg > * { position: relative; z-index: 1; }

.gold-glow { position: relative; overflow: hidden; }
.gold-glow::before {
  content: ""; position: absolute; inset: -20% -10%; pointer-events: none;
  background: radial-gradient(ellipse 55% 45% at 50% 30%, rgba(252, 163, 17, .16) 0%, rgba(0, 10, 36, 0) 70%);
}
.editorial-divider {
  width: 1px; height: 72px; margin-inline: auto;
  background: linear-gradient(to bottom, transparent, var(--im-gold), transparent);
}
.divider-h { height: 1px; width: 96px; background: linear-gradient(to right, transparent, var(--im-gold), transparent); }

/* --- Section heading signature: gold "light ray" leading into the title -
   Echoes the rays above the key in the IMKONIYAT emblem. Used on every
   section so the brand's core metaphor reads consistently. */
.section-head .ray {
  display: block; width: 1px; height: 46px; margin: 0 auto 22px;
  background: linear-gradient(to bottom, transparent, var(--im-gold));
}
.section-head { position: relative; }

/* --- Tag pill ---------------------------------------------------------- */
.tag-pill {
  display: inline-block; padding: .4rem 1.05rem; border-radius: 999px;
  font-size: .7rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; background: var(--im-gold); color: var(--im-navy);
}
.band-navy .tag-pill { background: var(--im-white); color: var(--im-navy); }

/* --- Buttons (pill, 44px touch target) ---------------------------------- */
.btn { border-radius: 999px; font-weight: 700; padding: .65rem 1.6rem; min-height: 44px; }
.btn-gold { background: var(--im-gold); border-color: var(--im-gold); color: var(--im-navy); }
.btn-gold:hover, .btn-gold:focus { background: #e2910d; border-color: #e2910d; color: var(--im-navy-dark); transform: translateY(-1px); }
.btn-outline-navy { border: 2px solid var(--im-navy); color: var(--im-navy); background: transparent; }
.btn-outline-navy:hover { background: var(--im-navy); color: var(--im-white); }
.btn-outline-white { border: 2px solid rgba(255,255,255,.85); color: var(--im-white); background: transparent; }
.btn-outline-white:hover { background: var(--im-white); color: var(--im-navy); }
.btn-navy { background: var(--im-navy); border-color: var(--im-navy); color: #fff; }
.btn-navy:hover { background: var(--im-navy-dark); border-color: var(--im-navy-dark); color: #fff; }
.btn-sm { min-height: 36px; padding: .35rem 1.1rem; }

/* ==========================================================================
   Direction cards — a full-bleed visual cover per direction.

   Artwork fills the card, a small label sits top-left, and the name plus
   course count sit at the bottom over a navy gradient. One monotone treatment
   for all seven: no per-direction hue, so gold stays meaningful.

   `--dir-field` is the exact background colour of the emblem files
   (sampled: rgb(4,17,47) on all seven). The card paints that same colour
   behind the `contain`-fitted image, so the image's own field and the card's
   field are indistinguishable — the artwork reads as edge-to-edge while
   nothing is cropped or stretched. See the direction_visual_card macro.
   ========================================================================== */
.direction-visual-card {
  --dir-field: #04112F;
  position: relative; display: flex; flex-direction: column; overflow: hidden;
  width: 100%;
  /* No fixed height. The card is as tall as its square picture plus its
     caption, so the artwork never has to be squeezed into a ratio it was not
     drawn for. */
  /* Radius stays where it was; only the card around it got smaller. */
  border-radius: 22px; text-decoration: none;
  background: var(--dir-field);
  border: 1px solid rgba(255, 255, 255, .10);
  box-shadow: 0 6px 18px rgba(20, 33, 61, .14);
  transition: transform .3s var(--ease-out), box-shadow .3s var(--ease-out),
              border-color .3s ease;
}
.direction-visual-card:hover,
.direction-visual-card:focus-visible {
  /* A gentle swell, not a jump: the row is moving underneath, and anything
     larger reads as the card lurching sideways rather than lifting. Dropped
     the extra upward slide — the scale alone is enough, and the two together
     were the sort of stacked effect that makes a card feel machine-styled. */
  transform: scale(1.025);
  border-color: rgba(252, 163, 17, .5);
  box-shadow: 0 14px 30px rgba(0, 10, 36, .28);
  z-index: 2;
}
.direction-visual-card:focus-visible {
  outline: 3px solid var(--im-gold); outline-offset: 3px;
}
.direction-visual-card:active { transform: scale(1.005); }

/* Media: a 1:1 box for a 1:1 file. Because the two ratios match, the image
   fills it exactly — `cover` and `contain` would give the same result, and
   neither crops nor stretches anything. The soft gold glow gives the flat navy
   field depth; the artwork is line-art, so without it the card reads as a
   plain block rather than a designed cover. */
.direction-visual-card__media {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 1 / 1; width: 100%;
  /* A hint of warmth behind the line-art, not a glow. At the old strength it
     read as an added effect sitting on the artwork rather than as the field
     the emblem was drawn on. */
  background:
    radial-gradient(ellipse 68% 58% at 50% 46%,
                    rgba(252, 163, 17, .09) 0%, rgba(252, 163, 17, 0) 70%);
}
.direction-visual-card__media img {
  width: 100%; height: 100%; display: block;
  object-fit: cover;                 /* identical to contain at 1:1 — no crop */
  transform: scale(1.0);
  transition: transform .5s var(--ease-out);
}
.direction-visual-card:hover .direction-visual-card__media img {
  transform: scale(1.04);
}
/* Fallback when a direction has no artwork: its own themed glyph on the same
   navy field — never a photograph borrowed from another direction. */
.direction-visual-card__glyph {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  color: var(--im-gold); font-size: clamp(2.7rem, 7vw, 4rem); opacity: .9;
}
/* The darkening gradient. It sits at the foot of the picture and runs into the
   caption panel below, so the two areas read as one surface instead of meeting
   at a hard seam — and any part of the emblem that reaches the bottom edge
   fades out under it rather than colliding with the title. */
.direction-visual-card__media::after {
  content: ""; position: absolute; inset: auto 0 0 0; height: 46%;
  background: linear-gradient(180deg,
    rgba(4, 17, 47, 0) 0%, rgba(4, 17, 47, .55) 55%, rgba(4, 17, 47, .96) 100%);
  pointer-events: none;
}
/* Надписи «НАПРАВЛЕНИЕ» поверх картинки больше нет: карточка стоит в разделе
   с заголовком «Направления», и слово повторяло его на каждой из семи
   обложек, закрывая часть эмблемы. Стили удалены вместе с разметкой. */

/* Caption. Same navy as the picture's own field, so the card is one block of
   colour and the gradient above dissolves into it. */
.direction-visual-card__content {
  position: relative;
  /* Grows into whatever height the row settles at, which is what lets the
     count sit on one line across every card regardless of how many lines its
     own title took. */
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  padding: .55rem .85rem .8rem;
  background: var(--dir-field);
}
/* The one flourish: a gold hairline along the seam between picture and caption,
   drawn in from the left on hover. One line, one direction, no glow — enough to
   answer the cursor without announcing itself. */
.direction-visual-card__content::before {
  content: ""; position: absolute; top: 0; left: .85rem; right: .85rem;
  height: 2px; border-radius: 2px;
  background: var(--im-gold);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .45s var(--ease-out);
}
.direction-visual-card:hover .direction-visual-card__content::before,
.direction-visual-card:focus-visible .direction-visual-card__content::before {
  transform: scaleX(1);
}
.direction-visual-card__title {
  font-family: "Montserrat", sans-serif;
  /* 800, not 700: only 600/800/900 are loaded, so 700 was being faked. */
  font-weight: 800;
  font-size: clamp(.9rem, 1.05vw, 1.02rem); line-height: 1.28; color: #fff;
  margin: 0;
  /* Up to three lines. Long names wrap instead of being cut, and the cards all
     take the row's tallest height anyway, so the loop stays even. */
  overflow-wrap: break-word; hyphens: auto;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.56em;                /* reserves a second line */
}
.direction-visual-card__count {
  /* Pushed to the foot of the caption: this is what keeps the counts aligned
     with each other across cards whose titles run to different lengths, and it
     is where the air between name and count comes from. */
  margin-top: auto; padding-top: .55rem;
  display: inline-flex; align-items: center; gap: .3rem;
  font-family: "Montserrat", sans-serif; font-weight: 600;
  font-size: .72rem; letter-spacing: .01em; color: var(--im-gold);
}
.direction-visual-card__count i {
  font-size: .8em;
  transition: transform .25s var(--ease-out);
}
.direction-visual-card:hover .direction-visual-card__count i {
  transform: translateX(3px);
}
/* Course card: one gold accent rail for every course, matching the direction
   cards. Needs .card-im in the selector — the shorthand `border` on .card-im is
   declared later in this file and would otherwise reset the left edge. */
.card-im.course-card-accent { border-left: 3px solid var(--im-gold); }
.course-card-accent .cover-placeholder { color: var(--im-gold); }
/* Course covers are square illustrations on a transparent background. `cover`
   would crop the top and bottom off a 1:1 image in a 16:9 frame and cut the
   artwork in half, so they are fitted whole onto the navy field instead. */
.course-card-accent .card-cover {
  background: linear-gradient(135deg, var(--im-navy) 0%, var(--im-navy-dark) 100%);
  object-fit: contain;
  padding: .6rem;
}
.course-direction-tag {
  font-size: .72rem; font-weight: 700; color: var(--im-navy);
}

/* Inline brand decor behind navy sections. Sits under the content and never
   competes with it — no text sits on a busy area, and contrast is unchanged. */
.has-decor { position: relative; overflow: hidden; }
.section-decor {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 0;
}
.has-decor > .container { position: relative; z-index: 1; }

/* ==========================================================================
   Horizontal scroll rail.
   Native overflow-x + scroll-snap, so the wheel, a trackpad swipe, a touch
   drag, Tab and the arrow keys all work with no JavaScript. The arrow buttons
   are enhancement only — rail.js reveals them when the content overflows.
   ========================================================================== */
.rail-wrap { position: relative; }
.rail { position: relative; }
.rail-track {
  display: flex; gap: 1.1rem;
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity; scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch;
  /* Room for the lifted card shadow and the focus ring. */
  padding: .5rem .25rem 1.25rem;
  scrollbar-width: thin; scrollbar-color: var(--im-silver) transparent;
}
.rail-track::-webkit-scrollbar { height: 6px; }
.rail-track::-webkit-scrollbar-track { background: transparent; }
.rail-track::-webkit-scrollbar-thumb {
  background: var(--im-silver); border-radius: 999px;
}
.rail-track::-webkit-scrollbar-thumb:hover { background: var(--im-gold); }
.rail-track:focus-visible { outline: 2px solid var(--im-gold); outline-offset: 2px; }
.rail-track > * {
  flex: 0 0 clamp(240px, 26vw, 290px);
  scroll-snap-align: start;
  /* Equal card heights across the rail. `height: 100%` (including Bootstrap's
     .h-100) would defeat this, so it is neutralised for rail children. */
  align-self: stretch;
}
.rail-track > .h-100 { height: auto !important; }

.rail-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 40px; height: 40px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--im-silver); background: var(--im-white);
  color: var(--im-navy); display: grid; place-items: center; font-size: 1.1rem;
  box-shadow: 0 6px 18px rgba(20, 33, 61, .12);
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
.rail-nav:hover { background: var(--im-gold); border-color: var(--im-gold); color: var(--im-navy-dark); }
.rail-nav:disabled { opacity: .35; cursor: default; box-shadow: none; }
.rail-nav[hidden] { display: none; }
.rail-prev { left: -18px; }
.rail-next { right: -18px; }

/* Touch devices scroll by finger — the buttons would only cover cards. */
@media (max-width: 991.98px) {
  .rail-nav { display: none !important; }
  .rail-track { gap: .85rem; padding-inline: .1rem; }
  .rail-track > * { flex-basis: min(78vw, 300px); }
}
@media (prefers-reduced-motion: reduce) {
  .rail-track { scroll-behavior: auto; }
}

/* --- Cards -------------------------------------------------------------- */
.card-im {
  background: var(--im-white); border: 1px solid var(--im-silver);
  border-radius: var(--im-radius-card);
  box-shadow: 0 10px 30px rgba(20, 33, 61, .05);
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.card-im:hover { transform: translateY(-4px); box-shadow: 0 16px 40px rgba(20, 33, 61, .1); border-color: #d5d5d5; }
.band-navy .card-im { background: rgba(255,255,255,.06); border-color: rgba(255,255,255,.12); color: var(--im-white); box-shadow: none; }
.band-navy .card-im h3, .band-navy .card-im h4 { color: var(--im-white); }
/* height: auto — обязательно. У картинки есть атрибуты width/height (они
   резервируют место и не дают макету прыгать при загрузке), но без height:auto
   именно атрибут задаёт высоту, а `aspect-ratio` не применяется: обложка
   рендерилась 675 px в высоту вместо 16:9 и раздувала карточку курса. */
.card-cover { border-radius: var(--im-radius-card) var(--im-radius-card) 0 0; aspect-ratio: 16/9; object-fit: cover; width: 100%; height: auto; background: linear-gradient(135deg, var(--im-navy) 0%, var(--im-navy-dark) 100%); }
.cover-placeholder { display: flex; align-items: center; justify-content: center; color: var(--im-gold); font-size: 2rem; }
.icon-circle {
  width: 48px; height: 48px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center;
  background: var(--im-navy); color: var(--im-gold); font-size: 1.2rem; flex: none;
}

/* --- Forms -------------------------------------------------------------- */
.form-control, .form-select {
  border-radius: var(--im-radius-input); border: 1px solid var(--im-silver);
  min-height: 44px; padding: .55rem .9rem;
}
.form-control:focus, .form-select:focus { border-color: var(--im-gold); box-shadow: 0 0 0 .2rem rgba(252, 163, 17, .18); }
.form-label { font-size: .74rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--im-navy); }
textarea.form-control { min-height: 110px; }

/* --- Header ------------------------------------------------------------- */
.navbar-im {
  background: rgba(20, 33, 61, .96); backdrop-filter: blur(10px);
  border-bottom: 1px solid rgba(252, 163, 17, .28); min-height: 76px;
}
.navbar-im .nav-link {
  color: var(--im-white); font-size: .78rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; padding: .7rem .85rem;
}
.navbar-im .nav-link:hover { color: var(--im-gold-ui); }
/* Colour only — the single underline is drawn by ::after in the polish layer. */
.navbar-im .nav-link.active { color: var(--im-gold); }
.brand-lockup { gap: .55rem; min-width: 0; }
.brand-lockup .brand-mark { width: auto; height: 54px; flex: 0 0 auto; }
.brand-lockup .brand-wordmark {
  display: block; width: min(202px, 31vw); height: auto; flex: 0 0 auto;
}
.brand-lockup--menu .brand-mark { height: 44px; }
.brand-lockup--menu .brand-wordmark { width: 180px; height: auto; }
@media (max-width: 575px) {
  .brand-lockup { gap: .4rem; }
  .brand-lockup .brand-mark { height: 44px; }
  .brand-lockup .brand-wordmark { width: 145px; height: auto; }
}
.offcanvas-im { background: var(--im-navy); color: var(--im-white); }
.offcanvas-im .nav-link { color: var(--im-white); font-weight: 700; padding: .8rem 0; font-size: 1.05rem; }
.offcanvas-im .nav-link:hover { color: var(--im-gold); }

/* --- Accessibility ------------------------------------------------------- */
/* Off-screen until focused, then it lands over the header where it is
   unmistakable. Hiding it with display:none would take it out of the tab order
   entirely, which defeats the point. */
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 2000;
  background: var(--im-gold); color: var(--im-navy-dark);
  padding: .6rem 1rem; border-radius: 0 0 8px 8px; font-weight: 700;
  text-decoration: none; transition: top .15s ease;
}
.skip-link:focus { top: 0; color: var(--im-navy-dark); }

/* A visible focus ring on every interactive element. Browsers draw one by
   default, but several components here restyle :focus and lose it — which
   leaves a keyboard user unable to tell where they are on the page. */
a:focus-visible, button:focus-visible, [role="button"]:focus-visible,
input:focus-visible, select:focus-visible, textarea:focus-visible,
summary:focus-visible {
  outline: 3px solid var(--im-gold);
  outline-offset: 2px;
  border-radius: 4px;
}
/* The gold ring disappears against the gold button; use the dark navy there. */
.btn-gold:focus-visible { outline-color: var(--im-navy-dark); }

/* ==========================================================================
   Hero (CRM-managed slides with optional photo background).
   Every hero rule lives in this one block — it used to be split with a second
   set of overrides near the end of the file that silently won the cascade,
   leaving the rules here dead. Consolidated so there is exactly one source of
   truth per selector.
   ========================================================================== */
.hero { position: relative; overflow: hidden; }
.hero-slide { display: none; position: relative; min-height: 560px; }
.hero-slide.active { display: flex; align-items: center; animation: heroSlideIn .55s cubic-bezier(.22,.61,.36,1); }
@keyframes heroSlideIn {
  from { opacity: .35; transform: translateX(4%); }
  to { opacity: 1; transform: translateX(0); }
}
.hero-slide.has-media {
  background-image: var(--hero-desktop);
  background-size: cover; background-position: center;
}
/* Scrim, not a blackout, and local to the copy rather than spread over the
   whole frame — the artwork is the point of the slide. Each alignment gets its
   own shape so the veil sits under the text and fades out well before it
   reaches the illustration. */
.hero-slide.has-media::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(20, 33, 61, .18) 0%, rgba(0, 10, 36, .42) 100%);
}
.hero-slide.has-media.hero-text-left::before {
  background:
    linear-gradient(90deg, rgba(8, 18, 42, .72) 0%, rgba(8, 18, 42, .34) 42%, rgba(8, 18, 42, 0) 68%),
    linear-gradient(180deg, rgba(20, 33, 61, .10) 0%, rgba(0, 10, 36, .26) 100%);
}
.hero-slide.has-media.hero-text-right::before {
  background:
    linear-gradient(270deg, rgba(8, 18, 42, .72) 0%, rgba(8, 18, 42, .34) 42%, rgba(8, 18, 42, 0) 68%),
    linear-gradient(180deg, rgba(20, 33, 61, .10) 0%, rgba(0, 10, 36, .26) 100%);
}
/* Centred copy has artwork on both sides and no gradient to hide behind, so it
   gets a soft pool of its own — enough for contrast, small enough that the
   illustration reads at full strength around it. */
.hero-slide.has-media.hero-text-center .hero-copy {
  padding: clamp(1rem, 2vw, 2rem);
  border-radius: 24px;
  background: radial-gradient(ellipse at center, rgba(0, 10, 36, .62) 0%, rgba(0, 10, 36, 0) 72%);
}
/* Text over artwork needs a shadow, not a darker image. */
/* Слайдер набран одним шрифтом — Manrope, тем же, что и подзаголовок под
   ним: заголовок и текст кадра читаются как одна надпись, а не как две
   разные. На остальных страницах крупные заголовки по-прежнему Montserrat.

   Здесь и ниже селектор `.display-title`, а не `h1`: на странице один H1, он
   у первого слайда, а заголовки остальных слайдов — теги <p> с тем же
   классом. По тегу правила доставались только первому слайду, и он отличался
   от соседних шрифтом, размером, тенью и отступами. */
.hero-slide .hero-copy .display-title {
  font-family: "Manrope", system-ui, sans-serif;
  /* 900 у Manrope нет: семейство кончается на 800, и его же браузер и
     возьмёт. Вес указан честно, чтобы не просить несуществующее начертание
     и не получать подделанный жир. */
  font-weight: 800;
  letter-spacing: -0.015em;
}
.hero-slide.has-media .hero-copy .display-title,
.hero-slide.has-media .hero-copy .lead-im {
  text-shadow: 0 2px 18px rgba(0, 10, 36, .55);
}
.hero-slide:not(.has-media)::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse 55% 45% at 50% 35%, rgba(252, 163, 17, .16) 0%, rgba(0, 10, 36, 0) 70%);
}
/* min-width:0 is what lets the copy actually fit a narrow phone. The active
   slide is a flex container, and a flex item defaults to min-width:auto — it
   refuses to shrink below its min-content width, which here is both buttons on
   one line (~430px). Below that the copy simply overflowed the screen. */
.hero-inner { position: relative; z-index: 2; width: 100%; min-width: 0; }
.hero-copy { max-width: 680px; }
.hero-text-center .hero-copy { margin-inline: auto; text-align: center; }
.hero-text-left .hero-copy { max-width: 560px; text-align: left; }
.hero-text-right .hero-copy { max-width: 560px; margin-left: auto; text-align: right; }
/* One primary action, one quiet link — a second equal-weight button made the
   eye choose instead of act. */
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: .85rem 1.5rem; }
.hero-text-center .hero-actions { justify-content: center; }
.hero-text-right .hero-actions { justify-content: flex-end; }
.hero-link {
  display: inline-flex; align-items: center; gap: .45rem;
  min-height: 44px; color: #fff; font-weight: 700; font-size: .95rem;
  text-decoration: none; border-bottom: 1px solid rgba(255, 255, 255, .35);
  padding-bottom: 2px;
  transition: color .18s ease, border-color .18s ease, gap .18s ease;
}
.hero-link:hover, .hero-link:focus-visible {
  color: var(--im-gold); border-color: var(--im-gold); gap: .7rem;
}
/* Landscape art-directed backgrounds put their empty space beside the artwork,
   so from tablet up the column is sized as a share of the frame. In pixels a
   560px column keeps its width while the frame shrinks and the copy walks onto
   the illustration; below 768px the artwork sits underneath instead, and these
   shares would squeeze the copy into a ~155px ribbon. */
@media (min-width: 768px) {
  .hero-slide.has-media.hero-text-left .hero-copy { max-width: 44%; }
  .hero-slide.has-media.hero-text-right .hero-copy { max-width: 44%; }
  /* Centred slides get no more room than the side-aligned ones: the per cent
     resolves against the Bootstrap container, itself ~92% of the frame, so 50%
     here already reached the artwork parked along both edges. */
  .hero-slide.has-media.hero-text-center .hero-copy { max-width: 44%; }
}
/* With the column pinned to a share of the frame, a fixed type scale is what
   breaks next: at 768px the 44% column is only ~330px wide, the headline wraps
   to four lines and spills out of the band. Fluid sizes keep the copy in
   proportion to the column at every width, and top out at the site's own
   display scale so wide screens look unchanged. */
.hero-slide.has-media .hero-copy .display-title { font-size: clamp(1.85rem, 2.2vw + .5rem, 2.4rem); }
.hero-slide.has-media .hero-copy .lead-im {
  font-size: clamp(1rem, 1vw + .3rem, 1.2rem); line-height: 1.5;
}
/* Ready-made full-bleed hero image (its own composition — no overlay/text). */
.hero-image-only {
  background-color: #fff;
  background-image: var(--hero-desktop);
  background-repeat: no-repeat; background-position: center; background-size: contain;
  aspect-ratio: 1717 / 916; min-height: 0; max-height: 90vh;
}
.hero-image-only.active { display: block; }
.hero-image-only::before { display: none; }
/* On phones prefer the admin's mobile image (if uploaded); the desktop
   composition keeps its native ratio as a clean full-width band otherwise. */
@media (max-width: 767px) {
  .hero-image-only { background-image: var(--hero-mobile, var(--hero-desktop)); }
}
.hero-dots { position: absolute; left: 0; right: 0; bottom: 26px; text-align: center; z-index: 3; }
.hero-dots button {
  width: 10px; height: 10px; border-radius: 50%; border: 0;
  background: rgba(255,255,255,.35); margin: 0 4px; padding: 0;
}
.hero-dots button.active { background: var(--im-gold); width: 26px; border-radius: 999px; }
/* From tablet up, let the slide take the artwork's own 1920x900 ratio so
   `cover` has nothing to crop. The bounds keep it a usable band: never a thin
   strip on a small laptop, never a 1200px wall on a wide monitor. */
@media (min-width: 768px) {
  .hero-slide.has-media {
    /* width must stay definite: with only aspect-ratio and min-height set, the
       browser resolves the ratio the other way and derives the *width* from
       the 460px floor (460 x 2.133 = 981px), overflowing the viewport. */
    width: 100%; aspect-ratio: 1920 / 900; min-height: 460px; max-height: 760px;
  }
}
@media (max-width: 767px) {
  .hero-slide.has-media {
    background-image: var(--hero-mobile, var(--hero-desktop));
    /* Same trick as the desktop rule, with the portrait frame's own ratio —
       and the same reason for pinning the width. */
    width: 100%; aspect-ratio: 1000 / 1800; min-height: 560px; max-height: 86vh;
    /* Anchor to the bottom: on a wide-but-short window (a 700px tablet, a
       landscape phone) max-height cuts the frame down, and a centred crop eats
       the illustration off the bottom edge. Cropping the empty band on top
       instead keeps the artwork on screen. */
    background-position: bottom center;
    /* The portrait build keeps the illustration along the bottom edge, so the
       copy is pinned to the free space above it rather than centred on top. */
    align-items: flex-start;
  }
  /* py-5 is an !important Bootstrap utility, so the override needs the weight. */
  .hero-slide.has-media .hero-inner { padding-top: 2rem !important; }

  /* On a phone the artwork sits underneath the copy rather than beside it, so
     there is no empty side of the frame to align to — every slide reads best
     centred, whatever placement its desktop composition asked for.
     Both halves are listed on purpose: `.hero-actions` takes its alignment
     from the slide's own `hero-text-*` class, so a left-placed slide kept its
     buttons pinned to the left edge while the text above them was already
     centred. All three alignments are named so the rule outweighs the
     `.hero-text-left/right` ones rather than relying on source order. */
  .hero-slide.hero-text-left .hero-copy,
  .hero-slide.hero-text-right .hero-copy,
  .hero-slide.hero-text-center .hero-copy {
    text-align: center; margin-inline: auto;
  }
  .hero-slide.hero-text-left .hero-actions,
  .hero-slide.hero-text-right .hero-actions,
  .hero-slide.hero-text-center .hero-actions { justify-content: center; }
  /* The pill is an inline-block, so it centres with the text; the actions row
     is flex and needed the rule above instead. */
  /* The copy has to clear the illustration, so the phone tightens the rhythm.
     The buttons stay stacked (both labels never fit one 375px row) — the side
     margin is dropped so they stay optically centred, and becomes a gap. */
  .hero-slide.has-media .hero-copy .display-title { margin-bottom: .6rem; }
  .hero-slide.has-media .hero-copy .lead-im { line-height: 1.45; margin-bottom: 1rem; }
  .hero-slide.has-media .hero-copy .tag-pill { margin-bottom: 1rem !important; }
  .hero-slide.has-media .hero-copy .btn-lg {
    font-size: 1rem; padding: .6rem 1.1rem; margin-right: 0 !important;
  }
  .hero-slide.has-media .hero-copy .btn-lg + .btn-lg { margin-top: .5rem; }
  .hero-slide { min-height: 460px; }
}
/* Landscape phones, and any other viewport that is short rather than narrow:
   every min-height floor above (460px desktop, 560px portrait) was sized
   against a laptop window or a tall phone, not a screen that is itself only
   350-430px tall — at 844x390 the hero alone used to be taller than the whole
   screen. Gated on height, not width, because that is the actual constraint;
   a landscape phone can be wide (844px) or narrow (667px) and needs the same
   fix either way. Placed last so it overrides whichever of the two branches
   above actually matched. */
@media (max-height: 500px) and (orientation: landscape) {
  .hero-slide, .hero-slide.has-media { min-height: 0; }
  .hero-slide.has-media { max-height: 88vh; }
  .hero-slide.has-media .hero-inner { padding-top: .75rem !important; padding-bottom: .75rem !important; }
  .hero-slide.has-media .hero-copy .tag-pill { margin-bottom: .4rem !important; }
  .hero-slide.has-media .hero-copy .display-title {
    margin-bottom: .3rem !important;
    font-size: clamp(1.4rem, 2vw + 1rem, 2rem) !important;
  }
  .hero-slide.has-media .hero-copy .lead-im { margin-bottom: .5rem !important; line-height: 1.3; }
  .hero-slide.has-media .hero-actions { gap: .5rem 1rem; }
  /* The 44% share above is sized for a tall frame with room to spare below the
     buttons; here vertical space is the scarce resource, not horizontal, so
     the column widens enough for both CTAs to sit on one row instead of
     stacking and pushing the second one past the fold. */
  .hero-slide.has-media.hero-text-left .hero-copy,
  .hero-slide.has-media.hero-text-right .hero-copy,
  .hero-slide.has-media.hero-text-center .hero-copy {
    max-width: min(560px, 78%) !important;
  }
}

/* --- Footer ------------------------------------------------------------- */
.footer-im { background: var(--im-navy-dark); color: #cfd6e4; }
.footer-im a { color: #cfd6e4; text-decoration: none; }
.footer-im a:hover { color: var(--im-gold); }
.footer-im h6 { color: var(--im-gold); font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; }
.footer-mark { height: 52px; width: auto; }
.footer-social a {
  width: 44px; height: 44px; border-radius: 12px; display: inline-flex;
  align-items: center; justify-content: center; font-size: 1.25rem;
  background: rgba(255,255,255,.06); color: #cfd6e4;
  transition: background .2s ease, color .2s ease, transform .2s ease;
}
.footer-social a:hover { background: var(--im-gold); color: var(--im-navy); transform: translateY(-2px); }

/* ==========================================================================
   Continuously moving row (marquee).

   Base state — no JavaScript — is an ordinary horizontal scroll rail: wheel,
   swipe, Tab and arrow keys all work and every card is reachable. rail.js adds
   `.is-looping` once it has duplicated the row, and only then does anything
   move. That ordering is what keeps the page usable when the script is blocked.
   ========================================================================== */
.im-marquee {
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
  padding-block: .5rem 1.25rem;
  scrollbar-width: thin; scrollbar-color: var(--im-silver) transparent;
}
.im-marquee-track { display: flex; width: max-content; }
/* No flex gap — each item owns its trailing space via margin-right, so the
   -50% loop lands exactly on the copy boundary and the scroll is seamless. */
.im-marquee-item {
  flex: 0 0 auto; width: clamp(240px, 24vw, 300px);
  margin-right: 1.25rem; display: flex; scroll-snap-align: start;
}
.im-marquee-item > * { width: 100%; }

/* Looping state. The movement itself is written by rail.js as a `transform` on
   the track — see that file for why a CSS keyframe cannot coexist with a drag.
   All this rule does is take the row out of native scrolling and hand the
   horizontal gesture to the script. */
.im-marquee.is-looping {
  overflow: hidden; scroll-snap-type: none;
  /* The browser keeps vertical panning for the page, we take horizontal. This
     is what lets a swipe move the row without ever blocking scrolling past it. */
  touch-action: pan-y;
  /* No edge mask. A `mask-image` fade does not tint anything — it makes the
     card transparent — but over a white section that reads as a white wash
     eating the first and last card. The ends are cut clean instead; the row is
     visibly in motion, so nothing is needed to suggest it continues. */
}
.im-marquee.is-looping .im-marquee-track {
  will-change: transform;
  /* No transition: the offset is set every frame, and a transition would fight
     both the loop and the finger. */
  transition: none;
}
.im-marquee-track:focus-visible { outline: 2px solid var(--im-gold); outline-offset: 2px; }

/* Visual direction cards are wider than the plain rail items and they swell on
   hover — the row needs vertical and horizontal room so the growth and its
   shadow are not clipped by the marquee's own overflow. */
.im-marquee-item--visual { width: clamp(198px, 15.5vw, 238px); margin-right: 16px; }
/* The looping row clips to its own box, so the hover shadow needs somewhere to
   land: the offset plus its blur reaches roughly 30px below the card, and
   without this the shadow is sliced off square at the row's edge.
   Scoped to the directions row — the discounts ticker shares the `.marquee-bleed`
   wrapper but not this card, and it keeps the spacing it already had. */
.marquee-bleed .im-marquee { padding-block: .75rem 1.5rem; }
.section--directions .marquee-bleed .im-marquee { padding-block: 1rem 2rem; }

@media (max-width: 575px) { .im-marquee-item { width: 78vw; } }
/* Tablets: three cards across with the fourth peeking in. */
@media (min-width: 768px) and (max-width: 991.98px) {
  .im-marquee-item--visual { width: min(calc(30vw - 20px), 216px); margin-right: 14px; }
}
/* Phones: one card with a clear slice of the next one showing, so it is obvious
   the row continues and there is something to swipe to. Declared after the
   575px rule above so it wins for visual cards — both selectors carry the same
   specificity, and order is what separates them. The card is a square plus a
   caption, so the cap is what keeps it from growing taller than a small
   phone's viewport. */
@media (max-width: 767px) {
  .im-marquee-item--visual {
    width: min(calc(100vw - 108px), 224px); margin-right: 12px;
  }
}
/* Smallest phones still in use (360px and down): the card would otherwise take
   almost the whole width and leave no hint of the next one. */
@media (max-width: 380px) {
  .im-marquee-item--visual { width: min(calc(100vw - 96px), 208px); }
}
@media (prefers-reduced-motion: reduce) {
  /* The one mode with no automatic movement at all: rail.js never adds
     `.is-looping`, so nothing is cloned and nothing animates. The row falls
     back to a native scroll rail, so every card is still reachable by hand. */
  .im-marquee { overflow-x: auto; }
  .im-marquee-item { margin-right: 1.25rem; }
  .im-marquee-item--visual { margin-right: 20px; }
  .direction-visual-card,
  .direction-visual-card__media img,
  .direction-visual-card__count i { transition: none; }
  /* No swell, no zoom, no arrow nudge — but the card still answers the cursor
     through its border and shadow, so it is visibly a control. */
  .direction-visual-card:hover,
  .direction-visual-card:focus-visible { transform: none; }
  .direction-visual-card:hover .direction-visual-card__media img { transform: none; }
  .direction-visual-card:hover .direction-visual-card__count i { transform: none; }
  /* The gold hairline appears without being drawn in. */
  .direction-visual-card__content::before { transition: none; }
}

/* --- Bright, readable form card (auth + lead on dark sections) ----------- */
.form-card {
  background: #fff; border: 1px solid var(--im-silver);
  border-radius: var(--im-radius-card);
  box-shadow: 0 24px 60px rgba(0, 10, 36, .30);
  animation: form-pop .55s cubic-bezier(.22,.61,.36,1);
}
.form-card .form-label { color: var(--im-navy); font-weight: 700; }
.form-card .form-control, .form-card .form-select { background: #fff; color: var(--im-text); font-size: 1rem; }
.form-card .form-control::placeholder { color: #9aa1ad; }
.form-card .form-check-label { color: var(--im-text); }
@keyframes form-pop { from { opacity: 0; transform: translateY(18px) scale(.98); } to { opacity: 1; transform: none; } }
.form-card .form-control:focus, .form-card .form-select:focus {
  border-color: var(--im-gold); box-shadow: 0 0 0 .22rem rgba(252,163,17,.22);
}
@media (prefers-reduced-motion: reduce) { .form-card { animation: none; } }

.edit-hint { font-size: .78rem; color: #B9C6EA; text-decoration: none; }
.edit-hint:hover { color: var(--im-gold); }

/* --- «Как мы учим» (О нас): вертикальный золотой таймлайн ---------------- */
/* --- Notification bell (header / panel topbar) --------------------------- */
.notif-bell {
  position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 42px; height: 42px; border-radius: 50%;
  color: #fff; font-size: 1.25rem; text-decoration: none;
  transition: background .2s ease, color .2s ease;
}
.navbar-im .notif-bell:hover { background: rgba(255,255,255,.1); color: var(--im-gold); }
.crm-topbar .notif-bell { color: var(--im-navy); }
.crm-topbar .notif-bell:hover { background: #fff7ea; color: var(--im-gold); }
.notif-dot {
  position: absolute; top: 3px; right: 1px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 999px; background: var(--im-error);
  color: #fff; font-size: .62rem; font-weight: 800; line-height: 17px;
  text-align: center; box-shadow: 0 0 0 2px var(--im-navy);
  animation: notif-pop .4s cubic-bezier(.22,.61,.36,1);
}
.crm-topbar .notif-dot { box-shadow: 0 0 0 2px #fff; }
@keyframes notif-pop { from { transform: scale(0); } to { transform: scale(1); } }

/* Gentle attention pulse for a primary call-to-action */
.pulse-cta { animation: cta-pulse 2.6s ease-in-out infinite; }
@keyframes cta-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(252,163,17,.0); }
  50% { box-shadow: 0 0 0 .5rem rgba(252,163,17,.16); }
}
.pulse-cta:hover { animation: none; }
@media (prefers-reduced-motion: reduce) { .pulse-cta { animation: none; } }

/* --- «Как проходит обучение»: минималистичный золотой путь ---------------
   Тонкая золотая линия соединяет нумерованные узлы — последовательность
   шагов обучения (сигнатура: «ключ открывает двери» по порядку). */
.journey { position: relative; }
.journey::before {
  content: ""; position: absolute; top: 33px; left: 13%; right: 13%; height: 2px;
  background: linear-gradient(90deg, transparent, rgba(252,163,17,.5) 8%,
              rgba(252,163,17,.5) 92%, transparent); z-index: 0;
}
@media (max-width: 991px) { .journey::before { display: none; } }
.journey-step { position: relative; z-index: 1; text-align: center; padding-inline: .4rem; }
.journey-node {
  width: 66px; height: 66px; margin: 0 auto 1.1rem; border-radius: 50%;
  background: var(--im-navy); border: 2px solid var(--im-gold); color: var(--im-gold);
  font-family: "Montserrat", sans-serif; font-weight: 800; font-size: 1.45rem;
  display: flex; align-items: center; justify-content: center;
  transition: transform .3s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease, background .3s ease;
}
.journey-step:hover .journey-node {
  transform: translateY(-5px); background: var(--im-gold); color: var(--im-navy);
  box-shadow: 0 0 0 6px rgba(252,163,17,.14);
}
.journey-step h3 { color: #fff; }
.journey-step p { color: #B9C6EA; }

/* --- FAQ polish --------------------------------------------------------- */
.accordion-im .accordion-item { transition: box-shadow .2s ease, border-color .2s ease; }
.accordion-im .accordion-item:hover { border-color: var(--im-gold); box-shadow: 0 8px 24px rgba(20,33,61,.06); }
.accordion-im .accordion-button::after { filter: sepia(1) saturate(4) hue-rotate(3deg); }

/* --- Hover-reveal cards (mentors / partners) ---------------------------- */
.reveal-card { position: relative; overflow: hidden; }
.reveal-card .reveal-more {
  position: absolute; inset: 0; padding: 1.25rem; display: flex;
  flex-direction: column; justify-content: center; text-align: center;
  background: linear-gradient(180deg, rgba(20,33,61,.94), rgba(0,10,36,.97));
  color: #fff; opacity: 0; transform: translateY(8px);
  transition: opacity .28s ease, transform .28s ease;
}
.reveal-card:hover .reveal-more, .reveal-card:focus-within .reveal-more { opacity: 1; transform: none; }
.reveal-card .reveal-more h3, .reveal-card .reveal-more h4 { color: #fff; }
.reveal-card .reveal-more .text-gold { color: var(--im-gold) !important; }

/* --- Smoother global motion --------------------------------------------- */
/* Animated page title (letters rise + gold sweep) */
.title-animate span { display: inline-block; opacity: 0; transform: translateY(24px);
  animation: title-rise .6s cubic-bezier(.22,.61,.36,1) forwards; }
.title-animate span:nth-child(3) { color: var(--im-gold); }
@keyframes title-rise { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .title-animate span { opacity: 1; transform: none; animation: none; } }

html { scroll-behavior: smooth; }
.btn, .card-im, .nav-link, .direction-visual-card { transition-timing-function: cubic-bezier(.22,.61,.36,1); }
.reveal { transition: opacity .7s cubic-bezier(.22,.61,.36,1), transform .7s cubic-bezier(.22,.61,.36,1); }

/* --- Reveal animation ----------------------------------------------------
   Starts hidden and is un-hidden by the IntersectionObserver in app.js. The
   `.js-reveal` gate on <html> is what makes that safe: with no JavaScript the
   class is never added, so the rule below never applies and the content is
   simply visible. Without the gate, a blocked script left every revealed
   section on the public site permanently at opacity 0. */
html.js-reveal .reveal {
  opacity: 0; transform: translateY(26px);
  transition: opacity .6s ease, transform .6s ease;
}
html.js-reveal .reveal.revealed { opacity: 1; transform: none; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .card-im, .btn { transition: none; }
  /* JS already stops auto-advancing; a manual switch (dot, swipe, arrow key)
     still works, just without the slide-in motion. */
  .hero-slide.active { animation: none; }
}

/* --- Misc ---------------------------------------------------------------- */
.badge-status { border-radius: 999px; font-weight: 700; font-size: .72rem; padding: .4em .9em; letter-spacing: .04em; }
/* "Бесплатно" is the strongest claim on the card, so it gets the brand navy
   rather than another pastel status pill — it has to win the row against the
   gold "Скоро" beside it without turning the card into a traffic light. */
.badge-free { background: var(--im-navy); color: #fff; text-transform: uppercase; letter-spacing: .08em; }

/* Whole-row target for the group choice: on a phone the radio dot alone is a
   16px tap target sitting next to three lines of text people naturally aim at. */
.join-group { border: 1px solid var(--im-silver); border-radius: var(--im-radius-input); padding: .8rem 1rem; cursor: pointer; transition: border-color .15s, background .15s; }
.join-group:hover { border-color: var(--im-gold); }
.join-group:has(input:checked) { border-color: var(--im-gold); background: rgba(252, 163, 17, .07); }
.join-group:focus-within { outline: 2px solid var(--im-gold); outline-offset: 2px; }
.announcement-bar { background: var(--im-gold); color: var(--im-navy); font-weight: 700; }
.table-im th { font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; color: var(--im-text-soft); border-bottom: 2px solid var(--im-silver); }
.table-im td { vertical-align: middle; }
.accordion-im .accordion-button { font-weight: 700; color: var(--im-navy); background: var(--im-white); border-radius: var(--im-radius-input) !important; }
.accordion-im .accordion-button:not(.collapsed) { color: var(--im-navy); background: #fff7ea; box-shadow: none; }
.accordion-im .accordion-item { border: 1px solid var(--im-silver); border-radius: var(--im-radius-input); margin-bottom: .6rem; overflow: hidden; }
/* ==========================================================================
   Tariff cards.
   Each card is a column of fixed bands, so the name, price, per-month figure
   and button sit on the same line across every card even when one tariff name
   wraps to two lines.
   ========================================================================== */
.price-tag { font-family: "Montserrat", sans-serif; font-weight: 900; font-size: 2.2rem; color: var(--im-navy); }
.band-navy .price-tag { color: var(--im-gold); }
.price-card {
  position: relative; display: flex; flex-direction: column; text-align: center;
  padding: 1.5rem 1.15rem 1.3rem;
  transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}
.price-card:hover { transform: translateY(-6px); }
.price-card.is-featured {
  border: 1px solid var(--im-gold); box-shadow: 0 16px 40px rgba(252,163,17,.14);
}
/* Reserved strip that keeps unbadged cards level with the badged one. A fixed
   height, not min-height: the badge is a shade taller than its text box, and
   the few pixels of difference pushed every band below it out of line. */
.price-card-flag {
  height: 1.8rem; margin-bottom: .3rem;
  display: flex; align-items: center; justify-content: center;
}
.price-badge {
  display: inline-block; background: var(--im-gold); color: var(--im-navy-dark);
  font-size: .66rem; font-weight: 800; letter-spacing: .07em;
  text-transform: uppercase; padding: .22rem .7rem; border-radius: 999px;
  white-space: nowrap;
}
/* Fixed two-line band. A one-line and a two-line tariff name must occupy the
   same height, or every row below it shifts and the cards stop lining up.
   Clamped at two lines so an unusually long name cannot break the grid. */
.price-name {
  font-size: .78rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: #B9C6EA; margin: 0 0 .15rem;
  line-height: 1.25; height: 2.5em;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: break-word;
}
.price-period {
  font-size: .76rem; color: #8E9DC4; margin: 0 0 .6rem;
  line-height: 1.3; height: 1.3em; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.price-amount { display: flex; align-items: baseline; justify-content: center; gap: .3rem; }
.price-currency { font-size: .8rem; color: #B9C6EA; }
/* Two optional lines (per-month, saving) — a fixed band, so a tariff with
   neither still lines up with one that has both. */
.price-extra {
  height: 3.2em; margin-top: .45rem; line-height: 1.6;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.price-permonth { font-size: .8rem; color: var(--im-gold); font-weight: 700; }
.price-saving { font-size: .76rem; color: #9FE0BC; }
.price-cta { margin-top: auto; width: 100%; }
.price-note { color: #B9C6EA; font-size: .88rem; max-width: 62ch; margin-inline: auto; }
.price-note :last-child { margin-bottom: 0; }

@media (max-width: 575.98px) {
  .price-card { padding: 1.2rem .8rem 1.1rem; }
  .price-tag { font-size: 1.6rem; }
  /* Narrower cards wrap more, so the name band grows to three lines. */
  .price-name {
    font-size: .7rem; letter-spacing: .04em;
    height: 3.75em; -webkit-line-clamp: 3;
  }
  .price-extra { height: 3.4em; }
  .price-cta { font-size: .8rem; }
}
.ratio-video { border-radius: var(--im-radius-card); overflow: hidden; border: 1px solid var(--im-silver); }
/* Логотип партнёра показывается в его собственных цветах. Раньше здесь стояли
   grayscale(1) и opacity .75, а цвет возвращался по наведению — на телефоне
   наведения нет, и логотип оставался блёклым серым пятном навсегда.
   width/height: auto снимают размер из атрибутов разметки, иначе картинка
   получает 400×200 и предел по высоте считается от растянутой рамки. */
.partner-logo {
  /* Постоянная площадка вместо пределов max-*: место под логотип занято ещё
     до загрузки файла (картинки отложенные), поэтому лента не дёргается, а
     логотипы разной формы стоят в ряд по одной линии. `scale-down` вписывает
     большой файл целиком и не растягивает маленький. */
  width: 190px; height: 64px;
  object-fit: scale-down;
}
.breadcrumb-im a { color: var(--im-text-soft); text-decoration: none; }
.progress-im { height: 10px; border-radius: 999px; background: var(--im-silver); }
.progress-im .progress-bar { background: var(--im-gold); border-radius: 999px; }
.avatar-circle { width: 44px; height: 44px; border-radius: 50%; object-fit: cover; background: var(--im-silver); display: inline-flex; align-items: center; justify-content: center; color: var(--im-navy); font-weight: 800; }
.route-step { border-left: 3px solid var(--im-silver); padding-left: 1rem; }
.route-step.mandatory { border-color: var(--im-error); }
.route-step.recommended { border-color: var(--im-gold); }
.route-step.mastered { border-color: #2e7d32; }
.route-step.advanced { border-color: var(--im-navy); }
.lesson-body img { max-width: 100%; border-radius: var(--im-radius-input); }
.lesson-body table { width: 100%; border-collapse: collapse; margin: 1rem 0; }
.lesson-body table td, .lesson-body table th { border: 1px solid var(--im-silver); padding: .5rem .7rem; }
.lesson-body pre { background: var(--im-navy-dark); color: #e5e5e5; padding: 1rem; border-radius: var(--im-radius-input); overflow-x: auto; }
.lesson-body blockquote { border-left: 3px solid var(--im-gold); padding: .2rem 0 .2rem 1rem; margin: 1rem 0; color: var(--im-text-soft); }
.lesson-body > *:first-child { margin-top: 0; }
.lesson-body > *:last-child { margin-bottom: 0; }

/* Imported lesson content.
   A course package brings glossary and rubric tables with long Russian prose in
   three columns. On a phone one of those measures ~1400px inside a ~300px
   column: `width: 100%` cannot shrink it below its own minimum, so without a
   scrolling wrapper the definition column is simply cut off the screen with no
   way to reach it — the terms table of every lesson, unreadable. The wrapper
   scrolls sideways on its own and the page never does. */
.lesson-body .im-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 1rem 0;
  /* Room for the scrollbar so it does not sit on the last row. */
  padding-bottom: .25rem;
}
.lesson-body .im-table-wrap > table { margin: 0; }
/* Below this the table stops shrinking and starts scrolling instead of
   squeezing every word onto its own line. */
.lesson-body .im-table { min-width: 34rem; }
.lesson-body .im-table th {
  background: var(--im-cloud, #f5f6f8);
  text-align: left;
  font-weight: 700;
}
.lesson-body .im-table tbody tr:nth-child(even) { background: rgba(0, 0, 0, .02); }

/* A boxed note carried over from the package ("Маршрут:", "Безопасность:"). */
.lesson-body .im-note {
  border-left: 3px solid var(--im-gold);
  background: rgba(0, 0, 0, .03);
  border-radius: var(--im-radius-input);
  padding: .75rem 1rem;
  color: inherit;
}
.lesson-body .im-note p:last-child { margin-bottom: 0; }

.lesson-body .im-visual { margin: 1.5rem 0; }
.lesson-body .im-visual img {
  width: 100%;
  height: auto;          /* never crop a diagram — it is the teaching material */
  display: block;
}
.lesson-body .im-visual figcaption {
  margin-top: .5rem;
  font-size: .9rem;
  color: var(--im-text-soft);
}

@media (max-width: 575.98px) {
  /* Narrower gutters buy back real width for the scrolling tables. */
  .lesson-body .im-table th, .lesson-body .im-table td { padding: .45rem .55rem; }
}

/* ==========================================================================
   Rich-text content classes.
   The editor writes these classes instead of inline `style`, so the server
   sanitizer needs only a tag/attribute allow-list. Shared by the editor
   surface and the rendered lesson so what a mentor sees is what a student gets.
   ========================================================================== */
.im-ff-sans    { font-family: "Manrope", system-ui, sans-serif; }
.im-ff-display { font-family: "Montserrat", sans-serif; }
.im-ff-serif   { font-family: Georgia, "Times New Roman", serif; }
.im-ff-mono    { font-family: ui-monospace, "Cascadia Code", Consolas, monospace; }

.im-fs-xs { font-size: .78em; }
.im-fs-sm { font-size: .9em; }
.im-fs-lg { font-size: 1.2em; }
.im-fs-xl { font-size: 1.45em; }

.im-c-navy    { color: var(--im-navy); }
.im-c-gold    { color: var(--im-gold); }
.im-c-muted   { color: var(--im-text-soft); }
.im-c-success { color: #198754; }
.im-c-danger  { color: var(--im-error); }

.im-hl-gold   { background: #FDE9C8; padding: 0 .18em; border-radius: 3px; }
.im-hl-silver { background: var(--im-silver); padding: 0 .18em; border-radius: 3px; }
.im-hl-mint   { background: #D6F5E3; padding: 0 .18em; border-radius: 3px; }

.im-ta-left { text-align: left; } .im-ta-center { text-align: center; }
.im-ta-right { text-align: right; } .im-ta-justify { text-align: justify; }

.im-hr { border: 0; border-top: 2px solid var(--im-silver); margin: 1.6rem 0; }
.im-formula { font-family: Georgia, serif; }
.im-table { width: 100%; border-collapse: collapse; }
.im-table th { background: var(--im-surface); font-weight: 700; text-align: left; }

/* Link to an external material with the mentor's explanation underneath. */
.im-material {
  border: 1px solid var(--im-silver); border-left: 3px solid var(--im-gold);
  border-radius: var(--im-radius-input); padding: .85rem 1rem; margin: 1rem 0;
  background: #fff;
}
.im-material-link { font-weight: 700; color: var(--im-navy); text-decoration: none; }
.im-material-link:hover { color: var(--im-gold); text-decoration: underline; }
.im-material-link::before { content: "\F1C5"; font-family: bootstrap-icons; margin-right: .45rem; color: var(--im-gold); }
.im-material-desc { margin: .35rem 0 0; font-size: .9rem; color: var(--im-text-soft); }

/* ==========================================================================
   Lesson video player — our chrome over an unlisted YouTube embed.
   The shield sits above the iframe so no YouTube UI is ever clickable.
   ========================================================================== */
.im-player {
  background: var(--im-navy-dark); border-radius: var(--im-radius-card);
  overflow: hidden; position: relative; user-select: none;
}
.im-player:focus { outline: none; }
.imp-stage { position: relative; aspect-ratio: 16 / 9; background: #000; }
.imp-stage iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* Nothing reaches the iframe: no logo click, no title bar, no end-screen links. */
.imp-shield { position: absolute; inset: 0; cursor: pointer; background: transparent; }

.imp-center { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.imp-big {
  pointer-events: auto; width: 74px; height: 74px; border-radius: 50%; border: 0;
  background: rgba(252,163,17,.94); color: var(--im-navy-dark); font-size: 2.1rem;
  display: grid; place-items: center; cursor: pointer;
  box-shadow: 0 10px 34px rgba(0,0,0,.45); transition: transform .16s ease;
}
.imp-big:hover { transform: scale(1.07); }
.imp-error { color: #fff; background: rgba(0,0,0,.6); padding: .9rem 1.2rem; border-radius: 12px; margin: 0; font-size: .92rem; max-width: 32ch; text-align: center; }

.imp-spinner { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.imp-spinner span {
  width: 42px; height: 42px; border-radius: 50%;
  border: 3px solid rgba(255,255,255,.25); border-top-color: var(--im-gold);
  animation: imp-spin .8s linear infinite;
}
@keyframes imp-spin { to { transform: rotate(360deg); } }

.imp-ended {
  position: absolute; inset: 0; background: rgba(0,10,36,.92);
  display: grid; place-items: center; align-content: center; gap: .9rem; text-align: center;
}
.imp-ended-title { color: #fff; font-family: "Montserrat", sans-serif; font-weight: 800; margin: 0; }
.imp-replay {
  border: 0; border-radius: 999px; padding: .55rem 1.3rem; cursor: pointer;
  background: var(--im-gold); color: var(--im-navy-dark); font-weight: 700;
}

.imp-bar { background: var(--im-navy-dark); padding: .1rem .8rem .55rem; }
.imp-seek { position: relative; height: 16px; cursor: pointer; display: flex; align-items: center; }
.imp-seek::before { content: ""; position: absolute; left: 0; right: 0; height: 4px; border-radius: 999px; background: rgba(255,255,255,.22); }
.imp-seek-buffer { position: absolute; left: 0; height: 4px; border-radius: 999px; background: rgba(255,255,255,.35); width: 0; }
.imp-seek-played { position: absolute; left: 0; height: 4px; border-radius: 999px; background: var(--im-gold); width: 0; }
.imp-seek-knob {
  position: absolute; left: 0; width: 12px; height: 12px; border-radius: 50%;
  background: var(--im-gold); transform: translateX(-50%); opacity: 0; transition: opacity .15s ease;
}
.imp-seek:hover .imp-seek-knob, .imp-seek:focus-visible .imp-seek-knob { opacity: 1; }
.imp-seek:focus-visible { outline: 2px solid var(--im-gold); outline-offset: 3px; }

.imp-controls { display: flex; align-items: center; gap: .15rem; color: #fff; }
.imp-btn {
  border: 0; background: transparent; color: #fff; width: 34px; height: 34px;
  border-radius: 8px; display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; font-size: 1rem;
}
.imp-btn:hover { background: rgba(255,255,255,.14); color: var(--im-gold); }
.imp-speed { width: auto; padding: 0 .5rem; font-size: .82rem; font-weight: 700; }
.imp-time { font-size: .8rem; color: rgba(255,255,255,.85); margin-left: .4rem; white-space: nowrap; }
.imp-time b { color: #fff; font-weight: 600; }
.imp-spacer { flex: 1; }
.imp-volume { display: flex; align-items: center; gap: .25rem; }
.imp-vol-range { width: 74px; accent-color: var(--im-gold); background: transparent; cursor: pointer; }
@media (max-width: 575.98px) {
  .imp-vol-range { display: none; }
  .imp-time { font-size: .72rem; }
}
.im-player.is-fullscreen { border-radius: 0; display: flex; flex-direction: column; justify-content: center; background: #000; }
.im-player.is-fullscreen .imp-stage { flex: 1; aspect-ratio: auto; }

/* Notice shown under the player: our own material, not for redistribution. */
.imp-note { font-size: .78rem; color: var(--im-text-soft); margin: .5rem 0 0; }

/* --- Rich-text editor chrome -------------------------------------------- */
.rt-wrap { border: 1px solid var(--im-silver); border-radius: var(--im-radius-input); background: #fff; overflow: hidden; }
.rt-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .25rem;
  padding: .4rem .5rem; background: var(--im-surface);
  border-bottom: 1px solid var(--im-silver);
}
/* Groups wrap too: without this the font+size pair overflowed the toolbar on
   a phone and its right-hand control became unreachable. */
.rt-group {
  display: flex; align-items: center; gap: .15rem; flex-wrap: wrap;
  padding-right: .4rem; border-right: 1px solid var(--im-silver);
}
.rt-group:last-child { border-right: 0; padding-right: 0; }
.rt-btn {
  border: 0; background: transparent; color: var(--im-navy);
  width: 30px; height: 30px; border-radius: 7px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center;
}
.rt-btn:hover { background: var(--im-silver); }
.rt-btn:active { background: var(--im-gold); color: #fff; }
.rt-select {
  border: 1px solid var(--im-silver); border-radius: 7px; background: #fff;
  font-size: .82rem; padding: .18rem .3rem; color: var(--im-text);
  max-width: 180px; min-width: 0; flex: 0 1 auto;
}
.rt-select-sm { max-width: 130px; }
.rt-hint { color: var(--im-text-soft); font-size: .85rem; margin-right: .15rem; }
.rt-swatches { gap: .2rem; }
.rt-swatch {
  width: 18px; height: 18px; border-radius: 5px; border: 1px solid rgba(0,0,0,.18);
  padding: 0; cursor: pointer;
}
.rt-swatch:hover { transform: scale(1.15); }
.rt-area {
  min-height: 260px; padding: 1rem 1.1rem; outline: none; overflow-y: auto;
  max-height: 70vh; background: #fff;
}
.rt-area:focus { box-shadow: inset 0 0 0 2px rgba(252,163,17,.35); }
.rt-area:empty::before { content: attr(data-placeholder); color: #9aa0a6; }
textarea.rt-source { display: none; }
.rt-show-source textarea.rt-source {
  display: block; width: 100%; border: 0; border-top: 1px solid var(--im-silver);
  font-family: ui-monospace, Consolas, monospace; font-size: .82rem; padding: .8rem 1rem;
  min-height: 200px; resize: vertical;
}
.rt-show-source .rt-area { display: none; }

/* Phones: let the two dropdowns share the row instead of forcing a scroll,
   and keep the editing surface tall enough to be usable. */
@media (max-width: 575.98px) {
  .rt-toolbar { gap: .3rem .2rem; padding: .45rem .4rem; }
  .rt-group { padding-right: .3rem; }
  .rt-select { max-width: 100%; flex: 1 1 8rem; }
  .rt-select-sm { flex: 1 1 6rem; }
  .rt-area { min-height: 220px; padding: .85rem .9rem; }
}

/* Touch devices: 30px icons are below a comfortable tap target. */
@media (pointer: coarse) {
  .rt-btn { width: 38px; height: 38px; }
  .rt-swatch { width: 24px; height: 24px; }
  .rt-select { padding: .35rem .4rem; font-size: .88rem; }
}

/* ==========================================================================
   Invoice ("Счёт на оплату") and payment method cards.
   ========================================================================== */
.invoice { padding: 2rem 2.2rem; }
.invoice-head {
  display: flex; flex-wrap: wrap; justify-content: space-between;
  align-items: flex-start; gap: 1rem;
  border-bottom: 2px solid var(--im-silver); padding-bottom: 1.2rem;
}
.invoice-kind {
  display: block; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .12em; color: var(--im-gold); font-weight: 800;
  margin-bottom: .3rem;
}
.invoice-body { padding: 1.4rem 0; }
.invoice-label {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .09em;
  color: var(--im-text-soft); font-weight: 700; margin-bottom: .5rem;
}
.invoice-table { width: 100%; border-top: 1px solid var(--im-silver); }
.invoice-table td { padding: .55rem 0; }
.invoice-table tfoot td {
  border-top: 2px solid var(--im-navy); padding-top: 1rem; vertical-align: middle;
}

.pm-logo { width: 34px; height: 34px; object-fit: contain; border-radius: 7px; }
.payment-method .pm-row {
  display: flex; justify-content: space-between; align-items: center;
  gap: .6rem; padding: .35rem 0; border-bottom: 1px dashed var(--im-silver);
  font-size: .9rem;
}
.payment-method .pm-row:last-of-type { border-bottom: 0; }
.payment-method .pm-row > span:first-child { color: var(--im-text-soft); }
.payment-method code {
  font-size: .95rem; font-weight: 700; color: var(--im-navy);
  overflow-wrap: anywhere;
}

@media (max-width: 575.98px) {
  .invoice { padding: 1.3rem 1.1rem; }
  .invoice-head { flex-direction: column; }
}

/* "О нас" presentation video and grouped contact blocks. */
.about-video {
  border-radius: var(--im-radius-card); overflow: hidden;
  background: var(--im-navy-dark);
  box-shadow: 0 18px 48px rgba(20, 33, 61, .16);
}
.about-video iframe { border: 0; }

.contact-block {
  display: flex; align-items: flex-start; gap: 1rem; padding: 1.25rem 1.4rem;
  text-align: left;
}
.contact-block .icon-circle { flex: 0 0 auto; }
.contact-block .contact-label {
  display: block; font-size: .72rem; text-transform: uppercase;
  letter-spacing: .09em; color: var(--im-text-soft); margin-bottom: .25rem;
}
.contact-block .contact-value {
  color: var(--im-navy); font-weight: 700; text-decoration: none;
  line-height: 1.5;
}
.contact-block a.contact-value:hover { color: var(--im-gold); }

/* ==========================================================================
   Document pages: an editorial reading column, brand palette only.
   ========================================================================== */
.doc-page { max-width: 74ch; margin: 0 auto; }
.doc-head { border-bottom: 2px solid var(--im-silver); padding-bottom: 1.2rem; }
.doc-meta { display: flex; flex-wrap: wrap; gap: .25rem 1.1rem; }
.doc-actions { display: flex; flex-wrap: wrap; gap: .5rem; }
.doc-body {
  margin-top: 1.8rem; font-size: 1.02rem; line-height: 1.75;
  overflow-wrap: break-word;
}
.doc-body h2 { font-size: 1.3rem; margin: 2rem 0 .7rem; }
.doc-body h3 { font-size: 1.1rem; margin: 1.5rem 0 .5rem; }
.doc-body p, .doc-body li { color: var(--im-text); }
.doc-body ol, .doc-body ul { padding-left: 1.4rem; }
.doc-body li { margin-bottom: .4rem; }
.doc-body table { display: block; overflow-x: auto; }

.page-hero-doc {
  position: relative; overflow: hidden; background: var(--im-navy);
}
.page-hero-decor {
  position: absolute; inset: auto 0 0 0; width: 100%; height: 100%;
  pointer-events: none;
}

.doc-card { transition: border-color .16s ease, transform .16s ease; }
.doc-card:hover { border-color: var(--im-gold); transform: translateY(-2px); }
.doc-card h2 { color: var(--im-navy); }
.doc-card-icon {
  width: 42px; height: 42px; flex: 0 0 42px; border-radius: 11px;
  background: var(--im-silver); color: var(--im-navy);
  display: grid; place-items: center; font-size: 1.15rem;
}
.doc-card:hover .doc-card-icon { background: var(--im-gold); color: var(--im-navy-dark); }
.doc-card-arrow { color: var(--im-silver); align-self: center; }
.doc-card:hover .doc-card-arrow { color: var(--im-gold); }

@media print {
  .footer-im, .navbar, .doc-actions, .breadcrumb-im { display: none !important; }
  .doc-page { max-width: none; }
  body { background: #fff; }
}

/* Referral / public ID chip — monospaced so characters can be read out. */
.referral-id {
  font-family: ui-monospace, Consolas, monospace; font-weight: 700;
  font-size: 1rem; letter-spacing: .06em; color: var(--im-navy);
  background: var(--im-silver); border-radius: 8px; padding: .25rem .6rem;
}

/* Wide Bootstrap gutters (g-4/g-5) apply a negative row margin larger than
   the container's padding, which pushed sections past the right edge on a
   phone. Narrow the gutter instead of the container so the grid still breathes
   on desktop. */
/* Applies up to the lg breakpoint: a container's horizontal padding is only
   half the gutter, so g-5 (3rem) overflows by 12px per side at every width
   below the point where the container gains its wider padding. */
@media (max-width: 991.98px) {
  .row.g-5, .row.gx-5 { --bs-gutter-x: 1.5rem; }
}
@media (max-width: 575.98px) {
  .row.g-5, .row.gx-5 { --bs-gutter-x: 1.25rem; }
  .row.g-4, .row.gx-4 { --bs-gutter-x: 1.25rem; }
}

/* Data tables scroll inside their own box instead of pushing the whole page
   sideways. Applied to the containers every table actually lives in, rather
   than by wrapping each of the ~40 table templates — that way no listing page
   can be missed and none can silently regress. Kept in app.css because
   crm.css is only loaded by the panel shell, while tables also appear in the
   student and parent cabinets and on public pages. */
@media (max-width: 991.98px) {
  .crm-card table, .card-im table, .crm-content table {
    display: block; width: 100%; max-width: 100%;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
  }
  .crm-card table > thead, .crm-card table > tbody,
  .card-im table > thead, .card-im table > tbody,
  .crm-content table > thead, .crm-content table > tbody {
    display: table; width: 100%; min-width: max-content;
  }
  .crm-card table td, .crm-card table th,
  .card-im table td, .card-im table th,
  .crm-content table td, .crm-content table th { white-space: nowrap; }
  /* Opt-out for a cell that should keep wrapping (long titles, notes). */
  .crm-card table .wrap, .card-im table .wrap,
  .crm-content table .wrap { white-space: normal; min-width: 12rem; }
}

/* --- Polish & accessibility --------------------------------------------- */
/* Visible keyboard focus everywhere. */
a:focus-visible, button:focus-visible, .btn:focus-visible,
.form-control:focus-visible, .form-select:focus-visible,
.accordion-button:focus-visible {
  outline: 2px solid var(--im-gold); outline-offset: 3px; box-shadow: none;
}

/* Team / mentor avatars: quiet gold ring that lifts on hover. */
.mentor-card { text-align: center; }
.mentor-card .avatar-circle {
  border: 3px solid var(--im-silver); transition: border-color .25s ease, transform .25s ease;
}
.mentor-card:hover .avatar-circle { border-color: var(--im-gold); transform: translateY(-3px); }

/* Big brand numbers share one rhythm instead of ad-hoc inline sizes. */
.stat-num { font-family: "Montserrat", sans-serif; font-weight: 900; line-height: 1;
  font-size: clamp(1.9rem, 4vw, 2.6rem); color: var(--im-navy); }
.band-navy .stat-num { color: var(--im-gold); }
.stat-label { font-size: .78rem; color: var(--im-text-soft); }
.band-navy .stat-label { color: #B9C6EA; }

/* Editorial hairline between stacked bands of the same tone. */
.hairline { height: 1px; background: var(--im-silver); border: 0; opacity: .8; }
.band-navy .hairline { background: rgba(255,255,255,.12); }

/* ==========================================================================
   Design refinement layer — motion tokens, press feedback, touch-safe
   hovers, brand selection & scrollbar. Additive polish only: no structural,
   content, or layout changes. Every motion here respects reduced-motion.
   ========================================================================== */
:root {
  /* Stronger-than-default curves (built-in CSS easings feel weak). */
  --ease-out: cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);
  --ease-spring: cubic-bezier(.34, 1.38, .64, 1);
  --dur-press: 150ms;
  --dur-ui: 220ms;
}

/* Brand text selection. */
::selection { background: var(--im-gold); color: var(--im-navy); }
::-moz-selection { background: var(--im-gold); color: var(--im-navy); }

/* Anchor jumps (#methodology, #contacts …) land just below the sticky navbar
   instead of hiding under it — the accessible, native equivalent of a smooth-
   scroll library's offset. Pairs with the existing scroll-behavior: smooth. */
html { scroll-padding-top: 5.25rem; }

/* Press feedback — every pressable element confirms the tap (Emil: buttons
   must feel like the UI is listening). Named properties only, never `all`. */
.btn {
  transition: transform var(--dur-press) var(--ease-out),
              background-color var(--dur-ui) ease, border-color var(--dur-ui) ease,
              color var(--dur-ui) ease, box-shadow var(--dur-ui) ease;
}
.btn:active { transform: scale(.97); }
.btn-gold:hover, .btn-gold:focus-visible { transform: translateY(-1px); }
.btn-gold:active { transform: translateY(0) scale(.97); }

/* Land the existing card/link lifts on the stronger curve. */
.card-im, .direction-visual-card, .price-card, .reveal-card .reveal-more,
.timeline-card, .mentor-card .avatar-circle, .partner-logo {
  transition-timing-function: var(--ease-out);
}

/* Touch devices: never leave a hover-lift stuck after a tap. */
@media (hover: none) {
  .card-im:hover, .price-card:hover,
  .btn-gold:hover, .mentor-card:hover .avatar-circle { transform: none; }
  /* The visual card keeps a gentle lift on tap — it is the affordance that
     says the whole cover is one link — but never the hover zoom. */
  .direction-visual-card:hover { transform: none; }
  .direction-visual-card:hover .direction-visual-card__media img { transform: scale(.94); }
}

/* One clean gold underline for nav links — grows from the centre. The active
   page shows it on every device; hover grows it only on pointer devices. This
   fully replaces the old .active border-bottom, so there is a single line. */
.navbar-im .nav-link { position: relative; }
.navbar-im .nav-link::after {
  content: ""; position: absolute; left: 50%; right: 50%; bottom: .35rem; height: 2px;
  background: var(--im-gold); border-radius: 2px;
  transition: left var(--dur-ui) var(--ease-out), right var(--dur-ui) var(--ease-out);
}
.navbar-im .nav-link.active::after { left: .85rem; right: .85rem; }
@media (hover: hover) and (pointer: fine) {
  .navbar-im .nav-link:hover::after { left: .85rem; right: .85rem; }
}

/* Neat brand scrollbar on pointer devices — a floating rounded pill on a faint
   track, warming to gold on hover. Mobile keeps its native overlay bar. */
@media (pointer: fine) {
  * { scrollbar-width: thin; scrollbar-color: #b7c0d6 transparent; }
  ::-webkit-scrollbar { width: 12px; height: 12px; }
  ::-webkit-scrollbar-track { background: rgba(20, 33, 61, .04); border-radius: 999px; }
  ::-webkit-scrollbar-thumb {
    border-radius: 999px; border: 3px solid transparent; background-clip: content-box;
    background-color: #b7c0d6; transition: background-color .2s ease;
  }
  ::-webkit-scrollbar-thumb:hover { background-color: var(--im-gold); background-clip: content-box; }
  ::-webkit-scrollbar-corner { background: transparent; }
  /* On navy bands the same document scrollbar reads better a touch lighter. */
}

/* ---- Layout robustness: keep every element inside its box on all clients ----
   These guard against the classic causes of a "broken" responsive layout —
   oversized media, flex/grid children that refuse to shrink, unbreakable long
   strings, and stray horizontal scroll — without touching any structure. */
img, svg, video, iframe, canvas { max-width: 100%; }
.row > [class*="col"], .navbar-nav > .nav-item, .d-flex > * { min-width: 0; }
/* overflow-x: clip on the body (never on <html>, which would break vertical
   scrolling) trims stray horizontal overflow without creating a scroll
   container, so the sticky navbar and smooth scrolling keep working. */
body { overflow-x: clip; overflow-wrap: break-word; }
table { max-width: 100%; }

/* Progressive image reveal — JS adds .fade-in-ready then .is-loaded, so with
   no JS every image stays fully visible (content never depends on script). */
img.fade-in-ready { opacity: 0; }
img.is-loaded { opacity: 1; transition: opacity .55s var(--ease-out); }

@media (prefers-reduced-motion: reduce) {
  .btn, .btn:active, .btn-gold:active, .navbar-im .nav-link::after { transition: none; transform: none; }
  img.fade-in-ready { opacity: 1; }
}

/* ==========================================================================
   Главная страница — доработки разделов (только оформление/поведение).
   ========================================================================== */

/* Курсы: карточки аккуратнее и плавнее — мягкий зум обложки, чётче тень. */
.course-card-cover, .card-cover { transition: transform .5s var(--ease-out); }
.card-im:hover .card-cover { transform: scale(1.045); }
.card-im { transition: transform .28s var(--ease-out), box-shadow .28s var(--ease-out), border-color .28s var(--ease-out); }

/* Тарифы: компактные карточки с сохранением фирменного вида. */
.tariff-card { padding: 1.05rem .75rem; border-radius: 14px; }
.tariff-card .price-tag { font-size: 1.7rem; line-height: 1.02; }
.tariff-name { font-size: .66rem; letter-spacing: .1em; color: #B9C6EA; }
.tariff-cur { font-size: .72rem; color: #B9C6EA; }
.tariff-permonth { font-size: .72rem; }
.tariff-card--best { position: relative; }
@media (max-width: 575px) { .tariff-card .price-tag { font-size: 1.45rem; } }

/* Социальные программы: компактная плашка скидки. */
.discount-card { padding: .85rem 1rem; }
.discount-badge {
  flex: 0 0 auto; font-family: "Montserrat", sans-serif; font-weight: 900;
  font-size: 1.35rem; line-height: 1; color: var(--im-navy);
  background: var(--im-gold); border-radius: 12px; padding: .35rem .55rem; min-width: 3rem; text-align: center;
}
.discount-name { font-size: .92rem; font-weight: 700; line-height: 1.15; color: var(--im-navy); }
.discount-note { font-size: .76rem; line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* Контакты (О нас): аккуратные карточки — иконка-кружок, подпись, значение. */
.contact-card {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: .2rem; padding: 1.35rem 1rem; text-decoration: none; color: var(--im-text);
}
.contact-card .icon-circle { margin-bottom: .55rem; transition: background .25s ease, color .25s ease, transform .25s var(--ease-out); }
.contact-card:hover .icon-circle { background: var(--im-gold); color: var(--im-navy); transform: translateY(-2px); }
.contact-label { font-size: .68rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--im-text-soft); }
.contact-value { font-weight: 700; color: var(--im-navy); font-size: .95rem; line-height: 1.3; word-break: break-word; }
.contact-card:hover .contact-value { color: var(--im-gold); }

/* FAQ: плавнее и компактнее. */
.accordion-im .accordion-item { margin-bottom: .4rem; }
.accordion-im .accordion-button { padding: .8rem 1.05rem; transition: background-color .25s ease, color .25s ease; }
.accordion-im .accordion-body { padding: .35rem 1.05rem 1rem; font-size: .92rem; }
.accordion-im .accordion-button::after { transition: transform .35s var(--ease-out), filter .2s ease; }
.accordion-im .accordion-collapse { transition: height .35s var(--ease-out); }

/* ==========================================================================
   Sign-in / registration screens.
   Two columns from lg up: a brand panel that carries the identity and a white
   card that carries the form. Below lg the panel is dropped entirely — a phone
   should spend its screen on the fields, not on decoration.
   ========================================================================== */
.auth-shell {
  position: relative; overflow: hidden;
  background: var(--im-navy);
  padding: clamp(1.5rem, 5vw, 4rem) 0;
  min-height: calc(100vh - 76px);
  display: flex; align-items: center;
}
.auth-shell > .container { position: relative; z-index: 1; }
.auth-shell .section-decor { opacity: .55; }
.auth-grid { box-shadow: 0 30px 80px rgba(0, 10, 36, .38); border-radius: 22px; }
.auth-aside {
  flex-direction: column; justify-content: center;
  padding: clamp(2rem, 3vw, 3.25rem);
  background: linear-gradient(150deg, #16264a 0%, var(--im-navy-dark) 100%);
  border-radius: 22px 0 0 22px;
  color: #fff;
}
.auth-emblem { width: 88px; height: 88px; object-fit: contain; }
.auth-aside-title {
  font-family: "Montserrat", sans-serif; font-weight: 800; color: #fff;
  font-size: clamp(1.4rem, 1.6vw + .7rem, 2rem); line-height: 1.2;
}
.auth-aside-text { color: #B9C6EA; font-size: .98rem; line-height: 1.6; }
.auth-points li {
  display: flex; align-items: flex-start; gap: .7rem;
  color: #cdd5e6; font-size: .9rem; line-height: 1.45; margin-bottom: .85rem;
}
.auth-points li:last-child { margin-bottom: 0; }
.auth-points i { color: var(--im-gold); font-size: 1.05rem; line-height: 1.35; flex: none; }

/* stretch is the default, but it is spelled out because the two panels share a
   rounded frame — a few pixels of difference in height shows as a notch at the
   seam between them. */
.auth-main { display: flex; align-items: stretch; }
.auth-card {
  flex: 1; background: #fff; color: var(--im-text);
  border-radius: 22px;
  padding: clamp(1.5rem, 3vw, 2.6rem);
  animation: form-pop .5s cubic-bezier(.22,.61,.36,1);
  /* The card scrolls inside the frame instead of pushing the page: the
     registration form is long, and a laptop viewport should not need a
     full-page scroll to reach the submit button. */
  max-height: min(86vh, 900px); overflow-y: auto;
}
@media (min-width: 992px) { .auth-card { border-radius: 0 22px 22px 0; } }
.auth-card-head { text-align: center; margin-bottom: 1.35rem; }
.auth-card-logo { display: block; margin: 0 auto .6rem; object-fit: contain; }
.auth-card h1 { color: var(--im-navy); }
@media (prefers-reduced-motion: reduce) { .auth-card { animation: none; } }

/* "Кто вы": the choice that reshapes the form, so it is shown, not hidden in
   a select. Radio inputs stay real for keyboard and screen readers. */
.profile-choice legend { float: none; width: auto; }
.profile-options { display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem; }
@media (min-width: 480px) { .profile-options { grid-template-columns: repeat(4, 1fr); } }
.profile-option { margin: 0; cursor: pointer; }
.profile-option input { position: absolute; opacity: 0; width: 0; height: 0; }
.profile-option-body {
  display: flex; flex-direction: column; align-items: center; gap: .3rem;
  padding: .7rem .4rem; height: 100%; text-align: center;
  border: 1.5px solid var(--im-silver); border-radius: 14px;
  background: #fff; color: var(--im-text-soft);
  transition: border-color .18s ease, background .18s ease, color .18s ease;
}
.profile-option-body i { font-size: 1.25rem; color: var(--im-navy); }
.profile-option-label { font-size: .76rem; font-weight: 700; line-height: 1.2; }
.profile-option:hover .profile-option-body { border-color: var(--im-gold); }
.profile-option input:checked + .profile-option-body {
  border-color: var(--im-gold); background: rgba(252, 163, 17, .09);
  color: var(--im-navy);
}
.profile-option input:checked + .profile-option-body i { color: var(--im-gold); }
.profile-option input:focus-visible + .profile-option-body {
  outline: 2px solid var(--im-gold); outline-offset: 2px;
}

/* Step indicator for password recovery.

   Numbers only. A tick on a finished step would tell the visitor which of
   their three answers matched, which is precisely what the flow refuses to
   disclose — so "done" and "not yet reached" look the same, and only the
   current step is marked. */
.reset-steps {
  display: flex; gap: .4rem; justify-content: center;
  list-style: none; margin: 0 0 1.25rem; padding: 0;
}
.reset-steps li {
  flex: 1; max-width: 3.5rem; text-align: center;
  font-size: .8rem; font-weight: 700; line-height: 1.9;
  border-radius: 999px;
  border: 1.5px solid var(--im-silver);
  background: var(--im-surface); color: var(--im-text-soft);
}
.reset-steps li.is-current {
  border-color: var(--im-gold); background: var(--im-gold);
  color: var(--im-navy);
}

/* Password requirements under the field.

   Shown on hover, on focus, and while the field has anything in it — the last
   one is what matters: the rules have to stay visible for the whole time the
   person is typing, not disappear when the pointer drifts off.

   Collapsed with grid-template-rows rather than display:none so the opening
   is animated and the list is never removed from the accessibility tree —
   `aria-describedby` on the input points at it. Motion is dropped for anyone
   who asked for less of it. */
.password-help { position: relative; }
.password-rules {
  display: grid; grid-template-rows: 0fr;
  opacity: 0; visibility: hidden;
  transition: grid-template-rows .22s ease, opacity .18s ease,
              visibility .18s ease, margin-top .22s ease;
  margin-top: 0;
}
.password-help:hover .password-rules,
.password-help:focus-within .password-rules,
.password-help--open .password-rules {
  grid-template-rows: 1fr; opacity: 1; visibility: visible; margin-top: .55rem;
}
.password-rules__inner { min-height: 0; overflow: hidden; }
.password-rules__title {
  margin: 0 0 .35rem; font-size: .82rem; font-weight: 700;
  color: var(--im-navy);
}
.password-rules ul {
  list-style: none; margin: 0; padding: .7rem .85rem;
  border: 1px solid var(--im-silver); border-radius: var(--im-radius-input);
  background: var(--im-surface);
}
.password-rules li {
  display: flex; align-items: flex-start; gap: .5rem;
  font-size: .84rem; line-height: 1.4; color: var(--im-text-soft);
  transition: color .18s ease;
}
.password-rules li + li { margin-top: .35rem; }
.password-rules li i { font-size: .95rem; line-height: 1.3; flex: none; color: #9aa0ad; }
.password-rules li.is-ok { color: #146c43; }
.password-rules li.is-ok i { color: #198754; }

/* Inside the auth card the surface is already white, so the panel needs its
   own tint to read as a separate block rather than a stray paragraph. */
.auth-card .password-rules ul { background: #F4F6FB; border-color: #DEE4F1; }

@media (prefers-reduced-motion: reduce) {
  .password-rules { transition: none; }
}

/* Consents: the document names are links, so they must read as links even
   inside a small grey label. */
.consent-box {
  border: 1px solid var(--im-silver); border-radius: var(--im-radius-input);
  padding: .85rem 1rem; background: var(--im-surface);
}
.consent-box .form-check + .form-check { margin-top: .4rem; }
.doc-link { color: var(--im-navy); font-weight: 700; text-decoration: underline; }
.doc-link:hover { color: var(--im-gold); }

/* Document viewer: read the attached file in place, not only download it. */
.doc-viewer {
  border: 1px solid var(--im-silver); border-radius: var(--im-radius-card);
  overflow: hidden; background: var(--im-surface);
}
.doc-viewer object { display: block; width: 100%; height: min(78vh, 900px); border: 0; }
@media (max-width: 767px) { .doc-viewer object { height: 60vh; } }

/* ==========================================================================
   Home page, second pass (ТЗ §3–§8). Hero rules for this section now live in
   the main "--- Hero ---" block near the top of the file.
   ========================================================================== */

/* --- Full-bleed marquee row --------------------------------------------- */
.marquee-bleed { width: 100%; overflow: hidden; }


/* --- Tariffs: a comparison row ------------------------------------------ */
.tariff-card {
  position: relative; display: flex; flex-direction: column;
  justify-content: flex-start; gap: .1rem;
  padding: 1.5rem .85rem 1.15rem;
  transition: transform .25s var(--ease-out), border-color .25s ease, box-shadow .25s ease;
}
.tariff-card:hover { transform: translateY(-5px); border-color: rgba(252, 163, 17, .55); }
.tariff-card--best {
  border-color: var(--im-gold);
  box-shadow: 0 0 0 1px var(--im-gold) inset, 0 18px 40px rgba(0, 10, 36, .35);
  background: rgba(252, 163, 17, .09);
}
.tariff-flag {
  position: absolute; top: -.7rem; left: 50%; transform: translateX(-50%);
  white-space: nowrap; background: var(--im-gold); color: var(--im-navy);
  font-size: .6rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase; padding: .22rem .6rem; border-radius: 999px;
}
.tariff-permonth { font-size: .78rem; color: #B9C6EA; line-height: 1.3; }

/* --- Discounts ----------------------------------------------------------- */
.discount-card {
  display: flex; align-items: center; gap: .9rem;
  padding: 1rem 1.1rem; width: 100%;
}
.discount-text { min-width: 0; }

/* --- Lead section: "что дальше" beside the form -------------------------- */
.lead-steps li {
  display: flex; align-items: flex-start; gap: .9rem;
  color: #cdd5e6; font-size: .95rem; line-height: 1.5; margin-bottom: 1.1rem;
}
.lead-steps li:last-child { margin-bottom: 0; }
.lead-steps strong { color: #fff; }
.lead-step-no {
  flex: none; width: 32px; height: 32px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: "Montserrat", sans-serif; font-weight: 800; font-size: .9rem;
  color: var(--im-navy); background: var(--im-gold);
}
.lead-contacts { display: flex; flex-direction: column; gap: .5rem; }
.lead-contacts a { color: #cdd5e6; text-decoration: none; }
.lead-contacts a:hover { color: var(--im-gold); }

/* --- Checkout summary: the price the server just quoted ------------------ */
.checkout-summary { position: sticky; top: 96px; }
@media (max-width: 991.98px) { .checkout-summary { position: static; } }
.summary-lines { margin: 0; }
.summary-lines > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .45rem 0; border-bottom: 1px solid var(--im-silver);
}
.summary-lines dt { font-weight: 600; font-size: .88rem; color: var(--im-text-soft); margin: 0; }
.summary-lines dd { margin: 0; font-weight: 700; font-size: .92rem; text-align: right; }
.summary-total {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: 1rem; padding-top: .6rem;
}
.summary-total span { font-weight: 700; color: var(--im-navy); }
.summary-total strong {
  font-family: "Montserrat", sans-serif; font-weight: 900;
  font-size: 1.5rem; color: var(--im-navy); line-height: 1.1;
}

/* ==========================================================================
   Course page (ТЗ §5): the cover from the catalogue card, the facts as a
   grid, and one price card that carries the buy action.
   ========================================================================== */
.course-facts {
  display: grid; gap: .9rem 1.75rem; margin: 0;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
.course-facts > div { min-width: 0; }
.course-facts dt {
  display: flex; align-items: center; gap: .45rem;
  font-size: .68rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: #8fa0c9; margin-bottom: .2rem;
}
.course-facts dt i { color: var(--im-gold); font-size: .9rem; }
.course-facts dd {
  margin: 0; color: #fff; font-weight: 700; font-size: .95rem; line-height: 1.35;
  overflow-wrap: break-word;
}

.course-buy { background: rgba(255, 255, 255, .07); border-color: rgba(255, 255, 255, .14); }
.course-buy:hover { transform: none; }
/* The catalogue covers are square illustrations on a transparent field, so
   they are fitted whole rather than cropped — same treatment as the card. */
.course-buy-cover {
  /* height: auto по той же причине, что и у .card-cover. */
  display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: contain;
  padding: .8rem; background: linear-gradient(135deg, var(--im-navy) 0%, var(--im-navy-dark) 100%);
}
.course-buy-cover.cover-placeholder { font-size: 3rem; }
/* Фотографии урока. Сетка, а не карусель: три снимка помещаются рядом на
   ноутбуке и складываются в колонку на телефоне без скрытого содержимого. */
.lesson-photos {
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.lesson-photo { margin: 0; }
.lesson-photo img {
  width: 100%; height: auto; display: block;
  /* Пропорция задана размерами файла (1600×900); height:auto не даёт
     растянуть кадр, а отсутствие object-fit — обрезать объект в нём. */
  border-radius: var(--im-radius-input);
  border: 1px solid var(--im-silver);
  background: var(--im-cloud, #f5f6f8);
}
.lesson-photo figcaption {
  margin-top: .4rem; font-size: .82rem; color: var(--im-text-soft);
}
/* Порядок прохождения урока: нумерованный список, номера — фирменным золотом. */
.lesson-steps { margin: 0; padding-left: 1.25rem; }
.lesson-steps li { margin-bottom: .55rem; }
.lesson-steps li::marker { color: var(--im-gold); font-weight: 700; }
.lesson-steps li:last-child { margin-bottom: 0; }

/* Citation list. A <details> so the references are one click away rather than
   a wall between the programme and the mentors. */
.course-sources > summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; gap: .35rem;
  padding: .75rem 0; border-top: 1px solid var(--im-silver);
  border-bottom: 1px solid var(--im-silver);
}
.course-sources > summary::-webkit-details-marker { display: none; }
.course-sources > summary::after {
  content: "\F282";                       /* bootstrap-icons chevron-down */
  font-family: "bootstrap-icons"; font-size: .8rem;
  margin-left: auto; color: var(--im-gold);
  transition: transform .25s var(--ease-out);
}
.course-sources[open] > summary::after { transform: rotate(180deg); }
.course-sources > summary:focus-visible { outline: 2px solid var(--im-gold); outline-offset: 2px; }
.course-sources a { color: var(--im-navy); text-decoration-color: var(--im-gold); overflow-wrap: anywhere; }
@media (prefers-reduced-motion: reduce) {
  .course-sources > summary::after { transition: none; }
}
.course-price-label {
  font-size: .66rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: #8fa0c9;
}
.course-price {
  font-family: "Montserrat", sans-serif; font-weight: 900; line-height: 1.05;
  font-size: clamp(1.7rem, 3vw, 2.2rem); color: #fff;
}
.course-price span {
  display: block; font-family: "Manrope", sans-serif; font-weight: 600;
  font-size: .85rem; color: var(--im-gold); letter-spacing: .02em;
}
.course-tariffs { border-top: 1px solid rgba(255, 255, 255, .14); }
.course-tariffs li {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .45rem 0; border-bottom: 1px solid rgba(255, 255, 255, .1);
  font-size: .88rem; color: #cdd5e6;
}
.course-tariffs strong { color: #fff; white-space: nowrap; }
.course-discount {
  color: var(--im-navy); background: var(--im-gold);
  border-radius: 10px; padding: .5rem .7rem; font-weight: 700;
}
.program-topics li {
  display: flex; align-items: flex-start; gap: .25rem;
  font-size: .9rem; color: var(--im-text-soft); padding: .18rem 0;
}
.program-topics i { color: var(--im-gold); font-size: 1.1rem; line-height: 1.3; flex: none; }

/* --- Browser notification permission banner ------------------------------ */
.notify-prompt {
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
  padding: .9rem 1.15rem; margin-bottom: 1.25rem;
  border: 1px solid var(--im-silver); border-left: 3px solid var(--im-gold);
  border-radius: var(--im-radius-card); background: #fff;
}
.notify-prompt > i { color: var(--im-gold); font-size: 1.35rem; flex: none; }
.notify-prompt-text { flex: 1 1 260px; min-width: 0; }
.notify-prompt-text strong { display: block; color: var(--im-navy); font-size: .95rem; }
.notify-prompt-text span { font-size: .84rem; color: var(--im-text-soft); line-height: 1.4; }
.notify-prompt-actions { display: flex; align-items: center; gap: .35rem; flex: none; }
.notify-prompt-actions .btn-link { text-decoration: none; font-weight: 600; }

/* --- Notification list: channel and category read at a glance ------------ */
.notif-item { display: flex; gap: .9rem; padding: .9rem 0; border-bottom: 1px solid var(--im-silver); }
.notif-item:last-child { border-bottom: 0; }
.notif-icon {
  flex: none; width: 38px; height: 38px; border-radius: 11px;
  display: grid; place-items: center; font-size: 1rem;
  background: var(--im-surface); color: var(--im-navy);
}
.notification-unread .notif-icon { background: var(--im-gold); color: var(--im-navy); }
.notif-body { min-width: 0; flex: 1; }
.notif-head { display: flex; justify-content: space-between; gap: .75rem; align-items: baseline; }
.notif-title { font-weight: 700; font-size: .95rem; color: var(--im-navy); }
.notif-time { font-size: .76rem; color: var(--im-text-soft); white-space: nowrap; }
.notif-text { font-size: .88rem; color: var(--im-text-soft); margin: .15rem 0 .25rem; }
.notif-tag {
  display: inline-block; font-size: .68rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; color: var(--im-text-soft);
  background: var(--im-surface); border: 1px solid var(--im-silver);
  border-radius: 999px; padding: .1rem .5rem;
}

/* Каналы доставки: состояние каждого — понятной точкой, а не текстом-статусом. */
.channel-list { display: grid; gap: .7rem; margin-bottom: .75rem; }
.channel-row { display: flex; align-items: flex-start; gap: .65rem; }
.channel-dot {
  flex: none; width: 10px; height: 10px; border-radius: 50%; margin-top: .35rem;
}
.channel-dot.on { background: #1f9d55; }
.channel-dot.idle { background: var(--im-gold); }
.channel-dot.off { background: var(--im-silver); }

/* ==========================================================================
   Student cabinet (ТЗ §18): course progress, and the welcome screen.
   ========================================================================== */
.course-progress-row { padding: .85rem 0; border-bottom: 1px solid var(--im-silver); }
.course-progress-row:last-child { border-bottom: 0; padding-bottom: 0; }
.course-progress-row .min-w-0 { min-width: 0; }
.progress-line {
  height: 6px; border-radius: 999px; background: var(--im-silver);
  overflow: hidden; margin: .5rem 0 .3rem;
}
.progress-line span {
  display: block; height: 100%; border-radius: 999px;
  background: linear-gradient(90deg, var(--im-gold), #e2910d);
  transition: width .5s var(--ease-out);
}

/* Welcome screen: three numbered steps, nothing else competing for attention. */
.intro-step { display: flex; gap: 1.1rem; padding: 1.4rem 0; border-bottom: 1px solid var(--im-silver); }
.intro-step:last-of-type { border-bottom: 0; }
.intro-no {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  font-family: "Montserrat", sans-serif; font-weight: 900; font-size: 1.05rem;
  background: var(--im-navy); color: var(--im-gold);
}
.intro-body { min-width: 0; flex: 1; }
.intro-list li {
  display: flex; align-items: flex-start; gap: .65rem;
  font-size: .92rem; color: var(--im-text-soft); line-height: 1.5;
  padding: .3rem 0;
}
.intro-list i { color: var(--im-gold); font-size: 1rem; line-height: 1.45; flex: none; }
.intro-list strong { color: var(--im-text); }

/* ==========================================================================
   Parent cabinet (ТЗ §19) and ID linking (§20).
   ========================================================================== */
.child-card {
  display: block; padding: 1.25rem; height: 100%;
  background: #fff; border: 1px solid var(--im-silver);
  border-radius: var(--im-radius-card); text-decoration: none;
  color: var(--im-text);
  transition: border-color .2s ease, transform .2s var(--ease-out), box-shadow .2s ease;
}
.child-card:hover, .child-card:focus-visible {
  border-color: var(--im-gold); transform: translateY(-3px);
  box-shadow: 0 14px 34px rgba(20, 33, 61, .10); color: var(--im-text);
}
.child-card .min-w-0 { min-width: 0; }
.child-figures {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: .5rem .75rem;
  margin-top: .75rem;
}
.child-figures b {
  display: block; font-family: "Montserrat", sans-serif; font-weight: 800;
  font-size: 1.05rem; color: var(--im-navy); line-height: 1.1;
}
.child-figures span { font-size: .72rem; color: var(--im-text-soft); }
.child-card-go {
  display: inline-flex; align-items: center; gap: .35rem;
  margin-top: .9rem; font-size: .82rem; font-weight: 700; color: var(--im-navy);
}
.child-card:hover .child-card-go { color: var(--im-gold); }

.child-switch { display: flex; gap: .4rem; flex-wrap: wrap; }
.child-tab {
  display: inline-flex; align-items: center; gap: .5rem; max-width: 190px;
  padding: .35rem .8rem .35rem .35rem; border-radius: 999px;
  border: 1px solid var(--im-silver); background: #fff;
  color: var(--im-text-soft); font-size: .85rem; font-weight: 600;
  text-decoration: none;
}
.child-tab .avatar-circle { width: 30px; height: 30px; font-size: .7rem; }
.child-tab:hover { border-color: var(--im-gold); color: var(--im-navy); }
.child-tab.active { background: var(--im-navy); border-color: var(--im-navy); color: #fff; }

/* Public IDs are read out loud and typed in, so they get a monospaced,
   letter-spaced treatment — that is what makes a misread character visible. */
.id-input {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  letter-spacing: .12em; text-transform: uppercase; font-weight: 700;
}
.id-steps { padding-left: 1.1rem; color: var(--im-text-soft); }
.id-steps li { margin-bottom: .3rem; }
.id-steps strong { color: var(--im-text); }

/* ==========================================================================
   Formula dialog (ТЗ §14): shapes to hand, and a preview before insertion.
   ========================================================================== */
.rt-modal {
  position: fixed; inset: 0; z-index: 1080;
  display: grid; place-items: center; padding: 1rem;
  background: rgba(0, 10, 36, .55);
}
.rt-modal[hidden] { display: none; }
.rt-modal-card {
  width: min(640px, 100%); max-height: 90vh; display: flex; flex-direction: column;
  background: #fff; border-radius: var(--im-radius-card);
  box-shadow: 0 24px 60px rgba(0, 10, 36, .35);
}
.rt-modal-head, .rt-modal-foot {
  display: flex; align-items: center; gap: .6rem;
  padding: .9rem 1.15rem;
}
.rt-modal-head { border-bottom: 1px solid var(--im-silver); justify-content: space-between; }
.rt-modal-foot { border-top: 1px solid var(--im-silver); justify-content: flex-end; }
.rt-modal-body { padding: 1.15rem; overflow-y: auto; }
.rt-fx-input {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: .92rem;
}
.rt-fx-label {
  font-size: .68rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; color: var(--im-text-soft);
  margin: 1rem 0 .4rem;
}
.rt-fx-chips { display: flex; flex-wrap: wrap; gap: .35rem; }
.rt-fx-chip {
  border: 1px solid var(--im-silver); background: #fff; border-radius: 8px;
  padding: .3rem .6rem; font-size: .8rem; color: var(--im-navy); cursor: pointer;
  transition: border-color .15s ease, background .15s ease;
}
.rt-fx-chip:hover { border-color: var(--im-gold); background: #fff7ea; }
.rt-fx-symbols .rt-fx-chip {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  min-width: 2.2rem; text-align: center;
}
.rt-fx-preview {
  min-height: 68px; display: grid; place-items: center; padding: .8rem;
  border: 1px dashed var(--im-silver); border-radius: var(--im-radius-input);
  background: var(--im-surface); overflow-x: auto;
}
/* A display formula sits on its own line, centred, like it does in the lesson. */
.im-formula-block { display: block; text-align: center; margin: 1rem 0; }

/* ==========================================================================
   Footer background and composition (ТЗ §8). Same has-decor/brand_decor
   pattern already used on navy sections above the fold — no new visual
   language, just applied where it was missing.
   ========================================================================== */
.footer-im.has-decor { position: relative; overflow: hidden; }
.footer-im .section-decor { opacity: .5; }
/* A quiet top edge instead of a hard cut from the page above — echoes
   .gold-glow without adding a second decoration system. */
.footer-im::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 1px;
  background: linear-gradient(90deg, transparent, rgba(252, 163, 17, .35), transparent);
}
.footer-mark { height: 52px; width: auto; }
.footer-brand-word { color: #fff; font-size: 1.15rem; letter-spacing: .01em; }
.footer-tagline { color: #9fa9c2; max-width: 32ch; line-height: 1.55; }
.footer-im .row.g-4 { row-gap: 2.25rem !important; }

/* Directions section: the marquee carries its own breathing room (padding for
   the hover lift and its shadow), so the section's own bottom padding is
   trimmed by that much — otherwise the two stack into a visibly empty band
   under the row. Top padding is untouched, so the section still sits in the
   page's normal rhythm. */
.section--directions { padding-bottom: calc(var(--im-section-y) - 1.5rem); }
@media (max-width: 767px) {
  .section--directions { padding-bottom: calc(var(--im-section-y-mobile) - 1rem); }
}

/* ==========================================================================
   Страница «О нас»: единая сетка карточек и компактный ритм
   ========================================================================== */

/* Одна сетка на три раздела — менторов, новости и партнёров. Колонки задаёт
   auto-fit с минимальной шириной, поэтому единственная карточка не растянется
   на весь экран, а десять сами лягут ровными рядами. Раньше это были три
   разных набора Bootstrap-колонок, и каждый ломался на своей ширине. */
.card-grid {
  display: grid;
  gap: clamp(1rem, 2vw, 1.5rem);
  /* min(…, 100%) — иначе minmax жёстко держит 300 px и на 320 px экране
     карточка вылезает за край: контейнеру после отступов остаётся 286. */
  grid-template-columns:
    repeat(auto-fit, minmax(min(var(--card-min, 260px), 100%), 1fr));
  align-items: stretch;
}
.card-grid--partners { --card-min: 280px; }
.card-grid > * { min-width: 0; }
/* При одной-двух карточках ряд не растягивается во всю ширину контейнера, а
   остаётся по центру в разумном размере. */
/* Потолок ширины — с 576 px, а не с 992: на планшете единственная карточка
   партнёра растягивалась на 734 px и переставала быть карточкой. Ниже 576 px
   потолок не нужен — там колонка и так уже 420 px.
   margin-inline: auto — карточка уже своей колонки, и без автополей она
   прижималась к левому краю: единственный партнёр стоял слева под заголовком
   по центру. Автополя поглощают остаток и ставят её посередине, а
   растягиваться по колонке уже потолка карточка по-прежнему может. */
@media (min-width: 576px) {
  .card-grid > * { max-width: 420px; margin-inline: auto; }
}
@media (min-width: 992px) {
  .card-grid { justify-content: center; }
}


/* Ценности — компактный список, а не четыре одинаковые плавающие карточки с
   иконками в цветных кружках: та раскладка занимала целый экран ради четырёх
   строк текста. */

/* Появление знака: короткое, один раз, без вращения и свечения. */
@media (prefers-reduced-motion: no-preference) {
  .about-mission__mark { animation: mark-in .42s cubic-bezier(.22,.61,.36,1) both; }
}
@keyframes mark-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

/* --- Карточка человека --------------------------------------------------- */
/* Всё видно сразу: наведение больше ничего не открывает, потому что на
   телефоне наведения нет и половина сведений о Менторе была недоступна. */
.person-card {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; padding: clamp(1.1rem, 2vw, 1.5rem); height: 100%;
}
.person-card__name {
  font-size: 1rem; font-weight: 700; color: var(--im-navy); margin-bottom: .15rem;
  overflow-wrap: anywhere;
}
.person-card__role { font-size: .875rem; font-weight: 700; color: var(--im-gold); margin-bottom: .5rem; }
.person-card__meta { font-size: .8rem; color: var(--im-text-soft); margin-bottom: .5rem; }
.person-card__achievements {
  font-size: .85rem; line-height: 1.5; color: var(--im-text-soft);
  margin-bottom: .5rem;
}
.person-card__achievements i { color: var(--im-gold); margin-right: .35rem; }
.person-card .contact-list { margin-top: auto; padding-top: .75rem; }

/* --- Карточка партнёра --------------------------------------------------- */
.partner-card {
  display: flex; flex-direction: column; height: 100%;
  padding: clamp(1.1rem, 2vw, 1.4rem);
}
/* Общая рамка постоянной высоты: логотипы приходят и вытянутыми, и
   квадратными, а contain вписывает любой целиком — без растягивания и без
   обрезки. */
.partner-card__logo {
  display: grid; place-items: center;
  min-height: 132px; margin-bottom: 1rem; padding: 1rem;
  border-radius: var(--im-radius-input);
  background: var(--im-white); border: 1px solid var(--im-silver);
  color: var(--im-navy); font-size: 2.2rem;
}
.partner-card__logo img {
  /* Размер рамки задаётся здесь, а не пределами max-*. У картинки есть
     атрибуты width и height (они держат место, пока файл грузится) — они
     давали ей 400×200, а процентный max-height против них не работал: процент
     считается от высоты грид-ячейки, браузер считает её неопределённой и
     отбрасывает ограничение. Логотип рисовался в свои 200 px, вылезал из
     рамки и ложился поверх названия партнёра.
     `scale-down`, а не `contain`: логотип вписывается целиком, но маленький
     файл не растягивается вверх до 100 px и не мылится. */
  width: 100%; height: 100px;
  object-fit: scale-down;
}
.partner-card__body { display: flex; flex-direction: column; gap: .4rem; flex: 1 1 auto; }
.partner-card__title {
  font-size: 1.05rem; font-weight: 800; color: var(--im-navy); margin: 0;
  line-height: 1.3; overflow-wrap: anywhere;
}
.partner-card__type {
  font-size: .72rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--im-gold); margin: 0;
}
.partner-card__about {
  /* Цвет темнее прежнего text-soft: описание партнёра — основной текст
     карточки, а не подпись, и на белом фоне серый в него не читался. */
  font-size: .9rem; line-height: 1.6; color: var(--im-text); margin: 0;
}
.partner-card__about p:last-child { margin-bottom: 0; }
.partner-card__address {
  display: flex; gap: .35rem; font-size: .85rem;
  color: var(--im-text-soft); margin: 0;
}
.partner-card__address i { color: var(--im-gold); flex: none; }
.partner-card .contact-list { margin-top: auto; padding-top: .9rem; }

/* --- Список контактов (менторы, партнёры) -------------------------------- */
.contact-list {
  display: flex; flex-direction: column; gap: .35rem;
  /* По умолчанию — золотой платформы. Каждая площадка ниже подменяет пару
     цветов на свою; всё остальное оформление у чипов общее.
     Значения объявлены на списке, а не на строке: у `.contact-list li`
     специфичность выше, чем у одиночного `.contact-chip--telegram`, и
     умолчание перебивало бы фирменный цвет. */
  --brand: var(--im-gold);
  --brand-soft: #FFF8EC;
}
.contact-list--inline { flex-direction: row; flex-wrap: wrap; gap: .4rem; }
.contact-list li { min-width: 0; }
.contact-list a, .contact-list > li > span {
  display: inline-flex; align-items: center; gap: .4rem;
  /* 44 px по высоте — палец попадает без промаха. */
  min-height: 44px; padding: .3rem .8rem;
  border: 1px solid var(--im-silver); border-radius: 999px;
  font-size: .82rem; font-weight: 600;
  color: var(--im-navy); text-decoration: none;
  background: var(--im-white); max-width: 100%;
  transition: border-color .2s ease, background-color .2s ease;
}
.contact-list a:hover, .contact-list a:focus-visible {
  border-color: var(--brand); color: var(--im-navy); background: var(--brand-soft);
}
.contact-list i {
  color: var(--brand); flex: none;
  /* Знак площадки крупнее подписи: по нему её и узнают. */
  font-size: 1.05rem; line-height: 1;
}
.contact-list span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Фирменные цвета площадок. Значки берутся из уже подключённого набора
   Bootstrap Icons — это официальные знаки Telegram, WhatsApp, Instagram и
   прочих, — а цвет доводит узнавание: одинаково золотые, они читались как
   декор платформы, а не как «здесь Telegram». Значения — фирменные цвета
   самих площадок. */
.contact-chip--telegram  { --brand: #229ED9; --brand-soft: #EAF6FC; }
.contact-chip--whatsapp  { --brand: #25D366; --brand-soft: #EAFBF0; }
.contact-chip--instagram { --brand: #E4405F; --brand-soft: #FDEEF2; }
.contact-chip--facebook  { --brand: #1877F2; --brand-soft: #EAF2FE; }
.contact-chip--linkedin  { --brand: #0A66C2; --brand-soft: #E9F1F9; }
.contact-chip--youtube   { --brand: #FF0000; --brand-soft: #FDECEC; }
/* Сайт, телефон, почта и адрес — не площадки, у них нет своего знака:
   остаются в цвете платформы. */
.contact-chip--website,
.contact-chip--phone,
.contact-chip--email,
.contact-chip--address,
.contact-chip--other { --brand: var(--im-navy); --brand-soft: #EEF1F7; }

/* У Instagram фирменный знак — градиентный, одним цветом он передаётся
   приблизительно. `@supports` обязателен: без обрезки фона по тексту буквы
   значка стали бы прозрачными, то есть невидимыми. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .contact-chip--instagram i {
    background-image: linear-gradient(45deg,
      #F58529 0%, #DD2A7B 45%, #8134AF 72%, #515BD4 100%);
    -webkit-background-clip: text; background-clip: text;
    color: transparent;
  }
}

/* --- Компактность страницы ----------------------------------------------
   Восемь разделов подряд с полным вертикальным ритмом давали страницу длиной
   в десяток экранов. Ритм уменьшен только на «О нас»; на остальных страницах
   он остаётся прежним. */
.page-about .section { padding-block: clamp(2.25rem, 4.5vw, 4rem); }
.page-about .section-head { margin-bottom: clamp(1.5rem, 3vw, 2.25rem); }

/* ==========================================================================
   Панель: повторяемые контакты и предпросмотр карточки
   ========================================================================== */

.contact-row {
  display: grid; align-items: center; gap: .4rem;
  grid-template-columns: auto auto minmax(110px, .8fr) minmax(120px, 1fr) auto;
  padding: .45rem; margin-bottom: .4rem;
  border: 1px solid var(--im-silver); border-radius: var(--im-radius-input);
  background: var(--im-surface);
}
.contact-row__grip { color: #9aa0ad; cursor: grab; }
.contact-row__toggle { display: inline-flex; align-items: center; margin: 0; cursor: pointer; }
.contact-row__actions { display: flex; gap: .2rem; }
.contact-row__actions .btn { min-width: 34px; }
@media (max-width: 575.98px) {
  /* На телефоне четыре колонки не помещаются — строка разворачивается, а
     кнопки уходят в свой ряд и остаются нажимаемыми. */
  .contact-row { grid-template-columns: 1fr; }
  .contact-row__grip { display: none; }
  .contact-row__actions { justify-content: flex-end; }
  .contact-row__actions .btn { min-width: 44px; min-height: 44px; }
}

.preview-panel {
  border: 1px solid var(--im-silver); border-radius: var(--im-radius-card);
  background: var(--im-surface); overflow: hidden;
}
.preview-panel__bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: .5rem;
  padding: .6rem .85rem; background: var(--im-white);
  border-bottom: 1px solid var(--im-silver);
}
.preview-panel__title { font-weight: 700; font-size: .9rem; color: var(--im-navy); margin-right: auto; }
.preview-panel__widths { display: flex; gap: .25rem; }
.preview-panel__widths .btn.active { background: var(--im-navy); color: var(--im-white); }
/* Содержимое прокручивается внутри панели, а не тянет за собой всю страницу
   панели управления. */
.preview-panel__scroll { max-height: 60vh; overflow: auto; padding: clamp(1rem, 3vw, 2rem); }
.preview-panel__stage { margin-inline: auto; transition: max-width .2s ease; }

.preview-modal {
  position: fixed; inset: 0; z-index: 1080;
  display: grid; place-items: center; padding: clamp(.75rem, 3vw, 2rem);
  background: rgba(0, 10, 36, .72);
}
.preview-modal[hidden] { display: none; }
.preview-modal__panel {
  position: relative; width: min(100%, 1200px); max-height: 92vh;
  display: flex; flex-direction: column;
  background: var(--im-white); border-radius: var(--im-radius-card);
  overflow: hidden;
}
.preview-modal__close { position: absolute; top: .75rem; right: .75rem; z-index: 2; }
.preview-modal__body { overflow: auto; padding: clamp(1rem, 3vw, 2rem); }
.preview-modal__body .preview-panel { border: 0; background: transparent; }
.preview-modal__body .preview-panel__scroll { max-height: none; }
body.preview-modal-open { overflow: hidden; }
@media (prefers-reduced-motion: reduce) {
  .preview-panel__stage { transition: none; }
}

/* ==========================================================================
   «О нас»: карточка Ментора, доступ к контактам, спокойные анимации
   ========================================================================== */


.person-card__meta i { color: var(--im-gold); margin-right: .3rem; }

/* Длинная биография сначала показывается тремя строками. Обрезка — только
   строками CSS, поэтому при отключённых стилях текст виден целиком, а без
   JavaScript кнопка просто не появляется (её рисует шаблон лишь для длинных
   текстов, а раскрывает скрипт). */
.person-card__bio {
  font-size: .875rem; line-height: 1.55; color: var(--im-text-soft);
  margin-bottom: .5rem; text-align: center;
}
.person-card__bio.is-clamped {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.person-card__more {
  border: 0; background: none; padding: .35rem .5rem; margin-bottom: .35rem;
  min-height: 44px;                    /* палец попадает без промаха */
  font-size: .82rem; font-weight: 700; color: var(--im-navy);
  display: inline-flex; align-items: center; gap: .3rem; cursor: pointer;
}
.person-card__more:hover { color: var(--im-gold); }
.person-card__more i { transition: transform .22s ease; }
.person-card__more[aria-expanded="true"] i { transform: rotate(180deg); }

.person-card__achievements {
  display: block; text-align: center;
}

/* Контакты и объяснение их отсутствия занимают одно и то же место внизу
   карточки, поэтому соседние карточки не разъезжаются по высоте. */
.person-card__contacts { margin-top: auto; padding-top: .85rem; width: 100%; }
.person-card__contacts-title {
  font-size: .78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .04em; color: var(--im-text-soft); margin-bottom: .5rem;
}
.person-card__contacts .contact-list { justify-content: center; }
.person-card__locked {
  margin-top: auto; padding-top: .85rem; margin-bottom: 0;
  font-size: .8rem; line-height: 1.5; color: var(--im-text-soft);
}
.person-card__locked i { color: var(--im-gold); margin-right: .35rem; }
.person-card__locked a { color: var(--im-navy); font-weight: 700; }

/* --- Появление карточек ---------------------------------------------------
   Одна анимация на страницу «О нас»: проявление и сдвиг на 14 px, 380 мс,
   с задержкой по порядку карточки. Ни вращения, ни масштабирования, ни
   постоянного движения.

   Гейт `.js-reveal` на <html> ставит тот же скрипт, что уже используется на
   сайте: без JavaScript класс не появляется, правило не срабатывает и
   содержимое просто видно. Скачков макета нет — двигается только transform,
   высота не меняется. */
.js-reveal .reveal-item {
  opacity: 0;
  transform: translateY(14px);
}
.js-reveal .reveal-item.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity .38s cubic-bezier(.22,.61,.36,1) var(--reveal-delay, 0ms),
              transform .38s cubic-bezier(.22,.61,.36,1) var(--reveal-delay, 0ms);
}
.page-about .card-im {
  transition: border-color .22s ease, box-shadow .22s ease;
}
.page-about .card-im:hover,
.page-about .card-im:focus-within {
  border-color: rgba(252, 163, 17, .45);
  box-shadow: 0 14px 34px rgba(20, 33, 61, .09);
}

@media (prefers-reduced-motion: reduce) {
  /* Полное выключение: ни проявления, ни задержек, ни плавной прокрутки. */
  .js-reveal .reveal-item,
  .js-reveal .reveal-item.is-visible {
    opacity: 1; transform: none; transition: none;
  }
  .person-card__more i,
  .page-about .card-im { transition: none; }
  html { scroll-behavior: auto; }
}

/* ==========================================================================
   «О нас»: миссия и бренд, методика, портрет Ментора
   ========================================================================== */

/* --- Общее для раздела ---------------------------------------------------- */
.about-eyebrow {
  font-size: .78rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .12em; color: var(--im-gold); margin-bottom: .6rem;
}
.about-edit {
  display: inline-flex; align-items: center; gap: .4rem; margin-top: 1.25rem;
  font-size: .82rem; color: var(--im-text-soft); text-decoration: none;
}
.about-edit:hover { color: var(--im-navy); }

/* --- Миссия и значение бренда ---------------------------------------------
   Одна сетка, а не Bootstrap-ряд: две колонки на компьютере, одна на
   планшете и телефоне. Ширина текста ограничена 62 знаками — строка длиннее
   читается заметно хуже, а контейнер страницы шире 1200 px. */
.about-mission {
  display: grid;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  align-items: center;
  max-width: 1040px; margin-inline: auto;
}
@media (max-width: 991.98px) {
  .about-mission { grid-template-columns: 1fr; text-align: center; }
  .about-mission__body { justify-items: center; }
}

.about-mission__figure { margin: 0; display: grid; place-items: center; }
.about-mission__mark {
  /* 160–200 px на компьютере, 120–150 на телефоне — знак читается как
     фирменный элемент, а не как иконка рядом с текстом. */
  width: clamp(120px, 16vw, 200px);
  height: auto; display: block;
}
@media (max-width: 575.98px) {
  .about-mission__mark { width: clamp(120px, 34vw, 150px); }
}

.about-mission__title {
  font-family: "Montserrat", sans-serif; font-weight: 800;
  font-size: clamp(1.5rem, 1.4vw + 1.05rem, 2.1rem);
  line-height: 1.2; color: var(--im-navy); margin-bottom: .9rem;
}
.about-mission__text {
  font-size: clamp(.98rem, .25vw + .93rem, 1.06rem);
  line-height: 1.65; color: var(--im-text); max-width: 62ch;
  margin-bottom: .85rem;
}
.about-mission__text p:last-child { margin-bottom: 0; }
.about-mission__text--muted { color: var(--im-text-soft); font-size: .95rem; }
@media (max-width: 991.98px) {
  .about-mission__text { margin-inline: auto; }
}

/* Итоговая мысль отделена тонкой золотой чертой слева — единственный
   декоративный элемент раздела, и он несёт функцию: отделяет вывод от
   изложения. */
.about-mission__closing {
  margin: 1.25rem 0 0; padding-left: .9rem;
  border-left: 2px solid var(--im-gold);
  font-size: .95rem; line-height: 1.6; color: var(--im-navy);
  max-width: 62ch;
}
@media (max-width: 991.98px) {
  .about-mission__closing {
    border-left: 0; border-top: 2px solid var(--im-gold);
    padding: .9rem 0 0; margin-inline: auto; max-width: 46ch;
  }
}

/* --- Методика: этапы ------------------------------------------------------
   Была вертикальная лента с золотой линией во всю высоту секции. Стала
   сетка: до четырёх этапов в ряд на большом экране, два на планшете, один
   столбец на телефоне.

   Соединитель — тонкая линия между соседними карточками, нарисованная
   псевдоэлементом. У последнего этапа её нет, и на телефоне она
   поворачивается вертикально вместе с раскладкой. */
.method-steps {
  list-style: none; margin: 0 0 clamp(2rem, 4vw, 3rem); padding: 0;
  display: grid; gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  counter-reset: step;
}
.method-step {
  position: relative;
  padding: clamp(1.25rem, 2vw, 1.6rem);
  background: var(--im-white);
  border: 1px solid var(--im-silver);
  border-radius: var(--im-radius-card);
  box-shadow: 0 8px 24px rgba(20, 33, 61, .04);
  transition: border-color .24s ease, box-shadow .24s ease,
              transform .24s ease;
}
.method-step:hover {
  border-color: rgba(252, 163, 17, .5);
  box-shadow: 0 14px 32px rgba(20, 33, 61, .08);
  transform: translateY(-2px);
}
.method-step__num {
  display: inline-grid; place-items: center;
  width: 40px; height: 40px; margin-bottom: .85rem;
  border-radius: 50%;
  background: var(--im-navy); color: var(--im-gold);
  font-family: "Montserrat", sans-serif; font-weight: 800; font-size: 1rem;
}
.method-step__title {
  font-size: 1.02rem; font-weight: 700; color: var(--im-navy);
  line-height: 1.35; margin-bottom: .45rem; overflow-wrap: anywhere;
}
.method-step__text {
  font-size: .9rem; line-height: 1.6; color: var(--im-text-soft);
}
.method-step__text p:last-child { margin-bottom: 0; }

/* Соединитель между этапами. `:not(:last-child)` — линия не свисает с
   последнего; на одноколоночной раскладке она вертикальная. */
.method-step:not(:last-child)::after {
  content: ""; position: absolute; pointer-events: none;
  background: var(--im-silver);
}
@media (min-width: 768px) {
  .method-step:not(:last-child)::after {
    top: calc(clamp(1.25rem, 2vw, 1.6rem) + 20px);
    right: calc(clamp(1rem, 2vw, 1.5rem) * -1);
    width: clamp(1rem, 2vw, 1.5rem); height: 1px;
  }
}
@media (max-width: 767.98px) {
  .method-step:not(:last-child)::after {
    left: calc(clamp(1.25rem, 2vw, 1.6rem) + 20px);
    bottom: calc(clamp(1rem, 2vw, 1.5rem) * -1);
    width: 1px; height: clamp(1rem, 2vw, 1.5rem);
  }
}

/* --- Методика: цифры ------------------------------------------------------ */
.method-facts {
  display: grid; gap: clamp(1rem, 2vw, 1.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
  max-width: 860px; margin-inline: auto; text-align: center;
}
.method-fact { display: grid; gap: .25rem; }
.method-fact__value {
  font-family: "Montserrat", sans-serif; font-weight: 800;
  font-size: clamp(1.6rem, 2vw + 1rem, 2.2rem);
  color: var(--im-navy); line-height: 1.1;
}
.method-fact__label {
  font-size: .82rem; line-height: 1.45; color: var(--im-text-soft);
}

/* --- Портрет Ментора ------------------------------------------------------
   Было квадратное фото 220 px в центре карточки. Стал портрет 4:5 во всю
   ширину верхней части: так лицо крупнее при той же ширине карточки, а
   пропорция ближе к тому, как люди снимают портреты.

   Карточка ограничена по ширине, поэтому единственный Ментор не
   растягивается на всю секцию, а стоит по центру. */
.card-grid--people { --card-min: 300px; }
/* Потолок ширины начинается сразу за телефонной раскладкой, а не с 992 px:
   на 768 px единственная карточка растягивалась на 734 px и переставала
   быть карточкой. Ниже 576 px потолок не нужен — там колонка и так уже,
   чем 360 px. */
@media (min-width: 576px) {
  .card-grid--people > * { max-width: 360px; }
}
.person-card { padding: 0; overflow: hidden; }

.person-card__frame {
  width: 100%; max-width: none; margin: 0 0 1.1rem;
  aspect-ratio: 4 / 5;
  border-radius: 0;
  overflow: hidden;
  background: var(--im-surface);
}
.person-card__photo {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Лицо на портрете почти всегда в верхней трети кадра: обрезка от центра
     срезала бы макушку. */
  object-position: center top;
  display: block;
  transition: transform .35s cubic-bezier(.22,.61,.36,1);
}
.person-card:hover .person-card__photo { transform: scale(1.03); }
.person-card__photo--initials {
  display: grid; place-items: center;
  font-family: "Montserrat", sans-serif; font-weight: 800;
  font-size: clamp(2.6rem, 9vw, 3.6rem);
  color: var(--im-gold);
  background: linear-gradient(150deg, #16264a 0%, var(--im-navy-dark) 100%);
}

/* Текст карточки получает собственные поля: у самой карточки их больше нет,
   иначе фотография не дотянулась бы до краёв. */
.person-card__name,
.person-card__role,
.person-card__meta,
.person-card__bio,
.person-card__achievements,
.person-card__more,
.person-card__contacts,
.person-card__locked {
  padding-inline: clamp(1.1rem, 2vw, 1.4rem);
}
.person-card__locked,
.person-card__contacts { padding-bottom: clamp(1.1rem, 2vw, 1.4rem); }
.person-card__achievements:last-child { padding-bottom: clamp(1.1rem, 2vw, 1.4rem); }

@media (prefers-reduced-motion: reduce) {
  .person-card__photo,
  .person-card:hover .person-card__photo,
  .method-step { transition: none; transform: none; }
  .method-step:hover { transform: none; }
}
