/* Navet · Tecken — tokens and the hub stylesheet.
   Ported 2026-10-04 from the Navet Live artifact (claude.ai/artifact/9rL8zFqHBzrW8ZJQFAwxuS).
   A page that links this file inherits the hub design; one that does not is free. */

/* hub-owned:begin the cascade layers the card motion layer composes in: kortlek.css (Kortlek, design/kortlek/) declares the same order. The card's own rules sit in navet-base, so an unlayered hub rule beats both. */
@layer navet-base, kortlek;
/* hub-owned:end */

/* tokens.json compiled: natt first (Tecken is night first), dag on data-theme="dag" */
:root {
  --void: #0a0b0c;
  --cell: #131518;
  --grid: #25292d;
  --wire: #646b72;
  --ink: #eceee9;
  --ink-dim: #a6aca8;
  --ink-faint: #8b918e;
  --on-ink: #0a0b0c;
  --free: #ffb454;
  --free-deep: #2e2110;
  --ok: #6cc7ff;
  --err: #ff7867;
  --q1: 4px;
  --q2: 8px;
  --q3: 12px;
  --q4: 16px;
  --q5: 20px;
  --q6: 24px;
  --q8: 32px;
  --q12: 48px;
  --square: 0px;
  --font-mono: "Martian Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  color-scheme: dark;
}
html[data-theme="dag"] {
  --void: #f2f2ee;
  --cell: #ffffff;
  --grid: #dadbd4;
  --wire: #7d8079;
  --ink: #0c0d0e;
  --ink-dim: #45494b;
  --ink-faint: #5c605d;
  --on-ink: #f2f2ee;
  --free: #8f4e00;
  --free-deep: #fbeedd;
  --ok: #005d8f;
  --err: #b3261e;
  color-scheme: light;
}



/* Navet · Tecken — the hub's stylesheet. Linking it is inheriting the hub design.
   Colours, spacing and the one radius come from tokens.css; nothing here names a colour. */

/* ------------------------------------------------------------ motion --
   The law, amended 2026-10-02: time is continuous, space is quantised.
   Whatever moves, eases: it leaves fast and settles long. Whatever is drawn as
   characters lands on the 20px text row. The wheel always worked this way: it turns
   smoothly and is drawn on the grid. Language and theme still cut. */
:root {
  --t-cut: 0ms;                    /* language and theme switch: instant */
  --t-blink: 80ms;                 /* hover, linear */
  --t-travel: 440ms;               /* a card title travelling into its page heading */
  --t-return: 310ms;               /* the same journey home, 30% shorter */
  --e-travel: cubic-bezier(.2, 0, 0, 1);
  --t-scan: 380ms;                 /* the page scanned in behind the title */
  --e-scan: linear;                /* replaced per navigation by an eased staircase, one step per 20px row */
  --d-scan: 60ms;                  /* the page follows the title, never leads it */
  --d-land: 170ms;                 /* lede and meta land last */
  --t-boot: 400ms;                 /* the emblem's ramp resolving from dots, first mount per session */
  --tk-dur: var(--t-travel);
}
html[data-tk-nav="out"] { --tk-dur: var(--t-return); }
@media (prefers-reduced-motion: reduce) {
  :root { --t-blink: 0ms; --t-scan: 0ms; --t-boot: 0ms; --t-travel: 0ms; --t-return: 0ms; }
}

@view-transition { navigation: auto; }
@keyframes tk-scan { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }
@keyframes tk-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes tk-in { from { opacity: 0; } to { opacity: 1; } }
::view-transition-group(*) { animation-duration: var(--tk-dur); animation-timing-function: var(--e-travel); }
/* The title is one face at two sizes, so the travel is pure scale. The two rasters swap
   while the sharper one is the smaller: early on the way in, late on the way home. */
::view-transition-old(*) { animation: tk-out calc(var(--tk-dur) * .3) linear both; }
::view-transition-new(*) { animation: tk-in calc(var(--tk-dur) * .3) linear both; }
html[data-tk-nav="out"]::view-transition-old(*) { animation: tk-out calc(var(--tk-dur) * .3) linear calc(var(--tk-dur) * .55) both; }
html[data-tk-nav="out"]::view-transition-new(*) { animation: tk-in calc(var(--tk-dur) * .3) linear calc(var(--tk-dur) * .55) both; }
/* Into or out of an own-design page the face itself changes: cut it at the midpoint, never blend two faces. */
html[data-tk-free]::view-transition-old(*) { animation: tk-out 1ms steps(1, end) calc(var(--tk-dur) * .5) both; }
html[data-tk-free]::view-transition-new(*) { animation: tk-in 1ms steps(1, end) calc(var(--tk-dur) * .5) both; }
/* The page: the old one holds still, the new one is scanned in row by row behind the title. */
::view-transition-old(root) { animation: none; }
::view-transition-new(root) { animation: tk-scan var(--t-scan) var(--e-scan) var(--d-scan) both; }
html[data-tk-nav="in"] :is(.pg-lede, .ug-lede, .bw-lede) { view-transition-name: tk-lede; }
html[data-tk-nav="in"] .pg-meta { view-transition-name: tk-meta; }
::view-transition-new(tk-lede), ::view-transition-new(tk-meta) { animation: tk-scan var(--t-scan) var(--e-scan) var(--d-land) both; }
/* Between pages the wheel is part of the page and is scanned over with it. */
html[data-tk-nav] .tk-emblem { view-transition-name: none !important; }
::view-transition-old(emblem) { display: none; }
::view-transition-new(emblem) { animation: none; }
/* A cut is a cut: language and theme switch with no animation at all. */
html[data-tk-transition="cut"]::view-transition-group(*),
html[data-tk-transition="cut"]::view-transition-old(*),
html[data-tk-transition="cut"]::view-transition-new(*) { animation: none; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
.tk-scan-in { animation: tk-scan var(--t-scan) var(--e-travel) both; }

/* -------------------------------------------------------------- page -- */
html { background: var(--void); color-scheme: dark; }
html[data-theme="dag"] { color-scheme: light; }
body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 13px; line-height: 20px; font-weight: 350; font-stretch: 112.5%;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
::selection { background: var(--ink); color: var(--on-ink); }
.tk-machine { font-stretch: 75%; }
/* in navet-base with the card's rules below: the card title is .tk-human and sets its own 75%, which only wins by coming later */
@layer navet-base { .tk-human { font-stretch: 112.5%; } }
.tk-hub *, .tk-hub *::before, .tk-hub *::after { box-sizing: border-box; }

.tk-link {
  color: var(--ink); text-decoration-line: underline; text-decoration-thickness: 1px; text-underline-offset: 3px;
}
.tk-link:hover { background: var(--ink); color: var(--on-ink); text-decoration: none; }
.tk-link:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; border-radius: var(--square); }

/* ------------------------------------------------------------ Emblem -- */
.tk-emblem { position: relative; display: block; margin: 0 auto; max-width: 100%; overflow: hidden; touch-action: pan-y; }
.tk-emblem-layer, .tk-emblem-probe {
  font-family: var(--font-mono); font-size: 11px; line-height: 11px; font-weight: 500; font-stretch: 75%;
  letter-spacing: 0; font-variant-ligatures: none; font-kerning: none; white-space: pre;
}
.tk-emblem-layer { position: absolute; left: 0; top: 0; margin: 0; pointer-events: none; }
.tk-emblem-probe { position: absolute; visibility: hidden; }
.tk-emblem-dim { color: var(--ink-faint); }
.tk-emblem-mid { color: var(--ink-dim); }
.tk-emblem-bright { color: var(--ink); }
.tk-emblem-free { color: var(--free); }
.tk-emblem-hot { color: var(--ink); }
.tk-emblem-hotfree { color: var(--free); }
.tk-emblem-layer { transition: color var(--t-blink) linear; }
/* A card under the pointer lights its own spoke; the rest of the wheel steps back. */
.tk-emblem.is-hot :is(.tk-emblem-mid, .tk-emblem-bright) { color: var(--ink-faint); }
.tk-emblem.is-hot .tk-emblem-free { color: color-mix(in srgb, var(--free) 38%, var(--void)); }

/* --------------------------------------------------------------- Tag -- */
.tk-tag {
  display: inline-flex; align-items: center; gap: var(--q1);
  min-height: 20px; padding: 1px var(--q1);
  border: 1px solid var(--wire); border-radius: var(--square);
  color: var(--ink); background: transparent;
  font-family: var(--font-mono); font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%;
  letter-spacing: 0.04em; text-transform: lowercase; white-space: nowrap;
}
.tk-tag-glyph { letter-spacing: 0; }
.tk-tag--free { color: var(--free); background: var(--free-deep); border-color: var(--free); }
.tk-tag--pending { color: var(--ink-faint); border-style: dashed; }
.tk-tag--ok { color: var(--ok); border-color: currentColor; }
.tk-tag--err { color: var(--err); border-color: currentColor; }
.tk-tag--caution { color: var(--on-ink); background: var(--ink); border-color: var(--ink); }

/* ------------------------------------------------------- ProjectCard -- */
/* The card's base rules sit in @layer navet-base (declared first above), below Kortlek's layer, so Kortlek's
   transition and edge replace these on a card it composes; a card without data-fx (pending, wip) keeps them. */
@layer navet-base {
.tk-card {
  display: flex; flex-direction: column; gap: var(--q3); min-width: 0;
  padding: var(--q4); color: var(--ink); text-decoration: none;
  background: var(--cell); border: 1px solid var(--wire); border-radius: var(--square);
  transition: background-color var(--t-blink) linear, color var(--t-blink) linear, border-color var(--t-blink) linear;
}
.tk-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--q2); min-width: 0; }
.tk-card-slug {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint);
}
/* The card title is set in the page title's own face (display: condensed, bold, -0.03em),
   so the travel from card to heading is a change of size and nothing else. */
.tk-card-title {
  margin: 0; width: fit-content; max-width: 100%;
  font-size: 20px; line-height: 20px; font-weight: 700; font-stretch: 75%; letter-spacing: -0.03em;
  color: var(--ink); overflow-wrap: anywhere;
}
.tk-card-blurb {
  margin: 0; max-width: 64ch; font-size: 13px; line-height: 20px; font-weight: 350; font-stretch: 112.5%;
  color: var(--ink-dim);
}
.tk-card-state { display: flex; align-items: center; gap: var(--q2); margin-top: auto; }
.tk-card-go {
  display: inline-block; padding: 0 var(--q1); margin-left: calc(-1 * var(--q1));
  font-size: 12px; line-height: 20px; font-weight: 600; font-stretch: 75%; color: var(--ink);
  transition: background-color var(--t-blink) linear, color var(--t-blink) linear;
}
.tk-card--link { cursor: pointer; -webkit-tap-highlight-color: transparent; }
/* Hover wakes the card instead of inverting it: the wire turns to ink, the -> becomes the one
   inverse-video cell, and the signature strip comes alive. The title never changes colour,
   so the title that travels into the page is the title you were reading. */
.tk-card--link:hover, .tk-card--link.is-awake, .tk-card.is-hover { border-color: var(--ink); }
.tk-card--link:is(:hover, .is-awake, .is-hover) .tk-card-go { background: var(--ink); color: var(--on-ink); }
.tk-card--link:active, .tk-card.is-active { border-color: var(--ink-dim); }
.tk-card--link:active .tk-card-go { background: var(--ink-dim); }
.tk-card--link:focus-visible, .tk-card.is-focus { outline: 2px solid var(--ink); outline-offset: 2px; }
}

/* Under construction: the card shows as much of itself as the project has earned. */
.tk-sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.tk-wip-h { color: var(--ink-faint); font-weight: 400; }
.tk-card--wip .tk-card-title .tk-wip-h { color: var(--ink-faint); font-weight: 500; }
.tk-strip-tape.is-narrow .tk-tag { display: none; }
.tk-card--wip .tk-card-slug { color: var(--ink-faint); }
/* Not open yet: a card with nowhere to go is drawn as an outline, not a cell. No fill, a dashed wire,
   its words faint; it stands at the bottom of the list under its own [~] label. */
.tk-card--pending { background: transparent; border-style: dashed; }
.tk-card--pending .tk-card-title { color: var(--ink-dim); }
.tk-card--pending .tk-card-blurb { color: var(--ink-faint); }
.tk-card--pending .tk-strip { border-bottom-style: dashed; }
.tk-hub-sub {
  grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--q2); margin-top: var(--q4); padding-top: var(--q4);
  border-top: 1px dashed var(--wire); color: var(--ink-faint);
  font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.04em; text-transform: lowercase;
}
.tk-wip-meter { font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.08em; color: var(--ink-faint); }
.tk-strip-tape {
  position: absolute; top: 0; bottom: 0; right: 0; width: calc((1 - var(--reveal, 1)) * 100%);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  border-left: 1px dashed var(--wire); background-color: var(--cell);
  background-image: repeating-linear-gradient(135deg, var(--grid) 0 4px, transparent 4px 8px);
  animation: tk-tape 1.4s linear infinite; animation-play-state: paused;
}
.tk-card.is-awake .tk-strip-tape { animation-play-state: running; }
.tk-strip-tape .tk-tag { background: var(--cell); }
@keyframes tk-tape { to { background-position: 11.314px 0; } }
@media (prefers-reduced-motion: reduce) { .tk-strip-tape { animation: none; } }

/* The signature strip: each project's own form, in the hub's ink. At rest it is faint;
   awake it turns ink, or amber when the project wears its own design. */
.tk-strip {
  --strip-ink: var(--ink-faint);
  position: relative; display: flex; align-items: center; height: 56px; overflow: hidden;
  margin: calc(-1 * var(--q4)) calc(-1 * var(--q4)) 0; padding: 0 var(--q2);
  border-bottom: 1px solid var(--grid); color: var(--strip-ink);
  transition: color var(--t-blink) linear;
}
.tk-card.is-awake .tk-strip { --strip-ink: var(--ink); }
.tk-card--free.is-awake .tk-strip { --strip-ink: var(--free); }
.tk-strip-txt, .tk-strip-probe {
  margin: 0; font-family: var(--font-mono); font-size: 11px; line-height: 12px; font-weight: 500; font-stretch: 75%;
  letter-spacing: 0; font-variant-ligatures: none; font-kerning: none; white-space: pre; color: inherit;
}
.tk-strip .is-big { font-size: 22px; line-height: 24px; font-weight: 700; letter-spacing: -0.02em; }
.tk-strip-probe { position: absolute; visibility: hidden; }
.tk-strip canvas { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; image-rendering: crisp-edges; }

/* ------------------------------------------------------------ Switch -- */
.tk-switch {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; justify-content: center; gap: var(--q1);
  min-width: 44px; min-height: 44px; margin: 0; padding: 0 var(--q3);
  background: var(--cell); color: var(--ink);
  border: 1px solid var(--wire); border-radius: var(--square);
  font-family: var(--font-mono); font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%;
  letter-spacing: 0.04em; text-transform: lowercase; white-space: nowrap;
  cursor: pointer; -webkit-tap-highlight-color: transparent;
  transition: background-color var(--t-blink) linear, color var(--t-blink) linear, border-color var(--t-blink) linear;
}
.tk-switch--lang .tk-switch-key { text-transform: none; }
.tk-switch-val { color: var(--ink-dim); }
.tk-switch:hover, .tk-switch.is-hover { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.tk-switch:active, .tk-switch.is-active { background: var(--ink-dim); color: var(--on-ink); border-color: var(--ink-dim); }
.tk-switch:hover .tk-switch-val, .tk-switch.is-hover .tk-switch-val,
.tk-switch:active .tk-switch-val, .tk-switch.is-active .tk-switch-val { color: var(--on-ink); }
.tk-switch:focus-visible, .tk-switch.is-focus { outline: 2px solid var(--ink); outline-offset: 2px; }
.tk-switch:disabled, .tk-switch.is-disabled {
  background: var(--cell); color: var(--ink-faint); border-color: var(--wire); border-style: dashed; cursor: not-allowed;
}
.tk-switch:disabled .tk-switch-val { color: var(--ink-faint); }

/* --------------------------------------------------------------- Hub -- */
.tk-hub { max-width: 1040px; margin: 0 auto; padding: var(--q4) var(--q4) var(--q12); }
/* The bar is the hub's nav: the palette's switch, language and theme. It sits at the top of the page and
   scrolls away with it; the glass belongs to the palette. */
.tk-hub-bar {
  display: flex; justify-content: flex-end; align-items: center; gap: var(--q4);
  margin: calc(-1 * var(--q2)) 0; padding: var(--q2) 0;
}
.tk-hub-switches { display: flex; gap: var(--q2); }
/* The hero: the name is the hub. One word fills the column, set in white and blended by difference
   over the wheel turning behind it: the wheel's glyphs read as ink on the ground and as the inverse
   inside the letters (Tecken's inverse cell, the size of a word). Everything else on the hub is set
   small, so the name owns the place. */
.tk-hub-head { margin-top: var(--q4); }
.tk-hub-stage { position: relative; display: grid; place-items: center; min-width: 0; }
.tk-hub-emblem { grid-area: 1 / 1; min-width: 0; max-width: 100%; }   /* the wheel's home: sized to it; the wheel rides the follower */
.tk-hub-title {
  grid-area: 1 / 1; position: relative; z-index: 3; margin: 0; width: 100%; text-align: center; white-space: nowrap;
  font-size: var(--fit, 96px); line-height: .8; font-weight: 800; font-stretch: 75%; letter-spacing: -0.045em; text-transform: uppercase;
  color: #fff; mix-blend-mode: difference;   /* white under difference is the exact inverse, in natt and dag alike */
  pointer-events: none;
}
.tk-hub-word { display: inline-block; }
.tk-hub-under { display: grid; gap: var(--q4); margin-top: var(--q5); }
.tk-hub-lede { margin: var(--q2) 0 0; max-width: 56ch; font-size: 11.5px; line-height: 20px; font-stretch: 100%; color: var(--ink-dim); }

/* The follower: as you scroll, the wheel leaves the name and keeps you company down the page,
   gathering what you pass. A zero-height sticky layer at the top of the hub; the wheel in it is
   placed every frame between its home in the name and its dock (the left margin when there is one,
   else a small cell in the top-left corner). It sits under the name and over the cards. */
.tk-follow { position: sticky; top: 0; z-index: 2; height: 0; pointer-events: none; }
.tk-follow-wheel { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.tk-follow-wheel .tk-emblem { margin: 0; pointer-events: auto; }
.tk-follow-cell { position: absolute; left: 0; top: 0; opacity: 0; background: var(--void); border: 1px solid var(--wire); }
.tk-follow-top {
  position: absolute; left: 0; top: 0; margin: 0; padding: 0; border: 0; border-radius: var(--square);
  background: transparent; cursor: pointer; pointer-events: auto; -webkit-tap-highlight-color: transparent;
}
.tk-follow-top:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }


/* v16 · The name, painted. The canvas paints the slab, its walls, the engraved wheel and its ghost; the h1
   keeps the word for readers and find-in-page, transparent. The bar sits above the canvas, the dateline
   is the floor the name stands on: a rule drawn once, the hub's counts on the left, where it is on the right. */
.tk-hub-bar { position: relative; z-index: 4; }
.tk-hub-stage.is-drawn { display: block; }
.tk-hub-stage.is-drawn .tk-hub-emblem { display: none; }
.tk-hub-stage.is-drawn .tk-hub-title {
  position: absolute; inset: 0; display: grid; place-items: center; overflow: hidden;
  color: transparent; mix-blend-mode: normal;
}
.tk-name-rig { position: absolute; z-index: 3; pointer-events: none; will-change: transform; }
.tk-name-rig canvas { position: absolute; display: block; }
.tk-follow-wheel { opacity: 0; }
.tk-dateline {
  position: relative; z-index: 2; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 var(--q4);
  padding-top: var(--q2); font-size: 11px; line-height: 16px; font-weight: 500; color: var(--ink-faint); font-variant-numeric: tabular-nums;
}
.tk-dateline::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 1px; background: var(--wire);
  transform: scaleX(0); transform-origin: 0 50%; transition: transform 760ms var(--e-travel);
}
.tk-dateline > span { opacity: 0; transition: opacity 240ms linear 300ms; }
.tk-dateline .tk-dl-r { transition-delay: 520ms; }
.tk-dateline.is-in::before { transform: scaleX(1); }
.tk-dateline.is-in > span { opacity: 1; }
.tk-dl-l b { font-weight: 600; color: var(--ink-dim); }
.tk-hub-stage.is-drawn + .tk-dateline + .tk-hub-under { margin-top: var(--q8); }
/* v17 · the motto is the name's sub-header: centred on the dateline, between the counts and the place.
   It writes itself in when the rule has drawn; its ampersand is in ink, the hand without the amber. */
.tk-dateline { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; }
.tk-dateline .tk-dl-r { text-align: right; }
.tk-dateline .tk-motto { justify-self: center; white-space: nowrap; opacity: 0; transition: opacity 240ms linear 200ms; }
.tk-dateline.is-in .tk-motto { opacity: 1; }
.tk-dateline:not(.is-in) :is(.tk-motto-port, .tk-motto-hand) { animation-play-state: paused; }
.tk-dateline .tk-motto-hand { color: var(--ink); margin: 0 0.1em; }
@container site (max-width: 719px) {
  .tk-dateline { grid-template-columns: minmax(0, 1fr) auto; }
  .tk-dateline .tk-motto { grid-column: 1 / -1; grid-row: 1; margin-bottom: var(--q1); }
}
@container site (min-width: 720px) {
  .tk-dateline .tk-motto-port, .tk-dateline .tk-motto-canvas-t { font-size: 16px; }
  .tk-dateline .tk-motto-hand { font-size: 24px; }
}
@media (prefers-reduced-motion: reduce) { .tk-dateline .tk-motto { transition: none; } }
/* v20 · The name comes first: nothing sits above it. Everything that operates the page lives on the line
   under it, the masthead's folio: the hub's counts on the left, the motto in the middle, and the three
   switches on the right, joined into one segmented instrument that shares its hairlines. */
.tk-hub-head { margin-top: var(--q6); }
.tk-dateline { padding-top: var(--q3); row-gap: var(--q2); }
.tk-dateline .tk-hub-switches { justify-self: end; gap: 0; opacity: 0; transition: opacity 240ms linear 420ms; }
.tk-dateline.is-in .tk-hub-switches, .tk-dateline .tk-hub-switches:focus-within { opacity: 1; }
.tk-dateline .tk-switch + .tk-switch { margin-left: -1px; }
.tk-dateline .tk-switch:is(:hover, :focus-visible, [aria-expanded="true"]) { position: relative; z-index: 1; }
.tk-dl-i { white-space: nowrap; }
/* on a phone the folio stacks: the motto centred, the counts, then the switches as one full-width strip at the thumb */
@container site (max-width: 719px) {
  .tk-dateline { grid-template-columns: minmax(0, 1fr); }
  .tk-dateline .tk-dl-place { display: none; }
  .tk-dateline .tk-dl-l { grid-row: 2; text-align: center; }
  .tk-dateline .tk-hub-switches { grid-row: 3; justify-self: stretch; display: flex; margin-top: var(--q1); }
  .tk-dateline .tk-hub-switches .tk-switch { flex: 1 1 auto; }
}
@media (prefers-reduced-motion: reduce) { .tk-dateline .tk-hub-switches { transition: none; } }
@media (prefers-reduced-motion: reduce) {
  .tk-dateline::before, .tk-dateline > span { transition: none; }
}

/* The companion is not shipped on the hub (drops.json: .nc). Its three keyframes stay, unused: a drop
   names selectors, and a keyframes block has none, so the check still asks for them. */
@keyframes nc-land {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--free) 70%, transparent); transform: scale(.82); }
  45% { transform: scale(1.06); }
  100% { box-shadow: 0 0 0 14px transparent; transform: none; }
}
@keyframes nc-in { from { clip-path: inset(100% 0 0 0); transform: translateY(6px); } to { clip-path: inset(0 0 0 0); transform: none; } }
@keyframes nc-blink { 50% { opacity: 0; } }

/* Smaller words on the hub: the name is the one large thing. */
.tk-hub .tk-card-title { font-size: 17px; }
.tk-hub .tk-card-blurb { font-size: 11.5px; line-height: 18px; font-stretch: 100%; }
.tk-hub .tk-card-slug { font-size: 11px; }

/* Depth: an open project stands off the page. Awake, it lifts, tips toward the pointer, its strip
   floats a step above it, and its edge extrudes in hard one-pixel steps: gold for an own design,
   light yellow to dark amber, silver for the hub's own. The strip's glyphs rise off the card as a
   fading trail (the spill, drawn behind everything), and on natt the gold carries a faint neon. */
:root {
  --gold-1: #fff3c4; --gold-2: #ffdc7a; --gold-3: #ffb454; --gold-4: #e8892c; --gold-5: #b0601a;
  --silv-1: #f4f5f1; --silv-2: #cfd3cd; --silv-3: #a6aca8; --silv-4: #7c8380; --silv-5: #555b59;
  --neon: .55;
}
html[data-theme="dag"] {
  --gold-1: #6a3a00; --gold-2: #8f4e00; --gold-3: #a8670f; --gold-4: #c48a2c; --gold-5: #ddb35c;
  --silv-1: #0c0d0e; --silv-2: #3a3e40; --silv-3: #5c605d; --silv-4: #8a8e8a; --silv-5: #b5b8b2;
  --neon: 0;
}
.tk-hub-item { position: relative; }
/* The card's lift, tilt, extruded edge and press are Kortlek's (kortlek.css, kortlek.js; the edge ramps --e1..--e6 are
   set there, and by the skins below). Nothing here sets a card's transform or transition. */
/* hub-owned:begin a card at rest paints no box-shadow. At --k-z 0 every step of Kortlek's list is a zero-offset copy hidden behind the card and the glow is transparent, so nothing is lost, but the blurred glow gave each card a visual overflow that, together with its transform, made Chromium promote one overlap layer per card under the name canvases (38 cards, 34 layers; handoff 0004 wants about 6 whatever the card count). A wake, a press or a settle (.k-live) puts the list back. */
.tk-hub [data-fx]:not(.is-awake, .k-live) { box-shadow: none; }
/* hub-owned:end */
.tk-hub .tk-card--link.tk-card--free.is-awake { border-color: var(--gold-2); }
.tk-hub .tk-card--link .tk-strip { transition: color var(--t-blink) linear; }
/* awake, the strip's ink runs down the card's ramp, with a faint neon on natt */
.tk-hub .tk-card--link.is-awake .tk-strip-txt {
  background: linear-gradient(180deg, var(--silv-1), var(--silv-3));
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; color: transparent;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--silv-2) calc(var(--neon) * 60%), transparent));
}
.tk-hub .tk-card--link.tk-card--free.is-awake .tk-strip-txt {
  background: linear-gradient(180deg, var(--gold-1), var(--gold-3) 55%, var(--gold-5));
  -webkit-background-clip: text; background-clip: text;
  filter: drop-shadow(0 0 3px color-mix(in srgb, var(--gold-3) calc(var(--neon) * 80%), transparent));
}
.tk-hub .tk-card--link.tk-card--free.is-awake .tk-strip canvas { filter: drop-shadow(0 0 2px color-mix(in srgb, var(--gold-3) calc(var(--neon) * 80%), transparent)); }
.tk-spill {
  position: absolute; z-index: -1; left: -48px; top: -80px; width: calc(100% + 96px); height: 160px;
  pointer-events: none; opacity: 0; transition: opacity 480ms var(--e-travel);
  -webkit-mask-image: linear-gradient(to top, #000 50%, transparent); mask-image: linear-gradient(to top, #000 50%, transparent);
}
.tk-hub-item.is-awake .tk-spill { opacity: 1; }

/* ------------------------------------------------------------ card skins --
   A skinned card is Navet's ink at rest and its own design awake. Each skin: its palette (natt and dag),
   its edge, its glow (::after, so the extrusion stays), its choreography as classes set by SKINS.<id>.wake. */
.tk-hub .tk-card--link[data-skin] { position: relative; }
.tk-hub .tk-card--link[data-skin]::after {
  content: ""; position: absolute; inset: -1px; pointer-events: none; opacity: 0;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--sk-a) calc(var(--sk-glow) * 60%), transparent),
    0 0 22px -2px color-mix(in srgb, var(--sk-a) calc(var(--sk-glow) * 75%), transparent),
    0 0 64px -10px color-mix(in srgb, var(--sk-c) calc(var(--sk-glow) * 55%), transparent);
}
.tk-hub .tk-card--link[data-skin][data-skin].is-awake .tk-strip-txt {
  background: none; -webkit-text-fill-color: currentColor; color: var(--sk-paper); filter: none;
}
.tk-hub .tk-card--link[data-skin].is-awake .tk-card-title { text-shadow: 0 0 calc(var(--sk-glow) * 14px) color-mix(in srgb, var(--sk-a) calc(var(--sk-glow) * 45%), transparent); }
.tk-card[data-skin] .sk-g { text-shadow: 0 0 calc(var(--sk-glow) * 6px) currentColor; }
.tk-card[data-skin] .sk-path, .tk-card[data-skin] .sk-l { color: var(--sk-paper); }
.tk-card[data-skin] .sk-br { color: var(--sk-b); }
.tk-card[data-skin] .sk-ok { color: var(--sk-ok); }
.tk-card[data-skin] .sk-err { color: var(--sk-err); }
.tk-card[data-skin] .sk-gl { color: var(--sk-glass); }
.tk-card[data-skin] .sk-pct { color: var(--sk-d); text-shadow: 0 0 calc(var(--sk-glow) * 7px) var(--sk-d); }
.tk-card[data-skin] .sk-signal { color: var(--sk-a); text-shadow: 0 0 calc(var(--sk-glow) * 8px) var(--sk-a); }
.tk-card[data-skin] .sk-num { color: var(--sk-core); }
.tk-card[data-skin] .sk-cur { color: var(--sk-core); text-shadow: 0 0 calc(var(--sk-glow) * 8px) var(--sk-a); }

/* Neon Sumi: tubes on a sumi scroll. Its edge steps out in magenta, violet and teal; it catches with a
   flicker, then hums, brighter than any other card on the hub. */
[data-skin="neon"] {
  --sk-a: #ff2ec4; --sk-b: #c46eff; --sk-c: #00ffcc; --sk-d: #00eaff; --sk-core: #ffc2ee;
  --sk-paper: #e8dcc6; --sk-glass: #544a46; --sk-ok: #40ffaa; --sk-err: #ff3864; --sk-glow: 1;
  --sk-spill-1: #ffc2ee; --sk-spill-2: #ff2ec4; --sk-spill-3: #c46eff; --sk-spill-4: #00c8b0; --sk-spill-5: #3a1854;
}
html[data-theme="dag"] [data-skin="neon"] {
  --sk-a: #b3007e; --sk-b: #7a2fc0; --sk-c: #00745e; --sk-d: #00707f; --sk-core: #5a0040;
  --sk-paper: #1d1817; --sk-glass: #8a7d70; --sk-ok: #0f7046; --sk-err: #c0143f; --sk-glow: 0;
  --sk-spill-1: #5a0040; --sk-spill-2: #b3007e; --sk-spill-3: #7a2fc0; --sk-spill-4: #00745e; --sk-spill-5: #c9bba8;
}
.tk-hub .tk-card--link[data-skin="neon"].is-awake {
  border-color: var(--sk-a);
}
.tk-card[data-skin="neon"].sk-ignite::after { animation: sk-ignite 560ms steps(1, end) both; }
.tk-card[data-skin="neon"].sk-ignite .tk-strip-txt { animation: sk-ignite-ink 560ms steps(1, end) both; }
.tk-card[data-skin="neon"].sk-stutter::after { animation: sk-stutter 1300ms steps(1, end) both; }
.tk-card[data-skin="neon"].sk-stutter .tk-strip-txt { animation: sk-stutter-ink 1300ms steps(1, end) both; }
.tk-card[data-skin="neon"].sk-lit::after { opacity: .9; animation: sk-hum 2.8s ease-in-out infinite; }
@keyframes sk-ignite { 0% { opacity: 0; } 10% { opacity: 1; } 16% { opacity: .1; } 28% { opacity: .95; } 34% { opacity: .3; } 50%, 100% { opacity: .9; } }
@keyframes sk-ignite-ink { 0% { opacity: .35; } 10% { opacity: 1; } 16% { opacity: .4; } 28%, 100% { opacity: 1; } }
@keyframes sk-stutter { 0% { opacity: 0; } 6% { opacity: .9; } 9% { opacity: 0; } 22% { opacity: .7; } 25% { opacity: 0; } 40% { opacity: .2; } 46% { opacity: 1; } 49% { opacity: .1; } 86%, 100% { opacity: .9; } }
@keyframes sk-stutter-ink { 0% { opacity: .3; } 6% { opacity: 1; } 9% { opacity: .3; } 22% { opacity: .9; } 25% { opacity: .35; } 46%, 100% { opacity: 1; } }
@keyframes sk-hum { 0%, 100% { opacity: .78; } 45% { opacity: 1; } 50% { opacity: .84; } 55% { opacity: 1; } }

/* Maskinrummet, in Lysrör: ink holds still, light is live. Its edge steps down in ink with one lit
   line; it flares white-hot and settles; when you leave, its light decays instead of cutting. */
[data-skin="lysror"] {
  --sk-a: #ff2ec4; --sk-b: #c46eff; --sk-c: #00ffcc; --sk-d: #00eaff; --sk-core: #ffe6f6;
  --sk-paper: #e8dcc6; --sk-stone: #9a8d7f; --sk-glass: #3a3034; --sk-ok: #40ffaa; --sk-err: #ff3864; --sk-glow: 1;
  --sk-spill-1: #ffe6f6; --sk-spill-2: #ff2ec4; --sk-spill-3: #9a8d7f; --sk-spill-4: #3a3034; --sk-spill-5: #1c1617;
}
html[data-theme="dag"] [data-skin="lysror"] {
  --sk-a: #b3007e; --sk-b: #7a2fc0; --sk-c: #00745e; --sk-d: #00707f; --sk-core: #3a0a2c;
  --sk-paper: #1d1817; --sk-stone: #5a4f47; --sk-glass: #d3c8b8; --sk-ok: #0f7046; --sk-err: #c0143f; --sk-glow: 0;
  --sk-spill-1: #3a0a2c; --sk-spill-2: #b3007e; --sk-spill-3: #5a4f47; --sk-spill-4: #857868; --sk-spill-5: #d3c8b8;
}
.tk-hub .tk-card--link[data-skin="lysror"].is-awake {
  border-color: var(--sk-a);
}
.tk-card[data-skin="lysror"].sk-flare::after { animation: sk-flare 1200ms cubic-bezier(.05, .7, .1, 1) both; }
.tk-card[data-skin="lysror"].sk-flare .tk-strip-txt { animation: sk-flare-ink 1200ms cubic-bezier(.05, .7, .1, 1) both; }
.tk-card[data-skin="lysror"].sk-lit::after { opacity: .75; }
.tk-card[data-skin="lysror"].sk-after::after { animation: sk-decay 1200ms cubic-bezier(.05, .7, .1, 1) both; }
.tk-card[data-skin="lysror"].sk-after .tk-strip-txt { animation: sk-decay-ink 1200ms cubic-bezier(.05, .7, .1, 1) both; }
@keyframes sk-flare { 0% { opacity: 1; filter: brightness(2.2) saturate(.4); } 100% { opacity: .75; filter: none; } }
@keyframes sk-flare-ink { 0% { filter: brightness(2) saturate(.5); } 100% { filter: none; } }
@keyframes sk-decay { 0% { opacity: .75; } 100% { opacity: 0; } }
@keyframes sk-decay-ink { 0% { filter: none; opacity: 1; } 100% { filter: saturate(0) brightness(.7); opacity: .8; } }
/* hub-owned:begin the skins' edge ramps: Kortlek draws the stepped edge of an awake card from --e1..--e6 (steps 5 and 6 repeat step 4, seen only when a card wears and raises --k-edge past 4); a skin sets the colours, never box-shadow or transform */
.tk-card[data-skin="neon"] { --e1: var(--sk-a); --e2: color-mix(in srgb, var(--sk-a) 50%, var(--sk-b)); --e3: var(--sk-b); --e4: var(--sk-c); --e5: var(--e4); --e6: var(--e4); }
.tk-card[data-skin="lysror"] { --e1: var(--sk-a); --e2: var(--sk-stone); --e3: color-mix(in srgb, var(--sk-stone) 50%, var(--sk-glass)); --e4: var(--sk-glass); --e5: var(--e4); --e6: var(--e4); }
/* on dag Kortlek drops steps 5 and 6 (step 4 is already decoration there); an unlayered skin rule would bring them back */
html[data-theme="dag"] .tk-card[data-skin] { --e5: transparent; --e6: transparent; }
/* hub-owned:end */
/* hub-owned:begin Patrick's card (handoff 0005): the patrick recipe draws its stepped edge from --gin-1..--gin-5, his coat's colours (design/kortlek/tokens.json; the snapshot has none). His strip stays Navet's 56px, so he only lies down: no rare moments (--k-rare 0), and his 58px lying frame sinks into the last 3px of the strip, flush with its rule */
[data-recipe="patrick"] { --gin-1: #fbe1c6; --gin-2: #f0b98a; --gin-3: #d99560; --gin-4: #b3703f; --gin-5: #7a4526; }
html[data-theme="dag"] [data-recipe="patrick"] { --gin-1: #5a2a14; --gin-2: #7d3e1c; --gin-3: #9b5a2c; --gin-4: #b87a45; --gin-5: #c9985f; }
[data-patrick] { --k-strip-h: 56px; --k-rare: 0; }
[data-patrick] .k-pat-cat { bottom: -3px; }
/* hub-owned:end */
/* hub-owned:begin the quiet recipe tilts as the hub did before Kortlek: at most 4deg pitch and 4.5deg yaw (Kortlek's default is 8deg and 9deg) */
[data-recipe="quiet"] { --k-tilt: 4deg; }
/* hub-owned:end */
@media (prefers-reduced-motion: reduce) {
  .tk-card[data-skin]::after { animation: none !important; }
  .tk-card[data-skin] .tk-strip-txt { animation: none !important; }
  .tk-card[data-skin].sk-lit::after { opacity: .8; }
}
/* hub-owned:begin the Design System's hand-set motion toggle (data-k-motion="off") stills the skins' animations like prefers-reduced-motion does */
:root[data-k-motion="off"] .tk-card[data-skin]::after { animation: none !important; }
:root[data-k-motion="off"] .tk-card[data-skin] .tk-strip-txt { animation: none !important; }
:root[data-k-motion="off"] .tk-card[data-skin].sk-lit::after { opacity: .8; }
/* hub-owned:end */
@media (prefers-reduced-motion: reduce) {
  .tk-spill { display: none; }
}
.tk-hub-list {
  position: relative; list-style: none; margin: var(--q12) 0 0; padding: 0;
  display: grid; gap: var(--q5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}
.tk-hub-item { display: flex; min-width: 0; }
.tk-hub-item > .tk-card { flex: 1 1 auto; }
.tk-hub-foot {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 var(--q4);
  margin-top: var(--q12); padding-top: var(--q4); border-top: 1px solid var(--grid);
  font-size: 11px; line-height: 20px; font-weight: 500; color: var(--ink-faint);
}
.tk-hub-foot-t { min-width: 0; }
.tk-hub-foot .tk-sig { margin-left: auto; }

/* ----------------------------------------------------------- Palette --
   ⌘K, or the bar's sök switch: one panel that finds and switches. The hub stays where it is, behind
   glass: the scrim frosts it lightly, the panel is near-opaque glass over it, so the page's lines blur
   behind a ground you can read on. Its border is ink, as a woken card's is. data-glas on <html> picks
   the glass: lins (the default), frost, raster. On a phone the panel rises from the bottom, the prompt
   at your thumb; from 720px it hangs under the bar with the preview beside the list. */
.tk-kbd {
  display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 20px; padding: 0 var(--q1);
  border: 1px solid currentColor; font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; text-transform: none;
}
.tk-switch--pal .tk-kbd { display: none; }
.tk-switch--pal[aria-expanded="true"] { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.tk-pal-scrim {
  position: fixed; inset: 0; z-index: 60; margin: 0; padding: 0; border: 0; border-radius: var(--square); cursor: default;
  background: color-mix(in srgb, var(--void) 52%, transparent);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.tk-pal {
  position: fixed; z-index: 61; left: 0; right: 0; bottom: 0; height: min(612px, 78vh);
  display: flex; flex-direction: column; box-sizing: border-box;
  color: var(--ink); font-family: var(--font-mono); font-size: 13px; line-height: 20px; font-weight: 350; font-stretch: 112.5%;
  background: color-mix(in srgb, var(--void) 84%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(140%); backdrop-filter: blur(24px) saturate(140%);
  border: 1px solid var(--ink); border-width: 1px 0 0; border-radius: var(--square);
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.tk-pal *, .tk-pal *::before, .tk-pal *::after { box-sizing: border-box; }
.tk-pal :focus { outline: none; }
.tk-pal :focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* frost: thicker glass, the page behind one soft wash */
html[data-glas="frost"] .tk-pal {
  background: color-mix(in srgb, var(--void) 74%, transparent);
  -webkit-backdrop-filter: blur(40px) saturate(160%); backdrop-filter: blur(40px) saturate(160%);
}
html[data-glas="frost"] .tk-pal-scrim { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }
/* raster: the panel is a screen of 4px cells over a light blur */
html[data-glas="raster"] .tk-pal {
  background-color: color-mix(in srgb, var(--void) 80%, transparent);
  background-image: linear-gradient(var(--void) 1px, transparent 1px), linear-gradient(90deg, var(--void) 1px, transparent 1px);
  background-size: 4px 4px;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.tk-pal-sh {
  order: 1; flex: none; display: flex; align-items: center; gap: var(--q2); min-height: 44px; padding: 0 var(--q4);
  border-bottom: 1px solid var(--grid); color: var(--ink-faint);
  font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.04em; text-transform: lowercase;
}
.tk-pal-cnt { margin-left: auto; }
.tk-pal-msg { color: var(--ink); text-transform: none; letter-spacing: 0; }
.tk-pal-msg b { color: var(--ok); font-weight: 600; }
.tk-pal-main { order: 2; flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; }
.tk-pal-pi { order: 3; flex: none; position: relative; display: flex; align-items: stretch; height: 56px; border-top: 1px solid var(--grid); }
.tk-pal-ps { flex: none; display: flex; align-items: center; padding-left: var(--q4); color: var(--ink); font-size: 17px; line-height: 20px; font-weight: 600; font-stretch: 75%; }
.tk-pal-hand {
  font-family: "Bitcount Prop Single", var(--font-mono); color: var(--free);
  font-variation-settings: "wght" 600, "ELSH" 0, "CRSV" 1, "slnt" -8;
}
.tk-pal-ps .tk-pal-hand { margin-left: 2px; }
.tk-pal-field { position: relative; flex: 1 1 auto; min-width: 0; }
.tk-pal-mirror {
  position: absolute; inset: 0; display: flex; align-items: center; padding: 0 10px; overflow: hidden; white-space: pre; pointer-events: none;
  color: var(--ink); font-size: 17px; line-height: 20px; font-weight: 600; font-stretch: 75%;
}
.tk-pal-cur { flex: none; display: inline-block; width: 10px; height: 20px; border: 1px solid var(--ink); }
.tk-pal-field:focus-within .tk-pal-cur { background: var(--ink); animation: tk-pal-blink 1060ms steps(1, end) infinite; }
@keyframes tk-pal-blink { 0% { opacity: 1; } 50% { opacity: 0; } }
.tk-pal-ph { min-width: 0; margin-left: 10px; overflow: hidden; text-overflow: ellipsis; color: var(--ink-faint); }
.tk-pal-inp {
  -webkit-appearance: none; appearance: none; position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0 10px;
  border: 0; border-radius: var(--square); background: transparent; color: transparent; caret-color: transparent;
  font-family: var(--font-mono); font-size: 17px; line-height: 20px; font-weight: 600; font-stretch: 75%;
}
/* the field shows its focus as the filled, blinking block cursor; no box around it */
.tk-pal .tk-pal-inp:focus-visible { outline: none; }
.tk-pal-esc { flex: none; display: none; align-items: center; padding: 0 var(--q2) 0 var(--q3); color: var(--ink-faint); }
.tk-pal-x {
  -webkit-appearance: none; appearance: none; flex: none; width: 44px; margin: 0; padding: 0;
  border: 0; border-left: 1px solid var(--grid); border-radius: var(--square); background: transparent; color: var(--ink); cursor: pointer;
  font-family: var(--font-mono); font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%;
  transition: background-color var(--t-blink) linear, color var(--t-blink) linear;
}
.tk-pal-x:hover { background: var(--ink); color: var(--on-ink); }
.tk-pal-list { flex: 1 1 auto; min-width: 0; min-height: 0; overflow-x: hidden; overflow-y: auto; padding: var(--q1) 0 var(--q2); scrollbar-width: thin; scrollbar-color: var(--wire) transparent; }
.tk-pal-grp {
  padding: var(--q3) var(--q4) var(--q1); color: var(--ink-faint);
  font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.04em; text-transform: lowercase;
}
.tk-pal-row {
  -webkit-appearance: none; appearance: none; display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; align-items: center; column-gap: var(--q2);
  width: 100%; min-height: 44px; margin: 0; padding: 0 var(--q4); border: 0; border-radius: var(--square);
  background: transparent; color: var(--ink); text-align: left; text-decoration: none; cursor: pointer;
  font-family: var(--font-mono); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%;
}
.tk-pal-row.is-on { background: var(--ink); color: var(--on-ink); }
.tk-pal-gl { color: var(--ink-faint); white-space: nowrap; }
.tk-pal-gl.tk-pal-hand { font-size: 28px; line-height: 20px; color: var(--free); }
.tk-pal-row.is-on .tk-pal-gl { color: inherit; }
.tk-pal-lab { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tk-pal-meta { color: var(--ink-faint); white-space: nowrap; font-size: 11px; line-height: 16px; font-weight: 600; letter-spacing: 0.04em; }
.tk-pal-row.is-on .tk-pal-meta { color: inherit; }
.tk-pal-hit { color: var(--free); text-decoration: underline; text-underline-offset: 3px; }
.tk-pal-row.is-on .tk-pal-hit { color: inherit; }
.tk-pal-none { margin: 0; padding: var(--q4); color: var(--ink-faint); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; }
.tk-pal-pv {
  order: -1; flex: none; max-height: 168px; min-width: 0; overflow-y: auto; display: flex; flex-direction: column; gap: var(--q2);
  padding: var(--q3) var(--q4); border-bottom: 1px solid var(--grid);
}
.tk-pal-k { color: var(--ink-faint); font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.04em; text-transform: lowercase; }
.tk-pal-m { font-size: 44px; line-height: 32px; }
.tk-pal-q { margin: 0; color: var(--ink); font-size: 17px; line-height: 24px; font-weight: 500; font-stretch: 112.5%; }
.tk-pal-by, .tk-pal-u { color: var(--ink-faint); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; overflow-wrap: anywhere; }
.tk-pal-n { margin: 0; font-size: 20px; line-height: 20px; font-weight: 700; font-stretch: 75%; letter-spacing: -0.03em; overflow-wrap: anywhere; }
.tk-pal-b { margin: 0; color: var(--ink-dim); }
.tk-pal-sw { display: flex; flex-wrap: wrap; align-items: center; gap: var(--q2); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; }
.tk-pal-chip { display: inline-flex; align-items: center; min-height: 28px; padding: 2px var(--q2); border: 1px solid var(--wire); text-transform: lowercase; }
.tk-pal-chip.is-new { background: var(--ink); color: var(--on-ink); border-color: var(--ink); }
.tk-pal-s {
  margin: 0; padding: var(--q2); border: 1px solid var(--grid); background: var(--cell); color: var(--ink-dim); white-space: pre; overflow: hidden;
  font-family: var(--font-mono); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; font-variant-ligatures: none;
}
.tk-pal-h { margin-top: auto; color: var(--ink-faint); font-size: 11px; line-height: 16px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.04em; }
.tk-pal-links { display: flex; flex-wrap: wrap; gap: var(--q2); }
.tk-pal-links .tk-switch { text-decoration: none; }
.tk-pal-pf {
  display: none; flex: none; flex-wrap: wrap; align-items: center; gap: var(--q1) var(--q4); min-height: 44px; padding: 0 var(--q4);
  border-top: 1px solid var(--grid); color: var(--ink-faint); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%;
}
.tk-pal-pf .tk-pal-cnt { margin-left: auto; }
@media (prefers-reduced-motion: reduce) { .tk-pal-field:focus-within .tk-pal-cur { animation: none; } }
@media (min-width: 720px) {
  .tk-switch--pal .tk-kbd { display: inline-flex; }
  .tk-pal { top: 76px; bottom: auto; left: 50%; right: auto; width: min(780px, calc(100% - 32px)); height: auto; transform: translateX(-50%); border-width: 1px; padding-bottom: 0; }
  .tk-pal-sh { display: none; }
  .tk-pal-pi { order: 1; border-top: 0; border-bottom: 1px solid var(--grid); }
  .tk-pal-esc { display: flex; }
  .tk-pal-main { order: 2; flex: none; height: 420px; display: grid; grid-template-columns: minmax(0, 1fr) 300px; }
  .tk-pal-pv { order: 0; max-height: none; height: 100%; padding: var(--q4); gap: var(--q3); border-bottom: 0; border-left: 1px solid var(--grid); }
  .tk-pal-m { font-size: 56px; line-height: 40px; }
  .tk-pal-pf { display: flex; order: 3; }
}

/* ------------------------------------------------------------- Motto --
   The hub's title carries its motto. The first word owns the place: Silkscreen, a pixel face cut on
   a square grid, in tracked capitals, ruled underneath like a deed, one pixel thick. It types itself
   in, and now and then a hard-edged glint crosses it a pixel step at a time, the way light catches a
   steel nameplate. The middle word is the hand: Bitcount Prop Single on its cursive axis, in the free
   amber, a letter a step. The last is a canvas: three lights (amber, coral, blue) drift through it on
   paths of their own, light its letters where they pass and glow behind them. */
@property --orb-ax { syntax: "<percentage>"; inherits: true; initial-value: 12%; }
@property --orb-ay { syntax: "<percentage>"; inherits: true; initial-value: 30%; }
@property --orb-bx { syntax: "<percentage>"; inherits: true; initial-value: 55%; }
@property --orb-by { syntax: "<percentage>"; inherits: true; initial-value: 75%; }
@property --orb-cx { syntax: "<percentage>"; inherits: true; initial-value: 90%; }
@property --orb-cy { syntax: "<percentage>"; inherits: true; initial-value: 35%; }
.tk-motto {
  margin: 0; font-family: "Bitcount Prop Single", var(--font-mono); font-size: 14px; line-height: 24px;
  font-variation-settings: "wght" 400, "ELSH" 0, "CRSV" 0, "slnt" 0;
  color: var(--ink);
}
.tk-motto-port {
  position: relative; display: inline-block; font-family: "Silkscreen", var(--font-mono); font-variation-settings: normal;
  font-size: 12px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
  background-image: linear-gradient(110deg, transparent 0 45%, var(--free) 45% 49%, transparent 49% 51%, var(--free) 51% 52%, transparent 52%), linear-gradient(var(--ink), var(--ink));
  background-size: 300% 100%, 100% 100%; background-position: 100% 0, 0 0; background-repeat: no-repeat;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  animation: tk-sig-write var(--t-boot) steps(8, end) both, tk-glint 9s linear 2s infinite;
}
/* the deed's rule, one of the face's pixels thick (1/8 em), a pixel under the baseline */
.tk-motto-port::after {
  content: ""; position: absolute; left: 0; right: 0.02em; top: calc(50% + 0.5em); height: 0.125em;
  background: var(--ink);
}
/* parked off the left edge for most of the cycle, then across in twelve hard steps */
@keyframes tk-glint {
  0%, 82% { background-position: 100% 0, 0 0; animation-timing-function: steps(12, end); }
  94%, 100% { background-position: 0% 0, 0 0; }
}
.tk-motto-hand, .tk-sig-hand {
  display: inline-block; font-size: 32px; color: var(--free);
  font-variation-settings: "wght" 600, "ELSH" 0, "CRSV" 1, "slnt" -8;
  animation: tk-sig-write var(--t-boot) steps(6, end) var(--d-land) both;
}
.tk-motto-hand { font-size: 18px; animation-delay: calc(var(--t-boot) + var(--d-land)); }
@keyframes tk-sig-write { from { clip-path: inset(-25% 100% -25% -10%); } to { clip-path: inset(-25% -10% -25% -10%); } }
.tk-motto-canvas {
  --glare: 1; position: relative; display: inline-block; isolation: isolate;
  animation: tk-orb-a 8.3s ease-in-out infinite alternate, tk-orb-b 11.7s ease-in-out infinite alternate, tk-orb-c 14.1s ease-in-out infinite alternate;
}
.tk-motto-canvas-t {
  font-size: 13px; font-variation-settings: "wght" 600, "ELSH" 0, "CRSV" 0, "slnt" 0;
  background-repeat: no-repeat;
  background-image:
    radial-gradient(circle 1.1em at var(--orb-ax) var(--orb-ay), var(--free), transparent),
    radial-gradient(circle 1.2em at var(--orb-bx) var(--orb-by), var(--err), transparent),
    radial-gradient(circle 1.3em at var(--orb-cx) var(--orb-cy), var(--ok), transparent),
    linear-gradient(90deg, color-mix(in oklch, var(--ok) 70%, var(--ink)), color-mix(in oklch, var(--free) 70%, var(--ink)) 50%, color-mix(in oklch, var(--err) 70%, var(--ink)));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
/* the lights themselves, behind the word: the same three, unclipped and out of focus. Its box reaches
   past the word on every side; content-box origin keeps each light where it lights the letters. */
.tk-motto-glow {
  position: absolute; inset: -0.4em -0.5em; z-index: -1; padding: 0.4em 0.5em; pointer-events: none;
  background-image:
    radial-gradient(circle 1.1em at var(--orb-ax) var(--orb-ay), var(--free), transparent),
    radial-gradient(circle 1.2em at var(--orb-bx) var(--orb-by), var(--err), transparent),
    radial-gradient(circle 1.3em at var(--orb-cx) var(--orb-cy), var(--ok), transparent);
  background-repeat: no-repeat; background-origin: content-box; background-clip: border-box;
  filter: blur(12px) saturate(1.4); opacity: calc(var(--glare) * .8);
  animation: tk-breathe 5.3s ease-in-out infinite alternate;
}
html[data-theme="dag"] .tk-motto-canvas { --glare: .4; }
html[data-theme="dag"] .tk-motto-glow { mix-blend-mode: multiply; }
@keyframes tk-orb-a {
  0% { --orb-ax: 0%; --orb-ay: 20%; }
  35% { --orb-ax: 45%; --orb-ay: 95%; }
  70% { --orb-ax: 85%; --orb-ay: 10%; }
  100% { --orb-ax: 35%; --orb-ay: 55%; }
}
@keyframes tk-orb-b {
  0% { --orb-bx: 60%; --orb-by: 90%; }
  40% { --orb-bx: 100%; --orb-by: 25%; }
  75% { --orb-bx: 20%; --orb-by: 5%; }
  100% { --orb-bx: 5%; --orb-by: 85%; }
}
@keyframes tk-orb-c {
  0% { --orb-cx: 95%; --orb-cy: 40%; }
  30% { --orb-cx: 55%; --orb-cy: 0%; }
  65% { --orb-cx: 10%; --orb-cy: 70%; }
  100% { --orb-cx: 70%; --orb-cy: 100%; }
}
@keyframes tk-breathe { from { opacity: calc(var(--glare) * .5); } to { opacity: calc(var(--glare) * .85); } }

/* --------------------------------------------------------- Signature --
   The name signs the foot of the page, bottom right, the way a painter signs a canvas: two words in
   the pixel face, the name between them in the motto's hand. It writes itself in when you get there. */
.tk-sig {
  margin: 0; font-family: "Bitcount Prop Single", var(--font-mono); font-size: 20px; line-height: 44px;
  font-variation-settings: "wght" 400, "ELSH" 0, "CRSV" 0, "slnt" 0;
  color: var(--ink-dim); white-space: nowrap;
}
.tk-sig-hand { font-size: 28px; animation-play-state: paused; }
.tk-sig.is-signed .tk-sig-hand { animation-play-state: running; }
@media (prefers-reduced-motion: reduce) {
  .tk-motto-port, .tk-motto-hand, .tk-sig-hand, .tk-motto-canvas, .tk-motto-glow { animation: none; }
}

/* ------------------------------------------------------------- Quote --
   One quote under the lede, the mark in the signature's hand. */
.tk-quote { margin: 0; max-width: 56ch; }
.tk-quote-q { margin: 0; display: grid; grid-template-columns: var(--q6) minmax(0, 1fr); align-items: start; }
.tk-quote-mark {
  font-family: "Bitcount Prop Single", var(--font-mono); font-size: 30px; line-height: 28px; color: var(--free);
  font-variation-settings: "wght" 600, "ELSH" 0, "CRSV" 1, "slnt" -8;
}
.tk-quote-text { margin: 0; font-size: 12px; line-height: 20px; font-stretch: 100%; color: var(--ink); }
.tk-quote-by {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--q3); margin-left: var(--q6);
  font-size: 11px; line-height: 20px; font-weight: 500; color: var(--ink-faint);
}
.tk-quote-who { color: var(--ink-dim); }
.tk-quote-next {
  -webkit-appearance: none; appearance: none;
  display: inline-flex; align-items: center; min-height: 44px; margin: 0 0 0 auto; padding: 0 var(--q3);
  background: transparent; color: var(--ink); border: 0; border-radius: var(--square); cursor: pointer;
  font-family: var(--font-mono); font-size: 12px; line-height: 20px; font-weight: 600; font-stretch: 75%;
  transition: background-color var(--t-blink) linear, color var(--t-blink) linear;
}
.tk-quote-next:hover { background: var(--ink); color: var(--on-ink); }
.tk-quote-next:active { background: var(--ink-dim); color: var(--on-ink); }
.tk-quote-next:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
@container site (min-width: 720px) {
  .tk-hub { padding: var(--q8) var(--q8) var(--q12); }
  .tk-motto-port, .tk-motto-canvas-t { font-size: 13px; }
  .tk-motto-hand { font-size: 20px; }
  .tk-hub-under { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; gap: var(--q8); }
}

/* ================================================================
   Navet Live — the site frame, the project page (Tecken extended)
   and the own-design page (Utgrävningen).
   ================================================================ */

/* Two more steps of the 4px quantum for page-level air on every page, own-design ones included. */
#site { --q16: 64px; --q24: 96px; container: site / inline-size; isolation: isolate; overflow-x: clip; min-height: 100vh; background: var(--void); }
#view { min-width: 0; }

/* ------------------------------------------------ project page -- */
.pg { max-width: 1040px; margin: 0 auto; padding: var(--q4) var(--q4) var(--q12); }
.pg *, .pg *::before, .pg *::after, .ug *, .ug *::before, .ug *::after { box-sizing: border-box; }

.pg-bar { position: relative; display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--q2); }
.pg-where { display: flex; align-items: center; gap: var(--q2); min-width: 0; }
.pg-back {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--q3); margin-left: calc(-1 * var(--q3));
  color: var(--ink); text-decoration: none; white-space: nowrap;
  font-family: var(--font-mono); font-size: 12px; line-height: 20px; font-weight: 600; font-stretch: 75%;
  transition: background-color var(--t-blink) linear, color var(--t-blink) linear;
}
.pg-back:hover { background: var(--ink); color: var(--on-ink); }
.pg-back:active { background: var(--ink-dim); color: var(--on-ink); }
.pg-back:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.pg-crumb { font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.pg-head { display: grid; gap: var(--q6); margin-top: var(--q6); }
.pg-id { display: flex; flex-wrap: wrap; align-items: center; gap: var(--q2); }
.pg-slug { font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint); }
.pg-title {
  width: fit-content; max-width: 100%;
  margin: var(--q3) 0 0; font-size: 44px; line-height: 44px; font-weight: 700; font-stretch: 75%;
  letter-spacing: -0.03em; color: var(--ink); overflow-wrap: anywhere;
}
.pg-lede { margin: var(--q5) 0 0; max-width: 64ch; color: var(--ink-dim); }

.pg-meta {
  position: relative; margin: 0; align-self: end;
  display: grid; grid-template-columns: max-content minmax(0, 1fr); column-gap: var(--q4);
  padding: var(--q3) var(--q4); background: var(--cell); border: 1px solid var(--wire);
}
.pg-meta dt {
  font-size: 11px; line-height: 20px; font-weight: 600; font-stretch: 75%; letter-spacing: 0.04em;
  text-transform: lowercase; color: var(--ink-faint);
}
.pg-meta dd { margin: 0; font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink); overflow-wrap: anywhere; }

.pg-sec { margin-top: var(--q12); padding-top: var(--q4); border-top: 1px solid var(--grid); display: grid; gap: var(--q4); position: relative; }
.pg-h2 { margin: 0; font-size: 17px; line-height: 20px; font-weight: 600; font-stretch: 75%; color: var(--ink); text-transform: lowercase; }
.pg-h2 .n { color: var(--ink-faint); font-weight: 500; }
.pg-body { min-width: 0; display: grid; gap: var(--q5); }

.pg-foot {
  position: relative; margin-top: var(--q12); padding-top: var(--q2); border-top: 1px solid var(--grid);
  display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--q2);
  font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint);
}
.pg-foot .pg-back:last-child { margin-left: 0; margin-right: calc(-1 * var(--q3)); }

@container site (min-width: 720px) {
  .pg { padding: var(--q8) var(--q8) var(--q12); }
  .pg-head { grid-template-columns: minmax(0, 1fr) 300px; gap: var(--q8); margin-top: var(--q8); }
  .pg-sec { grid-template-columns: 184px minmax(0, 1fr); gap: var(--q8); }
  .pg-h2 { position: sticky; top: var(--q4); align-self: start; }
}

/* figures */
.fig { position: relative; margin: var(--q12) 0 0; min-width: 0; }
.pg-body .fig { margin-top: 0; }
.fig-box { background: var(--cell); border: 1px solid var(--wire); padding: var(--q4); min-width: 0; }
.fig-cap {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 var(--q4); margin-top: var(--q1);
  font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint);
}
.fig-cap b { color: var(--ink); font-weight: 600; }

/* the hit raster: data as characters, one text row per channel */
.rs { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--q5) var(--q8); }
.rs-gridwrap { flex: 0 0 auto; max-width: 100%; }
.rs-grid { position: relative; overflow: hidden; }
.rs-rows, .rs-headtxt, .rs-probe {
  margin: 0; font-family: var(--font-mono); font-size: 11px; line-height: 20px; font-weight: 500; font-stretch: 75%;
  letter-spacing: 0; font-variant-ligatures: none; font-kerning: none; white-space: pre; color: var(--ink-faint);
}
.rs-probe { position: absolute; visibility: hidden; }
.rs-lab { color: var(--ink-faint); }
.rs-sep { color: var(--wire); }
.rs-d { color: var(--ink-faint); }
.rs-m { color: var(--ink-dim); }
.rs-b { color: var(--ink); }
.rs-head { position: absolute; left: 0; top: 0; background: var(--ink); will-change: transform; }
.rs-headtxt { color: var(--on-ink); text-align: center; }
.rs-side { flex: 1 1 200px; min-width: 0; display: grid; gap: var(--q2); align-content: start; }
.rs-line { margin: 0; font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.rs-line b { color: var(--ink); font-weight: 600; }
.rs-ramp { letter-spacing: 0.08em; }
.rs-emit { min-height: 40px; color: var(--ink-dim); overflow-wrap: anywhere; }
.rs-emit b { color: var(--ink); }
.rs-play { justify-self: start; margin-top: var(--q1); }

/* the pipeline as a chain of cells */
.flow { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--q5); max-width: 640px; position: relative; }
.flow-n {
  position: relative; display: grid; grid-template-columns: 104px minmax(0, 1fr); gap: 0 var(--q3); align-items: center;
  padding: var(--q2) var(--q3); border: 1px dashed var(--wire); background: transparent;
}
.flow-n.is-ok { border-style: solid; }
.flow-n.is-now { border: 1px solid var(--ink); background: var(--cell); }
.flow-n + .flow-n::before {
  content: "|"; position: absolute; left: calc(var(--q3) + 12px); top: -21px; line-height: 20px;
  font-size: 12px; font-weight: 600; font-stretch: 75%; color: var(--ink-faint);
}
.flow-tag { grid-row: 1 / span 2; justify-self: start; }
.flow-name { font-size: 12px; line-height: 20px; font-weight: 600; font-stretch: 75%; color: var(--ink); }
.flow-out { font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint); }
.flow-n.is-now .flow-out { color: var(--ink-dim); }
@container site (min-width: 720px) {
  .flow-n { grid-template-columns: 104px 120px minmax(0, 1fr); }
  .flow-tag { grid-row: auto; }
}

/* table */
.tbl-wrap { position: relative; overflow-x: auto; background: var(--cell); border: 1px solid var(--wire); max-width: 640px; }
.tbl {
  border-collapse: collapse; width: 100%; min-width: 440px;
  font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; font-variant-numeric: tabular-nums; color: var(--ink-dim);
}
.tbl th {
  text-align: left; padding: 10px var(--q3) 9px; border-bottom: 1px solid var(--wire); white-space: nowrap;
  font-size: 11px; font-weight: 600; letter-spacing: 0.04em; text-transform: lowercase; color: var(--ink-faint);
}
.tbl td { padding: 10px var(--q3) 9px; white-space: nowrap; }
.tbl tr + tr td { border-top: 1px solid var(--grid); }
.tbl td:first-child { color: var(--ink); font-weight: 600; }
.tbl .num { text-align: right; }
.tbl th.num { text-align: right; }
.tbl .bar { color: var(--ink-dim); letter-spacing: 0; padding-left: 0; }

/* code */
.code {
  position: relative; margin: 0; overflow-x: auto; max-width: 640px;
  background: var(--cell); border: 1px solid var(--wire); padding: var(--q3) var(--q4);
  font-family: var(--font-mono); font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-dim);
}
.code .p { color: var(--ink); font-weight: 600; }
.code .f { color: var(--ink-faint); }

/* the dithered plate: one 1-bit mask, painted with the theme's ink */
.plate-box { padding: 0; line-height: 0; background: var(--void); }
canvas.plate, canvas.ug-plate { display: block; width: 100%; height: auto; image-rendering: pixelated; image-rendering: crisp-edges; }

/* log */
.log { list-style: none; margin: 0; padding: 0; max-width: 640px; }
.log li {
  display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 0 var(--q3); align-items: center;
  padding: 10px 0 9px; border-top: 1px solid var(--grid);
}
.log li:first-child { border-top: 0; padding-top: 0; }
.log time { font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.log .tk-tag { justify-self: start; }
.log p { grid-column: 1 / -1; margin: var(--q1) 0 0; font-size: 12px; line-height: 20px; font-weight: 500; font-stretch: 75%; color: var(--ink-dim); }
@container site (min-width: 720px) {
  .log li { grid-template-columns: 88px 120px minmax(0, 1fr); }
  .log p { grid-column: auto; margin: 0; }
}
