Upload files to "/"

This commit is contained in:
2026-09-14 23:35:23 +08:00
parent 1e893db246
commit aa5c739f16
5 changed files with 1662 additions and 0 deletions
+319
View File
@@ -0,0 +1,319 @@
import React, { useState } from 'react';
import {
Palette,
Copy,
Check,
Sun,
Smile,
CheckCircle2,
Brush
} from 'lucide-react';
import { COLOR_PALETTE, ART_DIRECTION_GUIDE, CHARACTERS } from '../data/storyData';
import { soundManager } from '../utils/audio';
interface ArtDirectionViewProps {
isBedtimeMode: boolean;
}
export const ArtDirectionView: React.FC<ArtDirectionViewProps> = ({ isBedtimeMode }) => {
const [copiedHex, setCopiedHex] = useState<string | null>(null);
const [customStyle, setCustomStyle] = useState<string>('digital-gouache');
const [customSubject, setCustomSubject] = useState<string>('Pip holding his willow brush looking at Caelum');
const [customMood, setCustomMood] = useState<string>('Warm golden twilight');
const handleCopyHex = (hex: string) => {
soundManager.playPop();
navigator.clipboard.writeText(hex);
setCopiedHex(hex);
setTimeout(() => setCopiedHex(null), 2000);
};
const generatedCustomPrompt = `Whimsical children's picture book illustration of ${customSubject}. ${customMood}, in ${customStyle === 'digital-gouache' ? 'soft digital gouache and textured watercolor' : customStyle === 'classic-pastel' ? 'classic soft oil pastel with hand-drawn colored pencil contours' : 'dreamy storybook gouache with visible paper tooth grain'}. Color palette featuring ${COLOR_PALETTE.map(c => c.name).slice(0, 3).join(', ')}. Friendly character expressions, gentle magical atmosphere, heartwarming children's literature style.`;
return (
<div className={`min-h-[calc(100vh-7rem)] py-8 px-4 sm:px-6 lg:px-8 transition-colors duration-300 ${
isBedtimeMode
? 'bg-gradient-to-b from-indigo-950 via-slate-900 to-indigo-950 text-indigo-100'
: 'bg-[#faf6ee] text-stone-900'
}`}>
<div className="max-w-7xl mx-auto space-y-8">
{/* Header */}
<div className={`p-6 sm:p-8 rounded-3xl border shadow-sm ${
isBedtimeMode
? 'bg-slate-900/90 border-indigo-800'
: 'bg-white border-amber-200/90'
}`}>
<div className="flex items-center gap-2 mb-2">
<span className="px-3 py-1 rounded-full text-xs font-bold uppercase tracking-wider bg-rose-500/10 text-rose-700 dark:text-rose-400 border border-rose-300/40">
Art & Visual Direction Bible
</span>
<span className="text-xs text-stone-500 dark:text-indigo-300">
{ART_DIRECTION_GUIDE.styleName}
</span>
</div>
<h2 className="text-2xl sm:text-3xl font-heading font-bold text-amber-950 dark:text-white">
Color Palette, Expressions & Artistic Philosophy
</h2>
<p className="mt-1 text-sm sm:text-base text-stone-600 dark:text-indigo-200 max-w-3xl leading-relaxed">
Detailed art notes crafted so that any illustrator or AI visual model can render consistent, heartwarming, award-winning storybook spreads.
</p>
</div>
{/* Master Color Palette Section */}
<div className={`p-6 sm:p-8 rounded-3xl border ${
isBedtimeMode ? 'bg-slate-900 border-indigo-800' : 'bg-white border-amber-200/90'
}`}>
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-2">
<Palette className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<h3 className="text-xl font-heading font-bold text-stone-900 dark:text-white">
Master Storybook Color Palette
</h3>
</div>
<span className="text-xs font-semibold text-stone-500 dark:text-indigo-300">
Click any swatch to copy Hex
</span>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{COLOR_PALETTE.map((swatch) => (
<div
key={swatch.hex}
onClick={() => handleCopyHex(swatch.hex)}
className="p-4 rounded-2xl border border-stone-200 dark:border-indigo-800 bg-stone-50 dark:bg-indigo-950/40 hover:shadow-md cursor-pointer transition-all group"
>
<div className="flex items-center gap-3 mb-3">
<div
style={{ backgroundColor: swatch.hex }}
className="w-12 h-12 rounded-2xl shadow-inner border-2 border-white dark:border-slate-800 shrink-0 group-hover:scale-105 transition-transform"
/>
<div>
<h4 className="font-heading font-bold text-sm text-stone-900 dark:text-white">
{swatch.name}
</h4>
<div className="flex items-center gap-1.5 text-xs font-mono font-bold text-amber-700 dark:text-amber-400">
<span>{swatch.hex}</span>
{copiedHex === swatch.hex ? (
<Check className="w-3.5 h-3.5 text-emerald-600" />
) : (
<Copy className="w-3.5 h-3.5 opacity-40 group-hover:opacity-100" />
)}
</div>
</div>
</div>
<div className="space-y-1 text-xs">
<p className="text-stone-700 dark:text-stone-300">
<strong className="text-stone-900 dark:text-white">Usage:</strong> {swatch.usage}
</p>
<p className="text-stone-500 dark:text-indigo-300 italic">
<strong className="text-stone-700 dark:text-stone-200 not-italic">Mood:</strong> {swatch.mood}
</p>
</div>
</div>
))}
</div>
</div>
{/* Character Expression & Anatomy Guidelines */}
<div className={`p-6 sm:p-8 rounded-3xl border ${
isBedtimeMode ? 'bg-slate-900 border-indigo-800' : 'bg-white border-amber-200/90'
}`}>
<div className="flex items-center gap-2 mb-6">
<Smile className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<h3 className="text-xl font-heading font-bold text-stone-900 dark:text-white">
Character Expression & Visual Identity Rules
</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{CHARACTERS.map((char) => (
<div
key={char.name}
className="p-5 rounded-2xl border border-stone-200 dark:border-indigo-800 bg-stone-50/70 dark:bg-indigo-950/40 space-y-3"
>
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<span className="text-3xl">{char.avatarEmoji}</span>
<div>
<h4 className="font-heading font-bold text-base text-stone-900 dark:text-white">
{char.name}
</h4>
<span className="text-xs font-semibold text-stone-500 dark:text-indigo-300">
{char.role}
</span>
</div>
</div>
<span
style={{ backgroundColor: `${char.accentColor}20`, color: char.accentColor, borderColor: `${char.accentColor}40` }}
className="text-xs font-bold px-2.5 py-1 rounded-full border"
>
{char.species}
</span>
</div>
<div className="space-y-2 text-xs sm:text-sm text-stone-700 dark:text-stone-300">
<p>
<strong className="text-stone-900 dark:text-white">Key Visual Markers:</strong> {char.appearance}
</p>
<p>
<strong className="text-stone-900 dark:text-white">Signature Gesture / Quirk:</strong> {char.quirk}
</p>
<p>
<strong className="text-stone-900 dark:text-white">Emotional Color Transition:</strong> {char.name === 'Pip' ? 'Quills ripple like grass when inspired; scarf flaps cheerfully.' : char.name === 'Caelum' ? 'Shifts from misty slate-gray (timid) to soft lavender (shy) to radiant sunset gold and rosé (confident).' : char.name === 'Barnaby' ? 'Eyes crinkle warmly into crescents; spectacles catch amber rim-light.' : 'Wings flutter in excited loops; chest puffs with sky-blue pride.'}
</p>
</div>
</div>
))}
</div>
{/* Golden Rules Box */}
<div className="mt-6 p-4 rounded-2xl bg-amber-50 dark:bg-indigo-950/60 border border-amber-200 dark:border-indigo-800">
<h5 className="font-heading font-bold text-xs uppercase tracking-wider text-amber-800 dark:text-amber-300 mb-2">
Core Principles for the Children's Illustrator
</h5>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-3 text-xs text-stone-700 dark:text-stone-300">
<div className="flex items-start gap-2">
<CheckCircle2 className="w-4 h-4 text-emerald-600 shrink-0 mt-0.5" />
<span><strong>No Harsh Black Outlines:</strong> Use deep sepia, indigo, or forest bark for line work.</span>
</div>
<div className="flex items-start gap-2">
<CheckCircle2 className="w-4 h-4 text-emerald-600 shrink-0 mt-0.5" />
<span><strong>Tactile Paper Texture:</strong> Retain visible rag-paper tooth and watercolor bloom edges.</span>
</div>
<div className="flex items-start gap-2">
<CheckCircle2 className="w-4 h-4 text-emerald-600 shrink-0 mt-0.5" />
<span><strong>Gentle Scale & Proximity:</strong> Caelum hovers close to the grass to invite cuddles.</span>
</div>
</div>
</div>
</div>
{/* Lighting Keys Across The Story */}
<div className={`p-6 sm:p-8 rounded-3xl border ${
isBedtimeMode ? 'bg-slate-900 border-indigo-800' : 'bg-white border-amber-200/90'
}`}>
<div className="flex items-center gap-2 mb-6">
<Sun className="w-5 h-5 text-amber-600 dark:text-amber-400" />
<h3 className="text-xl font-heading font-bold text-stone-900 dark:text-white">
Lighting & Atmospheric Keys Across Acts
</h3>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{ART_DIRECTION_GUIDE.lightingKeys.map((key, idx) => (
<div
key={idx}
className="p-5 rounded-2xl border border-stone-200 dark:border-indigo-800 bg-stone-50 dark:bg-indigo-950/40 space-y-3"
>
<div className="flex items-center justify-between">
<span className="text-xs font-bold uppercase tracking-wider px-2.5 py-0.5 rounded-full bg-amber-100 dark:bg-indigo-900 text-amber-800 dark:text-amber-300 border border-amber-200 dark:border-indigo-700">
{key.scene}
</span>
<span className="text-[11px] font-mono text-stone-500 dark:text-indigo-300">
{key.colorTemp}
</span>
</div>
<h4 className="font-heading font-bold text-base text-stone-900 dark:text-white">
{key.mood}
</h4>
<p className="text-xs sm:text-sm text-stone-600 dark:text-indigo-200 font-reading leading-relaxed">
{key.description}
</p>
</div>
))}
</div>
</div>
{/* Interactive Storybook Prompt Builder */}
<div className={`p-6 sm:p-8 rounded-3xl border ${
isBedtimeMode ? 'bg-slate-900 border-indigo-800' : 'bg-white border-amber-200/90'
}`}>
<div className="flex items-center gap-2 mb-4">
<Brush className="w-5 h-5 text-rose-500" />
<div>
<h3 className="text-xl font-heading font-bold text-stone-900 dark:text-white">
Interactive Illustration Prompt Builder
</h3>
<p className="text-xs text-stone-500 dark:text-indigo-300">
Generate new children's book scene prompts matching this art bible
</p>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-4">
<div>
<label className="block text-xs font-bold uppercase text-stone-600 dark:text-indigo-300 mb-1">
Subject & Action
</label>
<input
type="text"
value={customSubject}
onChange={(e) => setCustomSubject(e.target.value)}
className="w-full px-3 py-2 text-sm rounded-xl border border-stone-300 dark:border-indigo-700 bg-stone-50 dark:bg-indigo-950 text-stone-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-amber-500"
/>
</div>
<div>
<label className="block text-xs font-bold uppercase text-stone-600 dark:text-indigo-300 mb-1">
Lighting & Time of Day
</label>
<select
value={customMood}
onChange={(e) => setCustomMood(e.target.value)}
className="w-full px-3 py-2 text-sm rounded-xl border border-stone-300 dark:border-indigo-700 bg-stone-50 dark:bg-indigo-950 text-stone-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-amber-500"
>
<option value="Morning sunbeams streaming through dewy oak leaves">Morning Dewy Sunbeams</option>
<option value="Warm golden twilight with pastel rainbow mist">Warm Golden Twilight</option>
<option value="Velvet indigo bedtime sky with twinkling stars and lanterns">Velvet Bedtime Stars</option>
<option value="Misty lavender afternoon breeze over purple clover">Misty Lavender Afternoon</option>
</select>
</div>
<div>
<label className="block text-xs font-bold uppercase text-stone-600 dark:text-indigo-300 mb-1">
Illustration Medium
</label>
<select
value={customStyle}
onChange={(e) => setCustomStyle(e.target.value)}
className="w-full px-3 py-2 text-sm rounded-xl border border-stone-300 dark:border-indigo-700 bg-stone-50 dark:bg-indigo-950 text-stone-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-amber-500"
>
<option value="digital-gouache">Digital Gouache & Soft Watercolor</option>
<option value="classic-pastel">Classic Soft Pastel & Colored Pencil</option>
<option value="storybook-ragpaper">Storybook Gouache with Rag-paper Grain</option>
</select>
</div>
</div>
<div className="p-4 rounded-2xl bg-amber-50 dark:bg-indigo-950/70 border border-amber-200 dark:border-indigo-800 space-y-2">
<div className="flex items-center justify-between">
<span className="text-xs font-heading font-bold uppercase text-amber-800 dark:text-amber-300">
Generated Artist / AI Prompt:
</span>
<button
onClick={() => handleCopyHex(generatedCustomPrompt)}
className="flex items-center gap-1 text-xs font-bold text-amber-700 dark:text-amber-300 hover:text-amber-900 bg-white dark:bg-indigo-900 px-2.5 py-1 rounded-lg border border-amber-200 dark:border-indigo-700"
>
{copiedHex === generatedCustomPrompt ? (
<>
<Check className="w-3.5 h-3.5 text-emerald-600" />
<span>Copied!</span>
</>
) : (
<>
<Copy className="w-3.5 h-3.5" />
<span>Copy Generated Prompt</span>
</>
)}
</button>
</div>
<p className="text-xs sm:text-sm font-reading italic text-stone-800 dark:text-stone-200 leading-relaxed">
"{generatedCustomPrompt}"
</p>
</div>
</div>
</div>
</div>
);
};