diff --git a/CHANGELOG.md b/CHANGELOG.md index 44be04a..40c5d5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- **OneOrigin brand copy: the new palette and marks (approved by the owner, 2026-11-12):** `brand/oneorigin/` is copied again from OnePhylogeny's `docs/oneorigin/` and relocked. It adds the suite's own palette (`palette` in `tokens.json`), the five marks in `marks/` (the suite and the four tools, each light, dark and small), and Palette and Marks sections in `brand.md`. This tool's app icon, tile, heart badge and interface colors are unchanged, because they aren't decided yet. The built CSS is unchanged too, because it doesn't read the palette. + - Example site: import jobs, and a script that clicks through the admin. `apps/payload-example` now turns the plugin's `imports` option on over a new `sources` upload collection that only a curator can read, add to, change or delete, so nobody else can fetch a source file by its address. The seed adds a job waiting to be run and one that failed on purpose, both over made-up files; a job doesn't run when it is made. Uploaded files go in a throwaway folder that is deleted when the site stops (`EXAMPLE_UPLOADS` names a folder to keep instead). The smoke test goes from 58 to 74 checks. New `pnpm click-through` builds the site, opens a Chrome already on the machine with no window and a throwaway profile, signs in as the made-up curator and does a curator's work on all four panels, 40 checks; it installs nothing, needs the network for Payload's code editor, fails on any other request off the site, and isn't in CI. - Payload plugin: three things that script found in the real admin (changes the unreleased plugin). The panels' paragraphs and lists sat flush against each other, because the panel's margin reset outranked its spacing rule; jsdom doesn't lay out, so no test saw it. The reset now carries no weight and the import panel's status and message are spaced too. The form under a panel repeated it: a snapshot's label, id, version, checksum and counts, and an import job's message, checksums, diagnostics, warnings and progress (three of them in Payload's code editor) are now hidden in the form with `admin.hidden`, still in its data, the API and the list's columns. And the "Made-up example data" tag touched the source's title. The docs said every button asks first; running an import never did, and they now say so. - Payload plugin: a snapshot's content is read only when it is asked for by name (changes the unreleased plugin). A stored snapshot can be 15 MB, and Payload read all of it for every list, every relationship it filled in and every admin page. Now a read, create, update or delete that names no `select` answers with every field except `snapshot`; `select: { snapshot: true }`, REST `?select[snapshot]=true` or GraphQL's `select: true` gives the content, and the export endpoint is as before. A caller's own `select` is left exactly as asked. In the admin the content field is on the new-snapshot form only: a stored snapshot's page is sent without the content and without the JSON editor, and Payload's own Save there sends the status alone. Hosts' code that read `doc.snapshot` from a plain read, or from the document an after-read or after-change hook is given, has to select it. The lock on sealed content doesn't depend on this. Fixed on the way: the admin panels showed the old status after Payload's own Save; they now read from the site again whenever Payload reports the document saved. Tested: 10 new tests (8 on a real Payload with an in-memory MongoDB, one of them over HTTP, and 2 in jsdom), 3 new checks over HTTP in the example site (58 in all), and five deliberate breaks, each caught. Also run in headless Chrome on the example site, outside CI: a stored snapshot's page has no content and no editor, a sealed snapshot pasted into the new-snapshot form is stored with the same checksum, and Payload's Save sends one small request. Not explained: in that run, after a snapshot was made through the form and its page loaded again, Payload's read-only Counts group showed no fields under its heading; four shorter runs of the same steps drew them. Not tested: Postgres, SQLite, a browser with a window. See [ADR 0012](docs/architecture/adr/0012-payload-plugin.md), point 17. diff --git a/brand/oneorigin.lock b/brand/oneorigin.lock index a880b56..b2a30f7 100644 --- a/brand/oneorigin.lock +++ b/brand/oneorigin.lock @@ -4,21 +4,36 @@ "repo": "https://github.com/CaptiveOrigins/onephylogeny", "branch": "main", "path": "docs/oneorigin", - "commit": "189c49f90076724c2b9d2c03d130f32b323b8964" + "commit": "35c7993d6915fb8c0622035a50f88b3e1970f4eb" }, "copy": "brand/oneorigin", "files": { "README.md": "sha256:25b8cfbe5df31ba8b18d63138bd82a6511ed88b9c154f081369cd0f003cd8489", - "brand.md": "sha256:43994d8e9271f6f1d555967dfb5733e2658c83b6a35dfb830aaad7d1af50b800", - "guidelines.md": "sha256:67ba425cdace4af5c9ea903b2da6523db609bade2068e5872a29f66bf84a54ea", + "brand.md": "sha256:94556ff48b6e4c29d65d7939cd6ddd37bc568e7bddb17afe977ee2eea19a5763", + "guidelines.md": "sha256:8dfd221189b7d68fcafcb9bc2652830e537374323203fc86436d1936f97fec3f", "icons/block.svg": "sha256:0ebfc31700e1e6ae1ed4c795fc83741503dcb42d73675d120ba3d6d9a0106c12", "icons/connector.svg": "sha256:5e545f134c8514c58282df7dae6c2e97cfab37d404b3df42dc80fe8ba63b0d0d", "icons/heart-badge.svg": "sha256:f755eda3873ad972b660f2a8999d22b65965ffc3f4375294dff0c0a065bb9415", "icons/tile-onepedigree.svg": "sha256:13729ff38e9957e5234515278bf694eb0c1279d7f0cf85e4b62f120758f79c88", "icons/tile-onephylogeny.svg": "sha256:61d6878f648dece5824c96959a2cb1a4a3858a001e8e0ee17284d0d460295f3d", "icons/tile-onetaxonomy.svg": "sha256:154bd2e7ce127e6fcf7f6b1ca2ab048f60f22483a7f96608170869de022b991c", - "tokens.json": "sha256:12c4455d602a0bea90b176ec7abed392a963a15513f658d90a66c02ed563ada5", - "tokens.schema.json": "sha256:f50d21a539fd2993f0b4103ad2e5db107c001117f2677e318a84220f62ff73b5" + "marks/onelineage-dark.svg": "sha256:fa8f1fa2b94b00c58a855feaaf57ea3e225cb6d55671dfdb30e5dcaa8169af53", + "marks/onelineage-light.svg": "sha256:16dc0b05e215de1eeb5cfb2e6b8aac1fc9090327f7aa2ab6df47c879d8f05bdf", + "marks/onelineage-small.svg": "sha256:9d7bd756409427a8a2e5f66cf55ea424f3554e64431bca068d2185489a796a43", + "marks/oneorigin-dark.svg": "sha256:6ba3863205c889adedee4ca7c6e8e2ebb89e56d4537295b4432555d5a3884793", + "marks/oneorigin-light.svg": "sha256:e4cb3c30312cf801185a5981a31a2e498886401b54d6cafa90be8a55e14a6e45", + "marks/oneorigin-small.svg": "sha256:3079a83899865d8cd518b553f62190fef40bba445ae45cd77999f4aa9021577a", + "marks/onepedigree-dark.svg": "sha256:bd67b505812cfbd83d6336a430ede3ea337be73bad6efa03505923726c65712c", + "marks/onepedigree-light.svg": "sha256:827f359f4864710312c66f3661c2a4ba0db27d6d6d64a707fa6d1a125016883f", + "marks/onepedigree-small.svg": "sha256:d8d28ef83825a43c5d1a11f23dc09269d5a6507f8b5492793a2371be562e6247", + "marks/onephylogeny-dark.svg": "sha256:660ac26a9beaa106476e43520be6f39918e7db9c54a31991f5d21f3994e64c1b", + "marks/onephylogeny-light.svg": "sha256:34721e221e59bdb0ea5e79baa8ec8921627e72c4c5f0f07d492c71e5b56a244d", + "marks/onephylogeny-small.svg": "sha256:85bbe784ba67ed724a21ed94eeeaac4a44096d670fe3a05f63852c906fcbffd8", + "marks/onetaxonomy-dark.svg": "sha256:00a491b0b7acb3372ada4feadc9d1e574e49bd3d7b071055032479819b07e91a", + "marks/onetaxonomy-light.svg": "sha256:4cd7410ff4cf6b2cc5c953310cbc05349169816f1116574b2b844c19e77cd7e7", + "marks/onetaxonomy-small.svg": "sha256:ae236afd68280a82d60af711c6be344e5d4cb5c157548d13b830755c7ce6c089", + "tokens.json": "sha256:d87f3fc103e7d3e145f72dd145ae0d48dea4208957d0be20e26786b70253b3a2", + "tokens.schema.json": "sha256:337fa1a63f1fa77a6a8816ee61cf074941e02a428dd64890b2b57cff3bc7cc9b" }, "outputs": { "apps/studio/src/oneorigin.css": "ot" diff --git a/brand/oneorigin/brand.md b/brand/oneorigin/brand.md index f277c37..8ae0d9b 100644 --- a/brand/oneorigin/brand.md +++ b/brand/oneorigin/brand.md @@ -1,11 +1,60 @@ # Brand -OnePedigree, OneTaxonomy and OnePhylogeny are separate tools from one maker: the [OneOrigin suite](README.md). Like a tool family, they share a backbone and keep their own character. The rules are in the [suite guidelines](guidelines.md); the values below are also in [tokens.json](tokens.json), and the shared icon parts are in [icons/](icons/). +OneTaxonomy, OnePhylogeny, OneLineage and OnePedigree are separate tools from one maker: the [OneOrigin suite](README.md). Like a tool family, they share a backbone and keep their own character. The rules are in the [suite guidelines](guidelines.md); the values below are also in [tokens.json](tokens.json), the marks are in [marks/](marks/), and the shared icon parts are in [icons/](icons/). This is the canonical brand text. It lives in OnePhylogeny's `docs/oneorigin/`, and each tool carries a locked copy in `brand/oneorigin/`. Change it in OnePhylogeny, never in a copy. +## Palette + +The OneOrigin palette has its own colors, no longer taken from Captive Origins. Approved by the owner on 2026-11-12. The values are in `palette` in [tokens.json](tokens.json). + +| | OneTaxonomy | OnePhylogeny | OneLineage | OnePedigree | +| --- | --- | --- | --- | --- | +| Base | `#fc9583` | `#44a446` | `#3fb1e4` | `#907be8` | +| Level 1 (one level away) | `#fdb5a8` | `#7cbf7e` | `#79c8ec` | `#b1a3ef` | +| Level 2 (two levels away) | `#feccc3` | `#a5d3a6` | `#a3daf2` | `#cac0f4` | +| Text, on white | `#a66256` (4.66:1) | `#388639` (4.53:1) | `#2c7ca0` (4.67:1) | `#7967c3` (4.62:1) | + +Shared by every tool: + +| | Light backgrounds | Dark backgrounds | +| --- | --- | --- | +| The one | `#1f6f6b` deep teal, 5.92:1 on white | `#3fb3a8`, 6.85:1 on `#1c1820` | +| Center of the one | `#fbf8f2` cream | `#fbf8f2` cream | +| Lines | `#363051` aubergine, 12.36:1 on white | `#ece6f2`, 14.30:1 on `#1c1820` | + +- **The tool colors form a tetradic rectangle**: two complementary pairs, coral and green, blue and violet. Teal sits apart as the shared accent. +- **The one is teal with a cream center** in every mark: the selected rank, the sample, the person, the animal, and the suite's origin. +- **Levels are shades.** Level 1 is the base 30% of the way to white, level 2 is 52% of the way. Siblings share a shade, and each level away from the one is a step lighter. In OneTaxonomy the ranks below are darker, so a parent and its child never match. +- **Text uses the text color, never the base.** The bases are for fills: on white they reach only 2.15:1 (OneTaxonomy) to 3.40:1 (OnePedigree). Each text color is its base darkened in 2% steps until it reaches 4.5:1 on white. +- **Lines are aubergine**, a deep shade of the palette's violet, so the structure belongs to the palette. On dark backgrounds they turn pale. + +### Checks + +These are tests on the tokens and the marks, in `scripts/oneorigin.test.mjs`, so a change that breaks one fails the build: + +- **Colorblind distinctness.** Any two of the four tool colors and the one (light) are at least 15 apart (CIELAB ΔE), seen with normal vision and under protanopia, deuteranopia and tritanopia. Today: 40.6, 27.2, 16.9 and 16.9. The closest pairs are blue and violet (deuteranopia) and green and blue (tritanopia). The colorblind views use the Machado, Oliveira and Fernandes (2009) matrices at full severity. +- **Contrast.** Every text color is 4.5:1 or better on white. The one is 4.5:1 or better on white and on its cream center, and its dark version on both dark backgrounds (`#1c1820`, and `#12151b` in the apps). Lines are 3:1 or better on their background. +- **The rule.** Level shades and text colors follow the rule above exactly. +- **The marks.** Each mark is plain SVG, labelled, uses only palette colors for its background, and draws the one in teal with a cream center. + +A limit the checks don't cover: on dark backgrounds the one's lighter teal `#3fb3a8` and OneLineage's blue are only 7.0 apart under tritanopia. The cream center tells the one apart by shape, so never draw the one without it. + +## Marks + +Five marks, each as light, dark and small SVGs in [marks/](marks/): `oneorigin`, `onetaxonomy`, `onephylogeny`, `onelineage` and `onepedigree`, as `-light.svg`, `-dark.svg` and `-small.svg`. They are drawn on a 200 × 200 view box, without a background. + +- **Light** is for light backgrounds, and **dark** for dark ones: pale lines and the lighter teal. +- **Small** is for 48 px and under. It has thicker lines and larger nodes, and OnePhylogeny drops its faint outer generation so it stays clean at icon size. It uses the light colors. +- **One node size, always solid.** No faded or see-through nodes. The only exception is OnePhylogeny's faint outer generation, which shows that the tree goes on. +- **Orientation follows each field.** The suite and OneTaxonomy read top-down from one origin. OnePhylogeny is a circular tree, OneLineage a spiral around a person, and OnePedigree reads like a pedigree certificate, with the animal on the left. +- **The zoom chain.** OneTaxonomy is the widest view, then OnePhylogeny, OneLineage and OnePedigree each zoom closer in. +- **The suite mark** grows from the one at the top to all four tool colors. + ## App icon +The app icons, their tiles and the heart badge below are the earlier ones, drawn from Captive Origins colors. They stay as they are for now: new app icons, tiles and the maker's mark aren't decided yet. + | | OnePedigree | OneTaxonomy | OnePhylogeny | | --- | --- | --- | --- | | Tile gradient (top → bottom) | `#f8dcc0` → `#eeb684` (pastel Captive Origins orange) | `#f8d6d7` → `#eda9ac` (pastel Captive Origins pink) | `#e6d6d2` → `#c9aca5` (pastel Captive Origins mauve) | @@ -27,6 +76,8 @@ The shared parts, cut from the three icons without changing a value, are in [ico ## Interface +The interface colors below are also the earlier ones, from Captive Origins colors, and the apps and React packages still use them. Whether they move to the palette above isn't decided yet. + Both React packages share these (colors from the Captive Origins palette: orange `#cf8137`, pink `#e48185`, brown `#4c312c`), under their own prefixes (`op-`, `ot-`), so neither depends on the other: - **Icons**: the same 24 × 24 line icons in `icons.tsx`, drawn from Lucide (ISC; the set Captive Origins uses), 1.75 stroke, round caps and joins, `currentColor`. Shown next to text where a label helps; alone only in compact floating toolbars, always with `aria-label` and a visible tooltip on hover and keyboard focus (`data-tip`). Icons standing alone must say the action (a magnifier for zoom, not a bare +). Buttons are at least 32 px (WCAG asks 24); icon strokes keep 3:1 contrast; overlays use shape as well as color. diff --git a/brand/oneorigin/guidelines.md b/brand/oneorigin/guidelines.md index 7b9d3bf..12523a5 100644 --- a/brand/oneorigin/guidelines.md +++ b/brand/oneorigin/guidelines.md @@ -24,6 +24,12 @@ They exist so the three tools feel like one suite and keep working together as t ## 3. Brand +### Palette and marks + +The OneOrigin palette and the five marks (the suite, OneTaxonomy, OnePhylogeny, OneLineage and OnePedigree) are in [brand.md](brand.md#palette), with the files in `marks/` and the values in `palette` in `tokens.json`. Approved by the owner on 2026-11-12. Use a tool's text color for text in its color, never the base. Draw the one in teal with its cream center, every time. + +The app icons and the interface colors below are the earlier ones. They stay until new ones are decided. + ### App icon | | OnePedigree | OneTaxonomy | OnePhylogeny | diff --git a/brand/oneorigin/marks/onelineage-dark.svg b/brand/oneorigin/marks/onelineage-dark.svg new file mode 100644 index 0000000..f93ebd6 --- /dev/null +++ b/brand/oneorigin/marks/onelineage-dark.svg @@ -0,0 +1 @@ +OneLineage mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onelineage-light.svg b/brand/oneorigin/marks/onelineage-light.svg new file mode 100644 index 0000000..7a6a393 --- /dev/null +++ b/brand/oneorigin/marks/onelineage-light.svg @@ -0,0 +1 @@ +OneLineage mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onelineage-small.svg b/brand/oneorigin/marks/onelineage-small.svg new file mode 100644 index 0000000..6aff148 --- /dev/null +++ b/brand/oneorigin/marks/onelineage-small.svg @@ -0,0 +1 @@ +OneLineage mark \ No newline at end of file diff --git a/brand/oneorigin/marks/oneorigin-dark.svg b/brand/oneorigin/marks/oneorigin-dark.svg new file mode 100644 index 0000000..9f62428 --- /dev/null +++ b/brand/oneorigin/marks/oneorigin-dark.svg @@ -0,0 +1 @@ +OneOrigin mark \ No newline at end of file diff --git a/brand/oneorigin/marks/oneorigin-light.svg b/brand/oneorigin/marks/oneorigin-light.svg new file mode 100644 index 0000000..076941d --- /dev/null +++ b/brand/oneorigin/marks/oneorigin-light.svg @@ -0,0 +1 @@ +OneOrigin mark \ No newline at end of file diff --git a/brand/oneorigin/marks/oneorigin-small.svg b/brand/oneorigin/marks/oneorigin-small.svg new file mode 100644 index 0000000..59bc2a5 --- /dev/null +++ b/brand/oneorigin/marks/oneorigin-small.svg @@ -0,0 +1 @@ +OneOrigin mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onepedigree-dark.svg b/brand/oneorigin/marks/onepedigree-dark.svg new file mode 100644 index 0000000..949204f --- /dev/null +++ b/brand/oneorigin/marks/onepedigree-dark.svg @@ -0,0 +1 @@ +OnePedigree mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onepedigree-light.svg b/brand/oneorigin/marks/onepedigree-light.svg new file mode 100644 index 0000000..7be2c26 --- /dev/null +++ b/brand/oneorigin/marks/onepedigree-light.svg @@ -0,0 +1 @@ +OnePedigree mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onepedigree-small.svg b/brand/oneorigin/marks/onepedigree-small.svg new file mode 100644 index 0000000..77ae75d --- /dev/null +++ b/brand/oneorigin/marks/onepedigree-small.svg @@ -0,0 +1 @@ +OnePedigree mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onephylogeny-dark.svg b/brand/oneorigin/marks/onephylogeny-dark.svg new file mode 100644 index 0000000..35ace2d --- /dev/null +++ b/brand/oneorigin/marks/onephylogeny-dark.svg @@ -0,0 +1 @@ +OnePhylogeny mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onephylogeny-light.svg b/brand/oneorigin/marks/onephylogeny-light.svg new file mode 100644 index 0000000..ef396ce --- /dev/null +++ b/brand/oneorigin/marks/onephylogeny-light.svg @@ -0,0 +1 @@ +OnePhylogeny mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onephylogeny-small.svg b/brand/oneorigin/marks/onephylogeny-small.svg new file mode 100644 index 0000000..41d7eb2 --- /dev/null +++ b/brand/oneorigin/marks/onephylogeny-small.svg @@ -0,0 +1 @@ +OnePhylogeny mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onetaxonomy-dark.svg b/brand/oneorigin/marks/onetaxonomy-dark.svg new file mode 100644 index 0000000..be84f29 --- /dev/null +++ b/brand/oneorigin/marks/onetaxonomy-dark.svg @@ -0,0 +1 @@ +OneTaxonomy mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onetaxonomy-light.svg b/brand/oneorigin/marks/onetaxonomy-light.svg new file mode 100644 index 0000000..5a6ff78 --- /dev/null +++ b/brand/oneorigin/marks/onetaxonomy-light.svg @@ -0,0 +1 @@ +OneTaxonomy mark \ No newline at end of file diff --git a/brand/oneorigin/marks/onetaxonomy-small.svg b/brand/oneorigin/marks/onetaxonomy-small.svg new file mode 100644 index 0000000..91033f5 --- /dev/null +++ b/brand/oneorigin/marks/onetaxonomy-small.svg @@ -0,0 +1 @@ +OneTaxonomy mark \ No newline at end of file diff --git a/brand/oneorigin/tokens.json b/brand/oneorigin/tokens.json index 66fcaed..b4e91e9 100644 --- a/brand/oneorigin/tokens.json +++ b/brand/oneorigin/tokens.json @@ -13,6 +13,19 @@ "muted": { "light": "#5b6577", "dark": "#a3acbb", "use": "Supporting text." }, "background": { "light": "#ffffff", "dark": "#12151b", "use": "The page, in every Mac app." } }, + "palette": { + "about": "The OneOrigin palette, approved by the owner 2026-11-12: four tool colors that form a tetradic rectangle, a shared teal for the one, a cream center and aubergine lines. The marks in marks/ use only these colors. brand.md explains the rules, and scripts/oneorigin.test.mjs checks the colorblind and contrast numbers.", + "tools": { + "onetaxonomy": { "base": "#fc9583", "level1": "#fdb5a8", "level2": "#feccc3", "text": "#a66256" }, + "onephylogeny": { "base": "#44a446", "level1": "#7cbf7e", "level2": "#a5d3a6", "text": "#388639" }, + "onelineage": { "base": "#3fb1e4", "level1": "#79c8ec", "level2": "#a3daf2", "text": "#2c7ca0" }, + "onepedigree": { "base": "#907be8", "level1": "#b1a3ef", "level2": "#cac0f4", "text": "#7967c3" } + }, + "the-one": { "light": "#1f6f6b", "dark": "#3fb3a8", "use": "The one: the selected rank, the sample, the person, the animal, the suite's origin. Always with a cream center." }, + "center": "#fbf8f2", + "lines": { "light": "#363051", "dark": "#ece6f2", "use": "Lines and joins in the marks: aubergine, pale on dark backgrounds." }, + "dark-background": "#1c1820" + }, "radius": { "button": { "px": 8, "use": "Buttons and fields." }, "card": { "px": 10, "use": "Cards and panels, with a soft shadow." } diff --git a/brand/oneorigin/tokens.schema.json b/brand/oneorigin/tokens.schema.json index 03eba14..db3eb1d 100644 --- a/brand/oneorigin/tokens.schema.json +++ b/brand/oneorigin/tokens.schema.json @@ -2,9 +2,9 @@ "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://github.com/CaptiveOrigins/onephylogeny/blob/main/docs/oneorigin/tokens.schema.json", "title": "OneOrigin tokens", - "description": "The shared look of the OneOrigin tools: colors per mode, radii, sizes, icon parts and each tool's tile.", + "description": "The shared look of the OneOrigin tools: colors per mode, the brand palette, radii, sizes, icon parts and each tool's tile.", "type": "object", - "required": ["schemaVersion", "name", "color", "radius", "size", "icon", "tools"], + "required": ["schemaVersion", "name", "color", "palette", "radius", "size", "icon", "tools"], "additionalProperties": false, "properties": { "$schema": { "type": "string" }, @@ -12,6 +12,35 @@ "name": { "const": "OneOrigin" }, "about": { "type": "string" }, "color": { "$ref": "#/$defs/colors" }, + "palette": { + "description": "The brand palette the marks are drawn in: each tool's color with two level shades and a text color, the one, the center and the lines.", + "type": "object", + "required": ["tools", "the-one", "center", "lines", "dark-background"], + "additionalProperties": false, + "properties": { + "about": { "type": "string" }, + "tools": { + "type": "object", + "minProperties": 1, + "propertyNames": { "pattern": "^one[a-z]+$" }, + "additionalProperties": { + "type": "object", + "required": ["base", "level1", "level2", "text"], + "additionalProperties": false, + "properties": { + "base": { "$ref": "#/$defs/hex" }, + "level1": { "$ref": "#/$defs/hex" }, + "level2": { "$ref": "#/$defs/hex" }, + "text": { "$ref": "#/$defs/hex" } + } + } + }, + "the-one": { "$ref": "#/$defs/colors/additionalProperties" }, + "center": { "$ref": "#/$defs/hex" }, + "lines": { "$ref": "#/$defs/colors/additionalProperties" }, + "dark-background": { "$ref": "#/$defs/hex" } + } + }, "radius": { "$ref": "#/$defs/lengths" }, "size": { "$ref": "#/$defs/lengths" }, "icon": {