diff --git a/components/portfolio/CapabilityRows.tsx b/components/portfolio/CapabilityRows.tsx new file mode 100644 index 0000000..69b36f7 --- /dev/null +++ b/components/portfolio/CapabilityRows.tsx @@ -0,0 +1,54 @@ +"use client"; + +import { m, useReducedMotion } from "motion/react"; + +import { capabilities } from "@/lib/portfolio"; + +export function CapabilityRows() { + const shouldReduceMotion = useReducedMotion(); + + return ( + + + + CAPABILITIES + + Built for hostile constraints. + + + /.01—/.05 + + + + {capabilities.map((capability, index) => ( + + + {capability.text} + + + /.{capability.index} + + + ))} + + + ); +} diff --git a/components/portfolio/FeaturedDossier.tsx b/components/portfolio/FeaturedDossier.tsx index c242f11..c6afd56 100644 --- a/components/portfolio/FeaturedDossier.tsx +++ b/components/portfolio/FeaturedDossier.tsx @@ -34,7 +34,7 @@ export function FeaturedDossier() { id="featured-dossier-title" className="font-display translate-y-4 text-[clamp(4.5rem,18vw,15rem)] font-semibold uppercase leading-[0.72] tracking-[-0.08em] text-blacksite-text" > - {featuredDossier.title} + {featuredDossier.title.toUpperCase()} @@ -74,7 +74,7 @@ export function FeaturedDossier() { key={link.href} href={link.href} target="_blank" - rel="noreferrer" + rel="noopener noreferrer" className="group flex items-center justify-between gap-4 border border-blacksite-line px-4 py-3 font-mono text-xs uppercase tracking-[0.14em] text-blacksite-text transition-colors hover:border-signal-cyan/70 hover:text-signal-cyan focus-visible:outline-signal-cyan" > {link.label} diff --git a/components/portfolio/Manifesto.tsx b/components/portfolio/Manifesto.tsx new file mode 100644 index 0000000..82256b2 --- /dev/null +++ b/components/portfolio/Manifesto.tsx @@ -0,0 +1,34 @@ +"use client"; + +import { m, useReducedMotion } from "motion/react"; + +import { manifesto } from "@/lib/portfolio"; + +export function Manifesto() { + const shouldReduceMotion = useReducedMotion(); + const [beforeSurvive, afterSurvive = ""] = manifesto.split("survive contact"); + const [betweenAccents, afterProof = ""] = afterSurvive.split("proof"); + + return ( + + OPERATING PRINCIPLE + + {beforeSurvive} + survive contact + {betweenAccents} + proof + {afterProof} + + + ); +}
CAPABILITIES
/.01—/.05
+ {capability.text} +
+ /.{capability.index} +
OPERATING PRINCIPLE