@arclux/brand
v2.0.2
Published
Arclight brand components — logo, wordmark, lockups, attribution badges, favicon and watermark, as self-contained Lit web components
Maintainers
Readme
@arclux/brand
The Arclight identity as self-contained Lit web components — logo, wordmark, lockups, attribution badges, favicon and watermark. Type is embedded as subsetted WOFF2, so a badge renders in the right face with no external request and no dependency on what the host page happens to load.
pnpm add @arclux/brandPeer dependency: lit ^3.3.0.
Which entry point
Importing this package does not define elements. Reach for the narrowest door that does the job:
| You want | Import |
| ------------------------------- | ------------------------------------------------- |
| One element | @arclux/brand/by (and friends — see below) |
| Every element | @arclux/brand/register |
| The classes, to register myself | @arclux/brand |
| Themeable markup, no JS | @arclux/brand/inline |
| The mark's shape as numbers | @arclux/brand/geometry |
| A file to download or link | @arclux/brand/assets/logo-lg.svg, /favicons/* |
| The favicon, imperatively | @arclux/brand/install-favicon |
| Colours | @arclux/brand/palette |
import '@arclux/brand/by'; // defines <arclight-by>Elements
<arclight-logo>
| Prop | Values | Default | Description |
| ------------ | ----------------- | ------- | -------------------------------------------------- |
| size | sm, md, lg | sm | 28, 48 or 96px tall |
| shape | round, square | round | Which drawing to use |
| animated | boolean | false | Breathe the rings; paused while off screen |
| decorative | boolean | false | Hide from assistive tech, inside a labelled lockup |
--logo-size overrides the height size sets.
<arclight-wordmark>
| Prop | Values | Default | Description |
| ------ | ---------------- | ------- | ----------------- |
| size | sm, md, lg | sm | Font size variant |
--arclight-wordmark-tracking overrides the tracking.
<arclight-logo-wordmark>
| Prop | Values | Default | Description |
| -------- | ------------------- | ------------------------ | ----------------------------- |
| layout | inline, stacked | inline | Horizontal or vertical lockup |
| href | URL string, or "" | https://arclight.build | Empty renders a non-link span |
<arclight-by> · <arclight-powered-by>
Attribution badges — "by ARCLIGHT" and "Powered by ARCLIGHT".
| Prop | Values | Default | Description |
| ------ | ------------------- | ------------------------ | ----------------------------- |
| size | sm, md | md | <arclight-powered-by> only |
| href | URL string, or "" | https://arclight.build | Empty renders a non-link span |
--arclight-label-font substitutes the label face.
<arclight-loading>
| Prop | Values | Default | Description |
| ------------ | ---------------- | ------- | ----------------------------------- |
| size | sm, md, lg | md | 28, 48 or 96px mark |
| fullscreen | boolean | false | Cover the viewport behind a scrim |
| label | string | "" | Announced, and shown under the mark |
<arclight-favicon>
Points the tab at the Arclight mark. Renders nothing.
| Prop | Values | Default | Description |
| ----- | ---------- | ------- | --------------------------------------- |
| svg | SVG markup | "" | Custom artwork; omit for the brand tile |
Prefer installFavicon() from @arclux/brand/install-favicon when you are already in a script.
<arclight-watermark>
Decorative brand mark behind page content. Renders nothing to the DOM — it is drawn by one
pseudo-element, masked so it takes the host's color.
| Prop | Values | Default | Description |
| ---------- | ---------------------------------------------------------------- | -------- | ---------------------- |
| mode | logo, tiled | logo | Single mark or repeat |
| size | sm, md, lg | md | 120, 240 or 400px wide |
| opacity | number | 0.04 | |
| animated | boolean | false | Slow opacity breath |
| position | center, top-left, top-right, bottom-left, bottom-right | center | |
Theming
These components declare no design tokens. They read the ones they need with fallbacks —
--text-primary, --text-ghost, --accent-primary-rgb, --accent-secondary-rgb, --space-md,
--ease-out-expo, --transition-fast, --interactive-focus — so they render correctly on a page
with no design system at all, and a value you set on :root or a [data-density] region still
reaches inside their shadow roots.
That is a deliberate divergence from arc-ui, which pins tokens on :host and re-opens them with a
:where(...) list in base.css. No arclight-* tag needs adding to that list; adding one would do
nothing.
The marks use currentColor; the wordmark uses --text-primary. On a light background, set color
on a parent.
Motion
Every element honours prefers-reduced-motion, in one place — src/base-styles.js. Nothing
animates by default except <arclight-loading>, which is a loading indicator. The logo's pulse is
opt-in (animated) and pauses when the mark scrolls off screen or the tab goes to the background.
Two forms of every mark
src/assets/svg/*.svg keeps literal brand hex, because those are also the files people download and
point <img> at, where currentColor would render black. @arclux/brand/inline carries the same
marks with currentColor and per-asset id prefixes, for inlining into a themed page:
import { inlineSvg } from '@arclux/brand/inline';
const markup = inlineSvg('logo-wordmark-inline', { idPrefix: 'footer', title: 'Arclight' });pnpm generate produces both from the one source. Do not unify them.
Geometry
The arc and orb, as numbers, for a canvas or shader that needs to line up with the mark:
import { logoLg } from '@arclux/brand/geometry';
logoLg.arc.crown; // { x: 1505.015, y: 1338.546 } — the apex, in viewBox units
logoLg.arc.radius; // 1617.066Derived from the SVGs by pnpm generate, so it cannot drift from the drawings.
Updating the artwork
- Drop
.svgfiles insrc/assets/svg/, or replacesrc/assets/favicon.svg. pnpm generate— rebuildslogo.js,inline.js,logo-geometry.jsandfavicon-svg.js.pnpm favicons— re-rasterizesfavicons/from the favicon artwork.
Generated files are committed because they ship in the tarball, which means they can drift from their sources without the diff looking wrong. CI regenerates and fails on a difference.
Updating the fonts
pnpm embed-fonts re-subsets the two embedded faces from the sources in fonts/ and rewrites the
base64 modules. Each module also exports the character set it was built for, and the test suite
asserts that covers every string the components render — a subset missing a glyph falls back to
another face mid-word, which is invisible in review.
Development
pnpm preview # the component gallery
pnpm test # smoke suite; runs in bare Node, which is also the SSR gate
pnpm lintUpgrading from 1.x
See MIGRATION.md.
