ui(tokens): replace arbitrary max-h/h viewport values with layout tokens

Migrate all max-h-[XXvh] and h-[XXvh] to design system tokens:
- max-h-[85vh] → max-h-layout-modal (9 modals)
- max-h-[80vh] → max-h-layout-modal-sm (4 modals + notification bell)
- max-h-[70vh] → max-h-layout-modal-xs (AddToPlaylistModal)
- max-h-[90vh] → max-h-layout-modal-lg (CreatorModal)
- max-h-[400px] → max-h-layout-list (QueuePanel, OfflineQueueManager)
- max-h-[500px] → max-h-layout-drawer (APIPlaygroundView)
- h-[60vh] → h-layout-lyrics (FullPlayer, TrackDetailPageHero/Skeleton)
- max-w-[400px] → max-w-lg (FullPlayer)

Zero arbitrary viewport heights remain in modals and panels.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
senke 2026-02-08 22:47:41 +01:00
parent dc88ea6805
commit 1f4b731e38
15 changed files with 17 additions and 17 deletions

View file

@ -147,7 +147,7 @@ export function OfflineQueueManager({
<p className="text-sm">All requests have been processed</p>
</div>
) : (
<div className="space-y-2 max-h-[400px] overflow-y-auto custom-scrollbar">
<div className="space-y-2 max-h-layout-list overflow-y-auto custom-scrollbar">
{queue.map((request) => (
<div
key={request.id}

View file

@ -132,7 +132,7 @@ export const APIPlaygroundView: React.FC = () => {
<div className="flex-1 bg-black/30 rounded border border-kodo-steel/50 p-4 relative group">
{response ? (
<>
<pre className="text-xs text-kodo-lime font-mono whitespace-pre-wrap overflow-auto h-full max-h-[500px]">
<pre className="text-xs text-kodo-lime font-mono whitespace-pre-wrap overflow-auto h-full max-h-layout-drawer">
{response}
</pre>
<button

View file

@ -96,7 +96,7 @@ export const CreateAPIKeyModal: React.FC<CreateAPIKeyModalProps> = ({
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-md"
onClick={step === 1 ? onClose : undefined}
></div>
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden glass-hud flex flex-col max-h-[85vh]">
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden glass-hud flex flex-col max-h-layout-modal">
{/* Header - Fixed */}
<div className="p-6 border-b border-kodo-steel/50 flex justify-between items-center bg-white/5 flex-none z-10">
<h3 className="text-xl font-bold text-white flex items-center gap-3 font-display">
@ -248,7 +248,7 @@ export const CreateAPIKeyModal: React.FC<CreateAPIKeyModalProps> = ({
) : (
<Button
onClick={onClose}
className="bg-kodo-cyan hover:bg-kodo-cyan/80 text-black font-semibold min-w-[100px] shadow-button-primary-glow hover:shadow-button-primary-glow-hover transition-all duration-[var(--duration-normal)]"
className="bg-kodo-cyan hover:bg-kodo-cyan/80 text-black font-semibold min-w-24 shadow-button-primary-glow hover:shadow-button-primary-glow-hover transition-all duration-[var(--duration-normal)]"
>
Done
</Button>

View file

@ -104,7 +104,7 @@ export const QuizModal: React.FC<QuizModalProps> = ({
return (
<div className="fixed inset-0 z-[100] flex items-center justify-center p-4">
<div className="absolute inset-0 bg-kodo-void/90 backdrop-blur-sm"></div>
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-[80vh]">
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal-sm">
{/* Header */}
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
<h3 className="font-bold text-white flex items-center gap-2">

View file

@ -75,7 +75,7 @@ export const AddToPlaylistModal: React.FC<AddToPlaylistModalProps> = ({
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-md bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-[70vh]">
<div className="relative w-full max-w-md bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal-xs">
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
<h3 className="font-bold text-white">Add to Playlist</h3>
<button onClick={onClose}>

View file

@ -20,7 +20,7 @@ export const LicenceDetailsModal: React.FC<LicenceDetailsModalProps> = ({
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-lg bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-[80vh]">
<div className="relative w-full max-w-lg bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal-sm">
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
<h3 className="font-bold text-white flex items-center gap-2">
<ShieldCheck className="w-5 h-5 text-kodo-steel" /> License Agreement

View file

@ -35,7 +35,7 @@ export const CreatorModal: React.FC<CreatorModalProps> = ({
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-4xl bg-kodo-graphite border border-kodo-steel rounded-2xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-[90vh]">
<div className="relative w-full max-w-4xl bg-kodo-graphite border border-kodo-steel rounded-2xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal-lg">
{/* Header */}
<div className="flex justify-between items-center p-8 border-b border-kodo-steel bg-kodo-ink">
<div className="flex items-center gap-4">

View file

@ -50,7 +50,7 @@ export const NotificationBell: React.FC<NotificationBellProps> = ({
</Button>
{isOpen && (
<div className="absolute top-full right-0 mt-4 w-96 bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl overflow-hidden animate-fadeIn origin-top-right ring-1 ring-white/5 flex flex-col max-h-[80vh]">
<div className="absolute top-full right-0 mt-4 w-96 bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl overflow-hidden animate-fadeIn origin-top-right ring-1 ring-white/5 flex flex-col max-h-layout-modal-sm">
<div className="p-4 border-b border-kodo-steel/50 flex justify-between items-center bg-kodo-ink">
<div>
<h3 className="font-bold text-white">Notifications</h3>

View file

@ -71,7 +71,7 @@ export const FullPlayer: React.FC<FullPlayerProps> = ({ onClose }) => {
className={`flex flex-col items-center md:items-start text-center md:text-left transition-all duration-[var(--duration-slow)] ${showLyrics ? 'md:w-1/3' : 'md:w-1/2'}`}
>
<div
className="aspect-square w-full max-w-[400px] rounded-2xl overflow-hidden shadow-2xl mb-8 border border-white/10 relative group cursor-pointer"
className="aspect-square w-full max-w-lg rounded-2xl overflow-hidden shadow-2xl mb-8 border border-white/10 relative group cursor-pointer"
onClick={() => setShowLyrics(!showLyrics)}
>
<img
@ -101,7 +101,7 @@ export const FullPlayer: React.FC<FullPlayerProps> = ({ onClose }) => {
{/* Right: Lyrics View */}
{showLyrics && (
<div className="flex-1 h-[60vh] w-full md:w-auto animate-slideInRight">
<div className="flex-1 h-layout-lyrics w-full md:w-auto animate-slideInRight">
<LyricsPanel />
</div>
)}

View file

@ -12,7 +12,7 @@ export function QueuePanel({ onClose }: QueuePanelProps) {
usePlayerStore();
return (
<div className="fixed bottom-16 right-4 w-96 bg-background border border-border rounded-lg shadow-lg z-40 max-h-[400px] flex flex-col">
<div className="fixed bottom-16 right-4 w-96 bg-background border border-border rounded-lg shadow-lg z-40 max-h-layout-list flex flex-col">
<div className="p-4 border-b border-border flex items-center justify-between">
<h3 className="font-semibold">Queue</h3>
<Button variant="ghost" size="icon" onClick={onClose}>

View file

@ -41,7 +41,7 @@ export const FlashSaleModal: React.FC<FlashSaleModalProps> = ({
className="absolute inset-0 bg-kodo-void/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-[85vh]">
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal">
<div className="p-4 border-b border-kodo-steel bg-kodo-ink flex justify-between items-center">
<h3 className="font-bold text-white flex items-center gap-2">
<Zap className="w-5 h-5 text-kodo-gold" /> Start Flash Sale

View file

@ -31,7 +31,7 @@ export const BulkUploadModal: React.FC<BulkUploadModalProps> = ({
className="absolute inset-0 bg-background/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-3xl bg-card border border-border rounded-2xl shadow-2xl overflow-hidden flex flex-col max-h-[80vh] animate-scaleIn">
<div className="relative w-full max-w-3xl bg-card border border-border rounded-2xl shadow-2xl overflow-hidden flex flex-col max-h-layout-modal-sm animate-scaleIn">
{/* Header */}
<div className="p-8 border-b border-border bg-muted flex justify-between items-center">
<div>

View file

@ -39,7 +39,7 @@ export const LyricsEditorModal: React.FC<LyricsEditorModalProps> = ({
className="absolute inset-0 bg-background/90 backdrop-blur-sm"
onClick={onClose}
></div>
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-[85vh]">
<div className="relative w-full max-w-2xl bg-kodo-graphite border border-kodo-steel rounded-xl shadow-2xl animate-scaleIn overflow-hidden flex flex-col max-h-layout-modal">
<div className="p-4 border-b border-border bg-muted flex justify-between items-center">
<h3 className="font-bold text-white flex items-center gap-2">
<Mic2 className="w-4 h-4 text-kodo-steel" /> Lyrics Editor

View file

@ -7,7 +7,7 @@ interface TrackDetailPageHeroProps {
export function TrackDetailPageHero({ track }: TrackDetailPageHeroProps) {
const coverUrl = (track as { cover_art_path?: string }).cover_art_path;
return (
<div className="absolute inset-0 h-[60vh] overflow-hidden pointer-events-none">
<div className="absolute inset-0 h-layout-lyrics overflow-hidden pointer-events-none">
<div
className="absolute inset-x-0 -top-40 h-[150%] opacity-20 blur-[120px] scale-110"
style={{

View file

@ -3,7 +3,7 @@ import { Card } from '@/components/ui/card';
export function TrackDetailPageSkeleton() {
return (
<div className="min-h-layout-page pb-24 relative overflow-hidden bg-background transition-opacity duration-[var(--duration-normal)]">
<div className="absolute inset-0 h-[60vh] bg-muted/30 pointer-events-none" />
<div className="absolute inset-0 h-layout-lyrics bg-muted/30 pointer-events-none" />
<div className="container mx-auto px-4 relative z-10 pt-8">
<div className="h-10 w-24 bg-muted animate-pulse rounded-full mb-8" />
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12 items-start">