Files
tlig-theme/README.md
T
2026-09-24 18:06:11 +02:00

9.3 KiB

tlig_css

The TLIG stylesheet rebuilt on SASS tokens and Vite, as a replacement for Avada-Child-Theme/css/tlig_en.css (7,082 lines) and the compiled Avada style.css it fights with.

This first pass covers the common foundation only: fonts, colour, type scale, links, buttons, form fields and the footer. Page-specific styling (messages, bookstore, menus, the wood and scroll backgrounds) is not here yet.

Layout

src/sass/        the stylesheet
src/images/      art: the parchment 9-slice, the scroll, the wood ground
src/demo/        the static style guide's own chrome
site/            WordPress docroot (core is gitignored; see below)
  wp-content/themes/tlig/    THE DELIVERABLE
local/           docker-compose for the clean rig

WordPress core sits in site/ but is not ours: it is extracted from the Docker image so the two cannot drift, and is gitignored. Only the theme and the asset mirror are versioned. To recreate core:

docker run --rm wordpress:php8.3-apache tar -cC /usr/src/wordpress . | tar -xC site/

Commands

npm install
npm run dev        # static style guide, live reload, localhost:5173
npm run preview    # static style guide as a built page, localhost:4173
npm run build      # the theme's stylesheet -> site/wp-content/themes/tlig/assets/

cd local && RUN_UID=$(id -u) RUN_GID=$(id -g) docker compose up -d
# the theme on real WordPress at localhost:8090  (admin / admin)

The rig is deliberately not the wp-migrate one. That mounts the production tree — Avada, 55 plugins, a 1.5 GB database — and exists to mirror what ships. This one boots with nothing but core, so the theme has to stand on its own. Keep both: the other is the reference to compare against. It runs on 8080, this on 8090, so they can run side by side.

A npm run build lands directly in the running theme — the docroot is this project's own site/, so there is no copy step and no container restart.

There is no way to open src/index.html from disk — it is an ES module that imports .scss, so it needs one of the two servers above. file:// gives a blank page.

npm run dev compiles the SASS in memory and injects the CSS through JavaScript. Fast, hot-reloading, and how you work. One caveat: because the CSS arrives after first paint, anything with a transition animates up from its unstyled state, so for a few milliseconds links are browser-blue and buttons are nearly transparent. That is a dev-server artifact, not the stylesheet.

npm run preview builds the demo to demo-dist/ and serves it. The page there loads the compiled stylesheet through a real <link rel="stylesheet"> in <head>, so it paints once, exactly as a browser will on the real site. Use this when judging how something actually looks, or when screenshotting.

npm run build emits only the deliverable — dist/tlig.css and the fonts, no HTML and no demo markup. The demo is built from src/index.html and the deliverable from src/main.js, so demo chrome cannot reach dist.

The demo page

npm run dev serves src/index.html: the foundation rendered on the real ground, inside the wood background and the papyrus scroll, with the real footer component at the bottom. It shows the type scale, every link and button variant, the dark-ground mechanism, and a colour grid generated at runtime from the --tlig-color-* properties the stylesheet actually emits — so the grid cannot drift from the code.

The toolbar has three controls:

  • Script — switches the sample heading between Latin, Hungarian, Cyrillic and Greek. No CSS changes when you do; the browser picks the font file by codepoint. Also addressable as ?script=bg for linking or screenshotting. Greek is included deliberately: no papyrus cut exists for it, so it shows the fallback face honestly.
  • Show boxes — outlines each component so the structure is visible.
  • A live viewport width and the active breakpoint.

What remains demo-only, in src/demo/demo.scss, is the toolbar, the swatch grid, the section scaffolding, and four :root declarations pointing the frame's image tokens at this project's local mirror. The demo is not a build input, so none of it can reach dist/tlig.css — the build is checked for exactly that.

A foundation only tells the truth on the ground it has to work on. Brown ink at 86% looks arbitrary on white and obviously right on papyrus.

Layout

src/sass/
  abstracts/      compile-time only; emits no CSS
    _palette.scss   every literal colour the live site uses
    _tokens.scss    semantic tokens: what a colour is *for*
    _functions.scss token accessors
    _mixins.scss    media queries, type, patterns
  base/
    _root.scss      emits every token as a CSS custom property
    _fonts.scss     @font-face
    _reset.scss
    _typography.scss
    _links.scss
  layout/
    _page.scss      the wood ground and the papyrus scroll
  components/
    _button.scss  _field.scss  _filter.scss  _footer.scss
src/fonts/        papyrus-bold (4 scripts) and Lato, self-hosted
src/demo/         demo page chrome and behaviour — never built
src/index.html    the demo page

The three rules that replace the jigsaw

One source of truth per value. No rule writes a hex code. _palette.scss holds the literals, _tokens.scss names them by role, base/_root.scss emits them as --tlig-* custom properties, and every rule reads a token. #482020 appears 74 times in tlig_en.css; it appears once here.

Context re-points tokens, it does not restate rules. The dark-ground mixin re-points nine custom properties; .site-footer and .on-dark both include it and declare no colours of their own. Every link, heading and button inside them is then correct — where the live CSS needs 24 id selectors to say the same thing. The list of what "dark" means exists once, so the two cannot drift: building the demo caught exactly that bug, an .on-dark that re-pointed the links but not --tlig-color-heading, rendering a heading dark-brown on dark-brown.

Specificity goes one way. Layer order in main.scss is tokens → base → components, and nothing later needs to outrank anything earlier. Every !important in the build — four of them — is in the single prefers-reduced-motion block, where overriding author animation is the point. There are none anywhere else. tlig_en.css has 518.

What the tokens were taken from

Values are the ones the site renders today, not new choices:

Token Value Source
--tlig-color-page-ink rgba(72,32,32,0.86) Avada --body_typography-color
--tlig-color-link #810008 Avada --link_color
--tlig-color-link-hover #ca4a1f tlig_en.css global a:hover
--tlig-color-heading #482020 Avada --h1_typography-color
--tlig-color-heading-message #7a0012 tlig_en.css global h2
--tlig-color-footer-ink #fbefc9 tlig_en.css #footer-container
--tlig-color-button-bg #8f0b06 tlig_en.css .btnSubmitNewsletter
--tlig-size-base 18px Avada --body_typography-font-size

Two deliberate departures, both noted in the source:

  • h2 is encoded as Trebuchet / #7a0012 / bold. Avada's own token says Lato / #333333, but tlig_en.css overrides it globally with four !importants, so the second is what actually renders.
  • Spacing is snapped to a 4px scale. The live CSS uses 6px, 23px, 35px and 46px in adjacent rules; those become the nearest step.

Fonts

papyrus-bold is declared four times under one family name, split by unicode-range across the Latin, Latin-Extended (Hungarian), Cyrillic and Cyrillic-Extended (Bulgarian) files. The browser picks the file by codepoint, so a Bulgarian heading needs no language class and no second stylesheet.

All font files are project assets. The live site points @font-face at absolute ww3.tlig.org URLs, which is why a staging copy renders in the fallback face; here Vite emits them into dist/fonts/ and the CSS references them relatively, so the bundle resolves at whatever path it is dropped.

Lato is self-hosted from the three files already in the child theme, replacing the 33 @font-face blocks Avada generates from its Google Fonts cache.

The page frame

layout/_page.scss carries the wood ground and the three-piece papyrus scroll. Two things it does differently from the live CSS:

  • The image URLs are custom properties. Swapping the set at a breakpoint is four declarations, where the live CSS duplicates six rules per breakpoint — and again under html.webp and html.no-webp, for a browser that no longer exists. A demo or a staging copy re-points the tokens instead of editing the stylesheet.
  • The overlaps are measured, not guessed. The foot image's top 18px ramp from alpha 15 to its 242 plateau; butt it against the body and that fade composites over bare wood, which reads as a hard line at the body's edge. The overlap is -20px: the ramp plus a little. It has to be a margin — the element is static, and top only moves a positioned box.

Not done yet

  • Header and nav
  • Message typography (.tbody, .vassula, .jc, .god, the bible-reference asides)
  • Bookstore, search, testimonies, downloads
  • Enqueuing the built CSS from the theme, and retiring tlig_en.css