diff --git a/public/images/discord.svg b/public/images/discord.svg new file mode 100644 index 0000000..345eebd --- /dev/null +++ b/public/images/discord.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/github.svg b/public/images/github.svg new file mode 100644 index 0000000..f5cc935 --- /dev/null +++ b/public/images/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/homepage/6.png b/src/assets/homepage/6.png new file mode 100644 index 0000000..79a7c5f Binary files /dev/null and b/src/assets/homepage/6.png differ diff --git a/src/assets/homepage/full-app-display.png b/src/assets/homepage/full-app-display.png new file mode 100644 index 0000000..b1eb02f Binary files /dev/null and b/src/assets/homepage/full-app-display.png differ diff --git a/src/assets/homepage/lyrics-plus.png b/src/assets/homepage/lyrics-plus.png new file mode 100644 index 0000000..fed5adb Binary files /dev/null and b/src/assets/homepage/lyrics-plus.png differ diff --git a/src/assets/homepage/marketplace.png b/src/assets/homepage/marketplace.png new file mode 100644 index 0000000..9954dc1 Binary files /dev/null and b/src/assets/homepage/marketplace.png differ diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 020dc91..da2d161 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,4 +1,8 @@ --- +interface Props { + discordMembers?: string; +} +const { discordMembers = '20k+' } = Astro.props; const year = new Date().getFullYear(); --- @@ -35,7 +39,7 @@ const year = new Date().getFullYear(); href="https://discord.gg/VnevqPp2Rr" target="_blank" rel="noopener noreferrer">Discord + >{discordMembers} members
  • + + diff --git a/src/components/icons/GitHubIcon.astro b/src/components/icons/GitHubIcon.astro new file mode 100644 index 0000000..0fbab3e --- /dev/null +++ b/src/components/icons/GitHubIcon.astro @@ -0,0 +1,9 @@ +--- +interface Props { + size?: number; +} +const { size = 18 } = Astro.props; +--- + + + diff --git a/src/pages/index.astro b/src/pages/index.astro index eda0aed..1b77495 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -5,9 +5,24 @@ import theme2 from '../assets/homepage/2.png'; import theme3 from '../assets/homepage/3.png'; import theme4 from '../assets/homepage/4.png'; import theme5 from '../assets/homepage/5.png'; -import theme7 from '../assets/homepage/7.png'; +import theme6 from '../assets/homepage/6.png'; +import heroFullApp from '../assets/homepage/full-app-display.png'; +import heroLyrics from '../assets/homepage/lyrics-plus.png'; +import heroMarketplace from '../assets/homepage/marketplace.png'; +import DiscordIcon from '../components/icons/DiscordIcon.astro'; +import GitHubIcon from '../components/icons/GitHubIcon.astro'; import BaseLayout from '../layouts/BaseLayout.astro'; +// Community stats — update these periodically +// Downloads: ~18.8M from GitHub release asset downloads as of March 2026 +// (gh api repos/spicetify/cli/releases --paginate --jq '[.[].assets[].download_count] | add') +const stats = { + githubStars: '22k+', + downloads: '18M+', + discordMembers: '20k+', + marketplaceItems: '200+', +}; + const themes = [ { src: theme1, @@ -35,36 +50,80 @@ const themes = [ label: 'Dribbblish', }, { - src: theme7, - alt: 'Spotify with Nord theme showing the Marketplace themes browser', + src: theme6, + alt: 'Spotify with Bloom theme — a vibrant purple and pink interface', + label: 'Bloom', + }, +]; + +const heroShowcase = [ + { + src: heroMarketplace, + alt: 'Spicetify Marketplace — browse and install themes, extensions, and custom apps', label: 'Marketplace', }, + { + src: heroLyrics, + alt: 'Lyrics Plus — a custom app that displays synced lyrics inside Spotify', + label: 'Custom Apps', + }, + { + src: heroFullApp, + alt: 'Full App Display — an extension showing immersive album art with live lyrics', + label: 'Extensions', + }, ]; ---
    +
    +
    +
    + {heroShowcase.map((item) => ( +
    + {item.alt} + {item.label} +
    + ))} +
    +
    @@ -87,10 +146,13 @@ const themes = [ ))} - - Browse all themes - - +
    + + Browse all themes + + + {stats.marketplaceItems} items in the Marketplace +
    @@ -132,9 +194,11 @@ const themes = [
    +
    -

    Install in seconds

    +

    Install in seconds

    One command to get started.

    +

    Join thousands of users who have made Spotify their own.

    @@ -157,43 +221,7 @@ const themes = [
    -
    -
    - -
    -
    -
    -
    - - - - 18k+ - GitHub Stars -
    -
    - - - - 20k+ - Discord Members -
    -
    - - - - 200+ - Marketplace Items -
    -
    -
    -
    - -
    -
    -
    -

    Ready to customize Spotify?

    -

    Join thousands of users who have made Spotify their own.

    -
    + @@ -341,22 +370,34 @@ const themes = [ .hero { position: relative; - min-height: calc(100vh - var(--navbar-height)); display: flex; + flex-direction: column; align-items: center; justify-content: center; - padding: calc(var(--navbar-height) + 4rem) 1.5rem 4rem; + padding: calc(var(--navbar-height) + 4rem) 1.5rem 0; overflow: hidden; } .hero-glow { position: absolute; - top: -40%; + top: -20%; left: 50%; transform: translateX(-50%); - width: 800px; - height: 600px; - background: radial-gradient(ellipse, rgba(235, 90, 55, 0.12) 0%, transparent 70%); + width: 900px; + height: 700px; + background: radial-gradient(ellipse, rgba(235, 90, 55, 0.15) 0%, rgba(235, 90, 55, 0.05) 40%, transparent 70%); + pointer-events: none; + } + + .hero-grid-pattern { + position: absolute; + inset: 0; + background-image: + linear-gradient(rgba(235, 90, 55, 0.03) 1px, transparent 1px), + linear-gradient(90deg, rgba(235, 90, 55, 0.03) 1px, transparent 1px); + background-size: 60px 60px; + mask-image: radial-gradient(ellipse 60% 50% at 50% 30%, black 20%, transparent 70%); + -webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 30%, black 20%, transparent 70%); pointer-events: none; } @@ -366,19 +407,46 @@ const themes = [ max-width: 700px; } + .hero-badge { + display: inline-flex; + align-items: center; + gap: 0.4rem; + padding: 0.35rem 0.85rem; + font-size: 0.8rem; + font-weight: 600; + color: var(--color-primary); + background: rgba(235, 90, 55, 0.08); + border: 1px solid rgba(235, 90, 55, 0.15); + border-radius: 100px; + margin-bottom: 1.5rem; + } + + [data-theme='dark'] .hero-badge { + background: rgba(235, 90, 55, 0.12); + border-color: rgba(235, 90, 55, 0.2); + } + .hero h1 { - font-size: clamp(2.75rem, 5vw, 4.25rem); + font-size: clamp(2.75rem, 6vw, 4.5rem); font-weight: 800; - line-height: 1.1; - letter-spacing: -0.02em; + line-height: 1.08; + letter-spacing: -0.03em; margin-bottom: 1.25rem; } + .hero-gradient { + background: linear-gradient(135deg, var(--color-primary) 0%, #ff8a65 50%, var(--color-primary) 100%); + background-size: 200% auto; + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + } + .hero-subtitle { font-size: 1.15rem; color: var(--color-text-secondary); line-height: 1.6; - max-width: 560px; + max-width: 520px; margin: 0 auto 2rem; } @@ -389,6 +457,79 @@ const themes = [ flex-wrap: wrap; } + .hero-showcase { + position: relative; + width: 100%; + max-width: 1100px; + margin-top: 3.5rem; + perspective: 1200px; + } + + .hero-showcase-track { + display: flex; + gap: 1rem; + justify-content: center; + transform: rotateX(4deg); + transform-origin: center bottom; + padding: 0 1rem; + } + + .hero-showcase-card { + position: relative; + flex: 0 0 340px; + aspect-ratio: 16 / 10; + border-radius: 12px; + overflow: hidden; + border: 1px solid var(--color-border); + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12), 0 4px 20px rgba(0, 0, 0, 0.06); + transition: transform 0.3s ease, box-shadow 0.3s ease; + line-height: 0; + } + + [data-theme='dark'] .hero-showcase-card { + box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4), 0 4px 20px rgba(0, 0, 0, 0.2); + } + + .hero-showcase-card:hover { + transform: translateY(-4px); + box-shadow: 0 28px 70px rgba(0, 0, 0, 0.16), 0 8px 24px rgba(0, 0, 0, 0.08); + } + + .hero-showcase-card :global(img) { + width: 100%; + height: 100%; + object-fit: cover; + object-position: top left; + display: block; + } + + .hero-showcase-label { + position: absolute; + top: 0.6rem; + left: 50%; + transform: translateX(-50%); + font-size: 0.75rem; + font-weight: 600; + padding: 0.2rem 0.6rem; + background: rgba(0, 0, 0, 0.6); + backdrop-filter: blur(8px); + color: #fff; + border-radius: 6px; + line-height: 1.4; + white-space: nowrap; + } + + .hero-showcase::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 50%; + background: linear-gradient(to bottom, transparent 0%, var(--color-bg) 90%); + pointer-events: none; + } + .themes-section { background: var(--color-bg-secondary); } @@ -605,79 +746,59 @@ const themes = [ outline-offset: 2px; } - .stats-section { - background: var(--color-bg-secondary); - } - - .stats-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - gap: 2rem; - text-align: center; - } - - .stat { + .browse-row { display: flex; - flex-direction: column; align-items: center; - gap: 0.5rem; - } - - .stat svg { - color: var(--color-text-secondary); - } - - .stat-number { - font-size: 2.5rem; - font-weight: 800; - letter-spacing: -0.02em; - line-height: 1; + gap: 1rem; + flex-wrap: wrap; } - .stat-label { - font-size: 0.85rem; + .browse-stat { + font-size: 0.8rem; color: var(--color-text-secondary); font-weight: 500; } - .cta-section { + .install-section { position: relative; - text-align: center; overflow: hidden; + padding-top: 0; } - .cta-glow { + .install-glow { position: absolute; - bottom: -30%; + top: 50%; left: 50%; - transform: translateX(-50%); - width: 600px; - height: 400px; + transform: translate(-50%, -50%); + width: 700px; + height: 500px; background: radial-gradient(ellipse, rgba(235, 90, 55, 0.1) 0%, transparent 70%); pointer-events: none; } - .cta-section .section-container { + .install-section .section-container { position: relative; } - .cta-section h2 { - font-size: 2rem; - font-weight: 700; - margin-bottom: 0.75rem; - } - - .cta-section p { - color: var(--color-text-secondary); - font-size: 1.05rem; - margin-bottom: 2rem; + .install-title { + color: var(--color-primary); } - .cta-actions { + .install-actions { display: flex; gap: 0.75rem; justify-content: center; flex-wrap: wrap; + margin-top: 2rem; + } + + .section-subtitle + .section-subtitle-secondary { + margin-bottom: 3rem; + font-size: 0.95rem; + } + + .section-subtitle:has(+ .section-subtitle-secondary) { + margin-bottom: 0.25rem; } @media (prefers-reduced-motion: no-preference) { @@ -685,11 +806,7 @@ const themes = [ .section-subtitle, .bento-item, .feature-card, - .install-block, - .stat, - .cta-section h2, - .cta-section p, - .cta-actions { + .install-block { opacity: 0; transform: translateY(20px); animation: fade-in-up 0.5s ease forwards; @@ -701,6 +818,12 @@ const themes = [ animation: fade-in-up 0.6s ease 0.1s forwards; } + .hero-showcase { + opacity: 0; + transform: translateY(30px); + animation: fade-in-up 0.7s ease 0.25s forwards; + } + .bento-1 { animation-delay: 0.05s; } .bento-2 { animation-delay: 0.1s; } .bento-3 { animation-delay: 0.15s; } @@ -722,8 +845,7 @@ const themes = [ } .hero { - min-height: auto; - padding: calc(var(--navbar-height) + 3rem) 1rem 3rem; + padding: calc(var(--navbar-height) + 2.5rem) 1rem 0; } .hero h1 { @@ -734,6 +856,20 @@ const themes = [ font-size: 1rem; } + .hero-showcase { + margin-top: 2.5rem; + } + + .hero-showcase-track { + transform: rotateX(2deg); + gap: 0.6rem; + padding: 0 0.5rem; + } + + .hero-showcase-card { + flex: 0 0 260px; + } + .bento-grid { grid-template-columns: repeat(2, 1fr); grid-template-rows: auto; @@ -747,15 +883,6 @@ const themes = [ gap: 1rem; } - .stats-grid { - grid-template-columns: repeat(3, 1fr); - gap: 1rem; - } - - .stat-number { - font-size: 1.75rem; - } - .section-title { font-size: 1.5rem; }