CSS helper classes
One utility class ships, and that is deliberate: a design system that ships utilities competes with the framework the consumer already chose.
v-visually-hidden
Takes an element out of sight while leaving it in the accessibility tree, which is what a label a screen reader needs and a sighted reader does not calls for. It lives in vectis.utilities, the strongest layer, so it wins over any component rule.
.v-visually-hidden {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
border: 0;
}Note what it is NOT. display: none and visibility: hidden both remove the element from the accessibility tree as well as from the page, and width: 0 is announced by some screen readers and skipped by others. The clip is what keeps it readable and unseen at once.
The layers
Four, declared in this order, and the order is the whole override model:
@layer vectis.reset, vectis.tokens, vectis.components, vectis.utilities;
/* your rule, in no layer at all, wins */
.checkout-cta { border-radius: 9999px; }Any non-layered consumer style wins automatically. Write an unlayered rule, or write into vectis.utilities. Never a specificity war, and never !important. Every line of CSS on this site takes that path: its layout, its fonts and its accent are all unlayered rules sitting on top of the library.
One trap comes with it. A layer name is GLOBAL and not namespaced, so writing @layer vectis.components { … } in your own stylesheet puts your rule inside the library's layer, where it is arbitrated by the order above instead of winning over it. Leaving your CSS unlayered is both simpler and stronger.The internal classes you will see in the DOM
These are not an API. They are named here because you will read them in devtools, and because a targeted override needs the right hook. They can change; a custom property cannot.
| Class | What carries it |
|---|---|
.v-control | Every control. Reads the size table and publishes --control-height, --control-padding-inline, --control-font-size and --control-gap for its children. |
.v-panel | The shared floating-panel chrome: overlay surface, 1px border, radius-overlay, shadow-lg. |
.v-overlay · .v-floating | Top-layer placement and the anchor-positioned entry animation (fade plus scale(0.97)). |
.v-tone | The tone table, on the element carrying data-tone. It publishes --tone-bg-solid, --tone-text-tinted and their kin, which the variants consume. |
.v-icon-symbol | An icon rendered as a font ligature rather than an embedded path. |
[data-theme] | Not a class: the one signal in the document. It moves the roles and drives color-scheme. |
The custom properties to aim at
Prefer repointing a property to rewriting a rule: --vectis-color-accent, --vectis-radius-interactive, --vectis-icon-size, --vectis-focus-ring-color, --vectis-text-family-heading. A component reads them on every render, so the change follows every state it has, hover, focus and disabled included, without a single one of them being restated.