/* ═══════════════════════════════════════════════
   FestivalLuts — Professional Design System
   Neutral colorist workstation UI
   ═══════════════════════════════════════════════ */

/* ─── CSS Custom Properties ─── */
:root {
    /* Background & Surface — True neutral workstation grays */
    --bg-deep: #09090B;
    --bg-base: #0F0F12;
    --bg-surface: #16161A;
    --bg-elevated: #1C1C21;
    --bg-card: #16161A;
    --bg-card-hover: #1C1C21;
    
    /* Primary — used sparingly on CTAs. Matches --accent-blue /
       .apple-btn-primary in apple-design.css so the whole site has one
       primary-action colour. */
    --accent: #0A84FF;
    /* Mirrors apple-design.css. See the note there: a blue that carries white text is
       not the same blue as one used AS text on a dark ground. */
    --accent-fill: #0A6FD0;
    --accent-fill-hover: #0961B8;
    --accent-hover: #0077ED;
    --accent-soft: rgba(10, 132, 255, 0.12);
    --accent-border: rgba(10, 132, 255, 0.3);
    
    /* Secondary — Cool neutral for secondary actions */
    --secondary: #3B82F6;
    --secondary-soft: rgba(59, 130, 246, 0.1);
    
    /* Semantic */
    --success: #22C55E;
    --success-soft: rgba(34, 197, 94, 0.1);
    --success-border: rgba(34, 197, 94, 0.3);
    --error: #EF4444;
    --error-soft: rgba(239, 68, 68, 0.1);
    --error-border: rgba(239, 68, 68, 0.3);
    
    /* Text — Clean neutral hierarchy */
    --text-primary: #FAFAFA;
    --text-secondary: #A1A1AA;
    /* Kept in step with apple-design.css:22, which loads later and wins. When these
       drifted, this value (#52525B, 2.48:1) was the silent fallback if that file
       ever failed to load — worse than the value it was shadowing. */
    --text-muted: #8A8A93;
    --text-on-accent: #FFFFFF;
    
    /* Borders — Subtle, no color shift */
    --border-subtle: rgba(255, 255, 255, 0.06);
    --border-default: rgba(255, 255, 255, 0.10);
    --border-hover: rgba(255, 255, 255, 0.16);
    /* Compat aliases for existing HTML class refs */
    --border-light: var(--border-default);
    --border-accent: var(--border-hover);
    
    /* Radius */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 14px;
    --radius-xl: 20px;
    --radius-pill: 100px;
    
    /* Spacing */
    --space-xs: 4px;
    --space-sm: 8px;
    --space-md: 16px;
    --space-lg: 24px;
    --space-xl: 40px;
    --space-2xl: 64px;
    --space-3xl: 96px;
    
    /* Transitions */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --ease-spring: cubic-bezier(0.2, 0, 0, 1);
    --duration-fast: 150ms;
    --duration-normal: 250ms;
    --duration-slow: 400ms;
    
    /* Typography */
    --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
    --font-display: 'Outfit', 'Inter', sans-serif;
    --font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', monospace;
    
    /* Z-Index */
    --z-sticky: 50;
    --z-navbar: 100;
    --z-modal: 200;
    --z-toast: 300;
}

/* ─── Reset & Base ─── */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

body {
    font-family: var(--font-sans);
    background: var(--bg-deep);
    color: var(--text-primary);
    line-height: 1.55;
    letter-spacing: -0.006em;
    overflow-x: hidden;
    min-height: 100vh;
    font-optical-sizing: auto;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-display);
    line-height: 1.15;
    font-weight: 700;
    letter-spacing: -0.02em;
}

a {
    color: inherit;
    text-decoration: none;
}

img {
    max-width: 100%;
    display: block;
}

button, input, select, textarea {
    font-family: inherit;
    font-size: inherit;
}

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--space-lg);
}

/* ─── Screen-reader utilities ─────────────────────────────────────────────────
   Neither existed anywhere in either stylesheet before 2026-08-24, which is why
   there was no skip link: there was nothing to build one out of.

   .sr-only uses the clip-path + 1px technique rather than display:none, because
   display:none removes an element from the accessibility tree entirely — the point
   is to be reachable by a screen reader and invisible to everyone else.
   ------------------------------------------------------------------------- */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Visible only once focused. /browse has 142 tab stops before the footer, so a
   keyboard user had no way past the nav and the two filter rows. WCAG 2.4.1. */
.skip-link {
    position: absolute;
    top: 0; left: 0;
    z-index: 2000;
    transform: translateY(-120%);
    padding: 0.7rem 1.1rem;
    background: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--accent);
    border-radius: 0 0 10px 0;
    font-size: 0.9rem;
    font-weight: 600;
    text-decoration: none;
    transition: transform 140ms ease;
}
/* :focus, not :focus-visible. focus-visible is a browser heuristic — it does not match
   programmatic focus, and a skip link is the one control that must appear the instant it
   receives focus by any route. It is only reachable by keyboard in the first place, so
   the usual reason to prefer focus-visible (not flashing a ring on mouse click) does not
   apply. Verified before the change: at rest and under .focus() the transform was
   identical, so the link never left the -120% offset. */
.skip-link:focus,
.skip-link:focus-visible {
    transform: translateY(0);
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
    .skip-link { transition: none; }
}

/* ─── Scrollbar ─── */
::-webkit-scrollbar {
    width: 6px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: var(--bg-elevated);
    border-radius: 3px;
}

::-webkit-scrollbar-thumb:hover {
    background: var(--text-muted);
}


/* ═══════════════════════════════════════════════
   NAVIGATION
   ═══════════════════════════════════════════════ */
.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: var(--z-navbar);
    padding: 14px 0;
    transition: background-color var(--duration-normal) var(--ease-out),
                padding var(--duration-normal) var(--ease-out),
                border-color var(--duration-normal) var(--ease-out);
    border-bottom: 1px solid transparent;
}

.navbar.scrolled {
    background: rgba(9, 9, 11, 0.92);
    backdrop-filter: blur(12px) saturate(150%);
    -webkit-backdrop-filter: blur(12px) saturate(150%);
    border-bottom-color: var(--border-subtle);
    padding: 10px 0;
}

.nav-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--space-lg);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-lg);
}

.nav-logo {
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.35rem;
    letter-spacing: -0.03em;
    flex-shrink: 0;
}

.logo-icon {
    display: flex;
    align-items: center;
    color: var(--accent);
}

.logo-text {
    color: var(--text-primary);
}

.logo-accent {
    color: var(--accent);
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 2px;
}

.nav-link {
    padding: 8px 14px;
    border-radius: var(--radius-md);
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--text-secondary);
    transition: color var(--duration-fast), background-color var(--duration-fast);
}

.nav-link:hover {
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.04);
}

.nav-link.active {
    color: var(--text-primary);
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: var(--space-md);
}

.nav-auth .btn {
    font-size: 0.825rem;
    padding: 7px 18px;
}

.nav-user {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    cursor: pointer;
    padding: 4px 12px 4px 4px;
    border-radius: var(--radius-pill);
    transition: background-color var(--duration-fast);
}

.nav-user:hover {
    background: rgba(255, 255, 255, 0.05);
}

.nav-user-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 1.5px solid var(--border-default);
}

.nav-user-name {
    font-size: 0.825rem;
    font-weight: 500;
    color: var(--text-primary);
}

.nav-user-dropdown {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    padding: var(--space-xs);
    min-width: 180px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5);
    display: none;
}

.nav-user-dropdown.open {
    display: block;
}

.nav-user-dropdown a,
.nav-user-dropdown button {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    width: 100%;
    padding: 8px 12px;
    border: none;
    background: none;
    color: var(--text-secondary);
    text-align: left;
    font-size: 0.825rem;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: all var(--duration-fast);
}

.nav-user-dropdown a:hover,
.nav-user-dropdown button:hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary);
}

/* Mobile toggle */
.nav-mobile-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    padding: 8px;
    background: none;
    border: none;
    cursor: pointer;
}

.nav-mobile-toggle span {
    width: 20px;
    height: 1.5px;
    background: var(--text-primary);
    border-radius: 1px;
    transition: all var(--duration-fast) var(--ease-out);
}


/* ═══════════════════════════════════════════════
   HERO SECTION
   ═══════════════════════════════════════════════ */
.hero {
    position: relative;
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    padding: 120px var(--space-lg) var(--space-3xl);
}

.hero-bg {
    position: absolute;
    inset: 0;
    z-index: 0;
}

.hero-gradient {
    position: absolute;
    inset: 0;
    background: 
        radial-gradient(ellipse 60% 40% at 50% 0%, rgba(10, 132, 255, 0.05) 0%, transparent 60%),
        radial-gradient(ellipse 100% 100% at 50% 100%, var(--bg-deep) 0%, transparent 60%);
}

.hero-grid-overlay {
    display: none; /* Removed — clean professional background */
}

.hero-particles {
    display: none; /* Removed — no particle canvas */
}

.hero-content {
    position: relative;
    z-index: 1;
    text-align: center;
    max-width: 720px;
}

.hero-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 16px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-pill);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-secondary);
    margin-bottom: var(--space-lg);
    letter-spacing: 0.02em;
}

.badge-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--success);
    box-shadow: 0 0 6px rgba(34, 197, 94, 0.4);
    animation: pulse-subtle 3s ease-in-out infinite;
}

@keyframes pulse-subtle {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

.hero-title {
    font-size: clamp(2.5rem, 5.5vw, 4rem);
    font-weight: 800;
    letter-spacing: -0.035em;
    margin-bottom: var(--space-lg);
    line-height: 1.05;
    color: var(--text-primary);
}

.hero-title-gradient {
    color: var(--accent);
}

.hero-subtitle {
    font-size: clamp(0.95rem, 1.5vw, 1.1rem);
    color: var(--text-secondary);
    max-width: 560px;
    margin: 0 auto var(--space-xl);
    line-height: 1.7;
}

/* Hero Search */
.hero-search {
    display: flex;
    max-width: 520px;
    margin: 0 auto var(--space-xl);
    background: var(--bg-surface);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: border-color var(--duration-normal) var(--ease-out),
                box-shadow var(--duration-normal) var(--ease-out);
}

.hero-search:focus-within {
    border-color: var(--border-hover);
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.03);
}

.search-input-wrap {
    flex: 1;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: 0 var(--space-md);
}

.search-icon {
    width: 18px;
    height: 18px;
    color: var(--text-muted);
    flex-shrink: 0;
}

.search-input {
    flex: 1;
    background: none;
    border: none;
    outline: none;
    color: var(--text-primary);
    font-size: 0.9rem;
    padding: 13px 0;
}

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

.search-btn {
    padding: 13px 24px;
    background: var(--accent-fill);
    border: none;
    color: var(--text-on-accent);
    font-weight: 600;
    font-size: 0.85rem;
    cursor: pointer;
    transition: background-color var(--duration-fast);
    white-space: nowrap;
}

.search-btn:hover {
    background: var(--accent-hover);
}

/* Hero Stats */
.hero-stats {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xl);
}

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

.stat-value {
    font-family: var(--font-display);
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    letter-spacing: -0.01em;
}

.stat-label {
    font-size: 0.72rem;
    color: var(--text-muted);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.stat-divider {
    width: 1px;
    height: 32px;
    background: var(--border-default);
}

/* Scroll indicator */
.hero-scroll-indicator {
    position: absolute;
    bottom: 40px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    color: var(--text-muted);
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    animation: fadeInUp 1s var(--ease-out) 1s both;
}

.scroll-arrow {
    width: 16px;
    height: 16px;
    border-right: 1.5px solid var(--text-muted);
    border-bottom: 1.5px solid var(--text-muted);
    transform: rotate(45deg);
    animation: bounceDown 2.5s var(--ease-out) infinite;
}

@keyframes bounceDown {
    0%, 100% { transform: rotate(45deg) translateY(0); opacity: 0.7; }
    50% { transform: rotate(45deg) translateY(4px); opacity: 0.3; }
}


/* ═══════════════════════════════════════════════
   INTERACTIVE LUT PREVIEW STUDIO
   ═══════════════════════════════════════════════ */
.preview-studio {
    padding: var(--space-2xl) 0 var(--space-xl);
    background: var(--bg-base);
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
}

.preview-header {
    text-align: center;
    margin-bottom: var(--space-xl);
}

.preview-canvas-wrap {
    position: relative;
    width: 100%;
    aspect-ratio: 16 / 9;
    max-height: 540px;
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--border-default);
    background: var(--bg-deep);
    cursor: crosshair;
    touch-action: none;
}

.preview-canvas-wrap canvas {
    width: 100%;
    height: 100%;
    display: block;
}

/* Split Handle */
.split-handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    width: 2px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 5;
    transform: translateX(-50%);
}

.split-handle-line {
    flex: 1;
    width: 1.5px;
    background: rgba(255, 255, 255, 0.4);
}

.split-handle-grip {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.12);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid rgba(255, 255, 255, 0.25);
    color: #fff;
    flex-shrink: 0;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* Labels */
.preview-labels {
    position: absolute;
    bottom: var(--space-md);
    left: var(--space-md);
    right: var(--space-md);
    display: flex;
    justify-content: space-between;
    pointer-events: none;
    z-index: 4;
}

.preview-label {
    padding: 4px 10px;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(4px);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.65rem;
    font-weight: 500;
    color: rgba(255, 255, 255, 0.6);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

/* Controls */
.preview-controls {
    display: flex;
    gap: var(--space-md);
    margin-top: var(--space-md);
    flex-wrap: wrap;
}

.preview-control-group {
    flex: 1;
    min-width: 200px;
}

.preview-control-label {
    display: block;
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--text-muted);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 6px;
}

.preview-select {
    width: 100%;
    padding: 9px 32px 9px 12px;
    background: var(--bg-surface);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 0.825rem;
    cursor: pointer;
    outline: none;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2352525B' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    transition: border-color var(--duration-fast);
}

.preview-select:focus {
    border-color: var(--border-hover);
}

.preview-select option {
    background: var(--bg-elevated);
}

/* Technical Metadata HUD */
.preview-meta-hud {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    margin-top: var(--space-md);
    padding: 8px 14px;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: var(--text-muted);
    letter-spacing: 0.01em;
    opacity: 0;
    transition: opacity var(--duration-normal);
    flex-wrap: wrap;
}

.meta-item {
    white-space: nowrap;
}

.meta-label {
    color: var(--text-secondary);
    font-weight: 500;
    margin-right: 4px;
}

.meta-divider {
    color: var(--border-default);
}

.preview-meta-hud.is-ready {
    opacity: 1;
}

/* Dim the frame while the next .cube is fetched and uploaded */
.preview-canvas-wrap.is-loading canvas {
    opacity: 0.45;
    transition: opacity var(--duration-fast);
}

.preview-canvas-wrap:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}


/* ═══════════════════════════════════════════════
   BROWSE KIND TOGGLE (Video LUTs / Photo Presets)
   ═══════════════════════════════════════════════ */
/* Outline pills: two separate bordered buttons, no filled-blue active. The active
   pill gets a bright hairline + a faint wash; inactive sits muted. Reset the native
   <button> chrome so only these rules show. */
.browse-kind {
    display: inline-flex;
    gap: 8px;
}
.browse-kind-btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0.5rem 1.1rem;
    border-radius: var(--radius-pill);   /* capsule, same as the category pills below */
    font-size: 0.9rem;
    font-weight: 600;
    font-family: inherit;
    line-height: 1;
    color: var(--text-secondary);
    background: transparent;
    border: 1px solid var(--border-subtle);   /* same hairline as an inactive category pill */
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--duration-fast), border-color var(--duration-fast), background var(--duration-fast);
}
.browse-kind-btn:hover { color: var(--text-primary); border-color: rgba(255, 255, 255, 0.30); }
.browse-kind-btn.active {
    color: var(--text-primary);
    border-color: rgba(255, 255, 255, 0.85);
    background: rgba(255, 255, 255, 0.06);
}
.browse-kind-sub { opacity: 0.6; font-weight: 500; }
.browse-kind-btn.active .browse-kind-sub { opacity: 0.8; }

/* The toggle swaps which grid is visible; every filter and the heading stay put.
   Both grids and both count labels are always in the DOM — only display flips. */
#browse[data-browse-kind="video"] #presets-grid,
#browse[data-browse-kind="video"] .browse-count-photo,
#browse[data-browse-kind="video"] .browse-photo-only { display: none; }
#browse[data-browse-kind="photo"] #luts-grid,
#browse[data-browse-kind="photo"] .browse-count-video,
#browse[data-browse-kind="photo"] .browse-video-only { display: none; }

/* ═══════════════════════════════════════════════
   CATEGORY PILLS
   ═══════════════════════════════════════════════ */
.categories-bar {
    position: sticky;
    top: 56px;
    z-index: var(--z-sticky);
    padding: var(--space-sm) 0;
    background: rgba(9, 9, 11, 0.95);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-bottom: 1px solid var(--border-subtle);
}

.categories-scroll {
    display: flex;
    gap: 6px;
    overflow-x: auto;
    scrollbar-width: none;
    padding: 4px 0;
}

.categories-scroll::-webkit-scrollbar {
    display: none;
}

.category-pill {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: 7px 14px;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    white-space: nowrap;
    transition: all var(--duration-fast) var(--ease-out);
    flex-shrink: 0;
}

.category-pill:hover {
    border-color: var(--border-hover);
    color: var(--text-primary);
    background: rgba(255, 255, 255, 0.03);
}

.category-pill.active {
    background: var(--text-primary);
    border-color: var(--text-primary);
    color: var(--bg-deep);
    font-weight: 600;
}

.pill-icon {
    display: flex;
    align-items: center;
    color: currentColor;
    opacity: 0.7;
}


/* ═══════════════════════════════════════════════
   SECTIONS
   ═══════════════════════════════════════════════ */
.section {
    padding: var(--space-2xl) 0;
}

.section-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    margin-bottom: var(--space-xl);
    gap: var(--space-md);
}

.section-title {
    /* Floor raised from 1.25rem on 2026-08-24. At 1.25rem the clamp bottomed out at
       20px below ~800px — exactly where .section-title--sub sits — so on every tablet
       and phone the section heading and its subsections rendered identically and the
       ladder collapsed to two steps. 1.5rem keeps three distinct ranks at every width:
       24 / 20 / 17.6 on a phone, 28 / 20 / 17.6 on a desktop. */
    font-size: clamp(1.5rem, 2.5vw, 1.75rem);
    font-weight: 700;
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* ── Ramp step: a subordinate section heading ──────────────────────────────────
   .section-title is clamp(1.5rem, 2.5vw, 1.75rem)/700. Fifteen <h2>s in
   routes/lutpage.js overrode it inline to 1.1rem or 1.15rem — and .card-title is
   1.1rem/700 in apple-design.css. So on /browse, "Browse by vibe" rendered at exactly
   the same size, weight and family as the card titles in the grid it introduces: a
   heading that did not outrank its own contents.

   google-typography.md: "Avoid small differences between adjacent styles; the point of
   the ramp is distinguishable steps." apple2.md section 16: "use hierarchy — order,
   spacing, contrast — so the most important thing is the most obvious."

   20px against the cards' 17.6px is a real step, and pinning it (rather than letting the
   base clamp run to 28px) keeps these genuinely subordinate to the h1. Leading and
   tracking move with the size, per apple2.md section 15 — tracking is size-specific. */
.section-title--sub {
    font-size: 1.25rem;
    line-height: 1.3;
    letter-spacing: -0.015em;
}

.title-icon {
    display: inline-flex;
    align-items: center;
    color: var(--text-muted);
}

.section-subtitle {
    font-size: 0.9rem;
    color: var(--text-muted);
    margin-top: 4px;
}

.section-link {
    color: var(--accent);
    font-size: 0.85rem;
    font-weight: 500;
    transition: color var(--duration-fast);
    white-space: nowrap;
}

.section-link:hover {
    color: var(--accent-hover);
}


/* ═══════════════════════════════════════════════
   LUT CARDS
   ═══════════════════════════════════════════════ */
.trending-grid,
.luts-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--space-md);
}

.trending-grid {
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
}

.lut-card {
    background: var(--bg-card);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: border-color var(--duration-normal) var(--ease-out),
                box-shadow var(--duration-normal) var(--ease-out);
    cursor: pointer;
}

.lut-card:hover {
    border-color: var(--border-hover);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
}

.lut-card-preview {
    position: relative;
    aspect-ratio: 16/10;
    background: var(--bg-elevated);
    overflow: hidden;
}

.lut-card-preview-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--duration-slow) var(--ease-out);
}

.lut-card:hover .lut-card-preview-img {
    transform: scale(1.03);
}

.lut-card-preview-gradient {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border-radius: inherit;
    opacity: 0.6;
}

.lut-card-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 3px 9px;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(6px);
    border-radius: var(--radius-pill);
    font-size: 0.68rem;
    font-weight: 500;
    color: var(--text-primary);
    letter-spacing: 0.01em;
}

.lut-card-filetype {
    position: absolute;
    top: 8px;
    right: 8px;
    padding: 3px 7px;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(6px);
    border-radius: var(--radius-sm);
    font-size: 0.62rem;
    font-weight: 600;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    font-family: var(--font-mono);
}

.lut-card-body {
    padding: 12px var(--space-md) 8px;
}

.lut-card-title {
    font-size: 0.9rem;
    font-weight: 600;
    margin-bottom: 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    letter-spacing: -0.01em;
}

.lut-card-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-sm);
}

.lut-card-uploader {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

.lut-card-uploader-avatar {
    width: 18px;
    height: 18px;
    border-radius: 50%;
}

.lut-card-stats {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: 0.75rem;
    color: var(--text-muted);
}

.lut-card-stats svg {
    width: 13px;
    height: 13px;
}

.lut-card-download {
    display: flex;
    align-items: center;
    gap: 3px;
}

.lut-card-actions {
    display: flex;
    gap: var(--space-sm);
    padding: 8px var(--space-md) var(--space-md);
}

.lut-card-dl-btn {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 9px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    font-size: 0.825rem;
    font-weight: 500;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
}

.lut-card-dl-btn:active {
    transform: scale(0.97);
    transition: transform 80ms ease-out;
}

.lut-card-dl-btn:hover {
    background: var(--accent-fill);
    border-color: var(--accent);
    color: var(--text-on-accent);
}

.lut-card-dl-btn svg {
    width: 15px;
    height: 15px;
}


/* ═══════════════════════════════════════════════
   BROWSE CONTROLS
   ═══════════════════════════════════════════════ */
.browse-controls {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
}

/* Pill count badges. These were inline `opacity: 0.4` on --text-secondary, which
   composites to 2.12:1 — the count is the one thing telling a reader whether a filter is
   worth clicking, and google-accessibility.md is explicit that essential information must
   meet contrast. --text-muted at full opacity gives 5.81:1 and reads as secondary without
   being unreadable. Six render sites used the inline style; they all point here now. */
.pill-count { font-size: 0.72rem; margin-left: 3px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.category-pill.active .pill-count { color: inherit; opacity: 0.75; }

/* The only one of the five `outline: none` sites in this file with no replacement.
   Verified: no :focus or :focus-visible rule for .sort-select existed anywhere. */
.sort-select:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.sort-select {
    padding: 7px 14px;
    background: var(--bg-surface);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: 0.825rem;
    cursor: pointer;
    outline: none;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2352525B' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 32px;
}

.sort-select option {
    background: var(--bg-elevated);
}

.load-more-wrap {
    text-align: center;
    margin-top: var(--space-xl);
}


/* ═══════════════════════════════════════════════
   EMPTY STATE
   ═══════════════════════════════════════════════ */
.empty-state {
    text-align: center;
    padding: var(--space-3xl) var(--space-lg);
}

.empty-icon {
    margin-bottom: var(--space-md);
    color: var(--text-muted);
}

.empty-state h3 {
    font-size: 1.3rem;
    font-weight: 600;
    margin-bottom: var(--space-sm);
}

.empty-state p {
    color: var(--text-muted);
    margin-bottom: var(--space-lg);
    font-size: 0.9rem;
}


/* ═══════════════════════════════════════════════
   UPLOAD CTA
   ═══════════════════════════════════════════════ */
.upload-cta-card {
    position: relative;
    border-radius: var(--radius-xl);
    padding: var(--space-2xl) var(--space-xl);
    text-align: center;
    overflow: hidden;
    border: 1px solid var(--border-default);
}

.upload-cta-bg {
    position: absolute;
    inset: 0;
    background: 
        radial-gradient(ellipse 60% 40% at 30% 50%, var(--accent-soft), transparent),
        var(--bg-surface);
    z-index: 0;
}

.upload-cta-content {
    position: relative;
    z-index: 1;
}

.upload-cta-content h2 {
    font-size: clamp(1.3rem, 2.5vw, 1.8rem);
    font-weight: 700;
    margin-bottom: var(--space-md);
}

.upload-cta-content p {
    color: var(--text-secondary);
    max-width: 460px;
    margin: 0 auto var(--space-lg);
    font-size: 0.95rem;
}

.upload-cta-formats {
    margin-top: var(--space-md);
    font-size: 0.78rem;
    color: var(--text-muted);
    letter-spacing: 0.01em;
    font-family: var(--font-mono);
}


/* ═══════════════════════════════════════════════
   BUTTONS
   ═══════════════════════════════════════════════ */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    padding: 10px 22px;
    border: none;
    border-radius: var(--radius-md);
    font-weight: 600;
    font-size: 0.875rem;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
    white-space: nowrap;
    line-height: 1.4;
}

.btn-primary {
    background: var(--accent-fill);
    color: var(--text-on-accent);
}

.btn-primary:hover {
    background: var(--accent-hover);
}

.btn-primary:active {
    transform: scale(0.97);
    transition: transform 80ms ease-out;
}

.btn-outline {
    background: transparent;
    border: 1px solid var(--border-default);
    color: var(--text-primary);
}

.btn-outline:hover {
    border-color: var(--border-hover);
    background: rgba(255, 255, 255, 0.04);
}

.btn-google {
    background: #fff;
    color: #333;
    font-weight: 600;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15);
}

.btn-google:hover {
    background: #f5f5f5;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.btn-lg {
    padding: 14px 32px;
    font-size: 0.95rem;
}

.btn-block {
    width: 100%;
}

.btn:disabled {
    opacity: 0.4;
    cursor: not-allowed;
    transform: none !important;
}


/* ═══════════════════════════════════════════════
   MODAL
   ═══════════════════════════════════════════════ */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.65);
    backdrop-filter: blur(4px);
    -webkit-backdrop-filter: blur(4px);
    z-index: var(--z-modal);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-lg);
    animation: fadeIn var(--duration-fast) var(--ease-out);
}

.modal {
    background: var(--bg-surface);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-xl);
    width: 100%;
    max-width: 480px;
    max-height: 90vh;
    overflow-y: auto;
    animation: slideUp var(--duration-normal) var(--ease-spring);
}

.modal-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-lg);
    border-bottom: 1px solid var(--border-subtle);
}

.modal-header h2 {
    font-size: 1.1rem;
    font-weight: 700;
}

.modal-close {
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.3rem;
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: all var(--duration-fast);
}

.modal-close:hover {
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary);
}

.modal-body {
    padding: var(--space-lg);
}

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

@keyframes slideUp {
    from { opacity: 0; transform: translateY(16px) scale(0.97); }
    to { opacity: 1; transform: translateY(0) scale(1); }
}


/* ═══════════════════════════════════════════════
   UPLOAD FORM
   ═══════════════════════════════════════════════ */
.auth-required {
    text-align: center;
    padding: var(--space-xl) 0;
}

.auth-icon {
    margin-bottom: var(--space-md);
    color: var(--text-muted);
}

.auth-required h3 {
    font-size: 1.2rem;
    margin-bottom: var(--space-sm);
}

.auth-required p {
    color: var(--text-secondary);
    margin-bottom: var(--space-lg);
    font-size: 0.9rem;
}

.dropzone {
    border: 1.5px dashed var(--border-default);
    border-radius: var(--radius-lg);
    padding: var(--space-2xl) var(--space-lg);
    text-align: center;
    cursor: pointer;
    transition: all var(--duration-fast) var(--ease-out);
    margin-bottom: var(--space-lg);
}

.dropzone:hover,
.dropzone.dragover {
    border-color: var(--accent);
    background: var(--accent-soft);
}

.dropzone-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-sm);
    color: var(--text-muted);
}

.dropzone-content svg {
    color: var(--text-muted);
    margin-bottom: var(--space-sm);
}

.dropzone-content p {
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.dropzone-hint {
    font-size: 0.78rem;
    color: var(--accent);
}

.dropzone-formats {
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-top: var(--space-xs);
    font-family: var(--font-mono);
}

/* Shown by app.js when .xmp presets are staged, so the uploader can see the form
   has switched products (camera/category hidden, preset wording) rather than
   wondering where those fields went. */
.upload-kind-note {
    margin: 0 0 1rem;
    padding: 0.6rem 0.8rem;
    font-size: 0.8rem;
    line-height: 1.45;
    color: var(--text-secondary);
    background: rgba(10, 132, 255, 0.08);
    border: 1px solid rgba(10, 132, 255, 0.25);
    border-radius: 10px;
}
.upload-kind-note[hidden] { display: none; }

.file-selected {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-md);
    background: var(--success-soft);
    border: 1px solid var(--success-border);
    border-radius: var(--radius-md);
    margin-bottom: var(--space-lg);
}

.file-info {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    font-size: 0.825rem;
    color: var(--success);
    min-width: 0;
}

.file-info svg {
    flex-shrink: 0;
}

#file-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#file-size {
    color: var(--text-muted);
    flex-shrink: 0;
}

.file-remove {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.2rem;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: var(--radius-sm);
    transition: all var(--duration-fast);
    flex-shrink: 0;
}

.file-remove:hover {
    color: var(--error);
    background: var(--error-soft);
}

.form-group {
    margin-bottom: var(--space-md);
}

.form-group label {
    display: block;
    font-size: 0.825rem;
    font-weight: 600;
    color: var(--text-secondary);
    margin-bottom: 6px;
}

.form-hint {
    font-weight: 400;
    color: var(--text-muted);
}

.form-input {
    width: 100%;
    padding: 10px 14px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    color: var(--text-primary);
    font-size: 0.875rem;
    outline: none;
    transition: border-color var(--duration-fast);
}

.form-input:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 2px var(--accent-soft);
}

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

textarea.form-input {
    resize: vertical;
    min-height: 80px;
}

select.form-input {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2352525B' stroke-width='2'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
    padding-right: 32px;
    cursor: pointer;
}

/* Upload progress */
.upload-progress {
    margin-bottom: var(--space-md);
}

.progress-bar {
    height: 3px;
    background: var(--bg-elevated);
    border-radius: 2px;
    overflow: hidden;
    margin-bottom: var(--space-xs);
}

.progress-fill {
    height: 100%;
    background: var(--accent);
    border-radius: 2px;
    width: 0%;
    transition: width var(--duration-fast);
}

.progress-text {
    font-size: 0.78rem;
    color: var(--text-muted);
}


/* ═══════════════════════════════════════════════
   TOAST NOTIFICATIONS
   ═══════════════════════════════════════════════ */
.toast-container {
    position: fixed;
    top: 80px;
    right: var(--space-lg);
    z-index: var(--z-toast);
    display: flex;
    flex-direction: column;
    gap: var(--space-sm);
}

.toast {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: 12px 18px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    font-size: 0.875rem;
    animation: slideInRight var(--duration-normal) var(--ease-spring);
    max-width: 340px;
}

.toast.success {
    border-color: var(--success-border);
}

.toast.error {
    border-color: var(--error-border);
}

.toast-icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
    color: var(--success);
}

.toast.error .toast-icon {
    color: var(--error);
}

.toast.removing {
    animation: slideOutRight var(--duration-normal) var(--ease-out) forwards;
}

@keyframes slideInRight {
    from { opacity: 0; transform: translateX(80px); }
    to { opacity: 1; transform: translateX(0); }
}

@keyframes slideOutRight {
    from { opacity: 1; transform: translateX(0); }
    to { opacity: 0; transform: translateX(80px); }
}


/* ═══════════════════════════════════════════════
   FOOTER
   ═══════════════════════════════════════════════ */
.footer {
    background: var(--bg-base);
    border-top: 1px solid var(--border-subtle);
    padding: var(--space-2xl) 0 var(--space-xl);
}

/* Brand row: identity on the left, plain social icons on the right — no
   icon-in-circle chips. The labelled link columns live in .footer-links below;
   this top row stays a simple two-item flex. */
.footer-top {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-xl);
    padding-bottom: var(--space-lg);
    margin-bottom: var(--space-lg);
    border-bottom: 1px solid var(--border-subtle);
}

.footer-logo {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 1.25rem;
    letter-spacing: -0.02em;
    color: var(--text-primary);
}
.footer-logo svg { color: var(--accent); }
.footer-logo-accent { color: var(--accent); }

.footer-tagline {
    color: var(--text-muted);
    font-size: 0.85rem;
    margin: 0.7rem 0 0;
    max-width: 360px;
    line-height: 1.6;
}

/* Plain icons, no circular chip behind them. */
.footer-social {
    display: flex;
    gap: 1.15rem;
    flex-shrink: 0;
}
.footer-social a {
    display: inline-flex;
    color: var(--text-muted);
    transition: color var(--duration-fast), transform var(--duration-fast);
}
.footer-social a:hover {
    color: var(--text-primary);
    transform: translateY(-1px);
}

/* Labelled sitemap columns. Every page linked here is otherwise a near-orphan, so
   keeping them present AND legible matters for crawl equity — the labels turn a
   flat run of links into something that reads as intentional. */
.footer-links {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr;
    gap: var(--space-lg) var(--space-xl);
    margin-bottom: var(--space-lg);
}
.footer-col {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.55rem;
}
.footer-col-title {
    margin: 0 0 0.3rem;
    font-family: var(--font-display);
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}
.footer-col a {
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.2;
    transition: color var(--duration-fast);
}
.footer-col a:hover { color: var(--text-primary); }

@media (max-width: 700px) {
    .footer-links { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 420px) {
    .footer-links { grid-template-columns: 1fr; gap: var(--space-md); }
}

/* ── "How to install" app cards (bottom of every LUT/preset page) ──
   Each links to a /luts/<app> guide with real per-app install steps. */
.install-apps {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
    gap: 0.75rem;
}
.install-app {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
    border: 1px solid var(--border-subtle);
    border-radius: 12px;
    background: var(--bg-surface);
    transition: border-color var(--duration-fast), background var(--duration-fast), transform var(--duration-fast);
}
.install-app:hover {
    border-color: var(--border-active);
    background: var(--bg-elevated);
    transform: translateY(-1px);
}
.install-app-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.install-app-name { font-weight: 600; color: var(--text-primary); font-size: 0.95rem; }
.install-app-hint { color: var(--text-muted); font-size: 0.8rem; }
.install-app-arrow { color: var(--text-muted); flex-shrink: 0; transition: color var(--duration-fast), transform var(--duration-fast); }
.install-app:hover .install-app-arrow { color: var(--accent); transform: translateX(2px); }

/* ── Click-to-play YouTube facade (software/tutorial pages) ──
   Poster is pure CSS — no YouTube request until the visitor clicks, so no cookies
   load and it stays outside the consent banner. The iframe is injected on click. */
.yt-embed {
    position: relative;
    aspect-ratio: 16 / 9;
    max-width: 720px;
    margin: 1.25rem 0 0.25rem;
    border-radius: 14px;
    overflow: hidden;
    border: 1px solid var(--border-subtle);
    background: radial-gradient(120% 120% at 30% 20%, #241844 0%, #0c1630 55%, #070b18 100%);
}
.yt-embed-btn {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    padding: 1rem;
    background: transparent;
    border: none;
    cursor: pointer;
    color: #fff;
}
.yt-embed-play {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 68px;
    height: 48px;
    border-radius: 13px;
    background: rgba(0, 0, 0, 0.55);
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
    transition: background var(--duration-fast), transform var(--duration-fast);
}
.yt-embed-play svg { width: 28px; height: 28px; margin-left: 2px; }
.yt-embed-btn:hover .yt-embed-play,
.yt-embed-btn:focus-visible .yt-embed-play { background: #ff0033; transform: scale(1.06); }
.yt-embed-label {
    font-size: 0.92rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: rgba(255, 255, 255, 0.94);
    text-align: center;
    max-width: 34ch;
}
.yt-embed-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.footer-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    flex-wrap: wrap;
    padding-top: var(--space-lg);
    border-top: 1px solid var(--border-subtle);
    font-size: 0.78rem;
    color: var(--text-muted);
}
.footer-legal { display: flex; gap: 1.15rem; }
.footer-legal a {
    color: var(--text-muted);
    transition: color var(--duration-fast);
}
.footer-legal a:hover { color: var(--text-primary); }

@media (max-width: 640px) {
    .footer-top { flex-direction: column; gap: var(--space-md); }
    .footer-bottom { flex-direction: column; align-items: flex-start; gap: var(--space-sm); }
}


/* ═══════════════════════════════════════════════
   SKELETON LOADING
   ═══════════════════════════════════════════════ */
.skeleton {
    background: linear-gradient(90deg, var(--bg-elevated) 25%, var(--bg-surface) 50%, var(--bg-elevated) 75%);
    background-size: 200% 100%;
    animation: skeletonPulse 1.8s ease-in-out infinite;
    border-radius: var(--radius-sm);
}

@keyframes skeletonPulse {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

.skeleton-card {
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.skeleton-card .skeleton-preview {
    aspect-ratio: 16/10;
}

.skeleton-card .skeleton-body {
    padding: var(--space-md);
}

.skeleton-card .skeleton-title {
    height: 16px;
    margin-bottom: var(--space-sm);
    width: 70%;
}

.skeleton-card .skeleton-meta {
    height: 12px;
    width: 50%;
}


/* ═══════════════════════════════════════════════
   ANIMATIONS
   ═══════════════════════════════════════════════ */
.animate-in {
    opacity: 0;
    transform: translateY(16px);
    transition: opacity 0.5s var(--ease-out), transform 0.5s var(--ease-out);
}

.animate-in.visible {
    opacity: 1;
    transform: translateY(0);
}

@keyframes fadeInUp {
    from { opacity: 0; transform: translateX(-50%) translateY(8px); }
    to { opacity: 1; transform: translateX(-50%) translateY(0); }
}


/* ═══════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════ */
@media (max-width: 1024px) {
    .footer-grid {
        grid-template-columns: 1fr 1fr;
        gap: var(--space-xl);
    }
}

@media (max-width: 768px) {
    .nav-links {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(9, 9, 11, 0.98);
        backdrop-filter: blur(16px);
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: var(--space-md);
        z-index: 99;
    }

    .nav-links.open {
        display: flex;
    }

    .nav-links .nav-link {
        font-size: 1.2rem;
        padding: var(--space-md) var(--space-xl);
    }

    .nav-mobile-toggle {
        display: flex;
    }

    .hero {
        padding: 100px var(--space-md) var(--space-2xl);
        min-height: auto;
    }

    .hero-search {
        flex-direction: column;
        border-radius: var(--radius-lg);
    }

    .search-btn {
        border-radius: 0 0 var(--radius-lg) var(--radius-lg);
    }

    .hero-stats {
        gap: var(--space-lg);
    }

    .stat-value {
        font-size: 0.9rem;
    }

    .section-header {
        flex-direction: column;
        align-items: flex-start;
    }

    .trending-grid,
    .luts-grid {
        grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
        gap: var(--space-md);
    }

    .footer-grid {
        grid-template-columns: 1fr;
        gap: var(--space-xl);
    }

    .footer-bottom {
        flex-direction: column;
        gap: var(--space-sm);
        text-align: center;
    }

    .hero-scroll-indicator {
        display: none;
    }

    .upload-cta-card {
        padding: var(--space-2xl) var(--space-md);
    }

    .categories-bar {
        top: 48px;
    }
}

@media (max-width: 480px) {
    .trending-grid,
    .luts-grid {
        grid-template-columns: 1fr;
    }

    .hero-stats {
        flex-direction: column;
        gap: var(--space-md);
    }

    .stat-divider {
        width: 40px;
        height: 1px;
    }
}


/* ═══════════════════════════════════════════════
   ACCESSIBILITY
   ═══════════════════════════════════════════════ */

/* Reduced Motion */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 150ms !important;
    }

    .lut-card:hover {
        transform: none;
    }

    .lut-card-dl-btn:active,
    .btn-primary:active {
        transform: none;
    }

    .badge-dot {
        animation: none;
    }

    .scroll-arrow {
        animation: none;
    }
}

/* Reduced Transparency */
@media (prefers-reduced-transparency: reduce) {
    .navbar.scrolled {
        background: var(--bg-deep);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    .categories-bar {
        background: var(--bg-deep);
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    .lut-card {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }
}

/* High Contrast */
@media (prefers-contrast: more) {
    :root {
        --border-subtle: rgba(255, 255, 255, 0.15);
        --border-default: rgba(255, 255, 255, 0.25);
        --bg-card: var(--bg-surface);
    }
}

/* ═══════════════════════════════════════════════
   LUT CARD PREVIEW — real before/after
   Each card shows the reference frame with that LUT's actual .cube data
   applied (rendered offline). Hovering cross-fades back to the ungraded
   frame so the grade can be judged against its own source.
   ═══════════════════════════════════════════════ */
.card-preview {
    position: relative;
    margin: 0;
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--bg-elevated);
}

.card-preview-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Was a hover cross-fade to opacity 0. Two problems: a phone has no hover, so
   mobile never saw the ungraded frame at all; and the server-rendered cards in
   routes/{lutpage,creator,download}.js reuse this class with no before-image
   underneath, so hovering those faded the preview into the empty grey panel.
   The homepage cards now clip instead (see .card-slider below); everyone else
   just keeps a static graded frame. */
.card-preview-after {
    opacity: 1;
}

.card-preview-tag {
    position: absolute;
    left: 8px;
    bottom: 8px;
    z-index: 1;
    display: grid;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #fff;
    background: rgba(0, 0, 0, 0.58);
    padding: 4px 7px;
    border-radius: 4px;
    pointer-events: none;
}

/* stack the labels so the chip never changes width as they swap */
.card-preview-tag > span {
    grid-area: 1 / 1;
    transition: opacity var(--duration-fast) var(--ease-out);
}

/* Leaderboard rank badge — only rendered for LUTs with real downloads */
.card-rank {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--text-on-accent, #fff);
    background: var(--accent);
    padding: 3px 8px;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
    pointer-events: none;
}

/* `hidden` must beat the display rules on .section and .nav-link */
[hidden] {
    display: none !important;
}

/* Card titles link to /lut/:slug — a real anchor so crawlers can follow it */
.card-title-link {
    color: inherit;
    text-decoration: none;
}

.card-title-link:hover,
.card-title-link:focus-visible {
    color: var(--accent);
    text-decoration: underline;
}

/* Which label shows is now driven by the slider position in app.js, not by
   hover. These are the starting values for a card that renders fully graded. */
.card-preview-tag .tag-ungraded,
.card-preview-tag .tag-missing { opacity: 0; }

/* ── Card slider — drag to compare graded against the original frame ──
   Only the homepage grid gets this: it needs a `.card-preview-before` sibling
   to reveal, and the server-rendered cards elsewhere ship the graded frame
   alone. Everything here is scoped to .card-slider so those stay untouched. */
.card-slider .card-preview-after {
    clip-path: inset(0 0 0 0);
}

.card-slider-handle {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 100%;
    width: 2px;
    margin-left: -1px;
    background: rgba(255, 255, 255, 0.9);
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
    cursor: ew-resize;
    z-index: 3;
    /* Without this a horizontal drag on the handle scrolls the page instead. */
    touch-action: none;
}

/* The 26px knob is the real touch target; the 2px line is only the seam. */
.card-slider-handle::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.94);
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
}

/* Chevrons drawn as a mask rather than a text glyph, which would depend on
   whatever font happens to resolve and drift between platforms. */
.card-slider-handle::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 14px;
    height: 10px;
    background: rgba(0, 0, 0, 0.6);
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10'%3E%3Cpath d='M5 1 1.6 5 5 9M9 1l3.4 4L9 9' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10'%3E%3Cpath d='M5 1 1.6 5 5 9M9 1l3.4 4L9 9' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/contain no-repeat;
}

.card-slider-handle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.card-slider.is-dragging {
    user-select: none;
    -webkit-user-select: none;
}

/* ── Pack badge ──
   Bottom-right, not top-right: .card-fav-btn owns top-right at 10px/z-4 and a
   badge there sits under the heart. Top-left is the rank badge and bottom-left
   is the graded/original chip, so this is the one free corner. */
.card-pack-badge {
    position: absolute;
    right: 8px;
    bottom: 8px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: #fff;
    background: linear-gradient(135deg, #5E5CE6, #BF5AF2);
    padding: 3px 8px;
    border-radius: 4px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
    pointer-events: none;
}

/* ── Pack contents, on the lead's page ── */
.pack-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 1rem;
    margin-bottom: 1rem;
}

.pack-badge-inline {
    display: inline-block;
    font-family: var(--font-mono);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #fff;
    background: linear-gradient(135deg, #5E5CE6, #BF5AF2);
    padding: 2px 8px;
    border-radius: 4px;
    margin-right: 10px;
    vertical-align: middle;
}

.pack-file-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.pack-file-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.7rem 1rem;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    transition: background 0.15s ease, border-color 0.15s ease;
}

.pack-file-item:hover { background: var(--bg-elevated); }

.pack-file-item.active {
    background: rgba(10, 132, 255, 0.09);
    border-color: rgba(10, 132, 255, 0.35);
}

.pack-file-info {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    min-width: 0;
}

.pack-file-position {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    flex-shrink: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.08);
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: var(--text-secondary);
}

.pack-file-name {
    font-size: 0.88rem;
    font-weight: 500;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.pack-file-meta {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.pack-file-actions {
    display: flex;
    gap: 0.5rem;
    flex-shrink: 0;
}

.pack-file-actions .apple-btn {
    padding: 0.38rem 0.8rem;
    font-size: 0.78rem;
}

@media (max-width: 560px) {
    .pack-file-item { flex-direction: column; align-items: stretch; gap: 0.6rem; }
    .pack-file-actions { justify-content: flex-end; }
    .pack-file-meta { display: none; }
}

/* ── Upload modal: the queued files ── */
.file-list-container { margin-bottom: 1rem; }

.file-list-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 0.45rem;
}

.file-list-count {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-primary);
}

.file-list-clear {
    font-size: 0.75rem;
    color: var(--accent);
    background: none;
    border: none;
    cursor: pointer;
    padding: 2px 4px;
}

.file-list-clear:hover { text-decoration: underline; }

.file-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 190px;
    overflow-y: auto;
}

.file-list-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    padding: 7px 11px;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 8px;
}

.file-list-item-info {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    color: var(--text-secondary);
}

.file-list-item-name {
    font-size: 0.82rem;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.file-list-item-size {
    font-family: var(--font-mono);
    font-size: 0.7rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.file-list-item-remove {
    background: none;
    border: none;
    color: var(--text-muted);
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 4px;
    flex-shrink: 0;
}

.file-list-item-remove:hover { color: #FF3B30; }

/* A LUT whose preview failed to render (e.g. a corrupt .cube): show the
   ungraded frame and say so, rather than implying a grade that isn't there. */
.card-preview.is-unavailable .card-preview-after { display: none; }
.card-preview.is-unavailable .card-slider-handle { display: none; }
.card-preview.is-unavailable .tag-graded,
.card-preview.is-unavailable .tag-ungraded { opacity: 0 !important; }
.card-preview.is-unavailable .tag-missing { opacity: 1 !important; }

.card-meta {
    font-size: 0.78rem;
    color: var(--text-muted);
}

@media (prefers-reduced-motion: reduce) {
    .card-preview-after,
    .card-preview-tag > span { transition: none; }
}

/* ═══════════════════════════════════════════════
   CREATOR PROFILES
   ═══════════════════════════════════════════════ */
.creator-header {
    display: flex;
    gap: var(--space-lg);
    align-items: flex-start;
    margin-bottom: var(--space-xl);
    flex-wrap: wrap;
}

.creator-meta h1 {
    font-family: var(--font-display, inherit);
    font-size: clamp(1.5rem, 4vw, 2.1rem);
    margin: 0 0 0.5rem;
}

.creator-bio {
    color: var(--text-secondary);
    max-width: 60ch;
    margin: 0 0 0.6rem;
    white-space: pre-wrap;
}

.creator-stats {
    margin: 0 0 0.3rem;
    font-size: 0.85rem;
    color: var(--text-muted);
}

.creator-stats a { color: var(--accent); text-decoration: none; }
.creator-stats a:hover { text-decoration: underline; }

/* Owner controls sit inside the card, below the body */
.card-owner-controls {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    padding: 0 var(--space-md) var(--space-md);
    border-top: 1px solid var(--border-subtle);
    padding-top: var(--space-sm);
    margin-top: auto;
}

.card-owner-controls .apple-btn {
    padding: 0.45rem 0.75rem;
    font-size: 0.78rem;
}

.card-owner-controls .card-danger:hover {
    border-color: #f43f5e;
    color: #f43f5e;
}

.owner-note {
    flex: 1 0 100%;
    margin: 0.35rem 0 0;
    font-size: 0.75rem;
    color: var(--text-muted);
}

@media (max-width: 480px) {
    .creator-header { gap: var(--space-md); }
}

/* ═══════════════════════════════════════════════
   ADMIN DASHBOARD
   ═══════════════════════════════════════════════ */
.admin-stats { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-bottom: var(--space-lg); }
.admin-stat {
    display: flex; flex-direction: column; gap: 2px;
    padding: 10px 16px; border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm); background: var(--bg-surface);
    font-size: 0.72rem; color: var(--text-muted);
}
.admin-stat-n { font-family: var(--font-mono); font-size: 1.15rem; color: var(--text-primary); }

.admin-tabs { display: flex; gap: 0.4rem; margin-bottom: var(--space-md); flex-wrap: wrap; }
.admin-tabs .apple-btn { padding: 0.45rem 0.9rem; font-size: 0.8rem; }
.admin-tabs .is-active { border-color: var(--accent); color: var(--text-primary); }

.admin-tab { overflow-x: auto; }
/* min-width belongs on the table, but a table with a min-width inside a page whose
   body is overflow-x:hidden is content you cannot reach. At 390px roughly 230px of the
   two measured spec tables was clipped with no scrollbar — WCAG 1.4.10 Reflow. The
   Academy guides already wrap their tables in an overflow-x:auto container; this is the
   same wrapper, so the two surfaces behave alike. */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; max-width: 100%; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 0.82rem; min-width: 620px; }
.admin-table th {
    text-align: left; padding: 8px 10px; font-weight: 500; color: var(--text-muted);
    border-bottom: 1px solid var(--border-default); white-space: nowrap;
}
.admin-table td { padding: 10px; border-bottom: 1px solid var(--border-subtle); vertical-align: top; }
.admin-table a { color: var(--accent); text-decoration: none; }
.admin-table a:hover { text-decoration: underline; }
.admin-table .apple-btn { padding: 0.35rem 0.7rem; font-size: 0.74rem; white-space: nowrap; }

/* community uploads sort first and are marked, since seed rows aren't the point */
.admin-table tr.is-community td:first-child { border-left: 2px solid var(--accent); padding-left: 8px; }

.admin-dim { display: block; color: var(--text-muted); font-size: 0.72rem; margin-top: 2px; }
.admin-msg { margin-top: var(--space-md); font-size: 0.82rem; min-height: 1.2em; }
.admin-ipform { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: var(--space-md); }
.admin-ipform .form-input { flex: 1 1 180px; }

/* Admin-only nav badge, revealed by app.js */
.nav-admin-badge {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 4px 9px; margin-left: 6px;
    border: 1px solid var(--accent-border); border-radius: var(--radius-pill);
    background: var(--accent-soft); color: var(--accent);
    font-size: 0.72rem; font-weight: 600; text-decoration: none;
}
.nav-admin-badge:hover { background: var(--accent); color: var(--text-on-accent); }

/* Badge only draws attention when something actually arrived */
.nav-admin-badge.is-new {
    background: var(--accent);
    color: var(--text-on-accent);
    border-color: var(--accent);
}

/* Second filter axis (camera), below the mood pills */
.camera-scroll {
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid var(--border-subtle);
    align-items: center;
}

.filter-axis-label {
    flex-shrink: 0;
    margin-right: 8px;
    font-family: var(--font-mono);
    font-size: 0.66rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
}

.camera-pill { font-size: 0.78rem; padding: 5px 11px; }

/* ═══════════════════════════════════════════════
   DOWNLOAD INTERSTITIAL
   ═══════════════════════════════════════════════ */
.dl-head { margin-bottom: var(--space-lg); }
.dl-kicker {
    font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--text-muted); margin: 0 0 0.35rem;
}
.dl-title { font-size: clamp(1.5rem, 4vw, 2.1rem); margin: 0 0 0.5rem; }
.dl-meta { font-size: 0.85rem; color: var(--text-muted); margin: 0; }
.dl-meta a { color: var(--accent); text-decoration: none; }
.dl-meta a:hover { text-decoration: underline; }

.dl-status {
    padding: var(--space-lg); margin-bottom: var(--space-lg);
    border: 1px solid var(--accent-border); border-radius: var(--radius-lg);
    background: var(--accent-soft); text-align: center;
}
.dl-status p { margin: 0 0 0.6rem; }
.dl-bar {
    height: 4px; border-radius: 2px; overflow: hidden;
    background: rgba(255, 255, 255, 0.08); margin-bottom: 0.75rem;
}
.dl-bar-fill {
    height: 100%; width: 0; background: var(--accent);
    transition: width 1s linear;
}
.dl-fallback { font-size: 0.82rem; color: var(--text-muted); margin: 0 !important; }
.dl-fallback a { color: var(--accent); }

.ad-download {
    min-height: 90px; margin-bottom: var(--space-xl);
    display: flex; align-items: center; justify-content: center;
}

.dl-h2 { font-size: 1.15rem; margin: 0 0 var(--space-md); }
.dl-instructions {
    display: grid; gap: var(--space-md); margin-bottom: var(--space-xl);
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.dl-step {
    padding: var(--space-md); border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md); background: var(--bg-surface);
}
.dl-step h3 { font-size: 0.95rem; margin: 0 0 0.4rem; }
.dl-step p { font-size: 0.82rem; color: var(--text-secondary); margin: 0; line-height: 1.6; }
.dl-step em { color: var(--text-primary); font-style: normal; font-weight: 500; }

/* ── Tag chip editor (upload modal) ──
   Wraps the entry field so the whole box reads as one input. Each committed tag
   is a chip with its own remove button. */
.tag-input {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    width: 100%;
    min-height: 44px;
    padding: 7px 10px;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
    cursor: text;
    transition: border-color 0.15s ease;
}

.tag-input:focus-within { border-color: var(--accent); }

.tag-chips { display: contents; }

.tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 4px 3px 10px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-light, rgba(255,255,255,0.12));
    border-radius: 999px;
    font-size: 0.8rem;
    line-height: 1.4;
    color: var(--text-primary);
    max-width: 100%;
}

.tag-chip-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    flex-shrink: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
}

.tag-chip-x:hover { background: rgba(255, 59, 48, 0.15); color: #FF3B30; }

.tag-entry {
    flex: 1 1 120px;
    min-width: 120px;
    border: none;
    background: none;
    outline: none;
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.9rem;
    padding: 3px 0;
}

.tag-entry::placeholder { color: var(--text-muted); }
.tag-entry:disabled { display: none; }

/* Pack manifest on the download interstitial — what the .zip contains. */
.dl-pack-files {
    margin: var(--space-md) 0;
    padding: 0.9rem 1.1rem;
    background: var(--bg-surface);
    border: 1px solid var(--border-subtle);
    border-radius: 10px;
}

.dl-pack-title {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.07em;
    color: var(--text-muted);
    margin: 0 0 0.6rem;
}

.dl-pack-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 6px 0;
}

.dl-pack-row + .dl-pack-row { border-top: 1px solid var(--border-subtle); }

.dl-pack-name {
    font-size: 0.85rem;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dl-pack-size {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--text-muted);
    white-space: nowrap;
}

.dl-back { margin-top: var(--space-xl); font-size: 0.85rem; }
.dl-back a { color: var(--text-muted); text-decoration: none; }
.dl-back a:hover { color: var(--text-primary); }

/* ═══════════════════════════════════════════════
   TRY ON YOUR FOOTAGE
   ═══════════════════════════════════════════════ */
.tryon {
    margin-top: var(--space-md);
    padding: var(--space-md);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    background: var(--bg-surface);
}
.tryon-head h3 { font-size: 0.95rem; margin: 0 0 0.25rem; }
.tryon-head p { font-size: 0.8rem; color: var(--text-muted); margin: 0 0 var(--space-md); }

.tryon-body {
    display: grid;
    gap: var(--space-md);
    grid-template-columns: minmax(220px, 1.2fr) minmax(200px, 1fr);
    align-items: start;
}

.tryon-drop {
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.9rem 1rem; cursor: pointer;
    border: 1px dashed var(--border-hover); border-radius: var(--radius-sm);
    background: var(--bg-elevated); color: var(--text-secondary);
    font-size: 0.82rem;
    transition: border-color var(--duration-fast), background var(--duration-fast);
}
.tryon-drop:hover, .tryon-drop:focus-visible, .tryon-drop.is-over {
    border-color: var(--accent); background: var(--accent-soft); color: var(--text-primary);
}
.tryon-drop svg { flex-shrink: 0; }

.tryon-controls { display: flex; flex-direction: column; gap: 0.4rem; }
.tryon-controls .apple-btn { padding: 0.5rem 0.8rem; font-size: 0.78rem; }
.tryon-msg { margin: var(--space-sm) 0 0; font-size: 0.78rem; color: var(--text-muted); min-height: 1.1em; }

@media (max-width: 620px) {
    .tryon-body { grid-template-columns: 1fr; }
}

/* ═══════════════════════════════════════════════
   FAVORITES & SAVED LUTS STYLING
   ═══════════════════════════════════════════════ */
.card-fav-btn {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 4;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: rgba(18, 18, 20, 0.65);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: var(--text-secondary, rgba(255, 255, 255, 0.7));
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}

.card-fav-btn:hover {
    background: rgba(30, 30, 35, 0.85);
    color: #FF3B30;
    transform: scale(1.1);
    border-color: rgba(255, 59, 48, 0.3);
}

.card-fav-btn.active {
    background: rgba(255, 59, 48, 0.15);
    border-color: rgba(255, 59, 48, 0.4);
    color: #FF3B30;
}

.card-fav-btn.active svg {
    fill: #FF3B30;
    stroke: #FF3B30;
    animation: heart-pop 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
}

@keyframes heart-pop {
    0% { transform: scale(0.7); }
    50% { transform: scale(1.25); }
    100% { transform: scale(1); }
}

.fav-btn.active {
    border-color: rgba(255, 59, 48, 0.4) !important;
    background: rgba(255, 59, 48, 0.12) !important;
    color: #FF3B30 !important;
}

.fav-btn.active svg {
    fill: #FF3B30;
    stroke: #FF3B30;
}

.saved-pill-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 6px;
    border-radius: 9px;
    font-size: 0.72rem;
    font-weight: 700;
    background: rgba(255, 59, 48, 0.2);
    color: #FF3B30;
    margin-left: 5px;
}


/* Creator credit on a LUT page — a link, so the name leads somewhere. */
.uploader-link {
    color: var(--text-secondary);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 1px solid transparent;
}

.uploader-link:hover,
.uploader-link:focus-visible {
    color: var(--accent);
    border-bottom-color: currentColor;
}


/* Pack marker inside a card's HUD row (creator profile). */
.hud-tag-pack {
    background: linear-gradient(135deg, #5E5CE6, #BF5AF2);
    border-color: transparent;
    color: #fff;
}

/* ── Server-rendered nav auth ──
   LUT, creator, download and admin pages have no app.js, so the account area is
   rendered by navFor() on the server rather than filled in by script. */
.nav-actions--server {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.nav-signin {
    padding: 0.45rem 1rem;
    font-size: 0.85rem;
    white-space: nowrap;
}

.nav-user-link {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    text-decoration: none;
    color: var(--text-primary);
    font-size: 0.88rem;
    font-weight: 500;
}

.nav-user-link:hover { color: var(--accent); }

.nav-user-link .nav-user-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    object-fit: cover;
}

.nav-user-initial {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 700;
}

.nav-signout {
    font-size: 0.82rem;
    color: var(--text-muted);
    text-decoration: none;
    white-space: nowrap;
}

.nav-signout:hover { color: var(--text-primary); }

@media (max-width: 560px) {
    .nav-user-link .nav-user-name { display: none; }
    .nav-signout { display: none; }
}
