The per-family remap (shared, member-1..4) only fills all-day pills whose Schedule-X colorName is registered. Member calendars absent from the current /api/me members list fall back to Schedule-X's built-in primary family, which was not remapped — so those all-day events degraded to the light tint. Remap --sx-color-primary-container as well so all-day pills stay solid in the fallback case too (production member-N calendars already covered).
141 lines
6.4 KiB
CSS
141 lines
6.4 KiB
CSS
/**
|
||
* FamilySync global styles entry point.
|
||
*
|
||
* Import order matters — tokens.css must be imported AFTER
|
||
* @schedule-x/theme-default/dist/index.css (handled in main.tsx)
|
||
* so the --sx-color-* overrides win the cascade.
|
||
*/
|
||
|
||
@import './tokens.css';
|
||
|
||
/* ── Schedule-X calendar sizing ───────────────────────────────────────────── */
|
||
/*
|
||
* Schedule-X renders .sx__calendar-wrapper (height:100%) inside a <div> that
|
||
* the React adapter emits without an explicit height. The parent container in
|
||
* CalendarShell is a flex item (flex:1; minHeight:0; height:100%) so we must
|
||
* propagate that height down through the React wrapper element to the
|
||
* .sx__calendar-wrapper so the week/day time-grid (.sx__view-container) can
|
||
* scroll correctly.
|
||
*
|
||
* Class names confirmed from @schedule-x/theme-default@4.6.0 dist/index.css:
|
||
* .sx__calendar-wrapper – outer wrapper emitted by the React adapter
|
||
* .sx__calendar – inner flex-column container (flex:1; height:100%)
|
||
* .sx__view-container – scrollable time-grid body (flex:1; overflow-y:auto)
|
||
*
|
||
* The React adapter (@schedule-x/react) wraps the calendar in a div with class
|
||
* `.sx-react-calendar-wrapper`. That element had no height, so .sx__calendar-wrapper's
|
||
* height:100% resolved against an auto-height parent and collapsed — killing the
|
||
* time-grid's internal scroll. Give the adapter wrapper height:100% too so the full
|
||
* chain (container → .sx-react-calendar-wrapper → .sx__calendar-wrapper → .sx__calendar
|
||
* → .sx__view-container[overflow-y:auto]) has a resolvable height end-to-end.
|
||
*/
|
||
.sx-react-calendar-wrapper,
|
||
.sx__calendar-wrapper {
|
||
height: 100%;
|
||
}
|
||
|
||
/* ── Minimal Global Reset ─────────────────────────────────────────────────── */
|
||
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
margin: 0;
|
||
font-family: var(--font-family-base);
|
||
font-size: var(--text-body-size);
|
||
font-weight: var(--text-body-weight);
|
||
line-height: var(--text-body-line-height);
|
||
color: var(--color-text-primary);
|
||
background-color: var(--color-surface);
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
|
||
/* ── Schedule-X overrides ──────────────────────────────────────────────────── */
|
||
|
||
/*
|
||
* 999.6 / D-12: All-day event visual distinction.
|
||
*
|
||
* All-day events render as full-width filled rounded pills so they are immediately
|
||
* distinct from timed event chips (partial-fill with colored left border accent).
|
||
*
|
||
* Contract (Surface 3 — UI-SPEC):
|
||
* all-day = solid filled pill → this override
|
||
* timed = partial-fill chip with colored border accent (Schedule-X default)
|
||
*
|
||
* Confirmed from @schedule-x/calendar@4.6.0 dist/core.js source inspection:
|
||
*
|
||
* Week/Day all-day row: events use class `.sx__date-grid-event` (exclusively for
|
||
* all-day events — timed events in week/day go to `.sx__time-grid-event`, a
|
||
* separate class; no overlap).
|
||
*
|
||
* Month grid: both timed and all-day share `.sx__month-grid-event`. Timed events
|
||
* also render a child `.sx__month-grid-event-time` element (when
|
||
* `calendarEvent.start instanceof Temporal.ZonedDateTime`). All-day events have
|
||
* a PlainDate start and never render that child. So
|
||
* `.sx__month-grid-event:not(:has(.sx__month-grid-event-time))` selects only
|
||
* all-day cells in month view.
|
||
*
|
||
* Color source: the member's `_familySync.color` propagates via `calendarId` color
|
||
* config in buildCalendarConfig() — no per-event inline override needed. The solid
|
||
* `background-color` override wins over the default `-container` tint; the
|
||
* `border-inline-start` override removes the left accent border so the pill reads
|
||
* as uniformly filled.
|
||
*/
|
||
|
||
/*
|
||
* In the date-grid (all-day row at top of week/day views) and in the month-grid
|
||
* all-day cell area, remap the Schedule-X *-container CSS variables to their
|
||
* corresponding solid main colors. This causes the event's inline
|
||
* `background-color: var(--sx-color-${colorName}-container)` to resolve to the
|
||
* solid main color instead of the 15%-opacity tint. The `-on-*-container`
|
||
* variable is set to #FFFFFF for white label text.
|
||
*
|
||
* Calendar colorNames used by this app (from buildCalendarConfig):
|
||
* shared — rose family calendar
|
||
* member-{N} — per-member personal calendars (N = users.id)
|
||
*
|
||
* Note: CSS custom properties cascade — these overrides on the container element
|
||
* apply to all descendants without affecting the rest of the document.
|
||
*/
|
||
.sx__date-grid,
|
||
.sx__month-grid-day__events {
|
||
/* Fallback: Schedule-X uses the built-in `primary` family for any event whose
|
||
* calendar colorName is not registered (e.g. a member calendar absent from the
|
||
* current /api/me members list). Remapping it keeps all-day events solid-filled
|
||
* even in that fallback case, so the pill never degrades to the light tint. */
|
||
--sx-color-primary-container: var(--sx-color-primary);
|
||
--sx-color-on-primary-container: #FFFFFF;
|
||
--sx-color-shared-container: var(--sx-color-shared);
|
||
--sx-color-on-shared-container: #FFFFFF;
|
||
--sx-color-member-1-container: var(--sx-color-member-1);
|
||
--sx-color-on-member-1-container: #FFFFFF;
|
||
--sx-color-member-2-container: var(--sx-color-member-2);
|
||
--sx-color-on-member-2-container: #FFFFFF;
|
||
--sx-color-member-3-container: var(--sx-color-member-3);
|
||
--sx-color-on-member-3-container: #FFFFFF;
|
||
--sx-color-member-4-container: var(--sx-color-member-4);
|
||
--sx-color-on-member-4-container: #FFFFFF;
|
||
}
|
||
|
||
/* Week/Day all-day row — .sx__date-grid-event is exclusively all-day in this view */
|
||
.sx__date-grid .sx__date-grid-event {
|
||
border-radius: 4px !important;
|
||
border-inline-start: none !important;
|
||
font-weight: 600 !important;
|
||
font-size: var(--text-label-size) !important;
|
||
/* background-color and color are driven by the container-var remapping above */
|
||
}
|
||
|
||
/* Month grid — exclude timed events (which have a child .sx__month-grid-event-time) */
|
||
.sx__month-grid-day__events .sx__month-grid-event:not(:has(.sx__month-grid-event-time)) {
|
||
border-radius: 4px !important;
|
||
border-inline-start: none !important;
|
||
font-weight: 600 !important;
|
||
font-size: var(--text-label-size) !important;
|
||
/* background-color and color are driven by the container-var remapping above */
|
||
}
|