# Checkbox (Lumen Halo): prompt.md (v1.0.0)

- id: `lumen-checkbox` · version 1.0.0 · component · free
- category: Selection
- build: Base UI (this item also ships a Radix build)
- install (this build): `npx shadcn@latest add https://beautiful-ui.dev/r/lumen-checkbox.json`
- npm dependencies: @base-ui/react@^1
- registry dependencies: utils, https://beautiful-ui.dev/r/lumen-foundation.json
- docs: https://beautiful-ui.dev/components/lumen-checkbox
- The install command carries everything this item needs (files, CSS, tokens, npm and registry dependencies). Prefer it to copying source by hand.

A checkbox that shows its work: the box presses in, fills with light and draws its own check, and a half-done parent fills cells for the children that are on. shadcn's Checkbox, cut from Lumen glass.

## Build it
- Stack: React 19 (`ref` is a plain prop), TypeScript, Tailwind CSS v4 utilities, a shadcn-initialised project with the `@/*` alias.
- Packages: `@base-ui/react@^1` (Base UI build); `radix-ui@^1` (Radix build).
- Files: `components/ui/lumen/checkbox.tsx`; shared code: `lib/beautiful-ui/lumen/glyphs.tsx`, `lib/beautiful-ui/lumen/meter.ts`, `lib/beautiful-ui/lumen/sound.ts`.
- Registry dependencies, installed with it automatically: shadcn `utils` (cn), `lumen-foundation`.
- Builds: separate Base UI and Radix files. Install the one that matches the project (see Install): a free item's bare URL installs the Base UI build of it and its dependencies.
- Exports to keep: `Checkbox`, `(indicator)`, and every exported type.
- CSS: the install merges this item's rules (the registry `css` field) into your global stylesheet, in `@layer components`, and adds the lumen foundation (tokens, keyframes, motion levels) once. Nothing to import by hand.
- Re-running `add` (or `--overwrite`) re-applies those rules: put overrides in your own CSS, never in the installed rules.
- Tokens: retheme with the `--lumen-*` custom properties (`--lumen-accent`, `--lumen-accent-text`, `--lumen-bad`, `--lumen-bad-text`, `--lumen-focus`, `--lumen-good`, `--lumen-good-text`, `--lumen-hairline`, `--lumen-ink`, `--lumen-muted-ink`, `--lumen-series-1`, `--lumen-series-2`, `--lumen-series-3`, `--lumen-series-4`, `--lumen-series-5`, `--lumen-series-6`, `--lumen-warn`, `--lumen-warn-text`); this item's CSS also reads `--lumen-radius-k`. Never add Tailwind colour classes inside the component.

```tsx
import { Checkbox } from "@/components/ui/lumen/checkbox";
```

## Parts

| Part | data-slot | What it is for |
|---|---|---|
| `Checkbox` | `checkbox` | The glass box. |
| `(indicator)` | `checkbox-indicator` | The drawn check, or the 3-cell meter. |

Style a part with `[data-slot="<slot>"]` selectors or its `className`; keep the attributes when editing.

## Sound
- Keep every `data-slot` and `data-sound` attribute: the sound layer reads them.
- Installing this item adds no audio. Nothing plays until the app mounts `GlassSoundProvider` once (install: `npx shadcn@latest add https://beautiful-ui.dev/r/glass-sound.json`, import from `@/components/beautiful-ui/glass-sound`); `GlassSoundToggle` is its mute control. Without a provider the audio engine never loads; `sound={false}` silences one instance.

## Match the original
- Read `components/ui/lumen/checkbox.tsx` as the reference implementation before changing or recreating anything, and match it: sizes, colours per theme, motion timings, copy and behaviour.
- If you deviate (a prop you can't honour, a style you changed, a dependency you swapped), say so in your reply, part by part.
- Keep the accessibility contract, the keyboard map and the motion levels listed below.

## Use it when
- checkbox, check all, select all, indeterminate, task list, terms, multi-select, shadcn checkbox, Lumen
- Independent on and off choices: tasks, filters, permissions
- Select all: indeterminate shows how many children are on, in cells
- A drop-in for shadcn's Checkbox: same export and data-slots

### Not when
- One setting that takes effect at once: use Lumen Switch
- Picking one of several: use Lumen Radio Group

## Mistakes
- Label it: wrap it in a label, or give it an id and a <label htmlFor>
- Indeterminate is a display state: clicking it sets checked, so update the children yourself

## Usage

```tsx
import { Checkbox } from "@/components/ui/lumen/checkbox";

<Checkbox id="terms" checked={agreed} onCheckedChange={setAgreed} />
<label htmlFor="terms">I agree to the terms</label>
```

## Props

| Prop | Type | Default | What it does |
|---|---|---|---|
| `checked / defaultChecked / onCheckedChange` | `boolean / boolean / (checked) => void` |  | Controlled or not, as shadcn. |
| `indeterminate (Base UI) · checked="indeterminate" (Radix)` | `boolean` |  | The tinted box with the 3-cell meter. |
| `mixedFraction` | `number` | `2/3` | Beautiful UI: the share of children on (0–1); lights 1–3 cells. |
| `aria-invalid` | `boolean` |  | Coral ring, and a coral fill when checked. |
| `sound` | `boolean` | `true` | Beautiful UI: false silences it; otherwise toggle-on and toggle-off through beautiful-ui-sound. |

Full docs: https://beautiful-ui.dev/components/lumen-checkbox

## Customising
- Colours: set the `--lumen-*` tokens on `:root`, or on a container with the `lumen-scope` class to retheme one area. Add the `lumen-inherit` class to follow your shadcn palette instead (`--chart-N`, `--destructive`).
- Dark mode follows the `.dark` class on an ancestor (the shadcn and next-themes convention).
- Update later by re-running the install with `--overwrite` (review the diff if you edited it). Changelog: https://beautiful-ui.dev/r/changelog.json

## Keyboard

| Keys | Action |
|---|---|
| Space | Toggle |
| Tab | Move to the next checkbox |

## Motion inventory

| Interaction | What moves |
|---|---|
| Press | The box presses to .88 on a spring |
| Check | Fills with the accent; the check draws in over .45s |
| Indeterminate | Three cells pop in, 50ms apart; lit ones show how many children are on |

## Accessibility contract (preserve when editing)
- role=checkbox with aria-checked (mixed when indeterminate), from Base UI or Radix
- Space toggles; the 44px touch target never changes the look
- 22px box on phones
- Reduced motion: the check appears without drawing; the cells don't pop

## Install

Base UI project (a base-* style in components.json):

```bash
npx shadcn@latest add https://beautiful-ui.dev/r/lumen-checkbox.json
```

Radix project (a radix-*, new-york or default style):

```bash
npx shadcn@latest add https://beautiful-ui.dev/r/radix-nova/lumen-checkbox.json
```

Or add the `@beautiful-ui` registry to components.json and run `npx shadcn@latest add @beautiful-ui/lumen-checkbox`: the CLI picks the build from your style.

## Credits
- Built on shadcn/ui (https://ui.shadcn.com)

## Source (Base UI build)

### components/ui/lumen/checkbox.tsx

```tsx
"use client";

/**
 * Checkbox (Lumen Halo) v1.0.0 · Beautiful UI
 * Docs: https://beautiful-ui.dev/components/lumen-checkbox · Agent prompt: https://beautiful-ui.dev/md/lumen-checkbox.md
 * Licensed to the purchaser under the Beautiful UI license: https://beautiful-ui.dev/license
 */

import * as React from "react";
import { Checkbox as CheckboxPrimitive } from "@base-ui/react/checkbox";
import { cn } from "@/lib/utils";
import { LumenCheckGlyph } from "@/lib/beautiful-ui/lumen/glyphs";
import { mixedCells } from "@/lib/beautiful-ui/lumen/meter";
import { emitSound, useMergedRef } from "@/lib/beautiful-ui/lumen/sound";

/*
 * Lumen Checkbox (Base UI build). shadcn's Checkbox in Lumen Halo: a recessed glass box that
 * presses in, fills with the accent and draws its check; indeterminate is a tinted box with a 3-cell
 * meter showing how many children are on. 22px on phones, a 44px touch target always. Plays
 * toggle-on / toggle-off through beautiful-ui-sound. Same export, parts and data-slots as shadcn.
 */

function Checkbox({
  className,
  mixedFraction,
  sound = true,
  onCheckedChange,
  ref,
  ...props
}: CheckboxPrimitive.Root.Props & {
  /** Indeterminate only: the share of children on (0–1), lighting 1–3 cells. Default 2/3. */
  mixedFraction?: number;
  /** false silences this checkbox. Default true. */
  sound?: boolean;
}) {
  const own = React.useRef<HTMLButtonElement>(null);
  const merged = useMergedRef(own, ref);
  const lit = mixedCells(mixedFraction);
  return (
    <CheckboxPrimitive.Root
      ref={merged}
      data-slot="checkbox"
      data-sound={sound ? "none" : "off"}
      className={cn(`lumen-checkbox lumen-control`, className)}
      onCheckedChange={(checked, details) => {
        emitSound(own.current, checked ? "toggleOn" : "toggleOff");
        onCheckedChange?.(checked, details);
      }}
      {...props}
    >
      <CheckboxPrimitive.Indicator data-slot="checkbox-indicator" className={`lumen-checkbox-indicator`}>
        {/* Both glyphs render; CSS shows the one for the primitive's state (so an uncontrolled mixed start works). */}
        <span aria-hidden className={`lumen-checkbox-mixed`}>
          {[0, 1, 2].map((i) => (
            <span key={i} data-lit={i < lit ? "" : undefined} />
          ))}
        </span>
        <span className={`lumen-checkbox-check`}>
          <LumenCheckGlyph />
        </span>
      </CheckboxPrimitive.Indicator>
    </CheckboxPrimitive.Root>
  );
}

export { Checkbox };
```

### lib/beautiful-ui/lumen/glyphs.tsx

```tsx
import type * as React from "react";

/*
 * Lumen's glyphs for its shadcn-built controls: the 4-cell loading ticker, the check that draws
 * itself in, the ! glyph, and the cell-drawn icon set. The same drawings as the glass family.
 */

const SVG = { width: "1.1em", height: "1.1em", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, focusable: false } as const;
const BOX: React.CSSProperties = { display: "block", flex: "none" };
const ST = { stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" } as const;
const cell = (x: number, y: number, s = 3) => <rect key={`${x}-${y}`} x={x} y={y} width={s} height={s} rx={0.9} fill="currentColor" />;

/** The 4-cell loading ticker in currentColor (.32em cells, .16em gaps). */
export function LumenTicker({ className }: { className?: string }) {
  return (
    <span aria-hidden className={className ? `lumen-tick ${className}` : `lumen-tick`}>
      <span />
      <span />
      <span />
      <span />
    </span>
  );
}

/** The check that draws itself in (stroke-dashoffset 16 → 0). Remount it (key) to replay. */
export function LumenCheckGlyph() {
  return (
    <svg {...SVG} className={`lumen-check`} style={BOX}>
      <path d="M3.5 8.4l2.9 2.9 6.1-6.6" {...ST} strokeWidth={1.9} />
    </svg>
  );
}

/** The ! glyph, cropped tight so its gap to a label matches the other glyphs. */
export function LumenErrorGlyph() {
  return (
    <svg {...SVG} width=".36em" viewBox="6.2 0 3.6 16" style={{ ...BOX, margin: "0 1px 0 -1px" }}>
      <rect x={6.9} y={2.6} width={2.2} height={7} rx={1.1} fill="currentColor" />
      <rect x={6.9} y={11.2} width={2.2} height={2.2} rx={0.8} fill="currentColor" />
    </svg>
  );
}

export const LUMEN_ICON_NAMES = ["plus", "grid", "more", "search", "filter", "copy", "arrow", "trash", "close", "check"] as const;
export type LumenIconName = (typeof LUMEN_ICON_NAMES)[number];
export const isLumenIconName = (v: unknown): v is LumenIconName => typeof v === "string" && (LUMEN_ICON_NAMES as readonly string[]).includes(v);

/** One icon from the Lumen set, 1.1em square in currentColor: plus, grid and more are cells; the rest are 1.6px strokes. */
export function LumenIcon({ name }: { name: LumenIconName }) {
  const p = { ...SVG, style: BOX };
  switch (name) {
    case "plus":
      return <svg {...p}>{[cell(6.5, 2.5), cell(2.5, 6.5), cell(6.5, 6.5), cell(10.5, 6.5), cell(6.5, 10.5)]}</svg>;
    case "more":
      return <svg {...p}>{[cell(2, 6.5), cell(6.5, 6.5), cell(11, 6.5)]}</svg>;
    case "grid":
      return <svg {...p}>{[cell(3, 3, 4), cell(9, 3, 4), cell(3, 9, 4), cell(9, 9, 4)]}</svg>;
    case "search":
      return (
        <svg {...p}>
          <circle cx={7} cy={7} r={4.25} {...ST} />
          <path d="M10.3 10.3L13.5 13.5" {...ST} />
        </svg>
      );
    case "copy":
      return (
        <svg {...p}>
          <rect x={5.5} y={5.5} width={8} height={8} rx={2} {...ST} />
          <path d="M10.5 5.5V4a1.5 1.5 0 0 0-1.5-1.5H4A1.5 1.5 0 0 0 2.5 4v5A1.5 1.5 0 0 0 4 10.5h1.5" {...ST} />
        </svg>
      );
    case "trash":
      return (
        <svg {...p}>
          <path d="M2.8 4.5h10.4M6.4 4.5V3h3.2v1.5M4.3 4.5l.6 8.5h6.2l.6-8.5" {...ST} />
        </svg>
      );
    case "arrow":
      return (
        <svg {...p}>
          <path d="M3 8h10M9 4l4 4-4 4" {...ST} />
        </svg>
      );
    case "close":
      return (
        <svg {...p}>
          <path d="M4.5 4.5l7 7M11.5 4.5l-7 7" {...ST} />
        </svg>
      );
    case "filter":
      return (
        <svg {...p}>
          <path d="M2.5 4.5h11M4.5 8h7M6.5 11.5h3" {...ST} />
        </svg>
      );
    case "check":
      return <LumenCheckGlyph />;
  }
}
```

### lib/beautiful-ui/lumen/meter.ts

```tsx
/*
 * The Lumen cell meter: a count drawn as cells (accent, amber from 90% of the limit, coral past it),
 * the same maths as the glass textarea. Pure, for tests and your own meters.
 */

export type MeterTone = "ok" | "near" | "over";
export type MeterCell = { fill: number; tone: MeterTone | "off"; opacity: number };

/** "over" past the limit, "near" from 90% of it, else "ok". A limit of 0 or less is always "ok". */
export function meterTone(length: number, limit: number | undefined): MeterTone {
  if (!limit || limit <= 0) return "ok";
  if (length > limit) return "over";
  return length >= limit * 0.9 ? "near" : "ok";
}

/**
 * `cells` cells for `length` of `limit`; the cell being filled is partial (opacity .3 → 1).
 * @example meterCells(124, 280, 20)[8] // { fill: 0.857…, tone: "ok", opacity: 0.9 }
 */
export function meterCells(length: number, limit: number, cells = 20): MeterCell[] {
  const n = Math.max(1, Math.round(cells));
  const over = limit > 0 && length > limit;
  const f = limit > 0 ? (Math.max(0, length) / limit) * n : 0;
  return Array.from({ length: n }, (_, i) => {
    const fill = over ? 1 : Math.max(0, Math.min(1, f - i));
    const tone: MeterCell["tone"] = fill <= 0 ? "off" : over ? "over" : i >= n * 0.9 ? "near" : "ok";
    return { fill, tone, opacity: fill > 0 ? 0.3 + 0.7 * fill : 1 };
  });
}

/**
 * How many of a mixed checkbox's 3 cells are lit for `fraction` of its children on: 1–3, rounding up
 * so every step shows (1, 2, 3 of 4 light 1, 2, 3 cells; the tinted box still says "not all").
 */
export function mixedCells(fraction = 2 / 3): number {
  const f = Number.isFinite(fraction) ? Math.min(1, Math.max(0, fraction)) : 2 / 3;
  return Math.min(3, Math.max(1, Math.ceil(f * 3 - 1e-9)));
}
```

### lib/beautiful-ui/lumen/sound.ts

```tsx
"use client";

import * as React from "react";

/**
 * Asks the page's sound layer (beautiful-ui-sound) to play `cue`. Silent when nothing listens, and inside
 * anything marked data-sound="off". `index` pitches select cues by position. No audio code ships in
 * the components themselves.
 */
export function emitSound(el: Element | null, cue: string, force?: boolean, index?: number) {
  if (!el || typeof CustomEvent === "undefined" || el.closest('[data-sound="off"]')) return;
  el.dispatchEvent(new CustomEvent("beautiful-ui:sound", { bubbles: true, detail: { cue, force, index } }));
}

/**
 * Plays the cue `pick` returns whenever `value` changes (never on mount): an error when a field
 * turns invalid, a success when a check passes.
 */
export function useCueOnChange<T>(ref: React.RefObject<Element | null>, value: T, pick: (next: T, prev: T) => string | null) {
  const prev = React.useRef(value);
  const pickRef = React.useRef(pick);
  React.useEffect(() => {
    pickRef.current = pick;
  });
  React.useEffect(() => {
    if (Object.is(prev.current, value)) return;
    const before = prev.current;
    prev.current = value;
    const cue = pickRef.current(value, before);
    if (cue) emitSound(ref.current, cue);
  }, [ref, value]);
}

/** Points one ref (callback or object) at `node`; returns how to let go of it. */
function assign<T>(r: React.Ref<T> | undefined, node: T | null): () => void {
  if (typeof r === "function") {
    const cleanup = r(node);
    return typeof cleanup === "function" ? cleanup : () => r(null);
  }
  if (r) {
    (r as React.RefObject<T | null>).current = node;
    return () => ((r as React.RefObject<T | null>).current = null);
  }
  return () => {};
}

/**
 * One stable callback ref for the component's own ref and the caller's. It changes only when one of
 * them does, so a caller's callback ref isn't detached and reattached on every render, and it
 * honours React 19 ref cleanups.
 */
export function useMergedRef<T>(own: React.Ref<T> | undefined, theirs: React.Ref<T> | undefined): React.RefCallback<T> {
  return React.useCallback(
    (node: T | null) => {
      const release = [assign(own, node), assign(theirs, node)];
      return () => release.forEach((f) => f());
    },
    [own, theirs],
  );
}

/** True when `el` sits in an input group whose status part speaks for it (one cue per change). */
export const statusSpeaksFor = (el: Element | null) => Boolean(el?.closest('[data-slot="input-group"]')?.querySelector('[data-slot="input-group-status"]'));
```

### CSS (the registry `css` / `cssVars`, merged into the global stylesheet by the shadcn CLI)

```css
@layer components {
  .lumen-checkbox {
    --k-sz: 18px;
    --k-r: 6px;
    --k-mk: 7px;
    --x-acc: var(--gc-p-acc);
    --x-ring: var(--gc-p-wr);
    --x-sh: inset 0 0 0 1.5px var(--x-ring),var(--gc-wellIn);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: none;
    width: var(--k-sz);
    height: var(--k-sz);
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: calc(var(--k-r) * var(--lumen-radius-k, 1));
    background: var(--gc-well);
    box-shadow: var(--x-sh);
    color: var(--gc-onSolid);
    cursor: pointer;
    outline: none;
    -webkit-appearance: none;
    appearance: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    transition: background min(0.25s, var(--gcp-cm)) ease,box-shadow min(0.25s, var(--gcp-cm)) ease,transform calc(0.4s * var(--gcp-k)) var(--gc-sp);
  }
  .lumen-checkbox::after {
    content: "";
    position: absolute;
    inset: min(-4px, calc((var(--k-sz) - 44px) / 2));
  }
  .lumen-checkbox[aria-invalid="true"] {
    --x-acc: var(--gc-bad);
    --x-ring: color-mix(in srgb, var(--gc-bad) 75%, transparent);
  }
  .lumen-checkbox:focus-visible {
    box-shadow: 0 0 0 2px var(--gc-gap), 0 0 0 4px var(--gc-p-focus), var(--x-sh);
  }
  .lumen-checkbox:not(:is([data-disabled],:disabled)):active {
    transform: scale(.88);
  }
  .lumen-checkbox:is([data-disabled],:disabled) {
    opacity: .4;
    cursor: not-allowed;
  }
  .lumen-checkbox:is([data-checked],[data-state="checked"]) {
    background: var(--x-acc);
    --x-sh: inset 0 1px 0 rgba(255,255,255,.3),0 4px 10px -4px color-mix(in srgb, var(--x-acc) 70%, transparent);
  }
  .lumen-checkbox:is([data-indeterminate],[data-state="indeterminate"]) {
    background: color-mix(in srgb, var(--x-acc) 14%, transparent);
    --x-sh: inset 0 0 0 1.5px color-mix(in srgb, var(--x-acc) 70%, transparent);
  }
  .lumen-checkbox-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: calc(var(--k-sz) - 4px);
  }
  .lumen-checkbox-check {
    display: contents;
  }
  .lumen-checkbox-indicator .lumen-check {
    width: 1em;
    height: 1em;
  }
  .lumen-checkbox:is([data-indeterminate],[data-state="indeterminate"]) .lumen-checkbox-check,.lumen-checkbox:not(:is([data-indeterminate],[data-state="indeterminate"])) .lumen-checkbox-mixed {
    display: none;
  }
  .lumen-checkbox-indicator .lumen-check path {
    animation-duration: calc(.45s * var(--gcp-k));
  }
  .lumen-checkbox-mixed {
    display: flex;
    gap: 1.5px;
  }
  .lumen-checkbox-mixed>span {
    width: 3px;
    height: 6px;
    border-radius: calc(1px * var(--lumen-radius-k, 1));
    background: color-mix(in srgb, var(--x-acc) 28%, transparent);
    animation: lumen-pop calc(.35s * var(--gcp-k)) var(--gc-sp) both;
    transition: background min(0.3s, var(--gcp-cm)) ease;
  }
  .lumen-checkbox-mixed>span:nth-child(2) {
    animation-delay: calc(50ms * var(--gcp-k));
  }
  .lumen-checkbox-mixed>span:nth-child(3) {
    animation-delay: calc(100ms * var(--gcp-k));
  }
  .lumen-checkbox-mixed>span[data-lit] {
    background: var(--x-acc);
  }
  .lumen-field-label:has(>.lumen-field) {
    --gcp-k: 1;
    --gcp-cm: 9s;
    --gc-sp: cubic-bezier(.34,1.5,.64,1);
    position: relative;
    display: flex;
    width: 100%;
    padding: 14px 16px;
    border-radius: calc(16px * var(--lumen-radius-k, 1));
    background: var(--gc-p-cardIn);
    --c-ring: var(--gc-hair);
    box-shadow: inset 0 0 0 1px var(--c-ring);
    color: var(--gc-ink);
    cursor: pointer;
    transition: box-shadow min(0.25s, var(--gcp-cm)) ease,background min(0.25s, var(--gcp-cm)) ease,transform calc(0.45s * var(--gcp-k)) var(--gc-sp);
  }
  @media (hover:hover) {
    .lumen-checkbox:not(:is([data-disabled],:disabled)):not([aria-invalid="true"]):not(:is([data-checked],[data-state="checked"])):not(:is([data-indeterminate],[data-state="indeterminate"])):hover {
      --x-ring: var(--gc-p-wrH);
    }
    .lumen-field-label:has(>.lumen-field):not(:has(:is([data-disabled],:disabled))):hover {
      transform: translateY(-1px);
      --c-ring: var(--gc-p-wrH);
    }
  }
  .lumen-field-label:has(>.lumen-field):not(:has(:is([data-disabled],:disabled))):active {
    transform: scale(.985);
  }
  .lumen-field-label:has(>.lumen-field):has(:is([data-checked],[data-state="checked"])) {
    background: color-mix(in srgb, var(--gc-p-acc) 7%, transparent);
    --c-ring: color-mix(in srgb, var(--gc-p-acc) 55%, transparent);
    box-shadow: inset 0 0 0 1.5px var(--c-ring);
  }
  .lumen-field-label:has(>.lumen-field):has(:focus-visible) {
    box-shadow: 0 0 0 2px var(--gc-gap), 0 0 0 4px var(--gc-p-focus), inset 0 0 0 1.5px var(--c-ring);
  }
  .lumen-field-label:has(>.lumen-field):has(:is([data-disabled],:disabled)) {
    opacity: .55;
    cursor: not-allowed;
  }
  @media (prefers-reduced-motion: reduce) {
    .lumen-field-label:has(>.lumen-field) {
      --gcp-k: 0;
      --gcp-cm: .15s;
    }
  }
  .lumen-field-label>.lumen-field {
    gap: 12px;
  }
  .lumen-field-label>.lumen-field .lumen-field-title {
    font-size: 14px;
  }
  .lumen-field-label>.lumen-field .lumen-field-description {
    font-size: 12.5px;
    line-height: 1.4;
  }
  @media (max-width: 699px) {
    .lumen-checkbox {
      --k-sz: 22px;
      --k-r: 7px;
      --k-mk: 8px;
      --k-sw: 52px;
      --k-sh: 32px;
      --k-kx: 8px;
      --k-cs: 5px;
      --k-ci: 10px;
    }
    .lumen-checkbox-mixed>span {
      width: 4px;
      height: 8px;
    }
  }
}
```

The lumen foundation (the tokens listed above, keyframes and motion levels) installs once with the first component; its CSS is public at https://beautiful-ui.dev/r/lumen-foundation.json.
