KQ-1621 · CURTAIN/COUNT
Curtain Count
A full-frame loading screen over its own box in five variants driven by one progress value, which the readout follows on springs.glide: a counter whose odometer wheels rest on their digits and roll on the carry beside a filling rule, the brand word filling with colour from its baseline, five stacked bars filling over overlapping windows of the load, a split frame whose field inverts the giant percentage where its edge crosses, and a radial wipe with a clock hand riding its edge. All five end the same way: at 100 % the curtain holds a beat and says Ready, its seams crack open on springs.flick, and two halves, vertical slats or horizontal bands lift out of the box on the exit ease in a cascade while the page beneath settles from a hair's scale on springs.glide. There is nothing to press: the page is inert and marked busy until it is revealed, and one progress bar carries the value for assistive technology.
Fieldline · autumn page
Holding the stage
Autumn 2026
Field notes for the season
Walks, maps and tide tables for the shortening days, gathered by people who were out there.
Salt marsh walks
Six routes at low tide
Orchard maps
Where the late pears are
loading · 0% · counter
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/curtain-count
Props
- progress
- number
- default 0
- How far the page has loaded, 0 to 1. At 1 the curtain holds a beat, then splits and lifts away; below 1 again, it falls back in.
- variant
- "counter" | "word" | "bars" | "split" | "radial" | number
- default "counter"
- Which way to hold the stage, by name or by its place 1–5 in that order.
- exitMotion
- "split" | "slats" | "shutter"
- default "split"
- How the frame leaves: two halves parting at the centre, vertical slats from the centre out, or horizontal bands from the top.
- accent
- string
- default "var(--accent-bright)"
- The fill colour, any CSS colour, taken at a lightness that reads on the curtain.
- children
- React.ReactNode
- default —
- The page beneath, inert and marked busy until the curtain has gone.
- brand
- string
- default "Fieldline"
- The brand on the curtain, and the word the word variant fills.
- caption
- string
- default "Loading the season"
- A line of copy on the curtain; it reads Ready at 100 %.
- stages
- readonly string[]
- default ["Fonts", "Pictures", "Routes", "Data", "Scripts"]
- Labels for the bars variant's five bars.
- label
- string
- default `Loading ${brand}`
- Names the progress bar for assistive technology.
- hold
- number
- default 280
- How long the curtain holds at 100 % before it splits, in ms.
- exitDuration
- number
- default 680
- How long each part takes to lift away, in ms; the cascade adds to it.
- slats
- number
- default 6
- How many slats or bands the slats and shutter exits cut the frame into, 3 to 10.
- curtainColor
- string
- default "var(--foreground)"
- The curtain's colour.
- inkColor
- string
- default "var(--background)"
- The type on the curtain.
- onRevealChange
- (revealed: boolean) => void
- default —
- Fires when the curtain has fully lifted (true), and when it falls back over the page (false).
- className
- string
- default "h-full w-full"
- Sizes the box; the curtain fills it. Give it a height.
| Prop | Type | Default | Description |
|---|---|---|---|
| progress | number | 0 | How far the page has loaded, 0 to 1. At 1 the curtain holds a beat, then splits and lifts away; below 1 again, it falls back in. |
| variant | "counter" | "word" | "bars" | "split" | "radial" | number | "counter" | Which way to hold the stage, by name or by its place 1–5 in that order. |
| exitMotion | "split" | "slats" | "shutter" | "split" | How the frame leaves: two halves parting at the centre, vertical slats from the centre out, or horizontal bands from the top. |
| accent | string | "var(--accent-bright)" | The fill colour, any CSS colour, taken at a lightness that reads on the curtain. |
| children | React.ReactNode | — | The page beneath, inert and marked busy until the curtain has gone. |
| brand | string | "Fieldline" | The brand on the curtain, and the word the word variant fills. |
| caption | string | "Loading the season" | A line of copy on the curtain; it reads Ready at 100 %. |
| stages | readonly string[] | ["Fonts", "Pictures", "Routes", "Data", "Scripts"] | Labels for the bars variant's five bars. |
| label | string | `Loading ${brand}` | Names the progress bar for assistive technology. |
| hold | number | 280 | How long the curtain holds at 100 % before it splits, in ms. |
| exitDuration | number | 680 | How long each part takes to lift away, in ms; the cascade adds to it. |
| slats | number | 6 | How many slats or bands the slats and shutter exits cut the frame into, 3 to 10. |
| curtainColor | string | "var(--foreground)" | The curtain's colour. |
| inkColor | string | "var(--background)" | The type on the curtain. |
| onRevealChange | (revealed: boolean) => void | — | Fires when the curtain has fully lifted (true), and when it falls back over the page (false). |
| className | string | "h-full w-full" | Sizes the box; the curtain fills it. Give it a height. |