Lay the Almanacka design foundation: tokens, type, shell

New token system in global.css (near-white surfaces, one ink-blue
accent, no sub-12px type), self-hosted Schibsted Grotesk, rewritten
primitives (buttons, fields, modal shell, segmented, disclosure,
skeleton), a borderless 56px header with an SV | EN language toggle,
an Icon component replacing glyphs, page skeletons that keep the
layout during loading, and leave-type colours moved out of TS into
CSS variables. Feature blocks keep their structure for later phases.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-19 18:25:04 +02:00
parent 95444d3bf4
commit d14f86478a
44 changed files with 1358 additions and 485 deletions
+8 -4
View File
@@ -25,12 +25,12 @@ import type {
WindowOutcome,
} from '@/types'
import { Layout } from '@/components/layout/Layout'
import { LoadingSpinner } from '@/components/common/LoadingSpinner'
import { PageSkeleton } from '@/components/common/PageSkeleton'
import { CalendarWeek, computeWeekLaneCount, type BandClickInfo } from '@/components/common/CalendarWeek'
import { PlannedDayModal } from '@/components/modals/PlannedDayModal'
import { PeriodPopover, type PeriodPopoverSavePayload, type PeriodDeleteScope } from '@/components/calendar/PeriodPopover'
import { PresetRail, type SeasonPreset } from '@/components/calendar/PresetRail'
import { getColorForType } from '@/utils/leaveTypes'
import { getColorForType, getTypeModifier } from '@/utils/leaveTypes'
import { resolveWishName, resolveWishNameFromData } from '@/utils/wishName'
import { datesInRange, formatDateForDisplay, formatDateLocalISO, isValidDate, parseInputDate } from '@/utils/dates'
import { renderRejection, type Translate } from '@/utils/rejectionMessages'
@@ -437,7 +437,11 @@ export function Calendar(): ReactNode {
}, [isDragging, dragAnchor, dragCurrent, personalDataUuid])
if (isLoading) {
return <LoadingSpinner message={t('calendar.loading')} />
return (
<Layout>
<PageSkeleton rows={5} />
</Layout>
)
}
const year = currentMonth.getFullYear()
@@ -1215,7 +1219,7 @@ export function Calendar(): ReactNode {
<span>{t('calendar.legendIncomeBased')}</span>
</div>
<div className="calendar__legend-item">
<span className="calendar__legend-swatch" style={{ backgroundColor: getColorForType('lagsta') }} />
<span className={`calendar__legend-swatch calendar__legend-swatch--${getTypeModifier('lagsta')}`} style={{ backgroundColor: getColorForType('lagsta') }} />
<span>{t('calendar.legendMinimumRate')}</span>
</div>
<div className="calendar__legend-item">