/**
 * Global CSS that Oxygen's stylesheet importer cannot hold — non-breakpoint
 * media queries (@keyframes, prefers-reduced-motion) and site-wide resets.
 * Loaded from the ella-core mu-plugin.
 */

/* Split-word reveal unit (JS wraps heading words in these). */
.ella-w { display: inline-block; will-change: transform, opacity; }

/* Lenis smooth scroll */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* Reveal anti-flash: pre-hide reveal targets until GSAP takes over. A head
   script adds .ella-anim synchronously (and removes it after 3s as a failsafe,
   so content is never permanently hidden if JS fails). */
html.ella-anim #oxy-main :is(.c-eyebrow, .t-h0, .t-h1, .t-h2, .t-h3, .t-h4, .t-body-m, .t-body, .t-body-s, .c-keyfacts__item, .c-btn, .c-tags, .c-card__title, .c-card__tag, .c-media, .c-hero__frame) { opacity: 0; }

/* Projekt page layouts — by id, because Oxygen's selector system wouldn't
   apply the ella-ti/scatter/cols/figure classes on this page. */
#ella-ti-1, #ella-ti-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); align-items: start; }
/* Text column: even vertical rhythm so the body copy + CTA balance the tall
   image stack on the right (the html-to-page __body class was dropped). */
#ella-ti-1 > .oxy-container:first-child { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-5); }
#ella-ti-1 > .oxy-container:first-child > * { margin: 0; }
/* Vertrauen images side by side (Figma Frame 138: row); captions sit in a
   second grid row, each under its image. */
#ella-ti-1-media { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: var(--sp-5); row-gap: var(--sp-3); align-items: start; }
/* Nachhaltigkeit headline spans full width above the two columns (Figma). */
#ella-ti-2 > :first-child { grid-column: 1 / -1; margin-bottom: var(--sp-3); }
/* Wide text+list column left, narrow portrait image right (Figma Frame 167). */
#ella-ti-2 { grid-template-columns: minmax(0, 2.5fr) minmax(0, 1fr); gap: var(--sp-9); }
#ella-nh-left { display: flex; flex-direction: column; gap: var(--sp-9); }
/* Scatter gallery: rendered by the [ella_gallery] shortcode with inline
   position styles (Oxygen kept overriding class/id positioning). .ella-eg is a
   .c-rail so it inherits the horizontal scroll + drift + drag behaviour. */
.ella-eg__track > .c-media { position: absolute; }
#ella-cols-1 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); margin-top: var(--sp-6); }
/* Architektur "Foyer" block: image left + text right (Figma Group 101). */
#ella-figure-1 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--sp-8); align-items: center; margin-top: var(--section-y); }
#ella-figure-1 figcaption { max-width: 34ch; }
@media (max-width: 767px) {
  #ella-ti-1, #ella-ti-2, #ella-cols-1, #ella-figure-1 { grid-template-columns: minmax(0, 1fr); }
  #ella-figure-1 figcaption { max-width: none; }
}

/* Marquee keyframe (referenced by .c-marquee__track). Track holds two copies
   of the text, so -50% is one full loop. */
@keyframes ella-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Full-bleed image reveal: grows 20% -> 100% width as it scrolls through view,
   reaching full width at 70% of the pass. Scroll-driven (no JS).
   Section keeps a fixed height so the growth causes no layout shift.
   NOTE: longhands (not the `animation` shorthand) so animation-duration stays
   `auto` and fills the scroll range — the shorthand would reset it to 0s. */
@keyframes ella-imgfull-grow {
  from { width: 20%; }
  to   { width: 100%; }
}
/* No fixed section height — image keeps its natural aspect and grows in both
   dimensions as it scrolls in (page reflows slightly). aspect-ratio override is
   more specific than Oxygen's `.ella-imgfull__img { aspect-ratio: 21/9 }`. */
.ella-imgfull .ella-imgfull__img { aspect-ratio: auto; }
.ella-imgfull__img {
  height: auto;
  margin-inline: auto;
}
/* Native scroll-driven growth — only where the browser supports the scroll
   timeline (Chrome/Edge 115+, Safari 26+). */
@supports (animation-timeline: view()) {
  .ella-imgfull__img {
    animation-name: ella-imgfull-grow;
    animation-timing-function: linear;
    animation-fill-mode: both;
    animation-timeline: view();
    animation-range: cover 0% cover 50%;
  }
}
/* Fallback for browsers without scroll-driven animations (Safari <= 17):
   ella-scroll.js drives an identical 20% -> 100% width scrub via GSAP
   ScrollTrigger over the same scroll range. The image rests at full width so
   that no-JS and reduced-motion visitors see the correct full-bleed end state;
   the scrub sets its own inline width from the moment the script initialises. */
@supports not (animation-timeline: view()) {
  .ella-imgfull__img { width: 100%; }
}

/* Shared scroll-reveal starting state — JS adds .is-inview to animate in. */
.js-reveal { opacity: 0; transform: translateY(1.5rem); transition: opacity 600ms cubic-bezier(.22,.61,.36,1), transform 600ms cubic-bezier(.22,.61,.36,1); }
.js-reveal.is-inview { opacity: 1; transform: none; }

/* Anchor offset so in-page jumps clear the sticky header. */
:target { scroll-margin-top: 5rem; }

::selection { background: var(--ella-neon); color: var(--ella-aubergine); }

/* ===== Kontakt form (rendered by [ella_kontaktformular]) =====
   Native HTML form (no builder element exists), styled to the Figma spec.
   Real radio/checkbox inputs are kept and restyled with appearance:none so
   they stay focusable and accessible (never display:none). */
.ko-form { display: flex; flex-direction: column; gap: 2.375rem; }
/* Figma: every text field is full width, stacked one per row (no 2-up grid). */
.ko-form__row { display: flex; flex-direction: column; gap: 2.375rem; }

/* Field wrapper: text inputs put the input first in DOM so the label renders
   below it (Figma); the Anmerkungen field puts its label first, so it sits
   above. Column layout + DOM order drives both, no per-field overrides. */
.ko-field { display: flex; flex-direction: column; gap: 0.75rem; }
.ko-field > label { font-family: var(--font-sans); font-size: 1.25rem; color: var(--ella-aubergine); }
.ko-form input[type="text"],
.ko-form input[type="email"],
.ko-form input[type="tel"],
.ko-form textarea {
  width: 100%;
  background: var(--ella-white);
  border: 0;
  border-radius: 0;
  padding: 0 1rem;
  min-height: 3.875rem;
  font-family: var(--font-sans);
  font-weight: 400;
  font-size: 1.25rem;
  color: var(--ella-aubergine);
}
.ko-form textarea { min-height: 8.0625rem; padding: 1rem; resize: vertical; }
.ko-form input:focus-visible,
.ko-form textarea:focus-visible { outline: 2px solid var(--ella-neon); outline-offset: 0; }

/* Honeypot: present for bots, off-screen for humans. */
.ko-hp { position: absolute !important; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* Radio groups: question on the left, options stacked on the right (Figma).
   Flex, not grid: <legend> won't act as a grid item, so grid stacked them. */
.ko-fieldset { border: 0; margin: 0; padding: 0; display: flex; column-gap: 3.5rem; align-items: start; }
.ko-legend { flex: 0 0 15rem; margin: 0; padding: 0; font-family: var(--font-sans); font-size: 1.25rem; line-height: 1.35; color: var(--ella-aubergine); }
.ko-choices { flex: 1 1 auto; display: flex; flex-direction: column; gap: 1rem; }

.ko-choice, .ko-consent { display: inline-flex; align-items: center; gap: 1rem; cursor: pointer; font-family: var(--font-sans); font-size: 1.25rem; color: var(--ella-aubergine); }
.ko-consent { align-items: flex-start; }
.ko-choice__mark { display: none; } /* the restyled real input is the visible control */
/* Choice + consent controls are checkboxes (multi-select), styled round. */
.ko-choice input[type="checkbox"],
.ko-consent input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  flex: 0 0 auto; margin: 0;
  width: 1.375rem; height: 1.375rem;
  border: 1px solid var(--ella-red);
  border-radius: 50%;
  background: var(--ella-white);
  cursor: pointer;
}
.ko-consent input[type="checkbox"] { margin-top: 0.15rem; }
.ko-choice input[type="checkbox"]:checked,
.ko-consent input[type="checkbox"]:checked { background: var(--ella-red); box-shadow: inset 0 0 0 4px var(--ella-white); }
.ko-choice input:focus-visible,
.ko-consent input:focus-visible { outline: 2px solid var(--ella-neon); outline-offset: 2px; }
.ko-consent__text { font-size: 1.25rem; line-height: 1.35; }
.ko-consent__text a { color: inherit; text-decoration: underline; }

.ko-form__required { margin: 0; font-family: var(--font-sans); font-size: 1.25rem; color: var(--ella-aubergine); }
.ko-form__submit { align-self: flex-start; margin-top: 0.5rem; text-transform: uppercase; letter-spacing: 0.09em; }
.ko-form__note { margin: 0; padding: 0.75rem 1rem; font-family: var(--font-sans); font-size: 1rem; }
.ko-form__note--ok { background: var(--ella-red-50); color: var(--ella-aubergine); }
.ko-form__note--error { background: var(--ella-neon); color: var(--ella-offwhite); }

#oxy-main .ko-contact__link { color: var(--ella-aubergine); }

@media (max-width: 767px) {
  /* Stack the radio question above its options on small screens. */
  .ko-fieldset { grid-template-columns: 1fr; row-gap: 0.75rem; }
}

/* Big display headlines are roman in Figma (Newsreader 250 normal), not italic.
   Italic stays reserved for the wordmark and inline .ella-em emphasis. */
#oxy-main .t-h0 { font-style: normal; }

/* ===== Wohnungen — Figma alignment overrides ===== */
/* Hero strip: flush, portrait 344×536 (≈5:8). */
#oxy-main .wo-hero__strip { gap: 0; }
#oxy-main .wo-hero__cell { aspect-ratio: 344 / 536; }

/* Statement: Newsreader display ~40px uppercase (Figma), not General Sans. */
#oxy-main .wo-statement { font-family: var(--font-display); font-weight: 500; font-size: var(--fs-h2); line-height: 1.12; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ella-aubergine); max-width: 34ch; }

/* Wohnungstyp hero: wide 2.4:1 banner + bottom gradient so the white text reads. */
#oxy-main .wo-wt__hero::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; background: linear-gradient(to bottom, rgba(33,21,27,0) 45%, rgba(33,21,27,0.72) 100%); }
/* Numeral: General Sans, white, above the gradient. */
#oxy-main .wo-wt__num { z-index: 2; font-family: var(--font-sans); color: var(--ella-white); }
/* Tagline bottom-right: white uppercase General Sans, no pill. */
#oxy-main .wo-wt__chip { z-index: 2; left: auto; right: var(--gutter); bottom: var(--sp-5); max-width: 32ch; justify-content: flex-end; text-align: right; background: none; padding: 0; border-radius: 0; font-family: var(--font-sans); font-weight: 500; font-size: 1.375rem; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ella-white); }
/* Floorplan is the popup trigger now (button + zoom-circle removed). */
#oxy-main .wo-wt__plan, #oxy-main .wo-wt__plan-img { cursor: zoom-in; }

@media (min-width: 768px) {
  #oxy-main .wo-wt__hero { aspect-ratio: 1376 / 570; }
}
@media (min-width: 1024px) {
  #oxy-main .wo-wt__cols { grid-template-columns: minmax(0, 1.9fr) minmax(0, 1fr); }
}

/* On touch the base .c-rail sets `touch-action: pan-x`, which lets the browser
   pan the rail horizontally but *blocks* vertical gestures entirely — so a
   finger that lands on a rail can no longer scroll the page up/down (it just
   sticks). Re-allow vertical so a horizontal swipe still scrolls the rail while
   a vertical swipe passes through to the page. Doubled class (.c-rail.c-rail)
   so it outweighs Oxygen's base .c-rail regardless of stylesheet load order. */
.c-rail.c-rail { touch-action: pan-x pan-y; }

/* ===== Card slider (.c-rail with .c-rail__item) =====
   Behaviour is set up in ella-ui.js (setupSlider): paged prev/next arrows and
   the live count are generated at runtime, so this only holds the styling.
   .is-slider wins over the base .c-rail on specificity, order-independent. */
.c-rail.is-slider { scroll-snap-type: x proximity; scroll-behavior: smooth; }
.c-rail.is-slider.is-dragging { scroll-snap-type: none; scroll-behavior: auto; }
/* Snap each direct child (the .c-rail__item card when authored statically). */
.c-rail.is-slider > * { scroll-snap-align: start; }
/* CMS loop: Oxygen wraps the cards in .bde-post-loop > .bde-loop > .bde-loop-item.
   Collapse the two outer wrappers with display:contents so each .bde-loop-item
   becomes a direct grid column of the rail — the rail keeps doing the layout,
   scrolling and snapping exactly as with static cards. */
.c-rail .bde-post-loop,
.c-rail .bde-loop { display: contents !important; }
.c-rail .bde-loop-item { padding: 0; }
.c-rail.is-slider .bde-loop-item { scroll-snap-align: start; }
/* Everything fits — collapse to a static row; drop the right-bleed so the cards
   sit tidily in the container, and hide the (unneeded) arrows + progress. */
.c-rail.is-static { margin-right: 0; cursor: default; }
.c-rail__nav[hidden], .c-rail__progress[hidden] { display: none; }

/* Layout: arrows in a fixed box to the LEFT of the slides (Figma). The rail
   fills the rest of the row and still bleeds to the right edge. On mobile the
   box drops above the rail. */
.c-rail__row { display: flex; align-items: flex-start; gap: 2rem; }
.c-rail__row > .c-rail { flex: 1 1 0%; min-width: 0; margin-right: 0; }
.c-rail__nav {
  display: flex; flex: 0 0 auto; flex-wrap: nowrap; align-items: center; justify-content: flex-start;
  gap: 0.75rem; width: 6.25rem;
}
@media (max-width: 767px) {
  .c-rail__row { flex-direction: column; gap: 1.25rem; }
  .c-rail__nav { width: auto; }
  /* Column flex doesn't constrain the cross-axis width, so pin the rail to the
     row width — otherwise the grid grows to its content and never overflows. */
  .c-rail__row > .c-rail { width: 100%; }
}

/* Prev/next arrows — 44px ring, 1px --ella-red, red arrow glyph (two fit the
   6.25rem box side by side). Hover fills neon with an aubergine arrow. */
.c-rail__arrow {
  display: inline-grid; place-items: center; box-sizing: border-box;
  flex: 0 0 auto; width: 2.75rem; height: 2.75rem; padding: 0;
  color: var(--ella-red);
  background: transparent;
  border: 1px solid var(--ella-red);
  border-radius: var(--radius-circle);
  cursor: pointer;
  transition: background-color 200ms ease, color 200ms ease, border-color 200ms ease, opacity 200ms ease;
}
.c-rail__arrow svg { display: block; width: 1.1rem; height: auto; }
.c-rail__arrow--prev svg { transform: rotate(180deg); }
.c-rail__arrow:hover { color: var(--ella-aubergine); background: var(--ella-neon); border-color: var(--ella-neon); }
.c-rail__arrow:focus-visible { outline: 2px solid var(--ella-neon); outline-offset: 2px; }
.c-rail__arrow:disabled { opacity: 0.3; cursor: default; }
.c-rail__arrow:disabled:hover { color: var(--ella-red); background: transparent; border-color: var(--ella-red); }

/* Motion opt-out — genuinely disables everything, including marquee + reveals. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .js-reveal { opacity: 1 !important; transform: none !important; }
  .ella-imgfull__img { width: 100% !important; animation: none !important; }
}
