commit e0949777fb94e0d6b3f232182c4e0f51ec350fb4
parent 210ba5cbd5ee59aba77c2fa6a3ee74b25d67cb0e
Author: Pablo Murad <pblmrd@gmail.com>
Date: Wed, 20 May 2026 21:30:21 -0300
getting better
Diffstat:
4 files changed, 123 insertions(+), 33 deletions(-)
diff --git a/src/App.css b/src/App.css
@@ -1,5 +1,5 @@
.page {
- max-width: 880px;
+ max-width: 960px;
margin: 0 auto;
padding: 2rem 1.25rem 4rem;
}
@@ -46,13 +46,57 @@
.main {
display: grid;
- gap: 1.5rem;
+ gap: 1.25rem;
+}
+
+.main-home {
+ gap: 1.25rem;
+}
+
+.main-sidebar {
+ display: flex;
+ flex-direction: column;
+ gap: 1.25rem;
+ min-width: 0;
}
@media (min-width: 720px) {
- .main {
- grid-template-columns: 1fr 1fr;
- align-items: start;
+ .main-home {
+ grid-template-columns: minmax(0, 1fr) minmax(0, 1.12fr);
+ grid-template-areas:
+ "sidebar player"
+ "embed embed";
+ align-items: stretch;
+ gap: 1.25rem 1.5rem;
+ }
+
+ .main-sidebar {
+ grid-area: sidebar;
+ min-height: 100%;
+ }
+
+ .main-home .now-playing {
+ grid-area: player;
+ display: flex;
+ flex-direction: column;
+ }
+
+ .main-home .main-embed {
+ grid-area: embed;
+ }
+
+ .main-home .history {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 12rem;
+ }
+
+ .main-home .history-list {
+ flex: 1;
+ max-height: none;
+ min-height: 6rem;
+ overflow-y: auto;
}
}
@@ -390,10 +434,14 @@
.history-list {
margin: 0;
padding-left: 1.1rem;
- max-height: 22rem;
+ max-height: 14rem;
overflow: auto;
}
+.main-home .history h2 {
+ margin-bottom: 0.75rem;
+}
+
.history-list li {
margin-bottom: 0.45rem;
font-size: 0.92rem;
@@ -455,10 +503,14 @@
}
.footer {
- margin-top: 2.5rem;
+ margin-top: 1.75rem;
text-align: center;
}
+.page:has(.main-home) .footer {
+ margin-top: 1.5rem;
+}
+
.footer code {
font-size: 0.85em;
color: color-mix(in srgb, var(--accent-cyan) 78%, var(--accent) 22%);
@@ -644,6 +696,13 @@
padding: 1.25rem 1.25rem 1.5rem;
}
+.main-home .main-embed.embed-snippet {
+ max-width: none;
+ width: 100%;
+ margin: 0.25rem 0 0;
+ padding: 1.15rem 1.25rem 1.35rem;
+}
+
.page-about .embed-snippet {
margin-top: 1.75rem;
}
@@ -675,6 +734,12 @@
border-radius: 10px;
resize: vertical;
min-height: 8rem;
+ max-height: 10rem;
+ box-sizing: border-box;
+}
+
+.main-home .embed-snippet-code {
+ max-height: 7.5rem;
}
.embed-snippet-copy {
@@ -718,7 +783,11 @@
}
.track-search {
- margin-bottom: 1rem;
+ margin-bottom: 0;
+}
+
+.card--search {
+ flex-shrink: 0;
}
.track-search-input {
@@ -769,6 +838,18 @@
margin-bottom: 0.75rem;
}
+@media (min-width: 600px) {
+ .embed-snippet-options {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 0.5rem 1rem;
+ }
+
+ .embed-snippet-start {
+ grid-column: 1 / -1;
+ }
+}
+
.embed-snippet-start {
display: flex;
flex-direction: column;
diff --git a/src/components/EmbedSnippet.tsx b/src/components/EmbedSnippet.tsx
@@ -26,7 +26,11 @@ function buildIframeSnippet(opts: {
></iframe>`;
}
-export function EmbedSnippet() {
+type Props = {
+ className?: string;
+};
+
+export function EmbedSnippet({ className }: Props = {}) {
const [copied, setCopied] = useState(false);
const [autoplay, setAutoplay] = useState(true);
const [compact, setCompact] = useState(false);
@@ -63,7 +67,10 @@ export function EmbedSnippet() {
}, [code]);
return (
- <section className="embed-snippet card" aria-label="Embed this player">
+ <section
+ className={["embed-snippet", "card", className].filter(Boolean).join(" ")}
+ aria-label="Embed this player"
+ >
<h2 className="embed-snippet-title">Embed on your site</h2>
<p className="embed-snippet-lead muted">
Paste this HTML wherever you want the player. Optional query params:{" "}
diff --git a/src/components/TrackSearch.tsx b/src/components/TrackSearch.tsx
@@ -49,7 +49,7 @@ export function TrackSearch({ onSelect, disabled }: Props) {
);
return (
- <section className="track-search card" aria-label="Search tracks">
+ <section className="track-search card card--search" aria-label="Search tracks">
<h2>Search</h2>
<input
type="search"
diff --git a/src/pages/Home.tsx b/src/pages/Home.tsx
@@ -69,8 +69,29 @@ export default function Home() {
) : null}
<SiteHeader nav="home" />
- <main className="main">
- <TrackSearch onSelect={(id) => void loadTrackById(id)} disabled={!!healthWarn} />
+ <main className="main main-home">
+ <div className="main-sidebar">
+ <TrackSearch onSelect={(id) => void loadTrackById(id)} disabled={!!healthWarn} />
+
+ <aside className="card history" aria-label="Recently played">
+ <h2>History</h2>
+ <ol className="history-list">
+ {history.map((t, idx) => (
+ <li key={`${t.id}-${idx}-${t.title}`}>
+ <button
+ type="button"
+ className="history-hit"
+ onClick={() => void loadTrackById(t.id)}
+ >
+ <span className="h-artist">{t.artist}</span>
+ <span className="sep">—</span>
+ <span className="h-title">{t.title}</span>
+ </button>
+ </li>
+ ))}
+ </ol>
+ </aside>
+ </div>
<article className="card now-playing">
<header className="card-head">
@@ -148,28 +169,9 @@ export default function Home() {
<PlayerAttribution />
</article>
- <aside className="card history" aria-label="Recently played">
- <h2>History</h2>
- <ol className="history-list">
- {history.map((t, idx) => (
- <li key={`${t.id}-${idx}-${t.title}`}>
- <button
- type="button"
- className="history-hit"
- onClick={() => void loadTrackById(t.id)}
- >
- <span className="h-artist">{t.artist}</span>
- <span className="sep">—</span>
- <span className="h-title">{t.title}</span>
- </button>
- </li>
- ))}
- </ol>
- </aside>
+ <EmbedSnippet className="main-embed" />
</main>
- <EmbedSnippet />
-
<footer className="footer">
<small className="muted">Developed by Pablo Murad — 2026</small>
</footer>