Files
Art-gallery/client/src/data/movement-interior-styles.ts
T

638 lines
26 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { ArtMovement } from '../types';
import type { SurfaceTextureKind } from '../utils/galleryProceduralTextures';
export type GalleryWindowStyle =
| 'roman-arch'
| 'gothic-lancet'
| 'baroque-pair'
| 'sash'
| 'factory'
| 'skylight'
| 'art-nouveau'
| 'glass-block'
| 'clerestory'
| 'round-oculus';
export interface GalleryWindowSpec {
wall: 'back' | 'left' | 'right' | 'ceiling';
/** Offset along wall axis from center (meters). */
x: number;
/** Vertical center height (meters). */
y: number;
width: number;
height: number;
style: GalleryWindowStyle;
lightColor: string;
lightIntensity: number;
}
export interface MovementInteriorStyle {
id: string;
label: string;
subtitle: string;
surfaces: {
wall: SurfaceTextureKind;
wallSide?: SurfaceTextureKind;
ceiling: SurfaceTextureKind;
floor: SurfaceTextureKind;
};
tints: {
wall: string;
wallSide?: string;
ceiling: string;
floor: string;
trim: string;
};
titleColor: string;
ambient: number;
warmLight: string;
sunLight: string;
fog: string;
background: string;
doorWood: [string, string, string];
windows: GalleryWindowSpec[];
trackLights: number;
details: 'palazzo' | 'baroque' | 'medieval' | 'neoclassical' | 'salon' | 'modern' | 'classical' | 'museum' | 'industrial' | 'atelier';
}
function windows(...specs: GalleryWindowSpec[]): GalleryWindowSpec[] {
return specs;
}
function mk(
id: string,
label: string,
subtitle: string,
surfaces: MovementInteriorStyle['surfaces'],
tints: MovementInteriorStyle['tints'],
opts: Partial<Omit<MovementInteriorStyle, 'id' | 'label' | 'subtitle' | 'surfaces' | 'tints'>> & {
details: MovementInteriorStyle['details'];
windows: GalleryWindowSpec[];
}
): MovementInteriorStyle {
return {
id,
label,
subtitle,
surfaces,
tints,
titleColor: opts.titleColor ?? '#4a3020',
ambient: opts.ambient ?? 0.55,
warmLight: opts.warmLight ?? '#fff4e8',
sunLight: opts.sunLight ?? '#fffaf0',
fog: opts.fog ?? '#1a1814',
background: opts.background ?? '#121010',
doorWood: opts.doorWood ?? ['#3d2818', '#4e3624', '#261a10'],
windows: opts.windows,
trackLights: opts.trackLights ?? 0.8,
details: opts.details,
};
}
/** Unique photo-real interior per movement (keyed by database id). */
const BY_MOVEMENT_ID: Record<number, MovementInteriorStyle> = {
27: mk(
'ancient-classical',
'Roman atrium',
'Marble-clad villa · mosaic floor · clerestory daylight',
{ wall: 'limestone', ceiling: 'plaster-warm', floor: 'mosaic-roman' },
{ wall: '#e8e0d0', ceiling: '#f5f0e8', floor: '#c8b898', trim: '#a89878' },
{
details: 'classical',
titleColor: '#5a4830',
ambient: 0.62,
warmLight: '#fff8e8',
windows: windows(
{ wall: 'back', x: -2.5, y: 3.2, width: 1.4, height: 1.8, style: 'roman-arch', lightColor: '#fff8e0', lightIntensity: 3.2 },
{ wall: 'back', x: 2.5, y: 3.2, width: 1.4, height: 1.8, style: 'roman-arch', lightColor: '#fff8e0', lightIntensity: 3.2 },
{ wall: 'left', x: 0, y: 3.0, width: 2.0, height: 1.6, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.8 },
{ wall: 'right', x: 0, y: 3.0, width: 2.0, height: 1.6, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.8 }
),
trackLights: 0.4,
doorWood: ['#6a5840', '#7a6848', '#5a4830'],
}
),
28: mk(
'byzantine-sanctuary',
'Byzantine chapel',
'Gold mosaic walls · amber light through arched windows',
{ wall: 'mosaic-byzantine', ceiling: 'gilded-stucco', floor: 'marble-checker' },
{ wall: '#d4af37', ceiling: '#c8a840', floor: '#ddd8cc', trim: '#b8860b' },
{
details: 'medieval',
titleColor: '#f0e8c0',
ambient: 0.48,
warmLight: '#ffd898',
sunLight: '#ffe8b0',
fog: '#0a0806',
background: '#060504',
windows: windows(
{ wall: 'back', x: 0, y: 2.8, width: 1.0, height: 2.2, style: 'roman-arch', lightColor: '#ffb860', lightIntensity: 2.4 },
{ wall: 'left', x: -1, y: 2.6, width: 0.7, height: 1.8, style: 'roman-arch', lightColor: '#ffb860', lightIntensity: 1.8 },
{ wall: 'right', x: 1, y: 2.6, width: 0.7, height: 1.8, style: 'roman-arch', lightColor: '#ffb860', lightIntensity: 1.8 }
),
trackLights: 0.5,
doorWood: ['#3a3020', '#4a3830', '#2a2018'],
}
),
29: mk(
'gothic-cathedral',
'Gothic hall',
'Stone vault · tall lancet windows · flagstone floor',
{ wall: 'rough-stone', ceiling: 'basalt', floor: 'flagstone' },
{ wall: '#8a8478', ceiling: '#3a3630', floor: '#6a6458', trim: '#5c5648' },
{
details: 'medieval',
titleColor: '#e8dcc8',
ambient: 0.52,
warmLight: '#e8d8c0',
sunLight: '#d0e8ff',
fog: '#0c0c10',
windows: windows(
{ wall: 'back', x: -2, y: 2.8, width: 0.8, height: 2.8, style: 'gothic-lancet', lightColor: '#c8e0ff', lightIntensity: 3.5 },
{ wall: 'back', x: 2, y: 2.8, width: 0.8, height: 2.8, style: 'gothic-lancet', lightColor: '#c8e0ff', lightIntensity: 3.5 },
{ wall: 'left', x: 0, y: 3.0, width: 0.9, height: 2.6, style: 'gothic-lancet', lightColor: '#c8e0ff', lightIntensity: 2.8 },
{ wall: 'right', x: 0, y: 3.0, width: 0.9, height: 2.6, style: 'gothic-lancet', lightColor: '#c8e0ff', lightIntensity: 2.8 }
),
trackLights: 0.3,
}
),
30: mk(
'early-renaissance-palazzo',
'Florentine palazzo',
'Lime-washed walls · terracotta accents · arched windows',
{ wall: 'painted-lime', wallSide: 'stucco-cream', ceiling: 'fresco-worn', floor: 'terracotta-tiles' },
{ wall: '#f4ebe0', ceiling: '#faf6ee', floor: '#c89070', trim: '#c9a227' },
{
details: 'palazzo',
titleColor: '#6b4423',
windows: windows(
{ wall: 'back', x: -2.2, y: 2.6, width: 1.3, height: 1.7, style: 'roman-arch', lightColor: '#fff4e0', lightIntensity: 3.0 },
{ wall: 'back', x: 2.2, y: 2.6, width: 1.3, height: 1.7, style: 'roman-arch', lightColor: '#fff4e0', lightIntensity: 3.0 },
{ wall: 'left', x: 0, y: 2.8, width: 2.2, height: 1.4, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.6 }
),
}
),
31: mk(
'high-renaissance-palazzo',
'Roman palazzo',
'Marble and stucco · coffered ceiling · checker floor',
{ wall: 'marble-veined-carrara', wallSide: 'stucco-cream', ceiling: 'plaster-warm', floor: 'marble-checker' },
{ wall: '#f0ece4', wallSide: '#efe4d4', ceiling: '#faf6ee', floor: '#ddd8cc', trim: '#c9a227' },
{
details: 'palazzo',
titleColor: '#6b4423',
windows: windows(
{ wall: 'back', x: 0, y: 2.8, width: 2.8, height: 1.8, style: 'baroque-pair', lightColor: '#fff8f0', lightIntensity: 3.8 },
{ wall: 'left', x: 0, y: 3.0, width: 2.0, height: 1.5, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.8 },
{ wall: 'right', x: 0, y: 3.0, width: 2.0, height: 1.5, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.8 },
{ wall: 'ceiling', x: 0, y: 0, width: 3.0, height: 2.0, style: 'round-oculus', lightColor: '#ffffff', lightIntensity: 4.0 }
),
}
),
32: mk(
'northern-renaissance-hall',
'Flemish panel hall',
'Oak wainscoting · leaded glass · herringbone floor',
{ wall: 'oak-panel', wallSide: 'plaster-warm', ceiling: 'dark-wood-panel', floor: 'parquet-herringbone' },
{ wall: '#8a6848', wallSide: '#f0ebe3', ceiling: '#3a2818', floor: '#8a6848', trim: '#5c4030' },
{
details: 'salon',
titleColor: '#f0e8d8',
warmLight: '#ffe8c8',
windows: windows(
{ wall: 'back', x: -2, y: 2.5, width: 1.2, height: 1.5, style: 'sash', lightColor: '#e8f0ff', lightIntensity: 2.8 },
{ wall: 'back', x: 2, y: 2.5, width: 1.2, height: 1.5, style: 'sash', lightColor: '#e8f0ff', lightIntensity: 2.8 },
{ wall: 'left', x: 0, y: 2.6, width: 1.8, height: 1.4, style: 'sash', lightColor: '#e8f0ff', lightIntensity: 2.4 }
),
doorWood: ['#4a3020', '#5c3a28', '#3a2010'],
}
),
33: mk(
'mannerist-villa',
'Mannerist gallery',
'Dramatic stucco · elongated windows · veined marble',
{ wall: 'stucco-terracotta', ceiling: 'gilded-stucco', floor: 'marble-veined-emerald' },
{ wall: '#d8b898', ceiling: '#d8c070', floor: '#dce8e0', trim: '#b8860b' },
{
details: 'baroque',
titleColor: '#4a2818',
windows: windows(
{ wall: 'back', x: -1.8, y: 2.7, width: 1.0, height: 2.2, style: 'roman-arch', lightColor: '#fff0d8', lightIntensity: 2.8 },
{ wall: 'back', x: 1.8, y: 2.7, width: 1.0, height: 2.2, style: 'roman-arch', lightColor: '#fff0d8', lightIntensity: 2.8 },
{ wall: 'right', x: 0, y: 3.0, width: 1.6, height: 1.2, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.2 }
),
}
),
34: mk(
'baroque-palace',
'Baroque state gallery',
'Crimson velvet · gilded stucco · grand windows',
{ wall: 'velvet-crimson', ceiling: 'gilded-stucco', floor: 'marble-veined-carrara' },
{ wall: '#5c1828', ceiling: '#d8c070', floor: '#ece8e0', trim: '#d4af37' },
{
details: 'baroque',
titleColor: '#f0d890',
ambient: 0.58,
warmLight: '#ffd898',
fog: '#100808',
windows: windows(
{ wall: 'back', x: 0, y: 2.6, width: 3.2, height: 2.2, style: 'baroque-pair', lightColor: '#fff8e8', lightIntensity: 4.5 },
{ wall: 'left', x: 0, y: 2.8, width: 1.8, height: 1.8, style: 'baroque-pair', lightColor: '#fff8e8', lightIntensity: 3.2 },
{ wall: 'right', x: 0, y: 2.8, width: 1.8, height: 1.8, style: 'baroque-pair', lightColor: '#fff8e8', lightIntensity: 3.2 },
{ wall: 'ceiling', x: 0, y: 0, width: 2.5, height: 1.8, style: 'skylight', lightColor: '#ffffff', lightIntensity: 3.5 }
),
trackLights: 0.6,
doorWood: ['#1a1008', '#2a1810', '#120c06'],
}
),
35: mk(
'rococo-salon',
'Rococo salon',
'Pastel painted walls · gilt trim · chevron parquet',
{ wall: 'painted-oil-satin', ceiling: 'silk-pale', floor: 'parquet-chevrons' },
{ wall: '#e8dce8', ceiling: '#faf6f0', floor: '#c8a882', trim: '#d4af37' },
{
details: 'salon',
titleColor: '#6a4858',
warmLight: '#fff0f0',
windows: windows(
{ wall: 'back', x: -2, y: 2.5, width: 1.4, height: 1.8, style: 'baroque-pair', lightColor: '#fff8ff', lightIntensity: 3.4 },
{ wall: 'back', x: 2, y: 2.5, width: 1.4, height: 1.8, style: 'baroque-pair', lightColor: '#fff8ff', lightIntensity: 3.4 },
{ wall: 'ceiling', x: 0, y: 0, width: 2.0, height: 1.5, style: 'skylight', lightColor: '#ffffff', lightIntensity: 3.0 }
),
}
),
36: mk(
'neoclassical-museum',
'Neoclassical museum',
'White painted walls · coffered ceiling · skylit salon',
{ wall: 'painted-flat', ceiling: 'plaster-white', floor: 'marble-veined-carrara' },
{ wall: '#f2f0ec', ceiling: '#fafafa', floor: '#eceae6', trim: '#b8b0a4' },
{
details: 'neoclassical',
titleColor: '#4a4844',
ambient: 0.65,
windows: windows(
{ wall: 'back', x: 0, y: 2.6, width: 2.8, height: 2.0, style: 'baroque-pair', lightColor: '#ffffff', lightIntensity: 4.0 },
{ wall: 'ceiling', x: 0, y: 0, width: 4.0, height: 2.5, style: 'skylight', lightColor: '#ffffff', lightIntensity: 5.0 },
{ wall: 'left', x: 0, y: 3.0, width: 2.0, height: 1.2, style: 'clerestory', lightColor: '#fffaf0', lightIntensity: 2.5 }
),
trackLights: 0.7,
}
),
37: mk(
'romantic-gothic-revival',
'Romantic gallery',
'Dark walnut paneling · pointed windows · Persian carpet tones',
{ wall: 'walnut-panel', ceiling: 'dark-plaster', floor: 'parquet-herringbone' },
{ wall: '#5a4030', ceiling: '#2a2420', floor: '#6a5040', trim: '#8a7050' },
{
details: 'salon',
titleColor: '#e8dcc8',
ambient: 0.5,
warmLight: '#ffe0c0',
windows: windows(
{ wall: 'back', x: -1.5, y: 2.6, width: 0.9, height: 2.2, style: 'gothic-lancet', lightColor: '#c8d8ff', lightIntensity: 2.6 },
{ wall: 'back', x: 1.5, y: 2.6, width: 0.9, height: 2.2, style: 'gothic-lancet', lightColor: '#c8d8ff', lightIntensity: 2.6 },
{ wall: 'right', x: 0, y: 2.5, width: 1.4, height: 1.6, style: 'sash', lightColor: '#e8f0ff', lightIntensity: 2.2 }
),
}
),
38: mk(
'realist-bourgeois',
'Realist picture gallery',
'Warm painted walls · bourgeois salon · oak parquet',
{ wall: 'painted-emulsion', ceiling: 'painted-emulsion', floor: 'parquet-herringbone' },
{ wall: '#e8e2d8', ceiling: '#f5f0e8', floor: '#a08060', trim: '#8a7050' },
{
details: 'salon',
windows: windows(
{ wall: 'back', x: 0, y: 2.5, width: 2.4, height: 1.6, style: 'sash', lightColor: '#f0f4ff', lightIntensity: 3.2 },
{ wall: 'left', x: 0, y: 2.7, width: 1.6, height: 1.3, style: 'sash', lightColor: '#f0f4ff', lightIntensity: 2.4 }
),
}
),
39: mk(
'impressionist-salon',
'Impressionist salon',
'North-light skylight · pale painted walls · herringbone floor',
{ wall: 'painted-emulsion', ceiling: 'painted-flat', floor: 'parquet-herringbone' },
{ wall: '#f0ebe3', ceiling: '#fafafa', floor: '#c8a882', trim: '#c9a96e' },
{
details: 'salon',
ambient: 0.68,
windows: windows(
{ wall: 'ceiling', x: 0, y: 0, width: 5.0, height: 3.0, style: 'skylight', lightColor: '#ffffff', lightIntensity: 6.0 },
{ wall: 'back', x: -2, y: 2.6, width: 1.2, height: 1.4, style: 'sash', lightColor: '#f0f8ff', lightIntensity: 2.5 },
{ wall: 'back', x: 2, y: 2.6, width: 1.2, height: 1.4, style: 'sash', lightColor: '#f0f8ff', lightIntensity: 2.5 }
),
trackLights: 0.5,
}
),
40: mk(
'post-impressionist-atelier',
'Montmartre atelier',
'Painted studio walls · large north window · worn floorboards',
{ wall: 'painted-emulsion', ceiling: 'painted-emulsion', floor: 'parquet-herringbone' },
{ wall: '#e8e0d0', ceiling: '#f0ebe0', floor: '#9a7858', trim: '#8a6848' },
{
details: 'atelier',
windows: windows(
{ wall: 'left', x: 0, y: 2.4, width: 2.8, height: 2.0, style: 'factory', lightColor: '#f0f8ff', lightIntensity: 4.5 },
{ wall: 'back', x: 0, y: 2.8, width: 1.0, height: 1.2, style: 'sash', lightColor: '#f0f4ff', lightIntensity: 2.0 }
),
}
),
41: mk(
'symbolist-chamber',
'Symbolist chamber',
'Deep green painted walls · amber window glow · dark parquet',
{ wall: 'painted-oil-matte', ceiling: 'dark-plaster', floor: 'parquet-herringbone' },
{ wall: '#1a4030', ceiling: '#1a1814', floor: '#4a3828', trim: '#8a7050' },
{
details: 'salon',
titleColor: '#d8e8c8',
ambient: 0.55,
warmLight: '#ffd898',
windows: windows(
{ wall: 'back', x: 0, y: 2.4, width: 1.0, height: 1.8, style: 'sash', lightColor: '#ffb860', lightIntensity: 2.0 },
{ wall: 'right', x: 0, y: 2.6, width: 0.8, height: 1.4, style: 'gothic-lancet', lightColor: '#ffd080', lightIntensity: 1.6 }
),
trackLights: 0.9,
}
),
42: mk(
'art-nouveau-salon',
'Art Nouveau salon',
'Painted plaster · stained glass · terrazzo floor',
{ wall: 'painted-oil-satin', ceiling: 'silk-gold', floor: 'terrazzo' },
{ wall: '#f0ece4', ceiling: '#d8c890', floor: '#d8d0c4', trim: '#6a9868' },
{
details: 'salon',
titleColor: '#3a5840',
windows: windows(
{ wall: 'back', x: 0, y: 2.5, width: 2.2, height: 2.0, style: 'art-nouveau', lightColor: '#e8ffe8', lightIntensity: 3.2 },
{ wall: 'left', x: 0, y: 2.6, width: 1.4, height: 1.8, style: 'art-nouveau', lightColor: '#ffe8f0', lightIntensity: 2.4 },
{ wall: 'ceiling', x: 0, y: 0, width: 2.0, height: 1.2, style: 'skylight', lightColor: '#ffffff', lightIntensity: 2.8 }
),
}
),
43: mk(
'fauvist-studio',
'Fauvist studio',
'Bold painted walls · flooded with color and light',
{ wall: 'painted-oil-matte', wallSide: 'painted-oil-matte', ceiling: 'painted-emulsion', floor: 'parquet-herringbone' },
{ wall: '#e89060', wallSide: '#e8c860', ceiling: '#f8f0e0', floor: '#a07048', trim: '#c04020' },
{
details: 'atelier',
titleColor: '#402010',
ambient: 0.7,
windows: windows(
{ wall: 'left', x: 0, y: 2.5, width: 3.0, height: 2.2, style: 'factory', lightColor: '#fff8f0', lightIntensity: 5.0 },
{ wall: 'back', x: 0, y: 2.8, width: 1.6, height: 1.2, style: 'sash', lightColor: '#fff0e0', lightIntensity: 2.5 }
),
}
),
44: mk(
'expressionist-room',
'Expressionist room',
'Angular wood panels · dramatic raking light',
{ wall: 'dark-wood-panel', ceiling: 'dark-plaster', floor: 'parquet-herringbone' },
{ wall: '#3a2818', ceiling: '#2a2018', floor: '#5a4030', trim: '#8a6040' },
{
details: 'atelier',
titleColor: '#f0d8b0',
ambient: 0.52,
windows: windows(
{ wall: 'back', x: -1.5, y: 2.6, width: 1.0, height: 1.6, style: 'sash', lightColor: '#ffe8c0', lightIntensity: 2.8 },
{ wall: 'right', x: 0, y: 2.4, width: 2.0, height: 1.8, style: 'factory', lightColor: '#fff0d8', lightIntensity: 3.5 }
),
}
),
45: mk(
'cubist-studio',
'Cubist studio',
'Paris atelier · factory windows · painted plaster',
{ wall: 'painted-emulsion', ceiling: 'painted-flat', floor: 'parquet-herringbone' },
{ wall: '#e8e4dc', ceiling: '#f5f5f5', floor: '#9a8870', trim: '#888888' },
{
details: 'atelier',
ambient: 0.65,
windows: windows(
{ wall: 'left', x: 0, y: 2.5, width: 3.5, height: 2.4, style: 'factory', lightColor: '#f0f8ff', lightIntensity: 5.5 },
{ wall: 'back', x: 0, y: 3.0, width: 1.8, height: 1.0, style: 'clerestory', lightColor: '#ffffff', lightIntensity: 2.5 }
),
}
),
46: mk(
'futurist-loft',
'Futurist loft',
'Steel and glass · industrial concrete · sweeping daylight',
{ wall: 'concrete-raw', ceiling: 'concrete-raw', floor: 'industrial-floor' },
{ wall: '#a8a8a8', ceiling: '#989898', floor: '#888880', trim: '#606060' },
{
details: 'industrial',
titleColor: '#303030',
ambient: 0.62,
fog: '#181818',
windows: windows(
{ wall: 'back', x: 0, y: 2.6, width: 4.0, height: 2.4, style: 'factory', lightColor: '#ffffff', lightIntensity: 6.0 },
{ wall: 'left', x: 0, y: 2.8, width: 2.5, height: 1.6, style: 'factory', lightColor: '#f0f8ff', lightIntensity: 3.5 },
{ wall: 'ceiling', x: 0, y: 0, width: 3.0, height: 2.0, style: 'skylight', lightColor: '#ffffff', lightIntensity: 4.0 }
),
doorWood: ['#606060', '#707070', '#505050'],
}
),
47: mk(
'suprematist-gallery',
'Suprematist white cube',
'Matte white paint · geometric light · polished floor',
{ wall: 'painted-flat', ceiling: 'painted-flat', floor: 'concrete-polished' },
{ wall: '#ffffff', ceiling: '#ffffff', floor: '#e0e0e0', trim: '#cccccc' },
{
details: 'modern',
titleColor: '#222222',
ambient: 0.72,
fog: '#1a1a1a',
background: '#111111',
windows: windows(
{ wall: 'ceiling', x: 0, y: 0, width: 4.5, height: 3.0, style: 'skylight', lightColor: '#ffffff', lightIntensity: 6.5 },
{ wall: 'back', x: 0, y: 2.8, width: 2.0, height: 1.2, style: 'clerestory', lightColor: '#ffffff', lightIntensity: 3.0 }
),
trackLights: 0.4,
doorWood: ['#aaaaaa', '#bbbbbb', '#999999'],
}
),
48: mk(
'constructivist-space',
'Constructivist space',
'Glass block · concrete · angular daylight',
{ wall: 'concrete-block', ceiling: 'concrete-raw', floor: 'concrete-polished' },
{ wall: '#b0b0b0', ceiling: '#a0a0a0', floor: '#c0c0c0', trim: '#808080' },
{
details: 'industrial',
titleColor: '#303030',
ambient: 0.65,
windows: windows(
{ wall: 'back', x: 0, y: 2.5, width: 2.8, height: 2.0, style: 'glass-block', lightColor: '#f0f8ff', lightIntensity: 4.0 },
{ wall: 'left', x: 0, y: 2.6, width: 2.0, height: 1.8, style: 'glass-block', lightColor: '#f0f8ff', lightIntensity: 3.2 },
{ wall: 'ceiling', x: 0, y: 0, width: 2.5, height: 1.5, style: 'skylight', lightColor: '#ffffff', lightIntensity: 3.5 }
),
doorWood: ['#707070', '#808080', '#606060'],
}
),
49: mk(
'dada-salon',
'Dada salon',
'Eclectic bourgeois room · painted walls and exposed brick',
{ wall: 'painted-emulsion', wallSide: 'brick', ceiling: 'painted-emulsion', floor: 'parquet-herringbone' },
{ wall: '#e8dcc8', wallSide: '#8a5040', ceiling: '#f0ebe0', floor: '#8a6848', trim: '#6a4830' },
{
details: 'salon',
windows: windows(
{ wall: 'back', x: -1.5, y: 2.5, width: 1.0, height: 1.4, style: 'sash', lightColor: '#f0f4ff', lightIntensity: 2.5 },
{ wall: 'back', x: 1.5, y: 2.6, width: 0.8, height: 1.8, style: 'gothic-lancet', lightColor: '#ffe8c0', lightIntensity: 2.0 },
{ wall: 'right', x: 0, y: 2.4, width: 1.6, height: 1.6, style: 'factory', lightColor: '#ffffff', lightIntensity: 3.0 }
),
trackLights: 1.0,
}
),
50: mk(
'surrealist-interior',
'Surrealist interior',
'Dark painted walls · uncanny warm light',
{ wall: 'painted-oil-matte', ceiling: 'dark-plaster', floor: 'parquet-herringbone' },
{ wall: '#1a2848', ceiling: '#2a2428', floor: '#5a4838', trim: '#8a7050' },
{
details: 'salon',
titleColor: '#e8dcc8',
ambient: 0.58,
warmLight: '#ffd898',
windows: windows(
{ wall: 'back', x: 0, y: 2.5, width: 1.4, height: 1.6, style: 'sash', lightColor: '#ffe8c8', lightIntensity: 2.8 },
{ wall: 'left', x: 0, y: 2.7, width: 1.0, height: 1.2, style: 'sash', lightColor: '#c8e0ff', lightIntensity: 2.0 },
{ wall: 'ceiling', x: 0, y: 0, width: 1.5, height: 1.0, style: 'skylight', lightColor: '#ffffff', lightIntensity: 2.5 }
),
trackLights: 0.85,
}
),
51: mk(
'abstract-expressionist-loft',
'NYC loft',
'Raw brick and painted plaster · north-light factory windows',
{ wall: 'brick', wallSide: 'painted-flat', ceiling: 'concrete-raw', floor: 'industrial-floor' },
{ wall: '#8a5040', wallSide: '#f5f5f5', ceiling: '#989898', floor: '#888880', trim: '#606060' },
{
details: 'industrial',
titleColor: '#303030',
ambient: 0.65,
windows: windows(
{ wall: 'left', x: 0, y: 2.5, width: 4.0, height: 2.6, style: 'factory', lightColor: '#f0f8ff', lightIntensity: 6.5 },
{ wall: 'ceiling', x: 0, y: 0, width: 3.5, height: 2.0, style: 'skylight', lightColor: '#ffffff', lightIntensity: 4.5 }
),
}
),
52: mk(
'pop-art-gallery',
'Pop Art gallery',
'White painted walls · fluorescent daylight · polished concrete',
{ wall: 'painted-flat', ceiling: 'painted-flat', floor: 'concrete-polished' },
{ wall: '#ffffff', ceiling: '#ffffff', floor: '#d8d8d8', trim: '#cccccc' },
{
details: 'modern',
titleColor: '#222222',
ambient: 0.75,
warmLight: '#ffffff',
fog: '#1a1a1a',
background: '#101010',
windows: windows(
{ wall: 'back', x: 0, y: 2.6, width: 3.0, height: 2.0, style: 'factory', lightColor: '#ffffff', lightIntensity: 5.5 },
{ wall: 'ceiling', x: 0, y: 0, width: 5.0, height: 3.0, style: 'skylight', lightColor: '#ffffff', lightIntensity: 6.0 }
),
trackLights: 0.6,
doorWood: ['#888888', '#999999', '#777777'],
}
),
};
function blendAccent(style: MovementInteriorStyle, accentHex?: string): MovementInteriorStyle {
if (!accentHex) return style;
const w = 0.08;
const mix = (a: string, b: string) => {
const pa = parseInt(a.replace('#', ''), 16);
const pb = parseInt(b.replace('#', ''), 16);
const r = Math.round(((pa >> 16) & 255) * w + ((pb >> 16) & 255) * (1 - w));
const g = Math.round(((pa >> 8) & 255) * w + ((pb >> 8) & 255) * (1 - w));
const bl = Math.round((pa & 255) * w + (pb & 255) * (1 - w));
return `#${((r << 16) | (g << 8) | bl).toString(16).padStart(6, '0')}`;
};
return {
...style,
tints: {
...style.tints,
wall: mix(accentHex, style.tints.wall),
wallSide: style.tints.wallSide ? mix(accentHex, style.tints.wallSide) : undefined,
trim: mix(accentHex, style.tints.trim),
},
};
}
/**
* Styles were authored with legacy ids 2752; gallery_dev uses 126.
* Northern (5) / High Renaissance (6) are swapped vs the legacy sequence.
*/
const DB_ID_TO_STYLE_KEY: Record<number, number> = {
1: 27,
2: 28,
3: 29,
4: 30,
5: 32,
6: 31,
7: 33,
8: 34,
9: 35,
10: 36,
11: 37,
12: 38,
13: 39,
14: 40,
15: 41,
16: 42,
17: 43,
18: 44,
19: 45,
20: 46,
21: 47,
22: 48,
23: 49,
24: 50,
25: 51,
26: 52,
};
/** Fallback name-based resolver for movements not in the catalog. */
function fallbackByName(movement: ArtMovement & { era_name?: string }): MovementInteriorStyle {
const n = movement.name.toLowerCase();
const era = (movement.era_name ?? '').toLowerCase();
if (n.includes('byzantine')) return BY_MOVEMENT_ID[28];
if (n.includes('gothic')) return BY_MOVEMENT_ID[29];
if (n.includes('renaissance')) return BY_MOVEMENT_ID[31];
if (n.includes('baroque') || n.includes('rococo')) return BY_MOVEMENT_ID[34];
if (era.includes('medieval')) return BY_MOVEMENT_ID[29];
if (n.includes('impression')) return BY_MOVEMENT_ID[39];
if (era.includes('modern') || era.includes('contemporary')) return BY_MOVEMENT_ID[52];
return BY_MOVEMENT_ID[36];
}
export function resolveMovementInteriorStyle(
movement: ArtMovement & { era_name?: string }
): MovementInteriorStyle {
const styleKey = DB_ID_TO_STYLE_KEY[movement.id] ?? movement.id;
const base = BY_MOVEMENT_ID[styleKey] ?? fallbackByName(movement);
return blendAccent(base, movement.color);
}
/** @deprecated use surfaces.floor — kept for transitional imports */
export type GalleryFloorKind = string;