/*
 * GENERATE-BUTTON.CSS - Unified Generate Button
 * 
 * Tank-tread style with stadium shape
 * Speed ramps: idle (12s) → hover (4s) → active (1.5s) → generating (0.8s)
 */

/* @property for CSS animation */
@property --angle {
    syntax: '<angle>';
    initial-value: 0deg;
    inherits: false;
}

@keyframes rotate-treads {
    to { --angle: 360deg; }
}

/* Sparkle wiggle for icon */
@keyframes sparkle-idle {
    0%, 100% { transform: rotate(0deg) scale(1); }
    25% { transform: rotate(-5deg) scale(1.02); }
    75% { transform: rotate(5deg) scale(1.02); }
}

@keyframes sparkle-hover {
    0%, 100% { transform: rotate(0deg) scale(1.1); }
    50% { transform: rotate(15deg) scale(1.15); }
}

/* ═══════════════════════════════════════════════════════════════════
   GENERATE BUTTON - Base Component (Stadium/Pill Shape)
   ═══════════════════════════════════════════════════════════════════ */

.generate-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.6rem 1.2rem;
    min-height: 38px;
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--secondary) 30%, var(--card-base)) 0%,
            color-mix(in srgb, var(--secondary) 18%, var(--card-base)) 100%);
    border: none;
    border-radius: 999px;  /* Stadium shape */
    /* Slot-tinted grey label — was a slot-11/slot-2 mix that vanished when
       both lighting and eyes were dark. Grey floor keeps it readable; the
       slot-2 tint adds character on bright palettes. */
    color: color-mix(in srgb, var(--secondary) 30%, var(--ui-text-strong));
    cursor: pointer;
    transition: all 0.15s ease;
    box-shadow:
        0 3px 8px rgba(0, 0, 0, 0.5),
        0 0 15px color-mix(in srgb, var(--secondary) 15%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.1),
        inset 0 -2px 4px rgba(0, 0, 0, 0.2);
    position: relative;
    isolation: isolate;  /* Stacking context so ::before z-index:-1 stays inside */
    background-clip: padding-box;
}

/* Tank treads — 12 chunky segments alternating two tread colors.
   --tread-a: hair (--primary).  --tread-b: eyes (--secondary) so treads always
   contrast tread-a and stay visible — both roles are always present. 30°
   per tread+gap pair, with each tread filling 60% (18° tread + 12° gap). */
.generate-btn::before {
    --tread-a: var(--primary);
    --tread-b: var(--secondary);

    content: '';
    position: absolute;
    inset: -3px;
    border-radius: 999px;
    background: conic-gradient(
        from var(--angle, 0deg),
        var(--tread-a) 0deg 18deg,
        transparent 18deg 30deg,
        var(--tread-b) 30deg 48deg,
        transparent 48deg 60deg,
        var(--tread-a) 60deg 78deg,
        transparent 78deg 90deg,
        var(--tread-b) 90deg 108deg,
        transparent 108deg 120deg,
        var(--tread-a) 120deg 138deg,
        transparent 138deg 150deg,
        var(--tread-b) 150deg 168deg,
        transparent 168deg 180deg,
        var(--tread-a) 180deg 198deg,
        transparent 198deg 210deg,
        var(--tread-b) 210deg 228deg,
        transparent 228deg 240deg,
        var(--tread-a) 240deg 258deg,
        transparent 258deg 270deg,
        var(--tread-b) 270deg 288deg,
        transparent 288deg 300deg,
        var(--tread-a) 300deg 318deg,
        transparent 318deg 330deg,
        var(--tread-b) 330deg 348deg,
        transparent 348deg 360deg
    );
    opacity: 0.6;
    animation: rotate-treads 20s linear infinite;  /* Idle — barely crawling */
    pointer-events: none;
    z-index: -1;
    -webkit-mask: 
        linear-gradient(#fff 0 0) content-box, 
        linear-gradient(#fff 0 0);
    mask: 
        linear-gradient(#fff 0 0) content-box, 
        linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    padding: 3px;
}

/* Hover - lift up, treads speed up */
.generate-btn:hover {
    transform: translateY(-2px);
    background:
        linear-gradient(180deg,
            color-mix(in srgb, var(--secondary) 40%, var(--card-base)) 0%,
            color-mix(in srgb, var(--secondary) 25%, var(--card-base)) 100%);
    box-shadow:
        0 6px 16px rgba(0, 0, 0, 0.5),
        0 0 25px color-mix(in srgb, var(--secondary) 25%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.15),
        inset 0 -2px 4px rgba(0, 0, 0, 0.15);
}

.generate-btn:hover::before {
    opacity: 0.8;
    animation-duration: 4s;
    animation-play-state: running;  /* Wake up on hover */
}

/* Active/Press - clamp down hard */
.generate-btn:active {
    transform: translateY(2px);
    box-shadow:
        0 1px 4px rgba(0, 0, 0, 0.6),
        0 0 8px color-mix(in srgb, var(--secondary) 20%, transparent),
        inset 0 3px 8px rgba(0, 0, 0, 0.4);
}

.generate-btn:active::before {
    opacity: 0.9;
    animation-duration: 1.5s;  /* Fast spin on press */
}

/* Icon - gentle idle animation */
.generate-btn .generate-icon {
    font-size: 1rem;
    filter: drop-shadow(0 0 6px color-mix(in srgb, var(--secondary) 60%, transparent));
    animation: sparkle-idle 3s ease-in-out infinite;
}

.generate-btn:hover .generate-icon {
    animation: sparkle-hover 0.6s ease-in-out infinite;
}

/* Label */
.generate-btn .generate-label {
    font-size: 0.65rem;
    font-weight: 700;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-shadow: 0 0 10px color-mix(in srgb, var(--secondary) 50%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════
   PROGRESS GAUGE - Matches view page: black track + accent fill
   Icon and label hide, gauge replaces them inline.
   ═══════════════════════════════════════════════════════════════════ */

.generate-btn .progress-gauge {
    display: none;
    align-items: center;
    gap: 0.6rem;
    width: 100%;
}

.generate-btn .progress-bar {
    flex: 1;
    height: 6px;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 3px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.1);
}

.generate-btn .progress-bar-fill {
    height: 100%;
    width: 0%;
    background: linear-gradient(90deg,
        var(--secondary) 0%,
        color-mix(in srgb, var(--secondary) 70%, white) 100%);
    border-radius: 2px;
    transition: width 0.15s ease-out;
    box-shadow: 0 0 8px var(--secondary);
}

.generate-btn .progress-percent {
    display: none;
}

/* ═══════════════════════════════════════════════════════════════════
   GENERATING STATE - Hide icon, show status label + gauge, fast treads
   ═══════════════════════════════════════════════════════════════════ */

/* Generating: hide sparkle, show label centered */
.generate-btn.generating .generate-icon {
    display: none;
}

.generate-btn.generating .generate-label {
    font-size: 0.5rem;
    letter-spacing: 0.06em;
    opacity: 0.85;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Progress gauge hidden by default during generating —
   only shown when WebSocket progress actually kicks in */
.generate-btn.generating .progress-gauge {
    display: none;
}

/* Progress (WebSocket): hide label, show gauge full width */
.generate-btn.generating.status-progress .generate-label {
    display: none;
}

.generate-btn.generating.status-progress .progress-gauge {
    display: flex;
    flex: 1;
}

.generate-btn.generating {
    transform: translateY(1px);
    box-shadow:
        0 2px 6px rgba(0, 0, 0, 0.5),
        0 0 20px color-mix(in srgb, var(--secondary) 30%, transparent),
        inset 0 2px 6px rgba(0, 0, 0, 0.3);
}

/* Tread speed: 3 gears — slow / fast / fastest
   Idle is paused. Thinking = slow cruise. Streaming/queued = fast.
   Progress (ComfyUI) = fastest. */
.generate-btn.generating::before {
    opacity: 0.9;
    animation-play-state: running;
    /* Default for any .generating state without a more specific rule —
       tool-call statuses (status-generatescene, status-quickscene, etc.)
       land here. Slower than the gen gears so tool-call moments feel
       deliberate; a fleeting tool call still moves visibly. */
    animation-duration: 10s;
}

.generate-btn.generating.status-thinking::before {
    animation-duration: 6s;  /* Gear 1 — slow cruise */
}

.generate-btn.generating.status-streaming::before {
    animation-duration: 1.5s;  /* Gear 2 — fast */
}

.generate-btn.generating.status-queued::before {
    animation-duration: 1.5s;  /* Gear 2 — fast (same as streaming) */
}

.generate-btn.generating.status-progress::before {
    /* Gear 3 — fastest, ComfyUI cranking. At 0.5s the eye reads the
       fast-spinning 10 treads as a denser phantom-tread band thanks
       to a 1:3 harmonic with the screen refresh rate; the user
       prefers the faster feel anyway. */
    animation-duration: 0.5s;
}

.generate-btn.generating.status-crystallize::before {
    /* Crystallize — short LLM calls (greeting-description on reset, card
       import). Sped from the original 12s to match the "this should feel
       responsive" expectation now that crystallize is the most common
       in-flight state on the page. */
    animation-duration: 1.5s;
}

.generate-btn.generating.status-prompt::before {
    /* HAL prompt-card lockout — the system is waiting on the user, not
       working. Slow-jog pace: noticeably faster than idle (20s) so the
       lock reads as live, but slower than crystallize (1.5s) and the
       gen gears so it's distinct from "AI is doing something." 4s
       matches the hover speed so it reads as "the button is awake." */
    animation-duration: 4s;
}

/* Pump while generating — .generating's translateY(1px) ties the base
   :active rule on specificity (both 0,2,0) and wins by source order,
   so clicks during generation produced no visible press. Re-press from
   the 1px resting state down to 3px so each click pumps another 2px. */
.generate-btn.generating:active {
    transform: translateY(3px);
    box-shadow:
        0 1px 4px rgba(0, 0, 0, 0.6),
        0 0 8px color-mix(in srgb, var(--secondary) 20%, transparent),
        inset 0 3px 8px rgba(0, 0, 0, 0.4);
}

.strip-generate-btn.generating:active {
    transform: translateY(3px) scale(0.98);
}

/* ═══════════════════════════════════════════════════════════════════
   GENERATE CARD - Placeholder front when no image exists
   Grid + gradient using character slot colors, centered generate button
   ═══════════════════════════════════════════════════════════════════ */

.generate-card {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(
        160deg,
        color-mix(in srgb, var(--secondary) 18%, color-mix(in srgb, var(--card-base) 70%, black)) 0%,
        color-mix(in srgb, var(--secondary) 8%, color-mix(in srgb, var(--card-base) 75%, black)) 45%,
        color-mix(in srgb, var(--card-base) 70%, black) 100%);
    overflow: hidden;
}

.generate-card-grid {
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(
            color-mix(in srgb, var(--secondary) 8%, transparent) 1px,
            transparent 1px),
        linear-gradient(90deg,
            color-mix(in srgb, var(--secondary) 8%, transparent) 1px,
            transparent 1px);
    background-size: 20px 20px;
    mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, black 0%, transparent 100%);
    -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, black 0%, transparent 100%);
}

/* Centered round button above the grid */
.generate-card .card-generate-btn {
    position: relative;
    z-index: 6;
    width: calc(140px * var(--card-zoom, 1));
    height: calc(140px * var(--card-zoom, 1));
    padding: 0;
    border-radius: 50%;
    margin: 0;
}

.generate-card .card-generate-btn::before {
    border-radius: 50%;
}

/* Don't let the action-deck pill rule (.card-generate-btn.generating
   { min-width: 140px }) leak onto the round generate-card button.
   When --card-zoom is < 1 the calc'd width drops below 140px, the
   min-width pins horizontal back to 140 while height shrinks normally
   → oval. The oval also distorts the conic-gradient treads, making
   them look packed/extra at the sides. */
.generate-card .card-generate-btn.generating {
    min-width: 0;
}

.generate-card .generate-icon {
    font-size: calc(3rem * var(--card-zoom, 1));
}

.generate-card .generate-label {
    display: none;
}

/* Hide percentage on generate card — the ring is enough */
.generate-card .progress-percent {
    display: none;
}

/* Progress ring — sits just inside the button edge like a disc brake */
.generate-card .progress-gauge {
    position: absolute;
    inset: calc(6px * var(--card-zoom, 1));
    width: auto;
    height: auto;
    border-radius: 50%;
    pointer-events: none;
}

.generate-card .progress-bar {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    background: transparent;
    border: calc(4px * var(--card-zoom, 1)) solid rgba(255, 255, 255, 0.04);
    border-radius: 50%;
    overflow: visible;
}

.generate-card .progress-bar-fill {
    position: absolute;
    inset: 0;
    width: auto !important;  /* Override JS inline width */
    height: auto;
    background: transparent;
    border: calc(4px * var(--card-zoom, 1)) solid var(--secondary);
    border-radius: 50%;
    box-shadow:
        0 0 8px color-mix(in srgb, var(--secondary) 60%, transparent),
        inset 0 0 8px color-mix(in srgb, var(--secondary) 30%, transparent);
    /* Clip arc via conic mask — JS updates --progress custom property */
    mask: conic-gradient(from 0deg, black var(--progress, 0%), transparent var(--progress, 0%));
    -webkit-mask: conic-gradient(from 0deg, black var(--progress, 0%), transparent var(--progress, 0%));
}

/* ── Elements toggle — spinning color ring from character's slot colors ── */
/* Pinned to the top-left corner of the generate button */
.card-front-elements-toggle {
    display: none;
    position: absolute;
    top: 0.5rem;
    right: calc(0.5rem + 60px * var(--card-zoom, 1) + 0.3rem);
    z-index: 6;
    width: calc(40px * var(--card-zoom, 1));
    height: calc(40px * var(--card-zoom, 1));
    padding: 0;
    border-radius: 50%;
    border: none;
    background: transparent;
    cursor: pointer;
    transition: transform 0.2s, filter 0.3s;
}

.strip-card.centered .card-front-elements-toggle {
    display: block;
}

/* The ring — conic gradient of slot colors, slow spin */
.card-front-elements-toggle::before {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: 50%;
    background: var(--ring-gradient, conic-gradient(rgba(255,255,255,0.1), rgba(255,255,255,0.05), rgba(255,255,255,0.1)));
    animation: element-ring-spin 8s linear infinite;
    opacity: 0.5;
    transition: opacity 0.3s;
}

/* Dark center — makes it a ring, not a disc */
.card-front-elements-toggle::after {
    content: '';
    position: absolute;
    inset: calc(4px * var(--card-zoom, 1));
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.7);
    transition: background 0.3s;
}

/* Icon sits above the pseudo-elements */
.card-front-elements-toggle .toggle-icon {
    position: relative;
    z-index: 1;
    font-size: calc(0.85rem * var(--card-zoom, 1));
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.8));
    opacity: 0.6;
    transition: opacity 0.3s;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.card-front-elements-toggle:hover {
    transform: scale(1.15);
}

.card-front-elements-toggle:hover::before {
    opacity: 0.8;
    animation-duration: 3s;
}

/* Active — ring glows, spins faster, center lit */
.card-front-elements-toggle.active::before {
    opacity: 1;
    animation-duration: 4s;
    box-shadow: 0 0 12px color-mix(in srgb, var(--secondary) 40%, transparent);
}

.card-front-elements-toggle.active::after {
    background: color-mix(in srgb, var(--primary) 25%, rgba(0, 0, 0, 0.5));
}

.card-front-elements-toggle.active .toggle-icon {
    opacity: 1;
}

@keyframes element-ring-spin {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* Module element bubbles — card front overlay (from appearance API) */
.module-elements {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 0.3rem;
}

.module-element-bubble {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    font-size: 0.6rem;
    font-weight: 500;
    border-radius: 10px;
    background: color-mix(in srgb, var(--bubble-color) 25%, var(--card-base));
    border: 1px solid color-mix(in srgb, var(--bubble-color) 60%, transparent);
    border-left-width: 3px;
    color: color-mix(in srgb, var(--bubble-color) 90%, white);
    white-space: nowrap;
    transition: all 0.15s ease;
}

.module-element-bubble:hover {
    background: color-mix(in srgb, var(--bubble-color) 40%, var(--card-base));
    border-color: var(--bubble-color);
    box-shadow: 0 0 8px color-mix(in srgb, var(--bubble-color) 40%, transparent);
    transform: scale(1.05);
}

/* Preview variant — gradient only, no button (for card back image area) */
.generate-card-preview {
    width: 100%;
    height: 100%;
    background: linear-gradient(
        160deg,
        color-mix(in srgb, var(--secondary) 18%, color-mix(in srgb, var(--card-base) 70%, black)) 0%,
        color-mix(in srgb, var(--secondary) 8%, color-mix(in srgb, var(--card-base) 75%, black)) 45%,
        color-mix(in srgb, var(--card-base) 70%, black) 100%);
    border-radius: inherit;
    cursor: pointer;
}


/* ═══════════════════════════════════════════════════════════════════
   CONTEXT: STRIP (Below Carousel) - Larger version
   ═══════════════════════════════════════════════════════════════════ */

.strip-generate-btn {
    order: 3;
    align-self: center;
    margin: 1rem auto;
    padding: 0.8rem 2rem;
    min-height: 48px;
    box-shadow: 
        0 4px 12px rgba(0, 0, 0, 0.5),
        0 0 25px color-mix(in srgb, var(--secondary) 20%, transparent),
        inset 0 1px 0 rgba(255, 255, 255, 0.12),
        inset 0 -2px 6px rgba(0, 0, 0, 0.25);
}

.strip-generate-btn::before {
    inset: -4px;
    padding: 4px;
}

.strip-generate-btn:hover {
    transform: translateY(-3px) scale(1.02);
}

.strip-generate-btn:active {
    transform: translateY(2px) scale(0.98);
}

.strip-generate-btn .generate-icon {
    font-size: 1.3rem;
}

.strip-generate-btn .generate-label {
    font-size: 0.8rem;
    letter-spacing: 0.12em;
}

.strip-generate-btn.generating {
    padding: 0.8rem 1.5rem;
    min-width: 180px;
}

/* Queue count badge */
.generate-btn .queue-count {
    position: absolute;
    top: -8px;
    right: -8px;
    min-width: 22px;
    height: 22px;
    padding: 0 5px;
    background: linear-gradient(180deg, 
        var(--secondary) 0%,
        color-mix(in srgb, var(--secondary) 60%, #000) 100%);
    border: 2px solid rgba(0, 0, 0, 0.6);
    border-radius: 11px;
    color: white;
    font-size: 0.65rem;
    font-weight: 700;
    font-family: 'SF Mono', Monaco, monospace;
    line-height: 18px;
    text-align: center;
    box-shadow: 
        0 2px 6px rgba(0, 0, 0, 0.5),
        0 0 10px color-mix(in srgb, var(--secondary) 40%, transparent);
    z-index: 15;
}

/* ═══════════════════════════════════════════════════════════════════
   CONTEXT: CARD BACK (Action Deck) - Same proportions as strip
   ═══════════════════════════════════════════════════════════════════ */

.card-generate-btn {
    /* DON'T stretch - fixed size like strip button */
    flex: 0 0 auto;
    padding: 0.6rem 1.5rem;
    min-height: 38px;
    margin-left: auto;  /* Push to right side of action deck */
}

.card-generate-btn::before {
    inset: -3px;
    padding: 3px;
}

.card-generate-btn.generating {
    min-width: 140px;
}

/* ═══════════════════════════════════════════════════════════════════
   CONTEXT: NAVBAR BRAND - Same as card-front-generate but always active
   (card-front-generate is inside @media max-width:768px)
   ═══════════════════════════════════════════════════════════════════ */

.navbar-generate-btn {
    flex: 0 0 36px;
    width: 36px;
    height: 36px;
    padding: 0;
    border-radius: 50%;
    min-height: 0;
    box-shadow: none;
}

.navbar-generate-btn:hover {
    transform: translateY(-2px);
    box-shadow: none;
}

.navbar-generate-btn::before {
    border-radius: 50%;
    inset: -2px;
    padding: 2px;
    animation: rotate-treads 8s linear infinite;
}

.navbar-generate-btn .generate-icon {
    font-size: 0.9rem;
}

.navbar-generate-btn .generate-label {
    display: none;
}

/* Progress ring — same as card-front-generate */
.navbar-generate-btn .progress-gauge {
    position: absolute;
    inset: 2px;
    width: auto;
    height: auto;
    border-radius: 50%;
    pointer-events: none;
}

.navbar-generate-btn .progress-bar {
    position: absolute;
    inset: 0;
    width: auto;
    height: auto;
    background: transparent;
    border: 2px solid rgba(255, 255, 255, 0.04);
    border-radius: 50%;
    overflow: visible;
}

.navbar-generate-btn .progress-bar-fill {
    position: absolute;
    inset: 0;
    width: auto !important;
    height: auto;
    background: transparent;
    border: 2px solid var(--secondary);
    border-radius: 50%;
    box-shadow: 0 0 6px color-mix(in srgb, var(--secondary) 60%, transparent);
    mask: conic-gradient(from 0deg, black var(--progress, 0%), transparent var(--progress, 0%));
    -webkit-mask: conic-gradient(from 0deg, black var(--progress, 0%), transparent var(--progress, 0%));
}

.navbar-generate-btn .generate-label {
    display: none;
}

/* ═══════════════════════════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════════════════════════ */

@media (max-width: 700px) {
    .strip-generate-btn {
        padding: 0.6rem 1.5rem;
        min-height: 42px;
    }
    
    .strip-generate-btn .generate-icon {
        font-size: 1.1rem;
    }
    
    .strip-generate-btn .generate-label {
        font-size: 0.7rem;
    }
    
    .strip-generate-btn.generating {
        min-width: 150px;
    }
}