Skip to content

v0.22.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 22:35
· 260 commits to main since this release

A component library worth building on, and a richer rich-text editor.
foldkit-mixins-ui 0.11.0 grows from the parity components to the whole UI
plan: the polish pass over every component (state colour, concentric corners,
the top layer, overlay scroll bars, right to left), the merges into one Alert,
Dialog, Sheet, Menu, Slider and date system, and chat (ChatMessage,
MessageScroller, Thinking Indicator, Thinking Steps, Questionnaire) and Zag's
long tail (Angle Slider, Timer, Marquee, Image Cropper, Signature Pad, QR Code,
Chart, Cascade Select, Floating Panel, Tour). foldkit-mixins 0.12.0 for the
state ink, nests/nested(), surface.field, the shadow and chart tokens;
foldkit-primitives 0.11.0 for ScrollBars, Swipe, ScrollSettle,
PointerPosition and TrackBox; foldkit-richtext 0.4.0,
foldkit-richtext-dom 0.5.0, foldkit-mixins-richtext 0.4.0 and
foldkit-richtext-markdown 0.3.0 for the editor's changes below;
foldkit-remote-server 0.15.0 for RemoteServer.memory's entities and
optional principal; foldkit-auth 0.1.1 and foldkit-ssr 0.7.1 for Fetch
Metadata on a request with no Origin; foldkit-mixins-data-grid 0.2.3 for
the motion tiers; and foldkit-plus 0.4.0. Every package that pins one of
them republishes with a patch to re-pin: foldkit-builder 0.3.3,
foldkit-cms 0.7.3, foldkit-cms-drizzle 0.6.6, foldkit-mixins-builder
0.3.3, foldkit-mixins-crud 0.7.3, foldkit-mixins-form 0.6.2,
foldkit-remote-drizzle 0.12.3, foldkit-richtext-code 0.2.1,
foldkit-richtext-code-shiki 0.2.1 and foldkit-site 0.4.1.

Changes that can break code written for 0.21 are marked "Breaking" in the
entries below; most are in foldkit-mixins-ui and the rich-text packages.

Added

  • foldkit-primitives/dom: TrackBox. A Mount that follows the element
    named by its data-target and writes its viewport box (and, asked, its
    corner radius) as --fk-<name>-x, -y, -w, -h and -radius, telling
    TrackedTarget { target, found }; the Tour's cutout now draws with it
    (its Spotlight Mount is gone, its properties are --fk-tour-w and -h,
    and its ring follows the target's corner).

  • foldkit-mixins-ui: Calendar options, presets and a locale. The
    fourth argument of Calendar.toView, inputs and resolve
    (CalendarOptions) takes weekNumbers (ISO weeks), caption: 'label' or
    month and year selects (dropdowns, answered by Calendar.show),
    paging with Calendar.alongside for two months side by side, and a
    range's preview under the pointer. Presets are Calendar.lastDays,
    nextDays, monthOf, day and presetsView; Calendar.localeOf(tag)
    reads upstream's locale from Intl; the recipe takes outside: 'hidden'.

  • foldkit-mixins-ui: Tabs, Segmented, Breadcrumb and a navigation menu
    with panels.
    Tabs take icons and counts (label and icon slots, a
    Badge after the words), overflow: 'scroll' (one line, its edges
    fading), size: 'lg', a vertical tablist's rule at its inline end, and
    closable tabs (TabsContext.close: a close button and Delete; answer with
    Tabs.closing). A Segmented option takes an icon, alone with
    iconOnly; the recipe adds tray: 'underline', width: 'fill' and size: 'lg'. Breadcrumb's collapse: { max, menu } makes the ellipsis open a
    Menu of the hidden steps (Breadcrumb.menuRows, Breadcrumb.chosen).
    Nav.view draws a navigation menu whose triggers open panels of link
    columns in the top layer, with the APG's disclosure-navigation keys, its
    open panel in Nav.init/Nav.update; the recipe adds indicator: 'pill'
    and a column.

  • foldkit-mixins-ui: Steps, Accordion, Table, Progress, Rating and
    Resizable grow.
    Steps take marker: 'dot', connector: 'progress' with
    the view's progress, and size on the Avatar's steps. The Accordion
    takes variant (plain, bordered, separated, filled, ghost),
    separators, indicator: 'plus', indicatorPosition: 'start', active
    and its own icon. Table sorts (sortKey, sort: { by, onSort },
    aria-sort, Table.nextSort), chooses rows with checkboxes
    (selection), opens a row's detail below it (expansion) and stands an
    empty state across itself, all the application's; the recipe adds
    rows, density and header: 'sticky'. Progress takes showValue, a
    value of stacked sections, a buffer and segments, and the recipe
    tone, stripes and size. Rating takes precision: 0.5, a read-only
    fraction, onClear, showValue, and Home and End (Rating.Ends); a
    read-only rating takes no onChange; the recipe adds glyph and an
    error tone. Resizable collapses a panel (collapsible, collapsedTo)
    on Enter or a double-click, nests either way, and handle: 'grip' shows
    a pill of dots.

  • foldkit-primitives/dom: ScrollSettle, a Mount that reports the
    item nearest a scroller's start once a scroll rests (scrollend, or a
    quiet scroll where it is missing), right to left from the right edge.

  • foldkit-mixins-ui: a custom Select, and Combobox chips, clearing and an
    empty panel.
    A select drawn over Listbox: Listbox.parts draws an
    option's icon, label, description and check, and the trigger's value (or
    its placeholder, muted) and chevron; Recipes.Listbox gains check
    (end, start, none), trigger (outline, filled, ghost) and size
    lg. The Combobox takes chips (each chosen value a chip in the field,
    its remove button choosing it again, which a multiple combobox toggles
    off), clearContent and clearLabel (a clear button while the field has
    text) and empty (a polite panel in the list's place with nothing to list,
    a loading line too); Combobox.parts draws an option with the typed text
    marked. ComboboxChipRender and ComboboxExtraInputs are exported.

  • foldkit-mixins-ui: TagsInput's max and refusals, PasswordInput's
    strength and rules, InputCopy's reset.
    TagsInput.init({ max }) holds at
    most max tags; a commit that adds nothing, or not all of the draft, is a
    Refusal (Repeat, Empty, Full), said in a polite message slot
    (refusalText words it) with a one-time shake that travel stills.
    PasswordInput takes strength (a Meter), requirements
    (PasswordRequirements listed under the field, each read as met or not)
    and capsLock: { on, onKey }, a polite hint while Caps Lock is on, read
    from each key by capsLockOf. InputCopy gains a Model (init({ resetAfter }), default 2000ms) and update: Copied shows the value as
    copied and starts Reset, which sets it back to "Copy" unless a later copy
    came first.

  • foldkit-mixins/theme: shadows tinted by shadow-h and shadow-c.
    Theme.oklch({ shadow: { h, c } }) sets two knobs every shadow reads,
    defaulting to the neutrals' hue at twice their chroma, so shadows take the
    page's hue rather than a neutral black.

  • foldkit-mixins-ui: Card, Avatar, Separator, Skeleton, Spinner, Item and
    Empty grow their looks.
    Card takes elevation (0 to 3, a step of
    the surface ladder: lighter in a dark scheme, a contact and an ambient
    shadow in a light one) and lift: 'hover' (a lift under the pointer,
    times travel); Card.overlay is the one stretched press control a
    pressable card or Item draws. Avatar takes src, initials, status
    and statusLabel; Avatar.group({ people, max, label, moreLabel }) draws
    overlapping avatars and counts the rest as one more (AvatarGroupSlots,
    Recipes.AvatarGroup({ overlap: 'tight' | 'loose' | 'none' })), and
    Recipes.Avatar gains sizes xs and xl, shape (circle, rounded,
    square), color: 'name' (a hue from the name) and ring. Separator
    takes label and decorative, and the recipe line (solid, dashed,
    dotted), thickness, spacing and inset. Skeleton gains lines,
    avatarRow, card and tableRow({ columns }), and animation (pulse,
    shimmer, none). Spinner takes showLabel, and the recipe kind
    (ring, dots, bars, pulse, orbit), size and tone (accent,
    neutral, current). Item is the row primitive: press, label,
    selected and disabled, Item.group for a list (ItemGroupSlots,
    Recipes.ItemGroup({ layout: 'divided' | 'separated' })), and the recipe's
    variant (plain, outline, muted) and media (plain, icon,
    image). Empty takes media (icon, illustration), frame (none,
    dashed, filled), tone (neutral, danger) and size.

  • foldkit-mixins-ui: menu check rows, groups and shortcuts; Command pages
    and hints; a Toast component.
    A Menu row may be a CheckRow (check: 'checkbox' | 'radio', checked): choosing it sends Selected and leaves
    the menu open, the application keeping checked. Any row may name a
    group (a heading, and a separator between groups), a shortcut (keys
    drawn as Kbd with kbd, named in aria-keyshortcuts) and tone: 'destructive'. A Menubar's menus take the same rows, and Menubar.init(ids, { isAnimated, isModal }) passes both to every menu. A Command row takes
    icon, description (matched by the query) and opensPage; the view
    takes page: { trail, onBack } (Backspace in an empty field goes back),
    loading, hints for a footer of keys and kbd; Command.hotkey(message)
    is ⌘K or Ctrl+K anywhere, and Recipes.Command({ frame: 'bare' }) sits in
    a dialog. Toast is now a component: init, show, settle, dismiss,
    update and view. Toasts stack after Sonner's, spread out when held,
    pause while the pointer or focus is on the stack or the page is hidden
    (keeping the time left), show three at most, swipe away toward their
    edge, and are spoken in a polite or, for an error, an assertive region.
    settle turns a loading toast into its outcome, a promise toast; an
    action sends Acted with its value. Recipes.Toast({ tone: 'rich' })
    tints each type. ToastView stays for toasts that carry their own payload.

  • foldkit-mixins-ui: popovers, tooltips and hover cards in the top layer,
    and the Sheet.
    Anchor.layer around a panel shows it in the browser's
    top layer, above every stacking context and outside every overflow box,
    with upstream's anchor placing it (the new layer slots), and an arrow
    slot points at the trigger. Popover.anchor(), Tooltip.anchor() and
    HoverIntent.anchor() are the placements: off the trigger (the Popover
    12px, room for its larger arrow; the others 8px), 8px inside the viewport,
    flipping and shifting to stay there. A Hover Card is placed
    by HoverIntent.toView's anchored: { id, anchor? }. The Popover and
    Tooltip recipes take arrow: 'none'. The Dialog gains body, scroll,
    scrollBar, scrollThumb and footer slots (a long body scrolls under a
    footer that stays), Dialog.overlayBars, sizes xl and full, covered
    (a dialog that another was opened from steps back) and
    DialogContext.attributes. Sheet is a component over the Dialog: its
    handle drags it between points and, unless dismissible: false, away,
    with vaul's thresholds; Sheet.view({ scalesPage }) with
    Recipes.sheetPage on the page beside it steps the page back. Swipe is
    in foldkit-primitives/dom.

  • foldkit-mixins-ui: a visible press and a filled toggle on buttons, four
    badge looks, key combinations, richer breadcrumbs, pagination and steps.

    A held button scales to 98% (the 2% multiplied by travel, so reduced
    motion holds its size); a solid or primary one also deepens to its
    family's active fill (a new tone, fill-active) and clears the 1px border
    of its own color its fill stands in, so the fill draws in by 1px a side.
    A pressed toggle rests on its tone's fill (a solid one on the active
    fill), keeps it hovered (an unfilled one takes the hover fill), deepens to
    the active fill while held, and keeps its text on the fill throughout.
    Badge takes appearance: tinted (default), dot, outline or
    solid. Kbd.combo({ keys, joiner? }) draws several keys in one kbd.
    Breadcrumb steps take icons, the view takes a custom separator and
    collapse: { max, onExpand } (with collapsedOf as the pure split), and
    the recipe takes a separator axis: slash (default), chevron or
    dot, a separator midway between its steps. Pagination takes siblings?,
    boundaries?, numbered?, ends? and range? (with summaryOf for
    "1–10 of 97", and range.choose: { sizes, onPerPage, label? } for a
    rows-per-page select), with new summary, first, last, perPage,
    perPageSelect and pageCount slots; the current stop holds " / 12",
    which the recipe's compact axis (narrow, the default, below a 30rem
    window; always; never) shows while it hides the other numbers. Steps
    take per-step icons and vertical content, whose line reaches both
    markers.

  • foldkit-mixins-ui: radio cards, and a wrapping row. RadioGroupSlots
    gains card, an option's whole row, which the application draws around
    its radio and words (h.label(option.card, …)) and which is
    data-checked while its option is; Recipes.RadioGroup takes variant: 'card', which frames each card and fills the chosen one. A horizontal
    group (aria-orientation="horizontal") wraps. The gallery shows
    descriptions, a row, and cards.

  • foldkit-mixins-ui: a checkbox group in a row, with an error.
    CheckboxGroup takes error (the group is aria-invalid and described by
    it) and orientation: vertical (default) or horizontal. The rows sit
    in an options slot, spaced on the ladder; a vertical list keeps them
    flush so checked rows stay one block. selectAll: { label, onSet } draws
    a first row whose checkbox is checked, mixed or unchecked by
    coverage(options, checked) (a disabled option counts for neither) and
    controls every option; a press sends onSet with setEnabled(options, checked, on), every enabled option or none, a disabled option keeping the
    state checked gives it. The checkbox sits on the label's row, so a
    description does not pull it down.

  • foldkit-mixins-ui: a checkbox check that wipes in. The mark is drawn
    clipped away and wipes on over the fast tier, travel-aware, so reduced
    motion shows it at once. The mixed dash clears the check's box, borders
    and turn. The gallery shows basic, indeterminate and a card checkbox.

  • An overlay scrollbar, after Fluid Functionalism's. ScrollBars in
    foldkit-primitives/dom; ScrollArea.overlayBars, Command.overlayBars,
    VirtualList.overlayBars, Menu.overlayBars, Listbox.overlayBars and
    Combobox.overlayBars, each a mixin list passed beside the style;
    Utilities.scrollDivider and
    scrollTimeline for a hairline at a scrolled edge. A browser's bar is
    thick, always shown and different on every system; this thumb rests at
    4px, widens to 6px under the pointer and fades when idle, its widening
    travelling so reduced motion keeps only the fades. A coarse pointer keeps
    its native bar. The bar sits beside the scroller, not in it, so the edge
    fade does not erase it: ScrollArea, Command and VirtualList always draw
    it, a popup whenever its panel has a scroll, and the recipe draws it only
    once ScrollBars marks it scrollable. It is opt-in, since its Mount sends
    no Message for a Scene test to resolve. ScrollArea's markup gains a root
    around viewport and a bar per axis: a width set on the area goes on
    root.

  • foldkit-mixins: Theme.nests and Theme.nested(). A container that
    pads its children spreads Theme.nests(radius, inset, border?), and any
    descendant's borderRadius: Theme.nested() is concentric with it, without
    repeating the container's arithmetic. Theme.nested(outer, inset, border?)
    is unchanged.

  • foldkit-mixins: a surface.field token for filled controls. The
    filled Input, Textarea and Select read var(--fk-surface-field) — the
    default step, so it tracks the surface-contrast knob — instead of the
    page-adjacent surface.subtle.

  • foldkit-mixins-ui: a label Slot on Segmented, the option's words,
    which hold the text-box trim.

  • foldkit-richtext-dom: arrows stop on an image, and a checkbox keeps the
    caret.
    An arrow leaving a block for an atom beside it selects the atom,
    where the browser stepped over it, and a press on an adornment no longer
    takes the caret away from the text.

  • foldkit-richtext-dom: a triple click selects its block's text, and Ctrl+A
    in code selects the code.
    The browser's triple-click selection ran on to the
    start of the next block, so typing over it swallowed that block's first line
    too. In code, a second Ctrl+A selects the document.

  • foldkit-richtext: a paste joins the line it lands in. The first pasted
    block joins the text before the caret and the last the text after it, so a
    copied word lands inside the sentence instead of splitting it onto a line of
    its own; an image or table stands between the halves, and a paste into code
    is its text. Breaking: Paste no longer puts content above a block at its
    start or below it at its end as separate blocks.

  • foldkit-richtext-dom: a press below the last block writes after it. The
    caret goes to the end of a last paragraph or heading; after a table, code or
    an image a new paragraph opens, where no caret could get below them.

  • foldkit-richtext: Backspace and Delete beside a list, a quote, a table or
    code.
    They reach the nearest line on that side: a list's or a quote's last or
    first line joins the caret's, and Delete at the end of a list item reaches the
    next item; a table or code is stepped into, and an empty line beside one is
    removed. All were refused, so an empty line after a table could not be
    removed. Backspace at the start of a heading now makes it a paragraph before a
    second press joins it.

  • foldkit-richtext-dom: a placement's keymap, and Mod+Shift+S. editorAt
    takes chords beside the built-in ones, and Strikethrough has a chord of its
    own. The playground binds Ctrl+U (underline), Ctrl+Shift+H (highlight) and
    Ctrl+K (the link editor), and its toolbar names them.

  • foldkit-richtext: node(…, { indents }), split from lineBreaks. A kind
    can keep line breaks (Enter breaks the line, Enter on an empty last line
    leaves it) without Tab indenting it, as a callout of several lines does in
    the playground, where Enter used to start a second callout. Breaking: Tab and
    a broken line's indentation now follow indents, which the standard
    CodeBlock declares beside lineBreaks; declare it on a code kind of your own.

  • foldkit-richtext-dom: Escape closes the slash menu. Message.DismissedSlash
    keeps EditorState.slashDismissed, the slash of the query it closed, so the
    menu stays shut while that query is typed on and Enter splits the line; it
    ends with the query. menuTextOf(view) is what a menu reads, so a view and
    Enter agree. EditorState and EditorView gain the field.

  • foldkit-richtext: an atom is selected whole. A press on an image or a
    divider selects it (outlined through data-selected), as does Backspace from
    the block after it or Delete from the block before; a second press deletes
    it, Enter opens a paragraph after it, typing replaces it, and an arrow leaves
    it for the text beside it. isAtom(nodes, block) is the test. Deleting a
    block now lands the caret where the block was even when it held no text,
    where it went to the top of the document.

  • foldkit-mixins-ui: Carousel, the APG carousel. A scroll-snap track
    of slides named "N of M", previous and next buttons, dots and a polite
    status. Its slide and rotation are a Model (Carousel.init({ id, slide?, autoplay?, delay? })) folded with Carousel.update({ count, perView?, loop? }), which returns Carousel.ShowSlide, the Command that scrolls the
    track, smoothly only without reduced motion; a swipe comes back through
    ScrollSettle, so the dots follow the finger. With autoplay it moves on
    every delay (4s), pauses under the pointer, stops when focus arrives by
    the keys, quiets its status while it rotates and draws the APG's rotation
    button first; the current dot is Fluid's pill, filling over the delay.
    thumbnails stand in for the dots, and perView shows several slides at
    once, a dot per place the track can rest. Recipe axis peek.
    Recipes.Carousel, Patterns.Carousel and a gallery page.

  • foldkit-mixins-ui: TreeView, the APG tree view. Nested rows with
    one tab stop: the arrows move through the rows showing and open, shut,
    enter or leave a row; Home and End; a character moves to the next row it
    starts; Enter, Space or a click chooses a row. Its Model (current,
    open, selected, checked) is folded with TreeView.update(nodes),
    which decides each key from its own Model, so keys faster than a frame
    still move on. It reuses TreeNavigation's shown, move and tabStop
    and Typeahead.match. Each item carries its depth as --fk-tree-level.
    A node takes an icon and an openIcon; Recipes.TreeView({ guides: 'lines' }) draws a guide down each open branch; checkable (on the view
    and update) gives every row a tri-state box, the Model's checked
    holding the leaves and a branch reading checked, mixed or not from them
    (TreeView.checksOf), Space checking in update. Recipes.TreeView,
    Patterns.TreeView and a gallery page.

  • foldkit-mixins-ui: ColorPicker, after ReUI's: a saturation and
    brightness area (the pointer and the keys), hue and alpha Sliders painted
    from the color (Recipes.Slider({ track: 'paint', label: 'hidden' })), the
    browser's EyeDropper where there is one (ColorPicker.Eyedrop,
    canEyedrop), text in hex, rgb, hsl or oklch that parses to an Option
    (format, parse, and color('#3b82f6') for a literal in code), and
    presets as a radio group of swatches. The color, its format and a draft
    being typed are ColorPicker.Model (init({ id, color?, format? })),
    folded with ColorPicker.update, so fast keys each step from the last
    color; toOklch reads a color for a theme. ColorPicker.popover draws it
    as a Popover's toView. Patterns.ColorPicker and a gallery page.

  • foldkit-mixins-ui: Recipes.Sheet, the Dialog from an edge.
    shadcn's Sheet and vaul's Drawer as one recipe over DialogSlots: the
    panel stands on the edge its data-side names (top, right, bottom,
    left, written by Sheet.view from Sheet.init({ side })) and slides in
    from there, the fade kept under reduced motion. handle: 'bar', the
    default, shows the handle, a Slot (handle on DialogSlots, aria-hidden,
    drawn as h.div(dialog.handle) in the panel), and rounds the inner
    corners: from the top or bottom it is the panel's last or first row, and
    from the left or right a bar standing on the edge facing the page, so a
    bottom sheet with its handle is a drawer as on a phone. One gallery
    page.

  • foldkit-mixins-ui: InputCopy, a value with a copy button. A
    read-only field and a button named after its label; InputCopy.Copy is
    the Command that writes the clipboard and reports Copied or CopyFailed
    as foldkit-primitives/dom's ClipboardMessage. The copied flag is the
    application's; copied, the button reads "Copied" and a status region
    announces it. Recipes.InputCopy, Patterns.InputCopy and a gallery page.

  • foldkit-mixins-ui: TagsInput, Zag's tags input: the tags as a
    list of chips named by the field's label, each with a Remove <tag>
    button, and a text input. Enter or the delimiter adds the draft, split at
    the delimiter and trimmed, refusing empty and repeated parts; Backspace on
    an empty draft removes the last tag; a removal sends focus back to the
    input. The tags and the draft are its own small Model (init, Message,
    update), and the keys reach update, so it decides from the current
    draft, not the last frame's. A recipe, a pattern and a gallery page.

  • foldkit-mixins-ui: PasswordInput, a password field whose toggle
    (aria-pressed, aria-controls) shows it as text, autocomplete kept as
    current-password or new-password. Recipes.PasswordInput reuses
    Input's pieces in InputGroup's box, draws the eye with Icons.glyph and
    hides the browser's own reveal button. Patterns.PasswordInput and a
    gallery page.

  • foldkit-mixins-ui: Rating, a row of stars as the APG's radio group
    of native radios: the application keeps value (an Option, none before
    anyone rates) and receives onChange with the star chosen. The arrows move
    the choice natively, readOnly draws one img that names the rating, and
    disabled stills it. The recipe cuts each star with clip-path on the
    radio's ::before, keeping its focus ring whole, and previews the rating
    under the pointer in CSS alone. Patterns.Rating and a gallery page.

  • foldkit-mixins-ui: Steps, a stepper. A named ordered list whose
    step at current is aria-current="step", those before it complete (a
    check in the marker) and those after upcoming, as data-state, joined by
    a connector. The application owns current; given onSelect, completed
    steps are buttons that go back. Recipe axis orientation. Recipes.Steps,
    Patterns.Steps and a gallery page.

  • foldkit-mixins-ui: VirtualList, @foldkit/ui's virtual list
    adapted.
    It draws only the rows in view; its Model stays upstream's,
    folded with that module's update. The root slot is the box it scrolls
    within and row each row's content; the box fills its container's width
    and, where the container takes its width from the box, offers 20rem, so
    the rows drawn as it scrolls never resize it. Recipes.VirtualList,
    Patterns.VirtualList and a gallery page of ten thousand rows.

  • foldkit-mixins-ui: Meter, @foldkit/ui's Meter adapted. A
    measurement within a range, its root's data-level (good, fair,
    poor) the HTML meter's judgment of the value against low, high and
    optimum (Meter.levelOf), which the recipe colours success, warning or
    error. Recipes.Meter, Patterns.Meter and a gallery page.

  • foldkit-mixins-ui: Progress, @foldkit/ui's Progress adapted,
    with Circular Progress as its recipe's shape: 'ring'. value is an
    Option, none for work whose end is not known, which the bar shows
    sliding and the ring turning, still under reduced motion. The root carries
    the share done as --fk-progress. Recipes.Progress, Patterns.Progress
    and a gallery page.

  • foldkit-mixins-ui: Menubar, a row of @foldkit/ui Menus. Its
    Model holds the menus and the bar's one tab stop, folded with
    Menubar.update, whose Selected OutMessage names the menu and the row.
    The arrows move the stop while the menus are shut and open the next menu
    while one is open; pointing at another trigger while one is open opens it,
    and opening any menu shuts the rest without sending focus back to its
    button. Recipes.Menubar, Recipes.MenubarMenu, Patterns.Menubar and a
    gallery page.

  • foldkit-mixins-ui: Nav, @foldkit/ui's Nav adapted, and with it
    the navigation menu: Nav.toView draws the landmark's links in a list,
    the current one aria-current="page", and Nav.fluid glides a line to
    the current link and a faint pill to the one the pointer nears, as Tabs'
    do. The keys stay the browser's (no roving tab stop for a landmark).
    Recipes.Nav, Patterns.Nav and a gallery page. shadcn's dropdown
    panels in a navigation menu are not here yet.

  • foldkit-mixins-ui: Sidebar, from the widgets island into the
    package: shadcn's sidebar with Fluid Functionalism's collapse. A named
    navigation landmark with a header and a footer, groups with or without a
    heading that open on the accordion's grid row (several at once), rows with
    icons and counts, branches of nested links, the current page marked
    aria-current with a marker that glides to it (Sidebar.fluid), and a
    toggle that collapses it off the page (collapse: 'offcanvas') or to a
    rail of icons named in Tooltips ('icons'); on a phone an opener shows it
    in a Sheet. Its Model (Sidebar.init({ id, rows, open?, collapsed? }),
    Sidebar.update) holds what is open and collapsed, the rail's Tooltips
    and the Sheet. width: 'fill' sizes it to a Resizable's panel. A recipe,
    a pattern and a gallery page.

  • foldkit-mixins-ui: Resizable, from the widgets island into the
    package: shadcn's Resizable and the APG's window splitter, two panels with
    a handle that is a separator with its value, stepped by the arrows and
    sent to the bounds by Home and End, and dragged, following the Move
    Mount from where the drag began over the group the Resize Mount
    measured. The split is a small Model of its own (init, Message,
    update) the application keeps; side by side or one over the other. A
    recipe, a pattern and a gallery page.

  • foldkit-mixins-ui: Command, the widgets island's command palette as
    shadcn's Command with Fluid Functionalism's CommandMenu behaviour: a field
    that points at the highlighted row through aria-activedescendant, ↑ and
    ↓ wrapping through enabled rows, Enter running the highlighted one, rows
    in groups with shortcuts, and an empty state. The filter (filtered)
    matches every query word against a row's label and keywords and never
    re-sorts; a highlight filtered away moves to the first enabled row. The
    query and highlight are the application's. A shortcut reads left to right
    on a right-to-left page. A recipe, a pattern and a page.

  • foldkit-mixins-ui: Recipes.HoverCard, the widgets island's hover
    card as @foldkit/ui's HoverIntent with a look: a trigger read as a link
    and a raised panel that fades in as it is drawn (@starting-style),
    placed against its trigger in the top layer by HoverIntent.toView's
    anchored. The delays stay HoverIntent's. A gallery
    page draws it.

  • foldkit-mixins-ui: OtpField, Input OTP, after shadcn's input-otp
    rather than the widgets island's cell per input: one real <input> over
    cells that only mirror it, so paste, Backspace, the caret and a phone's
    one-time-code autofill are the browser's and no Command moves focus.
    The code is the application's, kept to its pattern and length
    (OtpField.kept); groups draws runs with a separator, and the next cell
    draws a blinking caret while the field has focus. A recipe, a pattern and
    a gallery page.

  • foldkit-mixins-ui: NumberField, from the widgets island into the
    package: the APG's editable spinbutton and Zag's number input. The arrows,
    PageUp and PageDown, Home and End step it through SpinValue's spin, a
    typed number commits on change (text that is no number leaves the value),
    and steppers out of the tab order disable at their bound; every value is
    clamped onto its step (NumberField.settled), a decimal step kept exact.
    The value is the application's. Recipes.NumberField,
    Patterns.NumberField and a gallery page.

  • foldkit-mixins-ui: CheckboxGroup, from the widgets island into the
    package, as Zag's checkbox group with Fluid Functionalism's rows: a
    fieldset named by its legend, each option the APG's checkbox named by a
    label for it, the checked values the application's (toggled is the
    transition). Drawn as a list, checked rows fill and merge where they
    stand together. Recipes.CheckboxGroup reuses the Checkbox recipe's
    pieces; Patterns.CheckboxGroup and a gallery page. Accordion, Segmented
    and CheckboxGroup now share one step for a multiple choice.

  • foldkit-mixins-ui: an alert dialog is the Dialog with
    role: 'alertdialog'.
    Dialog.toView(mixins, { h, role: 'alertdialog' }, draw) (and Dialog.resolve) puts role="alertdialog" on the dialog
    bundle; 'dialog', the default, writes none, as the <dialog> element has
    it. Dialog.isDismissal(message) names upstream's own dismissal (Escape, a
    press on the backdrop, its close button): an application that drops those
    in update, draws no close button, and closes from its own buttons with
    @foldkit/ui's close has the APG's alert dialog. One recipe and one
    gallery page, Dialog, show both.

  • foldkit-mixins-ui: Toggle and Toggle Group, from the widgets islands,
    as what was already here.
    A toggle is a Button with pressed, which
    writes aria-pressed; every variant has its on look. A toggle group is a
    segmented control: Segmented.view draws the options from the
    application's pressed values, and Segmented.toggled(pressed, value, { multiple, optional }) is the transition, one at a time (kept pressed
    unless optional) or several. The gallery's segmented control is drawn
    with Segmented.view.

  • foldkit-mixins-ui: Accordion, from the examples/widgets island into
    the package, after the APG pattern, shadcn's and Zag's options and Fluid
    Functionalism's craft. Accordion.view draws the application's open ids,
    each trigger a button in a heading naming its region; Accordion.toggled
    is the transition, single or multiple, collapsible by default. A panel
    opens on a 0fr-1fr grid row (no measured height), clipped on its
    container, a shut one stays drawn and inert, the chevron turns 90°, and
    the open title turns semibold in its own width. Recipes.Accordion,
    Patterns.Accordion and a gallery page.

  • foldkit-mixins-ui: a table under fluid hover. Table.view({ …, fluid: true }) stands the table in a frame with one highlight behind the body
    rows, following the pointer to the nearest one, after Fluid
    Functionalism's: the lines above and below the lit row clear over 80ms, the
    header's too when the first row is lit, and the lit row's text lifts.
    FluidHover marks the item it is shown on data-fluid-lit for this.

  • foldkit-mixins-ui: merged choices. In a multiple listbox or
    combobox, chosen rows next to each other square the corners between them,
    so a run reads as one block.

  • foldkit-mixins-ui: popups and dialogs enter and leave. Drawn with
    @foldkit/ui's isAnimated, a menu, listbox or combobox panel fades in
    on the fast tier from a little smaller, sliding 4px from the side the
    anchor placed it on, and a dialog and its veil on the slow tier from 0.97;
    each leaves on its tier's quicker exit, and reduced motion keeps the fade
    alone. The Menu component passes it with Menu.init(id, rows, { isAnimated: true }). The gallery's widgets animate.

  • foldkit-mixins/utilities: steady(weight), weight without reflow.
    The element's data-label holds its text, which a hidden, zero-height
    ::after sets at weight, so a label that turns heavier when chosen
    moves nothing beside it; the element stays a block, so a text-box trim
    still works on it. A pressed segmented option and a chosen card title use
    it, and the card writes its title into data-label itself.

  • foldkit-mixins/theme: a surface ladder that nests by itself.
    Theme.raise(offset) sets an element offset levels above the raised
    element holding it, or the page (capped at 8), and Theme.raisedSurface()
    paints it for its level, after Fluid Functionalism's ladder: in a light
    scheme two steps toward white and then flat, so shadow carries elevation,
    and in a dark scheme an even step lighter per level (knob.raise-dark).
    Popups, popovers, date picker panels and toasts raise by 2 and dialogs by
    4, so a popover opened in a dialog lands above it instead of melting into
    a surface it shares. A popup keeps its menu look (popup.inverted, new,
    and the translucency) over its level.

  • foldkit-mixins/utilities: scrollFade(axis), after shadcn's and Fluid
    Functionalism's scroll-fade: a scroller's content dissolves toward an edge
    with more to scroll, its true start and end crisp until something is past
    them, by a mask a scroll timeline moves; no JavaScript, and no fade where
    scroll timelines are missing. ScrollArea and the popups' lists use it.

  • foldkit-primitives/dom: FluidHover's gapReach, the farthest a
    click in a gap may land from the highlighted item and still press it;
    Card.group uses 16px, after Fluid Functionalism's card grid. An item with
    no layout box yet keeps the highlight's last place and is measured again
    for three frames, rather than drawing the highlight at zero.

  • foldkit-richtext: InsertBlock and DeleteBlock. InsertBlock puts a
    block beside another under fresh identities (without a place, beside the
    caret's block); DeleteBlock deletes one with any container it empties and
    moves a caret inside it to the nearest text that stays. The editor sends them
    as InsertedBlock and DeletedBlock, and SetProps as ChangedProps.

  • foldkit-richtext: a rendering entry's adornments, elements drawn
    before a block's content that are not content (a checkbox, a figure's picture
    and caption, an icon). They hold no position and an HTML import drops them; a
    click on one with toggles flips that boolean prop through the document.

  • foldkit-richtext: the standard Image takes caption, width and
    align
    , all optional; the standard rendering still draws the img alone.

  • foldkit-richtext: deleting a selection across kinds of block. Select
    all and Delete did nothing, and so did any range over an image, a table, a
    list or a quote: the command refused a range it could not join. Such a range
    is now cleared (blocks wholly inside go, the ends are trimmed and joined where
    they can be, emptied containers go), and typing, Enter or pasting over it
    clears it first. A range that leaves a table cell only loses its text.

  • foldkit-richtext-dom: blockAnchor's side: 'inside-end'. A block's
    toolbar inside its top right corner, covering nothing around the block.

  • foldkit-mixins-richtext: linkEdit, and Enter that keeps up with typing.
    The link editor's Enter sent the edit its last drawing decided, a frame
    behind fast keys, so Enter straight after typing applied the address before
    the last character, or nothing. Its new optional submitted is sent instead,
    for update to apply linkEdit(document, selection, draft) to the Model's
    own draft.

  • foldkit-mixins-richtext: the link editor asks for a link and closes on
    Escape.
    Its field says "Paste or type a link", Escape in it sends the new
    optional closed, and its button reads Apply rather than Link.

  • foldkit-mixins-richtext: the find bar's Previous, Next, Match case and
    Close are icons
    , named by aria-label and title.

  • foldkit-richtext-dom: a floating element follows its own size. A
    toolbar measured before its styles settled was placed below the selection
    for good, covering the next line; selectionAnchor and blockAnchor now
    place it again when its size changes, as a slash menu's does while a query
    narrows it.

  • foldkit-mixins-richtext: blockStyleMenu. The block styles as one
    trigger naming the current style and a menu of them, the current one
    checked, for a toolbar with other things to hold.

  • A slash menu worth reading, and an icon set. foldkit-richtext-dom's
    SlashEntry gains description, group and icon, and the editor's entries
    have all three; matchingEntries groups the catalogue under / and ranks a
    query's matches, best first. foldkit-mixins-richtext's slashMenuView draws
    group headings, each entry's icon, label and description, and "No matches",
    through new slots, and richTextIcon/richTextIconUrl are the chrome's icons
    (after Lucide, ISC).

  • foldkit-richtext: video, audio and attachments. mediaNodes
    (Video, Audio, Attachment) are opt-in vocabulary, mediaRendering
    draws them with the browser's controls and a download link, and
    mediaBlock(file) makes the block a file's type calls for. A data: source
    is accepted only of the kind's own family, and an attachment's never as HTML,
    SVG or XML.

  • foldkit-richtext-markdown: footnotes. parse(markdown, { footnotes: true })
    reads [^label] and [^label]: … as FootnoteRef and FootnoteDefinition,
    and print writes them back; without the option they are reported and
    skipped, as before.

  • foldkit-richtext: typing at a block's edge leaves a mark that does not
    extend.
    Text typed after a link, inline code or footnote reference that ends
    a paragraph (or before one that starts it) used to join it, since there was
    no neighbouring run to move to; it now gets a run with only the marks that
    extend. resolveInsertion also reaches nested blocks, where it found nothing
    before, so a list item or table cell kept extending such marks.

  • Footnotes. foldkit-richtext declares FootnoteRef and
    FootnoteDefinition for a kit to opt into, reads them with footnotesOf,
    footnoteAt and nextFootnoteLabel, and inserts and renames them with
    InsertFootnote and RenameFootnote (the editor's InsertedFootnote,
    RenamedFootnote); foldkit-mixins-richtext's footnotePreview is the card
    at a reference.

  • foldkit-richtext-dom: a hint on the empty line. lineHint ("Type /
    for blocks") marks the empty paragraph the caret is in with data-hint, for
    a stylesheet to draw as it draws the placeholder. Changed: the host
    registry's placePlaceholder/placeholderFor are placePlaceholders and
    placeholdersFor, holding both strings.

  • A table of contents. foldkit-richtext's outlineOf lists a document's
    headings and sectionAt the section a selection is in;
    foldkit-mixins-richtext's tableOfContents draws them; and
    foldkit-richtext-dom's focus(hostId, selection) Command sends the reader
    into the text with that selection, scrolled into view.

  • Find and replace. foldkit-richtext's findMatches lists a query's
    matches (case not counting unless asked), searchDecorations takes a
    current match drawn as search-current, and Replace replaces one match or
    every one as a single undo step; the editor sends it as ReplacedText, and
    foldkit-mixins-richtext's findReplace is the bar. Changed: search
    ignores case by default; pass caseSensitive: true for the old exact match.

  • foldkit-richtext-markdown: inline markers close as they are typed.
    **bold**, *italic*, _italic_, `code` and ~~struck~~ become
    marked text when the closing marker is typed, and typing on is plain
    (markdownInlineRules, part of markdownInputRules). An input rule can say
    what the next text carries (InputMatch.storedMarks, read by
    resolveInputRules), which the editor keeps.

  • foldkit-mixins-richtext: tableToolbar and codeToolbar. The table
    toolbar adds and deletes rows and columns around the caret's cell, switches
    the header row and deletes the table; the code toolbar picks a code block's
    language and sends the caller's Copy Message. Both draw through slots.

  • foldkit-richtext-dom: Tab, table Messages, adornment actions, a toolbar's
    place.
    Tab and Shift+Tab send Indented and Outdented where
    RichText.takesTab says they mean something, and move focus elsewhere;
    InsertedRow, InsertedColumn, DeletedRow and DeletedColumn carry the
    table commands. An adornment with an action is reported as
    ActivatedAdornment, which edits nothing. blockAnchor({ side: 'above' })
    places a block's toolbar.

  • foldkit-richtext: tables as a grid, and Tab. InsertRow, InsertColumn,
    DeleteRow and DeleteColumn edit the table around the caret's cell, each as
    one undo step (tableAt reads where the caret is). Indent and Outdent are
    Tab and Shift+Tab: indentation in code (and Enter keeps a line's), the next or
    previous cell in a table, a new row after the last, and in a list item, nesting
    it under the item before it or moving it back out. takesTab says where Tab
    means something.

  • foldkit-richtext-dom: an empty line can be reached. It holds a
    <br data-richtext-filler>, where the caret stands, so it has a line's height
    and the arrow keys and a click land on it; before, a new line made with Enter
    had no height and the caret could not get to it. A caret restored onto an
    element, not only into text, is put back.

  • foldkit-richtext-dom: a drag shows itself and scrolls the page. The
    dragged block carries data-richtext-dragging once the pointer moves (and the
    page's root data-richtext-drag, for a grabbing cursor), and a
    pointer held near the window's top or bottom scrolls the page, so a block can
    be dragged past what the window shows.

  • foldkit-richtext: node(…, { lineBreaks: true }), a kind whose text
    keeps line breaks: Enter inserts a newline instead of splitting the block,
    and Enter on an empty last line leaves it for a paragraph after. The
    standard CodeBlock declares it, so Enter in code no longer makes a second
    code block.

  • foldkit-richtext: ClearMark takes a mark value, clearing only the
    runs carrying exactly it, so one discussion's highlight goes without
    another's inside it; the editor's ClearedMark carries either. eachBlock
    and siblingsOf are exported, for an application walking its document.

  • foldkit-richtext-dom: selectionAnchor({ caret: true }) follows a
    caret too, opening under it, which is where a slash menu goes.

  • foldkit-richtext-dom: editorAt(hostId, { slashEntries }), the slash
    catalogue Enter in a query resolves against, so an application's own entries
    (an image, a table) choose as the editor's do.

  • foldkit-remote-server: RemoteServer.memory takes entities, Sources
    for entities no row backs (foldkit-guard's GuardServer.me), served
    beside the rows. One naming an entity the rows' domain declares, or a second
    for the same entity, is refused when the backend is made.

  • foldkit-primitives/dom: FluidHover, a Mount that moves one highlight
    across a container's items: the item nearest the pointer, gaps included, on
    the x, y or xy axis, skipping disabled items and following keyboard
    focus. It writes the item's place as custom properties and sends no Message;
    with gapClick, a click in a gap presses the highlighted item. follows
    lights the item a menu's keys marked, and from names the item a fresh
    highlight grows out of and returns to.

  • foldkit-mixins/theme: Theme.oklch({ neutral: { h } }), a hue for the
    neutrals (surfaces, text, outlines, the shadow) apart from the accent's, as
    shadcn's base colors are; without it they take the accent's and follow its
    knob, as before. The hue is the neutral-h knob.

  • foldkit-mixins/theme: a menu's look, Theme.oklch({ menu: { accent, color } }),
    as shadcn's menu options: the lit row in a tint of the text or the
    accent's fill (bold), and the panel in the page's surface, the other
    scheme's (inverted), or either over a blur (translucent). The popup
    tokens carry it, and the menu, listbox and combobox recipes read them.

  • foldkit-mixins/theme: motion.settle and motion.spring, easings
    sampled from springs, for CSS transitions that spring with no JavaScript:
    settle critically damped, landing exactly, and spring at a damping ratio
    of 0.88 for large surfaces.

  • foldkit-mixins-ui: Card.group and Recipes.CardGroup, cards as one
    keyed list in one column or a grid, divided or apart, with one highlight that
    follows the pointer to the nearest card (FluidHover); a press in a gap
    presses the highlighted card.

  • foldkit-mixins-ui: Recipes.Calendar, the month grid in every mode,
    sized sm or md on the size ladder, for a calendar alone or in a date
    picker's panel. The design-system example uses it in place of its own.

  • foldkit-mixins-ui: Menu, Listbox and Combobox draw themselves.
    Their toView takes draw optionally; without it, upstream's markup is
    drawn from the styled bundles, so a styled menu is
    Menu.toView([MenuStyle.mixin], { h }) instead of forty lines of panel and
    option groups. The forks' default views share the same drawing.

  • foldkit-mixins-ui: Calendar draws itself too. CalendarSlots gains
    header, the row of the heading and its paging buttons, which no upstream
    bundle holds; Calendar.toView(selection, mixins, { h }) draws every mode
    through the slots, and Calendar.draw is that drawing for a toView of
    your own.
    DatePicker.toView's draw is optional the same way.

  • foldkit-mixins-ui: tabs glide. TabsSlots gains indicator and
    highlight, and Tabs.fluid measures the chosen tab and moves one hover
    to the tab nearest the pointer, born at the chosen tab; drawn, the recipe's
    rule or pill springs to a new choice. Until it runs, each tab marks itself.
    FluidHover sets data-fluid-hover on its container while it runs, which
    a recipe reads to draw a highlight in place of each item's own hover.

  • foldkit-mixins-ui: menus, listboxes and comboboxes glide. Menu.fluid,
    Listbox.fluid and Combobox.fluid move one highlight over the open
    panel's rows, for the pointer and the keys alike, and a listbox's or
    combobox's chosen-row marker glides to a new choice. Their slots gain
    rows, highlight and (listbox, combobox) indicator, which the default
    draw places. Segmented.fluid does the same for a segmented control's
    pressed pill, through its new indicator and highlight slots.

  • foldkit-mixins-ui: Item's content is optional, for a row its
    title and description say all of, such as a notification.

  • foldkit-mixins-ui: ChatMessage and MessageScroller. A chat
    message with an author, avatar, time, a sending/sent/failed status with a
    retry and named actions, the user's at the end in a bubble;
    ChatMessage.group draws a sender's following messages as continued. Its
    body wraps with text-wrap: wrap, so a streamed answer never moves a word
    off an earlier line, and a streaming message is aria-busy. Recipe axes
    layout (chat, thread), bubble and content (text, markdown,
    spaced as Prose). MessageScroller is a role="log" in a ScrollArea
    that follows the newest message while the reader is at the end, stops when
    they scroll up, offers a jump button counting what arrived (Appended),
    and holds the message in view as older ones load above; its FollowEnd
    Mount is exported for Scene tests.

  • foldkit-mixins-ui: ThinkingIndicator, ThinkingSteps and
    Questionnaire.
    The indicator is an assistant at work: dots, a pulse or
    the view's icon beside words a band of light sweeps, and a detail line, in
    a polite status drawn always (active: false draws it empty); recipe axes
    mark, label, tone. Thinking Steps is a trace of reasoning and tool
    calls under a button saying the running step or "Thought for 4s", each step
    pending, running, done or failed, in words too, with a duration, detail
    and steps of its own (onToggleStep); its openness is an Option the
    application keeps, none following the work. ThinkingSteps.stateOf,
    shown, elapsed; axes variant, connector. The Questionnaire asks
    single choice, multiple choice and free text questions, with an "Other"
    field, all at once or one at a time; update says what is missing and
    focuses it, and returns OutMessage.Answered once all are answered.
    Question is a Schema, so an assistant's tool input decodes into it; axes
    variant, actions.

  • foldkit-mixins-ui: AngleSlider, Timer and Marquee, after Zag's.
    A dial in degrees dragged round or stepped by the APG's slider keys, which
    go round past 0, with step, largeStep, labelled marks,
    restrictToMarks, read-only, invalid and a hidden input (recipe tone,
    track, value, size). A countdown or stopwatch started, paused,
    resumed, reset and restarted, its clock read by Commands on Effect's
    Clock so TestClock drives a run, a role="timer" with each unit in a
    Slot; Timer.phase, Timer.partsOf (recipe tone, look, progress,
    size). Content that scrolls on without a seam: measured copies filling
    the viewport, a speed in pixels a second, four sides, a delay and a round
    count, held by a pointer, by focus or by its pause press (WCAG 2.2.2), its
    copies inert, and still under reduced motion (recipe spacing,
    edges).

  • foldkit-mixins-ui: ImageCropper and SignaturePad, after Zag's. A
    crop of an image that a drag moves and eight handles resize, zoomed by a
    Slider, the wheel and +/- with the selection kept on screen, panned,
    turned by quarters, locked to an aspect or round; the crop is the Model's
    in the turned image's pixels (ImageCropper.crop), and RequestedExport
    returns the Export Command answering Exported({ url, width, height })
    or FailedExport (recipe guides, handles, viewport). Strokes drawn
    by one pointer, a pen's pressure used and a mouse's simulated from speed,
    kept as data and drawn as smoothed variable-width outlines (pathOf),
    with undo, clear, "Sign here" and a typed name instead; toSvg is pure
    and RequestedPng returns ExportPng (recipe surface, size).

  • foldkit-mixins: a chart group in Theme.oklch. chart-1 to
    chart-5, as shadcn names them: the dataviz reference palette's first five
    slots in its order, each a fixed turn from the chart-h knob at a
    lightness and chroma set per hue and per scheme.

  • foldkit-mixins-ui: QrCode and Chart. QrCode.view draws text as
    one SVG path in a quiet zone, one image named by what it encodes, with an
    overlay (a logo) that raises the level from M to H; QrCode.encode and
    pathOf are pure, QrCode.Download saves the drawn code as PNG or SVG
    in its colors, and the recipe draws it dark on light on any page
    (scheme, size). Encoded by uqr, now a dependency. Chart.view draws
    bars, a line, an area or a donut with round ticks, gridlines, a legend and
    a tooltip, in percentages, so it fills any width with nothing measured and
    renders the same on a server; Chart.Model holds the lit point, the
    arrows, Home and End step through the points while a status says each,
    and the data is a table, hidden unless table: 'shown'. Series take
    chart-1 to chart-5; recipe axes height, grid, indicator.

  • foldkit-mixins-ui: CascadeSelect, FloatingPanel and Tour. One
    value chosen as a path through nested options (CascadeSelect.update({ nodes })) from a top-layer APG tree with a column per level or one level
    at a time (layout: 'drill'), the arrows within and between levels,
    Home, End and a letter, expandOn: 'hover', parents, clearable,
    levels and a hidden input (recipe size, trigger, width). A
    non-modal window whose rect and stage are its Model: dragged, resized
    from eight edges within the viewport, min, max and a grid, moved and
    resized by the arrows, minimized, maximized, restored and closed, stacked
    by an order its Raised OutMessage updates (FloatingPanel.raise;
    recipe header). A tour of steps beside their targets in the top layer,
    over a dim with a cutout the target's presses reach, the target scrolled
    into view, Next, Back, the arrows, Skip and Escape, focus back to the
    opener and Ended { completed } at the end; a step without a target, or
    with a missing one, stands in the middle.

  • foldkit-mixins-ui: Anchor.layerBox, the top-layer box layer
    draws, without its TopLayer Mount, for a box whose own Mount shows it
    through topLayer.

  • foldkit-primitives/dom: PointerPosition({ focus? }), a Mount
    reporting one pointer's press, moves (with coalesced points and pressure)
    and release in the element's padding box, captured, with move listeners
    only during a press; paddingBoxOf({ rect, border }) and
    measurePaddingBox(element). In foldkit-mixins-ui the color picker's
    area, the angle slider's dial and the signature pad read the pointer
    through it (no API change).

  • Site: pages for every component above.

Changed

  • foldkit-mixins-ui: the Calendar's resolved days and a Segmented tray
    (breaking).
    ResolvedDays' paging buttons are Options and its heading
    is a caption (Grid, Label or Dropdowns); toView, inputs and
    resolve take an options object fourth, render among them. A Segmented
    tray is as wide as its options, not its container (width: 'fill' for
    the old strip). A tab is a flex row: draw its words in the label slot to
    keep their trim.

  • foldkit-mixins-ui: the Tooltip takes its id; the Toast recipe drops its
    accent edge (breaking).
    Tooltip.toView and Tooltip.resolve take the
    Tooltip's id, which the arrow points from.

  • foldkit-mixins-ui: Select's chevron and the display slots (breaking
    for hand-drawn slots).
    The native Select draws its own chevron and
    mutes a chosen placeholder. AvatarSlots gains status, and the
    avatar's root is one role="img" named by the person, its picture's alt
    empty. SeparatorSlots gains root and label, the line a border in
    outline.default. SkeletonSlots gains group, a bar a film of the
    text. SpinnerSlots gains part, root and text, a turn about 720ms
    times travel. ItemSlots gains overlay. Empty's title takes the
    subtitle role and its icon is aria-hidden.

  • foldkit-mixins, foldkit-mixins-ui: hovers take their surface’s paint,
    not grey.
    unfilledHover films the state ink instead of the text: the
    theme's --fk-state-ink (state.ink), unless a surface painted in a hue
    writes its paint in the local --_fk-state-ink, so a hover on a painted
    surface deepens the paint. The accent and danger tones name their fills, a
    subtle alert band its ink (its tint would film the band over itself) and a
    bold one its fill; the neutral and ink tones name the theme's ink back, so
    a neutral control on a band keeps the theme's hover. New
    OklchKnobs.stateHue sets the theme's ink, and one override reaches every
    component, neutral ghost and outline buttons, radios, sliders and toggles
    included: neutral (today: the text, with painted surfaces naming the text
    too through the derived surface-ink knob, which a scoped override also
    switches at runtime), surface (the default: the text, and surfaces name
    their paint), accent (the accent's ink, so hovers lean on the accent). A
    var() substitutes where the token is declared, so the state tokens
    themselves stay text-based; the ink travels as its own property, read where
    the film is drawn.

  • foldkit-mixins-ui: in-place menu, listbox and combobox panels draw in the
    top layer.
    Anchor.topLayer wraps an upstream anchor Mount when its config
    says portal: false: it shows the panel as a manual popover around the
    Mount’s own acquire and hides it once that Mount releases, keeping the
    Mount’s name, args and Messages, and does nothing on an element without the
    popover attribute or where the popover API is missing. Those panels carry
    popover="manual" and inset: auto (the anchor writes only left and
    top, and the browser's inset: 0 opened them at the viewport's far edge
    right to left); no stacking context or ancestor overflow reaches them,
    and the anchor positions them as before. The Menu's submenus and the
    Menubar's menus are drawn this way too. An unstyled panel keeps the
    browser's popover border, padding and Canvas fill, which every recipe
    replaces. Panels that relocate through an upstream portal keep upstream’s
    behavior, since moving a shown popover hides it again. The popup recipes
    take a width axis: trigger replaces the panel's 14rem minimum with its
    trigger's width (min-inline-size: var(--button-width, 14rem)), the
    default for Combobox, and auto keeps it, Listbox's default. Popover,
    Tooltip, Hover Card and DatePicker panels, modal <dialog> and arrows stay
    where upstream draws them until upstream owns top-layer mounting (their
    Mounts attach inside upstream views).

  • foldkit-mixins-ui: a Menu component, by a button, at a point, or
    down a submenu, over the Menu adapter.
    Menu.init(id, rows, { isAnimated?, isModal? }) (a row with items hosts a submenu, one level
    deep; isAnimated marks the menu's and its submenus' panels for the
    recipe's fade), folded with Menu.update, drawn with Menu.view({ model, rows, buttonContent, onMessage, opensAt?, direction?, isRowDisabled?, mixins, submenuMixins? }, h), the style one of its mixins. opensAt: 'point' with Menu.target(onMessage, h) on the area is the context menu:
    a right press records its point and the contextmenu after it opens the
    menu there. Selected names the value and the submenu it came from.
    Menu.fluid glides the highlight; Menu.overlayBars draws the overlay
    bar. The panel adapter (Menu.toView, Menu.resolve) stays for a
    @foldkit/ui Menu the application folds itself, for typed items or
    groups, and Menu.drawAtPoint(point, h) as its draw with
    Menu.pointTarget({ onPress, onOpen }, h) on the area opens one at a
    point (give its anchor gap: 0). MenuSlots gains label, sub and
    chevron, and scrollBar and scrollThumb drawn while a panel has a
    scroll. One recipe, one pattern, one gallery page.

  • foldkit-mixins-ui: one date system: Calendar.Selection.
    Single, Range or Multiple, owned by the application
    (Calendar.empty(mode); fold each SelectedDate through
    Calendar.picked, which orders a range's ends; Calendar.isComplete
    says when a picker may close). Draw inline by spreading
    Calendar.inputs(selection, mixins, { h }) into upstream's view inputs:
    its toView (Calendar.toView(selection, mixins, { h })) marks each
    chosen day (data-range-start, data-range-end, data-in-range on a
    range's band), the grid of a Range or Multiple selection is
    aria-multiselectable, and its maybeSelectedDate agrees with the marks.
    In a popover, DatePicker.update(selection) keeps the panel open while
    the day leaves the selection unfinished, and DatePickerView.view takes
    selection and triggerContent(selection) in place of
    maybeSelectedDate; under name each chosen day is a hidden input of its
    own, so FormData.getAll(name) reads a range's [start, end]. The
    gallery's Calendar and Date picker pages show one day and a range.
    Breaking: Calendar.toView takes the selection first.

  • foldkit-mixins-ui: one Slider, for a number or a { low, high }
    range.
    Slider.view({ id, label, value, onChange, … }, h) takes either
    kind, and onChange is handed the same kind. Both are native
    input type="range" thumbs, so the drag, the keys, right to left and the
    form value are the browser's: one number is a thumb across the whole
    track, named by the label; a range is two thumbs in a group, each bounded
    by the other (Slider.moved snaps, bounds and orders a range, as the APG's
    multi-thumb slider). marks dot values on the track (data-filled where
    the fill covers them) and showValue draws each value, both hidden from
    assistive technology. Recipes.Slider serves both, in Fluid
    Functionalism's look: track: 'thick' (the default, the fill reaching
    each thumb's far edge) or 'thin', and value: 'above' or 'inside' (a
    pill thumb). Patterns.Slider is the pattern. Breaking: @foldkit/ui's
    Slider is no longer adapted (Slider.resolve, Slider.toView and
    ResolvedSlider are gone, and SliderSlots is the new view's, with slots
    root, label, control, track, fill, mark, value and
    thumb); an application hosting that Submodel draws it with Slots of its
    own. orientation: 'vertical', ticks, labelled marks ({ value, label }) and the recipe's value: 'end', track: 'paint' and label: 'hidden'
    are the view's too; upstream's Escape-to-cancel and read-only mode are
    lost.

  • foldkit-mixins-ui: one Alert, inline or a banner. Alert.view takes
    layout: 'inline' (a live region for something that just happened:
    role="alert" when assertive, role="status" otherwise) or
    layout: 'banner' (a full-width strip there on load: a section landmark
    named by label, never a live region). Both take an optional icon, now
    aria-hidden, a title and description, actions (each a link or a button
    that sends a Message) and a dismiss button (onDismiss, dismissLabel).
    The root writes data-layout and data-dismissible, and the banner keeps
    room for the dismiss button only when it has one. Recipes.Alert gains
    an emphasis axis (subtle, the default, or bold) and the slots
    actions, action and dismiss; Patterns.Alert is the pattern, and
    the gallery's Alert page shows both layouts. Breaking: layout is
    required (write layout: 'inline' where an alert stood alone).

  • foldkit-mixins-ui: Menubar, Menu, TreeView, Resizable and a
    horizontal Listbox take direction?: 'ltr' | 'rtl', and under 'rtl'
    ArrowLeft and ArrowRight swap.
    A view cannot read the page's direction,
    so these components moved the wrong way right to left: a submenu opened on
    ArrowRight away from where it was drawn, and a split's handle grew the
    panel the arrow pointed away from. Each view now translates the two arrows
    before building its Message (as Zag's getEventKey does), so Messages and
    update stay in reading order, and draws the direction as its root's
    dir, so the CSS reads what the keys read; the Menu's submenu opens on
    the left with its chevron pointing there, and Resizable reverses a drag's
    horizontal movement. Tabs, RadioGroup and Calendar, whose arrows upstream
    bundles handle, take Tabs.readingKeys, RadioGroup.readingKeys and
    Calendar.readingKeys beside the style: a Mount that reads each arrow by
    the element's :dir() before upstream's handler does, opt-in because a
    Scene test must resolve every Mount with a Message. Segmented.fluid,
    Tabs.fluid and Nav.fluid measure their indicator again when a dir
    changes.

  • foldkit-auth, foldkit-ssr: a request with no Origin is taken by
    Fetch Metadata.
    AuthServer.resolver and SSR.entry's origins read
    Sec-Fetch-Site: same-origin in place of a missing Origin (a
    same-origin GET), as they already did for Origin: null, and still
    refuse a request with neither. The auth README says why the check rests on
    the origin rather than on SameSite or a token.

  • foldkit-mixins-ui: toggles on the ladder, and Fluid's switch. A
    checkbox, radio or switch with no size stands on the ladder's icon rung
    (16px, 14px compact) instead of defaulting to md. The switch is a 34×20
    track with a 16px thumb (its height a quarter over the toggle's edge, its
    track 1.7 of that), and its thumb stretches 2px into a pill under the
    pointer, growing back from the far end when on. Breaking: an unsized toggle
    no longer means md, and the switch is larger than its old 29×16.

  • foldkit-mixins-ui: an icon, a dialog and a tooltip on the systems. An
    Icon with no size stands on the size ladder (16px, 14px compact) instead of
    defaulting to md; a dialog is one notch narrower in a compact region (10%,
    as Fluid Functionalism's 400px to 360px); and a tooltip drawn with
    isAnimated fades in on the fast tier, sliding 4px toward its trigger from
    the side it opens on. Breaking: Recipes.Icon({}) no longer means md.

  • foldkit-mixins/theme, foldkit-mixins-ui: states as tints, and
    concentric corners.
    Theme.oklch gains a state group, what a state lays
    over the surface under it as a mix of the element's own text color
    (hover, the see-through tint and tint-hover, and edge, a hairline
    inside an image), with its amounts as knobs; and Theme.nested(outer, inset, border?) gives the radius of a surface inset in another. The menu,
    popover, pagination and calendar hovers read state.hover instead of the
    muted surface, which vanished on a page of that surface; the neutral button
    is see-through; avatar and card images carry the edge; and a popup's rows,
    a segmented option and a pill tab round concentrically inside their
    container. Breaking: a popup's panel has the xl radius, and the recipes
    read state.*, which a palette made without Theme.oklch must define.

  • foldkit-mixins/theme, foldkit-mixins-ui: six type roles. A type
    token group and Theme.role(name): display, title, subtitle, body,
    caption and micro, each a size and a whole-pixel leading that step with
    the size ladder, after Fluid Functionalism's (body at 14px on 20). The
    recipes set text by role (controls body, badges and tooltips caption,
    keycaps micro, dialog titles title), tab and segmented labels are
    trimmed to their capitals, a field's text is 16px on a coarse pointer
    so iOS does not zoom into it, and Typography takes the roles as levels.
    Breaking: control.text is gone (read Theme.role('body')), and dialog,
    empty-state and card titles are smaller.

  • foldkit-mixins/theme, foldkit-mixins-ui: one size ladder. After
    Fluid Functionalism's: a control token group holds the two ends (36px and
    28px controls, with their padding, gap, inset and icon), a step knob
    chooses between them, and Theme.ladder(name) writes the blend, read 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
    (portal: false). Buttons, fields, selects, tabs,
    segmented controls, table rows, calendar cells and the rows of a menu,
    listbox or combobox all stand one rung tall, so a popup's row lines up with
    its trigger. Breaking: a recipe's size only sets the step on its own
    element (sm compact, md default, lg a half step up at 40px), and no
    recipe defaults it any more, so an unset size follows the region. The
    popups' size sets it on their wrapper and their panel (which upstream
    portals by default), Tabs' on the tablist.
    Segmented's sizes are md, sm and xs (24px).

  • foldkit-mixins/theme: three motion tiers, and reduced motion keeps the
    fades.
    motion.fast, moderate and slow are 80, 160 and 240ms, each with
    an exit a tier quicker (fast-exit, moderate-exit, slow-exit, eased by
    ease-exit), after Fluid Functionalism's springs. A travel knob multiplies
    the durations of what moves or resizes, and Defaults.reset sets it to 0
    under prefers-reduced-motion instead of zeroing every transition, so a
    highlight snaps to its row while its fade still plays. The recipes' gliding
    overlays share one transition (hover on fast, a chosen marker on
    moderate), and the switch's thumb travels on moderate. Breaking:
    motion.normal is gone (read moderate, or slow for a loop's period), and
    a transition of a transform written outside the recipes no longer snaps
    under reduced motion unless it multiplies by knob.travel.

  • foldkit-mixins/theme: the surface contrast knob reaches 2.5 times as
    far, and defaults to 26%.
    At its top it moved a muted surface four points
    of lightness, which read as doing nothing; the default look is the one 65%
    drew. Breaking: a theme that sets surfaceContrast divides it by 2.5 to keep
    its look ('60%' is '24%').

  • foldkit-mixins/theme: radius.full squares off where radius-factor is
    0
    , as a boxy theme's pills should; at any other factor it is a pill.
    Recipes.Badge rounds by radius.xl, so the radius knob reaches it, and
    Recipes.Avatar is a disc at the default factor, rounder squares below it.

  • foldkit-remote-server: RemoteServer.memory's principal is optional
    for every principal type.
    It is only who layer answers as: without it,
    and with a principal type that does not admit undefined, the backend is a
    MemoryServed (its store and server, no layer), for serving through
    serveFetch or handlers as each request's principal. Code that omitted it
    for such a type used to fail to compile; it now has no layer to call.

  • foldkit-mixins-ui: Card is pressable, selectable and dismissible.
    press ({ onClick } or { href, external? }) stretches one button or link
    over the card, named by label or the title; selected, disabled,
    dismiss, an image and a media tile are new, content is optional, and
    the view takes the application's Message. Breaking: action sits at the end
    of the header rather than the footer, so a card that put its button in
    action puts it in footer. The recipe adds orientation (stacked,
    inline) and surface (outlined, elevated, filled, plain) axes and a
    compact padding, and its padding is one private --_fk-card-pad.

  • foldkit-mixins-ui: DatePicker.toView(mixins, draw) hands draw the
    date picker's builder.
    Breaking: it took a context with a builder, which an
    application had no way to give for the date picker's own Message;
    DatePickerView's toView input is called with that builder too.

  • foldkit-mixins-ui peers on foldkit-primitives, for Card.group's
    highlight.

  • foldkit-mixins-ui's stateless views take the application's builder.
    Alert, AspectRatio, Avatar, Badge, Breadcrumb, ButtonGroup,
    Empty, Icon, Item, Kbd, Label, ScrollArea, Separator,
    Skeleton, Spinner, Table and Typography are generic in the Message,
    where they took HtmlBuilder<never>, so what they hold can send one: an empty
    state's button, a badge in a pressable card. A call with no Message is
    unchanged.

Fixed

  • foldkit-mixins-ui: an unknown Progress holds still under reduced
    motion.
    The reset runs every animation for 0.01ms there, so the ring's
    quarter arc stood at a random angle each frame, and the bar's sweeping
    fill stopped near its last frame, mostly outside the track. The ring now
    stands still, as a Spinner's does, and the bar's fill rests faint across
    the track, as it does with no travel. Moving stripes, which slid at
    random the same way, stand still too.
  • foldkit-mixins-ui: a loading Toast's ring holds still under reduced
    motion.
    It breathed instead, and the reset's 0.01ms made the breath
    flicker; it now stands still, as every loading ring does.
  • foldkit-mixins-ui: the Questionnaire's "Other" label reads as an
    option.
    The other field's label was the Input's, which a text answer's
    question also uses, so it looked like a question heading. Its words are now
    in a new otherLabel Slot, which the recipe draws as the options' labels.
  • foldkit-mixins-ui: Cascade Select's columns stay on a phone's screen.
    At 390px the popup's columns ran past the window's edge. When the popup
    opens, PlaceCascade measures whether a column per level of the deepest
    path fits the window, and the columns layout drills in when it does not
    (the Model's new cramped, sent as Placed({ cramped })). The panel is
    capped to the window too, so one narrowed while open scrolls its columns.
  • foldkit-mixins-ui: the Angle Slider's needle clears the value in the
    middle.
    It ran from the center to the thumb, straight through "45°" or
    "1 of 4"; it now stops 2em of the value's type short of the center, and
    runs to the center only when the value is drawn below the dial.
  • foldkit-mixins-ui: the Image Cropper shows its image. The recipe hid
    the image under any ancestor without data-ready, body included, so it
    stayed hidden after loading; the image now carries the mark itself.
  • foldkit-mixins-ui: Steps and the Navigation menu at a phone's width.
    In a narrow Steps row the current title ran over the next connector; it
    is now cut with an ellipsis, and the connectors shorten so a short word
    stays whole. A dot marker's dot sat above its connector, pushed up by the
    hidden number's row. A Navigation menu trigger's chevron, squeezed in a
    narrow row, drew as a slanted tick; it keeps its size. A panel's groups,
    a fixed row of 12rem columns, ran off a phone's screen; they wrap.
  • foldkit-mixins-ui: the Popover's arrow can be seen. It was drawn,
    but as an 8px square in the panel's own fill and faint line, half of it
    showing in the gap: a nub too slight to see. The Popover's arrow is now
    space.sm across (arrow's new size) and its panel 12px off the
    trigger, so the arrow crosses most of the gap.
  • foldkit-mixins-ui: TagsInput keeps keys typed fast out of the tag just
    added.
    Keys typed before the emptied input was drawn joined the tag
    Enter had just added.
  • foldkit-mixins-ui: display fixes in a dark scheme. A chosen card and
    a Card Group's highlight no longer read as sunken; a card's "New" badge
    sits on its title's line; a Separator and a Skeleton show on a dark page.
  • foldkit-mixins-ui: rows, pills and highlights follow their container's
    corner.
    A menu's, listbox's or combobox's highlight and chosen marker,
    a Command's rows, a Menubar's triggers, a Segmented option's pill and
    hover, and a pill Tabs' chosen pill and hover kept a fixed radius that did
    not meet the panel or tray around them. Each container now publishes its
    corner with Theme.nests, and they read Theme.nested().
  • foldkit-mixins-ui: InputCopy's focus rings follow the group's corners.
    The input's and button's inset rings were square inside a rounded group
    that clips, so their outer corners were cut off; they now round those
    corners to the group's inner radius.
  • foldkit-mixins-ui: Steps line up, and fit a phone. Each step's text
    was centered on its marker, so a step with a description stood its title
    higher; titles now start on the marker's middle line, and the connectors
    sit on that line too. A horizontal row takes its container's width and,
    below 32rem of it, shows only the current step's label (the others stay
    for a screen reader), where every label had overlapped the markers.
  • foldkit-mixins-ui: Pagination fits a narrow row. At 390px "Previous"
    ran into the "1" beside it; the row now wraps and centers, and Previous
    and Next have room either side.
  • foldkit-mixins-ui: an Alert stacks its title over its description.
    Side by side, a narrow alert squeezed its title into a column of single
    words. The icon keeps its own column beside both.
  • foldkit-mixins-ui: a Hover Card no longer moves its trigger. The
    Anchor writes top and left but no position, so an unportaled card
    stood in the line beside its trigger and the centered row shifted; the
    anchored placement now takes the panel out of the flow.
  • foldkit-mixins-ui: a Segmented option's words sit centered. The
    text-box trim on the option ended at the hidden semibold copy after the
    words, its last line, so only their top was trimmed and they stood 2.5px
    high. Segmented.view now draws the words in a new label Slot that
    holds the trim; an option drawn by hand with a data-label should do the
    same.
  • foldkit-mixins-ui: smaller centering fixes. The Checkbox's check
    sits a pixel lower, on center, and is placed physically like its sides;
    a Kbd's line is trimmed to its capitals with the height given back as
    padding; a radio centers on the first line of a label beside it in a row
    aligned to its top (calc((1lh - edge) / 2)).
  • foldkit-mixins-ui: Progress's indeterminate bar sweeps right to left
    under dir="rtl".
    The fill starts at the inline start but moved by a
    physical translate, so right to left it appeared mid-track and slid off
    the wrong side; a mirrored keyframe now runs under :dir(rtl), with the
    same timing, so reduced motion still holds it still.
  • foldkit-mixins-ui: the Switch works right to left. Its thumb starts
    at the inline start but moved by a physical translate, so right to left
    it slid off the far side; it now moves left there.
  • foldkit-mixins-ui: the RadioGroup recipe stacks a vertical group. The
    group was a row whatever its aria-orientation, and upstream's groups are
    vertical by default; it is now a column unless aria-orientation is
    horizontal. The README and the skill now say to draw each option as a
    label around its radio, since upstream's label bundle carries only an id
    and a bare label took no press (the gallery's did not).
  • foldkit-mixins-ui: a Skeleton bar shows in a container that sizes to
    its content.
    Its inline-size: 100% resolved to nothing there (a
    centered column, a flex item), so the bar computed 0px wide and the
    gallery's skeleton showed nothing. A bar now has a 4rem floor.
  • foldkit-mixins-ui: chevrons point the right way right to left. The
    Accordion's, Sidebar's, TreeView's and Menu submenu rows' chevrons and the
    Carousel's arrows drew their two sides with logical borders, which mirror
    under dir="rtl", so a shut row's chevron pointed up and the arrows
    pointed up and down. They and the Steps check now share cornerSides
    (physical sides), and the Sidebar gains the right-to-left turn it lacked.
  • foldkit-mixins-ui: a Sidebar section's links and a TreeView group's
    rows hold still while they open.
    The heading row stretched into the room
    the opening grid left mid-transition, so the rows below it dropped (about
    16px in the Sidebar) and rose back.
    Sidebar and TreeView now share one opensBelow piece that keeps rows at
    the top (align-content: start).
  • foldkit-mixins: injected styles keep the page's layer order. The
    <style> a draw injects carries the page's own @layer order first. It
    carried none where the page had one, so once it stood ahead of the page's
    sheet (a test's or an application's sheet put in after it), its
    @layer components { … } made components the first layer, under the
    reset, and a button's text fell back to the reset's 16px.
  • foldkit-mixins-ui: a badge squeezed in a row keeps its words inside it.
    The page reset floors every element's min-width at 0, so a badge in a
    narrow row shrank under its unwrapped text, which ran into the next one.
  • foldkit-mixins-ui: Recipes.Dialog centers the open panel. @foldkit/ui
    draws the open dialog over the whole viewport, so the panel sat at its top.
  • foldkit-mixins-ui: Recipes.Slider keeps a track wide enough to drag
    (12rem at least) in a row or a centered box, where it shrank to its label.
  • foldkit-mixins-ui: a menu, listbox or combobox marks the row the keys
    are on.
    The shared popup row styled only :hover, so moving by the keys
    showed nothing; it now reads upstream's data-active, and the focused panel
    draws no browser ring around itself. A row's hover is a tint of its text, which
    reads in a dark scheme, where the muted surface was all but the panel's own.