ThreadCount Community edition

Uniform stock management for healthcare linen rooms. Licensed under the GNU AGPL v3.
This commit is contained in:
ThreadCount
2026-09-13 08:54:35 +10:00
commit 344b1701dd
505 changed files with 56231 additions and 0 deletions
@@ -0,0 +1,109 @@
import Link from "next/link";
import { Band, body, small } from "@/components/site";
import { GuideFoot, GuideHead, GuideMeta, Pitfalls, Steps, type Step } from "@/components/guide";
export const metadata = {
title: "Charging uniforms to the right cost centre",
description:
"How to attribute uniform spend to the ward, wing or clinic that incurred it: what to capture at the counter, how to value an issue, and what finance needs in the journal before they will accept it.",
alternates: { canonical: "/guides/cost-centre-reporting" },
};
const STEPS: Step[] = [
{
n: "01",
h: "Attribute at the moment of issue, not at month end",
p: <>The only person who reliably knows which ward, wing or clinic a garment is for is the person handing it over. Reconstructing that from invoices four weeks later is guesswork, and it is the reason most linen rooms end up charging everything to one central code. Capture the cost centre when the garment leaves the counter and the month-end job becomes an export rather than an investigation.</>,
},
{
n: "02",
h: "Hang the cost centre off the person, not the transaction",
p: <>Asking &ldquo;which cost centre?&rdquo; at every issue is a question that will be answered wrong under pressure. Put the ward and cost centre on the staff record, so the issue inherits it. The counter stays fast, and corrections happen once on the register rather than repeatedly at the counter.</>,
},
{
n: "03",
h: "Decide what an issue is worth",
p: <>Unit cost is the defensible answer: what you paid the supplier for that garment, per unit. Avoid apportioning freight and avoid an average across sizes if your sizes genuinely differ in price. The figure needs to be one you can explain in a sentence, because at some point someone will ask you to.</>,
},
{
n: "04",
h: "Decide when the charge lands",
p: <>There are two honest answers and you must pick one: at purchase, or at issue. Charging at purchase makes the linen room&rsquo;s budget lumpy and makes wards indifferent to what they take. Charging at issue is what most facilities want the ward or clinic feels the cost of its own consumption but it means your stock on hand is an asset carried by the linen room until it moves. Pick one, write it down, and don&rsquo;t quietly change it mid-year.</>,
},
{
n: "05",
h: "Produce one line per cost centre",
p: <>Finance does not want your transaction list. They want a journal: one debit line per cost centre, one credit to the GL account the stock was bought against, for a stated period, totalling to a number that matches. Give them exactly that as CSV and the upload takes minutes. Give them a spreadsheet of every issue and it will sit in an inbox.</>,
},
{
n: "06",
h: "Keep the detail behind the summary",
p: <>The summary is what gets uploaded; the detail is what settles the argument when a ward manager queries their figure. You want to be able to go from &ldquo;Ward 3A, $1,840&rdquo; to the individual issues behind it without rebuilding anything. If your summary can&rsquo;t be drilled into, expect to spend the following week defending it.</>,
},
];
const PITFALLS: [string, string][] = [
["One catch-all cost centre", "Everything charged centrally means no ward, wing or clinic ever sees the cost of its own uniform consumption, so nothing ever changes."],
["Cost centres that only exist in someones head", "If the mapping from ward or team to code lives in memory, it leaves when that person does. Put it on the record."],
["Charging at purchase and at issue", "Double-counting is the fastest way to lose finances trust, and it is easy to do accidentally when the method changes mid-year."],
["Retail price instead of unit cost", "There is no margin here. Anything other than what you paid invites a question you cannot answer."],
["No period stamped on the export", "A journal without an unambiguous date range cannot be reconciled and will be sent back."],
["Rounding per line", "Round the total, not each line, or the journal wont balance against the invoice and someone will spend an afternoon on eleven cents."],
];
export default function Page() {
return (
<>
<GuideMeta
slug="cost-centre-reporting"
title="Charging uniforms to the right cost centre"
description={metadata.description}
updated="2026-09-07"
/>
<GuideHead
kicker="Guide"
title="Charging uniforms to the right cost centre"
lede="Uniform spend that lands in one central code tells nobody anything. Attributing it properly is mostly a matter of capturing one field at the right moment."
/>
<Band>
<Steps steps={STEPS} />
</Band>
<Band tone="surface">
<div style={{ fontSize: 11.5, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 800, borderBottom: "2px solid var(--color-text)", paddingBottom: 9 }}>
What finance sends back
</div>
<Pitfalls items={PITFALLS} />
</Band>
<Band>
<h2 style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: "clamp(24px,3vw,36px)", letterSpacing: "-0.02em", margin: 0 }}>
Doing this in ThreadCount
</h2>
<p style={{ ...body, margin: "16px 0 0", maxWidth: "62ch" }}>
Ward and cost centre sit on the staff record, so every issue values itself at unit cost
against the right code without anyone being asked at the counter. The journal exports as
one debit line per cost centre for the month you choose, and each line opens the issues
behind it who, what, which size, what it cost when someone queries their
number.
</p>
<p style={{ ...small, margin: "14px 0 0", maxWidth: "62ch" }}>
If your finance team needs a different layout, that is usually a small change say what
they need.
</p>
<div style={{ display: "flex", gap: 12, marginTop: 24, flexWrap: "wrap" }}>
<Link href="/reporting" className="btn btn-primary">See the reporting</Link>
<Link href="/contact" className="btn btn-secondary">Ask about a layout</Link>
</div>
</Band>
<GuideFoot
related={[
["Staff entitlements and manager approvals", "/guides/manager-approvals"],
["How to run a uniform stocktake", "/guides/uniform-stocktake"],
]}
/>
</>
);
}
@@ -0,0 +1,113 @@
import Link from "next/link";
import { Band, body, small } from "@/components/site";
import { GuideFoot, GuideHead, GuideMeta, Pitfalls, Steps, type Step } from "@/components/guide";
export const metadata = {
title: "Staff uniform entitlements and manager approvals",
description:
"How to run a uniform entitlement that holds, on a ward or in an aged-care home: what an approval needs to record, how to handle part-time and agency staff, what to do when someone asks for more.",
alternates: { canonical: "/guides/manager-approvals" },
};
const STEPS: Step[] = [
{
n: "01",
h: "Write the entitlement down before you need it",
p: <>An entitlement that exists only as custom is one you will renegotiate at the counter, individually, forever. Agree the number of sets per role, put it somewhere both the linen room and the wards, homes or clinics it serves can see, and date it. The specific number matters far less than everyone knowing what it is.</>,
},
{
n: "02",
h: "Prorate honestly, or dont prorate at all",
p: <>Part-time staff are where entitlement schemes get messy. A nurse at 0.4 FTE or a care worker on two shifts a week, or a dental assistant covering Fridays still needs enough sets to get through a week without doing laundry nightly, so a straight multiplication produces something unworkable and quietly ignored. Either set a floor below which nobody drops, or don&rsquo;t prorate and say so. What you cannot do is have a rule on paper that the counter overrides in practice, because then there is no rule.</>,
},
{
n: "03",
h: "Make the approval carry its own evidence",
p: <>An approval should record who approved it, what they approved, for whom, and when. The approver is the staff member&rsquo;s own manager the ward, clinic or team manager. &ldquo;The manager said it was fine&rdquo; is not an approval, and it is exactly what you will be holding when someone asks why a ward went over budget. Name, number of sets, FTE if it bears on the calculation, and a date.</>,
},
{
n: "04",
h: "Separate the entitlement from the issue",
p: <>Someone can be entitled to five sets and take three today. Track the entitlement and the issues against it as different things, so the balance is visible. Otherwise the only way to know what someone is still owed is to add up their history, and nobody does that at a counter with three people waiting.</>,
},
{
n: "05",
h: "Give them the balance in writing",
p: <>When a staff member takes less than their entitlement because the size isn&rsquo;t there, or they only wanted two hand over something that records the balance. A credit slip stops the same conversation happening again in a fortnight with a different person at the counter, and it stops the quiet inflation that happens when nobody can remember what was already given.</>,
},
{
n: "06",
h: "Decide what happens when someone asks for more",
p: <>They will, and often for good reason: a garment condemned after a spill, a size change, a genuine increase in hours. Have a route that isn&rsquo;t &ldquo;no&rdquo; and isn&rsquo;t &ldquo;yes, quietly&rdquo;. An over-entitlement issue with a recorded approval keeps the room helpful and the numbers honest at the same time.</>,
},
{
n: "07",
h: "Handle agency and students explicitly",
p: <>Short-term staff are the fastest route to unreturned stock, because there is often nobody to ask afterwards. Decide in advance whether they get issued at all, and if so whether it is a loan against a return date. Whatever you decide, decide it once rather than at the counter.</>,
},
];
const PITFALLS: [string, string][] = [
["Verbal approvals", "Nothing to show and nothing to reconcile. The first budget query will land on the linen room, not on the person who approved it."],
["Entitlement with no start date", "Without a date you cannot tell an annual renewal from a duplicate issue, and long-serving staff quietly accumulate."],
["Prorating below a workable minimum", "A rule that makes it impossible to get through a week will be broken at the counter, and then no rule is being followed at all."],
["No record of whats outstanding", "If the balance isnt visible, the safe answer at the counter is always to hand over another set."],
["Treating a size change as a new issue", "It doubles the persons apparent consumption and hides a real signal about how youre buying sizes."],
["No closing routine for leavers", "The entitlement was correct; nobody asked for the garments back. This is the single largest source of unreturned stock in most rooms."],
];
export default function Page() {
return (
<>
<GuideMeta
slug="manager-approvals"
title="Staff uniform entitlements and manager approvals"
description={metadata.description}
updated="2026-09-07"
/>
<GuideHead
kicker="Guide"
title="Entitlements and manager approvals"
lede="Most disputes at a uniform counter are not about uniforms. They are about a rule nobody wrote down, applied inconsistently by people trying to be helpful."
/>
<Band>
<Steps steps={STEPS} />
</Band>
<Band tone="surface">
<div style={{ fontSize: 11.5, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 800, borderBottom: "2px solid var(--color-text)", paddingBottom: 9 }}>
Where entitlements come apart
</div>
<Pitfalls items={PITFALLS} />
</Band>
<Band>
<h2 style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: "clamp(24px,3vw,36px)", letterSpacing: "-0.02em", margin: 0 }}>
Doing this in ThreadCount
</h2>
<p style={{ ...body, margin: "16px 0 0", maxWidth: "62ch" }}>
Entitlement sits on the staff record and the balance is on screen at the counter, so the
person handing over garments can see what is still owed without adding anything up. An
approval records the approver, the sets approved and the FTE it was based on. Take less
than the entitlement and a credit slip prints for the balance.
</p>
<p style={{ ...small, margin: "14px 0 0", maxWidth: "62ch" }}>
Going over is allowed it just asks for the approval first, which is the only difference
between a helpful exception and an unexplained one.
</p>
<div style={{ display: "flex", gap: 12, marginTop: 24, flexWrap: "wrap" }}>
<Link href="/demo" data-umami-event="open-demo" data-umami-event-placement="guide" className="btn btn-primary">Open the demo</Link>
<Link href="/how-it-works" className="btn btn-secondary">How issuing works</Link>
</div>
</Band>
<GuideFoot
related={[
["Where hospital and aged-care uniforms actually go", "/guides/uniform-loss"],
["Charging uniforms to the right cost centre", "/guides/cost-centre-reporting"],
]}
/>
</>
);
}
+10
View File
@@ -0,0 +1,10 @@
import { permanentRedirect } from "next/navigation";
// The guide moved to /guides/manager-approvals once the approval stopped being a nursing-only
// idea. This is a 308 rather than the 307 /product uses: that path was live only briefly before
// launch, whereas this one has been in the sitemap, in cold emails and in search results for
// months. The move is permanent, so say so — search engines hand the ranking to the new URL and
// browsers stop asking for the old one.
export default function NumApprovalsRedirect() {
permanentRedirect("/guides/manager-approvals");
}
+74
View File
@@ -0,0 +1,74 @@
import Link from "next/link";
import { Band, CtaBand, PageHead, SiteNav, body, small } from "@/components/site";
export const metadata = {
title: "Guides",
description:
"Notes on running a linen room — hospital, aged care or clinic: stocktakes that produce a usable number, where uniforms actually go, charging spend to the right ward, and entitlements that hold up.",
alternates: { canonical: "/guides" },
};
/* Written for the person doing the job, not for the person buying software. Each of these is
useful with a clipboard and no product at all — which is the only reason anyone would link to
them. */
export const GUIDES: [string, string, string][] = [
[
"/guides/uniform-stocktake",
"How to run a uniform stocktake",
"What to count, how to split a room into shelves, what to do about garments at the laundry, and how to record a variance so the number still means something a month later.",
],
[
"/guides/uniform-loss",
"Where the uniforms actually go",
"Loss is rarely theft. Leavers nobody closed off, sizes swapped at the shelf, laundry that never came back, damage never written off — and how to tell them apart.",
],
[
"/guides/cost-centre-reporting",
"Charging uniforms to the right cost centre",
"Capturing the cost centre at the counter, valuing an issue defensibly, and producing a journal finance will actually accept.",
],
[
"/guides/manager-approvals",
"Entitlements and manager approvals",
"Writing the entitlement down, prorating part-time hours honestly, recording an approval that carries its own evidence, and what to do when someone asks for more.",
],
];
export default function Guides() {
return (
<>
<SiteNav />
<PageHead
kicker="Guides"
title="How the job is actually done."
lede="Notes from running a hospital linen room. What follows works the same in an aged-care home, a day surgery or a clinic cupboard. No product required — take the method and use a clipboard if that is what you have."
/>
<Band>
{GUIDES.map(([href, title, blurb], i) => (
<Link
key={href}
href={href}
style={{ textDecoration: "none", color: "var(--color-text)", display: "grid", gridTemplateColumns: "44px 1fr", gap: 20, padding: "32px 0", borderBottom: "1px solid var(--color-divider)" }}
>
<div style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: 15, color: "var(--color-neutral-600)" }}>
{String(i + 1).padStart(2, "0")}
</div>
<div>
<h2 style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: "clamp(20px,2.2vw,28px)", letterSpacing: "-0.02em", margin: 0 }}>
{title}
</h2>
<p style={{ ...body, margin: "10px 0 0", maxWidth: "64ch" }}>{blurb}</p>
</div>
</Link>
))}
<p style={{ ...small, margin: "26px 0 0", maxWidth: "58ch" }}>
Something missing that you had to work out the hard way?{" "}
<Link href="/contact" style={{ fontWeight: 700 }}>Tell us</Link> and it will get written up.
</p>
</Band>
<CtaBand />
</>
);
}
+104
View File
@@ -0,0 +1,104 @@
import Link from "next/link";
import { Band, body, small } from "@/components/site";
import { GuideFoot, GuideHead, GuideMeta, Pitfalls, Steps, type Step } from "@/components/guide";
export const metadata = {
title: "Where hospital and aged-care uniforms actually go",
description:
"Uniform loss is rarely theft. The honest causes — starters who never return a set, sizes swapped at the shelf, laundry that never comes back, leavers nobody closed off — and what to record so you can tell them apart.",
alternates: { canonical: "/guides/uniform-loss" },
};
const STEPS: Step[] = [
{
n: "01",
h: "Stop calling it shrinkage",
p: <>Borrowing the retail word imports the retail assumption, which is that stock is being stolen. In a linen room that is almost never the main cause, and starting there sours every conversation you need to have with the ward, wing or practice manager. What you have is unreturned stock, and most of it left through a door you can name.</>,
},
{
n: "02",
h: "Leavers who were never closed off",
p: <>The single largest cause in most rooms. Someone is issued three sets on their first day, works for two years, resigns, and nobody tells the linen room. The sets are gone and the record still shows them holding stock. This is a process gap, not a stock problem: what you need is a reliable signal from HR, the ward or the practice when someone leaves, and a routine for closing the record and asking for the garments back while there is still someone to ask.</>,
},
{
n: "03",
h: "Size changes that were never recorded",
p: <>A staff member takes a medium, finds it tight, and swaps it at the shelf for a large. Two garments have now moved and the record shows one. Do it a hundred times a year and your per-size figures drift far enough that ordering becomes guesswork. The fix is cheap: make the exchange a recorded action the old size back, the new size out, in one movement rather than something people do quietly because the proper route is slow.</>,
},
{
n: "04",
h: "Laundry that never came back",
p: <>Garments sent for washing are stock in transit, and transit is where things vanish without anyone noticing, because nobody owns the gap. If you send in bulk and receive in bulk, count both ends. A persistent difference between what went and what returned is a conversation with the laundry provider, and it is a conversation you can only have with numbers.</>,
},
{
n: "05",
h: "Damage that was never written off",
p: <>Torn, stained beyond use, or condemned on infection-control grounds. This is legitimate loss and should be recorded as such. If it isn&rsquo;t, it lands in the same bucket as unreturned stock and makes your genuine problem look worse than it is which costs you credibility exactly when you are asking for something.</>,
},
{
n: "06",
h: "Then, and only then, the small remainder",
p: <>When the four causes above are recorded properly, what is left is usually a modest number. That remainder is worth attention, and it is now attention you can direct, because you know it is not laundry, not leavers, not swaps and not damage.</>,
},
];
const PITFALLS: [string, string][] = [
["Issuing to a ward instead of a person", "Stock issued to “Ward 3A” can never be returned by anyone, because nobody holds it. Issue to a named person or accept that it is a write-off."],
["No opening entitlement", "If nobody agreed how many sets a role gets, there is no such thing as too many, and every request is reasonable."],
["Counting loss only in units", "A hundred lost XS gowns and a hundred lost theatre sets are the same number and very different money. Value it, or the case for change wont land."],
["Chasing individuals first", "Going after named staff before fixing the leaver process makes the room unpopular and recovers very little. Fix the doors before the people."],
["Annual review only", "A number produced once a year is a post-mortem. Monthly, it is a control, and you still remember what happened."],
["No agreed definition of loss", "If finance, the ward and the linen room each mean something different by it, the meeting is about definitions rather than uniforms."],
];
export default function Page() {
return (
<>
<GuideMeta
slug="uniform-loss"
title="Where hospital and aged-care uniforms actually go"
description={metadata.description}
updated="2026-09-07"
/>
<GuideHead
kicker="Guide"
title="Where the uniforms actually go"
lede="Almost every linen room — in a hospital, an aged-care home or a clinic — has a gap between what it bought and what it can find. Naming the causes honestly is what turns that gap from an accusation into a work plan."
/>
<Band>
<Steps steps={STEPS} />
</Band>
<Band tone="surface">
<div style={{ fontSize: 11.5, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 800, borderBottom: "2px solid var(--color-text)", paddingBottom: 9 }}>
What makes it worse
</div>
<Pitfalls items={PITFALLS} />
</Band>
<Band>
<h2 style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: "clamp(24px,3vw,36px)", letterSpacing: "-0.02em", margin: 0 }}>
Doing this in ThreadCount
</h2>
<p style={{ ...body, margin: "16px 0 0", maxWidth: "62ch" }}>
Every issue is against a named person, so a leaver&rsquo;s outstanding sets are a list
rather than a mystery. A size change is one recorded exchange rather than two movements
nobody made. Returns carry a condition, so damage is written off as damage. What remains
unexplained stays visible instead of being averaged away.
</p>
<div style={{ display: "flex", gap: 12, marginTop: 24, flexWrap: "wrap" }}>
<Link href="/demo" data-umami-event="open-demo" data-umami-event-placement="guide" className="btn btn-primary">Open the demo</Link>
<Link href="/reporting" className="btn btn-secondary">What the reports show</Link>
</div>
</Band>
<GuideFoot
related={[
["How to run a uniform stocktake", "/guides/uniform-stocktake"],
["Staff entitlements and manager approvals", "/guides/manager-approvals"],
]}
/>
</>
);
}
@@ -0,0 +1,113 @@
import Link from "next/link";
import { Band, body, small } from "@/components/site";
import { GuideFoot, GuideHead, GuideMeta, Pitfalls, Steps, type Step } from "@/components/guide";
export const metadata = {
title: "How to run a uniform stocktake in a hospital, aged-care home or clinic",
description:
"A count that survives scrutiny in a hospital linen room or an aged-care store: what to count, how to split a room into shelves, what to do about garments at the laundry, and how to record a variance.",
alternates: { canonical: "/guides/uniform-stocktake" },
};
const STEPS: Step[] = [
{
n: "01",
h: "Decide what a count is for before you start",
p: <>A stocktake answers one of two questions, and they need different counts. Either you are correcting the on-hand figure so ordering stops going wrong, or you are producing a stock valuation someone in finance will sign. The first can be done shelf by shelf over a fortnight. The second has to be a single point in time with issuing stopped, or the number is meaningless. Most linen rooms need the first far more often than the second, and get into trouble by attempting the second casually.</>,
},
{
n: "02",
h: "Freeze movement, or record it",
p: <>The commonest way a count goes wrong is that garments move while it is happening. If you can, stop issuing for the duration. If you cannot and on a ward or in an aged-care home at shift change you usually cannot then write down every issue and every return made during the count, and apply them afterwards. An unrecorded issue mid-count looks exactly like a loss, and you will spend an afternoon chasing it.</>,
},
{
n: "03",
h: "Break the room into shelves, not into products",
p: <>Count by location, not by catalogue. A person standing at a shelf can count everything on it accurately; the same person asked to count &ldquo;all scrub tops&rdquo; has to walk the whole room, and will miss the bay by the door. Give every shelf and bay a name, count it as a unit, and record the count against that location. It also means two people can count different parts of the room at once without colliding.</>,
},
{
n: "04",
h: "Count by size, always",
p: <>&ldquo;Forty scrub tops&rdquo; is not a usable number. Forty tops that are all XXL is a shortage of every other size wearing a healthy total. Every count line should be item plus size, because that is the level at which you run out, and the level at which you reorder.</>,
},
{
n: "05",
h: "Account for what isnt on the shelf",
p: <>At any moment a large share of your stock is legitimately elsewhere: at the laundry, issued to staff, in a delivery not yet put away, or set aside for a starter pack. None of that is missing, but if your count only covers shelves then all of it reads as a loss. Decide in advance how each of those is treated and be consistent the usual approach is to count shelves only, and compare against expected shelf stock rather than against everything you have ever bought.</>,
},
{
n: "06",
h: "Write down why, not just what",
p: <>A variance with no reason beside it is worthless three weeks later. &ldquo;Twelve fewer size M tops than expected&rdquo; tells you nothing; &ldquo;twelve fewer, ward reported a bin sent to laundry unlogged&rdquo; tells you where to look next time. Make a reason mandatory past a threshold you choose five is a sensible starting point so small counting noise passes without ceremony and real gaps get explained while the explanation is still known.</>,
},
{
n: "07",
h: "Apply it, then look at the pattern",
p: <>Correcting the on-hand figure is the easy half. The value is in what repeats: the same size short every count, the same shelf always over, a variance that appears only after a particular roster. One count is an anecdote. Four counts with reasons attached is an argument you can take to a manager.</>,
},
];
const PITFALLS: [string, string][] = [
["Counting into a spreadsheet nobody reconciles", "A count that never gets applied to the on-hand figure changes nothing. If the spreadsheet is where it ends, ordering carries on from the same wrong number."],
["Recounting only the lines that look wrong", "Recounting a shortfall and accepting every surplus quietly biases the result. Recount by shelf, not by whether you liked the answer."],
["Treating the laundry as loss", "Garments in the wash are stock. Counted as missing, they justify orders you do not need, and the surplus arrives a fortnight later."],
["One person counting their own room", "Not because anyone is dishonest — because you see what you expect. Where the count feeds a valuation, have someone else count at least a sample."],
["No date on the count", "A number without the moment it was true cannot be reconciled against anything. Record when the count was taken, not when it was typed up."],
["Stopping at the total", "The total is the least useful figure in a stocktake. The per-size variance is the one that changes what you order on Monday."],
];
export default function Page() {
return (
<>
<GuideMeta
slug="uniform-stocktake"
title="How to run a uniform stocktake in a hospital, aged-care home or clinic"
description={metadata.description}
updated="2026-09-07"
/>
<GuideHead
kicker="Guide"
title="How to run a uniform stocktake"
lede="Counting a linen room is not hard, and neither is counting an aged-care store or a clinic cupboard. Producing a number that still means something a month later is, and that difference is almost entirely in the preparation."
/>
<Band>
<Steps steps={STEPS} />
</Band>
<Band tone="surface">
<div style={{ fontSize: 11.5, letterSpacing: "0.12em", textTransform: "uppercase", fontWeight: 800, borderBottom: "2px solid var(--color-text)", paddingBottom: 9 }}>
Where counts go wrong
</div>
<Pitfalls items={PITFALLS} />
</Band>
<Band>
<h2 style={{ fontFamily: "var(--font-heading)", fontWeight: 800, fontSize: "clamp(24px,3vw,36px)", letterSpacing: "-0.02em", margin: 0 }}>
Doing this in ThreadCount
</h2>
<p style={{ ...body, margin: "16px 0 0", maxWidth: "62ch" }}>
Counts are taken by location, on a phone, scanning each garment. The expected figure stays
on screen as you go, the tally survives putting the phone down mid-shelf, and a gap past
your chosen threshold asks for a reason before it will commit. Nothing is applied to your
on-hand figures until you commit the count.
</p>
<p style={{ ...small, margin: "14px 0 0", maxWidth: "62ch" }}>
None of which you need in order to follow the steps above a clipboard and a consistent
method will do. It is just faster when the expected number is already in your hand.
</p>
<div style={{ display: "flex", gap: 12, marginTop: 24, flexWrap: "wrap" }}>
<Link href="/demo" data-umami-event="open-demo" data-umami-event-placement="guide" className="btn btn-primary">Open the demo</Link>
<Link href="/features" className="btn btn-secondary">What else it does</Link>
</div>
</Band>
<GuideFoot
related={[
["Where hospital and aged-care uniforms actually go", "/guides/uniform-loss"],
["Charging uniforms to the right cost centre", "/guides/cost-centre-reporting"],
]}
/>
</>
);
}