# DevOps Patterns 1.0.0

243 seamless background patterns from the DevOps app's Patterns tab, packaged for the web: SVG tiles, PNG tiles, plain CSS,
Stylus, SCSS, Sass, Less, Tailwind (v4 and v3), an ES module generator with TypeScript types, and a `<dp-pattern>` custom element.
No dependencies. Open [`index.html`](index.html) for the live gallery.

Every pattern has a stable kebab-case slug from its name (`Ring dots` → `ring-dots`); its class is `dp-<slug>`. Browse every
slug, category, tag, knob (with default and range) and file path in [`index.json`](index.json).

URLs below use `https://cdn.htmltool.io/patterns/1.0.0/`; pin the version for immutable caching, or use `latest/` (short cache) to follow releases.

## Plain CSS

```html
<!-- one pattern -->
<link rel="stylesheet" href="https://cdn.htmltool.io/patterns/1.0.0/css/patterns/dots.min.css">
<!-- one category, or everything -->
<link rel="stylesheet" href="https://cdn.htmltool.io/patterns/1.0.0/css/categories/japanese.min.css">
<link rel="stylesheet" href="https://cdn.htmltool.io/patterns/1.0.0/css/devops-patterns.min.css">

<section class="dp-dots">…</section>
```

Or from CSS: `@import url("https://cdn.htmltool.io/patterns/1.0.0/css/patterns/seigaiha.min.css");`

### Recolour with custom properties

Set them on the element or any ancestor; no regeneration needed:

```css
.hero {
  --dp-ink: #0b7285;      /* main colour */
  --dp-paper: #fff9db;    /* background (any colour, or transparent) */
  --dp-accent: #fab005;   /* second colour, where the pattern has one */
  --dp-size: 48px;        /* zooms the tile (strokes scale with it) */
  --dp-opacity: 0.6;      /* 0–1, multiplies ink and accent alpha */
  --dp-angle: 30deg;      /* rotating gradient patterns */
}
```

- **Gradient patterns** (57, `kind: "css"`) are pure `background-*` gradients that read the properties directly.
- **SVG patterns** (186) are drawn as the paper colour plus one masked colour layer per role on `::before`
  (ink) and `::after` (accent), so they recolour too. The class therefore sets `position: relative` and `isolation: isolate`
  (any other non-static position works) and uses both pseudo-elements; content inside stays on top. 123 of them
  work this way, e.g. `dp-seigaiha` or the two-colour `dp-isometric-cubes`.
- `stained-glass`, `de-stijl-blocks`, `memphis`, `sprinkles`, `bunting`, `donuts` use more colours than the three knobs, so their CSS is the tile at its default colours and only `--dp-paper`
  and `--dp-size` apply; recolour them with the JS generator or the element.
- On SVG patterns `--dp-opacity` fades each colour layer as a whole, so where translucent shapes of one colour overlap
  they don't darken each other; the JS generator and the element fade shape by shape, exactly like the app.
- `index.json` lists, per pattern, which `customProperties` its CSS honours.

| Category | Slug | Count | Bundle |
| --- | --- | ---: | --- |
| Lines | `lines` | 31 | `css/categories/lines.css` |
| Checks & Plaids | `checks-plaids` | 16 | `css/categories/checks-plaids.css` |
| Textiles | `textiles` | 19 | `css/categories/textiles.css` |
| Dots | `dots` | 19 | `css/categories/dots.css` |
| Grids | `grids` | 12 | `css/categories/grids.css` |
| Geometric | `geometric` | 22 | `css/categories/geometric.css` |
| Stars & Moorish | `stars-moorish` | 14 | `css/categories/stars-moorish.css` |
| Japanese | `japanese` | 19 | `css/categories/japanese.css` |
| Generative | `generative` | 14 | `css/categories/generative.css` |
| Nature | `nature` | 21 | `css/categories/nature.css` |
| Playful | `playful` | 22 | `css/categories/playful.css` |
| Architecture | `architecture` | 22 | `css/categories/architecture.css` |
| Tech | `tech` | 12 | `css/categories/tech.css` |

## Stylus

Each file has a mixin whose arguments are the custom properties' fallbacks, plus (by default) the class.

```styl
dp-emit-classes = false   // optional, before the import: mixins only
@import 'devops-patterns/styl/patterns/seigaiha'

.hero
  dp-seigaiha(ink: #0b7285, paper: #fff9db, size: 48px)
```

`@import 'devops-patterns/styl'` (index.styl) pulls in all 243; `styl/categories/<category>` one category.
Stylus can't import over HTTP: download the `styl/` folder (or the whole version) and add it to your include paths.

## SCSS

```scss
// optional, must come first: mixins only, no .dp-* classes
@use "devops-patterns/scss/config" with ($emit-classes: false);

@use "devops-patterns/scss/patterns/seigaiha" as p;
.hero { @include p.dp-seigaiha($ink: #0b7285, $size: 48px); }

// everything, or one category
@use "devops-patterns/scss" as dp;
@use "devops-patterns/scss/categories/japanese";
```

## Sass (indented)

```sass
@use "devops-patterns/sass/patterns/seigaiha" as p
.hero
  +p.dp-seigaiha($ink: #0b7285)
```

## Less

```less
@import "devops-patterns/less/patterns/seigaiha.less";
.hero { .dp-seigaiha-mixin(@ink: #0b7285; @size: 48px); }
@dp-emit-classes: false; // optional, after the imports: keep only the mixins
```

## Tailwind CSS

v4: import the utilities; `bg-dp-<slug>` draws the pattern and the knob utilities recolour it from your theme or arbitrary values.

```css
@import "tailwindcss";
@import "./devops-patterns/tailwind/devops-patterns.css";   /* or tailwind/categories/<category>.css, tailwind/patterns/<slug>.css */
```

```html
<div class="bg-dp-seigaiha dp-ink-sky-700 dp-paper-amber-50 dp-size-48 dp-opacity-70">…</div>
<div class="bg-dp-dots dp-ink-[#e8384f] dp-size-[2rem] dp-angle-30">…</div>
```

Knob utilities: `dp-ink-*`, `dp-paper-*`, `dp-accent-*` (theme colours or `[color]`), `dp-size-<px>` / `dp-size-[length]`,
`dp-opacity-<0–100>` / `dp-opacity-[0.4]`, `dp-angle-<deg>` / `dp-angle-[1turn]`. They're also in `tailwind/knobs.css`.

v3: add the preset (download `tailwind/tailwind.preset.js`); `bg-dp-<slug>` sets the image, size, position and paper colour:

```js
// tailwind.config.js
module.exports = { presets: [require('./tailwind.preset.js')] };
```

In v3 the gradient patterns still follow `--dp-*`; SVG patterns use their tile at the default colours.

## JavaScript generator

```js
import { pattern, names } from 'https://cdn.htmltool.io/patterns/1.0.0/js/index.mjs';

const { css, declarations, svg, dataURI } = pattern('seigaiha', { ink: '#0b7285', paper: '#fff9db', size: 48, angle: 30 });
element.style.cssText = css;           // background-color / -image / -size
// svg: the seamless tile (or a rotated fill), dataURI: the same as data:image/svg+xml,…

// one pattern only (small):
import { pattern as seigaiha } from 'https://cdn.htmltool.io/patterns/1.0.0/js/patterns/seigaiha.mjs';
seigaiha({ ink: 'rebeccapurple' });
```

Params: `ink`, `paper` (or `'transparent'`), `accent` (any CSS colour), `size` (px, zooms the tile), `opacity` (0–1),
`angle` (degrees; every SVG pattern and the rotating gradient ones). Every pattern recolours here, including the
multi-colour ones. Types: `js/index.d.ts` (`PatternName` is the union of all slugs).

Script tag (defines `window.DevOpsPatterns` with all data):

```html
<script src="https://cdn.htmltool.io/patterns/1.0.0/js/devops-patterns.min.js"></script>
<script>document.body.style.cssText = DevOpsPatterns.pattern('dots', { ink: '#e8384f' }).css;</script>
```

## Custom element

```html
<script type="module" src="https://cdn.htmltool.io/patterns/1.0.0/elements/index.mjs"></script>
<!-- or a classic script: <script src="https://cdn.htmltool.io/patterns/1.0.0/elements/devops-patterns-elements.min.js"></script> -->

<dp-pattern name="seigaiha" ink="#0b7285" paper="#fff9db" size="48" style="min-height: 240px">
  <h1>Slotted content sits on top</h1>
</dp-pattern>
<dp-pattern name="isometric-cubes" accent="crimson" angle="30" opacity="0.8"></dp-pattern>
```

| Attribute / property | Meaning |
| --- | --- |
| `name` | Pattern slug (also accepts the name or `dp-` class). |
| `ink`, `paper`, `accent` | Any CSS colour (`paper="transparent"` too). |
| `size` | px (`48` or `48px`); zooms the tile. |
| `opacity` | 0–1, multiplies ink and accent alpha. |
| `angle` | Degrees. |

Attributes are reflected as properties (`el.ink = 'teal'`); every change re-renders. The element is `display: block` and
paints itself through a `:host` rule, so your own CSS (`dp-pattern { … }`) still wins. `el.result` holds the last render
(`{ css, svg, dataURI, … }`); events `dp-render` and `dp-error` bubble. It fetches only the pattern it needs
(`js/patterns/<slug>.mjs`); if `js/index.mjs` is loaded, `register(patterns)` (exported by `elements/index.mjs`) skips that request.
Types: `elements/index.d.ts`.

## Files

```
1.0.0/
  index.json, index.html, README.md
  svg/            <slug>.svg (seamless tile at the defaults)
  png/            <slug>@2x.png
  css/            devops-patterns(.min).css, categories/<category>(.min).css, patterns/<slug>(.min).css
  styl/ less/     index, config, categories/<category>, patterns/<slug>
  scss/ sass/     _index, _config, categories/_<category>, patterns/_<slug>
  tailwind/       devops-patterns.css (v4 @utility), knobs.css, tailwind.preset.js (v3), categories/, patterns/
  js/             index.mjs, core.mjs, index.d.ts, devops-patterns(.min).js (classic), patterns/<slug>.mjs
  elements/       index.mjs, index.d.ts, devops-patterns-elements(.min).js
  demo/           gallery styles and script for index.html
```

Browser support: the CSS uses `color-mix()` and `mask-image` (Chrome/Edge 120+, Safari 16.4+, Firefox 113+).
