Skip to content

Latest commit

 

History

History
163 lines (115 loc) · 11.7 KB

File metadata and controls

163 lines (115 loc) · 11.7 KB

Customizing: move along an axis

Most themes document customization as a list of variables you may set. That tells you what is editable and nothing about what to edit. This file documents it the other way round: pick the axis you want to move along, and change the few tokens that carry the move.

The axes are the four from the creative direction framework, and they are the same four annotated throughout tokens/tokens.css. Where this theme currently sits:

Axis Position
Tone register Conversational
Aesthetic philosophy Polished Standard
Audience relationship Peer
Sensory ambition Resonant

One thing makes this file different from its siblings in the collection. This theme is a shell whose ground is a moving picture, so a re-skin here is not only a recolor: it changes the one part of the page that is doing the emotional work, and it can break the contrast contract that lets text sit on top of it. So the first move is worked in full, and a second move that fails is shipped beside it with a picture, because the failure is the more useful thing to have seen.

Every move below is an edit to tokens/tokens.css only. Nothing else in the repo changes, because nothing else in the repo holds a value.


Move 1, worked: take the ocean to midnight

The shipped water is daytime: a lit surface stop, cool sunbeams, sixteen metres down. This move takes the same ocean to night. Same schools, same beams, same window, no light left at the surface.

Ten tokens carry it, and the whole scene follows because nothing else in the repository holds a color.

- --vo-water-surface: #125781;
+ --vo-water-surface: #0a2f4a;
- --vo-water-mid: #0a3f61;
+ --vo-water-mid: #061f33;
- --vo-water-deep: #062c47;
+ --vo-water-deep: #04131f;
- --vo-water-abyss: #03192b;
+ --vo-water-abyss: #010a12;
- --vo-ray: #cfeeff;
+ --vo-ray: #d8e8ff;          /* moonlight is bluer than sunlight */
- --vo-ray-step: 0.05;
+ --vo-ray-step: 0.06;        /* one step up: less water to light, so it reads */
- --vo-fish-shallow: #0a4066;
+ --vo-fish-shallow: #041c2e; /* still darker than the water above it */
- --vo-fish-deep: #135b83;
+ --vo-fish-deep: #0d3a55;    /* still lighter than the water it swims in */
- --vo-rail-hover: rgba(3, 25, 43, 0.38);
+ --vo-rail-hover: rgba(1, 10, 18, 0.45);
- --vo-shadow-window: 0 2px 4px rgba(3, 25, 43, 0.22),
-   0 18px 44px -10px rgba(3, 25, 43, 0.5);
+ --vo-shadow-window: 0 2px 4px rgba(1, 10, 18, 0.3),
+   0 18px 44px -10px rgba(1, 10, 18, 0.6);

Every number improves, and they were measured rather than assumed. The lightest paint the scene can produce goes from #2e7095 to #2f5772, and against it:

shipped midnight
Ground ink on the lightest scene paint 4.94:1 7.01:1
Focus ring band 4.17:1 5.92:1
Focus ring halo 3.22:1 2.27:1
Window surface against the water 5.22:1 7.40:1

The halo is the one figure that gets worse, and it does not matter, which is the point of building the ring out of two colors: the guarantee is that one of the pair clears the 3:1 floor against any given backdrop, and at midnight the band is doing it at 5.92:1 with room to spare. A single-color ring would have had to be re-picked here.

The VivaOcean demo with the water re-skinned to midnight: the same window, rails, sunbeams and schools, at night

Nothing moves, and everything changes. The rails, the window chrome, the schools and every sunbeam are exactly where they were, drawn by the same rules; only the water they are made of is different. The window is untouched by this move, and it should be: a lit page held in dark water is the composition, and darkening the page as well would be a different theme rather than a different time of day.

What the ten tokens do not cover, and why the count is honest. The window surfaces, the ink, the accent and the semantic fills are all unchanged, so this is a re-skin of the ground rather than of the theme. A full dark move, window included, is a bigger diff and a different decision; it would have to move --vo-ink and then deal with the four --vo-fill-* badges, which are calibrated for full-strength dark ink and fail outright with cream on them. The desktop pilot's CUSTOMIZE.md documents that trap in full.


Move 1b, the failure, shipped on purpose

Here is the same move made in the other direction, to a bright tropical lagoon. Ten tokens, same shape, same discipline, and it is broken.

+ --vo-water-surface: #2fa9a6;
+ --vo-water-mid: #1c8a90;
+ --vo-water-deep: #116a73;
+ --vo-water-abyss: #0a4a55;
+ --vo-ray: #e6fffb;
+ --vo-ray-step: 0.06;
+ --vo-fish-shallow: #0d5f66;
+ --vo-fish-deep: #3ec2bb;
+ --vo-rail-hover: rgba(10, 74, 85, 0.45);
+ --vo-shadow-window: 0 2px 4px rgba(10, 74, 85, 0.3),
+   0 18px 44px -10px rgba(10, 74, 85, 0.55);

The same demo re-skinned to a bright turquoise lagoon, in which the rail labels have almost disappeared into the water

Look at the rail labels. Home, Features, Pricing, Docs. They measure 1.76:1 against the water behind them, against a floor of 4.5:1, and the current-page marker under the Home glyph has vanished entirely.

The reason this capture is in the repository is that it does not look broken. It looks like a nice tropical theme. The window is still crisp, the fish are still charming, the beams are still pretty, and the one thing that has failed is the only thing on the page written directly onto the ground. That is what makes lightening the water the dangerous direction and darkening it the safe one, and it is why the ground ink figure is the number to re-measure first and everything else second.

shipped midnight lagoon
Ground ink on the lightest scene paint 4.94:1 7.01:1 1.76:1
Focus ring band 4.17:1 5.92:1 1.48:1
Focus ring halo 3.22:1 2.27:1 9.06:1
The launcher's label, on its own plate 15.63:1 15.63:1 15.63:1
The launcher's plate, against that same paint 5.22:1 7.40:1 1.85:1

Two things survive, and both were built to. The focus ring still clears the floor at 9.06:1, on the halo this time rather than the band; the two-color ring was built for exactly this, and a re-skin can destroy the text on this theme and still not be able to lose the reader's place.

The other is the launcher, and its row is the flattest in the table on purpose. Its label is window ink on the window's own surface, so the ocean is not in the arithmetic at all and the number cannot move no matter what you do to the water. That is the argument for drawing the one control on the desk as a piece of the window rather than in the rails' language: had it been ground ink on the water, it would be sitting at 1.76:1 in the third column with the rail labels, and at 390, where a clear desk has nothing else on it, that is the whole way back to the site rendered illegible by a palette change. Its plate does lose its edge here, at 1.85:1 against the same paint — the shape gets harder to find, the words never do, and the ring's halo covers the shape at 9.06:1 for anyone arriving by keyboard.

The general rule, which is the same one the text index in phone-launcher-theme demonstrates from the other direction: the fewer of a theme's moving tokens a load-bearing surface spends, the more re-skins it survives.

How to fix a lagoon if you want one. Two options, and one of them is not "nudge it a bit". Either darken the water until the ground ink measures 4.5:1 again, which for this hue means roughly the depth of the shipped palette, or keep the bright water and add the scrim the class guarantee provides for: a token-driven layer between scene and content, with every ratio re-measured through it. What you may not do is ship the picture above.


Move 2, sketched: Sensory ambition, Resonant toward Considered

The move to make if the composition fits your product but the atmosphere does not: an internal tool, a documentation site, anything opened forty times a day where a moving ground stops being a pleasure and starts being a room-mate.

The tokens that carry it:

  • --vo-drift-near, --vo-drift-mid, --vo-drift-far, all up by a factor of three or four. The scene stops being something you could watch and becomes something you notice twice a day. This is most of the move.
  • --vo-ray-step, 0.05 down to 0.03. The beams recede into the water rather than falling through it.
  • Ship calm as the enhanced default instead of ocean, which is one string in shell.js, and let the switch in the title bar be how the water gets turned on rather than off.

What no token can do: make the demo's copy quieter. The tone axis runs through language before anything visual, and a token file has no opinion about a headline. Budget a copy pass alongside this move.


Move 3, sketched: Aesthetic philosophy, Polished Standard toward Editorial Restrained

For the version of this shell that carries writing rather than a product: an essay collection, a research group, a single long document that deserves the water.

The tokens that carry it:

  • --vo-radius-window, 14px to 0. A hard-edged sheet of paper in water reads as a page rather than as an app.
  • --vo-measure, 68ch down to 62ch, and --vo-window-width down with it. An editorial column is narrower than a product column, and the ground gets the difference.
  • --vo-accent, moved off coral to something that never appears except in a link. The accent here is spending part of its budget on a primary button, and an editorial page has no primary button.

The trap in this move is taking --vo-window-inset up at the same time. More water sounds like more atmosphere and it is the opposite: the window stops being held in the ocean and starts being a card on a background.


Adding a token

If a move needs a value the theme does not have, add it to tokens/tokens.css in the group whose axis it serves, with a comment saying what it is for. Then reference it from theme.css and preset.js so both Tailwind versions see it. Those two files hold no values, only references, and keeping it that way is what makes the next move a ten-line diff.

And if the value you are adding is a color the scene will paint with, measure it. The contrast contract in scene/scene.css names the exact set of tokens the ground may use and quotes the worst pairing that set can produce. A new paint outside that set makes the quoted number wrong, and nothing in the build will tell you.