/* =====================================================================
   LeadWin landing page (agent.feedbax.*) — page-scoped styles.

   Deliberately NOT imported into app.css: the landing's ~50 keyframes and
   demo choreography would weigh down every app page and its generic names
   would collide with global keyframes. Linked only by
   _LeadWinLandingLayout.cshtml; everything color-bearing uses the semantic
   tokens from tokens.css so the page follows light/dark automatically.
   Layout/typography of the sections lives in Tailwind utilities in the
   partials — this file carries only what utilities cannot: keyframes,
   state-driven classes toggled by agent-landing.js, and demo styling.
   ===================================================================== */

/* ---------- shared helpers ---------- */

.la-page {
    min-height: 100vh;
    background: var(--bg);
    color: var(--primary);
}

/* In-page jumps (the hero's example button, the menu's on-page links) glide instead of cutting, and stop
   below the sticky 68px header rather than under it. Only where the visitor has not asked for less motion. */
html:has(> body.la-page) {
    scroll-padding-top: 84px;
}

@media (prefers-reduced-motion: no-preference) {
    html:has(> body.la-page) {
        scroll-behavior: smooth;
    }
}

/* Hidden-scrollbar scroll areas inside the widget demos. */
.la-scroll {
    scrollbar-width: none;
    -ms-overflow-style: none;
    scroll-behavior: smooth;
}

.la-scroll::-webkit-scrollbar {
    display: none;
}

/* Scroll progress bar under the sticky header; scaleX is set from JS.
   The brand's two stops, laid flat: the bar spans the whole header, so a sweep at 135deg would show almost
   none of its travel. It used to run the accent through a violet into sky blue — three stops and a colour
   the product does not own, which put the loudest horizontal line on the page outside the palette
   everything under it is painted in. */
.la-progress {
    display: block;
    height: 3px;
    background: linear-gradient(90deg, var(--leadwin-gradient-from), var(--leadwin-gradient-to));
    transform: scaleX(0);
    transform-origin: left;
    will-change: transform;
}

/* ---------- entrance / ambient keyframes ---------- */

@keyframes la-rise {
    from { opacity: 0; transform: translateY(26px); }
    to { opacity: 1; transform: none; }
}

@keyframes la-soft {
    from { opacity: 0; transform: translateY(10px); }
    to { opacity: 1; transform: none; }
}

@keyframes la-orbit {
    0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
    50% { transform: translate3d(40px, -30px, 0) scale(1.1); }
}

@keyframes la-glow {
    0%, 100% { opacity: .6; transform: translate(0, 0); }
    50% { opacity: 1; transform: translate(-24px, 18px); }
}

@keyframes la-dot {
    0%, 60%, 100% { opacity: .25; transform: translateY(0); }
    30% { opacity: 1; transform: translateY(-3px); }
}

@keyframes la-bar {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
}

@keyframes la-caret {
    0%, 49% { opacity: 1; }
    50%, 100% { opacity: 0; }
}

/* Hero headline word rotation (4 words, 13s cycle). */
@keyframes la-word1 {
    0%, 21% { opacity: 1; transform: translateY(0); }
    25%, 93% { opacity: 0; transform: translateY(-18px); }
    94%, 96% { opacity: 0; transform: translateY(18px); }
    100% { opacity: 1; transform: translateY(0); }
}

@keyframes la-word2 {
    0%, 21% { opacity: 0; transform: translateY(18px); }
    25%, 46% { opacity: 1; transform: translateY(0); }
    50%, 100% { opacity: 0; transform: translateY(-18px); }
}

@keyframes la-word3 {
    0%, 46% { opacity: 0; transform: translateY(18px); }
    50%, 71% { opacity: 1; transform: translateY(0); }
    75%, 100% { opacity: 0; transform: translateY(-18px); }
}

@keyframes la-word4 {
    0%, 71% { opacity: 0; transform: translateY(18px); }
    75%, 93% { opacity: 1; transform: translateY(0); }
    96%, 100% { opacity: 0; transform: translateY(-18px); }
}

/* Sparkle icon inside the widget launcher bubbles. */
@keyframes la-spark {
    0%, 100% { opacity: .4; transform: scale(.7); }
    50% { opacity: 1; transform: scale(1); }
}

@keyframes la-spark-main {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.1); }
}

/* ---------- animation hook classes ---------- */

.la-anim-rise { animation: la-rise .7s ease-out both; }
.la-anim-rise-1 { animation: la-rise .7s ease-out .08s both; }
.la-anim-rise-2 { animation: la-rise .7s ease-out .16s both; }
.la-anim-rise-3 { animation: la-rise .7s ease-out .22s both; }
.la-anim-soft { animation: la-soft .6s ease-out both; }

.la-word { position: absolute; inset: 0; }
.la-word-1 { animation: la-word1 13s ease-in-out infinite; }
.la-word-2 { animation: la-word2 13s ease-in-out infinite; }
.la-word-3 { animation: la-word3 13s ease-in-out infinite; }
.la-word-4 { animation: la-word4 13s ease-in-out infinite; }

/* Rotating words (initRotators in agent-landing.js): stacked in one cell, the words not on show
   aria-hidden. The script sets the rotator's height to the shown word's, and the height glides. A group's
   rotator inside a word turns its endings behind a prefix that stays; its height does not glide by itself,
   so the outer rotator can read the group's new height at once and glide for both. */
.la-rotator {
    display: grid;
    transition: height .5s cubic-bezier(.2, .8, .2, 1);
}

.la-rotator .la-rotator {
    transition: none;
}

.la-rotator-item {
    grid-area: 1 / 1;
    align-self: start;
    opacity: 1;
    translate: 0 0;
    visibility: visible;
    transition: opacity .45s ease .15s, translate .6s cubic-bezier(.2, .8, .2, 1) .15s, visibility 0s linear 0s;
}

.la-rotator-item[aria-hidden="true"] {
    opacity: 0;
    translate: 0 .35em;
    visibility: hidden;
    transition: opacity .35s ease, translate .5s cubic-bezier(.2, .8, .2, 1), visibility 0s linear .35s;
}

/* A beat's title breaks only a word too long for the column ("Unternehmensprofil"), never an ordinary
   one ("Exper-ten", "di-rekt"): a browser that can limit hyphenation hyphenates words of 14 letters and
   more only, any other breaks a word only where it would run out of the column, without a hyphen. */
.la-beat-title {
    overflow-wrap: break-word;
}

@supports (hyphenate-limit-chars: 14 6 6) {
    .la-beat-title {
        hyphens: auto;
        hyphenate-limit-chars: 14 6 6;
    }
}

/* Hero beats: the title and description of the phase the demo is in. LeadWinAuthDemo.razor.js names the
   phase on the stage (data-demo-beat); before it runs, the first one shows. The texts of one kind share a
   grid cell and cross-fade. Only from lg, where the demo plays beside the text: below it the demo stands
   under the text, out of view while somebody reads, so the promise stays and the other beats take no room. */
.la-beat {
    grid-area: 1 / 1;
    opacity: 0;
    translate: 0 12px;
    visibility: hidden;
    transition: opacity .4s ease, translate .6s cubic-bezier(.2, .8, .2, 1), visibility 0s linear .4s;
}

@media (max-width: 1023.98px) {
    .la-beat[data-beat="intro"] {
        opacity: 1;
        translate: 0 0;
        visibility: visible;
    }

    .la-beat:not([data-beat="intro"]) {
        display: none;
    }
}

@media (min-width: 1024px) {
    [data-demo-stage]:not([data-demo-beat]) .la-beat[data-beat="intro"],
    [data-demo-stage][data-demo-beat="intro"] .la-beat[data-beat="intro"],
    [data-demo-stage][data-demo-beat="visit"] .la-beat[data-beat="visit"],
    [data-demo-stage][data-demo-beat="answer"] .la-beat[data-beat="answer"],
    [data-demo-stage][data-demo-beat="brief"] .la-beat[data-beat="brief"],
    [data-demo-stage][data-demo-beat="expert"] .la-beat[data-beat="expert"],
    [data-demo-stage][data-demo-beat="book"] .la-beat[data-beat="book"],
    [data-demo-stage][data-demo-beat="lead"] .la-beat[data-beat="lead"] {
        opacity: 1;
        translate: 0 0;
        visibility: visible;
        transition: opacity .5s ease .2s, translate .7s cubic-bezier(.2, .8, .2, 1) .2s, visibility 0s linear 0s;
    }
}

.la-glow-blob { animation: la-glow 14s ease-in-out infinite; }
.la-orbit-blob { animation: la-orbit 26s ease-in-out infinite; }
.la-orbit-blob-reverse { animation: la-orbit 26s ease-in-out infinite reverse; }
.la-spark-main { transform-origin: 9px 12px; animation: la-spark-main 2.6s ease-in-out infinite; }
.la-spark-top { transform-origin: 18px 6px; animation: la-spark 2.6s ease-in-out infinite; }
.la-spark-bottom { transform-origin: 16.5px 18.75px; animation: la-spark 2.6s ease-in-out 1.3s infinite; }

.la-typing-dot { animation: la-dot 1.2s ease-in-out infinite; }
.la-typing-dot:nth-child(2) { animation-delay: .18s; }
.la-typing-dot:nth-child(3) { animation-delay: .36s; }

.la-caret {
    display: inline-block;
    width: 8px;
    height: 16px;
    margin-left: 2px;
    vertical-align: -2px;
    background: #a5b4fc;
    animation: la-caret 1s steps(1) infinite;
}

/* ---------- mega menu (state toggled by JS) ----------
   Fades both ways: visibility waits for the fade on the way out and flips at once on the way in,
   so the closed card neither shows nor takes clicks, and nothing pops out of existence. */

.la-menu-panel {
    visibility: hidden;
    opacity: 0;
    transform: translateY(-6px);
    pointer-events: none;
    transition: opacity .18s ease-out, transform .18s ease-out, visibility 0s linear .18s;
}

.la-menu-panel.la-open {
    visibility: visible;
    opacity: 1;
    transform: none;
    pointer-events: auto;
    transition: opacity .18s ease-out, transform .18s ease-out, visibility 0s;
}

.la-menu-chevron { transition: transform .2s; }

/* ---------- language switcher (native details; JS animates it and closes it on an outside click) ----------
   Only once JS has marked the element (.la-js): without the script the native details must keep
   showing its list, so the hidden resting state is opt-in. The list is display:none while the
   details is closed, so the fade only needs an opacity/transform pair; JS adds .la-open a frame
   after opening and removes it a moment before closing, which is what the two directions animate. */

.la-lang.la-js > nav {
    opacity: 0;
    transform: translateY(-6px) scale(.98);
    transform-origin: top right;
    transition: opacity .16s ease-out, transform .16s ease-out;
}

.la-lang.la-js.la-open > nav {
    opacity: 1;
    transform: none;
}

@media (prefers-reduced-motion: reduce) {
    .la-lang.la-js > nav { transition: none; }
}

.la-menu-trigger.la-open .la-menu-chevron { transform: rotate(180deg); }

.la-menu-trigger.la-open {
    background: var(--color-surface-blue-strong);
    color: var(--color-brand);
}

/* Mobile nav: full-height panel under the sticky header, burger flips to an X. */
.la-mobile-panel { display: none; }

.la-mobile-panel.la-open {
    display: block;
    animation: la-soft .25s ease-out both;
}

.la-mobile-trigger .la-burger-close { display: none; }

.la-mobile-trigger.la-open .la-burger-close { display: block; }

.la-mobile-trigger.la-open .la-burger-open { display: none; }

/* ---------- conversation timeline ---------- */

/* Timeline rail: dot, connecting line and label follow the active stage. */
.la-timeline-dot {
    height: 14px;
    width: 14px;
    border-radius: 9999px;
    background: var(--border);
    transition: background .3s;
}

.la-timeline-line {
    flex: 1;
    width: 2px;
    background: var(--border);
    transition: background .4s;
}

.la-timeline-title {
    color: var(--muted);
    transition: color .3s;
}

.la-timeline-step.la-active .la-timeline-title { color: var(--primary); }

.la-timeline-step.la-active .la-timeline-line { background: #c7d2fe; }

.la-timeline-step.la-active .la-timeline-dot-1 { background: var(--brand); }
.la-timeline-step.la-active .la-timeline-dot-2 { background: #7c3aed; }
.la-timeline-step.la-active .la-timeline-dot-3 { background: #0369a1; }
.la-timeline-step.la-active .la-timeline-dot-4 { background: #047857; }

.dark .la-timeline-step.la-active .la-timeline-line { background: #4338ca; }

/* ---------- platform tabs (#bereiche) ---------- */

.la-tab-panel { display: none; }

.la-tab-panel.la-active {
    display: block;
    animation: la-soft .4s ease-out both;
}

.la-tab-progress {
    display: block;
    height: 3px;
    transform-origin: left;
    animation: la-bar 8s linear both;
}

/* When autoplay stops (user picked a tab) the progress bar holds full width. */
.la-tabs-manual .la-tab-progress { animation: none; transform: scaleX(1); }

/* ---------- FAQ (native details/summary) ---------- */

.la-faq details > summary {
    list-style: none;
    cursor: pointer;
}

.la-faq details > summary::-webkit-details-marker { display: none; }

.la-faq-icon {
    position: relative;
    display: inline-flex;
    height: 16px;
    width: 16px;
    flex-shrink: 0;
    align-items: center;
    justify-content: center;
    color: var(--brand);
}

.la-faq-icon::before,
.la-faq-icon::after {
    content: "";
    position: absolute;
    border-radius: 2px;
    background: currentColor;
}

.la-faq-icon::before {
    height: 2px;
    width: 100%;
}

.la-faq-icon::after {
    height: 100%;
    width: 2px;
    transition: transform .2s, opacity .2s;
}

/* A closing details keeps its open flag until pricing-page.js has slid it shut; the icon turns at once. */
.la-faq details[open]:not(.is-closing) .la-faq-icon::after {
    transform: scaleY(0);
    opacity: 0;
}

/* ---------- konfigurator (accent + appearance via custom properties) ---------- */

/* JS sets --la-accent / --la-accent-soft on .la-config and toggles
   .la-config-dark for the preview's own dark appearance (independent of
   the page theme: the visitor styles the widget for THEIR site). */
.la-config {
    --la-accent: var(--brand);
    --la-accent-soft: rgba(0, 0, 255, .1);
    --la-preview-bg: #f6f6f7;
    --la-skel-strong: #e4e4e7;
    --la-skel-soft: #ededf0;
    --la-panel-bg: #ffffff;
    --la-panel-border: #e4e4e7;
    --la-panel-text: #18181b;
    --la-agent-msg-bg: #f4f4f5;
    --la-input-bg: #f4f4f5;
    --la-placeholder: #a1a1aa;
}

.la-config.la-config-dark {
    --la-preview-bg: #101014;
    --la-skel-strong: #26262c;
    --la-skel-soft: #1b1b21;
    --la-panel-bg: #1b1b21;
    --la-panel-border: #2a2a32;
    --la-panel-text: #e4e4e7;
    --la-agent-msg-bg: #26262c;
    --la-input-bg: #26262c;
    --la-placeholder: #71717a;
}

.la-swatch {
    height: 40px;
    width: 40px;
    cursor: pointer;
    border: 0;
    border-radius: 13px;
    transition: box-shadow .2s, transform .2s;
    box-shadow: 0 0 0 3px var(--surface), 0 0 0 4px var(--border);
}

.la-swatch.la-active {
    transform: translateY(-3px);
    box-shadow: 0 0 0 3px var(--surface), 0 0 0 5px currentColor;
}

.la-config-widget {
    position: absolute;
    bottom: 26px;
    right: 26px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 14px;
    transition: all .35s;
}

.la-config.la-config-left .la-config-widget {
    right: auto;
    left: 26px;
    align-items: flex-start;
}

/* Toggle pills shared by konfigurator, tabs and the pricing interval switch. */
/* Zinc literals: this file sits outside the Tailwind pipeline, theme() is
   not available here. Values mirror zinc-100/800/900 from tokens usage. */
.la-pill {
    cursor: pointer;
    font-family: inherit;
    border: 0;
    border-radius: 9999px;
    padding: 9px 18px;
    font-size: 14px;
    font-weight: 500;
    background: #f4f4f5;
    color: var(--primary);
    transition: background .2s, color .2s;
}

.dark .la-pill { background: #27272a; }

.la-pill.la-active {
    background: #18181b;
    color: #fff;
    font-weight: 600;
}

.dark .la-pill.la-active {
    background: #f4f4f5;
    color: #18181b;
}

/* ---------- reduced motion ---------- */

@media (prefers-reduced-motion: reduce) {
    .la-anim-rise,
    .la-anim-rise-1,
    .la-anim-rise-2,
    .la-anim-rise-3,
    .la-anim-soft,
    .la-glow-blob,
    .la-orbit-blob,
    .la-orbit-blob-reverse,
    .la-word-1,
    .la-word-2,
    .la-word-3,
    .la-word-4,
    .la-spark-main,
    .la-spark-top,
    .la-spark-bottom,
    .la-typing-dot,
    .la-caret,
    .la-tab-progress,
    .la-eyebrow-dot,
    .la-presence-dot,
    .la-ob-head-l,
    .la-ob-head-r,
    .la-ob-msg-1,
    .la-ob-msg-2,
    .la-ob-msg-3,
    .la-ob-status-1,
    .la-ob-status-2,
    .la-ob-status-3,
    .la-ob-note-1,
    .la-ob-note-2,
    .la-ob-journey,
    .la-ob-presence,
    .la-ob-chat-1,
    .la-ob-chat-2,
    .la-ob-chat-3,
    .la-ob-outcome,
    .la-ob-step {
        animation: none;
    }

    /* Safety net for a mid-session switch to reduced motion: initSequences bails out before it
       ever sets the class, but if it is already on the section the gate must not strand it. */
    [data-la-sequence].la-seq-idle * {
        animation-play-state: running;
    }

    /* The panels open and close by switching `display`, so dropping their entrance
       animation only removes the fade — the panel still appears. */
    .la-mobile-panel.la-open,
    .la-tab-panel.la-active {
        animation: none;
    }

    .la-menu-panel,
    .la-menu-panel.la-open {
        transition: none;
    }

    .la-word { position: static; }

    .la-beat,
    .la-rotator,
    .la-rotator-item {
        transition: none;
    }

    .la-word-2,
    .la-word-3,
    .la-word-4 {
        display: none;
    }
}

/* ---------- theme toggle ---------- */

/* Both glyphs are in the markup and CSS picks the one that fits, so the button is already correct in the
   HTML the server sent — before agent-landing.js has run and without a flash of the wrong icon. The icon
   shows the theme a click switches TO, which is why the moon hides once the page is already dark. */
.la-theme-sun { display: none; }

.dark .la-theme-moon { display: none; }

.dark .la-theme-sun { display: block; }

/* ---------- legal pages ---------- */

/* Long-form CMS text (legal notice, privacy, terms, terms of use): the body comes out of the
   rich-text editor, so its elements carry no utility classes — this is the one place the landing
   styles bare tags. Kept to what a legal text needs; anything fancier belongs in the editor. */
.la-legal {
    font-size: 15px;
    line-height: 1.7;
    color: var(--secondary);

    /* A privacy text is the one long-form document on this site that is FULL of unbreakable strings:
       every processor it names comes with its opt-out URL, and a supervisory authority with an address
       nobody shortened. At 375px a single "https://policies.google.com/technologies/partner-sites?hl=de"
       is wider than the column, and an overflowing inline box widens the page itself — the reader then
       swipes a whole legal text sideways to read any of it. Breaking mid-word is allowed only where a
       word cannot fit at all, so ordinary German compounds still wrap at their spaces. */
    overflow-wrap: anywhere;
}

.la-legal h2 {
    margin: 2.25rem 0 0.75rem;
    font-size: 1.25rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    color: var(--primary);
}

.la-legal h3 {
    margin: 1.5rem 0 0.5rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--primary);
}

.la-legal h4 {
    margin: 1.25rem 0 0.5rem;
    font-size: 0.9375rem;
    font-weight: 600;
    color: var(--primary);
}

.la-legal p {
    margin: 0 0 0.9rem;
}

.la-legal ul,
.la-legal ol {
    margin: 0 0 1rem 1.25rem;
    padding: 0;
}

.la-legal ul {
    list-style: disc;
}

.la-legal ol {
    list-style: decimal;
}

.la-legal li {
    margin-bottom: 0.35rem;
}

.la-legal a {
    color: var(--brand);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.la-legal strong {
    font-weight: 600;
    color: var(--primary);
}

/* The one element of a legal text that cannot be made to wrap: a four-column processor table has a
   minimum width of its own, and on a phone that width is larger than the screen. The page wraps every
   table in the app's shared .table-wrapper (TableWrapperMarkup), which scrolls it in its own box, draws
   the rounded frame and sets the header row apart, exactly as around the tables of a help-center
   article. What stays here is the table's own width and type size inside that frame. */
.la-legal table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

/* Cells take back the break-anywhere of the column above. In a table it does more than wrap a long URL:
   it shrinks every column's minimum width to a single letter, so the browser squeezes the narrow columns
   down to "Untern|ehmen" to give the widest one its room. break-word still wraps a URL that cannot fit,
   but only after a column has been given the width of its longest word; a table that then outgrows a
   phone scrolls in its own box (above). */
.la-legal th,
.la-legal td {
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--border);
    text-align: left;
    vertical-align: top;
    overflow-wrap: break-word;
}

.la-legal hr {
    margin: 2rem 0;
    border: 0;
    border-top: 1px solid var(--border);
}
