diff --git a/apps/web/public/images/products/neroswap.png b/apps/web/public/images/products/neroswap.png new file mode 100644 index 0000000..f7736e6 Binary files /dev/null and b/apps/web/public/images/products/neroswap.png differ diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index ac00e75..9b56441 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -85,7 +85,9 @@ box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25); position: relative; overflow: hidden; - transition: all 300ms; + transition: transform 300ms cubic-bezier(0.16, 1, 0.3, 1), + box-shadow 300ms cubic-bezier(0.16, 1, 0.3, 1), + border-color 300ms ease; } .section-container { @@ -100,6 +102,52 @@ border-color: hsl(var(--primary) / 0.3); } + /* Bento grid entrance animation */ + @keyframes bento-enter { + from { + opacity: 0; + transform: translateY(16px); + } + to { + opacity: 1; + transform: translateY(0); + } + } + + .bento-item { + animation: bento-enter 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; + } + + /* Hover lift for bento links */ + .bento-item:hover .glass-card { + transform: translateY(-4px); + box-shadow: 0 32px 64px -16px rgb(0 0 0 / 0.3); + } + + /* Focus-visible ring for keyboard navigation */ + .bento-item:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 4px; + border-radius: 2.5rem; + } + + /* Respect reduced motion preferences */ + @media (prefers-reduced-motion: reduce) { + .bento-item { + animation: none; + } + .bento-item:hover .glass-card { + transform: none; + } + .glass-card { + transition: border-color 300ms; + } + .glass-card .object-contain, + .glass-card .object-cover { + transition: none !important; + } + } + /* Typography customization for blog posts */ .prose { --tw-prose-body: hsl(var(--foreground)); diff --git a/apps/web/src/components/portfolio/bento-grid.tsx b/apps/web/src/components/portfolio/bento-grid.tsx index bb1d0e9..bcea652 100644 --- a/apps/web/src/components/portfolio/bento-grid.tsx +++ b/apps/web/src/components/portfolio/bento-grid.tsx @@ -6,7 +6,7 @@ export const PortfolioGrid = () => { return (
{/* Row 1: r/CryptoCurrency (2x1) */} - +

r/CryptoCurrency

@@ -27,7 +27,7 @@ export const PortfolioGrid = () => { {/* Row 1: MoonPlace (1x1) */} - +

MoonPlace

@@ -46,7 +46,7 @@ export const PortfolioGrid = () => { {/* Row 1-2: Smirk Wallet (1x2 tall, far right) */} - +

Smirk Wallet

@@ -64,40 +64,27 @@ export const PortfolioGrid = () => { - {/* Row 2: Neroswap (1x1) */} - + {/* Row 2: Neroswap (2x1) */} +

Neroswap

DEX & CEX orderbook aggregator.

-
- - - {/* Row 2: Privacy Labs (1x1) */} - - -
-

Privacy Labs

-
    -
  • Monerogue / Wownerogue
  • -
  • (Blockchain Gaming)
  • -
+
+ Screenshot of Neroswap DEX and CEX orderbook aggregator interface
-
- Screenshots of Monerogue roguelike game and Wowne.ro WebAssembly wallet interface -
{/* Row 2: Bauhaus Echo (1x1) */} - +

Bauhaus Echo

@@ -115,8 +102,8 @@ export const PortfolioGrid = () => { - {/* Row 3: Occupy Wallets (4x1, full width) */} - + {/* Row 3: Occupy Wallets (2x1) */} +

Occupy Wallets

@@ -133,6 +120,28 @@ export const PortfolioGrid = () => {
+ + {/* Row 3: Privacy Labs (2x1) */} + + +
+

Privacy Labs

+
    +
  • Monerogue / Wownerogue
  • +
  • (Blockchain Gaming)
  • +
+
+
+ Screenshots of Monerogue roguelike game and Wowne.ro WebAssembly wallet interface +
+
+
); }; \ No newline at end of file