/* ==========================================================================
   Base reset & element defaults
   ========================================================================== */

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  height: 100%;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

/* Horizontal-overflow safety net for responsive layouts, scoped to <main>
   (where the content sections live) rather than <html>/<body>. Putting any
   overflow-x on the root/body relocates or removes the page's own vertical
   scrollbar, which reintroduced the sideways "jump" when a modal/lightbox
   opened (the scroll-lock could no longer measure/compensate the scrollbar
   width). Clipping only <main> keeps the page scrollbar — and the
   scroll-lock — untouched while still stopping any stray-wide section from
   creating a horizontal scrollbar. */
body > main {
  overflow-x: clip;
}

/* --- Responsive foundations ---
   Reducing --container-pad (and the header height) at each breakpoint
   cascades to EVERY section at once, since every layout consumes these
   tokens rather than hard-coded values. One change, whole-site effect. */
@media (max-width: 1024px) {
  :root {
    --container-pad: 32px;
  }
}

@media (max-width: 767px) {
  :root {
    --container-pad: 20px;
    --header-height: 68px;
  }
}

@media (max-width: 480px) {
  :root {
    --container-pad: 16px;
  }
}

/* Sticky footer: body is a column flex box spanning at least the full
   viewport height, and <main> (the middle child, between <header> and
   <footer> on every page) absorbs any leftover space via flex-grow. Short
   pages push the footer to the bottom of the screen instead of leaving it
   stranded mid-viewport, and — the case this was actually written for —
   a filtered listing page (e.g. Portfolio's category pills) that suddenly
   has far fewer cards just grows/shrinks the gap above the footer instead
   of the whole page jumping as the footer's position recalculates. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body > header {
  flex-shrink: 0;
}

body > main {
  flex: 1 0 auto;
}

body > footer {
  flex-shrink: 0;
}

img,
svg {
  display: block;
  max-width: 100%;
  user-select: none;
}

/* Accessibility (WCAG 2.4.1 "Bypass Blocks"): a keyboard/screen-reader
   shortcut that jumps focus past the repeated header nav straight to the
   page's <main id="main">. Off-screen until it receives focus (first Tab),
   then slides in at the top-left. Invisible to mouse users. */
.skip-link {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 2000;
  padding: 10px 16px;
  border-radius: var(--radius-sm);
  background: var(--color-bg-elevated);
  color: var(--color-text);
  font-size: var(--fs-small);
  font-weight: 700;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  transform: translateY(-150%);
  opacity: 0;
  transition: transform var(--duration-fast) var(--ease-standard),
    opacity var(--duration-fast) var(--ease-standard);
}

.skip-link:focus {
  transform: translateY(0);
  opacity: 1;
  outline: 2px solid var(--color-orange);
  outline-offset: 2px;
}

/* Visually hidden but still read by screen readers / indexed — for text
   that's been replaced by a visual (e.g. the 404 page's heading, which the
   Lottie now conveys). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* The <main> is only focusable programmatically (tabindex="-1" so the skip
   link can land focus there) — never show a focus ring around the whole
   page body when that happens. */
main:focus {
  outline: none;
}

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

/* Nav links, button labels, the logo — any interactive/decorative chrome —
   shouldn't highlight like body copy on a stray click-drag; only actual
   content text (paragraphs, headings, list copy) should stay selectable. */
a,
button,
[data-lottie] {
  user-select: none;
}

button {
  font: inherit;
  color: inherit;
  background: none;
  border: none;
  cursor: pointer;
}

ul {
  list-style: none;
}

h1,
h2,
h3,
h4 {
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.15;
}

:focus-visible {
  outline: 2px solid var(--color-orange);
  outline-offset: 2px;
}

.container {
  max-width: var(--container-max);
  margin-inline: auto;
  padding-inline: var(--container-pad);
}

/* Generic scroll-reveal utility (paired with js/reveal.js): add
   data-reveal to any element and it fades/slides up once scrolled into
   view. --reveal-delay lets a group of elements stagger (set via
   data-reveal-delay="120" etc, or hardcoded per selector). Timing/easing
   matches .faq__row exactly (css/faq.css) — that cascade is the reference
   "soft, smooth" feel every standard element (not one with its own bespoke
   animation, e.g. the roadmap map or the stats counters) should share. */
[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 1100ms var(--ease-standard) var(--reveal-delay, 0ms),
    transform 1100ms var(--ease-standard) var(--reveal-delay, 0ms);
}

[data-reveal].is-revealed {
  opacity: 1;
  transform: translate(0, 0);
}

/* Opt-out of the slide-up for elements that should only fade in place
   (the trust-bar logo strip, the footer brand mark, the footer bottom
   bar) — add alongside data-reveal, no separate JS handling needed since
   reveal.js only ever toggles the .is-revealed class. */
[data-reveal][data-reveal-fade],
[data-reveal][data-reveal-fade].is-revealed {
  transform: none;
}

/* Inner pages (everything except the homepage) share ONE calm animation
   logic: fade-only, no slide, so every section/carousel/block on every
   inner page reveals the same way. The homepage keeps its own slide-ups.
   Single source of truth — set once here, opted into by <body class="inner">. */
body.inner [data-reveal] {
  transform: none;
}

/* Tablet/mobile: no entrance/scroll motion at all — these viewports have
   no cursor and only need to display + respond to taps, so every
   [data-reveal] element is shown in its final state immediately with no
   fade, slide or transition. The stats counters are the one deliberate
   exception the user asked to keep: they run off their own
   IntersectionObserver (js/counter.js), independent of this class, so
   neutralising the reveal here doesn't touch them. Section-specific
   ambient/hover motion (roadmap timeline, banner mosaic drift, Lottie
   hover bursts, button hover-lifts) is disabled in each section's own
   ≤1024px block / hover guard. */
@media (max-width: 1024px) {
  [data-reveal],
  [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Shared thin gradient hairline for use between two dark sections whose
   background shades sit close enough that the seam otherwise reads as one
   long block — same technique/colors as .stats::before/::after (a
   full-bleed 1px purple->orange bar, transparent at both ends). */
.section-divider {
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(91, 42, 134, 0.5), rgba(255, 122, 26, 0.5), transparent);
}

/* Wraps any CTA button with a decorative fire-burst Lottie sitting behind
   it, centered on the button and bottom-aligned so the flame reads as
   shooting up from behind the button on hover. Reused across sections —
   see banner.css / roadmap.css for the specific instances and their own
   spacing. */
.cta-liquid {
  position: relative;
  display: inline-block;
}

.cta-liquid .btn {
  position: relative;
  z-index: 1;
}

.cta-liquid__fx {
  position: absolute;
  left: 50%;
  bottom: 0;
  transform: translateX(-50%);
  width: 130px;
  height: 255px;
  pointer-events: none;
  z-index: 0;
  filter: drop-shadow(0 0 0 rgba(192, 41, 139, 0));
  transition: filter 260ms var(--ease-standard);
}

.cta-liquid__fx.is-playing {
  filter: drop-shadow(0 0 22px rgba(192, 41, 139, 0.65)) drop-shadow(0 0 40px rgba(255, 122, 26, 0.35));
}

.cta-liquid__fx svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Fire burst + button hover-lift are a DESKTOP-only effect. On tablet/mobile
   (no cursor) the fire is hidden and the button stays static — a tap fires
   pointerenter right before click, so leaving it on made the effect play on
   every tap. Desktop keeps the fire exactly as it was. */
@media (max-width: 1024px) {
  .cta-liquid .btn--cta,
  .cta-liquid .btn--cta:hover,
  .cta-liquid .btn--cta:active,
  .cta-liquid .btn--cta:focus-visible {
    transform: none;
    box-shadow: var(--shadow-brand), inset 0 1px 0 rgba(255, 255, 255, 0.16);
  }

  .cta-liquid__fx {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   Mobile + tablet (≤1024px), per the studio's standing rules:
   • no entrance animation — [data-reveal] is shown immediately (js/reveal.js
     also early-returns at this width; this is the safety net);
   • .rm-hide-mobile hides a whole block on small screens (a per-block toggle
     in the section constructor / carousel / CTA);
   • the constructor "Кнопка" with the sticky toggle goes full-width and pins
     under the header on scroll (js/banner-cta-sticky.js, via data-sticky-cta),
     exactly like the homepage / verstka hero button.
   ========================================================================== */
/* Desktop default for the sticky-toggle button — a normal inline button (no
   inline style is emitted for it, so the ≤1024 rule below can switch it to a
   full-width block). */
.rm-sticky-cta {
  display: inline-block;
}

@media (max-width: 1024px) {
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
  .rm-hide-mobile {
    display: none !important;
  }
  .rm-sticky-cta {
    display: block;
    width: 100%;
    margin-top: var(--space-6);
  }
  .rm-sticky-cta .btn {
    width: 100%;
  }
  .rm-sticky-cta.is-stuck {
    position: fixed;
    top: var(--header-height);
    left: var(--container-pad);
    right: var(--container-pad);
    width: auto;
    margin: 0;
    z-index: 40;
  }
}

/* Touch screens have no persistent hover — neutralise the card image-zoom so a
   tap that briefly sticks :hover doesn't jerk the thumbnail. */
@media (hover: none) {
  a:hover .services__more-media img {
    transform: none;
  }
}
