Refactor code structure for improved readability and maintainability; removed redundant code blocks and optimized function calls.
This commit is contained in:
@@ -19,14 +19,14 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
- Same shape as primary.
|
||||
|
||||
**Ghost**
|
||||
- `text-bone hover:text-gold-light` — no border, no fill.
|
||||
- `text-bone hover:text-gold-light` no border, no fill.
|
||||
|
||||
**Forbidden**
|
||||
- Bright red CTA buttons (unless brand color is red).
|
||||
- Square corners on action buttons.
|
||||
- Solid `#000` or `#fff` backgrounds.
|
||||
- Loading text inside button that breaks layout — use a spinner icon + word swap with fixed min-width.
|
||||
- Success/error message **inside** button — render outside as a banner.
|
||||
- Loading text inside button that breaks layout use a spinner icon + word swap with fixed min-width.
|
||||
- Success/error message **inside** button render outside as a banner.
|
||||
|
||||
---
|
||||
|
||||
@@ -82,7 +82,7 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
- Always `text-balance` on h2 for clean wrapping.
|
||||
- `text-pretty` on subtitle.
|
||||
- Use SectionLabel with sequential index per page (01, 02, 03…). No mono font.
|
||||
- One gold-accent phrase max per heading — overdoing gold cheapens it.
|
||||
- One gold-accent phrase max per heading overdoing gold cheapens it.
|
||||
|
||||
---
|
||||
|
||||
@@ -99,7 +99,7 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
|
||||
## Footer
|
||||
|
||||
**Layout — 4 columns, no duplication**
|
||||
**Layout 4 columns, no duplication**
|
||||
|
||||
| Column 1 | Column 2 | Column 3 | Column 4 |
|
||||
|---|---|---|---|
|
||||
@@ -109,7 +109,7 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
**Rules**
|
||||
- No page link appears in two columns.
|
||||
- Privacy Policy lives only under Legal.
|
||||
- App badges only in Legal & App column (footer) — official SVGs at 132 px width, 8 px gap.
|
||||
- App badges only in Legal & App column (footer) official SVGs at 132 px width, 8 px gap.
|
||||
- External links open in new tab with rel attrs.
|
||||
- Background: `bg-obsidian` with subtle "LUXAM"-style watermark behind content (translate-y-[18%], opacity 0.025).
|
||||
- Bottom row: `© YYYY {brand}. All rights reserved.` + tagline + agency credit (subtle, gold-underlined on hover).
|
||||
@@ -128,7 +128,7 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
focus:shadow-[0_0_0_3px_rgba(212,164,55,0.18)]
|
||||
aria-[invalid=true]:border-[#a3261c]/60
|
||||
```
|
||||
- Honeypot field: hidden `<input name="website">` — silently succeed if filled.
|
||||
- Honeypot field: hidden `<input name="website">` silently succeed if filled.
|
||||
- Validation: server-side via `submitContact()` action; client gets `state.fieldErrors` + `state.message`.
|
||||
- Submission states: `useActionState` + `useFormStatus`. Spinner inside button, success/error banner **outside** button.
|
||||
|
||||
@@ -142,9 +142,9 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
- Wrapper for emphasis: `glass-gold size-11 grid place-items-center rounded-full`.
|
||||
- **Forbidden**: oversized icons (>32 px) standalone, multi-color icon sets, cartoonish flat icons.
|
||||
|
||||
**No lucide WhatsApp glyph** — use custom inline SVG from `snippets/WhatsAppLink.tsx`.
|
||||
**No lucide WhatsApp glyph** use custom inline SVG from `snippets/WhatsAppLink.tsx`.
|
||||
|
||||
**No lucide Instagram glyph in v1.16** — use custom inline SVG (see footer).
|
||||
**No lucide Instagram glyph in v1.16** use custom inline SVG (see footer).
|
||||
|
||||
---
|
||||
|
||||
@@ -229,8 +229,8 @@ Per-element rules. Apply when designing or reviewing the corresponding component
|
||||
## Don't
|
||||
|
||||
- Don't add hover effects without `transition-*` for smoothness.
|
||||
- Don't use `transform-origin` defaults on rotated icon discs — keep them small (8-12°).
|
||||
- Don't use `whileHover={{ scale: 1.1 }}` on cards — too theatrical. Use `-translate-y-1` instead.
|
||||
- Don't use `transform-origin` defaults on rotated icon discs keep them small (8-12°).
|
||||
- Don't use `whileHover={{ scale: 1.1 }}` on cards too theatrical. Use `-translate-y-1` instead.
|
||||
- Don't add box-shadows with multiple layers and bright colors. One subtle amber glow max.
|
||||
- Don't introduce a new font family per page — stick to display + sans.
|
||||
- Don't introduce a new font family per page stick to display + sans.
|
||||
- Don't render placeholder images (`via.placeholder.com`, gray boxes) in production code. Always use real assets the user provided.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Component Snippets
|
||||
|
||||
Overview of the reusable TSX snippets in `snippets/`. Each is a copy-paste base for a new project — adapt brand tokens + content via your own `lib/content.ts`.
|
||||
Overview of the reusable TSX snippets in `snippets/`. Each is a copy-paste base for a new project adapt brand tokens + content via your own `lib/content.ts`.
|
||||
|
||||
| File | Purpose | Depends on |
|
||||
|---|---|---|
|
||||
@@ -18,7 +18,7 @@ Overview of the reusable TSX snippets in `snippets/`. Each is a copy-paste base
|
||||
1. Copy the file you need into your project's `src/components/` (or wherever your component layer lives).
|
||||
2. Update import paths (`@/lib/cn`, `@/components/ui/...`) to match your project alias.
|
||||
3. Wire data: the snippets accept props or read from a `lib/content.ts` you control.
|
||||
4. Confirm Tailwind v4 `@theme` tokens (`obsidian`, `gold`, `bone`, `mist`, etc.) exist — see `DESIGN_SYSTEM.md`.
|
||||
4. Confirm Tailwind v4 `@theme` tokens (`obsidian`, `gold`, `bone`, `mist`, etc.) exist see `DESIGN_SYSTEM.md`.
|
||||
5. Confirm Framer Motion + lucide-react installed:
|
||||
```bash
|
||||
npm i framer-motion lucide-react
|
||||
|
||||
@@ -8,7 +8,7 @@ Reusable design tokens + scales extracted from the Luxam reference build. Drop i
|
||||
|
||||
```css
|
||||
@theme {
|
||||
/* Backgrounds — obsidian → graphite layering */
|
||||
/* Backgrounds obsidian → graphite layering */
|
||||
--color-obsidian: #08080A; /* page background */
|
||||
--color-graphite: #15161A; /* dark glass card */
|
||||
--color-graphite-2: #1C1D22; /* slightly lifted card variant */
|
||||
@@ -17,7 +17,7 @@ Reusable design tokens + scales extracted from the Luxam reference build. Drop i
|
||||
--color-bone: #F4F0E6; /* primary text on dark */
|
||||
--color-mist: #C7C2B5; /* secondary/muted text */
|
||||
|
||||
/* Brand — gold spectrum (use sparingly + structurally) */
|
||||
/* Brand gold spectrum (use sparingly + structurally) */
|
||||
--color-gold: #D4A437; /* core brand gold */
|
||||
--color-gold-light: #F2C25B; /* hover, highlight, gradient stops */
|
||||
--color-gold-deep: #7A4A12; /* gradient base */
|
||||
@@ -178,14 +178,14 @@ Every card/button uses the same hover vocabulary:
|
||||
6. Optional: top hairline gold gradient fade-in.
|
||||
7. Icon disc gets `rotate-[8deg]` + amber halo shadow.
|
||||
|
||||
Apply via `group` + `group-hover:` Tailwind variants — never per-element JS listeners.
|
||||
Apply via `group` + `group-hover:` Tailwind variants never per-element JS listeners.
|
||||
|
||||
---
|
||||
|
||||
## Container widths
|
||||
|
||||
```tsx
|
||||
// components/ui/Container.tsx — three variants
|
||||
// components/ui/Container.tsx three variants
|
||||
size="default" → max-w-7xl
|
||||
size="wide" → max-w-[1480px]
|
||||
size="narrow" → max-w-3xl
|
||||
|
||||
@@ -43,7 +43,7 @@ Do NOT invent links. Ask if missing.
|
||||
Inspect {{PAGE_ROUTE}}. Keep the content + intent but rebuild it to match the design DNA in .claude/skills/premium-frontend-designer/.
|
||||
|
||||
Requirements:
|
||||
- Reuse existing primitives (Section, Container, Button, Reveal, SectionLabel, etc.) — don't duplicate.
|
||||
- Reuse existing primitives (Section, Container, Button, Reveal, SectionLabel, etc.) don't duplicate.
|
||||
- Apply the cardGrid + cardCell motion variants for grid entrances.
|
||||
- Add a single gold-accent phrase per h2.
|
||||
- Centralize section padding via the Section primitive (no per-page overrides).
|
||||
@@ -176,7 +176,7 @@ Walk through the responsive checklist in .claude/skills/premium-frontend-designe
|
||||
|
||||
Test at 320 / 375 / 390 / 414 / 768 / 1024 viewports.
|
||||
|
||||
Don't redesign — only fix layout, spacing, overflow, clipping. Preserve the visual identity.
|
||||
Don't redesign only fix layout, spacing, overflow, clipping. Preserve the visual identity.
|
||||
|
||||
Return a table of issues + fixes (Before / After columns).
|
||||
```
|
||||
@@ -194,7 +194,7 @@ Audit and refine typography across all pages:
|
||||
4. Tracking: reduce all tracking-[0.32em+] on small labels to tracking-[0.22em].
|
||||
5. Nav links: text-sm font-medium tracking-[0.005em] (slightly larger + medium weight, near-zero tracking).
|
||||
6. BrandStrip marquee: smaller (text-xs md:text-sm uppercase) so it doesn't compete with hero.
|
||||
7. Section labels via SectionLabel primitive — never inline.
|
||||
7. Section labels via SectionLabel primitive never inline.
|
||||
8. text-balance on h1/h2, text-pretty on body paragraphs.
|
||||
|
||||
Confirm:
|
||||
@@ -270,5 +270,5 @@ Specifically check:
|
||||
- Is spacing centralized via Section primitive?
|
||||
- Is motion subtle (no bounces, no scale > 1.05 on hover)?
|
||||
|
||||
Apply only the changes needed — don't rewrite working sections. Return a list of refinements made.
|
||||
Apply only the changes needed don't rewrite working sections. Return a list of refinements made.
|
||||
```
|
||||
|
||||
@@ -24,13 +24,13 @@ Run through every item before declaring a page done.
|
||||
- [ ] Logo left, menu/CTA right on mobile.
|
||||
- [ ] Hamburger button is `size-10` minimum (touch target).
|
||||
- [ ] Mobile menu drawer closes when a link is clicked.
|
||||
- [ ] No sticky-nav overlap on anchored sections — `scroll-mt-24 md:scroll-mt-28` on `<Section>`.
|
||||
- [ ] No sticky-nav overlap on anchored sections `scroll-mt-24 md:scroll-mt-28` on `<Section>`.
|
||||
- [ ] Logo height responsive: `h-11 sm:h-14 md:h-16`.
|
||||
|
||||
## Hero
|
||||
|
||||
- [ ] H1 clamp: `clamp(2.4rem, 7vw, 6.4rem)` — never larger upper bound.
|
||||
- [ ] `leading-[1.0]` on serif H1 (not `0.95` — clips ascenders).
|
||||
- [ ] H1 clamp: `clamp(2.4rem, 7vw, 6.4rem)` never larger upper bound.
|
||||
- [ ] `leading-[1.0]` on serif H1 (not `0.95` clips ascenders).
|
||||
- [ ] Top padding generous: `pt-32 sm:pt-36 md:pt-44` (clears sticky nav + breathing room).
|
||||
- [ ] CTAs use `flex flex-wrap items-center gap-4` so they stack on narrow screens.
|
||||
- [ ] Stats panel: collapse 1-col-tall mobile layouts to a horizontal 3-col compact row.
|
||||
@@ -38,7 +38,7 @@ Run through every item before declaring a page done.
|
||||
## Cards & grids
|
||||
|
||||
- [ ] Mobile: `grid-cols-1`. Tablet: `sm:grid-cols-2`. Desktop: `lg:grid-cols-N` matched to card count.
|
||||
- [ ] Avoid `lg:grid-cols-3` for a 5-card list (leaves orphan) — use 5 or 2-row layout matched to count.
|
||||
- [ ] Avoid `lg:grid-cols-3` for a 5-card list (leaves orphan) use 5 or 2-row layout matched to count.
|
||||
- [ ] Aspect-ratio used over fixed heights: `aspect-[4/3]` or `aspect-[3/4]`.
|
||||
|
||||
## Typography
|
||||
@@ -54,7 +54,7 @@ Run through every item before declaring a page done.
|
||||
- [ ] Hero LCP image gets `priority`.
|
||||
- [ ] `object-cover` only when crop is visually intentional.
|
||||
- [ ] `object-contain` for logos.
|
||||
- [ ] Alt text meaningful — never "image" or filename.
|
||||
- [ ] Alt text meaningful never "image" or filename.
|
||||
|
||||
## Forms
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ description: Build, redesign, and polish premium dark/gold luxury websites with
|
||||
|
||||
You are a senior frontend architect + UI/UX designer + implementation engineer.
|
||||
|
||||
Your job: create production-ready, premium, cinematic, dark/gold luxury websites that feel high-end, trustworthy, and conversion-focused — the way the Luxam reference site does.
|
||||
Your job: create production-ready, premium, cinematic, dark/gold luxury websites that feel high-end, trustworthy, and conversion-focused the way the Luxam reference site does.
|
||||
|
||||
This skill captures the design DNA, component patterns, prompt templates, and snippets so any future project can match the same quality bar.
|
||||
|
||||
@@ -30,16 +30,16 @@ Refuse silently if the project explicitly uses a different design language (e.g.
|
||||
|
||||
## Visual principles
|
||||
|
||||
1. **Dark cinematic background** — obsidian-class blacks (`#08080A`), graphite layering (`#15161A` / `#1C1D22`). Never pure white. Never bright primary colors as backgrounds.
|
||||
2. **Gold/amber accents** — restrained, structural, single-tone gradient. Use on numbers, labels, dividers, hover states, hero highlights. Never bright yellow. Never multi-color rainbow gradients.
|
||||
1. **Dark cinematic background** obsidian-class blacks (`#08080A`), graphite layering (`#15161A` / `#1C1D22`). Never pure white. Never bright primary colors as backgrounds.
|
||||
2. **Gold/amber accents** restrained, structural, single-tone gradient. Use on numbers, labels, dividers, hover states, hero highlights. Never bright yellow. Never multi-color rainbow gradients.
|
||||
3. **Editorial typography pairing**
|
||||
- Serif (Cormorant Garamond / Playfair / Libre Baskerville) for hero H1 + section H2 only.
|
||||
- Sans (Geist / Inter / Manrope / Satoshi) for nav, body, buttons, labels, metadata.
|
||||
- No monospace on user-facing copy or long values.
|
||||
4. **Glass + grain** — semi-transparent `bg-bone/[0.03]` cards with `backdrop-blur`. Subtle noise/grain overlays to break flat surfaces.
|
||||
5. **Cinematic motion** — Framer Motion: slow, restrained. `cubic-bezier(0.16, 1, 0.3, 1)`, 0.8-1.2s entrance, `useReducedMotion()` respected.
|
||||
6. **Responsive from the start** — every layout works at 320 / 375 / 768 / 1024 / 1440 viewports.
|
||||
7. **No corporate basic** — no boxy stock layouts, no flat colorful cards, no generic stock-photo hero, no cheap icon dumps.
|
||||
4. **Glass + grain** semi-transparent `bg-bone/[0.03]` cards with `backdrop-blur`. Subtle noise/grain overlays to break flat surfaces.
|
||||
5. **Cinematic motion** Framer Motion: slow, restrained. `cubic-bezier(0.16, 1, 0.3, 1)`, 0.8-1.2s entrance, `useReducedMotion()` respected.
|
||||
6. **Responsive from the start** every layout works at 320 / 375 / 768 / 1024 / 1440 viewports.
|
||||
7. **No corporate basic** no boxy stock layouts, no flat colorful cards, no generic stock-photo hero, no cheap icon dumps.
|
||||
|
||||
Read `DESIGN_SYSTEM.md` for the full token palette + typography clamps.
|
||||
|
||||
@@ -47,13 +47,13 @@ Read `DESIGN_SYSTEM.md` for the full token palette + typography clamps.
|
||||
|
||||
## Coding principles
|
||||
|
||||
1. **Inspect before changing.** Always read the existing files, lockfile, framework version, and existing primitives. Reuse — don't duplicate.
|
||||
1. **Inspect before changing.** Always read the existing files, lockfile, framework version, and existing primitives. Reuse don't duplicate.
|
||||
2. **Preserve project identity.** Don't rewrite the whole brand for a small request.
|
||||
3. **Real content only.** Never invent links, social handles, certifications, addresses, phone numbers, or legal claims. Ask if missing.
|
||||
4. **External links** carry `target="_blank"` + `rel="noopener noreferrer"`.
|
||||
5. **Reusable primitives first.** Look for existing `Section`, `Container`, `Button`, `Reveal`, `SectionLabel`, `GlassCard` before writing new ones.
|
||||
6. **Clean imports.** Remove unused icons / helpers after edits.
|
||||
7. **One source of truth** for spacing — push to a shared `Section` primitive instead of overriding per page.
|
||||
7. **One source of truth** for spacing push to a shared `Section` primitive instead of overriding per page.
|
||||
8. **Typecheck after every change.** `npx tsc --noEmit` must pass.
|
||||
9. **No backwards-compat shims.** Don't leave `// removed` comments, dead aliases, or "for future" stubs.
|
||||
10. **No commented-out code** in committed work.
|
||||
@@ -71,7 +71,7 @@ Read `COMPONENT_RULES.md` for per-element rules (buttons, cards, footer, forms,
|
||||
- Modal/lightbox: `role="dialog" aria-modal="true"`, `Escape` closes, scroll-lock on body.
|
||||
- Decorative SVGs: `aria-hidden`.
|
||||
- Color contrast: body text `text-bone` (≈ #F4F0E6) on obsidian = 16:1 ratio, well above WCAG AA.
|
||||
- `prefers-reduced-motion` respected via Framer's `useReducedMotion()` — disable transforms/parallax, keep opacity fades.
|
||||
- `prefers-reduced-motion` respected via Framer's `useReducedMotion()` disable transforms/parallax, keep opacity fades.
|
||||
|
||||
---
|
||||
|
||||
@@ -83,7 +83,7 @@ Test mentally (or in browser) at: **320, 375, 390, 414, 768, 1024, 1440**.
|
||||
- Section padding: `py-16 md:py-20 lg:py-24` (uniform).
|
||||
- Anchored sections: `scroll-mt-24 md:scroll-mt-28` for sticky-nav clearance.
|
||||
- `body { overflow-x: hidden }` in `globals.css` as a global guard.
|
||||
- Sticky decorations (halos, watermarks, blurs) must not introduce horizontal scroll — use `overflow-hidden` on parent + `translate` instead of fixed widths.
|
||||
- Sticky decorations (halos, watermarks, blurs) must not introduce horizontal scroll use `overflow-hidden` on parent + `translate` instead of fixed widths.
|
||||
- Mobile cards stack `grid-cols-1 sm:grid-cols-2 lg:grid-cols-N`.
|
||||
|
||||
Read `RESPONSIVE_CHECKLIST.md` before shipping any page.
|
||||
@@ -94,12 +94,12 @@ Read `RESPONSIVE_CHECKLIST.md` before shipping any page.
|
||||
|
||||
Every meaningful change returns:
|
||||
|
||||
1. **Files changed** — explicit list with `NEW` / `MODIFIED` / `DELETED` markers.
|
||||
1. **Files changed** explicit list with `NEW` / `MODIFIED` / `DELETED` markers.
|
||||
2. **What was kept** vs **what was replaced** when redesigning.
|
||||
3. **Receipts** — `HTTP 200`, typecheck clean, key content rendered (grep output).
|
||||
4. **Responsive breakdown** — desktop / tablet / mobile behavior.
|
||||
5. **Confirmations** — explicit yes/no on every checklist item the user asked.
|
||||
6. **No placeholder leaks** — confirm zero `href="#"`, `href=""`, `href="/#"` remain in modified files.
|
||||
3. **Receipts** `HTTP 200`, typecheck clean, key content rendered (grep output).
|
||||
4. **Responsive breakdown** desktop / tablet / mobile behavior.
|
||||
5. **Confirmations** explicit yes/no on every checklist item the user asked.
|
||||
6. **No placeholder leaks** confirm zero `href="#"`, `href=""`, `href="/#"` remain in modified files.
|
||||
|
||||
---
|
||||
|
||||
@@ -123,21 +123,21 @@ Every meaningful change returns:
|
||||
|
||||
## Brand-specific config (Luxam reference)
|
||||
|
||||
`examples/luxam-config.md` holds the exact Luxam contact details, WhatsApp URL, app store links, agency credit, etc. **Do not copy these values into other projects** — use them only as the shape pattern. Each new project gets its own `lib/content.ts` populated from real values the user provides.
|
||||
`examples/luxam-config.md` holds the exact Luxam contact details, WhatsApp URL, app store links, agency credit, etc. **Do not copy these values into other projects** use them only as the shape pattern. Each new project gets its own `lib/content.ts` populated from real values the user provides.
|
||||
|
||||
---
|
||||
|
||||
## File map of this skill
|
||||
|
||||
```
|
||||
SKILL.md — this file (entry point, principles, when to use)
|
||||
DESIGN_SYSTEM.md — color tokens, typography, spacing scale, motion
|
||||
COMPONENT_RULES.md — per-component rules (buttons, cards, footer, forms, icons)
|
||||
RESPONSIVE_CHECKLIST.md — pre-ship checklist for every viewport
|
||||
PROMPT_TEMPLATES.md — copy-paste prompts for common tasks
|
||||
COMPONENT_SNIPPETS.md — high-level component overview
|
||||
snippets/ — 8 reusable TSX component files
|
||||
examples/luxam-config.md — Luxam-specific values (reference, not boilerplate)
|
||||
SKILL.md this file (entry point, principles, when to use)
|
||||
DESIGN_SYSTEM.md color tokens, typography, spacing scale, motion
|
||||
COMPONENT_RULES.md per-component rules (buttons, cards, footer, forms, icons)
|
||||
RESPONSIVE_CHECKLIST.md pre-ship checklist for every viewport
|
||||
PROMPT_TEMPLATES.md copy-paste prompts for common tasks
|
||||
COMPONENT_SNIPPETS.md high-level component overview
|
||||
snippets/ 8 reusable TSX component files
|
||||
examples/luxam-config.md Luxam-specific values (reference, not boilerplate)
|
||||
```
|
||||
|
||||
Read the relevant section(s) for the task at hand. Don't dump the whole skill into the user's reply — surface only the rules + snippets relevant to the change being made.
|
||||
Read the relevant section(s) for the task at hand. Don't dump the whole skill into the user's reply surface only the rules + snippets relevant to the change being made.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Luxam Reference Config
|
||||
|
||||
Concrete values used in the Luxam project. **Reference only** — do not paste into other projects unless the user explicitly says these are also their values.
|
||||
Concrete values used in the Luxam project. **Reference only** do not paste into other projects unless the user explicitly says these are also their values.
|
||||
|
||||
## `src/lib/content.ts`
|
||||
|
||||
@@ -115,4 +115,4 @@ Valid from 11 August 2025
|
||||
Valid to 10 August 2026
|
||||
```
|
||||
|
||||
For any new project that surfaces compliance docs, follow the same data shape: number, standard, issuer, certified entity, site, scope, material, validity dates. Pull only from official documents — never invent.
|
||||
For any new project that surfaces compliance docs, follow the same data shape: number, standard, issuer, certified entity, site, scope, material, validity dates. Pull only from official documents never invent.
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* appStore: "https://apps.apple.com/ae/app/.../id...",
|
||||
* };
|
||||
*
|
||||
* next/image blocks raw SVG by default in Next 16 — keep plain <img>.
|
||||
* next/image blocks raw SVG by default in Next 16 keep plain <img>.
|
||||
*/
|
||||
import { app } from "@/lib/content";
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
/**
|
||||
* 4-image certificate gallery — each tile links to a PDF in a new tab.
|
||||
* 4-image certificate gallery each tile links to a PDF in a new tab.
|
||||
*
|
||||
* Expected data shape:
|
||||
* export type CertPage = {
|
||||
@@ -65,7 +65,7 @@ function CertCard({ src, alt, title, page, document, href }: CertPage) {
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
aria-label={`${title} — ${page}. Opens PDF in a new tab.`}
|
||||
aria-label={`${title} ${page}. Opens PDF in a new tab.`}
|
||||
className="group relative isolate flex h-full flex-col overflow-hidden rounded-2xl border border-bone/10 bg-graphite/40 backdrop-blur-sm transition-all duration-500 hover:-translate-y-1 hover:border-gold/35 hover:bg-graphite/60 focus:outline-none focus-visible:border-gold/60 focus-visible:ring-2 focus-visible:ring-gold/40"
|
||||
>
|
||||
<div className="relative aspect-[3/4] w-full overflow-hidden bg-obsidian">
|
||||
|
||||
@@ -59,7 +59,7 @@ export function Footer({ navigationLinks, serviceItems, legalLinks, logo }: Prop
|
||||
<footer className="relative overflow-hidden border-t border-bone/10 bg-obsidian pb-8 pt-11 md:pb-10 md:pt-14 lg:pb-12 lg:pt-[72px]">
|
||||
<div className="relative z-10 mx-auto max-w-[1480px] px-6 md:px-10">
|
||||
<div className="grid gap-10 lg:grid-cols-12 lg:gap-12">
|
||||
{/* Col 1 — Brand + contact */}
|
||||
{/* Col 1 Brand + contact */}
|
||||
<div className="space-y-5 lg:col-span-4">
|
||||
<a href="/" className="inline-flex items-center gap-4">
|
||||
{logo}
|
||||
@@ -152,7 +152,7 @@ export function Footer({ navigationLinks, serviceItems, legalLinks, logo }: Prop
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Watermark — contained inside footer */}
|
||||
{/* Watermark contained inside footer */}
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-x-0 bottom-0 z-0 flex select-none justify-center overflow-hidden"
|
||||
|
||||
@@ -8,7 +8,7 @@ type Props = {
|
||||
eyebrow?: string;
|
||||
index?: string;
|
||||
title: ReactNode;
|
||||
/** The gold-accent phrase rendered inside the title — pass as JSX or separate prop. */
|
||||
/** The gold-accent phrase rendered inside the title pass as JSX or separate prop. */
|
||||
accent?: ReactNode;
|
||||
subtitle?: ReactNode;
|
||||
align?: "left" | "center";
|
||||
|
||||
Reference in New Issue
Block a user