forum: user profile pages + clickable bylines + neon pulse favicon

USER PROFILES (/forum/user/[username]):
- New API at /api/forum/user-by-username/[username] resolves by
  username OR display_name (URL-encoded), since forum threads/replies
  store author_name = display_name. Returns the persona's profile,
  thread history (up to 50), and recent replies (up to 20).
- New page renders the persona card with archetype badge
  (Audio Engineer / Colorist / etc.) + expertise level badge
  (beginner/intermediate/senior) + role title, company, location,
  years_experience, join date, and an expertise-tags chip row.
- Two columns underneath: "Threads started" and "Recent replies"
  with proper deep-links into each thread.
- Author names in /forum, /forum/[slug], and /forum/thread/[id] are
  now <Link> elements pointing to /forum/user/<displayname>, with
  onClick=stopPropagation so the card-level click handler doesn't
  also fire.

FAVICON:
- Hand-built neon pulse waveform — emerald→cyan→purple gradient on
  dark navy background, designed to read at 16×16 to 256×256.
- Multi-resolution favicon.ico (16/32/48/64) + SVG + PNGs at
  16/32/48/64/96/192/256 under /static/favicons/.
- layout.tsx icons block now references all sizes including the
  apple-touch sizes (192, 256).

No env / DB changes here — pure deploy.
This commit is contained in:
Ryan Salazar
2026-05-20 12:56:56 +00:00
parent dc166dfb10
commit f6b52f7c2d
15 changed files with 407 additions and 8 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256">
<defs>
<!-- Diagonal cyan→emerald sweep with a purple highlight on the peak -->
<linearGradient id="g" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#00d4ff"/>
<stop offset="55%" stop-color="#00ff9f"/>
<stop offset="100%" stop-color="#c400ff"/>
</linearGradient>
<!-- subtle glow for the peak so the icon reads at 16px -->
<filter id="glow" x="-20%" y="-20%" width="140%" height="140%">
<feGaussianBlur stdDeviation="3" result="b"/>
<feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<!-- Rounded-square dark background -->
<rect x="0" y="0" width="256" height="256" rx="44" fill="#050a08"/>
<!-- Pulse / waveform: a tight ECG-style spike that reads as "beat".
The shape is intentionally bold and asymmetric so the silhouette
survives 16×16 antialiasing. -->
<g fill="none" stroke="url(#g)" stroke-width="22" stroke-linecap="round"
stroke-linejoin="round" filter="url(#glow)">
<path d="M 24 140
L 78 140
L 100 92
L 122 200
L 144 60
L 166 168
L 188 140
L 232 140"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB