Changelog
Unreleased#
Fixed narrow reference metadata and prose-table readability. Current family voice pages put the title before a compact, expandable source explanation; shared browser coverage now checks the Voice page at narrow widths.
Established the company description and marketing architecture: independent product identities with secondary Cosmik endorsement, truthful demonstrations and useful next steps. Updated the family voice-page presentation to distinguish current product messaging from pinned shared guidance.
Removed superseded guide documents and archived alternate artwork from the current tree; recover them from Git history. Removed Historical navigation from the shared reference sites.
Versions follow semver; release tags are vX.Y.Z. Newest first. Family kits carry their own version in family.json; from 0.8.0 they live in their own repositories.
0.16.1 · 26 October 2026#
Licensing names COSMIK LABS, LLC. No token, mark, font or control changes; the baseline token version stays 0.11.0, so families' extends is unchanged.
Licence.
LICENSE.mdno longer says Cosmik is not a company or other legal entity. COSMIK LABS, LLC holds the copyright in this repository's own material and the Cosmik marks; the MIT notice reads "Copyright (c) 2026 COSMIK LABS, LLC", and the brand-use policy names COSMIK LABS, LLC where it named the owner of Cosmik Labs. Sections, grants and permissions are otherwise unchanged. Fonts keep their own OFL notices. The change applies from this release; earlier tags keep the terms they were published with.Guide. The identity guide's names table adds COSMIK LABS, LLC as the legal name for notices, and the identity and voice guides drop "not a company" while keeping "never imply a larger team". The voice guide now asks not to write like a press release.
0.16.0 · 26 October 2026#
Glass keeps the theme's tone. Choosing a tone from the content behind each surface made viewport controls flip between light and dark as a colourful scene moved under them, which read as jarring and scripted. Glass now stays dark in the dark theme and light in the light theme over anything, and gets its legibility from filtering the backdrop instead. Not breaking for markup; the baseline token version moves to 0.11.0, so families update extends and re-check their glass tints against the new contract.
Backdrop filter per tone. After the shared blur and
saturate(1.4), each tone appliescontrast()thenbrightness(): dark glasscontrast(0.75) brightness(0.5)dims the backdrop and lowers its contrast; light glasscontrast(0.5) brightness(1.35)lowers its contrast and brightens it, mapping black to a light grey and leaving white just short of clipping. New tokensglass.darkandglass.light(contrast,brightness), published as--c-glass-contrastand--c-glass-brightnessin each mode's block, so they follow the theme anddata-glass-tonelike the colour roles. Baseline-only.Lighter tints. With the filter doing the work, the tint drops from 60 % to 31 % on the dark tone (
#12121250) and to 56 % on the light tone (#FFFFFF8F), the most translucent values that pass over any backdrop with a small margin. The scene keeps a 2.42:1 (dark) and 2.05:1 (light) luminance ratio between its brightest and darkest content behind the glass.Contract: any backdrop. Each tone's text and
glass-muted(4.5:1), quiet control text including on the pressed tint (4.5:1), focus and selection (3:1), and the hover and pressed ramps are now checked over the full 4,913-colour grid, passed through the tone's filter as Chromium paints it (measured: per channel in sRGB, saturate clamped, then contrast, then brightness clamped), not over a luminance band. Worst cases: dark text 7.16:1, muted 4.67:1, pressed text 4.67:1; light text 10.24:1, muted 4.68:1. The report adds each tone's scene range.Removed: the tone threshold.
glass.toneThreshold,glass.toneHysteresis,--c-glass-tone-threshold,--c-glass-tone-hysteresisand the RustTONE_THRESHOLDandTONE_HYSTERESISare gone, with the guidance to pick a tone from the backdrop's luminance. Remove any per-backdrop tone switching: glass follows the theme, and switching by backdrop is discouraged because it flips in motion.data-glass-tonestays as an explicit override for a surface or region a product must force.Fallbacks unchanged in kind. No backdrop-filter, reduced transparency,
data-glass="solid"and forced colours stay solid;data-glass="flat"now keeps the tone's saturate, contrast and brightness and drops only the blur, since the tint alone no longer holds. The edge sheen is unchanged.Specimen and checks. Each theme shows its glass over light, dark and busy content, plus one override stage. The browser check asserts every glass surface in a theme paints that theme's tint, text and filter over all three, measures rendered text and muted contrast for each theme over white, black, greys, saturated primaries, stripes and checkers (all must pass; the old "wrong tone must fail" probes are gone), and records how much of the scene shows. The no-backdrop-filter fixture now restores the real stylesheet through its
mediaattribute; re-enabling adisabledlink no longer reapplied it synchronously in Chrome for Testing 156, which failed the reduced-transparency check onmain.
0.15.1 · 25 October 2026#
Pressed no longer looks like letting go. A fix; the baseline token version moves to 0.10.1, so families update extends and re-check their action roles.
Pressed is a deeper hover.
action-*-activeran the other way from hover: in the dark theme the secondary role went lighter on hover and then black when pressed, darker than rest, and in the light theme pressed returned to paper, almost the rest colour; the dark primary went lighter on hover and darker when pressed. Now rest → hover → pressed moves one way: dark secondary#121212→#1F1F1F→#2C2C2C, light secondary white →#E8E7E3→#D6D5D0, dark primary paper →#E8E7E3→#D6D5D0(hover now darkens), and the light primary was already monotonic. This covers every control that uses them: buttons (primary, secondary, quiet, icon), segment options and chips.Glass tints instead of swapping. New translucent roles
glass-hoverandglass-activeper tone (white 8 % and 16 % on the dark tone, black 6 % and 12 % on the light tone). A glass button layers the tint over its fill; quiet buttons and segment options inside a glass surface take the tint. Selected and disabled states are unchanged.Checks. The token check adds
statepairs: each rest → hover → pressed ramp must move one way with pressed at least 1.25:1 from rest and 1.08:1 beyond hover (for glass, over every backdrop in the tone's band, with quiet text at 4.5:1 on the pressed tint). The browser check measures the rendered fill of every control with a pressed state, in both themes and both glass tones, and asserts the same. Both fail on 0.15.0's values.
0.15.0 · 25 October 2026#
Glass loses its solid border: its edge is now a sheen of light caught by the rim. Not breaking for markup; the baseline token version moves to 0.10.0, so families update extends.
Edge sheen. Each glass surface draws a 1px gradient ring from its
::before, masked to the rim (mask-composite: exclude), so it follows any border radius and never tints the fill. Light comes from the top left: brightest there, fading along the sides, with a fainter return at the bottom right. A glass select draws it on its wrapper. Surfaces are positioned with zero specificity; a glass container that scrolls should scroll an inner element.Roles. New
glass-sheenandglass-sheen-low, translucent, per tone. Dark: white at 65 % fading to white at 20 %. Light: white at 95 % (a highlight that shows on mid-tones) fading to black at 25 %, a faint lower edge that keeps the shape on light content.glass-borderis now the plain, subtle border of the solid fallbacks (#414141dark,#C6C5C0light).Token.
glass.sheenAngle(160°),--c-glass-sheen-angle, baseline-only; families may tint the sheen roles.Contrast contract. A glass surface's own edge is decorative and no longer needs 3:1 against the content behind it. The 3:1 non-text requirement applies to what identifies the controls on glass: icons (the text colour), selection and focus, all checked over each tone's band. A standalone glass button or select trigger is identified by its label, icon or chevron, which meet 4.5:1, so it needs no boundary of its own; its focus ring keeps the solid halo.
Fallbacks. Without backdrop blur, with reduced transparency or in
data-glass="solid": the solid surface with a plainglass-borderand no sheen. Forced colours: no sheen, a solid system border.data-glass="flat"keeps the sheen.Checks. The panel-edge boundary assertions are gone (the edge contrast is still reported). The browser check asserts every glass surface has no solid border and a masked 1px sheen gradient matching its radius, that the sheen is brighter at the top left than the bottom right over every backdrop in both tones, the plain border in each solid fallback, and the solid system border in forced colours. The token check requires translucent sheen roles.
0.14.0 · 25 October 2026#
Glass you can see through, in two tones that follow the content behind it. 0.13.0's glass, at an 84 % tint, read as a solid surface. Not breaking for markup; the baseline token version moves to 0.9.0, so families update extends and review their glass roles.
Clearer glass. The tint drops to 60 % (
#12121299dark,#FFFFFF99light) over a stronger backdrop:glass.blur24px andglass.saturation1.4. Hairlines are white on the dark tone and black on the light tone;glass-mutedis#C8C8C8and#454545.Glass tones. Each mode is a glass tone.
data-glass-tone="dark"or"light"on a glass surface or a region gives it and its contents that mode's roles (tint, hairline, text, muted, selection, hover, focus) regardless of the page's theme; without it, glass follows the theme as before. The token CSS scopes the themes to[data-glass-tone]as well as[data-theme].Tone threshold.
glass.toneThreshold(0.2) andglass.toneHysteresis(0.05), relative luminances, in CSS (--c-glass-tone-threshold,--c-glass-tone-hysteresis), JSON, DTCG and Rust. Content at or above the threshold takes the light tone, below it the dark tone. Baseline-only.Contrast contract. Glass now holds over the content its tone is for, not over any content: the dark tone over backdrops of luminance 0–0.25, the light tone over 0.15–1. The check reports each pair over its band, and a test proves that each tone fails over the other's extreme, so a product must switch.
Tone crossfade. Glass surfaces transition background, border and text colour with the motion tokens, so a tone change crossfades and reduced motion snaps.
Reference and browser checks. The reference shows both tones over light and dark busy content in both themes. The browser check measures each tone over 12–13 backdrops in its band from screenshot pixels, asserts the wrong tone fails over the other extreme, and asserts a tone overrides the page theme. Fallbacks are unchanged and still checked.
Migrating#
Vendor 0.14.0 and set extends to "Cosmik baseline 0.9.0". Glass over content of varying brightness now needs data-glass-tone chosen from that content; see the interface guide. Families that set their own glass roles re-check them against the bands.
0.13.0 · 25 October 2026#
Glass variants for controls that float over busy or moving content. Not breaking: glass is opt-in per surface and no existing class changes. The baseline token version moves to 0.8.0 (new roles and tokens), so families update extends.
Roles.
glass(a translucent tint,#RRGGBBAA),glass-border(the hairline) andglass-muted(muted text on glass), in both modes. Dark: the dark surface at 84 % over the backdrop, a#C6C5C0hairline and the usual dark muted grey; light: white at 84 %, a#303030hairline and a new#595959muted grey. A family may override them undersemanticlike any colour role.Tokens. A
glassgroup:blur(12px) andsaturation(1.2), in CSS (--c-glass-blur,--c-glass-saturation), JSON (glassandnative.glass), DTCG and Rust (glass::BLUR,glass::SATURATION). Like spacing and motion they are baseline-only: the family contract now rejects aglasssection.Contrast check. Glass roles are checked against the tint composited over every backdrop on a grid of 17 levels per sRGB channel (4,913 colours), saturated as the token says: text,
glass-mutedandaction-secondary-fgat 4.5:1, focus and selection at 3:1, and a boundary at 3:1 where either the hairline or the fill must clear each backdrop. The solid fallback is checked againstsurface. Reports name the backdrop each pair is weakest over. Families get the same checks throughfamily.mjs check.Controls.
c-glass(a container for menus, popovers, hints and labels),c-toolbar--glass,c-button--glass(a standalone button, instead of--secondary, with--iconand--dense),c-segmented--glassandc-select--glass(the trigger). Selection stays opaque with its bar; hover and pressed use the action roles; a standalone glass control's focus ring sits on a solid halo. Inside glass,--c-mutedresolves toglass-muted.Fallbacks. Solid by default and glass only under
@supports (backdrop-filter …); solid underprefers-reduced-transparency: reduce; opaque system colours with the boundary kept in forced colours. Regions may choosedata-glass="flat"(tint, no blur, for where the blur is too costly) ordata-glass="solid".Docs and reference. Interface (when to use glass and when not), colour (the roles and how they are checked), families (the contract) and the consumer guide (classes and markup). The reference shows every glass control over white, black, saturated colours, fine stripes and a checker in both themes.
Browser checks assert the glass roles, blur and selection; measure text, muted text and boundary contrast from screenshots over 14 worst-case backdrops per theme; and prove each fallback (a copy of the layer with the
@supportscondition made false, emulated reduced transparency, bothdata-glassvalues, forced colours) and that a tapped glass button keeps no hover fill.
Migrating#
Vendor 0.13.0, set a family's extends to "Cosmik baseline 0.8.0", rebuild and check. A family that overrides surface or muted heavily should review its glass pairs in the report; override glass, glass-border or glass-muted only if the baseline values do not suit its palette.
0.12.2 · 25 October 2026#
Hover no longer sticks after a tap. Not breaking.
Hover treatments apply only under
(hover: hover). A tap on a touch screen leaves the browser's:hoveron what was tapped, so a quiet button, a segmented option or a chip kept its hover fill after the tap, and an unselected option could look half-selected beside the real selection. The hover rules ofc-button(primary, secondary, quiet),c-segmented__option,c-chip,c-link,c-inputand the select now sit in@media (hover: hover). Pressed (:active) feedback, selection and disabled roles are unchanged on every input.Docs. The interface guide and the consumer guide state the rule; consumers should gate their own hover styles the same way.
Browser checks emulate touch (which reports
hover: none), tap a quiet icon button, a segmented option (then move the selection without a pointer) and a chip (on and off), and assert each keeps:hoverbut shows its resting background. The check fails on 0.12.1.
No token value, mark or font changed; the baseline token version stays 0.7.0.
0.12.1 · 25 October 2026#
A fix to 0.12.0's toolbar controls, found in the first product to use them. Vendor 0.12.1 rather than 0.12.0.
c-segmentedno longer collapses in a shrink-to-fit container. Its tracks wereminmax(0, 1fr), so inside awidth: min-contentor wrapping container the options shrank to their minimum width and their labels overflowed. Tracks are nowminmax(min-content, 1fr): still equal shares of the widest option, never narrower than an option's content. The group takesmax-width: 100%and labels wrap instead of overflowing a narrow container or enlarged text.c-toolbarwraps (flex-wrap: wrap,max-width: 100%) rather than overflowing a narrow container or enlarged text.Browser checks add a shrink-wrapped segmented control whose options must keep their content (it fails on 0.12.0), and the existing 320 px, 200 % text check now covers the toolbar row.
No token value, mark or font changed; the baseline token version stays 0.7.0.
0.12.0 · 25 October 2026#
Toolbar controls, found missing while rebuilding a product's viewport toolbars on the kit. Not breaking: existing markup keeps working.
c-toolbar. A bounded group of related controls: the surface role, a border (so it reads over a busy canvas without a shadow; a family elevation shadow may add depth), the medium radius andspace-basepadding and gaps.c-toolbar--verticalstacks it. Role, name and placement are the consumer's.c-button--quiet. A button emphasis with no fill or boundary until hover, for actions inside a toolbar or other bounded group.c-button--icon. A square icon-only button at the button's target size,control-densewithc-button--denseon fine pointers andcontrol-minon touch. It needs an accessible name and a tooltip on hover and keyboard focus.Toggles. A
c-buttonwitharia-pressed="true"takes the selected roles plus a drawn bar along its bottom edge; hover and pressed never erase it.c-segmented. One choice from a few, as aradiogroupofc-segmented__optionradios oraria-pressedbuttons. Every option takes the widest option's width, so the group never resizes when the selection changes. Selection uses the selected roles plus the bar.c-segmented--densefollows the dense button sizes. Options share the focus ring, disabled roles and forced colours.Docs. Shared controls and the interface guide give the markup and rules, including the narrow-width rule for toolbars (drop labels together, keep icons, tooltips carry the names). The component reference shows a toolbar of icon buttons, a segmented control and a toolbar combining both, in both themes.
Browser checks assert, in both themes, the toolbar's border, surface and spacing; square 32 px dense icon buttons; quiet buttons with no fill until hover; no transform when pressed; pressed toggles and checked options in the selected roles under hover and pressed, with the drawn bar; equal option widths and an unchanged group width after arrow keys move the selection; the segmented focus ring; at least 44 px targets under touch emulation; and the toolbar boundary and selection bars in forced colours.
No token value, mark or font changed; the baseline token version stays 0.7.0.
Migration#
Re-sync. Replace local toolbar surfaces, icon buttons and segmented groups with
c-toolbar,c-button c-button--quiet c-button--iconandc-segmented. Remove any pressed-state scaling: the rules allow colour changes only.
0.11.0 · 24 October 2026#
A dense status label for compact contexts. Not breaking: c-status is unchanged.
c-status--dense. Add it to ac-statuslabel inside a dense row, header or card. It keeps the pill shape, the neutral status roles and thelabelfamily, weight, tracking and uppercase, at theui-smallsize and line height with tighter padding (0/space-2), aspace-basegap and aspace-6minimum height. A label is not a target, so it keeps that size on touch. Likec-statusit has no hover, pressed, focus, transition or pointer cursor, and in forced colours it takes the text colours.Docs. Shared controls and the interface guide describe when to use it. The component reference shows it beside the dense button and the standard status label in both themes.
Browser checks assert, in both themes, the
ui-smallsize and line height, the same family, weight and tracking as the standard label, the pill, default cursor, no focusability or transition, unchanged roles under forced hover and pressed, tighter padding, thespace-6minimum height belowcontrol-dense, the same size under touch emulation and the same forced colours asc-status.
No token value, mark or font changed; the baseline token version stays 0.7.0.
Migration#
Re-sync. Replace local compact status pills (smaller font, tighter padding) with
c-status c-status--dense.
0.10.0 · 24 October 2026#
Three refinements to the shared controls, found by using them on real pages. Not breaking: existing markup keeps working; c-status changes appearance.
c-statusreads as a label, not a button. It now uses thelabeltype role (IBM Plex Mono, its tracking and its uppercase transform), the full radius, which no control uses, the neutral status roles andcursor: default. It has no hover, pressed, focus or transition. In forced colours it takes the text colours (CanvasTextonCanvas) instead ofButtonText.c-select--denseandc-input--dense. Putc-select--denseon the select wrapper orc-input--denseon an input:control-denseand theuitype role on fine pointers, with the chevron and its clearance scaled to match; on coarse pointers they return tocontrol-minand thebodytype, so focusing one never zooms a mobile page.c-button--large. A taller target (control-min+ 3 ×space-base, 56 px at the baseline) and wider padding (space-4/space-8) for a page's prominent call to action. The type scale has no larger control step, so the label keeps thecontrolrole. A mechanism only; no product default.Docs. Shared controls and the interface guide describe the new sizes and the status label's rules. The component reference shows large, standard and dense buttons beside a status label, and dense fields, in both themes.
Browser checks assert the status label's label type, pill shape against the button, chip and field radii, default cursor, no focusability, no transition and unchanged roles under forced hover and pressed; dense fields at 32 px with the
uisize on a fine pointer and at least 44 px with thebodysize under touch emulation; and the large button's target.
No token value, mark or font changed; the baseline token version stays 0.7.0.
Migration#
Re-sync. Pages that styled
c-statuslocally (font, radius, padding) can drop those overrides. A status label inside a link or button should move out of it.Use
c-select c-select--densefor compact selects (footers, toolbars) andc-button--largewhere a product wants a ceremonious call to action.
0.9.1 · 24 October 2026#
Tests. The both-layers CLI test now accepts the platform's path separator;
vendor.mjsprints nested layer paths in native form, so the test failed on Windows in 0.9.0's CI. No tool, contract, token or asset change; of the distributed files onlypackage.json(the version) differs from 0.9.0. Vendor 0.9.1 rather than 0.9.0.
0.9.0 · 24 October 2026#
One distribution contract for every Cosmik brand repository, so a product can sync its product brand, with the foundation that brand was built on, using one tool and verify both layers in one check. Breaking for readers of the manifest's vendor section and of vendor.mjs's exports (see migration below).
Distribution contract. The manifest's
vendorsection is nowdistribution: what this repository publishes for consumers to vendor. Each entry is{ "path", "sha256" }; the build refreshes the hashes and the check fails when they differ from the bytes, without ever refreshing an upstream font, licence notice or approved original.package.jsongainsrepository, which names the release in locks. Any repository withname,versionandrepositoryinpackage.json,distribution.filesinasset-manifest.jsonand HEAD exactly atv<version>on a clean tree can be synced.scripts/vendor.mjsworks for any such repository.sync --from <checkout> --into <dir>checks every file against its distribution hash before copying, installs the set only after it verifies, refuses to replace a directory holding a different repository's release, and writes<short name>.lock.json(the package name without its scope:brand.lock.jsonhere,brand-tectra.lock.jsonfor@cosmiklabs/brand-tectra). Locks arelockfileVersion2 and addpackage.Nested layers. When a synced set contains a lock (a product brand's
vendor/brand/brand.lock.json),verifyalso checks that layer's files against it and names a change in both layers;--releaseproves the outer lock against its tag.verifyandsyncprint every layer.lockfileVersion1 locks from 0.8.0 still verify, with--releaseagainst a 0.8.0-shaped release too.Docs. Vendoring a release explains how a product consumes its product brand and how organisation surfaces consume this repository; publishing a product brand states what a
brand-<product>repository must publish.Tests sync a fictional product brand that vendors this release, check both layers, nested tampering (including an edited outer lock and an edited nested lock caught by
--release), refusal of a release whose nested layer is broken, a v1 lock, the--releaseproof on both manifest shapes, and the manifest's distribution hashes.
The family contract in scripts/generate-tokens.mjs, every baseline token value and the baseline token version (0.7.0) are unchanged; families' extends stays "Cosmik baseline 0.7.0", and family outputs change only in their provenance header.
Migration#
Product brand repositories: re-sync with
node <brand>/scripts/vendor.mjs sync --from <brand> --into vendor/brand, rename the manifest section that described the vendored foundation (it was also calledvendor) to thebrandreference plus adistributionthat lists your own deliverables and every file undervendor/brand/, including its lock; addrepositorytopackage.json. See publishing a product brand.Products (the Tectra app,
website-tectra, HPLX): sync your product brand instead of copying files by hand:node <brand-tectra>/vendor/brand/scripts/vendor.mjs sync --from <brand-tectra> --into vendor/brand-tectra, thenverify vendor/brand-tectrain CI. Loadvendor/brand-tectra/vendor/brand/kits/cosmik/tokens/cosmik.css, thenvendor/brand-tectra/tokens/tectra.css, then the optionalvendor/brand-tectra/vendor/brand/kits/cosmik/components/controls.css.Code reading
manifest.vendorreadsmanifest.distribution.files[].path.vendor.mjsno longer exportsvendorSetorLOCK; usedistributionSet,lockFileNameandfindLock.verify()also returnslockFileandlayers.Existing 0.8.0 locks keep verifying; re-sync to write a version 2 lock.
0.8.0 · 24 October 2026#
This repository now holds only the shared Cosmik foundation. Product families move to their own repositories, which build on a pinned release of this kit and can prove it. Breaking for consumers of the removed paths (see migration below).
Split. Remove
kits/hplx/andkits/tectra/(tokens, marks, icons, guides, the Tectra review board and validation record), their builders (build-glimmer-assets,build-hplx-assets,build-hplx-lockup,build-tectra-assets, the HPLX icon pack inbuild-icons) and tests, and Spectral (fonts/desktop/Spectral-SemiBold.ttf,fonts/web/Spectral-SemiBold.woff2,fonts/licenses/Spectral-OFL.txt). They continue incosmiklabs/brand-hplxandcosmiklabs/brand-tectra. The manifest dropsfamily_identities,tectra_identity,glimmer_assets, the family token entry points and Spectral.Family API.
scripts/family.mjs build|check <familyRoot>builds a family'stokens/family.jsonover the baseline of the checkout the script belongs to, including a copy vendored into another repository.checkfails on a contract violation, anextendsthat does not name this baseline, committed outputs that differ from regeneration, or a failing contrast pair (baseline and extension roles). The contract itself is unchanged.generate-tokens.mjsandvalidate-tokens.mjsexport their pieces;generate-tokens.mjsnow generates only the baseline, byte for byte as before. Family output headers name the brand release that generated them and use relative paths only.Provenance.
scripts/vendor.mjs sync --from <brand> --into <dir>copies the reviewablevendorset listed inasset-manifest.jsonfrom a clean checkout at avX.Y.Ztag and writesbrand.lock.json(repository, tag, commit, SHA-256 per file).vendor.mjs verify <dir>fails on any missing, extra or changed file;--release <brand>also proves the lock against the tag's own bytes.Shared controls.
kits/cosmik/components/controls.cssadds framework-neutralc-button(primary, secondary, dense),c-link,c-input,c-select(native select with a drawn, stroked chevron),c-chip,c-statusandc-focus-ring, bound only to semantic tokens, with hover, pressed, focus-visible, disabled, pending and forced-colour handling. Rules are in interface; the component reference now uses these classes, and the browser check verifies their computed states.Tests. A fictional, test-only family under
tests/fixtures/example/keeps the family path covered: contract violations, drift,extendsmismatches, contrast failures, vendored-path resolution and browser family scopes.
No baseline token value, mark, palette or bundled Inter or IBM Plex Mono file changes; the baseline token version stays 0.7.0, so families' extends remains "Cosmik baseline 0.7.0".
Migration#
Family repositories (
brand-hplx,brand-tectra): movekits/<id>/content to the repository root (tokens/family.json, assets, guide), and HPLX's Spectral files with their notice. Vendor this release withvendor.mjs sync, then runnode vendor/brand/scripts/family.mjs build .andcheck .in CI withvendor.mjs verify vendor/brand. Regenerated outputs are byte-identical to 0.7.0 apart from the provenance header (CSS comment, DTCG$description, Rust comment).Website and other organisation consumers: baseline paths are unchanged. Replace hand-written button, link, field and select styles with
kits/cosmik/components/controls.csswhere they match, loaded after the token CSS. Take any family CSS from that family's repository instead ofkits/<id>/.Tectra app (
packages/brand/sync.mjs): keep vendoringcosmik.css, the fonts and licences from this repository, but taketectra.cssand Latch from abrand-tectrarelease, or switch to that repository's vendored layout. Thekits/tectra/...paths invendor.jsonno longer exist at 0.8.0.[data-family]selectors, token names and generated JSON are unchanged.
0.7.0 · 23 October 2026#
Add a shared motion contract covering entrances, exits, interruptions, focus, reduced motion and pending/completed states, with offline interactive examples for menus, dialogs, tooltips and disclosures.
CSS now exposes normal, system-resolved and effective motion durations. The existing effective duration still follows the OS by default;
data-motionacceptssystem,reduceandfullfor explicit scope overrides. Consumers should use the effective token and apply the same scope to portalled content. Source durations and native exports are unchanged.Overhaul interface composition, responsive density, state/copy guidance, consumer onboarding, quality review and release governance. Correct stale family approvals, asset paths and icon-pack assumptions.
Strengthen token input validation, immutable asset protection, manifest inventory checks, PNG/SVG validation and reproducibility checks. Correct Tectra lockup metadata to match the existing artwork. Add Node 22/24 and Windows CI coverage without introducing dependencies.
Expand browser regressions to test actual exit transitions, cancellation, nested motion policy, short touch layouts and direct file opening. Fix the macOS test browser's keychain-related startup stall.
Clarify the licence with owner approval: written guidance is MIT; marks and artwork keep their separate restrictions, and fonts keep their OFL licences.
No palette, font family or approved artwork changes. Family revisions remain HPLX 0.1.0 and Tectra 0.2.0; both resolve against baseline 0.7.0.
0.6.0 · 21 October 2026#
Behaviour change: a root without
data-themenow follows the operating system's light or dark preference instead of staying dark, and family kits follow with it.data-theme="dark"or"light"still fixes a mode. The guide no longer prescribes a default mode; that is each product's decision.
0.5.0 · 21 October 2026#
Add dense application roles to the baseline, so every kit has them: type roles
ui(Inter 500, 14 px) andui-small(Inter 500, 12 px), and layoutcontrol-dense(32 px). The interface guide says where they apply: navigation, menus, toolbars and lists for a pointer, while touch keeps 44 px targets and forms keepcontrol. Families inherit them as utility type. Nothing existing changes.
0.4.0 · 21 October 2026#
Breaking layout change. Each kit now lives in one folder: kits/<kit>/ holds its tokens/, assets/, icons/, specimen and validation. tokens/<kit>/ becomes kits/<kit>/tokens/, assets/vector/ and the other baseline art move under kits/cosmik/, family art under kits/<family>/assets/, and tokens/README.md becomes kits/README.md. File names inside the kits are unchanged except Tectra's specimen (kits/tectra/specimen.html). Consumers must update their paths.
Add
package.jsonscripts (build,check,test,check:browser,check:reproducible) and a CI workflow that fails if committed generated files differ from a fresh build.checkdiscovers every test instead of a fixed list.The browser check loads every declared font face before asserting it loaded; it previously failed whenever a face was declared but unused on the page.
Rewrite the README as an entry point; baseline masters and evidence move to the baseline kit. Replace the stale "Tectra family draft" notes with the approved family's summary.
Tectra family 0.2.0 · 21 October 2026#
Rename the Tecton family to Tectra, the product's name. Paths, token names, the
data-familyselector, specimens, tests and the generator move fromtectontotectra;[data-family="tecton"]no longer applies. Lockups are regenerated with the outlined Inter label "Tectra". The Latch geometry, palette and every other value are unchanged.
HPLX Glimmer · 17 October 2026#
Adopt the approved compact Glimmer as the official HPLX symbol, with five transparent variants and matching Spectral lockups.
Canonical manifest paths select Glimmer. Preserve Ember assets and builders as deprecated historical compatibility files. HPLX theme values and Tecton remain unchanged.
Tecton family 0.1.0 · 17 October 2026#
Add the approved original angle-only Latch, five transparent symbol variants and matching outlined Inter lockups. Preserve exact source paths; document clear space and minimum sizes.
Owner-approved mineral/teal theme. Angle-only Latch symbol and Inter lockups approved; rendered browser accessibility checks remain unverified.
Improve specimen accessibility: scalable HTML diagram legends, 14 px small labels, wrapping, explicit pressed states, forced-colour treatment and board-specific regression coverage.
Mark the former organisation motto for retirement/replacement; no new motto adopted.
Lead Tecton presentation with creative benefits and intended workflow; exclude implementation architecture and unannounced commercial terms.
Add approved mineral/teal family tokens and offline review board, with Inter inherited throughout. Theme values and applications approved by owner.
Extend component selection and browser regression coverage to Tecton. No existing family values or parent rules changed. No product release or consumer rollout.
HPLX family approval · 15 October 2026#
HPLX family approved (owner, 2026-10-15): its palette, amber accent, Spectral headings, status hues and elevation, unchanged. Two rules join the guide: desktop products (the HPLX app and editor) follow the system theme until the person picks System, Dark or Light; dense tool panels (the HPLX Editor) use 28 px rows with a 24/32 px density setting, every target still at least 24 px.
HPLX small icon (accepted): an optical redraw of Ember for 16, 24, 32 and 48 px, where the faithful mark's upper arc vanishes: the same composition, drawn on whole pixels with thicker arcs (their top edges as shallow as the master's) and a larger diamond, from
kits/hplx/assets/ember-small.source.json.hplx-ember.icoand.icnsuse it up to 48 px; the Cosmik icons are unchanged.HPLX lockup (accepted): Ember centred above HPLX in Spectral SemiBold, the lettering the owner chose, set as outlines from the bundled font with its own advances and kerning plus tracking.
scripts/build-hplx-lockup.mjsbuilds primary (the banner, on the dark plate), amber, bone and ink SVGs at 2172 × 724 with full-size and 1024 px PNGs fromkits/hplx/assets/hplx-lockup.source.json.scripts/font-outlines.mjsreads the font; it adds no dependency.Vector lockup (accepted): the horizontal banner as vectors.
scripts/trace-cosmik-lockup.mjsoutlines the COSMIK wordmark from the approved banner (which stays unchanged) and places the accepted emblem master where the banner shows it;scripts/build-cosmik-lockup.mjsbuilds off-white, ink and primary SVGs at the banner's 2172 × 724 composition with full-size and 1024 px PNGs. The wordmark overlaps the banner by 99.1%; the master emblem differs slightly from the banner's own drawing (93.6%). Evidence is inkits/cosmik/validation/lockup-qa.jsonandlockup-trace-overlay.png.
0.3.0 · 8 October 2026#
HPLX Ember symbol: added the owner's selected original Ember (diamond above two shallow arcs), faithfully reconstructed as clean vector geometry. SVG variants, transparent PNGs and square platform-icon derivatives rebuild from
kits/hplx/assets/ember.source.json; the manifest exposes HPLX-specific entry points. No wordmark or splash artwork was invented, no consuming product was changed, and all HPLX theme values remain proposed.Theme inheritance: family CSS now follows the nearest explicit theme, including a dark family inside a light ancestor, using
light-dark()and the inherited colour scheme.Component reference: compare the baseline and proposed HPLX family in the same specimen. Headings consume type roles; tabs, story actions, confirmation dialogs, status hues and elevation examples are interactive. Narrow layouts reflow at 200% root text size.
Verification: headless Chromium checks cover both kits and the new interactions. Font licence notices are hashed immutable inputs; regression checks reject missing or changed notices, including during generated-hash refreshes.
Baseline approved (owner, 2026-10-07): typography, the semantic dark/light roles, layout and component rules. It stays monochrome, as the guide says (§5, §7): the status hues, the shadow role and the elevation levels proposed earlier in this release moved to the HPLX family; the
scrimrole stays.Family kits: product families get their own style on top of the baseline.
scripts/generate-tokens.mjsmergestokens/<id>/family.jsonover the baseline and refuses a family that breaks the contract (every baseline role and mode kept; colours through its own primitives; its own typeface only for heading roles; utility type, spacing, layout, radii, breakpoints and motion fixed). Each family gets the same outputs as the baseline, its CSS scoped to[data-family="<id>"]. The validator checks every kit against the baseline's pairs, plus pairs for a family's own roles.HPLX family (proposed):
kits/hplx/tokens/: warm blacks and bone text, a lantern-amber accent, Spectral 600 headings, the status tonesstatus-{error,warning,success,info}-{fg,bg,border},accent,shadowand elevation levels 1–3. 50 roles per mode; 184 contrast pairs pass.Spectral bundled: Spectral SemiBold (SIL OFL 1.1) for the HPLX family's headings:
fonts/desktop/Spectral-SemiBold.ttffrom Google Fonts' repository, a WOFF2 built byscripts/build-web-fonts.mjs, and its notice infonts/licenses/.Guide in Markdown:
guide/replaces the Word/PDF guide with eight pages of rules and judgement (identity, typography, colour, interface, product families, voice, documents, governance). Values live only in the tokens; the handle iscosmiklabs; the family-kit rules and the endorsement have their own page. The v0.2 Word/PDF guide moved toguide/archive/.Layout: every kit is a folder under
tokens/(cosmik/,hplx/); every script is inscripts/, run throughnode scripts/build.mjsandnode scripts/check.mjs.Licence:
LICENSE.mdsets a split: MIT for tooling and token data (copyright Cosmik Labs contributors), a brand-use policy for the emblem, wordmark and name (official Cosmik projects ship them unmodified; forks remove them), and the fonts' own OFL.Line endings:
.gitattributeskeeps text files LF on every platform; upstream licence notices keep their original bytes. Manifest hashes verify on a Windows checkout and the build reproduces the committed files byte for byte.Native units: each kit's JSON has a
nativesection: px at a 16 px root for spacing, radius, gutter, control height, breakpoints and type sizes; letter spacing as a fraction;lineas characters; easing as cubic-bezier points; durations in ms; colours as hex, sRGB floats and linear floats. The 0.2.0 CSS variables are unchanged, apart from the roles that moved to the HPLX family.W3C DTCG: each kit has a generated
<kit>.tokens.json(Format Module 2025.10). Semantic colours alias primitives; light/dark modes are carried in$extensions["com.cosmiklabs.modes"]with dark as the default value.Rust: each kit has a generated, dependency-free
<kit>_tokens.rs(DARK/LIGHTthemes, primitives, spacing, type, motion).New baseline roles:
scrim; radius scalesm/md/full; breakpointscompact(720 px) andnarrow(380 px); named decorative greys used by the website (divider-strong,ornament,ornament-faint,ornament-text,media-placeholder). 36 semantic roles per mode (was 30).Validator:
disabled-borderon every surface and the disabled fill, andmutedoninput-bgandstatus-bg, are now checked too. Translucent roles are excluded by design.App icons:
scripts/build-icons.mjsbuildscosmik.ico(16/24/32/48/64/256),cosmik.icns,cosmik-512.pngandcosmik-apple-touch-180.pngfrom the plate (primary) variant renders. Node only.Web font:
scripts/build-web-fonts.mjswraps IBM Plex Mono Regular as WOFF2 (every table unchanged; Brotli from Node). The specimen prefers it, with the TTF as a fallback.Manifest: entry points (tokens per kit), a
web_fontslist (family, weight, style, format), font family/weight/style on desktop fonts, arolefor every asset,visible_boundsrenamed tovisible_bounds_xywh,interim_identityandknown_gaps, and hashes for every generated file;scripts/verify-manifest.mjschecks them.Docs:
kits/cosmik/validation/vector-README.txtnames files that exist; the README explains how to pin and consume the kit, including from Rust.
0.2.0 · 4 October 2026#
Added the accepted real SVG emblem, exact geometry color reverses, and tested raster exports.
Kept approved raster originals unchanged and moved generated inverse alternatives to archive.
Distinguished the standalone emblem from the still-unresolved outlined wordmark/lockup.
Replaced incomplete light-mode tokens with 30 complete semantic roles in both themes.
Added synchronized CSS/JSON, a generator, and a dependency-free 94-pair contrast validator.
Added compact local component examples with native field, button, error, selected, focus, and reduced-motion behavior.
Added exact type roles, a 720 px layout breakpoint, live-label and endorsement rules, and a two-page editable document template.
Corrected SemiBold styling in document output.
Marked browser behavior, tiny optical refinement, print proofs, and rights/reuse decisions as remaining work.
0.1.0#
Initial eight-page visual-direction guide and unchanged raster asset bundle.