STYLE.md ·
How Thread works. Every rule, written down.
The forum and the community, as a website. It has four pieces:
- A thread list. Votes, tags, a solved badge and a reply count on every row. Sort by Latest, Top or Unanswered, and filter by tag; rows slide into their new order.
- A discussion. Replies hang off a visible thread line, so you can see who answered whom. The asker marks the answer that worked, branches collapse, and anyone can reply in place.
- A report on every post. Reasons in plain words, and a defamation path that promises a response within 7 days.
- A composer that searches as you type. Threads that might already answer your question appear under the title, before you post. It has a formatting toolbar, a live preview, tags (up to 3) and a short checklist.
The type is Space Grotesk, Inter and Fira Code, on paper with ink, one ultramarine, mint for what's solved and a red flag only for reports.
Friendly · useful · fair
Best for
- Forums and community sites. Hobby forums, support communities, member Q&A. It's written to the online safety and defamation rules (see "Forums: what we build in").
- Anywhere people ask and answer each other:
- software support communities (Ledgerly Community: staff answers labelled, code that keeps its formatting)
- neighbourhood noticeboards (Brightwater Residents: lost and found, recommendations, free stuff)
- club and association boards, alumni networks, course discussion boards, help centres with community answers
- Audiences: people with a question who want an answer from someone who's done it, and the volunteers who answer and moderate.
Less suited to: a news site with comments (use a news style), a chat app, or a site with one-way announcements only.
Personality and voice
Friendly and useful, like the regular who always knows. Ask well, get answered, and if something's wrong, say so and we'll deal with it.
- Headlines: "Ask @the bench." · "Replies that hang together." · "Ask well, get answered."
- Buttons: "Start a thread" · "Post your question" · "Accept answer" · "Send report"
- Microcopy:
- "Already asked? These might answer it:"
- "Still needed: a few more words of detail, at least one tag."
- "Your complaint is logged as R-23476. We'll tell you what we've done within 7 days."
- Words to avoid on a forum: "zero tolerance" (say what happens instead), "banned" without a reason, and "we are not responsible for user content" (a forum has duties once it's told).
Colour
| Token | Day (light) | Lights out (dark) | Role |
|---|---|---|---|
--paper |
#f6f6f3 |
#101114 |
Page |
--card |
#ffffff |
#18191e |
Thread list, discussion, composer |
--well |
#eeeee9 |
#14151a |
Alternate sections, toolbar, code |
--line |
#dcdcd4 |
#2a2c33 |
Hairlines between rows and posts |
--ink / --ink-2 |
#15171c / #3a3d45 |
#eceef3 / #c9ccd4 |
Text, the top line, the closing card |
--muted |
#5d6069 |
#9a9daa |
Meta: who, when, counts |
--ultra |
#2b45d6 |
#9fb0ff |
The one accent: buttons, links, votes, tags, the thread line, the @mention |
--mint / --mint-ink |
#b9f3d6 / #0f6b47 |
#1f4a39 / #7fe0b2 |
Solved and accepted (a background; mint-ink for text) |
--flag |
#b42318 |
#ff8b80 |
Reports, removed posts and threads no one's answered yet |
Measured contrast (WCAG).
- Day:
- ink on paper 16.6:1
- muted on paper 5.8:1 (5.4:1 on well)
- ultra on paper 6.6:1 (6.2:1 on well, 5.9:1 on its soft fill)
- white on ultra 7.2:1
- mint-ink on mint 5.2:1 (6.5:1 on card)
- flag on paper 6.1:1 (5.4:1 on its soft fill), white on flag 6.6:1
- Lights out:
- ink 16.3:1
- muted 7.0:1 (6.5:1 on card)
- ultra 9.1:1, text on ultra 8.5:1, ultra on its soft fill 7.4:1
- mint-ink on mint 6.3:1
- flag on card 7.7:1
- Example dials on paper (light / dark):
- deep teal (Ledgerly) 6.1:1 / 10.8:1
- plum (Brightwater) 7.0:1 / 9.9:1
- loam brown (Root & Branch) 6.8:1 / 10.5:1
Typography
- Display: Space Grotesk, 400–700. Headlines, thread titles, names, the brand.
- Body: Inter, 400–700. Posts, meta, buttons, forms.
- Mono: Fira Code, 400–500. Counts, tags, code, labels.
| Token | Size | Use |
|---|---|---|
--fs-h1 |
clamp(42px, 5.6vw, 84px) | Page headline |
--fs-h2 |
clamp(30px, 3.6vw, 52px) | Section headline |
--fs-h3 |
22px | Card titles |
--fs-lead |
clamp(17.5px, 1.35vw, 20.5px) | Intro paragraphs |
--fs-body |
16.5px | Body |
--fs-label |
12px, caps | Eyebrows after a hash (# BN·01) |
The signature move: the lit words sit in an ultramarine-soft pill like a mention, and in the page headline they get an "@": "Ask @the bench."
Layout
- Frame: a 1200px wrap with a
max(20px, 4vw)gutter. An ink top line carries a mint pill (new here, status, this week), and the header is sticky with a speech-bubble brand mark. - Hero: copy on the left; a discussion on the right whose replies spin in one by one, with "is replying…" dots.
- Then:
- the thread list with a sidebar (categories, who's moderating)
- a full discussion with collapse, accept, reply and report
- the composer with tips
- categories
- the guidelines, with how reports and complaints are handled
- an ink closing card with a thread line drawn in the corner
Shape
- Corners:
--r-s8px,--r-m12px,--r-l18px; chips and sort controls are pills. - The thread line: a 2px line in ultramarine at 30%, with a rounded elbow into each reply.
- Avatars: initials on a soft tint chosen per person (
--h), never photos by default. - The mark: a speech bubble with three dots and a mint reply tucked under it.
Motion language
- Thread list: sorting and filtering slide rows to their new place (FLIP); a vote bumps its count.
- Discussion: in the hero, replies spin in one by one with typing dots and the thread line draws down. A posted reply slides in from the line.
- Elsewhere: the report dialog rises in, the closing card's dot bobs, sections reveal with a 14px rise and fade over 650ms, and the phone menu drops in.
- Motion switch in the footer (
[data-motion-toggle],html.calm, remembered assite-motion, with the default fromprefers-reduced-motion). Calm shows the whole thread at once and stops the slides, dots and bob. - Lights out switch (
[data-theme-toggle]), remembered assite-theme;theme-colorfollows.
Imagery and illustration
The conversation is the picture. Members' own photos in posts are welcome. Don't use stock photos of people at laptops, and don't invent members, testimonials or activity counts for a real community.
Signature components
- Votes:
button.vote[data-vote][data-label]›svg+b, witharia-pressedand a label that says the count. - Thread list:
.threads[data-threads][data-unit][data-unit-one], containing:.seg > button[data-sort="latest"|"top"|"unanswered"]and[data-threads-count].threads-tags > button.chip[data-tag].thread-list > .trow[data-age][data-votes][data-replies][data-tags](.vote,.tmain›a.title+.tmetawith.solved,.who,.ttag;.tstat,.zerowhen unanswered)[data-threads-none]
- Discussion:
.discussion-card > h3([data-solved],.ttag) +.discussion[data-discussion][data-me][data-solution-label], with:article.post(.accepted,.removed) ›.av[style=--h]+.post-main›.post-head(b,.role.opor.role.mod,.sol),.post-body,.post-actions(.vote,[data-reply],[data-accept],[data-report])button.fold[data-fold][aria-controls]+.replies#id[data-spin]with[data-spin-item]posts andp.typing[data-typing]
- Report:
dialog.report[data-report-dialog][data-done][data-done-defamation]withinput[name=reason], paths[data-when="defamation"|"abuse"],[data-report-who],[data-report-error],[data-report-done],[data-report-send],[data-report-close]. - Composer:
form.composer[data-composer][data-max-tags][data-min-title][data-min-body], containing.title-in,[data-similar],.toolbar(button[data-md],button[data-tab]),textarea.body-in,.preview,button.chip[data-pick]with[data-tags-count],[data-before]checkboxes,[data-compose-status],[data-compose-go], andscript[type="application/json"][data-known]([{t, href, n, solved}]). - Supporting pieces:
.cat,.person,.rules,.facts(.stack),.notice(.warn),.side-box,.topline,.faq,.licence,.close-card(--close-em).
Multi-page kit
- Phone menu:
.menu-btn[aria-controls]opens.site-menu. Escape, an outside click or choosing a link closes it, and Tab stays inside while it's open. - Current page:
aria-current="page", shown as an ultra-soft pill. - Inner pages:
.page-head(with the dot grid),.crumbs, a.tagand a smaller.h1. - Fields:
.field,.fields,.field-wide,fieldset.field-set,.check,.form-card,[aria-invalid="true"](in flag red);form[data-template]. - Tiles, segmented control, gate, slider, switch, tables:
.choices,.seg,[data-gate],input.range,.switch[role=switch],.table. - Events:
vote(on, votes),threads(sort, tag, shown),accept(on),reply(to, text),report(reason, ref),compose(title, tags). - Helpers:
Thread.refresh(root)andThread.md(text)(the safe markdown used by replies and the preview: text is escaped first; only http and https links).
Forums: what we build in
We checked these rules for Australian forums and community sites in October 2026:
- A complaints path that works within 7 days. Under the Stage 2 model defamation provisions, a forum (a "digital intermediary") can rely on a defence if it has an easily accessible way to complain and, once told, takes reasonable access-prevention steps within 7 days. The report on every post includes "It's untrue and harms my reputation", which asks for the words complained of and a contact, gives a reference, and promises a response within 7 days. These provisions have commenced in NSW, the ACT and Victoria; check the state you operate in.
- Reporting and clear terms. eSafety's Basic Online Safety Expectations ask services to have easy ways to report harmful content and to enforce their terms. Every post has Report, the guidelines are short and numbered, and moderators say which rule a removal falls under. For serious abuse, the dialog points people to eSafety if it isn't removed within 48 hours.
- Minimum age. Since 10 December 2025, age-restricted social media platforms must take reasonable steps to stop under-16s having accounts. Whether a forum is covered depends on its purpose, so check eSafety's guidance; the templates say members are 16 or older and the industry template asks for a date of birth when you join.
- Privacy. Collection notices where people sign up and post: what's public, what's private, how to see, fix or delete it, and how to complain (OAIC).
These notes are design guidance, not legal advice.
Do and don't
- Do put Report on every post, and say what happens after.
- Do show similar threads before someone posts a duplicate.
- Do let the asker mark the answer that worked, and show it at the top of the thread's story.
- Don't use flag red for anything but reports, removals and unanswered counts.
- Don't use mint for anything but solved and accepted.
- Don't render members' text as HTML: escape it, then format.
Accessibility
- AA contrast throughout (measured above), a skip link and a 3px focus ring.
- Votes, sort and tags are toggle buttons with pressed states; vote labels say the count, and the thread count is announced politely.
- Discussion: collapse buttons say how many replies and use
aria-expanded; the reply box is labelled with who you're replying to and gets focus; a posted reply takes focus. The hero setsaria-busywhile replies spin in. - Report: a native
<dialog>(focus is trapped and Escape closes), reasons are radio buttons with descriptions, errors are announced, and focus returns to the Report button. - Composer: similar threads and the status are announced politely; the post button stays disabled and the status says exactly what's missing; tags past the limit are marked
aria-disabled. - Testing: responsive to 360px, and tested with motion on and off, in Day and Lights out.
How to make it yours
| Dial | Range |
|---|---|
| Accent | Ultramarine (default), deep teal (Ledgerly), plum (Brightwater), loam brown (Root & Branch). Set --ultra, --ultra-2, --ultra-soft, --focus (plus --on-ultra at night) and --close-em. |
| Words | "Solved" or "Answered" or "Reunited"; "Accepted answer" or "Helped most"; threads, questions or posts. |
| Roles | Asked, Mod, staff ("Ledgerly team"). |
| Report reasons | Yours, but keep the defamation path and the 7-day promise. |
| Not negotiable | The thread line, Report on every post with the defamation path, similar threads as you type, escaped member text, mint only for solved, flag only for reports, and the Motion switch. |



