- {Array.from({ length: BARS }).map((_, i) => (
-
{
- if (el) barRefs.current[i] = el;
- }}
- />
- ))}
-
- );
-}
diff --git a/frontend/src/components/Tape.tsx b/frontend/src/components/Tape.tsx
deleted file mode 100644
index c154e6c..0000000
--- a/frontend/src/components/Tape.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import type { Station } from '@lib/types';
-
-interface Props {
- station: Station;
- index: number;
- active: boolean;
- onSelect: (id: string) => void;
- listeners?: number | null;
-}
-
-export function Tape({ station, index, active, onSelect, listeners }: Props) {
- return (
-
- );
-}
diff --git a/frontend/src/components/TopNav.astro b/frontend/src/components/TopNav.astro
deleted file mode 100644
index 3e76fb5..0000000
--- a/frontend/src/components/TopNav.astro
+++ /dev/null
@@ -1,9 +0,0 @@
----
----
-
diff --git a/frontend/src/lib/store.ts b/frontend/src/lib/store.ts
deleted file mode 100644
index 09b6ff2..0000000
--- a/frontend/src/lib/store.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-let audioRef: HTMLAudioElement | null = null;
-const subs = new Set<() => void>();
-
-export const playerStore = {
- setAudio(el: HTMLAudioElement | null) {
- audioRef = el;
- subs.forEach((fn) => fn());
- },
- getAudio(): HTMLAudioElement | null {
- return audioRef;
- },
- subscribe(fn: () => void): () => void {
- subs.add(fn);
- return () => {
- subs.delete(fn);
- };
- },
-};
diff --git a/frontend/src/pages/index.astro b/frontend/src/pages/index.astro
deleted file mode 100644
index 02ca49e..0000000
--- a/frontend/src/pages/index.astro
+++ /dev/null
@@ -1,44 +0,0 @@
----
-import '@styles/tokens.css';
-import '@styles/global.css';
-import '@styles/components/hero.css';
-import '@styles/components/deck.css';
-import '@styles/components/spectrum.css';
-import '@styles/components/tape.css';
-import '@styles/components/history-card.css';
-import '@styles/components/listen-ways-card.css';
-import '@styles/components/footer.css';
-
-import TopNav from '@components/TopNav.astro';
-import HistoryCard from '@components/HistoryCard.astro';
-import ListenWaysCard from '@components/ListenWaysCard.astro';
-import FooterStrip from '@components/FooterStrip.astro';
-import { HeroPlayer } from '@components/HeroPlayer';
-import { listStations } from '@lib/stations';
-
-export const prerender = false;
-
-const root = process.env.LIBRARY_ROOT ?? '/library';
-const initialStations = await listStations(root);
-const firstStation = initialStations[0]?.id ?? '';
----
-
-
-
-
-
-
denpa.fm // 電波
-
-
-
-
-
-
-
- {firstStation ?
:
}
- {firstStation ?
:
}
-
-
-
-
-
diff --git a/frontend/src/styles/components/deck.css b/frontend/src/styles/components/deck.css
deleted file mode 100644
index 79e74df..0000000
--- a/frontend/src/styles/components/deck.css
+++ /dev/null
@@ -1,95 +0,0 @@
-.hero-deck {
- background: linear-gradient(180deg, var(--cream) 0%, #f5e0c4 100%);
- color: var(--ink);
- padding: 24px;
- border: 3px solid var(--ink);
- box-shadow: 8px 8px 0 var(--pink), 16px 16px 0 var(--cyan);
- position: relative;
-}
-.hero-deck::before {
- content: ""; position: absolute; inset: 5px;
- border: 1px dashed #0a041044; pointer-events: none;
-}
-
-.deck-screen {
- background: var(--ink); color: var(--green);
- font-family: var(--f-mono); font-size: 14px;
- padding: 14px 18px;
- border: 2px inset var(--ink);
- position: relative; overflow: hidden;
-}
-.deck-screen::after {
- content: ""; position: absolute; inset: 0; pointer-events: none;
- background: repeating-linear-gradient(0deg, rgba(94,255,155,0.08) 0 1px, transparent 1px 3px);
-}
-.deck-screen-row { display: flex; justify-content: space-between; opacity: 0.75; font-size: 12px; }
-.deck-now {
- font-family: var(--f-pixel); font-size: 28px; color: var(--cream);
- line-height: 1.1; margin: 6px 0 2px;
- text-shadow: 0 0 10px #5eff9b80;
-}
-.deck-artist { font-size: 16px; color: var(--cyan); margin-bottom: 8px; }
-.deck-progress-row {
- display: flex; align-items: center; gap: 10px;
- margin-top: 12px;
-}
-.deck-time { font-size: 12px; color: var(--cyan); min-width: 36px; }
-.deck-progress { flex: 1; height: 4px; background: #5eff9b22; border: 1px solid #5eff9b55; }
-.deck-progress-fill { height: 100%; background: var(--green); transition: width 200ms linear; }
-
-.deck-reels {
- display: flex; align-items: center; justify-content: space-around;
- gap: 14px; margin-top: 18px;
- padding: 14px; background: var(--ink); border: 2px solid var(--ink);
-}
-.reel {
- width: 110px; height: 110px; border-radius: 50%;
- background:
- radial-gradient(circle, var(--cream) 0 16px, transparent 16px),
- conic-gradient(from 0deg, var(--plum-2) 0 25%, var(--plum) 25% 50%, var(--plum-2) 50% 75%, var(--plum) 75%);
- border: 2px solid var(--cream);
- position: relative;
-}
-.reel::before {
- content: ""; position: absolute; inset: 7px; border-radius: 50%;
- border: 1px dashed #fff4e833;
-}
-.reel.spinning { animation: spin 1.6s linear infinite; }
-@keyframes spin { to { transform: rotate(360deg); } }
-.reel-strip {
- flex: 1; height: 7px;
- background: linear-gradient(90deg, var(--cream) 0%, #d4a578 50%, var(--cream) 100%);
- border-top: 1px solid var(--ink); border-bottom: 1px solid var(--ink);
-}
-
-.deck-controls {
- display: flex; align-items: center; gap: 10px; margin-top: 18px;
- flex-wrap: wrap;
-}
-.deck-btn {
- font-family: var(--f-pixel); font-size: 16px;
- background: var(--pink); color: var(--cream);
- border: 2px solid var(--ink); padding: 10px 14px;
- cursor: pointer; box-shadow: 3px 3px 0 var(--ink);
- letter-spacing: 1px;
- transition: transform 100ms, box-shadow 100ms;
-}
-.deck-btn:hover { transform: translate(-1px,-1px); box-shadow: 4px 4px 0 var(--ink); }
-.deck-btn:active { transform: translate(2px,2px); box-shadow: 1px 1px 0 var(--ink); }
-.deck-btn.play { font-size: 20px; padding: 16px 24px; background: var(--cyan); color: var(--ink); }
-.deck-btn.format { background: var(--cream); color: var(--ink); }
-.deck-btn.format[data-active=true] { background: var(--lemon); }
-
-.deck-vol {
- flex: 1; min-width: 200px;
- display: flex; align-items: center; gap: 10px;
- background: var(--ink); padding: 10px 14px; border: 2px solid var(--ink);
-}
-.deck-vol label { font-family: var(--f-pixel); font-size: 13px; color: var(--lemon); letter-spacing: 1.5px; }
-.deck-vol input { flex: 1; accent-color: var(--pink); }
-.deck-vol-pct { font-family: var(--f-mono); font-size: 13px; color: var(--cyan); min-width: 38px; text-align: right; }
-
-@media (max-width: 640px) {
- .reel { width: 80px; height: 80px; }
- .deck-vol { min-width: 100%; }
-}
diff --git a/frontend/src/styles/components/footer.css b/frontend/src/styles/components/footer.css
deleted file mode 100644
index 7579d5e..0000000
--- a/frontend/src/styles/components/footer.css
+++ /dev/null
@@ -1,9 +0,0 @@
-.footer {
- margin-top: 12px; padding: 30px 0 24px;
- border-top: 2px dashed #ff3ea566;
-}
-.footer-bot {
- display: flex; justify-content: space-between; gap: 14px;
- font-family: var(--f-mono); font-size: 12px; color: #fff4e8aa;
- flex-wrap: wrap;
-}
diff --git a/frontend/src/styles/components/hero.css b/frontend/src/styles/components/hero.css
deleted file mode 100644
index f0502e6..0000000
--- a/frontend/src/styles/components/hero.css
+++ /dev/null
@@ -1,106 +0,0 @@
-.topnav {
- display: flex; justify-content: space-between; align-items: center;
- font-family: var(--f-pixel); font-size: 13px; letter-spacing: 2px;
- padding: 6px 0 18px; border-bottom: 1px dashed #ff3ea533;
- margin-bottom: 24px;
- flex-wrap: wrap; gap: 10px;
-}
-.topnav-brand { color: var(--pink); }
-.topnav-links { display: flex; gap: 18px; }
-.topnav-links a { color: var(--cream); }
-.topnav-links a:hover { color: var(--lemon); }
-
-.hero {
- position: relative;
- padding: 30px 32px 36px;
- background:
- radial-gradient(ellipse at 30% 0%, #ff3ea522 0%, transparent 55%),
- radial-gradient(ellipse at 80% 100%, #5ef7ff1a 0%, transparent 55%),
- var(--plum);
- border: 2px solid var(--ink);
- margin-bottom: 36px;
- overflow: hidden;
-}
-.hero-header {
- display: grid;
- grid-template-columns: auto 1fr auto;
- align-items: end;
- gap: 24px; margin-bottom: 22px;
-}
-.hero-wordmark .eyebrow {
- font-family: var(--f-pixel); font-size: 16px; letter-spacing: 4px; color: var(--pink);
-}
-.hero-wordmark .big {
- font-family: var(--f-pixel);
- font-size: clamp(48px, 7vw, 88px);
- line-height: 0.9; letter-spacing: 0; margin-top: 6px;
- display: inline-block;
- padding-right: 0.12em;
- color: transparent;
- background: linear-gradient(180deg, var(--cream) 0%, var(--cream) 50%, var(--pink) 50%, var(--pink) 100%);
- -webkit-background-clip: text; background-clip: text;
- filter: drop-shadow(0 0 8px #ff3ea580);
-}
-.hero-tagline {
- font-family: var(--f-hand); font-size: 26px;
- color: var(--cream); transform: rotate(-2deg); line-height: 1.05;
- text-align: center;
-}
-.hero-status {
- font-family: var(--f-mono); font-size: 13px;
- color: var(--cyan); text-align: right; line-height: 1.55;
-}
-.hero-status .live { color: var(--pink); }
-.hero-status .blink { animation: blink 1s steps(2) infinite; }
-@keyframes blink { 50% { opacity: 0.15; } }
-
-.hero-body {
- display: grid;
- grid-template-columns: 260px 1fr;
- gap: 24px;
- position: relative;
-}
-.hero-stations { display: flex; flex-direction: column; gap: 10px; }
-.hero-stations-label {
- font-family: var(--f-pixel); color: var(--lemon);
- font-size: 14px; letter-spacing: 2px;
- padding: 5px 10px;
- background: var(--ink); border: 2px solid var(--lemon);
- align-self: flex-start; transform: rotate(-2deg);
- margin-bottom: 4px;
-}
-
-.hero-deck-wrap { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
-.hero-footer { display: flex; gap: 12px; align-items: stretch; }
-.share-btn {
- font-family: var(--f-mono); font-size: 13px;
- background: var(--ink); color: var(--cyan);
- padding: 10px 14px; border: 1.5px dashed #5ef7ff66;
- cursor: pointer; white-space: nowrap;
-}
-.share-btn:hover { border-style: solid; border-color: var(--cyan); }
-.ticker {
- flex: 1; overflow: hidden; white-space: nowrap;
- background: var(--ink); padding: 10px 0;
- border-top: 1px dashed #ff3ea566; border-bottom: 1px dashed #ff3ea566;
- display: flex; align-items: center;
-}
-.ticker-inner {
- display: inline-block; padding-left: 100%;
- animation: marq 30s linear infinite;
- color: var(--pink); font-family: var(--f-mono); font-size: 13px; letter-spacing: 1px;
-}
-@keyframes marq { to { transform: translateX(-100%); } }
-
-@media (max-width: 1000px) {
- .hero-body { grid-template-columns: 1fr; }
- .hero-stations { display: grid; grid-template-columns: repeat(2, 1fr); }
-}
-@media (max-width: 640px) {
- .page { padding: 14px; }
- .hero { padding: 20px 16px 24px; }
- .hero-header { grid-template-columns: 1fr; gap: 14px; }
- .hero-tagline { text-align: left; }
- .hero-status { text-align: left; }
- .hero-stations { grid-template-columns: 1fr; }
-}
diff --git a/frontend/src/styles/components/history-card.css b/frontend/src/styles/components/history-card.css
deleted file mode 100644
index 999115d..0000000
--- a/frontend/src/styles/components/history-card.css
+++ /dev/null
@@ -1,28 +0,0 @@
-.full-secthead { margin-bottom: 14px; }
-.full-secthead-jp { font-family: var(--f-pixel); font-size: 18px; color: var(--lemon); letter-spacing: 4px; }
-.full-secthead-en { font-family: var(--f-pixel); font-size: 22px; color: var(--cream); letter-spacing: 1px; margin-top: 2px; }
-
-.card {
- background: var(--plum);
- border: 2px solid var(--ink);
- padding: 22px 24px;
- position: relative;
-}
-.card::before {
- content: ""; position: absolute; inset: 4px; border: 1px dashed #ff3ea522; pointer-events: none;
-}
-
-.history-list { display: flex; flex-direction: column; }
-.history-row {
- display: grid; grid-template-columns: 50px 1fr auto;
- gap: 12px; padding: 8px 4px;
- border-bottom: 1px dashed #ff3ea522;
- font-size: 13px;
-}
-.history-row:last-child { border-bottom: none; }
-.history-row .t { font-family: var(--f-mono); color: var(--cyan); }
-.history-row .title { font-family: var(--f-pixel); font-size: 14px; color: var(--cream); }
-.history-row .artist { font-family: var(--f-mono); color: #fff4e8aa; font-size: 12px; }
-.history-empty {
- font-family: var(--f-mono); font-size: 13px; color: #fff4e8aa; padding: 8px 4px;
-}
diff --git a/frontend/src/styles/components/listen-ways-card.css b/frontend/src/styles/components/listen-ways-card.css
deleted file mode 100644
index 2e0a7ac..0000000
--- a/frontend/src/styles/components/listen-ways-card.css
+++ /dev/null
@@ -1,20 +0,0 @@
-.listen-ways-list { display: flex; flex-direction: column; gap: 14px; }
-.listen-way {
- border: 1.5px dashed #5ef7ff44;
- padding: 12px;
- background: #0a04108c;
-}
-.lw-label { font-family: var(--f-pixel); font-size: 12px; color: var(--lemon); letter-spacing: 2px; margin-bottom: 4px; }
-.lw-url {
- display: block; font-family: var(--f-mono); font-size: 13px;
- color: var(--cyan); background: var(--ink);
- padding: 6px 8px; word-break: break-all;
-}
-.lw-hint { font-family: var(--f-mono); font-size: 11px; color: #fff4e866; margin-top: 6px; }
-
-.row-grid { display: grid; gap: 24px; margin-bottom: 36px; }
-.row-grid.two { grid-template-columns: 1.2fr 1fr; }
-
-@media (max-width: 1000px) {
- .row-grid.two { grid-template-columns: 1fr; }
-}
diff --git a/frontend/src/styles/components/spectrum.css b/frontend/src/styles/components/spectrum.css
deleted file mode 100644
index d9d8f24..0000000
--- a/frontend/src/styles/components/spectrum.css
+++ /dev/null
@@ -1,10 +0,0 @@
-.deck-spectrum {
- display: flex; align-items: flex-end; gap: 2px;
- height: 80px; margin-top: 18px;
- padding: 10px; background: var(--ink); border: 2px solid var(--ink);
-}
-.spec-bar {
- flex: 1; min-height: 3px;
- background: linear-gradient(180deg, var(--pink) 0%, var(--lemon) 50%, var(--green) 100%);
- transition: height 80ms linear;
-}
diff --git a/frontend/src/styles/components/tape.css b/frontend/src/styles/components/tape.css
deleted file mode 100644
index db5cdcb..0000000
--- a/frontend/src/styles/components/tape.css
+++ /dev/null
@@ -1,23 +0,0 @@
-.tape {
- font-family: var(--f-mono);
- background: var(--cream); color: var(--ink);
- padding: 10px 12px 12px;
- border: 2px solid var(--ink);
- box-shadow: 3px 3px 0 var(--ink);
- cursor: pointer; text-align: left;
- transition: transform 120ms ease-out, box-shadow 120ms ease-out;
- width: 100%;
-}
-.tape:hover { transform: translate(-2px,-2px); box-shadow: 5px 5px 0 var(--ink); }
-.tape.active {
- background: var(--pink); color: var(--cream);
- transform: translate(-3px,-3px) rotate(-1deg);
- box-shadow: 6px 6px 0 var(--lemon);
-}
-.tape-num { font-family: var(--f-mono); font-size: 10px; opacity: 0.65; letter-spacing: 1.5px; }
-.tape-name { font-family: var(--f-pixel); font-size: 16px; line-height: 1.1; margin-top: 2px; }
-.tape-jp { font-family: var(--f-pixel); font-size: 11px; opacity: 0.85; letter-spacing: 1.5px; margin-top: 2px; }
-.tape-meta { font-family: var(--f-mono); font-size: 10px; margin-top: 6px; display: flex; justify-content: space-between; opacity: 0.75; }
-.tape-holes { display: flex; gap: 4px; margin-top: 6px; }
-.tape-holes span { width: 14px; height: 14px; border-radius: 50%; background: var(--ink); box-shadow: inset 0 0 0 3px var(--cream); }
-.tape.active .tape-holes span { box-shadow: inset 0 0 0 3px var(--pink); }