/* Starky's Software — static rebuild
   Increment 1: header / navigation.
   Increment 2: hero.
   Increment 3: brand strip.
   Tokens below are limited to what the built sections actually use (see
   verify/tokens/colors.md, typography.md). More tokens are added as
   later sections are rebuilt. */

:root {
  --blue: #4743ef;
  --blue30: #c6c5f0;
  --white: #fff;
  --white600: #adaca8;
  --black: #161616;
  --black800: #181715;
  --transparent: transparent;
  --heading-font: "Urbanist", sans-serif;
  --paragraph-font: "Mulish", sans-serif;
}

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

body {
  margin: 0;
  font-family: var(--paragraph-font);
  /* The original's body sets both of these; without the line-height every
     element that doesn't declare its own inherited `normal` instead of 24px
     (measured on the team role/e-mail lines and the header logo link). */
  font-size: 1rem;
  line-height: 1.5rem;
  color: var(--black800);
  /* Reference sets `background-color: #fff` on body (reference CSS line 224).
     Every homepage section already carries its own background so this never
     showed a gap there, but the legal pages' .legal-section doesn't set one
     and was falling through to the browser's own default canvas. */
  background-color: var(--white);
}

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

/* The original does not use the UA paragraph margins — Webflow's base sets
   `p { margin-top: 0; margin-bottom: 10px }`, which every paragraph on the
   live page inherits (verified: computed 0px/10px on About, Services and
   testimonial copy). Without this, every such paragraph gained 18px/18px UA
   margins and pushed About/Services out of parity. */
p {
  margin-top: 0;
  margin-bottom: 10px;
}

a {
  font-family: inherit;
}

/* The original wraps the whole page in `.page-wrapper`, which carries
   `margin-top: -55px` at <=479px — pulling every in-flow section up under the
   absolutely-positioned navbar. `main` is this build's equivalent in-flow
   wrapper, so the same offset is applied there (the header is absolute and
   unaffected either way, exactly as on the original). */
@media (max-width: 479px) {
  main {
    margin-top: -55px;
  }
}

/* ---------- Header ---------- */

.navbar {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  background-color: var(--transparent);
  padding-bottom: 1.875rem;
}

@media (max-width: 991px) {
  .navbar {
    padding-bottom: 0;
  }
}

.nav-container {
  position: relative;
  display: flex;
  flex-flow: row nowrap;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  max-width: 75rem;
  margin-left: auto;
  margin-right: auto;
  padding: 1.0625rem 1.8725rem;
  background-color: var(--blue);
}

@media (min-width: 1280px) {
  .nav-container {
    max-width: none;
  }
}

@media (min-width: 1440px) {
  .nav-container {
    padding-left: 4rem;
    padding-right: 4rem;
  }
}

@media (min-width: 1920px) {
  .nav-container {
    padding-left: 5rem;
    padding-right: 5rem;
  }
}

.brand-logo {
  display: block;
  flex: 0 0 auto;
}

/* Original: `.brandlogo { margin-left: -5px }` at <=479px (and
   `.nav-brand-logo { padding-left: 0 }`), which also shrinks the logo's flex
   base from 60px to 55px. */
@media (max-width: 479px) {
  .brand-logo {
    padding-left: 0;
  }

  .brand-logo img {
    margin-left: -5px;
  }
}

/* ---------- Hamburger ---------- */

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 6px;
  background: transparent;
  border: 0;
  padding: 8px;
  cursor: pointer;
}

@media (max-width: 991px) {
  .nav-toggle {
    display: flex;
  }
}

.nav-toggle-line {
  width: 24px;
  height: 2px;
  background-color: var(--white);
}

/* Open state is derived from the existing aria-expanded state set by
   nav.js (openMobileNav/closeMobileNav) — no separate visual state. */
#nav-toggle[aria-expanded="true"] .nav-toggle-line:nth-child(1) {
  transform: translateY(8px) rotate(45deg);
}

#nav-toggle[aria-expanded="true"] .nav-toggle-line:nth-child(2) {
  opacity: 0;
}

#nav-toggle[aria-expanded="true"] .nav-toggle-line:nth-child(3) {
  transform: translateY(-8px) rotate(-45deg);
}

/* ---------- Nav (desktop row / mobile collapsible panel) ---------- */

.site-nav {
  display: flex;
  flex-flow: row nowrap;
  align-items: center;
  gap: 1.875rem;
}

@media (max-width: 991px) {
  .site-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-flow: column;
    align-items: flex-start;
    gap: 0.75rem;
    background-color: var(--blue);
    padding: 1.25rem 1.875rem;
  }

  .site-nav.is-open {
    display: flex;
  }
}

.nav-link {
  font-family: var(--heading-font);
  color: var(--white);
  font-size: 1rem;
  line-height: 1rem;
  text-decoration: none;
  padding: 0.625rem;
  position: relative;
}

/* No :hover color rule: on the live original, .nav-link's own color
   (#d4d4d4, and :hover's var(--blue)) is never actually visible — the
   real text sits in a separate child, .nav-text, which carries its own
   explicit `color: var(--white)` that overrides the parent's color at
   every state, hover included. A 2026-09-08 corrective pass measured
   .nav-link's own computed color on hover (matched .nav-container's
   background exactly) and concluded the text goes unreadable there —
   without checking which element the visible text actually lives in.
   This markup has no .nav-text wrapper (the text sits directly inside
   .nav-link), so that same hover rule was visibly changing the text to
   blue-on-blue here — a real, rebuild-only regression, not a
   reproduction of the original. Corrected 2026-09-28: text is white,
   unchanged on hover, matching the original's true (if convoluted)
   behavior. See DECISIONS.md. */

/* Underline reveal: confirmed live via the IX2 action config (not guessed
   from resting CSS) — hover-in 500ms ease to width:100%, hover-out 300ms
   ease back to width:0%. The asymmetric duration is intentional: CSS takes
   the destination rule's `transition` value, so hover-in uses the width:100%
   rule's 0.5s and hover-out uses this rule's 0.3s. No `:focus-visible`: the
   original binds only MOUSE_OVER/MOUSE_OUT, no keyboard-focus equivalent
   confirmed — not added here (parity phase). */
.nav-link::after {
  content: "";
  position: absolute;
  left: 0.625rem;
  right: 0;
  bottom: 0;
  height: 1px;
  background-color: var(--white);
  width: 0%;
  transition: width 0.3s ease;
}

.nav-link:hover::after {
  width: 100%;
  transition: width 0.5s ease;
}

/* ---------- Language switcher ---------- */

.lang-switcher {
  position: relative;
}

.lang-toggle {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  border: 0;
  color: var(--white);
  font-family: var(--heading-font);
  font-size: 1rem;
  line-height: 1rem;
  padding: 0.625rem;
  cursor: pointer;
  position: relative;
}

/* Confirmed live: 35x35 (the toggle's own flag image, .icon-lang, and
   the dropdown items' flags share this exact size) — this rebuild had
   the toggle's flag at a non-square 20x14, a leftover guess from
   before the dropdown-item flags were measured. See DECISIONS.md. */
.lang-toggle-flag {
  display: block;
  flex-shrink: 0;
  width: 35px;
  height: 35px;
  object-fit: cover;
}

/* Confirmed live via IX2 (a-448/a-449): the hover TRIGGER here is a
   separate 1px-tall strip along the button's bottom edge, not the whole
   button — the original binds MOUSE_OVER/MOUSE_OUT directly to that
   strip's own element, whose child is the visual bar. Reproduced as two
   nested spans (a real hit-area element + the bar it reveals) rather
   than one, because a single 0%-width element can't be hovered to grow
   itself. Same 500ms-in/300ms-out timing as .nav-link/.lang-link. */
.lang-toggle-underline {
  position: absolute;
  left: 0.625rem;
  right: 0;
  bottom: 0;
  height: 1px;
}

.lang-toggle-underline-bar {
  display: block;
  height: 1px;
  width: 0%;
  background-color: var(--white);
  transition: width 0.3s ease;
}

.lang-toggle-underline:hover .lang-toggle-underline-bar {
  width: 100%;
  transition: width 0.5s ease;
}

/* CSS-only chevron (border-based), decorative — no icon-font dependency.
   No open-state rotation: not confirmed in the original (checked
   .w-icon-dropdown-toggle / .language-toggle.w--open — no transform
   defined there), so none is invented here. */
.lang-toggle-icon {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  margin-top: -3px;
}

.lang-list {
  display: none;
  list-style: none;
  margin: 0;
  padding: 8px 14px 16px;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 160px;
  /* Confirmed live: the base .language-list rule (closed state) sets
     var(--black800), but a separate, more specific
     .language-list.w--open rule (added by Webflow's own runtime once
     the dropdown is genuinely opened) overrides it to var(--blue) —
     that's the only state ever actually visible. A prior pass read the
     base rule via CSSOM without confirming which rule wins once really
     open, and built the wrong (black800) color as a result. See
     DECISIONS.md. */
  background-color: var(--blue);
}

.lang-list.is-open {
  display: block;
}

.lang-link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 45px;
  color: var(--white);
  text-decoration: none;
  position: relative;
}

/* Confirmed missing against live: the original renders a per-language
   flag (35x35) next to each dropdown item, not just on the toggle
   button. Sized at 24x24 first (a guess, not the measured value);
   corrected to the actually-confirmed 35x35 once the toggle's own
   flag was measured too. See DECISIONS.md. */
.lang-link-flag {
  display: block;
  flex-shrink: 0;
  width: 35px;
  height: 35px;
  object-fit: cover;
}

/* Confirmed live: this background-hover only exists at <=479px (checked —
   absent at wider breakpoints in the original stylesheet). Previously
   applied here unscoped at all widths; narrowed to match. */
@media (max-width: 479px) {
  .lang-link:hover {
    background-color: var(--blue);
  }
}

/* Underline reveal, same mechanism/timing as .nav-link (see there for the
   confirmed 500ms-in/300ms-out rationale). Insets baked directly into
   left/right (0.625rem each side) to match the original's visual result
   without reproducing its two-nested-div implementation. */
.lang-link::after {
  content: "";
  position: absolute;
  left: 0.625rem;
  right: 0.625rem;
  bottom: 0;
  height: 1px;
  background-color: var(--white);
  width: 0%;
  transition: width 0.3s ease;
}

.lang-link:hover::after {
  width: 100%;
  transition: width 0.5s ease;
}

/* ---------- Buttons / CTA ---------- */

.button {
  display: inline-block;
  border: 1px solid var(--blue);
  background-color: var(--blue);
  color: var(--white);
  font-family: var(--heading-font);
  letter-spacing: 3px;
  text-transform: uppercase;
  text-decoration: none;
  border-radius: 20px;
  padding: 0.875rem 1.25rem;
  font-size: 0.875rem;
  line-height: 0.875rem;
  transition: color 0.3s, border-color 0.4s, background-color 0.4s;
}

/* Site-wide: the original scales every `.button` up at >=1920px — this was
   missed during the original Hero increment (2026-08-31) and silently
   affected every button on the page (hero CTA, nav CTA, and now the contact
   submit). Confirmed root cause of the Hero section being 10px short at
   >=1920px on CZ/EN (open item in TODO.md before this fix): the hero CTA's
   height feeds directly into `.hero-inner`'s content height, since
   `.section-hero` has no fixed height at this breakpoint. */
@media (min-width: 1920px) {
  .button {
    font-size: 1.2rem;
    line-height: 1.5rem;
  }
}

.button:hover {
  background-color: var(--transparent);
  color: var(--blue);
}

.button.nav-cta {
  border-color: var(--white);
  background-color: var(--white);
  color: var(--blue);
}

/* Shared with Hero's CTA (plain .button, no modifier in the original) —
   confirmed original rule, added now because Hero is the first section
   that actually needs it (a .button inside a centered mobile column). */
@media (max-width: 479px) {
  .button {
    align-self: center;
  }
}

.cta-desktop {
  display: none;
}

.cta-mobile {
  display: none;
}

@media (min-width: 992px) {
  .cta-desktop {
    display: inline-block;
  }
}

@media (max-width: 991px) {
  .cta-mobile {
    display: inline-block;
  }
}

/* ---------- Shared content wrappers (confirmed shared primitive across
   Hero and the future About/Services/Team/Testimonials sections — see
   the Hero-increment PLAN discussion) ---------- */

.content-padding {
  padding-left: 2rem;
  padding-right: 1.5rem;
}

@media (min-width: 1280px) {
  .content-padding {
    padding-left: 1rem;
  }
}

@media (min-width: 1440px) {
  .content-padding {
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
  }
}

@media (min-width: 1920px) {
  .content-padding {
    padding-left: 1.5rem;
  }
}

@media (max-width: 991px) {
  .content-padding {
    /* width:100% (not auto) so this flex item (.hero uses
       align-items:flex-start, so a plain "auto" would shrink-to-fit its
       content instead of filling the row) gives .hero-inner a definite,
       viewport-bound containing block at every width in this range —
       closes the ~480-766px horizontal-overflow gap. See DECISIONS.md
       2026-09-27 (CLEAN). */
    width: 100%;
  }
}

@media (max-width: 767px) {
  .content-padding {
    margin-left: auto;
    margin-right: auto;
    padding-left: 1rem;
  }
}

@media (max-width: 479px) {
  .content-padding {
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

.content-container {
  max-width: 75rem;
  margin-left: auto;
  margin-right: auto;
}

@media (min-width: 1280px) {
  .content-container {
    width: auto;
    max-width: none;
  }
}

@media (min-width: 1440px) {
  .content-container {
    width: 90%;
    max-width: none;
    margin-left: 0;
    margin-right: 0;
  }
}

@media (min-width: 1920px) {
  .content-container {
    width: 90%;
    max-width: none;
  }
}

@media (max-width: 479px) {
  .content-container {
    width: 100%;
    max-width: 75rem;
    margin-left: 0;
    margin-right: 0;
  }
}

/* ---------- Hero ---------- */

.hero {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: flex-start;
  background-color: var(--white);
  background-image: url("../img/hero-bg.png");
  background-position: 100% 0;
  background-repeat: no-repeat;
  background-size: 565px;
  height: 52em;
  margin-top: 45px;
}

@media (min-width: 1280px) {
  .hero {
    background-size: 680px;
    height: 56em;
    margin-top: 35px;
    margin-left: auto;
    margin-right: auto;
  }
}

@media (min-width: 1440px) {
  .hero {
    background-size: 770px;
    height: 55em;
    padding-left: 0;
  }
}

@media (min-width: 1920px) {
  .hero {
    background-position: 100% 0;
    background-size: 50%;
    height: auto;
    margin-top: 90px;
  }
}

@media (max-width: 991px) {
  .hero {
    background-image: none;
    background-repeat: repeat;
    background-size: auto;
    height: 45rem;
  }
}

@media (max-width: 767px) {
  .hero {
    height: 45rem;
  }
}

@media (max-width: 479px) {
  .hero {
    height: 46rem;
    margin-top: 78px;
  }
}

/* DE gets its own confirmed height/background-size/margin values at every
   breakpoint — not a simple scale of the CZ/EN numbers. */
.hero.hero--de {
  background-size: 590px;
  height: 53.3em;
  margin-top: 0;
}

@media (min-width: 1280px) {
  .hero.hero--de {
    background-size: 690px;
    height: 57em;
    margin-top: 0;
  }
}

@media (min-width: 1440px) {
  .hero.hero--de {
    background-size: 730px;
    height: 56em;
    margin-top: 50px;
  }
}

@media (min-width: 1920px) {
  .hero.hero--de {
    background-size: 890px;
    height: 55em;
    margin-top: 96px;
    padding-top: 0;
  }
}

@media (max-width: 991px) {
  .hero.hero--de {
    height: 45em;
  }
}

@media (max-width: 479px) {
  .hero.hero--de {
    height: 52rem;
    margin-top: 70px;
  }
}

.hero-inner {
  display: flex;
  flex-flow: column;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 2.6rem;
  margin-top: -4rem;
  margin-bottom: 35px;
  /* Lets the fixed per-breakpoint width below (600/520/290px) shrink
     instead of overflowing once .content-padding gives it a definite,
     narrower containing block. See DECISIONS.md 2026-09-27 (CLEAN). */
  max-width: 100%;
}

@media (min-width: 1280px) {
  .hero-inner {
    margin-top: 0;
    margin-bottom: 35px;
    padding-left: 20px;
  }
}

@media (min-width: 1440px) {
  .hero-inner {
    gap: 1.5rem;
    width: 630px;
    margin-top: 1rem;
    margin-bottom: 20px;
    padding-left: 50px;
  }
}

@media (min-width: 1920px) {
  .hero-inner {
    justify-content: space-around;
    align-items: flex-start;
    width: auto;
    margin-top: 45px;
  }
}

@media (max-width: 991px) {
  .hero-inner {
    width: 600px;
    margin-top: 0.5rem;
  }
}

@media (max-width: 767px) {
  .hero-inner {
    width: 520px;
    padding-left: 20px;
  }
}

@media (max-width: 479px) {
  .hero-inner {
    text-align: center;
    width: 290px;
    padding-left: 10px;
  }
}

.hero-inner--de {
  margin-top: 0;
  margin-bottom: 40px;
}

@media (min-width: 1280px) {
  .hero-inner--de {
    margin-bottom: 50px;
  }
}

@media (min-width: 1440px) {
  .hero-inner--de {
    justify-content: center;
    align-items: flex-start;
    width: 640px;
    margin-top: 4rem;
  }
}

@media (min-width: 1920px) {
  .hero-inner--de {
    width: auto;
    padding-top: 165px;
    font-size: 4.3rem;
  }
}

@media (max-width: 991px) {
  .hero-inner--de {
    margin-bottom: 40px;
  }
}

@media (max-width: 479px) {
  .hero-inner--de {
    padding-left: 0;
  }
}

.hero-top {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  position: relative;
  padding-top: 0;
}

@media (min-width: 1440px) {
  .hero-top {
    width: auto;
    padding-top: 70px;
  }
}

@media (min-width: 1920px) {
  .hero-top {
    margin-top: 80px;
    padding-top: 37px;
  }
}

.hero-top--de {
  padding-top: 0;
}

@media (min-width: 1920px) {
  .hero-top--de {
    margin-top: -15px;
    padding-top: 0;
  }
}

/* .hero-line: 4px (.25rem) is both the plain CSS value and the Webflow
   IX2 action "a-435" ("Section Hero")'s confirmed animation end state —
   matches what a no-JS visitor sees on the original too (Webflow sets
   the pre-animation 889px via an inline style at runtime, not in its
   static stylesheet). See reveal.js for the scroll-into-view reveal
   (889px -> 4px, 600ms ease-out, one-shot) and DECISIONS.md for the
   audit. Height is not part of the IX2 config at all — it is purely
   CSS-driven and differs by breakpoint/locale below, confirmed by live
   measurement. */
.hero-line {
  background-color: var(--blue);
  width: 0.25rem;
  height: 11rem;
  position: absolute;
}

.hero-line.hero-line--armed {
  width: 889px;
}

.hero-line.hero-line--revealed {
  width: 0.25rem;
  transition: width 0.6s ease-out;
}

@media (min-width: 1280px) {
  .hero-line {
    height: 13rem;
  }
}

@media (min-width: 1440px) {
  .hero-line {
    height: 13.5rem;
  }
}

@media (min-width: 1920px) {
  .hero-line {
    height: 15.5rem;
  }
}

@media (max-width: 479px) {
  .hero-line {
    height: 8rem;
  }
}

.hero-line--en {
  height: 11.5rem;
}

@media (min-width: 1280px) {
  .hero-line--en {
    height: 13rem;
  }
}

@media (min-width: 1920px) {
  .hero-line--en {
    height: 14rem;
  }
}

.hero-line--de {
  height: 7.5rem;
}

@media (min-width: 1280px) {
  .hero-line--de {
    height: 8.5rem;
  }
}

@media (min-width: 1920px) {
  .hero-line--de {
    height: 12.1rem;
  }
}

@media (max-width: 479px) {
  .hero-line--de {
    height: 6.5rem;
  }
}

.hero-heading {
  display: flex;
  flex-flow: column;
  justify-content: flex-start;
  gap: 0.3rem;
  margin-left: 2rem;
  padding-top: 0;
}

@media (min-width: 1920px) {
  .hero-heading {
    align-items: stretch;
    padding-top: 0;
  }
}

@media (max-width: 479px) {
  .hero-heading {
    margin-left: 1.5rem;
    padding-top: 12px;
  }
}

.hero-heading h1 {
  font-family: var(--heading-font);
  color: var(--black);
  text-transform: uppercase;
  margin-top: 0;
  margin-bottom: 0;
  margin-left: 0;
  font-weight: 800;
  font-size: 2.8rem;
  line-height: 3.3rem;
}

@media (min-width: 1280px) {
  .hero-heading h1 {
    font-size: 3.4rem;
    line-height: 3.8rem;
  }
}

@media (min-width: 1440px) {
  .hero-heading h1 {
    font-size: 3.5rem;
    line-height: 3.8rem;
  }
}

@media (min-width: 1920px) {
  .hero-heading h1 {
    font-size: 4rem;
    line-height: 4.5rem;
  }
}

@media (max-width: 991px) {
  .hero-heading h1 {
    color: var(--black800);
  }
}

@media (max-width: 767px) {
  .hero-heading h1 {
    color: var(--black);
    margin-left: 0;
    font-size: 2rem;
  }
}

@media (max-width: 479px) {
  .hero-heading h1 {
    color: var(--black);
    text-align: left;
    align-self: flex-start;
    margin-left: 0;
    font-size: 1.7rem;
    line-height: 2rem;
  }
}

.hero-heading--de h1 {
  font-size: 2.6rem;
  line-height: 3.3rem;
}

@media (min-width: 1280px) {
  .hero-heading--de h1 {
    margin-top: 4px;
    font-size: 3rem;
    line-height: 3.5rem;
  }
}

@media (max-width: 479px) {
  .hero-heading--de h1 {
    font-size: 1.8rem;
    line-height: 2.7rem;
  }
}

.hero-copy {
  width: 40%;
  max-width: none;
  margin-top: 0;
  margin-bottom: 0;
  font-family: var(--paragraph-font);
  color: var(--black);
  font-weight: 500;
  font-size: 1rem;
  line-height: 1.625rem;
}

@media (min-width: 1280px) {
  .hero-copy {
    width: 38%;
    max-width: none;
    margin-top: 0;
  }
}

@media (min-width: 1440px) {
  .hero-copy {
    width: auto;
    max-width: none;
    margin-top: 35px;
    margin-bottom: 20px;
    font-size: 1.2rem;
  }
}

@media (min-width: 1920px) {
  .hero-copy {
    width: 45%;
    max-width: none;
    font-size: 1.7rem;
    line-height: 2.5rem;
  }
}

@media (max-width: 991px) {
  .hero-copy {
    width: auto;
    max-width: 100%;
  }
}

@media (max-width: 767px) {
  .hero-copy {
    max-width: 100%;
  }
}

@media (max-width: 479px) {
  .hero-copy {
    text-align: center;
    margin-bottom: -15px;
    font-size: 1rem;
  }
}

/* ---------- Brand strip ----------
   Nested inside the Hero section (confirmed in source.html: the brand
   strip markup is the last child of the hero section, not a sibling
   <section> — see the Brand Strip PLAN). */

.brand-padding {
  width: auto;
  align-self: stretch;
  padding-left: 0;
  padding-right: 0;
}

/* The original nests the strip in two extra wrappers this build flattens away
   (`.section-brand` > ... > `.brand-component`). Their only measurable effect
   is vertical spacing, folded onto .brand-padding here:
     .section-brand   padding-top 60px (>=1440), margin-top 45px (>=1920),
                      margin-top 20px (<=479)
     .brand-component margin-top 70px (>=1920) — held inside .section-brand
                      because a flex item is its own formatting context. */
@media (min-width: 1440px) {
  .brand-padding {
    padding-top: 60px;
  }
}

@media (min-width: 1920px) {
  .brand-padding {
    margin-top: 45px;
    padding-top: 70px;
  }
}

@media (max-width: 991px) {
  .brand-padding {
    padding-left: 2rem;
  }
}

@media (max-width: 767px) {
  .brand-padding {
    padding-left: 0;
  }
}

@media (max-width: 479px) {
  .brand-padding {
    width: 100%;
    margin-top: 20px;
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
    padding-right: 0;
  }
}

.brand-container {
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
}

.brand-strip {
  position: relative;
  overflow: hidden;
  width: 100%;
  background-color: var(--blue30);
  padding: 1.875rem;
}

@media (min-width: 1920px) {
  .brand-strip {
    padding-left: 5rem;
    padding-right: 0;
  }
}

/* Between 768px and 991px the original cancels .brand-padding's 2rem inset on
   the band itself (`.brand-content-wrapper { margin-left: -32px }`) so the
   coloured band still bleeds to the left viewport edge; below 768px the inset
   is gone and the offset is reset. The original's companion `min-width: 768px`
   is deliberately NOT ported — it only ever causes horizontal overflow just
   above 768px. */
@media (max-width: 991px) {
  .brand-strip {
    width: calc(100% + 2rem);
    margin-left: -2rem;
  }
}

@media (max-width: 767px) {
  .brand-strip {
    width: 100%;
    margin-left: 0;
    padding-left: 1.4rem;
    padding-right: 1.4rem;
  }
}

@media (max-width: 479px) {
  .brand-strip {
    margin-bottom: 10px;
    padding: 1rem 0;
  }
}

/* .brand-track is exactly two identical .brand-set copies placed side by
   side with NO extra track-level gap between them — each .brand-set
   reserves its own trailing gap (via padding-right, same value as its
   internal `gap`) so the visual spacing between the last logo of set 1
   and the first logo of set 2 matches every other inter-logo gap. This
   makes `track width = 2 × set width` exactly, so translateX(-50%)
   lands precisely on the start of the second (identical) copy — see
   DECISIONS.md for why this replaces the original's literal IX2 value. */

.brand-track {
  display: flex;
  width: max-content;
  animation: brand-scroll 25s linear infinite;
}

.brand-set {
  display: flex;
  flex: none;
  align-items: center;
  gap: 60px;
  padding-right: 60px;
}

.brand-set img {
  flex: none;
}

@media (min-width: 1920px) {
  .brand-set {
    gap: 90px;
    padding-right: 90px;
  }
}

@media (max-width: 991px) {
  .brand-set {
    gap: 30px;
    padding-right: 30px;
  }
}

@media (max-width: 767px) {
  .brand-set {
    gap: 50px;
    padding-right: 50px;
  }
}

@media (max-width: 479px) {
  .brand-set {
    gap: 18px;
    padding-right: 18px;
  }
}

@keyframes brand-scroll {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-50%);
  }
}

@media (prefers-reduced-motion: reduce) {
  .brand-track {
    animation: none;
    transform: none;
  }

  .brand-set[aria-hidden="true"] {
    display: none;
  }
}

/* ---------- About ----------
   .section-padding / .section-container map Webflow's
   .padding-global / .container-large.about — confirmed (containers.md)
   to be the shared "standard content wrapper" reused by 4 sections
   (About/Services/Team/Testimonials), not About-specific, hence the
   generic name. The EN-only `.padding-global.about` modifier was
   confirmed live (identical computed geometry vs. CZ/DE at 1440/1920px)
   to be a no-op Webflow artifact and is not reproduced — see
   DECISIONS.md. */

.section-padding {
  padding-left: 2rem;
  padding-right: 1.5rem;
}

@media (min-width: 1280px) {
  .section-padding {
    padding-left: 1rem;
  }
}

@media (min-width: 1440px) {
  .section-padding {
    margin-left: 0;
    margin-right: 0;
    padding-left: 0;
  }
}

@media (min-width: 1920px) {
  .section-padding {
    padding-left: 1.5rem;
  }
}

@media (max-width: 991px) {
  .section-padding {
    width: auto;
  }
}

@media (max-width: 767px) {
  .section-padding {
    margin-left: auto;
    margin-right: auto;
    padding-left: 1rem;
  }
}

@media (max-width: 479px) {
  .section-padding {
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    padding-left: 1rem;
    padding-right: 1rem;
  }
}

.section-container {
  max-width: 75rem;
  margin-left: auto;
  margin-right: auto;
}

@media (min-width: 1280px) {
  .section-container {
    width: auto;
    max-width: none;
  }
}

@media (min-width: 1440px) {
  .section-container {
    width: 90%;
    max-width: none;
    margin-left: auto;
    margin-right: auto;
  }
}

@media (min-width: 1920px) {
  .section-container {
    width: 95%;
  }
}

@media (max-width: 479px) {
  .section-container {
    width: 100%;
    max-width: 75rem;
    margin-left: 0;
    margin-right: 0;
  }
}

.about {
  margin-top: -80px;
  padding-top: 0;
}

@media (min-width: 1280px) {
  .about {
    margin-top: -60px;
  }
}

@media (min-width: 1440px) {
  .about {
    margin-left: auto;
    margin-right: auto;
    padding-top: 50px;
  }
}

@media (min-width: 1920px) {
  .about {
    margin-top: 100px;
  }
}

@media (max-width: 479px) {
  .about {
    margin-top: -50px;
  }
}

.about-inner {
  padding-top: 0;
  padding-bottom: 2rem;
}

@media (min-width: 1280px) {
  .about-inner {
    padding-top: 2rem;
  }
}

@media (min-width: 1440px) {
  .about-inner {
    margin-left: auto;
    margin-right: auto;
  }
}

@media (max-width: 479px) {
  .about-inner {
    padding-bottom: 0;
  }
}

.about-component {
  display: flex;
  flex-flow: row;
  justify-content: center;
  align-items: center;
  /* column-gap only: the original declares grid-column-gap, so once this
     switches to flex-flow: column at <=991px there is no gap between the
     stacked photo / text / photo blocks. */
  column-gap: 2.1875rem;
}

@media (max-width: 991px) {
  .about-component {
    flex-flow: column;
  }
}

.about-image-wrapper {
  position: relative;
  overflow: hidden;
  width: 40%;
  aspect-ratio: 1 / 1;
}

@media (min-width: 1920px) {
  .about-image-wrapper {
    width: 35%;
  }
}

@media (max-width: 991px) {
  .about-image-wrapper {
    width: 100%;
  }
}

.about-image-wrapper--secondary {
  display: none;
  width: 40%;
}

@media (max-width: 991px) {
  .about-image-wrapper--secondary {
    display: block;
    width: 80%;
  }
}

@media (max-width: 767px) {
  .about-image-wrapper--secondary {
    width: 68%;
  }
}

@media (max-width: 479px) {
  .about-image-wrapper--secondary {
    width: 100%;
  }
}

.about-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.about-image--mobile {
  display: none;
}

@media (max-width: 991px) {
  .about-image--desktop {
    display: none;
  }

  .about-image--mobile {
    display: block;
  }
}

/* Confirmed IX2 "About Page Load" (a-438, SCROLL_INTO_VIEW on
   .about-component): a curtain-reveal where this overlay starts
   opaque over the photo, then slides translateY(-100%) to uncover it
   (opacity stays 1 throughout — it moves away, it doesn't fade).
   Rendered here in its confirmed END state so the static build shows
   the finished look, not the covered/broken-looking initial state.
   Kept in the DOM (empty, aria-hidden) for JS/INTERACTIONS to animate
   later — see TODO.md. */
.about-overlay {
  position: absolute;
  inset: 0;
  background-color: var(--blue);
  transform: translateY(-100%);
}

.about-overlay.about-overlay--armed {
  transform: translateY(0);
}

.about-overlay.about-overlay--revealed {
  transform: translateY(-100%);
  transition: transform 1s linear 0.2s;
}

.about-content {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 2.5rem;
  width: 42.4375rem;
  margin-top: -40px;
  /* .about-component uses align-items:center (not stretch), so this
     fixed per-breakpoint width (35rem/19.5rem below) would otherwise
     overflow its own container instead of shrinking. Closes the
     ~480-766px horizontal-overflow gap. See DECISIONS.md 2026-09-27
     (CLEAN). */
  max-width: 100%;
}

.about-content.about-content--armed {
  transform: translateY(50px);
  opacity: 0;
}

.about-content.about-content--revealed {
  transform: translateY(0);
  opacity: 1;
  transition: transform 1s linear 0.2s, opacity 1s linear 0.2s;
}

@media (min-width: 1920px) {
  .about-content {
    width: 55rem;
  }
}

@media (max-width: 991px) {
  .about-content {
    margin-top: 60px;
  }
}

@media (max-width: 767px) {
  .about-content {
    width: 35rem;
  }
}

@media (max-width: 479px) {
  .about-content {
    width: 19.5rem;
  }
}

.about-text {
  display: flex;
  flex-flow: column;
  justify-content: flex-start;
  align-items: stretch;
  text-align: left;
  gap: 1rem;
  width: auto;
}

@media (min-width: 1280px) {
  .about-text {
    margin-top: -50px;
  }
}

@media (min-width: 1920px) {
  .about-text {
    width: 98%;
  }
}

@media (max-width: 991px) {
  .about-text {
    padding-top: 25px;
    padding-bottom: 25px;
  }
}

@media (max-width: 767px) {
  .about-text {
    width: 90%;
  }
}

.about-heading {
  font-family: var(--heading-font);
  color: var(--blue);
  text-transform: uppercase;
  margin-top: 0;
  margin-bottom: 0;
  font-size: 3.25rem;
  font-weight: 800;
  line-height: 3.75rem;
}

@media (min-width: 1440px) {
  .about-heading {
    flex: 0 auto;
    margin-bottom: 20px;
  }
}

@media (max-width: 767px) {
  .about-heading {
    align-self: flex-start;
    font-size: 2.5rem;
  }
}

@media (max-width: 479px) {
  .about-heading {
    text-align: center;
    align-self: center;
    font-size: 2.8rem;
    line-height: 3.3rem;
  }
}

.about-copy {
  font-family: var(--paragraph-font);
  color: var(--black);
  text-align: left;
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.4rem;
}

@media (min-width: 1280px) {
  .about-copy {
    align-self: center;
  }
}

@media (min-width: 1440px) {
  .about-copy {
    align-self: flex-start;
  }
}

@media (min-width: 1920px) {
  .about-copy {
    align-self: center;
    font-size: 1.3rem;
  }
}

@media (max-width: 991px) {
  .about-copy {
    text-align: left;
    align-self: flex-start;
  }
}

/* The original's shared `.text-size-regular` drops its 10px bottom margin at
   <=991px; both paragraphs derived from it need that. */
@media (max-width: 991px) {
  .about-copy,
  .service-copy {
    margin-bottom: 0;
  }
}

@media (max-width: 479px) {
  .about-copy {
    text-align: center;
    font-size: 0.9rem;
  }
}

/* Confirmed on the live original at every breakpoint (no media query
   re-enables it): .about-bottom-content.is-about { display:none }.
   Verified via live computed style + screenshot, identical on CZ/EN/DE.
   Reproduced as hidden for functional parity — see DECISIONS.md. */
.about-cta {
  display: none;
}

/* ---------- Services ----------
   .section-padding / .section-container reused unchanged (confirmed
   live: the EN-only `padding-global.about` modifier is a no-op here
   too, same mechanism as About — see DECISIONS.md). */

.services {
  padding-top: 0;
}

@media (min-width: 1440px) {
  .services {
    margin-left: auto;
    margin-right: auto;
  }
}

@media (max-width: 479px) {
  .services {
    display: flex;
    flex-flow: column;
    margin-left: auto;
    margin-right: auto;
  }
}

.section-inner-medium {
  color: var(--black);
  padding-top: 2rem;
  padding-bottom: 4rem;
}

@media (max-width: 767px) {
  .section-inner-medium {
    padding-top: 0;
    padding-bottom: 0;
  }
}

@media (max-width: 479px) {
  .section-inner-medium {
    padding-top: 2rem;
  }
}

.service-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1.5rem;
}

@media (max-width: 767px) {
  .service-grid {
    grid-template-columns: 1fr;
  }
}

@media (max-width: 479px) {
  .service-grid {
    grid-template-columns: 1fr;
    gap: 1.5rem 0;
    width: 100%;
    margin-left: auto;
    margin-right: auto;
    place-content: center;
  }
}

.service-card {
  position: relative;
  display: flex;
  flex-flow: column;
  gap: 1rem;
  font-family: var(--paragraph-font);
  color: var(--white);
  text-align: center;
  padding: 3.75rem 1.7rem;
  font-size: 1rem;
  line-height: 1.5rem;
}

/* Simplified equivalent of the original's per-card w-node-scoped
   `grid-area: span 1 / span 2` rules (identical on all 5 real cards,
   just duplicated once per card/locale in the source) — approved
   simplification, see DECISIONS.md. */
@media (max-width: 991px) {
  .service-card {
    grid-column: 1 / -1;
  }
}

.service-title-heading {
  font-family: var(--heading-font);
  color: var(--blue);
  text-transform: uppercase;
  margin-top: 0;
  margin-bottom: 0;
  font-size: 3.25rem;
  font-weight: 800;
  line-height: 3.75rem;
}

@media (max-width: 767px) {
  .service-title-heading {
    align-self: flex-start;
    font-size: 2.5rem;
  }
}

@media (max-width: 479px) {
  .service-title-heading {
    text-align: center;
    align-self: auto;
    font-size: 1.8rem;
    line-height: 3.3rem;
  }
}

/* ._01 cells: title + Software Development + Práce s daty a AI */
.service-card--content {
  color: var(--blue);
  justify-content: flex-start;
  align-items: center;
  padding-left: 2rem;
  padding-right: 1.5rem;
}

.service-card--title {
  grid-column: 1 / -1;
}

@media (min-width: 1280px) {
  .service-card--title,
  .service-card--content {
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}

@media (min-width: 1920px) {
  .service-card--title,
  .service-card--content {
    padding-left: 3rem;
  }
}

@media (max-width: 991px) {
  .service-card--title,
  .service-card--content {
    width: 100%;
    text-align: left;
    padding-left: 1.5rem;
    padding-right: 1.5rem;
  }
}

@media (max-width: 767px) {
  .service-card--title,
  .service-card--content {
    padding-top: 2rem;
    padding-bottom: 2rem;
  }
}

@media (max-width: 479px) {
  .service-card--title,
  .service-card--content {
    width: 100%;
    text-align: center;
    justify-content: flex-start;
    align-items: center;
  }
}

.service-card--light {
  background-color: var(--white);
  padding-left: 2rem;
  padding-right: 1.5rem;
}

/* Fix (2026-09-08): must come after the base rule above — same selector
   specificity (1 class each), so source order decides. The shared
   `>=1920px` rule further up the file (`.service-card--title,
   .service-card--content, .service-card--light { padding-left: 3rem }`)
   sits *before* this base rule in the file, so this base rule silently
   overrode it regardless of viewport width — only this card
   (`.service-card--light`, the original's `._02`) was affected; `--title`
   and `--content` both come before that shared rule and were unaffected. */
@media (min-width: 1920px) {
  .service-card--light {
    padding-left: 3rem;
  }
}

@media (max-width: 479px) {
  .service-card--light {
    margin-left: 0;
    margin-right: 0;
  }
}

.service-card-border {
  position: absolute;
  background-color: var(--blue);
  box-shadow: 0 0 4px 1px var(--blue);
}

.service-card-border--left,
.service-card-border--right {
  width: 1px;
  height: 100%;
  top: 0;
  bottom: 0;
}

.service-card-border--left {
  left: 0;
}

.service-card-border--right {
  right: 0;
}

.service-card-border--top,
.service-card-border--bottom {
  width: 100%;
  height: 1px;
  left: 0;
  right: 0;
}

.service-card-border--top {
  top: 0;
}

.service-card-border--bottom {
  bottom: 0;
}

.service-heading {
  display: inline-block;
  font-family: var(--heading-font);
  color: var(--blue);
  text-align: left;
  text-transform: uppercase;
  align-self: flex-start;
  margin-top: 0;
  margin-bottom: 0;
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 2rem;
}

@media (max-width: 479px) {
  .service-heading {
    text-align: center;
    align-self: center;
  }
}

.service-copy {
  max-width: none;
  color: var(--black);
  text-align: left;
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.4rem;
}

@media (min-width: 1280px) {
  .service-copy {
    align-self: center;
  }
}

@media (min-width: 1440px) {
  .service-copy {
    align-self: flex-start;
  }
}

@media (min-width: 1920px) {
  .service-copy {
    align-self: center;
    font-size: 1.3rem;
  }
}

@media (max-width: 991px) {
  .service-copy {
    align-self: flex-start;
  }
}

@media (max-width: 479px) {
  .service-copy {
    text-align: center;
    font-size: 0.9rem;
  }
}

/* Tech-logo grids: 3 layouts (Software Development / Práce s daty a AI /
   Provoz řešení), each with its own column split. */

.tech-logos {
  display: grid;
  place-content: center;
  /* The original's `.image-with-text` base sets align-items: center, so logos
     of differing heights are centred within their grid row rather than
     top-aligned. */
  align-items: center;
  align-self: flex-start;
  margin-left: 0;
}

.tech-logos--dev {
  grid-template-columns: 1.25fr 1.25fr 1.25fr 1fr;
  grid-template-rows: auto auto;
  gap: 20px 25px;
  flex: 1;
  width: 95%;
  margin-right: auto;
}

@media (min-width: 1280px) {
  .tech-logos--dev {
    grid-template-columns: 1.5fr 1.5fr 1fr 1fr;
    gap: 20px 5px;
    flex: 0 auto;
  }
}

@media (max-width: 991px) {
  .tech-logos--dev {
    grid-template-columns: 1.75fr 1.25fr 1.25fr 1.25fr;
    gap: 20px;
    align-self: flex-start;
  }
}

@media (max-width: 479px) {
  .tech-logos--dev {
    grid-template-columns: 1.25fr 1.25fr 1fr;
    align-self: center;
  }
}

.tech-logos--data {
  grid-template-columns: .5fr .5fr .25fr;
  gap: 35px;
  flex: 1;
  width: 90%;
}

@media (min-width: 1280px) {
  .tech-logos--data {
    grid-template-columns: .75fr .5fr .75fr;
    gap: 25px 3px;
  }
}

@media (max-width: 991px) {
  .tech-logos--data {
    grid-template-columns: .5fr .5fr .5fr;
  }
}

@media (max-width: 479px) {
  .tech-logos--data {
    grid-template-columns: 1fr .75fr;
    gap: 15px;
    align-self: center;
  }
}

.tech-logos--ops {
  grid-template-columns: 1fr 1fr 1fr;
  /* The shared `.image-with-text.grid` base gap (20px/25px, 20px at <=991)
     applies to this grid too in the original; only the >=1280 value was
     ported. */
  gap: 20px 25px;
  place-content: end start;
  align-self: center;
  flex: 1;
  width: 90%;
}

@media (max-width: 991px) {
  .tech-logos--ops {
    gap: 20px;
  }
}

@media (min-width: 1280px) {
  .tech-logos--ops {
    grid-template-columns: .5fr .5fr .5fr;
    gap: 10px;
    align-self: flex-start;
  }
}

@media (min-width: 1440px) {
  .tech-logos--ops {
    grid-template-columns: .75fr .75fr 1fr;
  }
}

@media (max-width: 479px) {
  .tech-logos--ops {
    display: flex;
    flex-flow: column;
    align-items: center;
    place-content: center;
  }
}

.tech-logo {
  width: auto;
  height: 23px;
}

@media (min-width: 1280px) {
  .tech-logo {
    height: 35px;
  }
}

.tech-logo--flutter {
  grid-area: span 1 / span 1;
}

/* Original: `.tech-logo.flutter, .tech-logo.react { height: 30px }` at >=1280
   overrides the shared 35px. */
@media (min-width: 1280px) {
  .tech-logo--flutter,
  .tech-logo--react {
    height: 30px;
  }

  /* Confirmed live (2026-09-27): react is centered in its grid cell at
     >=1280/1440/1920px, flutter stays `auto` at all of those — this is
     react-only, not shared with the flutter rule above. Below 1280px
     both are `auto` on live too, matching local already, so no base
     rule needed. */
  .tech-logo--react {
    justify-self: center;
  }
}

.tech-logo--kotlin {
  grid-area: span 1 / span 1;
  /* Original base: `.tech-logo.kotlin, .tech-logo.jira, .tech-logo.openai
     { height: 20px }` — below 1280px this is what kotlin renders at, not the
     shared 23px. */
  height: 20px;
}

@media (min-width: 1280px) {
  .tech-logo--kotlin {
    height: 19px;
    justify-self: start;
  }
}

.tech-logo--java {
  height: 60px;
  margin-right: 10px;
  justify-self: center;
}

@media (min-width: 1280px) {
  .tech-logo--java {
    grid-area: span 1 / span 1;
  }
}

/* Original has `@media (max-width: 479px) .tech-logo.kotlin { height: auto }`
   and no <=479 rule for java — java stays at its 60px. */
@media (max-width: 479px) {
  .tech-logo--kotlin {
    height: auto;
  }

  .tech-logo--java {
    justify-self: start;
  }
}

.tech-logo--node {
  height: 24px;
  justify-self: start;
}

@media (min-width: 1280px) {
  .tech-logo--node {
    height: 25px;
    place-self: center;
  }
}

/* Confirmed live (2026-09-27): node stays `place-self:center` (both
   axes) at >=1440px too, same as >=1280 — it never becomes `start`
   horizontally. The `place-self:center start` override that used to be
   here was a confirmed mismatch (a copy-paste bug of the same kind
   found during the earlier tech-logo _1 audit), not a real breakpoint
   change — removed rather than corrected in place, since >=1280's rule
   already produces the right value and needs nothing added at 1440. */

@media (min-width: 1920px) {
  .tech-logo--node {
    height: 40px;
    justify-self: center;
  }
}

@media (max-width: 479px) {
  .tech-logo--node {
    height: 23px;
    justify-self: start;
  }
}

.tech-logos--dev .tech-logo--aws {
  width: 40%;
  height: auto;
  grid-area: span 1 / span 1;
  justify-self: stretch;
}

@media (min-width: 1280px) {
  .tech-logos--dev .tech-logo--aws {
    justify-self: center;
  }
}

@media (min-width: 1440px) {
  .tech-logos--dev .tech-logo--aws {
    width: auto;
    height: 35px;
    grid-area: span 1 / span 1;
    justify-self: start;
  }
}

@media (max-width: 479px) {
  .tech-logos--dev .tech-logo--aws {
    width: 60%;
    align-self: center;
    justify-self: center;
    grid-column: span 1 / span 1;
    margin-left: auto;
    margin-right: auto;
  }
}

/* `_1` variant of the same logo — the original assigns this to AWS in the
   Software Development card on EN only (CZ/DE use the plain class above).
   Grid position (grid-area/justify-self) is identical to the plain variant
   at every breakpoint (position comes from the original's #w-node id, not
   the logo variant) — only width/height differ. */
.tech-logos--dev .tech-logo--aws-alt {
  width: 30%;
  height: auto;
  grid-area: span 1 / span 1;
  justify-self: stretch;
}

@media (min-width: 1280px) {
  .tech-logos--dev .tech-logo--aws-alt {
    justify-self: center;
  }
}

@media (min-width: 1440px) {
  .tech-logos--dev .tech-logo--aws-alt {
    width: 30%;
    height: auto;
    grid-area: span 1 / span 1;
    justify-self: start;
  }
}

@media (max-width: 479px) {
  .tech-logos--dev .tech-logo--aws-alt {
    width: 20%;
    align-self: center;
    justify-self: center;
    grid-column: span 1 / span 1;
    margin-left: auto;
    margin-right: auto;
  }
}

/* Plain variant — the original assigns this to azure in the Software
   Development card on DE only (CZ/EN use the `_1`/`-alt` class below).
   Grid position is `span 1 / span 2` (2 grid columns) at every breakpoint
   >=767px, collapsing to 1 column below that (handled by the shared
   `.tech-logos--dev` grid-template-columns change, not here) — confirmed
   by directly measuring computed `grid-column` on the live original at
   every tracked breakpoint (2026-09-08), not assumed from source order:
   the original's own media queries for this rule are NOT in ascending
   width order in its stylesheet (1920, then 1440, then 1280 — repeated
   blocks throughout the file), so copying its per-breakpoint rules
   literally into an ascending-order stylesheet like this one produces a
   different cascade result. Only the *outcome* is reproduced here. */
.tech-logos--dev .tech-logo--azure {
  width: auto;
  height: auto;
  grid-area: span 1 / span 2;
  place-self: center start;
}

@media (max-width: 479px) {
  .tech-logos--dev .tech-logo--azure {
    height: 25px;
  }
}

/* `_1` variant — CZ and EN both use this (DE uses the plain class above).
   Grid position: 2 columns below 1280px, 1 column at >=1280px, for both
   CZ and EN alike — confirmed by measurement, same method as above. The
   one place CZ and EN genuinely diverge is <=479px, where EN's own
   #w-node position widens to 3 columns instead of 2 (not locale content,
   a genuinely different position) — reproduced with a `lang` scoped
   override below, since it isn't expressible as a single shared rule. */
.tech-logos--dev .tech-logo--azure-alt {
  width: auto;
  height: 60%;
  grid-area: span 1 / span 2;
  place-self: center start;
}

@media (min-width: 1280px) {
  .tech-logos--dev .tech-logo--azure-alt {
    height: auto;
    grid-area: span 1 / span 1;
    justify-self: start;
  }
}

@media (max-width: 479px) {
  .tech-logos--dev .tech-logo--azure-alt {
    height: 35%;
  }

  html[lang="en"] .tech-logos--dev .tech-logo--azure-alt {
    grid-column: span 3 / span 3;
  }
}

/* Original: `@media (max-width: 479px) .tech-logo.azure { height: 25px }` —
   applies wherever the plain `azure` variant is used. The actual override
   for the ops grid is declared further down, right after
   `.tech-logos--ops .tech-logo--azure`'s own base rule (same selector
   specificity as that rule, so source order decides — it must come after,
   not before, per the 2026-09-08 fix note there). */

.tech-logo--elastic {
  height: 25px;
}

@media (min-width: 1280px) {
  .tech-logo--elastic {
    width: 80%;
    height: auto;
  }
}

.tech-logo--stack {
  height: 26px;
}

@media (min-width: 1280px) {
  .tech-logo--stack {
    width: 100%;
    height: auto;
  }
}

.tech-logo--bigquery {
  height: 26px;
}

@media (min-width: 1280px) {
  .tech-logo--bigquery {
    width: 50%;
    height: auto;
    justify-self: center;
  }
}

.tech-logo--power {
  height: 25px;
}

@media (min-width: 1280px) {
  .tech-logo--power {
    width: 60%;
    height: auto;
  }
}

.tech-logo--openai {
  height: 20px;
}

@media (min-width: 1280px) {
  .tech-logo--openai {
    width: 85%;
    height: auto;
  }
}

.tech-logo--chatgpt {
  height: 25px;
}

@media (min-width: 1280px) {
  .tech-logo--chatgpt {
    width: 53%;
    height: auto;
    justify-self: center;
  }
}

.tech-logos--ops .tech-logo--azure {
  height: auto;
}

@media (min-width: 1280px) {
  .tech-logos--ops .tech-logo--azure {
    place-self: center start;
  }
}

/* Fix (2026-09-08): must come after the base rule above — same selector
   specificity (2 classes each), so source order decides which wins, and
   this needs to win at <=479px. Previously declared as an earlier,
   lower-specificity `.tech-logo--azure` rule, which this same-specificity
   base rule silently overrode regardless of the media query. Without it,
   height stayed `auto`, and via `flex-basis: auto` in the <=479px
   column-flex layout, the logo stretched to the full container width
   instead of its own ~154px intrinsic size. */
@media (max-width: 479px) {
  .tech-logos--ops .tech-logo--azure {
    height: 25px;
  }
}

/* Plain variant — the original assigns this to aws in the Provoz řešení
   card on EN only (CZ/DE use the `_1`/`-alt` class below). Grid position
   is identical between the two variants at every breakpoint — only
   width/height differ. */
.tech-logos--ops .tech-logo--aws {
  width: 40%;
  height: auto;
  place-self: end center;
}

@media (min-width: 1280px) {
  .tech-logos--ops .tech-logo--aws {
    grid-area: span 1 / span 1;
    place-self: center;
  }
}

@media (min-width: 1440px) {
  .tech-logos--ops .tech-logo--aws {
    width: auto;
    height: 35px;
  }
}

@media (min-width: 1920px) {
  .tech-logos--ops .tech-logo--aws {
    justify-self: center;
  }
}

@media (max-width: 767px) {
  .tech-logos--ops .tech-logo--aws {
    justify-self: center;
  }
}

@media (max-width: 479px) {
  .tech-logos--ops .tech-logo--aws {
    width: 60%;
    align-self: center;
    justify-self: center;
    margin-left: auto;
    margin-right: auto;
  }
}

.tech-logos--ops .tech-logo--aws-alt {
  width: 30%;
  height: auto;
  place-self: end center;
}

@media (min-width: 1280px) {
  .tech-logos--ops .tech-logo--aws-alt {
    grid-area: span 1 / span 1;
    place-self: center;
  }
}

@media (min-width: 1440px) {
  /* Fix (2026-09-08): was `width: auto; height: 35px` — that's the plain
     variant's value, accidentally copied here. The original's own
     `.tech-logo.aws._1` rule at this breakpoint is `width: 30%; height:
     auto`, confirmed directly from the live stylesheet. */
  .tech-logos--ops .tech-logo--aws-alt {
    width: 30%;
    height: auto;
  }
}

@media (min-width: 1920px) {
  .tech-logos--ops .tech-logo--aws-alt {
    justify-self: center;
  }
}

@media (max-width: 767px) {
  .tech-logos--ops .tech-logo--aws-alt {
    justify-self: center;
  }
}

@media (max-width: 479px) {
  .tech-logos--ops .tech-logo--aws-alt {
    width: 20%;
    align-self: center;
    justify-self: center;
    margin-left: auto;
    margin-right: auto;
  }
}

.tech-logo--jira-service {
  width: 100%;
  height: auto;
  grid-area: span 1 / span 1;
  place-self: stretch;
}

@media (min-width: 1280px) {
  .tech-logo--jira-service {
    grid-area: span 1 / span 1;
    justify-self: start;
  }
}

@media (min-width: 1440px) {
  .tech-logo--jira-service {
    width: auto;
    height: auto;
  }
}

@media (max-width: 767px) {
  .tech-logo--jira-service {
    height: auto;
  }
}

@media (max-width: 479px) {
  .tech-logo--jira-service {
    height: 35px;
    grid-area: span 1 / span 2;
  }
}

/* ---------- Team ----------
   Team's title h2 reuses .about-heading (CZ, which has the confirmed
   `.blue` modifier in the source) or .service-title-heading (EN/DE,
   which don't) — see DECISIONS.md for why a Team heading references
   classes named after other sections. */

@media (max-width: 767px) {
  .team {
    padding-top: 60px;
  }
}

/* The original's `.team-component` (flex column, 3.75rem row gap) carried two
   effects this build lost by flattening it away: the 60px gap between the
   heading row and the card grid, and — because it is a column flex container —
   letting .team-grid's `margin-left/right: auto` shrink-wrap the grid to its
   two 400px columns and centre it, instead of stretching it across the full
   container width. */
.team-component {
  display: flex;
  flex-flow: column;
  row-gap: 3.75rem;
}

.team-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

@media (max-width: 479px) {
  .team-header {
    flex-flow: column;
    justify-content: space-between;
    align-self: center;
    align-items: flex-start;
  }
}

/* Confirmed hidden on the live original at every breakpoint (unconditional
   .hide { display:none }), same treatment as the About CTA. */
.team-link-all {
  display: none;
}

.team-grid {
  display: grid;
  /* minmax(0, 1fr), not bare 1fr: a bare 1fr track's minimum is "auto"
     (its content's min-content width), which the unbreakable e-mail
     address in .team-email drives past the viewport in the ~480-766px
     range. minmax(0, ...) lets the track actually shrink. See
     DECISIONS.md 2026-09-27 (CLEAN) — confirmed the same defect exists
     on the live original at this exact width, fixed here anyway per
     this phase's rule (no longer reproducing original bugs verbatim). */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 25px;
  margin-left: auto;
  margin-right: auto;
}

@media (max-width: 991px) {
  .team-grid {
    gap: 45px;
  }
}

@media (max-width: 479px) {
  .team-grid {
    grid-template-columns: 1fr;
  }
}

.team-card {
  display: flex;
  flex-flow: column;
  gap: 1rem;
}

/* Confirmed in source: only Michal's card gets this centering at
   <=479px — Barbora's doesn't. Asymmetric in the original; reproduced
   as-is, not corrected. */
@media (max-width: 479px) {
  .team-card--centered {
    place-self: center;
  }
}

.team-card-accent {
  border-left: 1px solid var(--blue);
  height: 2.1875rem;
  padding-left: 0.625rem;
}

.team-name {
  font-family: var(--heading-font);
  color: var(--black800);
  text-transform: uppercase;
  letter-spacing: 0;
  margin-top: 10px;
  margin-bottom: 10px;
  font-size: 1.4rem;
  font-weight: 600;
  line-height: 1.3rem;
}

@media (max-width: 767px) {
  .team-name {
    font-size: 1.3rem;
  }
}

@media (max-width: 479px) {
  .team-name,
  .team-photo-wrap,
  .team-card-bottom-content {
    text-align: center;
  }
}

.team-photo-wrap {
  display: block;
}

/* The original's link around the photo is a `.w-inline-block`, so it
   shrink-wraps the image (and contains its bottom margin) rather than being an
   inline box the image overflows. */
.team-photo-wrap a {
  display: inline-block;
  /* top-aligned so the inline-block doesn't sit on the wrapper's text baseline
     and leave ~6px of descender space below the photo (the original's wrapper
     measures exactly the link height). */
  vertical-align: top;
  max-width: 100%;
}

.team-image {
  display: block;
  width: 280px;
  /* The width/height attributes on the <img> are kept as an aspect-ratio hint
     (no layout shift), so the height must be released back to auto — otherwise
     the height attribute acts as a presentational hint and stretches the photo
     vertically (measured 400x861 instead of the original's 400x574). */
  height: auto;
  margin-bottom: 25px;
}

@media (min-width: 1280px) {
  .team-image {
    width: 400px;
  }
}

@media (min-width: 1920px) {
  .team-image {
    width: 450px;
  }
}

@media (max-width: 991px) {
  .team-image {
    width: 325px;
    min-height: auto;
  }
}

@media (max-width: 767px) {
  .team-image {
    width: auto;
    max-height: 330px;
    margin-bottom: 20px;
  }
}

@media (max-width: 479px) {
  .team-image {
    min-height: 250px;
  }
}

.team-card-bottom-content {
  display: flex;
  flex-flow: column;
  gap: 1rem;
  color: var(--black);
}

.team-role {
  text-transform: uppercase;
  font-size: 1.1rem;
  font-weight: 600;
}

.team-contact {
  display: flex;
  flex-flow: column;
  justify-content: center;
  align-items: stretch;
  gap: 0.6rem;
}

.team-email {
  color: var(--black);
  text-decoration: none;
  /* Companion to .team-grid's minmax(0, 1fr): once the column can
     shrink below the address's own min-content, the address itself
     needs somewhere to break instead of overflowing its own box. */
  overflow-wrap: anywhere;
}

/* Confirmed CZ-only quirk: only Barbora's CZ email link carries this
   class in the source, muting it to --white600 at <=479px. Michal's
   link and both EN/DE links stay black. Reproduced as-is. */
@media (max-width: 479px) {
  .team-email--muted {
    color: var(--white600);
  }
}

.team-linkedin {
  display: inline-flex;
}

.team-linkedin img {
  width: 1.5rem;
  height: 1.5rem;
}

/* ---------- References ----------
   Static build only: the original is a native Webflow slider
   (.w-slider, autoplay/infinite/swipe confirmed via HTML attributes)
   showing one of 4 reference cards at a time. Per-project decision,
   all JS/INTERACTIONS work (including this slider) is deferred to its
   own later phase — so all 4 cards render stacked here, always
   visible, with no arrows/dots/autoplay yet. See DECISIONS.md and
   TODO.md. Because nothing needs to fit a single measured slide
   anymore, the original's fixed mobile heights (685/781/895px) are
   dropped in favor of natural height — revisit when the slider itself
   is built. */

.references {
  padding-top: 20px;
}

.references-intro {
  font-family: var(--paragraph-font);
  color: var(--black);
  margin-bottom: 0;
  padding-top: 20px;
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.625rem;
}

/* Webflow preset "slideInLeft" (a-438-style SCROLL_INTO_VIEW, one-shot):
   confirmed live via rAF-sampled curve, not the IX2 config (presets carry
   no literal values there) — starts at opacity:0, translateX(-100px);
   fires when the element is roughly 20-28% short of the traditional
   "top at viewport bottom" point (matches the config's
   scrollOffsetValue:20%, reproduced here via IntersectionObserver
   rootMargin rather than a hand-rolled scroll-offset calculation); the
   curve is a fast-start/long-tail ease-out (~900ms), approximated with
   cubic-bezier(.16,1,.3,1) — close visual match, not a claimed exact
   reproduction of Webflow's internal preset curve. See DECISIONS.md. */
.references-intro.references-intro--armed {
  opacity: 0;
  transform: translateX(-100px);
}

.references-intro.references-intro--revealed {
  opacity: 1;
  transform: translateX(0);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

@media (max-width: 479px) {
  .references-intro {
    text-align: center;
  }
}

/* ---------- References slider ----------
   Native Webflow `w-slider` in the original (confirmed via HTML attributes:
   data-autoplay="true", data-duration="500", data-easing="ease",
   data-animation="outin", data-infinite="true", data-disable-swipe="false";
   data-delay differs per locale — 3000ms CZ, 4000ms EN/DE, see
   assets/js/references-slider.js and the HTML's own data-delay attribute).
   Reproduced with plain markup + minimal JS rather than the Webflow runtime
   — see DECISIONS.md for the confirmed behavioral audit this is based on. */

.testimonials-slider {
  position: relative;
  background-color: var(--blue30);
  margin-top: 20px;
  padding: 4rem 2rem 5rem;
}

/* Webflow preset "slideInBottom", same mechanism/timing as
   .references-intro's "slideInLeft" above (see there for the audit
   rationale) — direction and distance confirmed separately live:
   starts at opacity:0, translateY(100px). */
.testimonials-slider.testimonials-slider--armed {
  opacity: 0;
  transform: translateY(100px);
}

.testimonials-slider.testimonials-slider--revealed {
  opacity: 1;
  transform: translateY(0);
  transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
    transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}

@media (max-width: 991px) {
  .testimonials-slider {
    padding-top: 2rem;
    padding-bottom: 2rem;
  }
}

@media (max-width: 479px) {
  .testimonials-slider {
    width: 100%;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
  }
}

.testimonials-slider-mask {
  position: relative;
  overflow: hidden;
}

/* The original reserves a fixed slider height at these 3 breakpoints
   (confirmed in its stylesheet: 685px/781px/895px total, including
   padding) that is *larger* than any single slide's own content needs —
   presumably to leave room for the absolutely-positioned arrows below the
   content. JS below measures actual content height for every breakpoint;
   these floors only kick in where the original's fixed value exceeds it. */
@media (max-width: 991px) {
  .testimonials-slider-mask {
    min-height: 621px;
  }
}

@media (max-width: 767px) {
  .testimonials-slider-mask {
    min-height: 717px;
  }
}

@media (max-width: 479px) {
  .testimonials-slider-mask {
    min-height: 831px;
  }
}

/* Height is set explicitly by JS (measured from the tallest slide at the
   current breakpoint) — confirmed against the live original that the
   slider's own height stays constant across slides at a given breakpoint
   (measured 425.99px at both the shortest and longest slide at 1440px),
   rather than resizing per slide's own content length. */
.testimonial-slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}

.testimonial-slide.is-active {
  opacity: 1;
  pointer-events: auto;
  z-index: 1;
}

/* Confirmed live (2026-09-27), CZ+EN, 1440px and 767px, with a real
   mouse hover over the slider first: `.arrow-left`/`.arrow-right`
   compute to `display:none` with no inline-style override at all,
   despite `data-hide-arrows="false"` on the slider wrap — Webflow's own
   static stylesheet sets `display:none` unconditionally on these
   classes and no breakpoint or interaction state in it ever overrides
   `display`. The original's slider navigation is dots + autoplay +
   swipe only; the arrow buttons are real but permanently invisible.
   The previous local build showed them as solid, glyph-less black
   pills — a visible regression, not a confirmed variation. Hidden here
   to match; kept in the DOM (buttons, with their SVG glyph) rather
   than removed, mirroring the original's own "present but display:none"
   shape exactly, in case a later product decision wants them shown. */
.testimonials-arrow {
  display: none;
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
  flex-flow: column;
  align-items: center;
  position: absolute;
  z-index: 3;
  top: 50%;
  transform: translateY(-50%);
}

.testimonials-arrow--prev {
  left: 51.6%;
  transform: translate(-100%, -50%);
}

.testimonials-arrow--next {
  right: 41%;
}

@media (min-width: 1280px) {
  .testimonials-arrow--next {
    right: 41.2%;
  }
}

@media (min-width: 1440px) {
  .testimonials-arrow--next {
    right: 42%;
  }
}

@media (min-width: 1920px) {
  .testimonials-arrow--next {
    right: 43.4%;
  }
}

/* Vertical arrow (>=992px): rounded top/bottom pill with a divider line. */
.testimonials-arrow-icon {
  border: 1px solid var(--white600);
  background-color: var(--black);
  width: 40px;
  height: 50px;
  color: var(--white600);
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 16px;
  line-height: 1.3em;
}

.testimonials-arrow--prev .testimonials-arrow-icon {
  border-top-left-radius: 30px;
  border-top-right-radius: 30px;
}

.testimonials-arrow--next .testimonials-arrow-icon {
  border-width: 0 1px 1px;
  border-bottom-right-radius: 30px;
  border-bottom-left-radius: 30px;
}

.testimonials-arrow:hover .testimonials-arrow-icon {
  background-color: var(--gold);
  color: var(--white);
}

.testimonials-arrow::before {
  content: "";
  background-color: var(--white600);
  width: 1px;
  height: 100%;
}

.testimonials-arrow--prev::before {
  order: 2;
}

/* Horizontal arrow (<=991px): rounded left/right pill, bottom-positioned,
   no divider line. */
@media (max-width: 991px) {
  .testimonials-arrow {
    flex-flow: row;
    top: auto;
    bottom: 140px;
    transform: none;
  }

  .testimonials-arrow--prev {
    left: auto;
    right: 50%;
    justify-content: flex-end;
    width: 70%;
  }

  .testimonials-arrow--next {
    right: 4px;
    justify-content: flex-start;
    width: 25%;
  }

  .testimonials-arrow::before {
    display: none;
  }

  .testimonials-arrow-icon {
    width: 75px;
    height: 65px;
    font-size: 20px;
  }

  .testimonials-arrow--prev .testimonials-arrow-icon {
    border-radius: 0 0 0 30px;
    border-width: 1px 0 1px 1px;
  }

  .testimonials-arrow--next .testimonials-arrow-icon {
    border-radius: 0 30px 0 0;
    border-width: 1px 1px 1px 0;
  }
}

@media (max-width: 767px) {
  .testimonials-arrow {
    bottom: 40px;
  }
}

@media (max-width: 479px) {
  .testimonials-arrow {
    bottom: 20px;
  }

  .testimonials-arrow--prev,
  .testimonials-arrow--next {
    width: 50%;
  }

  .testimonials-arrow--prev {
    left: 0;
  }

  .testimonials-arrow--next {
    right: 0;
  }

  .testimonials-arrow-icon {
    justify-content: center;
    align-items: center;
  }
}

.testimonials-dots {
  z-index: 2;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0;
  position: absolute;
  inset: auto 0 0;
  padding-top: 10px;
  padding-bottom: 10px;
}

.testimonials-dot {
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
  background-color: rgba(255, 255, 255, 0.4);
  width: 16px;
  height: 16px;
  margin: 0 3px 8px;
  border-radius: 100%;
  transition: background-color 0.1s;
}

.testimonials-dot.is-active {
  background-color: var(--blue);
}

.testimonials-dot:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--white);
}

.testimonial-content {
  display: flex;
  justify-content: space-between;
  align-items: stretch;
  text-align: left;
}

@media (max-width: 991px) {
  .testimonial-content {
    flex-flow: column;
  }
}

.testimonial-details {
  display: flex;
  flex-flow: column;
  justify-content: space-around;
  align-items: stretch;
  gap: 1rem;
  max-width: 34.375rem;
  padding-left: 20px;
}

@media (min-width: 1440px) {
  .testimonial-details {
    padding-left: 0;
  }
}

@media (min-width: 1920px) {
  .testimonial-details {
    gap: 1.5rem;
    max-width: 39rem;
  }
}

@media (max-width: 991px) {
  .testimonial-details {
    align-self: flex-start;
    max-width: 40.5rem;
    padding-left: 0;
  }
}

@media (max-width: 479px) {
  .testimonial-details {
    padding-left: 0.5em;
  }
}

.testimonial-logo {
  align-self: flex-start;
  height: 40px;
}

.testimonial-logo--skoda {
  height: 25px;
}

.testimonial-logo--citrix {
  width: auto;
  height: 45px;
}

/* display:flex + flex-wrap (not a fixed grid-template-columns) so each
   pill sizes to its own text and only wraps to a new row once the row
   itself runs out of room — a fixed equal-width grid column forces
   longer tags ("React Native") to wrap their own text onto 2 lines
   instead, which happens on the live original too but reads as broken
   there; not reproduced here (approved improvement, not a parity
   deviation). See DECISIONS.md. */
.testimonial-tags {
  display: flex;
  flex-flow: row wrap;
  gap: 0.5rem;
  justify-content: flex-start;
  align-items: center;
  padding-top: 0.5rem;
  padding-bottom: 0.5rem;
}

@media (min-width: 1920px) {
  .testimonial-tags {
    gap: 0.7rem;
  }
}

.testimonial-tag-box {
  background-color: var(--blue);
  text-align: center;
  border-radius: 20px;
  padding: 0.5rem 0.9rem;
  display: flex;
  justify-content: center;
  align-items: center;
  flex: 0 0 auto;
}

@media (min-width: 1920px) {
  .testimonial-tag-box {
    text-align: left;
    padding: 1rem 2rem;
  }
}

.testimonial-tag {
  opacity: 0.8;
  color: var(--white);
  text-align: center;
  letter-spacing: 3px;
  text-transform: uppercase;
  white-space: nowrap;
  margin: 0 auto;
  font-size: 0.6rem;
  font-weight: 500;
  line-height: 1rem;
}

@media (min-width: 1440px) {
  .testimonial-tag {
    align-self: center;
  }
}

@media (min-width: 1920px) {
  .testimonial-tag {
    margin: 0;
    font-size: 0.9rem;
    line-height: 1.2rem;
  }
}

@media (max-width: 479px) {
  .testimonial-tag {
    font-weight: 600;
  }
}

.testimonial-copy {
  max-width: 520px;
  font-family: var(--paragraph-font);
  color: var(--black);
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.4rem;
}

@media (max-width: 991px) {
  .testimonial-copy {
    text-align: center;
    align-self: center;
    max-width: none;
    margin-bottom: 0;
    font-size: 1rem;
  }
}

@media (max-width: 479px) {
  .testimonial-copy {
    font-size: 1rem;
  }
}

.testimonial-photo-wrap {
  align-self: center;
  padding-right: 20px;
}

@media (max-width: 991px) {
  .testimonial-photo-wrap {
    margin-left: 0;
    margin-right: 0;
    padding-top: 30px;
  }
}

@media (max-width: 767px) {
  .testimonial-photo-wrap {
    padding-right: 0;
  }
}

.testimonial-photo {
  display: block;
  width: 400px;
}

@media (min-width: 1920px) {
  .testimonial-photo {
    width: 550px;
  }
}

@media (max-width: 991px) {
  .testimonial-photo {
    width: 350px;
  }
}

/* ---------- Contact / footer ----------
   6th and final section (originally the two-column "footer" — white
   contact-form column + black info column). Percentages/breakpoints below
   come directly from the original's `.footer-left`/`.footer-right`.
   The form is intentionally NOT wired to any backend — see
   assets/js/contact-form.js and DECISIONS.md (2026-09-08). The decorative
   gold circle behind the heading (`.title-circle`) is confirmed
   `display:none` at every breakpoint on all 3 locales in the original and
   is not reproduced (same treatment as the brand strip's inert duplicate
   blocks). */

.contact {
  position: relative;
}

.contact-inner {
  display: flex;
  max-width: 1920px;
  margin-left: auto;
  margin-right: auto;
  overflow: hidden;
}

@media (max-width: 991px) {
  .contact-inner {
    flex-flow: column;
  }
}

.contact-left {
  background-color: var(--white);
  color: var(--black);
  width: 44%;
  margin-left: auto;
  margin-right: auto;
  padding: 3rem 2rem;
  /* The original's `.contact-container` is itself a flex column with a
     2.5rem (2rem at <=767px) gap between the heading / divider / form
     block — reproduced here directly on the same element rather than as
     a separate nested wrapper. */
  display: flex;
  flex-flow: column;
  gap: 2.5rem;
  overflow: hidden;
}

@media (max-width: 767px) {
  .contact-left {
    gap: 2rem;
  }
}

@media (min-width: 1280px) {
  .contact-left {
    width: 46%;
    max-width: 37.1rem;
    padding-left: 0.8rem;
  }
}

@media (min-width: 1440px) {
  .contact-left {
    width: 53%;
    padding-left: 4.2rem;
  }
}

@media (min-width: 1920px) {
  .contact-left {
    width: 47%;
    padding-left: 5.5rem;
  }
}

@media (max-width: 991px) {
  .contact-left {
    width: 100%;
  }
}

@media (max-width: 767px) {
  .contact-left {
    width: 94%;
    padding-left: 0;
  }
}

@media (max-width: 479px) {
  .contact-left {
    padding-left: 0;
    padding-bottom: 2rem;
  }
}

.contact-heading {
  position: relative;
}

.contact-heading-title {
  font-family: var(--heading-font);
  color: var(--blue);
  text-transform: uppercase;
  font-size: 2.25rem;
  font-weight: 800;
  line-height: 2.5rem;
  /* The original never overrides this h4's own margin — Webflow's base
     typography reset sets `h4 { margin-top: 10px; margin-bottom: 10px }`,
     and nothing in `.contact-heading-title` zeroes it, so it stays. */
  margin-top: 10px;
  margin-bottom: 10px;
}

@media (max-width: 479px) {
  .contact-heading-title {
    font-size: 1.4rem;
  }
}

.contact-divider {
  background-color: var(--blue);
  width: 100%;
  height: 1px;
}

@media (max-width: 991px) {
  .contact-divider {
    width: 90%;
  }
}

@media (max-width: 479px) {
  .contact-divider {
    width: 100%;
    padding-left: 20px;
    padding-right: 20px;
  }
}

.contact-form {
  display: flex;
  flex-flow: column;
  /* Matches the original's `.w-form` wrapper margin (Webflow base rule,
     `margin: 0 0 15px`) around the form — reproduced directly on the form
     itself since this rebuild has no separate `.w-form`-equivalent wrapper. */
  margin-bottom: 15px;
}

.contact-field {
  border: 0;
  border-bottom: 1px solid var(--blue);
  background-color: var(--transparent);
  max-width: 27.5rem;
  min-height: 4.625rem;
  color: var(--black);
  margin-bottom: 0;
  padding: 1.563rem 0;
  font-family: inherit;
  font-size: 1.125rem;
}

.contact-field::placeholder {
  color: var(--black);
  font-weight: 700;
}

.contact-field:focus {
  outline: 0;
  border-bottom-color: var(--blue);
}

@media (min-width: 1280px) {
  .contact-field {
    max-width: none;
  }
}

@media (min-width: 1440px) {
  .contact-field {
    max-width: 31rem;
  }
}

@media (min-width: 1920px) {
  .contact-field {
    max-width: 45rem;
  }
}

@media (max-width: 991px) {
  .contact-field {
    max-width: 38.5rem;
  }
}

@media (max-width: 767px) {
  .contact-field {
    max-width: 27rem;
  }
}

@media (max-width: 479px) {
  .contact-field {
    max-width: none;
  }
}

.contact-message {
  min-width: 25.6rem;
  max-width: 27.5rem;
  min-height: 10.25rem;
  resize: vertical;
}

@media (min-width: 1280px) {
  .contact-message {
    min-width: auto;
    max-width: none;
  }
}

@media (min-width: 1440px) {
  .contact-message {
    min-width: 31rem;
    max-width: 31rem;
  }
}

@media (min-width: 1920px) {
  .contact-message {
    max-width: none;
  }
}

@media (max-width: 991px) {
  .contact-message {
    min-width: 38.5rem;
    max-width: 38.5rem;
  }
}

@media (max-width: 767px) {
  .contact-message {
    min-width: 27rem;
    max-width: 27rem;
  }
}

@media (max-width: 479px) {
  .contact-message {
    min-width: auto;
    max-width: 100%;
  }
}

/* Hidden from sighted users and assistive tech alike — off-screen, not
   display:none/visibility:hidden, since some bots skip fields a screen
   reader would also skip. Matches peaksolutions.cz's own honeypot. */
.contact-field-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.cf-turnstile {
  margin-top: 0.5rem;
  margin-bottom: 0.5rem;
}

.contact-verifying {
  margin: -0.2rem 0 0.5rem;
  color: var(--black800);
  font-size: 0.75rem;
}

.contact-submit {
  margin-top: 2.813rem;
  cursor: pointer;
}

@media (max-width: 479px) {
  .contact-submit {
    text-align: center;
    vertical-align: baseline;
    margin-left: auto;
    margin-right: auto;
    display: block;
  }
}

.contact-form-message {
  border-radius: 30px;
  padding: 12px 20px;
  margin-top: 1rem;
  font-family: var(--paragraph-font);
  font-size: 1rem;
  font-weight: 500;
  text-align: center;
}

.contact-form-message--success {
  background-color: var(--blue);
  color: var(--white);
}

.contact-form-message--error {
  background-color: var(--transparent);
  border: 1px solid #ec2626;
  color: #ec2626;
}

/* Link to the privacy notice, required per platform/docs/privacy.md. Only
   one instance (not also one right under the form, peaksolutions.cz-style)
   — Petra caught the duplicate (2026-09-30), see DECISIONS.md. Lives in
   .site-footer, below (see that section further down this file). */
.contact-privacy-footer {
  margin-top: 0.75rem;
  font-size: 0.875rem;
}

.contact-privacy-footer a {
  color: var(--blue);
  text-decoration: underline;
}

.contact-right {
  background-color: var(--black800);
  width: 56.5%;
}

@media (min-width: 1440px) {
  .contact-right {
    width: 50%;
  }
}

@media (min-width: 1920px) {
  .contact-right {
    width: 50%;
  }
}

@media (max-width: 991px) {
  .contact-right {
    width: 100%;
  }
}

/* The live original combines form + address/contact + copyright into one
   section (`.footer-container`, a flex column with the copyright pinned
   to the bottom via `space-between`). Petra approved a deliberate
   deviation from that here (2026-09-30, see DECISIONS.md): copyright +
   the privacy-notice link now live in their own `.site-footer` section
   below `.contact` instead, so this column only ever holds the
   address/contact grid — no more need for the flex-column/space-between
   trick or its former copyright-clearance bottom padding (that
   clearance now belongs to `.site-footer`, the new last-content-on-the-
   page section). */
.contact-right-inner {
  height: 100%;
  background-color: var(--white);
  padding: 3rem 2rem;
}

@media (max-width: 479px) {
  .contact-right-inner {
    padding-top: 0.5rem;
  }
}

.contact-info-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 5rem;
}

@media (max-width: 991px) {
  .contact-info-grid {
    grid-template-columns: 1.25fr 1fr;
  }
}

@media (max-width: 767px) {
  .contact-info-grid {
    margin-top: 2rem;
  }
}

@media (max-width: 479px) {
  .contact-info-grid {
    grid-template-columns: 1fr;
  }
}

.contact-info-heading {
  font-family: var(--heading-font);
  color: var(--blue);
  text-transform: uppercase;
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 2rem;
  margin-top: 0;
  margin-bottom: 0;
}

@media (max-width: 479px) {
  .contact-info-heading {
    display: block;
  }
}

.contact-info-text {
  color: var(--black);
  font-size: 1.125rem;
  font-weight: 400;
  line-height: 1.4rem;
  margin-top: 0;
  /* Same shared `.text-size-regular` base this section's paragraph also
     carries in the original (10px bottom margin, dropped at <=991px) — see
     the identical `.about-copy`/`.service-copy` note above. */
  margin-bottom: 10px;
}

@media (max-width: 991px) {
  .contact-info-text {
    margin-bottom: 0;
  }
}

/* Folds two of the original's separate rules onto this one element: the
   wrapping `.pages` flex column gets `margin-top: 10px` at <=767px (this
   rebuild has no equivalent wrapper, so the value moves to the paragraph
   itself — visually identical, since an adjacent-sibling margin still
   collapses with the heading's own margin the same way); the paragraph's
   own margin-top separately becomes 20px at <=479px, on top of that same
   10px (both conditions are true at once at <=479px, so the totals add:
   10 then 30, matching the original exactly at each width). */
@media (max-width: 767px) {
  .contact-info-text {
    margin-top: 10px;
  }
}

@media (max-width: 479px) {
  .contact-info-text {
    text-align: center;
  }

  /* Only the address paragraph carries the original's `.footer` modifier
     class, whose own `<=479px` override adds a further 20px on top of the
     10px above (total 30px) — the email block's paragraph (no `.footer`
     modifier in the original) stays at 10px. */
  .contact-info-text--address {
    margin-top: 30px;
  }
}

.contact-info-link {
  color: var(--black);
  text-decoration: none;
}

.contact-info-link:hover,
.contact-info-link:focus-visible {
  text-decoration: underline;
}

.contact-copyright {
  color: var(--black);
  font-size: 1rem;
  font-weight: 500;
  margin-top: 0;
  margin-bottom: 0;
}

/* No own font-weight: the reference actually renders the year LESS bold
   than the rest (`.bold-text-2{font-weight:600}` on the surrounding text,
   the year itself a plain, unstyled `<span>`) — but Petra asked for it to
   match the rest instead (2026-09-30), so it just inherits the same
   `<strong>` "bolder" resolution as its siblings now (700, confirmed via
   computed style) rather than fighting it with a lower explicit value.
   A deliberate deviation from the reference here, not a bug fix. */

/* New, plain site-wide footer bar (2026-09-30, Petra-approved deviation
   from the reference — see the .contact-right-inner comment above and
   DECISIONS.md): just the copyright line + the privacy-notice link,
   split out of the contact section into their own section at the very
   end of the page. Same .section-padding/.section-container width as
   the legal pages' own footer, for a consistent text column. */
.site-footer {
  background-color: var(--white);
  border-top: 1px solid var(--white600);
}

.site-footer-inner {
  padding-top: 2rem;
  /* .back-to-top is a position:fixed 64px button sitting 20px off the
     viewport bottom, right edge. Petra asked for it "at the level of
     copyright" (2026-09-30) — checked with the actual rendered text
     bounds (Range.getClientRects(), not the <p>'s own block box, which
     is misleadingly full-width even though text-align:center only
     centers the *glyphs* within it) at every canonical breakpoint:
     from 768px up, the centered text column never reaches anywhere
     near the button horizontally, so they can safely share the same
     vertical band. Below 768px the (longer, DE especially — wraps to
     2 lines) copyright text can get wide enough to genuinely intersect
     the button, so this keeps the old safe clearance there. See
     DECISIONS.md for the full breakpoint-by-breakpoint measurements. */
  padding-bottom: 5.5rem;
  /* Petra asked for this centered (2026-09-30) — matches the reference's
     own `.text-block-3{text-align:center}`, but only at <=479px there;
     applied here at every width, a further deliberate deviation. */
  text-align: center;
}

@media (min-width: 768px) {
  .site-footer-inner {
    padding-bottom: 2rem;
  }
}

/* Confirmed live on all 3 locales: resting background is var(--blue),
   icon var(--white) — via Webflow's own dynamically-added `w--current`
   class (not present in static source.html, added at runtime; a
   same-page `#Top` anchor apparently always reads as "current").
   Background/icon color never change on hover on any locale — reverses
   the previous (wrong) implementation, which had white/blue swapped
   between rest and hover. Locale-asymmetric hover lift below. */
.back-to-top {
  z-index: 20;
  background-color: var(--blue);
  color: var(--white);
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 64px;
  height: 64px;
  position: fixed;
  /* 20px, not the reference's 40px — Petra asked for this tighter
     (2026-09-30), see DECISIONS.md. Halving it also shrinks the
     required .site-footer-inner bottom clearance (see that rule). */
  bottom: 20px;
  right: 20px;
  transition: transform 0.5s linear;
}

/* The reference genuinely renders this var(--blue30) (pale lavender) at
   >=1920px — confirmed live via getComputedStyle well after the
   scroll-in fade settles, see DECISIONS.md 2026-09-29 for the full
   trail. Petra asked (2026-09-30) to keep it var(--blue) at every width
   instead, blue30 "looks worse" to her here — a deliberate deviation
   from that confirmed reference behavior, so the override is gone
   rather than just left unused: nothing should silently reintroduce it
   later. See DECISIONS.md. */

/* Confirmed live: EN/DE only (real IX2 MOUSE_OVER/MOUSE_OUT binding on
   this element in the original, CZ has none) — hover lifts the whole
   button translateY(-10px), 500ms both ways. Easing string is empty in
   the IX2 config same as the About curtain-reveal's animated group,
   which measured as linear — used here too, not separately re-sampled
   (small, low-impact detail; MEDIUM confidence on curve shape, HIGH on
   distance/duration/existence, which come from the config/live values
   directly). No :focus-visible: not confirmed live, matches the
   nav-link/lang-link corrective-pass precedent. */
html[lang="en"] .back-to-top:hover,
html[lang="de"] .back-to-top:hover {
  transform: translateY(-10px);
}

.back-to-top-icon {
  width: 22px;
  height: 22px;
  fill: currentColor;
}

/* Confirmed live: a second IX2 binding on this element (a-442, "Bottom
   To Top Link Animation"), SCROLL_INTO_VIEW, EN/DE only in the
   reference (CZ has no binding there — confirmed static opacity:1/1
   the whole time on live CZ). Not one-shot: rAF-sampled 3+ seconds
   live, still cycling, non-settled fractional opacity values
   throughout — a genuine infinite loop, not a reveal. All 4
   duration/easing values are literal in the IX2 config (custom
   action, not a preset) — "ease", 700ms and 500ms, asymmetric within
   each half of the cycle:
     arrow-1: 0.5 -> 1 over 700ms, hold, -> 0.5 over 500ms, hold
     arrow-2: 1 -> 0.5 over 500ms, hold, -> 1 over 700ms, hold
   both offset so exactly one is rising while the other is falling/
   holding — total cycle 1400ms (700+700), matches the measured live
   period (~1420ms) closely. Local markup already has 2 <path> layers
   in the icon (double-chevron), reused directly — no new elements.
   Petra asked to unify this onto CZ too (2026-09-30) — a further
   deliberate deviation from the reference (which never animates it on
   CZ); see DECISIONS.md. The `html[lang]` gating below is gone, so
   this now runs on all 3 locales; the separate EN/DE-only hover-lift
   above is untouched (she didn't ask about that one). */
@keyframes back-to-top-arrow-1 {
  0%,
  100% {
    opacity: 0.5;
  }
  50% {
    opacity: 1;
  }
  85.714% {
    opacity: 0.5;
  }
}

@keyframes back-to-top-arrow-2 {
  0%,
  100% {
    opacity: 1;
  }
  35.714% {
    opacity: 0.5;
  }
  50% {
    opacity: 0.5;
  }
}

.back-to-top-arrow--1 {
  animation: back-to-top-arrow-1 1.4s ease infinite;
}

.back-to-top-arrow--2 {
  animation: back-to-top-arrow-2 1.4s ease infinite;
}

/* ---------- Legal pages (Privacy Policy) ----------
   New standalone pages, not part of the original Webflow site (it never
   had one — platform/docs/privacy.md requires every site with a contact
   form to have its own). Reuses this site's own header/nav/footer
   markup and design tokens rather than peaksolutions.cz's different
   page structure, which only served as the content-outline template. */

.legal-section {
  padding-top: 8rem;
  padding-bottom: 3rem;
}

@media (min-width: 1280px) {
  .legal-section {
    padding-top: 9rem;
  }
}

@media (max-width: 479px) {
  .legal-section {
    /* `main` gets `margin-top: -55px` at this breakpoint (see the mobile
       page-wrapper offset near the top of this file), which every other
       first section already accounts for in its own top spacing (e.g.
       .hero's own tuned margin-top). This section didn't, so its padding
       needs the same 55px added back or the title sits under the navbar. */
    padding-top: 10rem;
  }
}

.legal-container {
  max-width: 48rem;
}

.legal-title {
  font-family: var(--heading-font);
  color: var(--blue);
  text-transform: uppercase;
  margin-top: 0;
  margin-bottom: 2rem;
  font-size: 2.5rem;
  font-weight: 800;
  line-height: 1.2;
}

.legal-heading {
  font-family: var(--heading-font);
  color: var(--black800);
  margin-top: 2.5rem;
  margin-bottom: 0.5rem;
  font-size: 1.3rem;
  font-weight: 700;
  line-height: 1.4;
}

.legal-copy {
  font-family: var(--paragraph-font);
  color: var(--black);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.6rem;
  margin-top: 0;
  margin-bottom: 0;
}

.legal-link {
  color: var(--blue);
}

/* 404 page's own CTA back to the homepage — just needs breathing room
   above it, .legal-copy's own margin-bottom:0 leaves none. */
.legal-cta {
  margin-top: 2rem;
  margin-bottom: 0;
}

/* .legal-footer/.legal-footer-grid (Sídlo společnosti/Kontakt +
   copyright, mirroring .contact-right-inner) removed 2026-09-30 —
   Petra asked for the legal pages' own footer to match the homepage's
   .site-footer instead (copyright + privacy link only, centered, no
   address/contact block). The legal pages now use .site-footer/
   .site-footer-inner directly; see DECISIONS.md. */
