Skip to content
AvandoLabs Theme help Deutsch

Technical page · Structure & adjustment points

For developers: how the theme is built

This page explains the technical foundation: the design variables (“tokens”), how they work together, the @layer cascade and the order in which you customise the theme – from “only when forking the framework” to “on a single element”. Finally: why this structure is well suited to AI-assisted design automation.

One value, in one place

All --av-* defaults are defined once in bundle/public/theme/tokens.css, in the av.tokens layer on :root. Rules in the theme never use raw values, always a token. That is why a colour change propagates consistently everywhere – and the reason for the name Advanced Variable Environment.

No build step in daily work. These are native CSS custom properties, not Sass/Less – no preprocessor, no compiling. Editing custom.css or theme-vars.css is enough, the browser resolves at runtime; clearing a CSS cache is only needed for a stubborn cache, not as a rule. The build (ave:css:build) only concerns concatenating the framework source files into one.

Values that derive from each other

Many tokens are not set but calculated:

/* Secondary colour: from the primary colour, via two dials */
--av-color-secondary:
  oklch(from var(--av-color-primary)
        l calc(c * var(--av-sec-chroma))
        calc(h + var(--av-sec-hue-shift)));

/* Muted text: a mix of text colour and surface */
--av-color-text-muted:
  color-mix(in oklch, var(--av-color-text) var(--av-muted-fraction),
            var(--av-color-surface));

/* Light/dark: color-scheme + light-dark(), switched via html.light / html.dark */
--av-color-primary-light: light-dark(var(--blue-3), var(--blue-9));

Change the primary colour and you automatically get the secondary colour, hover variants, muted text and the dark-mode values along with it.

Scale factor or absolute step

Sizes come as a ramp plus one factor. The factor moves the whole ramp; at 1, calc() collapses exactly to the original value (pixel-identical – which is why “saving with defaults” has no effect).

--av-radius-scale: 1;
--av-radius-sm: calc(var(--radius-2) * var(--av-radius-scale));
--av-radius-md: calc(var(--radius-3) * var(--av-radius-scale));
/* … */

/* move the whole ramp: */   :root { --av-radius-scale: 1.4; }
/* hard-set one step: */     .promo { --av-radius-lg: 8px; }

Other factors: --av-text-scale, --av-heading-scale, --av-space-scale (density), --av-layout-gap-scale, --av-shadow-scale, --av-glow-scale, --av-duration-scale, --av-bg-overlay-scale.

The Design Studio only writes the factor (e.g. --av-radius-scale), never the four steps. A hard-coded --av-radius-md: 16px in custom.css disables exactly this slider.

The @layer cascade

The order is declared once in tokens.css. Early layers have the lowest priority. Client CSS in custom.css is unlayered and therefore wins against all layered CSS – regardless of selector specificity.

custom.css — no @layer always wins · this is where project overrides belong

▲ higher priority

  1. av.animations
  2. av.layout
  3. av.theme
  4. av.forms
  5. av.components
  6. av.typography
  7. av.base
  8. av.tokens ← all --av-* defaults
  9. av.normalize
theme-vars.css (the deltas from the Design Studio) is unlayered as well, but included before custom.css – which is why a manual change in custom.css wins against the saved Studio state.

The adjustment points – from global to local

The Design Studio (ave-editor) is one of several equally valid tools, not the only one. It is an optional add-on bundle; the theme framework (bundle) works without it. On save it only writes files/theme/CSS/theme-vars.css (a :root { … } block). A project without the Studio sets the same --av-* values by hand – in theme-vars.css, in custom.css or as changed defaults in tokens.css (fork + build). If theme-vars.css is missing, everything comes from tokens.css.

WhereWhat forReach
bundle/public/theme/tokens.css Change the defaults themselves. Only when customising the framework; then run ave:css:build. all projects using the bundle
Design Studio The intended site-wide sliders. Writes files/theme/CSS/theme-vars.css, versioned. whole website
files/theme/CSS/custom.css Manual overrides: any --av-* on :root site-wide – or limited to a selector / a section / a page. Plus project CSS. Wins over everything. freely chosen
files/theme/CSS/theme.css Starter theme building blocks: header/footer/navigation, hero background, accordion variants, .display-hero, .section-index, .pull-quote. Comes from the bundle (bundles/avandoave/starter/); a file of your own at this path replaces it. whole website
Field Inline styles / CSS ID/class Per section or element: any declarations including --av-* (--av-gutter: 2rem); utility classes; bridge tokens --av-el-* / --av-section-color inherit from the wrapper into the children. one section / one element

Preparing a logo SVG for logo-tint

With the logo-tint class, the theme inserts an SVG into the page as code instead of as an image and colours its named parts. Naming is done with a CSS class on a group:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1017 170">
  <g class="logo-mark" fill="#1c7ed6"> … symbol … </g>
  <g class="logo-word" fill="#808080"> … lettering … </g>
</svg>

Arranging the header

The header spreads its parts across the full width: the first sits at the far left, the last at the far right, everything else evenly spaced in between. A part is every entry in the page layout (Themes → Page layouts → Included elements) in the header column.

Entries in headerResultDemo
Logo · navigation · buttonNavigation in the middleVion Consulting
Logo · element group (navigation + button)Navigation on the right, next to the buttonWasser für Morgen, Studio Halcyon, Praxis Lindenhof
Logo · navigationNavigation on the right–

An element group with the layout-row layout keeps its children together in one row and counts as one part of the header. With three parts, the navigation sits midway between logo and button – exactly in the centre of the page only if logo and button are the same width.

On a phone As soon as the navigation turns into a menu button (always below 768 px, on wider screens when it does not fit on one line), the header hides elements with the class desktop-only – such as a contact or donate button, which can then live inside the menu.

Build & operation

Pitfall: composite tokens

A custom property is resolved where it is declared. Tokens such as --av-card-border, --av-card-bg or the glow chains are therefore also set on the classes themselves. If you build a section that changes --av-color-border or --av-color-surface-2, you have to update the respective card token in the same block – otherwise the card inside keeps the root value. Likewise, relative URLs in --icon-src resolve at the place of use; custom icons need an absolute path.

Well suited to agentic workflows

The same structure that makes the theme maintainable also makes it predictable for AI agents. If you automate design changes, you benefit from:

Complete reference: bundle/cheat-sheet.md lists every --av-* token with its default and every utility class. Build and style rules are in bundle/ai-instructions.md.