/* timeline.css: the message list, history loading, image gallery modal, show-more button
   Flattened from the Blazor scoped CSS at commit 7af3454 (parent of 2c1b6c0 "Step 1: remove Blazor").
   Selectors and declarations are copied as they were; only ::deep was removed and a root
   class was put in front of selectors whose class names collided between components.
   See README.md in this folder for the prefixes and the dropped rules. */

/* ==== ImageGalleryModal (was Yap/Components/ImageGalleryModal.razor.css) ==== */

/* Full-screen media viewer. Layout and gestures are client-owned (see chat.js "Image gallery
   viewer"): the strip swipes with native scroll-snap, "fill" / "dragging" / "closing" are
   classes chat.js toggles, --drag is a 0..1 inline variable it sets during a drag-to-close. */

.image-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    --bg-alpha: 0.9;
    /* The backdrop follows the finger during a drag-to-close; the picture stays opaque. */
    background: rgb(0 0 0 / calc(var(--bg-alpha) * (1 - var(--drag, 0))));
}

/* The fade-out of the gallery (TL-27). gallery.js removes the element when it ends. */
.image-modal.closing {
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s;
}

/* ---- Strip: one viewport-sized stage per item, the browser snaps between them ---- */

.gallery-strip {
    position: absolute;
    inset: 0;
    display: flex;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}

.gallery-strip::-webkit-scrollbar {
    display: none;              /* Safari before 18.2 ignores scrollbar-width */
}

.modal-stage {
    position: relative;
    flex: 0 0 100%;
    height: 100%;
    scroll-snap-align: start;
    scroll-snap-stop: always;   /* a fling moves one item, never three */
    display: flex;              /* fit mode: centres the picture */
    overflow: hidden;
    /* pan-x leaves horizontal swipes to the strip. No pan-y: vertical drags reach chat.js
       (drag-to-close) instead of the browser, and native double-tap zoom is off, so the
       fill double-tap wins. Pinch stays native, as it always was. */
    touch-action: pan-x pinch-zoom;
    /* A pan inside a filled stage must stop at the picture edge, not leak into the strip and
       flip to the next item. (iOS < 16 lacks this and does leak; soft failure.) */
    overscroll-behavior: contain;
    transition: transform 0.2s;  /* springs back after a released drag-to-close */
}

.modal-stage.dragging {
    transition: none;           /* the picture follows the finger with no lag */
}

.modal-stage img,
.modal-stage .modal-video {
    /* margin:auto centres a smaller picture but, unlike justify-content:center, lets a larger
       one overflow to the right only, so the left edge is always reachable by scrolling. */
    margin: auto;
    max-width: 85%;
    max-height: 85%;
    object-fit: contain;
}

/* ---- Fill: the picture covers the viewport, native scroll is the pan ---- */

.modal-stage.fill {
    display: block;             /* block, not flex: the picture's own size drives the scroll area */
    overflow: auto;
    touch-action: pan-x pan-y pinch-zoom;   /* both axes pan the picture now */
}

/* Cover = scale along one axis and let the other overflow. Which axis depends on the picture's
   aspect against the stage's, which CSS cannot compare, so chat.js adds fill-w for pictures
   narrower than the stage. (min-width/min-height tricks fail here: once one axis is specified
   the CSS 2.1 ratio table no longer applies, and the box stretches around a letterboxed picture.) */
.modal-stage.fill img {
    display: block;
    max-width: none;
    max-height: none;
    height: 100%;
    width: auto;
}

.modal-stage.fill.fill-w img {
    width: 100%;
    height: auto;
}

/* ---- Chrome: round buttons floating over the picture ---- */

.modal-close,
.modal-nav,
.modal-fill {
    position: absolute;
    width: 48px;
    height: 48px;
    border: none;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.1);
    color: white;
    font-size: 2rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s;
}

.modal-close:hover,
.modal-nav:hover,
.modal-fill:hover {
    background-color: rgba(255, 255, 255, 0.25);
}

.modal-close {
    top: 20px;
    right: 20px;
}

.modal-nav {
    top: 50%;
    transform: translateY(-50%);
}

.modal-nav[hidden] {
    display: none;   /* the control at an end of the gallery (TL-25); `hidden` alone loses to the display: flex above */
}

.modal-nav.prev {
    left: 20px;
}

.modal-nav.next {
    right: 20px;
}

.modal-fill {
    bottom: 20px;
    right: 20px;
    background-repeat: no-repeat;
    background-position: center;
    background-size: 20px;
    /* Feather "maximize-2" (MIT). Swapped for "minimize-2" while the visible stage is filled. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='15 3 21 3 21 9'/%3E%3Cpolyline points='9 21 3 21 3 15'/%3E%3Cline x1='21' y1='3' x2='14' y2='10'/%3E%3Cline x1='3' y1='21' x2='10' y2='14'/%3E%3C/svg%3E");
}

.image-modal:has(.modal-stage.fill) .modal-fill {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 14 10 14 10 20'/%3E%3Cpolyline points='20 10 14 10 14 4'/%3E%3Cline x1='14' y1='10' x2='21' y2='3'/%3E%3Cline x1='3' y1='21' x2='10' y2='14'/%3E%3C/svg%3E");
}

.modal-counter {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    color: rgba(255, 255, 255, 0.7);
    font-size: 0.875rem;
}

/* ---- Phones: the picture gets the whole app area, the chrome floats over it ---- */
/* 600px = compact-component tier (see .claude-memory breakpoints note). The viewport meta is
   untouched on purpose, so nothing goes under the status bar or notch. */

@media (max-width: 600px) {
    .image-modal {
        --bg-alpha: 1;
    }

    .modal-stage img,
    .modal-stage .modal-video {
        max-width: 100%;
        max-height: 100%;
    }

    .modal-close,
    .modal-nav,
    .modal-fill {
        width: 40px;
        height: 40px;
        font-size: 1.5rem;
        background-color: rgba(0, 0, 0, 0.45);
    }

    .modal-close {
        top: 8px;
        right: 8px;
    }

    .modal-nav.prev {
        left: 8px;
    }

    .modal-nav.next {
        right: 8px;
    }

    .modal-fill {
        bottom: 8px;
        right: 8px;
    }

    .modal-counter {
        bottom: 8px;
        padding: 2px 10px;
        border-radius: 999px;
        background: rgba(0, 0, 0, 0.45);
    }
}

/* ==== ChatLayout (was Yap/Components/Layout/ChatLayout.razor.css) ==== */
/* Timeline part. The frame part of this file (.chat-container, .chat-main,
   .messages-container, scene, sidebar backdrop, error content) is in frame.css. */

/* Messages area (was ::deep in the scoped file; flat now) */
.messages {
    flex: 1;
    overflow-y: auto;
    padding: 1rem 0 0.25rem 0;
    min-width: 0; /* Allow flex item to shrink below content size */
}

/* The scrollable content. Carries the flex column that used to live on .messages,
   so the spacer still pushes a short conversation to the bottom (min-height 100%
   gives the spacer room to stretch into). */
.messages-flow {
    display: flex;
    flex-direction: column;
    min-height: 100%;
}

/* Spacer pushes messages to bottom when few messages */
.messages-spacer {
    flex: 1 1 auto;
}

/* Scrollbar styling */
.messages::-webkit-scrollbar {
    width: 16px;
}

.messages::-webkit-scrollbar-track {
    background: var(--bg-primary);
    border-radius: 8px;
}

.messages::-webkit-scrollbar-thumb {
    background: var(--bg-header);
    border: 4px solid var(--bg-primary);
    border-radius: 8px;
}

.messages::-webkit-scrollbar-thumb:hover {
    background: var(--bg-darkest);
}

/* System messages (for DM notice) */
.system-message {
    text-align: center;
    margin: 0 !important;
    padding: 0.0625rem 1rem !important;
}

.system-message .message-content {
    display: inline-block;
    color: var(--text-muted);
    font-style: italic;
    font-size: 0.8125rem;
    padding: 0;
    background: transparent;
    line-height: 1.4;
}

/* Loading indicator for infinite scroll */
.loading-more {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1rem;
    color: var(--text-muted);
    font-size: 0.875rem;
}

.loading-spinner {
    width: 16px;
    height: 16px;
    border: 2px solid var(--bg-muted);
    border-top-color: var(--text-primary);
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
}

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

/* History start message */
.history-start {
    text-align: center;
    padding: 1rem;
    color: var(--text-placeholder);
    font-size: 0.875rem;
    font-weight: 600;
}

/* ==== ShowMoreButton (was Yap/Components/ShowMoreButton.razor.css) ==== */

.show-more {
    width: 100%;
    margin-top: 8px;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
    border: none;
    border-radius: 6px;
    padding: 8px;
    font-size: 0.82rem;
    cursor: pointer;
}

.show-more:hover {
    color: var(--text-primary);
    background: var(--bg-hover);
}
