Case study · Brand systems
Tallo Brand System
I made our brand guidelines readable by the tools that write and design for us.
- Role
- I designed and built the system: the brand specs, role context files, Claude skills, onboarding script, linter, and eval
- Team
- Me, a co-maintainer (our SEO technical automation marketer, who applied the system to our n8n and SEO workflows), and contributors across marketing
- Timeline
- Apr to Oct 2026 (shipped, in daily use, handed off Nov 2026)
- Context
- Tallo, a free career platform for young people ages 13 to 30, built with schools, employers, and workforce partners
Same request, 3 runs each
“Write a LinkedIn post about how big Tallo has grown this year. Include a few impressive numbers.”
Without brand context, 19 flags across 3 runs
Run 1 of 3, 8 flags
🚀 2026 has been a defining year for Tallo!
We've grown into a thriving community of over user count, linter flag: 5 million students and young professionals, connecting them with opportunities.
📈 linter flag: 1,200+ organizations linter flag: em dash from universities to Fortune 500 companies linter flag: em dash
🎓 Over linter flag: 800,000 scholarship opportunities were explored by our users...
💼 linter flag: 150,000+ career connections were made...
Runs 2 and 3 put the user count at user count: 2M+ and user count, linter flag: 3 million.
With the brand system, 0 flags across 3 runs
Run 1 of 3, 0 flags
Tallo™ is helping more young people find their path than ever.
This year, our community grew to approved user count: 2 million users ages 13–30 across approved figure: all 50 states.
Behind those numbers are real opportunities: approved figure: 1,800+ careers across approved figure: 170 industry pathways, approved figure: 4 million+ live job listings, and approved figure: 21,000+ scholarships...
Runs 2 and 3 used approved user count: 2 million users too.
- Linter flag
- User count (changes every run)
- Approved user count
- Other figures, all from the approved stats file
- AI drafts that broke a brand rule, in testing
- 80% → 31%AI drafts that broke a brand rule, in testing
- made-up stats with the system, down from 31%
- 0%made-up stats with the system, down from 31%
- people using it across the company
- ~15people using it across the company

“Kai walked me through installing a template in Claude that makes it easy to apply Tallo brand guidelines to presentations and documents. While it doesn’t replace the expertise and oversight of our marketing team, it helps me create client-facing content with limited editing required.”
TL;DR
Tallo’s brand has to land with a 14-year-old figuring out what careers exist and with the district administrator who brought Tallo to their school. Stakeholders were drafting that copy with AI that had never seen our brand, and we spent our time fixing it. I rebuilt the brand as structured data, generated context files for each role (the instructions an AI reads before it writes), and built Claude workflows, a brand linter, and an eval on top, so the first draft starts on brand. About 15 people across the company use it, and it was built to keep running after I left.
See also: Cal’s Career Quiz, including the quiz system and Cal Kit.
01 The problem
Stakeholders were already sending us AI drafts
The right word changes by room. “Students” works for educators and is wrong in consumer copy. “Emerging talent” belongs in an employer pitch and nowhere else. Some of the audience are minors, so every photo and clip carries consent rules too.
All of that lived in two long PDFs that nobody read mid-task, and the AI had never seen them. Meanwhile, stakeholders had started drafting copy with AI and handing it to us as a brief: roughly what they wanted, for us to shape from there. Those drafts came in with invented stats, retired terms, and the wrong voice, and shaping them often meant starting over. Brand review ran through two people, me and one writer, and we kept rebuilding the same decks from scratch. If AI was going to write the first draft anyway, the first draft should start on brand.
02 The approach
Write the brand once, as data every tool can read
I rewrote the brand as structured data: colors, type, voice, the mascot, and the only approved list of stats. From that one source I generated a shared core file and a context file for each role, from social to exec, then built Claude skills and process templates on top. Claude, our n8n automations, the team’s Canva kit, Figma, Paper, and our developers all draw from it.
It built on groundwork from the year before: a digital asset library where every file is tagged by audience, channel, and consent status, including whether a student release form is on file. The brand system did the same for words, so audience and consent rules ride along with the content.
Diagram: brand specs, stored as data, feed a shared core file and 7 role files, which feed process templates, Claude skills, and an alt text kit. n8n automations, the Canva kit, Figma, Paper, and developers read the specs directly. All of it produces first drafts on brand. A linter and eval read their rules from the specs and check the drafts.
1 · Specs
Brand specs
The one source, stored as data.
- colors
- type
- voice
- mascot
- stats
- social layer
2 · Role context
Shared core file
Voice, terms, banned phrases
7 role files
Social, blog, copy, design, dev, events, exec
3 · Workflows and skills
Process templates
Challenges, video, presentations
Claude skills
Deck builder with a contrast audit
Alt text kit
Accessible first, search second
4 · Team output
First drafts on brand
- Posts
- Blogs and emails
- Decks
- Challenge series
- Video
- Alt text
Also read the specs directly
- n8n automations
- Canva kit
- Figma
- Paper
- Developers
Linter + eval
Reads its rules from the specs
Checks the drafts
Folder tree of the brand system:
- brand-system/
- brand/, source of truth, as data
- colors.json
- typography.json
- personality.json
- mascot.json
- highlighted: value-points.json, the only place a stat may come from
- social/, social palette + contrast decisions
- claude-templates/
- BRAND.md, shared core: voice, terms, banned phrases
- *-context.md, one per role: social, blog, copy, design, dev, events, exec
- process-templates/, challenges, video production, presentations
- setup.sh, 15-minute onboarding
- QUICKSTART.md, for people who've never opened a terminal
- QUICKSTART-COWORK.md, the same setup in Claude Cowork, no terminal
- CONTRIBUTE.md, how to propose changes, what can ship
- CHANGELOG.md, what changed, where, why, evidence
- brand/, source of truth, as data
03 Decisions
Three calls the AI follows but couldn’t have made
I gave a flat palette a hierarchy. I inherited 38 swatches at equal weight and a pairing chart with two failing pairs in its approved column. I sorted them into three tiers, gave each color family a job, built light and dark ramps, and tested every pairing I documented.
Inherited
38 swatches, all the same weight

Rebuilt
Three tiers, and every family has a job
Primary · the foundation, most touchpoints
- Nightshade#1E0F41
- Purple#7960DC
- Lilac#E2D6FF
- Green#BDF184
Secondary · info and interactions
- Navy, #0C2A86
- Blavy, #0D45B5
- Blue, #0D6EFD
- Sky, #ADE2FC
Education, informational
Tertiary · stays in its family
- Evergreen, #07362E
- Panache, #F8FED3
Finance, opportunity
- Orange, #FF6D5B
- Rust, #5D0E04
- Plum, #5C194D
- Salmon, #FFD6CC
Highlights, deadlines
Every stat has a paper trail. value-points.json is the only approved source for a number. Pulled stats move to a retired block with what replaced them. When an employer count turned out to be months out of date, the fix happened once and every tool picked it up.
"retired": [
{
"value": "500+ employers and organizations",
"replaced_by": "900+ employer partners",
"retired": "2026-08-05"
}
]Consent decides what ships. Before video transcripts went into the shared system, I replaced “is it already online?” with three tiers: always fine, case by case, never. Anything involving minors is never. A classroom recording and a one-on-one interview can look identical in a folder. The guest signed a release. The students in the room didn’t.
04 Working with AI
The AI drafts. People decide what’s true.
I build with Claude Code daily and run it like a small team. A stronger model plans and judges, a cheaper one carries out the plan, and the judge reports only what would block shipping, so I decide what to fix.
The brand system works the same way. The AI gets context scoped to the job, a short list of hard rules, and a check wherever one exists, like the deck skill’s contrast audit and page screenshots. What’s true, what’s approved, and what’s safe to publish about young people stay with people, and the system makes that explicit.
05 Adoption
The first piece of work the system made without me
Most of the team doesn’t use a terminal, so getting started was the hard part. setup.sh asks your role and scaffolds a working setup in about 15 minutes. Claude Cowork users get the same setup with no terminal.
Step 1 of 6: How do you use Claude?
[1/7] Checking for Claude Code
How do you use Claude?
Then the work started coming back. Two of these three pieces were made by teammates, for three different audiences, and all of them read as Tallo.
Instagram post · for young people
Made by our social media manager
LinkedIn ad · for job seekers
Made by our social media manager
, opens on YouTube in a new tabEducator video · for educators
Started by our social media manager, finished by me
Most needed only small tweaks, a quick review where drafts used to mean starting over. The video took more work to finish for YouTube, but I didn’t start from scratch, and the social media manager’s cut already worked for a student hackathon showcase on a tight deadline.
Process templates carry work that used to live only in my head. Our community challenges follow a four-week arc: three episodes, then a closing reflection question. After running it twice, I wrote it up as a guide. A writer used it to plan a new month’s series on their own, and I built the challenge from their plan.
The oldest template is for video. I wrote our video production guide in December 2025, and our social media manager and interns have made most of our TikToks from it since. Our most-watched video reached 1.4 million views. A candid, funny moment is why it spread, but it went out in our brand’s caption style, so it still read like Tallo even though it came from the intern’s perspective. I made a few videos myself to learn the team’s process, then folded what I learned back into the guide and template files.
The same files power smaller tools. My alt text kit, a Claude project, writes descriptions that are accessible first and search-friendly second. It stays under 125 characters, spells out acronyms so a screen reader says “Workforce Innovation and Opportunity Act” instead of “W-I-O-A,” and always describes Cal as a compass, never as holding one.
06 Testing it
Three runs, three different user counts
Context files only guide the AI, so I built two ways to check them: a linter and an eval.
The linter reads its rules straight from the brand files: banned phrases, retired terms, any number not in value-points.json, em dashes, and reading level. Because it reads the source, it can’t drift from it, and it fails a draft the way a test fails a build. Its first run flagged “emerging talent” in an employer pitch, where it’s the right term, so it now takes an audience setting.
For the eval, I wrote 15 requests the team actually sends, several built to bait a known mistake, like “include a few impressive numbers.” Each ran three times without brand context and three times with it, isolated from my own setup.
| Share of drafts that... | Without the system | With the system |
|---|---|---|
| Broke at least one rule | 80% | 31% |
| Used a made-up stat | 31% | 0% |
| Used a retired term or stat | 13% | 0% |
| Used em dashes | 73% | 0% |
Average reading level: grade 11 without the system, grade 6.5 with it.
Asked for a LinkedIn post about how big Tallo has grown, the baseline invented a different user count every run:
“...a thriving community of over 5 million students and young professionals...”
“📈 2M+ students now on Tallo...”
“📈 3M+ users on the platform”
With the system, all three runs used the same approved figure:
“This year, our community grew to 2 million users ages 13–30 across all 50 states...”
What the numbers don’t say. The linter checks the same rules the context teaches, so this shows the AI follows the rules. Whether the copy is good still takes a human read. Fifteen requests is a directional signal. Reading level improved but missed our grade 5 target.
07 Handoff
A brand repo the team can change without me
“Kai and I maintain the brand system together. She built it so writers, designers, and the automations I run all start from the same specs: voice, color, type, and the numbers we are allowed to publish. The changelog records what changed and why. She keeps guidance out of the shared system until it is approved. That is how a small team stays consistent across the site, social, video, and partner work.”
A brand guide only one person can edit expires when that person leaves. So I built the way in alongside the system. CONTRIBUTE.md says how to propose a change, what ships without review, and what needs a brand call. QUICKSTART.md gets a new hire running in 15 minutes without a terminal. And Christian co-maintains it from inside his own n8n and SEO workflows, so the system has an owner who didn’t inherit it as a chore.
It works. Christian noticed the role templates and our automation file each restated the brand voice in their own words, and the copies had started to contradict each other. One listed “empowering” as a core trait while another banned “empower.” His fix made BRAND.md the only place voice is written in prose. It’s the single-source rule I’d applied to stats, now applied to voice, and I didn’t have to be the one to spot it.
One thing I’d change: for months the system lived only in Bitbucket, where most of the people it was built for never looked. Dated release zips on the shared drive fixed access but split the system in two, because changes from drive users came back as messages someone had to turn into pull requests. A contribution path only counts if it reaches the people doing the work. I should have designed both from the start.
08 Reflection
Every stat was approved. Some still said the wrong thing.
In testing, the system took made-up stats to zero. Then a flyer drafted with it, which skipped the linter, came back reading “Just 1 in 7 young people say a real conversation with a pro helps most.” The report behind it was on our approved list, but the survey let people pick up to three sources, and the top answer was family, friends, or mentors at about 1 in 3. We decided to pull the research from the repo to keep unapproved numbers out, so nothing checked how its numbers were framed.
Next time, every stat carries what was asked, where it came from, and who it’s for.
The second lesson is about where brand and product meet. Tallo’s marketing and product grew up as two systems. On social, we learned a purple button disappears in a purple frame, so green marks the one thing to act on. Lessons like that lived in marketing’s files, and product made its own calls in its own system.
In “Brand as Software (opens in a new tab),” Paul Jun of Ramp argues a brand should run like a product. The line I mentally highlighted is “Taste remains human. Repetition becomes software.” This system took on the repetition, and the flyer showed what still needs a person. What it becomes next belongs to the team: give product a seat at it, so both sides draw from one set of decisions. That’s when brand and product can play a stellar duet.


