feat(ui): hero card più viva + nav gerarchia + contrast banner
Tre rifiniture dopo la seconda iterazione visiva della dashboard:
1. **DashboardHero più presente**: gradient bicolore (oliva→oro) con opacità 0.32 invece di 0.18, bordo 2px invece di 1, mesh-blob più grande (h-72) e più denso (opacity-75). Aggiunta art `<PlateArt>` SVG in basso-dx con piatto stilizzato + macchie ingredienti (oliva/pomodoro/oro). Titolo cresce a 6xl su desktop. Aggiunta riga di metadata in alto ("7 giorni · 21 pasti") + caption sotto. La card adesso ha peso visivo proporzionale al fatto che è la CTA principale del logged-in.
2. **NavItem gerarchia**: chapter (II/III/IV…) ora è un elemento prominente in italic 2xl a sx (era un piccolo number monospace inline). Eyebrow + label centrali. Freccia 2xl a dx con translate-x al hover. Hover non inverte più i colori (era bg-ink+text-carta) — più semplice: il chapter, eyebrow e freccia diventano pomodoro, il bordo si fa più scuro. Più "app" e meno aggressivo.
3. **Banner trial più leggibile**: subtitle da `text-carta/70` a `text-carta/85`, eyebrow da `text-carta-light/60` a `text-carta-light/75`. Contrasto AA su fondo nero.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
0722abc070
commit
f7f6410559
1 file changed
+74
-32
@@ -739,7 +739,7 @@ function FinalCta() {
|
||||
|
||||
<div className="relative grid grid-cols-12 gap-8 pt-16 md:min-h-[60vh]">
|
||||
{/* Pull-quote in alto, indentata */}
|
||||
<p className="font-display text-carta/70 col-span-12 max-w-xl text-xl italic leading-snug md:col-span-6 md:col-start-2 md:text-2xl">
|
||||
<p className="font-display text-carta/85 col-span-12 max-w-xl text-xl italic leading-snug md:col-span-6 md:col-start-2 md:text-2xl">
|
||||
{t('ctaSectionBody')}
|
||||
</p>
|
||||
|
||||
@@ -887,38 +887,75 @@ function DashboardHero({
|
||||
accent === 'oliva' ? 'text-oliva' : accent === 'pomodoro' ? 'text-pomodoro' : 'text-oro';
|
||||
const tintGrad =
|
||||
accent === 'oliva'
|
||||
? 'linear-gradient(135deg, hsl(var(--oliva) / 0.18) 0%, hsl(var(--carta-light)) 70%)'
|
||||
? 'linear-gradient(135deg, hsl(var(--oliva) / 0.32) 0%, hsl(var(--oro) / 0.18) 50%, hsl(var(--carta-light)) 90%)'
|
||||
: accent === 'pomodoro'
|
||||
? 'linear-gradient(135deg, hsl(var(--pomodoro) / 0.18) 0%, hsl(var(--carta-light)) 70%)'
|
||||
: 'linear-gradient(135deg, hsl(var(--oro) / 0.18) 0%, hsl(var(--carta-light)) 70%)';
|
||||
? 'linear-gradient(135deg, hsl(var(--pomodoro) / 0.32) 0%, hsl(var(--oro) / 0.18) 50%, hsl(var(--carta-light)) 90%)'
|
||||
: 'linear-gradient(135deg, hsl(var(--oro) / 0.32) 0%, hsl(var(--pomodoro) / 0.15) 50%, hsl(var(--carta-light)) 90%)';
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className="hover-lift border-ink/15 group col-span-12 -rotate-[0.5deg] overflow-hidden border md:col-span-7"
|
||||
className="hover-lift border-ink/20 group col-span-12 -rotate-[0.5deg] overflow-hidden border-2 md:col-span-7"
|
||||
style={{ background: tintGrad }}
|
||||
>
|
||||
<div
|
||||
aria-hidden
|
||||
className={`mesh-blob mesh-blob--${accent} animate-float-z -right-16 -top-16 h-60 w-60 opacity-50`}
|
||||
className={`mesh-blob mesh-blob--${accent} animate-float-z -right-16 -top-16 h-72 w-72 opacity-75`}
|
||||
/>
|
||||
<article className="relative flex min-h-[18rem] flex-col justify-between p-8">
|
||||
<p className={`editorial-eyebrow ${accentClass}`}>{eyebrow}</p>
|
||||
<div>
|
||||
<h2 className="font-display text-ink text-4xl font-medium leading-[1.05] tracking-tight sm:text-5xl">
|
||||
{title}
|
||||
</h2>
|
||||
<p
|
||||
aria-hidden
|
||||
className={`font-display mt-6 text-3xl italic leading-none ${accentClass} transition-transform duration-500 group-hover:translate-x-2`}
|
||||
>
|
||||
→
|
||||
<PlateArt accent={accent} />
|
||||
<article className="relative flex min-h-[20rem] flex-col justify-between p-8 sm:p-10">
|
||||
<div className="flex items-baseline justify-between gap-4">
|
||||
<p className={`editorial-eyebrow ${accentClass}`}>{eyebrow}</p>
|
||||
<p className="text-ink-dim font-mono text-[10px] uppercase tracking-[0.3em]">
|
||||
7 giorni · 21 pasti
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<h2 className="font-display text-ink text-4xl font-medium leading-[1.05] tracking-tight sm:text-5xl md:text-6xl">
|
||||
{title}
|
||||
<span className={accentClass}>.</span>
|
||||
</h2>
|
||||
<div className="mt-8 flex items-baseline justify-between gap-4">
|
||||
<p className="font-display text-ink-soft max-w-md text-base italic leading-snug">
|
||||
Il menu adattato al tuo BMR, alle tue esclusioni e ai tempi che hai in cucina.
|
||||
</p>
|
||||
<span
|
||||
aria-hidden
|
||||
className={`font-display text-3xl italic leading-none ${accentClass} transition-transform duration-500 group-hover:translate-x-3`}
|
||||
>
|
||||
→
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
/** Art decorativa "piatto stilizzato" per la card hero. Tre macchie di
|
||||
* colore che richiamano gli ingredienti, ruotate in modo asimmetrico. */
|
||||
function PlateArt({ accent }: { accent: 'oliva' | 'pomodoro' | 'oro' }) {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden
|
||||
viewBox="0 0 200 200"
|
||||
className="pointer-events-none absolute -bottom-8 -right-2 h-44 w-44 opacity-90 sm:h-56 sm:w-56"
|
||||
>
|
||||
<circle
|
||||
cx="100"
|
||||
cy="100"
|
||||
r="78"
|
||||
fill="hsl(var(--carta-light))"
|
||||
stroke={`hsl(var(--${accent}) / 0.45)`}
|
||||
strokeWidth="1.5"
|
||||
/>
|
||||
<circle cx="100" cy="100" r="65" fill="none" stroke="hsl(var(--ink) / 0.06)" />
|
||||
<ellipse cx="86" cy="92" rx="20" ry="14" fill="hsl(var(--oliva) / 0.85)" />
|
||||
<ellipse cx="118" cy="84" rx="14" ry="12" fill="hsl(var(--pomodoro) / 0.85)" />
|
||||
<ellipse cx="108" cy="118" rx="22" ry="9" fill="hsl(var(--oro) / 0.8)" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
function NavItem({
|
||||
href,
|
||||
label,
|
||||
@@ -934,22 +971,27 @@ function NavItem({
|
||||
<li>
|
||||
<Link
|
||||
href={href}
|
||||
className="border-ink/15 hover:bg-ink hover:text-carta-light group -mx-0 flex items-baseline justify-between gap-4 border-t py-4 transition-colors last:border-b hover:-mx-3 hover:px-3"
|
||||
className="border-ink/15 hover:border-ink group relative flex items-center gap-5 border-t py-5 transition-colors last:border-b"
|
||||
>
|
||||
<span className="flex items-baseline gap-4">
|
||||
{chapter ? (
|
||||
<span className="text-ink-dim group-hover:text-carta-light/60 font-mono text-xs">
|
||||
{chapter}
|
||||
</span>
|
||||
) : null}
|
||||
<span className="flex flex-col gap-1">
|
||||
<span className="editorial-eyebrow group-hover:text-carta-light/60">{eyebrow}</span>
|
||||
<span className="font-display text-xl leading-tight">{label}</span>
|
||||
{chapter ? (
|
||||
<span
|
||||
aria-hidden
|
||||
className="font-display text-ink-dim group-hover:text-pomodoro w-8 shrink-0 text-2xl italic leading-none transition-colors"
|
||||
>
|
||||
{chapter}
|
||||
</span>
|
||||
) : null}
|
||||
<span className="flex min-w-0 flex-1 flex-col gap-1">
|
||||
<span className="editorial-eyebrow text-ink-dim group-hover:text-pomodoro transition-colors">
|
||||
{eyebrow}
|
||||
</span>
|
||||
<span className="font-display text-ink text-xl leading-tight tracking-tight">
|
||||
{label}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
aria-hidden
|
||||
className="font-display text-ink-dim group-hover:text-carta-light text-xl"
|
||||
className="font-display text-ink-dim group-hover:text-pomodoro shrink-0 text-2xl leading-none transition-all duration-300 group-hover:translate-x-1"
|
||||
>
|
||||
→
|
||||
</span>
|
||||
@@ -978,13 +1020,13 @@ function TrialBanner({ billing }: { billing: BillingStatus | null }) {
|
||||
/>
|
||||
<div className="relative grid items-center gap-8 p-8 md:grid-cols-12 md:gap-12 md:p-12">
|
||||
<div className="md:col-span-7">
|
||||
<p className="editorial-eyebrow text-carta-light/60">{t('trialBannerTitle')}</p>
|
||||
<p className="editorial-eyebrow text-carta-light/75">{t('trialBannerTitle')}</p>
|
||||
<p className="font-display text-carta mt-3 text-4xl font-medium leading-[1.05] tracking-tight md:text-5xl">
|
||||
<span className="text-oro tabular-nums">{derived.trialDaysRemaining}</span>{' '}
|
||||
{derived.trialDaysRemaining === 1 ? 'giorno' : 'giorni'}
|
||||
<span className="text-pomodoro">.</span>
|
||||
</p>
|
||||
<p className="font-display text-carta/70 mt-3 max-w-md text-base italic leading-snug">
|
||||
<p className="font-display text-carta/85 mt-3 max-w-md text-base italic leading-snug">
|
||||
Tutto sbloccato fino al {endsAt}. Poi serve un abbonamento per generare nuovi piani.
|
||||
</p>
|
||||
</div>
|
||||
@@ -1011,12 +1053,12 @@ function TrialBanner({ billing }: { billing: BillingStatus | null }) {
|
||||
/>
|
||||
<div className="relative grid items-center gap-8 p-8 md:grid-cols-12 md:gap-12 md:p-12">
|
||||
<div className="md:col-span-7">
|
||||
<p className="editorial-eyebrow text-carta-light/60">{t('trialEndedBannerTitle')}</p>
|
||||
<p className="editorial-eyebrow text-carta-light/75">{t('trialEndedBannerTitle')}</p>
|
||||
<p className="font-display text-carta mt-3 text-4xl font-medium leading-[1.05] tracking-tight md:text-5xl">
|
||||
{t('trialEndedBannerTitle')}
|
||||
<span className="text-pomodoro">.</span>
|
||||
</p>
|
||||
<p className="font-display text-carta/70 mt-3 max-w-md text-base italic leading-snug">
|
||||
<p className="font-display text-carta/85 mt-3 max-w-md text-base italic leading-snug">
|
||||
{t('trialEndedBannerBody')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user