generated from knso/webklar-preview-template
App-Design-Politur: Papier-Look, Kacheln, Ampel-Streifen, großer Titel
- Theme: warmer Papier-Hintergrund (#FAF7F0) wie die Webseite, Inhalte als weiße Karten mit dezentem Schatten + warmem Rand; Marker-Gelb als Akzentfarbe für die Kernaussage - Home: iOS-Großtitel (kollabiert beim Scrollen), Hero-Button mit Schatten, Kachel-Navigation statt halbbreiter Text-Buttons (behebt Umbruch "Einstellunge/n"), Abschnitts-Label, Brief-Karten mit Ampel-Farbstreifen links, freundlicher Leerzustand - Analyse: Kernaussage als Textmarker-Karte (Markenzeichen), Frist/ Termin-Karte in Ampel-Tönung mit Farbstreifen, einheitliche Karten - Ampel-Banner: Streifen-Look statt Vollrahmen - Layout-Fix: Home als FlatList-Wurzel mit automatischem Inset (vorher verdeckte der große Titel die Kopf-Buttons) Barrierefreiheit unverändert: Schriftgrößen, Touch-Targets, Kontraste. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
12
App.tsx
12
App.tsx
@@ -36,13 +36,23 @@ export default function App() {
|
|||||||
<Stack.Navigator
|
<Stack.Navigator
|
||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerStyle: { backgroundColor: farben.hintergrund },
|
headerStyle: { backgroundColor: farben.hintergrund },
|
||||||
|
headerShadowVisible: false,
|
||||||
headerTintColor: farben.primaer,
|
headerTintColor: farben.primaer,
|
||||||
headerTitleStyle: { fontSize: schrift.gross, fontWeight: '700' },
|
headerTitleStyle: { fontSize: schrift.gross, fontWeight: '700' },
|
||||||
headerBackTitle: 'Zurück',
|
headerBackTitle: 'Zurück',
|
||||||
contentStyle: { backgroundColor: farben.hintergrund },
|
contentStyle: { backgroundColor: farben.hintergrund },
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Stack.Screen name="Home" component={HomeScreen} options={{ title: 'BehördenKlar' }} />
|
<Stack.Screen
|
||||||
|
name="Home"
|
||||||
|
component={HomeScreen}
|
||||||
|
options={{
|
||||||
|
title: 'BehördenKlar',
|
||||||
|
headerLargeTitle: true,
|
||||||
|
headerLargeTitleStyle: { color: farben.primaer, fontWeight: '800' },
|
||||||
|
headerLargeStyle: { backgroundColor: farben.hintergrund },
|
||||||
|
}}
|
||||||
|
/>
|
||||||
<Stack.Screen name="Consent" component={ConsentScreen} options={{ title: 'Datenschutz' }} />
|
<Stack.Screen name="Consent" component={ConsentScreen} options={{ title: 'Datenschutz' }} />
|
||||||
<Stack.Screen name="Scan" component={ScanScreen} options={{ title: 'Brief scannen' }} />
|
<Stack.Screen name="Scan" component={ScanScreen} options={{ title: 'Brief scannen' }} />
|
||||||
<Stack.Screen name="Analyse" component={AnalyseScreen} options={{ title: 'Ihr Brief erklärt' }} />
|
<Stack.Screen name="Analyse" component={AnalyseScreen} options={{ title: 'Ihr Brief erklärt' }} />
|
||||||
|
|||||||
BIN
rechtliches/~$hoerdenKlar-Datenschutz.docx
Normal file
BIN
rechtliches/~$hoerdenKlar-Datenschutz.docx
Normal file
Binary file not shown.
@@ -26,8 +26,9 @@ const styles = StyleSheet.create({
|
|||||||
banner: {
|
banner: {
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
borderWidth: 2,
|
borderWidth: 1,
|
||||||
borderRadius: 12,
|
borderLeftWidth: 6,
|
||||||
|
borderRadius: 14,
|
||||||
padding: abstand.m,
|
padding: abstand.m,
|
||||||
gap: abstand.s,
|
gap: abstand.s,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -61,16 +61,24 @@ export function GrossButton({
|
|||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
button: {
|
button: {
|
||||||
minHeight: TOUCH_TARGET,
|
minHeight: TOUCH_TARGET,
|
||||||
borderRadius: 14,
|
borderRadius: 16,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingHorizontal: abstand.l,
|
paddingHorizontal: abstand.l,
|
||||||
paddingVertical: abstand.s,
|
paddingVertical: abstand.s,
|
||||||
},
|
},
|
||||||
primaer: { backgroundColor: farben.primaer },
|
primaer: {
|
||||||
sekundaer: { backgroundColor: farben.hintergrund, borderWidth: 2, borderColor: farben.primaer },
|
backgroundColor: farben.primaer,
|
||||||
|
// Tiefe fürs wichtigste Element auf dem Bildschirm
|
||||||
|
shadowColor: farben.primaer,
|
||||||
|
shadowOffset: { width: 0, height: 4 },
|
||||||
|
shadowOpacity: 0.28,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 4,
|
||||||
|
},
|
||||||
|
sekundaer: { backgroundColor: farben.flaeche, borderWidth: 2, borderColor: farben.primaer },
|
||||||
gefahr: { backgroundColor: farben.fehler },
|
gefahr: { backgroundColor: farben.fehler },
|
||||||
deaktiviert: { opacity: 0.5 },
|
deaktiviert: { opacity: 0.5 },
|
||||||
gedrueckt: { opacity: 0.8 },
|
gedrueckt: { opacity: 0.8, transform: [{ translateY: 1 }] },
|
||||||
text: { fontSize: schrift.gross, fontWeight: '700', textAlign: 'center' },
|
text: { fontSize: schrift.gross, fontWeight: '700', textAlign: 'center' },
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { formatiereDatum } from '../services/erinnerungen';
|
|||||||
import { berechneAmpel } from '../utils/ampel';
|
import { berechneAmpel } from '../utils/ampel';
|
||||||
import { Ampel } from '../components/Ampel';
|
import { Ampel } from '../components/Ampel';
|
||||||
import { GrossButton } from '../components/GrossButton';
|
import { GrossButton } from '../components/GrossButton';
|
||||||
import { farben, schrift, abstand, TOUCH_TARGET } from '../theme';
|
import { farben, schrift, abstand, kartenSchatten, TOUCH_TARGET } from '../theme';
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<RootStackParamList, 'Analyse'>;
|
type Props = NativeStackScreenProps<RootStackParamList, 'Analyse'>;
|
||||||
|
|
||||||
@@ -154,7 +154,12 @@ export function AnalyseScreen({ navigation, route }: Props) {
|
|||||||
|
|
||||||
{/* Frist / Termin */}
|
{/* Frist / Termin */}
|
||||||
{(analyse.frist || analyse.termin) && (
|
{(analyse.frist || analyse.termin) && (
|
||||||
<View style={[styles.karte, { borderColor: ampel.farbe, borderWidth: 2 }]}>
|
<View
|
||||||
|
style={[
|
||||||
|
styles.karte,
|
||||||
|
{ backgroundColor: ampel.hintergrund, borderLeftWidth: 6, borderLeftColor: ampel.farbe },
|
||||||
|
]}
|
||||||
|
>
|
||||||
{analyse.frist && (
|
{analyse.frist && (
|
||||||
<Text style={styles.fristText}>
|
<Text style={styles.fristText}>
|
||||||
📅 Frist: <Text style={styles.fett}>{formatiereDatum(analyse.frist.datum)}</Text>
|
📅 Frist: <Text style={styles.fett}>{formatiereDatum(analyse.frist.datum)}</Text>
|
||||||
@@ -270,18 +275,23 @@ const styles = StyleSheet.create({
|
|||||||
zentriert: { flex: 1, justifyContent: 'center', alignItems: 'center' },
|
zentriert: { flex: 1, justifyContent: 'center', alignItems: 'center' },
|
||||||
karte: {
|
karte: {
|
||||||
backgroundColor: farben.flaeche,
|
backgroundColor: farben.flaeche,
|
||||||
borderRadius: 14,
|
borderRadius: 16,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: farben.rand,
|
||||||
padding: abstand.m,
|
padding: abstand.m,
|
||||||
marginTop: abstand.m,
|
marginTop: abstand.m,
|
||||||
gap: abstand.s,
|
gap: abstand.s,
|
||||||
|
...kartenSchatten,
|
||||||
},
|
},
|
||||||
|
// DIE Antwort der App — als "Textmarker"-Karte hervorgehoben (Markenzeichen)
|
||||||
karteWichtig: {
|
karteWichtig: {
|
||||||
backgroundColor: farben.flaeche,
|
backgroundColor: farben.markerHintergrund,
|
||||||
borderRadius: 14,
|
borderRadius: 16,
|
||||||
borderWidth: 2,
|
borderWidth: 1,
|
||||||
borderColor: farben.primaer,
|
borderColor: farben.markerRand,
|
||||||
padding: abstand.m,
|
padding: abstand.m,
|
||||||
marginTop: abstand.m,
|
marginTop: abstand.m,
|
||||||
|
...kartenSchatten,
|
||||||
},
|
},
|
||||||
abschnittTitel: {
|
abschnittTitel: {
|
||||||
fontSize: schrift.gross,
|
fontSize: schrift.gross,
|
||||||
@@ -289,7 +299,7 @@ const styles = StyleSheet.create({
|
|||||||
color: farben.primaer,
|
color: farben.primaer,
|
||||||
marginBottom: abstand.xs,
|
marginBottom: abstand.xs,
|
||||||
},
|
},
|
||||||
kernaussage: { fontSize: schrift.gross, color: farben.text, lineHeight: 30 },
|
kernaussage: { fontSize: schrift.gross, color: farben.text, lineHeight: 30, fontWeight: '500' },
|
||||||
text: { fontSize: schrift.basis, color: farben.text, lineHeight: 27 },
|
text: { fontSize: schrift.basis, color: farben.text, lineHeight: 27 },
|
||||||
fett: { fontWeight: '700' },
|
fett: { fontWeight: '700' },
|
||||||
fristText: { fontSize: schrift.basis, color: farben.text, lineHeight: 28 },
|
fristText: { fontSize: schrift.basis, color: farben.text, lineHeight: 28 },
|
||||||
@@ -307,11 +317,13 @@ const styles = StyleSheet.create({
|
|||||||
sprachButton: {
|
sprachButton: {
|
||||||
marginTop: abstand.m,
|
marginTop: abstand.m,
|
||||||
minHeight: TOUCH_TARGET,
|
minHeight: TOUCH_TARGET,
|
||||||
borderRadius: 14,
|
borderRadius: 16,
|
||||||
borderWidth: 2,
|
borderWidth: 1,
|
||||||
borderColor: farben.rand,
|
borderColor: farben.rand,
|
||||||
|
backgroundColor: farben.flaeche,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
paddingHorizontal: abstand.m,
|
paddingHorizontal: abstand.m,
|
||||||
|
...kartenSchatten,
|
||||||
},
|
},
|
||||||
sprachButtonText: { fontSize: schrift.basis, color: farben.text, fontWeight: '600' },
|
sprachButtonText: { fontSize: schrift.basis, color: farben.text, fontWeight: '600' },
|
||||||
modalHintergrund: {
|
modalHintergrund: {
|
||||||
|
|||||||
@@ -18,10 +18,36 @@ import { holeConsent } from '../services/storage';
|
|||||||
import { berechneAmpel } from '../utils/ampel';
|
import { berechneAmpel } from '../utils/ampel';
|
||||||
import { formatiereDatum } from '../services/erinnerungen';
|
import { formatiereDatum } from '../services/erinnerungen';
|
||||||
import { GrossButton } from '../components/GrossButton';
|
import { GrossButton } from '../components/GrossButton';
|
||||||
import { farben, schrift, abstand } from '../theme';
|
import { farben, schrift, abstand, kartenSchatten, TOUCH_TARGET } from '../theme';
|
||||||
|
|
||||||
type Props = NativeStackScreenProps<RootStackParamList, 'Home'>;
|
type Props = NativeStackScreenProps<RootStackParamList, 'Home'>;
|
||||||
|
|
||||||
|
/** Quadratische Navigations-Kachel: Symbol oben, Beschriftung darunter.
|
||||||
|
* (Löst das Platzproblem nebeneinanderstehender Text-Buttons.) */
|
||||||
|
function Kachel({
|
||||||
|
symbol,
|
||||||
|
titel,
|
||||||
|
onPress,
|
||||||
|
}: {
|
||||||
|
symbol: string;
|
||||||
|
titel: string;
|
||||||
|
onPress: () => void;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
style={({ pressed }) => [styles.kachel, pressed && { opacity: 0.7 }]}
|
||||||
|
onPress={onPress}
|
||||||
|
accessibilityRole="button"
|
||||||
|
accessibilityLabel={titel}
|
||||||
|
>
|
||||||
|
<Text style={styles.kachelSymbol}>{symbol}</Text>
|
||||||
|
<Text style={styles.kachelTitel} numberOfLines={1}>
|
||||||
|
{titel}
|
||||||
|
</Text>
|
||||||
|
</Pressable>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export function HomeScreen({ navigation }: Props) {
|
export function HomeScreen({ navigation }: Props) {
|
||||||
const briefe = useAppStore((s) => s.briefe);
|
const briefe = useAppStore((s) => s.briefe);
|
||||||
const removeBrief = useAppStore((s) => s.removeBrief);
|
const removeBrief = useAppStore((s) => s.removeBrief);
|
||||||
@@ -58,13 +84,16 @@ export function HomeScreen({ navigation }: Props) {
|
|||||||
const ampel = berechneAmpel(item.analyse);
|
const ampel = berechneAmpel(item.analyse);
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
style={({ pressed }) => [styles.karte, pressed && { opacity: 0.7 }]}
|
style={({ pressed }) => [
|
||||||
|
styles.karte,
|
||||||
|
{ borderLeftColor: ampel.farbe },
|
||||||
|
pressed && { opacity: 0.7 },
|
||||||
|
]}
|
||||||
onPress={() => navigation.navigate('Analyse', { briefId: item.id })}
|
onPress={() => navigation.navigate('Analyse', { briefId: item.id })}
|
||||||
onLongPress={() => loeschenBestaetigen(item)}
|
onLongPress={() => loeschenBestaetigen(item)}
|
||||||
accessibilityRole="button"
|
accessibilityRole="button"
|
||||||
accessibilityLabel={`Brief: ${item.analyse.brieftyp}. ${ampel.text}. Lange drücken zum Löschen.`}
|
accessibilityLabel={`Brief: ${item.analyse.brieftyp}. ${ampel.text}. Lange drücken zum Löschen.`}
|
||||||
>
|
>
|
||||||
<View style={[styles.ampelPunkt, { backgroundColor: ampel.farbe }]} />
|
|
||||||
<View style={{ flex: 1 }}>
|
<View style={{ flex: 1 }}>
|
||||||
<Text style={styles.kartenTitel} numberOfLines={1}>
|
<Text style={styles.kartenTitel} numberOfLines={1}>
|
||||||
{item.analyse.brieftyp}
|
{item.analyse.brieftyp}
|
||||||
@@ -82,65 +111,89 @@ export function HomeScreen({ navigation }: Props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<FlatList
|
||||||
<View style={styles.kopf}>
|
style={styles.container}
|
||||||
<GrossButton titel="Brief scannen" symbol="📷" onPress={scanStarten} />
|
// iOS: sorgt beim großen Titel für korrekte Abstände + Kollabieren beim Scrollen
|
||||||
<View style={styles.reihe}>
|
contentInsetAdjustmentBehavior="automatic"
|
||||||
<View style={{ flex: 1 }}>
|
keyboardShouldPersistTaps="handled"
|
||||||
<GrossButton
|
data={gefiltert}
|
||||||
titel="Glossar"
|
keyExtractor={(b) => b.id}
|
||||||
variante="sekundaer"
|
renderItem={renderBrief}
|
||||||
symbol="📖"
|
contentContainerStyle={styles.inhalt}
|
||||||
onPress={() => navigation.navigate('Glossar')}
|
ListHeaderComponent={
|
||||||
/>
|
<View style={styles.kopf}>
|
||||||
</View>
|
<GrossButton titel="Brief scannen" symbol="📷" onPress={scanStarten} />
|
||||||
<View style={{ width: abstand.s }} />
|
<View style={styles.reihe}>
|
||||||
<View style={{ flex: 1 }}>
|
<Kachel symbol="📖" titel="Glossar" onPress={() => navigation.navigate('Glossar')} />
|
||||||
<GrossButton
|
<Kachel
|
||||||
titel="Einstellungen"
|
|
||||||
variante="sekundaer"
|
|
||||||
symbol="⚙️"
|
symbol="⚙️"
|
||||||
|
titel="Einstellungen"
|
||||||
onPress={() => navigation.navigate('Einstellungen')}
|
onPress={() => navigation.navigate('Einstellungen')}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
{briefe.length > 0 && (
|
||||||
|
<>
|
||||||
|
<Text style={styles.abschnittsLabel}>Ihre Briefe</Text>
|
||||||
|
<TextInput
|
||||||
|
style={styles.suche}
|
||||||
|
placeholder="Im Archiv suchen…"
|
||||||
|
placeholderTextColor={farben.textSekundaer}
|
||||||
|
value={suche}
|
||||||
|
onChangeText={setSuche}
|
||||||
|
accessibilityLabel="Archiv durchsuchen"
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
}
|
||||||
|
ListEmptyComponent={
|
||||||
{briefe.length > 0 && (
|
briefe.length === 0 ? (
|
||||||
<TextInput
|
<View style={styles.leerBox}>
|
||||||
style={styles.suche}
|
<Text style={styles.leerSymbol}>📬</Text>
|
||||||
placeholder="Im Archiv suchen…"
|
<Text style={styles.leerTitel}>Noch keine Briefe</Text>
|
||||||
placeholderTextColor={farben.textSekundaer}
|
<Text style={styles.leer}>
|
||||||
value={suche}
|
Scannen Sie Ihren ersten Behördenbrief —{'\n'}in einer Minute
|
||||||
onChangeText={setSuche}
|
wissen Sie, was er bedeutet.
|
||||||
accessibilityLabel="Archiv durchsuchen"
|
</Text>
|
||||||
/>
|
</View>
|
||||||
)}
|
) : (
|
||||||
|
<Text style={styles.leer}>Keine Treffer.</Text>
|
||||||
<FlatList
|
)
|
||||||
data={gefiltert}
|
}
|
||||||
keyExtractor={(b) => b.id}
|
/>
|
||||||
renderItem={renderBrief}
|
|
||||||
contentContainerStyle={{ padding: abstand.m, paddingTop: 0 }}
|
|
||||||
ListEmptyComponent={
|
|
||||||
<Text style={styles.leer}>
|
|
||||||
{briefe.length === 0
|
|
||||||
? 'Noch keine Briefe.\nScannen Sie Ihren ersten Behördenbrief!'
|
|
||||||
: 'Keine Treffer.'}
|
|
||||||
</Text>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
container: { flex: 1, backgroundColor: farben.hintergrund },
|
container: { flex: 1, backgroundColor: farben.hintergrund },
|
||||||
kopf: { padding: abstand.m, gap: abstand.s },
|
inhalt: { paddingHorizontal: abstand.m, paddingBottom: abstand.l },
|
||||||
reihe: { flexDirection: 'row' },
|
kopf: { paddingTop: abstand.s, paddingBottom: abstand.s, gap: abstand.s },
|
||||||
|
reihe: { flexDirection: 'row', gap: abstand.s },
|
||||||
|
kachel: {
|
||||||
|
flex: 1,
|
||||||
|
minHeight: TOUCH_TARGET + 22,
|
||||||
|
backgroundColor: farben.flaeche,
|
||||||
|
borderRadius: 16,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: farben.rand,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
paddingVertical: abstand.s,
|
||||||
|
gap: 4,
|
||||||
|
...kartenSchatten,
|
||||||
|
},
|
||||||
|
kachelSymbol: { fontSize: 26 },
|
||||||
|
kachelTitel: { fontSize: schrift.klein + 1, fontWeight: '600', color: farben.primaer },
|
||||||
|
abschnittsLabel: {
|
||||||
|
marginTop: abstand.m,
|
||||||
|
fontSize: schrift.klein - 1,
|
||||||
|
fontWeight: '600',
|
||||||
|
letterSpacing: 1.2,
|
||||||
|
textTransform: 'uppercase',
|
||||||
|
color: farben.textSekundaer,
|
||||||
|
},
|
||||||
suche: {
|
suche: {
|
||||||
marginHorizontal: abstand.m,
|
backgroundColor: farben.flaeche,
|
||||||
marginBottom: abstand.s,
|
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderColor: farben.rand,
|
borderColor: farben.rand,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
@@ -154,20 +207,25 @@ const styles = StyleSheet.create({
|
|||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: farben.flaeche,
|
backgroundColor: farben.flaeche,
|
||||||
borderRadius: 14,
|
borderRadius: 14,
|
||||||
|
borderWidth: 1,
|
||||||
|
borderColor: farben.rand,
|
||||||
|
borderLeftWidth: 6,
|
||||||
padding: abstand.m,
|
padding: abstand.m,
|
||||||
marginBottom: abstand.s,
|
marginBottom: abstand.s,
|
||||||
gap: abstand.s,
|
gap: abstand.s,
|
||||||
|
...kartenSchatten,
|
||||||
},
|
},
|
||||||
ampelPunkt: { width: 16, height: 16, borderRadius: 8 },
|
|
||||||
kartenTitel: { fontSize: schrift.basis, fontWeight: '700', color: farben.text },
|
kartenTitel: { fontSize: schrift.basis, fontWeight: '700', color: farben.text },
|
||||||
kartenUntertitel: { fontSize: schrift.klein, color: farben.textSekundaer, marginTop: 2 },
|
kartenUntertitel: { fontSize: schrift.klein, color: farben.textSekundaer, marginTop: 2 },
|
||||||
kartenAmpelText: { fontSize: schrift.klein, fontWeight: '600', marginTop: 2 },
|
kartenAmpelText: { fontSize: schrift.klein, fontWeight: '600', marginTop: 2 },
|
||||||
pfeil: { fontSize: 32, color: farben.textSekundaer },
|
pfeil: { fontSize: 32, color: farben.textSekundaer },
|
||||||
|
leerBox: { alignItems: 'center', marginTop: abstand.xl, gap: abstand.xs },
|
||||||
|
leerSymbol: { fontSize: 52 },
|
||||||
|
leerTitel: { fontSize: schrift.gross, fontWeight: '700', color: farben.text },
|
||||||
leer: {
|
leer: {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
fontSize: schrift.basis,
|
fontSize: schrift.basis,
|
||||||
color: farben.textSekundaer,
|
color: farben.textSekundaer,
|
||||||
marginTop: abstand.xl,
|
|
||||||
lineHeight: 28,
|
lineHeight: 28,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
21
src/theme.ts
21
src/theme.ts
@@ -5,14 +5,18 @@
|
|||||||
* - Große Touch-Targets (min. 56px Höhe)
|
* - Große Touch-Targets (min. 56px Höhe)
|
||||||
*/
|
*/
|
||||||
export const farben = {
|
export const farben = {
|
||||||
// Grundfarben
|
// Grundfarben — warmer Papier-Ton als Markenzeichen (wie die Webseite):
|
||||||
hintergrund: '#FFFFFF',
|
// Inhalte liegen als weiße "Blätter" auf Papier
|
||||||
flaeche: '#F2F5F9',
|
hintergrund: '#FAF7F0',
|
||||||
|
flaeche: '#FFFFFF',
|
||||||
primaer: '#1A365D', // dunkles, ruhiges Blau
|
primaer: '#1A365D', // dunkles, ruhiges Blau
|
||||||
primaerText: '#FFFFFF',
|
primaerText: '#FFFFFF',
|
||||||
text: '#1A202C',
|
text: '#1A202C',
|
||||||
textSekundaer: '#4A5568',
|
textSekundaer: '#4A5568',
|
||||||
rand: '#CBD5E0',
|
rand: '#E4DECF',
|
||||||
|
// Akzent: Textmarker-Gelb (sparsam einsetzen — nur für DIE Kernaussage)
|
||||||
|
markerHintergrund: '#FFF6D2',
|
||||||
|
markerRand: '#EBDD9A',
|
||||||
|
|
||||||
// Dringlichkeits-Ampel (kräftig, gut unterscheidbar)
|
// Dringlichkeits-Ampel (kräftig, gut unterscheidbar)
|
||||||
ampelRot: '#C0392B',
|
ampelRot: '#C0392B',
|
||||||
@@ -43,3 +47,12 @@ export const abstand = {
|
|||||||
|
|
||||||
/** Mindesthöhe für alle interaktiven Elemente (Barrierefreiheit). */
|
/** Mindesthöhe für alle interaktiven Elemente (Barrierefreiheit). */
|
||||||
export const TOUCH_TARGET = 56;
|
export const TOUCH_TARGET = 56;
|
||||||
|
|
||||||
|
/** Dezenter Schatten, damit weiße Karten sich vom Papier-Grund abheben. */
|
||||||
|
export const kartenSchatten = {
|
||||||
|
shadowColor: '#1A202C',
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.07,
|
||||||
|
shadowRadius: 6,
|
||||||
|
elevation: 2,
|
||||||
|
} as const;
|
||||||
|
|||||||
Reference in New Issue
Block a user