# ColourLine Clock

An embeddable clock that renders the time in the [ColourLine](https://colourline.info) visual
language — three coloured lines per character — with the ordinary numbers overlaid.

One file, no dependencies, no webfont, no network calls. 24 KB (8 KB gzipped).

![ColourLine Clock: four configurations of 09:41:07 — numbers overlaid, italic with numbers below, bars only, and 12-hour with AM in ColourLine](preview.svg)

**[Live demo and playground →](https://colourline.info/widgets/colourline-clock/index.html)**

## Quick start

```html
<script src="https://colourline.info/widgets/colourline-clock/colourline-clock.js" defer></script>

<colourline-clock format="hh:mm"></colourline-clock>
```

That is the whole integration. The script defines a custom element and starts any clock it finds,
including ones added to the page later.

Three other ways in, depending on how much JavaScript you want to write:

```html
<!-- 1. No custom element: any container marked with data-colourline-clock is filled in -->
<div data-colourline-clock data-format="hh:mm:ss" data-italic></div>

<!-- 2. From JavaScript, into any container -->
<div id="clock"></div>
<script>
  const el = ColourLineClock.mount('#clock', { format: 'hh:mm:ss', animate: 'slide' });
  // el.options = { italic: true };   // re-render with new options
  // el.destroy();                    // stop the timer and remove the element
</script>

<!-- 3. Static: an SVG string for a fixed time, with no clock running at all -->
<script>
  document.body.innerHTML = ColourLineClock.renderSVG({ time: '09:41', italic: true });
</script>
```

`renderSVG()` also works under Node (`require('./colourline-clock.js')`), which is how
[preview.svg](preview.svg) above is generated — useful for emails, Open Graph images or anywhere a
live clock is not welcome.

## Options

Every option is an attribute on the element, a `data-` attribute on a container, or a key in the
options object. Attribute names may be written with or without the `data-` prefix.

| Attribute | Values | Default | |
|---|---|---|---|
| `format` | `hh:mm`, `hh:mm:ss` | `hh:mm` | With seconds, the clock ticks once a second instead of once a minute. |
| `hours` | `24`, `12` | `24` | `hour12` and `data-24hr` are accepted as aliases. |
| `numbers` | `overlay`, `below`, `off` | `overlay` | `overlay` centres the numeral on the glyph; `below` sets it underneath, specimen style. |
| `hide-numbers` | boolean | — | Shorthand for `numbers="off"`. |
| `italic` | boolean | `false` | The 7° right shear of ColourLine Italic. The baseline stays put; the bars lean. |
| `animate` | `fade`, `slide`, `none` | `fade` | `fade` morphs each bar's colour into the next; `slide` rolls the changed digit upwards. |
| `bars` | `gapped`, `touching` | `gapped` | `gapped` is the canonical 18-unit gap that the font ships with; `touching` is the poster reading. |
| `palette` | `solid`, `deuteranomaly`, `protanomaly`, `tritanomaly` | `solid` | The three simulation palettes match CPAL palettes 1–3 in the font. |
| `meridiem` | boolean | `false` | Sets AM/PM beside the clock, in ColourLine at half height and top-aligned. Its letters follow `numbers`, so they are overlaid, set below, or absent along with the rest. 12-hour mode only. |
| `timezone` | IANA name, e.g. `Europe/London` | local | Falls back to local time, with a console warning, if the zone is unknown. |
| `tracking` | number, in em | `0` | Extra space between glyphs. The glyphs already carry the font's side bearings. |
| `duration` | milliseconds | `380` | Animation length. `0` is the same as `animate="none"`. |

Boolean attributes are true when present (`italic`) and can be set explicitly
(`italic="false"`).

## Sizing and styling

The element is `inline-block` with an aspect ratio that matches whatever it is currently
rendering, so it behaves like a piece of type: set one dimension and the other follows.

```css
colourline-clock { height: 2.6em; }        /* the default — scales with the surrounding text */
colourline-clock { height: 180px; }        /* fixed height, width follows */
colourline-clock { width: 100%; height: auto; }  /* fill the container */
```

The internals live in a shadow root, so nothing on your page can leak in and break the layout.
These custom properties are the way through:

| Property | Default | Applies to |
|---|---|---|
| `--clc-number-color` | `#fff` | The overlaid numerals |
| `--clc-number-halo` | `rgba(18,22,23,.6)` | Their outline, which is what keeps them readable over yellow and over black |
| `--clc-number-font` | system sans stack | All numerals. Set to `inherit` to use the page's font |
| `--clc-label-color` | `currentColor` | Numerals in `below` mode |
| `--clc-ease` | `cubic-bezier(.2,.85,.25,1)` | Animation easing |

```css
/* On a dark background */
colourline-clock { --clc-label-color: #fff; }
```

## Behaviour

- **Ticking** is scheduled to the next whole second or minute rather than on a fixed interval, so
  the clock does not drift, and it re-syncs when a hidden tab becomes visible again.
- **Animation** only touches the glyphs that actually changed. `prefers-reduced-motion: reduce`
  turns the transitions off.
- **Accessibility**: the host element is `role="img"` with an `aria-label` of the current time
  (including AM/PM in 12-hour mode), and the SVG itself is hidden from assistive technology.

## Why not the webfont?

ColourLine ships as a real COLR/CPAL font, and for setting text that is the right tool —
see [github.com/mbsduk/colourline-font](https://github.com/mbsduk/colourline-font).

A clock wants things a font cannot give it: individual bars that can be animated as they change,
the italic shear (still unreleased as a font), the simulation palettes without `font-palette`
support, and a first frame that is correct before anything has finished downloading. So this
widget draws the fourteen glyphs it needs — the ten digits, the colon, and A, M, P for AM/PM — as SVG rectangles,
straight from the geometry in `colourline-v1.json`: 1000 units per em, 820 tall, 340 advance,
80-unit bars, 18-unit gaps. Nothing is fetched at runtime.

The encoding is canon: every digit shares a blue first bar, and the colon is green-red-indigo.

## Hosting

`https://colourline.info/widgets/colourline-clock/colourline-clock.js` is served from this
repository's deployment. Copy the single file into your own project if you would rather not depend
on it.

## Development

```sh
node make-preview.js     # regenerate preview.svg from the renderer
python3 -m http.server   # then open /widgets/colourline-clock/index.html for the playground
```

There is no build step. `colourline-clock.js` is the shipped file.

Browser support: any browser with custom elements and shadow DOM — Chrome, Edge, Firefox and
Safari 15+.

## License

MIT — Copyright © 2026 MBSD. Same terms as the font and the rest of ColourLine.
