/* ============================================================
   Filament Sidekick — push-aside assistant panel.

   Chrome (buttons, badges, inputs, callouts, empty state, icons)
   comes from Filament's own Blade components, so it follows the
   host panel's theme automatically. What lives here is the panel
   GEOMETRY plus the few chat primitives Filament has no component
   for (bubbles, activity rows, the confirm card).

   THEMING: override any --sidekick-* property below in your
   panel theme's CSS — declare it on `body` (or any closer
   element) and it wins over these defaults. Nothing here needs
   a PHP API to restyle.
   ============================================================ */

html {
    /* Geometry — width is also settable from config (sidekick.panel.*). */
    --sidekick-width: 23rem;
    --sidekick-top: 4rem;
    --sidekick-height: calc(100dvh - 4rem);
    --sidekick-edge-offset: 0px;

    /* Surfaces */
    --sidekick-bg: #fff;
    --sidekick-border: color-mix(in srgb, var(--gray-950, #030712) 8%, transparent);
    --sidekick-text: var(--gray-900, rgb(17 24 39));
    --sidekick-muted: var(--gray-500, rgb(107 114 128));

    /* Message bubbles — neutral by default; primary is reserved for actions. */
    --sidekick-bubble-user-bg: color-mix(in srgb, var(--gray-950, #030712) 8%, transparent);
    --sidekick-bubble-assistant-bg: color-mix(in srgb, var(--gray-950, #030712) 4%, transparent);
    --sidekick-bubble-radius: var(--radius-xl, 0.75rem);

    /* Composer button column: 2.25rem square by default. */
    --sidekick-composer-field-min: calc(var(--spacing, 0.25rem) * 19.5);
    --sidekick-composer-btn-px: calc(var(--spacing, 0.25rem) * 2);
    --sidekick-composer-btn-min: calc(var(--spacing, 0.25rem) * 9);
}

html.dark {
    --sidekick-bg: var(--gray-900, rgb(17 24 39));
    --sidekick-border: color-mix(in srgb, var(--gray-50, #f9fafb) 8%, transparent);
    --sidekick-text: var(--gray-50, #f9fafb);
    --sidekick-muted: var(--gray-400, rgb(156 163 175));
    --sidekick-bubble-user-bg: color-mix(in srgb, var(--gray-50, #f9fafb) 10%, transparent);
    --sidekick-bubble-assistant-bg: color-mix(in srgb, var(--gray-50, #f9fafb) 5%, transparent);
}

/* --- Geometry ---------------------------------------------- */

/* Erase the @persist wrapper's box so the aside is the layout's true flex item, not the sticky containing block. */
.fi-layout > [x-persist='sidekick-panel'] {
    display: contents;
}

/* overflow-x: clip not hidden (hidden detaches the card's sticky); contain: size stops the viewport-tall card inflating the aside. */
.sidekick-aside {
    width: 0;
    flex: none;
    overflow-x: clip;
    contain: size;
    align-self: stretch;
}

body.sidekick-open .sidekick-aside {
    width: var(--sidekick-width);
}

body.sidekick-ready .sidekick-aside {
    transition: width 0.3s ease;
}

.sidekick-card {
    position: sticky;
    top: var(--sidekick-top);
    height: var(--sidekick-height);
    width: var(--sidekick-width);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: var(--sidekick-bg);
    border-inline-start: 1px solid var(--sidekick-border);
}

/* Full-height mode: the aside climbs the layout's vertical padding, else the sticky card lifts off the viewport bottom. */
body.sidekick-full-height .sidekick-aside {
    margin-block: calc(-1 * var(--sidekick-edge-offset));
}

body.sidekick-full-height .sidekick-card {
    top: 0;
    height: 100dvh;
}

/* Native Filament keeps the topbar outside the row the panel squeezes, so push
   it by hand and let the aside climb past it. Themes that render the topbar
   inside .fi-main-ctn never get the body class — it already shrinks there. */
body.sidekick-full-height.sidekick-topbar-outside .sidekick-aside {
    margin-top: calc(-1 * var(--sidekick-topbar-height, 4rem));
}

body.sidekick-full-height.sidekick-topbar-outside.sidekick-open .fi-topbar-ctn {
    margin-inline-end: var(--sidekick-width);
}

body.sidekick-ready.sidekick-topbar-outside .fi-topbar-ctn {
    transition: margin 0.3s ease;
}

/* Desktop keeps the topbar toggle as the only control; the X appears in overlay mode. */
.sidekick-close {
    display: none;
}

@media (max-width: 1024px) {
    .sidekick-aside {
        position: fixed;
        inset-inline-end: 0;
        top: 0;
        height: 100dvh;
        z-index: 40;
        margin: 0 !important;
    }

    body.sidekick-open .sidekick-aside {
        width: min(calc(100vw - 2rem), 24rem);
        box-shadow: -8px 0 32px color-mix(in srgb, var(--gray-950, #030712) 18%, transparent);
    }

    .sidekick-card,
    body.sidekick-full-height .sidekick-card {
        position: static;
        top: auto;
        height: 100%;
        width: 100%;
    }

    .sidekick-close {
        display: inline-flex;
    }
}

@media (max-width: 640px) {
    body.sidekick-open .sidekick-aside {
        width: 100vw;
    }

    .sidekick-card {
        border-inline-start: none;
    }
}

/* --- Topbar toggle ----------------------------------------- */

.sidekick-toggle .sidekick-toggle-icon,
.sidekick-toggle .sidekick-toggle-icon svg {
    width: calc(var(--spacing, 0.25rem) * 5);
    height: calc(var(--spacing, 0.25rem) * 5);
}

.sidekick-toggle-open {
    color: var(--primary-600, #4f46e5);
}

/* --- Shell ------------------------------------------------- */

.sidekick-chat {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
}

.sidekick-header {
    display: flex;
    align-items: center;
    gap: calc(var(--spacing, 0.25rem) * 2);
    padding: calc(var(--spacing, 0.25rem) * 2.5) calc(var(--spacing, 0.25rem) * 3.5);
    /* Constant height with or without action buttons, so the header never jumps. */
    min-height: calc(var(--spacing, 0.25rem) * 14);
    border-bottom: 1px solid var(--sidekick-border);
}

.sidekick-header-title {
    font-size: 1.0625rem;
    font-weight: 600;
    color: var(--sidekick-text);
}

.sidekick-header-actions {
    margin-inline-start: auto;
    display: flex;
    align-items: center;
    gap: var(--spacing, 0.25rem);
}

.sidekick-log {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: calc(var(--spacing, 0.25rem) * 4);
    display: flex;
    flex-direction: column;
    gap: calc(var(--spacing, 0.25rem) * 2.5);
}

.sidekick-empty {
    margin: auto;
}

.sidekick-callout {
    align-self: stretch;
}

/* --- Bubbles ----------------------------------------------- */

.sidekick-bubble {
    max-width: 88%;
    border-radius: var(--sidekick-bubble-radius);
    padding: calc(var(--spacing, 0.25rem) * 2) calc(var(--spacing, 0.25rem) * 3);
    font-size: 0.875rem;
    line-height: 1.55;
    color: var(--sidekick-text);
    word-break: break-word;
}

.sidekick-bubble-user {
    align-self: flex-end;
    background: var(--sidekick-bubble-user-bg);
    white-space: pre-wrap;
}

.sidekick-bubble-assistant {
    align-self: flex-start;
    background: var(--sidekick-bubble-assistant-bg);
}

.sidekick-stream-text {
    white-space: pre-wrap;
}

.sidekick-stream-text::after {
    content: '▍';
    margin-inline-start: var(--spacing, 0.25rem);
    color: var(--primary-600, #4f46e5);
    animation: sidekick-blink 1s step-end infinite;
}

@keyframes sidekick-blink {
    50% {
        opacity: 0;
    }
}

/* --- Markdown ---------------------------------------------- */

.sidekick-prose p + p {
    margin-top: calc(var(--spacing, 0.25rem) * 2);
}

.sidekick-prose ul,
.sidekick-prose ol {
    margin: calc(var(--spacing, 0.25rem) * 1.5) 0 calc(var(--spacing, 0.25rem) * 1.5) calc(var(--spacing, 0.25rem) * 4.5);
    list-style: disc;
}

.sidekick-prose ol {
    list-style: decimal;
}

.sidekick-prose li + li {
    margin-top: calc(var(--spacing, 0.25rem) * 0.5);
}

.sidekick-prose code {
    font-size: 0.8125rem;
    background: color-mix(in srgb, var(--gray-500, rgb(107 114 128)) 18%, transparent);
    border-radius: var(--radius-sm, 0.25rem);
    padding: calc(var(--spacing, 0.25rem) * 0.25) var(--spacing, 0.25rem);
}

.sidekick-prose pre {
    background: color-mix(in srgb, var(--gray-500, rgb(107 114 128)) 15%, transparent);
    border-radius: var(--radius-lg, 0.5rem);
    padding: calc(var(--spacing, 0.25rem) * 2) calc(var(--spacing, 0.25rem) * 2.5);
    overflow-x: auto;
    margin: calc(var(--spacing, 0.25rem) * 1.5) 0;
}

.sidekick-prose pre code {
    background: none;
    padding: 0;
}

.sidekick-prose a {
    color: var(--primary-600, #4f46e5);
    text-decoration: underline;
}

/* --- Message action buttons (PresentActions) --------------- */

.sidekick-msg-actions {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--spacing, 0.25rem) * 1.5);
    padding-top: calc(var(--spacing, 0.25rem) * 0.5);
}

/* --- Confirm cards ----------------------------------------- */

/* The dock replaces the composer while a card awaits an answer. */
.sidekick-action-dock {
    padding: calc(var(--spacing, 0.25rem) * 3);
    border-top: 1px solid var(--sidekick-border);
}

.sidekick-action-card {
    border: 1px solid var(--primary-600, #4f46e5);
    border-radius: var(--sidekick-bubble-radius);
    padding: calc(var(--spacing, 0.25rem) * 3) calc(var(--spacing, 0.25rem) * 3.5);
    display: flex;
    flex-direction: column;
    gap: calc(var(--spacing, 0.25rem) * 2);
    color: var(--sidekick-text);
}

/* In a modal the chrome and heading are the modal's own. */
.sidekick-action-card-modal {
    border: none;
    border-radius: 0;
    padding: 0;
    gap: calc(var(--spacing, 0.25rem) * 3);
}

.sidekick-action-card-modal .sidekick-action-card-title {
    display: none;
}

.sidekick-action-card-modal .sidekick-action-card-rows {
    font-size: 0.875rem;
}

.sidekick-action-card-title {
    font-size: 0.875rem;
    font-weight: 600;
}

.sidekick-action-card-rows {
    display: flex;
    flex-direction: column;
    gap: var(--spacing, 0.25rem);
    font-size: 0.8125rem;
}

.sidekick-action-card-rows > div {
    display: flex;
    justify-content: space-between;
    gap: calc(var(--spacing, 0.25rem) * 3);
}

.sidekick-action-card-rows dt {
    color: var(--sidekick-muted);
}

.sidekick-action-card-rows dd {
    text-align: end;
    font-weight: 500;
}

.sidekick-action-card-buttons {
    display: flex;
    gap: calc(var(--spacing, 0.25rem) * 2);
    padding-top: var(--spacing, 0.25rem);
}

.sidekick-action-card-buttons .fi-btn {
    flex: 1;
    justify-content: center;
}

.sidekick-action-card-note {
    font-size: 0.6875rem;
    color: var(--sidekick-muted);
    text-align: center;
}

.sidekick-action-outcome {
    font-size: 0.8125rem;
    color: var(--sidekick-muted);
    border-inline-start: 2px solid var(--sidekick-border);
    padding-inline-start: calc(var(--spacing, 0.25rem) * 2.5);
}

.sidekick-action-outcome-executed {
    border-inline-start-color: var(--success-500, rgb(34 197 94));
}

.sidekick-action-outcome-failed {
    border-inline-start-color: var(--danger-600, rgb(220 38 38));
}

/* --- Tool activity + thinking ------------------------------ */

.sidekick-activity {
    display: flex;
    align-items: center;
    gap: calc(var(--spacing, 0.25rem) * 1.5);
    font-size: 0.75rem;
    color: var(--sidekick-muted);
    padding-inline-start: calc(var(--spacing, 0.25rem) * 0.5);
}

.sidekick-activity-icon {
    width: calc(var(--spacing, 0.25rem) * 3.5);
    height: calc(var(--spacing, 0.25rem) * 3.5);
    flex: none;
    color: var(--success-500, rgb(34 197 94));
}

.sidekick-activity .fi-loading-indicator {
    color: var(--sidekick-muted);
}

.sidekick-thinking {
    display: flex;
    gap: var(--spacing, 0.25rem);
    padding: calc(var(--spacing, 0.25rem) * 1.5) calc(var(--spacing, 0.25rem) * 0.5);
}

.sidekick-thinking span {
    width: calc(var(--spacing, 0.25rem) * 1.5);
    height: calc(var(--spacing, 0.25rem) * 1.5);
    border-radius: 9999px;
    background: var(--gray-400, rgb(156 163 175));
    animation: sidekick-pulse 1.2s ease-in-out infinite;
}

.sidekick-thinking span:nth-child(2) {
    animation-delay: 0.15s;
}

.sidekick-thinking span:nth-child(3) {
    animation-delay: 0.3s;
}

@keyframes sidekick-pulse {
    0%,
    100% {
        opacity: 0.35;
        transform: translateY(0);
    }
    50% {
        opacity: 1;
        transform: translateY(-2px);
    }
}

/* --- Composer ---------------------------------------------- */

.sidekick-composer {
    display: flex;
    flex-direction: column;
    gap: calc(var(--spacing, 0.25rem) * 2);
    padding: calc(var(--spacing, 0.25rem) * 3);
    border-top: 1px solid var(--sidekick-border);
}

.sidekick-composer-row {
    display: flex;
    align-items: flex-end;
    gap: calc(var(--spacing, 0.25rem) * 2);
}

.sidekick-composer-field {
    flex: 1;
    min-width: 0;
}

.sidekick-composer textarea {
    width: 100%;
    resize: none;
    min-height: var(--sidekick-composer-field-min);
    max-height: 120px;
}

.sidekick-composer-buttons {
    flex: none;
    display: flex;
    flex-direction: column;
    gap: calc(var(--spacing, 0.25rem) * 1.5);
}

/* !important: themes restyle .fi-btn with high-specificity selectors; tune the values via the vars instead. */
.sidekick-composer-buttons .fi-btn {
    padding-inline: var(--sidekick-composer-btn-px) !important;
    min-height: var(--sidekick-composer-btn-min) !important;
    cursor: pointer;
}

/* The label can't carry :disabled itself — mirror the hidden input's state. */
.sidekick-composer-buttons:has(input[type='file']:disabled) .sidekick-attach-btn {
    opacity: 0.5;
    pointer-events: none;
}

.sidekick-composer-buttons:has(input[type='file']:focus-visible) .sidekick-attach-btn {
    outline: 2px solid var(--primary-600, #4f46e5);
    outline-offset: 1px;
}

/* --- Attachments ------------------------------------------- */

.sidekick-chips {
    display: flex;
    flex-wrap: wrap;
    gap: calc(var(--spacing, 0.25rem) * 1.5);
}

.sidekick-chips-user {
    align-self: flex-end;
    justify-content: flex-end;
    max-width: 88%;
}

.sidekick-chip-size {
    opacity: 0.65;
}

.sidekick-upload-error {
    font-size: 0.75rem;
    color: var(--danger-600, rgb(220 38 38));
}

.sidekick-card-upload {
    display: flex;
    flex-direction: column;
    gap: calc(var(--spacing, 0.25rem) * 1.5);
}

.sidekick-card-upload-label {
    font-size: 0.8125rem;
    color: var(--sidekick-muted);
}

.sidekick-upload-required {
    color: var(--danger-600, rgb(220 38 38));
}

.sidekick-upload-field {
    position: relative;
    display: flex;
    align-items: center;
    gap: calc(var(--spacing, 0.25rem) * 2);
    padding: calc(var(--spacing, 0.25rem) * 2) calc(var(--spacing, 0.25rem) * 2.5);
    border: 1px dashed color-mix(in srgb, var(--gray-500, rgb(107 114 128)) 45%, transparent);
    border-radius: var(--radius-lg, 0.5rem);
    font-size: 0.8125rem;
    color: var(--sidekick-muted);
    cursor: pointer;
}

/* The input stretches invisibly across the field so clicks and native drops both work. */
.sidekick-upload-field input[type='file'] {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    opacity: 0;
    cursor: pointer;
}

.sidekick-upload-field:hover,
.sidekick-upload-field:focus-within {
    border-color: var(--primary-600, #4f46e5);
    color: var(--primary-600, #4f46e5);
}

.sidekick-upload-spinner {
    width: calc(var(--spacing, 0.25rem) * 4);
    height: calc(var(--spacing, 0.25rem) * 4);
    margin-inline-start: auto;
}
