/* components.css - Reusable UI Components */

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.625rem 1.25rem;
    border-radius: var(--radius-sm);
    font-family: 'DM Sans', sans-serif;
    font-weight: 600;
    font-size: 0.875rem;
    cursor: pointer;
    transition: all 0.2s ease;
    border: none;
    outline: none;
    letter-spacing: 0.01em;
}

.btn-primary {
    background: linear-gradient(135deg, #00E5FF 0%, #2979FF 100%);
    color: white;
    font-weight: 800;
    box-shadow: 0 4px 20px rgba(0, 229, 255, 0.35), inset 0 1px 1px rgba(255, 255, 255, 0.4);
    position: relative;
    overflow: hidden;
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.btn-primary::after {
    content: '';
    position: absolute;
    top: 0;
    left: -150%;
    width: 50%;
    height: 100%;
    background: linear-gradient(
        90deg,
        transparent,
        rgba(255, 255, 255, 0.4),
        transparent
    );
    transform: skewX(-20deg);
}

.btn-primary:hover {
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 6px 20px rgba(0, 229, 255, 0.45), inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

.btn-primary:hover::after {
    animation: global-shimmer 1.2s ease-out infinite;
}

.btn-primary:active {
    transform: translateY(-1px) scale(0.98);
}

@keyframes global-shimmer {
    100% {
        left: 200%;
    }
}

.btn-secondary {
    background: var(--bg-surface);
    color: var(--text-primary);
    border: var(--border-subtle);
    box-shadow: var(--shadow-sm);
}

.btn-secondary:hover {
    background: var(--bg-warm);
    transform: translateY(-1px);
    box-shadow: var(--shadow-md);
}

.btn-secondary:active {
    transform: translateY(0);
}

.btn-large {
    padding: 0.75rem 1.75rem;
    font-size: 0.95rem;
    border-radius: var(--radius-md);
}

/* Search Bar */
.search-container {
    position: relative;
    width: 100%;
    max-width: 480px;
    justify-self: center;
}

.search-input {
    width: 100%;
    padding: 0.625rem 1rem 0.625rem 2.5rem;
    border-radius: var(--radius-sm);
    background: var(--bg-surface);
    border: var(--border-subtle);
    color: var(--text-primary);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.875rem;
    transition: all 0.2s ease;
    box-shadow: var(--shadow-sm);
}

.search-input::placeholder {
    color: var(--text-light);
}

.search-input:focus {
    outline: none;
    border-color: var(--accent-royal-blue);
    box-shadow: 0 0 0 3px rgba(46, 90, 155, 0.1);
}

.search-btn {
    position: absolute;
    left: 0.75rem;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: var(--text-light);
    cursor: pointer;
    display: flex;
    transition: color 0.2s;
}

.search-input:focus ~ .search-btn {
    color: var(--accent-royal-blue);
}

/* Cards */
.toybox-card {
    border-radius: var(--radius-md);
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    text-decoration: none;
    color: inherit;
    background: var(--bg-card);
    border: var(--border-subtle);
    box-shadow: var(--shadow-sm);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.toybox-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
    border-color: rgba(0, 229, 255, 0.45);
}

.card-image-wrapper {
    position: relative;
    aspect-ratio: 16/9;
    overflow: hidden;
    background: var(--bg-warm);
    border-bottom: var(--border-subtle);
}

.card-image {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}

.toybox-card:hover .card-image {
    transform: scale(1.04);
}

.card-content {
    padding: 1.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    flex: 1;
    background: transparent;
}

.card-title {
    /* Was 1.15rem, which under a 200px-tall picture read as a caption rather
       than as the name of the thing. */
    font-size: 1.3rem;
    font-weight: 700;
    margin: 0;
    color: var(--text-primary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.35;
    min-height: 2.7em;
}

.card-creator {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
    color: var(--text-primary);
    font-weight: 600;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.82rem;
    min-height: 24px;
}

.card-date {
    font-size: 0.82rem;
    color: var(--text-secondary);
    font-family: 'DM Sans', sans-serif;
    font-weight: 400;
}

.metadata-separator {
    color: var(--text-light);
    font-weight: 400;
}

/* The candy gum from the Creators leaderboard, now the avatar everywhere.
   It is not just a colour: the white ring, the shading at the bottom and the
   soft highlight at the top left are what make it read as a glossy sweet
   rather than a flat disc. Copying the colour alone left every other page
   looking like a cheaper version of the same thing.
   Both colours come from the creator's NAME (candyFor in avatars.js), so one
   person looks the same in the ranking, on a toybox page and in the cart. */
.creator-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: linear-gradient(150deg, var(--tb-c1, #a97bf0), var(--tb-c2, #d2a6f8));
    box-shadow: inset 0 -3px 6px rgba(60, 16, 48, 0.18),
                0 0 0 2px rgba(255, 255, 255, 0.92);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Montserrat', 'DM Sans', sans-serif;
    font-size: 0.62rem;
    font-weight: 800;
    color: #3c1030;
    /* The photo (when there is one) is laid over the initial, so a missing
       file simply falls back to the coloured circle. */
    position: relative;
    overflow: hidden;
    flex-shrink: 0;
}

/* The highlight. Sits above the picture too, at a fraction of its strength,
   which is what stops a photo avatar looking pasted on. */
.creator-avatar::after {
    content: "";
    position: absolute;
    top: 11%;
    left: 16%;
    width: 44%;
    height: 32%;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.6);
    filter: blur(1.5px);
    pointer-events: none;
}

.creator-avatar.has-photo::after {
    opacity: 0.28;
}

/* With a photo the letter underneath would show through the round corners. */
.creator-avatar.has-photo .creator-avatar-initial {
    visibility: hidden;
}

.creator-avatar-initial {
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
}

.creator-avatar img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

.creator-avatar.has-photo {
    background: #fff;
}

/* Tag Pills */
.tags-container {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    position: absolute;
    top: 0.625rem;
    left: 0.625rem;
    z-index: 10;
}

.tag {
    padding: 0.2rem 0.5rem;
    border-radius: 4px;
    font-size: 0.6rem;
    font-weight: 700;
    font-family: 'DM Sans', sans-serif;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid rgba(44, 37, 32, 0.1);
    color: var(--text-secondary);
    transition: all 0.15s ease;
}

.tag:hover {
    box-shadow: var(--shadow-sm);
}

/* Specific Tag Colors */
.tag.star-wars { 
    color: #B8860B; 
    background: rgba(212, 168, 67, 0.12);
    border-color: rgba(212, 168, 67, 0.25);
}
.tag.marvel { 
    color: var(--accent-crimson); 
    background: rgba(192, 57, 43, 0.08);
    border-color: rgba(192, 57, 43, 0.2);
}
.tag.disney { 
    color: var(--accent-royal-blue); 
    background: rgba(46, 90, 155, 0.08);
    border-color: rgba(46, 90, 155, 0.2);
}

/* Horizontal Scroller */
.scroller-section {
    margin-bottom: 2.5rem;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.section-title {
    font-size: 1.85rem;
    font-weight: 800;
    color: var(--text-primary);
    margin: 0;
}

.horizontal-scroller {
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    padding-bottom: 0.75rem;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
}

.horizontal-scroller::-webkit-scrollbar {
    display: none;
}

.scroller-item {
    flex: 0 0 360px;
    scroll-snap-align: start;
    display: flex;
}

.scroller-item .toybox-card {
    width: 100%;
}

/* Hero Slideshow Carousel */
/* Hero Slideshow Carousel */
.hero-carousel {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    width: 100%;
    aspect-ratio: 21 / 9;
    min-height: 520px;
    max-height: 820px;
    margin-bottom: 2.5rem;
    border: var(--border-subtle);
    box-shadow: var(--shadow-lg);
}

.hero-slide {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    opacity: 0;
    z-index: 1;
    transition: opacity 0.8s ease-in-out;
    display: flex;
    align-items: flex-end;
    padding: clamp(2rem, 5vw, 4rem) clamp(2rem, 6vw, 5rem);
}

.hero-slide.active {
    opacity: 1;
    z-index: 2;
}

.hero-bg {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    object-fit: cover;
    z-index: 1;
}

.hero-overlay {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    background: linear-gradient(
        to right, 
        rgba(11, 14, 26, 0.95) 0%, 
        rgba(11, 14, 26, 0.75) 35%, 
        rgba(11, 14, 26, 0.2) 70%,
        transparent 100%
    );
    z-index: 2;
}

.hero-content {
    position: relative;
    z-index: 3;
    max-width: 750px;
    color: #FFFFFF;
}

.hero-title {
    font-size: clamp(2rem, 4vw, 3.8rem);
    margin-bottom: 0.8rem;
    color: #FFFFFF;
    font-weight: 800;
    line-height: 1.15;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.5);
}

.hero-desc {
    font-size: clamp(0.9rem, 1.2vw, 1.15rem);
    color: rgba(255, 255, 255, 0.85);
    margin-bottom: 1.75rem;
    font-family: 'DM Sans', sans-serif;
    line-height: 1.45;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

.hero-meta {
    font-size: 0.85rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: #FFFFFF;
    margin-bottom: 0.6rem;
}

.hero-carousel-dots {
    position: absolute;
    bottom: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 8px;
    z-index: 10;
}

.carousel-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.4);
    cursor: pointer;
    transition: all 0.3s ease;
    border: none;
    outline: none;
}

.carousel-dot.active {
    background: #00E5FF;
    transform: scale(1.2);
    width: 20px;
    border-radius: 4px;
}

/* Brand Category Cards */
.brand-categories {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr));
    gap: 20px;
    margin-bottom: 2.5rem;
}

.brand-card {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: var(--border-subtle);
    box-shadow: var(--shadow-md);
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    container-type: inline-size;
}

.brand-card::before {
    content: '';
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    background: radial-gradient(circle at center, rgba(255, 255, 255, 0.1) 0%, transparent 70%);
    transition: opacity 0.3s ease;
    z-index: 1;
}

.brand-card:hover {
    transform: translateY(-8px) scale(1.04);
    box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.brand-card-disney {
    background: linear-gradient(135deg, #00B0FF 0%, #002f6c 100%);
    border-color: rgba(0, 229, 255, 0.3);
}

.brand-card-disney:hover {
    border-color: #00E5FF;
    box-shadow: 0 8px 30px rgba(0, 229, 255, 0.45), var(--shadow-lg);
}

.brand-card-marvel {
    background: linear-gradient(135deg, #FF1744 0%, #3e0000 100%);
    border-color: rgba(255, 82, 82, 0.3);
}

.brand-card-marvel:hover {
    border-color: #FF5252;
    box-shadow: 0 8px 30px rgba(255, 82, 82, 0.45), var(--shadow-lg);
}

.brand-card-starwars {
    background: linear-gradient(135deg, #FF9100 0%, #1a0f00 100%);
    border-color: rgba(255, 213, 79, 0.3);
}

.brand-card-starwars:hover {
    border-color: #FFD54F;
    box-shadow: 0 8px 30px rgba(255, 213, 79, 0.45), var(--shadow-lg);
}

.brand-card-bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    opacity: 0.2; /* Exactly 20% opacity as requested */
    z-index: 1;
    transition: transform 0.5s cubic-bezier(0.25, 0.8, 0.25, 1);
    pointer-events: none;
}

.brand-card:hover .brand-card-bg {
    transform: scale(1.08);
}

/* Custom CSS Brand Logos using container query units (cqw) */
.brand-logo-disney {
    font-family: 'Montserrat', sans-serif;
    font-weight: 900;
    font-size: 11cqw;
    color: #2DF5FF;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-shadow: 0 0 20px rgba(45, 245, 255, 0.4);
    position: relative;
    z-index: 2;
}

.brand-logo-marvel {
    font-family: 'Montserrat', sans-serif;
    font-weight: 900;
    font-size: 12cqw;
    color: #FFFFFF;
    letter-spacing: -0.02em;
    text-transform: uppercase;
    text-shadow: 0 4px 15px rgba(0, 0, 0, 0.4);
    position: relative;
    z-index: 2;
}

.brand-logo-starwars {
    font-family: 'Montserrat', sans-serif;
    font-weight: 900;
    font-size: 10cqw;
    color: #FFC524;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-align: center;
    text-shadow: 0 0 16px rgba(255, 197, 36, 0.45);
    line-height: 1.1;
    position: relative;
    z-index: 2;
}

/* Homepage Centered Search Bar */
.homepage-search-section {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 3rem;
    width: 100%;
    /* The brand tiles below are position:relative, so they paint after this
       section and covered the suggestion dropdown — the panel's own z-index
       could not help, because it only competes inside its own parent. Lifting
       the whole section fixes it once for everything it contains. */
    position: relative;
    z-index: 30;
}

/* ══════════════════════════════════════════════════════════════════════════
   THE SEARCH BAR
   ══════════════════════════════════════════════════════════════════════════
   One frame holding both rows: the field on top, the filters beneath a hairline
   inside the same border. They were a bar with a separate row of buttons
   floating under it, which read as two unrelated things; the reference design
   keeps everything in the bar, and so does this.

   Colours and motion are borrowed from .btn-primary and .scroller-arrow rather
   than invented here — the cyan-to-blue gradient, the shimmer sweep on hover,
   the small lift. A search bar that glowed gold was the only gold thing on the
   page.
   ══════════════════════════════════════════════════════════════════════════ */
.search-shell {
    position: relative;
    /* As wide as the brand tiles below it are apart, centre to centre. With
       three equal columns of width W and a 20px gap in a container of width T,
       W = (T - 2*20)/3, so centre-to-centre is T - W = (2T + 40)/3. A fixed
       860px cap left the bar looking timid on a wide screen while the tiles
       under it ran the full width. */
    width: calc((200% + 40px) / 3);
    max-width: 100%;
    background: var(--bg-surface);
    border: 1.5px solid var(--border-color);
    border-radius: 28px;
    box-shadow: var(--shadow-md);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
}

.search-shell:hover {
    border-color: var(--field-border-hover);
}

/* focus-within, not :focus: the glow belongs to the whole bar, whichever part
   of it the visitor is actually in. */
.search-shell:focus-within {
    border-color: #2979FF;
    box-shadow: 0 0 0 4px rgba(41, 121, 255, 0.14),
                0 8px 28px rgba(0, 229, 255, 0.20),
                var(--shadow-md);
}

/* Inside the bar the input brings no frame of its own — the bar is the frame.
   The bare .homepage-search-input rules still apply on the search results
   page, where the field stands alone. */
.search-shell .homepage-search-input,
.search-shell .homepage-search-input:hover,
.search-shell .homepage-search-input:focus {
    background: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
    outline: none;
    padding: 1.15rem 4.4rem 1.15rem 3.85rem;
}

/* The row holding the field, the magnifier and the arrow. It carried a
   max-width of 860px from the days when this row WAS the search bar; now the
   bar around it sets the width, and the leftover cap pinned the arrow 860px
   from the left edge — which on a wide screen left it sitting in the middle of
   the bar with 300px of empty field beside it. The bar owns the width. */
.homepage-search-container {
    position: relative;
    width: 100%;
}

.homepage-search-input {
    width: 100%;
    padding: 1.3rem 4.4rem 1.3rem 3.85rem;
    border-radius: 40px;
    background: var(--bg-surface);
    border: 1.5px solid var(--border-color);
    color: var(--text-primary);
    font-family: 'DM Sans', sans-serif;
    font-size: 1.2rem;
    transition: border-color 0.2s ease, box-shadow 0.25s ease;
    box-shadow: var(--shadow-md);
}

.homepage-search-input::placeholder {
    color: var(--text-muted);
}

.homepage-search-input:hover {
    border-color: var(--field-border-hover);
}

.homepage-search-input:focus {
    outline: none;
    border-color: #2979FF;
    box-shadow: 0 0 0 4px rgba(41, 121, 255, 0.14), var(--shadow-lg);
}

.sb-input-icon {
    position: absolute;
    left: 1.4rem;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    color: var(--text-muted);
    pointer-events: none;
    transition: color 0.2s;
}

.homepage-search-input:focus ~ .sb-input-icon {
    color: #2979FF;
}

/* Same gradient, shadow and shimmer as .btn-primary, on a circle. */
.homepage-search-btn {
    position: absolute;
    right: 0.5rem;
    top: 50%;
    transform: translateY(-50%);
    width: 46px;
    height: 46px;
    border-radius: 50%;
    border: none;
    background: linear-gradient(135deg, #00E5FF 0%, #2979FF 100%);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    box-shadow: 0 4px 16px rgba(0, 229, 255, 0.35), inset 0 1px 1px rgba(255, 255, 255, 0.4);
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
}

.homepage-search-btn::after {
    content: '';
    position: absolute;
    top: 0;
    left: -150%;
    width: 50%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
    transform: skewX(-20deg);
}

/* translateY(-50%) has to be repeated in every transform that follows, or the
   button drops to the bottom of the field the moment it is hovered. */
.homepage-search-btn:hover,
.homepage-search-btn:focus-visible {
    transform: translateY(-50%) scale(1.08);
    box-shadow: 0 6px 22px rgba(0, 229, 255, 0.45), inset 0 1px 1px rgba(255, 255, 255, 0.4);
    outline: none;
}

.homepage-search-btn:hover::after {
    animation: global-shimmer 1.2s ease-out infinite;
}

.homepage-search-btn:active {
    transform: translateY(-50%) scale(0.98);
}

/* ── the filters, inside the bar ───────────────────────────────────────── */
.sb-filters {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border-top: 1px solid var(--border-color);
    min-width: 0;
}

.sb-pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    min-height: 38px;
    padding: 0.4rem 0.95rem;
    border-radius: 999px;
    border: 1.5px solid var(--border-color);
    background: var(--bg-card, #fff);
    color: var(--text-secondary);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.86rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.sb-pill:hover,
.sb-pill:focus-visible,
.sb-pill[aria-expanded="true"] {
    border-color: #2979FF;
    color: #2979FF;
    transform: translateY(-2px);
    box-shadow: 0 4px 14px rgba(41, 121, 255, 0.18);
    outline: none;
}

.sb-pill:active { transform: translateY(0) scale(0.98); }

/* The one button that has to be found without reading. */
/* No border, deliberately. A transparent one plus overflow:hidden and a
   999px radius left a dark ring around the whole pill: the background is cut
   to the border-box curve while the overflow clip follows the padding-box
   curve, and the seam between the two darkened every edge. The padding takes
   over the 1.5px so it stays the same size as the outlined Tags pill. */
.sb-pill-primary {
    position: relative;
    overflow: hidden;
    background: linear-gradient(135deg, #00E5FF 0%, #2979FF 100%);
    border: none;
    padding: calc(0.4rem + 1.5px) calc(0.95rem + 1.5px);
    color: #fff;
    font-weight: 800;
    box-shadow: 0 4px 16px rgba(0, 229, 255, 0.32), inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

.sb-pill-primary::after {
    content: '';
    position: absolute;
    top: 0;
    left: -150%;
    width: 50%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.4), transparent);
    transform: skewX(-20deg);
}

/* Wins over the shared .sb-pill:hover, which would turn this one blue-on-blue. */
.sb-pill-primary:hover,
.sb-pill-primary:focus-visible {
    border: none;
    color: #fff;
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 6px 22px rgba(0, 229, 255, 0.45), inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

.sb-pill-primary:hover::after {
    animation: global-shimmer 1.2s ease-out infinite;
}

.sb-caret { transition: transform 0.2s ease; }
.sb-pill[aria-expanded="true"] .sb-caret { transform: rotate(180deg); }

.sb-menu-wrap { position: relative; display: inline-flex; }

.sb-menu {
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    min-width: 260px;
    max-width: min(320px, 90vw);
    max-height: 340px;
    overflow-y: auto;
    padding: 6px;
    background: var(--bg-surface);
    border: var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    z-index: 40;
    animation: sb-menu-in 0.16s ease both;
}

@keyframes sb-menu-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce) {
    .sb-menu { animation: none; }
}

.sb-menu-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 0.55rem 0.7rem;
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    transition: background-color 0.15s ease, color 0.15s ease;
}

/* The colour is not optional here. A global `a:hover { color: #FFFFFF }` left
   over from the dark design turns every link white on hover, which on this
   cream row meant the tag name all but disappeared under the cursor. */
.sb-menu-row:hover,
.sb-menu-row:focus-visible {
    background: rgba(41, 121, 255, 0.08);
    color: #2979FF;
    outline: none;
}

.sb-dot {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--tb-tag-c, var(--accent-royal-blue));
}

.sb-menu-name { flex: 1 1 auto; min-width: 0; }

.sb-menu-count {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 800;
}

.sb-menu-row:hover .sb-menu-count { color: #2979FF; }

.sb-menu-empty {
    margin: 0;
    padding: 0.7rem;
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* Detail View */
.detail-view {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

.breadcrumb {
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-family: 'DM Sans', sans-serif;
    margin-bottom: 0.5rem;
    font-weight: 500;
}

.breadcrumb a {
    color: var(--text-secondary);
    font-weight: 500;
    opacity: 0.8;
}

.breadcrumb a:hover {
    color: var(--accent-royal-blue);
    opacity: 1;
}

.breadcrumb span {
    color: var(--text-primary);
    font-weight: 600;
}

.detail-grid {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 2rem;
    /* `start` left the right-hand panel floating at its own height with a gap
       of page under it whenever the description was short. Stretching makes
       the two columns end on the same line, whichever of them is taller. */
    align-items: stretch;
}

/* A grid item will not shrink below its content's own minimum unless it is
   told to. The thumbnail strip is a row of fixed 120px thumbs, so a toybox
   with nine screenshots demanded 986px — and on a phone the single column grew
   to 986px inside a 343px page and everything to the right of the fold was
   simply cut off. The strip already scrolls sideways on its own; this lets the
   column be narrower than it, which is what makes that scrolling work. */
.detail-left,
.detail-right {
    min-width: 0;
}

.detail-left {
    display: flex;
    flex-direction: column;
    gap: 2rem;
}

.detail-gallery {
    position: relative;
    padding: 0.75rem;
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.detail-gallery.has-thumbnails {
    padding-right: 0.75rem;
}

.main-image-container {
    width: 100%;
    aspect-ratio: 16/9;
    background: var(--bg-warm);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.detail-main-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.thumbnail-strip {
    position: relative;
    top: auto;
    bottom: auto;
    right: auto;
    width: 100%;
    display: flex;
    flex-direction: row;
    gap: 0.75rem;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
    scrollbar-color: rgba(0, 229, 255, 0.35) rgba(255, 255, 255, 0.05);
    padding-bottom: 4px;
}

.thumbnail-strip::-webkit-scrollbar {
    height: 5px;
}

.thumbnail-strip::-webkit-scrollbar-track {
    background: rgba(255, 255, 255, 0.03);
    border-radius: 10px;
}

.thumbnail-strip::-webkit-scrollbar-thumb {
    background: rgba(0, 229, 255, 0.35);
    border-radius: 10px;
}

.thumbnail-strip::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 229, 255, 0.6);
}

.detail-thumb {
    width: 120px;
    flex-shrink: 0;
    aspect-ratio: 16/9;
    object-fit: cover;
    border-radius: 6px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: all 0.2s ease;
    opacity: 0.5;
}

.detail-thumb.active, .detail-thumb:hover {
    border-color: #00E5FF;
    opacity: 1;
}

.detail-right {
    padding: 1.5rem;
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.detail-title {
    font-size: 2rem;
    margin: 0;
    font-weight: 800;
}

.detail-creator-block {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-bottom: 1.25rem;
}

.detail-creator {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.creator-avatar.large {
    width: 40px;
    height: 40px;
    font-size: 1rem;
    box-shadow: inset 0 -3px 6px rgba(60, 16, 48, 0.18),
                0 0 0 3px rgba(255, 255, 255, 0.92);
    border-radius: 50%;
    /* Inherits the candy pair from .creator-avatar — this rule used to repaint
       it purple-blue, which is why one and the same creator looked different
       on the leaderboard and on a toybox page. */
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 800;
}

.creator-avatar.large.has-photo {
    background: #fff;
}

/* Cart page: the person glyph in the "By <name>" bar becomes the real face. */
.creator-avatar.tiny {
    width: 18px;
    height: 18px;
    font-size: 0.55rem;
    /* A 2px ring around an 18px circle is a tenth of it — the same ring that
       looks right at 40px swallows the small one. */
    box-shadow: inset 0 -2px 4px rgba(60, 16, 48, 0.18),
                0 0 0 1.5px rgba(255, 255, 255, 0.92);
}

.creator-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.creator-label {
    font-size: 0.72rem;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-family: 'DM Sans', sans-serif;
    font-weight: 700;
    line-height: 1;
}

.creator-links {
    font-family: 'DM Sans', sans-serif;
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.2;
    color: var(--text-primary);
}

.detail-date {
    display: flex;
    align-items: center;
    color: var(--text-muted);
    font-size: 0.85rem;
    font-family: 'DM Sans', sans-serif;
    margin-top: 0.2rem;
}

.detail-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.tag-solid {
    padding: 0.35rem 0.75rem;
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    background: rgba(124, 77, 255, 0.08);
    border: 1px solid rgba(124, 77, 255, 0.2);
    color: #7C4DFF;
    font-weight: 600;
    transition: all 0.2s ease;
}

.detail-tag-link {
    text-decoration: none;
    display: inline-block;
}

.detail-tag-link:hover .tag-solid {
    border-color: #00E5FF;
    color: #00E5FF;
    background: rgba(0, 229, 255, 0.08);
    box-shadow: 0 2px 8px rgba(0, 229, 255, 0.15);
}

.detail-description {
    font-size: 1.02rem;
    font-weight: 500;
    line-height: 1.75;
    color: var(--text-secondary);
    font-family: 'DM Sans', sans-serif;
}

.detail-divider {
    border: none;
    border-top: var(--border-subtle);
    margin: 0.25rem 0;
}

.download-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.download-buttons {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.file-download-btn {
    width: 100%;
    justify-content: center;
    padding: 0.75rem;
}

.video-container {
    padding: 0;
    overflow: hidden;
    border-radius: var(--radius-lg);
    display: flex;
    flex-direction: column;
}

.video-container iframe {
    border-radius: 0;
    aspect-ratio: 16/9;
    height: auto;
    width: 100%;
    display: block;
    border: 0;
}

/* Click-to-play thumbnail. It replaces itself with the real <iframe> on the
   first click, so a player that never loads can no longer sit there as a dead
   rectangle that eats the click. */
.video-facade {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 16/9;
    padding: 0;
    border: 0;
    margin: 0;
    background: #000;
    cursor: pointer;
    overflow: hidden;
}

.video-facade img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.35s ease, opacity 0.2s ease;
}

.video-facade:hover img,
.video-facade:focus-visible img {
    transform: scale(1.03);
    opacity: 0.9;
}

.video-play-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    pointer-events: none;
    display: flex;
}

.video-play-btn svg {
    width: 68px;
    height: 48px;
    filter: drop-shadow(0 2px 6px rgba(0, 0, 0, 0.4));
}

.video-play-bg {
    fill: #212121;
    fill-opacity: 0.8;
    transition: fill 0.2s ease, fill-opacity 0.2s ease;
}

.video-facade:hover .video-play-bg,
.video-facade:focus-visible .video-play-bg {
    fill: #f00;
    fill-opacity: 1;
}

/* Always reachable, for the videos whose owner disabled embedding. */
.video-watch-link {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 0.6rem;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-secondary);
    text-decoration: none;
    border-top: 1px solid var(--border-subtle);
    transition: color 0.2s ease, background 0.2s ease;
}

.video-watch-link:hover {
    color: var(--accent-royal-blue);
    background: rgba(0, 0, 0, 0.03);
}

.creator-avatar-link {
    text-decoration: none;
    cursor: pointer;
    display: flex;
    align-items: center;
}

.creator-profile-link {
    color: var(--accent-royal-blue);
    text-decoration: none;
    transition: color 0.2s ease;
}

.creator-profile-link:hover {
    color: #00E5FF;
}

.more-from-creator-link {
    color: var(--text-primary);
    text-decoration: none;
    font-weight: 700;
    transition: color 0.2s ease;
}

.more-from-creator-link:hover {
    color: #00E5FF;
}

.creator-tb-card:hover {
    transform: translateY(-4px);
    border-color: rgba(0, 229, 255, 0.45) !important;
    box-shadow: var(--shadow-md) !important;
}

/* Subtoybox Badge on Cards */
.subtoybox-badge {
    position: absolute;
    bottom: 0.75rem;
    right: 0.75rem;
    z-index: 10;
    padding: 0.25rem 0.55rem;
    border-radius: 20px;
    font-size: 0.72rem;
    font-weight: 700;
    font-family: 'DM Sans', sans-serif;
    background: rgba(0, 0, 0, 0.82);
    border: 1px solid rgba(255, 255, 255, 0.18);
    color: #FFFFFF;
    display: flex;
    align-items: center;
    box-shadow: var(--shadow-sm);
    transition: transform 0.2s ease;
}
.toybox-card:hover .subtoybox-badge,
.creator-tb-card:hover .subtoybox-badge {
    transform: scale(1.05);
    background: rgba(0, 0, 0, 0.8);
    border-color: rgba(0, 229, 255, 0.4);
}

/* Subtoybox Details on Detail Page */
/* ══════════════════════════════════════════════════════════════════════════
   SUBTOYBOXES
   ══════════════════════════════════════════════════════════════════════════
   A list of plain rows separated by hairlines read as leftovers under the
   description. It is a panel of its own now: a tinted header saying how many
   there are, and one card per level. The number keeps the spacing it had —
   close to its title, not pushed away from it.
   ══════════════════════════════════════════════════════════════════════════ */
.detail-subtoyboxes-section {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin: 0;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.subtoyboxes-title {
    display: flex;
    align-items: center;
    margin: 0;
    padding: 0.8rem 1rem;
    background: rgba(41, 121, 255, 0.07);
    border-bottom: 1px solid var(--border-color);
    font-family: 'DM Sans', sans-serif;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--accent-royal-blue);
}

.subtoyboxes-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 10px;
}

.subtoybox-item {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 11px 13px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    transition: background-color 0.18s ease, border-color 0.18s ease;
}

.subtoybox-item:hover,
.subtoybox-item.has-desc {
    background: rgba(41, 121, 255, 0.05);
    border-color: rgba(41, 121, 255, 0.22);
}

.subtoybox-header {
    display: flex;
    align-items: center;
    /* Deliberately tight. The reference drawing had the number far from its
       title; at that distance the two stop reading as one line. */
    gap: 10px;
}

.subtoybox-number {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
    width: 26px;
    height: 26px;
    background: rgba(41, 121, 255, 0.12);
    color: var(--accent-royal-blue);
    font-size: 0.8rem;
    font-weight: 800;
    border-radius: 50%;
}

.subtoybox-name {
    font-family: 'DM Sans', sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--text-primary);
    min-width: 0;
}

.subtoybox-item.has-desc .subtoybox-name { color: var(--accent-royal-blue); }

.subtoybox-desc {
    font-family: 'DM Sans', sans-serif;
    font-size: 0.85rem;
    color: var(--text-secondary);
    /* 26px chip + 10px gap: the description lines up under the title. */
    margin: 2px 0 0 36px;
    line-height: 1.5;
}

@media screen and (max-width: 480px) {
    .subtoyboxes-list { padding: 8px; gap: 6px; }
    .subtoybox-item { padding: 10px; }
    .subtoybox-desc { margin-left: 0; }
}

/* Error Message */
.error-msg {
    text-align: center;
    padding: 4rem 2rem;
}

.text-muted {
    color: var(--text-muted);
}

/* Scroller wrapper and navigation arrows */
.scroller-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
}

.scroller-arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: rgba(11, 14, 26, 0.85);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: #FFFFFF;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 10;
    transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
}

.scroller-arrow:hover:not(.disabled) {
    background: rgba(255, 255, 255, 0.15);
    border-color: rgba(255, 255, 255, 0.25);
    transform: translateY(-50%) scale(1.08);
    box-shadow: 0 6px 20px rgba(255, 255, 255, 0.15), 0 4px 15px rgba(0, 0, 0, 0.4);
}

.scroller-arrow:active:not(.disabled) {
    transform: translateY(-50%) scale(0.98);
}

.scroller-arrow.disabled {
    opacity: 0;
    pointer-events: none;
}

.arrow-left {
    left: -24px;
}

.arrow-right {
    right: -24px;
}

/* Play Button Overlay on Cards */
.card-play-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%) scale(0.7);
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.96);
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
    z-index: 6;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.4);
    pointer-events: none;
}

/* The chest is a dark drawing on transparency, so it is turned white to sit
   on the translucent circle — brightness(0) flattens it to black first, which
   is what makes invert() come out as a clean white silhouette rather than the
   photo negative of its colours. */
.card-play-btn img {
    width: 30px;
    height: 30px;
    object-fit: contain;
    filter: brightness(0) invert(1);
}

/* A white chest needs a dark circle behind it — the light one it used to sit
   on would have swallowed it. */
.card-play-btn {
    background: rgba(20, 16, 12, 0.55);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    border: 1.5px solid rgba(255, 255, 255, 0.55);
}

.toybox-card:hover .card-play-btn {
    opacity: 1;
    transform: translate(-50%, -50%) scale(1);
}

/* The card is the box; the link is what sits inside it, next to the
   Add to Cart button. Both used to be one anchor. */
.creator-tb-card {
    display: flex;
    flex-direction: column;
    gap: 10px;
    flex: 0 0 240px;
    max-width: 240px;
    color: inherit;
    padding: 12px;
    border-radius: var(--radius-md);
    border: var(--border-subtle);
    background: var(--bg-card);
    box-shadow: var(--shadow-sm);
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: hidden;
    scroll-snap-align: start;
}

.creator-tb-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-md);
    border-color: rgba(0, 229, 255, 0.3);
}

.creator-tb-card-img-wrapper {
    position: relative;
    width: 100%;
    aspect-ratio: 16/9;
    overflow: hidden;
    border-radius: var(--radius-sm);
    margin-bottom: 12px;
    background: var(--bg-warm);
    border-bottom: var(--border-subtle);
}

.creator-tb-card-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.5s ease;
}

.creator-tb-card:hover .creator-tb-card-img {
    transform: scale(1.05);
}

.creator-tb-card-link {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
}

.creator-tb-card-title {
    margin: 0;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-primary);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.35;
    min-height: 2.6rem;
}

/* Slightly smaller than on the big cards: this row is a suggestion, not the
   main event, and the button should not shout over the title. */
.creator-tb-card .add-to-cart-btn {
    margin-top: auto;
    font-size: 0.78rem !important;
    min-height: 40px !important;
    padding: 0.5rem 0.75rem !important;
}

/* Holomap Section */
.holomap-section {
    margin-bottom: 2.5rem;
}

.holomap-wrapper {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    border: var(--border-subtle);
    background: #020611;
}

.holomap-iframe {
    width: 100%;
    border: none;
    display: block;
    aspect-ratio: 21 / 9;
    min-height: 520px;
    max-height: 820px;
}

/* Bundle Banner Section */
.bundle-banner-section {
    margin-bottom: 2.5rem;
}

.bundle-banner-wrapper {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    border: var(--border-subtle);
    background: #05070d;
}

.bundle-banner-iframe {
    width: 100%;
    border: none;
    display: block;
    aspect-ratio: 21 / 9;
    min-height: 520px;
    max-height: 820px;
}

/* Random Selection Section */
.random-selection-section {
    margin-bottom: 2.5rem;
}

.random-selection-wrapper {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    background: transparent;
}

.random-selection-iframe {
    width: 100%;
    border: none;
    display: block;
    height: 440px;
}

/* Mod Banner Section */
.mod-banner-section {
    margin-bottom: 2.5rem;
}

.mod-banner-wrapper {
    position: relative;
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    border: var(--border-subtle);
    background: #26140A;
}

.mod-banner-iframe {
    width: 100%;
    border: none;
    display: block;
    aspect-ratio: 21 / 9.5;
    min-height: 560px;
    max-height: 860px;
}

/* Responsive Design / Mobile Adjustments */
@media screen and (max-width: 768px) {
    /* Detail View Grid */
    .detail-grid {
        grid-template-columns: 1fr;
        gap: 1.5rem;
    }
    .detail-left {
        gap: 1.5rem;
    }
    .detail-right {
        padding: 1rem;
    }
    .detail-title {
        font-size: 1.6rem;
    }
    
    /* Horizontal Scroller */
    .scroller-item {
        flex: 0 0 85vw;
    }
    .section-title {
        font-size: 1.5rem;
    }
    
    /* Hero Carousel */
    .hero-carousel {
        min-height: 380px;
    }
    .hero-slide {
        padding: 2rem 1.5rem;
    }
    .hero-title {
        font-size: 1.8rem;
    }
    .hero-desc {
        font-size: 0.95rem;
    }
    
    /* Homepage Search */
    .homepage-search-input {
        padding: 1rem 4.4rem 1rem 3.3rem;
        font-size: 1.05rem;
    }
    .sb-input-icon { left: 1.15rem; }
    .search-shell .homepage-search-input {
        padding: 1rem 4.4rem 1rem 3.3rem;
    }
    .homepage-search-btn {
        width: 42px;
        height: 42px;
        right: 0.45rem;
    }
}

@media screen and (max-width: 480px) {
    /* Brand Categories Layout */
    .brand-categories {
        grid-template-columns: 1fr;
    }
    .brand-card {
        aspect-ratio: 21 / 9;
    }
}

/* ==========================================================================
   Main Nav Cart Item & Badge
   ========================================================================== */
.nav-cart-wrapper {
    position: relative;
    display: inline-flex;
    align-items: center;
    z-index: 2;
}

.nav-cart-link {
    display: inline-flex !important;
    align-items: center !important;
    gap: 6px !important;
    padding-right: 0.85rem !important;
}

.nav-cart-link svg {
    stroke: currentColor;
    transition: transform 0.2s ease;
}

.nav-cart-link:hover svg {
    transform: scale(1.1);
}

.cart-nav-badge {
    background: var(--accent-royal-blue);
    color: #FFFFFF;
    font-size: 0.72rem;
    font-weight: 800;
    padding: 1px 6px;
    border-radius: 10px;
    min-width: 17px;
    text-align: center;
    line-height: 1.3;
    transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1), background-color 0.2s ease;
}

.nav-link.active .cart-nav-badge {
    background: #FFFFFF;
    color: var(--accent-royal-blue);
}

@keyframes badgePop {
    0% { transform: scale(1); }
    40% { transform: scale(1.45); }
    100% { transform: scale(1); }
}

.cart-nav-badge.badge-pop {
    animation: badgePop 0.35s cubic-bezier(0.16, 1, 0.3, 1);
}

/* ==========================================================================
   eBay-Style Hover Dropdown Preview
   ========================================================================== */
.cart-hover-dropdown {
    position: absolute;
    top: calc(100% + 12px);
    right: -10px;
    width: 360px;
    max-width: 90vw;
    background: #FFFFFF;
    border: var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: 0 12px 35px rgba(44, 37, 32, 0.16), 0 2px 6px rgba(0, 0, 0, 0.04);
    padding: 1.15rem;
    z-index: 9999;
    opacity: 0;
    visibility: hidden;
    transform: translateY(6px);
    transition: all 0.22s cubic-bezier(0.16, 1, 0.3, 1);
    pointer-events: none;
    font-family: 'DM Sans', sans-serif;
    box-sizing: border-box;
}

/* Hover bridge to keep dropdown open when cursor transitions from nav link to dropdown */
.cart-hover-dropdown::before {
    content: '';
    position: absolute;
    top: -16px;
    left: 0;
    right: 0;
    height: 16px;
}

/* Only on devices with a real pointer. On a touchscreen there is no "unhover":
   tapping the cart latched :hover on, and the panel stayed over the page even
   after navigating to the cart. Phones and tablets go straight to #/cart
   instead, which is the better interaction there anyway. */
@media (hover: hover) and (pointer: fine) {
    .nav-cart-wrapper:hover .cart-hover-dropdown,
    .nav-cart-wrapper:focus-within .cart-hover-dropdown {
        opacity: 1;
        visibility: visible;
        transform: translateY(0);
        pointer-events: auto;
    }
}

.hover-dropdown-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-bottom: 0.65rem;
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: 0.75rem;
}

.hover-dropdown-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 6px;
}

.hover-badge {
    background: rgba(46, 90, 155, 0.12);
    color: var(--accent-royal-blue);
    font-size: 0.75rem;
    padding: 1px 6px;
    border-radius: 8px;
    font-weight: 700;
}

.hover-dropdown-empty {
    text-align: center;
    padding: 1.5rem 0.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}

.hover-dropdown-empty p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.9rem;
}

.hover-items-container {
    max-height: 250px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 0.75rem;
    padding-right: 4px;
}

.hover-item-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0;
    border-bottom: 1px solid rgba(44, 37, 32, 0.05);
}

.hover-item-row:last-child {
    border-bottom: none;
}

.hover-item-img {
    width: 50px;
    height: 50px;
    border-radius: 6px;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--bg-warm);
    border: var(--border-subtle);
}

.hover-item-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.hover-item-title {
    font-size: 0.86rem;
    font-weight: 700;
    color: var(--text-primary);
    text-decoration: none;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    display: block;
}

.hover-item-title:hover {
    color: var(--accent-royal-blue);
}

.hover-item-meta {
    font-size: 0.75rem;
    color: var(--text-muted);
}

.hover-item-remove {
    background: transparent;
    border: none;
    color: var(--text-muted);
    cursor: pointer;
    padding: 4px;
    border-radius: 4px;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
}

.hover-item-remove:hover {
    color: var(--accent-crimson);
    background: rgba(192, 57, 43, 0.08);
}

.hover-dropdown-footer {
    border-top: 1px solid var(--border-subtle);
    padding-top: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.hover-total-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.9rem;
}

.hover-total-label {
    font-weight: 700;
    color: var(--text-primary);
}

.hover-total-value {
    font-weight: 700;
    color: var(--accent-teal);
}

.hover-btn-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.hover-checkout-btn {
    width: 100%;
    justify-content: center;
    padding: 8px 12px;
    font-size: 0.9rem;
    font-weight: 700;
}

.hover-view-btn {
    width: 100%;
    justify-content: center;
    padding: 7px 12px;
    font-size: 0.85rem;
    font-weight: 600;
}

/* ==========================================================================
   Full-Page Detailed Cart View (#/cart) - eBay Style
   ========================================================================== */
.cart-page-wrap {
    /* The cart used to sit in a 1140px column while the rest of the site runs
       wider, which made it read as a narrow strip on a desktop screen. */
    max-width: 1320px;
    margin: 0 auto;
    width: 100%;
    padding: 1.5rem 0 4rem 0;
    font-family: 'DM Sans', sans-serif;
}

.cart-page-header {
    margin-bottom: 2rem;
}

.cart-page-title {
    font-size: 2rem;
    font-weight: 800;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 12px;
}

.cart-page-count-badge {
    font-size: 1.1rem;
    font-weight: 600;
    color: var(--text-muted);
}

.cart-page-layout {
    display: grid;
    grid-template-columns: 1fr 390px;
    gap: 2.25rem;
    align-items: start;
}

.cart-page-items-col {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.cart-page-item-card {
    padding: 1.5rem 1.75rem;
    background: #FFFFFF;
    border: var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    transition: all 0.2s ease;
}

.cart-page-item-card:hover {
    border-color: var(--accent-royal-blue);
    box-shadow: var(--shadow-md);
}

.cart-card-creator-bar {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.82rem;
    color: var(--text-muted);
    padding-bottom: 0.65rem;
    margin-bottom: 0.85rem;
    border-bottom: 1px solid var(--border-subtle);
}

.cart-card-creator-bar svg {
    stroke: var(--text-muted);
}

.cart-card-creator-bar strong {
    color: var(--text-primary);
}

.cart-card-creator-bar {
    font-size: 0.88rem;
}

/* Same link, same behaviour as on a toybox page and under "More from …":
   a creator's name turns cyan on hover wherever it appears. It used to go
   royal blue with an underline here and cyan everywhere else, which read as
   two different kinds of link. */
.cart-creator-link {
    color: var(--text-primary);
    font-weight: 700;
    text-decoration: none;
    transition: color 0.2s ease;
}

.cart-creator-link:hover,
.cart-creator-link:focus-visible {
    color: #00E5FF;
    outline: none;
}

.cart-creator-avatar {
    display: inline-flex;
    border-radius: 50%;
    transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.cart-creator-avatar:hover,
.cart-creator-avatar:focus-visible {
    transform: scale(1.12);
    outline: none;
}

.cart-card-main {
    display: flex;
    gap: 1.5rem;
}

.cart-card-img {
    width: 180px;
    height: 122px;
    border-radius: var(--radius-sm);
    object-fit: cover;
    flex-shrink: 0;
    background: var(--bg-warm);
    border: var(--border-subtle);
}

.cart-card-content {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

.cart-card-header-row {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 1rem;
}

.cart-card-title {
    font-size: 1.3rem;
    font-weight: 700;
    color: var(--text-primary);
    text-decoration: none;
    line-height: 1.3;
}

.cart-card-title:hover {
    color: var(--accent-royal-blue);
}

.cart-card-price {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--accent-teal);
    flex-shrink: 0;
}

.cart-card-desc {
    font-size: 0.88rem;
    color: var(--text-secondary);
    line-height: 1.45;
    margin: 6px 0 8px 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.cart-card-tags {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    margin-top: 4px;
}

.cart-sub-badge {
    background: rgba(46, 90, 155, 0.1);
    color: var(--accent-royal-blue);
    font-size: 0.72rem;
    font-weight: 700;
    padding: 2px 7px;
    border-radius: 4px;
}


.cart-card-footer-row {
    margin-top: 12px;
    display: flex;
    justify-content: flex-end;
}

.cart-card-remove-btn {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 8px;
    border-radius: 4px;
    transition: all 0.2s;
}

.cart-card-remove-btn:hover {
    color: var(--accent-crimson);
    background: rgba(192, 57, 43, 0.08);
}

/* Right Column: Sticky Summary */
.cart-page-summary-col {
    position: sticky;
    top: 110px;
}

.cart-summary-card {
    padding: 1.5rem;
    background: #FFFFFF;
    border: var(--border-subtle);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}

.summary-card-title {
    margin: 0 0 0.5rem 0;
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--text-primary);
}

.summary-line {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.92rem;
    color: var(--text-secondary);
}

.summary-val {
    font-weight: 700;
    color: var(--text-primary);
}

.summary-divider {
    height: 1px;
    background: var(--border-subtle);
    margin: 4px 0;
}

.summary-platform-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.summary-platform-label {
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--text-primary);
}

.cart-platform-select {
    width: 100%;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    border: 1.5px solid var(--field-border);
    background: var(--field-bg);
    color: var(--text-primary);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    outline: none;
    box-shadow: inset 0 1px 2px rgba(44, 37, 32, 0.05);
    transition: border-color 0.2s, box-shadow 0.2s;
}

.cart-platform-select:hover {
    border-color: var(--field-border-hover);
}

.cart-platform-select:focus {
    border-color: var(--accent-royal-blue);
    box-shadow: 0 0 0 3px rgba(46, 90, 155, 0.15);
}

.cart-platform-tip {
    margin: 3px 0 0 0;
    font-size: 0.74rem;
    color: var(--text-muted);
    line-height: 1.35;
    font-style: italic;
}

.summary-total-line {
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--text-primary);
    padding-top: 4px;
}

.summary-total-val {
    color: var(--accent-teal);
    font-size: 1.2rem;
}

.cart-page-download-btn {
    width: 100%;
    justify-content: center;
    padding: 12px;
    font-size: 1rem;
    font-weight: 700;
    margin-top: 4px;
}

.summary-clear-wrap {
    text-align: center;
    margin-top: 4px;
}

.cart-page-clear-link {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 0.8rem;
    cursor: pointer;
    text-decoration: underline;
    transition: color 0.2s;
}

.cart-page-clear-link:hover {
    color: var(--accent-crimson);
}

/* Output Structure Radio Buttons */
.summary-output-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.output-mode-radio {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color 0.15s ease;
    font-size: 0.82rem;
    color: var(--text-secondary);
    line-height: 1.35;
}

.output-mode-radio:hover {
    background: var(--bg-warm);
}

.output-mode-radio input[type="radio"] {
    accent-color: var(--accent-royal-blue);
    margin: 0;
    width: 15px;
    height: 15px;
    cursor: pointer;
    flex-shrink: 0;
}

.output-mode-radio input[type="radio"]:checked + span {
    color: var(--text-primary);
    font-weight: 600;
}

/* `hidden` has to beat the flex layouts below, which would otherwise re-show
   whichever of the two summary sections is meant to be put away. */
[hidden] {
    display: none !important;
}

/* PS4 / PS5 save request form (replaces Output Structure for that platform) */
.summary-order-section {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.order-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
}

.order-required-note {
    margin: -4px 0 2px 0;
    font-size: 0.73rem;
    color: var(--text-muted);
}

.order-field label {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--text-secondary);
}

.order-req {
    color: var(--accent-crimson);
    font-weight: 700;
}

.order-input {
    width: 100%;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    border: 1.5px solid var(--field-border);
    background: var(--field-bg);
    color: var(--text-primary);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.88rem;
    outline: none;
    box-shadow: inset 0 1px 2px rgba(44, 37, 32, 0.05);
    transition: border-color 0.2s, box-shadow 0.2s;
}

.order-input::placeholder {
    color: var(--text-light);
}

.order-input:hover {
    border-color: var(--field-border-hover);
}

.order-input:focus {
    border-color: var(--accent-royal-blue);
    background: var(--bg-card);
    box-shadow: 0 0 0 3px rgba(46, 90, 155, 0.15);
}

.order-select {
    font-weight: 600;
    cursor: pointer;
}

.order-input-invalid,
.order-input-invalid:hover {
    border-color: var(--accent-crimson);
    background: rgba(192, 57, 43, 0.06);
}

.order-input-invalid:focus {
    box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.15);
}

.order-info {
    margin-top: 2px;
    border: 1px solid rgba(46, 90, 155, 0.2);
    border-left: 3px solid var(--accent-royal-blue);
    border-radius: var(--radius-sm);
    background: rgba(46, 90, 155, 0.045);
    padding: 10px 12px;
}

.order-info-title {
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
    margin: 0 0 6px 0;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--accent-royal-blue);
}

.order-info-title::before {
    content: 'ⓘ ';
}

.order-info p {
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
    margin: 0 0 7px 0;
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-secondary);
}

.order-info p:last-child {
    margin-bottom: 0;
}

/* ── Toy Box submission page (#/upload) ───────────────────────────────── */
.submit-page {
    max-width: 620px;
    margin: 0 auto;
    width: 100%;
    /* Matches the headings and the rest of the site's UI copy. Without this the
       labels and hints fell through to the serif body default while the inputs
       next to them were already DM Sans. */
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
}

.submit-header {
    text-align: center;
    margin-bottom: 1.5rem;
}

.submit-header .section-title {
    margin-bottom: 0.5rem;
}

.submit-intro {
    margin: 0 auto;
    max-width: 520px;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--text-secondary);
}

.submit-card {
    padding: 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    margin-bottom: 3rem;
}

/* An empty field with a heading above it and nothing underneath: no example
   text inside, no explanation below. Everything worth saying is said once in
   the introduction, so the form itself is just labels and boxes.
   Sized like the search field on the Creators page — 15px type, a roomy box —
   because these are the fields a stranger fills in on a phone, and the old
   ones were noticeably tighter than anything else on the site. */
.submit-field {
    gap: 8px;
}

.submit-field label {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}

.submit-form .order-input {
    padding: 13px 16px;
    font-size: 0.95rem;
    border-radius: var(--radius-md, 10px);
    border-width: 2px;
}

.submit-form .submit-textarea {
    min-height: 96px;
    line-height: 1.55;
}

.submit-intro-how {
    margin-top: 0.9rem;
    font-size: 0.9rem;
    color: var(--text-muted, #8a8378);
}

.submit-hint {
    margin: 0;
    font-size: 0.74rem;
    color: var(--text-muted);
    line-height: 1.45;
}

.submit-textarea {
    resize: vertical;
    min-height: 62px;
    font-family: 'DM Sans', sans-serif;
    line-height: 1.5;
}

.submit-btn {
    width: 100%;
    justify-content: center;
    padding: 13px;
    margin-top: 0.25rem;
}

.submit-status {
    display: none;
    padding: 12px 14px;
    border-radius: var(--radius-sm);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.86rem;
    line-height: 1.55;
    text-align: center;
}

.submit-status-info,
.submit-status-error,
.submit-status-success {
    display: block;
}

.submit-status-info {
    background: var(--bg-warm);
    color: var(--text-secondary);
}

.submit-status-error {
    background: rgba(192, 57, 43, 0.08);
    border: 1px solid rgba(192, 57, 43, 0.3);
    color: var(--accent-crimson);
    font-weight: 600;
}

.submit-status-success {
    background: rgba(26, 140, 122, 0.09);
    border: 1px solid rgba(26, 140, 122, 0.35);
    color: var(--accent-teal);
}

.submit-fineprint {
    margin: 0;
    padding-top: 0.9rem;
    border-top: var(--border-subtle);
    font-size: 0.72rem;
    line-height: 1.5;
    color: var(--text-muted);
}

@media (max-width: 640px) {
    .submit-card {
        padding: 1.15rem;
    }
}

.order-rebuild-list {
    margin: 0;
    padding-left: 1.4rem;
    display: flex;
    flex-direction: column;
    gap: 5px;
    font-size: 0.86rem;
    color: var(--text-primary);
}

.order-rebuild-list span {
    color: var(--text-muted);
    font-weight: 400;
}

.order-info-privacy {
    padding-top: 6px;
    border-top: 1px solid var(--border-subtle);
    font-style: italic;
}

/* Full Page Empty State */
.cart-empty-full {
    text-align: center;
    padding: 4rem 2rem;
    max-width: 600px;
    margin: 3rem auto;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.cart-empty-circle {
    width: 90px;
    height: 90px;
    border-radius: 50%;
    background: var(--bg-warm);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1.5rem;
}

.cart-empty-full h2 {
    margin: 0 0 0.5rem 0;
    font-size: 1.6rem;
    color: var(--text-primary);
}

.cart-empty-full p {
    margin: 0 0 1.5rem 0;
    color: var(--text-muted);
    font-size: 0.95rem;
    line-height: 1.6;
}

/* ==========================================================================
   Add to Cart Buttons in Gallery & Detail Cards
   eBay-style outline button: gradient border + gradient text, white bg
   Same form as .btn-primary (Download) but outline variant
   ========================================================================== */
.add-to-cart-btn {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    gap: 0.5rem !important;
    width: 100%;
    padding: 0.625rem 1.25rem !important;
    min-height: 44px !important;
    box-sizing: border-box !important;
    border-radius: var(--radius-sm) !important;
    /* Gradient border via background-clip trick */
    border: 2px solid transparent !important;
    background-image: linear-gradient(#fff, #fff), linear-gradient(135deg, #00E5FF 0%, #2979FF 100%) !important;
    background-origin: padding-box, border-box !important;
    background-clip: padding-box, border-box !important;
    /* Gradient text color */
    color: #2979FF !important;
    font-family: 'DM Sans', sans-serif !important;
    font-weight: 800 !important;
    font-size: 0.875rem !important;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1) !important;
    position: relative;
    overflow: hidden;
}

.card-content .add-to-cart-btn {
    margin-top: auto !important;
}

.add-to-cart-btn:hover {
    /* Fill with green gradient on hover */
    background-image: linear-gradient(135deg, #1abc9c 0%, #16a085 100%), linear-gradient(135deg, #1abc9c 0%, #16a085 100%) !important;
    background-clip: padding-box, border-box !important;
    color: #FFFFFF !important;
    transform: translateY(-3px) scale(1.02);
    box-shadow: 0 6px 20px rgba(26, 188, 156, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

.add-to-cart-btn:active {
    transform: translateY(-1px) scale(0.98);
}

.add-to-cart-btn.in-cart {
    background-image: linear-gradient(#fff, #fff), linear-gradient(135deg, #1abc9c 0%, #16a085 100%) !important;
    background-origin: padding-box, border-box !important;
    background-clip: padding-box, border-box !important;
    color: #16a085 !important;
}

.add-to-cart-btn.in-cart:hover {
    /* Fill with red gradient on hover when already in cart */
    background-image: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%), linear-gradient(135deg, #e74c3c 0%, #c0392b 100%) !important;
    background-clip: padding-box, border-box !important;
    color: #FFFFFF !important;
    box-shadow: 0 6px 20px rgba(231, 76, 60, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.4);
}

@media (max-width: 900px) {
    .cart-page-layout {
        grid-template-columns: 1fr;
    }
    .cart-page-summary-col {
        position: static;
    }
    .cart-card-main {
        flex-direction: column;
    }
    .cart-card-img {
        width: 100%;
        height: 180px;
    }
}

/* ── Homepage closer: "How a Toy Box survived its own shutdown" ────────────
   The sketch for this was a dark editorial page in a serif face. It is kept
   here in the site's own light card, DM Sans and gold/crimson accents, with
   more line height and contrast than the sketch so the text is easier to read
   at the bottom of a long page. */
.timeline-section {
    margin: 3rem 0 3.5rem;
}

.timeline-card {
    padding: 2.5rem;
    display: grid;
    grid-template-columns: minmax(240px, 340px) 1fr;
    gap: 3rem;
    align-items: start;
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
}

.tl-header {
    position: sticky;
    top: 2rem;
}

.tl-eyebrow {
    display: block;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--accent-gold);
    margin-bottom: 0.85rem;
}

.tl-heading {
    margin: 0 0 0.85rem;
    font-size: clamp(1.7rem, 3.2vw, 2.4rem);
    font-weight: 800;
    line-height: 1.15;
    letter-spacing: -0.02em;
    color: var(--text-primary);
}

.tl-heading em {
    font-style: italic;
    color: var(--accent-gold);
}

.tl-intro {
    margin: 0;
    font-size: 0.95rem;
    line-height: 1.6;
    color: var(--text-secondary);
}

.tl-list {
    list-style: none;
    margin: 0;
    padding: 0 0 0 1.75rem;
    position: relative;
}

/* The spine the dots sit on. */
.tl-list::before {
    content: '';
    position: absolute;
    left: 5px;
    top: 6px;
    bottom: 6px;
    width: 2px;
    border-radius: 1px;
    background: linear-gradient(
        to bottom,
        var(--accent-gold),
        var(--accent-crimson) 55%,
        var(--accent-teal)
    );
    opacity: 0.35;
}

.tl-item {
    position: relative;
    padding-bottom: 2rem;
    opacity: 0;
    transform: translateY(18px);
    transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.22, 0.8, 0.3, 1);
    /* Later entries trail slightly behind the ones above them. */
    transition-delay: calc(var(--tl-i, 0) * 40ms);
}

.tl-item.tl-visible {
    opacity: 1;
    transform: none;
}

.tl-item:last-child {
    padding-bottom: 0;
}

.tl-dot {
    position: absolute;
    left: -1.75rem;
    top: 4px;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--accent-gold);
    box-shadow: 0 0 0 4px var(--bg-surface), 0 0 0 5px rgba(212, 168, 67, 0.35);
}

.tl-loss .tl-dot {
    background: var(--accent-crimson);
    box-shadow: 0 0 0 4px var(--bg-surface), 0 0 0 5px rgba(192, 57, 43, 0.3);
}

.tl-now .tl-dot {
    background: var(--accent-teal);
    box-shadow: 0 0 0 4px var(--bg-surface), 0 0 0 5px rgba(26, 140, 122, 0.3);
}

.tl-year {
    display: block;
    font-size: 0.74rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--accent-gold);
    margin-bottom: 0.3rem;
}

.tl-loss .tl-year { color: var(--accent-crimson); }
.tl-now  .tl-year { color: var(--accent-teal); }

.tl-title {
    margin: 0 0 0.4rem;
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--text-primary);
}

.tl-text {
    margin: 0;
    max-width: 62ch;
    font-size: 0.95rem;
    line-height: 1.65;
    color: var(--text-secondary);
}

@media (max-width: 860px) {
    .timeline-card {
        grid-template-columns: 1fr;
        gap: 2rem;
        padding: 1.75rem 1.5rem;
    }
    .tl-header {
        position: static;
    }
}

@media (prefers-reduced-motion: reduce) {
    .tl-item {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE & TABLET
   ══════════════════════════════════════════════════════════════════════════
   The desktop layout is deliberately untouched — every rule below sits behind
   a max-width query. What is fixed here, in order of how badly it hurt:

   · the four iframes (holomap, bundle banner, mod banner, random picker) all
     carried min-height 440–560px meant for a 21:9 desktop strip. Squeezed into
     a 322px-wide phone column that produced a tall, narrow box with content
     laid out for a wide one — the "zerschossen" banners.
   · the search placeholder was cut off mid-sentence at 1.1rem.
   · hero buttons and headings were sized for a screen four times as wide.
   · touch targets: Apple and Google both put the comfortable minimum at
     44px; several controls sat well below that.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Tablet (≤1024px): touch-first, but still roomy ────────────────────── */
@media screen and (max-width: 1024px) {
    /* A finger is not a mouse pointer. Anything tappable gets a real target. */
    .nav-link,
    .btn,
    .add-to-cart-btn,
    .cart-card-remove-btn,
    .hover-item-remove,
    .scroller-arrow {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }

    /* Horizontal card rows become swipeable with a proper stop per card,
       instead of drifting to a half-visible card. */
    .horizontal-scroller {
        scroll-snap-type: x mandatory;
        scroll-padding-left: 1rem;
        -webkit-overflow-scrolling: touch;
    }
    .horizontal-scroller > * {
        scroll-snap-align: start;
    }

    /* The arrows exist for mouse users; on touch the swipe is the gesture. */
    .scroller-arrow {
        display: none;
    }

    .holomap-iframe,
    .bundle-banner-iframe {
        min-height: 420px;
        aspect-ratio: 16 / 10;
    }
    .mod-banner-iframe {
        min-height: 460px;
        aspect-ratio: 16 / 11;
    }
}

/* ── Phone (≤768px) ────────────────────────────────────────────────────── */
@media screen and (max-width: 768px) {
    /* Banners: give the stacked layout the room it needs and stop forcing a
       widescreen shape onto a portrait column. */
    .holomap-iframe {
        aspect-ratio: auto;
        min-height: 0;
        height: 380px;
    }
    .bundle-banner-iframe {
        aspect-ratio: auto;
        min-height: 0;
        height: 400px;
    }
    .mod-banner-iframe {
        aspect-ratio: auto;
        min-height: 0;
        height: 520px;
    }
    /* The "Surprise Me" widget measures itself and posts its height to the
       parent (see the resize-iframe listener in app.js). Its tiles now sit two
       per row on a phone instead of stacking into a ~930px column, so it fits
       a sensible box. The floor below is a safety net for the case where the
       resize message is late — better slightly too tall than clipped. */
    .random-selection-iframe {
        min-height: 300px;
    }

    /* Search: at 1.1rem the placeholder was cut off mid-word. */
    .homepage-search-input {
        padding: 0.85rem 3.7rem 0.85rem 2.9rem;
        font-size: 0.95rem;
    }
    .sb-input-icon { left: 0.95rem; }
    .sb-input-icon svg { width: 17px; height: 17px; }
    .homepage-search-btn {
        width: 38px;
        height: 38px;
        right: 0.35rem;
    }
    .homepage-search-btn svg {
        width: 16px;
        height: 16px;
    }

    /* Hero: the button dominated the slide at desktop proportions. */
    .hero-carousel {
        min-height: 320px;
    }
    .hero-slide {
        padding: 1.5rem 1.25rem;
    }
    .hero-title {
        font-size: 1.45rem;
        line-height: 1.2;
    }
    .hero-desc {
        font-size: 0.88rem;
        line-height: 1.5;
    }
    .hero-slide .btn-large {
        padding: 0.6rem 1.15rem;
        font-size: 0.85rem;
        border-radius: var(--radius-sm);
    }

    /* Cards fill the column instead of being clipped by a fixed grid. */
    .grid-container {
        grid-template-columns: 1fr !important;
    }
    .scroller-item,
    .horizontal-scroller > .toybox-card {
        flex: 0 0 78vw;
        max-width: 78vw;
    }
    .creator-tb-card {
        flex: 0 0 60vw;
        max-width: 60vw;
    }

    .section-title {
        font-size: 1.35rem;
    }
    .section-header {
        gap: 0.75rem;
    }

    /* Cart page: the 340px sidebar cannot sit next to anything on a phone. */
    .cart-page-layout {
        grid-template-columns: 1fr;
    }
    .cart-card-main {
        flex-direction: column;
        gap: 0.85rem;
    }
    .cart-card-img {
        width: 100%;
        height: 180px;
    }
    .cart-summary-card {
        position: static;
    }

    /* Detail view */
    .detail-thumb {
        width: 64px;
        height: 40px;
    }
    .download-buttons {
        width: 100%;
    }
    .file-download-btn,
    .download-section .add-to-cart-btn {
        width: 100%;
    }

    /* The closing timeline: the sticky heading column has nothing to stick to
       once the two columns collapse into one. */
    .timeline-card {
        padding: 1.25rem 1rem;
    }
    .tl-heading {
        font-size: 1.5rem;
    }
}

/* ── Small phone (≤480px) ──────────────────────────────────────────────── */
@media screen and (max-width: 480px) {
    .hero-title {
        font-size: 1.25rem;
    }
    .hero-carousel {
        min-height: 290px;
    }
    .mod-banner-iframe {
        height: 560px;
    }
    .holomap-iframe {
        height: 340px;
    }
    .scroller-item,
    .horizontal-scroller > .toybox-card {
        flex: 0 0 86vw;
        max-width: 86vw;
    }
    .card-title {
        font-size: 1rem;
        min-height: 0;
    }
    .submit-card {
        padding: 1rem;
    }
    .detail-title {
        font-size: 1.35rem;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   SEARCH SUGGESTIONS
   ══════════════════════════════════════════════════════════════════════════
   Sits inside .homepage-search-container, which is already position:relative,
   so the panel hangs directly under the field on both search bars.
   ══════════════════════════════════════════════════════════════════════════ */
.suggest-panel {
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    right: 0;
    z-index: 200;
    background: var(--bg-surface);
    border: 1px solid var(--field-border);
    border-radius: var(--radius-md);
    box-shadow: 0 14px 40px rgba(44, 37, 32, 0.18), var(--shadow-sm);
    overflow: hidden auto;
    max-height: min(58vh, 420px);
    -webkit-overflow-scrolling: touch;
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
}

.suggest-row {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    /* 48px keeps every row a comfortable tap target on a phone. */
    min-height: 48px;
    padding: 10px 14px;
    background: none;
    border: none;
    border-bottom: var(--border-subtle);
    text-align: left;
    cursor: pointer;
    font-family: inherit;
    font-size: 0.9rem;
    color: var(--text-primary);
    transition: background-color 0.12s ease;
}

.suggest-row:last-child {
    border-bottom: none;
}

/* Keyboard cursor and mouse hover share one look, so arrow keys and the
   pointer never disagree about what is selected. */
.suggest-row.is-active,
.suggest-row:hover {
    background: rgba(46, 90, 155, 0.08);
}

.suggest-ico {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    /* The emoji rows were drawn at 16px while the chest and the avatars sit at
       26 — the column only looks tidy when all four are the same weight. */
    font-size: 1.25rem;
    line-height: 1;
    opacity: 0.75;
}

/* A picture, not a pictogram: the Toy Box chest for toyboxes, and the
   creator's actual face for creators — the same avatar the rest of the site
   draws, so the dropdown looks like it belongs to this archive. */
.suggest-ico-chest,
.suggest-ico-avatar {
    opacity: 1;
}

/* The chest is drawn with air around it inside its own square, so at the same
   box size as the magnifier it looked noticeably smaller. Overflowing its box
   slightly puts the two at the same visual weight. */
.suggest-ico-chest img {
    width: 28px;
    height: 28px;
    object-fit: contain;
    margin: -1px;
}

.suggest-ico-avatar .creator-avatar {
    width: 26px;
    height: 26px;
    font-size: 0.7rem;
}

.suggest-text {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
}

.suggest-text mark {
    background: transparent;
    color: var(--accent-royal-blue);
    font-weight: 800;
}

.suggest-meta {
    flex: 0 0 auto;
    max-width: 38%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.76rem;
    font-weight: 500;
    color: var(--text-muted);
}

/* The last row is the plain search; it carries the live result count. */
.suggest-all {
    background: var(--bg-warm);
    border-top: var(--border-subtle);
}

.suggest-all .suggest-text {
    font-weight: 500;
}

.suggest-all .suggest-meta {
    color: var(--accent-royal-blue);
    font-weight: 700;
}

@media screen and (max-width: 768px) {
    .suggest-panel {
        /* An on-screen keyboard eats the lower half of the display, so the
           panel has to stay short enough to sit in what is left of it. */
        max-height: 46vh;
        top: calc(100% + 6px);
    }
    .suggest-row {
        min-height: 52px;
        padding: 10px 12px;
        font-size: 0.88rem;
    }
    /* On a narrow row the title must win the space; the creator name and the
       "N results" tail are the first things to give way. */
    .suggest-meta {
        max-width: 30%;
        font-size: 0.72rem;
    }
}

@media screen and (max-width: 420px) {
    .suggest-meta {
        display: none;
    }
    .suggest-all .suggest-meta {
        display: block;      /* the result count is the point of that row */
        max-width: 45%;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   TOYBOX TAGS
   ══════════════════════════════════════════════════════════════════════════
   Shaped after the platform pills on the "Build Your Ultimate Toybox-Bundle"
   banner: a rounded outline that fills with its colour and lifts on hover.
   Each badge is a link — clicking it searches for that tag.
   Colours come from data/tags.json, so a new tag needs no CSS.
   ══════════════════════════════════════════════════════════════════════════ */
.tb-tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 1rem 0;
}

.tb-tag {
    --tb-tag-c: var(--accent-royal-blue);
    --tb-tag-bg: rgba(46, 90, 155, 0.08);
    position: relative;
    display: inline-flex;
    align-items: center;
    /* 34px keeps it tappable without turning into a button. */
    min-height: 34px;
    padding: 0.35rem 0.85rem;
    border-radius: 999px;
    overflow: hidden;
    font-family: 'DM Sans', 'Helvetica Neue', sans-serif;
    font-size: 0.7rem;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    color: var(--tb-tag-c);
    background: var(--tb-tag-bg);
    border: 1.5px solid var(--tb-tag-c);
    transition: transform 0.25s cubic-bezier(0.25, 0.8, 0.25, 1),
                box-shadow 0.25s ease, background-color 0.2s ease, color 0.2s ease;
}

/* A tag carrying an icon gets a little more room and a little more weight —
   the crown has to sit beside the words, not squeeze them. */
.tb-tag.has-icon {
    gap: 7px;
    min-height: 38px;
    padding: 0.4rem 1.05rem;
    font-size: 0.74rem;
    border-width: 2px;
}

.tb-tag-icon {
    flex: 0 0 auto;
    /* Follows the pill's text colour, so it turns white on hover with it. */
    color: currentColor;
}

.tb-tag:hover,
.tb-tag:focus-visible {
    color: #fff;
    background: var(--tb-tag-c);
    transform: translateY(-2px);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--tb-tag-c) 40%, transparent);
}

/* The banner's sheen, reused. It only runs on hover, so a page full of badges
   is never busy on its own. */
.tb-tag::after {
    content: '';
    position: absolute;
    top: 0;
    left: -150%;
    width: 50%;
    height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.45), transparent);
    transform: skewX(-20deg);
    pointer-events: none;
}

.tb-tag:hover::after {
    animation: tb-tag-sheen 1.1s ease-out infinite;
}

@keyframes tb-tag-sheen {
    100% { left: 200%; }
}

/* #E9A900, picked for the Launch Exclusive badge. Carries the gold dot on the
   tag rows and the Tags menu with it, so the colour stays one thing. */
.tb-tag-gold    { --tb-tag-c: #E9A900; --tb-tag-bg: rgba(233, 169, 0, 0.10); }
.tb-tag-orange  { --tb-tag-c: #D2691E; --tb-tag-bg: rgba(210, 105, 30, 0.12); }
.tb-tag-blue    { --tb-tag-c: var(--accent-royal-blue); --tb-tag-bg: rgba(46, 90, 155, 0.08); }
.tb-tag-teal    { --tb-tag-c: var(--accent-teal); --tb-tag-bg: rgba(26, 140, 122, 0.10); }
.tb-tag-crimson { --tb-tag-c: var(--accent-crimson); --tb-tag-bg: rgba(192, 57, 43, 0.09); }
.tb-tag-plum    { --tb-tag-c: var(--accent-plum); --tb-tag-bg: rgba(123, 63, 125, 0.10); }
/* green is the audience colour — "Great for Kids" is the only tag wearing it,
   and it should read as safe at a glance rather than as one more genre. */
.tb-tag-green   { --tb-tag-c: #2F8F4E; --tb-tag-bg: rgba(47, 143, 78, 0.10); }

@media screen and (max-width: 768px) {
    .tb-tag {
        min-height: 38px;          /* a finger, not a pointer */
        font-size: 0.68rem;
        padding: 0.4rem 0.8rem;
    }
    .tb-tag-row {
        gap: 6px;
    }
}

/* A shimmer that loops forever is a distraction, not a decoration. */
@media (prefers-reduced-motion: reduce) {
    .tb-tag {
        transition: background-color 0.2s ease, color 0.2s ease;
    }
    .tb-tag:hover {
        transform: none;
    }
    .tb-tag:hover::after {
        animation: none;
    }
}

/* ══════════════════════════════════════════════════════════════════════════
   XBOX 360 — THE VISITOR'S OWN SAVE
   ══════════════════════════════════════════════════════════════════════════
   Asking someone to hand over a save file is a big ask, so this panel has to
   look calm and say plainly what happens to it. Green once recognised, because
   the moment that matters is "yes, that is your Disney Infinity save".
   ══════════════════════════════════════════════════════════════════════════ */
.summary-xbox-section {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 4px;
}

.xbox-drop {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 18px 14px;
    border: 2px dashed var(--field-border, #c9c2b4);
    border-radius: var(--radius-md, 10px);
    background: rgba(46, 90, 155, 0.04);
    color: var(--text-secondary);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.2s ease, background-color 0.2s ease, transform 0.15s ease;
}

.xbox-drop:hover,
.xbox-drop:focus-visible,
.xbox-drop.is-over {
    border-color: var(--accent-royal-blue);
    background: rgba(46, 90, 155, 0.09);
    outline: none;
}

.xbox-drop.is-over { transform: scale(1.01); }

.xbox-drop-title {
    font-family: 'DM Sans', sans-serif;
    font-size: 0.9rem;
    color: var(--text-primary);
}

.xbox-drop-sub {
    font-family: 'DM Sans', sans-serif;
    font-size: 0.78rem;
    color: var(--text-muted, #8a8378);
}

/* The input covers the whole box so a click anywhere opens the picker, and
   keyboard users still reach it. */
.xbox-file-input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
}

.xbox-recognised {
    padding: 12px 14px;
    border-radius: var(--radius-md, 10px);
    border: 1.5px solid var(--accent-teal);
    background: rgba(26, 140, 122, 0.07);
}

.xbox-ok {
    font-family: 'DM Sans', sans-serif;
    font-weight: 800;
    font-size: 0.85rem;
    color: var(--accent-teal);
    margin-bottom: 8px;
}

.xbox-facts {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 3px 12px;
    margin: 0;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.8rem;
}

.xbox-facts dt { color: var(--text-muted, #8a8378); }
.xbox-facts dd { margin: 0; color: var(--text-primary); font-weight: 600; }
.xbox-facts code {
    font-size: 0.75rem;
    letter-spacing: 0.02em;
    word-break: break-all;
}

.xbox-keep {
    margin: 8px 0 0;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.76rem;
    line-height: 1.45;
    color: var(--text-secondary);
}

.xbox-error {
    padding: 10px 12px;
    border-radius: var(--radius-md, 10px);
    border: 1.5px solid var(--accent-crimson);
    background: rgba(192, 57, 43, 0.06);
    color: var(--accent-crimson);
    font-family: 'DM Sans', sans-serif;
    font-size: 0.8rem;
    line-height: 1.45;
}

.xbox-help {
    font-family: 'DM Sans', sans-serif;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.xbox-help summary {
    cursor: pointer;
    color: var(--accent-royal-blue);
    font-weight: 600;
    padding: 4px 0;
}

.xbox-help ol { margin: 8px 0 0; padding-left: 18px; line-height: 1.6; }
.xbox-help li { margin-bottom: 4px; }
.xbox-help code {
    font-size: 0.72rem;
    background: rgba(0, 0, 0, 0.05);
    padding: 1px 4px;
    border-radius: 3px;
    word-break: break-all;
}

.xbox-help-privacy {
    margin: 10px 0 0;
    font-size: 0.75rem;
    line-height: 1.5;
    color: var(--text-muted, #8a8378);
}

/* A button that cannot do anything yet should look like it. */
.cart-page-download-btn.is-waiting {
    opacity: 0.55;
    cursor: not-allowed;
}

@media screen and (max-width: 768px) {
    /* Creator names in the cart are links, and on a phone a 19px line of text
       is a poor thing to aim at. Room around them without turning the line
       into a stack of buttons. */
    .cart-card-creator-bar { line-height: 2.1; }
    .cart-creator-link { padding: 3px 0; }

    .xbox-drop { padding: 22px 14px; }        /* a comfortable tap target */
    .xbox-facts { grid-template-columns: 1fr; gap: 1px; }
    .xbox-facts dt { margin-top: 6px; }
}

.xbox-raw-link {
    align-self: flex-start;
    padding: 4px 0;
    background: none;
    border: none;
    font-family: 'DM Sans', sans-serif;
    font-size: 0.76rem;
    color: var(--text-muted, #8a8378);
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}

.xbox-raw-link:hover { color: var(--accent-royal-blue); }

/* ══════════════════════════════════════════════════════════════════════════
   A VIDEO THAT WILL NOT BE EMBEDDED
   ══════════════════════════════════════════════════════════════════════════
   Some uploaders switch off playback on other sites. YouTube then shows its
   own grey "video unavailable" box, which reads like our mistake and offers
   the visitor nothing. This says what is actually going on and hands them the
   working link instead.
   ══════════════════════════════════════════════════════════════════════════ */
.video-blocked {
    position: relative;
    width: 100%;
    min-height: 220px;
    border-radius: var(--radius-md, 10px);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #1b1b1b;
}

.video-blocked img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    filter: blur(3px) brightness(0.4);
}

.video-blocked-note {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    max-width: 30rem;
    padding: 26px 22px;
    text-align: center;
    font-family: 'DM Sans', sans-serif;
    color: #fff;
}

.video-blocked-note strong { font-size: 1rem; font-weight: 800; }

.video-blocked-note span {
    font-size: 0.85rem;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.82);
}

.video-blocked-btn {
    margin-top: 6px;
    text-decoration: none;
}

@media screen and (max-width: 768px) {
    .video-blocked { min-height: 190px; }
    .video-blocked-note { padding: 20px 16px; }
    .video-blocked-note span { font-size: 0.8rem; }
}

/* A coloured dot instead of an emoji, so a tag row in the dropdown reads as
   the same thing as the badge on a toybox. */
.suggest-ico-tag {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--tb-tag-c, var(--accent-royal-blue));
    box-shadow: inset 0 -2px 3px rgba(60, 16, 48, 0.18);
}

/* ══════════════════════════════════════════════════════════════════════════
   THE CREATOR LINE ON A CARD — ALWAYS ONE LINE
   ══════════════════════════════════════════════════════════════════════════
   Cards in a row are all as tall as the tallest one. A long credit line
   ("All Night Gaming, Professor Toybox • 26. Aug 2026") wrapped onto a second
   line, 52px instead of 24px, and stretched every card in that row by 28px —
   which is why "Launch Exclusives" and "Latest Toyboxes" looked looser than
   "Star Wars Universe" while being the very same markup.
   Keeping this line unbreakable makes every card identical in every row, and
   in every row added later.
   ══════════════════════════════════════════════════════════════════════════ */
.card-creator {
    flex-wrap: nowrap;
    min-width: 0;
}

/* The name is the only part allowed to give way; the date stays readable. */
.card-creator-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.card-creator .metadata-separator,
.card-creator .card-date,
.card-creator .creator-avatar {
    flex: 0 0 auto;
}

/* Two lines, always — whether the title needs one or three.
   A three-line title made its card taller, and a row is as tall as its
   tallest card, so one long name changed the whole row's proportions. With a
   fixed title box every card is identical in every row, including rows added
   later. The full title is still on the toybox's own page. */
.card-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    line-height: 1.35;
    height: 2.7em;
}

/* A card can never be wider than the slot it sits in.
   `.toybox-card` was `flex: 0 1 auto` with no width of its own, so it took its
   width from its contents. One toybox (TRON: TOWER DEFENSE) has no 400px
   thumbnail in the database, so the 1200px original is loaded without a
   srcset; while it loads, its intrinsic width pushed the card to 375px inside
   a 360px slot. With `aspect-ratio: 16/9` that became a 210px image box and a
   393px row — one card quietly changing the proportions of a whole row.
   Pinning the width fixes it for every row, including rows added later. */
.toybox-card {
    width: 100%;
    max-width: 100%;
    min-width: 0;
}

.toybox-card .card-image {
    width: 100%;
    height: 100%;
}

/* The slot, not just the card. A flex item defaults to `min-width: auto`,
   which lets oversized content push it past its own flex-basis: the slot is
   `flex: 0 0 360px` yet measured 375px, because the 1200px image inside it
   (that one toybox has no 400px thumbnail) refused to be squeezed. Allowing
   the slot to shrink to its basis is what actually holds a row's proportions. */
.scroller-item,
.horizontal-scroller > .toybox-card {
    min-width: 0;
}

/* ══════════════════════════════════════════════════════════════════════════
   THE CHECKOUT SCREEN
   ══════════════════════════════════════════════════════════════════════════
   What a shop shows after an order: what was ordered, for which console, and
   what happens next. It replaces the cart rather than sitting under it, so
   there is no half-finished state where a full cart and a confirmation are on
   screen at the same time and the same bundle can be built twice by accident.
   ══════════════════════════════════════════════════════════════════════════ */
.checkout-screen {
    max-width: 720px;
    margin: 0 auto;
    padding: 2.5rem 0 3rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.co-badge {
    width: 76px;
    height: 76px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(31, 143, 95, 0.12);
    color: var(--accent-green);
    margin-bottom: 1.25rem;
    animation: co-pop 0.42s cubic-bezier(0.175, 0.885, 0.32, 1.275) both;
}

@keyframes co-pop {
    from { opacity: 0; transform: scale(0.6); }
    to   { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
    .co-badge { animation: none; }
}

.co-title {
    margin: 0 0 0.4rem;
    font-size: 2rem;
    line-height: 1.2;
    color: var(--text-primary);
}

.co-sub {
    margin: 0 0 1.5rem;
    color: var(--text-secondary);
    font-size: 1.02rem;
}

/* The one string worth keeping — an order number, or the file that was just
   written to disk. */
.co-reference {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    max-width: 100%;
    padding: 0.55rem 1.1rem;
    border-radius: 999px;
    border: var(--border-subtle);
    background: var(--bg-warm);
}

.co-reference-label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 0.74rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.co-reference-value {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-primary);
    font-weight: 700;
    font-size: 0.92rem;
}

.co-mail {
    display: flex;
    align-items: center;
    justify-content: center;
    /* An address long enough to fill a phone's width has to be allowed onto a
       second line; without this it would simply run past the edge. */
    flex-wrap: wrap;
    gap: 4px 8px;
    margin: 1rem 0 0;
    max-width: 100%;
    color: var(--text-secondary);
    font-size: 0.92rem;
}

.co-mail strong { word-break: break-all; }

.co-card {
    width: 100%;
    margin-top: 1.5rem;
    padding: 1.25rem 1.4rem;
    background: var(--bg-surface);
    border: var(--border-subtle);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
    text-align: left;
}

.co-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-bottom: 0.9rem;
}

.co-card-head h2 {
    margin: 0;
    font-size: 1.05rem;
    color: var(--text-primary);
}

.co-card-head span {
    color: var(--text-muted);
    font-size: 0.85rem;
    font-weight: 600;
}

.co-items {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.co-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 0.55rem 0;
    border-bottom: var(--border-subtle);
}

.co-item:last-child { border-bottom: none; }

.co-item-img {
    flex: 0 0 auto;
    width: 68px;
    height: 44px;
    object-fit: cover;
    border-radius: var(--radius-sm);
    background: var(--bg-warm);
}

/* min-width:0 or a long title stretches the row instead of being trimmed —
   the same flex default that pushed a gallery card out of line. */
.co-item-text {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.co-item-title {
    color: var(--text-primary);
    font-weight: 700;
    font-size: 0.94rem;
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.co-item-title:hover { color: var(--accent-royal-blue); }

.co-item-meta {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    color: var(--text-muted);
    font-size: 0.8rem;
}

.co-item-meta > span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.co-item-count {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 0.78rem;
    font-weight: 700;
}

.co-summary {
    display: flex;
    flex-wrap: wrap;
    gap: 12px 32px;
    margin-top: 1rem;
    padding-top: 0.9rem;
    border-top: var(--border-subtle);
}

.co-summary div {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.co-summary span {
    color: var(--text-muted);
    font-size: 0.74rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.co-summary strong {
    color: var(--text-primary);
    font-size: 0.95rem;
}

.co-free { color: var(--accent-green) !important; }

.co-steps {
    margin: 0;
    padding-left: 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.55;
}

.co-steps strong { color: var(--text-primary); }

.co-steps code {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--bg-warm);
    font-size: 0.86em;
}

.co-note {
    margin: 0.9rem 0 0;
    padding: 0.7rem 0.9rem;
    border-radius: var(--radius-sm);
    background: var(--bg-warm);
    color: var(--text-secondary);
    font-size: 0.86rem;
    line-height: 1.5;
}

.co-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin-top: 1.75rem;
}

.co-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.co-footnote {
    margin: 1.25rem 0 0;
    max-width: 46ch;
    color: var(--text-muted);
    font-size: 0.8rem;
    line-height: 1.5;
}

@media screen and (max-width: 768px) {
    /* Four pills wrap onto two calm rows here. They deliberately do NOT scroll
       sideways the way the old chip row did: a scrolling strip would clip the
       dropdowns that now hang off the Tags and Franchise buttons. */
    /* One column of tiles down here, so there is no centre-to-centre to
       follow — the bar simply takes the width it is given. */
    .search-shell { width: 100%; }
    .sb-filters { gap: 8px; padding: 9px 10px; }
    .sb-pill {
        min-height: 36px;
        padding: 0.35rem 0.8rem;
        font-size: 0.82rem;
    }
    .search-shell { border-radius: 24px; }
    /* A menu anchored to its own button hangs off the screen when that button
       sits near the right edge. Dropping position:relative from the wrapper
       makes the menu measure against .search-shell instead, so it spans the
       bar's width and drops below the whole thing. */
    .sb-menu-wrap { position: static; }

    .sb-menu {
        left: 0;
        right: 0;
        width: auto;
        min-width: 0;
        max-width: none;
        max-height: 60vh;
    }

    .checkout-screen { padding: 1.5rem 0 2.5rem; }
    .co-badge { width: 64px; height: 64px; }
    .co-badge svg { width: 28px; height: 28px; }
    .co-title { font-size: 1.5rem; }
    .co-sub { font-size: 0.94rem; }
    .co-card { padding: 1.1rem; }
    .co-actions .btn { width: 100%; justify-content: center; }
}

@media screen and (max-width: 480px) {
    .sb-pill { font-size: 0.78rem; padding: 0.35rem 0.7rem; }

    .co-title { font-size: 1.3rem; }
    /* The label above the value instead of beside it — "Order number" plus a
       PS-MFQ2K8 does not fit on one line at 343px. */
    .co-reference {
        flex-wrap: wrap;
        justify-content: center;
        border-radius: var(--radius-md);
        padding: 0.6rem 0.8rem;
    }
    .co-reference-value { min-width: 0; }
    .co-item-img { width: 56px; height: 38px; }
    .co-item-count { display: none; }
    .co-summary { gap: 10px 20px; }
}

/* ══════════════════════════════════════════════════════════════════════════
   THE GALLERY, VIDEO INCLUDED
   ══════════════════════════════════════════════════════════════════════════ */
.main-image-container { position: relative; }

.detail-video-stage {
    position: absolute;
    inset: 0;
}

.detail-video-stage .video-facade,
.detail-video-stage iframe {
    width: 100%;
    height: 100%;
    aspect-ratio: auto;
    display: block;
    border: 0;
}

/* The thumbnails became buttons so the video one can carry a play badge and so
   the strip is reachable from a keyboard. The picture rules move inward. */
.detail-thumb {
    width: 120px;
    flex-shrink: 0;
    aspect-ratio: 16/9;
    border-radius: 6px;
    cursor: pointer;
    border: 2px solid transparent;
    transition: all 0.2s ease;
    opacity: 0.5;
    padding: 0;
    background: var(--bg-warm);
    overflow: hidden;
    position: relative;
    display: block;
}

.detail-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.detail-thumb-play {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    pointer-events: none;
}

.detail-thumb-play svg { width: 30px; height: 21px; }

.video-watch-link[hidden] { display: none !important; }

/* ══════════════════════════════════════════════════════════════════════════
   THE RIGHT-HAND COLUMN
   ══════════════════════════════════════════════════════════════════════════ */
.detail-byline {
    display: flex;
    align-items: center;
    gap: 14px;
    min-width: 0;
}

/* The creator sits under the title, so it must not outweigh it. At 52px and
   1.45rem the name competed with the toybox's own name for first read. */
.detail-byline .creator-avatar {
    width: 40px;
    height: 40px;
}

.detail-byline .creator-links {
    font-size: 1.1rem;
    font-weight: 700;
    line-height: 1.25;
    min-width: 0;
    word-break: break-word;
}

.detail-meta-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px 16px;
    min-width: 0;
}

/* Not a footnote: the date is one of the few hard facts on the page, so it
   gets the weight of one instead of the grey of a caption. */
.detail-meta-row .detail-date,
.detail-meta-row .detail-downloads {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--text-secondary);
    font-size: 0.95rem;
    font-weight: 600;
}

.detail-meta-row .detail-date svg { color: var(--text-light); }

.detail-meta-row .detail-downloads { color: var(--accent-royal-blue); }

.detail-meta-row .tb-tag-row { margin: 0; }

/* Stacked and full width, as in the draft: one obvious action, one secondary
   under it, rather than two half-width buttons competing side by side. */
.detail-right .download-buttons {
    flex-direction: column;
    gap: 10px !important;
}

.detail-right .download-buttons > * {
    width: 100%;
    justify-content: center;
}

.related-row-title {
    margin-bottom: 15px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: 'DM Sans', sans-serif;
    font-size: 1.35rem;
    font-weight: 700;
    color: var(--text-primary);
}

.related-row-dot {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: var(--tb-tag-c, var(--accent-royal-blue));
}

@media screen and (max-width: 768px) {
    .detail-byline .creator-avatar { width: 36px; height: 36px; }
    .detail-byline .creator-links { font-size: 1rem; }
    /* Two columns became one, so there is no left-hand media to match. */
    .detail-right { height: auto; }
    .detail-thumb { width: 96px; }
    .related-row-title { font-size: 1.15rem; }
}
