Improve emoji design

This commit is contained in:
MartinBraquet
2026-06-03 16:30:22 +02:00
parent 086e827628
commit e714c523bb
4 changed files with 142 additions and 64 deletions

View File

@@ -1,6 +1,8 @@
import {AdjustmentsHorizontalIcon, EyeIcon, UsersIcon} from '@heroicons/react/24/outline'
import {discordLink, githubRepo} from 'common/constants'
import Link from 'next/link'
import {useEffect, useRef} from 'react'
import {ComponentType, ReactNode, SVGProps, useEffect, useRef} from 'react'
import {FaDiscord, FaGithub} from 'react-icons/fa'
import {Col} from 'web/components/layout/col'
import {Row} from 'web/components/layout/row'
import {SignUpButton} from 'web/components/nav/sidebar'
@@ -9,8 +11,10 @@ import {useT} from 'web/lib/locale'
// ─── Types ────────────────────────────────────────────────────────────────────
type IconType = ComponentType<SVGProps<SVGSVGElement>>
interface FeatureCardProps {
icon: string
icon: IconType
title: string
text: string
}
@@ -31,18 +35,18 @@ function EyebrowBadge({children}: {children: React.ReactNode}) {
)
}
function FeatureCard({icon, title, text}: FeatureCardProps) {
function FeatureCard({icon: Icon, title, text}: FeatureCardProps) {
return (
<div
className="
group relative overflow-hidden
bg-canvas-50 border-[1.5px] border-canvas-200 rounded-2xl p-7
transition-all duration-200
hover:-translate-y-1 hover:shadow-[0_12px_32px_rgba(44,36,22,0.10)] hover:border-[#C17F3E]
hover:-translate-y-1 hover:shadow-[0_12px_32px_rgba(44,36,22,0.10)] hover:border-primary-500
"
>
<div className="w-11 h-11 rounded-xl bg-canvas-200 border border-canvas-300 flex items-center justify-center text-xl mb-5">
{icon}
<div className="w-11 h-11 rounded-xl bg-primary-100 border border-primary-200 flex items-center justify-center mb-5">
<Icon className="w-5 h-5 text-primary-600" strokeWidth={1.8} />
</div>
<h3 className="font-bold text-ink-1000 mb-2.5">{title}</h3>
<p className="text-sm text-primary-700 leading-relaxed">{text}</p>
@@ -99,7 +103,7 @@ function OpenSourceStrip({
}: {
title: string
description: string
badges: {label: string; url: string; primary?: boolean}[]
badges: {label: string; url: string; primary?: boolean; icon?: ReactNode}[]
}) {
return (
<div className="w-full max-w-3xl bg-canvas-950 dark:bg-canvas-300 rounded-2xl px-10 py-8 flex items-center justify-between gap-6 flex-wrap">
@@ -113,14 +117,15 @@ function OpenSourceStrip({
href={b.url}
key={b.label}
className={`
px-4 py-2 rounded-lg text-sm font-semibold border transition-all duration-150
inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold border transition-all duration-150
${
b.primary
? 'bg-primary-500 text-white border-[#C17F3E] hover:bg-primary-600'
? 'bg-primary-500 text-white border-primary-500 hover:bg-primary-600'
: 'bg-primary-500/30 text-white/75 border-primary-500/30 hover:bg-primary-500/50'
}
`}
>
{b.icon}
{b.label}
</Link>
))}
@@ -191,7 +196,7 @@ export function LoggedOutHome() {
const features: FeatureCardProps[] = [
{
icon: '🔍',
icon: EyeIcon,
title: t('home.feature1.title', 'Radically Transparent'),
text: t(
'home.feature1.text',
@@ -199,7 +204,7 @@ export function LoggedOutHome() {
),
},
{
icon: '🎯',
icon: AdjustmentsHorizontalIcon,
title: t('home.feature2.title', 'Built for Depth'),
text: t(
'home.feature2.text',
@@ -207,7 +212,7 @@ export function LoggedOutHome() {
),
},
{
icon: '🌍',
icon: UsersIcon,
title: t('home.feature3.title', 'Community Owned'),
text: t(
'home.feature3.text',
@@ -217,8 +222,16 @@ export function LoggedOutHome() {
]
const openSourceBadges = [
{label: t('home.strip.github', '⭐ GitHub'), url: githubRepo},
{label: t('home.strip.discord', '📖 Discord'), url: discordLink},
{
label: t('home.strip.github', 'GitHub'),
url: githubRepo,
icon: <FaGithub className="w-4 h-4" />,
},
{
label: t('home.strip.discord', 'Discord'),
url: discordLink,
icon: <FaDiscord className="w-4 h-4" />,
},
{label: t('home.strip.join', 'Join Now →'), url: '/register', primary: true},
]

View File

@@ -1,8 +1,22 @@
import {
BellIcon,
ChatBubbleLeftRightIcon,
CodeBracketIcon,
FlagIcon,
GiftIcon,
GlobeAltIcon,
HeartIcon,
LightBulbIcon,
MagnifyingGlassIcon,
MegaphoneIcon,
ScaleIcon,
SparklesIcon,
} from '@heroicons/react/24/outline'
import clsx from 'clsx'
import {discordLink, formLink, githubRepo} from 'common/constants'
import {DEPLOYED_WEB_URL} from 'common/envs/constants'
import Link from 'next/link'
import {ReactNode} from 'react'
import {ComponentType, ReactNode, SVGProps} from 'react'
import {CopyLinkOrShareButton, ShareProfileOnXButton} from 'web/components/buttons/copy-link-button'
import {GeneralButton} from 'web/components/buttons/general-button'
import {Row} from 'web/components/layout/row'
@@ -12,14 +26,16 @@ import {useT} from 'web/lib/locale'
// ─── Types ────────────────────────────────────────────────────────────────────
type IconType = ComponentType<SVGProps<SVGSVGElement>>
interface FeatureCardProps {
icon: string
icon: IconType
title: string
text: ReactNode
}
interface HelpCardProps {
icon: string
icon: IconType
title: string
text: ReactNode
buttonLabel: string
@@ -30,7 +46,7 @@ interface HelpCardProps {
// ─── Feature Card ─────────────────────────────────────────────────────────────
function FeatureCard({icon, title, text}: FeatureCardProps) {
function FeatureCard({icon: Icon, title, text}: FeatureCardProps) {
return (
<div
className="
@@ -41,8 +57,8 @@ function FeatureCard({icon, title, text}: FeatureCardProps) {
hover:border-primary-500
"
>
<div className="w-11 h-11 rounded-xl bg-canvas-200 border border-canvas-300 flex items-center justify-center text-xl mb-5 flex-shrink-0">
{icon}
<div className="w-11 h-11 rounded-xl bg-primary-100 border border-primary-200 flex items-center justify-center mb-5 flex-shrink-0">
<Icon className="w-5 h-5 text-primary-600" strokeWidth={1.8} />
</div>
<h3 className="font-bold text-ink-900 mb-2.5">{title}</h3>
<p className="text-sm text-ink-500 leading-relaxed">{text}</p>
@@ -52,7 +68,7 @@ function FeatureCard({icon, title, text}: FeatureCardProps) {
// ─── Full-width Feature Card ──────────────────────────────────────────────────
function FeatureCardWide({icon, title, text}: FeatureCardProps) {
function FeatureCardWide({icon: Icon, title, text}: FeatureCardProps) {
return (
<div
className="
@@ -64,8 +80,8 @@ function FeatureCardWide({icon, title, text}: FeatureCardProps) {
hover:border-primary-500
"
>
<div className="w-11 h-11 rounded-xl bg-canvas-200 border border-canvas-300 flex items-center justify-center text-xl flex-shrink-0">
{icon}
<div className="w-11 h-11 rounded-xl bg-primary-100 border border-primary-200 flex items-center justify-center flex-shrink-0">
<Icon className="w-5 h-5 text-primary-600" strokeWidth={1.8} />
</div>
<div className={'min-w-0'}>
<h3 className="font-bold text-ink-900 mb-2">{title}</h3>
@@ -77,7 +93,15 @@ function FeatureCardWide({icon, title, text}: FeatureCardProps) {
// ─── Help Card ────────────────────────────────────────────────────────────────
function HelpCard({icon, title, text, buttonLabel, buttonUrl, buttonPrimary, id}: HelpCardProps) {
function HelpCard({
icon: Icon,
title,
text,
buttonLabel,
buttonUrl,
buttonPrimary,
id,
}: HelpCardProps) {
return (
<div
className="
@@ -92,8 +116,8 @@ function HelpCard({icon, title, text, buttonLabel, buttonUrl, buttonPrimary, id}
// causing the absolute/flex-item to bleed past the corner radius.
// Removed for cross-browser consistency.
>
<div className="w-10 h-10 rounded-xl bg-canvas-200 border border-canvas-300 flex items-center justify-center text-lg mb-4 flex-shrink-0">
{icon}
<div className="w-10 h-10 rounded-xl bg-primary-100 border border-primary-200 flex items-center justify-center mb-4 flex-shrink-0">
<Icon className="w-[18px] h-[18px] text-primary-600" strokeWidth={1.8} />
</div>
<h3 id={id} className="font-bold text-ink-900 mb-2">
{title}
@@ -134,7 +158,10 @@ function ShareStrip({title, text}: {title: string; text: string}) {
return (
<div className="bg-canvas-950 rounded-2xl px-9 py-8 flex items-center justify-between gap-6 flex-wrap">
<div className={'max-w-[450px]'}>
<h3 className="text-white text-lg font-bold mb-1.5">📣 {title}</h3>
<h3 className="text-white text-lg font-bold mb-1.5 flex items-center gap-2.5">
<MegaphoneIcon className="w-5 h-5 text-primary-500 flex-shrink-0" strokeWidth={1.8} />
{title}
</h3>
<p className="text-primary-500 text-sm leading-relaxed">{text}</p>
</div>
<Row className="flex gap-2 flex-wrap">
@@ -178,7 +205,7 @@ export default function About() {
const features: (FeatureCardProps & {wide?: boolean})[] = [
{
icon: '🔍',
icon: MagnifyingGlassIcon,
title: t('about.block.keyword.title', 'Keyword Search the Database'),
text: t(
'about.block.keyword.text',
@@ -186,7 +213,7 @@ export default function About() {
),
},
{
icon: '🔔',
icon: BellIcon,
title: t('about.block.notify.title', 'Get Notified About Searches'),
text: t(
'about.block.notify.text',
@@ -194,17 +221,17 @@ export default function About() {
),
},
{
icon: '🎭',
icon: SparklesIcon,
title: t('about.block.personality.title', 'Personality-Centered'),
text: t('about.block.personality.text', 'Values and interests first, photos are secondary.'),
},
{
icon: '🎁',
icon: GiftIcon,
title: t('about.block.free.title', 'Completely Free'),
text: t('about.block.free.text', 'Subscription-free. Paywall-free. Ad-free.'),
},
{
icon: '🗳️',
icon: ScaleIcon,
title: t('about.block.democratic.title', 'Democratic'),
text: (
<span>
@@ -224,7 +251,7 @@ export default function About() {
),
},
{
icon: '🎯',
icon: FlagIcon,
title: t('about.block.mission.title', 'One Mission'),
text: t(
'about.block.mission.text',
@@ -232,7 +259,7 @@ export default function About() {
),
},
{
icon: '🌍',
icon: GlobeAltIcon,
title: t('about.block.vision.title', 'Vision'),
text: t(
'about.block.vision.text',
@@ -244,7 +271,7 @@ export default function About() {
const helpCards: HelpCardProps[] = [
{
icon: '💡',
icon: LightBulbIcon,
id: 'give-suggestions-or-contribute',
title: t('about.suggestions.title', 'Give Suggestions or Contribute'),
text: t(
@@ -256,7 +283,7 @@ export default function About() {
// buttonPrimary: true,
},
{
icon: '💻',
icon: CodeBracketIcon,
id: 'share',
title: t('about.dev.title', 'Develop the App'),
text: t(
@@ -267,7 +294,7 @@ export default function About() {
buttonUrl: githubRepo,
},
{
icon: '💬',
icon: ChatBubbleLeftRightIcon,
id: 'join-chats',
title: t('about.join.title', 'Join the Community'),
text: t(
@@ -278,7 +305,7 @@ export default function About() {
buttonUrl: discordLink,
},
{
icon: '❤️',
icon: HeartIcon,
id: 'donate',
title: t('about.donate.title', 'Donate'),
text: t(

View File

@@ -1,4 +1,10 @@
import {ReactNode} from 'react'
import {
ChartBarIcon,
InformationCircleIcon,
LifebuoyIcon,
ShieldCheckIcon,
} from '@heroicons/react/24/outline'
import {ComponentType, ReactNode, SVGProps} from 'react'
import {GeneralButton} from 'web/components/buttons/general-button'
import {PageBase} from 'web/components/page-base'
import {SEO} from 'web/components/SEO'
@@ -6,6 +12,8 @@ import {useT} from 'web/lib/locale'
// ─── Types ────────────────────────────────────────────────────────────────────
type IconType = ComponentType<SVGProps<SVGSVGElement>>
interface LinkItem {
url: string
label: string
@@ -13,7 +21,7 @@ interface LinkItem {
}
interface SectionCardProps {
icon: string
icon: IconType
title: string
description: string
links: LinkItem[]
@@ -21,7 +29,7 @@ interface SectionCardProps {
// ─── Section Card ─────────────────────────────────────────────────────────────
function SectionCard({icon, title, description, links}: SectionCardProps) {
function SectionCard({icon: Icon, title, description, links}: SectionCardProps) {
return (
<div
className="
@@ -33,8 +41,8 @@ function SectionCard({icon, title, description, links}: SectionCardProps) {
"
>
{/* Icon */}
<div className="w-11 h-11 rounded-xl bg-canvas-200 border border-canvas-300 flex items-center justify-center text-xl mb-5 flex-shrink-0">
{icon}
<div className="w-11 h-11 rounded-xl bg-primary-100 border border-primary-200 flex items-center justify-center mb-5 flex-shrink-0">
<Icon className="w-5 h-5 text-primary-600" strokeWidth={1.8} />
</div>
{/* Title & description */}
@@ -88,7 +96,7 @@ export default function Organization() {
const sections: SectionCardProps[] = [
{
icon: '',
icon: InformationCircleIcon,
title: t('organization.about.title', 'About us'),
description: t(
'organization.about.desc',
@@ -100,7 +108,7 @@ export default function Organization() {
],
},
{
icon: '📊',
icon: ChartBarIcon,
title: t('organization.proof.title', 'Proof & transparency'),
description: t(
'organization.proof.desc',
@@ -113,7 +121,7 @@ export default function Organization() {
],
},
{
icon: '💬',
icon: LifebuoyIcon,
title: t('organization.contactSection.title', 'Contact & support'),
description: t(
'organization.contactSection.desc',
@@ -125,7 +133,7 @@ export default function Organization() {
],
},
{
icon: '🔒',
icon: ShieldCheckIcon,
title: t('organization.trust.title', 'Trust & legal'),
description: t(
'organization.trust.desc',

View File

@@ -1,3 +1,4 @@
import {CodeBracketIcon, EnvelopeIcon, MegaphoneIcon, UsersIcon} from '@heroicons/react/24/outline'
import {
discordLink,
githubRepo,
@@ -6,22 +7,26 @@ import {
supportEmail,
xLink,
} from 'common/constants'
import {ReactNode} from 'react'
import {ComponentType, ReactNode, SVGProps} from 'react'
import {FaDiscord, FaGithub, FaInstagram, FaReddit} from 'react-icons/fa'
import {FaXTwitter} from 'react-icons/fa6'
import {PageBase} from 'web/components/page-base'
import {SEO} from 'web/components/SEO'
import {useT} from 'web/lib/locale'
// ─── Types ────────────── ──────────────────────────────────────────────────────
type IconType = ComponentType<SVGProps<SVGSVGElement>>
interface SocialLink {
url: string
label: string
icon: string
icon: ReactNode
primary?: boolean
}
interface SectionCardProps {
icon: string
icon: IconType
title: string
description: string
links: SocialLink[]
@@ -47,7 +52,7 @@ function SocialLinkButton({url, label, icon, primary}: SocialLink) {
}
`}
>
{icon && <span className="text-base leading-none">{icon}</span>}
{icon && <span className="flex items-center text-base leading-none">{icon}</span>}
{label}
</a>
)
@@ -55,7 +60,7 @@ function SocialLinkButton({url, label, icon, primary}: SocialLink) {
// ─── Section Card ─────────────────────────────────────────────────────────────
function SectionCard({icon, title, description, links}: SectionCardProps) {
function SectionCard({icon: Icon, title, description, links}: SectionCardProps) {
return (
<div
className="
@@ -67,8 +72,8 @@ function SectionCard({icon, title, description, links}: SectionCardProps) {
"
>
{/* Icon */}
<div className="w-11 h-11 rounded-xl bg-canvas-200 border border-canvas-300 flex items-center justify-center text-xl mb-5 flex-shrink-0">
{icon}
<div className="w-11 h-11 rounded-xl bg-primary-100 border border-primary-200 flex items-center justify-center mb-5 flex-shrink-0">
<Icon className="w-5 h-5 text-primary-600" strokeWidth={1.8} />
</div>
{/* Title & description */}
@@ -113,48 +118,73 @@ export default function Social() {
const sections: SectionCardProps[] = [
{
icon: '💬',
icon: UsersIcon,
title: t('social.community.title', 'Community'),
description: t(
'social.community.desc',
'Join our community chats and shape the platform with us.',
),
links: [
{url: discordLink, label: t('social.discord', 'Discord'), icon: '🎮', primary: true},
{url: redditLink, label: t('social.reddit', 'Reddit'), icon: ''},
{
url: discordLink,
label: t('social.discord', 'Discord'),
icon: <FaDiscord className="w-4 h-4" />,
primary: true,
},
{
url: redditLink,
label: t('social.reddit', 'Reddit'),
icon: <FaReddit className="w-4 h-4" />,
},
// {url: stoatLink, label: t('social.stoat', 'Revolt / Stoat'), icon: '💬'},
],
},
{
icon: '📣',
icon: MegaphoneIcon,
title: t('social.follow.title', 'Follow & Updates'),
description: t(
'social.follow.desc',
'Stay informed about announcements, releases, and news.',
),
links: [
{url: xLink, label: t('social.x', 'X / Twitter'), icon: '𝕏', primary: true},
{url: instagramLink, label: t('social.instagram', 'Instagram'), icon: '📸'},
{
url: xLink,
label: t('social.x', 'X / Twitter'),
icon: <FaXTwitter className="w-4 h-4" />,
primary: true,
},
{
url: instagramLink,
label: t('social.instagram', 'Instagram'),
icon: <FaInstagram className="w-4 h-4" />,
},
],
},
{
icon: '💻',
icon: CodeBracketIcon,
title: t('social.dev.title', 'Development'),
description: t(
'social.dev.desc',
'Explore our source code, open issues, or contribute a PR.',
),
links: [{url: githubRepo, label: t('social.github', 'GitHub'), icon: '⭐', primary: true}],
links: [
{
url: githubRepo,
label: t('social.github', 'GitHub'),
icon: <FaGithub className="w-4 h-4" />,
primary: true,
},
],
},
{
icon: '✉️',
icon: EnvelopeIcon,
title: t('social.contact.title', 'Contact'),
description: t('social.contact.desc', 'Reach out to us directly for inquiries or support.'),
links: [
{
url: `mailto:${supportEmail}`,
label: `${t('social.email_button', 'Email us')}`,
icon: '📧',
icon: <EnvelopeIcon className="w-4 h-4" strokeWidth={1.8} />,
primary: true,
},
],