/* ==========================================================================
   Germes club — new design-system layer.

   This file is an OVERRIDE loaded after the legacy static/index_files/style.css.
   It intentionally keeps the site's existing dark background and class
   structure (so the legacy JS — menu toggles, modals, Slick/Splide init,
   form AJAX — keeps working unmodified) and swaps in the new visual
   language ported from germes.network: Geologica typeface, pill-shaped
   buttons, badge "kicker" labels, and a new event-card/carousel component.
   ========================================================================== */

@font-face { font-family: "Geologica"; src: url("fonts/geologica-200.ttf") format("truetype"); font-weight: 200; font-style: normal; font-display: swap; }
@font-face { font-family: "Geologica"; src: url("fonts/geologica-300.ttf") format("truetype"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Geologica"; src: url("fonts/geologica-400.ttf") format("truetype"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Geologica"; src: url("fonts/geologica-500.ttf") format("truetype"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Geologica"; src: url("fonts/geologica-600.ttf") format("truetype"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Geologica"; src: url("fonts/geologica-700.ttf") format("truetype"); font-weight: 700; font-style: normal; font-display: swap; }

:root {
  --orange: #f47f00;
  --orange-hover: #ff9200;
  --orange-soft: rgba(244, 127, 0, .12);
  --card-bg: #141412;
  --radius-pill: 999px;
  --radius-card: 16px;
}

/* ---------- Typography base ---------- */
body, a, button, input, textarea, select {
  font-family: "Geologica", "MyriadPro", Arial, sans-serif;
}

/* ---------- Light theme: flip background + card panels ---------- */
:root { --ink: #1a1a1a; --ink-soft: rgba(26, 26, 26, .6); --page-bg: #faf6f1; --card-light: #ffffff; }

body { background: var(--page-bg); }

/* dark card/panel backgrounds that need to become light surfaces */
.footer,
.modal__content,
.events__item,
.moders__content,
.event__content--wrap,
.concept__text--content,
.calendar__item {
  background: var(--card-light);
}

/* CKEditor-authored rich text (goals, "Формат клуба", FAQ answers): these
   fields carry hardcoded inline color:#fff/#ffffff spans from when they
   were edited against the old dark theme, which beats any plain CSS
   selector — force it back to dark. New content edited going forward can
   still override with its own inline color if a manager picks one. */
.target__content, .target__content *,
.conf__inner, .conf__inner *,
.question__answer, .question__answer * {
  color: var(--ink) !important;
}
/* Exception: "Формат клуба"'s numbered badges keep their own dark circle
   background (#31312F, untouched by the light-theme flip — it's a small
   accent, not a full panel), so the blanket dark-ink fix above makes their
   number unreadable against it. Restore the light color the badge was
   authored with. */
.conf__inner .conf__item--img--num,
.conf__inner .conf__item--img--num * {
  color: #ddd !important;
}

/* body text on the now-light page: everything that was plain white text
   on the dark page background. Deliberately NOT touched: button text
   (buttons keep their own fill), and the .moders__item--content /
   .speakers__item--content hover-card overlays, which stay white-on-dark
   gradient by design (see the grid/hover-card block below). */
.header__nav li a, .footer__nav li a,
.header__contact--link--value,
.main__subtitle, .main__text,
.target__item--text,
.concept__text--text,
.face__text,
.for__item--title, .for__item--text,
.conf__item--text,
.event__all, .event__item--text,
.question__text, .question__value, .question__open, .question__answer,
.question__answer--box--text, .question__answer--box--title,
.gift__text, .gift__point, .gift__agree,
.footer__button, .footer__phone, .footer__mail, .footer__text,
.paggin__link,
.events__item--title, .events__item--text,
.modal__input, .modal__form--agree, .wpcf7-response-output,
.moders__city, .moders__year,
.calendar__tab,
.calendar__item--title span, .calendar__item--num,
.event__content--text--item--text, .event_text {
  color: var(--ink);
}
.header__contact--link--value.email { color: var(--ink); }
.moders__city.active, .moders__city:hover,
.moders__year.active, .moders__year:hover,
.calendar__tab.active, .calendar__tab:hover { color: var(--orange); }

.section__title, .event_title, .section__title_lending {
  font-family: "Geologica", Arial, sans-serif;
  font-weight: 600;
  letter-spacing: -.5px;
}

/* ---------- Buttons: angular clipped-corner -> pill ---------- */
.outline__button, .fill__button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  min-width: 0;
  padding: 1.2rem 2.8rem;
  border: 1px solid rgba(244, 127, 0, .5);
  border-radius: var(--radius-pill);
  background: transparent;
  box-shadow: 0 0 15px rgba(224, 147, 44, .12);
  color: var(--ink);
  font-family: "Geologica", Arial, sans-serif;
  font-size: 1.5rem;
  font-weight: 500;
  text-transform: none;
  transition: background-color .2s ease, transform .2s ease, border-color .2s ease;
}
.fill__button {
  border-color: var(--orange);
  background: var(--orange);
  box-shadow: 0 0 12px rgba(224, 147, 44, .35);
  color: #000;
}
/* neutralise the old triangle corner decoration */
.outline__button:before, .outline__button:after, .fill__button:before, .fill__button:after,
.button__part {
  content: none;
  display: none;
}
.outline__button:hover, .fill__button:hover {
  border-color: var(--orange);
  background: rgba(244, 127, 0, .15);
  transform: translateY(-1px);
}
.fill__button:hover { background: var(--orange-hover); border-color: var(--orange-hover); }

/* ---------- Section kicker / badge label (new component) ---------- */
.section-kicker {
  display: inline-flex;
  align-items: center;
  margin: 0;
  padding: 8px 16px;
  border: 1px solid rgba(244, 127, 0, .4);
  border-radius: var(--radius-pill);
  background: rgba(244, 127, 0, .08);
  color: var(--ink);
  font-family: "Geologica", Arial, sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: .6px;
  line-height: 18px;
  text-transform: uppercase;
}

/* ---------- "Лица клуба" gallery: slider of bento-grid collages ---------- */
/* overrides.js groups the flat list of tiles into N-per-collage slides
   (10 desktop / 5 tablet / 3 mobile) and inits Slick (slidesToShow:1) on
   the result — see makeCollageCarousel() in overrides.js. */
.face__inner { align-items: flex-start; gap: 12px; }
.face-gallery .slick-track { display: flex; align-items: stretch; }
.face-gallery .slick-slide { height: auto; }
.face-gallery__slide { width: 100%; margin-top: 32px; }
.face__carousel {
  display: grid;
  grid-auto-flow: row dense;
  grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: 250px;
  gap: 10px;
  width: 100%;
}
.face__tile {
  overflow: hidden;
  border-radius: var(--radius-card);
}
.face__carousel--img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* a repeating bento pattern: dense packing fills around the larger tiles */
.face__tile:nth-child(6n+1) { grid-column: span 2; grid-row: span 2; }
.face__tile:nth-child(6n+4) { grid-column: span 2; }

@media (max-width: 960px) {
  .face__carousel { grid-template-columns: repeat(4, 1fr); grid-auto-rows: 190px; }
}
@media (max-width: 600px) {
  .face__carousel { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 180px; gap: 8px; }
  .face__tile:nth-child(6n+1) { grid-column: span 2; grid-row: span 2; }
  .face__tile:nth-child(6n+4) { grid-column: span 1; }
}

/* ---------- Speakers / team: Slick carousel (4 cards/view) with hover-reveal card ---------- */
/* overrides.js re-inits Slick on these with slidesToShow:4 before this applies */
/* touch-action:pan-y tells the browser a horizontal drag on this element
   belongs to the carousel's own JS (Slick here), so it stops contesting
   that gesture with its native vertical scroll / pull-to-refresh handling.
   Without it, a horizontal swipe on iOS Safari can be interpreted as both
   at once, which is the known cause of the carousel's page stuttering,
   reloading, or (after repeated bad frames) the tab getting killed and
   showing "A problem repeatedly occurred". Vertical scroll still works
   normally since only the X axis is claimed. */
.moders__carousel, .speakers__carousel { width: 100%; touch-action: pan-y; }
/* align-items MUST NOT be stretch: .moders__item/.speakers__item size
   themselves via aspect-ratio (see below), and WebKit/iOS Safari has a
   real bug where a stretched flex item's aspect-ratio is ignored in favour
   of the stretch height, collapsing the card to its content's intrinsic
   height (near-zero, since both children are position:absolute) and
   squashing the photo into a thin strip. flex-start leaves aspect-ratio
   in control of the item's height on every engine. */
.moders__carousel .slick-track, .speakers__carousel .slick-track { display: flex; align-items: flex-start; }
.moders__carousel .slick-slide, .speakers__carousel .slick-slide { height: auto; }
.moders__arrow {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid rgba(0, 0, 0, .1);
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 4px 14px rgba(0, 0, 0, .08);
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, transform .2s ease;
}
.moders__arrow img { width: 16px; height: 16px; }
.moders__arrow:hover { background: var(--orange); border-color: var(--orange); transform: translateY(-1px); }
.moders__arrow.prev { margin-right: 12px; }
.moders__arrow.slick-disabled { opacity: .35; pointer-events: none; }

/* Primary fix is arrows:false in overrides.js's tablet/mobile configs (no
   arrow elements get created at all below 960px). This is a defensive
   backstop only — kept !important because Slick calls jQuery .show()/
   .hide() on arrow elements during normal slide-change updates, which
   writes a plain (non-!important) inline display style that would
   otherwise beat this rule. */
@media (max-width: 960px) {
  .moders__arrow { display: none !important; }
}

/* display:block!important beats the legacy .moders__item/.speakers__item
   {display:flex!important}: that flex layout was for the old horizontal
   photo+text row and fights aspect-ratio sizing here, where both children
   are position:absolute and contribute no in-flow height for flex to lay
   out against. */
.moders__item, .speakers__item {
  position: relative;
  display: block !important;
  width: 100%;
  aspect-ratio: 3 / 4;
  margin: 0 10px;
  overflow: hidden;
  border-radius: var(--radius-card);
  background: #1a1a1a;
}

.moders__item--img--inner, .speakers__item .moders__item--img--inner {
  position: absolute;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  margin: 0;
}
.moders__item--img {
  position: static;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: grayscale(1) contrast(1.02);
}
.moders__item--img--box { display: none; }

.moders__item--content, .speakers__item--content {
  position: absolute;
  inset: auto 0 0 0;
  gap: 4px;
  padding: 20px;
  background: linear-gradient(to top, rgba(0, 0, 0, .9) 0%, rgba(0, 0, 0, .55) 55%, rgba(0, 0, 0, 0) 100%);
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .25s ease, transform .25s ease;
  pointer-events: none;
}
.moders__item:hover .moders__item--content,
.moders__item:focus-within .moders__item--content,
.speakers__item:hover .speakers__item--content,
.speakers__item:focus-within .speakers__item--content {
  opacity: 1;
  transform: translateY(0);
}
.moders__item--name, .speakers__name {
  font-size: 1.3rem;
  border-bottom: 0;
  padding-bottom: 0;
  margin-top: 0;
}
.moders__item--box--text, .speakers__item--company { font-size: 1.1rem; }
.moders__item--box--title, .speakers__item--text { font-size: 1.3rem; }
.speakers__item--content--img { display: none; }

@media (max-width: 560px) {
  .moders__item--content, .speakers__item--content { opacity: 1; transform: none; padding: 12px; }
}

/* ---------- Video play button ("Что мы получаем"): was light-gray, invisible on the new light page ---------- */
.media__item--play path { fill: var(--orange); }
.media__item--video:hover .media__item--play path, .for__img--inner:hover .media__item--play path { fill: var(--orange-hover); }

/* ---------- Form inputs inside modals (join / question / analytics / pay) ---------- */
.modal__input { transition: border-color .2s ease; }
.modal__input:focus { outline: none; border-bottom-color: var(--orange); }
.modal__input--checkbox + label::before { border-color: rgba(244, 127, 0, .5); }
.modal__input::placeholder, .input::placeholder { color: var(--ink-soft); opacity: 1; }
.modal__content { border-radius: 24px; }

/* ---------- Off-canvas mobile menu: was solid black ---------- */
.modal__menu { background: var(--page-bg); box-shadow: 0 0 40px rgba(0, 0, 0, .12); }

/* ---------- Header ---------- */
.header { padding: 3.2rem 0; }
.header__logo--img { height: 48px; width: auto; }
.header__nav li a, .footer__nav li a { font-family: "Geologica", Arial, sans-serif; font-weight: 500; }
.header__logo-group { display: flex; align-items: center; gap: 1.6rem; }
.header__partner { display: flex; width: 104px; flex-direction: column; align-items: center; gap: 3px; }
.header__partner img { display: block; width: 100%; height: auto; }
/* .js-logo-materialize defaults to inline-block (shrink-wraps its image),
   but the Skolkovo badge's img is width:100% of its wrapper — give the
   wrapper itself that 100% so the img still has something real to resolve
   against instead of a circular inline-block/pre-image-load sizing guess. */
.header__partner .js-logo-materialize { display: block; width: 100%; }
.header__partner span { color: var(--ink-soft); font-size: 8px; font-weight: 500; letter-spacing: .35px; line-height: 11px; text-transform: uppercase; }

@media (max-width: 760px) {
  .header__partner { width: 60px; gap: 1px; }
  .header__partner span { font-size: 6px; letter-spacing: .2px; line-height: 8px; }
}

/* ---------- Footer legal requisites ---------- */
.footer__requisites {
  width: 100%;
  margin-top: 3.5rem;
  padding-top: 2.4rem;
  border-top: 1px solid rgba(0, 0, 0, .08);
}
.footer__requisites p {
  margin: 0 0 .8rem;
  color: var(--ink-soft);
  font-size: 1.3rem;
  font-weight: 300;
  line-height: 1.6;
}
.footer__requisites p:last-child { margin-bottom: 0; }

/* ---------- Event card (new component, used by the homepage carousel) ---------- */
.event-card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, .08);
  border-radius: var(--radius-card);
  background: var(--card-bg);
  color: #fff;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease;
}
.event-card:hover, .event-card:focus-visible { transform: translateY(-4px); box-shadow: 0 16px 40px rgba(0, 0, 0, .35); }
.event-card__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: #1a1a1a; }
.event-card__media img { width: 100%; height: 100%; object-fit: cover; }
.event-card__badge {
  position: absolute;
  top: 16px;
  left: 16px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background: rgba(244, 127, 0, .92);
  color: #000;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .3px;
  text-transform: uppercase;
}
.event-card__date {
  position: absolute;
  left: 16px;
  bottom: 16px;
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: .4px;
  text-transform: uppercase;
}
.event-card__body { display: flex; flex: 1; flex-direction: column; gap: 10px; padding: 24px; }
.event-card__city { margin: 0; color: rgba(255, 255, 255, .5); font-size: 13px; font-weight: 500; text-transform: uppercase; letter-spacing: .4px; }
.event-card__title { margin: 0; font-size: 21px; font-weight: 600; letter-spacing: -.3px; line-height: 1.25; }
.event-card__excerpt { margin: 0; color: rgba(255, 255, 255, .55); font-size: 14px; font-weight: 300; line-height: 1.5; flex: 1; }
.event-card__cta { align-self: flex-start; margin-top: 4px; }
/* .outline__button defaults to dark text for the light page — the card
   itself stays a dark tile, so its CTA needs the light variant instead. */
.event-card .outline__button {
  border-color: rgba(255, 255, 255, .3);
  color: #fff;
}
.event-card .outline__button:hover { border-color: var(--orange); background: rgba(244, 127, 0, .15); }

/* ---------- Events carousel: slider of grid pages ---------- */
/* overrides.js groups the flat list of event cards into N-per-page slides
   (6 desktop / 2 tablet / 1 mobile) and inits Slick (slidesToShow:1) on
   the result — see makeCollageCarousel() in overrides.js. */
.events-carousel { position: relative; padding: 48px 0 16px; }
.events-carousel__head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px; margin-bottom: 32px; }
.events-gallery .slick-track { display: flex; align-items: stretch; }
.events-gallery .slick-slide { height: auto; }
.events-gallery__slide { width: 100%; }
.events-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.events-gallery__item { padding: 10px; }
.events-carousel__footer { display: flex; justify-content: center; margin-top: 40px; }
.speakers__more { display: flex; justify-content: center; margin-top: 24px; }
.speakers__more--button:disabled { opacity: .6; cursor: default; }

@media (max-width: 960px) {
  .events-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .events-grid { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  .header { padding: 2rem 0; }
  .event-card__body { padding: 18px; }
  .event-card__title { font-size: 18px; }
  .events-carousel { padding: 32px 0 8px; }
}

/* ---------- Calendar page ---------- */
/* Year tabs and the event-type chips (inside the dropdown below) share
   .moders__city/.moders__year — legacy border was a near-invisible
   rgba(255,255,255,.5), meant for the old dark page. */
.moders__city, .moders__year {
  border-radius: var(--radius-pill);
  border-color: rgba(26, 26, 26, .18);
  transition: border-color .2s ease, background-color .2s ease;
}
.moders__city.active, .moders__city:hover,
.moders__year.active, .moders__year:hover {
  border-color: var(--orange);
  background: var(--orange-soft);
}

/* Event-type filter: a dropdown instead of a permanently-visible row of
   chips, so the filter doesn't compete with the calendar for attention.
   .filter__type's own click behaviour (toggling which event types show,
   in main.js) is untouched — this only adds a collapsible wrapper around
   the existing chip list. Toggled by a few lines in overrides.js. */
.calendar-filter { position: relative; width: 100%; max-width: 320px; margin-top: 3rem; }
.calendar-filter__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  padding: 1.2rem 2rem;
  border: 1px solid rgba(244, 127, 0, .5);
  border-radius: var(--radius-pill);
  background: #fff;
  color: var(--ink);
  font-family: "Geologica", Arial, sans-serif;
  font-size: 1.4rem;
  font-weight: 500;
  cursor: pointer;
  transition: border-color .2s ease;
}
.calendar-filter__toggle:hover { border-color: var(--orange); }
.calendar-filter__chevron { flex-shrink: 0; transition: transform .2s ease; }
.calendar-filter.open .calendar-filter__toggle { border-color: var(--orange); }
.calendar-filter.open .calendar-filter__chevron { transform: rotate(180deg); }

.calendar-filter__panel {
  position: absolute;
  z-index: 20;
  top: calc(100% + 8px);
  left: 0;
  width: max-content;
  min-width: 100%;
  max-width: min(480px, 90vw);
  margin-top: 0 !important;
  padding: 1.6rem;
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 16px 40px rgba(0, 0, 0, .14);
  display: none;
}
.calendar-filter.open .calendar-filter__panel { display: block; }
.calendar-filter__panel .filter__content--inner { gap: 8px; }
.calendar-filter__panel .moders__city { padding: .8rem 1.8rem; font-size: 1.3rem; }

.calendar-filter__actions {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 1.2rem;
  padding-bottom: 1.2rem;
  border-bottom: 1px solid rgba(26, 26, 26, .08);
}
.calendar-filter__action {
  padding: 0;
  border: none;
  background: none;
  color: var(--ink-soft);
  font-family: "Geologica", Arial, sans-serif;
  font-size: 1.2rem;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.calendar-filter__action:hover { color: var(--orange); }

/* The year-row + calendar grid both grew a margin-top from .moders__year--
   inner/.cal__carousel.active in legacy CSS; the filter dropdown above
   already carries its own margin-top, so give the grid a bit less. */
.cal__carousel.active { margin-top: 3rem; }

/* The 12 months were stacking one per row (.cal__carousel never got a
   layout for its .calendar__item children — only .calendar__box, a
   different/unused legacy wrapper, had flex-wrap), stretching the page
   into a tall single column. Let them wrap into a proper grid instead. */
.cal__carousel {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 24px;
}

/* Days with 2+ events ("selectlink" in custom_cal.py) render a day badge
   plus a <ul> of links. main.js already wires a click-to-toggle dropdown
   for this (.selectlink-control click -> slideToggle on the next <ul>),
   but the list itself never got any CSS — no default-hidden state, no
   positioning — so it always rendered open, inline, pushing the rest of
   that week out of the grid. */
/* .selectlink-control inherits .calendar__item--num's width, a percentage
   (100%/7 - 60px/7) meant to resolve against .calendar__item--content (the
   7-column week row). But .selectlink-control's real parent is .selectlink,
   an extra wrapper with no width of its own, so that percentage resolved
   against an ambiguous/shrinking box instead — collapsing the badge and,
   it turned out, its hit area along with it (fixing the visible size with
   a second percentage still left the two in a fragile mutual dependency).
   Give the control an explicit pixel width instead — matching the other
   day cells' actual rendered size at this fixed card width (380px card,
   4rem/64px side padding, 7 columns, 10px gaps: (380-128-60)/7) — so it no
   longer depends on its parent's size at all; .selectlink then naturally
   shrink-wraps to that one explicitly-sized child. */
/* .calendar__item--content is a flex row with the default align-items:
   stretch, and .selectlink has no height of its own — it was stretching
   to the row's cross-size instead of the 34.94px every other day cell
   gets from its own explicit height, squashing the circle into an oval. */
.selectlink { position: relative; z-index: 1; height: 34.94px; }
.selectlink .selectlink-control { width: 27.43px; cursor: pointer; }
/* .calendar__item--num:hover (legacy) sets background:none + color:#fff —
   fine on the old dark page, invisible on this light one. Only affects
   cells with no color class (plain empty days, and this one, which
   never gets one — see custom_cal.py's "selectlink" branch), since
   colored event days hover via their own more specific .orange/.green/etc
   rules instead. */
.selectlink-control:hover { background: #E59734; color: #fff; }
/* .selectlink-menu is styled as its own standalone class, not as a
   descendant of .selectlink — it gets moved out to a direct child of
   <body> while open (see overrides.js, escaping Slick's overflow:hidden
   clip), and a descendant selector like ".selectlink ul" simply stops
   matching the moment it's no longer nested inside .selectlink, which
   silently dropped every one of these rules (background, padding,
   shadow, and the open/closed opacity toggle alike) the instant it was
   portaled — this class applies identically wherever the element is. */
.selectlink-menu {
  position: absolute;
  z-index: 30;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 260px;
  margin: 0;
  padding: 10px;
  list-style: none;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 12px 30px rgba(0, 0, 0, .18);
  text-align: left;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity .15s ease, visibility 0s .15s;
}
.selectlink-menu.selectlink-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity .15s ease, visibility 0s;
}
.selectlink-menu li + li { margin-top: 6px; }
.selectlink-menu a {
  display: block;
  color: var(--ink);
  font-size: 1.2rem;
  line-height: 1.4;
  text-decoration: none;
}
.selectlink-menu a:hover { color: var(--orange); text-decoration: underline; }
.selectlink-city { display: none; }

/* ---------- "Мероприятие завершилось" modal (past-event join button) ---------- */
.modal__content.event-ended { align-items: center; text-align: center; max-width: 640px; }
.event-ended__text {
  max-width: 440px;
  margin: 0 auto;
  color: var(--ink-soft);
  font-size: 1.5rem;
  line-height: 1.6;
  font-weight: 300;
}
.event-ended__cards {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  width: 100%;
  margin-top: 3.2rem;
}
.event-ended__card {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  width: 220px;
  border-radius: var(--radius-card);
  background: var(--card-bg);
  text-align: left;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease;
}
.event-ended__card:hover { transform: translateY(-4px); box-shadow: 0 16px 40px rgba(0, 0, 0, .25); }
.event-ended__card-media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: #1a1a1a; }
.event-ended__card-media img { width: 100%; height: 100%; object-fit: cover; }
.event-ended__card-date {
  position: absolute;
  left: 10px;
  bottom: 10px;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(6px);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .3px;
  text-transform: uppercase;
}
.event-ended__card-body { display: flex; flex-direction: column; gap: 6px; padding: 14px 16px 18px; }
.event-ended__card-city { color: rgba(255, 255, 255, .5); font-size: 11px; font-weight: 500; text-transform: uppercase; letter-spacing: .3px; }
.event-ended__card-title { color: #fff; font-size: 14px; font-weight: 600; line-height: 1.3; }

@media (max-width: 560px) {
  .event-ended__card { width: 100%; max-width: 280px; }
}

/* ---------- Event page builder blocks (admin: Event > Блоки страницы) ---------- */
.event-blocks-section { padding: 48px 0 64px; }
.event-block { margin-bottom: 48px; }
.event-block:last-child { margin-bottom: 0; }
.event-block__title {
  margin: 0 0 16px;
  color: var(--ink);
  font-family: "Geologica", Arial, sans-serif;
  font-weight: 600;
  font-size: 2rem;
}
.event-block__richtext { color: var(--ink); font-size: 1.5rem; font-weight: 300; line-height: 1.7; }

.event-block--moderator .event-block__moderator {
  display: flex;
  gap: 24px;
  align-items: flex-start;
  padding: 24px;
  border-radius: var(--radius-card);
  background: #fff;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .08);
}
.event-block__moderator-photo { width: 140px; flex-shrink: 0; aspect-ratio: 3 / 4; border-radius: 12px; overflow: hidden; }
.event-block__moderator-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.event-block__moderator-logo { height: 30px; margin-bottom: 8px; }
.event-block__moderator-name { margin: 0; color: var(--ink); font-weight: 600; font-size: 1.6rem; }
.event-block__moderator-post, .event-block__moderator-org, .event-block__moderator-comp {
  margin: 4px 0 0;
  color: var(--ink-soft);
  font-size: 1.3rem;
  font-weight: 300;
}

.event-block__speakers-grid { display: flex; flex-wrap: wrap; gap: 20px; }
.event-block__speaker { width: 160px; }
.event-block__speaker-photo { aspect-ratio: 3 / 4; border-radius: var(--radius-card); overflow: hidden; background: #1a1a1a; }
.event-block__speaker-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.event-block__speaker-name { margin: 10px 0 0; color: var(--ink); font-weight: 600; font-size: 1.3rem; }
.event-block__speaker-org { margin: 2px 0 0; color: var(--ink-soft); font-size: 1.2rem; font-weight: 300; }

.event-block--quote {
  padding: 32px;
  border-left: 4px solid var(--orange);
  border-radius: 12px;
  background: var(--orange-soft);
}
.event-block__quote-text { color: var(--ink); font-size: 1.7rem; font-style: italic; line-height: 1.6; }
.event-block__quote-author { display: block; margin-top: 12px; color: var(--ink-soft); font-size: 1.3rem; font-style: normal; }

.event-block__gallery-item {
  display: inline-block;
  width: calc(33.333% - 14px);
  margin: 0 20px 20px 0;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-card);
  overflow: hidden;
  vertical-align: top;
}
.event-block__gallery-item:nth-child(3n) { margin-right: 0; }
.event-block__gallery-item img { display: block; width: 100%; height: 100%; object-fit: cover; }

.event-block--promo {
  display: flex;
  align-items: center;
  gap: 24px;
  overflow: hidden;
  border-radius: var(--radius-card);
  background: var(--card-bg);
}
.event-block--promo .event-block__promo-media { flex: 1; aspect-ratio: 16 / 9; align-self: stretch; }
.event-block--promo .event-block__promo-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.event-block--promo .event-block__promo-content { flex: 1; padding: 24px; }
.event-block--promo .event-block__title, .event-block--promo .event-block__richtext { color: #fff; }

.event-block--button { display: flex; justify-content: center; margin-top: 32px; }

@media (max-width: 760px) {
  .event-block--moderator .event-block__moderator { flex-direction: column; align-items: center; text-align: center; }
  .event-block__moderator-photo { width: 160px; }
  .event-block__gallery-item { width: calc(50% - 10px); }
  .event-block__gallery-item:nth-child(3n) { margin-right: 20px; }
  .event-block__gallery-item:nth-child(2n) { margin-right: 0; }
  .event-block--promo { flex-direction: column; }
  .event-block--promo .event-block__promo-media { width: 100%; }
}
@media (max-width: 480px) {
  .event-block__gallery-item { width: 100%; margin-right: 0; }
}

/* ---------- Event page: guest (.gest) carousel and moderator card reuse
   the homepage's .moders__item/.speakers__item hover-reveal pattern (see
   the "Speakers / team" rules above) for the same rounded-photo +
   hover-reveal-content + push-in-on-hover effect. .moders__item on the
   homepage is sized by its carousel slide; here the moderator card sits
   directly in the page (not a carousel slide), so it needs its own width
   or the 3:4 aspect-ratio box would stretch edge-to-edge. ---------- */
.event__moderator-card { max-width: 280px; margin: 0; }

/* The base .speakers__item rule above adds margin:0 10px on top of
   width:100%, which relies on Slick sizing the slide itself on the
   homepage. Here .speakers__item sits directly inside .carousel_2's
   legacy .splide__slide, which already has its own fixed width
   (calc(50% - 10px)) and its own margin for gutters between slides
   (style.css .carousel_2 .splide__slide) — adding more margin on top
   makes the card 20px wider than its slide, and Splide's base
   .splide__track{overflow:hidden} then clips that overflow off the
   right edge, which also hides the hover-reveal content sitting in
   the clipped area. Zero it out here so the card fills its slide
   exactly. */
.carousel_2 .speakers__item { margin: 0; }

/* Legacy .carousel_2 img{position:absolute; ...} (style.css) has higher
   specificity (class+type) than our single-class .moders__item--img rule,
   so it wins regardless of load order and forces the photo back to
   position:absolute — which then activates the unrelated legacy
   .moders__item--img{z-index:2} rule from the old non-hover-card layout
   (z-index only applies to positioned elements, and static was keeping it
   inert). With z-index:2 the photo paints above .speakers__item--content
   (z-index:auto), hiding the hover-reveal name/company text completely
   even though it's correctly shown and styled underneath. Re-assert
   position:static with matching specificity so the image stays in normal
   flow below the overlay, as intended. */
.carousel_2 .moders__item--img { position: static; z-index: auto; }

/* Same iOS Safari swipe-vs-scroll contention as the homepage's Slick
   carousel (see .moders__carousel, .speakers__carousel above) — this
   carousel is Splide, draggable once mounted below the 768px breakpoint
   (jinit.js), so it needs the same touch-action escape hatch. */
.js-carousel_2, .js-carousel_3 { touch-action: pan-y; }

/* ---------- Scroll reveal: sections fade/slide in as they enter the
   viewport (overrides.js watches .js-scroll-reveal with an
   IntersectionObserver and adds .is-visible once, on first entry).
   Gated behind html.js (flipped from .no-js by the inline script in
   <head>) so a page with JS disabled or broken never leaves content
   stuck invisible — the hidden starting state only exists once we know
   the reveal script can actually run to remove it. prefers-reduced-motion
   gets the same unconditionally-visible treatment. ---------- */
html.js .js-scroll-reveal {
  opacity: 0;
  transform: translateY(48px);
  transition: opacity .8s cubic-bezier(.16, .84, .44, 1), transform .8s cubic-bezier(.16, .84, .44, 1);
  will-change: opacity, transform;
}
html.js .js-scroll-reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  html.js .js-scroll-reveal { opacity: 1; transform: none; transition: none; }
}

/* ---------- Logo "materialize" intro: cyberpunk chromatic-aberration
   glitch. drop-shadow (not box-shadow) is what gives the cyan/magenta
   fringing — it follows the image's own alpha shape instead of drawing a
   rectangle behind it, so it reads as RGB-split color fringing on the
   logo itself. Two repeating-gradient scanline layers (cyan + magenta)
   sweep down independently for a CRT/HUD feel, and everything moves in
   steps() rather than eased so it reads as digital jump-cuts, not a
   smooth fade. Runs once on page load — these sit in the header, already
   in the first viewport, so there's nothing to scroll-trigger. */
.js-logo-materialize {
  position: relative;
  display: inline-block;
}
.js-logo-materialize img {
  animation: logoGlitchReveal 1.3s steps(14) both;
}
.js-logo-materialize::before,
.js-logo-materialize::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  mix-blend-mode: screen;
}
.js-logo-materialize::before {
  background: repeating-linear-gradient(0deg, rgba(0, 234, 255, .55) 0px, rgba(0, 234, 255, .55) 2px, transparent 2px, transparent 5px);
  animation: logoScanCyan 1.3s steps(11) both;
}
.js-logo-materialize::after {
  background: repeating-linear-gradient(0deg, rgba(255, 0, 170, .45) 0px, rgba(255, 0, 170, .45) 2px, transparent 2px, transparent 6px);
  animation: logoScanMagenta 1.3s steps(9) both;
}
@keyframes logoGlitchReveal {
  0% { clip-path: inset(0 0 100% 0); opacity: 0; filter: drop-shadow(-7px 0 0 #00eaff) drop-shadow(7px 0 0 #ff00aa) brightness(1.7) contrast(1.3); transform: translateX(0); }
  7% { clip-path: inset(0 0 85% 0); opacity: 1; transform: translateX(-8px); }
  14% { clip-path: inset(0 0 78% 0); transform: translateX(7px); }
  21% { clip-path: inset(0 0 66% 0); transform: translateX(-6px); filter: drop-shadow(-5px 0 0 #00eaff) drop-shadow(5px 0 0 #ff00aa) brightness(1.5) contrast(1.2); }
  29% { clip-path: inset(0 0 55% 0); transform: translateX(5px); }
  36% { clip-path: inset(0 0 48% 0); opacity: .35; transform: translateX(-9px); }
  43% { clip-path: inset(0 0 40% 0); opacity: 1; transform: translateX(4px); filter: drop-shadow(-4px 0 0 #00eaff) drop-shadow(4px 0 0 #ff00aa) brightness(1.3); }
  50% { clip-path: inset(0 0 32% 0); transform: translateX(-4px); }
  57% { clip-path: inset(0 0 25% 0); transform: translateX(3px); }
  64% { clip-path: inset(0 0 20% 0); opacity: .5; filter: drop-shadow(-3px 0 0 #00eaff) drop-shadow(3px 0 0 #ff00aa) brightness(1.2); }
  71% { clip-path: inset(0 0 14% 0); opacity: 1; transform: translateX(-2px); }
  79% { clip-path: inset(0 0 9% 0); transform: translateX(2px); filter: drop-shadow(-2px 0 0 #00eaff) drop-shadow(2px 0 0 #ff00aa) brightness(1.1); }
  88% { clip-path: inset(0 0 4% 0); transform: translateX(-1px); filter: drop-shadow(0 0 6px rgba(0, 234, 255, .8)) drop-shadow(0 0 6px rgba(255, 0, 170, .6)) brightness(1.3); }
  100% { clip-path: inset(0 0 0 0); opacity: 1; filter: none; transform: translateX(0); }
}
@keyframes logoScanCyan {
  0% { opacity: .9; clip-path: inset(0 0 100% 0); transform: translateX(-3px); }
  45% { opacity: .7; clip-path: inset(0 0 45% 0); transform: translateX(2px); }
  75% { opacity: .4; clip-path: inset(0 0 10% 0); transform: translateX(0); }
  100% { opacity: 0; clip-path: inset(0 0 0 0); transform: translateX(0); }
}
@keyframes logoScanMagenta {
  0% { opacity: .85; clip-path: inset(0 0 100% 0); transform: translateX(3px); }
  55% { opacity: .6; clip-path: inset(0 0 35% 0); transform: translateX(-2px); }
  80% { opacity: .3; clip-path: inset(0 0 8% 0); transform: translateX(0); }
  100% { opacity: 0; clip-path: inset(0 0 0 0); transform: translateX(0); }
}
@media (prefers-reduced-motion: reduce) {
  .js-logo-materialize img { animation: none; }
  .js-logo-materialize::before, .js-logo-materialize::after { content: none; }
}
