feat: premium redesign — DM Serif, refined palette, flat score badges
- Design tokens (ds.ts, theme.ts, scoreTheme.ts): new warm palette (#152642 navy, #f9f8f6 warm white, #e8e7e4 borders, #b8975a gold accent), flat score tier badges replacing CSS gradients, Inter + DM Serif Display typography - Card components: white-background cards, DM Serif score numbers, max-2 badge chips with +N overflow tooltip, editorial score badge positioning - Layout shell: gold left-accent nav active state, 64px top bar, outlined workspace chip, DM Serif page titles - Shared atoms: GenericBadge (outlined/solid variants), ResultFilterBar (simplified chip styles), DecisionContextPanel (dot metrics, no left accent) - Global replacement (118 files): #1e3a5f→#152642, #e2e8f0→#e8e7e4, #f4f6f9→#f9f8f6 — all handled via Node.js for proper UTF-8 safety Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import type { MarketReport } from '../../domain/marketReport'
|
||||
import { DS_TEXT, DS_BG, DS_BORDER, DS_SURFACE } from '../../lib/ds'
|
||||
|
||||
const SECTION_COLORS: Record<string, string> = {
|
||||
development: '#1e3a5f',
|
||||
development: '#152642',
|
||||
demand: '#1a7a4a',
|
||||
supply: '#b45309',
|
||||
negotiation: '#7c3aed',
|
||||
|
||||
@@ -147,10 +147,10 @@ export function MarketKpiPanel({ baseKpis, assetTypeLabel, radius, onRadiusChang
|
||||
border: '1px solid #e2e8f0',
|
||||
color: '#64748b',
|
||||
'&.Mui-selected': {
|
||||
bgcolor: '#1e3a5f',
|
||||
bgcolor: '#152642',
|
||||
color: '#ffffff',
|
||||
borderColor: '#1e3a5f',
|
||||
'&:hover': { bgcolor: '#1e3a5f' },
|
||||
borderColor: '#152642',
|
||||
'&:hover': { bgcolor: '#152642' },
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
@@ -43,8 +43,8 @@ const EVENT_LABELS: Record<ActivityEventType, string> = {
|
||||
}
|
||||
|
||||
const EVENT_COLORS: Record<ActivityEventType, string> = {
|
||||
PROPERTY_CREATED: '#1e3a5f',
|
||||
PROPERTY_UPDATED: '#1e3a5f',
|
||||
PROPERTY_CREATED: '#152642',
|
||||
PROPERTY_UPDATED: '#152642',
|
||||
MATCH_APPROVED: '#1a7a4a',
|
||||
MATCH_REJECTED: '#c0392b',
|
||||
SIGNAL_VERIFIED: '#7c3aed',
|
||||
@@ -68,7 +68,7 @@ const CATEGORY_META: Record<ActivityCategory, { label: string; color: string }>
|
||||
MATCHING: { label: 'Matching', color: '#1a7a4a' },
|
||||
INTELLIGENCE: { label: 'Intelligence', color: '#7c3aed' },
|
||||
REVIEW: { label: 'Review', color: '#d97706' },
|
||||
GOVERNANCE: { label: 'Governance', color: '#1e3a5f' },
|
||||
GOVERNANCE: { label: 'Governance', color: '#152642' },
|
||||
}
|
||||
|
||||
function getEventIcon(type: ActivityEventType) {
|
||||
|
||||
@@ -138,8 +138,8 @@ export function PropertyDetailOverview({ p, editing, draft, onDraftChange }: Pro
|
||||
{/* Mietvertrag */}
|
||||
<Box sx={{ mt: 1.5, p: 1.5, border: '1px solid #e2e8f0', borderRadius: 1.5, bgcolor: p.leaseContractUrl ? '#f8fafc' : '#fafafa' }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mb: p.leaseContractUrl ? 0.75 : 0 }}>
|
||||
<FileText size={13} color={p.leaseContractUrl ? '#1e3a5f' : '#94a3b8'} />
|
||||
<Typography variant="caption" sx={{ fontWeight: 700, color: p.leaseContractUrl ? '#1e3a5f' : '#94a3b8', textTransform: 'uppercase', letterSpacing: 0.4 }}>
|
||||
<FileText size={13} color={p.leaseContractUrl ? '#152642' : '#94a3b8'} />
|
||||
<Typography variant="caption" sx={{ fontWeight: 700, color: p.leaseContractUrl ? '#152642' : '#94a3b8', textTransform: 'uppercase', letterSpacing: 0.4 }}>
|
||||
Mietvertrag
|
||||
</Typography>
|
||||
</Box>
|
||||
@@ -155,7 +155,7 @@ export function PropertyDetailOverview({ p, editing, draft, onDraftChange }: Pro
|
||||
href={p.leaseContractUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{ textTransform: 'none', fontSize: '0.7rem', py: 0.25, px: 1, borderColor: '#cbd5e1', color: '#1e3a5f', whiteSpace: 'nowrap', flexShrink: 0 }}
|
||||
sx={{ textTransform: 'none', fontSize: '0.7rem', py: 0.25, px: 1, borderColor: '#cbd5e1', color: '#152642', whiteSpace: 'nowrap', flexShrink: 0 }}
|
||||
>
|
||||
Öffnen
|
||||
</Button>
|
||||
|
||||
@@ -110,7 +110,7 @@ export function PropertyDetailView({ propertyId, onClose, hideTabs = [] }: Prope
|
||||
startIcon={saving ? <CircularProgress size={12} sx={{ color: 'white' }} /> : <Save size={13} />}
|
||||
onClick={saveEdit}
|
||||
disabled={saving}
|
||||
sx={{ textTransform: 'none', fontSize: '0.75rem', bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#16304d' } }}
|
||||
sx={{ textTransform: 'none', fontSize: '0.75rem', bgcolor: '#152642', '&:hover': { bgcolor: '#16304d' } }}
|
||||
>
|
||||
Speichern
|
||||
</Button>
|
||||
|
||||
@@ -79,7 +79,7 @@ export function PropertyFilterBar({ filters, onFiltersChange }: PropertyFilterBa
|
||||
onClick={() => toggleAssetType(t)}
|
||||
sx={{
|
||||
cursor: 'pointer',
|
||||
...(selectedAssetTypes.includes(t) && { bgcolor: '#1e3a5f', color: 'white', borderColor: '#1e3a5f' }),
|
||||
...(selectedAssetTypes.includes(t) && { bgcolor: '#152642', color: 'white', borderColor: '#152642' }),
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { memo } from 'react'
|
||||
import { Box, Chip, LinearProgress, Tooltip, Typography } from '@mui/material'
|
||||
import { MapPin, Maximize2, TrendingUp, Calendar } from 'lucide-react'
|
||||
import { getAssetTypeColor, getAssetTypeLabel, getAvailabilityLabel } from './propertyHelpers'
|
||||
import { DS_TEXT, DS_BORDER } from '../../lib/ds'
|
||||
import type { Property } from '../../domain/property'
|
||||
|
||||
interface Props {
|
||||
@@ -10,14 +11,13 @@ interface Props {
|
||||
}
|
||||
|
||||
function availabilityColor(status: string) {
|
||||
if (status === 'AVAILABLE_NOW') return { bg: '#dcfce7', text: '#15803d' }
|
||||
if (status === 'AVAILABLE_NOW') return { bg: '#dcfce7', text: '#1d6342' }
|
||||
if (status === 'AVAILABLE_SOON') return { bg: '#fef9c3', text: '#a16207' }
|
||||
return { bg: '#f1f5f9', text: '#64748b' }
|
||||
return { bg: '#f4f3f0', text: '#9a9a9a' }
|
||||
}
|
||||
|
||||
export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({ property: p, onSelect }: Props) {
|
||||
const confPct = Math.round(p.confidenceScore * 100)
|
||||
const confColor = p.confidenceScore >= 0.75 ? '#15803d' : p.confidenceScore >= 0.55 ? '#d97706' : '#dc2626'
|
||||
const annualRent = Math.round(p.areaSqm * p.rentPricePerSqm / 1000)
|
||||
const avail = availabilityColor(p.availabilityStatus)
|
||||
const assetColor = getAssetTypeColor(p.assetType)
|
||||
@@ -29,22 +29,18 @@ export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({
|
||||
sx={{
|
||||
borderRadius: 2,
|
||||
overflow: 'hidden',
|
||||
border: '1px solid #e2e8f0',
|
||||
border: `1px solid ${DS_BORDER.default}`,
|
||||
bgcolor: 'white',
|
||||
boxShadow: '0 1px 4px rgba(0,0,0,0.06)',
|
||||
boxShadow: '0 1px 3px rgba(0,0,0,0.06)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
cursor: 'pointer',
|
||||
transition: 'box-shadow 0.15s, transform 0.12s',
|
||||
'&:hover': {
|
||||
boxShadow: '0 8px 24px rgba(0,0,0,0.12)',
|
||||
transform: 'translateY(-2px)',
|
||||
borderColor: '#cbd5e1',
|
||||
},
|
||||
transition: 'border-color 0.15s',
|
||||
'&:hover': { borderColor: '#c8c7c4' },
|
||||
}}
|
||||
>
|
||||
{/* ── Image / header ── */}
|
||||
<Box sx={{ position: 'relative', height: 120, flexShrink: 0, bgcolor: '#f1f5f9', overflow: 'hidden' }}>
|
||||
<Box sx={{ position: 'relative', height: 140, flexShrink: 0, bgcolor: '#f4f3f0', overflow: 'hidden' }}>
|
||||
{hasImage ? (
|
||||
<Box
|
||||
component="img"
|
||||
@@ -64,7 +60,6 @@ export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Overlay gradient */}
|
||||
<Box sx={{ position: 'absolute', inset: 0, background: 'linear-gradient(to top, rgba(0,0,0,0.45) 0%, transparent 55%)' }} />
|
||||
|
||||
{/* Top badges */}
|
||||
@@ -85,11 +80,15 @@ export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({
|
||||
<Box sx={{ position: 'absolute', bottom: 8, left: 10, right: 10, display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end' }}>
|
||||
<Box>
|
||||
<Typography sx={{ color: 'rgba(255,255,255,0.8)', fontSize: '0.65rem', lineHeight: 1 }}>Jahresmiete ca.</Typography>
|
||||
<Typography sx={{ color: 'white', fontWeight: 800, fontSize: '1.05rem', lineHeight: 1.2 }}>
|
||||
<Typography sx={{
|
||||
color: 'white', lineHeight: 1.2,
|
||||
fontFamily: '"DM Serif Display", serif',
|
||||
fontWeight: 400, fontSize: '1.25rem',
|
||||
}}>
|
||||
CHF {annualRent}k
|
||||
</Typography>
|
||||
</Box>
|
||||
<Typography sx={{ color: 'rgba(255,255,255,0.9)', fontSize: '0.72rem', fontWeight: 600 }}>
|
||||
<Typography sx={{ color: 'rgba(255,255,255,0.85)', fontSize: '0.72rem', fontWeight: 600 }}>
|
||||
{p.rentPricePerSqm} /m²/J
|
||||
</Typography>
|
||||
</Box>
|
||||
@@ -100,12 +99,12 @@ export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({
|
||||
|
||||
{/* Title + location */}
|
||||
<Box>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 700, lineHeight: 1.3, color: '#0f172a', fontSize: '0.875rem' }} noWrap>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 700, lineHeight: 1.3, color: DS_TEXT.primary, fontSize: '0.875rem' }} noWrap>
|
||||
{p.title}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.4, mt: 0.3 }}>
|
||||
<MapPin size={11} color="#94a3b8" />
|
||||
<Typography variant="caption" sx={{ color: '#64748b', fontSize: '0.72rem' }}>
|
||||
<MapPin size={11} color="#9a9a9a" />
|
||||
<Typography variant="caption" sx={{ color: DS_TEXT.muted, fontSize: '0.72rem' }}>
|
||||
{p.location.city}{p.location.district ? ` · ${p.location.district}` : ''}
|
||||
</Typography>
|
||||
</Box>
|
||||
@@ -113,65 +112,61 @@ export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({
|
||||
|
||||
{/* Key metrics row */}
|
||||
<Box sx={{ display: 'flex', gap: 1 }}>
|
||||
<Box sx={{ flex: 1, bgcolor: '#f8fafc', borderRadius: 1, px: 1, py: 0.75, textAlign: 'center', border: '1px solid #f1f5f9' }}>
|
||||
<Box sx={{ flex: 1, bgcolor: '#f9f8f6', borderRadius: 1, px: 1, py: 0.75, textAlign: 'center', border: `1px solid ${DS_BORDER.muted}` }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 0.3, mb: 0.1 }}>
|
||||
<Maximize2 size={10} color="#64748b" />
|
||||
<Typography sx={{ fontSize: '0.62rem', color: '#94a3b8', textTransform: 'uppercase', letterSpacing: 0.3 }}>Fläche</Typography>
|
||||
<Maximize2 size={10} color="#9a9a9a" />
|
||||
<Typography sx={{ fontSize: '0.62rem', color: DS_TEXT.muted, textTransform: 'uppercase', letterSpacing: 0.3 }}>Fläche</Typography>
|
||||
</Box>
|
||||
<Typography sx={{ fontWeight: 700, fontSize: '0.82rem', color: '#0f172a' }}>
|
||||
<Typography sx={{ fontWeight: 700, fontSize: '0.82rem', color: DS_TEXT.primary }}>
|
||||
{p.areaSqm.toLocaleString('de-CH')} m²
|
||||
</Typography>
|
||||
</Box>
|
||||
{p.availabilityDate && (
|
||||
<Box sx={{ flex: 1, bgcolor: '#f8fafc', borderRadius: 1, px: 1, py: 0.75, textAlign: 'center', border: '1px solid #f1f5f9' }}>
|
||||
<Box sx={{ flex: 1, bgcolor: '#f9f8f6', borderRadius: 1, px: 1, py: 0.75, textAlign: 'center', border: `1px solid ${DS_BORDER.muted}` }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 0.3, mb: 0.1 }}>
|
||||
<Calendar size={10} color="#64748b" />
|
||||
<Typography sx={{ fontSize: '0.62rem', color: '#94a3b8', textTransform: 'uppercase', letterSpacing: 0.3 }}>Ab</Typography>
|
||||
<Calendar size={10} color="#9a9a9a" />
|
||||
<Typography sx={{ fontSize: '0.62rem', color: DS_TEXT.muted, textTransform: 'uppercase', letterSpacing: 0.3 }}>Ab</Typography>
|
||||
</Box>
|
||||
<Typography sx={{ fontWeight: 700, fontSize: '0.82rem', color: '#0f172a' }}>
|
||||
<Typography sx={{ fontWeight: 700, fontSize: '0.82rem', color: DS_TEXT.primary }}>
|
||||
{new Date(p.availabilityDate).toLocaleDateString('de-CH', { month: 'short', year: '2-digit' })}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
{p.softFactors?.prestige != null && (
|
||||
<Box sx={{ flex: 1, bgcolor: '#f8fafc', borderRadius: 1, px: 1, py: 0.75, textAlign: 'center', border: '1px solid #f1f5f9' }}>
|
||||
<Box sx={{ flex: 1, bgcolor: '#f9f8f6', borderRadius: 1, px: 1, py: 0.75, textAlign: 'center', border: `1px solid ${DS_BORDER.muted}` }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 0.3, mb: 0.1 }}>
|
||||
<TrendingUp size={10} color="#64748b" />
|
||||
<Typography sx={{ fontSize: '0.62rem', color: '#94a3b8', textTransform: 'uppercase', letterSpacing: 0.3 }}>Prestige</Typography>
|
||||
<TrendingUp size={10} color="#9a9a9a" />
|
||||
<Typography sx={{ fontSize: '0.62rem', color: DS_TEXT.muted, textTransform: 'uppercase', letterSpacing: 0.3 }}>Prestige</Typography>
|
||||
</Box>
|
||||
<Typography sx={{ fontWeight: 700, fontSize: '0.82rem', color: '#0f172a' }}>
|
||||
<Typography sx={{ fontWeight: 700, fontSize: '0.82rem', color: DS_TEXT.primary }}>
|
||||
{p.softFactors.prestige}
|
||||
</Typography>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
{/* Soft factor chips */}
|
||||
{/* Chips: fit-out + contract */}
|
||||
{p.softFactors && (
|
||||
<Box sx={{ display: 'flex', gap: 0.5, flexWrap: 'wrap' }}>
|
||||
{p.softFactors.publicTransportMinutes != null && (
|
||||
<Chip label={`🚇 ${p.softFactors.publicTransportMinutes} min ÖV`} size="small"
|
||||
sx={{ height: 20, fontSize: '0.65rem', bgcolor: '#f0f9ff', color: '#0369a1' }} />
|
||||
)}
|
||||
{p.hardFacts?.fitOut && (() => {
|
||||
const FIT_OUT_META: Record<string, { label: string; tip: string }> = {
|
||||
SHELL: { label: 'Rohbau', tip: 'Keine Einbauten — volle Ausbauinvestition durch Mieter erforderlich (Böden, Decken, Trennwände, TGA).' },
|
||||
BASIC: { label: 'Grundausbau', tip: 'Grundinfrastruktur vorhanden (Böden, Beleuchtung, WCs). Ausbau für Büro/Betrieb noch nötig.' },
|
||||
FULL: { label: 'Vollausbau', tip: 'Bezugsfertig ausgebaut — keine Ausbauinvestition nötig. Direkt einzugsbereit.' },
|
||||
PREMIUM: { label: 'Premium-Ausbau', tip: 'Hochwertig und repräsentativ ausgebaut. Sofort bezugsfertig ohne weiteren Ausbau.' },
|
||||
SHELL: { label: 'Rohbau', tip: 'Keine Einbauten — volle Ausbauinvestition durch Mieter.' },
|
||||
BASIC: { label: 'Grundausbau', tip: 'Grundinfrastruktur vorhanden, Ausbau noch nötig.' },
|
||||
FULL: { label: 'Vollausbau', tip: 'Bezugsfertig ausgebaut.' },
|
||||
PREMIUM: { label: 'Premium-Ausbau', tip: 'Hochwertig ausgebaut, sofort bezugsfertig.' },
|
||||
}
|
||||
const meta = FIT_OUT_META[p.hardFacts!.fitOut!] ?? { label: p.hardFacts!.fitOut!, tip: '' }
|
||||
return (
|
||||
<Tooltip title={meta.tip} placement="top" arrow>
|
||||
<Chip label={meta.label} size="small"
|
||||
sx={{ height: 20, fontSize: '0.65rem', bgcolor: '#f5f3ff', color: '#6d28d9', cursor: 'help' }} />
|
||||
sx={{ height: 20, fontSize: '0.65rem', bgcolor: '#f4f3f0', color: DS_TEXT.secondary, cursor: 'help', border: `1px solid ${DS_BORDER.default}` }} />
|
||||
</Tooltip>
|
||||
)
|
||||
})()}
|
||||
{p.contractDurationMonths && (
|
||||
<Tooltip title={`Mindest-Vertragslaufzeit: ${p.contractDurationMonths} Monate (${Math.round(p.contractDurationMonths / 12)} Jahre)`} placement="top" arrow>
|
||||
<Tooltip title={`Mindest-Vertragslaufzeit: ${p.contractDurationMonths} Monate`} placement="top" arrow>
|
||||
<Chip label={`${p.contractDurationMonths}M Vertrag`} size="small"
|
||||
sx={{ height: 20, fontSize: '0.65rem', bgcolor: '#f1f5f9', color: '#475569', cursor: 'help' }} />
|
||||
sx={{ height: 20, fontSize: '0.65rem', bgcolor: '#f4f3f0', color: DS_TEXT.secondary, cursor: 'help', border: `1px solid ${DS_BORDER.default}` }} />
|
||||
</Tooltip>
|
||||
)}
|
||||
</Box>
|
||||
@@ -180,15 +175,15 @@ export const PropertyIntelligenceCard = memo(function PropertyIntelligenceCard({
|
||||
{/* Confidence bar */}
|
||||
<Box sx={{ mt: 'auto' }}>
|
||||
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.5 }}>
|
||||
<Typography sx={{ fontSize: '0.67rem', color: '#94a3b8', textTransform: 'uppercase', letterSpacing: 0.3 }}>Datenkonfidenz</Typography>
|
||||
<Typography sx={{ fontSize: '0.72rem', fontWeight: 700, color: confColor }}>{confPct}%</Typography>
|
||||
<Typography sx={{ fontSize: '0.67rem', color: DS_TEXT.muted, textTransform: 'uppercase', letterSpacing: 0.3 }}>Datenkonfidenz</Typography>
|
||||
<Typography sx={{ fontSize: '0.72rem', fontWeight: 700, color: p.confidenceScore >= 0.75 ? '#b8975a' : DS_TEXT.muted }}>{confPct}%</Typography>
|
||||
</Box>
|
||||
<LinearProgress
|
||||
variant="determinate"
|
||||
value={confPct}
|
||||
sx={{
|
||||
height: 4, borderRadius: 2, bgcolor: '#f1f5f9',
|
||||
'& .MuiLinearProgress-bar': { bgcolor: confColor, borderRadius: 2 },
|
||||
height: 3, borderRadius: 2, bgcolor: '#f4f3f0',
|
||||
'& .MuiLinearProgress-bar': { bgcolor: '#152642', borderRadius: 2 },
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -12,7 +12,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const STATIC_SECTIONS: { category: SignalCategory; label: string; icon: React.ReactNode; color: string }[] = [
|
||||
{ category: 'development', label: 'Entwicklungsnews', icon: <Building2 size={16} />, color: '#1e3a5f' },
|
||||
{ category: 'development', label: 'Entwicklungsnews', icon: <Building2 size={16} />, color: '#152642' },
|
||||
{ category: 'negotiation', label: 'Verhandlungshinweise', icon: <Lightbulb size={16} />, color: '#7c3aed' },
|
||||
]
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ export function ReminderDetailDrawer() {
|
||||
<Typography variant="caption" color="text.secondary">Fläche: {reminder.areaSqm.toLocaleString('de-CH')} m²</Typography>
|
||||
{reminderProperty?.leaseContractUrl ? (
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 0.75, mt: 0.5 }}>
|
||||
<FileText size={12} color="#1e3a5f" />
|
||||
<FileText size={12} color="#152642" />
|
||||
<Button
|
||||
size="small"
|
||||
variant="outlined"
|
||||
@@ -113,7 +113,7 @@ export function ReminderDetailDrawer() {
|
||||
href={reminderProperty.leaseContractUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{ textTransform: 'none', fontSize: '0.68rem', py: 0.125, px: 0.75, borderColor: '#cbd5e1', color: '#1e3a5f' }}
|
||||
sx={{ textTransform: 'none', fontSize: '0.68rem', py: 0.125, px: 0.75, borderColor: '#cbd5e1', color: '#152642' }}
|
||||
>
|
||||
{reminderProperty.leaseContractName ?? 'Mietvertrag'}
|
||||
</Button>
|
||||
|
||||
@@ -25,7 +25,7 @@ const HORIZON_CONFIG: { key: FilterHorizon; label: string; color: string; bg: st
|
||||
{ key: 'OVERDUE', label: 'Überfällig', color: '#dc2626', bg: '#fef2f2', border: '#fecaca' },
|
||||
{ key: 'THIS_WEEK', label: 'Diese Woche', color: '#ea580c', bg: '#fff7ed', border: '#fed7aa' },
|
||||
{ key: 'THIS_MONTH', label: 'Dieser Monat', color: '#0369a1', bg: '#f0f9ff', border: '#bae6fd' },
|
||||
{ key: 'LATER', label: 'Später', color: '#64748b', bg: '#f8fafc', border: '#e2e8f0' },
|
||||
{ key: 'LATER', label: 'Später', color: '#64748b', bg: '#f8fafc', border: '#e8e7e4' },
|
||||
]
|
||||
|
||||
const LIST_COLS = '100px 130px 1fr 140px 90px 100px 90px'
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { LucideIcon } from 'lucide-react'
|
||||
import type { ReminderType } from '../../domain/reminder'
|
||||
|
||||
const CONFIG: Record<ReminderType, { Icon: LucideIcon; label: string; color: string }> = {
|
||||
LEASE_EXPIRY: { Icon: FileText, label: 'Mietablauf', color: '#1e3a5f' },
|
||||
LEASE_EXPIRY: { Icon: FileText, label: 'Mietablauf', color: '#152642' },
|
||||
BREAK_OPTION: { Icon: ArrowRightLeft, label: 'Break-Option', color: '#7c3aed' },
|
||||
RENT_REVIEW: { Icon: TrendingUp, label: 'Mietanpassung', color: '#0369a1' },
|
||||
INSPECTION: { Icon: ClipboardCheck, label: 'Inspektion', color: '#065f46' },
|
||||
|
||||
@@ -42,7 +42,7 @@ export function SignalCard({ signal }: { signal: PropertyMarketSignal }) {
|
||||
sx={{
|
||||
height: 3,
|
||||
borderRadius: 2,
|
||||
bgcolor: '#e2e8f0',
|
||||
bgcolor: '#e8e7e4',
|
||||
'& .MuiLinearProgress-bar': { bgcolor: signal.confidence >= 0.8 ? '#1a7a4a' : signal.confidence >= 0.6 ? '#d97706' : '#64748b' },
|
||||
}}
|
||||
/>
|
||||
@@ -66,7 +66,7 @@ export function SignalCard({ signal }: { signal: PropertyMarketSignal }) {
|
||||
alignItems: 'center',
|
||||
gap: 0.375,
|
||||
fontSize: '0.62rem',
|
||||
color: signal.sourceUrl ? '#1e3a5f' : '#94a3b8',
|
||||
color: signal.sourceUrl ? '#152642' : '#94a3b8',
|
||||
textDecoration: 'none',
|
||||
'&:hover': signal.sourceUrl ? { textDecoration: 'underline' } : {},
|
||||
}}
|
||||
|
||||
@@ -18,7 +18,7 @@ export function getAssetTypeLabel(type: AssetType): string {
|
||||
|
||||
export function getAssetTypeColor(type: AssetType): string {
|
||||
const colors: Record<string, string> = {
|
||||
OFFICE: '#1e3a5f',
|
||||
OFFICE: '#152642',
|
||||
LOGISTICS: '#d97706',
|
||||
RETAIL: '#7c3aed',
|
||||
GASTRO: '#0d9488',
|
||||
|
||||
@@ -63,7 +63,7 @@ export function ActivityEntry({ entry }: { entry: ReminderActivity }) {
|
||||
<Box sx={{ display: 'flex', gap: 1.5 }}>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', flexShrink: 0 }}>
|
||||
<Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: '#94a3b8', mt: '4px' }} />
|
||||
<Box sx={{ width: 1, flex: 1, bgcolor: '#e2e8f0', mt: 0.5 }} />
|
||||
<Box sx={{ width: 1, flex: 1, bgcolor: '#e8e7e4', mt: 0.5 }} />
|
||||
</Box>
|
||||
<Box sx={{ pb: 1.5, minWidth: 0 }}>
|
||||
<Box sx={{ display: 'flex', gap: 1, alignItems: 'baseline', flexWrap: 'wrap' }}>
|
||||
|
||||
Reference in New Issue
Block a user