Tutorials

The Tailwind class that vanishes without an error

A custom type scale and a class merger that ignores it: the shipped HTML loses the class, and nothing says so.

AvancéArticle4 steps

The failure looks like this: the component is handed className="text-body-sm text-foreground", and the built HTML carries only text-foreground. No error, no warning — just text at the default size where the design called for another.

1. Work out what removes the class

tailwind-merge resolves conflicting classes: between px-2 and px-4, the last one wins. To decide, it has to file every class into a group — and it only knows Tailwind’s own groups. A custom scale declared in @theme is unknown to it: text-body-sm gets filed with text colours, is therefore judged to conflict with text-foreground, and is dropped.

2. Reproduce it in a test, not in a browser

The cn function is pure. The test that catches this fits on one line — expect(cn("text-body-sm", "text-foreground")) — and needs neither a build nor a DOM. Chased through the browser, the same failure presents as “a style that doesn’t apply”, and the stylesheet is the first thing you wrongly suspect.

3. Declare the custom scales

extendTailwindMerge takes the theme’s groups: spacing, text sizes, radii. Every value declared there is recognised as such, and stops being mistaken for a colour.

4. Stop the two files from drifting apart

The list handed to extendTailwindMerge has to mirror the @theme block in the stylesheet. Nothing in the tooling holds them together: adding a token without listing it here brings back exactly the same failure, silent in exactly the same place. A comment at each end, and one test per group, are what make the omission visible.

Act

Dark themePin the site's appearancesetTheme({theme:"dark"})
Light themePin the site's appearancesetTheme({theme:"light"})
System themeFollow the system preference againsetTheme({theme:"system"})
Switch the site to FrenchFrançaissetLocale({locale:"fr"})
Labs — ProductFilter Labs by typefilterLabs({type:"Produit"})
Labs — PrototypeFilter Labs by typefilterLabs({type:"Prototype"})
Labs — ResearchFilter Labs by typefilterLabs({type:"Recherche"})
Labs — Reset filtersClear every Labs filterfilterLabs({reset:true})
Journal — EngineeringFilter the Journal by categoryfilterJournal({category:"Ingénierie"})
Journal — SecurityFilter the Journal by categoryfilterJournal({category:"Sécurité"})
Journal — Agent-NativeFilter the Journal by categoryfilterJournal({category:"Agent-Native"})
Journal — StudioFilter the Journal by categoryfilterJournal({category:"Studio"})
Journal — Reset filtersClear every Journal filterfilterJournal({reset:true})
Tutorials — BeginnerFilter tutorials by levelfilterTutorials({level:"Débutant"})
Tutorials — IntermediateFilter tutorials by levelfilterTutorials({level:"Intermédiaire"})
Tutorials — AdvancedFilter tutorials by levelfilterTutorials({level:"Avancé"})
Tutorials — Reset filtersClear every tutorials filterfilterTutorials({reset:true})

Services

DiscoveryFrame the product before the first line of code, so the budget builds instead of correcting.openService({service:"discovery"})
Product designAn interface that holds together, carried by a design system your developers can keep alive without us.openService({service:"design"})
Web developmentA fast web application that holds up over time, with the tests and delivery chain to match.openService({service:"web"})
Mobile developmentAn iOS and Android app from a single codebase, published on both stores.openService({service:"mobile"})
Infrastructure & securityInfrastructure described as code, and Zero Trust access that does not rest on a text message.openService({service:"infrastructure"})
Maintenance & evolutionA product kept current, watched and fixed, with someone who answers when it breaks.openService({service:"maintenance"})
Agent-Native Architecture AdvisoryMake an existing product agent-operable without rewriting it — and without opening more than it should.openService({service:"agent-native"})

Go to

YorroProduct engineering studio in Abidjan and Paris. We design, we build, we ship.navigate({page:"home"})
ServicesBuild a product end to end, or advise a team on its agent-native architecture.navigate({page:"services"})
LabsWhat the studio has built: products, prototypes and research, with where each one actually stands.navigate({page:"labs"})
TutorialsStep-by-step guides drawn from real projects, grouped into tracks by topic.navigate({page:"tutorials"})
JournalThe studio's notes and positions.navigate({page:"journal"})
ContactDescribe your project; you get a framing back, not a boilerplate quote.navigate({page:"contact"})
AboutWho runs the studio, how it works, and what it turns down.navigate({page:"about"})
↑↓ move↵ runesc closeOne Actions layer