Template · Style guide

The Nordlys system on one page.

Tokens, type, components and motion hooks exactly as they ship in the shared CSS. Change a class once and every page follows.

Colours9 tokens + lilac
TypeInter Tight · Geist Mono
Grid12 col · 24 px gap
Build26.10.05
01ColoursTokens on :root

Black and greys carry the page; violet only appears as light. They are CSS variables with the same names in src/styles/template.css.

Black--black#000000Page and loader background.
Ink--ink#0A0A0APhoto frames before the image loads.
Foreground--fg#F3F3F3Headings, pills, active text.
Mute--mute#A6A6A6Body copy, labels, gray heading endings.
Dim--dim#5E5E5ECaptions, counters, placeholders.
Line--linergba(243,243,243,.12)Every hairline, border and frame.
Accent--accent#D9D9D9Live dots and rich-text body.
Violet--violet#6E4BFFShader, glows, hover sweeps, selection.
Lilacno token#C9BDFFLit dots, active states, small accents. Written as a hex value.
Plum--plum#1A1033Reserved deep tint. Not used by a class yet.
02TypographyTwo families, one scale

A grotesk for everything you read, a mono for everything you scan. Headings sit at weight 400 with tight tracking; sizes are fluid clamp() values, measured live below.

Sans · --sans300 · 400 · 500
Aa

Inter Tight. ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789 € $ % −

Rendering now—
Mono · --mono400
Aa

Geist Mono. ABCDEFGHIJKLM 0123456789 $1.62 −4 °C

Rendering now—
Display · .phero h1clamp(40px, 5.6vw, 96px)400 · −0.045em · 0.95Now —

Arctic air, hydro power.

Closing · .cta4 h2clamp(32px, 3.7vw, 66px)400 · −0.04em · 0.98Now —

Lock a rate for three years.

Heading 2 · .h2clamp(30px, 3.4vw, 58px)400 · −0.04em · 1.0Now —

Cooled by the climate.

Heading 3 · .h3clamp(22px, 2vw, 30px)400 · −0.03em · 1.1Now —

Racked and burned in within 11 days.

Rich text · .rt18px · 17px on phones400 · 1.6 · --accent

Narvik sits at 68.4° N. For about 8,400 hours a year, outside air is colder than the 24 °C we feed the cold aisle.

Body · .lede16px400 · 1.45 · --mute

Power, cooling, fabric and checkpoint storage are in the rate. Longer terms lower it.

Small · nav, lists14px400 · --mute

Engineers reply within one working day.

Label · .monoGeist Mono 10px400 · +0.1em · uppercase
69.6492° N — Arctic compute
Figures · .numGeist Mono · tabular400 · −0.04em · slashed zero

$1.46 · 99.995%

Wrap a short gray ending in <span class="tone nw"> so headings never break on an orphan word. Headings already use text-wrap: balance.

03ButtonsOne style, two weights

The pill is the only button. It draws its own square and arrow, so the label is plain text. Hover the specimens to see the fill sweep.

.pill

Primary. 38px high, 2px radius, mono 11px. On hover a black fill sweeps in from the left in 0.6s and the arrow cell shifts.

.pill.ghost

Secondary. Hairline outline at 30% white; on hover it fills white and the text turns black.

.mbtn

Menu toggle. The label rolls from Menu to Close and the bars cross when aria-expanded is true. Click to try.

Never type an arrow into a label and never make round icon buttons; use a ghost pill instead.

04Form elementsForm block

Fields are underlined, not boxed. A violet line draws in on focus. Choice chips are plain radio inputs styled through their label.

.fld · .opt · .form-foot

Request received. This is the form block's success message.

Something went wrong. Please try again, or email hello@example.com.

Checked chip: lilac outline, 10% violet fill and a glowing square. Focus a field to see the underline draw.

05Tags & chipsSmall labels

Tags mark a category or a state. Chips sit on photos and the shader, so they carry their own blurred backing.

EngineeringMost booked−4 °C outsideLivePress M
.tag

24px, hairline outline, gray mono text. Use with .mono.

.tag.v

Lilac variant for one highlighted state per view.

.chip4

Icon + label on a blurred dark backing. Add .lit to light the icon on hover.

06IconsDot-matrix set

Eight icons drawn on a 3px dot grid. Hover a cell: the dots light up in sequence and turn lilac.

Coldcold
Powerbolt
Waterdrop
Fabricloop
Computechip
Telemetrypulse
Airflowair
Sovereignshield

Each dot carries --i, which staggers its transition by 12ms. Put .lit on the hover parent, not on the SVG.

07ComponentsReusable blocks
Section label.lab
08PlatformBuilt into every hall

The number is a CSS counter on body, so labels count 01, 02, 03 down the page by themselves. Title first, subtitle second.

Tiles.tiles · .tile.lit

Air-cooled

Outside air below 10 °C for 300 days a year. No chillers to power.

Chillers0

Hydro power

Fixed-price hydro from the valleys behind Narvik.

Renewable98.7%

Fabric

Non-blocking InfiniBand on every pod, shared or dedicated.

Per node3.2 Tb/s
Framed quote.vq · mini
Customer since 2024
“In Narvik our runs just keep going. Fewer restarts, steadier throughput.”
Amara Okafor, Head of Infrastructure−38%job restarts

The frame lines draw in sequence on scroll. Pair with .vph for the portrait, as on Home 04.

Accordion.qa · .qi
What does all-in include?

Power, cooling, rack space, InfiniBand fabric, checkpoint storage and 24/7 hands on site.

Yes. The lower rate applies from the next billing month.

No setup fee on Pod or Dedicated. Sovereign fit-out is agreed up front.

One item open at a time. The shared script toggles .on and aria-expanded; height animates with a grid-row trick, no JS measuring.

09Spacing & gridFluid tokens

Two tokens set the rhythm: the side gutter and the section padding. Layouts sit on a 12-column grid with a fixed 24px gap.

--gutclamp(16px, 2.2vw, 32px)—
--secclamp(120px, 14vw, 220px)—
Grid gap24px · .grid1224px
Nav height64px · .nav-in64px
Rule padding22px · .rule22px
Desktop> 960

12 columns, side labels, sticky asides.

Tablet≤ 960

Spans collapse to full width; meta rows go to two columns.

Phone≤ 600

Single column, 16px gutter, tested at 375px.

10ShaderRibbed violet silk

One live SVG light draws every violet surface: soft silk folds seen through horizontal flutes, animated with GSAP. Each shader div takes its settings from a data-shader JSON attribute.

—Move the pointer over it
Pricing 01 hero
OptionTypeDefaultWhat it does
light[x, y] · 0–1[.6, .5]

Where the light sits. x from the left, y from the bottom. It drifts slowly around this point.

fillnumber · 0–1.8

How much of the block the light covers. Around .5 for cards, 1 for wide bands.

ribpx10

Height of one horizontal flute, in CSS pixels.

tonecolour#6E4BFF

Violet of the light. Change it to recolour one block; every page uses the default.

seednumber0

Start position, so two blocks never fold the same way.

glow0–1.95

Overall strength of the light.

cursor0–1.55

Strength of the small light that follows a fine pointer. 0 turns it off.

data-silkattributeon

Turns the live light on. Without it the block keeps only its data-still image.

With a fine pointer a small light follows the cursor. The silk pauses off screen, holds one still frame with reduced motion, and keeps the rendered still on .glass when JavaScript is off.

11MotionHooks, no timelines

Add a class or attribute and the shared script animates it with GSAP and ScrollTrigger. Without GSAP, with reduced motion or with ?still in the URL, everything simply shows.

HookWhenWhat it does
.bhOn load, after the loader

Hero headline. Split into letters that fade in from a 16px blur, 20ms apart.

.bsScroll · top at 88%

Same letter blur-in for section headlines, from a 14px blur.

[data-in]On load

Hero items rise 16px and fade in, 80ms apart, in DOM order.

.rvScroll · top at 88%

Reveal: the block rises 28px and fades in over 1.1s.

[data-stagger]Scroll · top at 85%

Each direct child reveals in turn, 70ms apart. Use on grids and lists.

.clipinScroll · scrubbed

An image frame opens from an inset clip to full size as it travels up the screen.

[data-count]Scroll · top at 92%

Counts from 0 to the written number in 1.6s, keeping prefix, suffix, commas and decimals: $1.46, −34%, 2,048.

AutomaticScroll

.lab labels rise in, .qa items stagger, .vq frames draw their lines, .vph portraits unclip with a slow parallax.

12
Next
From system to site

Make it yours
in ten steps.

Variables, fonts, shader, motion and CMS, explained against the real code.

Read the instructions