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:
@@ -134,7 +134,7 @@ export default function LoginScreen() {
|
||||
variant="contained"
|
||||
fullWidth
|
||||
disabled={loading}
|
||||
sx={{ bgcolor: '#1e3a5f', textTransform: 'none', fontWeight: 600, '&:hover': { bgcolor: '#162d4a' } }}
|
||||
sx={{ bgcolor: '#152642', textTransform: 'none', fontWeight: 600, '&:hover': { bgcolor: '#162d4a' } }}
|
||||
>
|
||||
{loading ? <CircularProgress size={20} sx={{ color: '#fff' }} /> : 'Anmelden'}
|
||||
</Button>
|
||||
@@ -146,7 +146,7 @@ export default function LoginScreen() {
|
||||
<Card elevation={0} sx={{ border: '1px solid #e2e8f0' }}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 2 }}>
|
||||
<Chip label="Demo" size="small" sx={{ bgcolor: '#1e3a5f', color: '#fff', fontSize: '0.7rem', height: 20 }} />
|
||||
<Chip label="Demo" size="small" sx={{ bgcolor: '#152642', color: '#fff', fontSize: '0.7rem', height: 20 }} />
|
||||
<Typography variant="body2" sx={{ fontWeight: 600 }}>
|
||||
Demo-Zugänge
|
||||
</Typography>
|
||||
@@ -169,7 +169,7 @@ export default function LoginScreen() {
|
||||
border: '1px solid #e2e8f0',
|
||||
cursor: 'pointer',
|
||||
transition: 'border-color 0.15s',
|
||||
'&:hover': { borderColor: '#1e3a5f', bgcolor: 'rgba(30,58,95,0.03)' },
|
||||
'&:hover': { borderColor: '#152642', bgcolor: 'rgba(30,58,95,0.03)' },
|
||||
}}
|
||||
>
|
||||
<Box>
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function PropertyDetail() {
|
||||
</Box>
|
||||
</Box>
|
||||
<Box sx={{ textAlign: 'right' }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, color: '#1e3a5f' }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 700, color: '#152642' }}>
|
||||
CHF {monthlyPerSqm.toLocaleString('de-CH')}/m²/Mt.
|
||||
</Typography>
|
||||
<Typography variant="caption" color="text.secondary">{property.areaSqm.toLocaleString('de-CH')} m² total</Typography>
|
||||
|
||||
@@ -138,7 +138,7 @@ export default function Results() {
|
||||
<Card sx={{ bgcolor: '#eff6ff', p: 2, mb: 2, border: '1px solid #bfdbfe' }}>
|
||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 2 }}>
|
||||
<Box>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 700, mb: 0.5 }} color="#1e3a5f">
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 700, mb: 0.5 }} color="#152642">
|
||||
Aktive Suche: {activeNeed.companyName}
|
||||
</Typography>
|
||||
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: '4px 16px' }}>
|
||||
@@ -203,7 +203,7 @@ export default function Results() {
|
||||
size="small"
|
||||
variant="text"
|
||||
onClick={() => navigate('/demand/ai-search')}
|
||||
sx={{ color: '#1e3a5f', flexShrink: 0 }}
|
||||
sx={{ color: '#152642', flexShrink: 0 }}
|
||||
>
|
||||
Suche ändern
|
||||
</Button>
|
||||
|
||||
@@ -170,7 +170,7 @@ const PropertyRow = memo(function PropertyRow({
|
||||
<IconButton
|
||||
size="small"
|
||||
onClick={() => onEdit(property.id)}
|
||||
sx={{ color: '#94a3b8', '&:hover': { color: '#1e3a5f' } }}
|
||||
sx={{ color: '#94a3b8', '&:hover': { color: '#152642' } }}
|
||||
>
|
||||
<Edit2 size={14} />
|
||||
</IconButton>
|
||||
|
||||
@@ -125,7 +125,7 @@ const LeadListItem = memo(function LeadListItem({
|
||||
sx={{
|
||||
px: 2, py: 1.5,
|
||||
borderBottom: '1px solid #f1f5f9',
|
||||
borderLeft: `3px solid ${selected ? '#1e3a5f' : 'transparent'}`,
|
||||
borderLeft: `3px solid ${selected ? '#152642' : 'transparent'}`,
|
||||
bgcolor: selected ? '#f0f9ff' : 'white',
|
||||
cursor: 'pointer',
|
||||
'&:hover': { bgcolor: selected ? '#f0f9ff' : '#f8fafc' },
|
||||
@@ -181,7 +181,7 @@ function ContactRow({ contact }: { contact: ExtractedContact }) {
|
||||
href={href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{ color: '#1e3a5f', fontWeight: 500, fontSize: '0.8125rem', textDecoration: 'none', '&:hover': { textDecoration: 'underline' }, display: 'flex', alignItems: 'center', gap: 0.5 }}
|
||||
sx={{ color: '#152642', fontWeight: 500, fontSize: '0.8125rem', textDecoration: 'none', '&:hover': { textDecoration: 'underline' }, display: 'flex', alignItems: 'center', gap: 0.5 }}
|
||||
>
|
||||
{contact.value}
|
||||
<ExternalLink size={11} />
|
||||
@@ -241,7 +241,7 @@ function PropertyMatchCard({
|
||||
}}
|
||||
onClick={() => navigate('/supply/properties')}
|
||||
>
|
||||
<Building2 size={14} color="#1e3a5f" style={{ flexShrink: 0 }} />
|
||||
<Building2 size={14} color="#152642" style={{ flexShrink: 0 }} />
|
||||
<Box sx={{ flex: 1, minWidth: 0 }}>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: '#0f172a', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||||
{p.title}
|
||||
@@ -271,8 +271,8 @@ function PropertyMatchCard({
|
||||
onClick={() => setOpen(v => !v)}
|
||||
sx={{
|
||||
textTransform: 'none', fontSize: '0.75rem',
|
||||
bgcolor: open ? '#1e3a5f' : undefined,
|
||||
borderColor: open ? '#1e3a5f' : undefined,
|
||||
bgcolor: open ? '#152642' : undefined,
|
||||
borderColor: open ? '#152642' : undefined,
|
||||
'&:hover': { bgcolor: open ? '#162d4a' : undefined },
|
||||
}}
|
||||
>
|
||||
@@ -302,7 +302,7 @@ function PropertyMatchCard({
|
||||
onClick={handleCopy}
|
||||
sx={{
|
||||
textTransform: 'none', fontSize: '0.72rem',
|
||||
color: copied ? '#16a34a' : '#1e3a5f',
|
||||
color: copied ? '#16a34a' : '#152642',
|
||||
}}
|
||||
>
|
||||
{copied ? 'Kopiert!' : 'Kopieren'}
|
||||
@@ -370,7 +370,7 @@ function LeadDetail({ lead }: { lead: MarketLead }) {
|
||||
href={signal.source.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
sx={{ display: 'flex', alignItems: 'center', gap: 0.5, ml: 'auto', color: '#1e3a5f', fontSize: '0.75rem', fontWeight: 600, textDecoration: 'none', '&:hover': { textDecoration: 'underline' } }}
|
||||
sx={{ display: 'flex', alignItems: 'center', gap: 0.5, ml: 'auto', color: '#152642', fontSize: '0.75rem', fontWeight: 600, textDecoration: 'none', '&:hover': { textDecoration: 'underline' } }}
|
||||
>
|
||||
Quelle öffnen <ExternalLink size={11} />
|
||||
</Box>
|
||||
@@ -403,7 +403,7 @@ function LeadDetail({ lead }: { lead: MarketLead }) {
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 0.5 }}>
|
||||
{signal.marketIndicators!.map((ind, i) => (
|
||||
<Box key={i} sx={{ display: 'flex', alignItems: 'flex-start', gap: 0.75 }}>
|
||||
<TrendingUp size={12} color="#1e3a5f" style={{ marginTop: 3, flexShrink: 0 }} />
|
||||
<TrendingUp size={12} color="#152642" style={{ marginTop: 3, flexShrink: 0 }} />
|
||||
<Typography variant="body2" sx={{ lineHeight: 1.5, color: '#1e293b' }}>{ind}</Typography>
|
||||
</Box>
|
||||
))}
|
||||
@@ -531,7 +531,7 @@ const HinweisPropertyCard = memo(function HinweisPropertyCard({
|
||||
cursor: 'default',
|
||||
}}
|
||||
>
|
||||
<Building2 size={14} color="#1e3a5f" style={{ flexShrink: 0 }} />
|
||||
<Building2 size={14} color="#152642" style={{ flexShrink: 0 }} />
|
||||
<Box sx={{ flex: 1, minWidth: 0 }}>
|
||||
<Typography variant="body2" sx={{ fontWeight: 600, color: '#0f172a', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
||||
{p.title}
|
||||
@@ -561,8 +561,8 @@ const HinweisPropertyCard = memo(function HinweisPropertyCard({
|
||||
onClick={() => setOpen(v => !v)}
|
||||
sx={{
|
||||
textTransform: 'none', fontSize: '0.75rem',
|
||||
bgcolor: open ? '#1e3a5f' : undefined,
|
||||
borderColor: open ? '#1e3a5f' : undefined,
|
||||
bgcolor: open ? '#152642' : undefined,
|
||||
borderColor: open ? '#152642' : undefined,
|
||||
'&:hover': { bgcolor: open ? '#162d4a' : undefined },
|
||||
}}
|
||||
>
|
||||
@@ -581,7 +581,7 @@ const HinweisPropertyCard = memo(function HinweisPropertyCard({
|
||||
size="small"
|
||||
startIcon={copied ? <CheckCircle2 size={13} /> : <Copy size={13} />}
|
||||
onClick={handleCopy}
|
||||
sx={{ textTransform: 'none', fontSize: '0.72rem', color: copied ? '#16a34a' : '#1e3a5f' }}
|
||||
sx={{ textTransform: 'none', fontSize: '0.72rem', color: copied ? '#16a34a' : '#152642' }}
|
||||
>
|
||||
{copied ? 'Kopiert!' : 'Kopieren'}
|
||||
</Button>
|
||||
@@ -644,7 +644,7 @@ const HinweisListItem = memo(function HinweisListItem({
|
||||
sx={{
|
||||
px: 2, py: 1.5,
|
||||
borderBottom: '1px solid #f1f5f9',
|
||||
borderLeft: `3px solid ${selected ? '#1e3a5f' : 'transparent'}`,
|
||||
borderLeft: `3px solid ${selected ? '#152642' : 'transparent'}`,
|
||||
bgcolor: selected ? '#f0f9ff' : 'white',
|
||||
cursor: 'pointer',
|
||||
'&:hover': { bgcolor: selected ? '#f0f9ff' : '#f8fafc' },
|
||||
@@ -654,7 +654,7 @@ const HinweisListItem = memo(function HinweisListItem({
|
||||
<Box sx={{ display: 'flex', alignItems: 'flex-start', gap: 0.75, mb: 0.25 }}>
|
||||
<Box sx={{ mt: 0.25, flexShrink: 0 }}>
|
||||
{hinweis.direction === 'SUCHE'
|
||||
? <Search size={14} color="#1e3a5f" />
|
||||
? <Search size={14} color="#152642" />
|
||||
: <Building2 size={14} color="#7c3aed" />
|
||||
}
|
||||
</Box>
|
||||
@@ -1003,7 +1003,7 @@ function HinweisErfassenDialog({
|
||||
variant="contained"
|
||||
onClick={handleSave}
|
||||
disabled={mutation.isPending || !isValid}
|
||||
sx={{ textTransform: 'none', bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#162d4a' } }}
|
||||
sx={{ textTransform: 'none', bgcolor: '#152642', '&:hover': { bgcolor: '#162d4a' } }}
|
||||
>
|
||||
Speichern
|
||||
</Button>
|
||||
@@ -1075,7 +1075,7 @@ export default function MarketIntelligence() {
|
||||
<Box sx={{ width: 360, flexShrink: 0, borderRight: '1px solid #e2e8f0', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
|
||||
<Box sx={{ px: 2, py: 1.25, borderBottom: '1px solid #e2e8f0', display: 'flex', alignItems: 'center', gap: 1, flexShrink: 0 }}>
|
||||
<Typography variant="subtitle2" sx={{ fontWeight: 600, flex: 1 }}>Erkannte Signale</Typography>
|
||||
<Chip label={leadsLoading ? '…' : leads.length} size="small" sx={{ bgcolor: '#1e3a5f', color: '#fff', fontSize: '0.7rem', height: 20 }} />
|
||||
<Chip label={leadsLoading ? '…' : leads.length} size="small" sx={{ bgcolor: '#152642', color: '#fff', fontSize: '0.7rem', height: 20 }} />
|
||||
</Box>
|
||||
<Box sx={{ flex: 1, overflowY: 'auto' }}>
|
||||
{leadsLoading
|
||||
@@ -1130,7 +1130,7 @@ export default function MarketIntelligence() {
|
||||
onClick={() => setErfassenOpen(true)}
|
||||
sx={{
|
||||
textTransform: 'none', fontSize: '0.72rem',
|
||||
bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#162d4a' },
|
||||
bgcolor: '#152642', '&:hover': { bgcolor: '#162d4a' },
|
||||
minWidth: 'auto',
|
||||
}}
|
||||
>
|
||||
@@ -1147,7 +1147,7 @@ export default function MarketIntelligence() {
|
||||
onClick={() => setHinweisFilter(f)}
|
||||
sx={{
|
||||
height: 22, fontSize: '0.68rem', cursor: 'pointer',
|
||||
bgcolor: hinweisFilter === f ? '#1e3a5f' : '#f1f5f9',
|
||||
bgcolor: hinweisFilter === f ? '#152642' : '#f1f5f9',
|
||||
color: hinweisFilter === f ? 'white' : '#475569',
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -104,7 +104,7 @@ function MatchListItem({
|
||||
sx={{
|
||||
textTransform: 'none',
|
||||
fontSize: '0.75rem',
|
||||
bgcolor: '#1e3a5f',
|
||||
bgcolor: '#152642',
|
||||
'&:hover': { bgcolor: '#162d4a' },
|
||||
}}
|
||||
>
|
||||
@@ -351,7 +351,7 @@ export default function MyListings() {
|
||||
variant="contained"
|
||||
startIcon={<Plus size={16} />}
|
||||
onClick={() => navigate('/supply/new-listing')}
|
||||
sx={{ bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#162d4a' }, textTransform: 'none' }}
|
||||
sx={{ bgcolor: '#152642', '&:hover': { bgcolor: '#162d4a' }, textTransform: 'none' }}
|
||||
>
|
||||
Neues Inserat
|
||||
</Button>
|
||||
|
||||
@@ -177,7 +177,7 @@ export default function Properties() {
|
||||
variant={criticalGaps.length > 0 || staleOrOutdated.length > 0 ? 'contained' : 'outlined'}
|
||||
onClick={() => navigate('/supply/data-quality')}
|
||||
sx={criticalGaps.length > 0 || staleOrOutdated.length > 0
|
||||
? { bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#162d4a' }, textTransform: 'none', fontSize: '0.75rem', py: 0.375, px: 1.5, flexShrink: 0 }
|
||||
? { bgcolor: '#152642', '&:hover': { bgcolor: '#162d4a' }, textTransform: 'none', fontSize: '0.75rem', py: 0.375, px: 1.5, flexShrink: 0 }
|
||||
: { textTransform: 'none', fontSize: '0.75rem', py: 0.375, px: 1.5, flexShrink: 0 }
|
||||
}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user