/* Maven360 CONNECT — marketing site (M360-4723).
 *
 * The design handoff arrived as React with every value inlined per element.
 * This file is the same design expressed as a small set of classes, so a
 * headline is `.h2` in four templates instead of the same twelve declarations
 * copy-pasted twelve times. Literal values live in tokens.css; anything here
 * that hardcodes a colour is either a one-off from the spec or lives inside a
 * DemoPharm mockup, where the palette is deliberately not ours.
 */

@import url('tokens.css');
@import url('fonts.css');

/* ── Base ──────────────────────────────────────────────────────────────── */

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

/* The UA's [hidden] rule is display:none at the lowest specificity, so any
   class that sets display — .stack, .grid — silently defeats it. That is how
   the contact form's success message ended up permanently on screen next to
   the empty form. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--c-bg);
  color: var(--c-text);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Form controls do not inherit the page font — without this, inputs and
   buttons render in the UA's Arial beside Geist, which is exactly the mix the
   font gate exists to catch. */
button, input, select, textarea { font-family: inherit; }

a { color: var(--c-text); text-decoration: none; }
a:hover { color: var(--c-cyan-text); }

img { max-width: 100%; }

::selection { background: var(--c-cyan); color: var(--c-white); }

:focus-visible {
  outline: 2px solid var(--c-cyan);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

/* Skip link — the header is sticky and the hero is long, so keyboard users
   need a way past both. Visible only once focused. */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--c-navy); color: var(--c-white);
  padding: 12px 20px; border-radius: 0 0 var(--r-sm) 0;
  font-size: 15px; font-weight: var(--fw-semi);
}
.skip-link:focus { left: 0; color: var(--c-white); }

/* ── Typography ────────────────────────────────────────────────────────── */

/* The brand device: exactly one italic cyan keyword per headline, and the
   full stop after it cyan too. Templates write <em>keyword</em><span
   class="dot">.</span> */
em { font-style: italic; color: var(--c-cyan-text); }
.dot { color: var(--c-cyan-text); }

.h1, .h2, .h3 {
  font-weight: var(--fw-black);
  letter-spacing: var(--ls-display);
  margin: 0;
}
.h1 { font-size: var(--fs-hero);     line-height: var(--lh-display); }
.h1--sub { font-size: var(--fs-hero-sub); }
.h2 { font-size: var(--fs-h2);       line-height: var(--lh-heading); }
.h2--sm { font-size: var(--fs-h2-sm); }
.h3 { font-size: var(--fs-h3);       line-height: 1.08; }

.lead { font-size: var(--fs-lead); line-height: var(--lh-body); color: var(--c-text-muted); margin: 0; }
.body { font-size: var(--fs-body); line-height: 1.65; color: var(--c-text-muted); margin: 0; }
.body--sm { font-size: var(--fs-body-sm); line-height: var(--lh-body-wide); }

/* Mono kicker over every section headline: `01 / 05 — Kickerwort`. */
.kicker {
  display: flex; align-items: center; gap: 14px;
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  letter-spacing: var(--ls-kicker);
  text-transform: uppercase;
  color: var(--c-label);
  margin: 0 0 var(--sp-6);
}
.kicker__rule { width: 26px; height: 1px; background: var(--c-border-strong); flex: 0 0 auto; }

.caption {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: var(--ls-kicker);
  text-transform: uppercase;
  color: var(--c-label);
}

/* Stat digits must not jitter while counting up. */
.stat__value {
  font-weight: var(--fw-black);
  font-size: var(--fs-stat);
  letter-spacing: var(--ls-display);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
[data-count] { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ── Layout ────────────────────────────────────────────────────────────── */

.container { max-width: var(--w-container); margin: 0 auto; }

.section { padding: var(--sp-section-y) var(--sp-section-x); }
.section--sm  { padding: var(--sp-section-y-sm) var(--sp-section-x); }
.section--ice { background: var(--c-surface-alt); }
.section--navy { background: var(--c-navy); color: var(--c-on-navy); }
.section--navy .body,
.section--navy .lead { color: var(--c-on-navy-muted); }
.section--navy .kicker,
.section--navy .caption { color: var(--c-on-navy-label); }
.section--navy .kicker__rule { background: var(--c-border-on-navy); }
.section--navy em { color: var(--c-cyan); }

/* min() on every track floor: a fixed minmax() minimum wider than the
   available column makes the grid overflow its own container. */
.grid { display: grid; gap: var(--sp-col-gap); }
.grid--2   { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }
.grid--3   { grid-template-columns: repeat(auto-fit, minmax(min(270px, 100%), 1fr)); }
.grid--4   { grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); }
.grid--tight { gap: clamp(32px, 4vw, 56px); }

.stack { display: flex; flex-direction: column; }
.stack--1 { gap: var(--sp-1); }
.stack--2 { gap: var(--sp-2); }
.stack--3 { gap: var(--sp-3); }
.stack--4 { gap: var(--sp-4); }

/* Every sub-page opens with this block. One rule rather than a per-page
   padding value, so the distance from the header to the first headline is
   identical on all of them and the eye has nothing to re-find after a
   navigation. */
.page-hero { padding: clamp(56px, 6vw, 96px) var(--sp-section-x) var(--sp-section-y); }

/* Section intro: headline left, supporting sentence right. */
.intro {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: var(--sp-col-gap);
  align-items: start;
  margin-bottom: clamp(48px, 6vw, 80px);
}
.intro .body { max-width: 34em; }

/* ── Actions ───────────────────────────────────────────────────────────── */

/* Exactly one primary CTA exists site-wide: "Demo anfragen". Everything else
   is a text link with an arrow. */
.cta {
  display: inline-flex; align-items: center; gap: 9px;
  background: var(--c-navy); color: var(--c-white);
  padding: 16px 24px; border-radius: var(--r-sm);
  font-size: 15.5px; font-weight: var(--fw-semi);
  width: fit-content; border: 0; cursor: pointer;
  font-family: inherit;
  box-shadow: var(--sh-card);
  transition: background var(--d-base) ease, transform var(--d-base) ease;
}
.cta:hover { background: #1a3a63; color: var(--c-white); transform: translateY(-2px); }
.cta__arrow { font-family: var(--font-mono); display: inline-block; transition: transform var(--d-fast) ease; }
.cta:hover .cta__arrow { transform: translateX(4px); }
/* The header CTA never wraps: two lines make the whole bar taller and
   lopsided, and "Demander une démo" is long enough to do it. */
.cta--sm {
  padding: 13px clamp(13px, 1.6vw, 20px);
  font-size: clamp(13px, 1.15vw, 14.5px);
  box-shadow: none;
  white-space: nowrap;
}

.txtlink {
  position: relative; width: fit-content;
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: var(--fw-semi); font-size: var(--fs-body-sm);
  color: var(--c-text);
}
.txtlink::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -5px; height: 1px;
  background: currentColor; transform: scaleX(0); transform-origin: left;
  transition: transform var(--d-base) ease;
}
.txtlink:hover::after { transform: scaleX(1); }
.txtlink__arrow { font-family: var(--font-mono); }
.section--navy .txtlink { color: var(--c-cyan); }

/* ── Cards ─────────────────────────────────────────────────────────────── */

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  padding: clamp(24px, 3vw, 36px);
  transition: transform var(--d-base) ease, border-color var(--d-base) ease;
}
/* Lift and a cyan edge — deliberately no shadow jump, which would read as the
   card leaving the page rather than responding to the pointer. */
.card:hover { transform: translateY(-2px); border-color: var(--c-cyan); }
.card--flat:hover { transform: none; border-color: var(--c-border); }
.section--navy .card {
  background: rgba(255, 255, 255, .04);
  border-color: var(--c-border-on-navy);
}
.card__num {
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: var(--ls-kicker); color: var(--c-cyan-label);
}
.section--navy .card__num { color: var(--c-cyan); }
/* `margin: 0` because these are <h3> elements since M360-4728 (F43) and the
   UA gives headings a block margin the stacks would then fight with. The
   class stays the style carrier — one card title is still a <span> (the
   contact form's confirmation, which is a status message, not a section). */
.card__title { font-weight: var(--fw-bold); font-size: 21px; letter-spacing: var(--ls-tight); margin: 0; }

.photo { border-radius: var(--r-md); overflow: hidden; display: block; }
.photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.photo--32 { aspect-ratio: 3 / 2; }

/* ── Header ────────────────────────────────────────────────────────────── */

.header {
  position: sticky; top: 0; z-index: 60;
  /* Tinted from the page colour so the sticky bar reads as the page in both
     themes rather than as a white slab floating over a dark one. */
  background: color-mix(in srgb, var(--c-bg) 92%, transparent);
  border-bottom: 1px solid var(--c-border);
  box-shadow: var(--sh-header);
  transition: background var(--d-base) ease, border-color var(--d-base) ease, box-shadow var(--d-base) ease;
}
/* On the home page only, and only at the very top: fully transparent so the
   hero photo runs behind it. No backdrop-filter, no rule, no shadow — the
   photo is light enough there for navy type to hold contrast.

   This class controls colour ONLY. Geometry is governed by .is-scrolled below,
   because the two used to be the same class: the home page started transparent
   and therefore tall, every sub-page started solid and therefore short, and the
   header visibly changed size when you navigated between them. */
/* Scoped under .js because only site.js ever takes the class off again: it
   toggles it on scroll, so without a script the header stays transparent all
   the way down the page — including over the closing navy panel, where the
   nav sits in --c-text (#0C2342) on --c-navy (#0C2342) and the whole header
   disappears (M360-4727, F31). Same convention as `.js [data-reveal]` below
   and `.js .hero__screen` in mockups.css: a rule that only applies when
   something is there to undo it. */
.js .header--transparent {
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}
.header__progress-track { position: absolute; left: 0; right: 0; top: 0; height: 2px; overflow: hidden; }
.header__progress { height: 2px; width: 0; background: var(--c-cyan); transition: width .1s linear; }
/* The logo sits on the same left edge as the content below it.
 *
 * A section puts its padding outside the width cap (`.section` pads by
 * --sp-section-x, `.container` caps at --w-container inside that), so the
 * content edge lands at --w-container. The header capped itself at
 * --w-container and *then* padded inwards, which pushed the logo past that
 * edge at every width — 16 px at 1440 (M360-4726).
 *
 * Widening the cap by the padding it carries makes the two edges coincide:
 * cap − padding == --w-container. The padding cannot move out to `.header`
 * instead, because `.header__progress-track` is positioned left:0/right:0
 * against it and would be indented with it.
 */
.header__inner {
  max-width: calc(var(--w-container) + 2 * var(--sp-section-x));
  margin: 0 auto;
  padding: 16px var(--sp-section-x);
  display: flex; align-items: center; gap: clamp(8px, 1.4vw, 24px);
  transition: padding var(--d-base) ease;
}
/* Every page starts at the same height and shrinks on scroll by the same
   amount — the shrink is a scroll response, not a per-page property. */
.header.is-scrolled .header__inner { padding-top: 12px; padding-bottom: 12px; }

.brand { display: flex; align-items: center; flex: 0 0 auto; height: 52px; }
.brand__logo { height: 42px; width: auto; display: block; transition: height var(--d-base) ease; }
.header.is-scrolled .brand__logo { height: 34px; }
.brand__sep { width: 1px; height: 22px; background: var(--c-border-strong); margin: 0 14px; flex: 0 0 auto; }
/* The wordmark is decoration; the navigation is function. Once the row is
   tight enough that the locale's labels would crowd it, the wordmark goes
   first.

   Staggered by language, because the widths are not close to each other. The
   threshold used to be a flat 1280px, which is where French starts to crowd
   ("Pour les laboratoires" / "Pour les pharmacies") — correct for French, and
   300px too early for everyone else. The result was a header without the
   product name on every ordinary laptop window.

   Measured by nav overflow (`scrollWidth - clientWidth`) with the wordmark
   forced visible, not by bounding boxes: `.nav` is `flex: 0 1 auto` with
   `min-width: 0` and `white-space: nowrap`, so the box shrinks while the text
   runs out of it. The rects never report an overlap; the labels visibly
   collide anyway. French overflows from 1280px down, the other four only
   below 960px, German not at all in that range.

   The thresholds count the language menu in, because both compete for the
   same row and measuring them apart gives numbers that do not hold together.
   With the menu visible the pair fits from 960px in German, 1024px in English
   and Italian, 1100px in Spanish and 1366px in French; the rules use 1100 and
   1366 so one value covers four languages with room to spare. The menu itself
   gets the lower thresholds further down — it is function and the wordmark is
   decoration, so the decoration goes first.

   Both rules carry a `min-width: 760px` floor, because below that the nav is
   gone entirely and there is nothing left to crowd. That is where the phone
   header takes over: it drops the CTA instead and keeps the wordmark. Without
   the floor these two rules reached into that range and took the wordmark
   away there as well — which is what made the phone header show a logo, a
   theme control, a burger, and no product name. */
@media (min-width: 760px) and (max-width: 1366px) {
  html[lang="fr"] .brand__sep,
  html[lang="fr"] .brand__mark { display: none; }
}
@media (min-width: 760px) and (max-width: 1099px) {
  .brand__sep, .brand__mark { display: none; }
}
.brand__mark {
  font-family: var(--font-mono);
  /* Two whole sizes rather than clamp(10px, 1.1vw, 14.5px). The fluid middle
     never earned its keep here: the wordmark is only ever visible on a phone
     (where 1.1vw is 4px and the clamp sat at its floor) or from 1100px up,
     which leaves 1100–1318px as the entire range where the vw term did
     anything — and it paid for that with computed sizes like 13.2px. The
     phone value went up because 10px beside a 30px logo read as a footnote. */
  font-size: 12px;
  /* Bold: at the mono default of 400 the word sat thin beside the logo and
     read as a caption rather than as half the brand. Semibold was still not
     enough at this letter-spacing. */
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-mark); margin-right: calc(var(--ls-mark) * -1);
  text-transform: uppercase; color: var(--c-cyan); white-space: nowrap;
}
/* The desktop step, at the width where the wordmark comes back. Must sit
   after the rule above: same specificity, so source order decides — stated
   before it, it silently lost. */
@media (min-width: 1100px) {
  .brand__mark { font-size: 15px; }
}

/* The nav has to survive labels of very different lengths: "Für Hersteller"
   in German is "Pour les laboratoires" in French. It shrinks before the logo
   or the CTA does, and the gap closes with it. */
.nav {
  flex: 0 1 auto; min-width: 0;
  display: flex; justify-content: center;
  gap: clamp(6px, 1.2vw, 28px);
  white-space: nowrap;
  margin: 0 clamp(20px, 2.4vw, 40px);
}
.nav__item {
  position: relative; padding: 6px 0;
  font-size: clamp(12.5px, 1.2vw, 15px); font-weight: var(--fw-medium);
  color: var(--c-text); transition: color var(--d-base) ease;
}
.nav__item:hover { color: var(--c-cyan-text); }
.nav__item[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 1.5px; background: var(--c-cyan);
}
.header__actions { display: flex; align-items: center; gap: clamp(10px, 1.4vw, 18px); flex: 0 0 auto; justify-content: flex-end; margin-left: auto; }

.burger {
  display: none; flex-direction: column; justify-content: center; gap: 5px;
  width: 40px; height: 40px; padding: 11px 8px;
  background: none; border: 0; cursor: pointer; flex: 0 0 auto;
}
.burger span { height: 1.5px; background: var(--c-text); display: block; }

.mobile-nav {
  display: none; flex-direction: column;
  border-top: 1px solid var(--c-border); background: var(--c-bg);
  padding: 8px clamp(18px, 3.4vw, 56px) 20px;
}
/* Scoped: the burger that opens this is inert without site.js, so an
   unscripted visitor never got here (M360-4727, F32). The unscripted fallback
   lives in the max-width query below, where .nav is hidden and this is the
   only set of links left. */
.js .mobile-nav[data-open="1"] { display: flex; }
.mobile-nav a {
  padding: 15px 0; font-size: 17px; font-weight: var(--fw-semi);
  border-bottom: 1px solid var(--c-border);
  /* Centred like the two switches at the foot of the panel — left-aligned
     they read as a different list from the controls under them. */
  text-align: center;
}
/* `last-of-type`, not `last-child`: since the language and theme menus sit at
   the foot of the panel the last link is no longer its last child, and the
   rule stopped applying — leaving its border stacked on the tools' own rule
   as a double line. */
.mobile-nav a:last-of-type { border-bottom: 0; }

/* Compact header below the two-column breakpoint. The handoff specifies logo,
   "Demo anfragen" and a menu icon — the CONNECT wordmark and its rule are the
   parts that go, because at 390px the full row measured 413px wide and pushed
   the menu button off the screen entirely. */
@media (max-width: 759px) {
  .nav { display: none; }
  /* The burger only appears when a script can open what it points at
     (M360-4727, F32). It used to be a visible, focusable control that did
     nothing without site.js, and since .nav is hidden at this width the
     footer was the only navigation left on the page. Unscripted, the mobile
     nav renders open instead — same links, no control that lies about being
     one. */
  .js .burger { display: flex; }
  html:not(.js) .mobile-nav { display: flex; }
  /* On a phone the header gives up the CTA, not the wordmark (M360-4726).
     It used to be the other way round, and it was the worse trade: the
     button repeats the hero CTA sitting right below it on the same screen —
     two loud calls to action in one thumb's reach — while the wordmark is
     the only thing in the header that says whose product this is. Every
     marketing page carries at least one CTA in its body plus the contact
     block; the legal pages carry none on purpose, and a privacy notice
     without a sales button is right rather than a gap. */
  .header__actions .cta--sm { display: none; }
  .brand { height: 44px; }
  .brand__logo,
  .header.is-scrolled .brand__logo { height: 30px; }
  /* The horizontal padding stays --sp-section-x here too: overriding it to
     16 px put the header 8 px inside the content, whose floor is 24 px. Only
     the gap is a phone concern. */
  .header__inner { gap: 8px; }
  /* The label must not wrap to two lines — that is what made the header tall
     and lopsided on a phone. */
  .cta--sm { padding: 10px 13px; font-size: 13px; white-space: nowrap; }
}

/* Very narrow phones: the CTA label alone no longer fits beside the logo and
   the menu button, so it becomes the arrow it already carries. The accessible
   name stays in aria-label. */
@media (max-width: 359px) {
  .cta--sm .cta__label { display: none; }
  .cta--sm { padding: 10px; }
}

/* ── Footer ────────────────────────────────────────────────────────────── */

.footer {
  background: var(--c-navy); color: var(--c-on-navy);
  padding: clamp(64px, 7vw, 96px) var(--sp-section-x) var(--sp-5);
}
.footer__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: clamp(36px, 5vw, 72px);
  padding-bottom: clamp(48px, 5vw, 72px);
  border-bottom: 1px solid var(--c-border-on-navy);
}
.footer__col { display: flex; flex-direction: column; gap: 14px; }
.footer__label {
  font-family: var(--font-mono); font-size: 10.5px;
  letter-spacing: .18em; text-transform: uppercase; color: var(--c-on-navy-label);
}
.footer a, .footer__text { font-size: 15.5px; color: var(--c-on-navy-muted); width: fit-content; }
.footer a:hover { color: var(--c-cyan); }
.footer__text { line-height: var(--lh-body-wide); }
.footer__brand { display: flex; align-items: center; gap: 10px; }
.footer__brand img { height: 27px; width: auto; display: block; }
.footer__brand-sep { width: 1px; height: 15px; background: rgba(255, 255, 255, .3); }
.footer__brand-mark {
  font-family: var(--font-mono); font-size: 11.5px;
  letter-spacing: var(--ls-mark); text-transform: uppercase; color: var(--c-cyan);
}
/* The handoff specifies a mono line here. That works for a label, and not for
   a company name and a version number: at 10.5px uppercase with .16em tracking
   the version read as "V1.29.1-15-G0500B00F" and was hard to parse. The row
   uses the text face at a readable size instead, which is also what the
   previous footer did. */
.footer__bottom {
  padding-top: 28px; display: flex; align-items: center;
  justify-content: space-between; gap: 20px; flex-wrap: wrap;
  font-size: 14px; line-height: 1.5;
  color: var(--c-on-navy-label);
}

/* ── Motion ────────────────────────────────────────────────────────────── */

/* Reveal: content lifts 20px and fades in. The stagger delay is set per element
   by site.js from its position within the section.

   Scoped under .js — a class the document sets for itself in <head> — because
   the starting state is invisible. Without that guard, a visitor whose script
   fails to run gets a page whose middle five sections never appear, and no
   error to explain it. No JS, no hiding: everything renders in its end state. */
.js [data-reveal] {
  opacity: 0; transform: translateY(20px);
  transition: opacity var(--d-reveal) var(--ease-out), transform var(--d-reveal) var(--ease-out);
}
.js [data-reveal].is-revealed { opacity: 1; transform: none; }

@keyframes dcPulse   { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.72); } }
@keyframes heroFloat { 0%, 100% { transform: translateY(-6px); } 50% { transform: translateY(6px); } }
@keyframes tapRing   { 0%, 60% { opacity: 0; transform: scale(.6); } 70% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.45); } }
@keyframes resNew    { 0%, 44% { opacity: 1; } 52%, 100% { opacity: 0; } }
@keyframes resDone   { 0%, 44% { opacity: 0; } 52%, 100% { opacity: 1; } }
@keyframes resTap    { 0%, 38% { transform: none; } 43% { transform: scale(.96); } 50%, 100% { transform: none; } }

/* The endpoint of every motion rule: show the final state, animate nothing. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .js [data-reveal] { opacity: 1 !important; transform: none !important; transition: none !important; }
  .hero__frame, .pulse-dot, .tap-ring, .res-card > * { animation: none !important; }
  .hero__photo { transform: none !important; }
}

/* ── Utilities ─────────────────────────────────────────────────────────── */

.mono { font-family: var(--font-mono); }
.muted { color: var(--c-text-muted); }
.center { text-align: center; }
.pulse-dot { animation: dcPulse 1.8s ease-in-out infinite; }
.vh {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ── Form + FAQ ────────────────────────────────────────────────────────── */

.field { display: flex; flex-direction: column; gap: 7px; }
.field__label { font-size: 13.5px; font-weight: var(--fw-medium); color: var(--c-text); }
.field__opt { color: var(--c-label); font-weight: var(--fw-regular); }
.field__input {
  /* font-family is set explicitly: form controls do not inherit it, and the
     one thing that gives a page away as unfinished is inputs in Arial next to
     headlines in Geist. */
  font-family: var(--font-sans);
  font-size: var(--fs-body-sm);
  color: var(--c-text);
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-sm);
  padding: 12px 14px;
  width: 100%;
  transition: border-color var(--d-base) ease;
}
.field__input:focus { border-color: var(--c-cyan); }
textarea.field__input { resize: vertical; min-height: 96px; }

.field-check { display: flex; align-items: flex-start; gap: 10px; }
.field-check input { margin-top: 4px; accent-color: var(--c-cyan); flex: 0 0 auto; }
.field-check a { text-decoration: underline; }

/* Honeypot: off-screen rather than display:none — some bots skip hidden
   fields, and one that fills this never reaches the endpoint. */
.form-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* A plain list separated by hairlines — the FAQ's frame without its behaviour.
   Its own component rather than borrowing `.faq`: those items are <details> and
   carry the open/close affordance, and a list that only reads would inherit a
   marker it never uses. Two rules, and they stay independent. */
.rows { border-top: 1px solid var(--c-border); }
.rows__item {
  border-bottom: 1px solid var(--c-border);
  padding: 26px 0;
  display: flex; flex-direction: column; gap: 8px;
}

.faq { border-top: 1px solid var(--c-border); }
.faq__item { border-bottom: 1px solid var(--c-border); }
.faq__q {
  cursor: pointer; list-style: none;
  padding: 20px 0; padding-right: 32px; position: relative;
  font-size: var(--fs-lead); font-weight: var(--fw-semi); color: var(--c-text);
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "+"; position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  font-family: var(--font-mono); font-size: 20px; color: var(--c-cyan);
}
.faq__item[open] .faq__q::after { content: "–"; }
.faq__q:hover { color: var(--c-cyan-text); }
.faq__a { padding: 0 32px 22px 0; max-width: 62em; }

/* Three photos in one row, inside a column that is already half the container.
   The generic .grid--3 has a 270px minimum and wraps to 2+1 here. */
.gallery-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--sp-2); }

/* Closing line above the contact block. Shallower than a full section: the
   form follows immediately, and the two read as one ending rather than two. */
.contact-lead { padding-top: var(--sp-section-y-sm); padding-bottom: var(--sp-section-y-sm); }

/* The header is sticky, and the anchor sits on the headline — the line the
   reader came for. Measured from it: the header's own height plus a little
   air, nothing more. On the section it would have stacked that section's top
   padding on top and left most of a screen empty; on the kicker it left a line
   of eyebrow text between the header and the title. */
#kontakt { scroll-margin-top: 104px; }

/* ── Touch targets ─────────────────────────────────────────────────────── */

/* On a phone every control has to be reachable with a thumb. Measured at
   390px, the footer links were 25px tall, the arrow links 26px, the burger 40
   and the privacy checkbox 13 — all under the 44px minimum, and the footer
   links sat close enough together to hit the wrong one. Desktop keeps the
   tighter spacing, where a pointer makes it a non-issue. */
@media (pointer: coarse), (max-width: 759px) {
  .footer__col a,
  .mobile-nav a { min-height: 44px; display: flex; align-items: center; justify-content: center; }
  .footer__brand { min-height: 44px; }
  .txtlink { min-height: 44px; align-items: center; }
  .burger { width: 44px; height: 44px; }
  .cta, .cta--sm { min-height: 44px; }
  .faq__q { padding-top: 22px; padding-bottom: 22px; }
  /* The label is the real target and wraps the box, but a 13px checkbox is
     still hard to hit deliberately. */
  .field-check { min-height: 44px; align-items: center; }
  .field-check input { width: 22px; height: 22px; }
  /* Links inside running text stay inline — padding them to 44px would break
     the line. The table-of-contents entries are their own rows, so those do
     get the full target. */
  .legal-toc a { display: block; padding: 11px 0; }
  /* Values in the register/contact lists are one link per row, so they are
     standalone targets rather than links inside a sentence. */
  .legal-grid dd a { display: inline-block; padding: 11px 0; }
}

/* The footer carries the language list for viewports where the header menu
   is hidden. */


/* ── Touch targets ─────────────────────────────────────────────────────── */

/* On a phone every control has to be reachable with a thumb. Measured at
   390px, the footer links were 25px tall, the arrow links 26px, the burger 40
   and the privacy checkbox 13 — all under the 44px minimum, and the footer
   links sat close enough together to hit the wrong one. Desktop keeps the
   tighter spacing, where a pointer makes it a non-issue. */
@media (pointer: coarse), (max-width: 759px) {
  .footer__col a,
  .mobile-nav a { min-height: 44px; display: flex; align-items: center; justify-content: center; }
  .footer__brand { min-height: 44px; }
  .txtlink { min-height: 44px; align-items: center; }
  .burger { width: 44px; height: 44px; }
  .cta, .cta--sm { min-height: 44px; }
  .faq__q { padding-top: 22px; padding-bottom: 22px; }
  /* The label is the real target and wraps the box, but a 13px checkbox is
     still hard to hit deliberately. */
  .field-check { min-height: 44px; align-items: center; }
  .field-check input { width: 22px; height: 22px; }
  /* Links inside running text stay inline — padding them to 44px would break
     the line. The table-of-contents entries are their own rows, so those do
     get the full target. */
  .legal-toc a { display: block; padding: 11px 0; }
  /* Values in the register/contact lists are one link per row, so they are
     standalone targets rather than links inside a sentence. */
  .legal-grid dd a { display: inline-block; padding: 11px 0; }
}

/* ── Language switcher (footer; the header uses the menu below) ────────── */

/* Five languages in a column would run two rows past the three-item columns
   beside it. Flowing them into two sub-columns keeps the footer's rhythm:
   three, then the remaining two alongside. */
.footer__langs {
  display: grid;
  grid-template-rows: repeat(3, auto);
  grid-auto-flow: column;
  grid-auto-columns: max-content;
  gap: 14px var(--sp-4);
  justify-content: start;
}
.footer__langs a[aria-current] { color: var(--c-cyan); }

/* ── Header menus (language, theme) ────────────────────────────────────── */

.header__tools { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }

.menu { position: relative; }
.menu__btn {
  display: flex; align-items: center; gap: 6px;
  background: none; border: 1px solid transparent; border-radius: var(--r-sm);
  padding: 8px 10px; cursor: pointer;
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--c-label);
  transition: color var(--d-base) ease, border-color var(--d-base) ease;
}
.menu__btn:hover { color: var(--c-cyan-text); border-color: var(--c-border); }
.menu__btn svg { width: 15px; height: 15px; flex: 0 0 auto; }

.menu__list {
  display: none;
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 80;
  min-width: 168px;
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  box-shadow: var(--sh-card);
  padding: 6px;
}
.js .menu.is-open .menu__list { display: block; }
/* Both header menus open from a button that only site.js is wired to, so
   without a script they were controls that could be focused and pressed and
   never did anything (M360-4727, F32). Theme selection is meaningless without
   a script anyway; language selection is the loss here, and it is tracked as
   its own follow-up rather than papered over with an always-open dropdown in
   the header. */
html:not(.js) .menu { display: none; }
.menu__list a,
.menu__list button {
  display: block; width: 100%; text-align: left;
  padding: 10px 12px; border: 0; border-radius: var(--r-sm);
  background: none; cursor: pointer;
  font-family: var(--font-sans); font-size: 14.5px;
  color: var(--c-text);
  transition: background var(--d-fast) ease, color var(--d-fast) ease;
}
.menu__list a:hover,
.menu__list button:hover { background: var(--c-surface-alt); color: var(--c-cyan-text); }
/* The active entry is marked, not hidden — a menu that omits the current
   choice leaves the reader unsure what is in effect. */
.menu__list .is-current { color: var(--c-cyan-text); font-weight: var(--fw-semi); }

/* The language menu goes first when the row gets tight; the theme menu is one
   icon and stays, and below 760px both move into the burger. Staggered by
   language for the same reason as the wordmark above, and measured with the
   wordmark already hidden — by then it has given way. On its own the menu
   fits from 860px in German, 900px in English and Italian, 960px in Spanish
   and 1100px in French. A flat 1180px was right for French and took the menu
   away 280px early for everyone else.

   Between 760px and this floor the language choice lives in the footer alone
   — it is there and it keeps the reader on their page, but it takes a scroll
   to the bottom to find. Closing that gap means moving the burger up to 960px,
   which would also settle F55; that is a layout decision and is written up in
   the 0826 audit rather than made here. */
@media (min-width: 760px) and (max-width: 1099px) {
  html[lang="fr"] .header__tools .menu:first-child { display: none; }
}
@media (min-width: 760px) and (max-width: 959px) {
  .header__tools .menu:first-child { display: none; }
}
/* The two menus at the foot of the burger panel. Centred as a pair, with a
   rule above them: they are a different kind of thing from the three
   navigation links over them, and reading them as a fourth and fifth entry
   would be wrong. */
.mobile-nav__tools {
  display: flex; justify-content: center; gap: var(--sp-2);
  border-top: 1px solid var(--c-border);
  margin-top: 8px; padding-top: 16px;
}
.mobile-nav__tools .menu__btn {
  border-color: var(--c-border);
  padding: 10px 14px;
}
/* Opened downward and from the left edge of their button — the header
   version anchors right, which would push these off-screen. */
.mobile-nav__tools .menu__list { right: auto; left: 0; }
@media (min-width: 760px) {
  .mobile-nav__tools { display: none; }
}

/* Measured: with the CTA gone the row needs 297px, which fits from 360px up.
   Below that the wordmark goes after all — the logo, the theme control and
   the burger are function, it is not. */
@media (max-width: 359px) {
  .brand__sep, .brand__mark { display: none; }
}

@media (max-width: 759px) {
  .menu__list { right: auto; left: 0; }
  /* Language and theme move into the burger here, where they were before the
     relaunch. This has to sit after `.header__tools { display: flex }` above:
     same specificity, so the later rule wins, and stated earlier in the file
     it silently did nothing. */
  .header__tools { display: none; }
}

/* ── Dark mode adjustments ─────────────────────────────────────────────── */

/* The navy CTA is the page background in dark mode, so it would vanish. Cyan
   keeps it the single most prominent thing on the page, which is its job. */
:root.dark .cta,
:root.dark .header--transparent .cta { background: var(--c-cyan); color: #06202B; }
:root.dark .cta:hover { background: #46CDE4; color: #06202B; }
/* The navy close sections invert the same way the page does, so their button
   has to stop being white-on-white. */
:root.dark .section--navy .cta { background: var(--c-cyan); color: #06202B; }

@media (prefers-color-scheme: dark) {
  :root:not(.light) .cta,
  :root:not(.light) .header--transparent .cta { background: var(--c-cyan); color: #06202B; }
  :root:not(.light) .cta:hover { background: #46CDE4; color: #06202B; }
  :root:not(.light) .section--navy .cta { background: var(--c-cyan); color: #06202B; }
}

/* Two logo files, one shown at a time: the navy wordmark disappears on a dark
   header and the white one disappears on a light one. */
.brand__logo--light { display: none; }
:root.dark .brand__logo--dark { display: none; }
:root.dark .brand__logo--light { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not(.light) .brand__logo--dark { display: none; }
  :root:not(.light) .brand__logo--light { display: block; }
}

/* ── Lightbox ──────────────────────────────────────────────────────────── */

.lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(12px, 4vw, 32px);
  background: color-mix(in srgb, var(--c-navy) 88%, transparent);
  /* The mockups are pinned to light tokens and would otherwise sit on a wash
     of their own colour. */
  backdrop-filter: blur(4px);
}
.lightbox[hidden] { display: none; }
.lightbox__stage { transform-origin: center center; }

/* A photo in the grid is cropped to 3:2 by object-fit: cover. Opened, it
   should be the whole picture — on a phone that is the real gain, because the
   image already fills the width there and scaling it up would add nothing. */
.lightbox__stage .photo {
  aspect-ratio: auto;
  width: min(92vw, 1100px);
  height: auto;
  max-height: 84vh;
  display: block;
}
.lightbox__stage .photo img {
  width: 100%; height: auto;
  max-height: 84vh;
  object-fit: contain;
}
.lightbox__close {
  position: absolute; top: 16px; right: 16px;
  width: 44px; height: 44px;
  display: flex; align-items: center; justify-content: center;
  background: var(--c-surface); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: 50%;
  font-size: 24px; line-height: 1; cursor: pointer;
  font-family: var(--font-sans);
}
.lightbox__close:hover { color: var(--c-cyan-text); }

/* The page must not scroll behind the overlay. `overflow: hidden` alone is
   ignored by iOS Safari, so the body comes out of flow at the offset site.js
   recorded — `top` is set inline and given back on close. */
html.has-lightbox { overflow: hidden; }
body.has-lightbox {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

/* Anything that opens gets a pointer and a hint that it is interactive. */
[data-zoom] { cursor: zoom-in; }
[data-zoom]:focus-visible { outline: 2px solid var(--c-cyan); outline-offset: 4px; }

/* The hero phone breathes on its own; a copy of it in the overlay should sit
   still while it is being read. */
.lightbox .hero__frame { animation: none; }
.lightbox .tap-ring { animation: none; opacity: 0; }

/* ── Lightbox gallery ──────────────────────────────────────────────────── */

.lightbox__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: var(--c-surface); color: var(--c-text);
  border: 1px solid var(--c-border); border-radius: 50%;
  cursor: pointer;
}
.lightbox__nav[hidden] { display: none; }
.lightbox__nav:hover { color: var(--c-cyan-text); }
.lightbox__nav svg { width: 22px; height: 22px; }
.lightbox__nav--prev { left: 12px; }
.lightbox__nav--next { right: 12px; }

.lightbox__count {
  position: absolute; bottom: 16px; left: 50%; transform: translateX(-50%);
  margin: 0;
  font-family: var(--font-mono); font-size: 11px;
  letter-spacing: .16em;
  color: var(--c-on-navy-label);
}

/* On a phone the side buttons would sit on top of the image. Swiping is the
   gesture people reach for there anyway, so they move under it. */
@media (max-width: 640px) {
  .lightbox__nav { top: auto; bottom: 14px; transform: none; width: 44px; height: 44px; }
  .lightbox__nav--prev { left: 20px; }
  .lightbox__nav--next { right: 20px; }
  .lightbox__count { bottom: 28px; }
}

/* The corporate mark next to the copyright line, linking to maven360.io — the
   footer's own logo is the CONNECT one, and this is the group it belongs to.
   Decorative alt: the link already carries the name. */
/* Icon and line share a baseline row: align-items centres the 24px mark
   against the cap height of the text next to it. */
.footer__mark { display: flex; align-items: center; gap: 10px; }
.footer__mark img { height: 24px; width: auto; display: block; }
.footer__mark a { display: flex; align-items: center; min-height: 44px; }
