/* APANI Audiophile — local overrides. Loaded AFTER main.css so these rules win the cascade. */

/*
 * Restore a visible, draggable document scrollbar.
 * main.css hides it site-wide (::webkit-scrollbar width:0 + body scrollbar-width:none).
 */
html {
  scrollbar-gutter: stable;
  scrollbar-width: thin !important;
  scrollbar-color: var(--accent, #8b7a50) transparent;
}

body {
  scrollbar-width: thin !important;
  scrollbar-color: var(--accent, #8b7a50) transparent;
}

html::-webkit-scrollbar,
body::-webkit-scrollbar {
  display: block !important;
  -webkit-appearance: none !important;
  width: 10px !important;
  height: 10px !important;
  background: transparent;
}

html::-webkit-scrollbar-track,
body::-webkit-scrollbar-track {
  background: transparent;
}

html::-webkit-scrollbar-thumb,
body::-webkit-scrollbar-thumb {
  background-color: var(--accent, #8b7a50);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}

html::-webkit-scrollbar-thumb:hover,
body::-webkit-scrollbar-thumb:hover {
  background-color: var(--t-bright, #121212);
}

/* Screen-reader-only utility for a semantic page <h1> without altering the visual design. */
.visually-hidden {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Map the template's font custom properties to the next/font CSS variables. */
body {
  --_font-default: var(--font-manrope, "Manrope", sans-serif);
  --_font-accent: var(--font-jetbrains-mono, "JetBrains Mono", sans-serif);
}

.image-auto {
  /* width: auto !important; */
  height: auto !important;
}

/* Services stack: main.css .line { translateY(100%) } applies vendor-prefixed transforms; GSAP’s
   y uses unprefixed transform — boxes and painted text desync. Neutralize so only inline GSAP owns y. */
.mxd-stack-services .services-card__title .line,
.mxd-stack-services .services-card__descr .line {
  -webkit-transform: none;
  -moz-transform: none;
  -ms-transform: none;
  transform: none;
}

/* Preview / landing demo stack — same global .line + SplitText as services stack */
.mxd-demo-stack .demo-card__title .line,
.mxd-demo-stack .demo-card__descr .line {
  -webkit-transform: none;
  -moz-transform: none;
  -ms-transform: none;
  transform: none;
}

/* Overlay menu: active section — theme accent on label / index / arrow (no background) */
.mxd-menu .main-menu__item.main-menu__item--current .main-menu__number {
  color: var(--accent);
}
.mxd-menu .main-menu__item.main-menu__item--current .main-menu__caption {
  color: var(--accent);
}
.mxd-menu .main-menu__item.main-menu__item--current .main-menu__toggle svg {
  fill: var(--accent);
}
.mxd-menu .main-menu__item.main-menu__item--current.open .main-menu__caption {
  color: var(--accent);
}
.no-touch
  .mxd-menu
  .main-menu__item.main-menu__item--current
  .main-menu__toggle:hover
  .main-menu__caption {
  color: var(--accent);
}
.no-touch
  .mxd-menu
  .main-menu__item.main-menu__item--current
  .main-menu__toggle:hover
  svg {
  fill: var(--accent);
}

/* Keep the fullwidth email/display text from overflowing at any viewport width. */
.headline-email-text .fullwidth-text__wrap,
.headline-email-text .fullwidth-text__content {
  max-width: 100%;
  overflow-wrap: anywhere;
}
.headline-email-text .fullwidth-text__content {
  font-size: min(7.5vw, 7rem);
  line-height: 1.15;
}

/* Long typed headline roles (e.g. "Mastering-Engineer") must wrap, not overflow, on mobile. */
.inner-headline__title.animated-type,
.inner-headline__title.animated-type .animated-type,
.animated-type {
  max-width: 100%;
  overflow-wrap: anywhere;
}

/* Theme-aware brand logo: dark-coloured logo on light backgrounds, light-coloured on dark.
   Both variants are in the DOM; CSS shows the correct one for the active color-scheme so the
   swap is instant with the theme toggle (no JS/hydration flash). */
.apani-logo {
  display: block;
  height: 2.1rem;
  width: auto;
}
.apani-logo--menu {
  height: 2.6rem;
}
/* Laptop and above: bump the header brand mark noticeably larger so it holds
   the top-left corner more confidently on wider viewports. Applies to the
   header logo only; the menu-overlay logo keeps its own size. */
@media (min-width: 992px) {
  .apani-logo:not(.apani-logo--menu) {
    height: 2.8rem;
  }
}
@media (min-width: 1400px) {
  .apani-logo:not(.apani-logo--menu) {
    height: 3.2rem;
  }
}
.apani-logo--light {
  display: none;
}
:root[color-scheme="dark"] .apani-logo--dark {
  display: none;
}
:root[color-scheme="dark"] .apani-logo--light {
  display: block;
}
/* The permanent header overlays a dark hero, so always use the light logo there. */
.mxd-header-permanent .apani-logo--dark {
  display: none;
}
.mxd-header-permanent .apani-logo--light {
  display: block;
}

/* Clutch SVG logo styles - replaces dangerouslySetInnerHTML */
.cls-1 {
  fill: var(--t-bright);
}
.cls-2 {
  fill: #e52421;
}

/* -------------------------------------------------------------------------
 * Global underline removal + accent-only active state.
 * The template shipped underline decorations on several link contexts
 * (submenu active items, breadcrumb current item, article inline links,
 * pricing table links). Every rule below removes those with !important
 * so no vendor override wins.
 *
 * For active/current items, use var(--accent) — currently mapped to
 * rgb(139, 122, 80) — so the ONLY visual cue for "you are here" is colour.
 * ------------------------------------------------------------------------- */

/* Kill every link underline site-wide.
 * text-decoration-color uses the APANI accent so any underline never
 * falls back to browser blue. Link `color` default is set in main.css
 * (bare `a`) so more specific nav/footer rules still win. */
a,
a:link,
a:visited,
a:hover,
a:focus,
a:active,
.breadcrumbs__nav span.current-item {
  text-decoration: none !important;
  text-decoration-color: rgb(139, 122, 80) !important;
}

/* -------------------------------------------------------------------------
 * Global hover colour: moss (RGB 86 98 35).
 *
 * The template's many hover rules change colour to various tokens
 * (t-bright, t-medium, t-opp-bright, accent, …). APANI wants a single,
 * consistent hover cue everywhere: dark moss. This block catches the
 * common hover text/icon targets. Buttons that rely on background or
 * transform for hover are left untouched — only colour/fill is unified.
 * ------------------------------------------------------------------------- */
.no-touch a:hover,
.no-touch a:focus,
.no-touch button:not(:disabled):hover,
.no-touch [role="button"]:hover,
.no-touch .btn:hover,
.no-touch .btn:hover .btn-caption,
.no-touch .footer-data a:hover,
.no-touch .datalist__item ul li a:hover,
.no-touch .mxd-socials-line__link:hover,
.no-touch .mxd-socials-list ul li a:hover,
.no-touch .socials-list__item:hover,
.no-touch .socials-list__item:hover .socials-list__name,
.no-touch .socials-list__item:hover .socials-list__number {
  color: rgb(86, 98, 35) !important;
}
.no-touch a:hover svg,
.no-touch button:not(:disabled):hover svg,
.no-touch .btn:hover svg,
.no-touch .btn:hover i,
.no-touch .socials-list__item:hover svg,
.no-touch .socials-list__item:hover .socials-list__arrow svg {
  fill: rgb(86, 98, 35) !important;
}

/* Overlay-menu submenu: active item is colour-only, no underline. */
.submenu__item.active a,
.submenu__item.active a:hover,
.submenu__item.active a:focus {
  text-decoration: none !important;
  color: var(--accent) !important;
}

/* Breadcrumb: current item colour-only, no underline. */
.breadcrumbs__nav span.current-item {
  text-decoration: none !important;
  color: var(--accent);
}

/* Editorial article inline links: no underline; accent for state. */
.mxd-article__normal a,
.mxd-article__normal a:hover,
.mxd-article__normal a:focus {
  text-decoration: none !important;
  color: var(--accent);
}

/* Pricing-table link cell: no underline; accent for state. */
.mxd-pricing-table__link a,
.mxd-pricing-table__link a:hover,
.mxd-pricing-table__link a:focus {
  text-decoration: none !important;
  color: var(--accent);
}

/* -------------------------------------------------------------------------
 * Menu overlay: match the site's Day theme.
 *
 * The template intentionally rendered the overlay in the *opposite* theme
 * to create a bold contrast — dark background over a light site (and vice
 * versa). APANI wants the overlay to sit in the same Day palette as
 * everything else, so we remap the "opposite" custom properties inside the
 * menu scope. Every rule that reads var(--base-opp) / var(--t-opp-*) still
 * works — it just resolves to the same values as var(--base) / var(--t-*),
 * making the menu light instead of dark.
 * ------------------------------------------------------------------------- */
.mxd-menu__overlay,
.mxd-menu__content {
  --base-opp: var(--base);
  --base-opp-rgb: var(--base-rgb);
  --t-opp-bright: var(--t-bright);
  --t-opp-medium: var(--t-medium);
  --t-opp-muted: var(--t-muted);
  --t-opp-muted-extra: var(--t-muted-extra);
  --st-opp-medium: var(--st-medium);
  --st-opp-bright: var(--st-bright);
  --st-opp-muted-extra: var(--st-muted-extra);
}
/* Backdrop uses the same base as the site for consistency. */
.mxd-menu__backdrop {
  background: rgba(var(--base-rgb), 0);
}

/* Menu panel background — pure white, not the site's cream `--base`
 * (#eeeae8). The overlay is the solid panel behind the menu content. */
.mxd-menu__overlay {
  background-color: #fff;
}

/* -------------------------------------------------------------------------
 * Footer brand mark + legal row.
 *
 * Year lives in the copyright string (not a separate right-corner cell).
 * Below xl: center the mark and stack legal lines as a balanced block.
 * Desktop: copyright left, Swiss credit right.
 * ------------------------------------------------------------------------- */
.apani-footer-data .footer-data {
  text-wrap: balance;
}
.apani-footer-data .footer-data span {
  /* Avoid nested inline-flex eating spaces around © / words. */
  display: inline;
  white-space: normal;
}
.apani-footer-data .footer-data span.apani-footer-credit {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
}
.apani-footer-credit__link {
  display: inline-flex !important;
  align-items: center;
  gap: clamp(0.45rem, 1.2vw, 0.75rem);
  max-width: 100%;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.apani-footer-credit__flag {
  width: clamp(1.2rem, 3.2vw, 1.6rem);
  height: auto;
  flex: 0 0 auto;
  display: block;
}
@media (max-width: 1199.98px) {
  .apani-footer-data {
    padding-inline: clamp(1.6rem, 5vw, 3.2rem);
  }
  .apani-footer-data .mxd-footer__data-item,
  .apani-footer-data .mxd-footer__data-item.justify-end {
    justify-content: center;
    text-align: center;
  }
  .apani-footer-data .footer-data {
    text-align: center;
    max-width: 42rem;
    margin-inline: auto;
    letter-spacing: 0.02em;
    line-height: 1.7;
  }
  .apani-footer-data .col-12 + .col-12 .mxd-footer__data-item {
    margin-top: 1rem;
  }
  .apani-footer-credit__link {
    justify-content: center;
  }
}

/* -------------------------------------------------------------------------
 * Menu overlay — hover colour.
 *
 * The template's menu hovers used var(--t-opp-medium/bright), which we now
 * remap to the light theme. Override every menu hover state to a dedicated
 * moss/olive tone (RGB 86 98 35) so the interaction cue stands apart from
 * the tan "current-section" accent (RGB 139 122 80).
 * ------------------------------------------------------------------------- */
.no-touch .mxd-menu .main-menu__toggle:hover .main-menu__caption,
.no-touch
  .mxd-menu
  .main-menu__item.open
  .main-menu__toggle:hover
  .main-menu__caption,
.no-touch .mxd-menu .submenu__item a:hover {
  color: rgb(86, 98, 35);
}
.no-touch .mxd-menu .main-menu__toggle:hover .main-menu__number {
  color: rgb(86, 98, 35);
}
.no-touch .mxd-menu .main-menu__toggle:hover svg {
  fill: rgb(86, 98, 35);
}
.no-touch .mxd-menu .menu-contact__list li a:hover {
  color: rgb(86, 98, 35) !important;
}

/* -------------------------------------------------------------------------
 * Editorial + product body: paint the base colour and sit above the pinned
 * hero.
 *
 * FreelancerHero (index-freelancer-portfolio) uses PinnedSection + GSAP
 * ScrollTrigger to pin the hero-09 video while the page scrolls, then
 * releases. In Azurio's own layout the section that follows (About) has
 * `.bg-color-base` painted on the section, so the prose visibly covers
 * the hero once the pin is released. Our editorial/product bodies were
 * transparent, letting the pinned hero content bleed through the prose.
 *
 * Applying background-color + a positive z-index to the wrappers gives
 * exactly the About behaviour: the prose scrolls up and cleanly paints
 * over the receding hero — same GSAP transition, no overlap.
 * ------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------
 * Section-manifest block (About-under-hero intro): full container width and
 * smaller responsive text.
 *
 * The block was originally shown right at the freelancer-portfolio home
 * page, where the Alex Walker manifesto is short. Editorial pages push a
 * whole hero-body paragraph into it, so the template's default sizing
 * looked oversized on desktop and the max-width cap left an awkward gutter.
 *
 * Overrides:
 * - Manifest text: fluid font size via clamp — ~2.2rem on mobile scaling
 *   up to ~3.6rem on wide desktop. Much calmer than the template's 4.8rem
 *   / 6.6rem defaults.
 * - Line height: 1.35 so a longer paragraph is comfortable to read.
 * - Width: remove the max-width cap so the block fills the container
 *   (`col-12` is already full width; the cap was on the text child).
 * ------------------------------------------------------------------------- */
.mxd-section-manifest__text.manifest-text-m {
  max-width: 100%;
}
.mxd-section-manifest__text .manifest.manifest-m {
  font-size: clamp(1.6rem, 2.4vw, 3.2rem) !important;
  line-height: 1.35 !important;
  letter-spacing: -0.02rem;
}

/* -------------------------------------------------------------------------
 * Freelancer hero H1: length-aware fluid size + wrap.
 *
 * The template hard-codes `white-space: nowrap` and a container-query
 * font-size (`clamp(1.6rem, 13cqw, 27rem)`) on `.mxd-hero-09__headline h1`
 * because Azurio's demo only ever showed the 11-char string "Alex Walker".
 * APANI titles run from 5 chars ("Qeviko") up to 46 chars ("77 Years of
 * Concentrated Audiophile Experience") — a fixed cqw scale that flatters
 * "Qeviko" overflows the viewport both horizontally AND vertically on any
 * long title.
 *
 * The fix is a two-pronged formula. The `--title-length` CSS variable
 * (set on the wrapping div in Hero.tsx) carries the character count of
 * whatever headline was passed in. We `min()` the template's original
 * clamp against `140cqw / --title-length` — the second term is
 * proportional to available width per character, so the more characters
 * a title has, the smaller each one gets rendered. The 140 constant
 * leaves ~15% side breathing room on all-caps text (uppercase glyphs are
 * roughly 0.55em wide in the display face). Wrap stays on as a safety
 * net for the rare edge case that still doesn't fit on one line — the
 * GSAP character-in animation is line-agnostic so wrapping is harmless.
 * ------------------------------------------------------------------------- */
.mxd-hero-09__headline {
  padding-inline: clamp(16px, 3vw, 48px);
}
.mxd-hero-09__headline h1 {
  white-space: normal !important;
  overflow-wrap: break-word;
  word-break: normal;
  max-width: 100%;
  /* The nested max() enforces a readability floor: no matter how long
     the title is, the H1 never drops below 32px. A 46-char title at 32px
     wraps to two lines on mobile — still fully in-frame vertically and
     far more legible than a squeezed single-line 12px. */
  font-size: min(
    clamp(1.6rem, 13cqw, 27rem),
    max(32px, calc(140cqw / var(--title-length, 15)))
  ) !important;
  line-height: 1.05;
}
@media (min-width: 1200px) {
  .mxd-hero-09__headline h1 {
    /* The template swaps to `14cqw` at ≥1200px — mirror it here so the
       length-aware formula uses the same peak scale. */
    font-size: min(
      clamp(1.6rem, 14cqw, 27rem),
      max(48px, calc(140cqw / var(--title-length, 15)))
    ) !important;
  }
}

/* Editorial + product + section-landing bodies (freelancer-hero based) —
   paint the base and layer above the pinned hero. */
.apani-page--editorial,
.apani-page--product,
.apani-page--section-landing {
  position: relative;
  z-index: 2;
  background-color: var(--base);
}

/* Explicit Explore / Entdecken link under each section-landing stack card. */
.mxd-stack-services .services-card__cta {
  margin-top: 1.5rem;
}
.mxd-stack-services .services-card__cta .btn {
  display: inline-flex;
}
/* Vertical breathing room between the last prose section (or spec table /
   enquire block on product pages) and whatever the next composition block
   is — DividerStickyImages on editorial, ProjectsList on product. Without
   this, the prose runs straight into the divider image. */
.apani-page--editorial,
.apani-page--product {
  padding-bottom: clamp(4rem, 8vw, 9rem);
}
/* Contact + Enquire (Azurio /contact composition). Their outer wrapper is
   `.mxd-page-content.inner-page-content` — paint the base so nested accent /
   opposite sections sit on a solid page, matching editorial/product bodies.
   Do NOT raise z-index here: these pages have no pinned hero beneath them,
   and a positive z-index would cover the absolute `.mxd-header` logo
   (header is z-index: 1 in main.css). */
.mxd-page-content.inner-page-content {
  position: relative;
  background-color: var(--base);
}

/* -------------------------------------------------------------------------
 * Editorial prose — .apani-prose sections.
 *
 * The template ships no rhythm for a long-form article: eyebrow, heading,
 * paragraphs and ordered lists collapse onto each other and the mobile view
 * runs edge-to-edge. Rules below give the ProseSection block a proper
 * editorial cadence — comfortable container padding on every viewport,
 * generous vertical rhythm between elements, a constrained reading
 * measure, and a real ordered-list style with visible markers.
 *
 * Applies to every apani editorial + product page since the ProseSection
 * component is shared across the whole [locale]/[...slug] catch-all.
 * ------------------------------------------------------------------------- */
/*  NOTE — the site's `html { font-size: 62.5% }` makes `1rem = 10px`, so
    prose sizes below use `px` for absolute type scale and `em` for the
    surrounding rhythm. Do NOT switch these to rem: the reader-facing
    typography must not shrink with the template's root font hack. */
.apani-prose {
  padding-block: clamp(36px, 4.5vw, 72px);
}
/* Consecutive prose blocks collapse the seam so the article reads as one
   continuous document, not a stack of boxes. */
.apani-prose + .apani-prose {
  padding-top: 0;
}
/* Every prose block gets real horizontal breathing room. Bootstrap's
   default `.container-xxl` gutter can be flattened to zero by the template
   on some breakpoints; re-establish it explicitly so mobile never runs
   edge-to-edge. */
.apani-prose > .container-xxl {
  padding-inline: clamp(20px, 4vw, 40px);
}
/* Eyebrow (small caps label above the heading). */
.apani-eyebrow {
  display: inline-block;
  font-size: clamp(11px, 0.9vw, 13px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 clamp(16px, 1.6vw, 24px);
  opacity: 0.6;
}
/* Section headings. Fluid scale keeps them balanced with the H1 on every
   viewport without a viewport query. */
.apani-h2 {
  font-size: clamp(28px, 3.4vw, 48px);
  line-height: 1.14;
  letter-spacing: -0.01em;
  color: var(--t-bright, currentColor);
  margin: clamp(36px, 4vw, 56px) 0 clamp(16px, 1.8vw, 24px);
}
/* When the eyebrow sits directly above an H2 keep them tight — the
   eyebrow's margin-bottom is the visual gap. */
.apani-eyebrow + .apani-h2 {
  margin-top: 0;
}
/* The first heading of a prose block already has section top padding
   above it — kill its own top margin so we don't double up. */
.apani-prose > .container-xxl .row > * > :first-child.apani-h2,
.apani-prose > .container-xxl .row > * > .apani-lead > :first-child.apani-h2 {
  margin-top: 0;
}
/* Paragraphs — fluid body size, comfortable line-height, real trailing
   space between them. */
.apani-prose p {
  font-size: clamp(16px, 1.2vw, 18px);
  line-height: 1.65;
  margin: 0 0 1.15em;
}
.apani-prose p:last-child {
  margin-bottom: 0;
}
/* Lead layout — the first section of every editorial page. Slightly
   heavier body scale so it reads as the article's opening statement. */
.apani-prose--lead .apani-lead p,
.apani-prose--lead p {
  font-size: clamp(18px, 1.5vw, 22px);
  line-height: 1.55;
}
/* Lists — the twelve-part outline, the four-question checklist, the
   step-by-step. Rendered as an unordered bulleted list even though the
   markup is <ol>, because APANI's editorial voice reads as a set of
   ideas, not a numbered enumeration. */
.apani-prose .apani-ol {
  padding-left: 1.4em;
  margin: clamp(16px, 1.6vw, 24px) 0 clamp(20px, 2vw, 28px);
  list-style: disc;
}
.apani-prose .apani-ol-item {
  padding-left: 0.35em;
  margin-bottom: 0.7em;
  line-height: 1.6;
  font-size: clamp(16px, 1.2vw, 18px);
}
.apani-prose .apani-ol-item:last-child {
  margin-bottom: 0;
}
.apani-prose .apani-ol-item::marker {
  color: var(--accent, currentColor);
  font-weight: 600;
}
/* Emphasis / attribution inline spans — keep them semantically distinct
   without shouting. */
.apani-prose em,
.apani-prose i {
  font-style: italic;
  opacity: 0.85;
}
.apani-prose strong,
.apani-prose b {
  color: var(--t-bright, currentColor);
  font-weight: 600;
}
/* Attribution glyph — the ProseSection wraps citations in .apani-attr,
   render it as an en-dash + name in a subdued weight. */
.apani-prose .apani-attr {
  display: inline;
  opacity: 0.8;
}
.apani-prose .apani-attr::before {
  content: " — ";
  white-space: nowrap;
}
/* Split-layout image column — keep the picture from running to the edge
   on mobile the same way the prose does. */
.apani-prose--split img {
  width: 100%;
  height: auto;
  border-radius: 4px;
}

/* -------------------------------------------------------------------------
 * Downloads block — /en/downloads and /de/downloads.
 *
 * Uses only the APANI system tokens (--base, --t-bright, --accent), the
 * same `.container-xxl` gutters as prose, and the template's `.btn.btn-line`
 * shape for the action buttons. No new colours, no new fonts. The block
 * sits directly under the pinned FreelancerHero and above the shared
 * footer; the .apani-downloads section paints the base backdrop and
 * elevates above the pinned hero (same z-index trick as the editorial
 * pages).
 * ------------------------------------------------------------------------- */
.apani-downloads {
  position: relative;
  z-index: 2;
  background-color: var(--base);
  padding-block: clamp(48px, 8vw, 120px);
  color: var(--t-bright, currentColor);
}
.apani-downloads > .container-xxl {
  padding-inline: clamp(20px, 4vw, 40px);
}
.apani-downloads__head {
  max-width: 720px;
  margin-bottom: clamp(40px, 6vw, 80px);
}
.apani-downloads__eyebrow {
  display: inline-block;
  font-size: clamp(11px, 0.9vw, 13px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: clamp(16px, 1.6vw, 24px);
  opacity: 0.6;
}
.apani-downloads__title {
  margin: 0 0 clamp(16px, 1.8vw, 24px);
}
.apani-downloads__intro {
  font-size: clamp(16px, 1.2vw, 18px);
  line-height: 1.6;
  margin: 0;
  opacity: 0.85;
}
/* Screen-reader-only. Local rather than Bootstrap's .visually-hidden so
   the downloads block does not depend on utility classes loading. */
.apani-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* -------------------------------------------------------------------------
 * Language filter.
 *
 * Button + listbox rather than a native <select>, which cannot be styled
 * consistently across browsers. Shape and type follow the same system as
 * the rest of the block: 6px radius, the 12% ink hairline, the uppercase
 * micro-label from the eyebrow.
 * ------------------------------------------------------------------------- */
.apani-downloads__toolbar {
  margin-bottom: clamp(28px, 3.5vw, 44px);
}
.apani-filter {
  display: flex;
  flex-direction: column;
  gap: clamp(8px, 0.9vw, 11px);
  /* Full width on small screens, a comfortable measure from tablet up. */
  width: 100%;
  max-width: 320px;
}
.apani-filter__label {
  font-size: clamp(11px, 0.9vw, 13px);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.6;
}
.apani-filter__control {
  position: relative;
}
.apani-filter__button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 48px;
  padding: 10px 16px;
  border: 1px solid rgba(18, 18, 18, 0.22);
  border-radius: 6px;
  background-color: transparent;
  color: var(--t-bright, currentColor);
  font-size: clamp(14px, 1vw, 16px);
  text-align: left;
  cursor: pointer;
  transition:
    border-color 200ms ease,
    background-color 200ms ease;
}
.apani-filter__button:hover {
  border-color: rgba(18, 18, 18, 0.44);
  background-color: rgba(18, 18, 18, 0.02);
}
.apani-filter__button[aria-expanded="true"] {
  border-color: rgba(18, 18, 18, 0.55);
}
.apani-filter__value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.apani-filter__chevron {
  display: inline-flex;
  flex: 0 0 auto;
  transition: transform 220ms ease;
}
.apani-filter__chevron.is-open {
  transform: rotate(180deg);
}
.apani-filter__list {
  position: absolute;
  z-index: 6;
  inset-inline: 0;
  top: calc(100% + 6px);
  margin: 0;
  padding: 5px;
  list-style: none;
  /* Opaque: the list overlaps card content when open. */
  background-color: var(--base, #ffffff);
  border: 1px solid rgba(18, 18, 18, 0.22);
  border-radius: 6px;
  box-shadow: 0 18px 44px rgba(18, 18, 18, 0.14);
  /* Never taller than the viewport allows; scrolls past that. */
  max-height: min(320px, 50vh);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.apani-filter__list:focus {
  outline: none;
}
.apani-filter__option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  min-height: 42px;
  padding: 9px 12px;
  border-radius: 4px;
  font-size: clamp(14px, 1vw, 16px);
  cursor: pointer;
}
.apani-filter__option.is-active {
  background-color: rgba(18, 18, 18, 0.06);
}
.apani-filter__option.is-selected {
  font-weight: 600;
}
.apani-filter__option-check {
  display: inline-flex;
  flex: 0 0 auto;
  opacity: 0.7;
}

/* One column per language on mobile, two on tablet+, three on wide
   desktop — comfortable card grid without shrinking rows. */
.apani-downloads__groups {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 4vw, 48px);
  /* Cards hug their content. Language groups hold between one and four
     products, so the default `stretch` would leave a tall void under
     Swedish and Chinese to match German in the same row. */
  align-items: start;
}
@media (min-width: 768px) {
  .apani-downloads__groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1440px) {
  .apani-downloads__groups {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
/* A single language selected: the card takes the full measure and its
   products flow into columns, so one card never sits alone in a third of
   an empty row. Declared after the breakpoints above so it overrides
   them at every width without needing extra specificity. */
.apani-downloads__groups--single {
  grid-template-columns: minmax(0, 1fr);
}
@media (min-width: 768px) {
  .apani-downloads__groups--single .apani-downloads__products {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(24px, 2.6vw, 34px);
    align-items: start;
  }
}
@media (min-width: 1200px) {
  .apani-downloads__groups--single .apani-downloads__products {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.apani-downloads__group {
  border: 1px solid rgba(18, 18, 18, 0.12);
  border-radius: 6px;
  padding: clamp(20px, 2.5vw, 32px);
  background-color: rgba(18, 18, 18, 0.02);
  transition:
    border-color 220ms ease,
    background-color 220ms ease;
}
.apani-downloads__group:hover {
  border-color: rgba(18, 18, 18, 0.22);
}
.apani-downloads__group-heading {
  font-size: clamp(18px, 1.5vw, 22px);
  line-height: 1.15;
  letter-spacing: -0.005em;
  margin: 0 0 clamp(16px, 1.8vw, 24px);
  padding-bottom: clamp(10px, 1.2vw, 16px);
  border-bottom: 1px solid rgba(18, 18, 18, 0.12);
  color: var(--t-bright, currentColor);
}
/* Product blocks inside a language card: cover thumbnail beside the
   product name and its link rows. Separated a little more generously
   than the rows within a block, so the eye groups by product. */
.apani-downloads__products {
  display: flex;
  flex-direction: column;
  gap: clamp(22px, 2.4vw, 30px);
}
.apani-download-product {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: clamp(14px, 1.6vw, 20px);
}
.apani-download-product__thumb-link {
  display: block;
  flex: 0 0 auto;
  line-height: 0;
}
.apani-download-product__thumb {
  display: block;
  /* height:auto is load-bearing — next/image emits width/height attrs,
     which are presentational hints that would otherwise pin the box to
     the intrinsic 509px. */
  width: clamp(64px, 6vw, 84px);
  height: auto;
  aspect-ratio: 693 / 980;
  object-fit: contain;
  border-radius: 4px;
  border: 1px solid rgba(18, 18, 18, 0.1);
  background-color: rgba(18, 18, 18, 0.03);
  transition:
    transform 200ms ease,
    opacity 200ms ease;
}
.apani-download-product__thumb-link:hover .apani-download-product__thumb {
  opacity: 0.88;
  transform: translateY(-1px);
}
.apani-download-product__meta {
  min-width: 0;
}
.apani-download-product__title {
  font-size: clamp(15px, 1.05vw, 17px);
  line-height: 1.35;
  margin: 0 0 clamp(10px, 1.1vw, 14px);
  color: var(--t-bright, currentColor);
  word-break: break-word;
}
.apani-downloads__rows {
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.1vw, 14px);
}
.apani-download-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
}
.apani-download-row__kind {
  font-size: clamp(12px, 0.85vw, 13px);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.55;
  min-width: 0;
}
.apani-download-row__cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  /* Shrinkable, not fixed: "Open document" fits on one line, "Ouvrir le
     document" and "Apri il documento" do not, and a `0 0 auto` button with a
     nowrap caption pushed the page 6-23px wide in fr/it/cs/sv. */
  flex: 0 1 auto;
  max-width: 100%;
  min-height: 40px;
  padding-block: 6px;
  padding-inline: 14px;
}
/* The template pins `.btn-line span` to nowrap; here the caption may wrap,
   which only ever happens in the languages that need it. */
.apani-download-row__cta .btn-caption {
  white-space: normal;
  text-align: left;
}
.apani-download-row__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: transform 200ms ease;
}
.apani-download-row__cta:hover .apani-download-row__icon {
  transform: translateY(1px);
}
@media (max-width: 480px) {
  .apani-download-product {
    gap: 14px;
  }
  .apani-download-product__thumb {
    width: 60px;
  }
  .apani-download-row {
    align-items: stretch;
  }
  .apani-download-row__kind {
    flex: 1 1 100%;
  }
  .apani-download-row__cta {
    flex: 1 1 100%;
    justify-content: center;
    text-align: center;
  }
  .apani-download-row__cta .btn-caption {
    text-align: center;
  }
}

/* -------------------------------------------------------------------------
 * Menu overlay — mobile / tablet tweak (< 1200px).
 *
 * Give the section labels room for descenders. The template only sets the
 * padding-bottom/margin-bottom "descender well" trick on line-mask at
 * ≥1200px, so "g" in Technology / Philosophy / etc. is clipped on mobile
 * and tablet. Same technique below 1200px, sized for the smaller font.
 * ------------------------------------------------------------------------- */
@media (max-width: 1199.98px) {
  .main-menu__link .line-mask {
    padding-bottom: 6px;
    margin-bottom: -6px;
  }
}

/* -------------------------------------------------------------------------
 * CTA background overlay — subtle black scrim.
 *
 * The freelancer CTA (product/editorial pages) ships a blue accent cover
 * over its background video. APANI just wants a light black wash so the
 * white text stays legible over the video. Override the vendor
 * `.mxd-background__cover.accent` gradient in place.
 * ------------------------------------------------------------------------- */
.mxd-background__cover.accent {
  background: rgba(0, 0, 0, 0.25);
}

/* -------------------------------------------------------------------------
 * CTA heading — reveal the descender on "listening".
 *
 * The promo caption h2 ("Let's talk about listening") uses the vendor 1.1
 * line-height, and the splitLines animation wraps each line in a GSAP
 * SplitText mask (overflow: clip) sized to that tight line box — so the
 * tail of "g" (and any y / p / q / j) is clipped at the bottom.
 *
 * Fix the container clipping, not the type: give each line a small
 * "descender well" — padding-bottom to extend the masked/clipped area
 * downward, cancelled by an equal negative margin-bottom so the line
 * position, inter-line spacing, font size and section height are all
 * unchanged. em units keep it correct across desktop / tablet / mobile.
 * Same technique already used for the menu labels above.
 * ------------------------------------------------------------------------- */
.mxd-promo__caption .mxd-split-lines .line {
  padding-bottom: 0.16em;
  margin-bottom: -0.16em;
}

/* ==================================================================
   Fixed header chrome — APANI Life + language switcher
   ------------------------------------------------------------------
   These two used to sit in `.mxd-header__controls`, the header's own
   right-edge slot. The template hides the header as soon as the page
   scrolls (`useHeaderScrollHidden`), which took them with it and left
   the burger alone on screen. They now live in the same fixed layer as
   the burger, immediately to its left.

   The geometry is derived from the burger rather than duplicated: the
   hamburger is 5.5rem wide and `.mxd-menu__contain` is inset by
   `--apani-burger-inset` (the same value the rule further down gives it),
   so `right = inset + hamburger + gap` puts this rail exactly where it
   sat before, at the same top and the same optical baseline.

   Scrolling past the header fades in a frosted surface. The burger can
   stay legible over anything with `mix-blend-mode: difference`; that
   would invert the flag emoji, so this rail earns its contrast from a
   backdrop instead — invisible over the light sections that make up most
   of the site, and enough to carry the text over dark photography. At the
   top of the page there is no surface at all, so the composition that was
   signed off is untouched.
   ================================================================== */
.apani-chrome {
  --apani-burger-inset: min(3rem, calc(100vw - 35.5rem));
  --apani-chrome-gap: 1.4rem;
  --apani-chrome-pad: 0rem;
  --apani-control: var(--t-medium);
  --apani-control-strong: var(--t-bright);

  position: fixed;
  top: 3rem;
  right: calc(
    var(--apani-burger-inset) + 5.5rem + var(--apani-chrome-gap) +
      var(--apani-chrome-pad)
  );
  z-index: 10; /* below the menu overlay (11) and the burger (12) */
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 1rem;
  height: 3.6rem;
  padding-inline: var(--apani-chrome-pad);
  border-radius: 999px;
  background-color: transparent;
  transition:
    background-color var(--_animspeed-medium) var(--_animbezier),
    box-shadow var(--_animspeed-medium) var(--_animbezier),
    padding-inline var(--_animspeed-medium) var(--_animbezier),
    right var(--_animspeed-medium) var(--_animbezier);
}
@media (max-width: 399px) {
  .apani-chrome {
    gap: 0.6rem;
  }
}
@media (min-width: 768px) {
  .apani-chrome {
    --apani-burger-inset: 6rem;
    --apani-chrome-gap: 3.5rem;
    gap: 1.6rem;
    height: 4rem;
  }
}
@media (min-width: 1400px) {
  .apani-chrome {
    gap: 2rem;
  }
}
@media (min-width: 1600px) {
  .apani-chrome {
    --apani-burger-inset: 10rem;
  }
}

/* Over a dark hero, until the page scrolls: the same white the header's
   own `.mxd-header-permanent` rule gives the logo. */
.apani-chrome--over-hero:not(.is-scrolled) {
  --apani-control: rgba(255, 255, 255, 0.66);
  --apani-control-strong: var(--nl-white);
}

/* Scrolled: the frosted surface, and back to the page's own text pair —
   the panel is light in both contexts, so white would disappear into it. */
.apani-chrome.is-scrolled {
  --apani-chrome-pad: 1.2rem;
  --apani-control: var(--t-medium);
  --apani-control-strong: var(--t-bright);
  background-color: rgba(249, 247, 247, 0.72);
  -webkit-backdrop-filter: blur(1.2rem) saturate(140%);
  backdrop-filter: blur(1.2rem) saturate(140%);
  box-shadow: 0 0.2rem 1.6rem rgba(18, 18, 18, 0.12);
}
@media (prefers-reduced-motion: reduce) {
  .apani-chrome {
    transition: none;
  }
}

/* Below ~386px the burger stops staying out of the way. It is `position:
   fixed` at `right: 3rem`, so it tracks the viewport; the header sits in the
   document, which the template never lets get narrower than
   `body { min-width: 360px }`. From ~386px up the two meet with a 14px gap —
   at 375px the hamburger's lines touch the language code, at 360px they
   cross it, and on a 320px screen the document scrolls while the burger does
   not.

   `min()` gives back the missing millimetres continuously rather than at a
   breakpoint: the inset stays 3rem while there is room for it and then
   shrinks 1px per lost pixel, keeping a ~10px gap. Below 360px the term goes
   negative, which parks the burger at the position it holds in the 360px
   min-width document. `--apani-burger-inset` above mirrors this value, so
   the rail follows the burger wherever it lands. Nothing moves at 768px and
   above, where the template's own 6rem/10rem insets rule.
   ------------------------------------------------------------------------ */
@media (max-width: 767px) {
  .mxd-menu__contain {
    right: min(3rem, calc(100vw - 35.5rem));
  }
}

/* Shared micro-typography for both controls: the template's accent mono,
   uppercase, matching `.btn-caption` in spirit but sized for the corner. */
.apani-header__link,
.apani-lang__toggle,
.apani-lang__option {
  font-family: var(--_font-accent);
  font-weight: 700;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: -0.02rem;
  text-transform: uppercase;
  white-space: nowrap;
}
@media (min-width: 480px) {
  .apani-header__link,
  .apani-lang__toggle,
  .apani-lang__option {
    font-size: 1.1rem;
  }
}
@media (min-width: 992px) {
  .apani-header__link,
  .apani-lang__toggle,
  .apani-lang__option {
    font-size: 1.3rem;
    letter-spacing: -0.03rem;
  }
}

/* These two get their own hover language, on purpose different from the
   site's gold accent: they are chrome sitting beside the burger, not content
   links, so they rest in grey and answer a pointer by coming up to full
   contrast and growing a touch. `transform` does not reflow, so the 6% never
   eats into the gaps measured down to 320px. The pair of custom properties
   above carries the colours, and the dark-hero / scrolled states re-point
   them.

   The selectors are deliberately over-qualified and the hover colour carries
   `!important`: the template colours links through `a:link` (0-1-1), which
   outweighs a bare class, and the site-wide moss hover a few hundred lines
   up is `!important` by design. This rail is the only place that opts out. */
.apani-chrome .apani-header__link,
.apani-chrome .apani-lang__toggle {
  color: var(--apani-control);
  transition:
    color var(--_animspeed-medium) var(--_animbezier),
    transform var(--_animspeed-medium) var(--_animbezier);
}
.apani-header__link {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}
.no-touch .apani-chrome .apani-header__link:hover,
.apani-chrome .apani-header__link:focus-visible,
.no-touch .apani-chrome .apani-lang .apani-lang__toggle:hover,
.apani-chrome .apani-lang .apani-lang__toggle:focus-visible,
.apani-chrome .apani-lang.is-open .apani-lang__toggle {
  color: var(--apani-control-strong) !important;
  transform: scale(1.06);
}
/* Respect a reduced-motion preference: the colour still answers, the size
   does not move. */
@media (prefers-reduced-motion: reduce) {
  .no-touch .apani-chrome .apani-header__link:hover,
  .apani-chrome .apani-header__link:focus-visible,
  .no-touch .apani-chrome .apani-lang .apani-lang__toggle:hover,
  .apani-chrome .apani-lang .apani-lang__toggle:focus-visible,
  .apani-chrome .apani-lang.is-open .apani-lang__toggle {
    transform: none;
  }
}

/* ---- Language switcher ---- */
.apani-lang {
  position: relative;
  display: inline-flex;
  align-items: center;
}

.apani-lang__toggle {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  transition: color var(--_animspeed-medium) var(--_animbezier);
}
.apani-lang__toggle:focus-visible,
.apani-lang__option:focus-visible {
  outline: 1px solid var(--accent);
  outline-offset: 3px;
}

/* Flags are emoji: give them their own optical size and stop the line box
   from growing with the taller glyph. */
.apani-lang__flag {
  font-size: 1.4rem;
  line-height: 1;
  font-family:
    "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
}
@media (min-width: 992px) {
  .apani-lang__flag {
    font-size: 1.6rem;
  }
}

.apani-lang__caret {
  flex: none;
  transition: transform var(--_animspeed-medium) var(--_animbezier);
}
.apani-lang.is-open .apani-lang__caret {
  transform: rotate(180deg);
}

.apani-lang__menu {
  position: absolute;
  top: calc(100% + 0.8rem);
  right: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  min-width: 100%;
  margin: 0;
  padding: 0.6rem;
  list-style: none;
  background-color: var(--base-tint);
  border: 1px solid var(--t-muted-extra);
  box-shadow: 0 1.2rem 3.2rem rgba(0, 0, 0, 0.16);
  /* Ten entries must stay reachable on a short phone in landscape. */
  max-height: min(60vh, 44rem);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.apani-lang__menu[hidden] {
  display: none;
}

.apani-lang__item {
  display: flex;
}

.apani-lang__menu .apani-lang__option {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.6rem 0.8rem;
  text-decoration: none;
  color: var(--t-medium);
  transition:
    color var(--_animspeed-medium) var(--_animbezier),
    background-color var(--_animspeed-medium) var(--_animbezier);
}
/* The panel keeps its own light background in both header contexts, so the
   options answer with the page's own text colour rather than the header's
   white-on-dark pair. */
.no-touch .apani-lang__menu .apani-lang__option:hover,
.apani-lang__menu .apani-lang__option:focus-visible {
  background-color: var(--base);
  color: var(--t-bright) !important;
}
.apani-lang__menu .apani-lang__option.is-current {
  color: var(--accent);
}

/* On the smallest phones the caret is the first thing to go: the flag and
   the code already say everything, and the 14px it frees is the difference
   between the trio fitting and the header wrapping. */
@media (max-width: 479px) {
  .apani-lang__caret {
    display: none;
  }
  .apani-lang__toggle {
    gap: 0.4rem;
  }
}

/* ---------------------------------------------------------------------------
   Long-language safety valve for the section-manifest eyebrow.

   The template pins `.btn-line span` to `white-space: nowrap`, which is right
   for the short captions it was drawn for. This one carries the page title,
   and titles run long outside English — "Privacy & Cookie Policy" fits at
   390px, "Datenschutzerklärung & Cookie-Richtlinie" and "Politique de
   confidentialité et de cookies" push the document 74–104px wide.

   Scoped to this one control so nothing else moves: the caption may wrap
   when it cannot fit, which changes nothing in any language where it already
   fits on one line.
--------------------------------------------------------------------------- */
.mxd-section-manifest__controls .btn-line {
  max-width: 100%;
}
.mxd-section-manifest__controls .btn-line span {
  white-space: normal;
}

/* ---------------------------------------------------------------------------
   Inner-page banner (InnerPageBanner) — persistent title over the Azurio
   `mxd-hero-04` scrolling slider.

   The slider itself needs no new CSS: `.mxd-hero-04*` already ships in
   main.css (it was authored for /index-web-studio) and the component reuses
   it verbatim. The only thing that did not exist in the template is a title
   that stays put while the slides travel, so this block does exactly one
   job: lift the title layer out of the slider's flow and reproduce the
   retired `mxd-hero-09` video-banner arrangement inside it.

   - `__overlay` is a non-interactive layer pinned over the whole banner, so
     the H1 cannot scroll away with an individual slide.
   - Below 1200px the template's hero-09 wrap is a plain column (the video
     section used to be `height: auto`), so it needs `space-between` to put
     the title block at the top and the scroll control at the bottom of the
     now fixed-height banner — the same positions the video banner produced.
     At ≥1200px main.css already absolute-centres `.mxd-hero-09__top` and
     right-aligns `.mxd-hero-09__bottom`, so nothing is overridden there.
   - Typography, colour, weight, wrap and the `--title-length` fluid-size
     formula all come from the existing `.mxd-hero-09__headline` rules.
   - The `z-index` here is load-bearing beyond stacking: it makes the overlay
     its own stacking context, so `.mxd-hero-09__top`'s `mix-blend-mode:
     difference` no longer blends the H1 into the artwork behind it. Over one
     controlled brand video that blend was flattering; over three high-contrast
     product photographs it drops the title to near-invisible grey on concrete
     and cyan on the red baffles. Solid white keeps the title readable through
     the whole scroll, which the banner brief requires.
--------------------------------------------------------------------------- */
.inner-page-banner__overlay {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
}
.inner-page-banner__overlay a {
  pointer-events: auto;
}
@media only screen and (max-width: 1199px) {
  .inner-page-banner__overlay .mxd-hero-09__wrap {
    justify-content: space-between;
  }
}

/* ---------------------------------------------------------------------------
   Art-directed images (ArtDirectedImage).

   `<picture>` exists only to let the browser choose between the landscape and
   portrait crops; it must not become a box of its own, or the `height: 100%`
   that `.mxd-hero-04__media img` and `.images__img` rely on would resolve
   against an auto-height inline wrapper instead of the sized parent and the
   images would collapse. `display: contents` removes the wrapper box and
   leaves the `<img>` parented exactly where the template CSS expects it, so
   not one existing image rule has to change.
--------------------------------------------------------------------------- */
.art-image {
  display: contents;
}

/* ---------------------------------------------------------------------------
   Inner-page banner: legibility vignette behind the persistent title.

   The banner ships one white H1 over whatever photograph the product happens
   to lead with, and the product photography is not tonally uniform: Qeviko
   opens on deep red, Auris V on a near-white studio collage. Measured against
   the brightest tenth of the area behind the title, white type sat at roughly
   3.1:1 on Qeviko but 1.0–1.5:1 on Auris V, Phase Zero, Iona and Cylindra —
   i.e. effectively invisible on four of the five pages.

   The template's own `.mxd-hero-04__cover` cannot fix this: it is a
   `soft-light` blend, which barely moves a white image, and it lives inside
   `__media` so it travels with each slide. This vignette instead sits on the
   slider itself — fixed, exactly where the title is — and only darkens the
   centre, so the framing and the edges of the artwork are left alone. It
   roughly doubles the worst-case contrast (Auris V 1.0 → 2.0, Phase Zero
   1.4 → 2.9, Iona 1.5 → 3.1, Cylindra 1.5 → 3.1, Qeviko 3.1 → 5.7).

   Tune the two alphas if the art direction changes; nothing else depends on
   them. Sits at z-index 2: above the slides, below the title overlay (3).
--------------------------------------------------------------------------- */
.inner-page-banner .mxd-hero-04__slider::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: radial-gradient(
    130% 60% at 50% 50%,
    rgba(0, 0, 0, 0.62) 0%,
    rgba(0, 0, 0, 0.42) 50%,
    rgba(0, 0, 0, 0) 82%
  );
}

/* ---------------------------------------------------------------------------
   Visual story slider (StorySlider) + fullscreen viewer.

   The slides are finished artwork with typography running to their edges, so
   the one rule that matters is that nothing ever crops them. That is why the
   image gets no fixed-height box: `width: 100%` + `height: auto` means the
   artwork sets its own height and the whole composition is on screen at every
   viewport, from 320px up. `aspect-ratio` reserves the space so the page does
   not jump while a slide loads.
--------------------------------------------------------------------------- */
.apani-story {
  position: relative;
  margin: 0 auto;
  padding: 0 clamp(16px, 3vw, 48px);
  max-width: 1280px;
}
.apani-story__swiper {
  width: 100%;
  overflow: hidden;
  border-radius: 8px;
  background-color: rgba(var(--nl-black-rgb), 0.04);
}
/* The slide is a button so it can be opened from the keyboard; it must carry
   none of a button's own chrome. */
.apani-story__zoom {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
  line-height: 0;
}
.apani-story__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1920 / 1358;
  object-fit: contain;
}
.apani-story__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 3vw, 2.4rem);
  margin-top: 1.6rem;
}
.apani-story__counter {
  margin: 0;
  min-width: 5.5rem;
  text-align: center;
  font-family: var(--_font-accent, inherit);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.08em;
  color: var(--t-medium, inherit);
}
/* `btn-line-permanent` paints its label white for the dark surfaces it was
   drawn for. These controls sit on the light page background, so the label
   has to be re-inked or it is white on white. */
.apani-story__btn {
  color: var(--t-bright);
  cursor: pointer;
}
.no-touch .apani-story__btn:hover {
  color: var(--accent);
}
.apani-story__btn.swiper-button-disabled {
  opacity: 0.35;
  pointer-events: none;
}
.apani-story__hint {
  margin: 0.8rem 0 0;
  text-align: center;
  font-size: 1.3rem;
  opacity: 0.6;
}
/* Announced to screen readers only — the visible counter is the fraction. */
.apani-story__sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.apani-lightbox {
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  background-color: rgba(0, 0, 0, 0.97);
  padding: clamp(8px, 2vw, 24px);
}
.apani-lightbox__swiper {
  flex: 1 1 auto;
  width: 100%;
  min-height: 0;
}
.apani-lightbox .swiper-zoom-container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.apani-lightbox .swiper-zoom-container img {
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.apani-lightbox__close {
  align-self: flex-end;
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  background: none;
  color: #fff;
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
}
.apani-lightbox__controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2rem;
  padding-top: 1.2rem;
  color: #fff;
}
.apani-lightbox__btn {
  width: 44px;
  height: 44px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 50%;
  background: none;
  color: #fff;
  font-size: 1.6rem;
  cursor: pointer;
}
.apani-lightbox__btn.swiper-button-disabled {
  opacity: 0.3;
}
.apani-lightbox__counter {
  margin: 0;
  min-width: 5.5rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: #fff;
}

/* Document CTA under an article intro, and the quiet closing clarification. */
.apani-doc-cta {
  display: flex;
  justify-content: center;
  padding: 0 clamp(16px, 3vw, 48px);
}
.apani-doc-cta__meta {
  margin-left: 0.8rem;
  opacity: 0.6;
}
.apani-article-note {
  margin: 3.2rem auto 0;
  padding: 0 clamp(16px, 3vw, 48px);
  max-width: 900px;
  font-size: 1.3rem;
  line-height: 1.6;
  text-align: center;
  opacity: 0.62;
}

/* ---------------------------------------------------------------------------
   Document CTA: let a long localised label wrap.

   The template pins `.btn-caption` to `white-space: nowrap`, which is right
   for the short captions it was drawn for. This one carries a whole
   sentence — "Vollständige Geschichte als PDF herunterladen" is 44
   characters — and on a 320px screen a single unbreakable line pushed the
   page wider than the viewport.
--------------------------------------------------------------------------- */
.apani-doc-cta .btn {
  max-width: 100%;
  text-align: center;
}
.apani-doc-cta .btn-caption {
  white-space: normal;
}
@media only screen and (max-width: 767px) {
  .apani-doc-cta__meta {
    display: block;
    margin-left: 0;
  }
}

/* Falling brand words in the CTA: a little smaller, so more of the video
   behind them stays visible. They are not rendered below 1200px at all. */
@media only screen and (min-width: 1200px) {
  .mxd-promo__objects .object {
    padding: 1.1rem 1.4rem;
  }
  .mxd-promo__objects .object p {
    font-size: 1.1rem;
  }
}

/* Email offered in place of the switched-off contact form. */
.apani-contact-direct {
  margin-top: 2.4rem;
}
.apani-contact-direct__lead {
  margin: 0 0 1.6rem;
}
.apani-contact-direct__cta {
  max-width: 100%;
}
.apani-contact-direct__cta .btn-caption {
  white-space: normal;
}

/* ---------------------------------------------------------------------------
   Cookie notice.

   A quiet bar at the foot of the window rather than a dialog over the page:
   nothing is blocked, the site stays readable while the visitor decides.
--------------------------------------------------------------------------- */
.apani-cookie {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 2vw, 2.4rem);
  padding: 1.6rem clamp(4.8rem, 6vw, 7rem) 1.6rem clamp(1.6rem, 3vw, 3rem);
  background-color: var(--base);
  border-top: 1px solid rgba(var(--nl-black-rgb), 0.12);
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.08);
}
.apani-cookie__text {
  margin: 0;
  flex: 1 1 28rem;
  max-width: 62rem;
  font-size: 1.4rem;
  line-height: 1.5;
}
.apani-cookie__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.2rem;
}
/* Same reason as the slider controls: the bar is a light surface, so the
   template's white label would be invisible. Accept carries the page ink,
   Decline the quieter body grey — readable on its own, clearly the
   secondary of the two. */
.apani-cookie__btn {
  color: var(--t-bright);
  cursor: pointer;
}
.apani-cookie__btn--quiet {
  color: var(--t-medium);
}
.no-touch .apani-cookie__btn:hover {
  color: var(--accent);
}
.apani-cookie__close {
  position: absolute;
  top: 50%;
  right: clamp(1.2rem, 2vw, 2.4rem);
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  border: 1px solid rgba(var(--nl-black-rgb), 0.2);
  border-radius: 50%;
  background: none;
  color: inherit;
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
}
@media only screen and (max-width: 767px) {
  .apani-cookie {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    padding-bottom: 2rem;
    gap: 1.4rem;
  }
  /* The row layout gives the paragraph a 28rem basis so it takes the space
     the buttons do not. Once the bar stacks, that basis is measured
     vertically and stretched the bar to a third of the screen — so on
     mobile the text is sized by its own content instead. */
  .apani-cookie__text {
    flex: 0 0 auto;
    max-width: 100%;
    padding-right: 3.2rem;
  }
  .apani-cookie__actions {
    width: 100%;
  }
  .apani-cookie__close {
    top: 1.2rem;
    transform: none;
  }
}
