/** * FamilySync Design System — Clean Theme (Phase 2, D-01/D-02) * * All colors, spacing, typography, and breakpoints are declared here as CSS * custom properties. No hard-coded hex or px values in component files. * * Import order in main.tsx: * 1. temporal-polyfill/global * 2. @schedule-x/theme-default/dist/index.css * 3. ./styles/index.css (imports this file) * * The Schedule-X --sx-color-* overrides at the bottom must come AFTER the * theme-default import so they win the cascade. */ :root, [data-theme="light"] { /* ───────────────────────────────────────────────────────────────────────── * BASE SURFACE / BORDER / TEXT PALETTE * ───────────────────────────────────────────────────────────────────────── */ --color-surface: #ffffff; --color-surface-dim: #f7f7f8; --color-surface-raised: #ffffff; --color-border: #e2e4e9; --color-border-subtle: #eceef2; --color-text-primary: #111318; --color-text-secondary: #6b7280; --color-text-muted: #9ca3af; --color-focus-ring: #4a90d9; --color-overlay: rgba(0, 0, 0, 0.32); /* ───────────────────────────────────────────────────────────────────────── * SEMANTIC CALENDAR COLORS * 10% accent band — ONLY for event chip fills and color legend swatches. * ───────────────────────────────────────────────────────────────────────── */ --color-member-0: #e8915a; /* brand accent — warm amber (approved 17-02 checkpoint) */ --color-member-1: #50c878; --color-member-2: #f5a623; --color-member-3: #9b59b6; --color-member-4: #e67e22; --color-member-5: #1abc9c; /* Shared-family calendar — rose, confirmed by user */ --color-shared-family: #f25c7a; /* Destructive — declared for Phase 3 reuse; not used in Phase 2 (read-only) */ --color-destructive: #dc2626; /* ───────────────────────────────────────────────────────────────────────── * SPACING SCALE (multiples of 4px) * ───────────────────────────────────────────────────────────────────────── */ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-6: 24px; --space-8: 32px; --space-12: 48px; /* Layout-chrome token — single source of truth for BottomTabBar effective height. * Consumed by: FAB offset (CalendarShell.tsx), content padding (App.tsx), BottomTabBar. * Workstreams A and D reference this token; do not hard-code 56px elsewhere. */ --bottom-chrome-h: calc(56px + env(safe-area-inset-bottom, 0px)); /* ───────────────────────────────────────────────────────────────────────── * TYPOGRAPHY * ───────────────────────────────────────────────────────────────────────── */ --font-family-base: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; /* Body — 15px/400/1.5: popover description, agenda location lines */ --text-body-size: 15px; --text-body-weight: 400; --text-body-line-height: 1.5; /* Label — 13px/400/1.4: event chip text, time labels, legend labels */ --text-label-size: 13px; --text-label-weight: 400; --text-label-line-height: 1.4; /* Heading — 18px/600/1.25: popover title, view section headers */ --text-heading-size: 18px; --text-heading-weight: 600; --text-heading-line-height: 1.25; /* Display — 24px/600/1.2: app name in nav bar (desktop), day number in day-view */ --text-display-size: 24px; --text-display-weight: 600; --text-display-line-height: 1.2; /* ───────────────────────────────────────────────────────────────────────── * BRAND SLOT — Phase 17 seam tokens * Phase 19 sets placeholder defaults; Phase 17 overrides these values only — * never the BrandSlot component structure (see 19-UI-SPEC.md §Brand Slot). * ───────────────────────────────────────────────────────────────────────── */ --brand-logo-bg: var(--color-member-0); /* placeholder circle background */ --brand-logo-text: #ffffff; /* placeholder initials color */ --brand-logo-size: 48px; /* reserved slot height; keep 1:1 aspect */ --brand-logo-border-radius: 0; /* SVG draws its own rounded-square background (rx=104); no CSS clip needed */ --brand-app-name: 'FamilySync'; /* drives doc only — not used as CSS content */ /* ───────────────────────────────────────────────────────────────────────── * BREAKPOINTS (reference; use in @media queries) * ───────────────────────────────────────────────────────────────────────── */ --bp-phone: 0px; --bp-tablet: 768px; --bp-desktop: 1280px; /* ───────────────────────────────────────────────────────────────────────── * SCHEDULE-X CSS TOKEN OVERRIDES * * Map all --sx-color-* vars to project tokens so no Schedule-X default * colors bleed through. These must come after the @schedule-x/theme-default * import (handled by import order in main.tsx). * * Source: https://schedule-x.dev/docs/calendar/configuration * ───────────────────────────────────────────────────────────────────────── */ --sx-color-primary: var(--color-member-0); --sx-color-on-primary: #ffffff; --sx-color-primary-container: var(--color-surface-dim); --sx-color-on-primary-container: var(--color-text-primary); --sx-color-surface: var(--color-surface); --sx-color-on-surface: var(--color-text-primary); --sx-color-on-surface-variant: var(--color-text-secondary); --sx-color-outline: var(--color-border); --sx-color-neutral: var(--color-text-secondary); --sx-color-neutral-variant: var(--color-border); --sx-font-family: var(--font-family-base); /* Ensure internal text color (chevrons, borders) uses our primary text */ --sx-internal-color-text: var(--color-text-primary); } /* ───────────────────────────────────────────────────────────────────────── * DARK THEME STUB — Phase 17 groundwork only. * Values are intentionally absent. Phase 999.20 fills these values and * wires prefers-color-scheme / data-theme toggle. * DO NOT add a live rule here until Phase 999.20. * ───────────────────────────────────────────────────────────────────────── * [data-theme="dark"] { ... } * ───────────────────────────────────────────────────────────────────────── */ /* ───────────────────────────────────────────────────────────────────────── * SKELETON SHIMMER ANIMATION * Used by SkeletonCalendar.tsx — no third-party animation library. * ───────────────────────────────────────────────────────────────────────── */ @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } }