makeover-webview 0.126.0

The webview renderer for makeover-layout. Emits CSS, and is the one renderer that needs no palette: var() is the late binding, so resolution stays with the browser. With the build feature, writes a consumer's generated frontend files and checks the hand-written ones against them.
Documentation
# makeover-webview

The webview renderer for
[`makeover-layout`](https://makenot.work/git/max/makeover-layout). Emits CSS.

## The renderer that needs no palette

`makeover-immediate` and `makeover-tui` both take a `Palette`, because egui and
a terminal need an actual colour before they can put anything on screen. A
webview does not. `var(--surface-raised)` *is* the late binding, and the browser
resolves it against whatever the theme layer last wrote onto `:root`.

So this crate emits text naming intents and never learns a colour. It is also
why the webview is the wrong renderer to derive a vocabulary from: it can
express anything, so it never pushes back.

## The stylesheet

`stylesheet(&Emit)` writes the component CSS: depths, controls, tokens,
selectors, rows, tables, facets, meters, charts, figures and placeholders. An
app that builds its own markup keeps every line of it and gains the classes.

```css
:root {
    --bevel-raised: inset 1px 1px 0 var(--bevel-light), inset -1px -1px 0 var(--bevel-dark);
    --bevel-inset: inset 1px 1px 0 var(--bevel-dark), inset -1px -1px 0 var(--bevel-light);
}

.raised { background: var(--surface-raised); box-shadow: var(--bevel-raised); }
.well { background: var(--surface-well, var(--surface-page)); box-shadow: var(--bevel-inset); }
.button:active { background: var(--surface-well, var(--surface-page)); box-shadow: var(--bevel-inset); }
```

The depth classes are surfaces and nothing more, and the states belong to the
named surfaces. `.button` is that same depth *and* a control, so it carries
hover, press, focus and disabled. `.card` is a raised object, and carries those
states only when it is written on a control: `a.card`, `button.card`,
`label.card`, or a card with `data-act`. A card that is only read has no hover
to cancel.

Hover rules are gated on the pointer density `makeover-layout`'s `Affordance`
and `makeover-geometry` answer for, never decided here, and every focus ring is the
one `focus_rule` writes.

## The markup

The description members (fields, columns, figures, meters, charts and the
rest) are drawn by the quasi hosts, `quasi-webview` for this renderer. This
crate holds what that markup has to agree with: the class names, the class
lists the vocabulary is checked against, and the rules behind them.

- `form` holds the escaper, `Markup` and `Filling`, the field classes and the
  form rules.
- `list` names a column as a class (`push_column_name`), holds the kind, part
  and flow classes, the cell wrapper and sizer, and the `short-N` ladder;
  `table` holds the rules that narrow a table by column priority.
- `chart`, `figure` and `meter` hold their class lists and rules.
- `facet` and `placeholder` render the members of the same names, each with an
  `_into` form that writes into a buffer the caller already has and a
  `_placed` form that also reports where each part landed, for a caller
  compiling the markup into a template.

One escaper covers both text and attribute sinks, and the single hole is
`form::Markup`, which a caller has to name. The copy markup carries (the
required marker, the exclude button's name, the markdown editor's modes) comes
from `Emit`, English by default.

Numbers the rules read, such as a bar's value, ride in `data-vars` rather than
`style`, so a page under a `style-src` without `'unsafe-inline'` still draws
them. Serve `VARS_JS` beside the stylesheet to apply them.

## Substitution, three ways

A theme with no `surface-well` is answered differently by each of the three
renderers, which is why substitution belongs to a renderer and not to the
description:

- `makeover-immediate` substitutes the page in Rust.
- `makeover-tui` refuses to substitute and draws an edge, because a terminal
  quantises the two together.
- here, CSS already has the mechanism. `var(--surface-well, var(--surface-page))`
  falls back in the browser and nothing in Rust decides anything.

## Status

On crates.io. A consumer takes it twice: as a dependency for the markup, and
as a build-dependency with `features = ["build"]`, whose `build` module writes
the themes, the generated stylesheets and the font faces into an app's frontend
and checks the hand-written CSS and JS against them. `links` keeps the two at
one version. The `build` module was the `makeover-build` crate, which is
retired.

## Licence

MIT.