CHORE/some cleanup work, few tweaks
This commit is contained in:
parent
41d9b23ff3
commit
e76da01ab6
@ -300,4 +300,18 @@
|
||||
.font-playfair {
|
||||
font-family: var(--font-playfair);
|
||||
}
|
||||
|
||||
.scrollbar-hide {
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.scrollbar-hide::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.perspective-1000 {
|
||||
perspective: 1000px;
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ type ArtistGridSet = {
|
||||
items: PublicArtist[]
|
||||
}
|
||||
|
||||
const GRID_SIZE = 16
|
||||
const GRID_SIZE = 8
|
||||
const GRID_INTERVAL = 12000
|
||||
|
||||
export function ArtistsSection() {
|
||||
@ -48,6 +48,7 @@ export function ArtistsSection() {
|
||||
const [gridSets, setGridSets] = useState<ArtistGridSet[]>([])
|
||||
const [activeSetIndex, setActiveSetIndex] = useState(0)
|
||||
const [previousSetIndex, setPreviousSetIndex] = useState<number | null>(null)
|
||||
const [centerIndex, setCenterIndex] = useState(0)
|
||||
|
||||
artistsRef.current = artists
|
||||
gridSetsRef.current = gridSets
|
||||
@ -117,23 +118,45 @@ export function ArtistsSection() {
|
||||
const next = prev + 1
|
||||
if (next >= gridSetsRef.current.length) {
|
||||
regenerateSets()
|
||||
setCenterIndex(0)
|
||||
return 0
|
||||
}
|
||||
setCenterIndex(0)
|
||||
return next
|
||||
})
|
||||
}, [regenerateSets])
|
||||
|
||||
const rotateCarousel = useCallback((direction: 'next' | 'prev') => {
|
||||
if (gridSetsRef.current.length === 0) return
|
||||
|
||||
const currentSet = gridSetsRef.current[activeSetRef.current]
|
||||
if (!currentSet) return
|
||||
|
||||
setCenterIndex((prev) => {
|
||||
const nextIndex = direction === 'next'
|
||||
? (prev + 1) % currentSet.items.length
|
||||
: (prev - 1 + currentSet.items.length) % currentSet.items.length
|
||||
|
||||
// If we've looped back to start on 'next', advance to next set
|
||||
if (direction === 'next' && nextIndex === 0 && prev === currentSet.items.length - 1) {
|
||||
setTimeout(() => advanceSet(), 0)
|
||||
}
|
||||
|
||||
return nextIndex
|
||||
})
|
||||
}, [advanceSet])
|
||||
|
||||
useEffect(() => {
|
||||
if (gridSets.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const interval = window.setInterval(() => {
|
||||
advanceSet()
|
||||
rotateCarousel('next')
|
||||
}, GRID_INTERVAL)
|
||||
|
||||
return () => window.clearInterval(interval)
|
||||
}, [advanceSet, gridSets.length])
|
||||
}, [rotateCarousel, gridSets.length])
|
||||
|
||||
const displayIndices = useMemo(() => {
|
||||
const indices = new Set<number>()
|
||||
@ -145,15 +168,20 @@ export function ArtistsSection() {
|
||||
}, [activeSetIndex, previousSetIndex])
|
||||
|
||||
const getArtistImage = (artist: PublicArtist) => {
|
||||
const candidate = (artist as any).faceImage || artist.workImages?.[0]
|
||||
if (candidate) {
|
||||
return candidate
|
||||
// Try faceImage from static data first
|
||||
if ((artist as any).faceImage) {
|
||||
return (artist as any).faceImage
|
||||
}
|
||||
// Fall back to first work image
|
||||
if (artist.workImages && artist.workImages.length > 0) {
|
||||
return artist.workImages[0]
|
||||
}
|
||||
// Final fallback
|
||||
return "/placeholder.svg"
|
||||
}
|
||||
|
||||
return (
|
||||
<section id="artists" className="relative isolate overflow-hidden pb-24 pt-24">
|
||||
<section id="artists" className="relative isolate overflow-hidden pb-32 pt-32 lg:pb-40 lg:pt-40">
|
||||
<div className="pointer-events-none absolute inset-0 -z-10">
|
||||
<div className="absolute inset-0 bg-[linear-gradient(180deg,rgba(14,11,9,0)_0%,rgba(14,11,9,0.85)_20%,rgba(14,11,9,0.92)_55%,rgba(14,11,9,0.98)_100%)]" />
|
||||
<div
|
||||
@ -177,135 +205,144 @@ export function ArtistsSection() {
|
||||
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_20%,rgba(255,255,255,0.08),transparent_55%)]" />
|
||||
</div>
|
||||
|
||||
<div className="relative mx-auto flex max-w-6xl flex-col gap-16 px-6 lg:px-10 xl:flex-row">
|
||||
<div className="flex-1 space-y-10 text-white">
|
||||
<div className="space-y-4">
|
||||
<div className="relative mx-auto flex max-w-7xl flex-col gap-16 px-6 lg:px-10 xl:flex-row">
|
||||
<div className="xl:w-[40%] space-y-10 text-white">
|
||||
<div className="space-y-8">
|
||||
<span className="inline-flex items-center gap-3 text-[0.7rem] font-semibold uppercase tracking-[0.55em] text-white/55">
|
||||
<span className="h-px w-8 bg-white/35" /> Resident & Guest Artists
|
||||
</span>
|
||||
<h2 className="font-playfair text-4xl leading-[1.1] tracking-tight sm:text-5xl lg:text-[3.6rem]">
|
||||
A Collective of Story-Driven Tattoo Artists
|
||||
Artists Who Know What They're Doing
|
||||
</h2>
|
||||
<p className="max-w-xl text-base leading-relaxed text-white/70 sm:text-lg">
|
||||
United Tattoo is home to cover-up virtuosos, illustrative explorers, anime specialists, and fine line minimalists.
|
||||
Every artist curates their chair with intention—offering custom narratives, flash experiments, and collaborative pieces
|
||||
that evolve with you.
|
||||
Cover-up specialists, illustrative work, anime, and fine line. Each artist brings years of experience and their own style.
|
||||
Custom work and flash drops.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-5 text-xs uppercase tracking-[0.32em] text-white/60 sm:grid-cols-2">
|
||||
<div className="rounded-3xl border border-white/10 bg-[rgba(255,255,255,0.05)] p-6">
|
||||
<p className="text-[0.65rem] font-semibold text-white/55">What to Expect</p>
|
||||
<p className="mt-3 text-sm tracking-[0.28em] text-white">Consultation-first Process</p>
|
||||
<p className="mt-3 text-[0.68rem] leading-relaxed tracking-[0.26em] text-white/45">
|
||||
Artist pairing • Mood-boards • Aftercare guides • CalDAV-synced scheduling
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-3xl border border-white/10 bg-[rgba(255,255,255,0.04)] p-6">
|
||||
<p className="text-[0.65rem] font-semibold text-white/55">Specialties</p>
|
||||
<p className="mt-3 text-sm tracking-[0.28em] text-white">Layered Stylescapes</p>
|
||||
<p className="mt-3 text-[0.68rem] leading-relaxed tracking-[0.26em] text-white/45">
|
||||
Black & grey realism • Neo-traditional color • Bold cover-ups • Fine line botanicals
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-6 pt-2 sm:flex-row sm:items-center">
|
||||
<div className="flex flex-col gap-4 sm:flex-row sm:items-center">
|
||||
<Button
|
||||
asChild
|
||||
className="group relative w-full overflow-hidden rounded-full bg-white/90 px-8 py-4 text-xs font-semibold uppercase tracking-[0.38em] text-[#1c1713] transition-all duration-300 hover:bg-white sm:w-auto"
|
||||
className="w-full bg-white px-8 py-4 text-sm font-semibold uppercase tracking-wide text-black transition-colors hover:bg-white/90 sm:w-auto"
|
||||
>
|
||||
<Link href="/book">
|
||||
Reserve with an Artist
|
||||
<span className="ml-3 inline-flex h-[1px] w-6 bg-[#1c1713] transition-all duration-300 group-hover:w-10" />
|
||||
</Link>
|
||||
<Link href="/book">Book Your Session</Link>
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
asChild
|
||||
className="w-full justify-start rounded-full border border-white/15 bg-white/5 px-6 py-4 text-xs font-semibold uppercase tracking-[0.32em] text-white/80 backdrop-blur sm:w-auto"
|
||||
className="w-full justify-start border border-white/20 bg-white/5 px-6 py-4 text-sm font-medium uppercase tracking-wide text-white/80 backdrop-blur hover:bg-white/10 sm:w-auto"
|
||||
>
|
||||
<Link href="/artists">View full roster</Link>
|
||||
<Link href="/artists">View All Artists</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex-1">
|
||||
<div className="relative overflow-hidden rounded-[36px] border border-white/12 bg-[rgba(12,10,8,0.82)] p-6 shadow-[0_45px_90px_-35px_rgba(0,0,0,0.75)]">
|
||||
<div className="pointer-events-none absolute inset-0 rounded-[36px] border border-white/[0.05]" aria-hidden="true" />
|
||||
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_30%_20%,rgba(255,255,255,0.12),transparent_55%)]" aria-hidden="true" />
|
||||
<div className="relative xl:w-[60%]">
|
||||
<div className="relative h-[500px] sm:h-[550px] lg:h-[600px] flex items-center justify-center">
|
||||
{gridSets[activeSetIndex] && (
|
||||
<div className="relative w-full h-full flex items-center justify-center">
|
||||
{gridSets[activeSetIndex].items.map((artist, index) => {
|
||||
const href = `/artists/${artist.slug}`
|
||||
const image = getArtistImage(artist)
|
||||
|
||||
<div className="relative min-h-[520px]">
|
||||
{displayIndices.map((index) => {
|
||||
const set = gridSets[index]
|
||||
if (!set) {
|
||||
return null
|
||||
}
|
||||
const isActive = index === activeSetIndex
|
||||
// Calculate position relative to center with wrapping for infinite loop
|
||||
let positionFromCenter = index - centerIndex
|
||||
const totalCards = gridSets[activeSetIndex].items.length
|
||||
|
||||
return (
|
||||
<div
|
||||
key={set.key}
|
||||
className={cn(
|
||||
"absolute inset-0 grid grid-cols-2 gap-3 sm:gap-4 md:gap-5 lg:grid-cols-4",
|
||||
"transition-opacity duration-[1300ms] ease-out",
|
||||
isActive ? "pointer-events-auto opacity-100" : "pointer-events-none opacity-0"
|
||||
)}
|
||||
// Wrap around for continuous loop effect
|
||||
if (positionFromCenter < -2) {
|
||||
positionFromCenter += totalCards
|
||||
} else if (positionFromCenter > totalCards / 2) {
|
||||
positionFromCenter -= totalCards
|
||||
}
|
||||
|
||||
// Only show center + 2 behind on each side
|
||||
const isVisible = Math.abs(positionFromCenter) <= 2
|
||||
|
||||
// Calculate transforms for stacked deck effect
|
||||
const isCenterCard = positionFromCenter === 0
|
||||
|
||||
// Cards stack behind based on position
|
||||
let translateY = 0
|
||||
let translateX = 0
|
||||
let scale = 1
|
||||
let opacity = 1
|
||||
let zIndex = 10
|
||||
|
||||
if (positionFromCenter > 0) {
|
||||
// Cards to the right (future cards) - stack behind on right
|
||||
translateY = positionFromCenter * 20
|
||||
translateX = positionFromCenter * 40
|
||||
scale = 1 - positionFromCenter * 0.08
|
||||
opacity = Math.max(0, 1 - positionFromCenter * 0.4)
|
||||
zIndex = 10 - positionFromCenter
|
||||
} else if (positionFromCenter < 0) {
|
||||
// Cards to the left (past cards) - slide out to left and fade
|
||||
translateX = positionFromCenter * 150
|
||||
opacity = Math.max(0, 1 + positionFromCenter * 0.5)
|
||||
zIndex = 10 + positionFromCenter
|
||||
}
|
||||
|
||||
if (!isVisible) return null
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={`${artist.id}-${artist.slug}-${index}`}
|
||||
href={href}
|
||||
className="group absolute aspect-[3/4] w-[280px] sm:w-[320px] lg:w-[380px] overflow-hidden rounded-2xl border border-white/12 text-left transition-all duration-700 ease-out hover:border-white/25"
|
||||
style={{
|
||||
transform: `translate(${translateX}px, ${translateY}px) scale(${scale})`,
|
||||
opacity,
|
||||
zIndex,
|
||||
pointerEvents: isCenterCard ? 'auto' : 'none',
|
||||
}}
|
||||
>
|
||||
<img
|
||||
src={image}
|
||||
alt={`${artist.name} portfolio sample`}
|
||||
className="absolute inset-0 h-full w-full object-cover transition-transform duration-700 group-hover:scale-[1.06]"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#0b0907] via-transparent to-transparent" />
|
||||
<div className="absolute right-5 top-5 h-12 w-12 rounded-full border border-white/20 bg-white/10 backdrop-blur">
|
||||
<span className="absolute inset-2 rounded-full border border-white/15" />
|
||||
</div>
|
||||
<div className="absolute bottom-0 left-0 right-0 p-6 space-y-2">
|
||||
<p className="text-lg font-semibold uppercase tracking-wider text-white">
|
||||
{artist.name}
|
||||
</p>
|
||||
<p className="text-sm uppercase tracking-wide text-white/60">
|
||||
{(artist as any).specialty || "Tattoo Artist"}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
|
||||
{/* Navigation buttons */}
|
||||
<button
|
||||
onClick={() => rotateCarousel('prev')}
|
||||
className="absolute left-0 z-20 p-3 text-white/60 transition-colors hover:text-white"
|
||||
aria-label="Previous artist"
|
||||
>
|
||||
{set.items.map((artist) => {
|
||||
const href = `/artists/${artist.slug}`
|
||||
const image = getArtistImage(artist)
|
||||
return (
|
||||
<Link
|
||||
key={`${set.key}-${artist.id}-${artist.slug}`}
|
||||
href={href}
|
||||
className="group relative flex flex-col overflow-hidden rounded-3xl border border-white/12 bg-white/[0.06] p-3 text-left transition-all duration-500 hover:-translate-y-1 hover:border-white/25 hover:bg-white/[0.1]"
|
||||
>
|
||||
<div className="relative aspect-[4/5] overflow-hidden rounded-2xl">
|
||||
<img
|
||||
src={image}
|
||||
alt={`${artist.name} portfolio sample`}
|
||||
className="h-full w-full object-cover transition-transform duration-700 group-hover:scale-[1.06]"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#0b0907] via-transparent to-transparent" />
|
||||
<div className="absolute right-4 top-4 h-10 w-10 rounded-full border border-white/20 bg-white/10 backdrop-blur">
|
||||
<span className="absolute inset-2 rounded-full border border-white/15" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 space-y-1">
|
||||
<p className="text-sm font-semibold uppercase tracking-[0.35em] text-white">
|
||||
{artist.name}
|
||||
</p>
|
||||
<p className="text-[0.65rem] uppercase tracking-[0.32em] text-white/55">
|
||||
{(artist as any).specialty || "Tattoo Artist"}
|
||||
</p>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
<svg className="h-8 w-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => rotateCarousel('next')}
|
||||
className="absolute right-0 z-20 p-3 text-white/60 transition-colors hover:text-white"
|
||||
aria-label="Next artist"
|
||||
>
|
||||
<svg className="h-8 w-8" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 mt-24 flex flex-col items-center gap-6 px-6 text-center text-white lg:px-10">
|
||||
<p className="uppercase tracking-[0.4em] text-white/45">Let's Plan Your Piece</p>
|
||||
<h3 className="font-playfair text-3xl leading-tight sm:text-4xl">
|
||||
Choose your artist, share your story, and build a tattoo ritual around intentional ink.
|
||||
</h3>
|
||||
<Button
|
||||
asChild
|
||||
className="rounded-full border border-white/20 bg-white text-sm font-semibold uppercase tracking-[0.32em] text-[#1c1713] shadow-[0_30px_60px_-35px_rgba(255,255,255,0.65)] transition-transform duration-300 hover:scale-[1.03]"
|
||||
>
|
||||
<Link href="/book" className="px-10 py-4">
|
||||
Start A Consultation
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@ -6,207 +6,205 @@ import { ArrowUp } from "lucide-react"
|
||||
import { Button } from "@/components/ui/button"
|
||||
|
||||
export function Footer() {
|
||||
const [showScrollTop, setShowScrollTop] = useState(false)
|
||||
const [showScrollTop, setShowScrollTop] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const scrolled = window.scrollY
|
||||
const threshold = window.innerHeight * 0.5
|
||||
setShowScrollTop(scrolled > threshold)
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const scrolled = window.scrollY
|
||||
const threshold = window.innerHeight * 0.5
|
||||
setShowScrollTop(scrolled > threshold)
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", handleScroll)
|
||||
handleScroll()
|
||||
return () => window.removeEventListener("scroll", handleScroll)
|
||||
}, [])
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({ top: 0, behavior: "smooth" })
|
||||
}
|
||||
|
||||
window.addEventListener("scroll", handleScroll)
|
||||
handleScroll()
|
||||
return () => window.removeEventListener("scroll", handleScroll)
|
||||
}, [])
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={scrollToTop}
|
||||
className={`fixed bottom-8 right-8 z-50 h-12 w-12 rounded-full border border-white/15 bg-white/90 p-0 text-[#1c1713] shadow-[0_30px_60px_-35px_rgba(255,255,255,0.65)] transition-all duration-300 hover:scale-[1.05] hover:bg-white ${showScrollTop ? "translate-y-0 opacity-100" : "pointer-events-none translate-y-4 opacity-0"
|
||||
}`}
|
||||
aria-label="Scroll to top"
|
||||
>
|
||||
<ArrowUp size={20} />
|
||||
</Button>
|
||||
|
||||
const scrollToTop = () => {
|
||||
window.scrollTo({ top: 0, behavior: "smooth" })
|
||||
}
|
||||
<footer className="bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.09),transparent_55%),linear-gradient(180deg,#15100d_0%,#0c0907_100%)] py-16 text-white">
|
||||
<div className="container mx-auto px-8">
|
||||
<div className="grid grid-cols-1 items-start gap-10 md:grid-cols-12">
|
||||
<div className="md:col-span-3">
|
||||
<div className="mb-6 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Services
|
||||
</div>
|
||||
<ul className="space-y-3 text-sm text-white/65">
|
||||
{[
|
||||
{ name: "TRADITIONAL", count: "" },
|
||||
{ name: "REALISM", count: "" },
|
||||
{ name: "BLACKWORK", count: "" },
|
||||
{ name: "FINE LINE", count: "" },
|
||||
{ name: "ILLUSTRATION", count: "" },
|
||||
{ name: "ANIME", count: "" },
|
||||
].map((service, index) => (
|
||||
<li key={index}>
|
||||
<Link href="/book" className="transition-colors duration-200 hover:text-white">
|
||||
{service.name}
|
||||
{service.count && <span className="text-white ml-2">{service.count}</span>}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button
|
||||
onClick={scrollToTop}
|
||||
className={`fixed bottom-8 right-8 z-50 h-12 w-12 rounded-full border border-white/15 bg-white/90 p-0 text-[#1c1713] shadow-[0_30px_60px_-35px_rgba(255,255,255,0.65)] transition-all duration-300 hover:scale-[1.05] hover:bg-white ${
|
||||
showScrollTop ? "translate-y-0 opacity-100" : "pointer-events-none translate-y-4 opacity-0"
|
||||
}`}
|
||||
aria-label="Scroll to top"
|
||||
>
|
||||
<ArrowUp size={20} />
|
||||
</Button>
|
||||
<div className="md:col-span-3">
|
||||
<div className="mb-6 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Artists
|
||||
</div>
|
||||
<ul className="space-y-3 text-sm text-white/65">
|
||||
{[
|
||||
{ name: "CHRISTY_LUMBERG", count: "" },
|
||||
{ name: "STEVEN_SOLE", count: "" },
|
||||
{ name: "DONOVAN_L", count: "" },
|
||||
{ name: "VIEW_ALL", count: "" },
|
||||
].map((artist, index) => (
|
||||
<li key={index}>
|
||||
<Link href="/artists" className="transition-colors duration-200 hover:text-white">
|
||||
{artist.name}
|
||||
{artist.count && <span className="text-white ml-2">{artist.count}</span>}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer className="bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.09),transparent_55%),linear-gradient(180deg,#15100d_0%,#0c0907_100%)] py-16 text-white">
|
||||
<div className="container mx-auto px-8">
|
||||
<div className="grid grid-cols-1 items-start gap-10 md:grid-cols-12">
|
||||
<div className="md:col-span-3">
|
||||
<div className="mb-6 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Services
|
||||
</div>
|
||||
<ul className="space-y-3 text-sm text-white/65">
|
||||
{[
|
||||
{ name: "TRADITIONAL", count: "" },
|
||||
{ name: "REALISM", count: "" },
|
||||
{ name: "BLACKWORK", count: "" },
|
||||
{ name: "FINE LINE", count: "" },
|
||||
{ name: "WATERCOLOR", count: "" },
|
||||
{ name: "COVER-UPS", count: "" },
|
||||
{ name: "ANIME", count: "" },
|
||||
].map((service, index) => (
|
||||
<li key={index}>
|
||||
<Link href="/book" className="transition-colors duration-200 hover:text-white">
|
||||
{service.name}
|
||||
{service.count && <span className="text-white ml-2">{service.count}</span>}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="md:col-span-3">
|
||||
<div className="mb-4 text-xs uppercase tracking-[0.4em] text-white/40">
|
||||
© <span className="text-white/80">L3 INVESTMENTS</span> LLC 2025 — All Rights Reserved
|
||||
</div>
|
||||
<div className="space-y-2 text-sm text-white/60">
|
||||
<p>5160 Fontaine Blvd</p>
|
||||
<p>Fountain, CO 80817</p>
|
||||
<Link href="tel:+17196989004" className="transition-colors duration-200 hover:text-white">
|
||||
(719) 698-9004
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-3">
|
||||
<div className="mb-6 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Artists
|
||||
</div>
|
||||
<ul className="space-y-3 text-sm text-white/65">
|
||||
{[
|
||||
{ name: "CHRISTY_LUMBERG", count: "" },
|
||||
{ name: "STEVEN_SOLE", count: "" },
|
||||
{ name: "DONOVAN_L", count: "" },
|
||||
{ name: "VIEW_ALL", count: "" },
|
||||
].map((artist, index) => (
|
||||
<li key={index}>
|
||||
<Link href="/artists" className="transition-colors duration-200 hover:text-white">
|
||||
{artist.name}
|
||||
{artist.count && <span className="text-white ml-2">{artist.count}</span>}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
<div className="md:col-span-3 space-y-8">
|
||||
{/* Legal */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Legal
|
||||
</div>
|
||||
<ul className="space-y-2 text-sm text-white/65">
|
||||
<li>
|
||||
<Link
|
||||
href="/aftercare"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
AFTERCARE
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="/deposit"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
DEPOSIT POLICY
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="/terms"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
TERMS OF SERVICE
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="/privacy"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
PRIVACY POLICY
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="#"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
WAIVER
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-3">
|
||||
<div className="mb-4 text-xs uppercase tracking-[0.4em] text-white/40">
|
||||
© <span className="text-white/80">UNITED.TATTOO</span> LLC 2025 — All Rights Reserved
|
||||
</div>
|
||||
<div className="space-y-2 text-sm text-white/60">
|
||||
<p>5160 Fontaine Blvd</p>
|
||||
<p>Fountain, CO 80817</p>
|
||||
<Link href="tel:+17196989004" className="transition-colors duration-200 hover:text-white">
|
||||
(719) 698-9004
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
{/* Social */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Social
|
||||
</div>
|
||||
<ul className="space-y-2 text-sm text-white/65">
|
||||
<li>
|
||||
<Link
|
||||
href="https://www.instagram.com/unitedtattoo719"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
INSTAGRAM
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="https://www.facebook.com/unitedtattoo719"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
FACEBOOK
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="https://www.tiktok.com/@united.tattoo"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
TIKTOK
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-3 space-y-8">
|
||||
{/* Legal */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Legal
|
||||
{/* Contact */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Contact
|
||||
</div>
|
||||
<Link
|
||||
href="mailto:info@united-tattoo.com"
|
||||
className="text-sm text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
INFO@UNITED-TATTOO.COM
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 flex justify-end gap-2">
|
||||
<div className="h-2 w-2 rounded-full bg-white/25" />
|
||||
<div className="h-2 w-2 rounded-full bg-white/60" />
|
||||
</div>
|
||||
</div>
|
||||
<ul className="space-y-2 text-sm text-white/65">
|
||||
<li>
|
||||
<Link
|
||||
href="/aftercare"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
AFTERCARE
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="/deposit"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
DEPOSIT POLICY
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="/terms"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
TERMS OF SERVICE
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="/privacy"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
PRIVACY POLICY
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="#"
|
||||
className="transition-colors duration-200 hover:text-white underline"
|
||||
>
|
||||
WAIVER
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Social */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Social
|
||||
</div>
|
||||
<ul className="space-y-2 text-sm text-white/65">
|
||||
<li>
|
||||
<Link
|
||||
href="https://www.instagram.com/unitedtattoo719"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
INSTAGRAM
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="https://www.facebook.com/unitedtattoo719"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
FACEBOOK
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link
|
||||
href="https://www.tiktok.com/@united.tattoo"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
TIKTOK
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contact */}
|
||||
<div>
|
||||
<div className="mb-4 flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-white/55">
|
||||
<span className="inline-flex h-2 w-2 rounded-full bg-white/40" /> Contact
|
||||
</div>
|
||||
<Link
|
||||
href="mailto:info@united-tattoo.com"
|
||||
className="text-sm text-white/65 underline transition-colors duration-200 hover:text-white"
|
||||
>
|
||||
INFO@UNITED-TATTOO.COM
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 flex justify-end gap-2">
|
||||
<div className="h-2 w-2 rounded-full bg-white/25" />
|
||||
<div className="h-2 w-2 rounded-full bg-white/60" />
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</>
|
||||
)
|
||||
</footer>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@ -10,166 +10,133 @@ import { useMultiLayerParallax, useReducedMotion } from "@/hooks/use-parallax"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
export function HeroSection() {
|
||||
const [isVisible, setIsVisible] = useState(false)
|
||||
const advancedNavAnimations = useFeatureFlag("ADVANCED_NAV_SCROLL_ANIMATIONS_ENABLED")
|
||||
const reducedMotion = useReducedMotion()
|
||||
const [isVisible, setIsVisible] = useState(false)
|
||||
const advancedNavAnimations = useFeatureFlag("ADVANCED_NAV_SCROLL_ANIMATIONS_ENABLED")
|
||||
const reducedMotion = useReducedMotion()
|
||||
|
||||
const parallax = useMultiLayerParallax(!advancedNavAnimations || reducedMotion)
|
||||
const parallax = useMultiLayerParallax(!advancedNavAnimations || reducedMotion)
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setIsVisible(true), 240)
|
||||
return () => clearTimeout(timer)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setIsVisible(true), 240)
|
||||
return () => clearTimeout(timer)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<section
|
||||
id="home"
|
||||
className="relative flex min-h-[110vh] items-center justify-center overflow-hidden px-6 pb-24 pt-32 sm:px-10 lg:pt-44"
|
||||
data-reduced-motion={reducedMotion}
|
||||
>
|
||||
<div
|
||||
ref={parallax.background.ref}
|
||||
className="pointer-events-none absolute inset-0 will-change-transform"
|
||||
style={{
|
||||
backgroundImage:
|
||||
"image-set(url('/assets/liberty/hero-statue-collage.avif') type('image/avif'), url('/assets/liberty/hero-statue-collage.webp') type('image/webp'))",
|
||||
backgroundPosition: "center top",
|
||||
backgroundSize: "cover",
|
||||
mixBlendMode: "soft-light",
|
||||
opacity: 0.35,
|
||||
...parallax.background.style,
|
||||
}}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
return (
|
||||
<section
|
||||
id="home"
|
||||
className="relative flex min-h-[100vh] items-center justify-center overflow-hidden px-6 pb-24 pt-22 sm:px-10 lg:pt-34"
|
||||
data-reduced-motion={reducedMotion}
|
||||
>
|
||||
<div
|
||||
ref={parallax.background.ref}
|
||||
className="pointer-events-none absolute inset-0 will-change-transform"
|
||||
style={{
|
||||
backgroundImage:
|
||||
"image-set(url('/assets/liberty/hero-statue-collage.avif') type('image/avif'), url('/assets/liberty/hero-statue-collage.webp') type('image/webp'))",
|
||||
backgroundPosition: "center top",
|
||||
backgroundSize: "cover",
|
||||
mixBlendMode: "soft-light",
|
||||
opacity: 0.35,
|
||||
...parallax.background.style,
|
||||
}}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<div
|
||||
ref={parallax.midground.ref}
|
||||
className="absolute inset-0 bg-[radial-gradient(circle_at_20%_10%,rgba(255,255,255,0.14),transparent_52%),linear-gradient(115deg,rgba(18,14,12,0.86)_18%,rgba(18,14,12,0.62)_48%,rgba(18,14,12,0)_100%)] will-change-transform"
|
||||
style={parallax.midground.style}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
ref={parallax.midground.ref}
|
||||
className="absolute inset-0 bg-[radial-gradient(circle_at_20%_10%,rgba(255,255,255,0.14),transparent_52%),linear-gradient(115deg,rgba(18,14,12,0.86)_18%,rgba(18,14,12,0.62)_48%,rgba(18,14,12,0)_100%)] will-change-transform"
|
||||
style={parallax.midground.style}
|
||||
aria-hidden="true"
|
||||
/>
|
||||
|
||||
<div
|
||||
ref={parallax.foreground.ref}
|
||||
className="relative z-10 w-full will-change-transform"
|
||||
style={parallax.foreground.style}
|
||||
>
|
||||
<div className="mx-auto flex max-w-6xl flex-col gap-14 lg:grid lg:grid-cols-[minmax(0,0.95fr)_minmax(0,1.1fr)] lg:items-center">
|
||||
<div
|
||||
className={cn(
|
||||
"relative space-y-8 text-left text-white transition-all duration-1000",
|
||||
isVisible ? "opacity-100 translate-y-0" : "translate-y-8 opacity-0"
|
||||
)}
|
||||
>
|
||||
<span className="inline-flex items-center gap-3 text-[0.7rem] font-semibold uppercase tracking-[0.6em] text-white/60">
|
||||
<span className="h-[1px] w-10 bg-white/40" /> Fountain, Colorado
|
||||
</span>
|
||||
<div className="space-y-4">
|
||||
<h1 className="font-playfair text-4xl leading-[1.1] tracking-tight sm:text-5xl lg:text-[4.2rem]">
|
||||
A Studio of Ritual, Craft, and Skin Stories
|
||||
</h1>
|
||||
<p className="max-w-xl text-base leading-relaxed text-white/70 sm:text-lg">
|
||||
United Tattoo is a sanctuary for custom work—where layered narratives, sculptural light, and precise linework
|
||||
merge into living art. Appointments are curated with intention, calm focus, and a love of experimentation.
|
||||
</p>
|
||||
<div
|
||||
ref={parallax.foreground.ref}
|
||||
className="relative z-10 w-full will-change-transform"
|
||||
style={parallax.foreground.style}
|
||||
>
|
||||
<div className="mx-auto flex max-w-6xl flex-col gap-14 lg:grid lg:grid-cols-[minmax(0,0.95fr)_minmax(0,1.1fr)] lg:items-center">
|
||||
<div
|
||||
className={cn(
|
||||
"relative space-y-8 text-left text-white transition-all duration-1000",
|
||||
isVisible ? "opacity-100 translate-y-0" : "translate-y-8 opacity-0"
|
||||
)}
|
||||
>
|
||||
<div className="space-y-6">
|
||||
<h1 className="font-playfair text-5xl leading-[1.05] tracking-tight sm:text-6xl lg:text-[5.5rem]">
|
||||
UNITED
|
||||
</h1>
|
||||
<p className="max-w-xl text-lg leading-relaxed text-white/75 sm:text-xl">
|
||||
Tattoos by artists who know what they're doing. Custom tattoos, flash & cover-ups.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 pt-6 md:flex-row md:items-center">
|
||||
<Button
|
||||
asChild
|
||||
className="w-full bg-white px-8 py-4 text-sm font-semibold uppercase tracking-wide text-black transition-colors hover:bg-white/90 md:w-auto"
|
||||
>
|
||||
<Link href="/book">Book Your Session</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative mx-auto flex w-full max-w-[520px] justify-center lg:justify-end">
|
||||
<div className="relative aspect-[4/5] w-full">
|
||||
<div className="absolute -inset-6 rounded-[32px] border border-white/12 bg-white/10 backdrop-blur-[2px]" aria-hidden="true" />
|
||||
<div className="absolute -inset-x-10 -top-10 h-[140px] rounded-full bg-[radial-gradient(circle,rgba(255,255,255,0.08),transparent_65%)]" aria-hidden="true" />
|
||||
<div className="absolute -right-10 top-16 hidden h-36 w-36 rounded-full border border-white/10 backdrop-blur-sm lg:block" aria-hidden="true">
|
||||
<div className="absolute inset-3 rounded-full border border-white/10" />
|
||||
</div>
|
||||
|
||||
<figure
|
||||
className={cn(
|
||||
"relative h-full w-full overflow-hidden rounded-[28px] border border-white/14 bg-black/40",
|
||||
isVisible ? "shadow-[0_45px_90px_-40px_rgba(0,0,0,0.9)]" : ""
|
||||
)}
|
||||
>
|
||||
<Image
|
||||
src="/assets/liberty/hero-statue-collage.webp"
|
||||
alt="Sculptural collage with the Statue of Liberty and tattoo studio elements"
|
||||
fill
|
||||
sizes="(min-width: 1024px) 520px, 90vw"
|
||||
priority
|
||||
className="object-cover object-center"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#0b0907]/70 via-transparent to-transparent" />
|
||||
</figure>
|
||||
|
||||
<div className="absolute -bottom-10 left-[-18%] hidden w-[220px] border border-white/12 bg-white/8 p-4 backdrop-blur-md lg:block">
|
||||
<p className="text-sm font-semibold text-white">United Tattoo</p>
|
||||
<p className="mt-2 text-xs leading-relaxed text-white/50">
|
||||
Fountain, Colorado
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<figure className="absolute -top-10 left-[-15%] hidden w-40 rotate-[-6deg] overflow-hidden rounded-3xl border border-white/15 bg-white/10 shadow-[0_35px_60px_-30px_rgba(0,0,0,0.7)] backdrop-blur md:block">
|
||||
<Image
|
||||
src="/assets/liberty/dove-tableau-close.webp"
|
||||
alt="Still life of studio textures with a dove"
|
||||
width={320}
|
||||
height={420}
|
||||
className="h-full w-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</figure>
|
||||
|
||||
<figure className="absolute -right-16 bottom-16 hidden w-32 rotate-[5deg] overflow-hidden rounded-3xl border border-white/15 bg-white/10 shadow-[0_25px_45px_-25px_rgba(0,0,0,0.7)] backdrop-blur sm:block">
|
||||
<Image
|
||||
src="/assets/liberty/palette-brush-liberty.webp"
|
||||
alt="Color palette with statue illustration"
|
||||
width={260}
|
||||
height={320}
|
||||
className="h-full w-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-6 pt-6 md:flex-row md:items-center">
|
||||
<Button
|
||||
asChild
|
||||
className="group relative w-full overflow-hidden rounded-full bg-white/90 px-8 py-4 text-xs font-semibold uppercase tracking-[0.4em] text-[#1c1713] transition-all duration-300 hover:bg-white md:w-auto"
|
||||
>
|
||||
<Link href="/book">
|
||||
<span className="flex items-center gap-3">
|
||||
Secure Consultation
|
||||
<span className="h-[1px] w-6 bg-[#1c1713] transition-transform duration-300 group-hover:w-10" />
|
||||
</span>
|
||||
</Link>
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
asChild
|
||||
className="w-full justify-start rounded-full border border-white/15 bg-white/5 px-6 py-4 text-xs font-semibold uppercase tracking-[0.32em] text-white/80 backdrop-blur md:w-auto"
|
||||
>
|
||||
<Link href="#artists">View the Artists</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid gap-4 pt-4 text-xs uppercase tracking-[0.32em] text-white/55 sm:grid-cols-2">
|
||||
<div className="rounded-2xl border border-white/10 bg-[rgba(255,255,255,0.06)] p-5">
|
||||
<p className="text-[0.65rem] font-semibold text-white/60">Studio Rhythm</p>
|
||||
<p className="mt-3 text-sm tracking-[0.2em] text-white">Appointment-Only Sessions</p>
|
||||
<p className="mt-2 text-[0.68rem] leading-relaxed tracking-[0.3em] text-white/45">
|
||||
Design consultations • Flash drops • Artist residencies
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-2xl border border-white/10 bg-[rgba(255,255,255,0.04)] p-5">
|
||||
<p className="text-[0.65rem] font-semibold text-white/60">Focus</p>
|
||||
<p className="mt-3 text-sm tracking-[0.2em] text-white">Layered Custom Work</p>
|
||||
<p className="mt-2 text-[0.68rem] leading-relaxed tracking-[0.3em] text-white/45">
|
||||
Black & grey realism • Neo-traditional • Fine line botanical
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative mx-auto flex w-full max-w-[520px] justify-center lg:justify-end">
|
||||
<div className="relative aspect-[4/5] w-full">
|
||||
<div className="absolute -inset-6 rounded-[32px] border border-white/12 bg-white/10 backdrop-blur-[2px]" aria-hidden="true" />
|
||||
<div className="absolute -inset-x-10 -top-10 h-[140px] rounded-full bg-[radial-gradient(circle,rgba(255,255,255,0.08),transparent_65%)]" aria-hidden="true" />
|
||||
<div className="absolute -right-10 top-16 hidden h-36 w-36 rounded-full border border-white/10 backdrop-blur-sm lg:block" aria-hidden="true">
|
||||
<div className="absolute inset-3 rounded-full border border-white/10" />
|
||||
</div>
|
||||
|
||||
<figure
|
||||
className={cn(
|
||||
"relative h-full w-full overflow-hidden rounded-[28px] border border-white/14 bg-black/40",
|
||||
isVisible ? "shadow-[0_45px_90px_-40px_rgba(0,0,0,0.9)]" : ""
|
||||
)}
|
||||
>
|
||||
<Image
|
||||
src="/assets/liberty/hero-statue-collage.webp"
|
||||
alt="Sculptural collage with the Statue of Liberty and tattoo studio elements"
|
||||
fill
|
||||
sizes="(min-width: 1024px) 520px, 90vw"
|
||||
priority
|
||||
className="object-cover object-center"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-[#0b0907]/70 via-transparent to-transparent" />
|
||||
</figure>
|
||||
|
||||
<div className="absolute -bottom-10 left-[-18%] hidden w-[220px] rounded-[26px] border border-white/12 bg-white/8 p-4 text-[0.65rem] uppercase tracking-[0.32em] text-white/70 backdrop-blur-md lg:block">
|
||||
<p>United Tattoo Collective</p>
|
||||
<p className="mt-2 text-[0.55rem] leading-[1.8] text-white/45">
|
||||
Sculptural light. Ritual care. Art that endures.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<figure className="absolute -top-10 left-[-15%] hidden w-40 rotate-[-6deg] overflow-hidden rounded-3xl border border-white/15 bg-white/10 shadow-[0_35px_60px_-30px_rgba(0,0,0,0.7)] backdrop-blur md:block">
|
||||
<Image
|
||||
src="/assets/liberty/dove-tableau-close.webp"
|
||||
alt="Still life of studio textures with a dove"
|
||||
width={320}
|
||||
height={420}
|
||||
className="h-full w-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</figure>
|
||||
|
||||
<figure className="absolute -right-16 bottom-16 hidden w-32 rotate-[5deg] overflow-hidden rounded-3xl border border-white/15 bg-white/10 shadow-[0_25px_45px_-25px_rgba(0,0,0,0.7)] backdrop-blur sm:block">
|
||||
<Image
|
||||
src="/assets/liberty/palette-brush-liberty.webp"
|
||||
alt="Color palette with statue illustration"
|
||||
width={260}
|
||||
height={320}
|
||||
className="h-full w-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ import { useCallback, useEffect, useState } from "react"
|
||||
import type { MouseEvent } from "react"
|
||||
import Link from "next/link"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
import { ArrowUpRight, Menu, X } from "lucide-react"
|
||||
import { Menu, X } from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
@ -122,33 +122,22 @@ export function Navigation() {
|
||||
return (
|
||||
<nav
|
||||
className={cn(
|
||||
"fixed top-0 left-0 right-0 z-50 transition-all duration-700 ease-out",
|
||||
"fixed top-0 left-0 right-0 z-50 transition-all duration-300",
|
||||
isScrolled
|
||||
? "backdrop-blur-md bg-[rgba(20,18,16,0.92)] border-b border-white/10 shadow-[0_12px_40px_-20px_rgba(0,0,0,0.8)]"
|
||||
? "backdrop-blur-xl bg-black/80 border-b border-white/10"
|
||||
: "bg-transparent"
|
||||
)}
|
||||
>
|
||||
<div className="relative mx-auto max-w-[1600px] px-5 sm:px-8">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-x-3 -top-4 h-[130px] rounded-3xl border border-white/10 transition-opacity duration-700",
|
||||
"before:absolute before:inset-0 before:rounded-3xl before:bg-[linear-gradient(130deg,rgba(255,255,255,0.16)_0%,rgba(255,255,255,0.02)_55%,rgba(10,10,10,0.35)_100%)] before:opacity-90",
|
||||
"after:absolute after:inset-0 after:rounded-3xl after:bg-[url('/assets/liberty/sketch-blue-etching.webp')] after:bg-cover after:bg-center after:opacity-10",
|
||||
isScrolled ? "opacity-100" : "opacity-80"
|
||||
)}
|
||||
/>
|
||||
|
||||
<div className="relative flex h-[90px] items-center justify-between gap-3">
|
||||
<div className="relative flex h-20 items-center justify-between gap-3">
|
||||
<Link
|
||||
href="/"
|
||||
className="group relative flex flex-col items-start text-white transition-colors duration-500"
|
||||
className="relative flex flex-col items-start text-white transition-opacity hover:opacity-80"
|
||||
>
|
||||
<span className="font-playfair text-[1.8rem] uppercase tracking-[0.28em] sm:text-[2.1rem]">
|
||||
<span className="font-playfair text-2xl uppercase tracking-[0.2em] sm:text-3xl">
|
||||
United
|
||||
</span>
|
||||
<span className="mt-1 flex items-center gap-3 text-[0.65rem] font-semibold uppercase tracking-[0.4em] text-white/70">
|
||||
<span className="h-px w-9 bg-white/60 transition-all duration-500 group-hover:w-12" />
|
||||
<span className="text-[0.65rem] font-semibold uppercase tracking-[0.3em] text-white/60">
|
||||
Tattoo Studio
|
||||
</span>
|
||||
</Link>
|
||||
@ -162,25 +151,17 @@ export function Navigation() {
|
||||
const isActive = activeSection === item.id
|
||||
|
||||
return (
|
||||
<NavigationMenuItem key={item.id} className="min-w-max">
|
||||
<NavigationMenuLink
|
||||
asChild
|
||||
data-active={isActive || undefined}
|
||||
className={cn(
|
||||
"relative inline-flex items-center text-[0.72rem] font-semibold uppercase tracking-[0.42em] text-white/60 transition-colors duration-300",
|
||||
"group hover:text-white focus-visible:text-white",
|
||||
isActive && "text-white"
|
||||
)}
|
||||
>
|
||||
<Link href={item.href} className="px-1 py-1">
|
||||
<NavigationMenuItem key={item.id}>
|
||||
<NavigationMenuLink asChild>
|
||||
<Link
|
||||
href={item.href}
|
||||
onClick={(e) => handleNavClick(e, item)}
|
||||
className={cn(
|
||||
"text-sm font-medium uppercase tracking-wider transition-colors px-3 py-2",
|
||||
isActive ? "text-white" : "text-white/60 hover:text-white"
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
<span
|
||||
className={cn(
|
||||
"pointer-events-none absolute inset-x-0 -bottom-2 h-[1px] origin-left scale-x-0 bg-white/70 transition-transform duration-300",
|
||||
isActive && "scale-x-100",
|
||||
"group-hover:scale-x-100"
|
||||
)}
|
||||
/>
|
||||
</Link>
|
||||
</NavigationMenuLink>
|
||||
</NavigationMenuItem>
|
||||
@ -191,29 +172,23 @@ export function Navigation() {
|
||||
|
||||
<Button
|
||||
asChild
|
||||
className={cn(
|
||||
"group relative overflow-hidden rounded-full px-8 py-3 text-xs font-semibold uppercase tracking-[0.36em] transition-all duration-300",
|
||||
"bg-white/90 text-[#1c1713] shadow-[0_10px_40px_rgba(0,0,0,0.22)] hover:bg-white"
|
||||
)}
|
||||
className="rounded-full bg-white px-6 py-2 text-sm font-semibold uppercase tracking-wide text-black transition-colors hover:bg-white/90"
|
||||
>
|
||||
<Link href="/book" className="flex items-center gap-2">
|
||||
<span>Book Now</span>
|
||||
<ArrowUpRight className="h-4 w-4 -translate-y-[1px] transition-transform duration-300 group-hover:translate-x-1 group-hover:-translate-y-1" />
|
||||
</Link>
|
||||
<Link href="/book">Book Now</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<button
|
||||
className="relative inline-flex rounded-full border border-white/20 p-3 text-white transition-all duration-300 hover:border-white/40 lg:hidden"
|
||||
className="rounded-lg border border-white/20 p-2 text-white transition-colors hover:border-white/40 lg:hidden"
|
||||
onClick={handleToggleMenu}
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
{isOpen ? <X size={22} /> : <Menu size={22} />}
|
||||
{isOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{isOpen && (
|
||||
<div className="relative z-10 mt-1 overflow-hidden rounded-3xl border border-white/10 bg-[rgba(21,19,16,0.96)] px-6 py-8 shadow-[0_35px_60px_-30px_rgba(0,0,0,0.65)] lg:hidden">
|
||||
<div className="absolute left-0 right-0 top-full mt-2 mx-5 rounded-2xl border border-white/10 bg-black/95 backdrop-blur-xl px-6 py-6 sm:mx-8 lg:hidden">
|
||||
<NavigationMenu viewport={false} className="w-full">
|
||||
<NavigationMenuList className="flex w-full flex-col gap-4">
|
||||
{navItems.map((item) => {
|
||||
@ -221,10 +196,10 @@ export function Navigation() {
|
||||
|
||||
if (item.isButton) {
|
||||
return (
|
||||
<NavigationMenuItem key={item.id} className="w-full pt-4">
|
||||
<NavigationMenuItem key={item.id} className="w-full pt-2">
|
||||
<Button
|
||||
asChild
|
||||
className="w-full rounded-full bg-white/90 py-4 text-sm font-semibold uppercase tracking-[0.32em] text-[#1c1713] shadow-[0_20px_45px_-25px_rgba(255,255,255,0.9)] hover:bg-white"
|
||||
className="w-full rounded-full bg-white py-3 text-sm font-semibold uppercase tracking-wide text-black hover:bg-white/90"
|
||||
>
|
||||
<Link href={item.href} onClick={handleCloseMenu}>
|
||||
{item.label}
|
||||
@ -236,22 +211,19 @@ export function Navigation() {
|
||||
|
||||
return (
|
||||
<NavigationMenuItem key={item.id} className="w-full">
|
||||
<NavigationMenuLink
|
||||
asChild
|
||||
data-active={isActive || undefined}
|
||||
className={cn(
|
||||
"block w-full rounded-2xl border border-transparent px-4 py-4 text-sm font-semibold uppercase tracking-[0.3em] text-white/70 transition-all duration-300",
|
||||
isActive
|
||||
? "border-white/20 bg-white/5 text-white"
|
||||
: "hover:border-white/10 hover:bg-white/5 hover:text-white"
|
||||
)}
|
||||
>
|
||||
<NavigationMenuLink asChild>
|
||||
<Link
|
||||
href={item.href}
|
||||
onClick={(event) => {
|
||||
handleNavClick(event, item)
|
||||
handleCloseMenu()
|
||||
}}
|
||||
className={cn(
|
||||
"block w-full px-4 py-3 text-sm font-medium uppercase tracking-wider transition-colors rounded-lg",
|
||||
isActive
|
||||
? "bg-white/10 text-white"
|
||||
: "text-white/60 hover:bg-white/5 hover:text-white"
|
||||
)}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
|
||||
283
docs/BRAND-LANGUAGE.md
Normal file
283
docs/BRAND-LANGUAGE.md
Normal file
@ -0,0 +1,283 @@
|
||||
# United Tattoo Brand Language Brainstorming Session
|
||||
|
||||
**Session Date:** December 19, 2024
|
||||
**Facilitator:** Business Analyst Mary
|
||||
**Participant:** United Tattoo Team
|
||||
|
||||
## Executive Summary
|
||||
|
||||
**Topic:** Creating a structured brand language rulebook for United Tattoo
|
||||
|
||||
**Session Goals:** Develop authentic brand language guidelines that transform generic copy into distinctive United Tattoo voice
|
||||
|
||||
**Techniques Used:** Progressive technique flow with analyst-recommended methods
|
||||
|
||||
**Total Ideas Generated:** [To be updated during session]
|
||||
|
||||
## Technique Sessions
|
||||
|
||||
### Assumption Reversal - 10 minutes
|
||||
|
||||
**Description:** Identify what United Tattoo would NEVER say to establish authentic boundaries
|
||||
|
||||
**Ideas Generated:**
|
||||
1. "For the ones who live loud, tattoo proud, and believe in better" - forced verb usage, empty promises
|
||||
2. "This isn't your average tattoo shop" - defensive positioning, cliche opening
|
||||
3. "We're here to rewrite the narrative" - vague corporate speak with no clear meaning
|
||||
4. "where everyone feels seen, respected, and hyped to walk through our doors" - outdated slang, trying too hard
|
||||
5. "elevate the experience" - buzzword soup, unnecessarily verbose
|
||||
6. "create a space where real connection matters" - stating obvious human nature as unique value
|
||||
7. "we hire great people, not just great artists" - setting bar impossibly low
|
||||
8. "bring both skill and soul to the table" - cliche metaphor mixing
|
||||
9. "Every tattoo here is a story, a statement, and a shared moment" - overwrought emotional manipulation
|
||||
|
||||
**Insights Discovered:**
|
||||
- LLM-generated copy defaults to meaningless adjective stacking
|
||||
- Generic "transformation" language ignores actual tattoo shop reality
|
||||
- Forced emotional narratives sound inauthentic and manipulative
|
||||
- Defensive positioning ("not your average") suggests insecurity
|
||||
- Buzzwords replace actual concrete value propositions
|
||||
|
||||
**Notable Connections:**
|
||||
- All bad examples try to be everything to everyone instead of something specific
|
||||
- Corporate speak completely disconnects from tattoo culture authenticity
|
||||
- Overuse of transformation/elevation language feels condescending
|
||||
|
||||
### Role Playing - 15 minutes
|
||||
|
||||
**Description:** Discover authentic voice through real stakeholder interactions
|
||||
|
||||
**Ideas Generated:**
|
||||
|
||||
**Nervous First-Timer Response:**
|
||||
- "Hey that's okay! Girl we all have been scared of getting a tattoo before, shit, I get scared sometimes even now"
|
||||
- "You just let me know if you need a break, we can step out at any time, take a smoke break, just hang out"
|
||||
- "We can go at your pace"
|
||||
|
||||
**Picky Client Response:**
|
||||
- "Holy-fuck yeah- that's a lot-- that's okay though, I love having references!"
|
||||
- "Do you mind taking a seat so you can break this down for me?"
|
||||
|
||||
**Insights Discovered:**
|
||||
- Authentic voice uses mild profanity naturally, not performatively
|
||||
- Real empathy comes from shared experience ("I get scared sometimes even now")
|
||||
- Practical solutions over emotional theater ("take a smoke break, just hang out")
|
||||
- Direct acknowledgment of chaos without judgment ("that's a lot")
|
||||
- Collaborative problem-solving approach ("break this down for me")
|
||||
|
||||
**Notable Connections:**
|
||||
- Authenticity = vulnerability + practicality
|
||||
- Real tattoo artists talk like humans, not customer service scripts
|
||||
- Genuine care shows through actions offered, not feelings described
|
||||
|
||||
### First Principles Thinking - 15 minutes
|
||||
|
||||
**Description:** Extract fundamental language rules from authentic interactions
|
||||
|
||||
**Core Rules Identified:**
|
||||
|
||||
**Rule 1: Direct acknowledgment beats diplomatic deflection**
|
||||
- Rationale: When you leave things unsaid, people internalize and make assumptions. Blunt but friendly prevents judgment feelings.
|
||||
- Bad: "We understand everyone has different comfort levels"
|
||||
- Good: "Holy-fuck yeah- that's a lot"
|
||||
|
||||
**Rule 2: Offer practical solutions, not emotional theater**
|
||||
- Rationale: "I'm not your fuckin dad" - beautiful humans interacting with beautiful humans, not therapy sessions
|
||||
- Bad: "create a safe space where you feel supported"
|
||||
- Good: "take a smoke break, just hang out"
|
||||
|
||||
**Rule 3: Plain speaking about pricing/time**
|
||||
- Example: "Hey so because this is 6 inches long and I can tell that the complexity of the linework and shading is gonna take me an extra 2 hours, I'd feel comfortable doing this for $650, does that work for you?"
|
||||
- Principle: Transparent, specific, respectful
|
||||
|
||||
**Rule 4: Handle difficult clients with patience, like a human**
|
||||
- No elaborate customer service scripts
|
||||
- Human-to-human problem solving
|
||||
|
||||
**Rule 5: Describe work in quantifiable terms with justified confidence**
|
||||
- Bad: "93% proficient in opaques" (arbitrary metrics)
|
||||
- Good: "I've been doing opaques on shading for 5 years, would you like to see some examples so you can judge for yourself?"
|
||||
- Principle: If the artist, shop, portfolio or work can't justify the statement, don't make it
|
||||
|
||||
**Rule 6: Talk about other shops with kindness**
|
||||
- "The shop doesn't fucking matter. It's a building with some idiots in it. People only come for the idiots."
|
||||
- Focus on the artists, not competitive positioning
|
||||
|
||||
**Insights Discovered:**
|
||||
- Transparency prevents assumptions and judgment feelings
|
||||
- Confidence must be backed by demonstrable skill/experience
|
||||
- Human-to-human interaction trumps customer service performance
|
||||
- Competition isn't about shops, it's about individual artist quality
|
||||
|
||||
### Morphological Analysis - 10 minutes
|
||||
|
||||
**Description:** Test filtering system by transforming bad copy through United Tattoo rules
|
||||
|
||||
**Copy Transformation Examples:**
|
||||
|
||||
**Original:** "Artistry with integrity"
|
||||
**Rules Applied:** Direct acknowledgment + quantifiable terms
|
||||
**United Tattoo Version:** "We've been tattooing for [X years]. Here's our work."
|
||||
|
||||
**Original:** "More than ink—it's identity"
|
||||
**Rules Applied:** No emotional theater + plain speaking
|
||||
**United Tattoo Version:** "Good tattoos that'll look good in 20 years"
|
||||
|
||||
**Original:** "A space where creativity thrives"
|
||||
**Rules Applied:** Focus on the idiots, not the building
|
||||
**United Tattoo Version:** "Artists who know what they're doing"
|
||||
|
||||
**Test Case:** "We're here to rewrite the narrative, where everyone feels seen, respected, and hyped to walk through our doors"
|
||||
**United Tattoo Filtered Version:** "It doesn't matter who you are, you will always have a home with the United Tattoo family."
|
||||
|
||||
**Analysis of Transformation:**
|
||||
- Removed corporate buzzwords ("rewrite the narrative")
|
||||
- Replaced performative emotions ("hyped") with genuine warmth
|
||||
- Maintained inclusivity message but made it personal and direct
|
||||
- Used "family" concept authentically rather than as marketing device
|
||||
|
||||
### Mind Mapping - 10 minutes
|
||||
|
||||
**Description:** Organize findings into practical rulebook structure
|
||||
|
||||
**Central Concept:** United Tattoo Brand Language Filter
|
||||
|
||||
**Branch 1: Core Principles**
|
||||
- Respect reader intelligence - no big empty words that only impress idiots
|
||||
- Use common ground language - not corporate speak or legal jargon
|
||||
- Direct acknowledgment beats diplomatic deflection
|
||||
- Practical solutions over emotional theater
|
||||
|
||||
**Branch 2: Language Guidelines**
|
||||
- Plain speaking about pricing/process/time
|
||||
- Justified confidence only (backed by demonstrable skill)
|
||||
- Human-to-human tone in all interactions
|
||||
- Transparency prevents assumptions and judgment
|
||||
|
||||
**Branch 3: Content Transformation Rules**
|
||||
- Remove corporate buzzwords and meaningless adjective stacking
|
||||
- Replace performative emotions with genuine warmth
|
||||
- Convert abstract concepts to concrete actions
|
||||
- Focus on artists and work, not building or brand positioning
|
||||
|
||||
**Branch 4: Communication Standards**
|
||||
- Do not use words average person won't understand
|
||||
- Goal: efficient communication on common ground
|
||||
- Avoid condescending lawyer-speak and dehumanizing corporate language
|
||||
- Need examples demonstrating accessible vs. inaccessible language
|
||||
|
||||
**Insights Discovered:**
|
||||
- Intelligence respect = foundation of authentic communication
|
||||
- Common ground language builds connection vs. corporate performance language
|
||||
- Accessibility isn't dumbing down - it's efficient human communication
|
||||
- Everything needs clear guidelines - meet but never exceed bare minimum professionalism
|
||||
- 7th grade reading level should be maximum complexity for any content
|
||||
- Nobody wants to read something 5 times to understand it
|
||||
|
||||
**Practical Examples:**
|
||||
|
||||
**Aftercare Instructions - Bad vs. Good:**
|
||||
- Bad: "As the body's largest organ, your skin deserves careful attention after receiving a tattoo. At United Tattoo, we provide aftercare instructions based on recommended best practices to ensure the proper healing of your new body art. Our goal is to offer the most reliable and accurate information in the industry, informed by insights from medical professionals. These guidelines combine professional expertise, scientific research, and recommendations from the National Environmental Health Association's Body Art Model Code."
|
||||
- Good: "### Read our aftercare instructions: *(informed by the National Environmental Health Association's Body Art Model Code)*"
|
||||
|
||||
**Pricing Communication:**
|
||||
- Approach: "Pricing custom tattoos is hard. It depends on the artist and varies from one tattoo to the next."
|
||||
|
||||
**Tattoo Style Explanations:**
|
||||
- Format: "this is realism. this is american traditional this is neotraditional this is cyber sigilism"
|
||||
|
||||
**Notable Connections:**
|
||||
- Brevity respects time and intelligence
|
||||
- Direct statements eliminate confusion
|
||||
- Professional credibility through source citation, not verbose explanation
|
||||
- Practical honesty about complexity instead of false simplification
|
||||
|
||||
## Idea Categorization
|
||||
|
||||
## Idea Categorization
|
||||
|
||||
### Immediate Opportunities
|
||||
*Ideas ready to implement now*
|
||||
|
||||
1. **7th Grade Reading Level Standard**
|
||||
- Description: All content must be understandable without re-reading
|
||||
- Why immediate: Clear communication prevents customer confusion and builds trust
|
||||
- Resources needed: Reading level checker tool, content audit
|
||||
|
||||
2. **Minimal Professional Standard**
|
||||
- Description: Meet but never exceed bare minimum professionalism
|
||||
- Why immediate: Eliminates pretentious language that alienates customers
|
||||
- Resources needed: Style guide with specific examples
|
||||
|
||||
3. **Honest Complexity Acknowledgment**
|
||||
- Description: "Pricing custom tattoos is hard" approach to difficult topics
|
||||
- Why immediate: Builds trust through honesty vs. false simplification
|
||||
- Resources needed: Template responses for complex topics
|
||||
|
||||
### Future Innovations
|
||||
*Ideas requiring development/research*
|
||||
|
||||
1. **Complete Content Transformation System**
|
||||
- Description: LLM filter that transforms any input through United Tattoo rules
|
||||
- Development needed: Training examples, rule weighting, testing protocols
|
||||
- Timeline estimate: 2-3 months development and testing
|
||||
|
||||
2. **Industry-Wide Language Movement**
|
||||
- Description: Influence other tattoo shops to adopt authentic communication
|
||||
- Development needed: Case studies, success metrics, outreach strategy
|
||||
- Timeline estimate: 6-12 months for measurable impact
|
||||
|
||||
### Moonshots
|
||||
*Ambitious, transformative concepts*
|
||||
|
||||
1. **Anti-Corporate Communication Standard for Service Industries**
|
||||
- Description: United Tattoo approach becomes model for all local businesses
|
||||
- Transformative potential: Reshape how small businesses communicate authentically
|
||||
- Challenges to overcome: Corporate marketing industry resistance, scaling personalization
|
||||
|
||||
### Insights & Learnings
|
||||
*Key realizations from the session*
|
||||
|
||||
- Corporate speak exists because people think it sounds professional, but it actually insults customer intelligence
|
||||
- Authentic tattoo shop communication = vulnerability + practicality + justified confidence
|
||||
- The best language guideline is asking "Would a human being actually say this?"
|
||||
- Brevity that respects time and intelligence builds more trust than verbose explanations
|
||||
- Professional credibility comes from source citation and honest complexity acknowledgment, not big words
|
||||
|
||||
## Action Planning
|
||||
|
||||
## Action Planning
|
||||
|
||||
### Top 3 Priority Ideas
|
||||
|
||||
#### #1 Priority: Implement 7th Grade Reading Level Standard
|
||||
- **Rationale:** Immediate impact on all customer communications, eliminates confusion and re-reading
|
||||
- **Next steps:** Audit current website copy, create reading level checklist, rewrite problem areas
|
||||
- **Resources needed:** Reading level checker tool, content inventory spreadsheet
|
||||
- **Timeline:** 2-3 weeks for complete website overhaul
|
||||
|
||||
#### #2 Priority: Create LLM Brand Language Filter
|
||||
- **Rationale:** Scalable solution for all future content creation, prevents regression to corporate speak
|
||||
- **Next steps:** Document all transformation rules with examples, test with current bad copy
|
||||
- **Resources needed:** Rule documentation, before/after examples database, LLM prompt engineering
|
||||
- **Timeline:** 1-2 weeks for initial filter creation and testing
|
||||
|
||||
#### #3 Priority: Transform High-Impact Pages First
|
||||
- **Rationale:** Focus on pages customers see most (pricing, aftercare, artist bios)
|
||||
- **Next steps:** Identify top 5 customer-facing pages, apply rules, A/B test if possible
|
||||
- **Resources needed:** Analytics data for page priority, rewrite time allocation
|
||||
- **Timeline:** 1 week for core page transformation
|
||||
|
||||
## Reflection & Follow-up
|
||||
|
||||
### What Worked Well
|
||||
|
||||
### Areas for Further Exploration
|
||||
|
||||
### Recommended Follow-up Techniques
|
||||
|
||||
### Questions That Emerged
|
||||
|
||||
---
|
||||
|
||||
*Session facilitated using the BMAD-METHOD™ brainstorming framework*
|
||||
Loading…
x
Reference in New Issue
Block a user