* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}


body {
    min-height: 100vh;
    background: #05010c;
    color: #e8dcff;
    font-family: Arial, Helvetica, sans-serif;
    overflow-x: hidden;
}


:root {
    --bg-opacity: 0.09;
    --font-modern: 'Space Grotesk', Arial, Helvetica, sans-serif;
}


.bg-layer {
    position: fixed;

    top: -10%;
    left: -10%;
    width: 120%;
    height: 120%;

    z-index: -1;
    pointer-events: none;

    background-image:
        url("../assets/background/Background.png"),
        radial-gradient(circle at 20% 10%, #1b0733 0%, transparent 45%),
        radial-gradient(circle at 85% 80%, #2a0a4a 0%, transparent 50%),
        linear-gradient(160deg, #05010c 0%, #0b0116 40%, #170025 100%);

    background-size: cover, cover, cover, cover;
    background-position: center, center, center, center;
    background-repeat: no-repeat;

    opacity: var(--bg-opacity);

    transition: transform 0.25s ease-out, opacity 0.3s ease;

    will-change: transform;
}


.app {
    min-height: 100vh;

    display: grid;

    grid-template-columns: 400px minmax(0, 1fr);

    position: relative;
}


/*
 * @property registration lets these two custom properties (the
 * left panel's gradient stops) be treated as animatable <color>
 * values - without this, browsers can't smoothly interpolate a
 * linear-gradient's colors when they change, they just hard-cut.
 */
@property --left-panel-grad-a {
    syntax: '<color>';
    inherits: true;
    initial-value: #0c0316;
}

@property --left-panel-grad-b {
    syntax: '<color>';
    inherits: true;
    initial-value: #140524;
}

@property --lp-dim {
    syntax: '<color>';
    inherits: true;
    initial-value: #3a1a5c;
}

@property --lp-soft {
    syntax: '<color>';
    inherits: true;
    initial-value: #4a2270;
}

@property --lp-mid {
    syntax: '<color>';
    inherits: true;
    initial-value: #9147d6;
}

@property --lp-bright {
    syntax: '<color>';
    inherits: true;
    initial-value: #d59bff;
}

@property --lp-text {
    syntax: '<color>';
    inherits: true;
    initial-value: #9a7cc9;
}

@property --lp-text-dim {
    syntax: '<color>';
    inherits: true;
    initial-value: #5c4880;
}

@property --lp-hover-bg {
    syntax: '<color>';
    inherits: true;
    initial-value: #2a1145;
}

@property --lp-surface {
    syntax: '<color>';
    inherits: true;
    initial-value: #14061f;
}

@property --lp-surface-hover {
    syntax: '<color>';
    inherits: true;
    initial-value: #20103a;
}

@property --lp-selected-a {
    syntax: '<color>';
    inherits: true;
    initial-value: #4a1c85;
}

@property --lp-selected-b {
    syntax: '<color>';
    inherits: true;
    initial-value: #7a2fc4;
}


.left-panel {
    padding: 26px;

    --left-panel-grad-a: #0c0316;
    --left-panel-grad-b: #140524;

    --lp-dim: #3a1a5c;
    --lp-soft: #4a2270;
    --lp-mid: #9147d6;
    --lp-bright: #d59bff;
    --lp-text: #9a7cc9;
    --lp-text-dim: #5c4880;
    --lp-hover-bg: #2a1145;
    --lp-surface: #14061f;
    --lp-surface-hover: #20103a;
    --lp-selected-a: #4a1c85;
    --lp-selected-b: #7a2fc4;

    background: linear-gradient(180deg, var(--left-panel-grad-a) 0%, var(--left-panel-grad-b) 100%);

    border-right: 1px solid #3a1a5c;
    box-shadow: inset -1px 0 20px rgba(150, 60, 220, 0.08);

    overflow-y: auto;

    transition:
        border-color 0.45s ease,
        box-shadow 0.45s ease,
        --left-panel-grad-a 0.45s ease,
        --left-panel-grad-b 0.45s ease,
        --lp-dim 0.45s ease,
        --lp-soft 0.45s ease,
        --lp-mid 0.45s ease,
        --lp-bright 0.45s ease,
        --lp-text 0.45s ease,
        --lp-text-dim 0.45s ease,
        --lp-hover-bg 0.45s ease,
        --lp-surface 0.45s ease,
        --lp-surface-hover 0.45s ease,
        --lp-selected-a 0.45s ease,
        --lp-selected-b 0.45s ease;
}


/* Matches the Upgrade Shop Calculator's blue/cyan theme (see
   Upgrades.css) while that panel is open. */
.left-panel.left-panel--upgrades {
    --left-panel-grad-a: #03121c;
    --left-panel-grad-b: #061424;

    --lp-dim: #0d3a52;
    --lp-soft: #1c6f96;
    --lp-mid: #2f8fc2;
    --lp-bright: #8fd9ff;
    --lp-text: #8fd9ff;
    --lp-text-dim: #4a7a91;
    --lp-hover-bg: #0a2440;
    --lp-surface: #061a29;
    --lp-surface-hover: #0b3047;
    --lp-selected-a: #0d3a52;
    --lp-selected-b: #2f8fc2;

    border-right-color: rgba(143, 217, 255, 0.55);
    box-shadow: inset -1px 0 26px rgba(143, 217, 255, 0.16);
}


/* Matches the Death Tracker's red/danger theme while that panel is
   open. */
.left-panel.left-panel--death {
    --left-panel-grad-a: #1c0505;
    --left-panel-grad-b: #240a0a;

    --lp-dim: #4a1010;
    --lp-soft: #7a1f1f;
    --lp-mid: #c23a3a;
    --lp-bright: #ff9d9d;
    --lp-text: #e0a3a3;
    --lp-text-dim: #8a5c5c;
    --lp-hover-bg: #3a0a0a;
    --lp-surface: #260909;
    --lp-surface-hover: #461010;
    --lp-selected-a: #5c0a0a;
    --lp-selected-b: #c23a3a;

    border-right-color: rgba(255, 157, 157, 0.55);
    box-shadow: inset -1px 0 26px rgba(174, 19, 19, 0.18);
}


.site-header {
    margin-bottom: 32px;
}

.live-viewer-badge {
    position: relative;

    display: flex;
    align-items: center;
    gap: 6px;

    padding: 5px 10px;

    background: color-mix(in srgb, var(--lp-surface, #14061f) 90%, var(--lp-bright, #d59bff) 10%);
    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 999px;

    color: var(--lp-text, #9a7cc9);
    font-size: 10px;
    font-weight: 700;
}


/*
 * Expandable list of everyone currently present, by username (data
 * from presence.js; open/close, sizing and placement from
 * live-viewers.js).
 *
 * position: fixed (placed under the badge by live-viewers.js), not
 * absolute: the sidebar scrolls and would clip anything sticking out
 * past its own 400px width, and this list needs to grow to the
 * right over the main area when lots of people are online.
 *
 * Names fill column by column (top to bottom, then the next column
 * to the right). live-viewers.js sets --viewer-cols / --viewer-rows
 * to fit however many people there are; the width is derived from
 * --viewer-cols so it transitions smoothly as people join or leave.
 * Closed, the box is clipped down to its own left edge; opening
 * sweeps the clip back out to the right.
 */
.live-viewer-badge {
    cursor: pointer;
    user-select: none;
}


.live-viewer-badge:focus-visible {
    outline: 2px solid var(--lp-bright, #d59bff);
    outline-offset: 2px;
}


/* Small chevron hinting that the badge expands sideways - points
   right while closed, flips to point back left while open. */
.live-viewer-badge::after {
    content: "\203A";

    margin-left: 1px;

    font-size: 13px;
    line-height: 1;

    opacity: 0.7;

    transition: transform 0.35s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.2s ease;
}


.live-viewer-badge.open::after {
    transform: rotate(180deg);

    opacity: 1;
}


.live-viewer-list {
    --viewer-cols: 1;
    --viewer-rows: 1;
    --viewer-col-w: 140px;
    --viewer-gap: 4px;
    --viewer-pad: 8px;

    position: fixed;
    top: 0;
    left: 0;

    z-index: 50;

    width: calc(
        var(--viewer-cols) * var(--viewer-col-w)
        + (var(--viewer-cols) - 1) * var(--viewer-gap)
        + 2 * var(--viewer-pad)
    );
    max-width: calc(100vw - 16px);

    display: grid;
    grid-auto-flow: column;
    grid-template-rows: repeat(var(--viewer-rows), auto);
    grid-template-columns: repeat(var(--viewer-cols), var(--viewer-col-w));
    gap: var(--viewer-gap);

    padding: var(--viewer-pad);

    overflow-x: hidden;
    overflow-y: auto;

    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--lp-mid, #9147d6) 55%, transparent) transparent;

    background: var(--lp-surface, #14061f);

    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);

    /* Closed: clipped away to the left edge. */
    clip-path: inset(0 100% 0 0 round 10px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;

    transition:
        clip-path 0.45s cubic-bezier(0.22, 1, 0.36, 1),
        opacity 0.25s ease,
        width 0.4s cubic-bezier(0.22, 1, 0.36, 1),
        visibility 0s linear 0.45s;
}


/* Open: the clip sweeps out to the right. The negative inset (rather
   than 0) leaves room around the box so its shadow isn't cut off by
   the clip. */
.live-viewer-list.open {
    clip-path: inset(-24px -24px -24px -24px round 10px);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;

    transition:
        clip-path 0.45s cubic-bezier(0.22, 1, 0.36, 1),
        opacity 0.25s ease,
        width 0.4s cubic-bezier(0.22, 1, 0.36, 1),
        visibility 0s;
}


.live-viewer-list::-webkit-scrollbar {
    width: 6px;
}


.live-viewer-list::-webkit-scrollbar-track {
    background: transparent;
}


.live-viewer-list::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--lp-mid, #9147d6) 55%, transparent);
    border-radius: 999px;
}


/* Names slide in one after another, following the column-by-column
   fill order (--i is set per name by live-viewers.js). Only while
   .opening is on, so it plays as the list opens rather than
   replaying every time someone joins or leaves. */
.live-viewer-list.opening .live-viewer-list-item {
    animation: live-viewer-item-in 0.34s cubic-bezier(0.22, 1, 0.36, 1) both;
    animation-delay: calc(60ms + min(var(--i, 0), 24) * 22ms);
}


@keyframes live-viewer-item-in {

    from {
        opacity: 0;
        transform: translateX(-12px);
    }

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

}


@media (prefers-reduced-motion: reduce) {

    .live-viewer-list,
    .live-viewer-list.open,
    .live-viewer-badge::after {
        transition-duration: 0.01ms;
    }

    .live-viewer-list.opening .live-viewer-list-item {
        animation: none;
    }

}


.live-viewer-list-item {
    padding: 4px 6px;

    background: color-mix(in srgb, var(--lp-surface, #14061f) 90%, var(--lp-bright, #d59bff) 10%);
    border-radius: 4px;

    color: #e8dcff;

    font-size: 10px;
    font-weight: 600;

    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}


.live-viewer-list-empty {
    padding: 4px 6px;

    color: #5c4880;

    font-size: 10px;
}


/*
 * First-visit username prompt (see ensureUsername in presence.js).
 * Fixed full-screen overlay that fades in/out via the --visible
 * modifier class, which presence.js toggles on the next animation
 * frame after insertion (and again right before removal on submit).
 */
.username-gate-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;

    display: flex;
    align-items: center;
    justify-content: center;

    background: rgba(5, 1, 12, 0.55);
    backdrop-filter: blur(10px);

    opacity: 0;

    transition: opacity 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}


.username-gate-overlay.username-gate-overlay--visible {
    opacity: 1;
}


.username-gate-box {
    width: min(90vw, 480px);

    padding: 0 20px;

    background: transparent;
    border: none;
    box-shadow: none;

    text-align: center;
}


.username-gate-title {
    margin-bottom: 10px;

    font-family: var(--font-modern);
    font-weight: 700;
    letter-spacing: 6px;

    color: #d59bff;
    text-shadow: 0 0 18px rgba(184, 102, 255, 0.4);

    text-align: center;

    font-size: clamp(24px, 6vw, 38px);
}


.username-gate-subtitle {
    margin-bottom: 22px;

    color: #c9b7eb;

    font-family: var(--font-modern);
    font-weight: 500;
    font-size: 14px;
    line-height: 1.5;
    letter-spacing: 0.2px;
}


/*
 * Staggered pop-in for the gate's title/subtitle/input/button. Each
 * element carries its own inline animation-delay (see presence.js)
 * so they land one after another instead of all at once; the
 * keyframe itself just handles the scale+fade shared by all of them.
 */
.username-gate-pop {
    opacity: 0;
    transform: scale(0.85) translateY(10px);

    animation: username-gate-pop-in 0.5s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}


@keyframes username-gate-pop-in {

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

}


#usernameGateInput {
    width: 100%;
    margin-bottom: 18px;

    padding: 10px 4px;

    background: transparent;

    border: none;
    border-bottom: 1px solid rgba(184, 102, 255, 0.4);
    border-radius: 0;

    color: #f0e4ff;

    font-family: var(--font-modern);
    font-size: 15px;
    letter-spacing: 0.3px;
    text-align: center;

    outline: none;

    transition: border-color 0.2s ease;
}


#usernameGateInput::placeholder {
    color: #6d5a94;
}


#usernameGateInput:focus {
    border-bottom-color: #d59bff;
    box-shadow: none;
}


#usernameGateSubmit {
    width: auto;

    padding: 6px 4px;

    background: transparent;

    border: none;
    border-radius: 0;

    color: #d59bff;

    font-family: var(--font-modern);
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 2px;

    cursor: pointer;

    transition: color 0.25s ease, text-shadow 0.25s ease, transform 0.2s ease;
}


#usernameGateSubmit:hover {
    color: #ffffff;
    text-shadow: 0 0 14px rgba(184, 102, 255, 0.6);
    transform: translateY(-1px);

    box-shadow: none;
}

.live-viewer-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #7be6a8;
    box-shadow: 0 0 6px rgba(123, 230, 168, 0.8);
}

.site-header-top {
    display: flex;

    align-items: center;
    justify-content: space-between;

    gap: 10px;
}


.mute-toggle-button {
    flex-shrink: 0;

    width: 30px;
    height: 30px;

    display: flex;

    align-items: center;
    justify-content: center;

    background: color-mix(in srgb, var(--lp-surface, #14061f) 90%, var(--lp-bright, #d59bff) 10%);

    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 50%;

    color: var(--lp-text, #9a7cc9);

    font-size: 14px;
    line-height: 1;

    cursor: pointer;

    transition: background 0.12s, border-color 0.12s, color 0.12s, box-shadow 0.12s;
}


.mute-toggle-button:hover {
    background: var(--lp-hover-bg, #2a1145);

    border-color: var(--lp-bright, #d59bff);

    color: #ffffff;
}


.mute-toggle-button.muted {
    background: rgba(174, 19, 19, 0.15);

    border-color: #ae1313;

    color: #ff9d9d;
}


.logo {
    font-size: 24px;
    font-weight: 900;
    letter-spacing: 2px;

    background: linear-gradient(
        90deg,
        #b866ff 0%,
        #d97dff 25%,
        #b866ff 50%,
        #d97dff 75%,
        #b866ff 100%
    );
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    text-shadow: 0 0 22px rgba(180, 90, 255, 0.35);
}


.logo-image {
    height: 64px;
    width: auto;

    display: block;
}


.subtitle {
    margin-top: 4px;

    color: #6d5a94;

    font-size: 11px;
    letter-spacing: 2px;
}


.control-section {
    margin-bottom: 28px;
}


.section-label,
.level-section label {
    display: block;

    margin-bottom: 9px;

    color: var(--lp-text, #9a7cc9);

    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;
}


.label-note {
    color: var(--lp-text-dim, #5c4880);

    font-size: 9px;
    font-weight: 500;
    letter-spacing: 0.3px;
    text-transform: none;
}


#levelInput,
#playerCountInput {
    width: 100%;

    padding: 14px 15px;

    background: var(--lp-surface, #14061f);

    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 8px;

    color: #f0e4ff;

    outline: none;

    font-size: 18px;
    font-weight: 700;

    transition: border-color 0.15s, box-shadow 0.15s;
}


#levelInput:focus,
#playerCountInput:focus {
    border-color: var(--lp-bright, #b866ff);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--lp-bright, #b866ff) 18%, transparent);
}


.medal-payout-indicator {
    display: flex;

    align-items: center;
    justify-content: space-between;

    margin-top: 10px;
    padding: 10px 12px;

    /* Same themed surface/border as the other left-panel inputs, so it
       follows whichever panel is open (purple by default). No glow.
       Only the number itself stays blue - see .medal-payout-value. */
    background: var(--lp-surface, #14061f);

    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 8px;
}


.medal-payout-label {
    color: var(--lp-text, #9a7cc9);

    font-size: 10px;
    font-weight: 700;
    letter-spacing: 1px;
}


.medal-payout-value {
    background: linear-gradient(90deg, #0d6efd, #8fd9ff);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    font-size: 16px;
    font-weight: 900;
}


.section-heading {
    display: flex;

    justify-content: space-between;
    align-items: center;

    margin-bottom: 10px;

    color: var(--lp-text, #a98fd6);

    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;
}


.count {
    color: var(--lp-text-dim, #5c4880);
}


.section-heading-controls {
    display: flex;

    align-items: center;
    gap: 6px;
}


/* Compact version of the curse-visibility-toggle switch (see below),
   sized to fit next to the Active Enemies header's count badge
   without crowding the sidebar. Warm/red accent so it reads as
   "enemy" controls rather than being confused with the curse pool
   toggles above. */
.mini-visibility-toggle {
    display: flex;

    align-items: center;
    gap: 4px;

    padding: 3px 7px;

    background: rgba(174, 19, 19, 0.08);

    border: 1px solid rgba(255, 157, 157, 0.35);
    border-radius: 999px;

    cursor: pointer;
    user-select: none;

    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, opacity 0.15s;
}


.mini-visibility-toggle:hover {
    border-color: rgba(255, 157, 157, 0.65);
}


.mini-visibility-toggle.active {
    background: rgba(255, 157, 157, 0.18);

    border-color: #ff9d9d;
    box-shadow: 0 0 10px rgba(174, 19, 19, 0.35);
}


.mini-visibility-toggle:disabled {
    opacity: 0.35;

    cursor: not-allowed;
}


.mini-visibility-track {
    position: relative;

    flex-shrink: 0;

    width: 20px;
    height: 12px;

    background: rgba(0, 0, 0, 0.35);

    border: 1px solid rgba(255, 157, 157, 0.4);
    border-radius: 999px;

    transition: background 0.18s, border-color 0.18s;
}


.mini-visibility-toggle.active .mini-visibility-track {
    background: linear-gradient(90deg, #7a0e0e, #ff9d9d);

    border-color: #ff9d9d;
}


.mini-visibility-thumb {
    position: absolute;
    top: 1px;
    left: 1px;

    width: 8px;
    height: 8px;

    background: #fff0f0;
    border-radius: 50%;

    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);

    transition: transform 0.18s ease;
}


.mini-visibility-toggle.active .mini-visibility-thumb {
    transform: translateX(8px);
}


.mini-visibility-label {
    color: #e0a3a3;

    font-family: var(--font-modern);
    font-size: 8px;
    font-weight: 800;
    letter-spacing: 0.6px;
    white-space: nowrap;
}


.mini-visibility-toggle.active .mini-visibility-label {
    color: #fff0f0;
}


.button-grid {
    display: grid;

    gap: 8px;
}


.difficulty-grid {
    grid-template-columns: repeat(3, 1fr);
}


.enemy-grid {
    grid-template-columns: repeat(5, 1fr);
    gap: 5px;
}


.select-button {
    min-height: 62px;

    display: flex;

    align-items: center;
    justify-content: center;

    padding: 10px;

    background: var(--lp-surface, #14061f);

    border: 1px solid var(--lp-dim, #3a1a5c);
    border-radius: 8px;

    color: var(--lp-text, #9a7cc9);

    text-align: center;

    font-size: 12px;
    font-weight: 700;

    cursor: pointer;

    user-select: none;

    transition:
        background 0.12s,
        border-color 0.12s,
        color 0.12s,
        transform 0.12s,
        box-shadow 0.12s;
}


.select-button.enemy-button {
    position: relative;

    aspect-ratio: 1 / 1;
    min-height: unset;

    padding: 5px;
}


/* Shown (via Show All Enemies) but not currently selectable - below
   its required level, or missing an enemy dependency (e.g.
   Voidbound Baby needing 2x Baby active). Same dimmed/grayscale
   treatment as a locked curse card. */
.select-button.enemy-button--locked {
    cursor: not-allowed;

    opacity: 0.4;
    filter: grayscale(0.6);
}


.select-button.enemy-button--locked:hover {
    background: var(--lp-surface, #14061f);

    border-color: rgba(174, 19, 19, 0.4);
    box-shadow: none;

    transform: none;
}


/* Small readout for enemies that can be marked active twice (Baby
   and Husk), showing the current stack against its cap. */
.enemy-stack-badge {
    position: absolute;
    right: 2px;
    bottom: 2px;

    z-index: 2;

    padding: 1px 4px;

    background: rgba(0, 0, 0, 0.6);

    border: 1px solid rgba(255, 157, 157, 0.6);
    border-radius: 999px;

    color: #ffdede;

    font-family: var(--font-modern);
    font-size: 7px;
    font-weight: 800;
    line-height: 1.2;
}


/* Dependency badge shown on an enemy button itself (Voidbound Baby
   showing a 2x Baby icon, etc). Reuses .curse-enemy-badge's shape
   and asset-loading logic, but pinned to the button's own
   bottom-right corner instead of poking out above it like the
   curse-card version does - the enemy grid's row-gap is only 5px,
   nowhere near enough room for that protrusion, so this stays fully
   inside the button's own bounds. Kept noticeably smaller than the
   curse-card version too, since these buttons are tiny (~1/5th of
   the sidebar wide). */
.enemy-dependency-badge {
    top: auto;
    left: auto;
    right: 2px;
    bottom: 2px;

    transform: none;

    width: 12px;
    height: 12px;

    box-shadow: 0 1px 3px rgba(174, 19, 19, 0.55);
}


/* Points back in toward the button's center (up-left) instead of
   further into the corner, so it doesn't spill past the button's
   own edge into whatever sits below/beside it. */
.enemy-dependency-badge .curse-enemy-badge-count {
    right: auto;
    bottom: auto;
    left: -5px;
    top: -5px;

    padding: 0 3px;

    font-size: 6px;
}


.select-button:hover {
    background: var(--lp-surface-hover, #20103a);

    border-color: var(--lp-mid, #9147d6);

    color: #ffffff;

    transform: translateY(-1px);
    box-shadow: 0 0 16px color-mix(in srgb, var(--lp-mid, #9147d6) 25%, transparent);
}


.select-button.selected {
    background: linear-gradient(135deg, var(--lp-selected-a, #4a1c85), var(--lp-selected-b, #7a2fc4));

    border-color: var(--lp-bright, #d59bff);

    color: #ffffff;

    box-shadow: 0 0 18px color-mix(in srgb, var(--lp-mid, #9147d6) 45%, transparent);
}


.select-button.difficulty-casual.selected {
    background: linear-gradient(135deg, #123a5c, #3a8dff);

    border-color: #8fd9ff;

    color: #ffffff;

    box-shadow: 0 0 18px rgba(58, 141, 255, 0.5);
}


.select-button.difficulty-standard.selected {
    background: linear-gradient(135deg, #4a1c85, #7a2fc4);

    border-color: #d59bff;

    color: #ffffff;

    box-shadow: 0 0 18px rgba(180, 90, 255, 0.4);
}


.select-button.difficulty-extreme.selected {
    background: linear-gradient(135deg, #5c0a0a, #ff2d2d);

    border-color: #ff9d9d;

    color: #ffffff;

    box-shadow: 0 0 18px rgba(255, 45, 45, 0.5);
}


.select-button.difficulty-casual:hover {
    background: #0a2440;

    border-color: #3a8dff;

    box-shadow: 0 0 16px rgba(58, 141, 255, 0.35);
}


.select-button.difficulty-standard:hover {
    background: #20103a;

    border-color: #9147d6;

    box-shadow: 0 0 16px rgba(145, 71, 214, 0.35);
}


.select-button.difficulty-extreme:hover {
    background: #3a0a0a;

    border-color: #ae1313;

    box-shadow: 0 0 16px rgba(174, 19, 19, 0.4);
}


.active-curse-search {
    position: relative;

    margin-bottom: 10px;
}


.active-curse-search-input {
    width: 100%;

    padding: 10px 34px 10px 12px;

    background: var(--lp-surface, #14061f);

    border: 1px solid var(--lp-dim, #3a1a5c);
    border-radius: 8px;

    color: #f0e4ff;

    outline: none;

    font-size: 12px;
    font-family: inherit;

    transition: border-color 0.15s, box-shadow 0.15s;
}


.active-curse-search-input::placeholder {
    color: var(--lp-text-dim, #5c4880);
}


.active-curse-search-input:focus {
    border-color: var(--lp-mid, #9147d6);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--lp-mid, #9147d6) 18%, transparent);
}


.active-curse-search-clear {
    position: absolute;
    top: 50%;
    right: 8px;

    transform: translateY(-50%);

    width: 20px;
    height: 20px;

    display: none;
    align-items: center;
    justify-content: center;

    background: rgba(255, 255, 255, 0.06);

    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 50%;

    color: #b6a3dd;

    font-size: 12px;
    line-height: 1;

    cursor: pointer;

    transition: background 0.12s, border-color 0.12s, color 0.12s;
}


.active-curse-search-clear.visible {
    display: flex;
}


.active-curse-search-clear:hover {
    background: color-mix(in srgb, var(--lp-mid, #9147d6) 25%, transparent);

    border-color: var(--lp-bright, #d59bff);

    color: #ffffff;
}


.active-curses {
    display: flex;

    flex-direction: column;

    gap: 7px;
}


.active-curse {
    position: relative;

    min-height: 52px;

    display: flex;

    align-items: center;

    padding: 0;
    overflow: hidden;

    background: linear-gradient(90deg, #6a1fd0, #b23fc4);

    border: 1px solid #e08cff;
    box-shadow: 0 0 20px rgba(198, 92, 255, 0.45);

    border-radius: 7px;

    color: #ffffff;

    font-size: 12px;
    font-weight: 700;
}


.active-curse--greater {
    background: linear-gradient(90deg, #b23a00, #ff6200);

    border-color: #ffa561;
    box-shadow: 0 0 20px rgba(255, 98, 0, 0.45);
}


.active-curse--medal {
    background: linear-gradient(90deg, #0077a3, #b0177f);

    border-color: #6fe0ff;
    box-shadow: 0 0 20px rgba(0, 200, 255, 0.4), 0 0 14px rgba(255, 92, 200, 0.35);
}


.active-curse--medal-purified {
    background: linear-gradient(90deg, #4a4d55, #4a4152);

    border-color: #7c8290;
    box-shadow: 0 0 10px rgba(120, 130, 150, 0.25);

    color: #cfcfd6;
}


.active-curse-content {
    position: relative;
    z-index: 2;

    flex: 1;
    min-width: 0;

    display: flex;

    align-items: center;
    gap: 10px;

    padding: 10px 12px;
}


.active-curse-name {
    flex: 1 1 auto;
    min-width: 0;

    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    font-family: var(--font-modern);
    letter-spacing: 0.4px;
    text-transform: uppercase;
}


.active-curse-remove {
    flex-shrink: 0;

    width: 22px;
    height: 22px;

    display: flex;

    align-items: center;
    justify-content: center;

    background: rgba(0, 0, 0, 0.2);

    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 50%;

    color: #ffffff;

    font-size: 13px;
    line-height: 1;

    cursor: pointer;

    transition:
        background 0.12s,
        border-color 0.12s,
        transform 0.12s;
}


.active-curse-remove:hover {
    background: rgba(255, 255, 255, 0.2);

    border-color: #ffffff;

    transform: scale(1.1);
}


.purify-button {
    flex-shrink: 0;

    margin-left: auto;
    margin-right: 58px;

    padding: 4px 9px;

    background: rgba(0, 0, 0, 0.25);

    border: 1px solid rgba(255, 255, 255, 0.4);
    border-radius: 999px;

    color: #ffffff;

    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.4px;

    cursor: pointer;

    transition: background 0.12s, border-color 0.12s, color 0.12s;
}


.purify-button:hover {
    background: rgba(255, 255, 255, 0.2);

    border-color: #ffffff;
}


.purify-button.purified {
    background: rgba(255, 255, 255, 0.12);

    border-color: rgba(255, 255, 255, 0.55);

    color: #d8d8de;
}


.purify-price {
    flex: 0 0 56px;

    text-align: right;

    color: #ff6b6b;

    font-family: var(--font-modern);
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.3px;
    white-space: nowrap;

    text-shadow: 0 0 8px rgba(255, 107, 107, 0.45);
}


.active-curse-icon {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;

    z-index: 1;

    width: 75px;

    pointer-events: none;
}


.active-curse-icon-image {
    width: 100%;
    height: 100%;

    object-fit: cover;

    opacity: 0.9;

    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 50%);
    mask-image: linear-gradient(to right, transparent 0%, black 50%);
}


.empty-state {
    padding: 18px;

    border: 1px dashed var(--lp-dim, #3a1a5c);
    border-radius: 8px;

    color: var(--lp-text-dim, #5c4880);

    text-align: center;

    font-size: 11px;
}


.run-controls {
    display: flex;

    gap: 8px;
}


.reset-button {
    flex: 1;

    padding: 13px;

    background: transparent;

    border: 1px solid var(--lp-soft, #4a2270);
    border-radius: 8px;

    color: var(--lp-text, #9a7cc9);

    font-size: 11px;
    font-weight: 700;
    letter-spacing: 1px;

    cursor: pointer;

    transition: background 0.12s, border-color 0.12s, color 0.12s;
}


.reset-button:hover {
    background: var(--lp-hover-bg, #2a1145);

    border-color: var(--lp-bright, #d59bff);

    color: #ffffff;
}


.remove-all-button:hover {
    background: #3a0a0a;

    border-color: #ae1313;

    color: #ffffff;
}


.right-panel {
    padding: 32px;

    overflow-y: auto;

    font-family: var(--font-modern);

    position: relative;
}


.pool-header {
    margin-bottom: 30px;

    display: flex;

    align-items: flex-start;
    justify-content: space-between;

    gap: 20px;
}


.pool-title {
    font-size: 35px;
    font-weight: 900;

    background: linear-gradient(
        90deg,
        #d59bff 0%,
        #7a2fc4 25%,
        #d59bff 50%,
        #7a2fc4 75%,
        #d59bff 100%
    );
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    text-shadow: 0 0 18px rgba(184, 102, 255, 0.35);
}


.pool-subtitle {
    margin-top: 6px;

    color: #c9b7eb;

    font-size: 11px;
}


.pool-controls {
    flex-shrink: 0;

    display: flex;

    flex-direction: column;
    align-items: flex-end;

    gap: 8px;
}


/* Track+thumb switch used for the Show All / Unlock All Curses
   toggles above the curse pools. Unlock All is disabled (see
   :disabled below) until Show All is on, since it has nothing to
   unlock until Show All is revealing the extra curses. */
.curse-visibility-toggle {
    display: flex;

    align-items: center;
    gap: 8px;

    padding: 7px 12px;

    background: rgba(184, 102, 255, 0.06);

    border: 1px solid rgba(184, 102, 255, 0.35);
    border-radius: 999px;

    cursor: pointer;
    user-select: none;

    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, opacity 0.15s;
}


.curse-visibility-toggle:hover {
    border-color: rgba(184, 102, 255, 0.65);
}


.curse-visibility-toggle.active {
    background: rgba(184, 102, 255, 0.16);

    border-color: #b866ff;
    box-shadow: 0 0 16px rgba(184, 102, 255, 0.35);
}


.curse-visibility-toggle:disabled {
    opacity: 0.35;

    cursor: not-allowed;
}


.curse-visibility-track {
    position: relative;

    flex-shrink: 0;

    width: 32px;
    height: 18px;

    background: rgba(0, 0, 0, 0.35);

    border: 1px solid rgba(184, 102, 255, 0.4);
    border-radius: 999px;

    transition: background 0.18s, border-color 0.18s;
}


.curse-visibility-toggle.active .curse-visibility-track {
    background: linear-gradient(90deg, #6a2f96, #d59bff);

    border-color: #d59bff;
}


.curse-visibility-thumb {
    position: absolute;
    top: 1px;
    left: 1px;

    width: 14px;
    height: 14px;

    background: #f0e4ff;
    border-radius: 50%;

    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);

    transition: transform 0.18s ease;
}


.curse-visibility-toggle.active .curse-visibility-thumb {
    transform: translateX(14px);
}


.curse-visibility-label {
    color: #b6a3dd;

    font-family: var(--font-modern);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 1px;
    white-space: nowrap;
}


.curse-visibility-toggle.active .curse-visibility-label {
    color: #f0e4ff;
}


.result-section {
    margin-bottom: 42px;
}


.result-heading {
    display: flex;

    align-items: baseline;

    gap: 10px;

    margin-bottom: 14px;
}


.result-heading h2 {
    font-size: 22px;
    font-weight: 700;
    letter-spacing: 0.5px;

    color: #e8dcff;
}


#medalHeading {
    background: linear-gradient(
        90deg,
        #00c8ff 0%,
        #ff5cc8 25%,
        #00c8ff 50%,
        #ff5cc8 75%,
        #00c8ff 100%
    );
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    text-shadow: 0 0 18px rgba(0, 200, 255, 0.4), 0 0 14px rgba(255, 92, 200, 0.35);
}


#globalHeading {
    background: linear-gradient(
        90deg,
        #d59bff 0%,
        #7a2fc4 25%,
        #d59bff 50%,
        #7a2fc4 75%,
        #d59bff 100%
    );
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    text-shadow: 0 0 18px rgba(184, 102, 255, 0.4);
}


#enemyHeading {
    background: linear-gradient(
        90deg,
        #ff6b6b 0%,
        #ae1313 25%,
        #ff6b6b 50%,
        #ae1313 75%,
        #ff6b6b 100%
    );
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    text-shadow: 0 0 18px rgba(174, 19, 19, 0.45);
}


#greaterHeading {
    background: linear-gradient(
        90deg,
        #ffb37a 0%,
        #ff6200 25%,
        #ffb37a 50%,
        #ff6200 75%,
        #ffb37a 100%
    );
    background-size: 200% auto;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;

    text-shadow: 0 0 18px rgba(255, 98, 0, 0.45);
}


.animated-header-text {
    --gradient-speed: 2.5s;

    animation: header-gradient-scroll var(--gradient-speed) linear infinite;
}


@keyframes header-gradient-scroll {

    0% {
        background-position: 0% 50%;
    }

    100% {
        background-position: 100% 50%;
    }

}


.result-heading span {
    color: #5c4880;

    font-size: 9px;
    letter-spacing: 1px;
}


.credit {
    margin-top: 10px;

    color: #4f4166;

    font-size: 10px;
    letter-spacing: 0.5px;
}


.credit-handle {
    color: var(--lp-bright, #d59bff);
    font-weight: 700;

    animation: credit-glow-pulse 2.5s ease-in-out infinite;
}


.data-source-note {
    margin-top: 4px;

    color: #3a3050;

    font-size: 9px;
    line-height: 1.4;
    letter-spacing: 0.3px;
}


.data-source-note a {
    color: var(--lp-text, #6d5a94);

    text-decoration: underline;
    text-underline-offset: 2px;

    transition: color 0.15s;
}


.data-source-note a:hover {
    color: var(--lp-bright, #d59bff);
}


@keyframes credit-glow-pulse {

    0%,
    100% {
        text-shadow: 0 0 5px color-mix(in srgb, var(--lp-bright, #d59bff) 35%, transparent);
    }

    50% {
        text-shadow:
            0 0 12px color-mix(in srgb, var(--lp-bright, #d59bff) 75%, transparent),
            0 0 4px rgba(255, 255, 255, 0.4);
    }

}


.result-grid {
    display: grid;

    grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));

    column-gap: 8px;
    row-gap: 26px;
}


.curse-card {
    position: relative;

    aspect-ratio: 1 / 1.16;
    min-height: unset;

    display: flex;

    flex-direction: column;

    align-items: center;
    justify-content: flex-start;

    gap: 3px;

    padding: 7px;

    background: linear-gradient(160deg, #150826 0%, #0d0416 100%);

    border: 1px solid #3a1a5c;
    border-radius: 8px;

    text-align: center;

    cursor: pointer;

    transition:
        background 0.12s,
        border-color 0.12s,
        transform 0.12s,
        box-shadow 0.12s;
}


.curse-card.medal {
    margin-bottom: 13px;
}


/* Enemy icon badges intentionally do NOT get a margin-top spacer
   here - pushing a card's own box down to make room for its badge
   broke row alignment, since grid items with a definite (aspect-
   ratio driven) size don't stretch to fill the row, so extra
   margin-top just shifted that one card down relative to its
   siblings. Instead, .result-grid's row-gap (below) is sized to
   give every row's badges room, keeping all cards' top edges level. */


/* Small circular badge showing the enemy an enemy-specific or
   enemy-gated curse depends on, in place of a plain text label.
   Positioned so it sits mostly outside the card, poking out past
   the top edge - the same "sticking out" treatment as the reward
   and unlock badges use at the bottom of the card. */
.curse-enemy-badge {
    position: absolute;
    top: -13px;
    left: 50%;

    transform: translateX(-50%);

    z-index: 2;

    width: 26px;
    height: 26px;

    background: linear-gradient(160deg, #2e0808 0%, #150826 100%);

    border: 1px solid #ff9d9d;
    border-radius: 50%;

    box-shadow: 0 3px 8px rgba(174, 19, 19, 0.45);
}


.data-source-note .contributors-link {
    display: block;

    margin-top: 5px;
}


/* Compact close control shared by each sliding toolkit panel. It is
   first in every panel header, placing it at the top-left while the
   accessible label makes the arrow's action explicit. */
.toolkit-panel-back {
    flex: 0 0 auto;

    width: 28px;
    height: 28px;

    display: inline-flex;

    align-items: center;
    justify-content: center;

    padding: 0;

    background: rgba(255, 255, 255, 0.08);

    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 7px;

    color: #ffffff;

    font-size: 18px;
    line-height: 1;

    cursor: pointer;

    transition: background 0.15s, border-color 0.15s, transform 0.15s;
}


.toolkit-panel-back:hover {
    background: rgba(255, 255, 255, 0.17);

    border-color: rgba(255, 255, 255, 0.75);

    transform: translateX(-2px);
}


.toolkit-panel-back:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}


/* A violet dependency icon for curses that need another curse, such
   as Burning Bouquet requiring Razorbloom. It is centered by
   default, then shifted only when it needs to share space with an
   enemy or another curse dependency badge. */
.curse-requirement-badge {
    position: absolute;
    top: -13px;
    left: 50%;

    transform: translateX(-50%);

    z-index: 2;

    width: 26px;
    height: 26px;

    background: linear-gradient(160deg, #321042 0%, #150826 100%);

    border: 1px solid #d59bff;
    border-radius: 50%;

    box-shadow: 0 3px 8px rgba(106, 31, 208, 0.45);
}


.curse-requirement-badge--left {
    left: 32%;
}


.curse-requirement-badge--right {
    left: 72%;
}


/* Holds the icon/placeholder and does the actual circular
   cropping - kept separate from .curse-enemy-badge itself so that
   badge's overflow doesn't also clip the count label, which is
   meant to poke out past this circle's edge. */
.curse-enemy-badge-inner {
    width: 100%;
    height: 100%;

    display: flex;

    align-items: center;
    justify-content: center;

    overflow: hidden;

    border-radius: 50%;
}


.curse-enemy-badge-image {
    width: 100%;
    height: 100%;

    object-fit: cover;

    display: block;
}


/* Overlay showing how many of that enemy are required, for
   dependencies asking for more than 1 (Husk Express and Voidbound
   Baby). Sits directly on .curse-enemy-badge (outside the
   .curse-enemy-badge-inner circular mask - see above) so it's never
   clipped off. */
.curse-enemy-badge-count {
    position: absolute;
    right: -3px;
    bottom: -3px;

    z-index: 3;

    padding: 1px 4px;

    background: #ae1313;

    border: 1px solid #ff9d9d;
    border-radius: 999px;

    color: #fff0f0;

    font-family: var(--font-modern);
    font-size: 7px;
    font-weight: 800;
    line-height: 1.1;
}


.curse-enemy-badge-placeholder {
    padding: 1px;

    color: #ff9d9d;

    font-size: 5px;
    font-weight: 700;
    line-height: 1;
    text-align: center;

    word-break: break-word;
}


.curse-card:hover {
    background: linear-gradient(160deg, #24103f 0%, #150826 100%);

    border-color: #b866ff;
    box-shadow: 0 0 22px rgba(184, 102, 255, 0.3);

    transform: translateY(-2px);
}


.card-media {
    width: 100%;
    flex: 1 1 auto;

    min-height: 0;

    display: flex;

    align-items: center;
    justify-content: center;

    overflow: hidden;

    background: rgba(255, 255, 255, 0.03);

    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 6px;
}


.curse-card .card-media {
    flex: 0 0 auto;

    width: 64%;
    height: 64%;

    margin: 2px auto 0;

    background: transparent;
    border: none;
}


.card-media-placeholder {
    padding: 6px;

    color: #d0bfef;

    font-size: 11px;
    font-weight: 700;
    line-height: 1.3;

    text-align: center;

    word-break: break-word;
}


.card-media-image {
    width: 100%;
    height: 100%;

    object-fit: contain;

    display: block;
}


.enemy-button .card-media {
    height: 100%;

    background: transparent;
    border: none;
}


.enemy-button .card-media-placeholder {
    color: #b6a3dd;

    font-size: 9px;
    padding: 3px;
    line-height: 1.15;
}


.enemy-button.selected .card-media-placeholder {
    color: #ffffff;
}


.curse-name-label {
    margin-top: 2px;

    font-family: var(--font-modern);
    font-weight: 700;
    font-size: 8px;
    letter-spacing: 0.4px;
    line-height: 1.25;
    text-transform: uppercase;

    color: #f0e4ff;

    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}


#medalCurseContainer .curse-name-label {
    color: #8fd9ff;
}


#globalCurseContainer .curse-name-label {
    color: #d59bff;
}


#enemyCurseContainer .curse-name-label {
    color: #ff9d9d;
}


#greaterCurseContainer .curse-name-label {
    color: #ffb37a;
}


.curse-info {
    margin-top: 2px;

    color: #6d5a94;

    font-family: var(--font-modern);
    font-size: 9px;
    letter-spacing: 0.3px;
}


.curse-info.stack-info {
    color: #d59bff;
    font-weight: 700;
    letter-spacing: 0.5px;
}


.curse-reward-badge {
    position: absolute;
    left: 50%;
    bottom: -10px;

    transform: translateX(-50%);

    padding: 2px 9px;

    background: linear-gradient(135deg, #00c8ff, #ff5cc8);

    border: 1px solid rgba(0, 200, 255, 0.6);
    border-radius: 999px;

    color: #ffffff;

    font-size: 9px;
    font-weight: 800;
    letter-spacing: 0.3px;

    white-space: nowrap;

    box-shadow: 0 3px 8px rgba(255, 92, 200, 0.35);

    z-index: 2;
}


/* Any curse that's visible in its pool but not currently selectable
   - a greater curse under its unlock level, or (with Show All
   Curses on) any curse missing its level/enemy/other requirement,
   already maxed, etc. Dimmed card with a lock badge underneath
   instead of disappearing from the list entirely. */
.curse-card--locked {
    margin-bottom: 13px;

    cursor: not-allowed;

    opacity: 0.45;
    filter: grayscale(0.55);
}


.curse-card--locked:hover {
    background: linear-gradient(160deg, #150826 0%, #0d0416 100%);

    border-color: #3a1a5c;
    box-shadow: none;

    transform: none;
}


/* Unlock All Curses: an owned/maxed card is still shown dimmed like
   any other locked card, but it's actually clickable (reclicking
   removes it), so the cursor and hover feedback need to read as
   interactive rather than dead-ended. Declared after
   .curse-card--locked:hover so it wins on the properties both set. */
.curse-card--removable {
    cursor: pointer;
}


.curse-card--removable:hover {
    background: linear-gradient(160deg, #3a0a0a 0%, #150826 100%);

    border-color: #ff9d9d;
    box-shadow: 0 0 18px rgba(174, 19, 19, 0.35);

    transform: translateY(-2px);

    opacity: 0.7;
}


/* Shared geometry for the badge on a locked curse card; the color
   comes from one of the modifier classes below. */
.curse-lock-badge {
    position: absolute;
    left: 50%;
    bottom: -10px;

    transform: translateX(-50%);

    padding: 2px 9px;

    border-radius: 999px;

    font-size: 8px;
    font-weight: 800;
    letter-spacing: 0.3px;

    white-space: nowrap;

    z-index: 2;
}


/* Already owned/maxed - purple palette. */
.curse-lock-badge--owned {
    background: linear-gradient(135deg, #d59bff, #6a1fd0);

    border: 1px solid rgba(184, 102, 255, 0.7);

    color: #f5eaff;

    box-shadow: 0 3px 8px rgba(122, 47, 196, 0.45);
}


/* Level requirement - a light-to-purple palette that remains clear
   on dimmed, Show All Curses cards. */
.curse-lock-badge--level {
    background: linear-gradient(135deg, #f3d7ff, #8b4fcb);

    border: 1px solid rgba(238, 198, 255, 0.9);

    color: #ffffff;

    box-shadow: 0 3px 8px rgba(146, 80, 207, 0.55);
}


.curse-card.medal {
    border-color: #00c8ff;
    box-shadow: 0 0 14px rgba(0, 200, 255, 0.3), 0 0 10px rgba(255, 92, 200, 0.22);
}


#medalCurseContainer .curse-card:hover {
    background: linear-gradient(160deg, #002738 0%, #380726 100%);

    border-color: #00c8ff;
    box-shadow: 0 0 20px rgba(0, 200, 255, 0.3), 0 0 14px rgba(255, 92, 200, 0.28);
}


#medalCurseContainer .card-media-placeholder {
    color: #8fd9ff;
}


#medalCurseContainer .curse-info {
    color: #6fa8c9;
}


#greaterCurseContainer .curse-card {
    border-color: rgba(255, 98, 0, 0.35);
}


#greaterCurseContainer .curse-card:hover {
    background: linear-gradient(160deg, #3a1500 0%, #150826 100%);

    border-color: #ff6200;
    box-shadow: 0 0 22px rgba(255, 98, 0, 0.35);
}


#greaterCurseContainer .card-media {
    border-color: rgba(255, 98, 0, 0.15);
}


#greaterCurseContainer .card-media-placeholder {
    color: #ffb37a;
}


#greaterCurseContainer .curse-info {
    color: #cc7a3d;
}


.enemy-button,
#enemyCurseContainer .curse-card {
    border-color: rgba(174, 19, 19, 0.4);
}


.enemy-button:hover,
#enemyCurseContainer .curse-card:hover {
    border-color: #ae1313;
    box-shadow: 0 0 16px rgba(174, 19, 19, 0.35);
}


#enemyCurseContainer .curse-card:hover {
    background: linear-gradient(160deg, #2e0808 0%, #150826 100%);
}


.enemy-button.selected {
    background: linear-gradient(160deg, #ff5c5c 0%, #7a0e0e 65%, #3d0505 100%);

    border-color: #ff9d9d;

    box-shadow: 0 0 18px rgba(174, 19, 19, 0.5);
}


#enemyCurseContainer .card-media-placeholder {
    color: #e08a8a;
}


#enemyCurseContainer .curse-info {
    color: #a35c5c;
}


.empty-pool {
    grid-column: 1 / -1;

    padding: 24px;

    border: 1px dashed #3a1a5c;
    border-radius: 8px;

    color: #5c4880;

    text-align: center;

    font-size: 11px;
}


.hold-button {
    position: relative;

    overflow: hidden;
}


.hold-button > *:not(.hold-fill) {
    position: relative;
    z-index: 1;
}


.hold-fill {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;

    width: 0%;

    z-index: 0;

    background: linear-gradient(90deg, rgba(220, 20, 20, 0.55), rgba(255, 70, 70, 0.8));

    pointer-events: none;
}


.hold-button.holding {
    box-shadow: 0 0 16px rgba(255, 40, 40, 0.5);
}


/*
 * Rolling number animation support (see tweenNumberText in
 * script.js). `.roll-pill` wrappers get their width flipped via
 * inline styles during a change, so overflow stays clipped to the
 * pill's rounded shape while that's happening. `.roll-number-active`
 * is applied to the number itself for the duration of the tween, for
 * a brief brightness pulse that reads as "this just changed."
 */
.roll-pill {
    overflow: hidden;
    white-space: nowrap;
}


.roll-number-active {
    animation: roll-number-glow 0.55s ease-out;
}


@keyframes roll-number-glow {

    0% {
        filter: brightness(1.5);
    }

    100% {
        filter: brightness(1);
    }

}


.left-panel,
.right-panel {
    scrollbar-width: thin;
}


.left-panel::-webkit-scrollbar,
.right-panel::-webkit-scrollbar {
    width: 6px;
}


.left-panel::-webkit-scrollbar-track,
.right-panel::-webkit-scrollbar-track {
    background: transparent;
}


.right-panel {
    scrollbar-color: rgba(184, 102, 255, 0.35) transparent;
}


.right-panel::-webkit-scrollbar-thumb {
    background: rgba(184, 102, 255, 0.3);
    border-radius: 999px;
}


.right-panel::-webkit-scrollbar-thumb:hover {
    background: rgba(184, 102, 255, 0.55);
}


.left-panel {
    scrollbar-color: var(--lp-mid, #9147d6) transparent;
}


.left-panel::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--lp-mid, #9147d6) 45%, transparent);
    border-radius: 999px;
}


.left-panel::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--lp-mid, #9147d6) 70%, transparent);
}


@media (max-width: 900px) {

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


    .left-panel {
        border-right: none;

        border-bottom: 1px solid #3a1a5c;
    }

}


@media (max-width: 500px) {

    .right-panel,
    .left-panel {
        padding: 18px;
    }


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


    .enemy-grid {
        grid-template-columns: repeat(3, 1fr);
    }


    .run-controls {
        flex-direction: column;
    }


    .pool-header {
        flex-direction: column;
    }


    .pool-controls {
        align-items: flex-start;

        width: 100%;
    }

}

.result-section--hidden {
    display: none;
}


/* The dedicated Medal Curses section keeps its cyan/pink treatment.
   When that section is hidden, medal cards are promoted back into
   their source pool instead, so their card and reward styling use
   that pool's theme: purple for Global and red for Enemy. */
#globalCurseContainer .curse-card.medal {
    background: linear-gradient(160deg, #25103f 0%, #11051e 100%);

    border-color: #d59bff;
    box-shadow: 0 0 14px rgba(184, 102, 255, 0.36);
}


#globalCurseContainer .curse-card.medal:hover {
    background: linear-gradient(160deg, #3a1761 0%, #18082a 100%);

    border-color: #efd6ff;
    box-shadow: 0 0 22px rgba(213, 155, 255, 0.46);
}


#globalCurseContainer .curse-card.medal .curse-reward-badge {
    background: linear-gradient(135deg, #f0d5ff, #8b4fcb);

    border-color: rgba(238, 198, 255, 0.85);

    box-shadow: 0 3px 8px rgba(146, 80, 207, 0.5);
}


#enemyCurseContainer .curse-card.medal {
    background: linear-gradient(160deg, #351010 0%, #170606 100%);

    border-color: #ff9d9d;
    box-shadow: 0 0 14px rgba(255, 92, 92, 0.36);
}


#enemyCurseContainer .curse-card.medal:hover {
    background: linear-gradient(160deg, #551717 0%, #220707 100%);

    border-color: #ffd0d0;
    box-shadow: 0 0 22px rgba(255, 157, 157, 0.46);
}


#enemyCurseContainer .curse-card.medal .curse-reward-badge {
    background: linear-gradient(135deg, #ffd0d0, #b52b3e);

    border-color: rgba(255, 208, 208, 0.85);

    box-shadow: 0 3px 8px rgba(190, 39, 57, 0.5);
}


/*
 * Floating toggle-button group
 * --------------------------
 * Wraps the Death Tracker and Upgrade Shop toggle buttons (styled
 * separately in DeathTracker.css / Upgrades.css) in a single fixed-
 * position flex row, instead of each button carrying its own
 * position: fixed + a hardcoded `right` offset. Those buttons now
 * collapse down to icon-only and expand on hover - with each one
 * positioned independently, the offset between them had to assume a
 * fixed width for its neighbor, so collapsing one left a stretch of
 * empty space (or, if both were sized for the collapsed state,
 * would have caused them to overlap once expanded). Flexbox's own
 * `gap` keeps a constant, correct space between them no matter which
 * one (if either) is currently expanded.
 */
.floating-toggle-buttons {
    position: fixed;
    right: 26px;
    bottom: 26px;

    z-index: 30;

    display: flex;

    align-items: center;
    gap: 12px;
}


/*
 * Inner wrapper holding the four panel-toggle buttons, separate from
 * the hide/show arrow itself - only this slides/fades away when
 * collapsed, so the arrow button stays put as a fixed anchor the
 * person can always find in the same spot.
 */
.floating-toggle-buttons-inner {
    display: flex;

    align-items: center;
    gap: 12px;

    transition:
        transform 0.45s cubic-bezier(0.22, 1, 0.36, 1),
        opacity 0.3s ease;
}


/* Collapsed: the four panel buttons slide out to the right and fade,
   leaving only the arrow toggle visible. translateX (not width/
   display) so it reads as an actual slide instead of an instant
   cut, and pointer-events: none keeps them unclickable while
   offscreen instead of sitting invisibly on top of other content. */
.floating-toggle-buttons.collapsed .floating-toggle-buttons-inner {
    transform: translateX(calc(100% + 24px));
    opacity: 0;

    pointer-events: none;
}


/*
 * The "<"/">" hide-show button itself - a small circular pill so it
 * doesn't compete visually with the four pill-shaped panel buttons
 * next to it. Same glyph is reused for both states (see the rotate
 * transform below) rather than swapping the character via JS.
 */
.floating-buttons-hide-toggle {
    flex-shrink: 0;

    width: 34px;
    height: 34px;

    display: flex;

    align-items: center;
    justify-content: center;

    padding: 0;

    background: rgba(20, 6, 31, 0.85);

    border: 1px solid rgba(216, 155, 255, 0.55);
    border-radius: 50%;

    color: #f0e4ff;

    font-size: 13px;
    line-height: 1;

    cursor: pointer;

    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4), 0 0 10px rgba(184, 102, 255, 0.25);

    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}


.floating-buttons-hide-toggle:hover {
    background: rgba(42, 17, 69, 0.95);

    border-color: #d59bff;

    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5), 0 0 16px rgba(184, 102, 255, 0.4);

    transform: scale(1.06);
}


.floating-buttons-hide-toggle:focus-visible {
    outline: 2px solid #d59bff;
    outline-offset: 2px;
}


.floating-buttons-hide-icon {
    display: inline-block;

    transition: transform 0.35s ease;
}


/* Collapsed state rotates the ">" glyph to read as "<" instead of
   swapping the character itself. */
.floating-toggle-buttons.collapsed .floating-buttons-hide-icon {
    transform: rotate(180deg);
}


@media (max-width: 500px) {

    .floating-toggle-buttons {
        right: 16px;
        bottom: 16px;

        gap: 8px;
    }


    .floating-toggle-buttons-inner {
        gap: 8px;
    }


    .floating-buttons-hide-toggle {
        width: 30px;
        height: 30px;

        font-size: 11px;
    }

}


/*
 * The three floating toggle buttons (Upgrades/Deaths/Altars) center
 * their icon glyph while collapsed - without this, the icon sits
 * flush against the button's flex-start edge and reads as pushed
 * to the left instead of centered in the pill.
 */
.upgrade-toggle-button,
.death-toggle-button,
.altars-toggle-button {
    justify-content: center;
}


.upgrade-toggle-icon,
.death-toggle-icon,
.altars-toggle-icon {
    display: inline-flex;

    align-items: center;
    justify-content: center;

    width: 1em;

    text-align: center;
}


/*
 * Keep the Upgrade toggle's keybind badge visible even while the
 * button is collapsed to just its icon, matching the Death Tracker
 * and Altars toggles (see the equivalent rule in their own CSS
 * files). Declared here with !important since Upgrades.css loads
 * after this file and would otherwise win the cascade with its own
 * (collapsed-by-default) rule for the same class.
 */
.upgrade-toggle-button .upgrade-toggle-key {
    max-width: 30px !important;
    margin-left: 6px !important;
    opacity: 1 !important;
}