Theme.define
function · packages/mixins/src/theme/core.ts:16
define<T extends ThemeTokens>(tokens: T): Readonly<T>Mixins / foldkit-mixins/theme
namespace · packages/mixins/src/theme.ts:27
const Theme = {
...Core.Theme,
root,
scoped,
tokens,
ladder,
role,
nested,
raise,
raisedSurface,
breakpointWidths,
inContainer,
oklch,
schemeScript,
chooseScheme,
currentScheme,
}Theme.definefunction · packages/mixins/src/theme/core.ts:16
define<T extends ThemeTokens>(tokens: T): Readonly<T>Theme.reffunction · packages/mixins/src/theme/core.ts:35
ref<T extends ThemeTokens>(theme: T): Refs<T>The theme's tokens as references: Theme.ref(theme).surface.overt is
var(--fk-surface-overt), and a group or name the theme lacks is a type
error. Only the names are read, never the values. Built once per theme.
Theme.variablesfunction · packages/mixins/src/theme/core.ts:54
variables<T extends ThemeTokens>(theme: T): StyleValueTheme.lightDarkfunction · packages/mixins/src/theme/core.ts:69
lightDark(light: string, dark: string): stringA token that follows the user's color scheme with CSS light-dark(): no
JavaScript and no Model field. A theme the user chooses is the other case,
and belongs in the Model as a class on the root; variables compiles both.
Theme.composefunction · packages/mixins/src/theme/core.ts:82
compose<A extends ThemeTokens, B extends ThemeTokens>(
base: A,
over: B,
): Readonly<Merge<A, B>>Themes merged at definition time, later tokens winning within a group.
Theme.rootfunction · packages/mixins/src/theme/root.ts:30
root(theme: ThemeTokens, options?: RootOptions): StyleValueTheme.scopedfunction · packages/mixins/src/theme/root.ts:49
scoped<T extends ThemeTokens>(
_theme: T,
selector: string,
overrides: Overrides<T>,
): StyleValueToken overrides under selector: a named theme the Model selects with a
root attribute (:root[data-theme="ocean"]), a scheme the user chose
(:root[data-color-scheme="dark"]), or a subtree (.marketing). Which
one is active is the Model's fact; this only says what it means.
theme is the theme being overridden and is read only for its type, so a
group or token it lacks is a type error rather than a variable nothing reads.
Theme.tokensconst · packages/mixins/src/theme/tokens.ts:27
tokens: Readonly<{ knob: { density: string; 'radius-factor': string; motion: string; travel: string; step: string; 'shadow-strength': string; }; space: { '3xs': string; '2xs': string; xs: string; sm: string; md: string; lg: string; xl: string; '2xl': string; '3xl': string; }; radius: { xs: string; sm: string; md: string; lg: string; xl: string; full: string; }; font: { body: string; heading: string; mono: string; }; size: { xs: string; sm: string; md: string; lg: string; xl: string; '2xl': string; '3xl': string; '4xl': string; }; leading: { tight: string; snug: string; normal: string; relaxed: string; }; weight: { normal: string; medium: string; semibold: string; bold: string; }; motion: { fast: string; moderate: string; slow: string; 'fast-exit': string; 'moderate-exit': string; 'slow-exit': string; ease: string; 'ease-exit': string; settle: string; spring: string; }; control: { height: string; 'height-compact': string; pad: string; 'pad-compact': string; 'row-pad': string; 'row-pad-compact': string; gap: string; 'gap-compact': string; inset: string; 'inset-compact': string; icon: string; 'icon-compact': string; }; type: { 'display-size': string; 'display-size-compact': string; 'display-leading': string; 'display-leading-compact': string; 'title-size': string; 'title-size-compact': string; 'title-leading': string; 'title-leading-compact': string; 'subtitle-size': string; 'subtitle-size-compact': string; 'subtitle-leading': string; 'subtitle-leading-compact': string; 'body-size': str …;Theme.ladderfunction · packages/mixins/src/theme/tokens.ts:181
ladder(name: Rung): stringA control's dimension on the size ladder: name's default end blended
toward its compact one by the step knob, and spacing multiplied by
density. The blend is written here, not in a token, because a custom
property resolves where it is declared: a token would read the step at
:root, while this expression reads it on the element that uses it, so
--fk-knob-step: 1 on a toolbar makes everything in it compact, a menu it
opens included while the panel stays in the page (an anchor's portal:
false); a portaled panel takes only the size its recipe chooses. A step of
-0.5 is shadcn's large size, 40px.
Theme.rolefunction · packages/mixins/src/theme/tokens.ts:203
role(name: Role): {
readonly fontSize: string
readonly lineHeight: string
}Text in role: its size and leading on the size ladder, read on the
element like ladder, so a compact region's text steps down with its
controls.
Theme.nestedfunction · packages/mixins/src/theme/tokens.ts:192
nested(outer: string, inset: string, border?: string): stringThe radius of a rounded surface inset in another, so their corners are concentric: the outer radius less the inset between them and the outer surface's border, never below zero. Past a large radius, or with uneven gaps, the two read as independent and may be tuned by eye.
Theme.raisefunction · packages/mixins/src/theme/raise.ts:43
raise(offset: number): StyleValueAn element offset levels above the raised element holding it, or the
page: popovers and menus are 2, dialogs 4. Paint it with raisedSurface.
Theme.raisedSurfacefunction · packages/mixins/src/theme/raise.ts:54
raisedSurface(): stringThe background of a raised element at its level, from Theme.oklch's base
surface. In a light scheme the first two steps go toward white and the rest
stay there, so shadow alone carries elevation; in a dark scheme each level
is an even step lighter (knob.raise-dark). Written as an expression, not
a token, because the level is the element's own and a token resolves at
:root.
Theme.breakpointWidthsfunction · packages/mixins/src/theme/tokens.ts:222
breakpointWidths(theme: {
readonly breakpoint: {
readonly [name: string]: string
}
}): Readonly<Record<string, number>>Each breakpoint query's min-width in pixels (rem at 16), so CSS and the
Model agree on what md means. A query that is not a plain min-width
is refused: it has no single threshold. A container's is its container's.
Theme.inContainerfunction · packages/mixins/src/theme/tokens.ts:250
inContainer<Breakpoints extends Readonly<Record<string, string>>>(
name: string,
breakpoints: Breakpoints,
): {
readonly [K in keyof Breakpoints]: string
}The same breakpoints measured on a named container rather than the window:
Theme.inContainer('page', Theme.tokens.breakpoint) gives md as
'@container page (min-width: 48rem)', for Style.responsive and a
responsive look. An element must be that container (container: page /
inline-size) for them to match.
Theme.oklchfunction · packages/mixins/src/theme/oklch.ts:161
oklch(knobs: OklchKnobs): Readonly<{ knob: { 'accent-h': string; 'accent-c': string; 'accent-l': string; 'accent-c-dark': string; 'accent-l-dark': string; 'neutral-h': string; 'secondary-shift': string; 'tertiary-shift': string; 'surface-c': string; 'surface-c-dark': string; 'surface-contrast': string; 'contrast-factor': string; 'base-l': string; 'base-l-dark': string; 'success-h': string; 'warning-h': string; 'error-h': string; 'info-h': string; 'syntax-c': string; 'popup-bold': string; 'popup-invert': string; 'popup-alpha': string; 'popup-blur': string; 'state-hover': string; 'state-tint': string; 'state-tint-dark': string; 'image-edge': string; 'raise-dark': string; }; hue: { accent: string; secondary: string; tertiary: string; neutral: string; }; surface: { base: string; muted: string; subtle: string; default: string; overt: string; bedrock: string; }; text: { default: string; muted: string; subtle: string; overt: string; link: string; 'link-hover': string; }; outline: { subtle: string; default: string; overt: string; focus: string; }; accent: { default: string; hover: string; active: string; subtle: string; outline: string; 'on-fill': string; ink: string; }; secondary: { default: string; hover: string; active: string; subtle: string; outline: string; 'on-fill': string; ink: string; }; tertiary: { default: string; hover: string; active: string; subtle: string; outline: string; 'on-fill': string; ink: string; }; shadow: { color: string; }; state: { hover: string; tint: string; 'tint-hover': string; …;Theme.schemeScriptfunction · packages/mixins/src/theme/scheme.ts:24
schemeScript(key?: string): stringThe text of a <script> for the document's head, before any stylesheet
draws: it applies the scheme kept under key, so a reader who chose dark
never sees one light frame. Storage that throws (a private window) or holds
anything else leaves the stylesheet's choice.
Theme.chooseSchemefunction · packages/mixins/src/theme/scheme.ts:40
chooseScheme(scheme: Scheme, key?: string): Effect.Effect<void>Applies scheme to the root element and keeps it under key for the next
visit, as a Command's effect. 'system' removes both. Storage that throws
still applies the scheme to this page.
Theme.currentSchemefunction · packages/mixins/src/theme/scheme.ts:29
currentScheme(): SchemeThe scheme the root element shows now: what schemeScript or chooseScheme applied.