Modernize the UI and fix the equalizer sizing bug
Bug fix
- EqualizerIcon: the SVG was rendering at the wrong size (filling
its parent) because it had no explicit width/height attributes.
Now it accepts a size prop with a 24px default and the SVG element
carries the size as width/height attributes, with the className
on top. Can't accidentally balloon.
Design
- Stripped the light-mode CSS — the app is dark-only now, and the
theme toggle was a no-op (clicking it just toggled a class that
had no matching rules). ThemeToggle.tsx and lib/theme.ts are
gone; initTheme() call removed from main.tsx.
- Reworked the input form:
• brand row is now small + refined (icon + wordmark, no huge
gradient title)
• Options is a single subtle collapsible card with a chevron and
a count badge showing how many options are non-default
• Vocals is now a segmented pill (single rounded container, two
flat segments) instead of two full-width grid buttons
• Generate button is slightly smaller (py-3.5, text-sm) and
uses a softer shadow (shadow-violet-900/20)
- Empty state in the results panel: dashed-border card, soft
gradient blur behind the music icon, cleaner copy.
- Results header: smaller heading, the 'Regenerate All' and
'Cancel' buttons are now tiny ghost-style pills in the top-right.
- Sticky ZIP bar: softer shadow, more refined copy.
- Result cards: smaller icon, single-line title, the Regenerate
button is now an inline pill that fits next to Revert + Copy.
- Home page header now has a tiny equalizer icon + 'MelodyMuse'
wordmark on the left (was just text). Settings page header has
the back arrow on the left and the title, no theme toggle.
- Global CSS: added modern focus-visible ring, custom selection
color, subtle scrollbar thumb, slightly tweaked the gradient
text to a softer violet-300 → cyan-300 instead of the loud
violet-400 → fuchsia-400 → cyan-400.
This commit is contained in:
@@ -1,35 +1,92 @@
|
||||
// Animated equalizer/waveform icon for the MelodyMuse header.
|
||||
export function EqualizerIcon({ className = 'w-7 h-7' }: { className?: string }) {
|
||||
// Equalizer/waveform mark for the MelodyMuse header. The SVG has explicit
|
||||
// width/height attributes (in addition to the Tailwind class) so it can't
|
||||
// accidentally balloon to fill its parent if the CSS fails to load.
|
||||
|
||||
interface EqualizerIconProps {
|
||||
className?: string;
|
||||
size?: number;
|
||||
}
|
||||
|
||||
export function EqualizerIcon({ className, size = 24 }: EqualizerIconProps) {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
aria-hidden="true"
|
||||
className={className}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="eq-grad" x1="0" y1="0" x2="32" y2="32" gradientUnits="userSpaceOnUse">
|
||||
<linearGradient
|
||||
id="eq-grad"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="32"
|
||||
y2="32"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0" stopColor="#a78bfa" />
|
||||
<stop offset="1" stopColor="#22d3ee" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g stroke="url(#eq-grad)" strokeWidth="2.4" strokeLinecap="round">
|
||||
<line x1="5" y1="13" x2="5" y2="19">
|
||||
<animate attributeName="y1" values="13;8;13" dur="1.2s" repeatCount="indefinite" />
|
||||
<animate attributeName="y2" values="19;24;19" dur="1.2s" repeatCount="indefinite" />
|
||||
<animate
|
||||
attributeName="y1"
|
||||
values="13;8;13"
|
||||
dur="1.2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="y2"
|
||||
values="19;24;19"
|
||||
dur="1.2s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</line>
|
||||
<line x1="11" y1="9" x2="11" y2="23">
|
||||
<animate attributeName="y1" values="9;14;9" dur="1.4s" repeatCount="indefinite" />
|
||||
<animate attributeName="y2" values="23;18;23" dur="1.4s" repeatCount="indefinite" />
|
||||
<animate
|
||||
attributeName="y1"
|
||||
values="9;14;9"
|
||||
dur="1.4s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="y2"
|
||||
values="23;18;23"
|
||||
dur="1.4s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</line>
|
||||
<line x1="17" y1="11" x2="17" y2="21">
|
||||
<animate attributeName="y1" values="11;6;11" dur="1.0s" repeatCount="indefinite" />
|
||||
<animate attributeName="y2" values="21;26;21" dur="1.0s" repeatCount="indefinite" />
|
||||
<animate
|
||||
attributeName="y1"
|
||||
values="11;6;11"
|
||||
dur="1.0s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="y2"
|
||||
values="21;26;21"
|
||||
dur="1.0s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</line>
|
||||
<line x1="23" y1="8" x2="23" y2="24">
|
||||
<animate attributeName="y1" values="8;13;8" dur="1.6s" repeatCount="indefinite" />
|
||||
<animate attributeName="y2" values="24;19;24" dur="1.6s" repeatCount="indefinite" />
|
||||
<animate
|
||||
attributeName="y1"
|
||||
values="8;13;8"
|
||||
dur="1.6s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
<animate
|
||||
attributeName="y2"
|
||||
values="24;19;24"
|
||||
dur="1.6s"
|
||||
repeatCount="indefinite"
|
||||
/>
|
||||
</line>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
Reference in New Issue
Block a user