Button
Ink-fill, outline, secondary, ghost, link and destructive (✕ icon) buttons; 44px hit targets.
The Eloquent · UI kit
Every component, brand component and block for React in one registry, built on Base UI and set in the house style: pure black, white and grey, structured by rules rather than boxes. Each one installs with the shadcn CLI and has a reference page.
Add the registry to components.json:
"registries": {
"@eloquent": "https://phamdonhatminh.vercel.app/ui/r/{name}.json"
}Then add the style and any item:
npx shadcn add @eloquent/style01
The tokens every item reads: colour, type, rules and the marker highlight.
paperGroundinkText and rulestint-1Highlights, panelstint-2Bands, warningshalftoneDecoration, disabledpressThe one inverse blockA roman lead, an italic tail
Source Serif 4 sets the body: ledes, descriptions and dialog text, at a reading measure.
1,280Barlow Condensed figures
Barlow for labels and controls
Hairline, 1px: between stories, rows and fields
Heavy rule, 3px: opens each section
npx shadcn add @eloquent/style02
Buttons, fields and choices, ruled like a newspaper form.
Ink-fill, outline, secondary, ghost, link and destructive (✕ icon) buttons; 44px hit targets.
Joins related buttons into one segmented control divided by shared 1px ink rules, with a text cell and separator.
Single-line text field as a 1px ink form line; invalid is a 2px rule; 44px high.
Shown on the front page. Keep it under 70 characters.
One form line with a control plus text, icons or buttons either side, split by ink hairlines.
Readers can open the edition from this address.
One-time code entry on Base UI OTP Field: square 44px cells sharing 1px ink rules, Barlow Condensed figures.
Enter the 6 digits we sent to your device.
Multi-line text field with the 1px ink form line; invalid is a 2px rule.
State the source and the time of the photograph.
Form label in the Barlow 600 kicker style.
Label, control, description and error layout on Base UI Field and Fieldset; errors shown by a 2px ink rule and an ! icon.
Shown on the front page. Keep it under 70 characters.
Validated forms on Base UI Form and Field with react-hook-form and zod; errors shown by ink rules, icons and an error summary at the top on submit.
Tick, untick or mixed choice on Base UI Checkbox; checked is an ink fill plus a check glyph.
Pick one option on Base UI RadioGroup and Radio; selected is an ink fill with a paper dot.
On/off setting on Base UI Switch; on is an ink track with a paper thumb, optional ON/OFF text.
Number or range input on Base UI Slider; hairline track, heavy ink range, square thumb.
Drag, or use the arrow keys.
Select on Base UI: ink trigger, paper popup with a 1px rule, ink check on the chosen item; no shadow or radius.
Native <select> with an ink border, chevron and 44px height; invalid is a 2px ink underline.
Filterable single or multiple select on Base UI Combobox; ink rules, tint-1 highlight with an ink rule, no shadow.
The desk that commissioned the story.
Two-state button on Base UI Toggle; pressed shown by an ink fill and aria-pressed, never colour alone.
Segmented set of toggles on Base UI ToggleGroup, divided by shared 1px ink rules; pressed segments are ink fills.
Keyboard key and shortcut chips: Barlow Condensed capitals in a 1px ink rule.
Press CtrlK to search the archive.
03
Dialogs, menus and notices on paper, with a 1px ink rule and no shadow. Open each one.
Dialog on Base UI: paper popup, 1px ink rule and heavy top rule, 85% paper backdrop, focus trapped.
Alert dialog on Base UI: Dialog's paper and rules, no corner close, Action and Cancel are Buttons, focus trapped.
Sheet on Base UI Dialog: full-height paper panel from any side, 1px inner ink rule, focus trapped.
Drawer on Base UI: paper panel from any edge, heavy 3px ink rule as the handle, swipe to dismiss, focus trapped.
Popover on Base UI: ink on paper, 1px ink rule, no shadow, radius or arrow.
Hover card on Base UI PreviewCard: link trigger with the marker highlight, popover-style paper and 1px ink rule, opens on hover and focus.
Read the full record in the archive before you republish.
Tooltip on Base UI: ink block, paper Barlow 12px, no arrow, shadow or radius; opens on focus.
Dropdown menu on Base UI Menu: paper popup, 1px ink rule, ink-fill highlight, hairline separators, checkbox, radio and submenu rows.
Context menu on Base UI ContextMenu: focusable area, opens at the pointer or from Shift+F10, ink-fill highlight, hairline separators.
Menubar on Base UI Menubar and Menu: heavy top rule and bottom hairline, ink-fill trigger when open, Dropdown Menu rows.
Command palette on Base UI Autocomplete (inline): type to filter, arrows to choose, Enter to run; CommandDialog for Ctrl+K.
Last command: none
Toaster and toast() on Base UI Toast: paper and 1px ink rule at bottom-right, state by icon, rule or hatched band, never colour.
05
Tables, states, progress and a greyscale chart; state never relies on colour alone.
Card with no box: heavy 3px top rule, serif content, hairline footer; header, title, description, action, content and footer parts.
Dispatch
A short standfirst sets the story in one sentence.
Procurement notices are filed, dated and indexed the same day, so a reader can follow a decision from the first notice to the last.
Semantic table in Barlow: heavy header rule, hairline rows, tabular right-aligned figures.
| Desk | Stories | Words |
|---|---|---|
| Politics | 42 | 51,230 |
| Business | 37 | 44,105 |
| Culture | 19 | 23,870 |
| Science | 11 | 15,402 |
| Total | 109 | 134,607 |
Table with sortable headers (aria-sort, ink glyphs), a column filter, a columns popover and paging, on TanStack Table and the Eloquent table.
| Budget passes second reading | Politics | 1,240 |
| Port strike enters third day | Business | 980 |
| Museum reopens its east wing | Culture | 760 |
| Telescope finds a quiet star | Science | 1,105 |
| Council rejects the tram plan | Politics | 870 |
Square status label in Barlow Condensed capitals: ink fill, tint, outline or 2px destructive outline with a cross.
Square avatar on Base UI Avatar: hairline frame, greyscale image, initials fallback from props.
Alert panel with a state per variant: tint-1 info, check success, hatched tint-2 warning, 2px ink rule error.
Progress bar on Base UI Progress: hairline track, ink fill, value text in Barlow Condensed.
Meter on Base UI Meter: same hairline track and ink fill as Progress, for a value in a known range.
tint-1 placeholder block that pulses only when motion is allowed.
Ink square outline that turns while loading; labelled status, still under reduced motion.
Empty state: ink hairline, tracked kicker, Playfair headline, serif sentence and an optional ink drawing or icon slot.
No filings
Notices appear here once the first tender is published. Until then the register is blank.
Row for a record: media, title, description and actions, closed by an ink hairline; renders as a link with the render prop.
Filed 3 November. Open for questions until 24 November.
Filed 5 November. Replaces section 2.
Month grid on react-day-picker: hairline weeks, ink-fill selection, heavy-rule today, Barlow Condensed numerals, 44px days.
| Mo | Tu | We | Th | Fr | Sa | Su |
|---|---|---|---|---|---|---|
Date field on Calendar and Popover: a ruled trigger opens a square, flat calendar; Esc returns focus to the trigger.
Slides on Embla: ruled slides, numbered Barlow Condensed controls, labelled previous and next, jumps under reduced motion.
Politics
The vote followed a long debate on the cost of the new rail link.
Business
Shipping firms say deliveries to the north will be late this week.
Culture
The restored galleries hold the city's oldest printed maps.
Science
Astronomers describe a calm, old sun with three small worlds.
Charts on Recharts in ink: series told apart by pattern, dash and label; one labelled image with a data table alternative; no animation under reduced motion.
A bar chart of stories filed and stories published for four desks. Politics leads on both. The table below gives every value.
| Desk | Filed | Published |
|---|---|---|
| Politics | 42 | 36 |
| Business | 37 | 31 |
| Culture | 19 | 18 |
| Science | 11 | 9 |
Brand text elements: two-voice headline, kicker, lede, body, drop cap, pull-quote, figure and meta.
Analysis
A newspaper of record sets its headlines in one voice and answers in another.
By the Editors · 9 November 2026
Every story opens with a rule. The type does the rest: a headline that carries weight, a lede that explains, and body text that rewards the careful reader.
Structure comes from rules, not boxes.
Names and figures are set in capitals so they can be scanned at a glance.
06
The pieces of The Eloquent itself: kickers, two-voice headlines, figures and story cards.
tracked-capitals label with an optional leading ink rule.
Work · Sep 2025 – Present
two-voice headline (roman lead, italic tail) in four sizes; the marker highlight shows only when it is a link.
middle-dot separated stack line in Barlow.
greyscale illustration frame (multiply blend) in 9:16, 16:9, 3:4 or 1:1, with required alt text.
tint-1 figure tile (Barlow Condensed figure, unit, caption) and StatRow, a row of exactly three.
21items
Brand items in phase 4
60primitives
Primitives in the registry
2languages
English and Vietnamese
EN · VI switch; the current locale in ink 700, the other a real link that keeps the hash and ?mode. No flags.
name · title · city between two ink hairlines, with the language switch.
Pham Do Nhat MinhAgentic Software EngineerHo Chi Minh City
three lines, Problem. / Built. / Result., with a bold sans lead word and serif text.
kicker, headline, lede and stack under a heavy rule, with an optional 96px 9:16 ink thumbnail.
Work · Sep 2025 – Present
A document pipeline in which each agent owns one stage, so that every draft can be traced back to its source.
kicker, two-voice headline and a 16:9 ink scene, for slide titles and social images.
Case study · 2026
a non-modal bottom bar that offers the other language once, written in that language.
a tint-2 band asking what brings you to the paper, with two large tabs (solid ink when selected) synced to the URL hash; controlled or uncontrolled.
The CV, recent work and how a project runs from brief to release.
the press band with a classifieds kicker, a two-voice Playfair headline and an outlined on-press mailto button.
Classifieds
Get in touch with labelled contact rows, a QR slot and an Email me button; variant=band is the press-black contact band for the CV.
Scan to save my contact
a 390 × 844 no-scroll screen with four contact buttons, two tiles and a black footer.
The EloquentCalling cardHo Chi Minh City
Agentic software engineer. Builds the Procurement Docs Platform.
07
Whole sections, from the masthead to the A4 print shell.
Brand block: front-page link, kicker, headline, standfirst and byline, body column, At a glance aside, pull quote and Keep reading.
Field notes · November 2026
How a component kit borrows its structure from the front page: hairlines, heavy rules and two voices of type.
By Minh Pham · 9 November 2026 · 6 min read
A newspaper never draws a box around a story. It opens each section with a heavy rule, separates stories with a hairline, and lets the type do the rest. The kit follows the same discipline.
Every headline has two voices: a roman lead and an italic tail. The first tells the reader what the story is; the second tells them why to stay. Both are set in the same face, so the page keeps one tone.
Colour is absent by design. Errors, successes and warnings are told apart by an icon, a rule or a hatched band, never by hue alone, which keeps the page readable in print and in greyscale.
Read it in serif, use it in sans.
Block: the nameplate, folio line with the language switch, and the section nav.
Pham Do Nhat MinhAgentic Software EngineerHo Chi Minh City
Block: the one inverse block, with contact, Download CV, a LinkedIn QR code slot, the language switch and Back to top.
Block: three tabs (I Leverage, II Habit, III Delivery), each with a Playfair quote, body text, a 3:4 ink panel and a signature.
Build the thing that builds the thing.
— Minh Pham
Block: the brief form (name, company, email, brief, four-way project size) with an error summary, inline success and error messages and an onSubmit prop; no network call.
Block: an A4 page shell (210 by 297mm, 44 to 52px margins, main column plus a 210 to 228px side column), a named @page rule for print and a page-break helper. Pure layout.
Curriculum vitae
Software engineer, placeholder profile
Placeholder text. A short paragraph about the person, set in the body face, that runs for three or four lines and says what they build and how they work.
2023 – present
Placeholder text. Designed the document workflow and the review screens, and kept the release process calm.
2020 – 2023
Placeholder text. Built internal tools for editors and wrote the first test suite for the publishing system.
2017 – 2020
Placeholder text. Maintained a set of services and moved the team to a weekly release.