diff --git a/public/press/assets/raster/Peanut_Full_Logotype-1200.png b/public/press/assets/raster/Peanut_Full_Logotype-1200.png new file mode 100644 index 0000000000..80fc1239ca Binary files /dev/null and b/public/press/assets/raster/Peanut_Full_Logotype-1200.png differ diff --git a/public/press/assets/raster/Peanut_Wordmark-1200.png b/public/press/assets/raster/Peanut_Wordmark-1200.png new file mode 100644 index 0000000000..626a255e18 Binary files /dev/null and b/public/press/assets/raster/Peanut_Wordmark-1200.png differ diff --git a/public/press/assets/raster/peanut-icon-1024-pink.png b/public/press/assets/raster/peanut-icon-1024-pink.png new file mode 100644 index 0000000000..4f037729bd Binary files /dev/null and b/public/press/assets/raster/peanut-icon-1024-pink.png differ diff --git a/public/press/assets/raster/peanut-icon-1024.png b/public/press/assets/raster/peanut-icon-1024.png new file mode 100644 index 0000000000..d11f741de5 Binary files /dev/null and b/public/press/assets/raster/peanut-icon-1024.png differ diff --git a/public/press/assets/raster/peanut-icon-512.png b/public/press/assets/raster/peanut-icon-512.png new file mode 100644 index 0000000000..4147b13447 Binary files /dev/null and b/public/press/assets/raster/peanut-icon-512.png differ diff --git a/public/press/assets/screenshots/en/01-hero.png b/public/press/assets/screenshots/en/01-hero.png new file mode 100644 index 0000000000..0b30e9288d Binary files /dev/null and b/public/press/assets/screenshots/en/01-hero.png differ diff --git a/public/press/assets/screenshots/en/02-qr-pay-local.png b/public/press/assets/screenshots/en/02-qr-pay-local.png new file mode 100644 index 0000000000..46b91932bf Binary files /dev/null and b/public/press/assets/screenshots/en/02-qr-pay-local.png differ diff --git a/public/press/assets/screenshots/en/04-send.png b/public/press/assets/screenshots/en/04-send.png new file mode 100644 index 0000000000..e4429bb3ad Binary files /dev/null and b/public/press/assets/screenshots/en/04-send.png differ diff --git a/public/press/assets/screenshots/en/05-add-money.png b/public/press/assets/screenshots/en/05-add-money.png new file mode 100644 index 0000000000..85c28c4f67 Binary files /dev/null and b/public/press/assets/screenshots/en/05-add-money.png differ diff --git a/public/press/assets/screenshots/en/06-withdraw.png b/public/press/assets/screenshots/en/06-withdraw.png new file mode 100644 index 0000000000..abfba5b139 Binary files /dev/null and b/public/press/assets/screenshots/en/06-withdraw.png differ diff --git a/public/press/assets/screenshots/es-AR/01-hero.png b/public/press/assets/screenshots/es-AR/01-hero.png new file mode 100644 index 0000000000..0dd61e5eaf Binary files /dev/null and b/public/press/assets/screenshots/es-AR/01-hero.png differ diff --git a/public/press/assets/screenshots/es-AR/02-qr-pay-local.png b/public/press/assets/screenshots/es-AR/02-qr-pay-local.png new file mode 100644 index 0000000000..e4c83f1feb Binary files /dev/null and b/public/press/assets/screenshots/es-AR/02-qr-pay-local.png differ diff --git a/public/press/assets/screenshots/es-AR/04-send.png b/public/press/assets/screenshots/es-AR/04-send.png new file mode 100644 index 0000000000..de4e5348a6 Binary files /dev/null and b/public/press/assets/screenshots/es-AR/04-send.png differ diff --git a/public/press/assets/screenshots/es-AR/05-add-money.png b/public/press/assets/screenshots/es-AR/05-add-money.png new file mode 100644 index 0000000000..249545320c Binary files /dev/null and b/public/press/assets/screenshots/es-AR/05-add-money.png differ diff --git a/public/press/assets/screenshots/es-AR/06-withdraw.png b/public/press/assets/screenshots/es-AR/06-withdraw.png new file mode 100644 index 0000000000..f1f11fc15f Binary files /dev/null and b/public/press/assets/screenshots/es-AR/06-withdraw.png differ diff --git a/public/press/assets/screenshots/pt-BR/01-hero.png b/public/press/assets/screenshots/pt-BR/01-hero.png new file mode 100644 index 0000000000..879eaa0814 Binary files /dev/null and b/public/press/assets/screenshots/pt-BR/01-hero.png differ diff --git a/public/press/assets/screenshots/pt-BR/02-qr-pay-local.png b/public/press/assets/screenshots/pt-BR/02-qr-pay-local.png new file mode 100644 index 0000000000..1ec7970202 Binary files /dev/null and b/public/press/assets/screenshots/pt-BR/02-qr-pay-local.png differ diff --git a/public/press/assets/screenshots/pt-BR/04-send.png b/public/press/assets/screenshots/pt-BR/04-send.png new file mode 100644 index 0000000000..dd4bef9482 Binary files /dev/null and b/public/press/assets/screenshots/pt-BR/04-send.png differ diff --git a/public/press/assets/screenshots/pt-BR/05-add-money.png b/public/press/assets/screenshots/pt-BR/05-add-money.png new file mode 100644 index 0000000000..a74f6c9770 Binary files /dev/null and b/public/press/assets/screenshots/pt-BR/05-add-money.png differ diff --git a/public/press/assets/screenshots/pt-BR/06-withdraw.png b/public/press/assets/screenshots/pt-BR/06-withdraw.png new file mode 100644 index 0000000000..4e948de882 Binary files /dev/null and b/public/press/assets/screenshots/pt-BR/06-withdraw.png differ diff --git a/public/press/assets/social/peanut-og-1200x630.png b/public/press/assets/social/peanut-og-1200x630.png new file mode 100644 index 0000000000..210f8ea5fb Binary files /dev/null and b/public/press/assets/social/peanut-og-1200x630.png differ diff --git a/public/press/assets/social/peanut-social-1200x1200.png b/public/press/assets/social/peanut-social-1200x1200.png new file mode 100644 index 0000000000..0057c654c4 Binary files /dev/null and b/public/press/assets/social/peanut-social-1200x1200.png differ diff --git a/src/app/[locale]/(marketing)/press/brand/page.tsx b/src/app/[locale]/(marketing)/press/brand/page.tsx new file mode 100644 index 0000000000..ca746d7c65 --- /dev/null +++ b/src/app/[locale]/(marketing)/press/brand/page.tsx @@ -0,0 +1,231 @@ +import { notFound } from 'next/navigation' +import { type Metadata } from 'next' +import Image from 'next/image' +import Link from 'next/link' +import { generateMetadata as metadataHelper } from '@/app/metadata' +import { MarketingHero } from '@/components/Marketing/MarketingHero' +import { MarketingShell } from '@/components/Marketing/MarketingShell' +import { Card } from '@/components/0_Bruddle/Card' +import { SUPPORTED_LOCALES, getAlternatesFor, isValidLocale } from '@/i18n/config' +import type { Locale } from '@/i18n/types' +import { getTranslations } from '@/i18n' +import { + BRAND_COLORS, + BRAND_FILE_GROUPS, + BRAND_TYPE, + LOGO_RULES, + MASCOTS, + SCREENSHOTS, + SCREENSHOT_LOCALES, + SCREENSHOT_SIZE, +} from '@/data/press-brand' + +// Companion page to /press. /press carries the prose kit (boilerplate, +// taglines, team, company facts) from the mono content mirror; this page +// carries the design side — palette, type, usage rules and every downloadable +// file — which is code-adjacent reference data, not marketing prose. + +interface PageProps { + params: Promise<{ locale: string }> +} + +export async function generateStaticParams() { + if (process.env.NODE_ENV === 'production') return [] + return SUPPORTED_LOCALES.map((locale) => ({ locale })) +} + +export async function generateMetadata({ params }: PageProps): Promise { + const { locale } = await params + if (!isValidLocale(locale)) return {} + + const i18n = getTranslations(locale as Locale) + + return { + ...metadataHelper({ + locale: locale as Locale, + title: `${i18n.pressBrandTitle} | Peanut`, + description: i18n.pressBrandSubtitle, + canonical: `/${locale}/press/brand`, + }), + alternates: { + canonical: `/${locale}/press/brand`, + languages: getAlternatesFor(SUPPORTED_LOCALES, 'press', 'brand'), + }, + } +} + +export default async function PressBrandPage({ params }: PageProps) { + const { locale } = await params + if (!isValidLocale(locale)) notFound() + + const i18n = getTranslations(locale as Locale) + + return ( + <> + + + +
+ + {i18n.pressBrandBackToPress} + + + {/* ---- the mark ---- */} +
+

{i18n.pressBrandTheMark}

+ + Peanut logotype + +
+ +

{i18n.pressBrandDo}

+
    + {LOGO_RULES.do.map((rule) => ( +
  • {rule}
  • + ))} +
+
+ +

{i18n.pressBrandDont}

+
    + {LOGO_RULES.dont.map((rule) => ( +
  • {rule}
  • + ))} +
+
+
+
+ + {/* ---- downloads ---- */} +
+

{i18n.pressBrandDownloads}

+
+ {BRAND_FILE_GROUPS.map((group) => ( + +
+

{group.label}

+

{group.description}

+
+
+ {group.files.map((file) => ( + + {file.name} + {file.meta} + + ))} +
+
+ ))} +
+
+ + {/* ---- palette ---- */} +
+

{i18n.pressBrandPalette}

+
+ {BRAND_COLORS.map((color) => ( + + + + {color.name} + + {color.hex} + + {color.note} + + + ))} +
+
+ + {/* ---- type ---- */} +
+

{i18n.pressBrandTypography}

+
+ {BRAND_TYPE.map((role) => ( + +

{role.role}

+

{role.face}

+

{role.note}

+
+ ))} +
+
+ + {/* ---- screenshots ---- */} +
+

{i18n.pressBrandScreenshots}

+

{i18n.pressBrandScreenshotsNote}

+ {SCREENSHOT_LOCALES.map((shotLocale) => ( +
+

{shotLocale.label}

+
+ {SCREENSHOTS.map((shot) => { + const href = `/press/assets/screenshots/${shotLocale.dir}/${shot.slug}.png` + return ( + + {`${shot.label} + + {shot.label} + + + ) + })} +
+
+ ))} +
+ + {/* ---- mascot ---- */} +
+

{i18n.pressBrandMascot}

+
+ {MASCOTS.map((mascot) => { + const href = `/press/assets/mascots/${mascot.slug}.webp` + return ( + + {mascot.label} + {mascot.label} + + ) + })} +
+
+
+
+ + ) +} diff --git a/src/app/[locale]/(marketing)/press/page.tsx b/src/app/[locale]/(marketing)/press/page.tsx index 23e2c6a30d..48af2c4658 100644 --- a/src/app/[locale]/(marketing)/press/page.tsx +++ b/src/app/[locale]/(marketing)/press/page.tsx @@ -1,6 +1,7 @@ import { notFound } from 'next/navigation' import { type Metadata } from 'next' import Image from 'next/image' +import Link from 'next/link' import { generateMetadata as metadataHelper } from '@/app/metadata' import { MarketingHero } from '@/components/Marketing/MarketingHero' import { MarketingShell } from '@/components/Marketing/MarketingShell' @@ -183,7 +184,12 @@ export default async function PressPage({ params }: PageProps) { {fm.brand_assets && fm.brand_assets.length > 0 && (
-

{i18n.pressBrandAssets}

+
+

{i18n.pressBrandAssets}

+ + {i18n.pressBrandLink} + +
{fm.brand_assets.map((group) => ( diff --git a/src/data/press-brand.ts b/src/data/press-brand.ts new file mode 100644 index 0000000000..2ec3f2d36c --- /dev/null +++ b/src/data/press-brand.ts @@ -0,0 +1,161 @@ +// Brand & assets data for /press/brand. +// +// This is design-system reference data (palette hexes, type rules, file +// manifests) rather than marketing prose, so it lives in code next to the +// files it describes rather than in the mono content mirror. The prose press +// kit — boilerplate, taglines, team, company facts — stays on /press and is +// authored in mono at content/press/{lang}.md. +// +// Source of truth for the values below: +// palette → src/styles/globals.css @theme + Brand Guidelines v1.2 p.25 +// typography → Brand Guidelines v1.2 p.17-23 +// logo rules → Brand Guidelines v1.2 p.5-7 + +export interface BrandColor { + name: string + hex: string + /** DS token whose value IS this colour, so the swatch paints with a token + * instead of an inline style — ds-lint ratchets inline styles. */ + swatchClass: string + note: string +} + +export const BRAND_COLORS: BrandColor[] = [ + { name: 'Pink', hex: '#FF90E8', swatchClass: 'bg-background-brand', note: 'Primary. The key-visual ground.' }, + { + name: 'Yellow', + hex: '#FFC900', + swatchClass: 'bg-background-icon-bubble-yellow', + note: 'Secondary. The mascot and accents.', + }, + { name: 'Lavender', hex: '#90A8ED', swatchClass: 'bg-background-icon-bubble-blue', note: 'Secondary.' }, + { name: 'Black', hex: '#000000', swatchClass: 'bg-foreground-primary', note: 'Type, outlines, 1px borders.' }, + { name: 'White', hex: '#FFFFFF', swatchClass: 'bg-foreground-inverse', note: 'Type on dark and pink grounds.' }, +] + +export interface BrandTypeRole { + role: string + face: string + note: string +} + +export const BRAND_TYPE: BrandTypeRole[] = [ + { role: 'Titles', face: 'Roboto Flex ExtraBold', note: 'Available from Google Fonts.' }, + { role: 'Body copy', face: 'Roboto Flex Regular', note: 'Available from Google Fonts.' }, + { + role: 'Accent lettering', + face: 'KNERD Filled + Outline', + note: 'Display only, never body copy. Download below.', + }, +] + +export const LOGO_RULES = { + do: [ + 'Keep clear space of at least 1× the height of the P on every side.', + 'Use the full logotype where the brand is unfamiliar; the icon alone where it is not.', + 'Place the black wordmark on light or pink grounds.', + ], + dont: [ + 'Do not recolour, rotate, outline or add effects to the mark.', + 'Do not set the black wordmark on a dark ground — use the icon alone instead.', + 'Do not rebuild the KNERD accent lettering as flat black type. It is always the three-layer offset: filled in the background colour, filled white shifted right, black outline on top.', + ], +} + +export interface BrandFile { + name: string + href: string + meta: string +} + +export interface BrandFileGroup { + label: string + description: string + files: BrandFile[] +} + +export const BRAND_FILE_GROUPS: BrandFileGroup[] = [ + { + label: 'Logotype', + description: 'Icon and wordmark locked up together. The default mark.', + files: [ + { name: 'SVG', href: '/press/assets/Peanut_Full_Logotype.svg', meta: 'vector' }, + { name: 'EPS', href: '/press/assets/Peanut_Full_Logotype.eps', meta: 'vector' }, + { name: 'AI', href: '/press/assets/Peanut_Full_Logotype.ai', meta: 'vector' }, + { name: 'PNG', href: '/press/assets/raster/Peanut_Full_Logotype-1200.png', meta: '1200×293' }, + ], + }, + { + label: 'Icon', + description: 'The mascot mark alone. Use for avatars and app tiles.', + files: [ + { name: 'SVG', href: '/press/assets/Peanut_Icon.svg', meta: 'vector' }, + { name: 'EPS', href: '/press/assets/Peanut_Icon.eps', meta: 'vector' }, + { name: 'PNG', href: '/press/assets/raster/peanut-icon-1024.png', meta: '1024×1024' }, + { name: 'PNG on pink', href: '/press/assets/raster/peanut-icon-1024-pink.png', meta: '1024×1024' }, + { name: 'PNG small', href: '/press/assets/raster/peanut-icon-512.png', meta: '512×512' }, + ], + }, + { + label: 'Wordmark', + description: 'Type alone, for lockups that already carry the icon.', + files: [ + { name: 'SVG', href: '/press/assets/Peanut_Wordmark.svg', meta: 'vector' }, + { name: 'EPS', href: '/press/assets/Peanut_Wordmark.eps', meta: 'vector' }, + { name: 'AI', href: '/press/assets/Peanut_Wordmark.ai', meta: 'vector' }, + { name: 'PNG', href: '/press/assets/raster/Peanut_Wordmark-1200.png', meta: '1200×248' }, + ], + }, + { + label: 'Social images', + description: 'Ready-sized cover art for link previews and directory listings.', + files: [ + { name: 'Landscape', href: '/press/assets/social/peanut-og-1200x630.png', meta: '1200×630' }, + { name: 'Square', href: '/press/assets/social/peanut-social-1200x1200.png', meta: '1200×1200' }, + ], + }, + { + label: 'Type', + description: 'KNERD accent face. Roboto Flex comes from Google Fonts.', + files: [ + { name: 'KNERD Filled', href: '/press/assets/font/KNERDFilled-Regular.woff2', meta: 'woff2' }, + { name: 'KNERD Outline', href: '/press/assets/font/KNERDOutline-Regular.woff2', meta: 'woff2' }, + { name: 'Fill', href: '/press/assets/font/Fill.otf', meta: 'otf' }, + { name: 'Outline', href: '/press/assets/font/Outline.otf', meta: 'otf' }, + ], + }, + { + label: 'Guidelines', + description: 'The full brand book. Read this before designing anything.', + files: [{ name: 'Brand Guidelines', href: '/press/assets/Peanut_Brand_Guidelines.pdf', meta: 'PDF · v1.2' }], + }, +] + +export interface Screenshot { + slug: string + label: string +} + +export const SCREENSHOTS: Screenshot[] = [ + { slug: '01-hero', label: 'Balance' }, + { slug: '02-qr-pay-local', label: 'Pay by QR' }, + { slug: '04-send', label: 'Send' }, + { slug: '05-add-money', label: 'Add money' }, + { slug: '06-withdraw', label: 'Withdraw' }, +] + +export const SCREENSHOT_LOCALES = [ + { dir: 'en', label: 'English' }, + { dir: 'pt-BR', label: 'Português (BR)' }, + { dir: 'es-AR', label: 'Español (AR)' }, +] + +export const SCREENSHOT_SIZE = { width: 1080, height: 1920 } + +export const MASCOTS = [ + { slug: 'peanut-waving-hello', label: 'Waving' }, + { slug: 'peanut-cool', label: 'Cool' }, + { slug: 'peanut-walking', label: 'Walking' }, + { slug: 'peanut-pointing-down', label: 'Pointing' }, + { slug: 'peanut-angry', label: 'Angry' }, +] diff --git a/src/i18n/en.json b/src/i18n/en.json index 122d1b6031..aa63acaf9e 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -38,6 +38,19 @@ "pressTeam": "Team", "pressCompany": "Company", "pressMediaContact": "Media contact", + "pressBrandTitle": "Brand & Assets", + "pressBrandSubtitle": "Logos, colours, type and product screenshots — everything you need to put Peanut on a page.", + "pressBrandBackToPress": "← Back to the press kit", + "pressBrandTheMark": "The mark", + "pressBrandDo": "Do", + "pressBrandDont": "Don't", + "pressBrandDownloads": "Downloads", + "pressBrandPalette": "Colour", + "pressBrandTypography": "Type", + "pressBrandScreenshots": "Product screenshots", + "pressBrandScreenshotsNote": "Full resolution, 1080×1920. Click any screenshot to download it.", + "pressBrandMascot": "Mascot", + "pressBrandLink": "Brand & assets →", "help": "Help", "helpCenter": "Help Center", "helpCenterDescription": "Get help with Peanut — verification, passkeys, payments, deposits, and account recovery. Step-by-step guides and answers to common questions.", diff --git a/src/i18n/es-419.json b/src/i18n/es-419.json index 92a9ef8b1c..e005ff3e16 100644 --- a/src/i18n/es-419.json +++ b/src/i18n/es-419.json @@ -38,6 +38,19 @@ "pressTeam": "Equipo", "pressCompany": "Empresa", "pressMediaContact": "Contacto de prensa", + "pressBrandTitle": "Marca y recursos", + "pressBrandSubtitle": "Logos, colores, tipografía y capturas del producto: todo lo que necesitas para mostrar Peanut.", + "pressBrandBackToPress": "← Volver al kit de prensa", + "pressBrandTheMark": "El logo", + "pressBrandDo": "Sí", + "pressBrandDont": "No", + "pressBrandDownloads": "Descargas", + "pressBrandPalette": "Color", + "pressBrandTypography": "Tipografía", + "pressBrandScreenshots": "Capturas del producto", + "pressBrandScreenshotsNote": "Resolución completa, 1080×1920. Haz clic en cualquier captura para descargarla.", + "pressBrandMascot": "Mascota", + "pressBrandLink": "Marca y recursos →", "help": "Ayuda", "helpCenter": "Centro de Ayuda", "helpCenterDescription": "Obtén ayuda con Peanut — verificación, passkeys, pagos, depósitos y recuperación de cuenta. Guías paso a paso y respuestas a preguntas frecuentes.", diff --git a/src/i18n/es-ar.json b/src/i18n/es-ar.json index c3ad6f1493..385137874e 100644 --- a/src/i18n/es-ar.json +++ b/src/i18n/es-ar.json @@ -38,6 +38,19 @@ "pressTeam": "Equipo", "pressCompany": "Empresa", "pressMediaContact": "Contacto de prensa", + "pressBrandTitle": "Marca y recursos", + "pressBrandSubtitle": "Logos, colores, tipografía y capturas del producto: todo lo que necesitás para mostrar Peanut.", + "pressBrandBackToPress": "← Volver al kit de prensa", + "pressBrandTheMark": "El logo", + "pressBrandDo": "Sí", + "pressBrandDont": "No", + "pressBrandDownloads": "Descargas", + "pressBrandPalette": "Color", + "pressBrandTypography": "Tipografía", + "pressBrandScreenshots": "Capturas del producto", + "pressBrandScreenshotsNote": "Resolución completa, 1080×1920. Hacé clic en cualquier captura para descargarla.", + "pressBrandMascot": "Mascota", + "pressBrandLink": "Marca y recursos →", "help": "Ayuda", "helpCenter": "Centro de Ayuda", "helpCenterDescription": "Obtené ayuda con Peanut — verificación, passkeys, pagos, depósitos y recuperación de cuenta. Guías paso a paso y respuestas a preguntas frecuentes.", diff --git a/src/i18n/pt-br.json b/src/i18n/pt-br.json index 41f1a55ed0..1a37e74639 100644 --- a/src/i18n/pt-br.json +++ b/src/i18n/pt-br.json @@ -38,6 +38,19 @@ "pressTeam": "Equipe", "pressCompany": "Empresa", "pressMediaContact": "Contato de imprensa", + "pressBrandTitle": "Marca e recursos", + "pressBrandSubtitle": "Logos, cores, tipografia e capturas do produto: tudo o que você precisa para mostrar a Peanut.", + "pressBrandBackToPress": "← Voltar ao kit de imprensa", + "pressBrandTheMark": "A marca", + "pressBrandDo": "Faça", + "pressBrandDont": "Não faça", + "pressBrandDownloads": "Downloads", + "pressBrandPalette": "Cor", + "pressBrandTypography": "Tipografia", + "pressBrandScreenshots": "Capturas do produto", + "pressBrandScreenshotsNote": "Resolução completa, 1080×1920. Clique em qualquer captura para baixá-la.", + "pressBrandMascot": "Mascote", + "pressBrandLink": "Marca e recursos →", "help": "Ajuda", "helpCenter": "Central de Ajuda", "helpCenterDescription": "Obtenha ajuda com o Peanut — verificação, passkeys, pagamentos, depósitos e recuperação de conta. Guias passo a passo e respostas para perguntas frequentes.", diff --git a/src/i18n/types.ts b/src/i18n/types.ts index 9cd37c10c0..ffb717b998 100644 --- a/src/i18n/types.ts +++ b/src/i18n/types.ts @@ -71,6 +71,19 @@ export interface Translations { pressTeam: string // "Team" pressCompany: string // "Company" pressMediaContact: string // "Media contact" + pressBrandTitle: string // "Brand & Assets" + pressBrandSubtitle: string // "Logos, colours, type and product screenshots — everything you need to put Peanut on a page." + pressBrandBackToPress: string // "← Back to the press kit" + pressBrandTheMark: string // "The mark" + pressBrandDo: string // "Do" + pressBrandDont: string // "Don't" + pressBrandDownloads: string // "Downloads" + pressBrandPalette: string // "Colour" + pressBrandTypography: string // "Type" + pressBrandScreenshots: string // "Product screenshots" + pressBrandScreenshotsNote: string // "Full resolution, 1080×1920. Click any screenshot to download it." + pressBrandMascot: string // "Mascot" + pressBrandLink: string // "Brand & assets →" // Help center help: string // "Help"