Files
portfolio/tailwind.config.ts
denshooter 731cd58ba8 feat: plakat redesign phase 2 (desk with throwable objects, mobile card deck)
- New "Tisch" section replaces the old projects block on the home page
- Objects: project cards from Directus (flip on tap, link to detail page),
  thesis ticket with countdown, server card, currently-reading book from
  Hardcover (with skeleton), polaroid photo, sticker
- Desktop: Framer Motion drag with momentum, elastic table edges, tilt that
  follows throw velocity, bring-to-front, "Tidy up" and "Mess it up"
- Mobile: card deck, swipe the top card away (distance or velocity),
  prev/next buttons, live counter, tap to flip
- Both layouts are server rendered and switched by CSS, so content is
  visible without JavaScript and nothing jumps on hydration
- Taps after a drag no longer flip cards
- New named colors polaroid/bookcover instead of raw hex classes
- Texts in de/en, i18n key check extended

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 23:48:53 +02:00

155 lines
5.1 KiB
TypeScript

// tailwind.config.ts
import type { Config } from "tailwindcss";
// tailwind.config.js
export default {
darkMode: "class", // Enables class-based dark mode
// Touch devices fire :hover on tap and keep it stuck; only apply hover styles
// where a real pointer exists.
future: {
hoverOnlyWhenSupported: true,
},
content: [
"./app/**/*.{js,ts,jsx,tsx}",
"./app/components/**/*.{js,ts,jsx,tsx}",
// Add other paths if necessary
],
theme: {
extend: {
// Stronger curves than the CSS defaults. Overriding `out` and `in-out`
// upgrades every existing `ease-out` / `ease-in-out` utility at once.
transitionTimingFunction: {
out: "cubic-bezier(0.23, 1, 0.32, 1)",
"in-out": "cubic-bezier(0.77, 0, 0.175, 1)",
drawer: "cubic-bezier(0.32, 0.72, 0, 1)",
},
keyframes: {
fadeIn: {
"0%": { opacity: "0", transform: "translateY(8px)" },
"100%": { opacity: "1", transform: "translateY(0)" },
},
slideDown: {
"0%": { opacity: "0", transform: "translateY(-12px)" },
"100%": { opacity: "1", transform: "translateY(0)" },
},
wordmarkUp: {
"0%": { opacity: "0", transform: "translateY(40%)" },
"100%": { opacity: "1", transform: "translateY(0)" },
},
marquee: {
"0%": { transform: "translateX(0)" },
"100%": { transform: "translateX(-50%)" },
},
scrollHint: {
"0%": { opacity: "0", transform: "scaleY(0.4)" },
"40%": { opacity: "1", transform: "scaleY(1)" },
"100%": { opacity: "0", transform: "scaleY(1)" },
},
},
animation: {
"fade-in": "fadeIn 600ms cubic-bezier(0.23, 1, 0.32, 1) both",
"slide-down": "slideDown 500ms cubic-bezier(0.23, 1, 0.32, 1) both",
"scroll-hint": "scrollHint 2.4s cubic-bezier(0.77, 0, 0.175, 1) infinite",
"spin-slow": "spin 4s linear infinite",
"wordmark-up": "wordmarkUp 900ms cubic-bezier(0.23, 1, 0.32, 1) both",
marquee: "marquee 32s linear infinite",
},
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
card: {
DEFAULT: "var(--card)",
foreground: "var(--card-foreground)",
},
popover: {
DEFAULT: "var(--popover)",
foreground: "var(--popover-foreground)",
},
primary: {
DEFAULT: "var(--primary)",
foreground: "var(--primary-foreground)",
},
secondary: {
DEFAULT: "var(--secondary)",
foreground: "var(--secondary-foreground)",
},
muted: {
DEFAULT: "var(--muted)",
foreground: "var(--muted-foreground)",
},
accent: {
DEFAULT: "var(--accent)",
foreground: "var(--accent-foreground)",
},
destructive: {
DEFAULT: "var(--destructive)",
foreground: "var(--destructive-foreground)",
},
border: "var(--border)",
input: "var(--input)",
ring: "var(--ring)",
// Plakat-Design: Rot, Tinte, Papier. Tinte und Papier tauschen im Dark Mode die Rollen.
signal: "rgb(var(--plakat-red) / <alpha-value>)",
ink: "rgb(var(--plakat-ink) / <alpha-value>)",
paper: {
DEFAULT: "rgb(var(--plakat-paper) / <alpha-value>)",
2: "rgb(var(--plakat-paper-2) / <alpha-value>)",
},
ok: "rgb(var(--plakat-ok) / <alpha-value>)",
// Feste Objektfarben auf dem Tisch, unabhängig vom Theme
polaroid: { DEFAULT: "#fbfaf8", ink: "#140c0b" },
bookcover: { DEFAULT: "#2b1a14", text: "#f3e7dc" },
// Warm brown palette
cream: "#FAF8F3",
sand: "#EFEBE9",
brown: {
50: "#EFEBE9",
100: "#D7CCC8",
200: "#BCAAA4",
300: "#A1887F",
400: "#8D6E63",
500: "#795548",
600: "#6D4C41",
700: "#5D4037",
800: "#4E342E",
900: "#3E2723",
},
stone: {
50: "#FAFAF9",
100: "#F5F5F4",
200: "#E7E5E4",
300: "#D6D3D1",
400: "#A8A29E",
500: "#78716C",
600: "#57534E",
700: "#44403C",
800: "#292524",
900: "#1C1917",
},
liquid: {
mint: "#A7F3D0",
lavender: "#DDD6FE",
blue: "#BFDBFE",
rose: "#FECACA",
yellow: "#FDE68A",
peach: "#FED7AA",
pink: "#FBCFE8",
sky: "#BAE6FD",
lime: "#D9F99D",
coral: "#FCA5A5",
purple: "#E9D5FF",
teal: "#99F6E4",
amber: "#FDE047",
},
},
fontFamily: {
sans: ["var(--font-geist)", "Helvetica Neue", "Arial", "sans-serif"],
display: ["var(--font-bricolage)", "Avenir Next", "Segoe UI", "sans-serif"],
serif: ["var(--font-bricolage)", "Avenir Next", "Segoe UI", "sans-serif"],
mono: ["var(--font-geist-mono)", "SF Mono", "Menlo", "monospace"],
},
},
},
plugins: [],
} satisfies Config;