:root {
    --bg-color: #f0f0f0;
    /* How much of the striped painting shows behind the pages: 0 hides it,
       1 is the painting as is. The operator's default (a 70% veil); a
       visitor's own choice (Settings → Appearance) overrides it from
       /bg-art.js. */
    --bg-art: 0.3;
    /* Behind the comic panels (the feed's card grid, the my-comics grid) the
       painting shows more strongly: 1.7x the base intensity, capped at the
       painting as is. The band's document position comes from /bg-art.js,
       which measures every [data-bg-art-zone] element; with no zone on the
       page both stay 0px and the band collapses to nothing. */
    --bg-band-factor: 1.7;
    --bg-art-panels: min(1, calc(var(--bg-art) * var(--bg-band-factor)));
    --bg-zone-top: 0px;
    --bg-zone-bottom: 0px;
    /* Where the painting fades in below the headline and out above the
       footer. On a page with a [data-bg-fade-start] element (the creator
       card, the gallery's comic grid) /bg-art.js moves the start to that
       element's top edge and the end that element's --bg-fade-length below
       it, so the page stays white down to the panels (lengths: see the
       rules after body). */
    --bg-fade-top-start: 200px;
    --bg-fade-top-end: 520px;
    --bg-fade-bottom: 420px;
    --panel-border: 4px solid #000;
    --shadow: 10px 10px 0px rgba(0, 0, 0, 0.2);
    --text-color: #333;
    --accent-color: #ffcc00;

    /* The fixed top-right rail: the feedback pill and the settings gear.
       They are separate position:fixed elements with nothing structural
       holding them together, so each used to carry its own `top` and its own
       height — 20px/50px for the gear, 16px/41px (font + padding) for the
       pill. That put their centres 8.5px apart at every width, and the
       mismatch reappeared at each breakpoint because the two were adjusted
       independently.

       Driving both from one top and one size makes them share a centre line
       by construction: nothing has to be recomputed when a font, a padding or
       a breakpoint changes. Resize the whole rail here, in one place. */
    --toprail-top: 20px;
    --toprail-size: 44px;
}

* {
    box-sizing: border-box;
}

body {
    font-family: 'Comic Neue', cursive;
    background-color: var(--bg-color);
    /* The striped painting, tiled at its own pixel size so nothing is
       stretched, under a white veil that varies down the page: fully white
       behind the headline (on the creator and the gallery, down to the
       panels), fading in to a veil of 1 - --bg-art; a stronger band
       (1 - --bg-art-panels) across the feed's comic panels, between the
       measured zone edges; back to the base veil below them; and fading out
       to white over the last 420px so the footer sits on white. Stops that
       land out of order are clamped by the browser, which is what collapses
       the band on a page without a zone. The tile (1800x1800) is the picture
       mirrored on both axes, so every edge of the repeat meets a reflection
       of itself and no seam shows in either direction. The query string is
       the tile's own cache-buster: the file name is referenced from the
       stylesheet, not from any page. */
    background-image:
        linear-gradient(to bottom,
            rgba(255, 255, 255, 1) 0,
            rgba(255, 255, 255, 1) var(--bg-fade-top-start),
            rgba(255, 255, 255, calc(1 - var(--bg-art))) var(--bg-fade-top-end),
            rgba(255, 255, 255, calc(1 - var(--bg-art))) var(--bg-zone-top),
            rgba(255, 255, 255, calc(1 - var(--bg-art-panels))) calc(var(--bg-zone-top) + 140px),
            rgba(255, 255, 255, calc(1 - var(--bg-art-panels))) calc(var(--bg-zone-bottom) - 140px),
            rgba(255, 255, 255, calc(1 - var(--bg-art))) var(--bg-zone-bottom),
            rgba(255, 255, 255, calc(1 - var(--bg-art))) calc(100% - var(--bg-fade-bottom)),
            rgba(255, 255, 255, 1) calc(100% - 60px),
            rgba(255, 255, 255, 1) 100%),
        url('/bg-stripes.webp?v=2');
    background-repeat: no-repeat, repeat;
    background-size: 100% 100%, auto;
    background-position: center top, center top;
    color: var(--text-color);
    margin: 0;
    padding: 2rem;
    display: flex;
    flex-direction: column;
    align-items: center;
}

/* Where the painting fades in, relative to the panels' top edge (read by
   /bg-art.js from the [data-bg-fade-start] element): --bg-fade-offset moves
   the start (negative is above the edge) and --bg-fade-length is how far
   further down it is fully in. Desktop: from the edge itself, over 120px
   under the creator card and 360px under the gallery grid. On a phone the
   panels fill almost the whole width, so the fade is short or none: the
   creator's starts 15px above the card and is fully in at its edge, the
   gallery's starts 200px into the comic grid with no fade (the panel
   covers the step). */
.creator-container[data-bg-fade-start] {
    --bg-fade-offset: 0px;
    --bg-fade-length: 120px;
}

#comicGrid[data-bg-fade-start] {
    --bg-fade-offset: 0px;
    --bg-fade-length: 360px;
}

@media (max-width: 768px) {
    .creator-container[data-bg-fade-start] {
        --bg-fade-offset: -15px;
        --bg-fade-length: 15px;
    }

    #comicGrid[data-bg-fade-start] {
        --bg-fade-offset: 200px;
        --bg-fade-length: 0px;
    }
}

@media (max-width: 600px) {
    body {
        padding: 0.5rem;
        /* Reduced global padding */
    }
}

header {
    text-align: center;
    margin-bottom: 3rem;
    position: relative;
    /* Body is a centering flex column; without an explicit width the header
       shrinks to its content and the absolute .header-account pins to the
       title edge instead of the page's top right. */
    width: 100%;
}

/* Model Selector */
.model-selector {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    background: #fff;
    padding: 8px 12px;
    border: 2px solid #000;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2);
}

.model-selector label {
    font-weight: bold;
}

.model-selector select {
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    padding: 4px 8px;
    border: 2px solid #000;
    background: #fff;
    cursor: pointer;
    /* Long option labels otherwise size the closed control past its container. */
    min-width: 0;
    max-width: 100%;
    text-overflow: ellipsis;
}


h1 {
    font-family: 'Bangers', cursive;
    font-size: 4rem;
    margin: 0;
    text-transform: uppercase;
    color: #000;
    text-shadow: 4px 4px 0px var(--accent-color);
    letter-spacing: 2px;
}

header p {
    font-size: 1.5rem;
    margin-top: 0.5rem;
}

.comic-grid {
    display: grid;
    /* Mobile first: 1 column */
    grid-template-columns: 1fr;
    gap: 1.5rem;
    max-width: 1300px;
    width: 100%;
    padding: 0 10px;
    /* Add padding for small screens */
}

@media (min-width: 600px) {
    .comic-grid {
        grid-template-columns: repeat(auto-fit, minmax(450px, 1fr));
        gap: 3rem;
        padding: 0;
    }
}

/* Panel container - now a flex row with image and button side by side */
/* Panel container */
.panel {
    background: #fff;
    border: var(--panel-border);
    box-shadow: var(--shadow);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
    display: flex;
    flex-direction: column;
    /* Mobile first: Stack vertically */
    position: relative;
    overflow: visible;
}

@media (min-width: 600px) {
    .panel {
        flex-direction: row;
        /* Desktop: Side-by-side */
    }
}

/* Featured "hero" panel — matches the gold hero accent shown in the creator
   layout preview. Kept subtle so it frames the art without obscuring it. */
.panel.hero-panel {
    box-shadow: 0 0 0 3px #FFD700, var(--shadow);
    z-index: 1;
}

.panel.reorder-enabled {
    cursor: grab;
}

.panel.reorder-enabled:active {
    cursor: grabbing;
}

.panel.dragging {
    opacity: 0.5;
    transform: rotate(5deg);
    cursor: grabbing;
}

.panel.drag-over {
    transform: scale(1.02);
    opacity: 0.8;
}

.panel.drop-target {
    outline: 4px solid var(--accent-color);
    outline-offset: 4px;
    box-shadow: 0 0 20px rgba(255, 204, 0, 0.6);
    transform: scale(1.02);
}

.panel.double-wide {
    /* "Toggle Size" enlarges THIS panel: it takes the whole grid row and the
       others flow after it. Full-row (1 / -1), not `span 2`: the grid is
       auto-fit, and when it has resolved to a single column a two-column span
       conjures an implicit second column — the expanded panel grew by a third
       while every other panel shrank to the 450px minimum. In one column the
       full row IS the column, so nothing else moves; in two it is the whole
       row, twice the size. No forced 8:3 window: panel art is usually square,
       and an 8:3 cover-crop hid ~60% of it. Bigger means the full image sets
       the height. */
    grid-column: 1 / -1;
}

.panel.double-wide .panel-image-wrapper {
    aspect-ratio: auto;
}

.panel.double-wide .panel-image-wrapper img {
    height: auto;
}

/* Art detected as a panorama (≥1.9:1, gallery.js measures the loaded image):
   cover-cropping it into the 4:3 cell would cut ~40% of its width and upscale
   the rest. Show it uncropped ACROSS the full grid row: in a shared row the
   4:3 neighbour would stretch this panel taller than its art (grid items fill
   the row height) and leave a blank band under the image; a full row lets the
   image set the row height, cinematic-strip style. */
.panel.panorama-art {
    grid-column: 1 / -1;
}

.panel.panorama-art .panel-image-wrapper {
    aspect-ratio: auto;
}

.panel.panorama-art .panel-image-wrapper img {
    height: auto;
}



.panel-placeholder {
    border: 2px dashed var(--accent-color);
    background: rgba(255, 204, 0, 0.1);
    border-radius: 8px;
    margin: 3rem 0;
}


.panel:hover {
    transform: translate(-5px, -5px);
    box-shadow: 15px 15px 0px rgba(0, 0, 0, 0.3);
}

/* Image wrapper to contain image and speech bubbles */
.panel-image-wrapper {
    position: relative;
    flex: 1;
    overflow: hidden;
    line-height: 0;
    font-size: 0;
    /* Force 4:3 aspect ratio */
    aspect-ratio: 4 / 3;
}

.panel img {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    object-position: center top;
    /* Slight scale to prevent any hairline rendering gaps/borders */
    transform: scale(1.01);
}

/* Mobile: panels are stored in varying aspect ratios (some are 2.36:1
   panoramas) — cropping them into a fixed 4:3 box loses most of the art on a
   phone. Let the image dictate the card height instead; the min-height keeps
   still-loading panels from collapsing. Desktop keeps the uniform 4:3 grid. */
@media (max-width: 600px) {
    .panel-image-wrapper {
        aspect-ratio: auto;
        min-height: 120px;
    }

    .panel img {
        height: auto;
    }
}

/* Blur-up preview. The gallery page ships a 32px WebP of each panel plus the
   art's real size (src/lib/panelPreviews.js); renderPanels() and the slide
   put it on the image's box as --lqip, with the art's anchor (--lqip-pos)
   and shape (--panel-aspect). Scaled up and blurred, it sits BEHIND the
   <img> (isolation + z-index -1), so the image simply paints over it when
   it arrives and a box without a preview looks exactly as before. */
.panel-image-wrapper.has-preview,
.slides-content .slide-panel-image.has-preview {
    isolation: isolate;
}

.panel-image-wrapper.has-preview::before,
.slides-content .slide-panel-image.has-preview::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: var(--lqip);
    background-position: var(--lqip-pos, 50% 50%);
    background-size: cover;
    background-repeat: no-repeat;
    /* The blur fades the edges; the scale pushes the faded rim out of view. */
    filter: blur(14px);
    transform: scale(1.12);
    pointer-events: none;
}

/* Where the box takes the art's own shape (a double-wide or panorama panel,
   a panorama slide, and every panel and slide on a phone), the preview's
   size gives the box that shape before the image exists, so nothing below
   it moves when the image lands. */
.panel.double-wide .panel-image-wrapper.has-preview,
.panel.panorama-art .panel-image-wrapper.has-preview,
.slides-content .slide-panel-image.panorama-art.has-preview {
    aspect-ratio: var(--panel-aspect, auto);
}

@media (max-width: 600px) {
    .panel-image-wrapper.has-preview {
        aspect-ratio: var(--panel-aspect, auto);
    }
}

@media (pointer: coarse), (max-width: 800px) {
    .slides-content .slide-panel-image.has-preview {
        aspect-ratio: var(--panel-aspect, auto);
    }
}

/* Relocated Resize Button */
.panel-resize-btn {
    position: absolute;
    bottom: 10px;
    right: 10px;
    width: 30px;
    height: 30px;
    background: rgba(255, 255, 255, 0.9);
    border: 2px solid #333;
    border-radius: 50%;
    cursor: pointer;
    z-index: 20;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    transition: transform 0.2s, opacity 0.2s;
    opacity: 0;
}

.panel:hover .panel-resize-btn {
    opacity: 1;
}

.panel-resize-btn:hover {
    transform: scale(1.1);
    background: #fff;
}

from {
    opacity: 0;
    transform: scale(0.98);
}

to {
    opacity: 1;
    transform: scale(1);
}

to {
    opacity: 1;
    transform: scale(1);
}


.text-bracket {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.95), rgba(0, 0, 0, 0.5) 80%, rgba(0, 0, 0, 0));
    padding: 40px 20px 20px 20px;
    /* Bigger touch target/visual area */
    /* More padding at top for gradient fade */
    font-size: 1rem;
    font-family: 'Comic Neue', cursive;
    color: #fff;
    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
    z-index: 5;
    pointer-events: none;
    text-align: center;
    font-weight: bold;
    letter-spacing: 0.5px;
    /* Dynamic height for long text */
    min-height: fit-content;
    max-height: 60%;
    overflow-y: auto;
    word-wrap: break-word;
    overflow-wrap: break-word;
    line-height: 1.4;
}

.text-bracket.editing,
.caption-display.editing {
    pointer-events: auto;
    cursor: text;
    outline: 2px dashed var(--accent-color);
    outline-offset: 2px;
    background: rgba(0, 0, 0, 0.85);
    user-select: text;
    -webkit-user-select: text;
}

/* Caption Wrapper - contains caption + edit/delete buttons */
.caption-wrapper {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 5;
}

.caption-wrapper .text-bracket {
    position: relative;
}

/* Caption Edit Button */
.caption-edit-btn {
    position: absolute;
    top: 10px;
    right: 35px;
    width: 24px;
    height: 24px;
    background: rgba(255, 255, 255, 0.9);
    border: 2px solid #333;
    border-radius: 50%;
    cursor: pointer;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s, visibility 0.2s;
    z-index: 10;
    pointer-events: auto;
}

/* Caption Delete Button */
.caption-delete-btn {
    position: absolute;
    top: 10px;
    right: 5px;
    width: 24px;
    height: 24px;
    background: #c62828;
    color: white;
    border: 2px solid #fff;
    border-radius: 50%;
    cursor: pointer;
    font-size: 16px;
    font-weight: bold;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s, visibility 0.2s;
    z-index: 10;
    pointer-events: auto;
}

.caption-wrapper:hover .caption-edit-btn,
.caption-wrapper:hover .caption-delete-btn {
    opacity: 1;
    visibility: visible;
}

.caption-edit-btn:hover {
    background: #fff;
    transform: scale(1.1);
}

.caption-delete-btn:hover {
    background: #f44336;
    transform: scale(1.1);
}

.bubble {
    position: absolute;
    background: #fff;
    border: 3px solid #000;
    border-radius: 50% / 10%;
    padding: 1rem;
    text-align: center;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 1rem;
    line-height: 1.3;
    color: #000;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.1);
    max-width: 60%;
    z-index: 10;
}

.bubble.thought {
    border-style: dashed;
    color: #555;
    border-radius: 20px;
}

/* Positioning */
.bubble.top-left {
    top: 20px;
    left: 20px;
}

.bubble.top-right {
    top: 20px;
    right: 20px;
}

.bubble.bottom-left {
    bottom: 20px;
    left: 20px;
}

.bubble.bottom-right {
    bottom: 20px;
    right: 20px;
}

@media (max-width: 600px) {
    h1 {
        font-size: 2.5rem;
    }

    .comic-grid {
        grid-template-columns: 1fr;
    }

    .panel {
        flex-direction: column;
    }

    /* Mobile: Regenerate/Edit become full-width labeled bars below the
       panel image, ALWAYS visible (no hover on touch; keeping them
       opacity-hidden reserved ~100px of blank space per panel).
       .panel prefix keeps these winning over the desktop base rules that
       appear LATER in the file (same class specificity would lose). */
    .panel .regenerate-btn {
        position: relative;
        width: 100%;
        border-radius: 0;
        right: auto;
        top: auto;
        transform: none !important;
        opacity: 1;
        pointer-events: auto;
        writing-mode: horizontal-tb !important;
        text-orientation: mixed !important;
        margin-top: 5px;
        box-shadow: none !important;
        border: none;
        border-top: 2px solid #000;
        background: #222;
        /* Match the gallery's other labeled controls (.toggle-details-btn):
           the desktop hover overlay uses Bangers, but as a permanent bar next
           to Comic Neue captions/buttons that reads as a font clash. */
        font-family: 'Comic Neue', cursive;
        font-weight: 700;
        font-size: 0.95rem;
        padding: 10px;
        gap: 6px;
    }

    .panel .edit-ai-btn {
        position: relative;
        width: 100%;
        border-radius: 0;
        left: auto;
        top: auto;
        transform: none !important;
        opacity: 1;
        pointer-events: auto;
        box-shadow: none !important;
        border: none;
        border-top: 2px solid #444;
        background: #222;
        font-family: 'Comic Neue', cursive;
        font-weight: 700;
        font-size: 0.95rem;
        padding: 10px;
        gap: 6px;
    }

    /* Adjust delete button for mobile - hidden by default */
    .delete-btn {
        opacity: 0;
        pointer-events: none;
        width: 36px;
        height: 36px;
        top: 5px;
        right: 5px;
        background: rgba(255, 0, 0, 0.8);
        transition: opacity 0.2s ease;
    }

    .panel.tapped .delete-btn {
        opacity: 1;
        pointer-events: auto;
    }

    /* Adjust resize button for mobile - hidden by default */
    .panel-resize-btn {
        opacity: 0;
        pointer-events: none;
        width: 36px;
        height: 36px;
        background: rgba(255, 255, 255, 0.9);
        transition: opacity 0.2s ease;
    }

    .panel.tapped .panel-resize-btn {
        opacity: 1;
        pointer-events: auto;
    }

    /* History navigation - hidden by default */
    .hist-nav {
        opacity: 0;
        pointer-events: none;
        background: rgba(0, 0, 0, 0.5);
        padding: 5px;
        transition: opacity 0.2s ease;
    }

    /* Desktop keeps the right arrow clear of the vertical regenerate bar
       (right: 70px); on mobile that bar is below the image, so mirror the
       left arrow instead of floating 70px into the panel. .panel prefix
       outranks the later desktop base rule. */
    .panel .hist-right {
        right: 10px;
    }

    .panel.tapped .hist-nav,
    .panel.tapped .version-counter {
        opacity: 1;
        pointer-events: auto;
    }

    .panel:hover {
        transform: none;
        box-shadow: var(--shadow);
    }

    /* Panel text controls - hidden by default */
    .panel-text-controls {
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease;
    }

    .panel.tapped .panel-text-controls {
        opacity: 1;
        pointer-events: auto;
    }
}

/* Regeneration UI - Absolutely positioned, inside the panel on the right */
.regenerate-btn {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    writing-mode: vertical-rl;
    text-orientation: mixed;
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    border: 2px solid #fff;
    padding: 15px 10px;
    font-family: 'Bangers', cursive;
    font-size: 1.1rem;
    cursor: pointer;
    transition: all 0.2s ease;
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
    border-radius: 5px;
}

@media (max-width: 600px) {
    /* regenerate/edit mobile layout lives in the .panel-prefixed
       rules in the first max-width:600px block above; repeating them here
       at lower specificity would silently lose to the desktop base rules. */
    .hist-nav {
        font-size: 1rem;
        padding: 5px;
    }
}

.panel:hover .regenerate-btn,
.panel.tapped .regenerate-btn {
    opacity: 1;
    pointer-events: auto;
}

.regenerate-btn:hover {
    background: var(--accent-color);
    color: #000;
    transform: translateY(-50%) scale(1.05);
    border-color: #000;
}

/* The Repaint brush no longer has a panel button of its own — it is a mode
   inside the Edit modal (#editMaskSection), reached through .edit-ai-btn. */

/* Edit AI Button - positioned at center top of the panel */
.edit-ai-btn {
    position: absolute;
    left: 50%;
    top: 10px;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    border: 2px solid #fff;
    padding: 8px 16px;
    font-family: 'Bangers', cursive;
    font-size: 1.1rem;
    cursor: pointer;
    transition: all 0.2s ease;
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
    border-radius: 5px;
}

.panel:hover .edit-ai-btn,
.panel.tapped .edit-ai-btn {
    opacity: 1;
    pointer-events: auto;
}

.edit-ai-btn:hover {
    background: var(--accent-color);
    color: #000;
    transform: translateX(-50%) scale(1.05);
    border-color: #000;
}

/* Modal */
.modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    align-items: center;
    justify-content: center;
}

.modal.active {
    display: flex;
}

.modal-content {
    background-color: #fff;
    padding: 2rem;
    border: 4px solid #000;
    width: 95%;
    /* Wider on mobile */
    max-width: 600px;
    box-shadow: 10px 10px 0px var(--accent-color);
    position: relative;
    font-family: 'Comic Neue', cursive;
    max-height: 90vh;
    /* Prevent vertical overflow */
    overflow-y: auto;
    /* Scroll if too tall */
}

@media (max-width: 600px) {
    .modal-content {
        padding: 1rem;
        width: 98%;
        box-shadow: 5px 5px 0px var(--accent-color);
        margin: 10px;
    }
}

.close-modal {
    position: absolute;
    top: 10px;
    right: 15px;
    font-size: 2rem;
    font-weight: bold;
    cursor: pointer;
}

.modal h2 {
    font-family: 'Bangers', cursive;
    margin-top: 0;
}

#promptInput {
    width: 100%;
    height: 150px;
    margin: 1rem 0;
    padding: 1rem;
    font-family: monospace;
    border: 2px solid #ccc;
    resize: vertical;
}

#generateBtn,
#startReimaginBtn,
#editGenerateBtn {
    background: #000;
    color: #fff;
    border: none;
    padding: 1rem 2rem;
    font-size: 1.2rem;
    font-family: 'Bangers', cursive;
    cursor: pointer;
    width: 100%;
    transition: background 0.2s;
}

#generateBtn:hover,
#startReimaginBtn:hover,
#editGenerateBtn:hover {
    background: var(--accent-color);
    color: #000;
}

/* Modal Model Test Status */
.modal-model-test-status {
    margin-top: 8px;
    padding: 10px 12px;
    border-radius: 6px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.95rem;
    font-weight: bold;
    text-align: center;
}

.modal-model-test-status.testing {
    background: #fff3cd;
    border: 2px solid #ffc107;
    color: #856404;
}

.modal-model-test-status.success {
    background: #d4edda;
    border: 2px solid #28a745;
    color: #155724;
}

.modal-model-test-status.error {
    background: #f8d7da;
    border: 2px solid #dc3545;
    color: #721c24;
}

/* Reference images info */
.reference-info {
    font-size: 0.85rem;
    color: #666;
    margin-top: 0.5rem;
    padding: 0.5rem;
    background: #f5f5f5;
    border-radius: 4px;
}

/* History Navigation Arrows */
.hist-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    border: 2px solid #fff;
    font-size: 1.5rem;
    cursor: pointer;
    z-index: 90;
    padding: 10px;
    opacity: 0;
    transition: opacity 0.2s, background 0.2s;
    pointer-events: none;
}

.panel:hover .hist-nav {
    opacity: 1;
    pointer-events: auto;
}

.hist-nav:hover {
    background: var(--accent-color);
    color: #000;
}

.hist-left {
    left: 10px;
}

.hist-right {
    right: 70px;
    /* Left of regenerate button */
}

/* Version counter in top right */
.version-counter {
    position: absolute;
    top: 10px;
    right: 45px;
    background: rgba(0, 0, 0, 0.7);
    color: #fff;
    font-family: 'Comic Neue', cursive;
    font-size: 0.8rem;
    font-weight: bold;
    padding: 4px 8px;
    border-radius: 4px;
    z-index: 90;
    opacity: 0;
    transition: opacity 0.2s;
    pointer-events: none;
}

.panel:hover .version-counter {
    opacity: 1;
}


/* Delete Button */
.delete-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    background: #d32f2f;
    color: #fff;
    border: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1rem;
    cursor: pointer;
    z-index: 95;
    opacity: 0;
    transition: opacity 0.2s, background 0.2s;
    pointer-events: none;
}

.panel:hover .delete-btn {
    opacity: 1;
    pointer-events: auto;
}

.delete-btn:hover {
    background: #b71c1c;
    color: white;
    transform: scale(1.1);
}

/* Undo Button - Positioned on the left side */
.undo-btn {
    position: absolute;
    left: -60px;
    top: 50%;
    transform: translateY(-50%);
    display: none;
    /* Hidden by default, shown by JS if history exists */
    align-items: center;
    justify-content: center;
    writing-mode: vertical-rl;
    text-orientation: mixed;
    background: #000;
    color: #fff;
    border: 2px solid #fff;
    padding: 20px 15px;
    /* Enlarged */
    font-family: 'Bangers', cursive;
    font-size: 1.3rem;
    /* Enlarged */
    cursor: pointer;
    transition: all 0.2s ease;
    z-index: 100;
    opacity: 0;
    pointer-events: none;
    box-shadow: -5px 5px 0px rgba(0, 0, 0, 0.3);
}

/* Bridge the gap between panel and button */
.undo-btn::before {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 100%;
    width: 30px;
    /* Covers the gap */
    background: transparent;
}

.panel:hover .undo-btn {
    opacity: 1;
    pointer-events: auto;
}


.undo-btn:hover {
    background: #ff4757;
    color: #fff;
    transform: translateY(-50%) scale(1.05);
}

/* Modal Form Elements */
.input-group {
    margin-bottom: 1rem;
}

.input-group label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: bold;
    font-family: 'Bangers', cursive;
    font-size: 1.1rem;
}

.modal textarea {
    width: 100%;
    padding: 0.5rem;
    border: 2px solid #ccc;
    border-radius: 4px;
    font-family: monospace;
    resize: vertical;
}

.options-row {
    margin: 1rem 0;
    display: flex;
    align-items: center;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    font-family: 'Comic Neue', cursive;
    font-size: 1.1rem;
}

.checkbox-label input[type="checkbox"] {
    width: 20px;
    height: 20px;
}

/* Toast Notification Container */
#toast-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    z-index: 2000;
    pointer-events: none;
}

.toast {
    background: #fff;
    border: 3px solid #000;
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
    padding: 1rem 1.5rem;
    min-width: 250px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 1.1rem;
    display: flex;
    align-items: center;
    gap: 10px;
    animation: toastSlideIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    pointer-events: auto;
}

.toast.success {
    border-left: 8px solid #4CAF50;
}

.toast.error {
    border-left: 8px solid #F44336;
}

.toast.info {
    border-left: 8px solid var(--accent-color);
}

.toast.hiding {
    animation: toastFadeOut 0.3s ease forwards;
}

@keyframes toastSlideIn {
    from {
        opacity: 0;
        transform: translateX(50px) scale(0.9);
    }

    to {
        opacity: 1;
        transform: translateX(0) scale(1);
    }
}

/* --- FEEDBACK POPUP (small corner box asking for alpha feedback) --- */
/* Always-visible feedback trigger, top right. Offset left of .settings-btn
   (fixed, 50px wide at right:20px) — at right:16px this button covered the
   settings gear completely and swallowed its clicks. Sits below the popup's
   z-index so the open box is never covered by the button that opened it. */
.feedback-fab {
    position: fixed;
    top: var(--toprail-top);
    right: 84px;
    z-index: 2000;
    /* Rail-sized rather than font-sized, so the pill keeps the gear's centre
       line whatever the label says or the font does. Vertical padding would
       fight the fixed height; the flex centring replaces it. */
    height: var(--toprail-size);
    display: inline-flex;
    align-items: center;
    padding: 0 0.9rem;
    background: #ffd93d;
    color: #000;
    border: 3px solid #000;
    border-radius: 8px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.25);
    font-family: 'Bangers', 'Comic Neue', cursive;
    font-size: 1rem;
    letter-spacing: 0.5px;
    cursor: pointer;
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}

.feedback-fab:hover {
    transform: translate(-1px, -1px);
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.3);
}

.feedback-fab:active {
    transform: translate(2px, 2px);
    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25);
}

@media (max-width: 768px) {
    /* Keep the right offset: .settings-btn stays 50px at right:20px on the
       creator/gallery pages at every width, so the clearance must not shrink.
       Only the button's own size comes down. */
    /* Move the whole rail rather than the pill alone — adjusting one of the
       two is what pulled them apart at this breakpoint before. */
    :root {
        --toprail-top: 12px;
        --toprail-size: 40px;
    }

    .feedback-fab {
        padding: 0 0.6rem;
        font-size: 0.85rem;
    }

    /* …and reserve the band it occupies. The desktop fix above moved the
       header CONTROLS out from under the fab, but the <h1> itself still ran
       under it: on a phone the title is centred and full-width, so the pill
       landed straight on the words. Rendered at 390px, the homepage read
       "BROWSE S▮▮▮▮S" and the creator "COMIC S▮▮▮▮ CREATOR" — the first thing
       every mobile visitor saw.

       Pushing the whole header down is the fix that holds for every page,
       because all of them put the fab in the same fixed band and none of them
       agree on what the first header child is. */
    header {
        padding-top: 52px;
    }
}

.feedback-popup {
    position: fixed;
    bottom: 20px;
    right: 20px;
    width: 300px;
    max-width: calc(100vw - 40px);
    background: #fff;
    border: 3px solid #000;
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
    padding: 1rem;
    font-family: 'Comic Neue', cursive;
    z-index: 2100;
    animation: toastSlideIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.feedback-popup .feedback-title {
    font-weight: bold;
    font-size: 1.05rem;
    margin-bottom: 8px;
    padding-right: 24px;
}

.feedback-popup .feedback-thanks {
    padding-right: 0;
    margin-bottom: 0;
    text-align: center;
}

.feedback-popup .feedback-text {
    width: 100%;
    box-sizing: border-box;
    border: 2px solid #000;
    padding: 8px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.95rem;
    resize: vertical;
    margin-bottom: 8px;
}

.feedback-popup .feedback-send {
    width: 100%;
    background: var(--accent-color);
    border: 2px solid #000;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2);
    padding: 8px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 1rem;
    cursor: pointer;
}

.feedback-popup .feedback-send:hover:not(:disabled) {
    transform: translate(-1px, -1px);
    box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.2);
}

.feedback-popup .feedback-send:disabled {
    opacity: 0.6;
    cursor: wait;
}

.feedback-popup .feedback-error {
    color: #F44336;
    font-size: 0.9rem;
    margin-bottom: 8px;
}

.feedback-popup .feedback-close {
    position: absolute;
    top: 6px;
    right: 8px;
    background: none;
    border: none;
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    color: #333;
}

/* --- VIEWER CONTROLS --- */
.viewer-controls {
    display: block;
    margin-bottom: 0.6rem;
}

.viewer-controls h2 {
    margin: 0;
    font-family: 'Bangers', cursive;
    font-size: 2rem;
}

.story-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    flex-wrap: nowrap;
}

.story-title-left {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 5px;
    min-width: 0;
    flex: 1 1 auto;
}

.title-row-toggle {
    margin-left: auto;
    flex: 0 0 auto;
}

.controls-right {
    display: flex;
    gap: 1rem;
    align-items: center;
    flex-wrap: wrap;
}

.style-selector {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    background: #fff;
    padding: 8px 12px;
    border: 2px solid #000;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2);
}

.style-selector label {
    font-weight: bold;
}

.style-selector select {
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    padding: 4px 8px;
    border: 2px solid #000;
    background: #fff;
    cursor: pointer;
}

/* --- STORY CREATOR STYLES --- */

nav {
    font-size: 1.5rem;
    font-family: 'Bangers', cursive;
    margin-top: 1rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    column-gap: 26px;
    row-gap: 6px;
}

nav a {
    color: #333;
    text-decoration: none;
    margin: 0;
    padding-bottom: 5px;
}

nav a.active {
    color: #000;
    border-bottom: 3px solid var(--accent-color);
}

/* Top-level nav search: an icon that expands an inline input. Injected by
   core.js on every page (survives router header swaps). */
.nav-search {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.nav-search-toggle {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1.3rem;
    line-height: 1;
    padding: 0 2px 5px;
    color: #333;
}

.nav-search-toggle:hover {
    transform: scale(1.1);
}

.nav-search-input {
    width: 0;
    opacity: 0;
    padding: 0;
    border: 3px solid #000;
    border-radius: 10px;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 1rem;
    background: #fffef5;
    transition: width 0.22s ease, opacity 0.22s ease, padding 0.22s ease;
    pointer-events: none;
}

.nav-search.open .nav-search-input {
    width: min(200px, 40vw);
    opacity: 1;
    padding: 7px 12px;
    pointer-events: auto;
}

@media (pointer: coarse) {
    .nav-search-toggle {
        padding-top: 10px;
        padding-bottom: 10px;
    }
}

/* Touch screens: pad the nav links vertically so the tap target reaches the
   recommended ~44px without changing the desktop look. */
@media (pointer: coarse) {
    nav a {
        padding-top: 10px;
        padding-bottom: 10px;
    }
}

/* The trash bin is a logged-in feature: hidden by default, revealed when the
   session scripts stamp body.user-logged-in (core.js, stories.html, trash.html). */
nav .trash-link {
    display: none;
}

body.user-logged-in nav .trash-link {
    display: inline;
}

/* Same treatment for the admin panel, which had no entry point at all: it is
   reachable only by typing /admin.html, so an operator had to remember the URL
   on a site that otherwise navigates by nav bar. Revealed by body.user-is-admin,
   stamped from the server-issued session role.

   Cosmetic only. Hiding a link is not access control — /api/admin/* is gated by
   authenticateAdmin and the panel itself renders an "Admins only" screen for
   anyone else, so forcing the class on just buys you a page full of 401s.
   admin.html stays out of router.js's ROUTABLE set, so this navigates for real
   rather than swapping content in place. */
nav .admin-link {
    display: none;
}

body.user-is-admin nav .admin-link {
    display: inline;
}

/* Top-right header cluster holding the language switcher + account control.
   Pinned to the top right of the header; falls back below the nav on narrow
   screens where it would collide with the centered title / fixed gear. */
.header-controls {
    position: absolute;
    top: 0;
    /* Clears the fixed settings gear pinned in the top-right corner
       (gear left edge sits ~70px from the viewport edge). */
    right: 56px;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    max-width: 100%;
    min-width: 0;
}

/* .feedback-fab is position:fixed in the same top-right corner (top:16px,
   ~41px tall). It clears the settings gear horizontally, but nothing reserved
   room for this cluster, so wherever the header is the topmost element the fab
   landed straight on top of the Log in pill and the language switcher and
   swallowed their clicks. It only looked fine while something above the header
   — the rebuild-etiquette banner — happened to push it down, i.e. never for a
   logged-out visitor.

   Separate them vertically rather than horizontally: the fab's label is
   translated (measured 84px in fr up to 118px in es), so any right: offset
   large enough today is one long translation away from colliding again.
   Only needed from 961px up; below that .header-controls goes static and
   centers under the nav, well clear of the fab.

   Dropping the cluster below the fab's band is enough on its own — it lands
   beside the centred title, where there is already empty space, so the header
   needs no extra padding and nothing else on the page shifts. */
@media (min-width: 961px) {
    .header-controls {
        top: 46px;
    }
}

/* Account control sits left, language switcher is the far-right element,
   regardless of which script appended first. */
.header-controls .header-account { order: 1; }
.header-controls .lang-switcher { order: 2; }

/* nowrap keeps "👤 name  PRO ✦  Log out" on one line; the row must therefore
   be allowed to SHRINK, or a long username (plus the badge, which only ever
   adds width) pushes the log-out link and the language switcher out of the
   viewport. min-width:0 lets the flex item drop below its content width so the
   username can ellipsize instead — see .header-account-name below. */
.header-account {
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    max-width: 100%;
}

/* The username is the only elastic part of the cluster: the badge, the log-out
   link and the login pill all stay at their natural size. */
.header-account .pro-badge,
.header-account a {
    flex: 0 0 auto;
}

@media (max-width: 960px) {
    .header-controls {
        position: static;
        justify-content: center;
        width: 100%;
        margin-top: 10px;
    }
}

.header-account .header-account-name {
    margin: 0;
    color: #333;
    /* Truncate the name rather than let the row overflow the header. */
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

.header-account a {
    color: #333;
}

/* Paid-Pro marker on the account control (public/pro-status.js decides when it
   is rendered — never on a billing-disabled deployment, where the server hands
   everyone Pro entitlements and the badge would mean nothing).

   Same recipe as .header-login-pill: a solid accent fill behind black text with
   a black keyline, so the mark carries its own contrast and stays legible on
   the light page background and on the dark hero/cover treatments alike,
   instead of depending on whatever sits behind it. */
.pro-badge {
    display: inline-block;
    background: var(--accent-color);
    color: #000;
    border: 2px solid #000;
    border-radius: 999px;
    padding: 0 9px 1px;
    font-family: 'Bangers', cursive;
    font-size: 0.85rem;
    letter-spacing: 1px;
    line-height: 1.6;
    white-space: nowrap;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
}

/* Weekly-event winner badge. Deliberately a quieter sibling of .pro-badge: it
   sits inline in a story card's byline rather than in the header, so it takes
   the same comic-panel outline at a smaller weight and never wraps away from
   the name it belongs to. Permanent and stacking — "🏆" for one win, "🏆 3×"
   for repeat winners. */
.winner-badge {
    display: inline-block;
    background: #fff3c4;
    color: #000;
    border: 2px solid #000;
    border-radius: 999px;
    padding: 0 6px;
    margin-left: 4px;
    font-family: 'Bangers', cursive;
    font-size: 0.72rem;
    letter-spacing: 0.5px;
    line-height: 1.5;
    white-space: nowrap;
    vertical-align: baseline;
}

/* The account control is a nowrap inline-flex row pinned next to the fixed
   settings gear; on touch/narrow layouts it moves under the nav and shares the
   full width with the language switcher, so the badge gives back the space it
   does not need rather than pushing the username out of the viewport.

   Scoped to body.user-is-pro (core.js / stories.html stamp it from the same
   pro-status.js predicate as the badge itself) so it only re-spaces a cluster
   that actually GAINED an element. Unscoped, the tightened gap reached every
   visitor on any touchscreen — including all of billing-disabled production,
   where nobody can ever see a badge and the header should look untouched. */
@media (pointer: coarse), (max-width: 600px) {
    body.user-is-pro .pro-badge {
        font-size: 0.75rem;
        padding: 0 7px 1px;
        letter-spacing: 0.5px;
        box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
    }

    body.user-is-pro .header-account {
        gap: 6px;
    }
}

/* The account control is a single round person icon: logged in it opens the
   account menu (public/account-menu.js — name, Pro status, your comics, log
   out), logged out it opens the login prompt. The name itself is only for
   assistive tech + the tooltip. */
.header-account-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 2px solid #000;
    border-radius: 50%;
    background: #fff;
    color: #000;
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
    transition: transform 0.12s, box-shadow 0.12s;
}

.header-account-btn:hover {
    transform: translate(1px, 1px);
    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
}

/* .header-login-pill below sets `display: inline-block`, and it wins over
   .header-account-btn's `inline-flex` on equal specificity by coming later in
   the file. That silently cancelled the flex centring, so the person glyph sat
   on a text baseline inside a 38px circle instead of in the middle of it —
   visibly high and to the left. This rule already existed to reconcile the two
   classes (padding, radius, line-height); `display` was the one it missed. */
.header-account-btn.header-login-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-radius: 50%;
    line-height: 1;
}

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

/* Phones/tablets: the cluster itself drops below the nav (see the 960px rule
   above), but the person icon is asked for in the top-right corner — so it
   leaves the cluster and sits fixed under the settings gear (top:20px, 50px
   tall, right:20px), in the same column, clear of the feedback fab to its
   left. Pages without a gear get the same spot for consistency. */
@media (max-width: 960px) {
    .header-account {
        position: fixed;
        /* 40px tall at top:11px centres on the feedback fab's band (top:12px,
           ~34px tall) and the phone-size settings gear (top:10px, 42px). */
        top: 11px;
        right: 20px;
        z-index: 899;
        gap: 4px;
    }

    .header-account .header-account-btn {
        width: 40px;
        height: 40px;
        border-width: 3px;
        font-size: 1.3rem;
        box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.2);
    }

    /* The creator and the gallery keep their settings gear in the corner
       (.settings-btn, fixed at right:20px, 50px wide): the icon moves in
       beside it, and the feedback fab shifts left by the same amount. */
    body:has(.settings-btn) .header-account {
        right: 78px;
    }

    .feedback-fab {
        right: 72px;
    }

    body:has(.settings-btn) .feedback-fab {
        right: 130px;
    }
}

/* Under 700px the gear shrinks to 42px at right:10px (see the 700px block
   further down): close the column up with it. */
@media (max-width: 700px) {
    body:has(.settings-btn) .header-account {
        right: 62px;
    }

    body:has(.settings-btn) .feedback-fab {
        right: 114px;
    }

    /* PRO badge becomes a small tag on the icon rather than a second pill in
       the corner. */
    .header-controls .header-account .pro-badge {
        position: absolute;
        right: -8px;
        bottom: -8px;
        font-size: 0.55rem;
        line-height: 1.5;
        padding: 0 4px;
        letter-spacing: 0.5px;
        box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
    }
}

/* Accent is a fill behind black text, never yellow text on light bg. */
.header-login-pill {
    display: inline-block;
    background: var(--accent-color);
    color: #000;
    border: 2px solid #000;
    border-radius: 999px;
    padding: 1px 16px 3px;
    line-height: 1.5;
    text-decoration: none;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
    transition: transform 0.12s, box-shadow 0.12s;
}

.header-login-pill:hover {
    transform: translate(1px, 1px);
    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
}

.creator-container {
    max-width: 800px;
    width: 100%;
    background: #fff;
    padding: 2rem;
    border: var(--panel-border);
    box-shadow: var(--shadow);
}

@media (max-width: 600px) {
    .creator-container {
        padding: 0.5rem;
        /* Reduced padding */
        width: 100%;
        border: none;
        /* No border on mobile */
        box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
    }

    .style-input-group>div {
        flex-direction: column;
        gap: 5px;
    }

    #stylePresetSelect,
    #styleInput,
    .model-selector select {
        width: 100% !important;
        /* Full width */
        flex: 1 1 auto !important;
        min-width: 0 !important;
    }

    #autoStyleBtn {
        width: 100%;
        /* Full width button */
    }
}

.step {
    margin-bottom: 2rem;
    padding: 1.5rem;
    border: 2px dashed #ccc;
    border-radius: 8px;
    transition: all 0.3s ease;
}

.step.disabled {
    opacity: 0.5;
    pointer-events: none;
    background: #f9f9f9;
}

.step.hidden-step {
    display: none;
}

.step h2 {
    font-family: 'Bangers', cursive;
    margin-top: 0;
}

textarea {
    width: 100%;
    min-height: 120px;
    padding: 1rem;
    font-family: 'Comic Neue', cursive;
    font-size: 1.1rem;
    border: 2px solid #000;
    margin-bottom: 1rem;
    resize: vertical;
}

.action-btn {
    background: #000;
    color: #fff;
    border: none;
    padding: 10px 20px;
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    cursor: pointer;
    transition: transform 0.1s;
}

.action-btn:hover {
    background: var(--accent-color);
    color: #000;
    transform: scale(1.05);
}

.action-btn.primary {
    width: 100%;
    font-size: 1.5rem;
    padding: 15px;
}

.action-btn.quick-create {
    background: var(--accent-color);
    color: #000;
    font-size: 1.1rem;
    padding: 10px 20px;
    border: 2px solid #000;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.3);
    text-transform: uppercase;
    letter-spacing: 1px;
}

.action-btn.quick-create:hover {
    background: #fff;
    transform: scale(1.05);
    box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.4);
}

/* Creation date at the top of the gallery's Story Details panel */
.story-created-info {
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
    font-weight: 700;
    color: #666;
    margin-bottom: 10px;
}

/* Provider + pollen-cost line under the Quick Create button */
.quick-create-meta {
    margin-top: 8px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
    color: #555;
}

.quick-create-meta .quick-create-switch {
    color: #1565c0;
    font-weight: 700;
    text-decoration: underline;
    cursor: pointer;
}

.quick-create-meta .quick-create-pollen {
    margin-top: 2px;
}

/* Toggle Switch */
.toggle-switch {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
}

.toggle-switch input {
    display: none;
}

.toggle-slider {
    width: 44px;
    height: 24px;
    background: #fff;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.15);
    border-radius: 24px;
    position: relative;
    transition: background 0.3s;
    border: 2px solid #000;
}

.toggle-slider::before {
    content: '';
    position: absolute;
    width: 18px;
    height: 18px;
    background: #ddd;
    border-radius: 50%;
    top: 1px;
    left: 2px;
    transition: transform 0.3s;
    border: 1px solid #000;
}

.toggle-switch input:checked+.toggle-slider {
    background: var(--accent-color);
}

.toggle-switch input:checked+.toggle-slider::before {
    background: #fff;
}

.toggle-switch input:checked+.toggle-slider::before {
    transform: translateX(20px);
}

.toggle-label {
    font-weight: bold;
}

/* Style Preview */
.style-preview-container {
    width: 60px;
    height: 45px;
    border: 2px solid #000;
    border-radius: 4px;
    overflow: hidden;
    background: #f0f0f0;
}

.style-preview-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.panel-input-group {
    margin-bottom: 1rem;
    border-left: 5px solid var(--accent-color);
    padding-left: 10px;
}

.panel-input-group label {
    font-weight: bold;
    display: block;
}

/* Panel Layout Preview next to story textarea */
.idea-layout-row {
    display: flex;
    gap: 15px;
    align-items: stretch;
}

.rough-story-area {
    flex: 1;
    min-height: 250px;
}

.layout-tools {
    width: 220px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-self: stretch;
}

.layout-template-select {
    width: 100%;
    padding: 8px 10px;
    border: 2px solid #000;
    border-radius: 6px;
    background: #ffd84d;
    color: #111;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    cursor: pointer;
}

.panel-layout-preview {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-flow: dense;
    grid-auto-rows: 40px;
    gap: 3px;
    width: 100%;
    padding: 6px;
    background: #f5f5f5;
    border: 2px solid #000;
    border-radius: 6px;
    align-content: start;
    direction: ltr;
}

.panel-layout-preview-box {
    min-height: 36px;
    border: 1.5px solid #000;
    border-radius: 3px;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Bangers', cursive;
    font-size: 0.75rem;
    color: #333;
}

.panel-layout-preview-box.hero-box {
    background: #ffe07a;
    border-color: #9b6a00;
}

.panel-layout-preview-box.cut-corner {
    clip-path: polygon(0 0, 88% 0, 100% 18%, 100% 100%, 0 100%);
}

.panel-layout-preview-box.diagonal-left {
    clip-path: polygon(0 8%, 100% 0, 100% 100%, 0 92%);
}

.panel-layout-preview-box.diagonal-right {
    clip-path: polygon(0 0, 100% 8%, 100% 92%, 0 100%);
}

.panel-count-controls {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 6px;
    position: relative;
}

.panel-count-split {
    display: flex;
    align-items: center;
    padding: 0;
    width: 54px;
    height: 28px;
    border: 2px solid #000;
    border-radius: 6px;
    background: #fff6cc;
    color: #111;
    cursor: pointer;
    overflow: hidden;
}

.panel-count-split-plus {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Comic Neue', cursive;
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1;
}

.panel-count-split-arrow {
    width: 16px;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    border-left: 1.5px solid #000;
    font-family: 'Comic Neue', cursive;
    font-size: 0.7rem;
    font-weight: 700;
    line-height: 1;
}

.panel-count-split:hover {
    background: #ffd84d;
}

.panel-count-menu {
    position: absolute;
    top: 30px;
    left: 0;
    z-index: 10;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
    min-width: 110px;
    padding: 6px;
    border: 2px solid #000;
    border-radius: 6px;
    background: #fff;
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.12);
}

.panel-count-option {
    border: 1.5px solid #000;
    border-radius: 4px;
    background: #fff;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 0.8rem;
    padding: 3px 0;
    cursor: pointer;
}

.panel-count-option:hover,
.panel-count-option.active {
    background: #ffd84d;
}

@media (max-width: 860px) {
    .idea-layout-row {
        flex-direction: column;
    }

    .layout-tools {
        width: 100%;
    }
}

.loading-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(12, 16, 30, 0.55);
    backdrop-filter: blur(3px);
    z-index: 5000;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 20px;
    box-sizing: border-box;
}

.loading-overlay.active {
    display: flex;
}

#loadingText {
    font-family: 'Comic Neue', cursive;
    font-size: 1.05rem;
    font-weight: 700;
    color: #fff;
    text-align: center;
    margin: 0.3rem 0 0.2rem;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
    max-width: min(92vw, 760px);
}

.spinner {
    width: 50px;
    height: 50px;
    border: 5px solid #ccc;
    border-top: 5px solid #000;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin-bottom: 1rem;
}

@keyframes spin {
    0% {
        transform: rotate(0deg);
    }

    100% {
        transform: rotate(360deg);
    }
}

input[type="text"]#storyTitle {
    width: 100%;
    font-size: 1.3rem;
    padding: 10px;
    margin-bottom: 1rem;
    border: 3px solid #000;
    font-family: 'Bangers', cursive;
}

/* Panel Actions */
.panel-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.delete-story-btn {
    background: transparent;
    border: none;
    font-size: 1.2rem;
    cursor: pointer;
    opacity: 0.6;
    transition: opacity 0.2s;
    padding: 0 5px;
}

.delete-story-btn:hover {
    opacity: 1;
    transform: scale(1.1);
}

/* --- STORY LIST STYLES --- */
#storyList {
    list-style: none;
    padding: 0;
    margin: 0;
}

#storyList li {
    margin-bottom: 10px;
}

#storyList li a {
    display: block;
    background: linear-gradient(135deg, #ffcc00 0%, #ffdd44 50%, #ffcc00 100%);
    color: #000;
    padding: 12px 15px;
    border: 3px solid #000;
    box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.3);
    font-family: 'Bangers', cursive;
    font-size: 1.1rem;
    text-decoration: none;
    letter-spacing: 1px;
    transition: all 0.2s ease;
    position: relative;
    overflow: hidden;
}

#storyList li a::before {
    content: '📖 ';
}

#storyList li a:hover {
    background: linear-gradient(135deg, #fff176 0%, #ffee58 50%, #fff176 100%);
    transform: translateX(5px) scale(1.02);
    box-shadow: 6px 6px 0px rgba(0, 0, 0, 0.4);
}

#storyList li a.active,
#storyList li a:active {
    background: linear-gradient(135deg, #000 0%, #333 100%);
    color: var(--accent-color);
    box-shadow: 2px 2px 0px rgba(0, 0, 0, 0.5);
    transform: translateX(3px);
}

.delete-story-btn {
    background: rgba(255, 0, 0, 0.1);
    border: 2px solid #c62828;
    border-radius: 4px;
    font-size: 1rem;
    cursor: pointer;
    opacity: 0.7;
    transition: all 0.2s;
    padding: 4px 8px;
    margin-left: 8px;
}

.delete-story-btn:hover {
    opacity: 1;
    background: #c62828;
    color: white;
    transform: scale(1.1);
}

/* Story Sidebar Container */
.story-sidebar {
    background: #fff;
    border: 3px solid #000;
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
    padding: 15px;
}

.story-sidebar h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.5rem;
    margin: 0 0 15px 0;
    padding-bottom: 10px;
    border-bottom: 3px solid var(--accent-color);
    text-transform: uppercase;
    letter-spacing: 2px;
}

/* Trash page styles */
.trash-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 20px;
    padding: 20px;
}

.trash-item {
    background: #fff;
    border: 3px solid #000;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.2);
    padding: 10px;
}

.trash-item img {
    width: 100%;
    height: auto;
    display: block;
}

.trash-item-actions {
    display: flex;
    gap: 8px;
    margin-top: 10px;
}

.trash-item-actions button {
    flex: 1;
    padding: 8px;
    border: 2px solid #000;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    cursor: pointer;
}

.restore-btn {
    background: #e8f5e9;
}

.restore-btn:hover {
    background: #4CAF50;
    color: white;
}

.perm-delete-btn {
    background: #ffebee;
}

.perm-delete-btn.is-armed {
    background: #c0392b;
    color: #fff;
}

.perm-delete-btn:hover {
    background: #c62828;
    color: white;
}

.trash-empty {
    text-align: center;
    padding: 60px 20px;
    font-family: 'Comic Neue', cursive;
    font-size: 1.3rem;
    color: #666;
}

.trash-filename {
    font-size: 0.75rem;
    color: #666;
    margin-top: 8px;
    word-break: break-all;
}

/* Modal Actions */
.modal-actions {
    display: flex;
    gap: 10px;
    margin-bottom: 10px;
}

.secondary-btn {
    background: #f5f5f5;
    border: 2px solid #000;
    padding: 10px 20px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    cursor: pointer;
}

.secondary-btn:hover {
    background: #e0e0e0;
}

/* Modal Tabs */
.modal-tabs {
    display: inline-flex;
    gap: 0;
    margin-bottom: 15px;
    background: #e0e0e0;
    border-radius: 20px;
    padding: 3px;
}

.modal-tab {
    padding: 6px 16px;
    background: transparent;
    border: none;
    border-radius: 17px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s ease;
    color: #666;
}

.modal-tab.active {
    background: #000;
    color: #fff;
}

.modal-tab:hover:not(.active) {
    background: rgba(0, 0, 0, 0.1);
    color: #333;
}

.tab-content {
    display: none;
}

.tab-content.active {
    display: block;
}

/* Regenerate Modal Styling */
.regen-modal .input-group {
    margin-bottom: 15px;
}

.regen-modal .input-group label {
    display: block;
    margin-bottom: 6px;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    font-weight: bold;
    color: #333;
}

.regen-modal textarea,
.regen-modal .modal-select {
    width: 100%;
    padding: 10px;
    border: 2px solid #ccc;
    border-radius: 4px;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    background: #fff;
    transition: border-color 0.2s ease;
}

.regen-modal textarea:focus,
.regen-modal .modal-select:focus {
    outline: none;
    border-color: #000;
}

.regen-modal #promptInput {
    height: 120px;
    resize: vertical;
}

.regen-modal #stylePromptInput {
    height: 60px;
    resize: vertical;
}

/* History Grid */
.history-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 15px;
    max-height: 400px;
    overflow-y: auto;
    padding: 5px;
}

.history-item {
    background: #fff;
    border: 3px solid #000;
    border-radius: 8px;
    overflow: hidden;
    cursor: pointer;
    transition: all 0.2s ease;
}

.history-item:hover {
    transform: translateY(-3px);
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.2);
    border-color: var(--accent-color);
}

.history-thumbnail {
    width: 100%;
    height: 120px;
    object-fit: cover;
    border-bottom: 2px solid #000;
    background: #f0f0f0;
}

.history-info {
    padding: 10px;
}

.history-date {
    font-size: 0.75rem;
    color: #666;
    margin-bottom: 5px;
}

.history-prompt {
    font-size: 0.85rem;
    color: #333;
    font-family: 'Comic Neue', cursive;
    line-height: 1.3;
    max-height: 50px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.history-empty {
    color: #666;
    font-style: italic;
    text-align: center;
    padding: 40px 20px;
    grid-column: 1 / -1;
}

/* Story Details Section */

/* Remove outer border from sidebar - keep only inner section borders */
.story-sidebar {
    border: none !important;
    box-shadow: none !important;
    background: transparent;
}

/* Stories Section - separated from buttons */
.stories-section {
    background: #fff;
    border: 3px solid #000;
    padding: 15px;
    margin-bottom: 15px;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.2);
    width: 100%;
    box-sizing: border-box;
}

.stories-section h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.4rem;
    margin: 0 0 10px 0;
    color: #333;
    border-bottom: 3px solid var(--accent-color);
    padding-bottom: 8px;
}

.sidebar-actions {
    background: #fff;
    border: 3px solid #000;
    padding: 15px;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.2);
}

/* Sidebar Selectors (Model & Style) */
.story-meta-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: nowrap;
}

.viewer-controls-right {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 15px;
    margin-left: auto;
    flex-wrap: wrap;
}

.panel-action-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 4px 0 8px;
    flex-wrap: wrap;
}

.panel-actions-left,
.panel-actions-right {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.style-action-group {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.panel-action-bar .style-selector {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 0;
}

.panel-action-bar .style-selector label {
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    font-weight: 700;
}

.panel-action-bar .style-selector select {
    min-width: 170px;
    min-height: 36px;
    padding: 6px 24px 6px 10px;
    background: linear-gradient(135deg, #fffef7 0%, #fff6cf 100%);
    border-radius: 10px;
    border: 2px solid #000;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    font-weight: 700;
}

body.slides-view-active .panel-action-bar .style-selector select {
    width: 11ch;
    max-width: 11ch;
    min-width: 11ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.panel-action-bar .delete-style-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 0;
    background: transparent;
    color: #111;
    padding: 4px 2px;
    cursor: pointer;
    font-size: 1.15rem;
    line-height: 1;
    box-shadow: none;
}

.panel-action-bar .delete-style-btn:hover {
    transform: translateY(-1px);
    color: #b71c1c;
}

/* The rebuild selector reuses the style selector's chrome — same control, other
   axis: styles are how the comic is drawn, rebuilds are whose version it is.
   Slides view squeezes the style dropdown to 11ch, which is fine for a style
   name but cuts "Rebuild by …" down to "Re…" — a version that names nobody. */
body.slides-view-active .panel-action-bar .rebuild-selector select {
    width: 20ch;
    max-width: 20ch;
    min-width: 20ch;
}

/* A small text action, not an icon: "Default" appears only while the shown
   version is NOT the default; the state itself lives on the select's tint
   (.is-default-version below). */
.panel-action-bar .set-default-rebuild-btn {
    font-family: 'Comic Neue', cursive;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 2px 7px;
    opacity: 0.75;
}

/* The selected option IS the default — say it with colour, quietly. */
.rebuild-selector select.is-default-version {
    background: #fff3c4;
    border-color: #d9a400;
}

.panel-action-bar .set-default-rebuild-btn:hover {
    transform: translateY(-1px);
    filter: none;
    opacity: 1;
    color: #111;
}

/* (kept for markup compatibility; the button hides when already default) */
.panel-action-bar .set-default-rebuild-btn.is-default {
    filter: none;
    opacity: 1;
    cursor: default;
}

.panel-action-bar .set-default-rebuild-btn.is-default:hover {
    transform: none;
}


.viewer-controls-right .style-selector {
    display: flex;
    align-items: center;
    gap: 8px;
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
    box-shadow: none;
}

.viewer-controls-right .style-selector label {
    font-family: 'Bangers', cursive;
    font-size: 1rem;
    letter-spacing: 0.5px;
    color: #111;
    white-space: nowrap;
    margin: 0;
}

.viewer-controls-right .style-selector select {
    padding: 6px 10px;
    border: 2px solid #000;
    border-radius: 16px;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 0.9rem;
    background: linear-gradient(135deg, #fffef7 0%, #fff6cf 100%);
    cursor: pointer;
    min-width: 170px;
}

.viewer-controls-right .style-selector select:focus {
    outline: none;
    box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.35);
}

.viewer-controls-right .delete-style-btn {
    border: none;
    border-radius: 6px;
    background: #d32f2f;
    color: #fff;
    padding: 7px 10px;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
}

.viewer-controls-right .delete-style-btn:hover {
    background: #b71c1c;
    transform: translateY(-1px);
}

.owner-preview-card {
    margin-top: 8px;
    margin-bottom: 4px;
    width: min(650px, 100%);
    background: #fff;
    border: 3px solid #000;
    border-radius: 10px;
    overflow: hidden;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.18);
}

.owner-preview-image-wrap {
    position: relative;
    width: 100%;
    height: 210px;
    background: #f4f4f4;
}

.owner-preview-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: 50% 50%;
}

.owner-preview-pan.image-pan-handle {
    z-index: 31;
    opacity: 1;
    font-size: 0;
    color: transparent;
}

.owner-preview-card-content {
    padding: 10px 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}

.owner-preview-title {
    font-family: 'Bangers', cursive;
    font-size: 1.25rem;
    margin: 0;
    color: #000;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

.owner-preview-meta {
    display: flex;
    gap: 10px;
    color: #666;
    font-size: 0.95rem;
    flex-shrink: 0;
}

.sidebar-selectors .model-selector,
.sidebar-selectors .style-selector {
    margin-bottom: 10px;
    width: 100%;
}

.sidebar-selectors .model-selector select,
.sidebar-selectors .style-selector select {
    width: 100%;
    padding: 8px;
    margin-top: 5px;
}

/* Prominent Story Title */
.story-title {
    font-family: 'Bangers', cursive;
    font-size: 2.5rem;
    color: #000;
    text-shadow: 3px 3px 0 var(--accent-color);
    margin: 30px 0 20px 0;
    padding: 15px 0;
    border-bottom: 4px solid #000;
    text-transform: uppercase;
    letter-spacing: 2px;
}

.toggle-details-btn {
    background: #222;
    color: white;
    border: 2px solid #000;
    padding: 6px 10px;
    min-height: 36px;
    line-height: 1.1;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
    transition: all 0.2s ease;
    white-space: nowrap;
    border-radius: 10px;
}

.toggle-details-btn:hover {
    transform: translateY(-2px);
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.3);
}

#toggleDetailsBtn,
#togglePreviewCardBtn {
    background: #fff;
    color: #111;
    position: relative;
    padding-right: 34px;
}

#toggleDetailsBtn::after,
#togglePreviewCardBtn::after {
    content: '';
    position: absolute;
    right: 10px;
    top: 50%;
    width: 16px;
    height: 16px;
    border-radius: 999px;
    border: 2px solid #000;
    background: #ddd;
    transform: translateY(-50%);
}

#toggleDetailsBtn.active,
#togglePreviewCardBtn.active {
    background: linear-gradient(135deg, #fffef7 0%, #fff6cf 100%);
}

#toggleDetailsBtn.active::after,
#togglePreviewCardBtn.active::after {
    background: #ffd84d;
}


/* Speech Bubble Wrapper */
.speech-bubble-wrapper {
    position: absolute;
    z-index: 100;
    cursor: move;
    user-select: none;
    -webkit-user-select: none;
}

/* Bubble Delete Button */
.speech-bubble-wrapper .bubble-delete-btn {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(50%, -50%);
    width: 20px;
    height: 20px;
    background: #c62828;
    color: white;
    border: 2px solid #fff;
    border-radius: 50%;
    font-size: 14px;
    font-weight: bold;
    cursor: pointer !important;
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    padding: 0;
    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
    transition: opacity 0.2s ease, visibility 0.2s ease;
    z-index: 200;
    opacity: 0;
    visibility: hidden;
    pointer-events: auto;
    user-select: none;
    -webkit-user-select: none;
}

.speech-bubble-wrapper:hover .bubble-delete-btn {
    opacity: 1;
    visibility: visible;
}

.speech-bubble-wrapper .bubble-delete-btn:hover {
    background: #f44336;
    transform: translate(50%, -50%) scale(1.1);
}

/* Speech Bubble Base Styles */
.speech-bubble {
    position: relative;
    background: white;
    border: 3px solid #000;
    border-radius: 15px;
    padding: 10px 15px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 0.9rem;
    max-width: 200px;
    min-width: 60px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
    z-index: 1;
}

.speech-bubble:focus {
    outline: 2px dashed var(--accent-color);
    outline-offset: 2px;
    cursor: text;
    user-select: text;
    -webkit-user-select: text;
}

.speech-bubble[contenteditable="true"] {
    cursor: text;
    user-select: text;
    -webkit-user-select: text;
}

.speech-bubble::after {
    content: '';
    position: absolute;
    bottom: -15px;
    left: 20px;
    border-width: 15px 10px 0;
    border-style: solid;
    border-color: #000 transparent transparent;
}

.speech-bubble::before {
    content: '';
    position: absolute;
    bottom: -10px;
    left: 22px;
    border-width: 12px 8px 0;
    border-style: solid;
    border-color: white transparent transparent;
    z-index: 1;
}

/* Per-Panel Text Controls */
.panel-text-controls {
    position: absolute;
    bottom: 10px;
    left: 10px;
    display: flex;
    gap: 5px;
    opacity: 0;
    transition: opacity 0.2s ease;
    z-index: 50;
}

.panel:hover .panel-text-controls {
    opacity: 1;
}

.panel-text-btn {
    width: 32px;
    height: 32px;
    border: 2px solid #000;
    background: #fff;
    border-radius: 5px;
    cursor: pointer;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
}

.panel-text-btn:hover {
    background: #f0f0f0;
    transform: translateY(-2px);
}

.panel-text-btn.active {
    background: var(--accent-color);
    box-shadow: inset 2px 2px 4px rgba(0, 0, 0, 0.2);
}

.panel-lock-btn {
    width: 32px;
    height: 32px;
    border: 2px solid #000;
    background: #4CAF50;
    color: white;
    border-radius: 5px;
    cursor: pointer;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
}

.panel-lock-btn:hover {
    background: #43a047;
    transform: translateY(-2px);
}

.panel-lock-btn.hidden {
    display: none;
}

/* New Panel Control Buttons */
.add-caption-btn,
.edit-caption-btn,
.delete-caption-btn,
.add-bubble-btn,
.ai-bubble-btn,
.ai-bubble-crazy-btn {
    width: 32px;
    height: 32px;
    border: 2px solid #000;
    background: #fff;
    border-radius: 5px;
    cursor: pointer;
    font-size: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
}

/* Panel Info Button - Top Left */
.panel-info-btn {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 28px;
    height: 28px;
    border: 2px solid #000;
    background: #2196F3;
    color: white;
    border-radius: 50%;
    cursor: pointer;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
    z-index: 20;
    opacity: 0;
}

.panel:hover .panel-info-btn,
.panel.tapped .panel-info-btn {
    opacity: 1;
}

.panel-info-btn:hover {
    transform: scale(1.1);
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.3);
}

/* Image Pan Handle - Centered */
.image-pan-handle {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 40px;
    height: 40px;
    background: rgba(255, 255, 255, 0.3);
    border: 2px solid rgba(255, 255, 255, 0.8);
    border-radius: 50%;
    cursor: move;
    z-index: 30;
    opacity: 0;
    transition: opacity 0.2s, background 0.2s;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
    font-size: 0;
    color: transparent;
}

.panel:hover .image-pan-handle,
.panel.tapped .image-pan-handle {
    opacity: 1;
}

.image-pan-handle:hover,
.image-pan-handle.active {
    background: rgba(255, 255, 255, 0.6);
    border-color: #fff;
}

/* Icon inside handle */
.image-pan-handle::after {
    content: '✥';
    color: #333;
    font-size: 24px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-shadow: 0 0 2px rgba(255, 255, 255, 0.8);
}

.add-caption-btn,
.add-bubble-btn {
    position: relative;
}

.add-caption-btn::after,
.add-bubble-btn::after {
    content: '+';
    position: absolute;
    bottom: -2px;
    right: -2px;
    width: 14px;
    height: 14px;
    background: #4caf50;
    color: white;
    font-size: 12px;
    font-weight: bold;
    line-height: 12px;
    text-align: center;
    border-radius: 50%;
    border: 1px solid #fff;
    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.3);
}

.add-caption-btn {
    background: #fff;
}

.add-bubble-btn {
    background: #e3f2fd;
}

.ai-bubble-btn {
    background: #e8f5e9;
}

.ai-bubble-crazy-btn {
    background: #fff3e0;
}

.ai-bubble-btn:disabled,
.ai-bubble-crazy-btn:disabled {
    opacity: 0.6;
    cursor: wait;
}

.bubble-loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.55);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    z-index: 50;
    border-radius: inherit;
}

.bubble-loading-spinner {
    width: 40px;
    height: 40px;
    border: 4px solid rgba(255, 255, 255, 0.3);
    border-top: 4px solid #fff;
    border-radius: 50%;
    animation: spin 0.8s linear infinite;
    margin-bottom: 10px;
}

.bubble-loading-text {
    color: #fff;
    font-family: 'Comic Neue', cursive;
    font-size: 14px;
    font-weight: bold;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.panel-info-btn:hover,
.add-caption-btn:hover,
.edit-caption-btn:hover,
.delete-caption-btn:hover,
.add-bubble-btn:hover,
.ai-bubble-btn:hover,
.ai-bubble-crazy-btn:hover {
    transform: translateY(-2px);
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.3);
}

.delete-caption-btn:hover {
    background: #ffcdd2;
}

.add-caption-btn.hidden,
.edit-caption-btn.hidden,
.delete-caption-btn.hidden {
    display: none;
}

/* Speech bubbles container */
.speech-bubbles-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.speech-bubbles-container .speech-bubble {
    pointer-events: auto;
}


/* Panel info modal */
.panel-info-modal {
    text-align: left;
    background: #e0e0e0;
    padding: 15px;
    border-radius: 8px;
}

.panel-info-modal h3 {
    margin-top: 0;
    font-family: 'Bangers', cursive;
    color: #333;
}

.panel-info-modal .info-section {
    margin-bottom: 15px;
}

.panel-info-modal .info-section strong {
    display: block;
    margin-bottom: 5px;
    color: #222;
}

.panel-info-modal .info-section p {
    margin: 0;
    padding: 10px;
    background: #fff;
    border-radius: 5px;
    font-size: 0.9rem;
    border: 1px solid #ccc;
}

.panel-info-modal .info-section ul {
    margin: 0;
    padding: 10px 10px 10px 30px;
    background: #fff;
    border-radius: 5px;
    border: 1px solid #ccc;
}

.panel-lock-btn.locked {
    background: #c62828;
    /* Red for locked */
}

.panel-lock-btn.locked:hover {
    background: #b71c1c;
}

.set-preview-btn {
    width: 32px;
    height: 32px;
    border: 2px solid #000;
    background: #fff;
    border-radius: 5px;
    cursor: pointer;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    transition: all 0.15s ease;
}

.set-preview-btn:hover {
    background: #e3f2fd;
    transform: translateY(-2px);
}

.set-preview-btn.active {
    background: #2196F3;
    color: #fff;
    box-shadow: inset 2px 2px 4px rgba(0, 0, 0, 0.2);
}

/* --- STORY TRANSCRIPT (the comic as text, under its panels) --- */
/* Collapsed by default: closed, it is one quiet line under the comic; the
   box appears only once a reader opens it. */
.story-transcript {
    margin: 28px auto 0;
    max-width: 860px;
    font-family: 'Comic Neue', cursive;
    color: #222;
    line-height: 1.55;
}

.story-transcript[hidden] {
    display: none;
}

.story-transcript-details[open] {
    background: #fff;
    border: 3px solid #000;
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.15);
    padding: 16px 24px 20px;
}

.story-transcript summary {
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: #555;
}

.story-transcript summary::-webkit-details-marker {
    display: none;
}

.story-transcript summary::before {
    content: '▸';
    font-size: 0.9rem;
    transition: transform 0.15s ease;
}

.story-transcript-details[open] summary::before {
    transform: rotate(90deg);
}

.story-transcript summary:hover,
.story-transcript summary:focus-visible {
    color: #000;
}

.story-transcript summary h2 {
    display: inline;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 0.95rem;
    margin: 0;
}

.story-transcript-details[open] summary {
    color: #000;
    margin-bottom: 8px;
}

.story-transcript-details[open] summary h2 {
    font-family: 'Bangers', cursive;
    font-weight: normal;
    font-size: 1.5rem;
    letter-spacing: 1px;
    text-shadow: 2px 2px 0 var(--accent-color);
}

.story-transcript h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    letter-spacing: 1px;
    margin: 18px 0 8px;
    border-bottom: 3px solid var(--accent-color);
    display: inline-block;
    padding-right: 12px;
}

.story-transcript-byline {
    margin: 0 0 6px;
    color: #555;
}

.story-transcript-idea {
    margin: 0;
}

.story-transcript-panels {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    gap: 12px;
}

.story-transcript-panel {
    border-left: 4px solid var(--accent-color);
    padding: 2px 0 2px 14px;
}

.story-transcript-panel h4 {
    margin: 0 0 4px;
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.story-transcript-panel p {
    margin: 0 0 4px;
}

.story-transcript-scene {
    color: #444;
}

.story-transcript-line {
    font-weight: 700;
}

.story-transcript-label {
    font-weight: 700;
    color: #666;
}

@media (max-width: 640px) {
    .story-transcript {
        margin-top: 20px;
    }

    .story-transcript-details[open] {
        padding: 14px 16px 16px;
    }
}

.story-details {
    background: #fff;
    border: 3px solid #000;
    margin-bottom: 20px;
    /* Space above grid */
    padding: 20px;
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.2);
}

.story-section {
    margin-bottom: 20px;
}

.story-section:last-child {
    margin-bottom: 0;
}

.story-section h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.3rem;
    margin: 0 0 10px 0;
    color: #000;
    text-shadow: 2px 2px 0 var(--accent-color);
}

.enhanced-story-content {
    font-family: 'Comic Neue', cursive;
    line-height: 1.6;
    color: #333;
    max-height: 200px;
    overflow-y: auto;
    padding: 10px;
    background: #f9f9f9;
    border: 2px solid #ddd;
}

.enhanced-story-content p {
    margin: 0 0 10px 0;
}

.panel-prompts-content {
    max-height: 300px;
    overflow-y: auto;
}

.prompt-item {
    background: #f5f5f5;
    border: 2px solid #ddd;
    padding: 10px;
    margin-bottom: 10px;
}

.prompt-label {
    font-family: 'Bangers', cursive;
    font-size: 1rem;
    color: var(--accent-color);
    margin-bottom: 5px;
}

.prompt-text {
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    color: #555;
    line-height: 1.4;
}

.no-content {
    color: #999;
    font-style: italic;
}

/* Input Groups */
.input-group {
    margin-bottom: 15px;
}

.input-group label {
    display: block;
    margin-bottom: 5px;
    font-family: 'Bangers', cursive;
    color: #333;
}

.input-group textarea {
    width: 100%;
    padding: 10px;
    border: 2px solid #ccc;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    resize: vertical;
}

.style-input-group {
    flex-grow: 1;
    margin: 0 10px;
}

.style-input-group label {
    display: block;
    font-family: 'Bangers', cursive;
    color: #333;
    margin-bottom: 2px;
}

.style-input-group textarea {
    width: 100%;
    padding: 8px;
    border: 3px solid #000;
    font-family: 'Comic Neue', cursive;
    border-radius: 4px;
}

.final-actions {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    margin-top: 20px;
    flex-wrap: wrap;
}

/* --- SPEECH BUBBLES (Slides/Export View Only) --- */
/* Note: .panel-image-wrapper has overflow:hidden for images, 
   but bubbles use high z-index and stay within bounds via JS clamping */

.slides-content .speech-bubble,
.print-bubbles-container .speech-bubble {
    position: absolute;
    background: white;
    border: 3px solid black;
    border-radius: 20px;
    padding: 10px 15px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 1rem;
    text-align: center;
    color: black;
    z-index: 200;
    /* Higher than controls so always visible */
    min-width: 80px;
    max-width: 220px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.2);
    cursor: move;
    user-select: none;
    /* Default position - overridden by JS */
    top: 15%;
    left: 50%;
    transform: translateX(-50%);
}

.speech-bubble:hover {
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.3);
    z-index: 60;
}

.speech-bubble:focus {
    outline: 2px dashed #ff9800;
    background: #fffDE7;
    cursor: text;
    user-select: text;
}

/* Tail for bubble - simplified */
.speech-bubble::before {
    content: '';
    position: absolute;
    bottom: -15px;
    left: 20px;
    border-width: 15px 10px 0;
    border-style: solid;
    border-color: black transparent;
    display: block;
    width: 0;
}

.speech-bubble::after {
    content: '';
    position: absolute;
    bottom: -10px;
    left: 23px;
    border-width: 13px 7px 0;
    border-style: solid;
    border-color: white transparent;
    display: block;
    width: 0;
}



/* ============================================
   CONFIRMATION DIALOG (replaces browser confirm/alert)
   ============================================ */
.confirm-dialog {
    display: none;
    position: fixed;
    z-index: 3000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    align-items: center;
    justify-content: center;
    animation: fadeIn 0.2s ease;
}

.confirm-dialog.active {
    display: flex;
}

.confirm-dialog-content {
    background-color: #fff;
    padding: 2rem;
    border: 4px solid #000;
    width: 90%;
    max-width: 450px;
    box-shadow: 10px 10px 0px var(--accent-color);
    font-family: 'Comic Neue', cursive;
    text-align: center;
    animation: slideUp 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@media (max-width: 600px) {
    .confirm-dialog-content {
        padding: 1.5rem;
        box-shadow: 5px 5px 0px var(--accent-color);
    }
}

@keyframes slideUp {
    from {
        opacity: 0;
        transform: translateY(30px) scale(0.95);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.confirm-dialog-icon {
    font-size: 3rem;
    margin-bottom: 1rem;
}

.confirm-dialog-icon.warning {
    color: #ff9800;
}

.confirm-dialog-icon.error {
    color: #f44336;
}

.confirm-dialog-icon.success {
    color: #4CAF50;
}

.confirm-dialog-icon.info {
    color: #2196f3;
}

.confirm-dialog-title {
    font-family: 'Bangers', cursive;
    font-size: 1.5rem;
    margin-bottom: 0.5rem;
    letter-spacing: 1px;
}

.confirm-dialog-message {
    font-size: 1.1rem;
    margin-bottom: 1.5rem;
    line-height: 1.5;
    color: #555;
}

.confirm-dialog-buttons {
    display: flex;
    gap: 1rem;
    justify-content: center;
}

.confirm-dialog-btn {
    padding: 12px 24px;
    font-family: 'Bangers', cursive;
    font-size: 1.1rem;
    border: 3px solid #000;
    cursor: pointer;
    transition: all 0.2s ease;
}

.confirm-dialog-btn.primary {
    background: #000;
    color: #fff;
}

.confirm-dialog-btn.primary:hover {
    background: var(--accent-color);
    color: #000;
    transform: scale(1.05);
}

.confirm-dialog-btn.secondary {
    background: #fff;
    color: #000;
}

.confirm-dialog-btn.secondary:hover {
    background: #eee;
    transform: scale(1.05);
}

.confirm-dialog-btn.danger {
    background: #f44336;
    color: #fff;
    border-color: #c62828;
}

.confirm-dialog-btn.danger:hover {
    background: #c62828;
    transform: scale(1.05);
}

/* ============================================
   SETTINGS MODAL
   ============================================ */
.settings-btn {
    position: fixed;
    top: var(--toprail-top);
    right: 20px;
    background: #fff;
    border: 3px solid #000;
    width: var(--toprail-size);
    height: var(--toprail-size);
    border-radius: 50%;
    font-size: 1.5rem;
    cursor: pointer;
    z-index: 900;
    box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.2);
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
}

.settings-btn:hover {
    background: var(--accent-color);
    transform: rotate(45deg) scale(1.1);
}

.settings-modal {
    display: none;
    position: fixed;
    z-index: 2500;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    align-items: center;
    justify-content: center;
}

.settings-modal.active {
    display: flex;
}

.settings-modal-content {
    background-color: #fff;
    padding: 2rem;
    border: 4px solid #000;
    width: 90%;
    max-width: 500px;
    box-shadow: 10px 10px 0px var(--accent-color);
    position: relative;
    font-family: 'Comic Neue', cursive;
    animation: slideUp 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.settings-modal h2 {
    font-family: 'Bangers', cursive;
    margin-top: 0;
    padding-right: 30px;
}

.settings-close {
    position: absolute;
    top: 10px;
    right: 15px;
    font-size: 2rem;
    font-weight: bold;
    cursor: pointer;
    transition: color 0.2s;
}

.settings-close:hover {
    color: #f44336;
}

.settings-section {
    margin-bottom: 1.5rem;
    padding-bottom: 1rem;
    border-bottom: 2px dashed #ddd;
}

.settings-section:last-child {
    border-bottom: none;
    margin-bottom: 0;
}

.settings-section h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    margin-bottom: 0.5rem;
    color: #333;
}

.settings-row {
    margin-bottom: 1rem;
}

.settings-row label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: bold;
    font-size: 0.95rem;
}

.settings-row input[type="text"],
.settings-row input[type="password"] {
    width: 100%;
    padding: 10px;
    border: 2px solid #000;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
}

.settings-row .hint {
    font-size: 0.85rem;
    color: #666;
    margin-top: 0.5rem;
}

.settings-save-btn {
    width: 100%;
    padding: 12px;
    background: #000;
    color: #fff;
    border: none;
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    cursor: pointer;
    transition: all 0.2s;
}

.settings-save-btn:hover {
    background: var(--accent-color);
    color: #000;
}

/* ============================================
   LOGIN MODAL
   ============================================ */
.login-modal {
    display: none;
    position: fixed;
    z-index: 4000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.9);
    align-items: center;
    justify-content: center;
}

.login-modal.active {
    display: flex;
}

.login-modal-content {
    background-color: #fff;
    padding: 2.5rem;
    border: 4px solid #000;
    width: 90%;
    max-width: 400px;
    box-shadow: 10px 10px 0px var(--accent-color);
    font-family: 'Comic Neue', cursive;
    text-align: center;
    animation: slideUp 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

.login-modal h2 {
    font-family: 'Bangers', cursive;
    font-size: 2rem;
    margin-top: 0;
    margin-bottom: 1.5rem;
}

.login-modal .login-icon {
    font-size: 4rem;
    margin-bottom: 1rem;
}

.login-row {
    margin-bottom: 1rem;
    text-align: left;
}

.login-row label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: bold;
}

.login-row input {
    width: 100%;
    padding: 12px;
    border: 2px solid #000;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
}

.login-error {
    color: #f44336;
    font-weight: bold;
    margin-bottom: 1rem;
    display: none;
}

.login-error.visible {
    display: block;
}

.login-btn {
    width: 100%;
    padding: 14px;
    background: #000;
    color: #fff;
    border: none;
    font-family: 'Bangers', cursive;
    font-size: 1.3rem;
    cursor: pointer;
    transition: all 0.2s;
    margin-top: 1rem;
}

.login-btn:hover {
    background: var(--accent-color);
    color: #000;
}

/* ============================================
   TOGGLE CAPTIONS BUTTON
   ============================================ */
.toggle-captions-btn {
    width: 100%;
    background-color: #2196f3;
    color: white;
    border: none;
    padding: 10px;
    cursor: pointer;
    font-family: 'Bangers', cursive;
    font-size: 1.1rem;
    border-radius: 5px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-top: 10px;
    transition: background 0.2s;
}

.toggle-captions-btn:hover {
    background-color: #1565c0;
}

.toggle-captions-btn.active {
    background-color: #4CAF50;
    box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.3);
}

/* ============================================
   TEXT OVERLAY BUTTON GROUP
   ============================================ */
.text-overlay-group {
    display: flex;
    gap: 5px;
    margin-top: 10px;
}

.overlay-btn {
    flex: 1;
    background-color: #888;
    color: #ccc;
    border: 2px solid #666;
    padding: 12px 8px;
    cursor: pointer;
    font-family: 'Bangers', cursive;
    font-size: 1rem;
    border-radius: 5px;
    transition: all 0.2s ease;
    opacity: 0.6;
}

.overlay-btn:hover {
    opacity: 0.8;
    transform: scale(1.02);
}

.overlay-btn.active {
    opacity: 1;
    color: white;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.overlay-btn.active[data-mode="captions"] {
    background-color: #2196f3;
    border-color: #1565c0;
}

.overlay-btn.active[data-mode="bubbles"] {
    background-color: #9c27b0;
    border-color: #6a1b9a;
}

.overlay-btn.active[data-mode="none"] {
    background-color: #666;
    border-color: #444;
}

/* ============================================
   FEATURED STORIES SECTION (Index Page)
   ============================================ */
/* --- HOME INTRO (what the site is, between the featured row and the feed) --- */
.home-intro {
    max-width: 1300px;
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 40px;
    padding: 24px 28px;
    background: #fff;
    border: 4px solid #000;
    box-shadow: 8px 8px 0px rgba(0, 0, 0, 0.15);
    font-family: 'Comic Neue', cursive;
    color: var(--text-color);
}

.home-intro h2 {
    font-family: 'Bangers', cursive;
    font-size: clamp(1.5rem, 3.2vw, 2.1rem);
    letter-spacing: 1px;
    margin: 0 0 10px;
    text-shadow: 2px 2px 0 var(--accent-color);
}

.home-intro p {
    font-size: 1.05rem;
    line-height: 1.6;
    margin: 0 0 12px;
}

.home-intro-lead {
    max-width: 920px;
}

.home-intro-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 18px;
    margin: 18px 0;
}

.home-intro-card {
    border: 3px solid #000;
    border-top-width: 8px;
    border-top-color: var(--accent-color);
    padding: 14px 16px 6px;
    background: #fffdf3;
}

.home-intro-card h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.3rem;
    letter-spacing: 1px;
    margin: 0 0 8px;
}

.home-intro-card p {
    font-size: 1rem;
}

.home-intro a {
    color: #000;
    font-weight: 700;
    text-decoration-color: var(--accent-color);
    text-decoration-thickness: 3px;
}

.home-intro-outro {
    margin-bottom: 0 !important;
}

@media (max-width: 860px) {
    .home-intro-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 640px) {
    .home-intro {
        padding: 18px 16px;
        margin-bottom: 28px;
    }
}

.featured-stories-section {
    max-width: 1300px;
    width: 100%;
    margin-bottom: 40px;
    padding: 20px;
    background: #fff;
    border: 4px solid #000;
    box-shadow: 8px 8px 0px rgba(0, 0, 0, 0.15);
}

.featured-stories-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 15px;
    border-bottom: 3px solid #000;
}

.featured-stories-header h2 {
    font-family: 'Bangers', cursive;
    font-size: 2rem;
    margin: 0;
    letter-spacing: 1px;
}

.view-all-link {
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    color: #000;
    text-decoration: none;
    padding: 8px 16px;
    border: 2px solid #000;
    background: var(--accent-color);
    transition: all 0.2s;
}

.view-all-link:hover {
    transform: translateY(-2px);
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2);
}

/* Creation-time rebuild toggle */
.rebuild-option {
    margin-top: 12px;
}

.rebuild-option label,
.rebuild-option span {
    display: flex;
    align-items: center;
    gap: 8px;
    /* Every text-bearing control must request an app font — tests/e2e/
       font-consistency.spec.js fails the build otherwise. */
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    cursor: pointer;
}

.rebuild-option span {
    display: inline;
}

.rebuild-option input[type="checkbox"] {
    width: 18px;
    height: 18px;
    /* A checkbox's implicit value is "on", which the font-consistency audit
       reads as text — so it needs an app font like any other control. */
    font-family: 'Comic Neue', cursive;
    cursor: pointer;
}

.rebuild-option-hint {
    margin: 4px 0 0 26px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
    color: #555;
}

/* --- Bring Your Own Pollen prompt (create page) --------------------------- */
.byop-prompt {
    margin-top: 10px;
    padding: 12px 14px;
    border: 2px dashed #888;
    border-radius: 8px;
    background: #f9f9f9;
    font-family: 'Comic Neue', cursive;
}

.byop-ask {
    margin: 0 0 8px;
    font-size: 0.9rem;
    color: #333;
}

.byop-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.byop-row input {
    flex: 1;
    min-width: 180px;
    padding: 8px;
    border: 2px solid #000;
    border-radius: 4px;
    font-family: 'Comic Neue', cursive;
}

.byop-status {
    margin: 6px 0 0;
    font-size: 0.85rem;
    color: #555;
    min-height: 1em;
}

.byop-status.is-bad {
    color: #b00020;
    font-weight: 700;
}

.byop-links {
    margin: 8px 0 0;
    font-size: 0.85rem;
}

/* Shown once when a visitor is rebuilding someone else's comic. */
.rebuild-etiquette {
    margin: 0 0 16px;
    padding: 10px 14px;
    border: 3px solid #000;
    border-radius: 8px;
    background: #fff3cd;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    color: #000;
}

/* A panel someone else locked: the controls are gone, so say why. */
.panel-rebuild-locked {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.8rem;
    color: #666;
}

/* The lock note is appended as a direct CHILD of .panel, which is a flex row
   from 600px up. That made it a second flex item competing with
   .panel-image-wrapper (flex: 1), so the image lost the note's width — and
   because the wrapper is aspect-ratio locked, it lost the matching height too:
   a logged-out visitor saw every panel at ~70% (worst measured: 63% at 620px)
   with a white gutter beside it. Locked panels have no side controls to put in
   a row, so stack them and let the note sit under a full-width image. */
.panel-rebuild-locked-panel {
    flex-direction: column;
}

/* Fill the available width at any resolution instead of snapping between
   fixed column counts: the old repeat(4, 1fr) with a 1200px breakpoint left a
   wide gutter on monitors sitting just inside that band. auto-fit collapses
   empty tracks, and minmax()'s 0 floor (rather than the card's min-content)
   is what stops a long title forcing an overflow. */
.featured-stories-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
    gap: 20px;
}

.featured-stories-grid > * {
    min-width: 0;
}

@media (max-width: 500px) {
    .featured-stories-grid {
        grid-template-columns: 1fr;
    }
}

.featured-story-card {
    /* Rendered as <a> — see .story-card. */
    display: block;
    text-decoration: none;
    color: inherit;
    background: #fff;
    border: 3px solid #000;
    border-radius: 8px;
    overflow: hidden;
    transition: transform 0.2s, box-shadow 0.2s;
    cursor: pointer;
}

/* Keyboard users get the same "this one is selected" cue mouse users get from
   :hover — the cards became focusable when they became links. */
.story-card:focus-visible,
.featured-story-card:focus-visible {
    outline: 4px solid #ffc700;
    outline-offset: 3px;
}

.featured-story-card:hover {
    transform: translateY(-5px);
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
}

.featured-story-card-image-wrapper {
    position: relative;
    width: 100%;
    height: 220px;
    overflow: hidden;
}

.featured-story-card-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.featured-story-badge {
    position: absolute;
    top: 5px;
    right: 5px;
    background: #FFD700;
    color: #000;
    padding: 2px 8px;
    border-radius: 3px;
    font-size: 0.65rem;
    font-weight: bold;
}

.featured-story-badge.recent {
    background: #4CAF50;
    color: #fff;
}

.featured-story-card-content {
    padding: 10px 12px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
}

.featured-story-card-title,
.featured-story-card h3,
.featured-story-card-content h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.35rem;
    margin: 0;
    padding: 0;
    color: #000;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    /* A long owner name must not crush the title to a single letter. */
    min-width: 45%;
    border: none !important;
    border-bottom: none !important;
    background: none;
}

.featured-story-card-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 1.05rem;
    color: #666;
    min-width: 0;
}

.featured-story-card-owner {
    max-width: 14ch;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.featured-story-card-views {
    display: flex;
    align-items: center;
    gap: 3px;
}

.featured-stories-loading {
    text-align: center;
    padding: 40px;
    color: #666;
}

.featured-stories-empty {
    text-align: center;
    padding: 30px;
    color: #999;
    font-style: italic;
}

/* Featured stories in sidebar (gallery page) */
.story-sidebar .featured-stories-section {
    max-width: 100%;
    margin-bottom: 20px;
    padding: 15px;
}

.story-sidebar .featured-stories-header h2 {
    font-size: 1.3rem;
}

.story-sidebar .featured-stories-grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
}

@media (max-width: 768px) {
    .story-sidebar .featured-stories-grid {
        grid-template-columns: 1fr;
    }
}


/* Gallery Layout - Side Navigation */
.gallery-layout {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    gap: 20px;
    width: 100%;
    position: relative;
    /* Width of the story-nav gutter. The arrows are pinned to the viewport
       (see .nav-arrow.side-nav), so they no longer size this row themselves —
       .nav-arrow-slot reserves the column for them and the two must agree. */
    --story-nav-width: 112px;
}

/* Ensure main viewer takes central space */
.comic-viewer {
    flex: 1;
    max-width: 1300px;
    /* The arrows are pinned (position: fixed) and take their horizontal place
       from their static position inside this row — and a fixed box does not
       move when the page is scrolled sideways. So the row must never be wider
       than the viewport, or the arrows are pushed off screen with no way to
       reach them.
       Without this, the flex default `min-width: auto` floors the viewer at its
       min-content width: .comic-grid is repeat(auto-fit, minmax(450px, 1fr))
       with a definite max-width: 1300px, so the auto-repeat resolves to TWO
       450px tracks (948px with the 3rem gap) even when the viewport cannot
       hold them. That made the row 112 + 20 + 948 + 20 + 112 = 1212px minimum
       and clipped both arrows off screen everywhere below it — measured at
       1024px: 18px of each 112px arrow visible, document not scrollable.
       Letting the viewer shrink lets the grid resolve to one column instead;
       above 1212px nothing moves. */
    min-width: 0;
}

/* Holds open the gutter the arrow itself no longer occupies: a fixed box
   contributes nothing to the flex row, so without this the comic viewer grows
   into the side space and the arrows land on top of the panels. */
.nav-arrow-slot {
    flex: 0 0 var(--story-nav-width);
}

/* Side Navigation Arrows (pinned to the viewport) */
.nav-arrow.side-nav {
    /* Centred on the VIEWPORT, not on the document flow. These were sticky
       flex items, which made their resting place depend on the header being
       in flow: view mode sets the <header> to display:none, that lifts the
       whole row by the header's height (~150px), and a sticky box can only be
       pushed DOWN from its flow position, never up. So at the top of the page
       edit mode drew the arrows level with the story title while view mode
       drew them at the sticky top:88px, and every Edit/View toggle made them
       jump. Giving both modes the same `top` (the previous attempt) could not
       fix it — sticky only honours `top` once the flow has scrolled past it.
       Nothing in the flow can move a fixed box, so the modes now agree by
       construction. 48px is half of min-height below; :hover owns `transform`,
       so the centring deliberately stays out of it. */
    position: fixed;
    top: calc(50% - 48px);
    transform: none;
    background: #ffcc00;
    color: #111;
    border: 3px solid #000;
    border-radius: 18px;
    width: var(--story-nav-width);
    min-height: 96px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 6px;
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.25);
    z-index: 100;
    flex-shrink: 0;
    transition: all 0.2s ease;
    padding: 10px 8px;
}

.nav-arrow.side-nav svg {
    display: block;
}

.nav-arrow-label {
    display: block;
    text-align: center;
    font-family: 'Bangers', cursive;
    font-size: 0.85rem;
    line-height: 0.95;
    letter-spacing: 0.03em;
}

.nav-arrow.side-nav:hover {
    transform: scale(1.1);
    background: #ffd84d;
    box-shadow: 8px 8px 0px rgba(0, 0, 0, 0.3);
    color: #000;
}

/* View mode only: story arrows recolored. The vertical anchor is deliberately
   NOT redeclared here — a mode-specific `top` is what made the arrows jump. */
body.slides-view-active .nav-arrow.side-nav {
    background: #ffcc00;
    color: #111;
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.25);
}

body.slides-view-active .story-title-left {
    display: none !important;
}

body.slides-view-active .story-title-row {
    justify-content: flex-end;
}

body.slides-view-active .nav-arrow.side-nav:hover {
    transform: scale(1.08);
    background: #ffd84d;
    color: #000;
}

.nav-arrow.side-nav:disabled {
    opacity: 0.3;
    pointer-events: none;
    box-shadow: none;
}

/* Special mode: jump arrows */
.nav-arrow.side-nav.newest,
.nav-arrow.side-nav.oldest {
    background: rgba(255, 245, 200, 0.95);
}

/* Mobile: Move arrows to bottom because side space is limited */
@media (max-width: 800px) {
    .gallery-layout {
        flex-direction: column;
        align-items: center;
    }

    /* Phones stack the arrows above and below the comic, so there is no gutter
       to reserve: drop the slot's box and let the buttons be the flex items
       again, which is what the #prevStoryBtn/#nextStoryBtn order rules below
       reorder. */
    .nav-arrow-slot {
        display: contents;
    }

    .nav-arrow.side-nav {
        position: static;
        /* Back in flow: the viewport pinning and its width are desktop-only.
           A compact centred pill — the full-width 72px bars this used to be
           were the tallest thing on a phone screen. */
        transform: none;
        width: auto;
        min-height: 0;
        border-width: 2px;
        border-radius: 999px;
        margin: 6px auto;
        padding: 5px 14px 5px 10px;
        gap: 4px;
        flex-direction: row;
        box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.25);
    }

    .nav-arrow.side-nav svg {
        width: 20px;
        height: 20px;
    }

    .nav-arrow-label {
        font-size: 0.85rem;
    }

    /* Reorder for mobile: Top arrow (Prev) above, Bottom arrow (Next) below */
    #prevStoryBtn {
        order: -1;
    }

    #nextStoryBtn {
        order: 2;
    }

    .comic-viewer {
        order: 1;
    }
}

/* Legacy wrapper removal backup */
.story-title-wrapper {
    display: none;
}

/* === Panel Progress Indicator === */
/* Text-phase progress: shown while a text model is working (story expansion,
   panel breakdown). Width is driven from the model's measured latency in
   generation.js; the indeterminate variant is used when no measurement
   exists yet, so the bar never implies a duration nobody has observed. */
.text-progress {
    width: min(320px, 80vw);
    height: 8px;
    margin: 14px auto 0;
    background: rgba(0, 0, 0, 0.18);
    border: 2px solid #000;
    border-radius: 6px;
    overflow: hidden;
}

.text-progress-fill {
    height: 100%;
    width: 0;
    background: #ffd93d;
    transition: width 0.2s linear;
}

.text-progress.is-indeterminate .text-progress-fill {
    width: 100%;
    background: repeating-linear-gradient(
        90deg,
        #ffd93d 0 14px,
        rgba(255, 217, 61, 0.35) 14px 28px
    );
    animation: text-progress-slide 1s linear infinite;
}

@keyframes text-progress-slide {
    from { background-position: 0 0; }
    to { background-position: 28px 0; }
}

@media (prefers-reduced-motion: reduce) {
    .text-progress-fill { transition: none; }
    .text-progress.is-indeterminate .text-progress-fill { animation: none; }
}

.panel-progress-container {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin-top: 20px;
    max-width: 400px;
}

.panel-progress-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 5px;
    min-width: 50px;
}

.panel-progress-icon {
    position: relative;
    width: 40px;
    height: 40px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    line-height: 1;
    white-space: nowrap;
    overflow: hidden;
    border: 3px solid #ddd;
    background: #f5f5f5;
    transition: all 0.3s ease;
}

.panel-progress-glyph {
    display: block;
    line-height: 1;
}

/* Completion is a corner badge, so the box only ever holds one glyph. */
.panel-progress-icon.completed .panel-progress-glyph::after {
    content: '✓';
    position: absolute;
    right: 1px;
    bottom: 0;
    font-size: 0.6rem;
    font-weight: bold;
    line-height: 1;
    color: #fff;
    background: #4CAF50;
    border-radius: 50%;
    width: 13px;
    height: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.panel-progress-icon.pending {
    border-color: #ddd;
    background: #f5f5f5;
    color: #999;
}

.panel-progress-icon.generating {
    border-color: #2196F3;
    background: #e3f2fd;
    animation: pulse-blue 1s infinite;
}

.panel-progress-icon.completed {
    border-color: #4CAF50;
    background: #e8f5e9;
    color: #4CAF50;
}

.panel-progress-icon.failed {
    border-color: #f44336;
    background: #ffebee;
    color: #f44336;
}

.panel-progress-label {
    font-family: 'Comic Neue', cursive;
    font-size: 0.75rem;
    color: #666;
    font-weight: bold;
}

.panel-progress-note {
    min-height: 12px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.65rem;
    color: #666;
    text-align: center;
}

.panel-progress-note.fallback {
    color: #ad6800;
    font-weight: bold;
}

@keyframes pulse-blue {

    0%,
    100% {
        box-shadow: 0 0 0 0 rgba(33, 150, 243, 0.4);
    }

    50% {
        box-shadow: 0 0 0 8px rgba(33, 150, 243, 0);
    }
}

.spinner-small {
    display: inline-block;
    animation: spin 1s linear infinite;
}

/* === Story Complete Modal === */
.story-complete-modal {
    max-width: 500px;
    text-align: center;
}

.complete-header {
    margin-bottom: 20px;
}

.complete-icon {
    font-size: 3rem;
    display: block;
    margin-bottom: 10px;
}

.complete-header h2 {
    font-family: 'Bangers', cursive;
    font-size: 2rem;
    margin: 0;
}

.complete-preview {
    background: #f9f9f9;
    border-radius: 12px;
    padding: 20px;
    margin-bottom: 20px;
}

.complete-preview h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.3rem;
    margin: 0 0 5px 0;
}

.complete-preview p {
    font-family: 'Comic Neue', cursive;
    color: #666;
    margin: 0 0 15px 0;
    font-size: 0.9rem;
}

.complete-panel-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}

.complete-panel-thumb {
    aspect-ratio: 1;
    border-radius: 6px;
    border: 2px solid #000;
    background-size: cover;
    background-position: center;
    background-color: #eee;
}

.complete-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
}

/* === ReImagine Button === */
.reimagine-btn {
    background: linear-gradient(135deg, #fff4a8 0%, #ffd84d 100%);
    color: #111;
    border: 2px solid #000;
}

.reimagine-btn:hover {
    background: linear-gradient(135deg, #ffe985 0%, #ffcd2b 100%);
}

.export-btn,
.print-btn {
    background: #222;
}

.export-btn:hover,
.print-btn:hover {
    background: #000;
}

.reimagine-progress {
    background: #f5f5f5;
    border-radius: 12px;
    padding: 15px;
    margin: 15px 0;
}

.progress-header {
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    margin-bottom: 10px;
    color: #333;
}

/* Loading overlay panel progress presentation */
.loading-overlay .panel-progress-container {
    margin-top: 14px;
    max-width: min(92vw, 760px);
    padding: 14px 16px;
    border-radius: 16px;
    border: 2px solid #111;
    background: linear-gradient(180deg, #ffffff 0%, #f3f4f8 100%);
    box-shadow: 0 12px 35px rgba(0, 0, 0, 0.25);
    gap: 12px;
}

.loading-overlay .panel-progress-item {
    min-width: 72px;
    gap: 6px;
}

.loading-overlay .panel-progress-icon {
    width: 46px;
    height: 46px;
    border-radius: 12px;
    border-width: 2px;
    font-size: 1.1rem;
}

.loading-overlay .panel-progress-label {
    font-size: 0.72rem;
    color: #30343b;
}

.loading-overlay .panel-progress-note {
    font-size: 0.63rem;
}

/* Model Test Container */
.model-test-container {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    border-radius: 12px;
    padding: 15px;
    margin-bottom: 20px;
    position: relative;
    box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
}

.model-test-content {
    display: flex;
    align-items: center;
    gap: 15px;
    flex-wrap: wrap;
}

.model-test-container img {
    width: 120px;
    height: 120px;
    object-fit: cover;
    border-radius: 8px;
    border: 3px solid white;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.model-test-info {
    flex: 1;
    color: white;
    font-family: 'Comic Neue', cursive;
}

.model-test-info span {
    font-size: 1rem;
    font-weight: bold;
}

.hide-test-btn {
    background: rgba(255, 255, 255, 0.2);
    border: 2px solid white;
    color: white;
    padding: 8px 16px;
    border-radius: 8px;
    cursor: pointer;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    transition: all 0.2s ease;
}

.hide-test-btn:hover {
    background: rgba(255, 255, 255, 0.3);
    transform: scale(1.05);
}

.model-test-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 120px;
    height: 120px;
    background: rgba(255, 255, 255, 0.2);
    border-radius: 8px;
    border: 3px solid white;
}

.model-test-loading .spinner {
    width: 40px;
    height: 40px;
    border: 4px solid rgba(255, 255, 255, 0.3);
    border-top-color: white;
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

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

/* Model unavailable warning */
.model-test-container.error {
    background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
}

.model-test-container.success {
    background: linear-gradient(135deg, #00b894 0%, #00cec9 100%);
}

/* ===== SLIDES VIEW MODE ===== */
.slides-view-container {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
    padding: 40px 20px;
    min-height: 70vh;
    background: transparent;
    border-radius: 0;
    margin-top: 0;
}

/* Slides Title in View Mode */
.slides-title {
    text-align: center;
    margin-bottom: 10px;
}

.slides-title h2 {
    font-family: 'Bangers', cursive;
    font-size: 2.5rem;
    color: #ffcc00;
    text-shadow: 3px 3px 0 rgba(0, 0, 0, 0.5);
    margin: 0;
    letter-spacing: 2px;
}

.slides-creator {
    font-family: 'Comic Neue', cursive;
    font-size: 1.1rem;
    color: rgba(255, 255, 255, 0.7);
    margin-top: 5px;
    display: block;
}

.slides-nav {
    display: flex;
    align-items: center;
    gap: 20px;
    background: rgba(255, 255, 255, 0.1);
    padding: 12px 24px;
    border-radius: 50px;
}

.slides-nav-btn {
    width: 50px;
    height: 50px;
    border-radius: 50%;
    border: 2px solid rgba(255, 255, 255, 0.5);
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
}

.slides-nav-btn svg {
    stroke: #fff;
}

.slides-nav-btn:hover {
    background: var(--accent-color);
    border-color: var(--accent-color);
    transform: scale(1.1);
}

.slides-nav-btn:hover svg {
    stroke: #000;
}

.slides-nav-btn:active {
    transform: scale(0.95);
}

.slides-counter {
    font-family: 'Bangers', cursive;
    font-size: 1.5rem;
    color: rgba(255, 255, 255, 0.8);
    min-width: 80px;
    text-align: center;
}

.slides-content {
    width: 100%;
    max-width: 1020px;
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) 64px;
    align-items: center;
    gap: 14px;
}

.slides-nav-counter-only {
    background: transparent;
    padding: 0;
}

.slides-panel-host {
    grid-column: 2;
    width: 100%;
}

.slides-nav-side {
    position: static;
    width: 56px;
    height: 56px;
}

.slides-nav-side.left {
    justify-self: end;
}

.slides-nav-side.right {
    justify-self: start;
}

.slides-content .slide-panel {
    grid-column: 2;
    width: 100%;
    background: #000;
    border: 4px solid #000;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
    border-radius: 8px;
    overflow: hidden;
}

.slides-content .slide-panel-image {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    line-height: 0;
    font-size: 0;
}

/* Panorama slides (tagged by gallery.js from the loaded image's dimensions):
   the 4:3 cover-crop would cut ~40% of the art — let the image set the box
   height instead, like the mobile rules below already do for everything. */
.slides-content .slide-panel-image.panorama-art {
    aspect-ratio: auto;
}

.slides-content .slide-panel-image.panorama-art img {
    height: auto;
}

.slides-content .slide-panel-image img {
    width: 100%;
    height: 100%;
    display: block;
    max-height: 70vh;
    object-fit: cover;
    object-position: center top;
    border-radius: 0;
    margin: 0;
    padding: 0;
}

.slides-content .slide-caption {
    padding: 20px 30px;
    background: rgba(0, 0, 0, 0.8);
    border-top: none;
    font-family: 'Comic Neue', cursive;
    font-size: 1.3rem;
    text-align: center;
    color: #fff;
    line-height: 1.5;
    margin: 0;
}

.slides-hint {
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    color: rgba(255, 255, 255, 0.5);
    text-align: center;
    margin-top: 10px;
}

/* Edit/View Toggle Switch */
.view-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    background: linear-gradient(135deg, #fffef7 0%, #fff6cf 100%);
    border: 2px solid #000;
    padding: 6px 12px;
    border-radius: 30px;
    cursor: pointer;
    user-select: none;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.1);
    transition: all 0.2s ease;
}

.view-toggle:hover {
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.15);
    transform: translateY(-1px);
}

.view-toggle-label {
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 0.9rem;
    color: #888;
    transition: color 0.2s ease;
}

.view-toggle-label.active {
    color: #000;
}

.view-toggle-switch {
    width: 44px;
    height: 24px;
    background: #ddd;
    border-radius: 12px;
    position: relative;
    border: 2px solid #000;
    transition: background 0.2s ease;
}

.view-toggle.view-mode .view-toggle-switch {
    background: var(--accent-color);
}

.view-toggle-slider {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    background: #fff;
    border-radius: 50%;
    border: 2px solid #000;
    transition: transform 0.2s ease;
}

.view-toggle.view-mode .view-toggle-slider {
    transform: translateX(20px);
}

.title-row-toggle .view-toggle {
    background: transparent;
    border: none;
    border-bottom: 4px solid var(--accent-color);
    border-radius: 0;
    box-shadow: none;
    padding: 2px 4px 4px;
}

.title-row-toggle .view-toggle:hover {
    transform: none;
    box-shadow: none;
}

.title-row-toggle .view-toggle-label {
    color: #444;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    font-weight: 700;
    letter-spacing: 0;
    text-shadow: none;
}

.title-row-toggle .view-toggle-label.active {
    color: #000;
    text-shadow: none;
}

.title-row-toggle .view-toggle.view-mode .view-toggle-label {
    color: #fff;
    text-shadow: 1px 1px 0 #000;
}

.title-row-toggle .view-toggle.view-mode .view-toggle-label.active {
    color: #fff;
    text-shadow: 1px 1px 0 #000, 0 0 2px #ffd84d;
}

.title-row-toggle .view-toggle-switch {
    background: #ffd84d;
}

/* Hide the old button styles */
#toggleSlidesViewBtn {
    display: none;
}

@media (max-width: 900px) {
    .story-title-row {
        align-items: flex-start;
    }

    .title-row-toggle {
        margin-left: auto;
    }

    .panel-action-bar {
        flex-direction: column;
        align-items: stretch;
    }

    .panel-actions-left,
    .panel-actions-right {
        width: 100%;
    }

    .panel-actions-right {
        justify-content: space-between;
    }
}

@media (max-width: 600px) {
    /* Phones: even 2-column grid instead of ragged wrapped rows. */
    .panel-actions-right {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: 8px;
    }

    .panel-actions-right .toggle-details-btn {
        width: 100%;
        white-space: normal;
    }

    .style-action-group {
        display: flex;
        width: 100%;
        gap: 8px;
    }

    .panel-action-bar .style-selector {
        flex: 1;
        min-width: 0;
    }

    .panel-action-bar .style-selector select {
        width: 100%;
        min-width: 0;
    }

    .style-action-group .reimagine-btn {
        flex-shrink: 0;
    }
}

/* Touch/mobile slides layout lives in the single
   `@media (pointer: coarse), (max-width: 800px)` block further down
   (after the 768px adjustments, so it wins the cascade). */

/* Speech bubbles in slides view */
.slides-content .slide-bubbles-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.slides-content .slide-bubble {
    position: absolute;
    background: white;
    border: 3px solid #000;
    border-radius: 20px;
    padding: 12px 18px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 1.2rem;
    min-width: 80px;
    max-width: 200px;
    text-align: center;
    /* No transform - positions come from JS with correct offsets */
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.3);
    /* Prevent text from collapsing into one line */
    white-space: pre-wrap;
    word-wrap: break-word;
    overflow-wrap: break-word;
    line-height: 1.4;
}

.slides-content .slide-bubble::after {
    content: '';
    position: absolute;
    bottom: -12px;
    left: 20px;
    border-width: 12px 8px 0;
    border-style: solid;
    border-color: #000 transparent transparent;
}

.slides-content .slide-bubble::before {
    content: '';
    position: absolute;
    bottom: -8px;
    left: 22px;
    border-width: 10px 6px 0;
    border-style: solid;
    border-color: white transparent transparent;
    z-index: 1;
}

/* Responsive adjustments for slides view */
@media (max-width: 768px) {
    .slides-view-container {
        padding: 20px 10px;
        border-radius: 8px;
    }

    .slides-nav {
        padding: 8px 16px;
        gap: 12px;
    }

    .slides-nav-btn {
        width: 40px;
        height: 40px;
    }

    .slides-counter {
        font-size: 1.2rem;
    }

    .slides-content {
        grid-template-columns: 44px minmax(0, 1fr) 44px;
        gap: 8px;
    }

    .slides-nav-side {
        width: 40px;
        height: 40px;
    }

    .slides-content .slide-caption {
        padding: 15px 20px;
        font-size: 1.1rem;
    }

    .slides-content .slide-bubble {
        font-size: 1rem;
        padding: 8px 12px;
        max-width: 150px;
    }
}

@media (pointer: coarse), (max-width: 800px) {
    .slides-content {
        grid-template-columns: minmax(0, 1fr) !important;
        gap: 0 !important;
        max-width: 100%;
        position: relative;
    }

    .slides-panel-host,
    .slides-content .slide-panel {
        grid-column: 1 !important;
    }

    .slides-panel-host {
        width: min(100%, 420px) !important;
        justify-self: center !important;
        margin: 0 auto;
    }

    /* Keep prev/next usable on touch: overlay them on the panel edges
       instead of hiding them (swipe still works too). Negative margin
       centers vertically so the :hover scale transform doesn't shift them. */
    .slides-nav-side {
        display: flex !important;
        position: absolute;
        top: 50%;
        margin-top: -22px;
        width: 44px;
        height: 44px;
        z-index: 10;
        background: rgba(0, 0, 0, 0.45);
        border-color: rgba(255, 255, 255, 0.7);
    }

    .slides-nav-side.left {
        left: 8px;
    }

    .slides-nav-side.right {
        right: 8px;
    }

    .slides-view-container {
        padding-left: 0;
        padding-right: 0;
    }

    .slides-content .slide-panel {
        width: min(100%, 420px);
        margin: 0 auto;
    }

    /* Same reasoning as the grid view: panel art comes in varying aspect
       ratios — show the whole image and let it set the card height rather
       than cropping into the fixed 4:3 box. */
    .slides-content .slide-panel-image {
        aspect-ratio: auto;
        min-height: 120px;
    }

    .slides-content .slide-panel-image img {
        height: auto;
        max-height: 80vh;
    }
}

/* ============================================
   SETTINGS MODAL STYLES
   ============================================ */
.settings-modal {
    display: none;
    position: fixed;
    z-index: 2000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    align-items: center;
    justify-content: center;
}

.settings-modal.active {
    display: flex;
}

.settings-modal-content {
    background-color: #fff;
    padding: 2rem;
    border: 4px solid #000;
    width: 95%;
    max-width: 500px;
    box-shadow: 10px 10px 0px var(--accent-color);
    position: relative;
    font-family: 'Comic Neue', cursive;
    max-height: 90vh;
    overflow-y: auto;
    border-radius: 8px;
}

.settings-modal-content h2 {
    font-family: 'Bangers', cursive;
    font-size: 1.8rem;
    margin: 0 0 1.5rem 0;
    text-transform: uppercase;
    letter-spacing: 1px;
    border-bottom: 3px solid #000;
    padding-bottom: 10px;
}

.settings-close {
    position: absolute;
    top: 10px;
    right: 18px;
    font-size: 2rem;
    font-weight: bold;
    cursor: pointer;
    transition: transform 0.2s;
}

.settings-close:hover {
    transform: scale(1.2);
    color: #f44336;
}

.settings-section {
    margin-bottom: 1.5rem;
    padding: 1rem;
    background: #f9f9f9;
    border: 2px solid #000;
    border-radius: 6px;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.1);
}

.settings-section h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    margin: 0 0 1rem 0;
    border-bottom: 2px solid #ddd;
    padding-bottom: 8px;
}

.settings-row {
    margin-bottom: 1rem;
}

.settings-row:last-child {
    margin-bottom: 0;
}

.settings-row label {
    display: block;
    font-weight: bold;
    margin-bottom: 6px;
    font-size: 0.95rem;
}

.settings-row input[type="text"],
.settings-row input[type="password"] {
    width: 100%;
    padding: 10px 12px;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    border: 2px solid #000;
    border-radius: 4px;
    background: #fff;
    box-shadow: 2px 2px 0px rgba(0, 0, 0, 0.1);
    transition: border-color 0.2s, box-shadow 0.2s;
}

.settings-row input[type="text"]:focus,
.settings-row input[type="password"]:focus {
    outline: none;
    border-color: var(--accent-color);
    box-shadow: 3px 3px 0px var(--accent-color);
}

.settings-row select {
    width: 100%;
    padding: 10px 12px;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    border: 2px solid #000;
    border-radius: 4px;
    background: #fff;
    box-shadow: 2px 2px 0px rgba(0, 0, 0, 0.1);
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23000' d='M6 8L1 3h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 35px;
    transition: border-color 0.2s, box-shadow 0.2s;
}

.settings-row select:focus {
    outline: none;
    border-color: var(--accent-color);
    box-shadow: 3px 3px 0px var(--accent-color);
}

.settings-row select:hover {
    border-color: #555;
}

.settings-row .hint {
    margin: 6px 0 0 0;
    font-size: 0.85rem;
    color: #666;
    font-style: italic;
}

.settings-row .hint a {
    color: #1976d2;
    text-decoration: none;
}

.settings-row .hint a:hover {
    text-decoration: underline;
}

.settings-save-btn {
    width: 100%;
    padding: 12px 20px;
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    background: #000;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2);
}

.settings-save-btn:hover {
    background: var(--accent-color);
    color: #000;
    transform: translateY(-2px);
    box-shadow: 5px 5px 0px rgba(0, 0, 0, 0.2);
}

/* The gear's second definition used to live here — a leftover from when it sat
   bottom-right. It declared `bottom: 20px` alongside the top-anchored rule
   above (inert: with a fixed height, `top` wins), re-stated the same hover, and
   re-declared width/height, which would have overridden the shared rail size.
   It also lifted the gear to z-index 1000, level with .modal, where a floating
   control does not belong. Removed; the definition above is the only one. */

/* Login Modal */
.login-modal {
    display: none;
    position: fixed;
    z-index: 2100;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.85);
    align-items: center;
    justify-content: center;
}

.login-modal.active {
    display: flex;
}

.login-modal-content {
    background-color: #fff;
    padding: 2rem;
    border: 4px solid #000;
    width: 95%;
    max-width: 400px;
    box-shadow: 10px 10px 0px var(--accent-color);
    text-align: center;
    font-family: 'Comic Neue', cursive;
    border-radius: 8px;
}

.login-icon {
    font-size: 3rem;
    margin-bottom: 10px;
}

.login-modal-content h2 {
    font-family: 'Bangers', cursive;
    font-size: 1.6rem;
    margin: 0 0 1rem 0;
}

.login-error {
    display: none;
    background: #f8d7da;
    border: 2px solid #dc3545;
    color: #721c24;
    padding: 8px 12px;
    border-radius: 4px;
    margin-bottom: 1rem;
    font-weight: bold;
}

.login-error.show {
    display: block;
}

.login-row {
    margin-bottom: 1rem;
    text-align: left;
}

.login-row label {
    display: block;
    font-weight: bold;
    margin-bottom: 6px;
}

.login-row input {
    width: 100%;
    padding: 10px 12px;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    border: 2px solid #000;
    border-radius: 4px;
    box-shadow: 2px 2px 0px rgba(0, 0, 0, 0.1);
}

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

.login-btn {
    width: 100%;
    padding: 12px 20px;
    font-family: 'Bangers', cursive;
    font-size: 1.2rem;
    background: #000;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;
    box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.2);
}

.login-btn:hover {
    background: var(--accent-color);
    color: #000;
    transform: translateY(-2px);
}


/* ============================================
   SOCIAL & AUTH UI
   Shared design system for the auth, invite, voting,
   reporting, comments, events, and consent surfaces.
   ============================================ */

/* ---- Modal scaffold (overlay + card) ---- */
.app-modal {
    display: flex;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    align-items: center;
    justify-content: center;
    z-index: 10000;
    font-family: 'Comic Neue', cursive;
    padding: 16px;
    animation: appModalFadeIn 0.18s ease;
}

@keyframes appModalFadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

.app-modal-card {
    background: #fff;
    border: 4px solid #000;
    border-radius: 8px;
    box-shadow: 10px 10px 0 var(--accent-color);
    padding: 24px 28px;
    width: 100%;
    max-width: 480px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    animation: appModalSlideUp 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes appModalSlideUp {
    from { opacity: 0; transform: translateY(20px) scale(0.96); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}

.app-modal-card.is-narrow { max-width: 400px; }
.app-modal-card.is-wide { max-width: 560px; }

@media (max-width: 600px) {
    .app-modal-card {
        padding: 18px 20px;
        box-shadow: 5px 5px 0 var(--accent-color);
    }
}

.app-modal-title {
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    font-size: 1.7rem;
    margin: 0 0 10px;
    line-height: 1.1;
}

.app-modal-text {
    margin: 10px 0;
    line-height: 1.5;
}

.app-modal-actions {
    display: flex;
    gap: 10px;
    margin-top: 18px;
}

.app-modal-actions.is-stacked {
    flex-direction: column;
}

/* ---- Buttons ---- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 10px 16px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 0.95rem;
    line-height: 1;
    background: #fff;
    color: #000;
    border: 2px solid #000;
    border-radius: 4px;
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease, color 0.15s ease;
    text-decoration: none;
    user-select: none;
}

.btn:hover { transform: translateY(-1px); box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.18); }
.btn:active { transform: translateY(0); box-shadow: none; }
.btn[disabled], .btn.is-disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }

.btn-primary {
    background: #000;
    color: #fffaf0;
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    font-size: 1.05rem;
    border-color: #000;
}
.btn-primary:hover { background: var(--accent-color); color: #000; }

.btn-accent {
    background: var(--accent-color);
    color: #000;
    font-weight: bold;
}
.btn-accent:hover { background: #ffd633; }

.btn-secondary {
    background: #fff;
    color: #000;
}
.btn-secondary:hover { background: #f4f4f4; }

.btn-danger {
    background: #b43838;
    color: #fff;
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    font-size: 1.05rem;
    border-color: #000;
}
.btn-danger:hover { background: #921a1a; }

.btn-danger-outline {
    background: #fff;
    color: #b43838;
    border-color: #b43838;
}
.btn-danger-outline:hover { background: #fdf0f0; }

.btn-success-outline {
    background: #fff;
    color: #2a7f2a;
    border-color: #2a7f2a;
}
.btn-success-outline:hover { background: #f0fbf0; }

.btn-ghost {
    background: transparent;
    border: none;
    color: #0a58ca;
    padding: 0;
    font-weight: normal;
}
.btn-ghost:hover { box-shadow: none; transform: none; text-decoration: underline; }

.btn-block { width: 100%; }
.btn-sm { padding: 6px 10px; font-size: 0.85rem; }
.btn-lg { padding: 14px 22px; font-size: 1.15rem; }

/* ---- Inputs (consistent with the rest of the app) ---- */
.app-input,
.app-textarea,
.app-select {
    width: 100%;
    padding: 10px 12px;
    font-family: 'Comic Neue', cursive;
    font-size: 1rem;
    border: 2px solid #000;
    border-radius: 4px;
    background: #fff;
    box-sizing: border-box;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.08);
}
.app-input:focus,
.app-textarea:focus,
.app-select:focus {
    outline: none;
    box-shadow: 3px 3px 0 var(--accent-color);
}
.app-textarea { resize: vertical; min-height: 70px; }

.app-form-error {
    color: #b43838;
    font-size: 0.85rem;
    margin: 0 0 10px;
    display: none;
    font-weight: bold;
}
.app-form-error.is-visible { display: block; }

/* ---- Banners (top invite welcome, bottom cookie consent) ---- */
.app-banner {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 18px;
    font-family: 'Comic Neue', cursive;
    flex-wrap: wrap;
}

.app-banner-invite {
    background: #fff8e1;
    border-bottom: 3px solid var(--accent-color);
    /* Inserted as a direct child of the centering flex column that is <body>;
       without a width it shrinks to its text and reads as a pill instead of a
       bar. The cookie variant escapes this only because it is position:fixed. */
    width: 100%;
}

.app-banner-cookie {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: #fffaf0;
    border-top: 3px solid #000;
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.15);
    z-index: 9999;
    padding: 8px 14px;
    gap: 10px;
}

.app-banner-cookie .app-banner-text {
    font-size: 0.85rem;
    min-width: 180px;
}

.app-banner-actions {
    display: flex;
    gap: 8px;
    margin-left: auto;
    flex-shrink: 0;
}

/* Keep page content clear of the fixed banner. */
body.has-cookie-banner {
    padding-bottom: 84px;
}

.app-banner-text {
    flex: 1;
    min-width: 240px;
    font-size: 0.92rem;
}

/* ---- Site footer (privacy / terms / cookie settings — injected by consent.js) ---- */
.site-footer {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    /* Appended to <body>, a centering flex column: without a width the footer
       shrinks to its links, so the border-top becomes a stub floating mid-page
       (and on .legal-page-body, which aligns to flex-start, it is pinned to the
       far left while the card stays centered). Same reason header sets it. */
    width: 100%;
    margin-top: 30px;
    padding: 18px 14px;
    border-top: 2px solid rgba(0, 0, 0, 0.12);
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
    color: #555;
}

.site-footer a {
    color: #555;
    text-decoration: underline;
}

/* The provider credit sits at the right end of the footer — the "lower right"
   of the page — WITHOUT moving the legal links, which were centred and should
   stay centred.
   
   `margin-left: auto` would have done the first part and broken the second: it
   eats all the free space to the credit's left, so the links get pushed off
   centre and into a left-aligned group. Instead the credit and an equal-width
   flexible spacer sit on either side of the link group, which keeps the middle
   centred no matter how wide the credit's translation is. Neither side can
   collide with the links, because both are laid out in flow.
   
   The footer already wraps; below 700px the three-column arrangement is
   dropped and the credit takes its own full-width centred line rather than
   being squeezed against the last link. */
/* The left column. It began as an empty ::before purely to balance the credit;
   the Discord link now occupies it, so the footer reads social · legal · credit
   with the legal group still dead centre. Equal flex on both outer columns is
   what holds that centre, whatever either side's content or translation. */
.site-footer a.site-footer-social {
    flex: 1 1 0;
    display: flex;
    align-items: center;
    color: #555;
    /* The three legal links are underlined; an icon with an underline under it
       reads as a rendering fault rather than a link. */
    text-decoration: none;
}

.site-footer a.site-footer-social:hover {
    color: #5865F2;
}

.site-footer-credit {
    flex: 1 1 0;
    text-align: right;
    color: #666;
    white-space: nowrap;
}

@media (max-width: 700px) {
    /* Stacked: the icon leads its own centred line, the links follow, the
       credit closes. Three columns at this width would squeeze the middle. */
    .site-footer a.site-footer-social {
        flex: 1 1 100%;
        justify-content: center;
    }

    .site-footer-credit {
        flex: 1 1 100%;
        text-align: center;
    }
}

/* Sits in a row of three real navigation links and used to be styled exactly
   like them — same colour, same underline — so it read as a fourth link to a
   fourth page. It is not one: it reopens the consent banner in place, on the
   page you are already on. Underline is what promises a navigation here, so
   drop it and give the control a button's affordance instead. */
.site-footer-btn {
    background: none;
    border: 1px solid rgba(0, 0, 0, 0.25);
    border-radius: 999px;
    padding: 2px 10px;
    color: #555;
    font: inherit;
    line-height: 1.4;
    text-decoration: none;
    cursor: pointer;
}

.site-footer a:hover {
    color: #000;
}

.site-footer-btn:hover {
    border-color: rgba(0, 0, 0, 0.55);
    background: rgba(0, 0, 0, 0.04);
    color: #000;
}

/* Keyboard users lose the underline too, so the focus ring has to carry it. */
.site-footer-btn:focus-visible {
    outline: 2px solid #000;
    outline-offset: 2px;
}

.site-footer-sep {
    color: #aaa;
}

.app-banner-dismiss {
    background: none;
    border: none;
    font-size: 1.3rem;
    cursor: pointer;
    color: #000;
    padding: 0 4px;
}

/* ---- Recovery password modal — special content ---- */
.recovery-password-box {
    display: flex;
    align-items: center;
    gap: 8px;
    background: #fff;
    border: 2px solid #000;
    border-radius: 4px;
    padding: 12px;
    margin: 14px 0;
}

.recovery-password-value {
    flex: 1;
    font-family: 'Courier New', monospace;
    font-size: 1.05rem;
    word-break: break-all;
}

.recovery-warning {
    font-size: 0.85rem;
    color: #a35200;
    background: #fff8e1;
    padding: 10px;
    border-left: 4px solid var(--accent-color);
    border-radius: 2px;
    margin: 12px 0;
}

.recovery-confirm {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 16px 0 8px;
    font-size: 0.95rem;
    cursor: pointer;
}

.recovery-confirm input[type="checkbox"] {
    width: 18px;
    height: 18px;
}

/* ---- Story reactions (upvote + report) ---- */
.story-reactions {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: 14px;
    vertical-align: middle;
    font-size: 0.9rem;
    font-family: 'Comic Neue', cursive;
}

.story-reaction-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 0.95rem;
    background: #fff;
    color: #000;
    border: 2px solid #000;
    border-radius: 20px;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
}
.story-reaction-btn:hover { transform: translateY(-1px); }
.story-reaction-btn[disabled] { opacity: 0.6; cursor: not-allowed; }

.story-reaction-btn.is-active {
    background: var(--accent-color);
}

.story-reaction-btn-report {
    color: #b43838;
    border-color: #b43838;
    font-size: 0.85rem;
    padding: 4px 10px;
}
.story-reaction-btn-report:hover { background: #fdf0f0; }

/* ---- Panel heart button (overlay on each comic panel) ---- */
.panel-heart-btn {
    position: absolute;
    top: 8px;
    left: 48px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    background: rgba(255, 255, 255, 0.92);
    border: 2px solid #000;
    border-radius: 18px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.85rem;
    font-weight: bold;
    cursor: pointer;
    z-index: 6;
    /* Hidden until the panel is hovered/focused (revealed below). A liked panel
       keeps its heart visible so you can still see your own like state. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.15s ease, visibility 0.15s ease, background 0.15s ease, transform 0.15s ease;
}
.panel:hover .panel-heart-btn,
.panel:focus-within .panel-heart-btn,
.panel-heart-btn.is-liked {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
.panel-heart-btn:hover { transform: translateY(-1px); }
.panel-heart-btn.is-liked { background: var(--accent-color); }
.panel-heart-btn[disabled] { opacity: 0.6; cursor: not-allowed; }

/* ---- Comments section ---- */
.comments-section {
    max-width: 1200px;
    margin: 30px auto 60px;
    padding: 22px 24px;
    background: #fff;
    border: 4px solid #000;
    border-radius: 8px;
    box-shadow: 8px 8px 0 #000;
    font-family: 'Comic Neue', cursive;
}

.comments-section-title {
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    margin: 0 0 14px;
    font-size: 1.6rem;
}

.comments-empty {
    color: #888;
    font-style: italic;
    margin: 8px 0 0;
}

.comment-composer {
    margin: 14px 0 22px;
}

.comment-composer-meta {
    font-size: 0.85rem;
    color: #555;
    margin: 0 0 6px;
}

.comment-composer-actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 8px;
}

.comments-list { display: block; }

.comment {
    padding: 14px;
    background: #fff;
    border: 2px solid #000;
    border-radius: 6px;
    margin-bottom: 12px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.12);
}

.comment.is-collapsed {
    background: #f5f5f5;
    opacity: 0.7;
    box-shadow: none;
}

.comment-collapsed-toggle {
    background: none;
    border: none;
    color: #0a58ca;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
    padding: 0;
}

.comment-body-wrap {
    display: block;
}

.comment.is-collapsed .comment-body-wrap {
    display: none;
}

.comment-meta {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.comment-author { font-weight: bold; }
.comment-time { font-size: 0.8rem; color: #888; }

.comment-vote-group {
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.comment-rate-btn {
    background: #fff;
    border: 2px solid #000;
    border-radius: 4px;
    width: 26px;
    height: 26px;
    cursor: pointer;
    font-family: 'Comic Neue', cursive;
    line-height: 1;
    transition: background 0.12s ease;
}
.comment-rate-btn.is-active { background: var(--accent-color); }
.comment-rate-btn:hover { background: #fff8d4; }

.comment-score {
    min-width: 24px;
    text-align: center;
    font-weight: bold;
}

.comment-body {
    margin-top: 8px;
    white-space: pre-wrap;
    word-break: break-word;
}

.comment-actions {
    margin-top: 8px;
    display: flex;
    gap: 10px;
    font-size: 0.85rem;
}

.comment-actions .btn-ghost { font-size: 0.85rem; }
.comment-action-link {
    background: none;
    border: none;
    color: #0a58ca;
    cursor: pointer;
    font-family: inherit;
    padding: 0;
    font-size: 0.85rem;
}
.comment-action-link.is-danger { color: #b43838; }
.comment-action-link:hover { text-decoration: underline; }

.comment-reply-list {
    margin-top: 12px;
    padding-left: 16px;
    border-left: 3px solid #ddd;
}

.comment-reply {
    padding: 10px;
    background: #fff;
    border-radius: 4px;
    margin-bottom: 8px;
    border: 1px solid #ddd;
}

.comment-reply.is-collapsed {
    background: #fafafa;
    opacity: 0.7;
}

.comment-reply .comment-author { font-size: 0.92rem; }
.comment-reply .comment-time { font-size: 0.78rem; }
.comment-reply .comment-body { font-size: 0.92rem; margin-top: 6px; }
.comment-reply .comment-rate-btn { width: 22px; height: 22px; font-size: 0.75rem; }
.comment-reply .comment-score { min-width: 20px; font-size: 0.85rem; }
.comment-reply .comment-actions { margin-top: 6px; font-size: 0.8rem; }

.comment-edit-form {
    display: block;
}

.comment-edit-form-actions {
    margin-top: 6px;
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}

/* ---- Account row in settings panel ---- */
.account-status-row {
    border-top: 1px solid #ddd;
    padding-top: 12px;
    margin-top: 12px;
}

.account-status-line {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.account-status-line-text {
    flex: 1;
    min-width: 120px;
}

.account-status-line-text.is-muted { color: #666; }

/* ---- Toast for ephemeral confirmations (e.g. report submitted) ---- */
.app-toast-banner {
    position: fixed;
    top: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: #dff0d8;
    border: 2px solid #2a7f2a;
    color: #2a7f2a;
    padding: 10px 20px;
    border-radius: 4px;
    z-index: 10002;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.12);
    animation: appModalSlideUp 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

/* ---- Admin: invite list ---- */
.invite-create-row {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    align-items: center;
    margin: 10px 0;
}

.invite-create-row input[type="text"],
.invite-create-row input[type="number"] {
    padding: 6px 8px;
    border: 2px solid #000;
    border-radius: 4px;
    font-family: 'Comic Neue', cursive;
}

.invite-create-row .invite-label-input { flex: 1; min-width: 160px; }
.invite-create-row .invite-num-input { width: 80px; }

.invite-list,
.report-list,
.hidden-stories-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.invite-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 2px solid #000;
    border-radius: 4px;
    margin-bottom: 8px;
    background: #fff;
}

.invite-status {
    font-weight: bold;
    text-transform: uppercase;
    font-size: 0.78rem;
    width: 80px;
    letter-spacing: 0.5px;
}
.invite-status-active { color: #2a7f2a; }
.invite-status-used { color: #666; }
.invite-status-expired { color: #a35200; }
.invite-status-revoked { color: #b43838; }

.invite-item-body { flex: 1; min-width: 160px; }
.invite-item-label { font-weight: bold; }
.invite-item-label.is-empty { color: #888; font-style: italic; font-weight: normal; }
.invite-item-meta { font-size: 0.8rem; color: #666; margin-top: 2px; }

/* ---- Admin: reports list ---- */
.report-item {
    padding: 12px;
    border: 2px solid #000;
    border-radius: 4px;
    margin-bottom: 10px;
    background: #fff;
}

.report-item-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.report-item-title {
    flex: 1;
    min-width: 160px;
    font-weight: bold;
}
.report-item-title a { color: #000; text-decoration: none; }
.report-item-title a:hover { text-decoration: underline; }

.report-item-hidden-badge {
    background: #b43838;
    color: #fff;
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.report-item-count {
    font-size: 0.85rem;
    color: #666;
}

.report-reasons { margin-top: 8px; }

.report-reason {
    border-top: 1px solid #eee;
    padding: 8px 0;
}

.report-reason-tag {
    background: var(--accent-color);
    padding: 2px 6px;
    border-radius: 4px;
    font-size: 0.78rem;
    font-weight: bold;
}

.report-reason-time {
    color: #888;
    font-size: 0.78rem;
    margin-left: 8px;
}

.report-reason-message {
    margin-top: 4px;
    font-size: 0.9rem;
}

/* ---- Admin: hidden stories list ---- */
.hidden-story-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    border: 2px solid #000;
    border-radius: 4px;
    margin-bottom: 8px;
    background: #fff;
}
.hidden-story-item-title { flex: 1; font-weight: bold; }
.hidden-story-item-meta { font-size: 0.8rem; color: #666; }

/* ---- Standalone "legal" pages: privacy, terms, invite-not-found ---- */
.legal-page-body {
    background: var(--bg-color, #fffaf0);
    min-height: 100vh;
    margin: 0;
    padding: 30px 16px;
    font-family: 'Comic Neue', cursive;
    color: var(--text-color, #333);
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

.legal-card {
    max-width: 800px;
    width: 100%;
    margin: 0 auto;
    background: #fff;
    border: 4px solid #000;
    border-radius: 8px;
    padding: 32px;
    box-shadow: 10px 10px 0 var(--accent-color);
}

.legal-card h1,
.legal-card h2 {
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    color: #000;
}
.legal-card h1 { font-size: 2.4rem; margin: 0 0 8px; }
.legal-card h2 { margin-top: 28px; font-size: 1.5rem; }
.legal-card a { color: #0a58ca; }
.legal-card ul { padding-left: 24px; line-height: 1.55; }
.legal-card p { line-height: 1.55; }
.legal-card p em { color: #666; }
.legal-card .back-link {
    display: inline-block;
    margin-bottom: 14px;
    color: #0a58ca;
    text-decoration: none;
}
.legal-card .back-link:hover { text-decoration: underline; }
.legal-card code {
    background: #f4f4f4;
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 0.92em;
}

/* Invite-not-found landing card variant */
.legal-card.is-centered {
    max-width: 480px;
    text-align: center;
}
.legal-card.is-centered h1 { font-size: 2rem; }
.legal-card-cta {
    display: inline-block;
    margin-top: 16px;
    padding: 10px 24px;
    background: #000;
    color: #fffaf0;
    text-decoration: none;
    border-radius: 4px;
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    border: 2px solid #000;
    transition: background 0.15s ease, color 0.15s ease;
}
.legal-card-cta:hover { background: var(--accent-color); color: #000; }

/* ---- Events page ---- */
.events-page-body {
    background: var(--bg-color, #fffaf0);
    min-height: 100vh;
    margin: 0;
    /* Same top/side padding as the global body rule — without it the header
       (and the login/lang cluster) sits flush against the viewport top. */
    padding: 2rem 2rem 60px;
    font-family: 'Comic Neue', cursive;
    color: var(--text-color, #333);
}

@media (max-width: 600px) {
    .events-page-body {
        padding: 0.5rem 0.5rem 60px;
    }
}

.events-container {
    max-width: 900px;
    margin: 0 auto;
    padding: 20px;
}

.events-card {
    background: #fff;
    border: 4px solid #000;
    border-radius: 8px;
    box-shadow: 8px 8px 0 #000;
    padding: 24px 28px;
    margin-bottom: 20px;
}
.events-card h1,
.events-card h2 {
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
}
.events-card h1 { font-size: 1.6rem; margin: 0 0 6px; }
.events-card h2 { font-size: 1.4rem; margin: 0 0 6px; }

.event-status-badge {
    display: inline-block;
    padding: 4px 12px;
    background: var(--accent-color);
    border: 2px solid #000;
    border-radius: 16px;
    font-size: 0.78rem;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-left: 8px;
    vertical-align: middle;
}

.event-theme-list,
.event-submission-list {
    list-style: none;
    padding: 0;
    margin: 12px 0;
}

.event-theme-list li,
.event-submission-list li {
    padding: 12px;
    border: 2px solid #000;
    border-radius: 4px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;
    gap: 12px;
    background: #fff;
}

.event-vote-btn {
    padding: 8px 18px;
    border: 2px solid #000;
    background: #fff;
    cursor: pointer;
    border-radius: 16px;
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.25);
    transition: transform 0.12s, box-shadow 0.12s, background 0.15s ease;
}
.event-vote-btn:hover {
    background: var(--accent-color);
    transform: translate(1px, 1px);
    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.25);
}
.event-vote-btn.is-voted {
    background: var(--accent-color);
    transform: translate(2px, 2px);
    box-shadow: none;
}

.event-theme-list li.is-leader,
.event-submission-list li.is-leader {
    background: #fff6d6;
    border-width: 3px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.15);
}

.event-leader-flag {
    font-size: 0.78rem;
    font-weight: bold;
    background: var(--accent-color);
    border: 2px solid #000;
    border-radius: 999px;
    padding: 1px 10px;
    white-space: nowrap;
}

.event-countdown-chip {
    display: inline-block;
    font-family: 'Bangers', cursive;
    font-size: 1.05rem;
    letter-spacing: 1px;
    background: var(--accent-color);
    border: 2px solid #000;
    border-radius: 8px;
    padding: 3px 14px;
    margin: 2px 0 6px;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.25);
}

.event-deadline-abs {
    font-size: 0.82rem;
    color: #777;
    margin-left: 10px;
    white-space: nowrap;
}

.event-input-row {
    display: flex;
    gap: 10px;
    align-items: center;
    margin: 10px 0;
}
.event-input-row .app-input { flex: 1; }


/* ==========================================================================
   Stories browse page — newsstand layout: toolbar, card grid, contest banner
   ========================================================================== */
.stories-container {
    /* body is a column flexbox with align-items: center, so without an explicit
       width this container is sized shrink-to-fit by its content and never
       reaches max-width — the page looked narrow no matter how wide the
       monitor. width:100% opts back into filling the available space. */
    width: 100%;
    max-width: 1340px;
    margin: 0 auto;
    padding: 24px clamp(12px, 3vw, 40px) 60px;
}

/* --- search + sort toolbar --- */
.stories-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    background: #fff;
    border: 4px solid #000;
    border-radius: 14px;
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.2);
    padding: 14px 16px;
    margin: 0 0 28px;
}

/* The toolbar moved to the top of the landing page: give it a touch more
   presence as the first thing under the header. */
.stories-toolbar--top {
    margin-top: 4px;
}

.stories-toolbar--top .stories-search {
    flex: 1 1 340px;
    font-size: 1.12rem;
}

.stories-search {
    flex: 1 1 260px;
    min-width: 200px;
    padding: 12px 16px;
    border: 3px solid #000;
    border-radius: 10px;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 1.05rem;
    background: #fffef5;
    box-shadow: inset 3px 3px 0 rgba(0, 0, 0, 0.08);
}

.stories-search:focus {
    outline: none;
    background: #fff;
    box-shadow: inset 3px 3px 0 rgba(0, 0, 0, 0.08), 0 0 0 4px var(--accent-color);
}

.sort-chips {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.sort-chip {
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    font-size: 1.05rem;
    padding: 9px 16px;
    background: #fff;
    color: #000;
    border: 3px solid #000;
    border-radius: 999px;
    cursor: pointer;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.25);
    transition: transform 0.12s, box-shadow 0.12s, background 0.12s;
}

.sort-chip:hover {
    transform: translateY(-2px);
    box-shadow: 4px 5px 0 rgba(0, 0, 0, 0.25);
}

.sort-chip.active {
    background: var(--accent-color);
    transform: translate(2px, 2px);
    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
}

/* --- story card grid --- */
.stories-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(310px, 1fr));
    gap: 26px;
    padding: 6px 0 20px;
}

.story-card {
    /* Rendered as <a> (card-renderers.js): an anchor is inline by default and
       inherits link colour/underline, so restate the box here. */
    display: block;
    text-decoration: none;
    color: inherit;
    background: #fff;
    border: 4px solid #000;
    border-radius: 14px;
    overflow: hidden;
    cursor: pointer;
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.18);
    transition: transform 0.18s, box-shadow 0.18s;
    animation: story-card-pop 0.45s cubic-bezier(0.2, 0.9, 0.3, 1.2) both;
}

.stories-grid .story-card:nth-child(2n) { animation-delay: 0.06s; }
.stories-grid .story-card:nth-child(3n) { animation-delay: 0.12s; }

@keyframes story-card-pop {
    from { opacity: 0; transform: translateY(18px) scale(0.97); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .story-card { animation: none; }
}

.story-card:hover {
    transform: translateY(-6px) rotate(-0.6deg);
    box-shadow: 10px 12px 0 rgba(0, 0, 0, 0.22);
}

.story-card-image-wrapper {
    position: relative;
    height: 230px;
    border-bottom: 4px solid #000;
    background: #f0f0f0;
    overflow: hidden;
}

.story-card-image {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.35s ease;
}

.story-card:hover .story-card-image { transform: scale(1.05); }

.story-card-badge {
    position: absolute;
    top: 10px;
    right: 10px;
    background: var(--accent-color);
    color: #000;
    border: 3px solid #000;
    border-radius: 8px;
    transform: rotate(3deg);
    font-family: 'Comic Neue', cursive;
    font-weight: bold;
    font-size: 0.8rem;
    padding: 3px 10px;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
}

.story-card-content { padding: 12px 14px 14px; }

.story-card-title {
    font-family: 'Bangers', cursive;
    font-size: 1.45rem;
    letter-spacing: 1px;
    color: #000;
    margin: 0 0 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.story-card-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 0.9rem;
    color: #555;
}

.story-card-owner {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.story-card-stats {
    display: flex;
    gap: 12px;
    flex-shrink: 0;
    color: #777;
}

/* --- list states --- */
.stories-header { text-align: center; margin-bottom: 20px; }
.stories-header h2 { font-family: 'Bangers', cursive; font-size: 2.5rem; margin: 0; letter-spacing: 2px; }
.stories-header p { color: #666; margin-top: 5px; }

.loading-more {
    text-align: center;
    padding: 30px;
    font-family: 'Comic Neue', cursive;
    font-size: 1.1rem;
    color: #666;
}

.loading-more .spinner { width: 40px; height: 40px; margin: 0 auto 15px; }

.no-more-stories {
    text-align: center;
    padding: 30px;
    font-family: 'Comic Neue', cursive;
    color: #999;
    border-top: 3px dashed #ccc;
    margin-top: 20px;
}

.empty-state { text-align: center; padding: 60px 20px; color: #666; }
.empty-state-icon { font-size: 4rem; margin-bottom: 20px; }
.empty-state h3 { font-family: 'Bangers', cursive; font-size: 1.8rem; margin-bottom: 10px; }

/* --- weekly theme contest banner (featured section) --- */
.contest-banner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 18px;
    margin: 0 0 20px;
    padding: 16px 20px;
    background: repeating-linear-gradient(135deg, #15151c 0 16px, #20202b 16px 32px);
    color: #fff;
    border: 4px solid #000;
    border-radius: 14px;
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.25);
}

.contest-burst {
    font-family: 'Bangers', cursive;
    font-size: 1.25rem;
    letter-spacing: 1px;
    background: var(--accent-color);
    color: #000;
    border: 3px solid #000;
    border-radius: 10px;
    padding: 6px 14px;
    transform: rotate(-3deg);
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.4);
    flex-shrink: 0;
}

.contest-info { flex: 1 1 260px; min-width: 220px; }

.contest-title {
    font-family: 'Bangers', cursive;
    font-size: 1.6rem;
    letter-spacing: 1.5px;
    margin: 0 0 4px;
    color: #fff;
    text-shadow: 2px 2px 0 #000;
}

.contest-sub {
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 0.95rem;
    color: #ffeea8;
    margin: 0;
}

.contest-themes {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 10px;
}

.contest-theme-chip {
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 0.85rem;
    background: #fff;
    color: #000;
    border: 2px solid #000;
    border-radius: 999px;
    padding: 3px 12px;
}

.contest-theme-chip .votes { color: #b3261e; margin-left: 4px; }

.contest-cta {
    font-family: 'Bangers', cursive;
    font-size: 1.15rem;
    letter-spacing: 1px;
    text-decoration: none;
    background: var(--accent-color);
    color: #000;
    padding: 10px 22px;
    border: 3px solid #000;
    border-radius: 12px;
    box-shadow: 4px 4px 0 rgba(0, 0, 0, 0.4);
    transition: transform 0.12s, box-shadow 0.12s;
    flex-shrink: 0;
}

.contest-cta:hover {
    transform: translate(2px, 2px);
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.4);
}

/* --- panel regeneration progress overlay (gallery) --- */
.panel-regen-overlay {
    position: absolute;
    inset: 0;
    z-index: 12;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: rgba(255, 253, 242, 0.78);
    backdrop-filter: blur(1px);
    font-family: 'Bangers', cursive;
    pointer-events: none;
}

.panel-regen-hourglass {
    font-size: 2.4rem;
    line-height: 1;
    animation: panel-regen-flip 1.8s linear infinite;
}

.panel-regen-count {
    font-size: 1.3rem;
    letter-spacing: 1px;
    color: #333;
    text-shadow: 1px 1px 0 #fff;
}

@keyframes panel-regen-flip {
    0%   { transform: rotate(0deg); }
    40%  { transform: rotate(180deg); }
    50%  { transform: rotate(180deg); }
    90%  { transform: rotate(360deg); }
    100% { transform: rotate(360deg); }
}

/* --- character-consistency model guide (create page) --- */
.model-consistency-card {
    background: #fffdf2;
    border: 3px solid #000;
    border-radius: 12px;
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.15);
    padding: 14px 16px;
    font-family: 'Comic Neue', cursive;
    max-width: 560px;
}

/* Hoverable consistency hint next to model selects */
.mcc-hint {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
    font-size: 0.8rem;
    padding: 3px 12px;
    background: var(--accent-color);
    border: 2px solid #000;
    border-radius: 999px;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    cursor: help;
    white-space: nowrap;
    z-index: 20;
}

.mcc-hint:focus {
    outline: 2px solid #000;
    outline-offset: 2px;
}

.mcc-pop {
    display: none;
    position: absolute;
    top: calc(100% + 12px);
    left: 50%;
    transform: translateX(-50%);
    width: min(360px, 88vw);
    z-index: 6000;
    white-space: normal;
}

/* core.js re-anchors the open popover at the viewport level so scroll
   containers (e.g. the regenerate modal's overflow-y: auto) can't clip it;
   left/top/width are set inline from the pill's position. */
.mcc-pop.mcc-pop-fixed {
    position: fixed;
    right: auto;
    transform: none;
}

/* Bridge the gap so the popover doesn't close while moving the cursor down. */
.mcc-pop::after {
    content: '';
    position: absolute;
    bottom: 100%;
    left: 0;
    right: 0;
    height: 14px;
}

/* When flipped above the pill, the gap to bridge is below the popover. */
.mcc-pop.mcc-pop-above::after {
    bottom: auto;
    top: 100%;
}

.mcc-hint:hover,
.mcc-hint:focus,
.mcc-hint:focus-within {
    z-index: 6000;
}

.mcc-hint:hover .mcc-pop,
.mcc-hint:focus .mcc-pop,
.mcc-hint:focus-within .mcc-pop {
    display: block;
}

@media (max-width: 700px) {
    .mcc-pop {
        left: auto;
        right: -10px;
        transform: none;
    }
}

.mcc-title {
    font-family: 'Bangers', cursive;
    font-size: 1.25rem;
    letter-spacing: 1px;
    margin: 0 0 10px;
}

.mcc-row {
    display: grid;
    grid-template-columns: 104px 1fr 36px;
    gap: 10px;
    align-items: center;
    margin: 6px 0;
    font-weight: 700;
    font-size: 0.9rem;
}

/* The name column is a fixed 104px track: anything longer must ellipsize
   instead of wrapping under the bar and stretching the row. The full name is
   on the title attribute. */
.mcc-row span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.mcc-row b { text-align: right; }

.mcc-bar {
    height: 13px;
    border: 2px solid #000;
    border-radius: 99px;
    background: #fff;
    overflow: hidden;
}

.mcc-bar i {
    display: block;
    height: 100%;
    background: var(--accent-color);
}

.mcc-row.is-best .mcc-bar i { background: #4caf50; }

.mcc-note {
    margin: 10px 0 0;
    font-size: 0.85rem;
    color: #555;
    line-height: 1.45;
}

/* ==========================================================================
   Trash empty state + mobile header chrome
   ========================================================================== */
.trash-empty-state {
    max-width: 460px;
    margin: 40px auto;
    background: #fff;
    border: 4px solid #000;
    border-radius: 14px;
    box-shadow: 8px 8px 0 rgba(0, 0, 0, 0.18);
    padding: 36px 28px;
    text-align: center;
    font-family: 'Comic Neue', cursive;
}

.trash-empty-state .trash-empty-icon { font-size: 3.4rem; }

.trash-empty-state h3 {
    font-family: 'Bangers', cursive;
    font-size: 1.9rem;
    letter-spacing: 1.5px;
    margin: 10px 0 6px;
}

.trash-empty-state p { color: #555; margin: 0 0 18px; }

.trash-empty-state .btn { text-decoration: none; display: inline-block; }

@media (max-width: 700px) {
    h1 {
        font-size: 2.3rem;
        text-shadow: 3px 3px 0 var(--accent-color);
    }

    /* Keep the fixed gear clear of the title. */
    header {
        padding-left: 50px;
        padding-right: 50px;
    }

    header p { font-size: 1.05rem; }

    nav {
        font-size: 1.1rem;
        column-gap: 16px;
    }

    :root {
        --toprail-top: 10px;
        --toprail-size: 38px;
    }

    .settings-btn {
        right: 10px;
        font-size: 1.2rem;
    }

    body.has-cookie-banner { padding-bottom: 110px; }
}

/* Language switcher (top-right header cluster) — same pill language as .header-login-pill */
.lang-switcher {
    -webkit-appearance: none;
    appearance: none;
    font-family: 'Bangers', cursive;
    font-size: 1rem;
    letter-spacing: 1px;
    color: #000;
    padding: 1px 26px 3px 14px;
    border: 2px solid #000;
    border-radius: 999px;
    background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E") no-repeat right 9px center;
    cursor: pointer;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.3);
    transition: transform 0.12s, box-shadow 0.12s;
}

.lang-switcher:hover {
    transform: translate(1px, 1px);
    box-shadow: 1px 1px 0 rgba(0, 0, 0, 0.3);
}

.lang-switcher option {
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
}

/* --- Admin: ranking debugger --- */
.ranking-debug-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: flex-end;
    margin-bottom: 12px;
}
.ranking-debug-controls label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.78rem;
    color: #555;
}
.ranking-debug-controls input {
    width: 92px;
    padding: 4px 6px;
    border: 1px solid #ccc;
    border-radius: 6px;
    font: inherit;
}
.ranking-debug-table-wrap {
    overflow: auto;
    max-height: 340px;
}
.ranking-debug-table {
    border-collapse: collapse;
    font-size: 0.8rem;
    white-space: nowrap;
    width: 100%;
}
.ranking-debug-table th,
.ranking-debug-table td {
    padding: 4px 8px;
    border-bottom: 1px solid #eee;
    text-align: right;
}
.ranking-debug-table th:nth-child(2),
.ranking-debug-table td.ranking-debug-story {
    text-align: left;
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.ranking-debug-table thead th {
    position: sticky;
    top: 0;
    background: #fff;
    border-bottom: 2px solid #ddd;
}
.ranking-debug-owner {
    color: #888;
    font-size: 0.72rem;
}

/* ---------------------------------------------------------------------------
   Story share surface (the retired /s/:id page; rules kept for the licence line, see tests/unit/story-license.spec.js)

   Deliberately self-contained: this page is not routable, loads no page module
   and no core.js, and is the first thing a visitor arriving from a shared link
   sees. It must be readable before any JavaScript runs.
   --------------------------------------------------------------------------- */

.story-share-page {
    max-width: 780px;
    margin: 0 auto;
    padding: 24px 16px 64px;
}

.share-header {
    text-align: center;
    margin-bottom: 32px;
}

.share-eyebrow {
    font-family: 'Bangers', 'Comic Neue', cursive;
    letter-spacing: 1px;
    margin-bottom: 4px;
}

.share-eyebrow a {
    color: #000;
    text-decoration: none;
}

.story-share-page h1 {
    font-family: 'Bangers', 'Comic Neue', cursive;
    font-size: clamp(2rem, 7vw, 3rem);
    line-height: 1.1;
    margin: 0 0 8px;
}

.share-byline {
    color: #444;
    margin: 0 0 18px;
}

.share-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
}

.share-cta {
    display: inline-block;
    padding: 10px 18px;
    background: #ffd93d;
    color: #000;
    border: 3px solid #000;
    border-radius: 10px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.25);
    font-family: 'Bangers', 'Comic Neue', cursive;
    letter-spacing: 0.5px;
    text-decoration: none;
}

.share-cta--secondary {
    background: #fff;
}

.share-cta:hover {
    transform: translate(-1px, -1px);
    box-shadow: 5px 5px 0 rgba(0, 0, 0, 0.3);
}

.share-panels {
    display: flex;
    flex-direction: column;
    gap: 28px;
}

.share-panel {
    margin: 0;
    border: 4px solid #000;
    border-radius: 12px;
    overflow: hidden;
    background: #fff;
    box-shadow: 6px 6px 0 rgba(0, 0, 0, 0.18);
}

.share-panel img {
    display: block;
    width: 100%;
    height: auto;
    object-fit: cover;
}

.share-panel-text {
    padding: 12px 16px;
    border-top: 3px solid #000;
}

.share-panel-line {
    margin: 0 0 6px;
    font-family: 'Comic Neue', system-ui, sans-serif;
}

.share-panel-line:last-child {
    margin-bottom: 0;
}

.share-panel-line--bubble::before {
    content: '💬 ';
}

.share-panel-line--caption {
    font-weight: 700;
}

.share-footer {
    margin-top: 48px;
    text-align: center;
    color: #555;
    font-size: 0.9rem;
}

.share-footer a {
    color: #555;
}

/* The pricing page's Free card explains itself when billing is switched off. */
.plan-note {
    margin: 10px 0 0;
    font-size: 0.85rem;
    color: #444;
    line-height: 1.4;
}

/* --- Weekly event generator (admin) --- */
.event-current {
    margin-bottom: 14px;
}
.event-current-card {
    border: 2px solid #ddd;
    border-radius: 8px;
    padding: 10px 12px;
    font-size: 0.85rem;
    background: #fafafa;
}
.event-current-row {
    margin-bottom: 4px;
}
.event-empty {
    font-size: 0.85rem;
    color: #777;
    margin: 0;
}
.event-admin-form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 16px;
}
.event-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 0.78rem;
    color: #555;
}
.event-field input {
    padding: 6px 8px;
    border: 1px solid #ccc;
    border-radius: 6px;
    font: inherit;
}
.event-dates {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}
.event-admin-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}
.event-suggestions-title {
    font-size: 0.9rem;
    margin: 6px 0 10px;
}
.event-suggestions {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 8px;
}
.event-suggestions > * {
    min-width: 0;
}
.event-suggestion {
    text-align: left;
    border: 2px solid #ddd;
    border-radius: 8px;
    background: #fff;
    padding: 8px 10px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    gap: 3px;
    font: inherit;
    transition: border-color 0.12s ease, background 0.12s ease;
}
.event-suggestion:hover {
    border-color: #888;
    background: #fffdf3;
}
.event-suggestion.is-picked {
    border-color: #b45309;
    background: #fff8e6;
}
.event-suggestion-title {
    font-weight: 700;
    font-size: 0.85rem;
}
.event-suggestion-blurb {
    font-size: 0.75rem;
    color: #666;
    line-height: 1.35;
}

/* --- Model speed benchmark (admin) --- */
.model-eta-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    align-items: center;
    margin-bottom: 12px;
}
.model-eta-force {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    color: #555;
}
.model-eta-status {
    font-size: 0.78rem;
    color: #666;
}
.model-eta-status.running {
    color: #b45309;
    font-weight: 600;
}
.model-eta-table-wrap {
    overflow: auto;
    max-height: 340px;
}
.model-eta-table {
    border-collapse: collapse;
    font-size: 0.8rem;
    white-space: nowrap;
    width: 100%;
}
.model-eta-table th,
.model-eta-table td {
    padding: 4px 8px;
    border-bottom: 1px solid #eee;
    text-align: right;
}
.model-eta-table th:first-child,
.model-eta-table td:first-child {
    text-align: left;
    max-width: 260px;
    overflow: hidden;
    text-overflow: ellipsis;
}
.model-eta-table thead th {
    position: sticky;
    top: 0;
    background: #fff;
    border-bottom: 2px solid #ddd;
}
.model-eta-table tr.model-eta-unmeasured td {
    color: #999;
}

/* Licence line on the server-rendered story page. Quieter than the body text:
   it is a legal fact about the comic, not part of the comic. */
.share-license {
    margin: 0 0 6px;
    font-size: 0.85rem;
}

.share-license a {
    color: #555;
}

/* --- The landing page as a comic page (tutorial-derived styling) -----------
   public/tutorial.html reads better than the rest of the site because it
   commits to being a comic: a halftone paper background, sections framed as
   panels with a slight tilt, and Bangers headings with the accent shadow.
   Those three moves are ported here, scoped to body.comic-page so no other
   page shifts. Everything else (cards, grids, toolbar) is untouched. */
body.comic-page {
    background-color: #f6f1e5;
    background-image: radial-gradient(rgba(0, 0, 0, 0.07) 1.2px, transparent 1.2px);
    background-size: 14px 14px;
}

/* The header becomes the issue cover: tilted panel, yellow light-wash. */
body.comic-page > header {
    position: relative;
    max-width: 1300px;
    background: #fff;
    border: 4px solid #000;
    box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
    /* Bottom padding clears the header-controls cluster (login/language),
       which flows under the nav on narrow viewports — no overflow:hidden
       here, or that cluster gets clipped by the cover frame. */
    padding: 34px 24px 56px;
    margin-bottom: 2.2rem;
    transform: rotate(-0.5deg);
}

body.comic-page > header::before {
    content: '';
    position: absolute;
    inset: 0;
    /* Kept inside the frame without overflow:hidden on the header itself. */
    clip-path: inset(0);
    background:
        linear-gradient(120deg, rgba(255, 204, 0, 0.35) 0 22%, transparent 22.5%),
        linear-gradient(-60deg, rgba(255, 204, 0, 0.22) 0 14%, transparent 14.5%);
    pointer-events: none;
}

body.comic-page > header > * {
    position: relative;
}

/* Sections read as panels on the page: alternating micro-tilt, deeper shadow,
   and they straighten on hover like a page being smoothed flat. */
body.comic-page .featured-stories-section,
body.comic-page .stories-toolbar {
    box-shadow: 10px 10px 0 rgba(0, 0, 0, 0.2);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}

body.comic-page .featured-stories-section {
    transform: rotate(-0.35deg);
}

body.comic-page .featured-stories-section:nth-of-type(even) {
    transform: rotate(0.4deg);
}

body.comic-page .featured-stories-section:hover,
body.comic-page .stories-toolbar:hover {
    transform: rotate(0deg);
    box-shadow: 12px 12px 0 rgba(0, 0, 0, 0.22);
}

/* Panel headings get the cover's lettering treatment. */
body.comic-page .featured-stories-header h2 {
    text-shadow: 3px 3px 0 var(--accent-color);
    letter-spacing: 2px;
}

@media (prefers-reduced-motion: reduce) {
    body.comic-page > header,
    body.comic-page .featured-stories-section,
    body.comic-page .stories-toolbar {
        transform: none;
        transition: none;
    }
}

/* The base rule above out-specifies the plain `header { padding-top: 52px }`
   that reserves the fixed feedback fab's band on small screens, so restate the
   clearance here — without it the pill lands straight on the <h1>. */
@media (max-width: 768px) {
    body.comic-page > header {
        padding-top: 52px;
    }
}

@media (max-width: 600px) {
    /* Tilts read as broken layout on a narrow screen. */
    body.comic-page > header,
    body.comic-page .featured-stories-section,
    body.comic-page .featured-stories-section:nth-of-type(even) {
        transform: none;
    }

    body.comic-page > header {
        padding: 52px 14px 16px;
    }
}

/* --- Mask mode of the edit modal (#editMaskSection): brush a region,
   describe what belongs there --------------------------------------------- */
.inpaint-hint {
    margin: 0 0 12px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    color: #555;
}

/* The canvas sits exactly on top of the image, so the stroke the user sees is
   the stroke that becomes the mask. Both are sized by the image's own aspect
   ratio; the canvas keeps its natural pixel dimensions underneath. */
.inpaint-stage {
    position: relative;
    display: block;
    max-height: 52vh;
    margin: 0 auto 12px;
    line-height: 0;
}

.inpaint-stage img,
.inpaint-stage canvas {
    display: block;
    width: 100%;
    max-height: 52vh;
    object-fit: contain;
    border: 3px solid #000;
    border-radius: 6px;
}

.inpaint-stage canvas {
    position: absolute;
    inset: 0;
    border-color: transparent;
    cursor: crosshair;
    touch-action: none;
}

.inpaint-tools {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
    font-family: 'Comic Neue', cursive;
    font-weight: 700;
}

.inpaint-tools input[type="range"] {
    flex: 1;
    min-width: 100px;
}

/* Stop button inside the generation overlay. Deliberately quiet next to the
   spinner — it is an escape hatch, not the primary action — but it stays a
   real button (not a text link) because it performs an action on this page
   rather than navigating. */
.stop-generation-btn {
    margin-top: 18px;
    padding: 8px 18px;
    background: #fff;
    color: #000;
    border: 3px solid #000;
    border-radius: 8px;
    box-shadow: 3px 3px 0 rgba(0, 0, 0, 0.25);
    font-family: 'Bangers', 'Comic Neue', cursive;
    font-size: 1rem;
    letter-spacing: 0.5px;
    cursor: pointer;
}

.stop-generation-btn:hover:not(:disabled) {
    background: #ffd93d;
}

.stop-generation-btn:disabled {
    opacity: 0.55;
    cursor: default;
}

.stop-generation-btn:focus-visible {
    outline: 2px solid #000;
    outline-offset: 2px;
}

/* Which model generated this version — one quiet line per history entry. */
.history-model {
    font-family: 'Comic Neue', cursive;
    font-size: 0.75rem;
    color: #666;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* The keyless Pollinations connect, sitting in the quick-create meta row. */
.quick-create-connect {
    display: inline-block;
    padding: 2px 10px;
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 700;
    color: #1a1a1a;
    background: #fff;
    border: 2px solid #1a1a1a;
    border-radius: 6px;
    cursor: pointer;
    vertical-align: baseline;
}

.quick-create-connect:hover {
    background: #f2f2f2;
}

/* ---- Gallery on phones: stacked panels, icon-only action bar ----
   Stories carry a desktop panel layout (gallery.js writes it as inline
   grid-template-columns on the grid and grid-column/row spans on each panel),
   which put three panels side by side on a 390px screen. On a phone the panels
   read one after another, full width, and the whole image shows. */
@media (max-width: 600px) {
    .comic-grid {
        grid-template-columns: minmax(0, 1fr) !important;
        grid-auto-flow: row !important;
        gap: 1.25rem;
    }

    .comic-grid .panel {
        grid-column: auto !important;
        grid-row: auto !important;
        width: 100%;
        max-width: 100%;
    }

    .panel-image-wrapper {
        height: auto !important;
    }

    .panel img {
        width: 100%;
        height: auto !important;
        object-fit: contain;
        transform: none;
    }

    /* Action bar: only the icons, the label spans are for wider screens. The
       two-column button grid the 600px block above builds is for labelled
       buttons; icons sit in one right-aligned row. The 10px side padding is
       the comic grid's own, so the bar ends flush with the panel edges. */
    .panel-action-bar {
        gap: 6px;
        padding: 0 10px;
    }

    /* The mobile Regenerate bar carries a 5px margin-top (600px block above)
       that showed as a white strip between the art and the bar. */
    .comic-grid .panel .regenerate-btn {
        margin-top: 0;
    }

    /* Upvote sits centred directly above the panels on phones (gallery.js
       moves it there); Report mirrors it below. */
    .story-reactions.is-above-grid {
        display: flex;
        justify-content: center;
        margin: 0 0 10px;
    }

    .panel-actions-left,
    .panel-actions-right {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
    }

    .panel-actions-right {
        justify-content: flex-end;
    }

    .panel-actions-right .toggle-details-btn {
        width: auto;
    }

    /* View mode hides the header, which leaves the Previous pill in the band
       the fixed feedback fab occupies (top:12px, ~40px tall). */
    body.slides-view-active #prevStoryBtn {
        margin-top: 60px;
    }

    .panel-action-bar .toggle-details-btn {
        padding: 0 9px;
        min-height: 34px;
        min-width: 34px;
        font-size: 1.05rem;
    }

    .panel-action-bar .btn-label {
        display: none;
    }

    #toggleDetailsBtn,
    #togglePreviewCardBtn {
        padding-right: 9px;
    }

    #toggleDetailsBtn::after,
    #togglePreviewCardBtn::after {
        display: none;
    }
}

/* Report sits below the comic (all widths) — off the title row, where it
   competed with the story name on a phone. */
.story-report-row {
    display: flex;
    justify-content: center;
    margin: 18px 0 8px;
    font-family: 'Comic Neue', cursive;
}

/* ---- Account menu (public/account-menu.js) ---- */
.account-menu-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
    min-width: 0;
}

.account-menu-head .account-menu-name {
    font-family: 'Bangers', cursive;
    letter-spacing: 1px;
    font-size: 1.5rem;
    line-height: 1.1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.account-menu-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 12px;
    background: #e0e0e0;
    border-radius: 20px;
    padding: 3px;
}

.account-menu-tab {
    flex: 1;
    padding: 6px 12px;
    background: transparent;
    border: none;
    border-radius: 17px;
    font-family: 'Comic Neue', cursive;
    font-size: 0.9rem;
    font-weight: bold;
    cursor: pointer;
    color: #666;
}

.account-menu-tab.active {
    background: #000;
    color: #fff;
}

.account-menu-pane {
    min-height: 120px;
    max-height: 50vh;
    overflow-y: auto;
}

.account-menu-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.account-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px;
    border: 2px solid #000;
    border-radius: 8px;
    background: #fff;
    color: #000;
    text-decoration: none;
    box-shadow: 2px 2px 0 rgba(0, 0, 0, 0.2);
    min-width: 0;
}

.account-menu-item:hover {
    background: #fffbe6;
}

.account-menu-item img {
    width: 56px;
    height: 42px;
    object-fit: cover;
    border: 2px solid #000;
    border-radius: 4px;
    flex: 0 0 auto;
    background: #eee;
}

.account-menu-item-title {
    font-weight: bold;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.account-menu-item-meta {
    font-size: 0.8rem;
    color: #666;
}

.account-menu-muted {
    color: #666;
    text-align: center;
    padding: 20px 0;
}

.account-menu-pro-status {
    font-weight: bold;
    padding: 10px 12px;
    border: 2px solid #000;
    border-radius: 8px;
    background: #fffbe6;
    margin-bottom: 12px;
}

.account-menu-pro-status.is-pro {
    background: var(--accent-color);
}

.account-menu-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 16px;
}

.account-menu-actions .btn {
    flex: 1 1 auto;
    justify-content: center;
}

/* Phones/tablets: the title row becomes a two-column grid so the Edit/View
   toggle can sit on the title's underline (its bottom = the h2's bottom,
   whatever the title's line count) with the "by …" line underneath both. */
@media (max-width: 900px) {
    .story-title-row {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: end;
        column-gap: 10px;
    }

    .story-title-left {
        display: contents;
    }

    #viewerTitle {
        grid-column: 1;
        grid-row: 1;
        min-width: 0;
    }

    .title-row-toggle {
        grid-column: 2;
        grid-row: 1;
        align-self: end;
        margin-left: 0;
    }

    #storyCreator {
        grid-column: 1 / -1;
        grid-row: 2;
        margin-left: 0 !important;
    }

    .story-title-row > .story-reactions {
        grid-column: 1 / -1;
        margin-left: 0;
    }

    /* Next Story lives inside the viewer on phones (gallery.js moves it
       there, above the comments): a centred pill, a size up from Previous. */
    main.comic-viewer > #nextStoryBtn {
        width: fit-content;
        margin: 18px auto 6px;
        padding: 8px 20px 8px 14px;
        gap: 6px;
        border-width: 3px;
        box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.25);
    }

    main.comic-viewer > #nextStoryBtn svg {
        width: 26px;
        height: 26px;
    }

    main.comic-viewer > #nextStoryBtn .nav-arrow-label {
        font-size: 1.05rem;
    }
}

/* API-key fields in the settings modal: masked like a password, but a plain
   text input so no password manager treats the settings modal as a login form
   (Brave autofilled the account password into the first key field and asked
   to save it on every gallery navigation). Firefox honours the prefix too. */
.settings-row input.api-key-input {
    -webkit-text-security: disc;
}
