/* ==========================================================================
   A-Projekt — extended motion & effects layer (paired with assets/js/fx.js)

   Loaded after style.css, so rules here intentionally win where they overlap.
   Everything is additive: without JS the page keeps the calm static design,
   and prefers-reduced-motion switches every effect below off (see the block at
   the end of the file).
   ========================================================================== */

:root {
  /* film grain used on the dark sections (hero, page hero, counters, footer) */
  --fx-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --fx-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---------- 1. Global polish ---------- */
::selection { background: var(--red); color: #fff; }

/* A visible, on-brand focus ring for keyboard users (mouse clicks keep the
   clean look thanks to :focus-visible). */
a:focus-visible, button:focus-visible, summary:focus-visible,
input:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 3px;
}

/* Brand-tinted scrollbar */
html { scrollbar-color: var(--red) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, var(--red-light), var(--red));
  border-radius: 6px; border: 2px solid var(--bg);
}
::-webkit-scrollbar-thumb:hover { background: var(--red); }

/* ---------- 2. Page enter / leave ---------- */
@keyframes fxPageIn { from { opacity: 0; } to { opacity: 1; } }
html.js body { animation: fxPageIn 0.45s ease both; }

/* Leaving veil: a dark panel wipes up from the bottom before the browser
   navigates, so page-to-page jumps read as one continuous motion. */
#fx-veil {
  position: fixed; inset: 0; z-index: 200; pointer-events: none;
  background: var(--dark);
  transform: scaleY(0); transform-origin: 50% 100%;
  will-change: transform;
}
#fx-veil::after {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: linear-gradient(90deg, var(--red), var(--red-light), var(--red));
}
#fx-veil.fx-veil-cover { animation: fxVeilCover 0.3s cubic-bezier(0.7, 0, 0.3, 1) forwards; }
@keyframes fxVeilCover { from { transform: scaleY(0); } to { transform: scaleY(1); } }

/* ---------- 3. Film grain + ambient light on the dark sections ---------- */
.hero::after, .page-hero .fx-grain, .counters .fx-grain {
  content: ''; position: absolute; inset: -80px; z-index: 1;
  pointer-events: none; opacity: 0.05;
  background-image: var(--fx-grain);
  animation: fxGrain 1.1s steps(4) infinite;
}
@keyframes fxGrain {
  0%   { transform: translate3d(0, 0, 0); }
  25%  { transform: translate3d(-24px, 12px, 0); }
  50%  { transform: translate3d(16px, -18px, 0); }
  75%  { transform: translate3d(-14px, -8px, 0); }
  100% { transform: translate3d(20px, 16px, 0); }
}

/* ---------- 4. Section headings: character-by-character rise ---------- */
.h2.fx-split { perspective: 700px; }
.h2 .fx-word { display: inline-block; white-space: nowrap; }
.h2 .fx-char { display: inline-block; }
html.js .h2.fx-split .fx-char { opacity: 0; }
html.js .h2.fx-split.fx-in .fx-char {
  animation: fxCharIn 0.6s var(--fx-ease) both;
  animation-delay: calc(var(--i, 0) * 24ms);
}
@keyframes fxCharIn {
  from { opacity: 0; transform: translateY(0.55em) rotateX(-62deg); }
  to   { opacity: 1; transform: none; }
}
/* the red underline keeps growing in, now driven by fx.js's own observer too */
.h2.fx-in::after { width: 56px; }

/* Kicker: small blinking caret while fx.js decodes the text */
.kicker.fx-decoding::after {
  content: ''; display: inline-block; width: 0.5em; height: 1em; margin-left: 4px;
  background: currentColor; vertical-align: -0.12em;
  animation: fxCaret 0.6s steps(2) infinite;
}
@keyframes fxCaret { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }

/* ---------- 5. Cards & tiles: extra hover choreography ---------- */
/* cooperation steps and policy cards join the tilt/spotlight family */
.cooperate-step, .policy-card { position: relative; overflow: hidden; }
.cooperate-step::after, .policy-card::after {
  content: ''; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  opacity: 0; transition: opacity 0.3s ease;
  background: radial-gradient(220px circle at var(--mx, 50%) var(--my, 50%),
              rgba(224, 90, 95, 0.16), transparent 60%);
  mix-blend-mode: soft-light;
}
.cooperate-step.tilt-active::after, .policy-card.tilt-active::after { opacity: 1; }
.cooperate-step, .policy-card {
  transition: border-color 0.25s ease, box-shadow 0.3s ease, transform 0.3s ease;
}
.cooperate-step:hover, .policy-card:hover {
  border-color: var(--red); border-top-color: var(--red);
  box-shadow: 0 14px 34px rgba(20, 22, 25, 0.1);
}
.cooperate-step .num, .policy-card .num { transition: letter-spacing 0.3s ease, color 0.3s ease; }
.cooperate-step:hover .num, .policy-card:hover .num { letter-spacing: 0.3em; color: var(--red); }

/* Project cards: the category line spreads out and the title slides slightly */
.project-card h3, .project-card .cats { transition: transform 0.35s var(--fx-ease), letter-spacing 0.35s ease; }
.project-card:hover h3 { transform: translateX(4px); }
.project-card:hover .cats { letter-spacing: 0.12em; }
/* thumbnail gets a slow red wash on hover */
.project-card .thumb { position: relative; }
.project-card .thumb::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(0deg, rgba(201, 37, 44, 0.32), transparent 55%);
  opacity: 0; transition: opacity 0.4s ease;
}
.project-card:hover .thumb::after { opacity: 1; }

/* Client tiles lift and lose their grayscale with a small spring */
.clients-set .client-tile {
  transition: border-color 0.25s ease, transform 0.35s var(--fx-ease), box-shadow 0.35s ease;
}
.clients-set .client-tile:hover {
  transform: translateY(-6px) scale(1.03);
  box-shadow: 0 16px 32px rgba(20, 22, 25, 0.14);
}

/* Reference cards: the scan lifts slightly out of the frame */
.ref-item img { transition: transform 0.45s var(--fx-ease), filter 0.45s ease; }
.ref-item:hover img { transform: scale(1.02); }
.ref-entity { transition: letter-spacing 0.3s ease; }
.ref-item:hover .ref-entity { letter-spacing: 0.14em; }

/* Benefit / job cards: the accent bar sweeps in a lighter tone */
.benefit-card .bar { background: linear-gradient(90deg, var(--red), var(--red-light)); }
.job-card h3 { transition: transform 0.35s var(--fx-ease); }
.job-card:hover h3 { transform: translateX(5px); }

/* Contact rows: the phone / e-mail links get a growing underline */
.contact-main .rows a, .site-footer .col-links a {
  position: relative; display: inline-block;
}
.contact-main .rows a::after, .site-footer .col-links a::after {
  content: ''; position: absolute; left: 0; bottom: -2px; height: 1px; width: 100%;
  background: currentColor; transform: scaleX(0); transform-origin: right;
  transition: transform 0.35s var(--fx-ease);
}
.contact-main .rows a:hover::after, .site-footer .col-links a:hover::after {
  transform: scaleX(1); transform-origin: left;
}
.site-footer .col-links a { transition: color 0.25s ease, transform 0.25s ease; }
.site-footer .col-links a:hover { transform: translateX(3px); }

/* Modal thumbnails zoom a touch under the pointer */
.modal-thumbs img { transition: border-color 0.2s ease, opacity 0.2s ease, transform 0.25s ease; }
.modal-thumbs img:hover { transform: translateY(-2px) scale(1.04); }

/* Open detail window: the page behind it blurs away */
.modal-backdrop { backdrop-filter: blur(0); transition: backdrop-filter 0.35s ease; }
.modal-backdrop.open { backdrop-filter: blur(4px); }

/* Language switcher + theme toggle micro-interactions */
.lang-switch a { position: relative; }
.lang-switch a:not(.active):hover { transform: translateY(-1px); }
.theme-toggle { transition: border-color 0.25s ease, color 0.25s ease, transform 0.45s var(--fx-ease); }
.theme-toggle:hover { transform: rotate(-25deg) scale(1.08); }
.theme-toggle:active { transform: scale(0.92); }

/* ---------- 6. Buttons: click ripple ---------- */
/* the ripple is appended inside the control, so every target needs a
   positioning context and a clip (.btn / .nl-btn / .filter-btn already have
   both; the absolutely-positioned window controls only need the clip) */
.theme-toggle, .modal-projnav-btn { position: relative; overflow: hidden; }
.modal-close, .lightbox-close, .modal-nav, .lightbox-nav, .hero-scroll { overflow: hidden; }
.fx-ripple {
  position: absolute; z-index: 1; border-radius: 50%; pointer-events: none;
  background: rgba(255, 255, 255, 0.45);
  transform: translate(-50%, -50%) scale(0);
  animation: fxRipple 0.65s ease-out forwards;
}
.fx-ripple--ink { background: rgba(201, 37, 44, 0.28); }
@keyframes fxRipple {
  to { transform: translate(-50%, -50%) scale(1); opacity: 0; }
}
/* the red hero/CTA buttons also glow while hovered */
.btn--red:hover, .btn--red-sm:hover, .nl-btn:hover {
  box-shadow: 0 10px 30px rgba(201, 37, 44, 0.35);
}
.btn, .nl-btn, .filter-btn { transition-property: background-color, border-color, color, box-shadow, transform; }

/* Filter buttons fill from the bottom on hover */
.filter-btn::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--red); transform: scaleY(0); transform-origin: bottom;
  transition: transform 0.3s var(--fx-ease);
}
.filter-btn:not(.active):hover { color: #fff; border-color: var(--red); }
.filter-btn:not(.active):hover::before { transform: scaleY(1); }
.filter-btn { isolation: isolate; }

/* ---------- 7. Hero extras ---------- */
/* vignette + a red glow along the bottom edge, so the slider sits deeper */
.hero::before {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(10, 12, 14, 0.55) 100%),
    linear-gradient(0deg, rgba(201, 37, 44, 0.22), transparent 28%);
}
/* slow light band drifting across the hero */
.hero-sheen {
  position: absolute; top: -25%; bottom: -25%; left: -30%; width: 26%;
  z-index: 1; pointer-events: none;
  background: linear-gradient(105deg, transparent, rgba(255, 255, 255, 0.07), transparent);
  transform: skewX(-16deg);
  animation: fxHeroSheen 11s ease-in-out infinite;
}
@keyframes fxHeroSheen {
  0%, 40% { left: -35%; }
  100% { left: 125%; }
}
/* the incoming slide also scales in a hair, on top of the Ken Burns drift */
.hero-slide { transition: opacity 1.2s ease, transform 1.4s var(--fx-ease); }
.hero-caption .word { will-change: transform, opacity; }

/* Subpage hero: a thin animated rule under the lead + drifting grid */
.page-hero .container::after {
  content: ''; display: block; width: 0; height: 2px; margin-top: 22px;
  background: linear-gradient(90deg, var(--red), transparent);
  animation: fxRuleGrow 1.1s var(--fx-ease) 0.5s forwards;
}
@keyframes fxRuleGrow { to { width: 160px; } }
.page-hero { background-image:
  linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px),
  linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 46px 46px, 46px 46px;
  animation: fxGridDrift 24s linear infinite;
}
@keyframes fxGridDrift { to { background-position: 46px 46px, 46px 46px; } }

/* ---------- 8. Counters ---------- */
.counters .container { position: relative; z-index: 2; }
/* blueprint grid slowly drifting behind the numbers */
.counters::before {
  content: ''; position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px);
  background-size: 54px 54px, 54px 54px;
  animation: fxGridDrift 30s linear infinite reverse;
  mask-image: radial-gradient(120% 90% at 50% 50%, #000 30%, transparent 78%);
  -webkit-mask-image: radial-gradient(120% 90% at 50% 50%, #000 30%, transparent 78%);
}
/* the finished number keeps a soft, slow pulse */
.counter-num.done {
  animation: counterPop 0.45s ease, fxCounterGlow 4.5s ease-in-out 0.5s infinite;
}
@keyframes fxCounterGlow {
  0%, 100% { filter: drop-shadow(0 8px 26px rgba(224, 90, 95, 0.35)); }
  50%      { filter: drop-shadow(0 8px 34px rgba(224, 90, 95, 0.65)); }
}
.counter { transition: transform 0.35s var(--fx-ease); }
.counter:hover { transform: translateY(-4px); }

/* ---------- 9. FAQ accordion ---------- */
.faq-answer { overflow: hidden; }
.faq-item summary { transition: color 0.25s ease, padding-left 0.3s var(--fx-ease); }
.faq-item summary:hover { color: var(--red); padding-left: 8px; }
.faq-item summary::after { transition: transform 0.3s var(--fx-ease), color 0.25s ease; }
.faq-item[open] summary::after { transform: rotate(180deg); }
.faq-item { transition: background-color 0.3s ease; }
.faq-item[open] { background: linear-gradient(90deg, rgba(201, 37, 44, 0.05), transparent 60%); }

/* ---------- 10. Footer ---------- */
.site-footer { position: relative; overflow: hidden; }
.site-footer::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; z-index: 2;
  background: linear-gradient(90deg, transparent, var(--red), var(--red-light), var(--red), transparent);
  background-size: 50% 100%;
  animation: fxFooterLine 9s linear infinite;
}
@keyframes fxFooterLine {
  from { background-position: -100% 0; }
  to   { background-position: 200% 0; }
}
.site-footer .cols, .site-footer .bottom { position: relative; z-index: 2; }
.nl-form input[type=email] { transition: border-color 0.25s ease, background-color 0.25s ease, box-shadow 0.25s ease; }
.nl-form input[type=email]:focus { box-shadow: 0 0 0 3px rgba(201, 37, 44, 0.2); }

/* ---------- 10b. Theme switch: the whole page crossfades ---------- */
html.fx-theming, html.fx-theming * {
  transition: background-color 0.45s ease, color 0.45s ease,
              border-color 0.45s ease, box-shadow 0.45s ease;
}

/* ---------- 12. Scroll UI ---------- */
/* progress bar gets a glow and a leading spark */
#scroll-progress {
  box-shadow: 0 0 14px rgba(201, 37, 44, 0.7);
  transition: width 0.1s linear;
}
#scroll-progress::after {
  content: ''; position: absolute; right: 0; top: -3px; width: 9px; height: 9px;
  border-radius: 50%; background: var(--red-light);
  box-shadow: 0 0 12px 3px rgba(224, 90, 95, 0.8);
  opacity: 0; transition: opacity 0.25s ease;
}
/* the spark only appears once there is progress to show */
#scroll-progress.fx-has-progress::after { opacity: 1; }

/* header slides away when scrolling down, returns on the way up */
.site-header { transition: box-shadow 0.3s ease, transform 0.4s var(--fx-ease); }
.site-header.fx-hidden { transform: translateY(-100%); }

/* back-to-top button: circular, wrapped in a live reading-progress ring */
#to-top { border-radius: 50%; }
#to-top::before {
  content: ''; position: absolute; inset: -6px; border-radius: 50%; pointer-events: none;
  background: conic-gradient(var(--red-light) calc(var(--fx-progress, 0) * 1%), rgba(255, 255, 255, 0.22) 0);
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
}
#to-top:hover { transform: translateY(-3px); }
#to-top.visible:hover { transform: translateY(-3px) scale(1.06); }

/* ---------- 13. Images: blur-up as they load ---------- */
img.fx-img {
  opacity: 0; filter: blur(14px); transform: scale(1.03);
  transition: opacity 0.7s ease, filter 0.7s ease, transform 0.7s var(--fx-ease);
}
img.fx-img.fx-loaded { opacity: 1; filter: none; transform: none; }

/* ---------- 14. Reduced motion: everything above stands still ---------- */
@media (prefers-reduced-motion: reduce) {
  html.js body { animation: none; opacity: 1; }
  #fx-veil { display: none; }
  .hero::after, .hero-sheen, .page-hero .fx-grain, .counters .fx-grain,
  .site-footer::before, .counters::before { animation: none; }
  .page-hero { animation: none; background-image: none; }
  .page-hero .container::after { animation: none; width: 160px; }
  html.js .h2.fx-split .fx-char { opacity: 1; animation: none; }
  .kicker.fx-decoding::after { display: none; }
  .counter-num.done { animation: none; }
  .fx-ripple { display: none; }
  .site-header.fx-hidden { transform: none; }
  img.fx-img { opacity: 1; filter: none; transform: none; }
  .cooperate-step::after, .policy-card::after { display: none; }
  .modal-backdrop.open { backdrop-filter: none; }
}
