We use cookies to understand how this site is used. You can accept or reject them — see our Cookie Policy for details.

Release notes

Everything shipped in srcdev-hair-treatments, newest first. Check here before upgrading, especially for anything marked Breaking. Found a bug? Let us know via the contact form.

v1.2.0

September 11, 2026

v1.2.0
Changed
  • createHairTreatmentslicenseKey can now be passed inline on the config object (createHairTreatments({ licenseKey })), matching how every other setting is already passed; the old two-argument form (createHairTreatments(config, licenseKey)) still works. Fixes two real consumers who guessed the inline form and silently shipped unlicensed.

v1.1.3

September 10, 2026

v1.1.3
New
  • config.text.recommendations — the Results colour-recommendation card's method/notes/details copy (previously hardcoded in matrix.ts) is now configurable per hair-colour combination, alongside new config.text.recommendationFallback, texturedHairNote, and sameShadeNoteFormat fields, so the whole card can be localised like the rest of the wizard
Fixed
  • The Results recommendation card showed hardcoded English text regardless of locale — the underlying suitability classification (which combinations are "great" vs "not-recommended") stays internal, but every string shown to the user is now sourced from config

v1.1.2

September 10, 2026

v1.1.2
New
  • config.text.labels — a handful of UI strings that were still hardcoded directly in component templates (the "no cut today" skip option, the hair-type-excluded note, the treatment-conflict message, and the granular shade catalog's "All Shades" tab) are now config-driven like the rest of the wizard's copy, so they can be localised or overridden
Fixed
  • The "Powered by GuideMyHair" link now shows on every step for a non-Premium license (including trial), not just the Results screen
  • Consuming apps on Node versions below 24 could hit a missing @oxc-transform binding on deploy (e.g. Vercel) — engines.node >= 24.0.0 is now declared in package.json

v1.1.1

August 19, 2026

v1.1.1
New
  • remoteCheck.ts — logs a one-time (per page load) console.warn when the periodic remote license check-in fails, distinguishing a Content-Security-Policy connect-src block from a genuine network error/timeout (previously indistinguishable to script, and both silently ignored — the check still fails open either way, this only adds visibility). A CSP block gets a message naming the exact fix (add https://guidemyhair.com to connect-src); a non-2xx response is flagged as a guidemyhair-side issue, not the consumer's.
Documentation
  • Documented the connect-src requirement, and why a failed remote check never downgrades functionality (the plan itself is already cryptographically authoritative in the signed license token), in .claude/skills/private/licensing.md.

v1.1.0

August 18, 2026

v1.1.0
New
  • behaviour.theme — switch the component's colour treatment via config: "default" (existing dark brand-coloured canvas), "monochrome-light" (white canvas, foreground darkening to near-black), or "monochrome-dark" (same dark-canvas/light-text layout as "default", with brand hue removed). Neither monochrome theme carries any hue anywhere the default theme uses brand colour — both use a new dedicated chroma-0 grey ramp (--mono-00--mono-10, added to dist/tokens.css) instead of --brand-*, so they stay fully desaturated even if you've customised your app's --brand-* tokens.
  • behaviour.sharpCorners — set true to square off every rounded corner (option cards, buttons, panels, the license watermark). Deliberately circular/pill shapes (the circle swatch, the checkmark badge, progress dots/bars) are unaffected.
  • Storybook: new Theme select and Sharp corners boolean controls, plus MonochromeLightTheme, MonochromeDarkTheme, and SharpCorners stories.
  • The colour recommendation on the Results step now notes when you've picked the exact same granular shade for both your natural and dream colour (e.g. Jet Black → Jet Black) — e.g. "You've selected your current shade (Jet Black) — this refreshes rather than changes your colour" — instead of silently presenting it as if it were a meaningful colour change.
Fixed
  • The option button and colour-swatch outline is now invisible at rest and only appears on hover/focus, instead of showing a static ring at all times.
  • A selected option's swatch ring no longer reverts to the generic hover colour instead of staying checked-green when the option is both selected and hovered at once.
  • The header's progress bar was a fixed 12rem width regardless of the step label's actual rendered text width, so on longer labels ("Step 7 of 7 — Results") it read as an underline that stopped partway through the text instead of spanning it. Now always matches the label's width.
  • Removed a redundant, visually-duplicated progress line above the step content that repeated the header's own progress label. The screen-reader announcement of step changes moves onto the header's progress label itself (aria-live="polite") rather than a separate hidden element — if you've replaced the header slot with custom markup, add the same aria-live="polite" aria-atomic="true" to your own progress text to keep step changes announced (documented in README).
  • The "No cut today" / "I don't want any treatments" cards had their label and sublabel visually misaligned (label sitting low, sublabel's text stranded at the top of an oversized box) — both now share one vertical centre with the icon.
Changed
  • Several --option-*/--option-swatch-* default values changed as part of the outline-visibility fix above — if you've overridden any of these, or hardcoded them elsewhere (e.g. in your own docs), check against the new defaults in README's "Overriding Styles" reference:
    • --option-outline-width / --option-swatch-outline-width: 1px2px
    • --option-swatch-border-width: 3px1px
    • --option-outline-color / --option-swatch-outline-color: now theme-driven (var(--_outline-default), transparent) rather than a fixed value
    • --option-outline-offset-hover: calc(0.1 * var(--_rem)) (~1px) → 0
  • Per-step swatch style overrides in the Dream Colour, Natural Colour and Results steps were removed — they duplicated what are now the shared defaults above.

v1.0.1

August 17, 2026

v1.0.1
Fixed
  • TreatmentConsultant — root element collapsed to near-0 width in consumers using container-type: inline-size, since size containment blocks the shrink-to-fit calculation margin-inline: auto relies on to center it; now sets an explicit inline-size: 100% so containment has nothing to break, while max-inline-size and margin-inline: auto keep capping and centering it as before

v1.0.0

August 16, 2026

v1.0.0
New
  • Redesign — reordered the wizard to ask Natural Colour before Hair Type (feedback was that leading with hair type felt backwards); added a persistent header (brand/title + live progress) and per-step explainer content above each selection step to fill the previously-sparse early steps
  • Granular shade catalogs — Natural Colour and Dream Colour can now opt into a tabbed catalog of ~40 named shades each (behaviour.naturalColourMode/dreamColourMode: "granular") instead of the broad 7-item grid, backed by real photography (43 dream + 34 natural shades) and a new scripts/convert-shade-images.mjs pipeline; gated to Premium plans, silently falling back to the basic grid below that
  • Grey coverage — new independent question on the Natural Colour step (config.greyCoverageOptions), tracked and shown on Results but excluded from suitability/autoAdvance logic
  • Retina images — shade/hair-type images gained an optional image2x, rendered via srcset, cutting standard-DPR download size roughly 3x with no change for consumers who don't provide a retina asset
  • OptionSwatch (renamed from CircleSwatch) — now supports circle/square/portrait/landscape shapes via a variant prop, plus new hover tokens for border/outline width and image scale; a new behaviour.swatchVariant config option sets the shape wizard-wide
  • ApplicationTypeOption foil-placement warnings — Highlights, Lowlights, and T-Section now warn for curly/coily hair (placement needs adjusting for shrinkage/curl pattern), using the same warnForHairTypes/warnings pattern already used by cuts
Fixed
  • Results summary card order now matches actual step order, and the summary grid no longer leaves a half-empty trailing row
  • Granular catalog no longer hard-blocks the wizard when its shade list is empty on a Premium license (falls back to the basic grid instead)
  • Results summary thumbnails now get a real srcset, not just src
  • Raw rem literals in TreatmentConsultant.vue/OptionButton.vue that caused misaligned label/sublabel on the "no cut today" option — a new scripts/check-raw-rem.mjs lint check (wired into npm run lint and CI) catches this class of regression going forward
Changed
  • --option-border/--option-outline shorthand tokens split into -width/-color pairs so consumers can override just one independently
  • Circle promoted to the implicit default swatch shape (no modifier class emitted)
  • ShadeTabs dropped role="tablist"/tab ARIA in favour of aria-pressed on plain buttons, matching the existing toggle-button-group pattern rather than implying unimplemented roving-tabindex keyboard nav
  • Vivid Red bumped from #E31B23 (read as natural auburn) to #FF1E1E for clearer separation from the natural palette

v0.4.0

August 11, 2026

v0.4.0
New
  • Plain HTML embed builddist/embed.js is a standalone entry point for sites with no bundler and no Vue app of their own. Vue is bundled in, so a single <script type="module"> tag is all that's needed. Every [data-hair-treatments] element on the page auto-mounts its own TreatmentConsultant instance, configured per-element via data-config (JSON) and data-license-key. The change/complete Vue emits are bridged to native, bubbling hair-treatments:change/hair-treatments:complete CustomEvents. Ships alongside a new dist/embed-style.css (exported from the package) and a tokens.css requirement, same as the main build.
  • "Powered by GuideMyHair" badge — a discrete link now appears bottom-right of the results screen for Basic and Standard license plans. Premium licenses, and any unlicensed/invalid state (already covered by the existing watermark), don't show it.
Documentation
  • embed skill — new consumer skill covering the plain-HTML/CDN embed flow: usage, multiple instances, per-element config, license key, event bridging, and known limitations. Cross-linked from setup.md and index.md.
  • licensing skill (private) — new developer-facing skill documenting the license verification architecture, the repo split with the sibling guidemyhair sales site, and where plan-gated UI (like the powered-by badge) hooks in.
  • treatment-consultant skill — documents the licenseKey prop and the licensing/plan behaviour (watermark vs. powered-by badge vs. Premium).
Tests
  • Added embed-focused Vitest coverage: DOM auto-mounting, the double-mount guard, data-config JSON parsing (valid and invalid), data-license-key passthrough, and change/complete event dispatch.

v0.3.1

August 3, 2026

v0.4.0
Added
  • Periodic remote license revocation check. On top of the existing local JWT verification (signature, expiry, domain), TreatmentConsultant now does a cached, best-effort check-in against guidemyhair's license API to catch a license that's been canceled or expired server-side even though its token is still validly signed and unexpired.
    • Checked once per 24 hours per license key (cached in localStorage), not on every page load.
    • Fails open: a network error or an unreachable guidemyhair never revokes a locally-valid license — only an explicit "inactive" response from the server does. A customer's site is never broken by our uptime.
    • New "revoked" license status, with its own watermark message ("This license is no longer active.").
Notes
  • No prop or config changes — this is transparent to existing consumers of licenseKey.
  • Requires the corresponding guidemyhair server endpoint (/api/license/verify), which is already live.

v0.3.0

August 2, 2026

v0.3.0
New
  • licenseKey prop — RS256 JWT-based license verification (via a new licenseKey prop or matching plugin option). Unlicensed usage now renders a visible watermark overlay instead of silently working. Verification runs client-only, checking signature, expiry, and domain (wildcard + www support, localhost always allowed), and re-checks automatically whenever licenseKey changes after mount.
Documentation
  • README — documented the <ClientOnly> workaround needed for a Nuxt SSR crash (this package has no SSR render; the wizard has no SEO value, so it should be rendered client-only in Nuxt)
  • README — noted that omitting the plugin's createHairTreatments install triggers a Vue inject() warning, visible in the server terminal on SSR or the browser console on client navigation depending on how the route was reached

v0.2.4

July 6, 2026

v0.2.4
Features
  • Split the single font token into a 3-tier system for finer typographic control:
    • --treatment-consultant-font-body (renamed from --treatment-consultant-font-family) — default text, sublabels, notes
    • --treatment-consultant-font-heading — step titles, Results title, section titles, suitability label
    • --treatment-consultant-font-label (new) — small uppercase UI chrome (progress status, option labels), defaults to font-body so it's a no-op unless overridden (75579c3)
Chores
  • Rename --treatment-consultant-font-display to --treatment-consultant-font-heading for clarity (75579c3)
Docs
  • Update README, Storybook demo, and skill docs for the new font token names (75579c3)

Breaking: consumers overriding --treatment-consultant-font-family must rename it to --treatment-consultant-font-body. Consumers overriding --treatment-consultant-font-display must rename it to --treatment-consultant-font-heading.

v0.2.3

July 6, 2026

v0.2.3
Features
  • Add global app configuration plugin (createHairTreatments / HAIR_TREATMENTS_CONFIG_KEY) (#1) (c6ccf34)
  • Add i18n text support and merge the config/types split into a single canonical module (a46cddf)
  • Add shared OptionButton atom, used across all selection steps and results summary cards (2a70f97, ee01972, b620f94)
  • Add colour ramps and rename CSS custom properties to semantic names (--brand-*, --success-*, --warning-*, --error-*) (ce2fb63)
  • Add fluid typography scale and make component sizing self-contained via --_unit, independent of the host app's root font-size (dbceae7)
  • Wire up accent font and update default font family (dbceae7, 39dd4ae)
Fixes
  • Align Results step option buttons with the styling used by other steps (2e92116)
Chores
  • Remove unused font file (8bfd77d)
Tests & Docs
  • Add component integration tests for TreatmentConsultant (26fa50a)
  • Add Playwright visual regression tests for the new OptionButton atom (b620f94)
  • Update tests, README, and Storybook/skills docs to match the above changes (6360533, ee01972)

Breaking: consumers overriding CSS custom properties directly must update to the new semantic token names (--brand-*, --success-*, --warning-*, --error-*).

v0.2.2

June 7, 2026

v0.2.2 — Hair type images & edit-from-results
New features

Hair type image swatches Hair type options now support an image?: string field on HairTypeOption. Default images are bundled with the package and displayed as circular crops in both the Hair Type step and the results summary card, with object-fit: cover for non-square sources. Falls back to the existing pattern text (|||, ∿∿∿ etc.) when no image is provided.

Bundled image assets All default images (hair type swatches and colour swatches) are now shipped with the package under public/images/. Copy them into your app's public directory with: ```bash cp -r node_modules/srcdev-hair-treatments/public/images/. public/images/ ```

Edit from results Summary cards on the results step are now clickable — tapping one navigates directly back to that step. This enters an edit mode where:

  • autoAdvance is suppressed regardless of config
  • A Back to Results button appears in the navigation bar alongside Back / Next, allowing the user to jump straight back without stepping through every subsequent step
  • Edit mode clears automatically on returning to results

text.navigation.backToResults New text config key (default: "Back to Results") for the edit-mode shortcut button label.

Bug fixes
  • Results summary hair type card now shows the hair type's own visual representation instead of a generic scissors icon

v0.2.1

June 7, 2026

v0.2.1
New
  • behaviour.showCutStep — new config flag (default true); set to false to skip the Cut step entirely, mirroring the
    existing showTreatmentsStep pattern
  • Hair Type image swatchesStepHairType now displays a .webp image per hair type; HairTypeOption gains an optional
    image field; defaultConfig ships four bundled images (straight, wavy, curly, coily)
  • Results step — return to any step — clicking a summary item on the Results step now navigates directly back to that step; ConsultantNavigation exposes the action and useTreatmentConsultant handles the jump logic
Documentation
  • release-notes skill — new: documents the standard format and process for generating release notes for this project

v0.2.0

June 6, 2026

v0.2.0
New
  • ConsultationSelections emitTreatmentConsultant now emits update:selections on every step change, giving consuming apps read-only visibility into the wizard state (hairType, naturalColour, desiredColour, applicationType, cut, treatments) without needing to manage the state themselves
Changed
  • TreatmentConsultant is now the only component — the basic variant has been removed; the advanced wizard (previously TreatmentConsultantAdvanced) is now the canonical TreatmentConsultant export
  • Step components extracted — each wizard step (StepHairType, StepNaturalColour, StepDreamColour, StepApplicationType, StepCut, StepTreatments, StepResults, ConsultantNavigation) is now a separate file using provide/inject via consultantKey; no public API change
  • CSS class names simplified — dropped the treatment-consultant__ BEM prefix from all internal classes; CSS nesting under .treatment-consultant {} provides the specificity. Shared styles consolidated into the parent component. CSS bundle reduced from ~55 kB to 20.5 kB (gzip: 3.05 kB)

v0.1.8

April 4, 2026

  • Steps buttons updates (5802db6)
  • Bemify some css classes, consuming app generic classes can apply classes (7cff765)

v0.1.7

April 3, 2026

  • Bugfix - Step to final not available under specific circumstances (67f229c)

v0.1.6

April 3, 2026

  • Add exclusions and warning for cuts based on hair types (7387875)
  • Bugfix - Icon missing from treatment selected in results summary (6da11d4)
  • TreatmentConsultantAdvanced - Add cuts step (5582f58)
  • Applications added to results summary (012883b)

v0.1.5

April 3, 2026

  • TreatmentConsultantAdvanced - New component added and file structure refactor (d7ac79c)
  • Add prices if required (acc0475)
  • settings update (a812b5a)
  • fix(ci): add emnapi optional deps to lock file for Linux CI (909de48)

v0.1.4

March 31, 2026

  • Skills updated (0a7b673)
  • Skills - updated (c8603e7)

v0.1.3

March 30, 2026

  • Publish issue - css missing (2b05a22)

v0.1.2

March 30, 2026

  • Fix - types not being exported (5f56a95)

v0.1.1

March 30, 2026

  • release-it - prepare for release to npm (edeb20f)
  • Claude memory updated (f9a3ea7)
  • Package - Major version bumped plus fix some test breakages (9062454)
  • Packages - all up to date and version pinned (1a593cc)
  • Tests - fix issues due to recent updates (5e2148d)
  • Scroll to top on step change and make treatments (last step) single column (221bc62)
  • Steps transition updated to mirror main content (acaf3ce)
  • Steps button update transition (2015d86)
  • Steps alignment < 768px (5d6f5c9)
  • Steps - Button styles for < tablet 768px (fa98821)
  • global font size reset to base 10 for 1rem (4eb7702)
  • npm run dev spins up Storybook as this is used for component only development. (4a4ab87)
  • Add licensing and commercialisation plan (72daa57)
  • Add configure-treatments skill for consumer developers (437ff2c)
  • Split skills into public/ and private/ directories (d9142ab)
  • Update CLAUDE.md with accurate architecture and testing notes (e061a9d)
  • Fix TS error in matrix.test.ts (5f94026)
  • Add CI workflow and README badges (ecd1caa)
  • Add unit tests — 98 tests across 4 suites (74c3b83)
  • feat: add swatch images for Storybook development (1196db4)
  • feat: ship Claude Code skills with package (df14878)
  • docs: add README with installation, config, and development guide (fb40871)
  • refactor: extract composable, config, and matrix from TreatmentConsultant (89b2378)
  • feat: initial project setup and TreatmentConsultant component migration (f249dd9)