Files
kjol/go/cmd/kjol-website/css/app.css
2026-07-17 16:58:16 -04:00

185 lines
10 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ---------------------------------------------------------------------------
kjol-website — brand stylesheet for the Kjol Go/WASM section (/wasm/*).
---------------------------------------------------------------------------
There is deliberately no `@import "tailwindcss"` and no `@custom-variant dark`
here. twcss compiles this file via tw.CompileAppFiles, which prepends kjol's
shared extension layer (tw/kjol_theme.css) — the import, the class-based dark
variant, the semantic tokens (surface/line/ink/…), and the chart palette. This
file carries only what is genuinely this app's: the brand.
The values below match the /js side's frontend/css/style.css on purpose — same
Open Sans, same navy accent — so that crossing between /wasm and /js reads as two
parts of ONE site rather than two demos that happen to share a domain. The two
sections are built by completely different pipelines; they should not look like it.
--------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
Open Sans — self-hosted (files in wwwroot/fonts). One variable file per subset
carries weights 400700 upright and italic, so the four faces below cover the
whole UI. unicode-range keeps the browser to the one subset a glyph needs, and
font-display: swap paints text in the fallback first rather than blocking on the
download. The same four blocks live in the /js side's frontend/css/style.css so
both front-ends render in one typeface. --font-sans (below) points at it. */
@font-face {
font-family: "Open Sans";
font-style: normal;
font-weight: 400 700;
font-display: swap;
src: url("/fonts/opensans-latin-normal.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Open Sans";
font-style: normal;
font-weight: 400 700;
font-display: swap;
src: url("/fonts/opensans-latin-ext-normal.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Open Sans";
font-style: italic;
font-weight: 400 700;
font-display: swap;
src: url("/fonts/opensans-latin-italic.woff2") format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Open Sans";
font-style: italic;
font-weight: 400 700;
font-display: swap;
src: url("/fonts/opensans-latin-ext-italic.woff2") format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* The brand — the values the shared kit's tokens are re-pointed to. Everything the
kit already defines (surfaces, lines, ink, the chart palette, the state colours)
comes from tw/kjol_theme.css; this block sets only what is this site's own. */
@theme {
--radius-default: 0.375rem;
/* The UI typeface. --font-sans is what Tailwind's preflight points html at, and
the kit's utilities (font-sans) resolve to, so this one line moves the whole
site onto Open Sans; the fallbacks cover the swap window and any glyph outside
the vendored subsets. */
--font-sans: "Open Sans", ui-sans-serif, system-ui, sans-serif;
/* Navy and red — the flag, muted. kjøl is a Norwegian word and the palette says so.
Both are dark and low-key: the page is mostly prose, code and tables, and the brand's
job is to mark the few things you can act on, not to compete with them for attention. */
--color-primary: #1e3a63; /* muted navy — FILLS; they carry white text */
--color-primary-hover: #16294a;
--color-primary-subtle: #eef2f8; /* a navy wash — tinted panels, badges, callouts */
--color-primary-border: #c5d1e2;
/* accent is for TEXT and icons — links, the eyebrow, an active sidebar row. It is still a
separate token from primary, because the two have opposite constraints: a fill must be
dark enough for white text on TOP of it, and accent text must be readable ON the
surface. Here they are the same hue — navy — but not the same value: the accent is a
touch deeper so a navy link on white is unmistakably a link. */
--color-accent: #1c3a66; /* navy — accent TEXT */
/* Heading ink — a touch stronger than body ink. Not part of the shared contract, so
the site names it here and re-points it in the .dark block below. */
--color-text-heading: #111827;
}
/* ---------------------------------------------------------------------------
Grid background
---------------------------------------------------------------------------
Plain CSS, not a utility: Tailwind's arbitrary-value syntax cannot carry a
background-image with commas in it without becoming unreadable, and this is a
single named thing rather than a composition of atoms. kjol's Tailwind engine
passes rules it does not recognise straight through, so this lands in the output
untouched.
The grid is drawn with two 1px gradients — a vertical set and a horizontal set —
tiled at --grid-size. It is deliberately faint: it should register as texture, not
as graph paper you have to read the page through.
--------------------------------------------------------------------------- */
:root {
--grid-line: rgba(30, 58, 99, 0.06); /* the navy, at the edge of visible */
}
/* The dark values for the brand.
---------------------------------------------------------------------------
The shared surfaces/lines/ink re-point themselves in tw/kjol_theme.css's own .dark
block; this one moves only the site's brand. Navy is too dark to read on a near-black
page, so both brand tokens climb to a lighter blue. The accent (TEXT) climbs furthest,
to a soft sky a link stays legible in; the fill climbs less, to a steel blue that still
looks like a button and still carries white text. The tinted panel inverts outright,
because a pale wash on #101013 is not a tint, it is a white box. */
.dark {
--color-accent: #9fc1ec;
--color-primary: #2b4f80;
--color-primary-hover: #37619b;
--color-primary-subtle: #182234;
--color-primary-border: #2c3e5c;
--color-text-heading: #f5f5f5;
/* The grid is drawn in ink, not in shadow, once the page is dark. */
--grid-line: rgba(226, 232, 240, 0.05);
}
/* Only the font. The page's background and text colour come from the shared layer's
`html` rule, which paints them from --color-surface / --color-ink — the tokens the
.dark block re-points. Setting them here would pin the page to white and leave a dark
app sitting in a white window. */
html {
font-family: var(--font-sans);
}
/* ---------------------------------------------------------------------------
The wordmark's logo tile: a muted Norwegian flag.
---------------------------------------------------------------------------
kjøl is a Norwegian word — the mark says so. It is the flag's Scandinavian cross: a
navy cross with an off-white outline on a red field, offset LEFT as the real flag is
(the vertical bar sits at ~38% rather than centre). Muted, not the flag's full
saturation — it is a 32px tile next to body text, not a banner.
Drawn in layered gradients over a red base rather than as an <img>, so it inherits the
tile's rounded corners and border, needs no asset request, and cannot 404. Layers paint
TOP-first, so the reading is: dim scrim, then navy cross, off-white cross, red field. Each
band is transparent outside its stripe (hard stops via doubled positions) so the layer
beneath shows through. The bands are constant across light and dark — a flag does not
change with the page theme.
The topmost layer is a flat dark scrim, and it is there so the WHITE sailboat on top of
the tile reads on its own — no outline, no shadow on the glyph. The boat is a thin white
stroke and the off-white cross is exactly the band it would vanish into; rather than trace
the boat in shadow, the whole flag is dimmed until white stands out against every band of
it, the pale cross included. A dimmer, moodier flag with a crisp white boat, on purpose.
The cross geometry, as percentages of the tile:
vertical (offset left, centre 38%): off-white 2749%, navy 32.543.5%
horizontal (centred, centre 50%): off-white 3961%, navy 44.555.5% */
.flag-no {
background-color: #a83f4c; /* the red field, muted (then dimmed by the scrim above) */
background-image:
linear-gradient(rgba(0, 0, 0, 0.42), rgba(0, 0, 0, 0.42)), /* the dim scrim, on top */
linear-gradient(180deg, transparent 44.5%, #294c76 44.5%, #294c76 55.5%, transparent 55.5%),
linear-gradient(90deg, transparent 32.5%, #294c76 32.5%, #294c76 43.5%, transparent 43.5%),
linear-gradient(180deg, transparent 39%, #ece6da 39%, #ece6da 61%, transparent 61%),
linear-gradient(90deg, transparent 27%, #ece6da 27%, #ece6da 49%, transparent 49%);
}
.bg-grid {
background-image:
linear-gradient(to right, var(--grid-line) 1px, transparent 1px),
linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px);
/* Written out rather than as var(--size) var(--size): the CSS minifier drops the
space between two adjacent var() calls, and while that is still legal CSS, a
background-size that depends on how a minifier tokenises is not worth the cleverness. */
background-size: 56px 56px;
background-position: center top;
}
/* Fades the grid out towards the bottom, so it frames the hero and then gets out of
the way of the content below rather than running under it the whole page. */
.grid-fade {
-webkit-mask-image: linear-gradient(to bottom, #000, #000 35%, transparent 100%);
mask-image: linear-gradient(to bottom, #000, #000 35%, transparent 100%);
}