polish: deep visual pass across all homepage sections
All checks were successful
Build & Push / build-and-push (push) Successful in 1m26s

Hero:
- Removed fake trust proof avatars
- Added decorative gradient separator line
- Pushed content down for better vertical rhythm
- More visible secondary CTA button

TrustBar:
- Icon circles with primary tint backdrops
- Gradient top accent bar on hover
- Gradient fade transition from hero section
- Increased card padding

Services:
- Subtle grid texture background
- Larger primary-colored feature dots
- Enhanced AI narrative with horizontal decorative rules
- Hover shadow elevation on pillars

Configurator:
- Step numbers in tinted circles with vertical rail
- ShieldCheck trust icon
- Radial gradient glow on wizard panel
- Sparkles icon on AI toggle
- Empty-state hint message
- Service card icons in circular primary backdrops

Process:
- Gradient top accent strips on cards
- Icon containers with primary tint
- Vertical accent bar on section heading
- Dashed SVG connector lines between cards

SelectedWorks:
- Distinct geometric compositions per card (Monaco, Nimara, Amador)
- Bottom gradient fade on placeholder images
- Dot separators between tags
- Animated background pulse on coming-soon cards
- Enhanced CTA hover animations

Philosophy:
- Enriched decorative panel (circle rings, diagonal lines, navy gradient)
- Primary-colored pillar numbers
- Left border accent on pull-quote card

CTABanner:
- Grid pattern + circle ring overlays
- Email link underline-on-hover animation

Footer:
- Full logo image replacing text wordmark
- Larger social icons
- Gradient divider line
- Larger nav logo (h-14 desktop, h-11 mobile)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 21:11:30 +01:00
parent a6882d517a
commit 7ca9f6f5e2
11 changed files with 644 additions and 212 deletions

View File

@@ -92,97 +92,278 @@ const comingSoonVariants = {
function GeometricPlaceholder({
variant = 'featured',
cardVariant = 'default',
className,
}: {
variant?: 'featured' | 'small';
cardVariant?: 'default' | 'nimara' | 'amador';
className?: string;
}) {
const isFeatured = variant === 'featured';
// Different gradient bases per card so secondary cards look distinct
const gradientMap = {
default: 'from-primary-dark/90 to-primary/70',
nimara: 'from-navy/95 to-primary-dark/75',
amador: 'from-[#1a3a4a]/95 to-primary/60',
};
return (
<div
className={cn(
'relative overflow-hidden bg-gradient-to-br from-primary-dark/90 to-primary/70',
'relative overflow-hidden bg-gradient-to-br',
gradientMap[cardVariant],
className,
)}
aria-hidden="true"
>
{/* Abstract geometric shapes */}
<div className="absolute inset-0">
{/* Large circle top-right */}
<div
className="absolute rounded-full bg-white/[0.06]"
style={{
width: isFeatured ? '55%' : '70%',
height: isFeatured ? '55%' : '70%',
top: '-15%',
right: '-10%',
}}
/>
{/* Medium circle bottom-left */}
<div
className="absolute rounded-full bg-white/[0.08]"
style={{
width: isFeatured ? '40%' : '50%',
height: isFeatured ? '40%' : '50%',
bottom: '-20%',
left: '-5%',
}}
/>
{/* Diagonal stripes overlay */}
<div
className="absolute inset-0 opacity-[0.04]"
style={{
backgroundImage:
'repeating-linear-gradient(-45deg, #fff 0, #fff 1px, transparent 0, transparent 50%)',
backgroundSize: isFeatured ? '28px 28px' : '20px 20px',
}}
/>
{/* Small accent rectangle */}
<div
className="absolute bg-white/[0.12] rounded-sm"
style={{
width: isFeatured ? '18%' : '24%',
height: isFeatured ? '28%' : '36%',
bottom: '18%',
right: '15%',
transform: 'rotate(-6deg)',
}}
/>
{/* Thin horizontal line accent */}
<div
className="absolute bg-white/20 rounded-full"
style={{
width: isFeatured ? '30%' : '40%',
height: '1px',
top: '38%',
left: '10%',
}}
/>
{/* Grid-dot accent */}
<div
className="absolute opacity-[0.07]"
style={{
width: isFeatured ? '25%' : '30%',
height: isFeatured ? '25%' : '30%',
top: '50%',
right: '22%',
backgroundImage: 'radial-gradient(circle, #fff 1px, transparent 1px)',
backgroundSize: '8px 8px',
}}
/>
{isFeatured ? (
/* ── Featured (Monaco): blueprint feel ── */
<>
{/* Large filled circle top-right */}
<div
className="absolute rounded-full bg-white/[0.06]"
style={{ width: '55%', height: '55%', top: '-15%', right: '-10%' }}
/>
{/* Large circle ring — blueprint layer */}
<div
className="absolute rounded-full"
style={{
width: '45%',
height: '45%',
top: '10%',
left: '5%',
border: '1px solid rgba(255,255,255,0.12)',
opacity: 0.4,
}}
/>
{/* Medium circle bottom-left */}
<div
className="absolute rounded-full bg-white/[0.08]"
style={{ width: '40%', height: '40%', bottom: '-20%', left: '-5%' }}
/>
{/* Subtle grid overlay (blueprint feel) */}
<div
className="absolute inset-0 opacity-[0.035]"
style={{
backgroundImage:
'linear-gradient(rgba(255,255,255,1) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,1) 1px, transparent 1px)',
backgroundSize: '32px 32px',
}}
/>
{/* Diagonal stripes very subtle */}
<div
className="absolute inset-0 opacity-[0.025]"
style={{
backgroundImage:
'repeating-linear-gradient(-45deg, #fff 0, #fff 1px, transparent 0, transparent 50%)',
backgroundSize: '28px 28px',
}}
/>
{/* Small dot cluster */}
<div
className="absolute opacity-[0.12]"
style={{
width: '20%',
height: '20%',
top: '55%',
right: '18%',
backgroundImage: 'radial-gradient(circle, #fff 1.5px, transparent 1.5px)',
backgroundSize: '8px 8px',
}}
/>
{/* Blueprint horizontal line — wide, white/20 */}
<div
className="absolute bg-white/[0.22] rounded-full"
style={{ width: '60%', height: '1px', top: '50%', left: '5%' }}
/>
{/* Second thinner line below */}
<div
className="absolute bg-white/[0.10] rounded-full"
style={{ width: '40%', height: '1px', top: 'calc(50% + 10px)', left: '5%' }}
/>
{/* Accent rotated rectangle */}
<div
className="absolute bg-white/[0.10] rounded-sm"
style={{
width: '18%',
height: '28%',
bottom: '18%',
right: '15%',
transform: 'rotate(-6deg)',
}}
/>
{/* Small diagonal accent line */}
<div
className="absolute bg-white/[0.15]"
style={{
width: '25%',
height: '1px',
top: '28%',
right: '8%',
transform: 'rotate(-30deg)',
transformOrigin: 'left center',
}}
/>
</>
) : cardVariant === 'nimara' ? (
/* ── Port Nimara: horizontal bands + arc ── */
<>
{/* Large arc ring top-left */}
<div
className="absolute rounded-full"
style={{
width: '80%',
height: '80%',
top: '-30%',
left: '-20%',
border: '1px solid rgba(255,255,255,0.10)',
opacity: 0.5,
}}
/>
{/* Smaller ring center */}
<div
className="absolute rounded-full"
style={{
width: '45%',
height: '70%',
bottom: '-15%',
right: '-10%',
border: '1px solid rgba(91,164,217,0.25)',
}}
/>
{/* Horizontal rule band */}
<div
className="absolute bg-white/[0.06]"
style={{ height: '28%', bottom: 0, left: 0, right: 0 }}
/>
{/* Fine horizontal lines */}
<div
className="absolute bg-white/20 rounded-full"
style={{ width: '50%', height: '1px', top: '35%', right: '8%' }}
/>
<div
className="absolute bg-white/10 rounded-full"
style={{ width: '30%', height: '1px', top: '45%', right: '8%' }}
/>
{/* Dot cluster top-right */}
<div
className="absolute opacity-[0.14]"
style={{
width: '25%',
height: '30%',
top: '5%',
right: '5%',
backgroundImage: 'radial-gradient(circle, #fff 1.5px, transparent 1.5px)',
backgroundSize: '8px 8px',
}}
/>
{/* Diagonal line */}
<div
className="absolute bg-white/[0.12]"
style={{
width: '40%',
height: '1px',
top: '60%',
left: '5%',
transform: 'rotate(-20deg)',
transformOrigin: 'left center',
}}
/>
</>
) : (
/* ── Port Amador: triangular/radial composition ── */
<>
{/* Central radial glow */}
<div
className="absolute"
style={{
width: '70%',
height: '70%',
top: '-10%',
right: '-15%',
background:
'radial-gradient(circle, rgba(91,164,217,0.18) 0%, transparent 70%)',
}}
/>
{/* Diamond/rotated square accent */}
<div
className="absolute"
style={{
width: '30%',
height: '50%',
bottom: '-10%',
left: '10%',
border: '1px solid rgba(255,255,255,0.12)',
transform: 'rotate(45deg)',
}}
/>
{/* Diagonal stripes (different angle) */}
<div
className="absolute inset-0 opacity-[0.03]"
style={{
backgroundImage:
'repeating-linear-gradient(30deg, #fff 0, #fff 1px, transparent 0, transparent 50%)',
backgroundSize: '20px 20px',
}}
/>
{/* Top horizontal line */}
<div
className="absolute bg-white/20 rounded-full"
style={{ width: '40%', height: '1px', top: '22%', left: '8%' }}
/>
{/* Small filled rectangle */}
<div
className="absolute bg-white/[0.12] rounded-sm"
style={{
width: '20%',
height: '32%',
top: '15%',
right: '12%',
transform: 'rotate(8deg)',
}}
/>
{/* Dot accent bottom-right */}
<div
className="absolute opacity-[0.16]"
style={{
width: '22%',
height: '22%',
bottom: '8%',
right: '8%',
backgroundImage: 'radial-gradient(circle, #fff 1.5px, transparent 1.5px)',
backgroundSize: '7px 7px',
}}
/>
</>
)}
</div>
{/* Bottom gradient fade */}
<div className="absolute inset-x-0 bottom-0 h-1/3 bg-gradient-to-t from-primary-dark/50 to-transparent" />
{/* Bottom gradient fade — card bg color bleed for text readability */}
<div
className="absolute inset-x-0 bottom-0 h-2/5"
style={{
background: isFeatured
? 'linear-gradient(to top, rgba(0,100,148,0.55) 0%, transparent 100%)'
: cardVariant === 'nimara'
? 'linear-gradient(to top, rgba(28,43,58,0.60) 0%, transparent 100%)'
: 'linear-gradient(to top, rgba(26,58,74,0.55) 0%, transparent 100%)',
}}
/>
</div>
);
}
// ─── Tag Chip ─────────────────────────────────────────────────────────────────
function TagChip({ label }: { label: string }) {
function TagChip({ label, showDot = false }: { label: string; showDot?: boolean }) {
return (
<span className="inline-flex items-center bg-primary/10 text-primary-dark text-xs font-medium px-2.5 py-1 rounded-full leading-none">
<span className="inline-flex items-center gap-1.5 bg-primary/10 text-primary-dark text-[0.75rem] font-semibold px-3 py-1 rounded-full leading-none tracking-wide">
{showDot && (
<span className="w-1 h-1 rounded-full bg-primary/50 shrink-0" aria-hidden="true" />
)}
{label}
</span>
);
@@ -203,6 +384,7 @@ function FeaturedCard({ project, readLabel }: { project: Project; readLabel: str
{/* Geometric image placeholder */}
<GeometricPlaceholder
variant="featured"
cardVariant="default"
className="w-full aspect-[16/9] md:aspect-[2/1]"
/>
@@ -210,8 +392,8 @@ function FeaturedCard({ project, readLabel }: { project: Project; readLabel: str
<div className="flex flex-col flex-1 p-7 gap-4">
{/* Tags */}
<div className="flex flex-wrap gap-2">
{project.tags.map((tag) => (
<TagChip key={tag} label={tag} />
{project.tags.map((tag, i) => (
<TagChip key={tag} label={tag} showDot={i > 0} />
))}
</div>
@@ -230,16 +412,15 @@ function FeaturedCard({ project, readLabel }: { project: Project; readLabel: str
href={`/work/${project.slug}`}
className={cn(
'inline-flex items-center gap-2 text-sm font-medium text-primary-dark',
'transition-gap duration-200 group/link',
'mt-1',
'mt-1 group/link',
)}
>
<span className="underline underline-offset-4 decoration-primary/40 group-hover/link:decoration-primary-dark transition-colors duration-200">
<span className="relative after:absolute after:bottom-0 after:left-0 after:h-px after:w-full after:bg-primary-dark after:origin-left after:scale-x-100 after:transition-transform after:duration-200">
{readLabel}
</span>
<ArrowRight
size={14}
className="transition-transform duration-200 group-hover/link:translate-x-1"
size={15}
className="transition-transform duration-200 group-hover/link:translate-x-1.5"
/>
</Link>
</div>
@@ -249,7 +430,14 @@ function FeaturedCard({ project, readLabel }: { project: Project; readLabel: str
// ─── Small Card ───────────────────────────────────────────────────────────────
const SLUG_TO_VARIANT: Record<string, 'nimara' | 'amador'> = {
'port-nimara': 'nimara',
'port-amador': 'amador',
};
function SmallCard({ project, readLabel }: { project: Project; readLabel: string }) {
const cardVariant = SLUG_TO_VARIANT[project.slug] ?? 'nimara';
return (
<motion.article
variants={smallCardVariants}
@@ -271,6 +459,7 @@ function SmallCard({ project, readLabel }: { project: Project; readLabel: string
>
<GeometricPlaceholder
variant="small"
cardVariant={cardVariant}
className="w-full aspect-[16/7]"
/>
</div>
@@ -280,8 +469,8 @@ function SmallCard({ project, readLabel }: { project: Project; readLabel: string
<div className="flex flex-col flex-1 p-5 gap-3">
{/* Tags */}
<div className="flex flex-wrap gap-1.5">
{project.tags.map((tag) => (
<TagChip key={tag} label={tag} />
{project.tags.map((tag, i) => (
<TagChip key={tag} label={tag} showDot={i > 0} />
))}
</div>
@@ -300,12 +489,12 @@ function SmallCard({ project, readLabel }: { project: Project; readLabel: string
href={`/work/${project.slug}`}
className="inline-flex items-center gap-1.5 text-xs font-medium text-primary-dark group/link"
>
<span className="underline underline-offset-4 decoration-primary/40 group-hover/link:decoration-primary-dark transition-colors duration-200">
<span className="relative after:absolute after:bottom-0 after:left-0 after:h-px after:w-full after:bg-primary-dark after:origin-left after:scale-x-100 after:transition-transform after:duration-200">
{readLabel}
</span>
<ArrowRight
size={12}
className="transition-transform duration-200 group-hover/link:translate-x-0.5"
size={13}
className="transition-transform duration-200 group-hover/link:translate-x-1"
/>
</Link>
</div>
@@ -368,14 +557,21 @@ export default function SelectedWorks() {
0% { background-position: 0 0, 100% 0, 100% 100%, 0 100%; }
100% { background-position: 100% 0, 100% 100%, 0 100%, 0 0; }
}
@keyframes coming-soon-bg-pulse {
0%, 100% { background-color: var(--color-surface-low); }
50% { background-color: var(--color-surface); }
}
@keyframes coming-soon-fade {
0%, 100% { opacity: 0; }
50% { opacity: 1; }
}
.coming-soon-card {
animation: coming-soon-bg-pulse 4s ease-in-out infinite;
}
.coming-soon-pulse {
background: radial-gradient(
ellipse at center,
rgba(91, 164, 217, 0.04) 0%,
rgba(91, 164, 217, 0.06) 0%,
transparent 70%
);
animation: coming-soon-fade 4s ease-in-out infinite;