Skip to content

Commit 8b62a0c

Browse files
Slashgearclaude
andcommitted
feat: add press kit page with logo assets and brand guidelines
Add /presse page with downloadable logo variants (SVG, PNG, WebP), brand color reference, and usage guidelines. Remove .ai source files from distribution and regenerate raster images from SVG. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b84daab commit 8b62a0c

37 files changed

Lines changed: 1311 additions & 215 deletions

app/presse/PressKit.module.css

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
.intro {
2+
color: var(--font-color-default);
3+
max-width: 720px;
4+
line-height: 1.7;
5+
}
6+
7+
.section {
8+
margin-top: 3rem;
9+
}
10+
11+
.logoGrid {
12+
display: grid;
13+
grid-template-columns: 1fr;
14+
gap: 1.5rem;
15+
margin-top: 1rem;
16+
}
17+
18+
@media (min-width: 600px) {
19+
.logoGrid {
20+
grid-template-columns: repeat(2, 1fr);
21+
}
22+
}
23+
24+
.colorGrid {
25+
margin-top: 1rem;
26+
max-width: 280px;
27+
}
28+
29+
.guidelineColumn {
30+
background-color: var(--background-card);
31+
border: 1px solid var(--border-light);
32+
border-radius: 12px;
33+
padding: 1.25rem;
34+
margin-top: 1rem;
35+
max-width: 600px;
36+
}
37+
38+
.guidelineList {
39+
display: flex;
40+
flex-direction: column;
41+
gap: 0.5rem;
42+
}
43+
44+
.guidelineItem {
45+
display: flex;
46+
align-items: baseline;
47+
gap: 0.5rem;
48+
font-size: 0.875rem;
49+
color: var(--font-color-default);
50+
line-height: 1.5;
51+
}
52+
53+
.guidelineIconDo {
54+
color: #4ade80;
55+
flex-shrink: 0;
56+
}

app/presse/opengraph-image.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ImageResponse } from 'next/og';
2+
import { SimpleText } from '../../modules/og/SimpleText';
3+
4+
export const runtime = 'edge';
5+
6+
export const alt = 'Kit Presse LyonJS';
7+
export const size = {
8+
width: 1200,
9+
height: 630,
10+
};
11+
export const contentType = 'image/png';
12+
13+
export default async function Image() {
14+
return new ImageResponse(<SimpleText text="Kit Presse" />, {
15+
...size,
16+
});
17+
}

app/presse/page.tsx

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { Metadata } from 'next';
2+
import { Heading } from '../../modules/atoms/heading/Heading';
3+
import { LogoCard } from '../../modules/press-kit/LogoCard';
4+
import { ColorSwatch } from '../../modules/press-kit/ColorSwatch';
5+
import { logos, brandColor, guidelines } from '../../data/press-kit';
6+
import styles from './PressKit.module.css';
7+
8+
const title = 'LyonJS | Kit Presse';
9+
const description =
10+
"Retrouvez les logos, couleurs et consignes d'utilisation de la marque LyonJS pour vos supports de communication.";
11+
12+
export const metadata: Metadata = {
13+
title,
14+
description,
15+
twitter: {
16+
title,
17+
description,
18+
},
19+
openGraph: {
20+
title,
21+
description,
22+
},
23+
};
24+
25+
export default function PressePage() {
26+
return (
27+
<main>
28+
<Heading Component="h1">Kit Presse</Heading>
29+
<p className={styles.intro}>
30+
Retrouvez ici les ressources visuelles de LyonJS&nbsp;: logos, couleur et consignes d&apos;utilisation.
31+
N&apos;hésitez pas à les utiliser pour vos articles, présentations ou supports de communication.
32+
</p>
33+
34+
<section className={styles.section}>
35+
<Heading Component="h2">Logos</Heading>
36+
<div className={styles.logoGrid}>
37+
{logos.map((logo) => (
38+
<LogoCard key={logo.name} logo={logo} />
39+
))}
40+
</div>
41+
</section>
42+
43+
<section className={styles.section}>
44+
<Heading Component="h2">Couleur</Heading>
45+
<div className={styles.colorGrid}>
46+
<ColorSwatch color={brandColor} />
47+
</div>
48+
</section>
49+
50+
<section className={styles.section}>
51+
<Heading Component="h2">Consignes d&apos;utilisation</Heading>
52+
<div className={styles.guidelineColumn}>
53+
<div className={styles.guidelineList}>
54+
{guidelines.map((item) => (
55+
<div key={item.text} className={styles.guidelineItem}>
56+
<span className={styles.guidelineIconDo}>&#10003;</span>
57+
<span>{item.text}</span>
58+
</div>
59+
))}
60+
</div>
61+
</div>
62+
</section>
63+
</main>
64+
);
65+
}

app/sitemap.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
4545
changeFrequency: 'monthly',
4646
priority: 0.5,
4747
},
48+
{
49+
url: `${BASE_URL}/presse`,
50+
lastModified: new Date(),
51+
changeFrequency: 'yearly',
52+
priority: 0.4,
53+
},
4854
...Array.from(years)
4955
.toReversed()
5056
.map((year) => {

data/press-kit.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
export type LogoVariant = {
2+
format: string;
3+
filePath: string;
4+
previewPath?: string;
5+
};
6+
7+
export type LogoAsset = {
8+
name: string;
9+
description: string;
10+
variants: LogoVariant[];
11+
};
12+
13+
export type BrandColor = {
14+
name: string;
15+
description: string;
16+
hex: string;
17+
hsl: string;
18+
cssVariable: string;
19+
};
20+
21+
export type GuidelineItem = {
22+
text: string;
23+
};
24+
25+
export const logos: LogoAsset[] = [
26+
{
27+
name: 'Logo complet',
28+
description: 'Logo avec le texte "LyonJS". Version principale à privilégier.',
29+
variants: [
30+
{ format: 'SVG', filePath: '/press-kit/lyon-js-complet.svg', previewPath: '/press-kit/lyon-js-complet.svg' },
31+
{ format: 'PNG 128', filePath: '/press-kit/lyon-js-complet-128.png' },
32+
{ format: 'PNG 256', filePath: '/press-kit/lyon-js-complet-256.png' },
33+
{ format: 'PNG 512', filePath: '/press-kit/lyon-js-complet-512.png' },
34+
{ format: 'PNG 1024', filePath: '/press-kit/lyon-js-complet-1024.png' },
35+
{ format: 'WebP 128', filePath: '/press-kit/lyon-js-complet-128.webp' },
36+
{ format: 'WebP 256', filePath: '/press-kit/lyon-js-complet-256.webp' },
37+
{ format: 'WebP 512', filePath: '/press-kit/lyon-js-complet-512.webp' },
38+
{ format: 'WebP 1024', filePath: '/press-kit/lyon-js-complet-1024.webp' },
39+
],
40+
},
41+
{
42+
name: 'Icône seule',
43+
description: "Logo sans texte. À utiliser quand l'espace est limité (avatar, favicon…).",
44+
variants: [
45+
{ format: 'SVG', filePath: '/press-kit/lyon-js.svg', previewPath: '/press-kit/lyon-js.svg' },
46+
{ format: 'PNG 128', filePath: '/press-kit/lyon-js-128.png' },
47+
{ format: 'PNG 256', filePath: '/press-kit/lyon-js-256.png' },
48+
{ format: 'PNG 512', filePath: '/press-kit/lyon-js-512.png' },
49+
{ format: 'PNG 1024', filePath: '/press-kit/lyon-js-1024.png' },
50+
{ format: 'WebP 128', filePath: '/press-kit/lyon-js-128.webp' },
51+
{ format: 'WebP 256', filePath: '/press-kit/lyon-js-256.webp' },
52+
{ format: 'WebP 512', filePath: '/press-kit/lyon-js-512.webp' },
53+
{ format: 'WebP 1024', filePath: '/press-kit/lyon-js-1024.webp' },
54+
],
55+
},
56+
];
57+
58+
export const brandColor: BrandColor = {
59+
name: 'Jaune LyonJS',
60+
description: 'Couleur principale de la marque',
61+
hex: '#EDD533',
62+
hsl: 'hsl(52, 83%, 62%)',
63+
cssVariable: '--yellow-0',
64+
};
65+
66+
export const guidelines: GuidelineItem[] = [
67+
{ text: 'Utiliser le logo sur un fond sombre pour un meilleur contraste' },
68+
{ text: 'Respecter une zone de protection autour du logo (min. 50% de sa hauteur)' },
69+
{ text: 'Utiliser les couleurs officielles de la charte' },
70+
{ text: "Pointer vers lyonjs.org lors de l'utilisation du logo" },
71+
];

0 commit comments

Comments
 (0)