Primitive OKLCH scales. Mode-agnostic — they do not change between
light and dark themes (ADR 0003). Semantic mappings live in
semantic.css.
teal
50oklch(0.99 0.01 195)#f5fefergb(245, 254, 254)
100oklch(0.97 0.05 195)#cfffffrgb(207, 255, 255)
200oklch(0.96 0.08 195)#b1ffffrgb(177, 255, 255)
300oklch(0.93 0.13 195)#68ffffrgb(104, 255, 255)
400oklch(0.85 0.19 195)#00f2f4rgb(0, 242, 244)
500oklch(0.68 0.15 195)#00b3b5rgb(0, 179, 181)
600oklch(0.55 0.13 195)#008889rgb(0, 136, 137)
700oklch(0.38 0.09 195)#005051rgb(0, 80, 81)
800oklch(0.27 0.06 195)#002f2frgb(0, 47, 47)
900oklch(0.18 0.04 195)#001717rgb(0, 23, 23)
950oklch(0.11 0.02 195)#000606rgb(0, 6, 6)
green
50oklch(0.99 0.01 146)#f8fef8rgb(248, 254, 248)
100oklch(0.97 0.05 146)#e1ffe1rgb(225, 255, 225)
200oklch(0.96 0.08 146)#d0ffd2rgb(208, 255, 210)
300oklch(0.93 0.13 146)#aeffb3rgb(174, 255, 179)
400oklch(0.86 0.19 146)#72f181rgb(114, 241, 129)
500oklch(0.68 0.15 146)#51b05crgb(81, 176, 92)
600oklch(0.56 0.13 146)#388842rgb(56, 136, 66)
700oklch(0.38 0.09 146)#1c4f23rgb(28, 79, 35)
800oklch(0.28 0.06 146)#123116rgb(18, 49, 22)
900oklch(0.19 0.04 146)#071808rgb(7, 24, 8)
950oklch(0.11 0.02 146)#020602rgb(2, 6, 2)
yellow
50oklch(0.99 0.01 105)#fdfcf5rgb(253, 252, 245)
100oklch(0.98 0.05 105)#fdfbd4rgb(253, 251, 212)
200oklch(0.96 0.08 105)#f9f6b7rgb(249, 246, 183)
300oklch(0.94 0.13 105)#f8f085rgb(248, 240, 133)
400oklch(0.87 0.19 105)#e8d900rgb(232, 217, 0)
500oklch(0.7 0.15 105)#ada200rgb(173, 162, 0)
600oklch(0.57 0.13 105)#837a00rgb(131, 122, 0)
700oklch(0.39 0.09 105)#4d4700rgb(77, 71, 0)
800oklch(0.28 0.06 105)#2d2a00rgb(45, 42, 0)
900oklch(0.19 0.04 105)#171500rgb(23, 21, 0)
950oklch(0.11 0.02 105)#050500rgb(5, 5, 0)
neutral
50oklch(0.99 0.005 90)#fdfcf8rgb(253, 252, 248)
100oklch(0.97 0.008 90)#f7f5efrgb(247, 245, 239)
200oklch(0.95 0.01 90)#f1eee7rgb(241, 238, 231)
300oklch(0.9 0.012 90)#e1ded5rgb(225, 222, 213)
400oklch(0.8 0.014 90)#c1bdb4rgb(193, 189, 180)
500oklch(0.65 0.012 90)#928f87rgb(146, 143, 135)
600oklch(0.5 0.01 90)#65635drgb(101, 99, 93)
700oklch(0.38 0.008 90)#44423ergb(68, 66, 62)
800oklch(0.28 0.006 90)#2a2926rgb(42, 41, 38)
900oklch(0.1913 0 0)#141414rgb(20, 20, 20)
950oklch(0.1 0 90)#030303rgb(3, 3, 3)
Semantic tokens
Role-named mappings to primitives. The resolved value below each
swatch updates live when you toggle the theme — that is the light/dark
behaviour these tokens encode.
--surface-default
…
…
light var(--c-juli-yellow-50) dark var(--c-juli-teal-950)
--surface-elevated
…
…
light var(--c-white) dark var(--c-juli-teal-900)
--text-default
…
…
light var(--c-juli-teal-800) dark var(--c-juli-yellow-50)
--text-strong
…
…
light var(--c-juli-teal-700) dark var(--c-juli-yellow-100)
--text-muted
…
…
light var(--c-juli-green-600) dark var(--c-juli-yellow-400)
--border-subtle
…
…
light var(--c-juli-neutral-200) dark var(--c-juli-neutral-800)
--focus-ring
…
…
light var(--c-juli-teal-700) dark var(--c-juli-green-300)
--surface-action
…
…
light var(--c-juli-green-400) dark var(--c-juli-green-500)
--text-on-action
…
…
light var(--c-juli-teal-800) dark var(--c-juli-neutral-950)
--status-available-surface
…
…
light var(--c-juli-green-200) dark var(--c-juli-green-900)
--status-available-text
…
…
light var(--c-juli-green-900) dark var(--c-juli-green-300)
--status-reserved-surface
…
…
light var(--c-juli-teal-200) dark var(--c-juli-teal-800)
--status-reserved-text
…
…
light var(--c-juli-teal-900) dark var(--c-juli-teal-200)
--status-coming-soon-surface
…
…
light var(--c-juli-teal-100) dark var(--c-juli-teal-700)
--status-coming-soon-text
…
…
light var(--c-juli-teal-700) dark var(--c-juli-teal-100)
--status-let-surface
…
…
light var(--c-juli-neutral-200) dark var(--c-juli-neutral-800)
--status-let-text
…
…
light var(--c-juli-neutral-700) dark var(--c-juli-neutral-300)
--flag-new-surface
…
…
light var(--c-juli-yellow-400) dark var(--c-juli-yellow-400)
--flag-new-text
…
…
light var(--c-juli-neutral-950) dark var(--c-juli-neutral-950)
--status-pill-border
…
…
light transparent dark var(--c-juli-teal-700)
Type scale
Fluid type steps from Utopia. Each clamp() interpolates between
a 320 px and 1440 px viewport. Sample text is rendered at the live value
of each step.
--step--2
The quick brown fox jumps over the lazy dog
clamp(0.6944rem, 0.6919rem + 0.0129vw, 0.7035rem)
--step--1
The quick brown fox jumps over the lazy dog
clamp(0.8333rem, 0.8035rem + 0.1491vw, 0.9377rem)
--step-0
The quick brown fox jumps over the lazy dog
clamp(1rem, 0.9286rem + 0.3571vw, 1.25rem)
--step-1
The quick brown fox jumps over the lazy dog
clamp(1.2rem, 1.0668rem + 0.6661vw, 1.6663rem)
--step-2
The quick brown fox jumps over the lazy dog
clamp(1.44rem, 1.2168rem + 1.1159vw, 2.2211rem)
--step-3
The quick brown fox jumps over the lazy dog
clamp(1.728rem, 1.3758rem + 1.7611vw, 2.9607rem)
--step-4
The quick brown fox jumps over the lazy dog
clamp(2.0736rem, 1.5384rem + 2.6758vw, 3.9467rem)
--step-5
The quick brown fox jumps over the lazy dog
clamp(2.4883rem, 1.6962rem + 3.9608vw, 5.2609rem)
Spacing scale
Fluid spacing steps from Utopia. Each bar's width is the live value of
its token. Pairs (e.g. --space-s-m) interpolate between
two base steps over the viewport range.
Corner-radius primitives. Mode-agnostic. --radius-pill is an
arbitrarily large value that fully rounds any box into a pill or circle.
Each demo box has the token applied as its
border-radius.
--radius-s0.5rem
--radius-m1rem
--radius-pill624.9375rem
Section tones
data-tone contexts (ADR 0013) remap the semantic
surface/text/border tokens for their subtree, so any component inside
adapts. dark and light hold their tone in
both site modes (shifting shade per mode); inverse is the
page's opposite tone; accent is the gentle same-tone
raise. Toggle the theme to watch each shade shift.
data-tone="accent"
Heading, body copy and a link all read from the
remapped tokens.
data-tone="inverse"
Heading, body copy and a link all read from the
remapped tokens.
data-tone="light"
Heading, body copy and a link all read from the
remapped tokens.
data-tone="dark"
Heading, body copy and a link all read from the
remapped tokens.
Link
An inline text link. Carries its own styling (underlined,
--text-default, hover to --text-strong) so
it settles link appearance for the blocks that use it without touching
the global <a> defaults (ADR 0011).
The action / CTA affordance. Polymorphic: with href it is
an <a> (a CTA that navigates), otherwise a
<button> (a real action) — same look, picked by
intent. primary fills with --surface-action;
secondary is an outline that reads
--text-default, so it adapts inside tone contexts. A
link-styled affordance stays the Link primitive's job (no third
variant). Toggle the theme to check both.
A Listing rendered as a card, in the brand layout (ADR 0014): a mint
garden-tone header band (name + address) on top, then the
photo, then the body — price, an inline status line with a colour-coded
dot (one per Availability state, ADR 0010), and the specs. Presentational:
all strings are pre-localized by the caller. Toggle the theme to check
contrast in both modes.
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum.
Strandgade 7, 1.5000 Odense C
6.950 kr/md.Lejlighed
New Coming soon
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero.
Bredgade 44, 3.5200 Odense V
9.500 kr/md.Lejlighed
Let
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet.
The same cards inside a data-tone="dark" band. The card
reads only semantic tokens, so it adapts to the tone (ADR 0013) — the
header band, status dot and text all stay legible. Toggle the theme to
confirm both directions.
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum.
Strandgade 7, 1.5000 Odense C
6.950 kr/md.Lejlighed
New Coming soon
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero.
The Property kind (kind="property"): a
development/building shown with general info — area + rooms ranges and
a read-more cue, no single price, type, deposit, or availability status
(CONTEXT.md). Same component, varies by kind.
A full-bleed band: prose + CTA on the left, an Embla-powered row of
listing cards that bleeds off the right edge (ADR 0011). Tone-agnostic
— drop it in a data-tone section and it adapts, pills
included (ADR 0013). Drag or scroll; tab into a card and it scrolls
into view (ADR 0007). Shown here in a dark band; the
progress bar stands in for a scrollbar.
Andra bostadssökande tittade också på dessa
I samma område hittar du även andra intressanta hyresbostäder.
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum.
Strandgade 7, 1.5000 Odense C
6.950 kr/md.Lejlighed
New Coming soon
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero.
Bredgade 44, 3.5200 Odense V
9.500 kr/md.Lejlighed
Let
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet.
Listings grid
A responsive grid of listing cards whose bands line up across the row
via subgrid (ADR 0015): header bands share a height so the photos start
on a common line, and footers share a baseline — no clamped line counts
or measured heights. Note the varied address and description lengths;
the cards still align. A real list (ul/li),
one tab stop per card. This is the static "browse all" surface; the
carousel above shares the same band alignment (its track is a
horizontal grid).
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum.
Strandgade 7, 1.5000 Odense C
6.950 kr/md.Lejlighed
New Coming soon
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero.
Bredgade 44, 3.5200 Odense V
9.500 kr/md.Lejlighed
Let
Worem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vulputate libero et velit interdum, ac aliquet.
Hero
The page-leading block in the Juli brand layout (ADR 0014): a soft
mint garden-tone panel — headline, a handwritten accent
line, a lede and the green primary CTA — beside a contained
feature photo. Editor-friendly: the photo is a plain contained block,
so any image crops cleanly and the panel (not the photo) carries text
contrast. Presentational — strings are pre-localized.
Koti joka antaa vapauden
syödä pizzaa aamiaiseksi
Juli tekee vuokra-asumisesta helpompaa ja laadukkaampaa kuin koskaan.
A row of Feature items. Two-up by default; the odd trailing item spans
the full row and flips to media-beside-text — count-driven CSS, not a
per-item prop (ADR 0011). This sample has three items, so both layouts
show. Resize narrow to see it collapse to a single column.
Helppo vuokraus tyytyväisyystakuulla
Teemme asumisen helpoksi alusta alkaen. Koko vuokrausprosessimme hoituu nopeasti verkossa – tyytyväisyystakuulla.
Me Juli Livingillä haluamme tarjota sinulle erityisen laadukkaan kodin ja mukavan arjen. Olemme skandinaavinen brändi ja toimineet Suomessa vuodesta 2020 alkaen.
Site chrome: brand wordmark + primary nav. Sub-menus use the W3C APG
disclosure pattern (a <button aria-expanded> toggling
a sibling list) — keyboard-operable, Escape-to-close, axe-clean (ADR
0006/0007). Open a sub-menu, then press Escape or click outside. Resize
below 48rem to collapse the nav behind the menu toggle.
Footer
Site chrome: multi-column link grid + a utility row with copyright, the
EAA-mandated Accessibility Statement link (ADR 0007), and the theme
switcher. Each column is a <nav> landmark named by its
heading. Presentational — strings are pre-localized by the caller.