Files
picpeak/frontend/tailwind.config.js
T
Paul Nothaft de3a7f70bf fix(cms): enable the Tailwind typography plugin so prose classes work (#1288)
tailwind.config.js had plugins: [] and @tailwindcss/typography was never
installed, so every prose / prose-neutral / dark:prose-invert class in the
app resolved to nothing. Preflight, which IS active, resets h1-h6 to
inherit size and weight and strips list-style from ul/ol — so an applied
<h2> rendered pixel-identical to the <p> it replaced.

The editor was never broken. The toolbar highlighted because
editor.isActive('heading') correctly returned true; only the CSS to show
it was missing. That also explains why pasting rendered rich text worked:
it carries inline styles.

Ten surfaces rely on these classes, including the PUBLIC CMS pages — so
impressum/datenschutz were serving unstyled headings to visitors too.

Review follow-ups: prose colours are mapped to the theme tokens wherever
.text-theme marks theme-owned text (a dark gallery preset sets
--color-text but no .dark class, so dark:prose-invert never engages and
headings would have gone near-black on dark); code blocks inherit rather
than being scaled twice; and H5/H6 get explicit rules, since the plugin
only styles h1-h4.

Closes #1288
2026-09-04 14:26:51 +02:00

122 lines
4.1 KiB
JavaScript

/** @type {import('tailwindcss').Config} */
export default {
darkMode: 'class',
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
colors: {
// 8-token CI palette aliases — these read CSS variables that are set
// either by ThemeContext.applyTheme (gallery + branding) or by the
// :root.dark { } block in index.css (admin dark mode). Use these in
// place of bg-white / text-neutral-900 / border-neutral-200 so that
// every component flips with dark/light mode automatically.
background: 'var(--color-background)',
surface: 'var(--color-surface)',
elevated: 'var(--color-elevated)',
'border-token': 'var(--color-surface-border)',
'text-primary': 'var(--color-text)',
'text-secondary': 'var(--color-muted-text)',
accent: 'var(--color-accent)',
'accent-dark': 'var(--color-accent-dark)',
primary: {
50: '#f0fdf4',
100: '#dcfce7',
200: '#bbf7d0',
300: '#86efac',
400: '#4ade80',
500: '#22c55e',
600: '#5C8762', // Main brand color from scrappbook.de
700: '#4a6f4f',
800: '#3f5d42',
900: '#365238',
},
sand: {
50: '#fdfcfb',
100: '#f7f5f2',
200: '#f0ebe5',
300: '#e6ddd4',
400: '#d4c2b0',
500: '#c2a68c',
600: '#b18b68',
},
neutral: {
50: '#fafafa',
100: '#f5f5f5',
200: '#e5e5e5',
300: '#d4d4d4',
400: '#a3a3a3',
500: '#737373',
600: '#525252',
700: '#404040',
800: '#262626',
900: '#171717',
}
},
fontFamily: {
sans: ['Inter', 'Noto Sans', 'system-ui', '-apple-system', 'sans-serif'],
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
'scale-in': 'scaleIn 0.2s ease-out',
'shimmer': 'shimmer 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
scaleIn: {
'0%': { transform: 'scale(0.95)', opacity: '0' },
'100%': { transform: 'scale(1)', opacity: '1' },
},
shimmer: {
'0%': { backgroundPosition: '-200% 0' },
'100%': { backgroundPosition: '200% 0' },
},
},
spacing: {
'18': '4.5rem',
'88': '22rem',
},
borderRadius: {
'xl': '1rem',
'2xl': '1.25rem',
},
boxShadow: {
'soft': '0 2px 8px rgba(0, 0, 0, 0.04)',
'medium': '0 4px 16px rgba(0, 0, 0, 0.08)',
'large': '0 8px 32px rgba(0, 0, 0, 0.12)',
},
},
},
safelist: [
// Dynamic grid-cols classes used by thumbnail scale offsets
...Array.from({ length: 12 }, (_, i) => `grid-cols-${i + 1}`),
...Array.from({ length: 12 }, (_, i) => `sm:grid-cols-${i + 1}`),
...Array.from({ length: 12 }, (_, i) => `lg:grid-cols-${i + 1}`),
...Array.from({ length: 12 }, (_, i) => `xl:grid-cols-${i + 1}`),
],
plugins: [
// Tailwind's Preflight resets h1-h6 to inherit their size and weight, and
// strips list-style and padding from ul/ol. Ten places in this app render
// rich text inside a `prose` container and rely on this plugin to put that
// typography back — the CMS editor and its preview, the public CMS page,
// release notes, and the gallery welcome message among them.
//
// Without it every `prose*` class is a no-op, so applying a heading or a
// list in the CMS editor changed the document and changed NOTHING on
// screen: the toolbar button lit up (the editor state was correct) while
// the text stayed visually a paragraph. That is issue #1288.
require('@tailwindcss/typography'),
],
}