/* SuperBold Sidekick — frontend widget for the public site.
   BEM-named, scoped under #jsSidekickFrontend so it doesn't leak into the host site's styles.
   Only renders when the visitor is logged in to the Umbraco backoffice.

   Sizing is intentionally in PX, not rem. The widget is a drop-in component
   that must render identically on ANY host, and rem is always relative to the
   host's <html> font-size — which differs per site (SuperBold templates use
   62.5% so 1rem=10px, but a Bootstrap-based area like the WVM dashboard keeps
   the 16px browser default, which blew the widget up ~1.6x). rem cannot be
   re-based per subtree, so the widget pins a fixed px scale instead and stays
   host-independent. (Values map 1rem=10px from the original design; browser
   zoom still scales px, so accessibility zoom is unaffected.)

   HOST-DEFENCE — om dezelfde reden. De scoping onder #jsSidekickFrontend voorkomt dat ONZE stijlen
   in de host lekken, maar niet andersom: de widget rendert in de page-DOM (geen Shadow DOM, geen
   iframe), dus elke KALE element-selector van de host raakt ons. Dat is geen theoretisch risico —
   `header { position: fixed; top: 0; width: 100% }` voor een sticky sitenavigatie is doodnormaal, en
   die rukt onze <header class="sidekick-frontend__head"> uit het paneel en pint 'm over de pagina.
   Gezien bij korzo.nl (site-nav.css), alleen op desktop omdat het in een media query stond.

   Daarom zetten de regels op onze semantische elementen (<header>, <section>) `position` en `width`
   EXPLICIET, ook waar de default al goed is. Een class (0,1,0) wint van een kale element-selector
   (0,0,1), dus dit is genoeg — en het is bewust hier gedaan en niet met een reset-blok als
   `#jsSidekickFrontend header { … }`: die zou met specificiteit (1,0,1) juist onze eigen
   class-regels overrulen.

   Voeg je een nieuw <header>/<section>/<form>/<nav>/<main>/<footer>/<aside> toe? Zet dan `position`
   en `width` expliciet op de bijbehorende class. Elementen die dat al doen (`__panel` = fixed,
   `__composer` = relative) zijn vanzelf beschermd. */

#jsSidekickFrontend {
    --sk-bg: #fff;
    --sk-fg: #1b264f;
    --sk-muted: #66686e;
    --sk-border: #d8d7d9;
    --sk-accent: #e65d41;
    --sk-accent-fg: #fff;
    --sk-error-bg: #ffe7e7;
    --sk-error-fg: #8a1f1f;
    --sk-confirm-bg: #fff3cd;
    --sk-confirm-border: #ffe49b;
}

.sidekick-frontend__trigger {
    position: fixed;
    bottom: 24px;
    right: 24px;
    z-index: 10000;
    width: 52px;
    height: 52px;
    border-radius: 50%;
    border: none;
    background:
        radial-gradient(circle at 32% 28%, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0) 55%),
        var(--sk-accent);
    color: var(--sk-accent-fg);
    cursor: pointer;
    box-shadow:
        inset 0 0 0 1px rgba(255, 255, 255, 0.18),
        0 6px 18px rgba(0, 0, 0, 0.32);
    padding: 0;
    overflow: visible;
    /* Smoother feel — slightly longer transition + a snappy ease-out so the
       button feels physically responsive when you hover/press it. */
    transition:
        transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
        box-shadow 220ms ease-out;
}
.sidekick-frontend__trigger svg {
    position: absolute;
    height: 28px;
    width: 28px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    overflow: visible;
    pointer-events: none;
    display: block;
    filter: drop-shadow(0 1.5px 2px rgba(0, 0, 0, 0.25));
    transition: transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1);
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__trigger:hover {
        transform: scale(1.08) translateY(-2px);
        box-shadow:
            inset 0 0 0 1px rgba(255, 255, 255, 0.22),
            0 10px 26px rgba(0, 0, 0, 0.36);
    }
    /* Tiny icon wobble on hover — adds life without being distracting. */
    .sidekick-frontend__trigger:hover svg {
        transform: translate(-50%, -50%) rotate(-6deg);
    }
}
/* Press-state: brief squash so the click feels acknowledged before the panel
   opens. The :active state lives a fraction of a second so this is essentially
   a flash, not a sustained scale. */
.sidekick-frontend__trigger:active {
    transform: scale(0.94);
    transition-duration: 80ms;
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__trigger,
    .sidekick-frontend__trigger svg { transition: none; }
    .sidekick-frontend__trigger:hover,
    .sidekick-frontend__trigger:active,
    .sidekick-frontend__trigger:hover svg { transform: translate(-50%, -50%); }
    .sidekick-frontend__trigger:hover,
    .sidekick-frontend__trigger:active { transform: none; }
}

.sidekick-frontend__panel {
    position: fixed;
    bottom: 90px;
    right: 24px;
    z-index: 10000;
    /* Public widget panel — ~20% wider than the original 420px so the
       composer + chips don't feel cramped. Clamped to viewport so it
       still fits on tablets without overflowing the right edge. */
    width: min(510px, calc(100vw - 40px));
    height: min(600px, calc(100vh - 140px));
    background: var(--sk-bg);
    color: var(--sk-fg);
    border: 1px solid var(--sk-border);
    border-radius: 10px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
    display: flex;
    flex-direction: column;
    /* `visible` so hover-tooltips on the crew-chips can spill out of the panel.
       The transcript inside still scrolls because it owns its own overflow-y. */
    overflow: visible;
    font-family: inherit;
    font-size: 14px;
    line-height: 1.4;

    /* --- Smooth open/close animation, anchored to the FAB ---
       Closed state: the panel is collapsed into the bottom-right corner (where
       the FAB sits), scaled down and faded. transform-origin pulls the scale
       toward the trigger so it visually "grows out" of the button.
       Opens via .is-open class — JS toggles that (we dropped the `hidden`
       attribute pattern because display:none kills transitions).

       `contain` isolates the panel's own layout/paint from the rest of the
       page, so scaling it doesn't trigger reflow / repaint up the tree. Combined
       with `is-opening` (suppresses child animations during open transition)
       this keeps the open feeling silky even on populated transcripts. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    /* Lower scale ratio (0.92 vs 0.86) keeps the visual paint area small and
       reduces sub-pixel jitter. The translate is also gentler. */
    transform: translate3d(4px, 8px, 0) scale(0.92);
    transform-origin: 100% 100%;     /* bottom-right corner = FAB position */
    transition:
        opacity 220ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 320ms cubic-bezier(0.16, 1, 0.3, 1),
        visibility 0s linear 320ms,
        box-shadow 320ms ease-out;
    will-change: transform, opacity;
    contain: layout paint;
}
.sidekick-frontend__panel.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translate3d(0, 0, 0) scale(1);
    transition:
        opacity 200ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 320ms cubic-bezier(0.16, 1, 0.3, 1),
        visibility 0s linear 0s,
        box-shadow 320ms ease-out;
}
/* While the panel is in its opening transition, every child animation is
   suppressed. Otherwise re-opening a populated transcript fires N bubble
   entrance animations on top of the panel scale — visible as a jittery
   stack. After 360ms the flag clears and new bubbles animate normally. */
.sidekick-frontend__panel.is-opening .sidekick-frontend__bubble,
.sidekick-frontend__panel.is-opening .sidekick-frontend__chip,
.sidekick-frontend__panel.is-opening .sidekick-frontend__confirm,
.sidekick-frontend__panel.is-opening .sidekick-frontend__bubble--assistant.is-streaming {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__panel {
        transform: none;
        transition: opacity 120ms linear, visibility 0s linear 120ms;
    }
    .sidekick-frontend__panel.is-open {
        transition: opacity 120ms linear, visibility 0s linear 0s;
    }
}
.sidekick-frontend__refresh[hidden],
.sidekick-frontend__crew[hidden] {
    display: none;
}

/* ----- Crew selector (chip-row under the panel header) ----- */
.sidekick-frontend__crew {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--sk-border);
    background: var(--sk-bg);
}
.sidekick-frontend__crew-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px 3px 3px;
    border-radius: 9990px;
    border: 1px solid var(--sk-border);
    background: transparent;
    color: var(--sk-fg);
    cursor: pointer;
    font-family: inherit;
    font-size: 11px;
    line-height: 1;
}
.sidekick-frontend__crew-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--sk-border);
    color: var(--sk-fg);
    font-size: 9.5px;
    font-weight: 700;
    flex-shrink: 0;
}
.sidekick-frontend__crew-wrap {
    position: relative;
    display: inline-flex;
}
.sidekick-frontend__crew-tip {
    /* The crew row sits at the top-LEFT of the panel, so the tooltip must open
       to the RIGHT (into the panel's empty space) — pinning it left or centering
       it would spill past the panel/viewport edge (the crew chips are clustered
       on the left, there is no room to their left). Every tooltip therefore pins
       its LEFT edge to its own chip and extends right; the arrow (--ax) sits
       ~30px in, landing over the chip avatar. --tx is the X-translation. */
    --tx: 0;
    --ax: 30px;
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: auto;
    width: 240px;
    max-width: calc(100vw - 32px);
    box-sizing: border-box;
    padding: 16px 14px 14px;
    border-radius: 12px;
    background: linear-gradient(155deg, #620905 0%, #e65d41 100%);
    color: #fff;
    box-shadow:
        0 14px 40px rgba(27, 38, 79, 0.32),
        0 2px 6px rgba(27, 38, 79, 0.18);
    font-size: 12.5px;
    line-height: 1.45;
    z-index: 60;
    opacity: 0;
    pointer-events: none;
    transform: translate(var(--tx), -8px) scale(0.96);
    transform-origin: top center;
    transition:
        opacity 200ms cubic-bezier(0.2, 0.8, 0.2, 1),
        transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    text-align: center;
}
/* No per-position overrides: every tooltip pins left + opens right (see the
   base rule above). The old nth-child(-n+2)/nth-last-child(-n+2) pair conflicted
   on the MIDDLE chip of a 3-chip crew (it matched both, and the right-pin won —
   pushing the tooltip left, off the panel). Left-pinning all of them is correct
   for a left-clustered crew row and removes that whole class of overflow. */
/* Up-pointing arrow as a real CSS triangle (border-trick) so we don't get
   the rotated-square seam where the tooltip's gradient doesn't perfectly
   match the arrow color. Positioned via --ax to always land above the
   hovered chip. The border-bottom matches the tooltip's TOP gradient stop
   (#1b264f) so the seam is invisible. */
.sidekick-frontend__crew-tip::before {
    content: '';
    position: absolute;
    top: -7px;
    left: var(--ax);
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 7px solid transparent;
    border-right: 7px solid transparent;
    border-bottom: 7px solid #620905;
}
.sidekick-frontend__crew-tip-avatar {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.12);
    box-shadow:
        0 0 0 3px rgba(255, 255, 255, 0.22),
        0 6px 18px rgba(0, 0, 0, 0.32);
    overflow: hidden;
    margin-bottom: 4px;
    flex-shrink: 0;
}
.sidekick-frontend__crew-tip-img {
    width: 76px;
    height: 76px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}
.sidekick-frontend__crew-tip-initials {
    font-size: 24px;
    font-weight: 700;
    color: #fff;
    letter-spacing: 0.05em;
}
.sidekick-frontend__crew-tip-name {
    font-weight: 700;
    font-size: 15.5px;
    letter-spacing: 0.01em;
    margin-top: 2px;
}
.sidekick-frontend__crew-tip-role {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    opacity: 0.78;
}
.sidekick-frontend__crew-tip-notes {
    margin-top: 6px;
    font-size: 12px;
    font-style: italic;
    opacity: 0.92;
    line-height: 1.5;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__crew-wrap:hover .sidekick-frontend__crew-tip,
    .sidekick-frontend__crew-wrap:focus-within .sidekick-frontend__crew-tip {
        opacity: 1;
        transform: translate(var(--tx), 0) scale(1);
    }
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__crew-tip {
        transition: opacity 140ms ease;
        transform: translate(var(--tx), 0);
    }
}
.sidekick-frontend__crew-avatar--img {
    background: transparent;
    object-fit: cover;
}
.sidekick-frontend__crew-chip--active {
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
    border-color: var(--sk-accent);
}
.sidekick-frontend__crew-chip--active .sidekick-frontend__crew-avatar {
    background: rgba(255, 255, 255, 0.18);
    color: var(--sk-accent-fg);
}
.sidekick-frontend__crew-chip--active .sidekick-frontend__crew-avatar--img {
    background: transparent;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__crew-chip:not(.sidekick-frontend__crew-chip--active):hover {
        background: var(--sk-border);
    }
}

/* Assistant message row — wraps the bubble + the crew-member's avatar in a
   flex row. Falls back to a bare bubble when no crew is configured. */
.sidekick-frontend__message {
    display: flex;
    gap: 6px;
    align-items: flex-start;
    align-self: flex-start;
    max-width: 100%;
}
.sidekick-frontend__message-avatar {
    flex-shrink: 0;
    margin-top: 2px;
    width: 26px;
    height: 26px;
}
.sidekick-frontend__message-avatar .sidekick-frontend__crew-avatar {
    width: 26px;
    height: 26px;
    font-size: 10px;
}

.sidekick-frontend__head {
    /* position/width expliciet: zie de host-defence toelichting bovenaan dit bestand.
       Een kale `header { position: fixed; width: 100% }` in de site-CSS (heel gebruikelijk voor
       een sticky sitenavigatie) rukt deze balk anders uit het paneel en pint 'm over de pagina. */
    position: static;
    width: auto;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border-bottom: 1px solid var(--sk-border);
}
.sidekick-frontend__brand {
    width: 32px;
    height: 22px;
    display: block;
    flex-shrink: 0;
}
.sidekick-frontend__title {
    flex: 1;
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
}

.sidekick-frontend__head-btn {
    background: transparent;
    border: none;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    color: inherit;
    font-size: 14px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
/* Inline-SVG icon-buttons (the new pick-mode button) need explicit sizing —
   the existing text-buttons (+/×) just use font-size, but an SVG without
   width/height defaults to 300×150 and looks wrong. */
.sidekick-frontend__head-btn svg {
    width: 16px;
    height: 16px;
    display: block;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__head-btn:hover { background: rgba(0, 0, 0, 0.06); }
}

.sidekick-frontend__transcript {
    flex: 1;
    overflow-y: auto;
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.sidekick-frontend__bubble {
    padding: 9px 12px;
    border-radius: 12px;
    max-width: 85%;
    overflow-wrap: anywhere;
    word-break: break-word;
    /* Slightly longer + a small scale so the bubble lifts in instead of just
       fading. Same easing curve as the panel for a coherent feel. */
    animation: sk-bubble-in 280ms cubic-bezier(0.16, 1, 0.3, 1);
    transform-origin: bottom center;
}
@keyframes sk-bubble-in {
    from { opacity: 0; transform: translateY(8px) scale(0.96); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
/* Markdown tables (e.g. Claude's score-/vergelijkings-tabellen in de transcript).
   Scoped under the widget root so --sk-* variables resolve. Bordered + header
   tint + zebra rows so a table is readable instead of raw pipes. */
.sidekick-frontend__table {
    border-collapse: collapse;
    width: 100%;
    margin: 8px 0;
    font-size: 12.5px;
    line-height: 1.4;
}
.sidekick-frontend__table th,
.sidekick-frontend__table td {
    border: 1px solid var(--sk-border, #d8d7d9);
    padding: 5px 8px;
    text-align: left;
    vertical-align: top;
}
.sidekick-frontend__table thead th {
    background: rgba(33, 82, 163, 0.08);
    font-weight: 700;
    color: var(--sk-fg, #1b264f);
}
.sidekick-frontend__table tbody tr:nth-child(even) td {
    background: rgba(27, 38, 79, 0.035);
}
.sidekick-frontend__typing {
    display: inline-flex;
    gap: 6px;
    padding: 4px 0;
    align-items: center;
}
.sidekick-frontend__typing-dots {
    display: inline-flex;
    gap: 4px;
    align-items: center;
}
.sidekick-frontend__typing-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.35;
    animation: sk-typing 1.2s ease-in-out infinite;
}
.sidekick-frontend__typing-dot:nth-child(2) { animation-delay: 0.18s; }
.sidekick-frontend__typing-dot:nth-child(3) { animation-delay: 0.36s; }
/* Playful status-term — small italic line next to the dots, updates every
   ~2.6s while streaming. Empty when not streaming or when the site disabled
   the feature via Sidekick:StatusTerms:Enabled = false. */
.sidekick-frontend__typing-term {
    font-size: 0.85em;
    font-style: italic;
    opacity: 0.7;
    line-height: 1.2;
    /* Subtle fade between term-swaps so the eye notices movement without
       jarring text replacement. */
    transition: opacity 200ms ease-out;
}
.sidekick-frontend__typing-term:empty { display: none; }
@keyframes sk-typing {
    0%, 60%, 100% { opacity: 0.25; transform: translateY(0); }
    30%          { opacity: 1; transform: translateY(-2px); }
}
.sidekick-frontend__spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    border: 2px solid currentColor;
    border-top-color: transparent;
    animation: sk-spin 700ms linear infinite;
    vertical-align: -2px;
    margin-right: 4px;
}
@keyframes sk-spin { to { transform: rotate(360deg); } }
.sidekick-frontend__confirm--busy { opacity: 0.85; }
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__bubble { animation: none; }
    .sidekick-frontend__typing-dot { animation: none; opacity: 0.55; }
    .sidekick-frontend__spinner { animation: none; border-top-color: currentColor; }
}
.sidekick-frontend__bubble--user {
    align-self: flex-end;
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
}
.sidekick-frontend__bubble--assistant {
    align-self: flex-start;
    background: #f4f4f4;
}
.sidekick-frontend__text pre {
    background: rgba(0, 0, 0, 0.06);
    padding: 8px;
    border-radius: 6px;
    overflow: auto;
    font-size: 0.85em;
}
.sidekick-frontend__text code {
    background: rgba(0, 0, 0, 0.06);
    padding: 0 4px;
    border-radius: 3px;
    font-size: 0.85em;
}
/* ── Markdown blocks (mdToHtml) — mirror of the backoffice renderMarkdown
   styling (app.ts): proposal-style answers read as visual blocks (section
   headers, tinted Huidig/Voorstel-panels) instead of #/dash soup.
   HOST-DEFENCE: hosts style bare <p>/<h4>/<ul>/<blockquote>/<hr> with
   element-selectors, often in rem (which the widget must not inherit — see
   the px-rationale at the top of this file). So every rule pins margin,
   padding and font-size explicitly, even where the default would do; a
   class-selector (0,2,0) beats any bare element-selector. ── */
.sidekick-frontend__text .md-p {
    margin: 0 0 8px;
    padding: 0;
    font-size: inherit;
    line-height: inherit;
}
.sidekick-frontend__text .md-p:last-child { margin-bottom: 0; }
.sidekick-frontend__text .md-h {
    margin: 14px 0 5px;
    padding: 0;
    font-size: 0.95em;
    font-weight: 700;
    line-height: 1.35;
    letter-spacing: 0.01em;
    color: inherit;
}
.sidekick-frontend__text .md-h:first-child { margin-top: 0; }
.sidekick-frontend__text .md-hr {
    border: 0;
    border-top: 1px solid rgba(27, 38, 79, 0.12);
    height: auto;
    margin: 12px 0;
    background: none;
}
.sidekick-frontend__text .md-quote {
    margin: 5px 0 10px;
    padding: 8px 12px;
    border: 0;
    border-left: 3px solid rgba(27, 38, 79, 0.18);
    border-radius: 0 6px 6px 0;
    background: rgba(27, 38, 79, 0.05);
    font-size: inherit;
    font-style: normal;
    color: inherit;
}
/* Grey "Huidig:"-panel vs green "Voorstel:"-panel — same tints as the
   backoffice bubbles so both chats read as one product. */
.sidekick-frontend__text .md-quote--huidig {
    border-left-color: rgba(27, 38, 79, 0.28);
    background: rgba(27, 38, 79, 0.07);
    color: var(--sk-muted, #66686e);
}
.sidekick-frontend__text .md-quote--voorstel {
    border-left-color: #2f9e63;
    background: #eaf7f0;
    color: #1b264f; /* pinned — the panel is light in dark mode too */
}
.sidekick-frontend__text .md-list {
    margin: 5px 0 10px;
    padding: 0 0 0 20px;
    /* Hosts routinely reset bare ul/ol to list-style:none for their nav;
       revert restores the UA default (disc for ul, decimal for ol). */
    list-style: revert;
    font-size: inherit;
}
.sidekick-frontend__text .md-list li { margin: 2px 0; padding: 0; }

.sidekick-frontend__chips {
    display: flex;
    flex-direction: column;
    gap: 5px;
    margin-bottom: 6px;
}
.sidekick-frontend__chip summary {
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.04);
    font-size: 0.85em;
    display: inline-flex;
    gap: 8px;
    align-items: center;
    list-style: none;
}
.sidekick-frontend__chip summary::-webkit-details-marker { display: none; }
.sidekick-frontend__chip--read summary { border-left: 3px solid #4a90e2; }
.sidekick-frontend__chip--write summary { border-left: 3px solid #f5a623; }
.sidekick-frontend__chip--destructive summary { border-left: 3px solid #d0021b; }

.sidekick-frontend__confirm {
    background: var(--sk-confirm-bg);
    border: 1px solid var(--sk-confirm-border);
    border-radius: 8px;
    padding: 10px 12px;
}
.sidekick-frontend__confirm-title { font-weight: 600; margin-bottom: 4px; }
.sidekick-frontend__confirm-summary { font-size: 0.9em; margin-bottom: 8px; }
.sidekick-frontend__confirm-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}
.sidekick-frontend__confirm-actions button {
    padding: 6px 12px;
    border-radius: 6px;
    border: 1px solid var(--sk-border);
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
}
.sidekick-frontend__confirm-actions .js-confirm-reject { background: #fff; }
.sidekick-frontend__confirm-actions .js-confirm-ok {
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
    border-color: var(--sk-accent);
}

.sidekick-frontend__refresh {
    display: flex;
    gap: 6px;
    align-items: center;
    padding: 8px 12px;
    background: #e8f5e9;
    border-top: 1px solid #b7e0bc;
    color: #1f6f2c;
    font-size: 12px;
    flex-wrap: wrap;
}
.sidekick-frontend__refresh-text {
    flex: 1;
    min-width: 120px;
}
.sidekick-frontend__refresh-btn {
    background: #1f6f2c;
    color: #fff;
    border: none;
    padding: 5px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
}
.sidekick-frontend__refresh-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
/* Rollback is a secondary action — outline-style so the primary "Pagina
   verversen"-button stays the obvious next step. */
.js-sidekick-rollback-btn {
    background: transparent;
    color: #1f6f2c;
    border: 1px solid #1f6f2c;
}

.sidekick-frontend__mentions {
    position: absolute;
    bottom: calc(100% + 8px);
    /* Inset matching the saved-prompts menu so both popovers feel like
       breathing-room cards rather than panel-wide strips. */
    left: 12px;
    right: 12px;
    max-height: 260px;
    overflow-y: auto;
    background: var(--sk-bg);
    border: 1px solid var(--sk-border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    z-index: 30;
}
.sidekick-frontend__mentions[hidden] { display: none; }
.sidekick-frontend__mention-item {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 12px;
    border: none;
    background: transparent;
    color: inherit;
    cursor: pointer;
    text-align: left;
    border-radius: 6px;
    font-family: inherit;
}
.sidekick-frontend__mention-item.is-active {
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
}
.sidekick-frontend__mention-label {
    font-weight: 600;
    font-size: 14px;
    line-height: 1.3;
}
.sidekick-frontend__mention-sub {
    font-size: 12px;
    line-height: 1.4;
    opacity: 0.75;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__mention-item:not(.is-active):hover { background: rgba(0, 0, 0, 0.05); }
}

.sidekick-frontend__composer {
    position: relative;
    display: flex;
    gap: 8px;
    margin-top: 10px;
    padding: 10px 12px;
    border-top: 1px solid var(--sk-border);
    /* Inherit the panel background instead of painting its own — the panel
       has rounded corners + overflow:visible (needed for crew-tooltips), so
       a composer-coloured background here would paint past the panel's
       rounded bottom-corners. Border-radius below is a safety net for sites
       that override the composer background to a different colour. */
    background: transparent;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
}
.sidekick-frontend__input {
    flex: 1;
    /* 3 zichtbare regels bij font-size 14px + line-height 1.4 →
       ~59px aan tekst + 16px padding + 2px border ≈ 77px.
       Bumped to 90px zodat de hand-grip ook lekker zichtbaar is en
       een lange vraag niet onmiddellijk scrolt. */
    min-height: 90px;
    max-height: 220px;
    resize: vertical;
    padding: 8px 10px;
    border-radius: 6px;
    border: 1px solid var(--sk-border);
    font-family: inherit;
    font-size: 14px;
    line-height: 1.4;
    box-sizing: border-box;
    background: var(--sk-bg);
    color: var(--sk-fg);
}
/* Send button — compact square icon-button (Claude-style up-arrow) instead of
   a wide "Stuur" text button. Bottom-aligned at the composer's right edge. */
.sidekick-frontend__send {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    align-self: flex-end;
    flex-shrink: 0;
    border-radius: 8px;
    border: none;
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
    cursor: pointer;
}
.sidekick-frontend__send svg { width: 20px; height: 20px; display: block; }
.sidekick-frontend__send:disabled { opacity: 0.5; cursor: not-allowed; }

/* Left tool column — dictation mic stacked above the paperclip, bottom-aligned
   so both round icon-buttons hug the bottom of the composer next to the input.
   Frees the horizontal space the mic used to take between input and send, so
   the textarea grows wider. */
.sidekick-frontend__tools {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-self: flex-end;
    flex-shrink: 0;
}

/* ----- Voice dictation button ----- */
.sidekick-frontend__mic {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    align-self: flex-end;
    border-radius: 50%;
    border: 1px solid var(--sk-border);
    background: var(--sk-bg);
    color: var(--sk-fg);
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color 120ms ease, color 120ms ease, border-color 120ms ease;
}
.sidekick-frontend__mic svg { width: 20px; height: 20px; }
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__mic:hover:not(.sidekick-frontend__mic--recording) {
        background: var(--sk-accent);
        color: var(--sk-accent-fg);
        border-color: var(--sk-accent);
    }
}
.sidekick-frontend__mic--recording {
    background: #dc2626;
    color: #fff;
    border-color: #dc2626;
    animation: sk-mic-pulse 1.4s ease-in-out infinite;
}
@keyframes sk-mic-pulse {
    0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0.45); }
    50%      { box-shadow: 0 0 0 8px rgba(220, 38, 38, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__mic { transition: none; }
    .sidekick-frontend__mic--recording { animation: none; }
}

/* ----- Quick actions bar ----- */
.sidekick-frontend__quick-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    /* Padding lives on .sidekick-frontend__actions-row now — chips fill
       the row and the prompts-toggle sits next to them. */
    padding: 0;
    background: transparent;
    flex: 1;
    min-width: 0;
}
.sidekick-frontend__chip.js-sidekick-quick {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 6px 10px;
    border-radius: 9990px;
    border: 1px solid var(--sk-border);
    background: transparent;
    color: var(--sk-fg);
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
}
.sidekick-frontend__chip-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__chip.js-sidekick-quick:hover {
        background: var(--sk-accent);
        color: var(--sk-accent-fg);
        border-color: var(--sk-accent);
    }
}

/* ----- Action result card (SEO / Copy) ----- */
.sidekick-frontend__action-card {
    border: 1px solid var(--sk-border);
    border-radius: 10px;
    padding: 14px 16px;
    background: var(--sk-bg);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 4px;
}
.sidekick-frontend__action-head {
    /* <header> — host-defence, zie boven. */
    position: static;
    width: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.sidekick-frontend__action-title {
    font-size: 14px;
    font-weight: 600;
}
.sidekick-frontend__action-score {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.sidekick-frontend__action-grade {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    font-size: 14px;
    font-weight: 700;
    color: white;
    background: #999;
}
.sidekick-frontend__action-grade--a { background: #16a34a; }
.sidekick-frontend__action-grade--b { background: #65a30d; }
.sidekick-frontend__action-grade--c { background: #ca8a04; }
.sidekick-frontend__action-grade--d { background: #ea580c; }
.sidekick-frontend__action-grade--f { background: #dc2626; }
.sidekick-frontend__action-num {
    font-size: 18px;
    font-weight: 700;
    color: var(--sk-fg);
    min-width: 32px;
    text-align: right;
}
.sidekick-frontend__action-headline {
    margin: 0;
    color: var(--sk-fg);
    font-size: 13px;
    line-height: 1.4;
}
.sidekick-frontend__action-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    border-top: 1px solid var(--sk-border);
    padding-top: 10px;
}
.sidekick-frontend__action-item {
    display: grid;
    grid-template-columns: 20px 1fr;
    align-items: baseline;
    column-gap: 6px;
    row-gap: 2px;
    padding: 4px 0;
    font-size: 13px;
    line-height: 1.4;
}
.sidekick-frontend__action-icon {
    grid-column: 1;
    grid-row: 1 / span 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    font-weight: 700;
    font-size: 11px;
    color: white;
    align-self: center;
}
.sidekick-frontend__action-item--pass .sidekick-frontend__action-icon { background: #16a34a; }
.sidekick-frontend__action-item--warn .sidekick-frontend__action-icon { background: #ca8a04; }
.sidekick-frontend__action-item--fail .sidekick-frontend__action-icon { background: #dc2626; }
.sidekick-frontend__action-label {
    grid-column: 2;
    grid-row: 1;
    font-weight: 500;
}
.sidekick-frontend__action-note {
    grid-column: 2;
    grid-row: 2;
    color: var(--sk-fg-muted, #6b7280);
    font-size: 12px;
}
.sidekick-frontend__action-suggestions {
    border-top: 1px solid var(--sk-border);
    padding-top: 10px;
    font-size: 13px;
}
.sidekick-frontend__action-suggestions summary {
    cursor: pointer;
    font-weight: 600;
    margin-bottom: 6px;
}
.sidekick-frontend__action-suggestions ul {
    margin: 0;
    padding-left: 20px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sidekick-frontend__action-history {
    font-size: 11px;
    color: var(--sk-fg-muted, #6b7280);
    border-top: 1px solid var(--sk-border);
    padding-top: 8px;
    min-height: 14px;
}
.sidekick-frontend__history-delta--up { color: #16a34a; font-weight: 600; }
.sidekick-frontend__history-delta--down { color: #dc2626; font-weight: 600; }
.sidekick-frontend__history-delta--flat { color: var(--sk-fg-muted, #6b7280); }

/* ----- Top-right analysis panel ----- */
.sidekick-analysis {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 9999;
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 13px;
    line-height: 1.4;
    color: #111827;
}
.sidekick-analysis__toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 9px;
    border-radius: 9990px;
    border: 1px solid rgba(0, 0, 0, 0.08);
    background: rgba(255, 255, 255, 0.96);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
    cursor: pointer;
    color: inherit;
    font-family: inherit;
    font-size: inherit;
    line-height: 1;
}
.sidekick-analysis__pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 7px;
    border-radius: 9990px;
    background: #f3f4f6;
    font-size: 11px;
    font-weight: 500;
    /* `position` so the box-shadow ring renders cleanly when --fresh fires. */
    position: relative;
}
/* Fresh-pulse — added by JS for ~1.6s after a chat-driven SEO/Copy run
   completes. Brief glow + tiny scale-up + a yellow ring so the editor's
   eye catches the badge update without it being distracting. Removed by
   the JS timeout so the resting state stays neutral. */
.sidekick-analysis__pill--fresh {
    animation: sb-pill-fresh 1.6s ease-out 1;
}
@keyframes sb-pill-fresh {
    0%   { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 214, 102, 0); }
    20%  { transform: scale(1.18); box-shadow: 0 0 0 6px rgba(255, 214, 102, 0.6); }
    60%  { transform: scale(1.04); box-shadow: 0 0 0 4px rgba(255, 214, 102, 0.3); }
    100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(255, 214, 102, 0); }
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-analysis__pill--fresh { animation: none; outline: 2px solid #ffd666; outline-offset: 1px; }
}
.sidekick-analysis__pill--empty { color: #6b7280; font-style: italic; }
.sidekick-analysis__pill--a { background: #d1fae5; color: #065f46; }
.sidekick-analysis__pill--b { background: #d9f99d; color: #365314; }
.sidekick-analysis__pill--c { background: #fef3c7; color: #78350f; }
.sidekick-analysis__pill--d { background: #fed7aa; color: #7c2d12; }
.sidekick-analysis__pill--f { background: #fecaca; color: #7f1d1d; }
.sidekick-analysis__pill-grade { font-weight: 700; }
.sidekick-analysis__chev { width: 12px; height: 12px; opacity: 0.6; }

.sidekick-analysis__panel {
    margin-top: 6px;
    width: 380px;
    max-width: calc(100vw - 32px);
    max-height: calc(100vh - 60px);
    overflow-y: auto;
    background: #fff;
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 8px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18);
    padding: 14px;
}
/* <section> — host-defence, zie boven. */
.sidekick-analysis__section { position: static; width: auto; margin-bottom: 14px; }
.sidekick-analysis__section:last-of-type { margin-bottom: 10px; }
.sidekick-analysis__section-head {
    /* <header> — host-defence, zie boven. */
    position: static;
    width: auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 6px;
    font-size: 14px;
}
.sidekick-analysis__run {
    padding: 4px 9px;
    border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, 0.15);
    background: #fff;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    line-height: 1;
}
.sidekick-analysis__run:disabled { opacity: 0.5; cursor: progress; }
@media (hover: hover) and (pointer: fine) {
    .sidekick-analysis__run:not(:disabled):hover {
        background: var(--sk-accent, #1c3aa9);
        color: #fff;
        border-color: var(--sk-accent, #1c3aa9);
    }
}
.sidekick-analysis__card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
    font-size: 12px;
}
.sidekick-analysis__card-headline { color: #1f2937; flex: 1; }
.sidekick-analysis__card-date { color: #6b7280; font-size: 11px; flex-shrink: 0; }
.sidekick-analysis__items {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.sidekick-analysis__item {
    display: grid;
    grid-template-columns: 18px 1fr;
    align-items: baseline;
    column-gap: 5px;
    row-gap: 1px;
    font-size: 12px;
    line-height: 1.35;
}
.sidekick-analysis__item-icon {
    grid-column: 1;
    grid-row: 1 / span 2;
    align-self: center;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    color: #fff;
    font-weight: 700;
    font-size: 9px;
}
.sidekick-analysis__item--pass .sidekick-analysis__item-icon { background: #16a34a; }
.sidekick-analysis__item--warn .sidekick-analysis__item-icon { background: #ca8a04; }
.sidekick-analysis__item--fail .sidekick-analysis__item-icon { background: #dc2626; }
.sidekick-analysis__item-label { grid-column: 2; grid-row: 1; }
.sidekick-analysis__item-note { grid-column: 2; grid-row: 2; color: #6b7280; font-size: 11px; }
.sidekick-analysis__empty { color: #6b7280; font-style: italic; margin: 0; font-size: 12px; }

.sidekick-analysis__more {
    /* <section> — host-defence, zie boven. */
    position: static;
    width: auto;
    display: flex;
    gap: 6px;
    padding-top: 10px;
    border-top: 1px solid #e5e7eb;
}
.sidekick-analysis__chat-btn {
    flex: 1;
    padding: 6px 8px;
    border-radius: 6px;
    border: 1px solid rgba(0, 0, 0, 0.15);
    background: #fff;
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-analysis__chat-btn:hover {
        background: #f3f4f6;
    }
}
@media (max-width: 768px) {
    .sidekick-analysis { display: none; }
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-analysis__toggle { transition: none; }
}

/* ----- Session-expired toast ----- */
.sidekick-session-banner {
    position: fixed;
    top: 16px;
    right: 16px;
    z-index: 10001;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: #fef3c7;
    border: 1px solid #facc15;
    border-radius: 6px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    font-size: 13px;
    color: #78350f;
    max-width: calc(100vw - 32px);
}
.sidekick-session-banner__text { flex: 1; line-height: 1.4; }
.sidekick-session-banner__link {
    padding: 4px 9px;
    background: #92400e;
    color: #fff;
    border-radius: 4px;
    text-decoration: none;
    font-weight: 600;
    white-space: nowrap;
}
.sidekick-session-banner__link:hover { background: #78350f; }
.sidekick-session-banner__close {
    background: transparent;
    border: none;
    cursor: pointer;
    color: #78350f;
    font-size: 15px;
    line-height: 1;
    padding: 2px 4px;
}

/* Quick-reply choice buttons rendered under an assistant bubble when the agent
   surfaced an options-list with request_user_input. Click sends the option
   text immediately as the user's reply. */
.sidekick-frontend__choices {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 10px;
}
.sidekick-frontend__choice {
    padding: 6px 12px;
    border-radius: 9990px;
    border: 1px solid var(--sk-accent);
    background: transparent;
    color: var(--sk-accent);
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    line-height: 1.2;
    transition: background-color 120ms ease, color 120ms ease;
}
.sidekick-frontend__choice:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__choice:not(:disabled):hover {
        background: var(--sk-accent);
        color: var(--sk-accent-fg);
    }
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__choice { transition: none; }
}

/* Selection chip rendered ABOVE a user-bubble when that turn carried a
   pick-mode selection. Visual confirmation that the highlighted element
   went along to the agent. Sits aligned with the bubble (right-side). */
.sidekick-frontend__user-context {
    align-self: flex-end;
    max-width: 85%;
    margin: 4px 0 -2px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 8px;
    border: 1px dashed var(--sk-accent);
    border-radius: 6px;
    background: rgba(33, 82, 163, 0.06);
    font-size: 11px;
    line-height: 1.3;
}
.sidekick-frontend__user-context-pin { font-size: 12px; }
.sidekick-frontend__user-context-tag {
    flex-shrink: 0;
    padding: 1px 5px;
    border-radius: 9990px;
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
    font-size: 9.5px;
    font-weight: 700;
    text-transform: lowercase;
}
.sidekick-frontend__user-context-text {
    color: var(--sk-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Pointer / pick-mode — editor enables it via the 🎯 button in the header,
   then clicks any element on the page to attach it as chat-context. */
.sidekick-frontend__head-btn.is-active {
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
}
body.sk-pick-mode {
    cursor: crosshair !important;
}
body.sk-pick-mode * {
    cursor: crosshair !important;
}
.sk-pick-overlay {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none;
    /* The overlay lives on <body>, OUTSIDE #jsSidekickFrontend, so the widget's
       --sk-accent custom property does NOT cascade to it — without a fallback the
       border collapsed to currentColor and was practically invisible (no "frame"
       around the hovered element). The fallback hard-codes the accent so the
       highlight always shows, on any host (dashboard, public site, …). */
    border: 2px solid var(--sk-accent, #2152a3);
    border-radius: 6px;
    background: rgba(33, 82, 163, 0.12);
    box-shadow:
        0 0 0 2px rgba(33, 82, 163, 0.28),
        0 6px 18px rgba(27, 38, 79, 0.28);
    /* Near-max z-index so the frame sits above Bootstrap/dashboard stacking contexts. */
    z-index: 2147483600;
    transition: transform 60ms linear, width 60ms linear, height 60ms linear;
}
@media (prefers-reduced-motion: reduce) {
    .sk-pick-overlay { transition: none; }
}
.sidekick-frontend__pick-hint {
    margin: 6px 0;
    padding: 8px 10px;
    border-radius: 6px;
    background: #fff7ed;
    color: #78350f;
    font-size: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
/* `[hidden]` would normally apply `display: none`, but the rule above sets
   `display: flex` with higher specificity. Re-assert the hidden behaviour
   explicitly. Same trick for the context-chip below. */
.sidekick-frontend__pick-hint[hidden] { display: none; }
.sidekick-frontend__pick-cancel {
    margin-left: auto;
    background: transparent;
    border: 1px solid #c2410c;
    color: #78350f;
    padding: 3px 8px;
    border-radius: 4px;
    cursor: pointer;
    font-size: 11px;
    font-family: inherit;
}

/* Selection-chip rendered above the composer — shows tag + text-preview +
   a × to clear. Click × to drop the selection without clearing the chat. */
.sidekick-frontend__context {
    margin: 6px 0;
    padding: 0;
}
.sidekick-frontend__context[hidden] { display: none; }
.sidekick-frontend__context-inner {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    border-radius: 5px;
    border: 1px solid var(--sk-accent);
    background: rgba(33, 82, 163, 0.06);
    font-size: 12px;
}
.sidekick-frontend__context-tag {
    display: inline-flex;
    padding: 1px 5px;
    border-radius: 9990px;
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
    font-size: 10px;
    font-weight: 700;
    text-transform: lowercase;
    flex-shrink: 0;
}
.sidekick-frontend__context-text {
    flex: 1;
    color: var(--sk-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.sidekick-frontend__context-clear {
    width: 24px;
    height: 24px;
    border: none;
    background: transparent;
    color: var(--sk-fg);
    cursor: pointer;
    border-radius: 50%;
    font-size: 14px;
    line-height: 1;
    flex-shrink: 0;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__context-clear:hover {
        background: rgba(0, 0, 0, 0.08);
    }
}

/* Combined row for quick-actions + saved-prompts toggle. The chips fill the
   available space and wrap; the 📋-toggle sits flush on the right. */
.sidekick-frontend__actions-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px 0;
    flex-wrap: nowrap;
}
/* Saved-prompts picker — compact icon-button living inline with the quick-
   actions row so it doesn't add a separate strip. */
.sidekick-frontend__prompts {
    position: relative;
    display: flex;
    justify-content: flex-end;
    flex-shrink: 0;
    margin: 0;
    padding: 0;
}
.sidekick-frontend__prompts[hidden] { display: none; }
.sidekick-frontend__prompts-toggle {
    position: relative;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    border: 1px solid var(--sk-border);
    background: var(--sk-bg);
    color: var(--sk-fg);
    cursor: pointer;
    font-family: inherit;
    font-size: 12px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.sidekick-frontend__prompts-count {
    position: absolute;
    top: -3px;
    right: -3px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 9990px;
    background: var(--sk-accent);
    color: var(--sk-accent-fg);
    font-size: 9.5px;
    font-weight: 700;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__prompts-toggle:hover { background: var(--sk-border); }
}
.sidekick-frontend__prompts-menu {
    position: absolute;
    bottom: calc(100% + 6px);
    /* Right-anchored to the toggle (which sits at the row's right edge) and
       wide enough to feel like a proper card without spilling out of the
       panel. Caps at the panel's effective width via max-width. */
    right: 0;
    width: 280px;
    max-width: calc(100vw - 60px);
    max-height: 280px;
    overflow-y: auto;
    background: var(--sk-bg);
    border: 1px solid var(--sk-border);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    z-index: 30;
}
/* `[hidden]` would normally apply `display: none`, but the rule above sets
   `display: flex` with higher specificity — re-assert hidden behaviour. */
.sidekick-frontend__prompts-menu[hidden] { display: none; }
.sidekick-frontend__prompt-item {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 12px;
    border: none;
    background: transparent;
    color: inherit;
    cursor: pointer;
    text-align: left;
    border-radius: 6px;
    font-family: inherit;
}
.sidekick-frontend__prompt-title {
    font-weight: 600;
    font-size: 14px;
    line-height: 1.3;
}
.sidekick-frontend__prompt-desc {
    font-size: 12px;
    line-height: 1.4;
    color: var(--sk-fg-alt, #66686e);
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__prompt-item:hover {
        background: rgba(0, 0, 0, 0.05);
    }
}

/* =====================================================================
   INTERACTION POLISH — added late so it overrides earlier base styles.
   Shared timing language across all surfaces:
     - Springy ease: cubic-bezier(0.34, 1.56, 0.64, 1)  (hover lift, icon wobble)
     - Soft eOutExpo: cubic-bezier(0.16, 1, 0.3, 1)    (panel + bubble entrance)
     - Snap: 80-120ms linear                            (active press)
   ===================================================================== */

/* --- Universal button transitions ---
   Anything clickable inside the widget gets the same baseline transition
   so hover / focus / active changes feel uniform. Per-element overrides
   below tune the actual transform/colour. */
#jsSidekickFrontend .sidekick-frontend__send,
#jsSidekickFrontend .sidekick-frontend__mic,
#jsSidekickFrontend .sidekick-frontend__head-btn,
#jsSidekickFrontend .sidekick-frontend__refresh-btn,
#jsSidekickFrontend .sidekick-frontend__pick-cancel,
#jsSidekickFrontend .sidekick-frontend__prompts-toggle,
#jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick,
#jsSidekickFrontend .sidekick-frontend__crew-chip,
#jsSidekickFrontend .sidekick-frontend__confirm-btn,
#jsSidekickFrontend .sidekick-frontend__confirm-cancel {
    transition:
        transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
        background-color 180ms ease-out,
        border-color 180ms ease-out,
        color 180ms ease-out,
        box-shadow 220ms ease-out;
    /* Hardware-accelerate to avoid sub-pixel jitter during transform. */
    will-change: transform;
}

/* Hover-lift — applies to primary buttons (send + confirm + quick chips).
   Subtle: 1px translateY + soft shadow growth so it feels physical, not
   bouncy. Hover only on devices that actually hover (touch screens skip). */
@media (hover: hover) and (pointer: fine) {
    #jsSidekickFrontend .sidekick-frontend__send:hover:not(:disabled),
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick:hover,
    #jsSidekickFrontend .sidekick-frontend__refresh-btn:hover:not(:disabled),
    #jsSidekickFrontend .sidekick-frontend__head-btn:hover,
    #jsSidekickFrontend .sidekick-frontend__pick-cancel:hover {
        transform: translateY(-1px);
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    }
    /* Icon-only header-buttons (close, new chat, history toggle, pick-mode)
       get a softer accent-tint instead of a heavy lift. */
    #jsSidekickFrontend .sidekick-frontend__head-btn:hover {
        background: rgba(33, 82, 163, 0.08);
        color: var(--sk-accent);
    }
}

/* Press feedback — every clickable element scales down briefly. Same gesture
   across send, mic, confirm, chips, etc. Short 80ms transition so the user
   sees the squash without it feeling sluggish. */
#jsSidekickFrontend .sidekick-frontend__send:active:not(:disabled),
#jsSidekickFrontend .sidekick-frontend__mic:active,
#jsSidekickFrontend .sidekick-frontend__head-btn:active,
#jsSidekickFrontend .sidekick-frontend__refresh-btn:active:not(:disabled),
#jsSidekickFrontend .sidekick-frontend__pick-cancel:active,
#jsSidekickFrontend .sidekick-frontend__prompts-toggle:active,
#jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick:active,
#jsSidekickFrontend .sidekick-frontend__crew-chip:active,
#jsSidekickFrontend .sidekick-frontend__confirm-btn:active:not(:disabled),
#jsSidekickFrontend .sidekick-frontend__confirm-cancel:active:not(:disabled) {
    transform: scale(0.95);
    transition-duration: 80ms;
}

/* Keyboard focus ring — visible only on :focus-visible (not on mouse-click
   focus) so we don't drown the UI in rings during normal use. */
#jsSidekickFrontend button:focus-visible,
#jsSidekickFrontend textarea:focus-visible {
    outline: 2px solid var(--sk-accent);
    outline-offset: 2px;
}

/* Composer textarea — soft accent glow on focus instead of the default ring.
   Replaces the harsh box-shadow look that browsers ship with. */
#jsSidekickFrontend .sidekick-frontend__input {
    transition:
        border-color 180ms ease-out,
        box-shadow 220ms ease-out;
}
#jsSidekickFrontend .sidekick-frontend__input:focus {
    outline: none;
    border-color: var(--sk-accent);
    box-shadow: 0 0 0 3px rgba(33, 82, 163, 0.18);
}

/* Send button morph — when streaming, the button background goes to red and
   shows a small stop indicator. Triggered by JS adding `is-streaming` (see
   sidekick-frontend.js where the textContent flips to "Stop"). The button
   already changes text via JS; this just makes the colour transition smooth. */
#jsSidekickFrontend .sidekick-frontend__send {
    /* Keep the send transition slightly different so the colour change reads
       as deliberate, not a flicker. */
    transition:
        background-color 220ms ease-out,
        color 220ms ease-out,
        transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
        box-shadow 220ms ease-out;
}

/* Crew-chip — extra polish on active state so the selected crewlid has visual
   weight. The base styles already swap colours; we add a subtle ring + soft
   shadow that pulses once on selection. */
#jsSidekickFrontend .sidekick-frontend__crew-chip--active {
    box-shadow: 0 0 0 2px rgba(33, 82, 163, 0.18), 0 2px 6px rgba(0, 0, 0, 0.08);
    animation: sk-crew-select 360ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes sk-crew-select {
    0%   { transform: scale(0.94); }
    55%  { transform: scale(1.04); }
    100% { transform: scale(1);    }
}

/* Quick-action chips — gentle ripple on click. The ::after pseudo grows from
   the click position (set as --sk-ripple-x/y in JS, or fallback center). */
#jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick {
    position: relative;
    overflow: hidden;
}
#jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick::after {
    content: "";
    position: absolute;
    top: 50%; left: 50%;
    width: 0; height: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.35);
    transform: translate(-50%, -50%);
    pointer-events: none;
    transition: width 360ms ease-out, height 360ms ease-out, opacity 360ms ease-out;
    opacity: 0;
}
#jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick:active::after {
    width: 220%;
    height: 220%;
    opacity: 1;
    transition-duration: 0s;
}

/* FAB entrance — when the widget first mounts on a page-load, the trigger
   bounces in from below. Avoids the "ping! a button suddenly appeared"
   feeling. Runs once because animation has no infinite. */
.sidekick-frontend__trigger {
    animation: sk-fab-in 520ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes sk-fab-in {
    from { opacity: 0; transform: translateY(20px) scale(0.7); }
    60%  { opacity: 1; transform: translateY(-4px) scale(1.04); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Notification banner inside the transcript (open pending actions on load).
   Slides down from top so it doesn't appear out of nowhere. */
#jsSidekickFrontend .sidekick-frontend__notif {
    animation: sk-notif-in 380ms cubic-bezier(0.16, 1, 0.3, 1);
    transform-origin: top center;
}
@keyframes sk-notif-in {
    from { opacity: 0; transform: translateY(-8px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

/* Confirm-card subtle attention pulse — draws the eye to a pending action
   that just appeared. Runs once on first mount, doesn't repeat. */
#jsSidekickFrontend .sidekick-frontend__confirm {
    animation:
        sk-confirm-in 340ms cubic-bezier(0.16, 1, 0.3, 1),
        sk-confirm-attention 1.4s ease-out 200ms;
    transform-origin: top center;
}
@keyframes sk-confirm-in {
    from { opacity: 0; transform: translateY(-6px) scale(0.97); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes sk-confirm-attention {
    0%, 100% { box-shadow: 0 0 0 0 rgba(255, 196, 0, 0); }
    30%      { box-shadow: 0 0 0 6px rgba(255, 196, 0, 0.18); }
}

/* Streaming-text shimmer — while the assistant is generating, the most recent
   assistant bubble gets a soft gradient sweep across its background. Subtle:
   only visible when actually streaming, fades the moment the stream ends.
   JS adds `is-streaming` to the bubble during the open turn. */
#jsSidekickFrontend .sidekick-frontend__bubble--assistant.is-streaming {
    background: linear-gradient(
        110deg,
        var(--sk-bubble-assistant-bg, #f4f4f4) 30%,
        rgba(33, 82, 163, 0.06) 50%,
        var(--sk-bubble-assistant-bg, #f4f4f4) 70%
    );
    background-size: 200% 100%;
    animation: sk-stream-shimmer 2.8s linear infinite;
}
@keyframes sk-stream-shimmer {
    from { background-position: 200% 0; }
    to   { background-position: -200% 0; }
}

/* Reduced-motion: kill every animation we just added. */
@media (prefers-reduced-motion: reduce) {
    #jsSidekickFrontend .sidekick-frontend__send,
    #jsSidekickFrontend .sidekick-frontend__mic,
    #jsSidekickFrontend .sidekick-frontend__head-btn,
    #jsSidekickFrontend .sidekick-frontend__refresh-btn,
    #jsSidekickFrontend .sidekick-frontend__pick-cancel,
    #jsSidekickFrontend .sidekick-frontend__prompts-toggle,
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick,
    #jsSidekickFrontend .sidekick-frontend__crew-chip,
    #jsSidekickFrontend .sidekick-frontend__confirm-btn,
    #jsSidekickFrontend .sidekick-frontend__confirm-cancel,
    #jsSidekickFrontend .sidekick-frontend__input { transition: none; }
    #jsSidekickFrontend .sidekick-frontend__crew-chip--active,
    .sidekick-frontend__trigger,
    #jsSidekickFrontend .sidekick-frontend__notif,
    #jsSidekickFrontend .sidekick-frontend__confirm,
    #jsSidekickFrontend .sidekick-frontend__bubble--assistant.is-streaming { animation: none; }
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick::after { transition: none; }
    #jsSidekickFrontend .sidekick-frontend__send:hover,
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick:hover,
    #jsSidekickFrontend .sidekick-frontend__refresh-btn:hover,
    #jsSidekickFrontend .sidekick-frontend__head-btn:hover,
    #jsSidekickFrontend .sidekick-frontend__pick-cancel:hover,
    #jsSidekickFrontend [class*="sidekick-frontend__"]:active { transform: none; }
}

/* ════════════════════════════════════════════════════════════════════════
   Inline-edit system (SbEditable elements, toolbar, editor, undo toast)
   ════════════════════════════════════════════════════════════════════════
   Activated when an editor is logged into the backoffice; the
   sidekick-frontend.js bootstrap adds `.sb-editable-hint` to <body> so
   these hover hints only apply for authenticated editors. The animated
   "marching ants" selection style runs only on the explicitly picked
   element so the rest of the page stays calm.
   ──────────────────────────────────────────────────────────────────── */

/* Subtle hover preview on editable elements (only on devices with real
   hover, not touch — touch-hover is sticky and would look broken). */
@media (hover: hover) and (pointer: fine) {
    body.sb-editable-hint .sb-editable {
        cursor: default;
    }
    body.sb-editable-hint.sk-pick-mode .sb-editable:hover {
        outline: 2px dashed rgba(245, 158, 11, 0.55);
        outline-offset: 3px;
        cursor: pointer;
    }
}

/* The "marching ants" dashed border that appears on the actively-selected
   editable element. Uses outline (not border) so it never affects the
   element's box-model — text reflow is avoided regardless of element. */
.sb-editable--selected {
    outline: 2.5px dashed #f59e0b;
    outline-offset: 4px;
    border-radius: 2px;
    animation: sb-marching-ants 1.2s linear infinite;
}
@keyframes sb-marching-ants {
    to { outline-offset: 8px; }
}
@media (prefers-reduced-motion: reduce) {
    .sb-editable--selected { animation: none; }
}

/* Floating toolbar attached to the selected element. position: absolute
   on document.body so it can extend past any clipping ancestor. JS
   sets left/top each frame to keep it pinned during scroll. */
.sb-inline-toolbar {
    position: absolute;
    z-index: 2147483640;
    display: inline-flex;
    align-items: stretch;
    gap: 2px;
    padding: 3px;
    background: #1c2333;
    border-radius: 8px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28), 0 2px 8px rgba(0, 0, 0, 0.18);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    animation: sb-toolbar-in 220ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes sb-toolbar-in {
    from { opacity: 0; transform: translateY(-4px) scale(0.96); }
    to   { opacity: 1; transform: translateY(0)    scale(1); }
}
.sb-inline-toolbar__btn {
    appearance: none;
    background: transparent;
    color: #fff;
    border: 0;
    padding: 7px 10px;
    border-radius: 5px;
    font: inherit;
    font-size: 13px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    line-height: 1;
    white-space: nowrap;
    transition: background-color 120ms ease;
}
.sb-inline-toolbar__btn:hover {
    background: rgba(255, 255, 255, 0.12);
}
.sb-inline-toolbar__btn--ghost {
    color: rgba(255, 255, 255, 0.55);
    padding: 7px 9px;
    font-size: 14px;
}
.sb-inline-toolbar__btn--ghost:hover {
    color: #fff;
}

/* Dictionary-edit variant of the toolbar gets an amber "Sitewide" badge so
   the editor knows the wijziging niet page-local is — every page that uses
   the key picks up the new value. */
.sb-inline-toolbar--sitewide {
    border: 1px solid rgba(245, 158, 11, 0.55);
}
.sb-inline-toolbar__warning {
    display: inline-flex;
    align-items: center;
    padding: 0 8px;
    margin-right: 2px;
    font-size: 11px;
    font-weight: 600;
    color: #1c2333;
    background: linear-gradient(180deg, #fbbf24, #f59e0b);
    border-radius: 5px;
    line-height: 1;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    white-space: nowrap;
    cursor: help;
}

/* The inline editor that replaces the element's contents during edit.
   --text variant is a single <input>; --rich is contenteditable + a
   tiny mini-toolbar (B/I/U/Link/Reset). Style scoped so it doesn't
   inherit page-level h1/p typography quirks. */
.sb-inline-editor {
    /* `inline-block` (i.p.v. block) zodat de editor ook binnen een inline
       parent — bv. een `<span>` rond een button-label binnen een `<a>` —
       een eigen block-context heeft. Anders 'unwrappen' browsers de inner
       `<div>` als inline en stapelt de actions-bar niet meer onder de input.
       min-width voorkomt dat een edit op een KORT label resulteert in een
       onbruikbaar smal invoerveld. max-width houdt 'm leesbaar in brede
       containers. */
    display: inline-block;
    width: 100%;
    max-width: 480px;
    min-width: 240px;
    box-sizing: border-box;
    vertical-align: top;
    text-align: left;
    /* Reset typografie binnen de editor — het kan in een h1/h2/h3 staan en
       die heeft grote font-size, line-height + kleur. We willen dat de
       editor-knoppen + hint altijd dezelfde look hebben, ongeacht waar de
       inline-edit gemount wordt. Specifieke editor-elementen (input/content/
       textarea) krijgen daarna hun eigen typografie. */
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.4;
    color: #1c2333;
    text-transform: none;
    letter-spacing: normal;
    font-style: normal;
}
/* Reset alle UI-controls binnen de editor zodat ze niet van een wrapping
   h1/h2/h3 of een knop-achtige link erven (font-size/weight/transform). */
.sb-inline-editor button,
.sb-inline-editor input,
.sb-inline-editor textarea,
.sb-inline-editor__hint,
.sb-inline-editor__actions,
.sb-inline-editor__rich-toolbar,
.sb-inline-editor__rich-toolbar button {
    font-family: inherit;
    font-style: normal;
    text-transform: none;
    letter-spacing: normal;
}
.sb-inline-editor__input,
.sb-inline-editor__content {
    /* Block + width:100% zorgt dat de actions-bar er ALTIJD onder valt,
       ook in een flex- of inline-parent. */
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 6px 10px;
    /* ONDOORZICHTIGE achtergrond + eigen tekstkleur, bewust NIET `color: inherit` met een
       doorschijnende achtergrond. De editor wordt naast het bewerkte element in de PAGINA
       geinjecteerd -- dus buiten #jsSidekickFrontend, waar de --sk-*-variabelen niet reiken -- en
       erfde daarmee de kleuren van de host. Op een site met een donkere achtergrond (korzo.nl doet
       `html { background-color: #000 }`) leverde een 6%-doorzichtige vulling plus geerfde tekst
       zwarte letters op een zwarte achtergrond op: onleesbaar, en niet te repareren zonder de site
       te kennen. Een floating editor is een eigen UI-oppervlak en hoort zijn eigen kleuren te zetten,
       net als elke popover. De amber outline blijft het herkenningspunt. */
    background: #fff;
    color: #1b264f;
    border: 0;
    outline: 2px solid #f59e0b;
    outline-offset: 0;
    border-radius: 4px;
    /* font: inherit houdt de editor in de typografie van het element dat je bewerkt -- dat is juist
       gewenst, want je ziet zo hoe de tekst er straks uitziet. Alleen de KLEUREN mogen niet erven. */
    font: inherit;
}
/* Links in de rich-text-editor moeten zichtbaar blijven tegen de eigen witte achtergrond, ook als
   de host ze wit maakt voor zijn donkere pagina. */
.sb-inline-editor__content a {
    color: #1d4ed8;
    text-decoration: underline;
}
.sb-inline-editor__input:focus,
.sb-inline-editor__content:focus {
    outline-width: 2.5px;
    /* Ook hier ONDOORZICHTIG. Dit was de laatste plek waar de host-achtergrond doorheen schemerde:
       het veld zag er ongefocust prima uit (wit met donkere tekst) en sloeg bij de eerste klik om
       naar zwart-op-zwart, omdat deze regel de vulling terugzette naar 10% amber. Een fractie
       donkerder dan de basis zodat focus zichtbaar blijft, maar zonder de pagina erachter te tonen. */
    background: #fdf6e9;
}
.sb-inline-editor__content {
    min-height: 1.5em;
    cursor: text;
    line-height: 1.4;
}
.sb-inline-editor__content p:first-child { margin-top: 0; }
.sb-inline-editor__content p:last-child  { margin-bottom: 0; }
.sb-inline-editor__rich-toolbar {
    display: inline-flex;
    background: #1c2333;
    border-radius: 6px;
    padding: 2px;
    margin-bottom: 6px;
    gap: 1px;
}
.sb-inline-editor__rich-toolbar button {
    appearance: none;
    background: transparent;
    color: #fff;
    border: 0;
    padding: 5px 9px;
    border-radius: 4px;
    cursor: pointer;
    font: inherit;
    font-size: 13px;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    transition: background-color 120ms ease;
}
.sb-inline-editor__rich-toolbar button:hover {
    background: rgba(255, 255, 255, 0.12);
}
.sb-inline-editor__rich-toolbar svg { display: block; }
.sb-inline-editor__actions {
    /* Eigen block-row onder de input. flex (geen inline-flex) zodat 'ie
       een nieuwe lijn pakt en niet naast de input gaat staan in een
       flex-parent. */
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}
.sb-inline-editor__btn {
    appearance: none;
    padding: 6px 14px;
    border: 0;
    border-radius: 4px;
    font: inherit;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    line-height: 1.2;
    transition: filter 120ms ease, transform 80ms ease;
}
.sb-inline-editor__btn:hover { filter: brightness(0.95); }
.sb-inline-editor__btn:active { transform: translateY(1px); }
.sb-inline-editor__btn--save {
    background: linear-gradient(135deg, #fbbf24, #f59e0b);
    color: #1c2333;
}
.sb-inline-editor__btn--cancel {
    background: #e5e7eb;
    color: #1c2333;
}

/* TextArea editor — multi-line voor TextArea + MultipleTextstring. */
.sb-inline-editor--textarea .sb-inline-editor__textarea {
    width: 100%;
    min-height: 90px;
    padding: 8px 10px;
    font: inherit;
    font-size: 14px;
    line-height: 1.5;
    border: 2px solid #f59e0b;
    border-radius: 6px;
    background: #ffffff;
    color: #1f2937;
    resize: vertical;
    box-sizing: border-box;
    margin-bottom: 4px;
}
.sb-inline-editor--textarea .sb-inline-editor__textarea:focus {
    outline: none;
    border-color: #d97706;
    box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.18);
}
.sb-inline-editor__hint {
    font-size: 11px;
    color: #6b7280;
    margin-bottom: 6px;
    font-style: italic;
}
.sb-inline-editor__btn[disabled] {
    opacity: 0.6;
    cursor: progress;
    pointer-events: none;
}
.sb-inline-editor__btn.is-saving {
    /* Wat lichter zodat de spinner contrastrijk leest op de gele knop. */
    background: linear-gradient(135deg, #fcd34d, #fbbf24);
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

/* Generieke spinner — wordt momenteel alleen in de save-knop gebruikt maar
   herbruikbaar voor andere "ben bezig"-states later. */
.sb-spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: sb-spin 0.7s linear infinite;
    vertical-align: -2px;
}
@keyframes sb-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    /* Spinner niet animeren bij motion-reduce; gewoon statisch tonen.
       De combinatie disabled-knop + tekst "Opslaan…" geeft genoeg signaal. */
    .sb-spinner { animation: none; }
}

/* Undo toast — bottom-center, dismissable, auto-vanishes after 30s. */
.sb-undo-toast {
    position: fixed;
    bottom: 28px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2147483641;
    display: inline-flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px 12px 20px;
    background: #1c2333;
    color: #fff;
    border-radius: 10px;
    box-shadow: 0 10px 32px rgba(0, 0, 0, 0.32), 0 2px 8px rgba(0, 0, 0, 0.18);
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 14px;
    animation: sb-undo-in 280ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes sb-undo-in {
    from { opacity: 0; transform: translate(-50%, 12px); }
    to   { opacity: 1; transform: translate(-50%, 0); }
}
.sb-undo-toast__text {
    font-weight: 500;
}
.sb-undo-toast__btn {
    appearance: none;
    background: linear-gradient(135deg, #fbbf24, #f59e0b);
    color: #1c2333;
    border: 0;
    padding: 7px 14px;
    border-radius: 5px;
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: filter 120ms ease;
}
.sb-undo-toast__btn:hover { filter: brightness(0.95); }
.sb-undo-toast__close {
    appearance: none;
    background: transparent;
    color: rgba(255, 255, 255, 0.45);
    border: 0;
    cursor: pointer;
    font-size: 15px;
    padding: 0 4px;
    line-height: 1;
    transition: color 120ms ease;
}
.sb-undo-toast__close:hover { color: #fff; }

@media (prefers-reduced-motion: reduce) {
    .sb-inline-toolbar,
    .sb-undo-toast,
    .sb-proposal-overlay { animation: none; }
    .sb-editable--proposed { animation: none; }
}

/* ============================================================
   Stale-conflict view inside the editable element
   Replaces the inline editor when /sb-sidekick/inline-edit POST
   replies 409 — the editor sees their version vs the server's
   and picks which one wins.
   ============================================================ */

.sb-inline-conflict {
    border: 2px solid #f59e0b;
    border-radius: 8px;
    padding: 12px;
    background: #fffbeb;
    color: #1f2937;
}
.sb-inline-conflict__header {
    font-weight: 600;
    color: #b45309;
    margin-bottom: 8px;
}
.sb-inline-conflict__panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
    margin-bottom: 8px;
}
@media (max-width: 700px) {
    .sb-inline-conflict__panels { grid-template-columns: 1fr; }
}
.sb-inline-conflict__panel {
    background: #fff;
    border: 1px solid #fcd34d;
    border-radius: 6px;
    padding: 8px;
}
.sb-inline-conflict__label {
    font-size: 12px;
    font-weight: 600;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 4px;
}
.sb-inline-conflict__content {
    font-size: 14px;
    line-height: 1.5;
    color: #1f2937;
    max-height: 200px;
    overflow-y: auto;
}
.sb-inline-conflict__actions {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
}

/* ============================================================
   propose_text_change diff overlay
   Anchored card showing current vs proposed text when the AI
   agent calls propose_text_change. Editor accepts (commits
   through inline-edit POST) or cancels — agent flow is not
   blocked by either choice.
   ============================================================ */

.sb-proposal-overlay {
    position: absolute;
    z-index: 2147483641;  /* one above the inline toolbar */
    width: min(560px, calc(100vw - 24px));
    background: #ffffff;
    border-radius: 10px;
    box-shadow: 0 18px 40px rgba(15, 23, 42, 0.25), 0 2px 8px rgba(15, 23, 42, 0.10);
    border: 1px solid #e5e7eb;
    color: #1f2937;
    animation: sb-proposal-in 200ms ease-out;
}
@keyframes sb-proposal-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}
.sb-proposal-overlay--floating {
    /* Modal fallback when no anchor element was found. Centred near top. */
    position: fixed;
    top: 80px;
    left: 50%;
    transform: translateX(-50%);
}
.sb-proposal-overlay__inner {
    display: flex;
    flex-direction: column;
}
.sb-proposal-overlay__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    border-bottom: 1px solid #e5e7eb;
    background: linear-gradient(to bottom, #fffaf0, #fff);
}
.sb-proposal-overlay__title {
    font-weight: 600;
    font-size: 14px;
    color: #92400e;
}
.sb-proposal-overlay__close {
    background: transparent;
    border: 0;
    color: #6b7280;
    font-size: 16px;
    line-height: 1;
    padding: 4px 6px;
    cursor: pointer;
    border-radius: 4px;
}
.sb-proposal-overlay__close:hover { background: #f3f4f6; color: #1f2937; }
.sb-proposal-overlay__reason {
    padding: 8px 12px;
    background: #fef3c7;
    border-bottom: 1px solid #fcd34d;
    font-size: 13px;
    color: #78350f;
    font-style: italic;
}
.sb-proposal-overlay__panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    background: #e5e7eb;
}
@media (max-width: 600px) {
    .sb-proposal-overlay__panels { grid-template-columns: 1fr; }
}
.sb-proposal-overlay__panel {
    background: #ffffff;
    padding: 10px 12px;
}
.sb-proposal-overlay__panel--after {
    background: #f0fdf4;  /* subtle green wash on the "new" side */
}
.sb-proposal-overlay__label {
    font-size: 11px;
    font-weight: 600;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 4px;
}
.sb-proposal-overlay__panel--after .sb-proposal-overlay__label { color: #166534; }
.sb-proposal-overlay__content {
    font-size: 14px;
    line-height: 1.55;
    color: #1f2937;
    max-height: 220px;
    overflow-y: auto;
    word-break: break-word;
}
.sb-proposal-overlay__content em { color: #9ca3af; font-style: italic; }
.sb-proposal-overlay__actions {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
    padding: 8px 12px 10px;
    border-top: 1px solid #e5e7eb;
    background: #fafafa;
}
.sb-proposal-overlay__btn {
    border: 0;
    border-radius: 6px;
    padding: 7px 14px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: filter 120ms ease, background 120ms ease;
}
.sb-proposal-overlay__btn[disabled] { opacity: 0.5; cursor: progress; }
.sb-proposal-overlay__btn--primary {
    background: #f59e0b;
    color: #fff;
}
.sb-proposal-overlay__btn--secondary {
    background: #fff;
    color: #4b5563;
    border: 1px solid #d1d5db;
}
@media (hover: hover) and (pointer: fine) {
    .sb-proposal-overlay__btn--primary:hover { filter: brightness(1.07); }
    .sb-proposal-overlay__btn--secondary:hover { background: #f9fafb; color: #1f2937; }
}

/* Halo on the anchor element while the proposal is being reviewed —
   makes it obvious which text the diff card refers to. */
.sb-editable--proposed {
    outline: 2px dashed #f59e0b !important;
    outline-offset: 4px;
    border-radius: 4px;
    animation: sb-marching-ants 18s linear infinite;
}

/* =========================================================================
   Inline proposal card — chat-bubble version of the floating overlay.
   Lives in the normal document flow inside an assistant chat-bubble; same
   payload + same shared commit handler. Tighter padding than the overlay
   because the chat-bubble already gives us a container chrome.
   ------------------------------------------------------------------------- */
.sb-proposal-inline {
    margin-top: 8px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #ffffff;
    overflow: hidden;
    color: #1f2937;
}
.sb-proposal-inline__header {
    padding: 7px 10px;
    border-bottom: 1px solid #e5e7eb;
    background: linear-gradient(to bottom, #fffaf0, #fff);
}
.sb-proposal-inline__title {
    font-weight: 600;
    font-size: 13px;
    color: #92400e;
}
.sb-proposal-inline__reason {
    padding: 6px 10px;
    background: #fef3c7;
    border-bottom: 1px solid #fcd34d;
    font-size: 12px;
    color: #78350f;
    font-style: italic;
}
.sb-proposal-inline__panels {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    background: #e5e7eb;
}
@media (max-width: 600px) {
    .sb-proposal-inline__panels { grid-template-columns: 1fr; }
}
.sb-proposal-inline__panel {
    background: #ffffff;
    padding: 7px 9px;
}
.sb-proposal-inline__panel--after { background: #f0fdf4; }
.sb-proposal-inline__label {
    font-size: 10px;
    font-weight: 600;
    color: #6b7280;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: 3px;
}
.sb-proposal-inline__panel--after .sb-proposal-inline__label { color: #166534; }
.sb-proposal-inline__content {
    font-size: 13px;
    line-height: 1.5;
    color: #1f2937;
    max-height: 180px;
    overflow-y: auto;
    word-break: break-word;
}
.sb-proposal-inline__content em { color: #9ca3af; font-style: italic; }
.sb-proposal-inline__actions {
    display: flex;
    gap: 5px;
    justify-content: flex-end;
    padding: 6px 10px 8px;
    border-top: 1px solid #e5e7eb;
    background: #fafafa;
}
.sb-proposal-inline__btn {
    border: 0;
    border-radius: 6px;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    transition: filter 120ms ease, background 120ms ease;
}
.sb-proposal-inline__btn[disabled] { opacity: 0.5; cursor: progress; }
.sb-proposal-inline__btn--primary { background: #f59e0b; color: #fff; }
.sb-proposal-inline__btn--secondary {
    background: #fff;
    color: #4b5563;
    border: 1px solid #d1d5db;
}
@media (hover: hover) and (pointer: fine) {
    .sb-proposal-inline__btn--primary:hover { filter: brightness(1.07); }
    .sb-proposal-inline__btn--secondary:hover { background: #f9fafb; color: #1f2937; }
}

/* =========================================================================
   LIQUID GLASS — frontend widget theme
   =========================================================================
   Mirror of the backoffice liquid-glass treatment from `app.ts`. Tokens use
   the existing `--sk-*` prefix so they don't clash with backoffice variables
   (the widget runs ON the public site, not in Umbraco's shadow-DOM).
   Light + dark adaptive via @media (prefers-color-scheme: dark). Same
   no-nested-glass perf rule: panel + composer get backdrop-filter, bubbles
   only get rgba+border so the GPU doesn't repaint 20 frosted rects per
   scroll. Site-developers can override any token by re-declaring it at
   #jsSidekickFrontend level.
   ------------------------------------------------------------------------- */
#jsSidekickFrontend {
    --sk-glass-bg: rgba(255, 255, 255, 0.55);
    --sk-glass-bg-strong: rgba(255, 255, 255, 0.72);
    --sk-glass-bg-subtle: rgba(255, 255, 255, 0.42);
    --sk-glass-bg-tint: rgba(245, 247, 255, 0.6);
    --sk-glass-blur: 24px;
    --sk-glass-blur-strong: 36px;
    --sk-glass-blur-subtle: 14px;
    --sk-glass-saturate: 180%;
    --sk-glass-edge-hi: rgba(255, 255, 255, 0.85);
    --sk-glass-edge-lo: rgba(0, 0, 0, 0.06);
    --sk-glass-border: rgba(255, 255, 255, 0.6);
    --sk-glass-border-subtle: rgba(255, 255, 255, 0.35);
    --sk-glass-shadow:
        0 8px 32px rgba(31, 38, 135, 0.12),
        0 2px 8px rgba(31, 38, 135, 0.06);
    --sk-glass-shadow-strong:
        0 24px 70px rgba(31, 38, 135, 0.22),
        0 6px 18px rgba(31, 38, 135, 0.1);
    --sk-glass-shadow-floating:
        0 40px 100px rgba(31, 38, 135, 0.28),
        0 10px 30px rgba(31, 38, 135, 0.12);
    /* Pastel gradient that sits BEHIND the panel's glass tint as a layered
       background, so the frosted surface has something coloured to read as.
       Without this the panel reads as solid white over a white page. Mirrors
       the --sb-stage-bg in the backoffice; same indigo / magenta / cyan
       hints so the brand-feel matches across surfaces. */
    --sk-stage-bg:
        radial-gradient(circle at 15% 10%, rgba(99, 102, 241, 0.14), transparent 45%),
        radial-gradient(circle at 85% 90%, rgba(236, 72, 153, 0.10), transparent 50%),
        radial-gradient(circle at 50% 50%, rgba(56, 189, 248, 0.08), transparent 60%),
        linear-gradient(135deg, rgba(244, 245, 250, 0.4), rgba(232, 236, 248, 0.4));
    --sk-spring-soft: cubic-bezier(0.34, 1.56, 0.64, 1);
    --sk-spring-snap: cubic-bezier(0.22, 1.2, 0.36, 1);
    --sk-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

@media (prefers-color-scheme: dark) {
    #jsSidekickFrontend {
        --sk-glass-bg: rgba(28, 30, 38, 0.55);
        --sk-glass-bg-strong: rgba(28, 30, 38, 0.78);
        --sk-glass-bg-subtle: rgba(28, 30, 38, 0.42);
        --sk-glass-bg-tint: rgba(36, 40, 56, 0.58);
        --sk-glass-edge-hi: rgba(255, 255, 255, 0.18);
        --sk-glass-edge-lo: rgba(0, 0, 0, 0.5);
        --sk-glass-border: rgba(255, 255, 255, 0.12);
        --sk-glass-border-subtle: rgba(255, 255, 255, 0.07);
        --sk-glass-shadow: 0 8px 32px rgba(0, 0, 0, 0.45);
        --sk-glass-shadow-strong: 0 24px 70px rgba(0, 0, 0, 0.55);
        --sk-glass-shadow-floating: 0 40px 100px rgba(0, 0, 0, 0.7);
        --sk-stage-bg:
            radial-gradient(circle at 15% 10%, rgba(99, 102, 241, 0.20), transparent 45%),
            radial-gradient(circle at 85% 90%, rgba(236, 72, 153, 0.14), transparent 50%),
            radial-gradient(circle at 50% 50%, rgba(56, 189, 248, 0.10), transparent 60%),
            linear-gradient(135deg, rgba(18, 20, 28, 0.6), rgba(24, 26, 36, 0.6));
    }
}

/* Panel — full liquid-glass treatment. Replaces the original solid-white
   background with a floating frosted card. Stronger blur than the inline
   chat surfaces because the panel sits over arbitrary website content
   that we want hidden behind the glass for focus. */
.sidekick-frontend__panel {
    /* Two-layer background: glass-bg-strong on top (white-ish wash),
       stage-bg below (pastel gradient). Together they give the panel a
       stable refracted look regardless of what the user's page shows
       behind it — backdrop-filter still blurs the page-pixels for added
       depth, but we no longer depend on those pixels having any colour.

       The white wash MUST be expressed as a gradient layer, not a bare colour.
       A <color> is only valid as the FINAL background layer; putting it first
       (`background: <color>, <gradients>`) made the whole shorthand invalid at
       computed-value time (it comes in via var()), so `background` fell back to
       its initial `transparent`. On a light host that still looked white-ish, but
       on a dark host the panel was see-through and the text became unreadable.
       `linear-gradient(colour, colour)` is a valid image layer and paints the
       same flat wash on top of the pastel stage. */
    background: linear-gradient(var(--sk-glass-bg-strong), var(--sk-glass-bg-strong)), var(--sk-stage-bg) !important;
    -webkit-backdrop-filter: blur(var(--sk-glass-blur-strong)) saturate(var(--sk-glass-saturate));
    backdrop-filter: blur(var(--sk-glass-blur-strong)) saturate(var(--sk-glass-saturate));
    border: 1px solid var(--sk-glass-border) !important;
    border-radius: 18px !important;
    box-shadow:
        var(--sk-glass-shadow-floating),
        inset 0 1px 0 var(--sk-glass-edge-hi),
        inset 0 -1px 0 var(--sk-glass-edge-lo) !important;
}
/* Top-edge sheen — 1px highlight line that reads as refracted light.
   Inset 12% from corners so it tapers in (reads as curve rather than rule). */
.sidekick-frontend__panel::before {
    content: '';
    position: absolute;
    top: 0; left: 12%; right: 12%; height: 1px;
    background: linear-gradient(90deg, transparent, var(--sk-glass-edge-hi), transparent);
    pointer-events: none;
    border-radius: inherit;
    z-index: 1;
}

/* Composer — subtle-glass pill around the input + buttons. Inherits the
   panel's stronger blur via parent context; just needs the rgba tint +
   inset highlight to read as its own surface. */
.sidekick-frontend__composer {
    background: var(--sk-glass-bg-subtle) !important;
    border-top: 1px solid var(--sk-glass-border-subtle) !important;
    backdrop-filter: blur(var(--sk-glass-blur-subtle));
    -webkit-backdrop-filter: blur(var(--sk-glass-blur-subtle));
    box-shadow: inset 0 1px 0 var(--sk-glass-edge-hi);
    transition:
        box-shadow 280ms var(--sk-spring-snap),
        border-color 200ms var(--sk-ease-out);
}
.sidekick-frontend__composer:focus-within {
    box-shadow:
        0 0 0 3px rgba(99, 102, 241, 0.18),
        inset 0 1px 0 var(--sk-glass-edge-hi);
    border-top-color: rgba(99, 102, 241, 0.35) !important;
}

/* Input field — slight glass tint, keeps text-readable opaque enough but
   blends with the composer. Border softens to match. */
.sidekick-frontend__input {
    background: var(--sk-glass-bg-strong) !important;
    border: 1px solid var(--sk-glass-border-subtle) !important;
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    transition: border-color 200ms var(--sk-ease-out);
}
.sidekick-frontend__input:focus {
    border-color: rgba(99, 102, 241, 0.5) !important;
    outline: none;
}

/* Mic button — single coherent rest/hover recipe matching the backoffice
   paperclip + mic. Rest = subtle glass-tint with a navy-hinted rim and a
   soft drop + inner highlight that gives the button a proper liquid-glass
   contour against the composer-glass behind it. Hover = same bg/border/
   colour (no flip — only lift + shadow growth, Apple-TV settle). */
.sidekick-frontend__mic {
    background: rgba(255, 255, 255, 0.5) !important;
    border: 1px solid rgba(31, 41, 75, 0.18) !important;
    backdrop-filter: blur(10px) saturate(160%);
    -webkit-backdrop-filter: blur(10px) saturate(160%);
    box-shadow:
        0 2px 8px rgba(31, 38, 135, 0.08),
        inset 0 1px 0 rgba(255, 255, 255, 0.6) !important;
    /* GPU layer-promotion so the hover-scale doesn't re-sample under the
       backdrop-filter and blur the icon. Same fix as the backoffice. */
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    transition:
        background-color 180ms var(--sk-ease-out),
        border-color 180ms var(--sk-ease-out),
        color 180ms var(--sk-ease-out),
        box-shadow 260ms var(--sk-ease-out),
        transform 260ms var(--sk-ease-out) !important;
}
@media (prefers-color-scheme: dark) {
    .sidekick-frontend__mic {
        background: rgba(255, 255, 255, 0.08) !important;
        border-color: rgba(255, 255, 255, 0.18) !important;
        color: rgba(255, 255, 255, 0.92) !important;
        box-shadow:
            0 2px 10px rgba(0, 0, 0, 0.35),
            inset 0 1px 0 rgba(255, 255, 255, 0.12) !important;
    }
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__mic:hover:not(.sidekick-frontend__mic--recording):not(:disabled) {
        background: rgba(255, 255, 255, 0.5) !important;
        border-color: rgba(31, 41, 75, 0.18) !important;
        color: var(--uui-color-text, #1b264f) !important;
        /* translateY-lift instead of scale-up. A scaled element with an
           active backdrop-filter is pre-rasterized at rest-size and then
           bilinearly upscaled on hover, making the SVG-icon look soft.
           translateY moves the same crisp raster up — same lift cue, no
           blur. Mirrors the backoffice fix in app.ts block 3. */
        transform: translateY(-3px) !important;
        box-shadow:
            0 10px 24px rgba(31, 38, 135, 0.22),
            0 3px 6px rgba(31, 38, 135, 0.14),
            inset 0 1px 0 rgba(255, 255, 255, 0.7) !important;
    }
    @media (prefers-color-scheme: dark) {
        .sidekick-frontend__mic:hover:not(.sidekick-frontend__mic--recording):not(:disabled) {
            background: rgba(255, 255, 255, 0.08) !important;
            border-color: rgba(255, 255, 255, 0.18) !important;
            color: rgba(255, 255, 255, 0.92) !important;
            box-shadow:
                0 10px 28px rgba(0, 0, 0, 0.55),
                0 3px 8px rgba(0, 0, 0, 0.4),
                inset 0 1px 0 rgba(255, 255, 255, 0.18) !important;
        }
    }
}
.sidekick-frontend__mic:active:not(:disabled) {
    transform: scale(0.96);
    transition-duration: 60ms !important;
}

/* Send button — flat SuperBold brand colour (matches user-bubble accent),
   inset sheen, ambient shadow. Hover = brighter tint + heavier shadow. */
.sidekick-frontend__send {
    background: #e65d41 !important;
    border-radius: 8px !important;
    box-shadow:
        0 4px 14px rgba(230, 93, 65, 0.28),
        inset 0 1px 0 rgba(255, 255, 255, 0.25);
    transition:
        background 200ms var(--sk-ease-out),
        transform 80ms ease-out,
        box-shadow 200ms var(--sk-ease-out);
}
@media (hover: hover) and (pointer: fine) {
    /* Id-prefixed so the brighter-gradient + glass-shadow win over the
       legacy "universal hover-lift" rule earlier in the file (which would
       otherwise apply a generic translateY(-1px) + grey shadow on send). */
    #jsSidekickFrontend .sidekick-frontend__send:not(:disabled):hover {
        background: #ec6e54 !important;
        box-shadow:
            0 6px 18px rgba(230, 93, 65, 0.34),
            inset 0 1px 0 rgba(255, 255, 255, 0.32) !important;
        transform: none;
    }
    #jsSidekickFrontend .sidekick-frontend__send:active:not(:disabled) {
        transform: scale(0.97);
    }
}

/* Assistant bubble — subtle tinted glass; no nested backdrop-filter (perf).
   User bubble keeps solid gradient as contrast anchor (same recipe as backoffice). */
.sidekick-frontend__bubble--assistant {
    background: var(--sk-glass-bg-tint) !important;
    border: 1px solid var(--sk-glass-border-subtle) !important;
    box-shadow:
        0 4px 14px rgba(31, 38, 135, 0.06),
        inset 0 1px 0 var(--sk-glass-edge-hi);
}
.sidekick-frontend__bubble--user {
    /* Flat SuperBold brand colour instead of the blue gradient. */
    background: #620905 !important;
    color: #fff !important;
    box-shadow:
        0 6px 20px rgba(98, 9, 5, 0.28),
        inset 0 1px 0 rgba(255, 255, 255, 0.25);
}

/* Paperclip-attach button — shares the single coherent rest/hover recipe
   with the mic. See the mic block above for the design rationale (navy
   rim, inset highlight, Apple-TV-style lift on hover, no colour flip). */
.sidekick-frontend__attach {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    align-self: flex-end;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.5);
    border: 1px solid rgba(31, 41, 75, 0.18);
    color: var(--uui-color-text, #1b264f);
    cursor: pointer;
    flex-shrink: 0;
    backdrop-filter: blur(10px) saturate(160%);
    -webkit-backdrop-filter: blur(10px) saturate(160%);
    box-shadow:
        0 2px 8px rgba(31, 38, 135, 0.08),
        inset 0 1px 0 rgba(255, 255, 255, 0.6);
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    transition:
        background-color 180ms var(--sk-ease-out),
        border-color 180ms var(--sk-ease-out),
        color 180ms var(--sk-ease-out),
        box-shadow 260ms var(--sk-ease-out),
        transform 260ms var(--sk-ease-out);
    padding: 0;
}
.sidekick-frontend__attach svg { width: 20px; height: 20px; }
.sidekick-frontend__attach:disabled { opacity: 0.5; cursor: not-allowed; }
@media (prefers-color-scheme: dark) {
    .sidekick-frontend__attach {
        background: rgba(255, 255, 255, 0.08);
        border-color: rgba(255, 255, 255, 0.18);
        color: rgba(255, 255, 255, 0.92);
        box-shadow:
            0 2px 10px rgba(0, 0, 0, 0.35),
            inset 0 1px 0 rgba(255, 255, 255, 0.12);
    }
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__attach:not(:disabled):hover {
        background: rgba(255, 255, 255, 0.5);
        border-color: rgba(31, 41, 75, 0.18);
        color: var(--uui-color-text, #1b264f);
        /* translateY-lift instead of scale — see mic-hover block above. */
        transform: translateY(-3px);
        box-shadow:
            0 10px 24px rgba(31, 38, 135, 0.22),
            0 3px 6px rgba(31, 38, 135, 0.14),
            inset 0 1px 0 rgba(255, 255, 255, 0.7);
    }
    @media (prefers-color-scheme: dark) {
        .sidekick-frontend__attach:not(:disabled):hover {
            background: rgba(255, 255, 255, 0.08);
            border-color: rgba(255, 255, 255, 0.18);
            color: rgba(255, 255, 255, 0.92);
            box-shadow:
                0 10px 28px rgba(0, 0, 0, 0.55),
                0 3px 8px rgba(0, 0, 0, 0.4),
                inset 0 1px 0 rgba(255, 255, 255, 0.18);
        }
    }
}
.sidekick-frontend__attach:active:not(:disabled) {
    transform: scale(0.96);
    transition-duration: 60ms;
}

/* Pending uploads row — appears above the composer when files are queued.
   Compact chips with icon + filename + remove-X. */
.sidekick-frontend__uploads {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 12px 0;
}
.sidekick-frontend__upload-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 8px;
    background: var(--sk-glass-bg-subtle);
    border: 1px solid var(--sk-glass-border-subtle);
    border-radius: 14px;
    font-size: 12px;
    max-width: 220px;
}
.sidekick-frontend__upload-chip--busy {
    font-style: italic;
    color: var(--sk-muted);
}
.sidekick-frontend__upload-icon {
    width: 14px;
    height: 14px;
    flex-shrink: 0;
    color: var(--sk-accent);
}
.sidekick-frontend__upload-name {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sidekick-frontend__upload-remove {
    width: 18px;
    height: 18px;
    border: none;
    background: transparent;
    cursor: pointer;
    color: var(--sk-muted);
    font-size: 14px;
    line-height: 1;
    border-radius: 50%;
    padding: 0;
}
@media (hover: hover) and (pointer: fine) {
    .sidekick-frontend__upload-remove:hover {
        background: rgba(0, 0, 0, 0.08);
        color: #d0021b;
    }
}
/* Attachments shown inside an earlier user-bubble (historical record). */
.sidekick-frontend__bubble-attachments {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 6px;
}
.sidekick-frontend__bubble-attachment {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    background: rgba(255, 255, 255, 0.15);
    border-radius: 10px;
    font-size: 11px;
}

/* =========================================================================
   LIQUID GLASS — chrome buttons (chips, choices, prompts toggle, crew chips)
   =========================================================================
   The widget had a "reverse-out blue" hover pattern on most chrome-buttons:
   transparent rest → solid accent-blue on hover. That clashed with the
   liquid-glass chrome and read as "selected/pressed" on every hover, which
   the backoffice resolved earlier by switching to a coherent rest = glass
   tint + hover = lift-only (no colour flip) recipe. Mirrored here so the
   widget and backoffice feel like one product. Specificity prefixed with
   #jsSidekickFrontend so the new rules win over the legacy class-only
   declarations earlier in the file without needing !important everywhere.
   ------------------------------------------------------------------------- */
#jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick,
#jsSidekickFrontend .sidekick-frontend__choice,
#jsSidekickFrontend .sidekick-frontend__prompts-toggle,
#jsSidekickFrontend .sidekick-frontend__crew-chip:not(.sidekick-frontend__crew-chip--active) {
    background: rgba(255, 255, 255, 0.5);
    border: 1px solid rgba(31, 41, 75, 0.18);
    color: var(--uui-color-text, #1b264f);
    backdrop-filter: blur(8px) saturate(160%);
    -webkit-backdrop-filter: blur(8px) saturate(160%);
    box-shadow:
        0 2px 6px rgba(31, 38, 135, 0.07),
        inset 0 1px 0 rgba(255, 255, 255, 0.55);
    /* Pre-allocate a GPU layer so the hover-scale stays crisp under
       backdrop-filter — same trick as the composer side-buttons. */
    will-change: transform;
    transform: translateZ(0);
    backface-visibility: hidden;
    -webkit-backface-visibility: hidden;
    transition:
        background-color 180ms var(--sk-ease-out),
        border-color 180ms var(--sk-ease-out),
        color 180ms var(--sk-ease-out),
        box-shadow 260ms var(--sk-ease-out),
        transform 260ms var(--sk-ease-out);
}
@media (prefers-color-scheme: dark) {
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick,
    #jsSidekickFrontend .sidekick-frontend__choice,
    #jsSidekickFrontend .sidekick-frontend__prompts-toggle,
    #jsSidekickFrontend .sidekick-frontend__crew-chip:not(.sidekick-frontend__crew-chip--active) {
        background: rgba(255, 255, 255, 0.08);
        border-color: rgba(255, 255, 255, 0.18);
        color: rgba(255, 255, 255, 0.92);
        box-shadow:
            0 2px 8px rgba(0, 0, 0, 0.3),
            inset 0 1px 0 rgba(255, 255, 255, 0.1);
    }
}
@media (hover: hover) and (pointer: fine) {
    /* Hover = lift + shadow growth only. Background, border and colour stay
       identical to the rest-state so the button never looks "selected" on a
       casual hover — same Apple-TV settle as the backoffice. */
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick:hover,
    #jsSidekickFrontend .sidekick-frontend__choice:not(:disabled):hover,
    #jsSidekickFrontend .sidekick-frontend__prompts-toggle:hover,
    #jsSidekickFrontend .sidekick-frontend__crew-chip:not(.sidekick-frontend__crew-chip--active):hover {
        background: rgba(255, 255, 255, 0.5);
        border-color: rgba(31, 41, 75, 0.18);
        color: var(--uui-color-text, #1b264f);
        /* translateY-lift instead of scale — see mic-hover block above. */
        transform: translateY(-2px);
        box-shadow:
            0 10px 22px rgba(31, 38, 135, 0.2),
            0 3px 6px rgba(31, 38, 135, 0.12),
            inset 0 1px 0 rgba(255, 255, 255, 0.7);
    }
    @media (prefers-color-scheme: dark) {
        #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick:hover,
        #jsSidekickFrontend .sidekick-frontend__choice:not(:disabled):hover,
        #jsSidekickFrontend .sidekick-frontend__prompts-toggle:hover,
        #jsSidekickFrontend .sidekick-frontend__crew-chip:not(.sidekick-frontend__crew-chip--active):hover {
            background: rgba(255, 255, 255, 0.08);
            border-color: rgba(255, 255, 255, 0.18);
            color: rgba(255, 255, 255, 0.92);
            box-shadow:
                0 10px 26px rgba(0, 0, 0, 0.5),
                0 3px 8px rgba(0, 0, 0, 0.36),
                inset 0 1px 0 rgba(255, 255, 255, 0.16);
        }
    }
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .sidekick-frontend__panel,
    .sidekick-frontend__composer,
    .sidekick-frontend__input,
    .sidekick-frontend__mic,
    .sidekick-frontend__attach,
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick,
    #jsSidekickFrontend .sidekick-frontend__choice,
    #jsSidekickFrontend .sidekick-frontend__prompts-toggle,
    #jsSidekickFrontend .sidekick-frontend__crew-chip { background: var(--sk-bg) !important; }
}

@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__composer,
    .sidekick-frontend__input,
    .sidekick-frontend__mic,
    .sidekick-frontend__send,
    .sidekick-frontend__attach,
    #jsSidekickFrontend .sidekick-frontend__chip.js-sidekick-quick,
    #jsSidekickFrontend .sidekick-frontend__choice,
    #jsSidekickFrontend .sidekick-frontend__prompts-toggle,
    #jsSidekickFrontend .sidekick-frontend__crew-chip { transition: none !important; }
}

/* =================================================================
   Right-click context menu — liquid-glass quick-launcher
   Appended inside #jsSidekickFrontend so it inherits the widget's
   CSS-var scope. Positioned at cursor with `position: fixed` so
   parent layout doesn't affect placement.
   ================================================================= */
#jsSidekickFrontend .sidekick-frontend__pagemenu {
    /* Liquid-glass surface — same recipe the backoffice widget uses but
       with a touch less blur (16px ipv 24px) zodat de tekst zelf knapper
       blijft renderen op de meeste GPU's. Background opacity bumped to
       0.85 voor extra contrast op donkere achtergronden zonder dat het
       glass-effect verdwijnt. */
    position: fixed;
    min-width: 300px;
    max-width: 380px;
    z-index: 10010;
    padding: 8px;
    border-radius: 14px;
    background: rgba(255, 255, 255, 0.85);
    -webkit-backdrop-filter: blur(16px) saturate(180%);
    backdrop-filter: blur(16px) saturate(180%);
    border: 1px solid rgba(255, 255, 255, 0.6);
    box-shadow:
        0 24px 70px rgba(31, 38, 135, 0.22),
        0 6px 18px rgba(31, 38, 135, 0.10);
    color: var(--sk-fg, #1b264f);
    font-family: inherit;
    /* Match the chat panel's base font-size (14px) — public-site
       widgets often run on hosts with 10px root, which made 9.5px
       read as ~9.5px and the editor said "oogt niet scherp". */
    font-size: 14px;
    line-height: 1.4;
    display: flex;
    flex-direction: column;
    gap: 1.5px;
    animation: sk-pagemenu-in 160ms cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes sk-pagemenu-in {
    from { opacity: 0; transform: translateY(-6px) scale(0.98); }
    to   { opacity: 1; transform: translateY(0) scale(1); }
}

#jsSidekickFrontend .sidekick-frontend__pagemenu-head {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 5px 8px 7px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
    margin-bottom: 4px;
    font-weight: 600;
    font-size: 14px;
    letter-spacing: 0.01em;
    color: var(--sk-accent, #2152a3);
}
#jsSidekickFrontend .sidekick-frontend__pagemenu-logo {
    width: 22px;
    height: auto;
    flex-shrink: 0;
}

#jsSidekickFrontend .sidekick-frontend__pagemenu-sep {
    height: 1px;
    background: rgba(0, 0, 0, 0.07);
    margin: 5px 5px;
}

#jsSidekickFrontend .sidekick-frontend__pagemenu-section {
    padding: 5px 9px 3px;
    font-size: 10.5px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--sk-muted, #66686e);
    font-weight: 600;
}

#jsSidekickFrontend .sidekick-frontend__pagemenu-item {
    appearance: none;
    -webkit-appearance: none;
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    text-align: left;
    padding: 8px 9px;
    border: none;
    background: transparent;
    color: inherit;
    font: inherit;
    font-size: 14px;
    line-height: 1.3;
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 120ms ease-out, transform 120ms ease-out;
}
#jsSidekickFrontend .sidekick-frontend__pagemenu-item:hover,
#jsSidekickFrontend .sidekick-frontend__pagemenu-item:focus-visible {
    background: rgba(33, 82, 163, 0.10);
    outline: none;
}
#jsSidekickFrontend .sidekick-frontend__pagemenu-item:active {
    transform: scale(0.985);
}
#jsSidekickFrontend .sidekick-frontend__pagemenu-icon {
    width: 17px;
    height: 17px;
    flex-shrink: 0;
    color: var(--sk-accent, #2152a3);
}
#jsSidekickFrontend .sidekick-frontend__pagemenu-bullet {
    width: 17px;
    text-align: center;
    flex-shrink: 0;
    font-size: 14.5px;
    line-height: 1;
}

/* Dark-mode adaptation — flips the glass tint so the menu stays
   readable on dark host sites (Umbraco backoffice + most modern
   landing pages with dark-themed sections). Matches the widget
   panel's own dark variant.  */
@media (prefers-color-scheme: dark) {
    #jsSidekickFrontend .sidekick-frontend__pagemenu {
        background: rgba(28, 30, 38, 0.78);
        border-color: rgba(255, 255, 255, 0.12);
        color: rgba(255, 255, 255, 0.92);
        box-shadow:
            0 24px 70px rgba(0, 0, 0, 0.5),
            0 6px 18px rgba(0, 0, 0, 0.3);
    }
    #jsSidekickFrontend .sidekick-frontend__pagemenu-head {
        border-bottom-color: rgba(255, 255, 255, 0.08);
        color: #b8d1ff;
    }
    #jsSidekickFrontend .sidekick-frontend__pagemenu-sep {
        background: rgba(255, 255, 255, 0.08);
    }
    #jsSidekickFrontend .sidekick-frontend__pagemenu-item:hover,
    #jsSidekickFrontend .sidekick-frontend__pagemenu-item:focus-visible {
        background: rgba(255, 255, 255, 0.08);
    }
    #jsSidekickFrontend .sidekick-frontend__pagemenu-icon {
        color: #b8d1ff;
    }
}

@media (prefers-reduced-motion: reduce) {
    #jsSidekickFrontend .sidekick-frontend__pagemenu {
        animation: none;
    }
    #jsSidekickFrontend .sidekick-frontend__pagemenu-item {
        transition: none;
    }
}

/* ─────────────────────────────────────────────────────────────────────────
   PropertyMagic — inline-toolbar action, suggestion overlay, busy-pulse on
   the trigger-icon, and the friendly chat-rendering of toverstafje prompts
   + suggestion-blocks. Lives at the end of the file so it overrides the
   bubble defaults when the .sidekick-frontend__bubble--magic modifier is
   present.
   ───────────────────────────────────────────────────────────────────────── */

/* "Genereer met Sidekick"-knop in de inline-edit toolbar — same surface
   treatment as the existing toolbar buttons (subtle on dark), with the
   sparkle emoji as the only accent. Hard-purple background was visually
   loud + clashed with the overlay below. */
.sb-inline-toolbar__btn--magic > span[aria-hidden="true"] {
    margin-right: 2px;
}

/* Trigger-icoon pulse-ring tijdens denken / werken. Twee uit-schalende
   rings rondom de trigger; geen layout-impact (absolute positionering),
   werkt naast eventuele andere badges. */
/* No position override here — the trigger is already `position: fixed`
   (line 18) which establishes a containing block for the ::before /
   ::after pseudo-elements below. The previous `position: relative`
   override here STOMPED the fixed positioning and pushed the trigger
   into normal flow, making it disappear from the viewport entirely
   (only the inline-edit context-menu still worked because that flow
   doesn't rely on the trigger element). */
.sidekick-frontend__trigger--busy::before,
.sidekick-frontend__trigger--busy::after {
    content: '';
    position: absolute;
    inset: -4px;
    border-radius: 50%;
    border: 2px solid rgba(180, 164, 220, 0.85);
    box-shadow: 0 0 12px rgba(180, 164, 220, 0.5);
    animation: sb-magic-pulse 1.8s ease-out infinite;
    pointer-events: none;
    z-index: -1;
}
.sidekick-frontend__trigger--busy::after { animation-delay: 0.9s; }
@keyframes sb-magic-pulse {
    0%   { transform: scale(0.88); opacity: 0.9; }
    70%  { transform: scale(1.45); opacity: 0; }
    100% { transform: scale(1.45); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
    .sidekick-frontend__trigger--busy::before,
    .sidekick-frontend__trigger--busy::after {
        animation: none;
        opacity: 0.6;
    }
}

/* Suggestion-overlay — anchored near the selected element on the page.
   Eén samenhangend wit kaartje: subtiele title-row bovenaan, content
   eronder, kleine close-X in de hoek. Geen gekleurde gradient-header
   meer (botste met de inline-toolbar erboven én met de error-banner
   eronder — drie kleur-zones is teveel). */
.sb-magic-overlay {
    position: absolute;
    z-index: 2147483600;
    width: min(640px, 92vw);
    background: #fff;
    color: #1b264f;
    border-radius: 12px;
    box-shadow: 0 14px 36px rgba(17, 18, 35, 0.22), 0 0 0 1px rgba(0, 0, 0, 0.06);
    overflow: hidden;
    /* No explicit font-size — inherit from the surrounding page so the
       overlay-text matches the rest of the site rather than reading as
       a separate tiny widget. Line-height kept for breathing room
       inside the cards. */
    line-height: 1.5;
}
.sb-magic-overlay__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px 4px;
    color: #1b264f;
    border-bottom: 0;
}
.sb-magic-overlay__title {
    font-weight: 600;
    color: var(--sk-accent, #2152a3);
    letter-spacing: 0.01em;
}
.sb-magic-overlay__close {
    background: transparent;
    color: #8a8c93;
    border: 0;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    cursor: pointer;
    line-height: 26px;
    text-align: center;
    font-size: 10.5px;
    transition: background 100ms ease, color 100ms ease;
}
@media (hover: hover) and (pointer: fine) {
    .sb-magic-overlay__close:hover { background: rgba(0, 0, 0, 0.06); color: #1b264f; }
}
.sb-magic-overlay__loading {
    padding: 14px 16px 18px;
    display: flex;
    align-items: center;
    gap: 10px;
    color: #66686e;
}
.sb-magic-overlay__spinner {
    width: 14px;
    height: 14px;
    border: 2px solid rgba(91, 62, 168, 0.3);
    border-top-color: #5b3ea8;
    border-radius: 50%;
    animation: sb-magic-spin 0.9s linear infinite;
}
@keyframes sb-magic-spin { to { transform: rotate(360deg); } }
.sb-magic-overlay__error,
.sb-magic-overlay__applied,
.sb-magic-overlay__needsinput {
    margin: 4px 14px 14px;
    padding: 10px 12px;
    line-height: 1.5;
    border-radius: 8px;
}
.sb-magic-overlay__error    { background: #fdecec; color: #8a1f1f; border-left: 3px solid #c33a3a; }
.sb-magic-overlay__applied  { background: #ecf7ef; color: #14512e; border-left: 3px solid #2f8f5b; }
.sb-magic-overlay__needsinput { background: #fff6e0; color: #6a4a00; border-left: 3px solid #d8a82e; }
.sb-magic-overlay__muted { color: #66686e; }
.sb-magic-overlay__list { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; max-height: 60vh; overflow: auto; }
.sb-magic-suggestion {
    border: 1px solid rgba(33, 82, 163, 0.2);
    border-radius: 8px;
    padding: 10px 12px;
    background: #fafbfd;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sb-magic-suggestion__head { display: flex; align-items: baseline; gap: 8px; }
.sb-magic-suggestion__idx {
    flex: 0 0 auto;
    min-width: 14px;
    height: 14px;
    line-height: 14px;
    text-align: center;
    border-radius: 50%;
    background: #e5edf9;
    color: var(--sk-accent, #2152a3);
    font-size: 7.8px;
    font-weight: 600;
}
.sb-magic-suggestion__rationale { color: var(--sk-accent, #2152a3); font-weight: 500; }
.sb-magic-suggestion__value { color: #1b264f; line-height: 1.5; word-break: break-word; }
/* mdToHtml now wraps text in <p class="md-p"> (and rich-text values carry
   their own <p>) — flatten the margins inside the compact suggestion card,
   same as .propertymagic-suggestion__value p in the backoffice. */
.sb-magic-suggestion__value p { margin: 0; }
.sb-magic-suggestion__json {
    display: inline-block;
    padding: 2px 8px;
    background: #eef2f9;
    border-radius: 4px;
    color: #66686e;
    font-style: italic;
}
.sb-magic-suggestion__actions { display: flex; justify-content: flex-end; }
.sb-magic-suggestion__accept {
    background: #2f8f5b;
    color: #fff;
    border: 0;
    padding: 6px 14px;
    border-radius: 6px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.sb-magic-suggestion__accept[disabled] { opacity: 0.6; cursor: not-allowed; }
@media (hover: hover) and (pointer: fine) {
    .sb-magic-suggestion__accept:hover:not([disabled]) { background: #257548; }
}
.sb-magic-overlay__foot {
    padding: 10px 14px;
    border-top: 1px solid rgba(0, 0, 0, 0.06);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}
.sb-magic-overlay__reject {
    background: transparent;
    color: #66686e;
    border: 1px solid #d0d2d8;
    padding: 6px 14px;
    border-radius: 6px;
    font: inherit;
    cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
    .sb-magic-overlay__reject:hover { background: #f4f4f6; color: #1b264f; }
}

/* PropertyMagic generation-controls panel — public-widget mirror of the
   backoffice preview-modal "Meer opties" panel. */
.sb-magic-opts {
    padding: 8px 14px 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.sb-magic-opts__toggle {
    align-self: flex-start;
    background: none;
    border: 0;
    padding: 4px 2px;
    font: inherit;
    font-size: 0.86rem;
    color: #1b264f;
    cursor: pointer;
}
.sb-magic-opts__body {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 10px;
    background: #f7f5fc;
    border: 1px solid #e0ddf0;
    border-radius: 8px;
}
.sb-magic-opts__row { display: flex; align-items: center; gap: 10px; }
.sb-magic-opts__row--col { flex-direction: column; align-items: stretch; gap: 4px; }
.sb-magic-opts__label { flex: 0 0 6.5rem; font-size: 0.84rem; color: #66686e; }
/* Column rows put the flex main-axis vertical, so the 6.5rem basis would
   become the label's HEIGHT and open a gap above the textarea — reset it. */
.sb-magic-opts__row--col .sb-magic-opts__label { flex: 0 0 auto; }
.sb-magic-opts__select {
    flex: 1 1 auto;
    padding: 5px 8px;
    border: 1px solid #d0d2d8;
    border-radius: 6px;
    background: #fff;
    font: inherit;
    font-size: 0.86rem;
    color: #1b264f;
}
.sb-magic-opts__textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 6px 8px;
    border: 1px solid #d0d2d8;
    border-radius: 6px;
    font: inherit;
    font-size: 0.86rem;
    resize: vertical;
}
.sb-magic-seg {
    display: inline-flex;
    border: 1px solid #d0d2d8;
    border-radius: 6px;
    overflow: hidden;
    background: #fff;
}
.sb-magic-seg__btn {
    border: 0;
    border-right: 1px solid #d0d2d8;
    background: #fff;
    padding: 5px 12px;
    font: inherit;
    font-size: 0.84rem;
    color: #1b264f;
    cursor: pointer;
}
.sb-magic-seg__btn:last-child { border-right: 0; }
.sb-magic-seg__btn.is-active { background: #e65d41; color: #fff; }
.sb-magic-overlay__regen {
    background: #efe9fb;
    color: #3c2b6b;
    border: 1px solid #c9bdec;
    padding: 6px 14px;
    border-radius: 6px;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.sb-magic-overlay__regen[disabled] { opacity: 0.6; cursor: not-allowed; }
@media (hover: hover) and (pointer: fine) {
    .sb-magic-seg__btn:not(.is-active):hover { background: #ece4f8; }
    .sb-magic-overlay__regen:hover:not([disabled]) { background: #e3d9f7; }
    .sb-magic-opts__toggle:hover { color: #e65d41; }
}

/* PropertyMagic loader — Sidekick "working" animation (initial run + regenerate). */
.sb-magic-loader {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 190px;
    padding: 20px 18px;
    text-align: center;
}
/* Mark + status + dots centre in the free space; the tip is pinned below. */
.sb-magic-loader__main {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
}
.sb-magic-loader__mark {
    font-size: 2.2rem;
    line-height: 1;
    animation: sb-magic-loader-pulse 1.6s ease-in-out infinite;
}
.sb-magic-loader__status {
    font-size: 0.98rem;
    font-weight: 600;
    color: #1b264f;
    min-height: 1.4em;
}
.sb-magic-loader__dots { display: inline-flex; gap: 5px; }
.sb-magic-loader__dots span {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #5b3ea8;
    animation: sb-magic-loader-bounce 1.2s ease-in-out infinite;
}
.sb-magic-loader__dots span:nth-child(2) { animation-delay: 0.15s; }
.sb-magic-loader__dots span:nth-child(3) { animation-delay: 0.3s; }
.sb-magic-loader__tip {
    margin-top: 4px;
    max-width: 28rem;
    padding: 10px 14px;
    background: #f7f3ff;
    border: 1px solid #e0ddf0;
    border-radius: 8px;
    color: #66686e;
    font-size: 0.88rem;
    line-height: 1.45;
    animation: sb-magic-loader-fade 0.4s ease;
}
@keyframes sb-magic-loader-pulse {
    0%, 100% { transform: scale(1); opacity: 0.85; }
    50% { transform: scale(1.18); opacity: 1; }
}
@keyframes sb-magic-loader-bounce {
    0%, 100% { transform: translateY(0); opacity: 0.5; }
    50% { transform: translateY(-5px); opacity: 1; }
}
@keyframes sb-magic-loader-fade { from { opacity: 0; } to { opacity: 1; } }
.sb-magic-loader--static .sb-magic-loader__mark,
.sb-magic-loader--static .sb-magic-loader__dots span,
.sb-magic-loader--static .sb-magic-loader__tip { animation: none; }
.sb-magic-loader--static .sb-magic-loader__mark { opacity: 1; }
.sb-magic-loader--static .sb-magic-loader__dots span { opacity: 0.7; }
@media (prefers-reduced-motion: reduce) {
    .sb-magic-loader__mark,
    .sb-magic-loader__dots span,
    .sb-magic-loader__tip { animation: none; }
}

/* PropertyMagic chat-bubbles — friendly prompt-card + suggestion-cards in
   plaats van XML-soup. Match's the backoffice look (purple accent) maar
   binnen de bestaande widget-bubble dimensions. */
.sidekick-frontend__bubble--magic {
    background: #620905;
    color: #fff;
}
.sb-magic-prompt { display: flex; align-items: flex-start; gap: 10px; }
.sb-magic-prompt__icon { font-size: 12px; line-height: 1.4; }
.sb-magic-prompt__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.sb-magic-prompt__head { font-size: 9.5px; line-height: 1.35; color: #fff; }
.sb-magic-prompt__head strong { color: #fff; font-weight: 600; }
.sb-magic-prompt__sub { font-size: 8.4px; color: rgba(255, 255, 255, 0.82); line-height: 1.35; }
.sb-magic-prompt__sub strong { color: #fff; font-weight: 600; }
.sb-magic-prompt__toggle {
    align-self: flex-start;
    margin-top: 4px;
    padding: 2px 10px;
    border: 1px solid rgba(255, 255, 255, 0.45);
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    border-radius: 999px;
    cursor: pointer;
    font: inherit;
    font-size: 7.8px;
}
@media (hover: hover) and (pointer: fine) {
    .sb-magic-prompt__toggle:hover { background: rgba(255, 255, 255, 0.22); }
}
.sb-magic-prompt__raw {
    margin: 8px 0 0;
    padding: 8px 10px;
    max-height: 180px;
    overflow: auto;
    background: rgba(0, 0, 0, 0.18);
    border: 1px solid rgba(255, 255, 255, 0.18);
    border-radius: 6px;
    white-space: pre-wrap;
    word-break: break-word;
    font: 7.8px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    color: rgba(255, 255, 255, 0.92);
}

.sb-magic-response { display: flex; flex-direction: column; gap: 10px; }
.sb-magic-response__intro { margin: 0; color: #66686e; font-size: 9.2px; }
.sb-magic-response__list { display: flex; flex-direction: column; gap: 8px; }
.sb-magic-response__card {
    border: 1px solid rgba(91, 62, 168, 0.25);
    border-radius: 8px;
    background: #fdfcff;
    padding: 8px 12px 10px;
}
.sb-magic-response__head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 4px; }
.sb-magic-response__idx {
    flex: 0 0 auto;
    min-width: 14px;
    height: 14px;
    line-height: 14px;
    text-align: center;
    border-radius: 50%;
    background: #efeaf9;
    color: #3c2b6b;
    font-size: 7.8px;
    font-weight: 600;
}
.sb-magic-response__rationale { color: #3c2b6b; font-size: 8.2px; font-weight: 500; }
.sb-magic-response__value { color: #1b264f; font-size: 9.5px; line-height: 1.5; word-break: break-word; }
/* Same p-flatten as .sb-magic-suggestion__value above — mdToHtml emits real
   <p class="md-p"> paragraphs since the block-rendering port. */
.sb-magic-response__value p { margin: 0; }
.sb-magic-response__json {
    display: inline-block;
    padding: 2px 8px;
    background: #f4f1fa;
    border-radius: 4px;
    color: #66686e;
    font-size: 8.5px;
    font-style: italic;
}
