DP17: use folds Icons + named brand-color consts in UrlPreviewCard

Replace literal-glyph UI icons in the URL preview cards with folds
Icon/Icons components, and hoist hardcoded provider brand hex values
into a single named BRAND_COLORS map.

Glyph -> folds icon:
- TikTok/Spotify musical note (♫) -> Icons.VolumeHigh
- Portrait play button (▶)        -> Icons.Play
- Reddit comment count (💬)       -> Icons.Message
- Steam gear (⚙)                  -> Icons.Setting
All use size="Inherit" so they keep the surrounding font-size/color.

Brand hex now referenced via BRAND_COLORS (tiktok, spotify, steam,
twitch, reddit, discord, npm, stackOverflow) instead of scattered
literals; colors are byte-for-byte identical and remain fixed brand
identities (not converted to TDS theme vars).

The game controller glyph (🎮) is left as-is: folds has no game/
controller icon and no close semantic match.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 23:40:49 -04:00
parent 101e4116e8
commit 4fa4327a18
@@ -33,6 +33,22 @@ import {
const linkStyles = { color: color.Success.Main };
// ---------------------------------------------------------------------------
// Provider brand identity colors.
// These are official brand-palette values (logos, badges), NOT theme colors,
// so they intentionally stay as fixed hex and must not become --lt-* TDS vars.
// ---------------------------------------------------------------------------
const BRAND_COLORS = {
tiktok: '#EE1D52',
spotify: '#1db954',
steam: '#c7d5e0',
twitch: '#9146ff',
reddit: '#ff4500',
discord: '#5865f2',
npm: '#cb3837',
stackOverflow: '#f48024',
} as const;
// ---------------------------------------------------------------------------
// Helpers — URL parsing & variant detection
// ---------------------------------------------------------------------------
@@ -474,7 +490,11 @@ function TikTokCard({
<div className={previewCss.ShortsHeader}>
{/* TikTok badge with musical note icon */}
<span className={`${previewCss.SiteBadge} ${previewCss.BadgeTikTok}`}>
<span style={{ color: '#EE1D52', marginRight: '2px' }}></span>
<Icon
style={{ color: BRAND_COLORS.tiktok, marginRight: '2px' }}
size="Inherit"
src={Icons.VolumeHigh}
/>
TikTok
</span>
{username && (
@@ -512,12 +532,14 @@ function TikTokCard({
loading="lazy"
/>
<div className={previewCss.PortraitPlayOverlay}>
<div className={previewCss.PortraitPlayButton}></div>
<div className={previewCss.PortraitPlayButton}>
<Icon size="Inherit" src={Icons.Play} />
</div>
</div>
</a>
) : (
<div className={previewCss.PortraitPlaceholder}>
<span style={{ color: '#EE1D52' }}></span>
<Icon style={{ color: BRAND_COLORS.tiktok }} size="Inherit" src={Icons.VolumeHigh} />
</div>
)}
<Box grow="Yes" direction="Column" gap="100">
@@ -828,7 +850,7 @@ function TwitchCard({
width={28}
height={28}
viewBox="0 0 24 24"
fill="#9146ff"
fill={BRAND_COLORS.twitch}
aria-hidden="true"
role="img"
>
@@ -921,11 +943,11 @@ function RedditCard({
width={28}
height={28}
viewBox="0 0 24 24"
fill="#ff4500"
fill={BRAND_COLORS.reddit}
aria-hidden="true"
role="img"
>
<circle cx="12" cy="12" r="12" fill="#ff4500" />
<circle cx="12" cy="12" r="12" fill={BRAND_COLORS.reddit} />
<path
fill="#ffffff"
d="M20 12a2 2 0 0 0-2-2 2 2 0 0 0-1.36.54C15.28 9.8 13.72 9.4 12 9.39l.7-3.26 2.23.47a1.4 1.4 0 1 0 .15-.69l-2.5-.52a.25.25 0 0 0-.29.19l-.78 3.65c-1.74.06-3.3.46-4.63 1.17A2 2 0 0 0 4 12a2 2 0 0 0 1.07 1.76 3.5 3.5 0 0 0 0 .49C5.07 16.69 8.27 19 12.07 19s6.97-2.31 6.97-4.75a3.5 3.5 0 0 0 0-.47A2 2 0 0 0 20 12zm-13 2a1 1 0 1 1 2 0 1 1 0 0 1-2 0zm5.59 2.71c-.72.72-2.1.77-2.53.77s-1.82-.05-2.53-.77a.25.25 0 0 1 .35-.35c.46.46 1.48.62 2.18.62s1.72-.16 2.18-.62a.25.25 0 0 1 .35.35zm-.15-1.71a1 1 0 1 1 2 0 1 1 0 0 1-2 0z"
@@ -1005,7 +1027,11 @@ function RedditCard({
{/* Stats row */}
<div className={previewCss.RedditMeta}>
{upvotes && <span className={previewCss.RedditUpvote}> {upvotes}</span>}
{comments && <span>💬 {comments}</span>}
{comments && (
<span>
<Icon size="Inherit" src={Icons.Message} /> {comments}
</span>
)}
</div>
</Box>
@@ -1473,7 +1499,11 @@ function SpotifyCard({ url, prev }: { url: string; prev: IPreviewUrlResponse })
justifyContent="Center"
className={previewCss.IconWrapper}
>
<span style={{ fontSize: '2rem', color: '#1db954' }}></span>
<Icon
style={{ fontSize: '2rem', color: BRAND_COLORS.spotify }}
size="Inherit"
src={Icons.VolumeHigh}
/>
</Box>
)}
<UrlPreviewContent>
@@ -1533,7 +1563,11 @@ function SteamCard({ url, prev }: { url: string; prev: IPreviewUrlResponse }) {
justifyContent="Center"
className={previewCss.IconWrapper}
>
<span style={{ fontSize: '1.5rem', color: '#c7d5e0' }}></span>
<Icon
style={{ fontSize: '1.5rem', color: BRAND_COLORS.steam }}
size="Inherit"
src={Icons.Setting}
/>
</Box>
)}
<UrlPreviewContent>
@@ -1640,7 +1674,7 @@ function DiscordCard({ url, prev }: { url: string; prev: IPreviewUrlResponse })
width={28}
height={28}
viewBox="0 0 24 24"
fill="#5865f2"
fill={BRAND_COLORS.discord}
aria-hidden="true"
role="img"
>
@@ -1693,13 +1727,13 @@ function NpmCard({ url, prev }: { url: string; prev: IPreviewUrlResponse }) {
>
{/* npm logo — simple square mark */}
<svg width={32} height={32} viewBox="0 0 18 7" fill="none" aria-hidden="true" role="img">
<rect width="18" height="7" fill="#cb3837" />
<rect width="18" height="7" fill={BRAND_COLORS.npm} />
<rect x="1" y="1" width="4" height="5" fill="white" />
<rect x="2" y="1" width="1" height="4" fill="#cb3837" />
<rect x="2" y="1" width="1" height="4" fill={BRAND_COLORS.npm} />
<rect x="6" y="1" width="4" height="5" fill="white" />
<rect x="7" y="1" width="1" height="3" fill="#cb3837" />
<rect x="7" y="1" width="1" height="3" fill={BRAND_COLORS.npm} />
<rect x="11" y="1" width="4" height="4" fill="white" />
<rect x="12" y="1" width="1" height="3" fill="#cb3837" />
<rect x="12" y="1" width="1" height="3" fill={BRAND_COLORS.npm} />
</svg>
</Box>
<UrlPreviewContent>
@@ -1747,7 +1781,7 @@ function StackOverflowCard({ url, prev }: { url: string; prev: IPreviewUrlRespon
width={28}
height={28}
viewBox="0 0 24 24"
fill="#f48024"
fill={BRAND_COLORS.stackOverflow}
aria-hidden="true"
role="img"
>