chahinebrini c7fc237dfd feat(android-protection): device-admin uninstall-block + boot-receiver + config plugin
Android self-bind protection auf nahezu MDM-Niveau ohne Device-Owner:
- Device-Admin (RebreakDeviceAdminReceiver) blockt Uninstall OS-seitig, aktiv ab
  Boot ohne Prozess/a11y. Deaktivierung nur via 24h-Cooldown (removeDeviceAdmin in
  forceDisable). a11y blockt die DeviceAdminAdd-Settings-Seite (Class-Match, auf
  Samsung One UI per Logcat verifiziert).
- Boot-Receiver (RebreakVpnBootReceiver) startet VPN+a11y nach Reboot, damit der
  Tamper-Lock ohne manuellen App-Start hochkommt.
- Manifest-Wiring (Device-Admin-Receiver, Boot-Receiver, RECEIVE_BOOT_COMPLETED,
  device_admin.xml) ins with-rebreak-protection-android Config-Plugin verlagert →
  ueberlebt 'expo prebuild' (android/ ist gitignored).
- a11y-Detection zurueck auf die funktionierende Version: zu breites 'loeschen'-
  Uninstall-Keyword raus (blockte halbe Settings); a11y-Label jetzt 'ReBreak Schutz'.
- a11y-Deeplink behaelt den Samsung-Step-Guide (openAccessibilitySettings).

Session-Frontend in diesem Batch:
- Avatar-Placeholder: neutrales clarity-avatar-line SVG statt dominantem Blau.
- DiGA-Milestone folgt kumulativen protectedDays (erreicht rueckfall-anfaellige User).
- Dev-Build crasht nicht mehr ohne CallKit-Native-Modul.
- VPN-Permission-Dialog nur noch im Bypass-Fall.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 04:52:49 +02:00

80 lines
2.0 KiB
TypeScript

import { useThemeStore } from '../stores/theme';
export const theme = {
bg: 'bg-white',
surface: 'bg-neutral-50',
surfaceElevated: 'bg-neutral-100',
border: 'border-neutral-200',
text: 'text-neutral-900',
textMuted: 'text-neutral-500',
brandOrange: 'text-rebreak-500',
brandOrangeBg: 'bg-rebreak-500',
brandBlue: 'bg-midnight-800',
} as const;
export type ColorScheme = {
bg: string;
surface: string;
surfaceElevated: string;
/** iOS systemGroupedBackground — page background for list/settings screens */
groupedBg: string;
/** iOS secondarySystemGroupedBackground — card/row surface within grouped pages */
card: string;
border: string;
text: string;
textMuted: string;
/** Neutraler Grauton für Initialen-Avatare ohne Foto (iOS-Kontakt-Look:
graue Scheibe, weiße Initialen). Bewusst NICHT brandOrange (=#007AFF, blau). */
avatarPlaceholder: string;
brandOrange: string;
brandBlue: string;
success: string;
error: string;
warning: string;
};
const light: ColorScheme = {
bg: '#ffffff',
surface: '#fafafa',
surfaceElevated: '#f5f5f5',
groupedBg: '#F2F2F7',
card: '#ffffff',
border: '#e5e5e5',
text: '#0a0a0a',
textMuted: '#737373',
avatarPlaceholder: '#8E8E93',
brandOrange: '#007AFF',
brandBlue: '#0e1f3a',
success: '#16a34a',
error: '#dc2626',
warning: '#f59e0b',
};
const dark: ColorScheme = {
bg: '#000000',
surface: '#1c1c1e',
surfaceElevated: '#2c2c2e',
groupedBg: '#000000',
card: '#1c1c1e',
border: '#38383a',
text: '#ffffff',
textMuted: '#8e8e93',
avatarPlaceholder: '#48484A',
brandOrange: '#007AFF',
brandBlue: '#0e1f3a',
success: '#30d158',
error: '#ff453a',
warning: '#ffd60a',
};
export const colorSchemes = { light, dark };
export function useColors(): ColorScheme {
const scheme = useThemeStore((s) => s.colorScheme);
return scheme === 'dark' ? dark : light;
}
// Legacy flat export — used by files that haven't migrated to useColors() yet.
// Wave 2 should remove this.
export const colors = light;