Files
video-downloader/docs/superpowers/specs/2026-08-10-minimalist-ui-design.md
anthonyandClaude Sonnet 4.6 83a67928da docs: add minimalist UI design spec
Covers Tailwind CSS setup, dark mode via next-themes, flag image language
switcher, SEO metadata + JSON-LD, and full layout for home and status pages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-10 15:48:33 +02:00

7.0 KiB

Ombrora -- Refonte UI minimaliste

Date : 2026-08-10 Statut : Approuve

Contexte

L'application est fonctionnelle mais entierement non stylee (inline styles uniquement). Objectifs : interface minimaliste, SEO-optimisee, light/dark mode, language switcher avec drapeaux images.

Stack technique ajoutee

Package Role Compatibilite o2switch
tailwindcss + @tailwindcss/postcss Styles utility-first, compile en CSS statique OK (build-time)
next-themes Dark/light mode via class sur <html> OK (pure JS)
Flag SVGs locaux dans /public/flags/ Drapeaux langue OK (assets statiques)

Aucun package avec bindings natifs.

Fichiers touches

Nouveaux

  • tailwind.config.ts
  • src/app/globals.css
  • src/components/Header.tsx
  • src/components/ThemeToggle.tsx
  • src/components/ReassuranceSection.tsx
  • public/flags/en.svg
  • public/flags/fr.svg
  • public/flags/es.svg
  • public/flags/it.svg

Modifies

  • src/app/[locale]/layout.tsx -- ThemeProvider, Inter font, JSON-LD, metadata complete
  • src/app/[locale]/page.tsx -- hero + form + reassurance
  • src/app/[locale]/status/[uuid]/page.tsx -- layout status restylee
  • src/components/SubmitForm.tsx -- Tailwind, UI refaite
  • src/components/StatusView.tsx -- Tailwind, UI refaite
  • src/components/LanguageSwitcher.tsx -- <img> drapeaux SVG
  • messages/en.json, fr.json, es.json, it.json -- cles SEO + reassurance

Design

Palette

Light : bg-white / text-gray-900 / accent violet-600
Dark  : bg-slate-950 / text-gray-50 / accent violet-400
Input : border-gray-200 / dark:border-slate-700
Card  : bg-gray-50 / dark:bg-slate-900

Tailwind strategy : darkMode: 'class' dans tailwind.config.ts.

Typographie

next/font/google avec Inter (subsets latin, latin-ext). Latin-ext couvre les accents FR/ES/IT. Preload automatique par Next.js, zero CDN runtime.

Layout -- Page home

<header>  Logo | ThemeToggle | LanguageSwitcher  </header>

<main>
  <section> <!-- hero -->
    <h1>Telechargez vos videos gratuitement</h1>
    <p>Sous-titre</p>

    <!-- glow violet radial derriere l'input -->
    <SubmitForm />   <!-- URL + bouton inline, options compactes dessous -->
  </section>

  <section> <!-- reassurance -->
    <ReassuranceSection />  <!-- 4 cards -->
  </section>
</main>

<footer>  Copyright Ombrora  </footer>

Layout -- Page status

<header>  (identique)  </header>

<main>
  <section>
    <h1>Statut du telechargement</h1>
    <StatusView />   <!-- card centree -->
  </section>
</main>

Composant SubmitForm

  • Input URL : pleine largeur, rounded-xl, bouton violet inline a droite (rounded-r-xl)
  • Glow : div absolue violet blur-3xl opacity-15 positionnee derriere l'input, visible en both modes
  • Options : ligne flex sous l'input -- Format (select), Qualite (select), Sous-titres (checkbox styled), Options avancees (collapse/details)
  • Bouton submit : bg-violet-600 hover:bg-violet-700 dark:bg-violet-500 + spinner animate-spin quand loading
  • Erreur : texte rouge sous les options

Composant StatusView

  • Card max-w-md mx-auto rounded-2xl border bg-gray-50 dark:bg-slate-900 p-6
  • PENDING/PROCESSING : spinner animate-spin violet + texte statut
  • DONE : bouton telechargement violet, nom fichier, taille, expiration en text-sm text-gray-500
  • FAILED : bloc bg-red-50 dark:bg-red-950 border-red-200 avec <pre> pour le message d'erreur
  • FILE_DELETED : message informatif gris

Composant Header

  • <header class="sticky top-0 z-50 border-b bg-white/80 dark:bg-slate-950/80 backdrop-blur">
  • Logo : "Ombrora" texte, "O" en text-violet-600
  • Droite : ThemeToggle + LanguageSwitcher
  • Padding px-6 py-3, flex justify-between

Composant ThemeToggle

  • Bouton icon-only, SVG lune (dark) ou soleil (light) inline
  • Pas de librairie d'icones -- SVG paths hardcodes (moon : M 12 3 a 6 6 0 0 0 9 9 ..., sun : rayons simples)
  • aria-label="Basculer le theme"

Composant LanguageSwitcher

  • Flex row, gap-2
  • Chaque locale : <button> avec <img src="/flags/{loc}.svg" alt="{nom_langue}" width="28" height="20" />
  • Actif : opacity-100 ring-2 ring-violet-500 rounded-sm
  • Inactif : opacity-40 hover:opacity-70
  • SVG sources : telecharger depuis https://flagcdn.com/w40/{code}.png equivalents SVG ou utiliser flag-icons open-source (MIT)

Composant ReassuranceSection

4 cards en grille grid grid-cols-2 md:grid-cols-4 gap-4 :

Icone SVG Titre Sous-titre
Cadeau Gratuit Sans compte, sans inscription
Eclair Rapide Pret en quelques secondes
Verrou Prive Aucune donnee conservee
Film Multi-format mp4, mp3, webm, mkv -- jusqu'en 1080p

Chaque card : rounded-xl border p-4 bg-gray-50 dark:bg-slate-900 text-center.

SEO

Metadata (par locale, dans generateMetadata du layout)

{
  title: t('meta.title'),            // "Ombrora -- Telechargeur de videos gratuit"
  description: t('meta.description'), // ~155 chars, locale-specific
  robots: { index: true, follow: true },
  openGraph: {
    title, description,
    url: `${process.env.NEXT_PUBLIC_BASE_URL}/${locale}`,
    siteName: 'Ombrora',
    locale,
  },
  alternates: {
    canonical: `${process.env.NEXT_PUBLIC_BASE_URL}/${locale}`,
    languages: { en: '/en', fr: '/fr', es: '/es', it: '/it' },
  },
}

HTML semantique

  • <html lang={locale}> : deja en place
  • <header>, <main>, <section aria-labelledby="hero-heading">, <footer>
  • <h1> unique par page (traduit)
  • <h2> pour titres reassurance
  • <h1> sur status page : "Statut du telechargement"

JSON-LD (WebApplication)

Injecte dans <head> via <script type="application/ld+json"> dans le layout :

{
  "@context": "https://schema.org",
  "@type": "WebApplication",
  "name": "Ombrora",
  "url": "${process.env.NEXT_PUBLIC_BASE_URL}",
  "description": "Telechargeur de videos gratuit, rapide et prive.",
  "applicationCategory": "MultimediaApplication",
  "operatingSystem": "Web",
  "offers": {
    "@type": "Offer",
    "price": "0",
    "priceCurrency": "EUR"
  }
}

Traductions -- nouvelles cles

A ajouter dans chaque messages/*.json :

"meta": {
  "title": "Ombrora -- Telechargeur de videos gratuit",
  "description": "Telechargez vos videos YouTube, Vimeo et plus en mp4, mp3, webm -- gratuit, rapide, sans compte."
},
"reassurance": {
  "free": "Gratuit",
  "freeDesc": "Sans compte, sans inscription",
  "fast": "Rapide",
  "fastDesc": "Pret en quelques secondes",
  "private": "Prive",
  "privateDesc": "Aucune donnee conservee",
  "formats": "Multi-format",
  "formatsDesc": "mp4, mp3, webm, mkv -- jusqu'en 1080p"
},
"footer": {
  "copyright": "© 2026 Ombrora"
}

Contraintes

  • Pas de CSS framework avec runtime JS (Tailwind compile en statique)
  • Pas de librairie d'icones externe -- SVG inline pour ThemeToggle, SVG fichiers pour drapeaux
  • Flag SVGs stockes dans /public/flags/ (pas de CDN runtime)
  • next/font/google pour Inter (preload auto, pas de FOUT)
  • next-themes : ajouter suppressHydrationWarning sur <html> pour eviter hydration mismatch