Sharpen services page and bump deps to patch known vulns

- Brand Motion card rewritten with concrete capability language
- Revenue-share card clarified: no upfront fees, no retainers, low % after launch
- Recent Work section added with Occupy Wallets as the first case study
- Bumped next to ^15.5.15 to patch 2 high and 3 moderate advisories
- Added pnpm override for yaml ^2.8.3 to resolve the transitive next-mdx-remote
  stack-overflow advisory. Production audit now reports no known vulnerabilities.
This commit is contained in:
jwinterm
2026-04-20 13:19:51 -04:00
parent ca5f555918
commit 7eb531170d
4 changed files with 100 additions and 49 deletions
+1 -1
View File
@@ -18,7 +18,7 @@
"framer-motion": "^11.0.0",
"gray-matter": "^4.0.3",
"lucide-react": "^0.350.0",
"next": "^15.1.3",
"next": "^15.5.15",
"next-mdx-remote": "^6.0.0",
"next-themes": "^0.4.6",
"react": "^19.2.4",
+39 -4
View File
@@ -2,6 +2,7 @@ import { DataGrid } from "@repo/ui/procedural/data-grid";
import { Button } from "@repo/ui/components/button";
import { Header } from "@/components/layout/header";
import { MobileNav } from "@/components/layout/mobile-nav";
import Image from "next/image";
import Link from "next/link";
import { Card } from "@repo/ui/components/card";
import type { Metadata } from "next";
@@ -68,8 +69,7 @@ export default function ServicesPage() {
<Card className="glass-card hover:border-indigo-500/30">
<h3 className="text-xl font-bold mb-3">Revenue-Share Model</h3>
<p className="text-base text-muted-foreground leading-relaxed">
No massive setup fees or monthly retainers. We invest in your success
and earn a percentage of sales—aligned incentives from day one.
No upfront fees. No monthly retainers. We earn a low percentage of sales after launch. Aligned incentives, no fixed-cost risk.
</p>
</Card>
<Card className="glass-card hover:border-indigo-500/30">
@@ -100,9 +100,9 @@ export default function ServicesPage() {
</p>
</Card>
<Card className="glass-card hover:border-purple-500/30">
<h3 className="text-xl font-bold mb-3">Brand Motion</h3>
<h3 className="text-xl font-bold mb-3">Brand Motion & Interactive UX</h3>
<p className="text-base text-muted-foreground leading-relaxed">
Smooth, animated interfaces with purposeful motion and visual depth.
Interfaces that move with intent, not decoration. Scroll-driven narratives, data-reactive visuals, and 3D scenes for brands that need to feel alive.
</p>
</Card>
</div>
@@ -134,6 +134,41 @@ export default function ServicesPage() {
</div>
</div>
{/* Recent Work */}
<div className="mb-24">
<div className="text-left mb-10 section-container border-l-4 border-l-amber-500">
<h2 className="text-3xl font-bold mb-2">Recent Work</h2>
<p className="text-muted-foreground text-lg max-w-2xl leading-relaxed">
Long-term partnerships over one-off projects.
</p>
</div>
<Card className="glass-card hover:border-amber-500/30">
<div className="flex items-start gap-4 mb-4">
<Image
src="/images/products/occupy-wallets.png"
alt="Occupy Wallets"
width={72}
height={72}
className="rounded-xl flex-shrink-0"
/>
<div>
<h3 className="text-xl font-bold mb-1">Occupy Wallets</h3>
<a
href="https://occupywallets.art"
target="_blank"
rel="noopener noreferrer"
className="text-sm text-muted-foreground hover:text-primary transition-colors"
>
occupywallets.art
</a>
</div>
</div>
<p className="text-base text-muted-foreground leading-relaxed">
With us since day one. Five years on WordPress, migrating to a custom Medusa v2 storefront this spring.
</p>
</Card>
</div>
<div className="mt-20 p-16 rounded-[2.5rem] bg-gradient-to-br from-slate-900 via-slate-800 to-indigo-950 text-white text-center shadow-2xl relative overflow-hidden group border-2 border-white/5">
<div className="absolute inset-0 bg-blue-500/10 opacity-0 group-hover:opacity-100 transition-opacity" />
<h2 className="text-4xl font-bold mb-6 relative z-10 tracking-tight">Let's build together</h2>
+5
View File
@@ -21,5 +21,10 @@
},
"dependencies": {
"@types/react": "^18.0.0"
},
"pnpm": {
"overrides": {
"yaml": "^2.8.3"
}
}
}
+55 -44
View File
@@ -4,6 +4,9 @@ settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
overrides:
yaml: ^2.8.3
importers:
.:
@@ -46,8 +49,8 @@ importers:
specifier: ^0.350.0
version: 0.350.0(react@19.2.4)
next:
specifier: ^15.1.3
version: 15.5.9(@playwright/test@1.57.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
specifier: ^15.5.15
version: 15.5.15(@playwright/test@1.57.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
next-mdx-remote:
specifier: ^6.0.0
version: 6.0.0(@types/react@19.2.14)(react@19.2.4)
@@ -426,56 +429,56 @@ packages:
'@napi-rs/wasm-runtime@0.2.12':
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==}
'@next/env@15.5.9':
resolution: {integrity: sha512-4GlTZ+EJM7WaW2HEZcyU317tIQDjkQIyENDLxYJfSWlfqguN+dHkZgyQTV/7ykvobU7yEH5gKvreNrH4B6QgIg==}
'@next/env@15.5.15':
resolution: {integrity: sha512-vcmyu5/MyFzN7CdqRHO3uHO44p/QPCZkuTUXroeUmhNP8bL5PHFEhik22JUazt+CDDoD6EpBYRCaS2pISL+/hg==}
'@next/eslint-plugin-next@15.5.9':
resolution: {integrity: sha512-kUzXx0iFiXw27cQAViE1yKWnz/nF8JzRmwgMRTMh8qMY90crNsdXJRh2e+R0vBpFR3kk1yvAR7wev7+fCCb79Q==}
'@next/swc-darwin-arm64@15.5.7':
resolution: {integrity: sha512-IZwtxCEpI91HVU/rAUOOobWSZv4P2DeTtNaCdHqLcTJU4wdNXgAySvKa/qJCgR5m6KI8UsKDXtO2B31jcaw1Yw==}
'@next/swc-darwin-arm64@15.5.15':
resolution: {integrity: sha512-6PvFO2Tzt10GFK2Ro9tAVEtacMqRmTarYMFKAnV2vYMdwWc73xzmDQyAV7SwEdMhzmiRoo7+m88DuiXlJlGeaw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-x64@15.5.7':
resolution: {integrity: sha512-UP6CaDBcqaCBuiq/gfCEJw7sPEoX1aIjZHnBWN9v9qYHQdMKvCKcAVs4OX1vIjeE+tC5EIuwDTVIoXpUes29lg==}
'@next/swc-darwin-x64@15.5.15':
resolution: {integrity: sha512-G+YNV+z6FDZTp/+IdGyIMFqalBTaQSnvAA+X/hrt+eaTRFSznRMz9K7rTmzvM6tDmKegNtyzgufZW0HwVzEqaQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@next/swc-linux-arm64-gnu@15.5.7':
resolution: {integrity: sha512-NCslw3GrNIw7OgmRBxHtdWFQYhexoUCq+0oS2ccjyYLtcn1SzGzeM54jpTFonIMUjNbHmpKpziXnpxhSWLcmBA==}
'@next/swc-linux-arm64-gnu@15.5.15':
resolution: {integrity: sha512-eVkrMcVIBqGfXB+QUC7jjZ94Z6uX/dNStbQFabewAnk13Uy18Igd1YZ/GtPRzdhtm7QwC0e6o7zOQecul4iC1w==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@15.5.7':
resolution: {integrity: sha512-nfymt+SE5cvtTrG9u1wdoxBr9bVB7mtKTcj0ltRn6gkP/2Nu1zM5ei8rwP9qKQP0Y//umK+TtkKgNtfboBxRrw==}
'@next/swc-linux-arm64-musl@15.5.15':
resolution: {integrity: sha512-RwSHKMQ7InLy5GfkY2/n5PcFycKA08qI1VST78n09nN36nUPqCvGSMiLXlfUmzmpQpF6XeBYP2KRWHi0UW3uNg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-x64-gnu@15.5.7':
resolution: {integrity: sha512-hvXcZvCaaEbCZcVzcY7E1uXN9xWZfFvkNHwbe/n4OkRhFWrs1J1QV+4U1BN06tXLdaS4DazEGXwgqnu/VMcmqw==}
'@next/swc-linux-x64-gnu@15.5.15':
resolution: {integrity: sha512-nplqvY86LakS+eeiuWsNWvfmK8pFcOEW7ZtVRt4QH70lL+0x6LG/m1OpJ/tvrbwjmR8HH9/fH2jzW1GlL03TIg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@15.5.7':
resolution: {integrity: sha512-4IUO539b8FmF0odY6/SqANJdgwn1xs1GkPO5doZugwZ3ETF6JUdckk7RGmsfSf7ws8Qb2YB5It33mvNL/0acqA==}
'@next/swc-linux-x64-musl@15.5.15':
resolution: {integrity: sha512-eAgl9NKQ84/sww0v81DQINl/vL2IBxD7sMybd0cWRw6wqgouVI53brVRBrggqBRP/NWeIAE1dm5cbKYoiMlqDQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-win32-arm64-msvc@15.5.7':
resolution: {integrity: sha512-CpJVTkYI3ZajQkC5vajM7/ApKJUOlm6uP4BknM3XKvJ7VXAvCqSjSLmM0LKdYzn6nBJVSjdclx8nYJSa3xlTgQ==}
'@next/swc-win32-arm64-msvc@15.5.15':
resolution: {integrity: sha512-GJVZC86lzSquh0MtvZT+L7G8+jMnJcldloOjA8Kf3wXvBrvb6OGe2MzPuALxFshSm/IpwUtD2mIoof39ymf52A==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@next/swc-win32-x64-msvc@15.5.7':
resolution: {integrity: sha512-gMzgBX164I6DN+9/PGA+9dQiwmTkE4TloBNx8Kv9UiGARsr9Nba7IpcBRA1iTV9vwlYnrE3Uy6I7Aj6qLjQuqw==}
'@next/swc-win32-x64-msvc@15.5.15':
resolution: {integrity: sha512-nFucjVdwlFqxh/JG3hWSJ4p8+YJV7Ii8aPDuBQULB6DzUF4UNZETXLfEUk+oI2zEznWWULPt7MeuTE6xtK1HSA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -1948,8 +1951,8 @@ packages:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
next@15.5.9:
resolution: {integrity: sha512-agNLK89seZEtC5zUHwtut0+tNrc0Xw4FT/Dg+B/VLEo9pAcS9rtTKpek3V6kVcVwsB2YlqMaHdfZL4eLEVYuCg==}
next@15.5.15:
resolution: {integrity: sha512-VSqCrJwtLVGwAVE0Sb/yikrQfkwkZW9p+lL/J4+xe+G3ZA+QnWPqgcfH1tDUEuk9y+pthzzVFp4L/U8JerMfMQ==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
@@ -2115,7 +2118,7 @@ packages:
jiti: '>=1.21.0'
postcss: '>=8.0.9'
tsx: ^4.8.1
yaml: ^2.4.2
yaml: ^2.8.3
peerDependenciesMeta:
jiti:
optional: true
@@ -2657,6 +2660,11 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
yaml@2.8.3:
resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==}
engines: {node: '>= 14.6'}
hasBin: true
yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
@@ -2947,34 +2955,34 @@ snapshots:
'@tybys/wasm-util': 0.10.1
optional: true
'@next/env@15.5.9': {}
'@next/env@15.5.15': {}
'@next/eslint-plugin-next@15.5.9':
dependencies:
fast-glob: 3.3.1
'@next/swc-darwin-arm64@15.5.7':
'@next/swc-darwin-arm64@15.5.15':
optional: true
'@next/swc-darwin-x64@15.5.7':
'@next/swc-darwin-x64@15.5.15':
optional: true
'@next/swc-linux-arm64-gnu@15.5.7':
'@next/swc-linux-arm64-gnu@15.5.15':
optional: true
'@next/swc-linux-arm64-musl@15.5.7':
'@next/swc-linux-arm64-musl@15.5.15':
optional: true
'@next/swc-linux-x64-gnu@15.5.7':
'@next/swc-linux-x64-gnu@15.5.15':
optional: true
'@next/swc-linux-x64-musl@15.5.7':
'@next/swc-linux-x64-musl@15.5.15':
optional: true
'@next/swc-win32-arm64-msvc@15.5.7':
'@next/swc-win32-arm64-msvc@15.5.15':
optional: true
'@next/swc-win32-x64-msvc@15.5.7':
'@next/swc-win32-x64-msvc@15.5.15':
optional: true
'@nodelib/fs.scandir@2.1.5':
@@ -4901,9 +4909,9 @@ snapshots:
react: 19.2.4
react-dom: 19.2.4(react@19.2.4)
next@15.5.9(@playwright/test@1.57.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
next@15.5.15(@playwright/test@1.57.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
dependencies:
'@next/env': 15.5.9
'@next/env': 15.5.15
'@swc/helpers': 0.5.15
caniuse-lite: 1.0.30001764
postcss: 8.4.31
@@ -4911,14 +4919,14 @@ snapshots:
react-dom: 19.2.4(react@19.2.4)
styled-jsx: 5.1.6(react@19.2.4)
optionalDependencies:
'@next/swc-darwin-arm64': 15.5.7
'@next/swc-darwin-x64': 15.5.7
'@next/swc-linux-arm64-gnu': 15.5.7
'@next/swc-linux-arm64-musl': 15.5.7
'@next/swc-linux-x64-gnu': 15.5.7
'@next/swc-linux-x64-musl': 15.5.7
'@next/swc-win32-arm64-msvc': 15.5.7
'@next/swc-win32-x64-msvc': 15.5.7
'@next/swc-darwin-arm64': 15.5.15
'@next/swc-darwin-x64': 15.5.15
'@next/swc-linux-arm64-gnu': 15.5.15
'@next/swc-linux-arm64-musl': 15.5.15
'@next/swc-linux-x64-gnu': 15.5.15
'@next/swc-linux-x64-musl': 15.5.15
'@next/swc-win32-arm64-msvc': 15.5.15
'@next/swc-win32-x64-msvc': 15.5.15
'@playwright/test': 1.57.0
sharp: 0.34.5
transitivePeerDependencies:
@@ -5737,7 +5745,7 @@ snapshots:
vfile-matter@5.0.1:
dependencies:
vfile: 6.0.3
yaml: 2.8.2
yaml: 2.8.3
vfile-message@4.0.3:
dependencies:
@@ -5798,7 +5806,10 @@ snapshots:
wrappy@1.0.2: {}
yaml@2.8.2: {}
yaml@2.8.2:
optional: true
yaml@2.8.3: {}
yocto-queue@0.1.0: {}