
250 ml · rust glaze
Kiln 2.7.3
16 sections, 23 primitives and 56 tokens in two modes, shown once each at real size. Eleven of the primitives are the repository's own component library, refined here and vendored unedited.
Every swatch is painted by a semantic utility, so this panel follows theme.css instead of repeating it.
Aa
--background
--foreground
Aa
--card
--card-foreground
Aa
--muted
--muted-foreground
Aa
--secondary
--secondary-foreground
Aa
--accent
--accent-foreground
Aa
--primary
--primary-foreground
--primary · -hover · -active
--input-border · 3.0+ everywhere
--shadow-color · warm, never black
--radius · 0.375rem, plus pills
--border · hairline
--ring · focus outline
--surface-tint · quiet hover
src/fonts.ts
Three shipped faces, self-hosted under OFL: Newsreader for display, Karla for text and UI, and Spline Sans Mono for prices, SKUs and dates. The display ladder steps by 1.333 from 1.5rem; tracking belongs to the step, not to the author.
src/components/ui/
Button, ButtonLink, Badge, Eyebrow, Container, the KilnMark, the mode toggle, and the field family every Kiln form is built from, in each state a shop actually reaches. The cart is a sheet now — it is in the header above and it has its own frame below; the store behind it is ui/cart-store.
primary
secondary
ghost
Whitstable, Kent
Unsubscribe from any email in one click
That address is missing an @. Check it and send it again.
Set when the order was placed
We post within the UK while the studio is two people
Written on a card and tucked in beside the wool
Container · prose 48rem / default 72rem / wide 80rem
Escape, the focus trap, the focus return, the scroll lock, the roving keyboard models and every ARIA graph below come from ui/ at the repository root and are vendored, unedited, into src/components/ui/_tt/. Every class string, every glyph and every word on this page is Kiln's, in the file beside each frame.
src/components/ui/accordion-disclosure.tsx
The returns questions, the product specs and the cart's gift note. Native <details>, so the answers are in the page a crawler reads and the row opens before hydration.
Enter and Space open a row. Escape inside an open answer closes it and puts focus back on the question — the one thing <details> does not do.
closed
Email us within thirty days and we send a prepaid label back.
Photograph the box and the piece and email us.
open
Yes, within thirty days, for anything in the current batch. Ash comes back at the next firing, so it is usually the one we cannot swap to.
Anything that has been used. A mug that has held tea is yours.
Under prefers-reduced-motion the 250ms height tween is off and the answer is simply there.
src/components/ui/sheet-drawer.tsx
The cart and the narrow-width nav, which through 2.6.0 were two hand-written panels drawn as sheets with no role, no trap and no Escape.
Enter and Space open it. Tab is held inside the panel, the page behind stops scrolling, the scrim closes it, and Escape hands focus back to the control that opened it.
default · the panel, no layer
3 pieces · £146.00
Delivery is free over £60
side · left, the narrow-width nav
live · the real layer
Sizes sm 18rem · md 24rem · lg 30rem, measured from the edge it arrives on. Open 400ms, close 350ms, 16px and a fade; under prefers-reduced-motion it is gone on the same tick focus returns.
src/components/ui/quantity-stepper.tsx
One control for a quantity, in the cart and on the product page. The figure is a real number input: it posts, the browser clamps it, and six is two keystrokes.
Up and Down step it. A typed figure commits on blur or Enter; an emptied field falls back to the last good value, never to one.
default
2 Ridge tumbler in your cart
min · the floor
1 Ridge tumbler in your cart
max · the whole firing
6 is all there is from this firing
The bound is spoken by the readback, not written on the dead button: a disabled control is out of the tab order and its description is a sentence nothing reads.
disabled · a sold-out line
src/components/ui/variant-selector.tsx
The glaze axis on the product page: native radios in a fieldset, so the choice posts with no script at all.
One tab stop for the group. Arrow keys move and select; an option that is out is skipped, and its reason is inside its own label.
default · all three in the batch
disabled · one out, with its reason
An option with `disabled: true` and no note is a compile error, not a review comment.
src/components/ui/rating-input.tsx
The rating a buyer sets, in the review form under the quotes. Whole marks only — a half-mark input is a pointer gesture a keyboard cannot reach.
One tab stop. Arrow keys move and select; the first option is No rating, so ArrowLeft from one star takes the rating back off.
default
empty · what the form opens as
disabled · already sent
The five is still the checked radio, so it is what a screen reader reports; the marks do not draw their fill while the group is off, because the part writes one data-state for both facts. Reported to the library.
src/components/ui/filter-chip.tsx
The collection browser's active-filter receipts. The value is text and the control is named for the value, so what a buyer reads is what a screen reader hears.
Removing a chip moves focus to the control that set the filter — a node that survives the removal — before the chip goes.
default
row · where a chip is seen
src/components/ui/search-input.tsx
The shelf search, over name, piece family and glaze. A real type=search with a persistent label — never a placeholder standing in for one.
The clear control returns focus to the field before it empties the value, so the button that vanishes never takes focus with it.
rest
6 pieces shown
filled · the clear appears
1 piece shown
no-result · the query is kept
0 pieces shown
Nothing on the shelf matches teapot.
disabled
src/components/ui/pagination.tsx
The reviews, three to a page. The ends disable rather than wrap, and the range sentence is the announcement a filter reset would otherwise make in silence.
Every target is a real button. Previous and Next leave the tab order when they run out.
default · a long run, one elision
disabled · one page, both ends dead
long unit · the sentence wraps
src/components/ui/field.tsx
One shell for the input, the select and the textarea. One message line per field, precedence error then success then description — so a form that is wrong in one place does not reveal every sentence it holds.
Every id derives from the control's own, which is what lets the error summary link to it in markup a server rendered.
One email per firing, about four a year
We post within the UK for now
Written on a card, tucked in beside the wool
That address is missing an @. Check it and send it again.
Pick where it is going before we can price the postage.
A little more than that. Twenty characters or so.
On the list since the January firing.
Free over £60, otherwise £4.20 tracked.
Saved with the order.
Set when the order was placed
Fixed once a piece is glazed
Posted with the order on 3 March
Wholesale opens after the summer firing
We post within the UK while the studio is two people
Available once there is something in the cart
The submitting state is the fieldset, not the field: ui/form disables it and marks it aria-busy while a request is out, which is what the restock band and the review form under the quotes both do. There is no ui/form frame — a form has no appearance of its own to photograph.
src/components/ui/form-error-summary.tsx
Where focus lands when more than one field is refused. One field goes straight to the control instead, because a summary listing one item is a redirection for no reason.
The panel is a -1 tab stop that only exists when it has something to say; each row is a link to the control it is about.
error-summary · two refused fields
2 things to fix before this can go.
src/components/hero.tsx
A8: the statement offset on the plaster wall, the studio photograph bleeding off the page.
Whitstable, Kent
Everything here was thrown by hand and came out of the kiln last week.

src/components/product-grid.tsx
The shelf: the full-bleed hairline plate. Props: heading, lede, only, showFiringNote, surface.
Six pieces from the March firing, and no repeats until the kiln goes on again.
6 pieces

250 ml · rust glaze

22 cm · serves four
Last one300 ml each · rust and sand

200 ml · cream glaze

21 cm · oatmeal glaze
Sold out£72
26 cm tall · one stem
Next firing opens 14 March. Sold-out pieces come back then, in a slightly different glaze.
src/components/collection-browser.tsx
A search field, availability, price and sort over one catalogue fixture, with removable receipts — shown in default, five-result, sparse and no-result states.
Default
6 pieces
Pieces shown

250 ml · rust glaze

£64
22 cm · serves four
Last one£52
300 ml each · rust and sand

£38
200 ml · cream glaze

£34
21 cm · oatmeal glaze
Sold out£72
26 cm tall · one stem
Filtered
5 pieces
Pieces shown

250 ml · rust glaze

£64
22 cm · serves four
Last one£52
300 ml each · rust and sand

£38
200 ml · cream glaze

£34
21 cm · oatmeal glaze
Sparse
1 piece
Piece shown
Last one£52
300 ml each · rust and sand
No results
0 pieces
Pieces shown
No pieces match these filters.
src/components/product-detail.tsx
Gallery, the glaze selector, the quantity stepper, a working add to cart, spec disclosures at prose width.
£28
4.8from 6 reviews of this piece



A short, heavy-bottomed cup for water, whisky or a flat white. Thrown with the ridges left in, so it sits in the hand without trying.
MRL-014
250 ml, 9 cm tall, 8 cm across the rim. Dishwasher and microwave safe. Each one is thrown by hand, so heights vary by a few millimetres.
Free UK delivery over £60, otherwise £4.20 tracked. Posted within two days of your order. 30 days to send it back unused, postage included.
Wood ash, iron oxide and a little tin, poured over the upper half so it breaks where the clay ridges catch it. No two come out of the kiln alike.
src/components/cart-contents.tsx
The live cart above, reading the same store the header does; the designed empty state below via variant='empty'.
£56
£52
£38
One of these is the last from this firing.
Delivery is free over £60. Posted within two days, tracked, with 30 days to send it back.
Keep shoppingSix pieces came out of the March firing and they are all on the shop page.
Back to the shopsrc/components/collection-split.tsx
Process photograph beside the four stages, split seven columns to five. Optional moreHref adds the link to the long version.

The making
Nothing here is cast, and nothing is finished by anyone who did not throw it.
Clay from a pit in Devon, wedged by hand until there is no air left in it.
Nell throws twelve at a sitting. Nine usually survive trimming the next day.
Iwan mixes in five-litre buckets: wood ash, iron oxide, a little tin.
Two firings up to 1,260°C. What the kiln does to the glaze is not up to us.
src/components/firing-calendar.tsx
The kiln year: a reading block at prose width, the next date at display size, and the four firings in the hairline plate.
The kiln year
A load takes 36 hours to fire and two days to cool, so nothing here is made to order.
Spring
Tumblers, mugs and jugs, and the glazes that sold out over winter.
Summer
Bowls and plates, and the first ash glazes of the year.
Autumn
Tableware, thrown early so it is dry before the damp sets in.
Winter
One small load, mostly repeats of whatever sold fastest.
src/components/promises.tsx
Dispatch, packing and returns: the three objections a fragile object raises. Optional moreHref points at the full terms.
Orders placed before 2pm on a weekday go out the next morning, tracked, from the Whitstable post office.
Wool fleece and recycled paper, no plastic. Four breakages in 412 orders, and every one was replaced.
Unused, for a full refund, postage included. Email us first and we send the label.
src/components/delivery-rates.tsx
The threshold at display size beside a real table of costs and transit windows, five columns to seven.
Rates
Free UK delivery over
£60
Below that it is £4.20, tracked, whatever is in the box.
Orders outside the UK may attract duty on arrival, which we cannot pay for you.
| Where | Cost | In the post |
|---|---|---|
| UK, over £60 | Free | 2–3 days |
| UK, under £60 | £4.20 | 2–3 days |
| Europe | £14 | 5–8 days |
| Rest of world | £24 | 8–14 days |
src/components/returns-faq.tsx
Four questions on ui/accordion-disclosure, the same part the product page's specs and the cart's gift note use.
Sending it back
Thirty days, postage both ways, and a replacement if it arrives in pieces.
Email us within thirty days and we send a prepaid label back. It has to come back unused, in the wool it arrived in, and the refund goes out the day it lands.
Photograph the box and the piece and email us. We replace it out of the next firing or refund you, whichever you would rather, and we never ask for the broken one back.
Yes, within thirty days, for anything in the current batch. Ash comes back at the next firing, so it is usually the one we cannot swap to.
Anything that has been used. A mug that has held tea is yours.
src/components/small-print.tsx
Who you buy from, when an order is an order, what happens to your email. Unboxed on purpose, because /delivery already runs a plate.
src/components/reviews.tsx
Named buyers, each quote tied to the piece they own, three to a page. The write-a-review form under them is the theme's only multi-field form and the rating input's home.
Reviews
4.8average across the studio
Small enough for an espresso, heavy enough that it does not skate across the counter. I have ordered two more.
Femi Adeyemi, Hackney
Ridge tumbler
The rim is thinner than I expected and it is the only mug I reach for now. Four months of daily use and it still looks new.
Ama Boateng, Bristol
Everyday mugs, pair
Ordered on the Tuesday, on my shelf by the Thursday, wrapped in wool like something borrowed from a museum.
Tom Rees, Cardiff
Fluted milk jug
We read every one and publish it with your first name and town. Nothing else is kept.
src/components/newsletter.tsx
The restock list, which replaces a back-order button — and the theme's simplest submit flow: one field, a pending button, a receipt focus lands on.
One email per firing, about four a year, with what came out and what it costs.
src/components/page-header.tsx
Editorial opener with a constrained measure, for every page that is not the shop front.
Four items
Delivery is free over £60, so this one ships for nothing.
The header above and the footer below are the same components every page uses, shown in place.