Comet landing page.

feat: initial basic roadmap

ovyerus.com fc23ff38 93cd07dc

verified
+226 -17
+1
package.json
··· 11 11 }, 12 12 "dependencies": { 13 13 "@fontsource-variable/work-sans": "^5.2.6", 14 + "@lucide/astro": "^0.539.0", 14 15 "@tailwindcss/vite": "^4.1.11", 15 16 "astro": "^5.12.9", 16 17 "simple-icons-astro": "^15.10.0",
+12
pnpm-lock.yaml
··· 11 11 '@fontsource-variable/work-sans': 12 12 specifier: ^5.2.6 13 13 version: 5.2.6 14 + '@lucide/astro': 15 + specifier: ^0.539.0 16 + version: 0.539.0(astro@5.12.9(@types/node@24.2.1)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2)) 14 17 '@tailwindcss/vite': 15 18 specifier: ^4.1.11 16 19 version: 4.1.11(vite@6.3.5(@types/node@24.2.1)(jiti@2.5.1)(lightningcss@1.30.1)) ··· 363 366 364 367 '@jridgewell/trace-mapping@0.3.30': 365 368 resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==} 369 + 370 + '@lucide/astro@0.539.0': 371 + resolution: {integrity: sha512-PCAo48RsERkmyWX+bmssGlu0mb84cP8kLMyc1JuW5pRY4zkx7cnyZMr3RkfPFvDKJZf2/2KPoaZz8j6BjXaXcA==} 372 + peerDependencies: 373 + astro: ^4 || ^5 366 374 367 375 '@oslojs/encoding@1.1.0': 368 376 resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} ··· 2029 2037 dependencies: 2030 2038 '@jridgewell/resolve-uri': 3.1.2 2031 2039 '@jridgewell/sourcemap-codec': 1.5.5 2040 + 2041 + '@lucide/astro@0.539.0(astro@5.12.9(@types/node@24.2.1)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2))': 2042 + dependencies: 2043 + astro: 5.12.9(@types/node@24.2.1)(jiti@2.5.1)(lightningcss@1.30.1)(rollup@4.46.2)(typescript@5.9.2) 2032 2044 2033 2045 '@oslojs/encoding@1.1.0': {} 2034 2046
+100
src/components/Roadmap.astro
··· 1 + --- 2 + import { 3 + AppWindow, 4 + Cloudy, 5 + Copyright, 6 + DatabaseZap, 7 + FlaskConical, 8 + LibraryBig, 9 + Rss, 10 + Scale, 11 + Share2, 12 + } from "@lucide/astro"; 13 + import RoadmapItem from "./RoadmapItem.astro"; 14 + --- 15 + 16 + <section class="flex flex-col gap-4 text-left"> 17 + <h2 class="text-4xl font-bold">Roadmap</h2> 18 + <p> 19 + A rough roadmap of what we have planned for the future. Subject to change at 20 + any time. 21 + </p> 22 + 23 + <ol class="flex flex-col"> 24 + <RoadmapItem 25 + title="Foundational libraries" 26 + status="in-progress" 27 + icon={LibraryBig} 28 + > 29 + <p> 30 + From-scratch Elixir libraries and tooling to interact with the AT 31 + Protocol. 32 + </p> 33 + <ul class="mt-0.5 list-disc"> 34 + <li class="ml-6"> 35 + <a 36 + href="https://github.com/cometsh/atex" 37 + class="inline-block underline" 38 + > 39 + atex 40 + </a> - Core utilities and frameworks for AT Protocol 41 + </li> 42 + <li class="ml-6"> 43 + <a 44 + href="https://github.com/cometsh/drinkup" 45 + class="inline-block underline" 46 + > 47 + Drinkup 48 + </a> 49 + - AT Protocol firehose & subscription listener 50 + </li> 51 + </ul> 52 + </RoadmapItem> 53 + 54 + <RoadmapItem title="Basic MVP" icon={AppWindow}> 55 + Basic chronological timeline, follows, uploading of music, and playback. 56 + Private testing. 57 + </RoadmapItem> 58 + 59 + <RoadmapItem title="Audio CDN" icon={Cloudy}> 60 + Custom CDN for converting uploaded audio to streaming-friendly formats for 61 + the music player, reducing strain on self-hosters and mobile bandwidth. 62 + </RoadmapItem> 63 + 64 + <RoadmapItem title="Alpha release" icon={FlaskConical} /> 65 + 66 + <RoadmapItem title="Social graph" icon={Share2}> 67 + Expand the basic follow-only social graph with blocks and mutes applying 68 + to commenting on tracks and playlists. 69 + </RoadmapItem> 70 + 71 + <RoadmapItem title="Discovery algorithm & custom feeds" icon={Rss}> 72 + Create a discovery/recommendations algorithm for finding new content. 73 + Additionally, create tools to allow the creation of custom feeds (and 74 + autoplay?) for those who want them 75 + </RoadmapItem> 76 + 77 + <RoadmapItem title="Moderation" icon={Scale}> 78 + Moderation tools for dealing with offensive content, modelled after 79 + Bluesky's labelling system. 80 + </RoadmapItem> 81 + 82 + <RoadmapItem title="Copyright" icon={Copyright}> 83 + A system to deal with copyright violations and piracy on the platform, 84 + forwarding DMCA requests to PDS hosts and blocking content from the app 85 + where needed, while still fighting for fair use and remix culture. 86 + </RoadmapItem> 87 + 88 + <!-- <RoadmapItem title="Out of alpha" icon={Rocket}> 89 + Our UI and UX should be nice and shiny, and most major features should be 90 + implemented. We're ready for adoption! 91 + </RoadmapItem> --> 92 + 93 + <RoadmapItem title="Hosted PDS offering" icon={DatabaseZap}> 94 + Provide a hosted PDS offering with increased storage limits to allow 95 + uploading longer tracks (e.g. mixes and podcasts) or other larger AT 96 + Protocol media, without having to deal with the technical hassle of 97 + self-hosting. 98 + </RoadmapItem> 99 + </ol> 100 + </section>
+104
src/components/RoadmapItem.astro
··· 1 + --- 2 + import { Check, Lightbulb, Clock, type Icon as IconType } from "@lucide/astro"; 3 + 4 + const statusStrings = { 5 + planned: "Planned", 6 + "in-progress": "In Progress", 7 + complete: "Complete", 8 + } as const; 9 + 10 + interface Props { 11 + title: string; 12 + icon: typeof IconType; 13 + status?: "planned" | "in-progress" | "complete"; 14 + } 15 + 16 + const { title, icon: Icon, status = "planned" } = Astro.props; 17 + let StatusIcon: typeof IconType; 18 + 19 + switch (status) { 20 + case "planned": 21 + StatusIcon = Lightbulb; 22 + break; 23 + case "in-progress": 24 + StatusIcon = Clock; 25 + break; 26 + case "complete": 27 + StatusIcon = Check; 28 + break; 29 + } 30 + --- 31 + 32 + <li class="roadmap-item"> 33 + <div 34 + class="icon flex size-10 items-center justify-center rounded-lg border-2 border-black/20 bg-black/50" 35 + > 36 + <Icon aria-hidden="true" /> 37 + </div> 38 + 39 + <article class="flex flex-col items-start gap-0.5"> 40 + <p 41 + class="flex items-center gap-1 rounded-full border-2 border-black/20 px-2 py-0.5 text-xs tracking-wide uppercase" 42 + class:list={{ 43 + "bg-black/50": status === "planned", 44 + "bg-purple-950/70": status === "in-progress", 45 + "bg-emerald-950/70": status === "complete", 46 + }} 47 + > 48 + <StatusIcon size={12} aria-hidden="true" /> 49 + {statusStrings[status]} 50 + </p> 51 + <h3 class="text-lg font-semibold">{title}</h3> 52 + <slot /> 53 + </article> 54 + 55 + <hr aria-hidden="true" /> 56 + <hr aria-hidden="true" /> 57 + </li> 58 + 59 + <style> 60 + @reference "../style/main.css"; 61 + 62 + .roadmap-item { 63 + display: grid; 64 + grid-template-columns: 40px 1fr; 65 + grid-template-rows: 2rem 40px auto; 66 + grid-template-areas: 67 + "top-vr blank" 68 + "icon content" 69 + "bottom-vr content"; 70 + 71 + & > div { 72 + grid-area: icon; 73 + } 74 + 75 + & > article { 76 + grid-area: content; 77 + padding-left: 2rem; 78 + } 79 + 80 + & > hr { 81 + @apply bg-black/60; 82 + width: 0.25rem; 83 + height: 100%; 84 + border: none; 85 + margin: 0 auto; 86 + 87 + &:first-of-type { 88 + grid-area: top-vr; 89 + } 90 + 91 + &:last-of-type { 92 + grid-area: bottom-vr; 93 + } 94 + } 95 + 96 + &:first-child > hr:first-of-type { 97 + display: none; 98 + } 99 + 100 + &:last-child > hr:last-of-type { 101 + display: none; 102 + } 103 + } 104 + </style>
+1 -14
src/layouts/Layout.astro
··· 26 26 <script 27 27 defer 28 28 src="https://stats.ovy.sh/script.js" 29 - data-website-id="8ef06cd9-9afa-4b67-a4ce-789d4b2a1edf" 30 - > 31 - </script> 29 + data-website-id="8ef06cd9-9afa-4b67-a4ce-789d4b2a1edf"></script> 32 30 </head> 33 31 <body> 34 32 <slot /> 35 33 </body> 36 34 </html> 37 - 38 - <style> 39 - html, 40 - body { 41 - margin: 0; 42 - width: 100%; 43 - height: 100%; 44 - min-width: 100vw; 45 - min-height: 100vh; 46 - } 47 - </style>
+8 -3
src/pages/index.astro
··· 1 1 --- 2 2 import Logo from "../assets/logo.svg"; 3 3 import Layout from "../layouts/Layout.astro"; 4 + import Roadmap from "../components/Roadmap.astro"; 4 5 import { Bluesky, Discord, Github } from "simple-icons-astro"; 5 6 --- 6 7 7 8 <Layout> 8 9 <main 9 - class="flex flex-col items-center justify-center gap-3 text-center leading-none" 10 + class="flex h-full w-full max-w-xl flex-col items-center gap-3 px-4 py-8 text-center leading-none sm:py-16 lg:py-24 2xl:py-32" 10 11 > 11 12 <div class="flex items-center justify-center gap-4"> 12 13 <Logo width="48px" height="48px" class="rounded-md shadow-md" /> 13 14 <h1 class="text-[64px] font-bold">Comet</h1> 14 15 </div> 16 + 15 17 <p class="leading-tight"> 16 18 Decentralised music streaming on ATProtocol.<br />Coming soon. 17 19 </p> 18 - <p class="flex items-center gap-2 font-semibold"> 20 + 21 + <p class="flex items-center gap-2 pb-7 font-semibold"> 19 22 <span class="mr-2">Follow us:</span> 20 23 <a href="https://bsky.app/profile/comet.sh" rel="noopener me"> 21 24 <Bluesky /> ··· 23 26 <a href="https://discord.gg/ZKK7DnubD9" rel="noopener"><Discord /></a> 24 27 <a href="https://github.com/cometsh" rel="noopener me"><Github /></a> 25 28 </p> 29 + 30 + <Roadmap /> 26 31 </main> 27 32 </Layout> 28 33 ··· 30 35 @reference "../style/main.css"; 31 36 32 37 body { 33 - @apply from-brand-light flex items-center justify-center bg-radial-[circle_at_50%_150%] via-amber-900 to-stone-950 text-white; 38 + @apply from-brand-light flex justify-center bg-radial-[circle_at_50%_150%] via-amber-900 to-stone-950 bg-fixed text-white; 34 39 } 35 40 </style>