English
About this handbook

This handbook belongs to the template Example for QuartzControl. It explains the template and, at the same time, shows everything it can do.

The text here comes from a Markdown file, not from the configuration.

6.4 – Variables

Neither this template’s colours nor its measures live in the stylesheets; both come from 66 variables. That is not cosmetics: after the import they stay editable in QuartzControl under Styles → Variables, a value in SCSS does not.

The six with the widest reach

TokenValueWhat changes
--tpl-space-md1rembase gap; the whole scale hangs on it
--tpl-target44pxminimum size of every control
--tpl-indent0.85remone level in the explorer and the table of contents
--tpl-radius-md8pxcorners of cards, code blocks, callouts
--tpl-accent-bar3pxevery accent bar
--tpl-motion150msevery transition duration

Two line heights, not one

--tpl-leading-normal is 1.65 and applies to the body text. For everything set in --tpl-text-sm or smaller there is --tpl-leading-snug at 1.45.

That is not a nicety. 1.65 is a ratio measured for 1 rem across six grid columns. The same number at 0.875 rem in a bar three columns wide puts nearly 21 px between two lines of 14 px height — a three-line paragraph then reads like three separate ones. That is exactly how the note box in the sidebar looked. The three areas that consist of small type — left bar, right bar, footer — say it once, instead of every component inside them repeating it.

What the 66 are

All 66 are our own --tpl-* tokens — the actual system. Typefaces and the colours of the palette do not stand here but under Styles → Basics; from those Quartz itself writes --bodyFont, --secondary and the rest. Until 2026-09-20 font stacks and Quartz variables stood here too, and the font stacks hid Quartz’s own fallback (6.3).

Three groups among them are younger than the rest and deserve a sentence each:

  • Thirteen callout colours (--tpl-callout-note to --tpl-callout-quote), light and dark each. They mean status, not palette: a warning that follows the accent colour is no longer a warning. And they are measured, not chosen — eleven of Quartz’s twelve callout colours fail AA on a light ground. Every title colour holds 4.5:1 on the ground and on the tinted surface of its own box. Whoever changes one here can put it below that threshold, and QuartzControl says nothing about it.
  • Two for the scrim behind every drawer (--tpl-backdrop, --tpl-backdrop-blur): dimming and blur, the same value for the navigation and the explorer.
  • Six switches for the side columns, see the next section.

The side columns: staying put or scrolling along

Whether a side column stays put while the page scrolls is decided by three variables per column, and they belong together: a column that stays put needs a height cap (otherwise it runs out of the window and does not stay put at all) and a soft lower edge (otherwise the cap cuts a line in half). Whoever switches the right column switches all three; on the left, the position is enough (see below).

Variablestays putscrolls along
--tpl-col-…-positionstickystatic
--tpl-col-…-heightcalc(100dvh - var(--tpl-header-h) - 2 * var(--tpl-space-lg))none
--tpl-col-…-maskvar(--tpl-fade-mask-end)none

… stands for left or right. The default: the right one stays put, the left one scrolls along. A half state is possible and looks like a bug — static with a height cap is a column that stops in the middle of the text and scrolls inside itself.

On the left, the position is enough. When --tpl-col-left-position is sticky and height and mask are still none, the template fills in the two values from the table itself. Anyone who enters a height of their own keeps it. This holds in every current browser; an older one without this ability still needs all three lines.

A column that scrolls inside itself hands the mouse wheel on to the page at its end. And one that has nothing to scroll does not hold on to it in the first place — the page scrolls even with the pointer over the navigation.

Switching the left one is a decision with consequences: this handbook’s navigation is about 1640 px tall with a chapter open, about 2560 px on the home page, at a window height of 900 px. Staying put there necessarily means “scrolls inside itself”. The basic template comes to about 700 px and would simply stand still. The two columns switch at different widths: the left one from 901 px, the right one from 1201 px — below that they sit under the text, where staying put means nothing.

What does stand literally

Counted on 2026-09-21 across the 31 stylesheets, comments and variable declarations excluded: 16 colour values in three files. All for the same reason — a variable cannot stand in that place.

WhereWhatWhy
body-code10 coloursThe five syntax corrections — the replaced and the replacing value each.
body-mermaid4 coloursMermaid’s error state and its two footnote colours, which it colours itself.
a11y2 greysInside @media print. On paper neither the light nor the dark palette applies.
everywhere20× 1px/2pxHairlines and focus rings. A line is one pixel wide, not one step of a grid.
everywhere56× 0.1em, 1em and othersMeasures that relate to the type size rather than to the spacing scale — the padding of an inline-code pill, the size of an icon in line height. The three recurring letter-spacings became tokens on 2026-09-05.
28 media queries480px, 720px, 900px, 901px, 1200px, 1201pxA media query cannot read a variable.

What repeats, and why it may

Two shapes stand in several sections of the stylesheets nearly word for word:

Shapein how many sections
The panel heading — heading face, uppercase, semibold, muted, --tpl-tracking-label9
The hovered link — accent colour, underlined, --tpl-underline-offset8

That could be pulled into one shared rule, and here that would be the wrong move. The sections of the stylesheets are cut by component, and the documentation hangs off that: every page in this section carries the table of the variables its component reads. Move the panel heading into the base section and it disappears from nine of those tables and turns up in one that nobody reads while adjusting the backlinks.

What has to be shared are the values — and they are: --tpl-tracking-label and --tpl-underline-offset stand once each and hold everywhere. The shape beside them is six lines, readable where they take effect.

A shared file would not be straightforward here anyway

Sass solves this with partials (_shared.scss). QuartzControl does not allow a filename with a leading underscore, and a file without one would sit in the list under Styles → Custom CSS as a stylesheet that emits nothing.

What Quartz does instead

Out of the box there are the nine colour variables and the typeface roles, but no scale for spacing, radii, target sizes or motion. Values stand directly in the rules there. Anyone wanting to change the base gap has to look for it in many places.

Which variables apply here

These 49 variables are read by the section base in foundation.scss, layout.scss and content.scss. They can be changed in QuartzControl under Styles → Variables — without a line of CSS.

VariableValuealso applies to
--bodyFont"Noto Sans", system-ui, "Segoe UI", Robot…3 other components
--col-ring-reachset in the stylesheet (layout.scss)only here
--dark#17171A · dark #FCFCFA13 other components
--darkgray#333333 · dark #DDDDDD18 other components
--gray#5F5F5F · dark #A1A1A122 other components
--headerFont"Noto Sans", system-ui, "Segoe UI", Robot…15 other components
--icon-chevronset in the stylesheet (foundation.scss)Callout colours
--light#FCFCFA · dark #16171A14 other components
--tpl-col-left-heightnoneonly here
--tpl-col-left-masknoneonly here
--tpl-col-left-positionstaticonly here
--tpl-col-right-heightcalc(100dvh - var(--tpl-header-h) - 2 * v…only here
--tpl-col-right-maskvar(--tpl-fade-mask-end)only here
--tpl-col-right-positionstickyonly here
--tpl-fade14pxonly here
--tpl-fade-maskset in the stylesheet (foundation.scss)only here
--tpl-fade-mask-endset in the stylesheet (foundation.scss)only here
--tpl-focus-colorvar(--secondary) = #1463A3only here
--tpl-focus-offset2pxCallout colours, The explorer
--tpl-focus-width2pxCallout colours, The explorer
--tpl-header-hset in the stylesheet (layout.scss)The explorer, The navigation
--tpl-header-padset in the stylesheet (layout.scss)The header
--tpl-icon-sm0.95rem3 other components
--tpl-leading-normal1.6The navigation
--tpl-leading-snug1.4rem4 other components
--tpl-leading-tight1.25only here
--tpl-motion150ms ease13 other components
--tpl-page-fade24pxThe header
--tpl-radius-md8px17 other components
--tpl-radius-sm4px10 other components
--tpl-rulevar(--lightgray) = #DDDDDD19 other components
--tpl-rule-controlcolor-mix(in srgb, var(--gray) 70%, var(-…11 other components
--tpl-rule-strongvar(--gray) = #5F5F5F8 other components
--tpl-rule-width1px25 other components
--tpl-space-lg1.5rem12 other components
--tpl-space-md1rem18 other components
--tpl-space-sm0.75rem10 other components
--tpl-space-xl2.5rem5 other components
--tpl-space-xs0.5rem20 other components
--tpl-surface-tintvar(--highlight) = rgba(42, 78, 108, 0.10)14 other components
--tpl-target44px12 other components
--tpl-text-2xl1.75remTitle and date
--tpl-text-3xl2.25remTitle and date, Error page
--tpl-text-base1rem4 other components
--tpl-text-lg1.15remSearch, Link preview
--tpl-text-sm0.875rem20 other components
--tpl-text-xl1.4remThe language switcher
--tpl-tracking-caps0.06emCode styling, 3.1 – Bases
--tpl-tracking-label0.08em9 other components

This table is generated: it is read out of the stylesheets rather than kept by hand.

Read on

This page belongs to Example — the example template for QuartzControl. An overview of every area is on the English home page.

On a narrow screen the navigation is collapsed at the top.