/* /kokeile — self-service demo page. Reuses landing.css tokens and base classes;
   this file only adds the demo-specific input row + browser-frame placeholder. */

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.kokeile-hero {
    padding-bottom: 80px;
}

/* URL input + submit row */
.kokeile-form {
    display: flex;
    gap: 12px;
    max-width: 640px;
    margin: 0 auto 56px;
    align-items: stretch;
}

.kokeile-input {
    flex: 1;
    min-width: 0;
    padding: 14px 18px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border-strong);
    border-radius: 12px;
    font-family: inherit;
    font-size: 1rem;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.kokeile-input::placeholder {
    color: var(--text-muted);
}

.kokeile-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-dim);
}

.kokeile-submit {
    flex-shrink: 0;
    padding: 14px 28px;
    font-size: 1rem;
    border-radius: 12px;
}

@media (max-width: 640px) {
    .kokeile-form {
        flex-direction: column;
    }
    .kokeile-submit {
        width: 100%;
    }
}

/* Disclaimer line sitting directly below the URL input row, always visible
   regardless of state. Negative top margin tightens the gap to the form. */
.kokeile-disclaimer {
    max-width: 640px;
    margin: -19px auto 50px;
    color: var(--text-muted);
    font-size: 0.85rem;
    text-align: center;
    line-height: 1.5;
    font-style: italic;
}

/* Browser-frame. The frame is the dominant thing on screen and the visitor
   scrolls the screenshot inside it rather than juggling two scroll contexts.
   The default rules below are mobile: width fills the viewport (minus a 12px
   gutter each side) and height uses 100dvh — dynamic viewport height, which
   tracks the mobile browser URL bar correctly. The 140px reserve leaves room
   for the site header, the URL input row above, and a hint of the CTA below.
   Desktop sizing is in the min-width: 768px block further down. */
.kokeile-demo-wrap {
    display: flex;
    justify-content: center;
}

.kokeile-frame {
    position: relative;
    width: calc(100vw - 24px);
    height: calc(100dvh - 140px);
    background: var(--bg-secondary);
    border: 1px solid var(--border-strong);
    border-radius: 18px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
}

/* Desktop: a large, browser-window-sized frame. .kokeile-demo-wrap sits outside
   the narrow hero text column (see kokeile/index.html) so it can simply be
   centered at up to 1400px wide. The frame fills it and takes a viewport-relative
   height — it scales like a real browser window. The 200px height reserve leaves
   room for the site header, the URL input row above, and a peek of the CTA
   section below the fold. */
@media (min-width: 768px) {
    .kokeile-demo-wrap {
        width: calc(100vw - 64px);
        max-width: 1400px;
        margin: 0 auto;
    }

    .kokeile-frame {
        width: 100%;
        height: calc(100vh - 200px);
    }
}

.kokeile-frame-bar {
    flex-shrink: 0;
    padding: 10px 14px;
    background: var(--bg-tertiary);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
}

.kokeile-frame-url {
    width: 100%;
    max-width: 260px;
    padding: 6px 12px;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    color: var(--text-muted);
    font-size: 0.78rem;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.kokeile-frame-body {
    flex: 1;
    position: relative;
    overflow: hidden;
}

/* State machine — exactly one .kokeile-state visible at a time. Active state
   is selected by data-state on .kokeile-frame, so phases 2-4 can swap the
   .kokeile-state-ready block content without touching the surrounding wiring. */
.kokeile-state {
    position: absolute;
    inset: 0;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 24px;
    gap: 16px;
}

.kokeile-frame[data-state="idle"] .kokeile-state-idle,
.kokeile-frame[data-state="loading"] .kokeile-state-loading,
.kokeile-frame[data-state="error"] .kokeile-state-error {
    display: flex;
}

/* Ready state is a block, not a centered flex box — the screenshot renders at
   its natural height and the state itself is the vertical scroll container. */
.kokeile-frame[data-state="ready"] .kokeile-state-ready {
    display: block;
}

.kokeile-state-hint {
    color: var(--text-secondary);
    font-size: 0.95rem;
    line-height: 1.5;
    max-width: 280px;
}

/* Loading spinner — calm, not flashy. */
.kokeile-spinner {
    width: 36px;
    height: 36px;
    border: 3px solid var(--border-strong);
    border-top-color: var(--accent);
    border-radius: 50%;
    animation: kokeile-spin 0.9s linear infinite;
}

@keyframes kokeile-spin {
    to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .kokeile-spinner {
        animation-duration: 2.4s;
    }
}

/* Ready state — the scrollable content area of the browser-frame. The screenshot
   renders at natural height and the visitor scrolls it vertically inside the
   frame, just like scrolling a real website. The widget button is NOT inside
   this element (it is anchored to .kokeile-frame-body), so it stays put while
   the screenshot scrolls. The scrollbar is kept subtly but always visible. */
.kokeile-state-ready {
    padding: 0;
    overflow-y: auto;
    overflow-x: hidden;
    scrollbar-width: thin;
    scrollbar-color: rgba(255, 255, 255, 0.25) transparent;
}

.kokeile-state-ready::-webkit-scrollbar {
    width: 8px;
}

.kokeile-state-ready::-webkit-scrollbar-track {
    background: transparent;
}

.kokeile-state-ready::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.25);
    border-radius: 4px;
}

.kokeile-state-ready::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.4);
}

.kokeile-screenshot {
    display: block;
    width: 100%;
    height: auto;
}

.kokeile-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: repeating-linear-gradient(
        45deg,
        rgba(148, 163, 184, 0.08),
        rgba(148, 163, 184, 0.08) 12px,
        rgba(148, 163, 184, 0.14) 12px,
        rgba(148, 163, 184, 0.14) 24px
    );
    color: var(--text-secondary);
    font-size: 0.9rem;
    font-weight: 500;
}

/* Production-widget overrides for demo mode.
   The widget's own CSS anchors #cb-widget-container to the VIEWPORT (position: fixed,
   bottom/right 20px). When the widget is moved into .kokeile-frame-body — which is
   position: relative — we re-anchor the container to the frame's bottom-right corner.

   The container is left at its natural ~60×60 auto-size (it shrink-wraps the toggle
   button). Because the container itself is now positioned, the button needs no
   override — it stays in the widget's normal flow and fills the container, landing
   exactly at bottom: 16px / right: 16px of the frame.

   Specificity (`.class #id` = 0,1,1) beats the widget's bare `#id` rules without
   needing !important, including inside the widget's own mobile @media rules.
*/
.kokeile-frame-body #cb-widget-container {
    position: absolute;
    top: auto;
    left: auto;
    bottom: 16px;
    right: 16px;
    z-index: 5;
}

/* Chat panel: anchored to the container (and thus the frame), not the viewport.
   Explicit top/left reset stops the widget's mobile @media rule from stretching
   it to a full-screen overlay. On mobile the width tracks the viewport so it
   stays legible; on desktop it uses the real production widget size so the demo
   represents the actual product. */
.kokeile-frame-body #cb-chat-window {
    position: absolute;
    top: auto;
    left: auto;
    bottom: 76px;
    right: 0;
    width: min(340px, calc(100vw - 48px));
    height: min(460px, 70vh);
    /* Re-assert the rounded panel + shadow so the widget's ≤480px full-bleed
       rules (which zero these out) don't leak into the demo frame. */
    border-radius: 12px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.25);
}

@media (min-width: 768px) {
    .kokeile-frame-body #cb-chat-window {
        width: 380px;
        height: 520px;
    }
}

/* Mobile demo: fill the frame instead of floating as a small box. Mirrors
   what the production widget does on real phones (its own ≤480px rules
   pin it to the viewport edges).

   Critical: in this mode we demote #cb-widget-container to position:static
   (see the rule below) so the chat's position:absolute resolves against
   .kokeile-frame-body (position:relative), NOT the container — otherwise
   inset:0 + 100% sizing collapses to the container's 0×0 box once the
   toggle is hidden by the open-state rule, and the chat renders as an
   invisible 2px dot in the bottom-right corner.

   Specificity (0,2,1) beats the base .kokeile-frame-body #cb-chat-window
   rules (0,1,1), including inside @media (min-width: 768px). */
.kokeile-frame-body.kokeile-device-mobile #cb-chat-window {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    border-radius: 0;
    box-shadow: none;
}

/* Move the chat's positioning ancestor from the container to the frame body
   in mobile demo only. Desktop demo keeps the container positioned because
   its small floating chat (340×460 / 380×520, anchored bottom-right) is laid
   out relative to the container by design. */
.kokeile-frame-body.kokeile-device-mobile #cb-widget-container {
    position: static;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
}

/* Container is static now, so the toggle button needs its own positioning
   to stay in the bottom-right corner of the frame body when the chat is
   closed. The selector includes #cb-widget-container so its specificity
   (2,2,0) beats widget.css's #cb-widget-container.cb-style-bubble
   #cb-toggle-btn { position: relative } at (2,1,0) — widget.js adds the
   cb-style-bubble class by default, and without the ID-count match the
   widget rule would override position back to relative and the bottom/
   right offsets would no-op (toggle would render in normal flow at the
   container's top-left). The open-state toggle-hide rule below still
   wins (higher specificity) so this is only visible when chat is closed. */
.kokeile-frame-body.kokeile-device-mobile #cb-widget-container #cb-toggle-btn {
    position: absolute;
    bottom: 16px;
    right: 16px;
}

/* Force the chat window visible inside the demo frame whenever .cb-open is
   set. The widget's base #cb-chat-window rule hides it via opacity:0 +
   transform + pointer-events:none and only #cb-chat-window.cb-open undoes
   that. When the real browser viewport is < 480px the widget's mobile
   @media rules fire and can leave the open state incompletely asserted
   inside the demo frame (the chat ends up invisible or anchored to the
   viewport instead of the frame). One selector covers both demo modes —
   specificity (0,2,1) > (0,1,1) of #cb-chat-window.cb-open, so this wins
   regardless of widget CSS load order or media-query interference. */
.kokeile-frame-body #cb-chat-window.cb-open {
    opacity: 1;
    transform: none;
    pointer-events: auto;
}

/* The widget's own toggle-hide rule lives inside @media (max-width: 480px),
   so on a desktop viewport simulating a mobile demo the toggle button would
   otherwise peek through the bottom-right corner once the chat is open.
   Re-assert it unconditionally for mobile-device demos. */
.kokeile-frame-body.kokeile-device-mobile #cb-widget-container:has(#cb-chat-window.cb-open) #cb-toggle-btn {
    display: none;
}

/* No popup CTA in demo mode — the demo widget config always 404s so popup
   defaults stay off, but belt-and-braces. */
.kokeile-frame-body #cb-popup {
    display: none !important;
}

/* Conversion CTA — sits below the browser-frame in ready state. Reuses the
   landing page's accent-button system; only the surrounding spacing/typography
   is new. Visibility is toggled from kokeile.js, not via CSS sibling combinators,
   because the data-state attribute lives on .kokeile-frame (a descendant of
   .kokeile-demo-wrap), not on a shared ancestor of this section. */
.kokeile-cta-section {
    text-align: center;
    margin-top: 64px;
}

.kokeile-cta-title {
    font-size: clamp(1.5rem, 2.8vw, 2rem);
    font-weight: 700;
    color: var(--text-primary);
    line-height: 1.25;
    margin-bottom: 12px;
    letter-spacing: -0.01em;
}

.kokeile-cta-sub {
    color: var(--text-secondary);
    font-size: 1rem;
    margin-bottom: 28px;
    line-height: 1.5;
}

@media (max-width: 640px) {
    .kokeile-cta-section {
        margin-top: 48px;
    }
    .kokeile-cta-section .btn {
        display: block;
        width: 100%;
    }
}

/* Dev-only delete row */
.kokeile-delete-row {
    text-align: center;
    margin-top: 24px;
}

.kokeile-delete-link {
    color: var(--text-muted);
    font-size: 0.85rem;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.kokeile-delete-link:hover {
    color: var(--text-secondary);
}

/* Error state retry link */
.kokeile-retry {
    color: var(--accent);
    font-weight: 600;
    font-size: 0.95rem;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.kokeile-retry:hover {
    color: var(--accent-hover);
}
