Tints & Shades Generator Developer Reference
Architecture and maintenance notes for the Tints & Shades Generator runtime, including page ids, state, color conversions, OKLab and CIELAB math, relative luminance, WCAG and APCA contrast, ramp engines, scale generation, canvas renderers, exports, URL state, public API, Library capture and test coverage.
Overview
The Tints & Shades Generator is implemented as a browser-only IIFE in js/tool/tonal-steps.js. The engine
owns sRGB transfer functions, XYZ, CIELAB, LCh, OKLab, relative luminance, WCAG labels, APCA-W3 Lc,
HSL conversion, four mixing engines, full ramp generation, tints, shades, tones, neutrals, 50–950 and
50–900 key ladders, HTML rendering, canvas charts, exports, batch analysis, URL state,
window.AATonalSteps and window.AATonalEngine. The shell in
tool/general/gamut-and-rendering/tonal-steps-tints-shades/index.html declares the controls,
the Lab, Ramps, Contrast, Data, Export and Reference panels, canvases and action buttons;
js/tool/tonal-steps-views.js renders those views, including the standards, formulas and
citations.
1. File map
+- Tool shell:
tool/general/gamut-and-rendering/tonal-steps-tints-shades/index.htmlcontains page metadata, hero content, controls, the six tab panels, canvases, hidden action buttons, fullscreen chart overlay and script includes. - Tool engine:
js/tool/tonal-steps.jscontains the standalone IIFE for color math, generation, rendering, exports, state and API. It also exposeswindow.AATonalEngine, whichjs/tool/tonal-steps-views.jsreads to render the Lab, Ramps, Contrast, Data, Export and Reference views;js/tool/ts/ts-sources.jsholds the dataset register aswindow.AATonalSources. - Library binding:
js/library/tool-bindings.jsregisters/tool/general/gamut-and-rendering/tonal-steps-tints-shades/as tool idtonal-steps, nameTints & Shades Generator, categoryGamut & Renderingand asset typepalette. - Shared runtime capture:
js/library/tool-bindings.jsmapstonalStepstowindow.AATonalSteps.getStateand restore towindow.AATonalSteps.restoreState. - Discovery outputs: documentation additions must flow into
data/documentation.json, RSS, feed, sitemaps, PWA cache manifest and search index.
2. Page shell and UI contract
+- App root:
ts-appwraps the tool and the main workspace ismainwith the labelTints & Shades Generator workspace. - Tabs: tab buttons use
data-ts-taband panelsp-ts-lab,p-ts-ramps,p-ts-contrast,p-ts-data,p-ts-exportandp-ts-reference. - Primary controls: the runtime reads
ts-base-picker,ts-base-hex,ts-engine,ts-mix-mode,ts-steps,ts-gamma,ts-scale-typeandts-vis-toggles. - Output nodes: generated UI writes to
ts-base-info,ts-schemes,ts-scale-output,ts-uniformity-statsandts-contrast-body. - Canvas ids:
ts-ramp-canvas,ts-lightness-canvas,ts-uniformity-canvas,ts-contrast-canvas,ts-gamut-canvasandts-cie-canvas. - Action ids:
ts-copy-hex,ts-copy-css,ts-copy-scss,ts-copy-json,ts-copy-csv,ts-copy-tailwind,ts-export-png,ts-export-lightness,ts-draw-uniformity,ts-draw-contrast,ts-draw-gamut,ts-draw-cie,ts-batch-runandts-batch-csv. - Share id note: the runtime writes the link to the read-only
ts-share-urlfield in the Export tab and binds the hiddents-copy-linkbutton; the visible path is Export, A link to this view, Copy the link. Test this path before changing share behavior.
3. State model
+The runtime state is produced by readState().
hex: validated six-digit base HEX, fallback#2563EB, the page default.engine:hsl,luminanceorcontrast.steps: integer step count, page range 3 through 21, default 11.gamma: gamma bias, page range 0.4 through 2.6, default 1.0.mode: mixing mode, one ofoklab,lab,srgb(what the sRGB linear button sends;srgb-linearis accepted too) orhsl.scaleType:tailwind(page default) ormaterial;customis the fallback when the field is missing.vis: object keyed byramp,tints,shades,tonesandneutrals.
updateAll() generates ramp data, tints, shades, tones and neutrals, updates HTML
outputs, draws the primary canvases, stores the latest data on window.__tsData and
dispatches a ts:updated event, which the views refresh on.
4. Color math
+- sRGB transfer:
srgbToLinear()andlinearToSrgb()implement the IEC sRGB piecewise transfer functions. - HEX and RGB:
hexToRgb()parses six-digit colors andrgbToHex()serializes clipped 8-bit RGB. - XYZ and Lab:
M_S2X,M_X2S,rgbToXyz(),xyzToRgb(),xyzToLab()andlabToXyz()use D65 reference white. - LCh:
labToLch()derives chroma and hue angle from CIELAB a/b values for export diagnostics. - OKLab:
rgbToOklab()andoklabToRgb()implement the OKLab transform used by the recommended mixing path and uniformity charts. - Relative luminance:
relativeLuminance()uses BT.709/sRGB coefficients from linearized RGB. - WCAG:
contrastRatio(),wcagLabel()andbestTextColor()power the contrast table and swatch labels. - APCA:
apcaLc()implements APCA-W3 0.1.9 and returns signed, polarity-aware Lc values for text on white and black backgrounds;apcaLcLegacy()keeps the superseded approximation so the Contrast view can show the difference. - HSL:
rgbToHsl()andhslToRgb()support the HSL ramp engine and HSL mixing mode.
5. Ramp and mixing engines
+- Mixing functions:
mixLinear(),mixLab(),mixOklab()andmixHslEngine()are selected bymixColors(). - Swatch object:
buildSwatch()returns index, ratio, RGB, HEX, HSL, Lab, LCh, OKLab L, luminance, WCAG contrast, APCA contrast, text color and label. - Tints:
generateTints()mixes the base color toward white. - Shades:
generateShades()mixes the base color toward black. - Tones:
generateTones()mixes the base color toward middle gray. - Neutrals:
generateNeutrals()builds a grayscale ladder using step count and gamma. - Scales:
tailwindScale()andmaterialScale()generate named scale stops anchored at 500. - Full ramp:
generateRamp()handles the HSL lightness, Equal luminance and Equal contrast engines. The contrast engine lands on the same colors as the luminance engine, so the Lab view offers two andcontrastis kept for saved links. - Luminance solve:
solveForLuminance()binary-searches HSL lightness for a target relative luminance.
6. Rendering pipeline
+- Base info:
updateBaseInfo()writes the base chip and colorimetric metrics. - Swatch HTML:
renderSwatchSet()renders chips for the visible ramp, tint, shade, tone and neutral sets. - Contrast table: the Contrast view in
tonal-steps-views.jsfillsts-contrast-bodywith each step's WCAG ratio, rating and APCA Lc against white, black or the base; the engine's oldupdateContrastTable()was removed. - Scale output:
updateScaleOutput()renders Tailwind or Material scale chips. - Uniformity stats:
updateUniformityStats()computes mean Delta L, standard deviation and max deviation from OKLab L steps. - Primary canvases:
drawSwatchStrip()draws the ramp preview anddrawLightnessChart()draws OKLab L distribution. - Research canvases:
drawUniformityChart(),drawContrastChart(),drawGamutScatter()anddrawCIEChromaticityDiagram()render deeper diagnostics when the Ramps, Contrast and Reference tabs open. - Device pixel ratio: canvas functions scale backing stores by
window.devicePixelRatiofor sharper exports.
7. Exports, batch and URL state
+- PNG export:
exportPNG()serializes a canvas throughtoDataURL("image/png")and downloads it through an anchor. - Clipboard helper:
copyText()writes tonavigator.clipboardand displays the toast on success. - CSS variables: the Export tab uses
EXPORTERS(exportRampCSS(),exportRampSCSS(),exportRampJSON(),exportRampCSV()), which write--tonal-0and later properties, a$tonalmap, JSON and CSV under a provenance header. The olderbuildCssVars()behind the hiddents-copy-cssbutton outputs--color-0,--color-100and later stops from the main ramp. - SCSS map:
buildScssMap()outputs a named Sass map. - JSON:
buildJSON()exports full ramp diagnostics. - CSV:
buildCSV()exports index, HEX, HSL, Lab, LCh, OKLab L, luminance, WCAG and APCA columns. - Tailwind CSS:
buildTailwindCSS()exports 50-950 custom properties fromtailwindScale(). - Batch:
runBatch()parses HEX input, generates tints and shades, and returns Lab, OKLab L, luminance and count data. - URL encode:
stateToURL()storeshex,engine,steps,gammaandmode. - URL decode:
loadFromURL()restores those fields before initial event binding and render. - URL limitation:
scaleType, visible-set toggles and batch input are preserved by full Library state, not by the current share URL.
8. Public API and library binding
+- API:
window.AATonalSteps = { getState, restoreState }. getState(): returns{ state, data, batchInput }, wherestateisreadState(),datais a deep copy ofwindow.__tsDatawhen available andbatchInputis the batch textarea value.restoreState(saved): accepts either the full object or a bare state, applies known controls, restores visible-set toggles, restores batch input and schedules an update.- Simple Library capture: the route binding scans a host node for HEX colors and saves a palette preview when at least two colors are found.
- Capture data: simple capture stores
preview_data.colorsandasset_data.colors. Full runtime capture can preserve the richerAATonalStepsstate. - Simple restore note: the generic binding still references older ids such as
ts-base,tonal-base,ts-generate,tonal-generateandts-render. Preferwindow.AATonalSteps.restoreState()for exact restore on this page. - Storage boundary: the tool itself does not create persistent local palettes. Persistence is handled by Auric Library capture or by exported token data.
9. Extension checklist
+- When adding a ramp engine, update
generateRamp(), theENGINESlist that builds the engine buttons, keyboard shortcuts, standards copy, formulas, docs and tests. - When adding a mixing mode, update
mixColors(), theMIX_MODESlist, export interpretation and uniformity expectations. - When changing the swatch schema, update
buildJSON(),buildCSV(), contrast table rendering, Library state expectations and docs. - When adding scale conventions, create a generator like
tailwindScale(), updateupdateScaleOutput(), add export support and document stop naming. - When changing URL state, update
stateToURL(),loadFromURL(), share UI, Library docs and smoke tests. - When changing control ids, update
readState(),restoreState(), event binding, generated inline click targets, Library simple binding and tests. - When changing canvas dimensions, test DPR scaling, fullscreen copy behavior, PNG export and mobile layout.
- When changing APCA or WCAG logic, update labels and docs because exported accessibility values become different compatibility data.
- Regenerate discovery outputs after documentation changes with
scripts/generate-discovery.mjs,scripts/generate-pwa-cache-manifest.mjsandsearch/client/build-index.js. - Keep user-facing text clear that WCAG and APCA values are guidance metrics, not final legal accessibility certification.
10. Testing and risk notes
+- Boot: verify the Lab tab appears, the default base color renders, the ramp and lightness canvases draw, and the contrast table fills.
- Inputs: test valid and invalid HEX, color picker sync, random color, both
offered engines plus
contrastby URL, all four mixing modes, step extremes and gamma extremes. - Visible sets: toggle ramp, tints, shades, tones and neutrals independently.
- Scales: test the 50–950 and 50–900 key sets and verify 500 remains the anchor stop for named scales.
- Actions: test every Export tab selection (the ramp, the key set, the contrast table, a link) in each offered format, and share URL restore.
- Research: open the Ramps, Contrast and Reference tabs and check the uniformity, gamut, contrast and CIE charts draw; then run batch analysis and batch CSV.
- Keyboard: test
1,2,3andRoutside form controls. - Library: save a palette, confirm preview colors, restore full runtime state and verify visible toggles and batch input return.
- Numerical risk: changes to sRGB transfer, matrices, OKLab constants, luminance coefficients, APCA exponents or gamma handling will alter charts and exports.
- UX risk: very high step counts can crowd swatches and canvas labels on small screens. Verify mobile layout after changing chip sizes or text labels.