import Link from "next/link"; import JsonLd from "@/components/JsonLd"; import { graph, softwareApplication } from "@/lib/schema"; import { Band, CtaBand, SiteNav, body, h2, kicker, small, wrap } from "@/components/site"; import { PRICES } from "@/lib/plan"; import { plansLive } from "@/lib/plans-live"; import { COMMUNITY } from "@/lib/edition"; import { redirect } from "next/navigation"; export const metadata = { alternates: { canonical: "/" } }; const CARDS = [ { k: "Know", t: "What’s on the shelf", b: "On-hand by size, updated as you issue, and flagged before a size runs out on you." }, { k: "Prove", t: "Where it went", b: "Every garment against the staff member who took it, dated, on a slip they signed." }, { k: "Charge", t: "The right ward or clinic", b: "Issues carry the wearer’s cost centre at the price you paid, so the journal is already written." }, ]; const LOOP = [ { n: "1", t: "Issue", b: "Scan the garment, pick the staff member, done. Their ward or clinic, cost centre and last sizes are already there, so a repeat visit takes seconds.", pad: 0 }, { n: "2", t: "Replenish", b: "What you take off the shelf lands on a draft order for that supplier. Check it, add their order number, send. Nothing you issue goes quietly unreplaced.", pad: 36 }, { n: "3", t: "Receive", b: "Tick lines off against the invoice as you unpack, then send each one to the shelf or to whoever is waiting. A short delivery becomes a back order on its own.", pad: 72 }, ]; const row: React.CSSProperties = { display: "flex", justifyContent: "space-between", padding: "8px 0", borderBottom: "1px solid var(--color-divider)", fontSize: 13 }; export default async function Home() { // A Community instance is the product, not the website: its front door is the sign-in. if (COMMUNITY) redirect("/auth"); const live = await plansLive(); return ( <> {/* The product, with its price as it stands today, on the page that is actually about it. */} {/* Hero: full-bleed greyscale photograph with a solid ink panel flush left over it. */}
{/* eslint-disable-next-line @next/next/no-img-element */}
{/* The panel sizes to its widest line rather than a fixed 760: the headline scales to 84px, where "ACCOUNTED FOR." is 753px and was breaking out of the box onto the photograph from 1440px up. Hugging the content means the ink always contains the words. */}
{live ? "For hospitals, aged care and clinics" : "Free for hospitals, aged care and clinics"}

Every garment out the door, accounted for.

ThreadCount follows a garment from the shelf, to the person wearing it, to the order that puts another one back.

Open the working demo How it works
{/* Card row pulls up over the hero's bottom padding. */}
{CARDS.map((c, i) => (
{c.k}
{c.t}

{c.b}

))}
{/* Proposition split */}

One coordinator can run the whole room from a phone.

Scan the garment, pick the staff member, record it. The order to replace it starts itself, the cost lands on the right ward, wing or clinic, and the month-end pack is a button rather than a weekend.

See everything it does
{/* The loop, with the designed vertical stagger */}
The loop
{LOOP.map((l) => (
{l.n}
{l.t}

{l.b}

))}
{/* Pricing band */}
Pricing
{live ?
Free to run.
Paid to host.
:
Free
}

{live ? `Every feature in every edition. Run it yourself for nothing, or have it hosted from $${PRICES.hostedAnnual.toLocaleString("en-AU")} a year — free for a room under ${PRICES.freeStaff} staff records.` : "No licence, no per-device charge, no per-user charge. Every feature, every report, everyone in the room."}

{live ? "The plans" : "What free covers"}
{/* Recreated product UI */}
On the screen

The whole counter on one screen.

ThreadCount — Dashboard Signed in · Coordinator
{[["Orders", "3 open", "1 overdue — NL-48211, 6 days", true], ["Stock", "$18,240", "7 sizes at or below reorder", false], ["Staff", "212 active", "14 issues recorded this week", false]].map(([k, v, s, red], i) => (
{k}
{v}
{s}
))}
Awaiting pickup — call list
{[["K. Osei · Softshell Jacket M", "16 days", "tag tag-accent", "Contacted"], ["T. Nguyen · Polo Shirt L ×2", "4 days", "tag tag-neutral", "Call"], ["R. Patel · Cargo Pant 88R", "1 day", "tag tag-neutral", "Call"]].map(([n, d, cls, act]) => (
{n}{d}{act}
))}
Reorder flags
{[["RN Scrub Top · S", "2 left"], ["Chef Jacket · L", "0 left"], ["Security Polo · XL", "3 left"]].map(([n, v]) => (
{n}{v}
))}
Inventory, issuing, ordering, stocktakes and reports all work the same way, so there is only one thing to learn.
{/* The guides. Someone arriving from a search for their problem rather than for a product should find the useful writing without hunting for it — and someone weighing this up wants evidence the person behind it knows the job. These do both. */}
Guides

Written from the counter, not the brochure.

Notes on running a linen room — in a hospital, an aged-care home or a clinic — that are useful whether or not you ever use ThreadCount. Take the method and use a clipboard if that’s what you have.

{[ ["How to run a uniform stocktake", "/guides/uniform-stocktake"], ["Where the uniforms actually go", "/guides/uniform-loss"], ["Charging uniforms to the right cost centre", "/guides/cost-centre-reporting"], ["Entitlements and manager approvals", "/guides/manager-approvals"], ].map(([label, href]) => ( {label} ))}
); }