/*
 * Praxis Javadi — cinematic design layer.
 *
 * Dark, editorial surfaces with a single mint accent, derived from the
 * practice's own palette (deep green #10312A / green #1E7A5F / mint #6FD3AE)
 * rather than borrowed from any reference site.
 *
 * Sections:
 *   1. Tokens
 *   2. Motion primitives (paired with assets/js/motion.js)
 *   3. Surfaces and type
 *   4. Hero
 *   5. Cards and rails
 *   6. Mega menu
 *   7. Reduced motion
 */

/* ── 1. Tokens ───────────────────────────────────────────────────────────── */
:root {
    /* Surfaces, darkest to lightest */
    --jv-ink:        #061713;  /* cinematic base */
    --jv-ink-2:      #0B2620;  /* elevated dark surface */
    --jv-ink-3:      #10312A;  /* card on dark */
    --jv-paper:      #FCFBF8;  /* light section */
    --jv-paper-2:    #F4F1EA;  /* alternating light section */

    /* Type on dark */
    --jv-on-dark:      #F4F1EA;
    --jv-on-dark-soft: rgba(244, 241, 234, 0.68);
    --jv-on-dark-mute: rgba(244, 241, 234, 0.44);

    /* Type on light. Derived from the palette's own ink rather than fixed —
       none of the palettes redefined these, so every light section kept the
       original green text no matter which theme was picked. Palettes that
       state their own values still win, since they come later in the file. */
    --jv-on-light:      var(--jv-ink);
    --jv-on-light-soft: color-mix(in srgb, var(--jv-ink) 80%, var(--jv-paper));
    --jv-on-light-mute: color-mix(in srgb, var(--jv-ink) 58%, var(--jv-paper));

    /* The single accent */
    --jv-accent:      #6FD3AE;
    --jv-accent-deep: #1E7A5F;
    --jv-gold:        #C9962B;
    /* Label colour for anything filled with the accent (buttons, chips). */
    --jv-on-accent:   #FFFFFF;

    /* Lines */
    --jv-line-dark:  rgba(244, 241, 234, 0.14);
    --jv-line-light: rgba(16, 49, 42, 0.12);

    /* Rhythm */
    --jv-section-y:  clamp(72px, 8vw, 140px);
    --jv-gutter:     clamp(16px, 4vw, 24px);
    --jv-content:    1192px;
    --jv-radius:     24px;
    --jv-radius-lg:  32px;

    /* Motion */
    --jv-ease:       cubic-bezier(0.22, 1, 0.36, 1);
    --jv-ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
    --jv-dur:        720ms;
    --jv-dur-fast:   240ms;

    /* Type — reference-site scale: Rajdhani everywhere, positive tracking. */
    --jv-font-display: "Rajdhani", "Poppins", sans-serif;

    /* Smoke surfaces (legacy warm-dark bands) + ink as raw RGB for scrims. */
    --jv-smoke:   #4A443A;
    --jv-smoke-2: #2A2318;
    --jv-ink-rgb: 6, 23, 19;
    --jv-ink2-rgb: 11, 38, 32;
}

/* ── Elementor global colours ────────────────────────────────────────────────
   The kit bakes four fixed hex values onto `.elementor-kit-N`, and every widget
   that was never given an explicit colour — default buttons, the Posts badge,
   form controls — reads them. That bypassed the palette entirely, which is why
   those elements stayed green on every theme. Forward them to our tokens.
   `body[class*=...]` outranks the kit's own single-class selector. */
body[class*="elementor-kit-"] {
    --e-global-color-primary: var(--jv-ink-3);
    --e-global-color-secondary: var(--jv-accent-deep);
    --e-global-color-text: var(--jv-on-light-soft);
    --e-global-color-accent: var(--jv-accent);
}

/* Two-tone heading accents (class-based so themes recolour them live). */
.elementor-heading-title .jv-acc { color: var(--jv-accent); }
.elementor-heading-title .jv-acc-d { color: var(--jv-accent-deep); }

/* Smooth palette hand-off: the switcher pins this class for ~700ms. */
.jv-theme-anim,
.jv-theme-anim * {
    transition: background-color 600ms ease, color 600ms ease,
                border-color 600ms ease, fill 600ms ease !important;
}

/* ── Farbwelten: four two-colour palettes, driven by one attribute. ─────── */
/* The practice colour, captured on <html> where the palette lives. A page
   that repoints the accent tokens for its own colour world (Kinderzahnarzt)
   inherits this untouched, so its decisive actions can still carry the
   brand rather than the page accent. */
html { --jv-signal: var(--jv-accent-deep); }

html[data-jv-theme="beige"] {
    --jv-ink: #26211D; --jv-ink-2: #322B26; --jv-ink-3: #3B332D;
    --jv-smoke: #4A4038; --jv-smoke-2: #2E2620;
    --jv-accent: #D9B98C; --jv-accent-deep: #8A6B42;
    --jv-paper: #F7F2EA; --jv-paper-2: #EFE7DB;
    --jv-ink-rgb: 38, 33, 29;
    --jv-ink2-rgb: 50, 43, 38;
}
html[data-jv-theme="anthrazit"] {
    --jv-ink: #1B1D1F; --jv-ink-2: #26292C; --jv-ink-3: #2F3336;
    --jv-smoke: #3C4043; --jv-smoke-2: #26292C;
    --jv-accent: #D89A6A; --jv-accent-deep: #9A5F33;
    --jv-paper: #F4F3F0; --jv-paper-2: #EAE8E3;
    --jv-ink-rgb: 27, 29, 31;
    --jv-ink2-rgb: 38, 41, 44;
}
/* PRIMARY — Emre's swatch İDEAL VG 1155: slate smoke + cool grey.
   Two colours only, exactly as briefed; also the :root default below. */
html[data-jv-theme="fume"] {
    --jv-ink: #2F3A40; --jv-ink-2: #3B474E; --jv-ink-3: #46535A;
    --jv-smoke: #4E5C64; --jv-smoke-2: #3B474E;
    --jv-accent: #C3CBD0; --jv-accent-deep: #6E7C85;
    --jv-paper: #F4F5F6; --jv-paper-2: #E6E9EB;
    --jv-on-light-soft: #46535A; --jv-on-light-mute: #6E7C85;
    --jv-ink-rgb: 47, 58, 64;
    --jv-ink2-rgb: 59, 71, 78;
}
html[data-jv-theme="navy"] {
    --jv-ink: #0C1B2A; --jv-ink-2: #122536; --jv-ink-3: #17304A;
    --jv-smoke: #1C3550; --jv-smoke-2: #122536;
    --jv-accent: #D8C39A; --jv-accent-deep: #8F7443;
    --jv-paper: #F6F3EC; --jv-paper-2: #ECE6D9;
    --jv-ink-rgb: 12, 27, 42;
    --jv-ink2-rgb: 18, 37, 54;
}

/* Demo palette picker, fixed on the right edge. */
.jv-themer {
    position: fixed;
    right: 14px;
    top: 50%;
    translate: 0 -50%;
    z-index: 900;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px 10px;
    border-radius: 999px;
    background: rgba(20, 20, 20, 0.55);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.16);
}
.jv-themer button {
    width: 30px;
    height: 30px;
    border-radius: 999px;
    border: 2px solid rgba(255, 255, 255, 0.35);
    cursor: pointer;
    padding: 0;
    transition: transform 160ms var(--jv-ease), border-color 160ms linear;
}
.jv-themer button:hover { transform: scale(1.15); }
.jv-themer button[aria-pressed="true"] {
    border-color: #fff;
    transform: scale(1.18);
}
@media (max-width: 767px) {
    .jv-themer { right: 8px; padding: 10px 8px; }
    .jv-themer button { width: 26px; height: 26px; }
}

/* Rajdhani carries every text role, like the reference. */
.jv-dark, .jv-dark-2, .jv-light, .jv-light-2, .jv-hero, .jv-emotion,
.jv-dark .elementor-heading-title, .jv-light .elementor-heading-title,
.jv-dark .elementor-widget-text-editor, .jv-light .elementor-widget-text-editor,
.jv-dark .elementor-button, .jv-light .elementor-button {
    font-family: var(--jv-font-display);
}

/* Two-tone headings: the trailing words carry the accent. */
.elementor-heading-title .jv-acc { color: var(--jv-accent); }
.jv-light .elementor-heading-title .jv-acc,
.jv-light-2 .elementor-heading-title .jv-acc { color: var(--jv-accent-deep); }

/* Round prev/next controls on horizontal rails. */
.jv-rail-nav {
    display: flex;
    gap: 10px;
}

.jv-rail-nav button,
.jv-rail-nav button:hover,
.jv-rail-nav button:focus,
.jv-rail-nav button:active {
    width: 46px;
    height: 46px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    border: 1px solid var(--jv-line-dark);
    background: transparent !important;
    color: var(--jv-on-dark);
    font-size: 17px;
    cursor: pointer;
    box-shadow: none !important;
    transition: border-color 180ms linear, color 180ms linear;
}

.jv-light .jv-rail-nav button,
.jv-light-2 .jv-rail-nav button {
    border-color: var(--jv-line-light);
    color: var(--jv-on-light);
}

.jv-rail-nav button:hover {
    border-color: var(--jv-accent);
    color: var(--jv-accent);
}

/* Reference-style card label: white pill, bottom-left on the photo. */
.jv-pill .elementor-heading-title {
    display: inline-block;
    background: var(--jv-paper);
    color: var(--jv-on-light);
    padding: 9px 18px;
    border-radius: 999px;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: 0.02em;
}

/* Icon feature card (dark grid). */
.jv-icon-card {
    background: rgba(244, 241, 234, 0.045);
    border: 1px solid rgba(244, 241, 234, 0.08);
    border-radius: 20px;
    transition: border-color 200ms linear, transform 260ms var(--jv-ease);
}

.jv-icon-card:hover {
    border-color: color-mix(in srgb, var(--jv-accent) 40%, transparent);
    transform: translateY(-3px);
}

.jv-icon-card .elementor-icon {
    width: 68px;
    height: 68px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: color-mix(in srgb, var(--jv-accent) 8%, transparent);
}

/* ── 2. Motion primitives ────────────────────────────────────────────────── */

/* Base: fade + rise. Hiding is gated behind html.jv-motion, which motion.js
   only sets once its observer is safely installed — content can never be
   trapped invisible by a script failure. */
.jv-motion [data-reveal] {
    opacity: 0;
    transform: translate3d(0, 26px, 0);
    transition:
        opacity var(--jv-dur) var(--jv-ease-out) var(--jv-delay, 0ms),
        transform var(--jv-dur) var(--jv-ease-out) var(--jv-delay, 0ms),
        filter var(--jv-dur) var(--jv-ease-out) var(--jv-delay, 0ms);
    will-change: opacity, transform;
}

[data-reveal].is-revealed {
    opacity: 1;
    transform: none;
    filter: none;
}

/* Blur-to-clear, for imagery. */
.jv-motion [data-reveal="blur"] {
    filter: blur(14px);
    transform: translate3d(0, 18px, 0) scale(1.02);
}

/* Mask wipe retired: it left containers permanently clipped when the
   observer missed them. Media may never be invisible — mask now behaves
   as a plain fade. */
[data-reveal="mask"] {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
}

/* Per-line heading reveal; spans are created by motion.js. */
[data-reveal="lines"] {
    opacity: 1;
    transform: none;
}

.jv-line {
    display: block;
    overflow: hidden;
}

.jv-motion .jv-line__inner {
    display: block;
    transform: translate3d(0, 105%, 0);
    transition: transform 820ms var(--jv-ease-out);
    transition-delay: calc(var(--jv-line-index, 0) * 90ms + var(--jv-delay, 0ms));
}

[data-reveal="lines"].is-revealed .jv-line__inner {
    transform: none;
}

/* Scale-in for framed media. */
.jv-motion [data-reveal="zoom"] {
    transform: scale(1.06);
    opacity: 0;
}

/* ── 3. Surfaces and type ────────────────────────────────────────────────── */
.jv-dark {
    background: var(--jv-ink);
    color: var(--jv-on-dark);
}

.jv-dark-2 { background: var(--jv-ink-2); color: var(--jv-on-dark); }
.jv-light  { background: var(--jv-paper); color: var(--jv-on-light); }
.jv-light-2 { background: var(--jv-paper-2); color: var(--jv-on-light); }

.jv-dark  .elementor-heading-title,
.jv-dark-2 .elementor-heading-title { color: var(--jv-on-dark); }

/* Small uppercase section label with a rule. */
.jv-eyebrow .elementor-heading-title {
    display: inline-flex;
    align-items: center;
    gap: 12px;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.jv-eyebrow .elementor-heading-title::before {
    content: "";
    width: 28px;
    height: 1px;
    background: currentColor;
    opacity: 0.6;
}

/* Editorial display heading. */
.jv-display .elementor-heading-title {
    text-wrap: balance;
}

/* ── 4. Hero ─────────────────────────────────────────────────────────────── */
.jv-hero {
    position: relative;
    min-height: 100svh;
    overflow: clip;
    isolation: isolate;
}

/* The cue pins to the hero's lower edge, under the copy. */
.jv-hero .elementor-widget-html:has(.jv-scrollcue) {
    position: static;
}

.jv-hero__media,
.jv-hero__media video,
.jv-hero__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: -2;
}

/* Legibility: a vertical wash plus a corner vignette. */
.jv-hero::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background:
        linear-gradient(180deg,
            rgba(var(--jv-ink-rgb), 0.72) 0%,
            rgba(var(--jv-ink-rgb), 0.34) 34%,
            rgba(var(--jv-ink-rgb), 0.62) 74%,
            rgba(var(--jv-ink-rgb), 0.94) 100%),
        radial-gradient(120% 90% at 50% 10%,
            rgba(var(--jv-ink-rgb), 0) 40%,
            rgba(var(--jv-ink-rgb), 0.55) 100%);
}

/* Mouse-shaped cue: slim pill outline, a mint dot drops inside it, a soft
   chevron breathes underneath. */
.jv-scrollcue {
    position: absolute;
    left: 50%;
    /* The badge row now occupies the strip this used to sit in, so the cue
       drops below it rather than landing on top of the pills. */
    bottom: 34px;
    translate: -50% 0;
    width: 26px;
    height: 42px;
    border: 1.5px solid rgba(244, 241, 234, 0.45);
    border-radius: 999px;
    background: rgba(var(--jv-ink-rgb), 0.25);
}

@media (max-width: 767px) {
    /* On a phone the pills scroll on one line and sit lower — the cue would
       collide with them, so it steps aside entirely. */
    .jv-scrollcue { display: none; }
}

.jv-scrollcue::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 7px;
    width: 4px;
    height: 9px;
    border-radius: 4px;
    background: var(--jv-accent);
    transform: translate(-50%, 0);
    animation: jv-cue-drop 2.1s var(--jv-ease) infinite;
}

/* Parallax duty for the emotion band, same treatment as the quote band. */
@media (min-width: 1025px) {
    .jv-emotion { background-attachment: fixed; }
}

.jv-scrollcue::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -16px;
    width: 9px;
    height: 9px;
    border-right: 1.5px solid rgba(244, 241, 234, 0.55);
    border-bottom: 1.5px solid rgba(244, 241, 234, 0.55);
    transform: translateX(-50%) rotate(45deg);
    animation: jv-cue-chev 2.1s var(--jv-ease) infinite;
}

@keyframes jv-cue-drop {
    0%   { transform: translate(-50%, 0); opacity: 1; }
    65%  { transform: translate(-50%, 15px); opacity: 0; }
    100% { transform: translate(-50%, 15px); opacity: 0; }
}

@keyframes jv-cue-chev {
    0%, 100% { opacity: 0.35; transform: translateX(-50%) rotate(45deg) translate(0, 0); }
    50%      { opacity: 0.9;  transform: translateX(-50%) rotate(45deg) translate(2px, 2px); }
}

/* ── 5. Cards and rails ──────────────────────────────────────────────────── */

/* Treatment card: image with a wash, title bottom-left, arrow bottom-right. */
.jv-card {
    position: relative;
    display: block;
    border-radius: var(--jv-radius);
    overflow: hidden;
    isolation: isolate;
    text-decoration: none;
}

.jv-card img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 900ms var(--jv-ease);
}

.jv-card::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
        rgba(var(--jv-ink-rgb), 0) 32%,
        rgba(var(--jv-ink-rgb), 0.58) 68%,
        rgba(var(--jv-ink-rgb), 0.9) 100%);
    transition: opacity var(--jv-dur-fast) linear;
}

.jv-card:hover img,
.jv-card:focus-visible img {
    transform: scale(1.06);
}

/* A flex parent sizes a wrapped child to its content, so every scroller
   must pin itself to the container or it dictates the page width — on
   phones that pushed the burger and the info bar off the right edge. */
.jv-railwrap,
.jv-rail,
.javadi-rail,
.javadi-marquee {
    width: 100%;
    min-width: 0;
    max-width: 100%;
}

.javadi-marquee {
    overflow-x: clip;
}

/* Safety net: a phone never pans sideways, whatever still overflows.
   `clip` rather than `hidden`: it forbids scrolling without creating a
   scroll container, so the sticky header keeps working. */
@media (max-width: 767px) {
    html, body {
        overflow-x: clip;
    }

    /* The info bar's three entries need two lines on a phone; they were
       being cut off at the right edge instead. */
    .elementor-location-header #javadi-topbar > .e-con-inner {
        flex-wrap: wrap;
        justify-content: center;
        row-gap: 1px;
        column-gap: 14px;
    }
    .elementor-location-header #javadi-topbar .elementor-heading-title {
        font-size: 11px;
        white-space: nowrap;
    }
}

/* While the drawer is open the floating contact pill has no business on
   top of it — it punches through the header's stacking context. */
body.pjv-mm-locked .contact-fab,
body.pjv-mm-locked #ContactPanel {
    opacity: 0 !important;
    visibility: hidden !important;
    pointer-events: none !important;
}

/* Horizontal rail that bleeds past the content column. */
.jv-rail {
    --jv-bleed: max(var(--jv-gutter), (100vw - var(--jv-content)) / 2);
    display: flex;
    gap: 20px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    -ms-overflow-style: none;
    margin-inline-end: calc(-1 * var(--jv-bleed));
    /* The negative margin already carries the rail out to the window edge, so
       a matching padding on top of it is scrollable emptiness: at the end of
       the strip the reader was left staring at a bleed-wide blank. A gutter is
       enough to keep the last card off the glass. */
    padding-inline-end: var(--jv-gutter, 24px);
}

.jv-rail::-webkit-scrollbar { display: none; }
.jv-rail > * { scroll-snap-align: start; flex: 0 0 auto; }

/* Drag-to-scroll: the whole rail behaves like a physical strip of photos.
   Driven by rail-drag.js; the cursor states are the affordance. */
.jv-rail--auto { cursor: grab; }
.jv-rail--auto.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.jv-rail--auto.is-dragging * { pointer-events: none; user-select: none; }

.jv-rail-hint {
    margin: 4px 0 0;
    font-family: "Poppins", sans-serif;
    font-size: 13.5px;
    letter-spacing: 0.04em;
    color: var(--jv-on-light-mute);
    opacity: 0.85;
}
.jv-dark .jv-rail-hint, .jv-dark-2 .jv-rail-hint {
    color: var(--jv-on-dark-mute);
}
.jv-rail-hint span {
    display: inline-block;
    animation: jv-hint-nudge 2.4s ease-in-out infinite;
}
@keyframes jv-hint-nudge {
    0%, 100% { transform: translateX(0); }
    50% { transform: translateX(5px); }
}
@media (prefers-reduced-motion: reduce) {
    .jv-rail-hint span { animation: none; }
}

/* ── 6. Mega menu ────────────────────────────────────────────────────────── */
.jv-mega {
    position: absolute;
    inset-inline: 0;
    top: 100%;
    background: var(--jv-ink-2);
    border-top: 1px solid var(--jv-line-dark);
    opacity: 0;
    visibility: hidden;
    transform: translate3d(0, -8px, 0);
    filter: blur(6px);
    transition:
        opacity 260ms var(--jv-ease),
        transform 320ms var(--jv-ease),
        filter 260ms var(--jv-ease),
        visibility 0s linear 320ms;
    z-index: 400;
}

.jv-mega.is-open {
    opacity: 1;
    visibility: visible;
    transform: none;
    filter: none;
    transition-delay: 0s;
}

/* ── 6b. Transparent header over the hero ────────────────────────────────────
   Homepage only: the header floats transparent over the video and regains its
   solid surface as soon as the page is scrolled (sticky-header.js toggles
   `javadi-is-stuck` on <body>). */
/* body.home:not(...) outranks the child theme's sticky rule. */
body.home:not(.elementor-editor-active) .elementor-location-header {
    position: fixed;
    inset-inline: 0;
    top: 0;
    z-index: 500;
}

/* Liquid-glass bar: dark frosted surface on every page… */
.elementor-location-header #javadi-header {
    background: rgba(var(--jv-ink-rgb), 0.86);
    border-bottom: 1px solid rgba(244, 241, 234, 0.08);
    transition: background-color 280ms linear, border-color 280ms linear,
                backdrop-filter 280ms linear;
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .elementor-location-header #javadi-header {
        background: rgba(var(--jv-ink-rgb), 0.55);
        -webkit-backdrop-filter: blur(18px) saturate(1.5);
        backdrop-filter: blur(18px) saturate(1.5);
    }
}

/* …its type goes light, the dark lockup flips to white… */
.elementor-location-header #javadi-header .elementor-heading-title,
.elementor-location-header .pjv-meganav__link {
    color: var(--jv-on-dark);
}

#javadi-logo img {
    filter: brightness(0) invert(1);
}

/* …and over the hero, before any scroll, it is a soft frosted band that
   dissolves at its lower edge. The glass lives on a ::before layer: masking
   the element itself would also clip the mega panel that hangs below it. */
.home:not(.javadi-is-stuck) .elementor-location-header #javadi-header {
    position: relative;
    background: transparent;
    border-bottom-color: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

.home:not(.javadi-is-stuck) .elementor-location-header #javadi-header::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgba(var(--jv-ink-rgb), 0.5);
    -webkit-backdrop-filter: blur(14px) saturate(1.35);
    backdrop-filter: blur(14px) saturate(1.35);
    -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
}

/* Belt and braces: a whisper of shadow behind the letters themselves. */
.home:not(.javadi-is-stuck) .elementor-location-header #javadi-header .pjv-meganav__link,
.home:not(.javadi-is-stuck) .elementor-location-header #javadi-header .elementor-heading-title {
    text-shadow: 0 1px 14px rgba(var(--jv-ink-rgb), 0.55);
}

/* ── Subpages: the same floating glass ───────────────────────────────────────
   The bar used to sit in the flow above a white page, so its translucency had
   nothing behind it to pick up and it read as a flat slab. Float it over the
   page hero, exactly as on the homepage. Scoped with :has() so any page
   without a hero image keeps the solid bar and stays readable. */
body:has(.jv-subheader):not(.home):not(.elementor-editor-active) .elementor-location-header {
    position: fixed;
    inset-inline: 0;
    top: 0;
    z-index: 500;
}

/* The hero gives back the height the bar no longer occupies in the flow. */
body:has(.jv-subheader) .jv-subheader {
    padding-top: 128px;
}

body:has(.jv-subheader):not(.javadi-is-stuck) .elementor-location-header #javadi-header {
    position: relative;
    background: transparent;
    border-bottom-color: transparent;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

body:has(.jv-subheader):not(.javadi-is-stuck) .elementor-location-header #javadi-header::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: rgba(var(--jv-ink-rgb), 0.5);
    -webkit-backdrop-filter: blur(14px) saturate(1.35);
    backdrop-filter: blur(14px) saturate(1.35);
    -webkit-mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
    mask-image: linear-gradient(180deg, #000 62%, transparent 100%);
}

body:has(.jv-subheader):not(.javadi-is-stuck) .elementor-location-header #javadi-header .pjv-meganav__link,
body:has(.jv-subheader):not(.javadi-is-stuck) .elementor-location-header #javadi-header .elementor-heading-title {
    text-shadow: 0 1px 14px rgba(var(--jv-ink-rgb), 0.55);
}

@media (max-width: 1024px) {
    body:has(.jv-subheader) .jv-subheader { padding-top: 104px; }
}

/* Premium nav interaction: a mint bar grows under the active/hovered item. */
.pjv-meganav__link {
    position: relative;
}

.pjv-meganav__link::after {
    content: "";
    position: absolute;
    inset-inline: 12px;
    bottom: 4px;
    height: 2px;
    border-radius: 2px;
    background: var(--jv-accent);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 240ms var(--jv-ease);
}

.pjv-meganav__link:hover::after,
.pjv-meganav__link.is-current::after,
.pjv-meganav__trigger[aria-expanded="true"]::after {
    transform: scaleX(1);
}

/* The booking pill glows gently on hover. */
#javadi-cta {
    transition: box-shadow 240ms linear, transform 240ms var(--jv-ease);
}

#javadi-cta:hover {
    box-shadow: 0 10px 30px rgba(111, 211, 174, 0.28);
    transform: translateY(-1px);
}

/* The template's own hairline divider is replaced by the glass border. */
.elementor-location-header .elementor-widget-divider {
    display: none;
}

/* ── Mobile drawer: fully palette-bound. The widget ships Figma greens as
      inline Elementor settings, so these overrides are what the switcher
      actually drives. ──────────────────────────────────────────────────── */
.pjv-mm-drawer,
.pjv-mm-panel,
[class*="pjv-mm"][class*="panel"],
[class*="pjv-mm"][class*="drawer"] {
    background: var(--jv-ink-2) !important;
}

.pjv-mm-drawer a,
.pjv-mm-drawer .pjv-mm-link,
[class*="pjv-mm"] a:not(.elementor-button) {
    color: var(--jv-on-dark) !important;
}

.pjv-mm-drawer a:hover,
[class*="pjv-mm"] a:not(.elementor-button):hover,
[class*="pjv-mm"] a[aria-current="page"],
[class*="pjv-mm"] .is-current {
    color: var(--jv-accent) !important;
}

/* Row separators and the accordion chevron plate. */
[class*="pjv-mm"] li,
[class*="pjv-mm"] [class*="item"] {
    border-color: var(--jv-line-dark) !important;
}

/* The burger is deliberately plateless — see the minimal-burger block below.
   Only the sub-toggles and the close button keep a tinted chip. */
[class*="pjv-mm"] button[class*="sub-toggle"],
[class*="pjv-mm"] [class*="chev"],
[class*="pjv-mm"] [class*="close"] {
    background: color-mix(in srgb, var(--jv-accent) 12%, transparent) !important;
    color: var(--jv-on-dark) !important;
    border-color: var(--jv-line-dark) !important;
}

/* Substring matching also caught the glyph inside the chip (close-x), so the
   plate was painted twice: once round on the button, once square on the
   glyph, which read as a leftover box behind the close button. The chip is
   the button; whatever sits inside it stays bare. */
[class*="pjv-mm"] [class*="close"] [class*="close"],
[class*="pjv-mm"] [class*="close"] > span,
[class*="pjv-mm"] [class*="close"] > svg,
[class*="pjv-mm"] button[class*="sub-toggle"] > span,
[class*="pjv-mm"] button[class*="sub-toggle"] > svg {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
}

/* Booking pill and the call plate at the drawer's foot. */
[class*="pjv-mm"] .elementor-button,
[class*="pjv-mm"] [class*="cta"] {
    background: var(--jv-accent-deep) !important;
    color: var(--jv-on-dark) !important;
}

[class*="pjv-mm"] [class*="phone"],
[class*="pjv-mm"] [class*="call"] {
    background: color-mix(in srgb, var(--jv-paper) 5%, transparent) !important;
    border-color: var(--jv-line-dark) !important;
}

[class*="pjv-mm"] [class*="phone"] [class*="icon"],
[class*="pjv-mm"] [class*="call"] [class*="icon"] {
    background: color-mix(in srgb, var(--jv-accent) 16%, transparent) !important;
    color: var(--jv-accent) !important;
}

/* The drawer declares these on `.pjv-mm-root` / `.elementor-widget-pjv-mobile-menu`,
   which sit closer to it than :root. A custom property resolves from the
   NEAREST defining ancestor — specificity never enters into it — so an :root
   override could not reach the drawer. Redefine them on the same elements.

   The widget also writes its saved control values onto its own wrapper
   (`.elementor-element-xxxx.pjv-mm-side--right`), and those were still the
   retired green palette: the panel looked right only because the surfaces
   are repainted below, while anything reading the raw variable — the focus
   ring, active link colour — stayed green. Matching that wrapper and
   marking the values important keeps every menu colour on the tokens. */
.pjv-mm-root,
.elementor-widget-pjv-mobile-menu,
[class*="pjv-mm"],
html:root {
    --pjv-mm-surface: var(--jv-ink-2) !important;
    --pjv-mm-surface-2: var(--jv-ink-3) !important;
    --pjv-mm-accent: var(--jv-accent-deep) !important;
    --pjv-mm-text: var(--jv-on-dark) !important;
    --pjv-mm-muted: var(--jv-on-dark-soft) !important;
    --pjv-mm-toggle-color: var(--jv-on-dark) !important;
    --pjv-mm-scrim: rgba(var(--jv-ink-rgb), 0.62) !important;
    --pjv-mm-hairline: var(--jv-line-dark) !important;
}

/* Remaining hard-coded greens inside the panel. */
.pjv-mm__nav .sub-menu li {
    border-inline-start-color: color-mix(in srgb, var(--jv-accent) 55%, transparent) !important;
}
.pjv-mm__panel {
    box-shadow: -24px 0 60px rgba(var(--jv-ink-rgb), 0.45) !important;
}
/* The CTA carried a green drop shadow in both its rest and pressed state. */
.pjv-mm__cta {
    background: var(--jv-accent-deep) !important;
    color: var(--jv-on-accent, #FFFFFF) !important;
    box-shadow: 0 8px 22px rgba(var(--jv-ink-rgb), 0.26) !important;
}
.pjv-mm__cta:active {
    box-shadow: 0 4px 14px rgba(var(--jv-ink-rgb), 0.22) !important;
}
.pjv-mm__cta-badge {
    background: color-mix(in srgb, var(--jv-accent) 22%, transparent) !important;
}

/* The phone disc and its label were painted with literal greens, not vars. */
.pjv-mm__tel-icon {
    background: color-mix(in srgb, var(--jv-accent) 22%, transparent) !important;
    border-color: var(--jv-accent-deep) !important;
    color: var(--jv-accent) !important;
}
.pjv-mm__tel-label,
.pjv-mm__meta {
    color: var(--jv-on-dark-soft) !important;
}
.pjv-mm__foot {
    background-color: var(--jv-ink-3) !important;
}

/* Mega panel drop shadow was a fixed dark green. */
.pjv-mega {
    box-shadow: 0 30px 60px rgba(var(--jv-ink-rgb), 0.35) !important;
}

/* Drawer rhythm: head, list and foot all carried more air than the panel
   needed, so the CTA sat far below the last link. Tighten without dropping
   under the 44px touch floor. */
.pjv-mm__head { padding-block: 14px !important; }
.pjv-mm__nav a { padding-block: 11px !important; }
.pjv-mm__foot {
    padding-block: 14px !important;
    gap: 10px !important;
}
.pjv-mm__tel { padding: 10px 12px !important; }
.pjv-mm__cta { min-height: 48px !important; }
.pjv-mm__meta { margin-top: 4px !important; }

/* Backdrop behind the open drawer. */
[class*="pjv-mm"][class*="backdrop"],
[class*="pjv-mm"][class*="overlay"] {
    background: color-mix(in srgb, var(--jv-ink) 72%, transparent) !important;
}

/* Minimal burger: no plate, no border — two hairlines that read as a mark.
   Palette-bound, and it inverts to a clean X while the drawer is open. */
.pjv-mm__toggle,
.pjv-mm__toggle:hover,
.pjv-mm__toggle:focus {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--jv-on-dark) !important;
    --pjv-mm-bar-w: 26px;
    --pjv-mm-bar-h: 1.6px;
}

/* Bars are absolutely positioned with `inset-inline: 0`, so shortening one
   means releasing its start edge — `width` alone would do nothing. */
.pjv-mm__bars i {
    height: 1.6px !important;
    border-radius: 2px;
    transition: transform 260ms var(--jv-ease), opacity 180ms linear,
                inset-inline-start 260ms var(--jv-ease);
}

/* The middle rule sits short — that asymmetry is the whole mark. */
.pjv-mm__bars i:nth-child(2) {
    inset-inline-start: 34% !important;
}

.pjv-mm__toggle:hover .pjv-mm__bars i:nth-child(2) {
    inset-inline-start: 0 !important;
}

/* Open state: the X must stay symmetric, so restore the short bar first. */
.pjv-mm__toggle[aria-expanded="true"] .pjv-mm__bars i:nth-child(2) {
    inset-inline-start: 0 !important;
}

/* ── Mobile rails ────────────────────────────────────────────────────────────
   Elementor switches every flex container to `flex-wrap: wrap` at the mobile
   breakpoint, so the rails stacked their cards vertically instead of forming
   one scrollable row — scrollWidth equalled clientWidth, so there was nothing
   to swipe. Force one row and let the finger do the rest. */
@media (max-width: 767px) {
    .jv-rail,
    .jv-rail > .e-con-inner {
        flex-wrap: nowrap !important;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        /* Bleed to the screen edge so a card can sit flush while scrolling. */
        margin-inline: calc(var(--jv-bleed, 16px) * -1);
        padding-inline: var(--jv-bleed, 16px);
    }

    .jv-rail::-webkit-scrollbar,
    .jv-rail > .e-con-inner::-webkit-scrollbar { display: none; }

    /* Cards keep their width instead of being squeezed into the viewport. */
    .jv-rail > .e-con-inner > .e-con,
    .jv-rail > .e-con-inner > .elementor-widget,
    .jv-rail > .e-con,
    .jv-rail > .elementor-widget {
        flex: 0 0 auto !important;
        scroll-snap-align: start;
        max-width: 82vw;
    }

    /* The nested inner must not add a second scroller inside the outer one. */
    .jv-rail > .e-con-inner { margin-inline: 0; padding-inline: 0; }

    /* Certificates ride an auto-scrolling marquee on desktop; on a phone that
       wrapped into a vertical stack. Stop the animation and hand the row to
       the finger instead. */
    .javadi-marquee {
        overflow-x: auto !important;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        margin-inline: -16px;
        padding-inline: 16px;
    }
    .javadi-marquee::-webkit-scrollbar { display: none; }

    .javadi-marquee-track {
        flex-wrap: nowrap !important;
        animation: none !important;
    }
    .javadi-marquee-track > * {
        flex: 0 0 auto !important;
        scroll-snap-align: start;
    }

    /* The bar is thin here and rides over photographs — the 0.55 veil left the
       white lockup unreadable once the page scrolled. */
    .elementor-location-header #javadi-header {
        background: rgba(var(--jv-ink-rgb), 0.9);
    }
    body:not(.javadi-is-stuck) .elementor-location-header #javadi-header::before {
        background: rgba(var(--jv-ink-rgb), 0.74);
    }
}

/* Ästhetik-Siegel — Emre's live sizing: 50px smaller than the built value
   (max 340 → 290) and a 20px gap from the top of the band. Lives here, not in
   the page's own CSS, so the page content is never rewritten to restyle it.
   `.jv-smile` prefix outranks the page rule whichever loads first. */
.jv-smile .jv-seal--ae {
    width: clamp(140px, 20vw, 290px);
    /* Sits 60px down and 70px in from the right edge, which centres it in
       the empty column beside the headline. */
    top: 60px;
    right: calc(max(24px, (100vw - 1192px) / 2) + 70px);
}
@media (max-width: 1024px) {
    .jv-smile .jv-seal--ae { width: 110px; top: 60px; right: 86px; }
}
@media (max-width: 767px) {
    .jv-smile .jv-seal--ae { width: 78px; top: 48px; right: 30px; }
}

/* Service cards ("Wobei dürfen wir helfen?"): each card is the same height,
   but the CTA sat directly under its link list, so a card with four links
   put its button 60px higher than the card with six. Push every button to
   the card floor — they then line up on the lowest one. */
.e-con:has(> .javadi-linklist) > .elementor-widget-button {
    margin-top: auto;
}

/* ── Journal cards ───────────────────────────────────────────────────────────
   The band is now a live Posts query, but it has to read as the same card the
   page was designed around: full-bleed 16:9 image, category above the title in
   mono caps, Rajdhani headline, muted excerpt, read-more pinned to the floor. */
.jv-journal .elementor-posts-container { align-items: stretch; }

.jv-journal .elementor-post__card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--jv-paper);
    border: 1px solid var(--jv-line-light);
    border-radius: 18px;
    overflow: hidden;
    box-shadow: 0 4px 18px rgba(var(--jv-ink-rgb), 0.04);
    transition: transform 320ms var(--jv-ease), box-shadow 320ms var(--jv-ease);
}

.jv-journal .elementor-post__card:hover {
    transform: translateY(-4px);
    box-shadow: 0 18px 40px rgba(var(--jv-ink-rgb), 0.10);
}

/* Image sits flush at the top, cropped to a steady ratio. */
.jv-journal .elementor-post__thumbnail__link { order: 1; margin: 0; }
.jv-journal .elementor-post__thumbnail {
    padding-bottom: 0 !important;
    aspect-ratio: 16 / 10;
}
.jv-journal .elementor-post__thumbnail img {
    position: static !important;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transform: none !important;
    transition: scale 700ms var(--jv-ease);
}
.jv-journal .elementor-post__card:hover .elementor-post__thumbnail img { scale: 1.04; }

/* The category badge belongs above the title, not floating on the photo. */
/* Elementor's own cards-skin rule matches with the same weight, so the
   plain-text treatment needs to win outright. */
.jv-journal .elementor-post__badge {
    order: 2;
    position: static !important;
    align-self: flex-start;
    margin: 22px 22px 0 !important;
    padding: 0 !important;
    background: none !important;
    border-radius: 0 !important;
    font-family: "Poppins", sans-serif;
    font-size: 11px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--jv-accent-deep);
}

.jv-journal .elementor-post__text {
    order: 3;
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    padding: 9px 22px 22px;
    margin: 0;
}

.jv-journal .elementor-post__title {
    margin: 0 0 10px;
    font-family: "Rajdhani", sans-serif;
}
.jv-journal .elementor-post__title a { color: var(--jv-on-light); }
.jv-journal .elementor-post__card:hover .elementor-post__title a {
    color: var(--jv-accent-deep);
}

.jv-journal .elementor-post__excerpt p {
    margin: 0;
    color: var(--jv-on-light-mute);
}

/* Read-more sits on the card floor so every card lines up. */
.jv-journal .elementor-post__read-more {
    margin-top: auto;
    padding-top: 14px;
    color: var(--jv-on-light-mute);
    text-decoration: none;
}
.jv-journal .elementor-post__card:hover .elementor-post__read-more {
    color: var(--jv-accent-deep);
}

/* Date/comments and the avatar have no place in this card. */
.jv-journal .elementor-post__meta-data,
.jv-journal .elementor-post__avatar { display: none; }

@media (max-width: 767px) {
    .jv-journal .elementor-post__badge { margin: 18px 18px 0; }
    .jv-journal .elementor-post__text { padding: 8px 18px 18px; }
}

/* ── Trust badges on the hero ────────────────────────────────────────────────
   They used to sit in their own band, which left a wide empty strip under the
   video. Now they ride the bottom of the hero itself: glass pills over the
   footage, legible without a solid plate behind them. */
.jv-hero-badges {
    margin-top: clamp(28px, 5vh, 64px) !important;
    padding: 0 !important;
    z-index: 3;
}

.jv-hero-badges > .e-con,
.jv-hero-badges > .e-con-inner > .e-con {
    background-color: rgba(var(--jv-ink-rgb), 0.34) !important;
    border-color: rgba(255, 255, 255, 0.22) !important;
    -webkit-backdrop-filter: blur(14px) saturate(1.3);
    backdrop-filter: blur(14px) saturate(1.3);
    box-shadow: 0 8px 24px rgba(var(--jv-ink-rgb), 0.22) !important;
}

/* On the footage the copy has to be light, whatever the pill said before. */
.jv-hero-badges .elementor-heading-title {
    color: var(--jv-on-dark) !important;
}

/* Without a backdrop filter the glass would read as a grey smear. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .jv-hero-badges > .e-con,
    .jv-hero-badges > .e-con-inner > .e-con {
        background-color: rgba(var(--jv-ink-rgb), 0.62) !important;
    }
}

@media (max-width: 767px) {
    /* Five pills would stack into a wall; let them scroll on one line. */
    .jv-hero-badges > .e-con-inner {
        flex-wrap: nowrap !important;
        overflow-x: auto;
        scrollbar-width: none;
        justify-content: flex-start !important;
        margin-inline: -16px;
        padding-inline: 16px;
    }
    .jv-hero-badges > .e-con-inner::-webkit-scrollbar { display: none; }
    .jv-hero-badges > .e-con-inner > .e-con { flex: 0 0 auto !important; }
}

/* ── Header aligned to the content column ────────────────────────────────────
   The bar ran the full viewport while every section below sits in a 1192px
   box, so the logo and the Doctolib button never lined up with the hero copy —
   the button ran right off the edge. Both header rows now share the page's
   content box, which puts the logo exactly under the headline's left edge. */
.elementor-location-header #javadi-header > .e-con > .e-con-inner,
.elementor-location-header #javadi-header > .e-con-inner,
.elementor-location-header #javadi-topbar > .e-con-inner {
    /* Exactly the body column. The outer container already supplies the
       gutter, so the inner box adds none — it was adding 24px on top, which
       pushed the logo that far right of the headline below it. */
    max-width: var(--jv-content);
    margin-inline: auto;
    padding-inline: 0 !important;
}

/* The lockup and the CTA carried their own edge padding on top of that. */
.elementor-location-header #javadi-logo {
    padding-inline-start: 0 !important;
}
.elementor-location-header #javadi-header .elementor-widget-button:last-child {
    padding-inline-end: 0 !important;
    margin-inline-end: 0 !important;
}

/* ── Header at in-between widths ─────────────────────────────────────────────
   The desktop nav only gave way to the drawer below 1024px, but logo + eight
   items + the Doctolib pill stop fitting well before that — the button ended
   up sitting on top of the last menu entries. Two steps: tighten the bar
   through the middle range, and hand over to the drawer once even that is
   not enough. */

/* Nothing in the bar may overlap: each part shrinks, none overflows.
   The row was centred, which parked the lockup ~38px inside the column while
   every headline below started at its edge. Pushing the parts to the ends
   puts the logo and the CTA exactly on the content lines. */
.elementor-location-header #javadi-header .e-con-inner {
    flex-wrap: nowrap;
    justify-content: space-between !important;
}
/* The template leaves an empty flex child at the end; it would eat a slot. */
.elementor-location-header #javadi-header-bar > .e-con-inner > .e-con:empty {
    display: none;
}
/* `flex: 0 1 auto` let the nav's BOX shrink while its items kept their size,
   so the box measured fine while the links spilled under the CTA. Pinning the
   basis to the content means the row is honest about how much space it needs. */
.elementor-location-header .pjv-meganav {
    flex: 0 0 auto;
}
/* The flex child of the row is Elementor's widget WRAPPER, not the <nav>
   inside it. Pinning only the inner element left the wrapper free to shrink,
   so the wrapper measured 679px while the list inside it needed 769px and the
   last two entries went under the Doctolib pill — the overlap a visitor
   reported. The wrapper is pinned to its content as well. */
.elementor-location-header #javadi-nav {
    flex: 0 0 auto;
}
.elementor-location-header .pjv-meganav__list {
    flex-wrap: nowrap;
}
.elementor-location-header #javadi-header .elementor-widget-button {
    flex: 0 0 auto;
}

/* Measured on the live bar: lockup 268 + gap + six items 769 + gap + Doctolib
   pill 221 = 1282px of content. The header column was capped at the 1192px
   content width, so the row could never hold it at any screen size. The cap
   is lifted here — the header is allowed to run wider than the text column
   below it, which is what keeps the bar honest — and the items give up a
   couple of pixels each so the whole thing lands under 1240. */
@media (min-width: 1300px) {
    /* The bar declares --content-width: 1312px, which is the width it was
       drawn for, but its inner column carries a hard width: 1192px — the text
       column's measure — and that is 42px short of what the row needs. The
       header is given its own declared width back; it may run wider than the
       text column below, which is normal for a bar that carries a logo, six
       entries and a button. */
    .elementor-location-header #javadi-header .e-con-inner {
        width: min(1312px, 100%) !important;
        max-width: min(1312px, 100%) !important;
    }
    .pjv-meganav__list { gap: 1px; }
    .pjv-meganav__link {
        padding-inline: 7px;
        font-size: 14.5px;
        white-space: nowrap;
    }
    .elementor-location-header #javadi-header .elementor-button {
        padding-inline: 18px !important;
        font-size: 14.5px !important;
    }
}

@media (max-width: 1299px) {
    /* Below this even the widened bar cannot hold the six items without
       shrinking them past reading size, so the drawer takes over. The old
       threshold was 1259px, measured when the menu was shorter. */
    .pjv-meganav { display: none !important; }
    .elementor-location-header .elementor-widget-pjv-mobile-menu {
        display: block !important;
    }
}

/* Trust pills on the service-page banners: glass over the photograph.
   Elementor gives a nested container `width: 100%`, so each pill claimed a
   full line and they stacked. Width has to come from the content. */
.jv-subheader-trust {
    flex-direction: row !important;
    flex-wrap: wrap !important;
    align-items: center !important;
}

.jv-subheader-trust > .e-con {
    width: auto !important;
    max-width: none !important;
    flex: 0 0 auto !important;
    -webkit-backdrop-filter: blur(12px) saturate(1.25);
    backdrop-filter: blur(12px) saturate(1.25);
}

@media (max-width: 767px) {
    /* One line the thumb can drag, rather than a five-row wall. */
    .jv-subheader-trust {
        flex-wrap: nowrap !important;
        overflow-x: auto;
        scrollbar-width: none;
        justify-content: flex-start !important;
        margin-inline: -16px;
        padding-inline: 16px;
    }
    .jv-subheader-trust::-webkit-scrollbar { display: none; }
    .jv-subheader-trust > .e-con { flex: 0 0 auto !important; }
}

/* ── Homepage V2: a clearer hero ─────────────────────────────────────────────
   Same layout, lighter wash. The client found the standard hero too hazy over
   the footage, so this variant roughly halves the veil and keeps the darkening
   only where type actually sits — a band behind the copy and the lower edge,
   so the headline stays readable without fogging the whole frame. */
.jv-hero--clear::before {
    /* The frame itself is left alone. All that remains is a soft foot so the
       badges and the section below do not cut off against raw footage. */
    background: linear-gradient(180deg,
        rgba(var(--jv-ink-rgb), 0.14) 0%,
        rgba(var(--jv-ink-rgb), 0) 22%,
        rgba(var(--jv-ink-rgb), 0) 58%,
        rgba(var(--jv-ink-rgb), 0.55) 100%) !important;
}

/* The heavy one. `::after` carried a 96% diagonal wash across the left half —
   that, not ::before, was what fogged the footage. Reduced to a narrow band
   that only backs the copy column and fades out well before mid-frame. */
.jv-hero--clear::after {
    background: linear-gradient(100deg,
        rgba(var(--jv-ink-rgb), 0.48) 0%,
        rgba(var(--jv-ink-rgb), 0.30) 22%,
        rgba(var(--jv-ink-rgb), 0.08) 42%,
        rgba(var(--jv-ink-rgb), 0) 56%) !important;
}

/* With no wash to sit on, the type has to carry its own legibility. A tight
   shadow plus a wide one reads on both bright and dark frames. */
.jv-hero--clear .elementor-heading-title,
.jv-hero--clear .elementor-widget-text-editor,
.jv-hero--clear .elementor-widget-text-editor p {
    text-shadow:
        0 1px 3px rgba(var(--jv-ink-rgb), 0.85),
        0 4px 30px rgba(var(--jv-ink-rgb), 0.75);
}

/* The bar floats clear of the footage as well: on this variant it has no
   plate and no frosted band, so nothing dims the top of the frame. It only
   takes a surface back once the page is scrolled and the video is gone. */
body:has(.jv-hero--clear):not(.elementor-editor-active) .elementor-location-header {
    position: fixed;
    inset-inline: 0;
    top: 0;
    z-index: 500;
}

/* Fully transparent left the menu floating on bright footage with nothing to
   read against. A glass bar gives the type a ground while the video still
   shows through it — the frame below stays untouched. */
body:has(.jv-hero--clear):not(.javadi-is-stuck) .elementor-location-header #javadi-header {
    position: relative;
    background: rgba(var(--jv-ink-rgb), 0.42) !important;
    border-bottom: 1px solid rgba(244, 241, 234, 0.10) !important;
    -webkit-backdrop-filter: blur(16px) saturate(1.3) !important;
    backdrop-filter: blur(16px) saturate(1.3) !important;
}

body:has(.jv-hero--clear):not(.javadi-is-stuck) .elementor-location-header #javadi-topbar {
    background: rgba(var(--jv-ink-rgb), 0.52) !important;
    -webkit-backdrop-filter: blur(16px) !important;
    backdrop-filter: blur(16px) !important;
}

/* The masked band the homepage uses would double up with the bar. */
body:has(.jv-hero--clear):not(.javadi-is-stuck) .elementor-location-header #javadi-header::before {
    display: none;
}

/* Without a backdrop filter the glass reads as a flat smear — go more solid. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    body:has(.jv-hero--clear):not(.javadi-is-stuck) .elementor-location-header #javadi-header {
        background: rgba(var(--jv-ink-rgb), 0.72) !important;
    }
}

/* With no band behind it, the bar's own type needs to hold its own. */
body:has(.jv-hero--clear):not(.javadi-is-stuck) .elementor-location-header .pjv-meganav__link,
body:has(.jv-hero--clear):not(.javadi-is-stuck) .elementor-location-header .elementor-heading-title {
    text-shadow: 0 1px 16px rgba(var(--jv-ink-rgb), 0.7);
}

@media (max-width: 767px) {
    /* A phone shows far less of the frame and the type covers most of it, so
       the foot comes up a little — still far lighter than the standard hero. */
    .jv-hero--clear::before {
        background: linear-gradient(180deg,
            rgba(var(--jv-ink-rgb), 0.22) 0%,
            rgba(var(--jv-ink-rgb), 0) 26%,
            rgba(var(--jv-ink-rgb), 0.68) 100%) !important;
    }
}

/* Inline links inside draft content: something upstream displayed them as
   blocks, splitting one sentence over three lines, and they had no brand
   colour. Pin them inline, accent, underlined. */
.jv-draft .elementor-icon-list-text a,
.jv-draft .elementor-widget-text-editor a,
.jv-draft .elementor-widget-heading a {
    display: inline !important;
    color: var(--jv-accent-deep) !important;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.jv-draft-dark .elementor-icon-list-text a,
.jv-draft-dark .elementor-widget-text-editor a,
.jv-draft-dark .elementor-widget-heading a {
    color: var(--jv-accent) !important;
}

/* Keep the palette picker clear of the drawer while it is open. */
body.pjv-mm-open .jv-themer,
body.pjv-menu-open .jv-themer { display: none; }

/* The mega panel joins the glass system — theme-aware. */
/* Over the hero the panel can float, but once the page scrolls it sits on
   photos and certificates — 0.72 let them read straight through the links.
   Near-opaque with a heavier blur keeps the glass feel and the legibility. */
.pjv-mega {
    background: rgba(var(--jv-ink2-rgb), 0.95);
    -webkit-backdrop-filter: blur(30px) saturate(1.4);
    backdrop-filter: blur(30px) saturate(1.4);
}

/* Browsers without backdrop-filter get a fully solid panel. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .pjv-mega { background: var(--jv-ink-2); }
}

/* ── 6c. Before/after slider ─────────────────────────────────────────────────
   Markup: .javadi-beforeafter > img.javadi-ba__before + img.javadi-ba__after.
   before-after.js injects the range input and the handle; the range drives
   --javadi-ba-pos, so mouse, touch, keyboard and screen readers all work. */
.javadi-beforeafter {
    --javadi-ba-pos: 50%;
    position: relative;
    overflow: hidden;
    border-radius: 28px;
    height: 480px;
    isolation: isolate;
}

@media (max-width: 767px) {
    .javadi-beforeafter { height: 320px; }
}

.javadi-beforeafter > img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    margin: 0;
}

.javadi-ba__after {
    clip-path: inset(0 0 0 var(--javadi-ba-pos));
}

.javadi-ba__range {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    margin: 0;
    opacity: 0;
    cursor: ew-resize;
    z-index: 4;
    -webkit-appearance: none;
    appearance: none;
}

.javadi-ba__handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--javadi-ba-pos);
    width: 2px;
    background: rgba(255, 255, 255, 0.95);
    box-shadow: 0 0 22px rgba(var(--jv-ink-rgb), 0.55);
    z-index: 3;
    pointer-events: none;
    translate: -1px 0;
}

.javadi-ba__handle::after {
    content: "↔";
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 48px;
    height: 48px;
    display: grid;
    place-items: center;
    border-radius: 999px;
    background: #FFFFFF;
    color: var(--jv-accent-deep);
    font-family: var(--jv-font-display);
    font-size: 19px;
    font-weight: 600;
    box-shadow: 0 8px 22px rgba(var(--jv-ink-rgb), 0.4);
}

.javadi-ba__range:focus-visible ~ .javadi-ba__handle::after {
    outline: 3px solid var(--jv-accent);
    outline-offset: 2px;
}

.javadi-ba__label {
    position: absolute;
    top: 18px;
    z-index: 3;
    padding: 8px 15px;
    border-radius: 999px;
    font-family: var(--jv-font-display);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    pointer-events: none;
}

.javadi-ba__label--before {
    left: 18px;
    background: rgba(var(--jv-ink-rgb), 0.82);
    color: var(--jv-on-dark);
}

.javadi-ba__label--after {
    right: 18px;
    background: var(--jv-accent-deep);
    color: #FFFFFF;
}

/* ── 6c2. Premium footer ─────────────────────────────────────────────────────
   Editorial column heads, hairline separators, links that slide to the
   accent, and a hairline rule above the copyright line. */
.elementor-location-footer {
    position: relative;
}
/* 2px accent rule across the top, brightest in the middle. */
.elementor-location-footer::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 2px;
    z-index: 2;
    background: linear-gradient(90deg,
        transparent 0%,
        color-mix(in srgb, var(--jv-accent) 30%, transparent) 22%,
        var(--jv-accent) 50%,
        color-mix(in srgb, var(--jv-accent) 30%, transparent) 78%,
        transparent 100%);
}

/* A very soft glow beneath that rule, so the edge reads as designed. */
.elementor-location-footer::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 160px;
    pointer-events: none;
    background: radial-gradient(70% 100% at 50% 0%,
        color-mix(in srgb, var(--jv-accent) 10%, transparent), transparent 72%);
}
.elementor-location-footer > * { position: relative; z-index: 1; }

/* Column separators. The four columns sit one level below .e-con-inner;
   the copyright row is its own sibling and must stay unruled. */
.elementor-location-footer .e-con-inner > .e-con:first-child > .e-con + .e-con {
    border-left: 1px solid color-mix(in srgb, var(--jv-paper) 10%, transparent);
    padding-left: clamp(18px, 2.4vw, 38px);
}
@media (max-width: 1024px) {
    .elementor-location-footer .e-con-inner > .e-con:first-child > .e-con + .e-con {
        border-left: 0;
        padding-left: 0;
    }
}

/* Column heads get a short accent underline. */
.elementor-location-footer .elementor-widget-heading:first-child
    .elementor-heading-title {
    position: relative;
    padding-bottom: 12px;
    display: inline-block;
}
.elementor-location-footer .elementor-widget-heading:first-child
    .elementor-heading-title::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0;
    width: 26px;
    height: 2px;
    border-radius: 2px;
    background: var(--jv-accent);
}

/* Copyright row sits under its own hairline, with breathing room. */
.elementor-location-footer .e-con-inner > .e-con:last-child {
    border-top: 1px solid color-mix(in srgb, var(--jv-paper) 9%, transparent);
    margin-top: clamp(28px, 3vw, 46px);
    padding-top: clamp(20px, 2vw, 28px);
}

/* Column headings: small caps with a short accent rule beneath. */
.elementor-location-footer .elementor-widget-heading .elementor-heading-title {
    font-family: "Poppins", sans-serif;
}
.elementor-location-footer h3.elementor-heading-title,
.elementor-location-footer .elementor-widget-heading:first-child .elementor-heading-title {
    letter-spacing: 0.16em;
}

/* Link lists: quiet by default, accent + nudge on hover. */
.elementor-location-footer .elementor-icon-list-item a,
.elementor-location-footer .elementor-widget-text-editor a {
    color: var(--jv-on-dark-soft);
    text-decoration: none;
    transition: color 200ms linear, padding-left 240ms var(--jv-ease);
}
.elementor-location-footer .elementor-icon-list-item a:hover,
.elementor-location-footer .elementor-widget-text-editor a:hover {
    color: var(--jv-accent);
    padding-left: 5px;
}

/* Address block reads as a plate, not raw text. */
.elementor-location-footer .elementor-widget-text-editor p {
    line-height: 1.85;
}

/* ── 6d. Tooth back-to-top ───────────────────────────────────────────────── */
/* Kit button styling would repaint this on hover — every state is pinned. */
.jv-totop,
.jv-totop:hover,
.jv-totop:focus,
.jv-totop:focus-visible,
.jv-totop:active {
    position: fixed;
    right: 18px;
    bottom: 22px;
    z-index: 850;
    width: 54px;
    height: 54px;
    display: grid;
    place-items: center;
    padding: 0;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.25) !important;
    background: var(--jv-accent-deep) !important;
    background-image: none !important;
    color: #fff !important;
    cursor: pointer;
    box-shadow: 0 14px 34px rgba(var(--jv-ink-rgb), 0.45);
    transition: transform 220ms var(--jv-ease), box-shadow 220ms linear,
                background-color 220ms linear;
}
.jv-totop[hidden] { display: none !important; }
/* The viewBox is cropped to the glyph's ink, so no nudge is needed. */
.jv-totop svg {
    fill: currentColor;
    display: block;
}
.jv-totop:hover {
    background: var(--jv-accent) !important;
    color: var(--jv-ink) !important;
    transform: translateY(-4px);
    box-shadow: 0 20px 44px rgba(var(--jv-ink-rgb), 0.55);
}
@media (max-width: 767px) {
    .jv-totop { right: 12px; bottom: 14px; width: 48px; height: 48px; }
}

/* ── 7. Reduced motion ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    [data-reveal],
    [data-reveal].is-revealed,
    .jv-line__inner {
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
        clip-path: none !important;
        transition: none !important;
    }

    .jv-card img,
    .jv-mega {
        transition: none !important;
    }

    .jv-scrollcue::before,
    .jv-scrollcue::after {
        animation: none;
    }
}

/* ── Buttons must read as buttons: shared motion feedback on every button.
      Colours come from each widget's own (Elementor-editable) hover settings;
      this block adds the lift, glow and focus ring the whole site shares. ── */
.elementor-button {
    transition: background-color 180ms ease, color 180ms ease,
                border-color 180ms ease, box-shadow 180ms ease,
                transform 180ms ease;
}
.elementor-button:hover,
.elementor-button:focus-visible {
    transform: translateY(-2px);
    box-shadow: 0 12px 26px rgba(var(--jv-ink-rgb), 0.22);
}
.elementor-button:active {
    transform: translateY(0);
    box-shadow: 0 5px 14px rgba(var(--jv-ink-rgb), 0.18);
}
.elementor-button:focus-visible {
    outline: 2px solid var(--jv-accent);
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .elementor-button,
    .elementor-button:hover,
    .elementor-button:active {
        transform: none;
        transition: none;
    }
}

/* ── 6d. Horizontal rails ────────────────────────────────────────────────────
   The team row is wider than its column and scrolls, but the card at the edge
   simply stopped mid-name and read as a rendering fault rather than as "there
   is more this way". A fade at the trailing edge says the row continues, and
   snapping means a card never comes to rest half-shown. */
.javadi-rail {
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    /* The operating system's scrollbar sat under every rail as a heavy grey
       beam. The arrows are the control now; the bar goes. The rail still
       scrolls by wheel, touch and keyboard. */
    scrollbar-width: none;
    -webkit-mask-image: linear-gradient(to right,
        #000 0, #000 calc(100% - 64px), transparent 100%);
            mask-image: linear-gradient(to right,
        #000 0, #000 calc(100% - 64px), transparent 100%);
}
.javadi-rail::-webkit-scrollbar { display: none; }
.javadi-rail > * { scroll-snap-align: start; }
/* Same trailing-blank fix as .jv-rail: the bleed belongs in the negative
   margin only, never doubled as scrollable padding. */
.elementor-37 .javadi-rail,
.javadi-rail { padding-inline-end: var(--jv-gutter, 24px); }
/* Once the reader has scrolled to the end there is nothing more to hint at,
   so the fade is dropped and the last card is shown whole. */
.javadi-rail.is-rail-end {
    -webkit-mask-image: none;
            mask-image: none;
}

/* Minimal previous/next arrows, laid over the rail's edges by a wrapper the
   script puts around it. One quiet paper chip per side; an arrow that cannot
   go further fades rather than vanishes, so the pair does not jump around. */
.jv-railwrap { position: relative; }
.jv-railbtn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 5;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1px solid rgba(38, 33, 29, 0.22);
    background: var(--jv-paper);
    color: var(--jv-ink);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
    box-shadow: 0 4px 14px rgba(38, 33, 29, 0.14);
    transition: opacity .18s, transform .18s, background-color .18s;
}
.jv-railbtn:hover { background: var(--jv-paper-2); }
.jv-railbtn:focus-visible {
    outline: 2px solid var(--jv-accent-deep);
    outline-offset: 2px;
}
.jv-railbtn:active { transform: translateY(-50%) scale(0.94); }
.jv-railbtn svg { width: 16px; height: 16px; display: block; }
.jv-railbtn--prev { left: -8px; }
.jv-railbtn--next { right: -8px; }
.jv-railbtn[disabled] { opacity: 0.25; pointer-events: none; }
/* Nothing to scroll: no controls at all. */
.jv-railwrap--static .jv-railbtn { display: none; }
@media (max-width: 767px) {
    .jv-railbtn { width: 34px; height: 34px; }
    .jv-railbtn--prev { left: -4px; }
    .jv-railbtn--next { right: -4px; }
}

/* ── Hero: copy on the left, callback card on the right ─────────────────────
   The design moved the callback out of its own band and set it beside the
   headline. 760 + 32 + 400 is exactly the 1192 the hero is boxed to, so the
   two columns are pinned rather than fluid; below 1100 the card drops under
   the copy and stretches. */
.jv-hero-grid {
    align-items: flex-end;
}
.jv-hero-form {
    box-shadow: 0 24px 60px rgba(var(--jv-ink-rgb), 0.28);
}
.jv-hero-form .elementor-widget-heading,
.jv-hero-form .elementor-widget-text-editor { margin-bottom: 0; }

/* Field colours live on the form widget's own controls, so the practice can
   change them from the panel and so they beat Elementor's per-element rule.
   What is left here is the one thing the panel cannot express: a select is
   rendered as a box inside a box, and both were being painted — the inner
   one then sat 15px in from the outer, which read as a misaligned field.
   Only the wrapper keeps the box; the select itself becomes plain. */
.jv-hero-form .elementor-field-group .elementor-select-wrapper {
    padding: 0;
    border: 0;
    background: transparent;
    border-radius: 0;
    display: flex;
    align-items: center;
    position: relative;
}
.jv-hero-form .elementor-field-group .elementor-select-wrapper select {
    width: 100%;
}
/* The chevron is drawn on the wrapper, so it has to be pulled back inside
   the field now that the wrapper carries no padding of its own. */
.jv-hero-form .elementor-field-group .elementor-select-wrapper::before {
    right: 14px;
}
.jv-hero-form .elementor-field-group > label {
    margin-bottom: 6px;
}
/* Elementor pulls the field rows 5px outward and pads each group back in.
   Dropping the outward pull leaves the fields 338 wide inside the card's
   348 — the inset the design draws. */
.elementor-37 .jv-hero-form .elementor-form-fields-wrapper.elementor-labels-above {
    margin-left: 0;
    margin-right: 0;
}
.jv-hero-form .elementor-field-group .elementor-field:focus,
.jv-hero-form .elementor-field-group select:focus {
    outline: none;
    border-color: var(--jv-accent-deep);
    box-shadow: 0 0 0 3px rgba(138, 107, 66, 0.18);
}
.jv-hero-form .elementor-field-type-acceptance .elementor-field-label,
.jv-hero-form .elementor-field-type-acceptance label {
    font-size: 14px;
    line-height: 22px;
    color: var(--jv-on-light-mute);
}
.jv-hero-form .elementor-button[type="submit"] {
    border-radius: 999px;
    background: var(--jv-accent);
    color: var(--jv-ink);
    font-weight: 600;
    padding: 13px 28px;
}
.jv-hero-form .elementor-button[type="submit"]:hover,
.jv-hero-form .elementor-button[type="submit"]:focus-visible {
    background: var(--jv-accent-deep);
    color: var(--jv-paper);
}

@media (max-width: 1100px) {
    .jv-hero-grid { flex-wrap: wrap; }
    .jv-hero-grid > .e-con,
    .jv-hero-grid > .e-con-inner > .e-con { width: 100% !important; }
}

/* ── Behandlungen: the design drops the tick and marks the row with a small
   triangle in the deep accent. ─────────────────────────────────────────── */
.jv-sec-behandlungen .elementor-icon-list-icon { display: none; }
.jv-sec-behandlungen .elementor-icon-list-item > a::after,
.jv-sec-behandlungen .elementor-icon-list-item > span::after {
    content: "\25B8";
    color: var(--jv-accent-deep);
    /* the glyph sits well inside its em box, so it needs a larger size to
       read at the 14px the design draws. */
    font-size: 22px;
    line-height: 1;
}

/* ── A band that carries a photograph behind its copy ───────────────────── */
.jv-band-photo { position: relative; isolation: isolate; }

/* ── Awards strip: the design drops the white tiles and prints the marks in
   one muted tone on the warm band. The logo files carry white boxes, so
   multiply lifts them off the tint instead of masking each one by hand. ── */
.jv-sec-awards-strip .elementor-widget-image img {
    height: 54px;
    width: auto;
    object-fit: contain;
    filter: grayscale(1) contrast(1.04);
    opacity: 0.72;
    mix-blend-mode: multiply;
}
.jv-sec-awards-strip .elementor-widget-image { box-shadow: none; }

/* ── Picture corners and crops, to the design's own radii ───────────────────
   Elementor's kit prints `border-radius: 0` on images, so these have to carry
   a class each and win on specificity. The children's photographs are tall
   portraits in landscape frames: anchoring the crop to the top keeps the face
   in shot instead of slicing it at the eyes. */
.elementor-37 .elementor-widget-image.jv-profil-pic img,
.elementor-37 .elementor-widget-image.jv-dvt-pic img,
.elementor-37 .elementor-widget-image.jv-cta-pic img,
.elementor-37 .elementor-widget-image.jv-kinder-pic img {
    display: block;
    width: 100%;
    border-radius: 22px;
}
.elementor-37 .elementor-widget-image.jv-dvt-pic img {
    border-radius: 28px;
    object-fit: cover;
}
.elementor-37 .elementor-widget-image.jv-kinder-pic img {
    border-radius: 20px;
    object-fit: cover;
    object-position: center 22%;
}
.elementor-37 .elementor-widget-image.jv-pic-r20 img {
    border-radius: 20px;
    display: block;
    width: 100%;
}
/* Inside a card that already clips its corners, the photograph must stay
   square — otherwise the card's white ground shows as two slivers on top. */
.elementor-37 .elementor-widget-image.jv-flush img {
    border-radius: 0;
    display: block;
    width: 100%;
}

/* ── KONTAKT | TERMIN floating button ────────────────────────────────────────
   Geometry, type and behaviour are the old site's, value for value: 230px
   pill, 14px radius, DM Sans 12/500 with 1px tracking, panel 70px above it.
   Only the colours are translated into this site's palette — the old teal
   would have been the one thing on the page from another brand.

   The relationships are kept rather than the hex codes: solid deep accent
   with paper type, hover lifting to the light accent on ink, dark elevated
   surface for the panel. The kit paints every <button>, so each state is
   pinned or the pill turns into the theme's own button on hover. */
.contact-fab,
.contact-fab:hover,
.contact-fab:focus,
.contact-fab:focus-visible,
.contact-fab:active {
    position: fixed;
    bottom: 20px;
    right: 20px;
    width: 230px;
    padding: 14px 20px;
    box-sizing: border-box;
    border: 0;
    border-radius: 14px;
    /* The practice asked for the old site's petrol/ice-blue pair here:
       brown on brown did not separate from the page. Fixed hexes on
       purpose - this element deliberately steps outside the palette. */
    background: #004962;
    color: #fff;
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 1px;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    text-transform: none;
    cursor: pointer;
    z-index: 1000;
    box-shadow: 0 6px 18px rgba(var(--jv-ink-rgb), 0.28);
    transition: background 0.3s ease, color 0.3s ease,
                transform 0.2s ease, box-shadow 0.2s ease;
}
.contact-fab:hover,
.contact-fab:focus-visible {
    background: #9fe3ff;
    color: #004962;
    transform: scale(1.06);
    box-shadow: 0 10px 24px rgba(var(--jv-ink-rgb), 0.34);
}
.contact-fab:focus-visible {
    outline: 2px solid #9fe3ff;
    outline-offset: 3px;
}
.contact-fab:active {
    background: #9fe3ff;
    color: #004962;
    transform: scale(0.98);
    box-shadow: 0 2px 8px rgba(var(--jv-ink-rgb), 0.4);
}

.contact-panel {
    position: fixed;
    bottom: 70px;
    right: 20px;
    width: 230px;
    padding: 16px 20px;
    box-sizing: border-box;
    background-color: #004962;
    color: #fff;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 14px;
    box-shadow: 0 6px 18px rgba(var(--jv-ink-rgb), 0.36);
    z-index: 999;
    font-family: 'DM Sans', sans-serif;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(10px);
    /* visibility flips at the end of the fade rather than being interpolated,
       which is what leaves a panel stranded half-open when a tab is throttled */
    transition: opacity 0.35s ease, transform 0.35s ease,
                visibility 0s linear 0.35s;
}
.contact-panel.show {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
    transition: opacity 0.35s ease, transform 0.35s ease, visibility 0s;
}
.contact-panel p { margin: 8px 0; font-size: 0.95rem; }
.contact-panel hr { border: 0; border-top: 1px solid rgba(244, 241, 234, 0.16); margin: 8px 0; }
.contact-panel a { color: var(--jv-paper); text-decoration: none; font-weight: 300; }
.contact-panel a:hover,
.contact-panel a:focus-visible { color: #9fe3ff; text-decoration: none; }

/* ── Certificate strip: no double white ground, larger, quicker ─────────────
   Each frame sat in a white card on the paper band; multiply lets the
   photograph's own white ground take the band's colour instead. */
.javadi-marquee .e-con.e-child {
    background: transparent !important;
}
/* No blending here: the animated transform isolates the track's
   compositing group, so the band's paper tone is baked into the
   photographs themselves (the -papier copies). */
.javadi-marquee .elementor-widget-image img {
    height: clamp(240px, 24vw, 330px) !important;
    width: auto !important;
    max-width: none !important;
}
.javadi-marquee-track {
    animation-duration: 45s !important;
}

.contact-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.contact-row img,
.contact-row .contact-row__icon { flex-shrink: 0; }
.contact-row .contact-row__icon { color: #9fe3ff; display: block; }
.contact-panel a:hover .contact-row__icon,
.contact-panel a:focus-visible .contact-row__icon { color: #fff; }
.contact-row span,
.contact-row a { max-width: calc(100% - 40px); }

@media (max-width: 600px) {
    .contact-fab,
    .contact-fab:hover,
    .contact-fab:focus,
    .contact-fab:focus-visible,
    .contact-fab:active {
        bottom: 15px;
        right: 15px;
        width: 190px;
        padding: 10px 20px;
    }
    .contact-panel { right: 15px; width: 190px; bottom: 62px; }
}

/* The scroll-to-top control moves to the opposite corner: the contact pill
   now owns the bottom right, and two round targets on top of each other is
   how a call-to-action gets missed. */
.jv-totop,
.jv-totop:hover,
.jv-totop:focus,
.jv-totop:focus-visible,
.jv-totop:active {
    right: auto !important;
    left: 18px !important;
}

/* ── Dr-Javadi profile band ─────────────────────────────────────────────── */
.elementor-37 .elementor-widget-image.jv-profil-pic img {
    width: 100%;
    height: 620px;
    object-fit: cover;
    object-position: center 30%;
    border-radius: 22px;
    display: block;
}

/* ── DGOI band on dark ──────────────────────────────────────────────────── */
.elementor-37 .jv-sec-dgoi .elementor-widget-image img {
    border-radius: 10px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.32);
}
.jv-sec-profil .elementor-widget-heading,
.jv-sec-profil .elementor-widget-text-editor { margin-bottom: 0; }
@media (max-width: 1024px) {
    .jv-sec-profil .jv-profil-pic img { height: 420px; }
}
@media (max-width: 767px) {
    /* The studio portrait sits black-on-black inside the dark band and the
       person disappears on small screens; a lift pulls him back out. */
    .jv-sec-profil .jv-profil-pic img {
        filter: brightness(1.32) contrast(1.04);
    }
    /* Rail arrows sit over the captions at phone widths; the rail swipes
       natively there, so the buttons step aside. */
    .jv-railbtn {
        display: none !important;
    }
}


/* ── Rueckruf popup (dokuman 696) ──────────────────────────────────────────
   The popup renders outside the page wrapper, so the kit's pink link
   default leaks in; links take the palette instead. */
.elementor-popup-modal .elementor-696 a {
    color: var(--jv-accent-deep) !important;
    text-decoration: underline;
}
.elementor-popup-modal .elementor-696 a:hover,
.elementor-popup-modal .elementor-696 a:focus-visible {
    color: var(--jv-ink) !important;
}


/* ── Footer ayrimi ─────────────────────────────────────────────────────────
   Service pages end on an ink-2 band and the footer painted the very same
   tone - one continuous surface. The footer now sits a step deeper with a
   hairline, so the boundary reads on every page. */
.elementor-location-footer .e-con.e-parent {
    background-color: var(--jv-ink) !important;
}
.elementor-location-footer > .elementor-element:first-child,
.elementor-location-footer .e-con.e-parent:first-child {
    border-top: 1px solid rgba(244, 241, 234, 0.14);
}

/* ── Footer tipografisi ────────────────────────────────────────────────────
   Pure white sat cold inside the warm palette; the footer now speaks the
   same paper tones as every other dark band. */
.elementor-location-footer .elementor-heading-title {
    color: var(--jv-paper) !important;
}
.elementor-location-footer,
.elementor-location-footer p,
.elementor-location-footer a,
.elementor-location-footer .elementor-icon-list-text,
.elementor-location-footer .e-n-accordion-item-title-text {
    color: rgba(244, 241, 234, 0.78) !important;
}
.elementor-location-footer a:hover,
.elementor-location-footer a:focus-visible {
    color: var(--jv-accent) !important;
}

/* Kart siralarindaki butonlar tek hizada biter: anasayfanin Drei-Wege
   bandi ve hizmet sayfalarinin koyu kapanis bantlari. Fazla bosluk yoksa
   auto-marj etkisizdir, o yuzden kurala takilan baska kart bozulmaz. */
.elementor-element-15dc6bcc .e-con.e-child > .elementor-widget-button,
.jv-draft-dark .e-con.e-child > .elementor-widget-button {
    margin-top: auto;
}


/* Mobil hero fotografi yalnizca telefon genisliginde; cihaz cevrilirse
   (>=768px) figur gizlenir ve Elementor'un kendi arka plani geri gelir. */
.jv-hero-mobilfoto { display: none; }

/* ── Servis hero'lari mobil: duz zemin + basligin altinda fotograf ─────── */
@media (max-width: 767px) {
    .jv-subheader.jv-hero-flat {
        background-image: none !important;
        background-color: var(--jv-ink-2) !important;
    }
    .jv-subheader.jv-hero-flat > .elementor-background-overlay {
        display: none !important;
    }
    /* Hero'nun ust boslugu iki kez sayiliyordu (dis 104 + Elementor'un ic
       104); duz zeminde basligi yukari alip nefes payini koruyoruz. */
    .jv-subheader.jv-hero-flat {
        padding-top: 56px !important;
    }
    .jv-hero-mobilfoto {
        display: block;
        margin: 18px 0 24px;
        align-self: stretch;
        width: 100%;
    }
    .jv-hero-mobilfoto img {
        display: block;
        width: 100%;
        height: clamp(240px, 66vw, 330px);
        object-fit: cover;
        object-position: 50% 42%;
        border-radius: 18px;
        box-shadow: 0 16px 34px rgba(0, 0, 0, .34);
    }
    /* Cocuk fotografinda yuz merkezin biraz altinda. */
    .jv-kids .jv-hero-mobilfoto img {
        object-position: 50% 56%;
    }
}
