@danieldeusing/design 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/danieldeusing-design.css +83 -67
- package/dist/danieldeusing-design.min.css +2 -47
- package/package.json +1 -1
- package/src/chrome.css +82 -4
- package/src/components.css +0 -62
- package/templates/documentation.html +5 -5
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! danieldeusing-design v0.
|
|
1
|
+
/*! danieldeusing-design v0.17.0 | MIT | https://github.com/danieldeusing/danieldeusing-design */
|
|
2
2
|
/* ===== reset.css ===== */
|
|
3
3
|
/*
|
|
4
4
|
* danieldeusing-design — minimal reset.
|
|
@@ -994,68 +994,6 @@ details.fold > summary:focus-visible {
|
|
|
994
994
|
.legend > li { line-height: 1.6; }
|
|
995
995
|
.legend > li > :first-child { margin-right: 0.45rem; }
|
|
996
996
|
|
|
997
|
-
/* ── ticker strip: one standard header for every poller ────────────────────────────────────────
|
|
998
|
-
Daniel: "For all pollers / tickers we should make a standard layout ... on top of the pages,
|
|
999
|
-
compact and like dashboard style."
|
|
1000
|
-
|
|
1001
|
-
Every poller answers the same four questions — what ran, when, when next, what did it count —
|
|
1002
|
-
and each page was answering them in its own prose box, so "is anything stalled?" took four
|
|
1003
|
-
paragraphs instead of one glance.
|
|
1004
|
-
|
|
1005
|
-
A real TABLE, not a grid per row. The first version made each row its own `display: grid`,
|
|
1006
|
-
which cannot align anything across rows: every row sized its columns to its own content, so
|
|
1007
|
-
`next` sat wherever that row's name happened to end and the layout moved when a label changed.
|
|
1008
|
-
One table means one set of column widths for the whole strip, and scanning a column is the only
|
|
1009
|
-
thing the strip is for. Borderless by design — rules between cells draw a grid nobody reads.
|
|
1010
|
-
|
|
1011
|
-
Colour comes only from --primary and --destructive, both per-theme. Hardcoded accents miss AA
|
|
1012
|
-
on at least one theme (measured 2026-08-04), so a strip inventing its own greens and ambers
|
|
1013
|
-
would have added five more. */
|
|
1014
|
-
/* Breathing room above: the strip follows the page's lede, and butted straight up against a
|
|
1015
|
-
paragraph it read as part of the prose rather than as instrumentation. */
|
|
1016
|
-
.tickstrip:not(:empty) { border: 1px solid var(--border); background: var(--card); margin: 1.6rem 0 1.5rem; }
|
|
1017
|
-
.ticktable { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
|
|
1018
|
-
.ticktable td { padding: 0.5rem 0.75rem; vertical-align: baseline; border: 0; white-space: nowrap; }
|
|
1019
|
-
/* Only the last column may grow, so the four fixed columns keep the same width on every row. */
|
|
1020
|
-
.ticktable td.tick-stats { width: 100%; white-space: normal; }
|
|
1021
|
-
.tick { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
|
|
1022
|
-
.tick:last-child { border-bottom: 0; }
|
|
1023
|
-
/* State reads THREE ways, so it survives every context: the GLYPH (two themes are near-black and
|
|
1024
|
-
a printout has no colour at all), the COLOUR, and a left edge-marker that makes a bad row
|
|
1025
|
-
findable by shape alone when the strip is scanned rather than read. */
|
|
1026
|
-
.tick-dot {
|
|
1027
|
-
font-size: 0.7em; width: 1.5rem; padding-right: 0 !important;
|
|
1028
|
-
border-left: 3px solid transparent; padding-left: 0.6rem !important;
|
|
1029
|
-
}
|
|
1030
|
-
/* --success is per-theme and AA-measured (0.3.0). `ok` used to borrow --primary — the BRAND
|
|
1031
|
-
colour — so a healthy poller and the page heading were the same ink, and "everything is fine"
|
|
1032
|
-
had to be read rather than seen. */
|
|
1033
|
-
.tick--ok .tick-dot { color: var(--success); border-left-color: color-mix(in srgb, var(--success) 45%, transparent); }
|
|
1034
|
-
.tick--stale .tick-dot { color: var(--destructive); border-left-color: var(--destructive); }
|
|
1035
|
-
.tick--never .tick-dot { color: var(--muted-foreground); border-left-color: color-mix(in srgb, var(--muted-foreground) 35%, transparent); }
|
|
1036
|
-
/* The NAME is an identifier, not an accent. Making it --primary put brand colour on every row of
|
|
1037
|
-
a strip whose entire job is that the exceptions stand out. */
|
|
1038
|
-
.tick-name { font-weight: 700; color: var(--foreground); letter-spacing: 0.01em; }
|
|
1039
|
-
.tick-last, .tick-next { font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
|
|
1040
|
-
/* "next 57s" is a prediction; the age beside it is an observation. It should not compete. */
|
|
1041
|
-
.tick-next { opacity: 0.72; }
|
|
1042
|
-
.tick--stale .tick-last { color: var(--destructive); font-weight: 700; }
|
|
1043
|
-
.tick--never .tick-last { font-style: italic; }
|
|
1044
|
-
/* The NUMBER is what gets scanned; its label is context. Weight and colour on the value alone
|
|
1045
|
-
means a row reads as its numbers first and its wording second. */
|
|
1046
|
-
.tick-stats { color: var(--muted-foreground); }
|
|
1047
|
-
.tick-stats b { font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
|
|
1048
|
-
.tick-sep { font-style: normal; opacity: 0.35; margin: 0 0.5rem; }
|
|
1049
|
-
/* A stale row earns the only background tint in the strip — an all-tinted strip is one the eye
|
|
1050
|
-
stops reading. */
|
|
1051
|
-
.tick--stale { background: color-mix(in srgb, var(--destructive) 8%, transparent); }
|
|
1052
|
-
@media (max-width: 40rem) {
|
|
1053
|
-
.ticktable, .ticktable tbody, .tick, .ticktable td { display: block; }
|
|
1054
|
-
.tick { padding: 0.4rem 0.5rem; }
|
|
1055
|
-
.ticktable td { display: inline-block; padding: 0.1rem 0.5rem 0.1rem 0; }
|
|
1056
|
-
.ticktable td.tick-stats { display: block; width: auto; }
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
997
|
/* ── zoomable diagrams ────────────────────────────────────────────────────────────────────────
|
|
1060
998
|
An architecture diagram authored for a text column is unreadable at exactly the moment someone
|
|
1061
999
|
needs it. Pair with `initDiagramZoom()`: every `.diagram` becomes a real button that opens
|
|
@@ -1171,9 +1109,9 @@ html.dgm-locked, html.dgm-locked body { overflow: hidden; }
|
|
|
1171
1109
|
/* ===== chrome.css ===== */
|
|
1172
1110
|
/*
|
|
1173
1111
|
* chrome.css — the app chrome kit: sticky header bar, fixed status footer,
|
|
1174
|
-
* and the responsive site navigation (desktop `ls -l` RAIL,
|
|
1175
|
-
* the footer folded in). Extracted from danieldeusing.de and
|
|
1176
|
-
* so every app ships the same chrome without rebuilding it.
|
|
1112
|
+
* the ticker strip, and the responsive site navigation (desktop `ls -l` RAIL,
|
|
1113
|
+
* mobile burger with the footer folded in). Extracted from danieldeusing.de and
|
|
1114
|
+
* the cockpit portal so every app ships the same chrome without rebuilding it.
|
|
1177
1115
|
*
|
|
1178
1116
|
* Markup contract (see templates/documentation.html for the full example):
|
|
1179
1117
|
*
|
|
@@ -1284,6 +1222,83 @@ html.dgm-locked, html.dgm-locked body { overflow: hidden; }
|
|
|
1284
1222
|
background: var(--background, #f5efe2);
|
|
1285
1223
|
}
|
|
1286
1224
|
|
|
1225
|
+
/* ── ticker strip: one standard header for every poller ────────────────────────────────────────
|
|
1226
|
+
Daniel: "For all pollers / tickers we should make a standard layout ... on top of the pages,
|
|
1227
|
+
compact and like dashboard style."
|
|
1228
|
+
|
|
1229
|
+
Every poller answers the same four questions — what ran, when, when next, what did it count —
|
|
1230
|
+
and each page was answering them in its own prose box, so "is anything stalled?" took four
|
|
1231
|
+
paragraphs instead of one glance.
|
|
1232
|
+
|
|
1233
|
+
A real TABLE, not a grid per row. The first version made each row its own `display: grid`,
|
|
1234
|
+
which cannot align anything across rows: every row sized its columns to its own content, so
|
|
1235
|
+
`next` sat wherever that row's name happened to end and the layout moved when a label changed.
|
|
1236
|
+
One table means one set of column widths for the whole strip, and scanning a column is the only
|
|
1237
|
+
thing the strip is for. Borderless by design — rules between cells draw a grid nobody reads.
|
|
1238
|
+
|
|
1239
|
+
Colour comes only from --primary and --destructive, both per-theme. Hardcoded accents miss AA
|
|
1240
|
+
on at least one theme (measured 2026-08-04), so a strip inventing its own greens and ambers
|
|
1241
|
+
would have added five more.
|
|
1242
|
+
|
|
1243
|
+
IT LIVES IN CHROME, NOT COMPONENTS (0.17.0), and the move is what makes it reachable. The strip
|
|
1244
|
+
is page-level status furniture — it sits above the content and reports whether the page's own
|
|
1245
|
+
machinery is running — which is the same job as the header bar and the status footer, not the
|
|
1246
|
+
job of a card or a button. The practical half: components.css is not separable in practice.
|
|
1247
|
+
Taking it brings base.css's scanline overlay, its table type and its control styling, so a
|
|
1248
|
+
surface with its own layout cannot load it for one component. netmon is the case — it is read
|
|
1249
|
+
DURING an outage, so it ships tokens.css + chrome.css as a same-origin snapshot and nothing
|
|
1250
|
+
else, and for two releases the estate's standard status strip was the one piece of shared
|
|
1251
|
+
vocabulary it could not have. It had a bare timestamp in its header bar instead.
|
|
1252
|
+
|
|
1253
|
+
A tokens+chrome consumer therefore gets: the column, table scroll, the a11y helpers, the header
|
|
1254
|
+
bar, the footer, the `ls -l` rail, the burger — AND the strip. Bundle consumers are unaffected;
|
|
1255
|
+
dist/ concatenates both layers, and the rules reference only tokens, so source order cannot
|
|
1256
|
+
change what they resolve to. */
|
|
1257
|
+
/* Breathing room above: the strip follows the page's lede, and butted straight up against a
|
|
1258
|
+
paragraph it read as part of the prose rather than as instrumentation. */
|
|
1259
|
+
.tickstrip:not(:empty) { border: 1px solid var(--border); background: var(--card); margin: 1.6rem 0 1.5rem; }
|
|
1260
|
+
.ticktable { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
|
|
1261
|
+
.ticktable td { padding: 0.5rem 0.75rem; vertical-align: baseline; border: 0; white-space: nowrap; }
|
|
1262
|
+
/* Only the last column may grow, so the four fixed columns keep the same width on every row. */
|
|
1263
|
+
.ticktable td.tick-stats { width: 100%; white-space: normal; }
|
|
1264
|
+
.tick { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
|
|
1265
|
+
.tick:last-child { border-bottom: 0; }
|
|
1266
|
+
/* State reads THREE ways, so it survives every context: the GLYPH (two themes are near-black and
|
|
1267
|
+
a printout has no colour at all), the COLOUR, and a left edge-marker that makes a bad row
|
|
1268
|
+
findable by shape alone when the strip is scanned rather than read. */
|
|
1269
|
+
.tick-dot {
|
|
1270
|
+
font-size: 0.7em; width: 1.5rem; padding-right: 0 !important;
|
|
1271
|
+
border-left: 3px solid transparent; padding-left: 0.6rem !important;
|
|
1272
|
+
}
|
|
1273
|
+
/* --success is per-theme and AA-measured (0.3.0). `ok` used to borrow --primary — the BRAND
|
|
1274
|
+
colour — so a healthy poller and the page heading were the same ink, and "everything is fine"
|
|
1275
|
+
had to be read rather than seen. */
|
|
1276
|
+
.tick--ok .tick-dot { color: var(--success); border-left-color: color-mix(in srgb, var(--success) 45%, transparent); }
|
|
1277
|
+
.tick--stale .tick-dot { color: var(--destructive); border-left-color: var(--destructive); }
|
|
1278
|
+
.tick--never .tick-dot { color: var(--muted-foreground); border-left-color: color-mix(in srgb, var(--muted-foreground) 35%, transparent); }
|
|
1279
|
+
/* The NAME is an identifier, not an accent. Making it --primary put brand colour on every row of
|
|
1280
|
+
a strip whose entire job is that the exceptions stand out. */
|
|
1281
|
+
.tick-name { font-weight: 700; color: var(--foreground); letter-spacing: 0.01em; }
|
|
1282
|
+
.tick-last, .tick-next { font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
|
|
1283
|
+
/* "next 57s" is a prediction; the age beside it is an observation. It should not compete. */
|
|
1284
|
+
.tick-next { opacity: 0.72; }
|
|
1285
|
+
.tick--stale .tick-last { color: var(--destructive); font-weight: 700; }
|
|
1286
|
+
.tick--never .tick-last { font-style: italic; }
|
|
1287
|
+
/* The NUMBER is what gets scanned; its label is context. Weight and colour on the value alone
|
|
1288
|
+
means a row reads as its numbers first and its wording second. */
|
|
1289
|
+
.tick-stats { color: var(--muted-foreground); }
|
|
1290
|
+
.tick-stats b { font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
|
|
1291
|
+
.tick-sep { font-style: normal; opacity: 0.35; margin: 0 0.5rem; }
|
|
1292
|
+
/* A stale row earns the only background tint in the strip — an all-tinted strip is one the eye
|
|
1293
|
+
stops reading. */
|
|
1294
|
+
.tick--stale { background: color-mix(in srgb, var(--destructive) 8%, transparent); }
|
|
1295
|
+
@media (max-width: 40rem) {
|
|
1296
|
+
.ticktable, .ticktable tbody, .tick, .ticktable td { display: block; }
|
|
1297
|
+
.tick { padding: 0.4rem 0.5rem; }
|
|
1298
|
+
.ticktable td { display: inline-block; padding: 0.1rem 0.5rem 0.1rem 0; }
|
|
1299
|
+
.ticktable td.tick-stats { display: block; width: auto; }
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1287
1302
|
/* ── a11y helpers ── */
|
|
1288
1303
|
.skip-link {
|
|
1289
1304
|
position: absolute; left: -999px; top: 0; z-index: 100;
|
|
@@ -1324,7 +1339,8 @@ footer.status .dropdown summary, footer.status .anim-toggle { padding: 0.55rem 0
|
|
|
1324
1339
|
`.doc-link` is deliberately quiet because it is footer furniture, and a row action inherited
|
|
1325
1340
|
that quietness: a column of grey `open →` reads as disabled text rather than as the way in.
|
|
1326
1341
|
It carries the accent from rest, not only on hover, because a row action is the reason the
|
|
1327
|
-
row is interactive at all and hover cannot advertise itself.
|
|
1342
|
+
row is interactive at all and hover cannot advertise itself.
|
|
1343
|
+
|
|
1328
1344
|
THE ARROW IS PART OF THE LABEL, so this never wraps. Every `→` in the estate is an author-typed
|
|
1329
1345
|
U+2192 after an ordinary space — 86 of them in cockpit alone, not one using a no-break space —
|
|
1330
1346
|
so every forward link was one narrow column away from putting its arrow alone on the next line.
|
|
@@ -1,47 +1,2 @@
|
|
|
1
|
-
/*! danieldeusing-design v0.
|
|
2
|
-
*,*::before,*::after{box-sizing: border-box}*{margin: 0}html{-webkit-text-size-adjust: 100%;text-size-adjust: 100%;tab-size: 4}body{min-height: 100vh;min-height: 100dvh;line-height: 1.5}img,picture,video,canvas,svg{display: block;max-width: 100%}input,button,textarea,select{font: inherit;color: inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap: break-word}ul,ol{list-style: none;padding: 0}a{color: inherit;text-decoration: none}table{border-collapse: collapse}:root{--background: #f5efe2;--foreground: #43352a;--card: #efe7d4;--card-foreground: #43352a;--popover: #efe7d4;--popover-foreground: #43352a;--primary: #8a4516;--primary-foreground: #f8f3e8;--secondary: #ece3cf;--secondary-foreground: #43352a;--muted: #ece3cf;--muted-foreground: #71614e;--accent: #8a4516;--accent-foreground: #f8f3e8;--destructive: #a02c2c;--success: #1a6b2e;--warning: #845600;--info: #1c5f9e;--pending: #5f3dc4;--border: #d9cdb6;--input: #d9cdb6;--ring: #8a4516;--glow: rgba(160,82,45,0.1);--glow-soft: rgba(160,82,45,0.05);--scanline-opacity: 0.15;--radius: 0rem;--font-mono: "JetBrains Mono Variable","JetBrains Mono","Menlo",monospace}html[data-theme="green"]{--background: #020604;--foreground: #4fdd7d;--card: #04110a;--card-foreground: #4fdd7d;--popover: #04110a;--popover-foreground: #4fdd7d;--primary: #33ff66;--primary-foreground: #02160a;--secondary: #071509;--secondary-foreground: #4fdd7d;--muted: #071509;--muted-foreground: #3da45e;--accent: #33ff66;--accent-foreground: #02160a;--destructive: #ff5c5c;--success: #4ade80;--warning: #f5b32b;--info: #4dabf7;--pending: #b197fc;--border: #1c4a2c;--input: #1c4a2c;--ring: #33ff66;--glow: rgba(51,255,102,0.35);--glow-soft: rgba(51,255,102,0.12);--scanline-opacity: 0.5}html[data-theme="mono"]{--background: #050505;--foreground: #d4d4d4;--card: #0d0d0d;--card-foreground: #d4d4d4;--popover: #0d0d0d;--popover-foreground: #d4d4d4;--primary: #ffffff;--primary-foreground: #050505;--secondary: #111111;--secondary-foreground: #d4d4d4;--muted: #111111;--muted-foreground: #8a8a8a;--accent: #ffffff;--accent-foreground: #050505;--destructive: #ff5c5c;--success: #4ade80;--warning: #f5b32b;--info: #4dabf7;--pending: #b197fc;--border: #333333;--input: #333333;--ring: #ffffff;--glow: rgba(255,255,255,0.25);--glow-soft: rgba(255,255,255,0.08);--scanline-opacity: 0.45}html[data-theme="paper"]{--background: #fafafa;--foreground: #1f1f1f;--card: #f1f1f1;--card-foreground: #1f1f1f;--popover: #f1f1f1;--popover-foreground: #1f1f1f;--primary: #000000;--primary-foreground: #fafafa;--secondary: #efefef;--secondary-foreground: #1f1f1f;--muted: #efefef;--muted-foreground: #595959;--accent: #000000;--accent-foreground: #fafafa;--destructive: #b3261e;--success: #1a7031;--warning: #8f5d00;--info: #1c5f9e;--pending: #5f3dc4;--border: #d4d4d4;--input: #d4d4d4;--ring: #000000;--glow: rgba(0,0,0,0.06);--glow-soft: rgba(0,0,0,0.04);--scanline-opacity: 0.12}:root{--content-w: 78rem;--content-pad: 1.5rem;--fs-xs: 0.625rem;--fs-sm: 0.6875rem;--fs-base: 0.75rem;--fs-md: 0.8125rem;--fs-lg: 0.9375rem;--fs-xl: 1.125rem;--fs-2xl: 1.5rem;--lh-tight: 1.3;--lh-base: 1.5;--field-label-w: 8.5rem}html{scroll-behavior: smooth}*,*::before,*::after{border-color: var(--border)}:focus-visible{outline: 2px solid var(--ring);outline-offset: 2px}body{background: var(--background);color: var(--foreground);font-family: var(--font-mono);font-size: var(--fs-base);line-height: var(--lh-base);overflow-x: hidden;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}table{font-size: var(--fs-md);width: 100%}th,td{padding: 0.45rem 0.85rem;text-align: left;vertical-align: top;border-block-end: 1px solid color-mix(in srgb,var(--border) 55%,transparent)}thead th{border-block-end-color: var(--border);color: var(--muted-foreground);font-weight: 600}tbody tr:last-child>*{border-block-end: 0}tr>*:first-child{padding-inline-start: 0}tr>*:last-child{padding-inline-end: 0}button:not(:disabled),summary,[role="button"]{cursor: pointer}body::after{content: "";position: fixed;inset: 0;z-index: 40;pointer-events: none;background: repeating-linear-gradient( 0deg,rgba(0,0,0,0.25) 0px,rgba(0,0,0,0.25) 1px,transparent 1px,transparent 3px );opacity: var(--scanline-opacity)}::selection{background: var(--primary);color: var(--primary-foreground)}.glow{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.glow-lg{color: var(--primary);text-shadow: 0 0 12px var(--glow)}.field-row{display: grid;grid-template-columns: var(--field-label-w) minmax(0,1fr);align-items: center;gap: 0.5rem 0.75rem;margin: 0.35rem 0}.field-row>.lbl{color: var(--muted-foreground);font-size: var(--fs-sm);text-align: left}.field-row>.field-val{display: flex;flex-wrap: wrap;align-items: center;gap: 0.4rem 0.9rem;min-width: 0}@media (max-width: 40rem){.field-row{grid-template-columns: 1fr;gap: 0.2rem}}.prompt{font-size: 0.75rem;font-weight: 700;color: var(--muted-foreground)}.prompt::before{content: "$ ";color: var(--primary)}.comment::before{content: "# ";color: var(--border)}.cursor-block{display: inline-block;width: 0.55em;height: 1em;margin-left: 8px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em);animation: ddd-blink 1.1s step-end infinite}@keyframes ddd-blink{50%{opacity: 0}}.btn-terminal{display: inline-block;background: var(--primary);color: var(--primary-foreground);font-weight: 700;padding: 12px 24px;box-shadow: 0 0 16px var(--glow);transition: box-shadow 0.15s ease,transform 0.15s ease}.btn-terminal::before{content: "> "}.btn-terminal--ghost{background: transparent;color: var(--primary);border: 1px solid var(--border);box-shadow: none;font-weight: 400}.btn-terminal--ghost::before{content: ""}.btn-terminal--ghost:hover{border-color: var(--primary);background: color-mix(in srgb,var(--primary) 10%,transparent);box-shadow: none}.btn-terminal:hover{box-shadow: 0 0 28px var(--glow);transform: translateY(-2px)}.btn-terminal--compact{padding: 0.28rem 0.7rem;font-size: var(--fs-sm)}.btn-terminal--destructive{display: inline-flex;align-items: center;justify-content: center;padding: 0.3rem;color: var(--destructive);border-color: color-mix(in srgb,var(--destructive) 45%,var(--border))}.btn-terminal--destructive::before{content: ""}.btn-terminal--destructive::after{content: "";display: block;width: 0.875rem;height: 0.875rem;background: currentColor;-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 3h6v3H9zM4 6h16v2H4zM6 9h12l-1 12H7z'/%3E%3C/svg%3E") center / contain no-repeat;mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 3h6v3H9zM4 6h16v2H4zM6 9h12l-1 12H7z'/%3E%3C/svg%3E") center / contain no-repeat}.btn-terminal--destructive:hover{border-color: var(--destructive);background: color-mix(in srgb,var(--destructive) 12%,transparent);box-shadow: none}@media (pointer: coarse){.btn-terminal--destructive{min-width: 44px;min-height: 44px}}.link-quiet{color: var(--muted-foreground);text-decoration: underline;text-underline-offset: 4px;transition: color 0.15s ease}.link-quiet:hover{color: var(--primary)}.anim-toggle{display: inline-flex;align-items: center;gap: 6px;font: inherit;color: var(--muted-foreground);background: none;border: 0;cursor: pointer;transition: color 0.15s ease}.anim-toggle:hover{color: var(--primary)}.anim-toggle[aria-pressed="true"] [data-anim-box]{color: var(--primary)}.dd-dot{display: inline-block;width: 11px;height: 11px;flex: none;border-radius: 50%;background: currentColor}.dd-flag{display: inline-block;width: 15px;height: 10px;flex: none;border: 1px solid var(--border);background-size: cover;background-repeat: no-repeat}.dd-flag-de{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='4' fill='%23262626'/><rect y='4' width='18' height='4' fill='%23c83232'/><rect y='8' width='18' height='4' fill='%23e8be32'/></svg>")}.dd-flag-en{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%23b22234'/><rect y='4' width='18' height='4' fill='%23ececec'/><rect width='8' height='6' fill='%233c3b6e'/></svg>")}.dd-flag-pt{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%231c9148'/><polygon points='9,1.5 15.5,6 9,10.5 2.5,6' fill='%23e8c832'/><rect x='8' y='5' width='2' height='2' fill='%232c3f87'/></svg>")}.dd-flag-es{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='6' height='12' fill='%2315734c'/><rect x='6' width='6' height='12' fill='%23ececec'/><rect x='12' width='6' height='12' fill='%23bf2233'/><rect x='8' y='5' width='2' height='2' fill='%237a5c3a'/></svg>")}.ascii-rule{margin: 1rem 0;border: 0;color: var(--border);line-height: 1;white-space: nowrap;overflow: hidden;user-select: none}.ascii-rule::before{content: "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"}.card-terminal{background: var(--card);border: 1px solid var(--border);transition: border-color 0.15s ease,box-shadow 0.15s ease}.card-terminal:hover{border-color: var(--primary);box-shadow: 0 0 20px var(--glow-soft)}.dropdown{position: relative}.dropdown>summary{display: inline-flex;align-items: center;gap: 6px;cursor: pointer;user-select: none;list-style: none;color: var(--muted-foreground);transition: color 0.15s ease}.dropdown>summary::-webkit-details-marker{display: none}.dropdown>summary:hover,.dropdown[open]>summary{color: var(--primary)}.dropdown-panel{position: absolute;right: 0;bottom: calc(100% + 12px);z-index: 50;min-width: 128px;margin: 0;padding: 4px 0;list-style: none;background: var(--card);border: 1px solid var(--border);border-radius: var(--radius);box-shadow: 0 0 20px var(--glow-soft)}.dropdown-panel--down{top: calc(100% + 8px);bottom: auto;left: 0;right: auto}.dropdown-item{display: flex;align-items: center;gap: 8px;width: 100%;padding: 5px 14px;text-align: left;font: inherit;line-height: 1.5;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;white-space: nowrap;transition: color 0.15s ease}.dropdown-item:hover{color: var(--primary);background: var(--muted)}.dropdown-item[aria-current="true"],html:not([data-theme]) .dropdown-item[data-theme-value="warm"],html[data-theme="green"] .dropdown-item[data-theme-value="green"],html[data-theme="mono"] .dropdown-item[data-theme-value="mono"],html[data-theme="paper"] .dropdown-item[data-theme-value="paper"],html[data-theme="warm"] .dropdown-item[data-theme-value="warm"]{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.eli5{margin: 1.25em 0;padding: 0.7em 1em;color: var(--foreground);background: color-mix(in srgb,var(--primary) 7%,var(--card));border: 1px solid var(--border);border-left: 3px solid var(--primary);border-radius: var(--radius);font-size: 0.92em;line-height: 1.6}.eli5::before{content: "ELI5";display: inline-flex;align-items: center;justify-content: center;margin-right: 0.6em;vertical-align: 0.08em;font-family: var(--font-mono);font-size: 0.72em;font-weight: 700;line-height: 1;letter-spacing: 0.04em;padding: 0.34em 0.6em;border-radius: var(--radius);background: var(--destructive);color: var(--primary-foreground)}.eli5-term{font-weight: 700;color: var(--primary)}html.anim-off *,html.anim-off *::before,html.anim-off *::after{animation: none !important}html.anim-off .cursor-block{display: none}@media (prefers-reduced-motion: no-preference){html.term-anim [data-term] .prompt:not(.term-live),html.term-anim [data-term] .prompt:not(.term-live)::before{color: transparent}html.term-anim [data-term] [data-term-out]:not(.term-show){visibility: hidden}html.term-anim [data-term] [data-term-out].term-show{animation: ddd-term-output 0.2s steps(3,end) both}@keyframes ddd-term-output{from{opacity: 0}}html.term-anim [data-term] [data-term-out].term-show>*{animation: ddd-term-output 0.25s steps(3,end) both}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(2){animation-delay: 0.09s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(3){animation-delay: 0.18s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(4){animation-delay: 0.27s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(5){animation-delay: 0.36s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(6){animation-delay: 0.45s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(7){animation-delay: 0.54s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(8){animation-delay: 0.63s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(9){animation-delay: 0.72s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(10){animation-delay: 0.81s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(n + 11){animation-delay: 0.9s}.term-caret{display: inline-block;width: 0.55em;height: 1em;margin-left: 2px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em)}}.tabs{display: flex;flex-wrap: wrap;gap: 0.15rem;margin: 1.35rem 0 0;border-bottom: 2px solid color-mix(in srgb,var(--border) 80%,transparent)}.tab{background: transparent;border: 0;margin-bottom: -2px;font: inherit;font-size: 0.86em;cursor: pointer;padding: 0.5rem 0.95rem;color: var(--muted-foreground);transition: background 0.12s ease,color 0.12s ease}.tab:hover{color: var(--primary);background: color-mix(in srgb,var(--primary) 10%,transparent)}.tab[aria-selected="true"]{background: var(--primary);color: var(--background);font-weight: 700}.tab:focus-visible{outline: 2px solid color-mix(in srgb,var(--primary) 55%,transparent);outline-offset: -2px}.tab--info{margin-inline-start: auto}@media (max-width: 40rem){.tab--info{margin-inline-start: 0}}@media (pointer: coarse),(max-width: 40rem){.tab{padding: 0.7rem 0.8rem;min-height: 44px}}section.doc.tab-panel{margin-top: 1.35rem}details.fold{border-top: 1px solid color-mix(in srgb,currentColor 15%,transparent)}details.fold>summary{display: flex;align-items: center;gap: 0.5rem;cursor: pointer;list-style: none;padding: 0.55rem 0;font-size: 0.85rem;color: var(--muted-foreground)}details.fold>summary::-webkit-details-marker{display: none}details.fold>summary::before{content: "\25B8";flex: none;opacity: 0.6}details.fold[open]>summary::before{content: "\25BE"}details.fold>summary:hover{color: var(--primary)}details.fold>summary:focus-visible{outline: 2px solid color-mix(in srgb,currentColor 45%,transparent);outline-offset: 2px}.fold-body{font-size: 0.9rem;padding: 0 0 0.7rem 1.1rem}.fold-body>* + *{margin-top: 0.6rem}.legend{list-style: none;padding: 0;margin: 0.7rem 0 0;display: grid;gap: 0.4rem 1.4rem;font-size: 0.86rem}@media (min-width: 52rem){.legend{grid-template-columns: repeat(2,minmax(0,1fr))}}.legend>li{line-height: 1.6}.legend>li>:first-child{margin-right: 0.45rem}.tickstrip:not(:empty){border: 1px solid var(--border);background: var(--card);margin: 1.6rem 0 1.5rem}.ticktable{width: 100%;border-collapse: collapse;font-size: 0.82rem}.ticktable td{padding: 0.5rem 0.75rem;vertical-align: baseline;border: 0;white-space: nowrap}.ticktable td.tick-stats{width: 100%;white-space: normal}.tick{border-bottom: 1px solid color-mix(in srgb,var(--border) 55%,transparent)}.tick:last-child{border-bottom: 0}.tick-dot{font-size: 0.7em;width: 1.5rem;padding-right: 0 !important;border-left: 3px solid transparent;padding-left: 0.6rem !important}.tick--ok .tick-dot{color: var(--success);border-left-color: color-mix(in srgb,var(--success) 45%,transparent)}.tick--stale .tick-dot{color: var(--destructive);border-left-color: var(--destructive)}.tick--never .tick-dot{color: var(--muted-foreground);border-left-color: color-mix(in srgb,var(--muted-foreground) 35%,transparent)}.tick-name{font-weight: 700;color: var(--foreground);letter-spacing: 0.01em}.tick-last,.tick-next{font-variant-numeric: tabular-nums;color: var(--muted-foreground)}.tick-next{opacity: 0.72}.tick--stale .tick-last{color: var(--destructive);font-weight: 700}.tick--never .tick-last{font-style: italic}.tick-stats{color: var(--muted-foreground)}.tick-stats b{font-weight: 700;color: var(--primary);font-variant-numeric: tabular-nums}.tick-sep{font-style: normal;opacity: 0.35;margin: 0 0.5rem}.tick--stale{background: color-mix(in srgb,var(--destructive) 8%,transparent)}@media (max-width: 40rem){.ticktable,.ticktable tbody,.tick,.ticktable td{display: block}.tick{padding: 0.4rem 0.5rem}.ticktable td{display: inline-block;padding: 0.1rem 0.5rem 0.1rem 0}.ticktable td.tick-stats{display: block;width: auto}}.dgm-zoomable{position: relative;cursor: zoom-in}.dgm-zoomable::after{content: "⤢";position: absolute;top: 0.4rem;right: 0.5rem;font-size: 0.85rem;line-height: 1;opacity: 0.45;pointer-events: none;color: var(--muted-foreground)}.dgm-zoomable:hover::after,.dgm-zoomable:focus-visible::after{opacity: 1;color: var(--primary)}.dgm-zoomable:focus-visible{outline: 2px solid var(--primary);outline-offset: 3px}html.dgm-locked,html.dgm-locked body{overflow: hidden}.dgm-overlay{display: none;position: fixed;inset: 0;z-index: 90;background: color-mix(in srgb,var(--background) 96%,transparent);flex-direction: column}.dgm-overlay.open{display: flex}.dgm-bar{flex: none;display: flex;align-items: center;justify-content: flex-end;gap: 0.4rem;padding: 0.5rem 0.75rem;border-bottom: 1px solid var(--border);background: var(--card)}.dgm-btn{font: inherit;font-size: 0.82rem;cursor: pointer;padding: 0.3rem 0.7rem;min-height: 32px;background: transparent;border: 1px solid var(--border);color: var(--foreground)}.dgm-btn:hover{border-color: var(--primary);color: var(--primary)}.dgm-btn:focus-visible{outline: 2px solid var(--primary);outline-offset: 1px}.dgm-close{border-color: color-mix(in srgb,var(--destructive) 55%,transparent);color: var(--destructive)}.dgm-close:hover{border-color: var(--destructive);color: var(--destructive)}.dgm-stage{flex: 1;overflow: hidden;display: grid;place-items: center;cursor: grab;touch-action: none}.dgm-stage.is-grabbing{cursor: grabbing}.dgm-art{transform-origin: center center;will-change: transform}.dgm-art>svg,.dgm-art>img{display: block;max-width: none;max-height: none}@media print{.dgm-overlay,.dgm-zoomable::after{display: none !important}}.minimap{position: fixed;left: 0;top: var(--ls-nav-top,3rem);bottom: var(--ls-nav-bottom,2.2rem);z-index: 20;display: none;flex-direction: column;justify-content: center;gap: 0.5rem;width: 2rem;padding: 0.75rem 0 0.75rem 0.75rem;overflow-y: auto;overscroll-behavior: contain;scrollbar-width: none}.minimap::-webkit-scrollbar{display: none}@media (min-width: 64rem){.minimap{display: flex}}.minimap-bar{flex: 0 0 auto;width: var(--minimap-bar-w,100%);height: 2px;padding: 0;border: 0;border-radius: 1px;background: var(--border);cursor: pointer;transition: background 0.15s ease,transform 0.15s ease;transform-origin: left center}.minimap-bar:hover{background: var(--muted-foreground);transform: scaleY(2)}.minimap-bar[data-tip]{cursor: pointer}.minimap-bar:focus-visible{outline: 2px solid var(--ring);outline-offset: 3px}.minimap-bar.active{background: var(--primary);transform: scaleY(2)}@media print{.minimap{display: none !important}}.wrap{max-width: var(--content-w);margin-inline: auto;padding-inline: var(--content-pad)}.tablewrap{position: relative;overflow-x: auto;overflow-y: auto;max-block-size: var(--tablewrap-max-h,none)}.tablewrap::after{content: "";position: absolute;inset-block: 0;right: 0;width: 1.5rem;pointer-events: none;opacity: 0.9;background: linear-gradient(to right,transparent,var(--background,transparent))}.tablewrap thead th{position: sticky;inset-block-start: 0;z-index: 1;background: var(--background,#f5efe2)}.skip-link{position: absolute;left: -999px;top: 0;z-index: 100;background: var(--card);border: 1px solid var(--primary);padding: 0.5rem 1rem;color: var(--primary)}.skip-link:focus{left: 0.5rem;top: 0.5rem}.visually-hidden{position: absolute;width: 1px;height: 1px;overflow: hidden;clip: rect(0 0 0 0);white-space: nowrap}header.bar{position: sticky;top: 0;z-index: 30;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.6rem 1.25rem;border-bottom: 1px solid var(--border);background: var(--card)}header.bar .brand{display: inline-flex;align-items: center;font-weight: 700;font-size: 1rem}header.bar .brand,header.bar .brand a{color: inherit;text-decoration: none}header.bar .dropdown summary{padding: 0.6rem 0.4rem}.bar-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}footer.status{position: fixed;inset-inline: 0;bottom: 0;z-index: 50;min-height: 2rem;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.35rem 1.25rem;border-top: 1px solid var(--border);background: var(--card);font-size: 0.7rem}footer.status .dropdown summary,footer.status .anim-toggle{padding: 0.55rem 0.4rem}.status-left{color: var(--muted-foreground);min-width: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.status-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}.sep{width: 1px;height: 0.9rem;background: var(--border)}.doc-link{color: var(--muted-foreground);text-decoration: none;transition: color 0.15s ease}.doc-link:hover{color: var(--primary)}THE ARROW IS PART OF THE LABEL,so this never wraps. Every `→` in the estate is an author-typed U+2192 after an ordinary space — 86 of them in cockpit alone,not one using a no-break space — so every forward link was one narrow column away from putting its arrow alone on the next line. ci/cd's activity table is where it showed: `log → forge →` broke mid-arrow. Fixing it here fixes
|
|
3
|
-
all 86, and fixing it at the call site would have fixed one and left the shape of the bug in
|
|
4
|
-
place. A row action is one atom; nothing is gained by breaking inside it. */
|
|
5
|
-
.doc-link--forward { color: var(--primary); white-space: nowrap; }
|
|
6
|
-
.doc-link--forward:hover { color: var(--primary); text-decoration: underline; }
|
|
7
|
-
|
|
8
|
-
/* A group heading inside the rail. It was in the canonical template and styled by NOTHING —
|
|
9
|
-
it rendered as a plain inline span, so every surface that wanted grouped navigation wrote its
|
|
10
|
-
own rule and they all differed. netmon had already noticed and said so in a comment; cockpit
|
|
11
|
-
had its own. Shipping the name without the look is worse than not shipping it, because the
|
|
12
|
-
markup reads as supported. */
|
|
13
|
-
.ls-group {
|
|
14
|
-
display: block;
|
|
15
|
-
padding: 0.55rem 0 0.15rem;
|
|
16
|
-
font-size: var(--fs-xs);
|
|
17
|
-
letter-spacing: 0.08em;
|
|
18
|
-
color: var(--muted-foreground);
|
|
19
|
-
opacity: 0.75;
|
|
20
|
-
}
|
|
21
|
-
.ls-panel > li:first-child .ls-group { padding-top: 0; }
|
|
22
|
-
|
|
23
|
-
/* ── ls-listing rows (shared by the desktop rail + mobile menu) ── */
|
|
24
|
-
.ls-row { display: flex; align-items: baseline; gap: 0.9rem; }
|
|
25
|
-
.ls-perm { color: var(--muted-foreground); font-size: 0.72rem; letter-spacing: 0; }
|
|
26
|
-
|
|
27
|
-
/* DEPTH IS DRAWN, NOT JUST INDENTED. Whitespace alone did not carry it — with the
|
|
28
|
-
permission column in front of every row, a child sat only ~1rem right of its
|
|
29
|
-
parent and the eye had nothing to follow. Three signals now do the work:
|
|
30
|
-
a vertical guide per level (stacked children form one continuous rule, which is
|
|
31
|
-
what actually shows WHICH parent a row belongs to), directories in the primary
|
|
32
|
-
colour and bolder, and leaves left muted. The guide is the load-bearing one —
|
|
33
|
-
colour alone fails on the two near-black themes and on paper. */
|
|
34
|
-
.ls-row--sub .ls-name {
|
|
35
|
-
margin-left: 0.55rem; padding-left: 0.75rem;
|
|
36
|
-
border-left: 1px solid color-mix(in srgb, var(--muted-foreground) 40%, transparent);
|
|
37
|
-
}
|
|
38
|
-
.ls-row--sub2 .ls-name { margin-left: 1.7rem; }
|
|
39
|
-
/* A directory anchors the level beneath it, so it takes the weight and the colour;
|
|
40
|
-
leaves stay muted. Keyed on a class the renderer emits, not on the trailing slash
|
|
41
|
-
in the label — CSS cannot select on text content. */
|
|
42
|
-
.ls-panel .ls-name { color: var(--muted-foreground); }
|
|
43
|
-
.ls-panel .ls-row--dir .ls-name { color: var(--primary); font-weight: 700; }
|
|
44
|
-
/* The pre-rail dropdown form. Kept, and scoped to the dropdown panel, because the
|
|
45
|
-
other surfaces still ship that markup — when they unpin they get this file, and
|
|
46
|
-
their nav should stay right-aligned rather than quietly jumping to the left. The
|
|
47
|
-
rail's own <ul>carries `ls-panel` WITHOUT `dropdown-panel`,so it is unaffected. */ .dropdown-panel.ls-panel{min-width: 17rem;left: auto !important;right: 0}:root{--ls-nav-w: 17rem;--ls-nav-top: 3rem;--ls-nav-bottom: 2.2rem}@media (min-width: 48.0625rem){html{--ls-nav-inset: 0rem}html:has(.ls-nav):not([data-ls-nav="off"]){--ls-nav-inset: var(--ls-nav-w)}body{padding-right: var(--ls-nav-inset)}header.bar,.bleed-rail{margin-right: calc(-1 * var(--ls-nav-inset))}.ls-nav{position: fixed;top: var(--ls-nav-top);right: 0;bottom: var(--ls-nav-bottom);width: var(--ls-nav-w);z-index: 25;display: flex;flex-direction: column;overflow: hidden;background: var(--card);border-left: 1px solid var(--border)}html:not(.anim-off) .ls-nav{transition: transform 0.18s ease}html[data-ls-nav="off"] .ls-nav{transform: translateX(100%)}.ls-nav-head{display: inline-flex;align-items: center;gap: 0.5rem;margin-left: 0.75rem}.ls-nav-title{font-weight: 700;font-size: 0.9rem}.ls-nav .ls-panel{flex: 1;min-height: 0;overflow-y: auto;list-style: none;margin: 0;padding: 0.5rem 0 1rem}.ls-nav-toggle{background: none;border: 0;font: inherit;cursor: pointer;line-height: 1;color: var(--muted-foreground);padding: 0.4rem 0.55rem}.ls-nav-toggle::after{content: "\00BB"}html[data-ls-nav="off"] .ls-nav-toggle::after{content: "\00AB"}.ls-nav-toggle:hover{color: var(--primary)}.ls-nav-toggle:focus-visible{outline: 2px solid color-mix(in srgb,var(--primary) 55%,transparent);outline-offset: -2px}}.nav-burger{display: none;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;padding: 0.55rem;margin: -0.3rem -0.3rem -0.3rem 0}.nav-burger:hover{color: var(--primary)}.mobile-nav{display: none;list-style: none;margin: 0;padding: 0}.mobile-footer{display: none}@media (max-width: 48rem){.nav-burger{display: inline-flex;align-items: center}.site-nav{display: none;position: absolute;top: 100%;left: 0;right: 0;z-index: 40;background: var(--card);border-bottom: 1px solid var(--border);padding: 0.4rem 1.25rem 0.9rem;max-height: calc(100vh - 6rem);overflow-y: auto}.site-nav.open{display: block}.site-nav>.ls-nav,.mobile-nav{display: flex;flex-direction: column}.site-nav:has(>.ls-nav) .mobile-nav{display: none}.site-nav>.ls-nav .ls-row{align-items: center;min-height: 44px;border-bottom: 1px solid var(--border)}.site-nav>.ls-nav .ls-row .ls-name{display: flex;align-items: center;flex: 1;min-height: 44px}.site-nav>.ls-nav .ls-row:last-child{border-bottom: 0}.mobile-nav .mobile-item{display: flex;align-items: baseline;gap: 0.9rem;padding: 0.65rem 0;text-decoration: none;color: var(--foreground);font-size: 0.9rem;border-bottom: 1px solid var(--border)}.mobile-nav li:last-child .mobile-item{border-bottom: 0}.mobile-nav .mobile-item:active .ls-name,.mobile-nav .mobile-item:hover .ls-name{color: var(--primary)}.ls-nav-toggle{display: none}footer.status{display: none}.mobile-footer{display: flex;flex-direction: column;gap: 0.55rem;margin-top: 0.8rem;border-top: 1px solid var(--border);padding-top: 0.8rem;font-size: 0.85rem}.mobile-footer .doc-link{padding: 0.2rem 0}.mobile-footer .mobile-theme summary{list-style: none;display: flex;align-items: center;gap: 0.5rem;color: var(--muted-foreground);cursor: pointer;padding: 0.2rem 0}.mobile-footer .mobile-theme summary::-webkit-details-marker{display: none}.mobile-footer .mf-chev{margin-left: auto;opacity: 0.7}.mobile-footer .mf-panel{display: flex;flex-direction: column;margin-top: 0.3rem}.mobile-footer .mf-panel .dropdown-item{text-align: left;padding: 0.4rem 0.6rem}.mobile-footer .anim-toggle{display: inline-flex;gap: 0.5rem;align-items: center;background: none;border: 0;padding: 0.2rem 0;color: var(--muted-foreground);font: inherit;cursor: pointer}}[data-tip]{cursor: help}span[data-tip],th[data-tip]{border-bottom: 1px dotted var(--muted-foreground)}#ddtip{position: fixed;z-index: 9999;display: none;max-width: 340px;background: var(--background);color: var(--foreground);border: 1px solid var(--muted-foreground);border-radius: var(--radius);padding: 7px 10px;font-size: 0.72rem;line-height: 1.45;font-weight: 400;text-align: left;white-space: normal;pointer-events: none;box-shadow: 0 4px 14px rgba(0,0,0,0.25)}@media print{@page{margin: 14mm 12mm}:root,html,html[data-theme]{--background: #ffffff;--foreground: #111111;--card: #ffffff;--card-foreground: #111111;--popover: #ffffff;--popover-foreground: #111111;--primary: #000000;--primary-foreground: #ffffff;--secondary: #ffffff;--secondary-foreground: #111111;--muted: #ffffff;--muted-foreground: #444444;--accent: #000000;--accent-foreground: #ffffff;--destructive: #7a1c1c;--border: #9a9a9a;--input: #9a9a9a;--ring: #000000;--glow: transparent;--glow-soft: transparent;--scanline-opacity: 0}html{zoom: 1 !important;font-size: 16px;scroll-behavior: auto}body{background: #ffffff;color: var(--foreground);font-size: 12px;line-height: 1.45;overflow: visible}body::after{display: none !important}*,*::before,*::after{animation: none !important;transition: none !important;text-shadow: none !important;box-shadow: none !important}html.term-anim [data-term] [data-term-out],html.term-anim [data-term] [data-term-out]:not(.term-show),html.term-anim [data-term] [data-term-out]>*{visibility: visible !important;opacity: 1 !important}html.term-anim [data-term] .prompt:not(.term-live){color: var(--muted-foreground) !important}html.term-anim [data-term] .prompt:not(.term-live)::before{color: var(--primary) !important}header.bar,footer.status,.site-nav,.nav-burger,.mobile-nav,.mobile-footer,.skip-link,.dropdown,.dropdown-panel,.anim-toggle,.cursor-block,.term-caret,.ascii-rule,.toc,#ddtip{display: none !important}body{padding-right: 0 !important}[data-tip]{cursor: auto}span[data-tip],th[data-tip]{border-bottom: 0}.wrap{max-width: none !important;margin: 0 !important;padding: 0 !important}.layout{display: block !important}.content{min-width: 0}h1,.title{font-size: 1.5rem !important}h2{font-size: 1.15rem !important}h3,.sub{font-size: 1rem !important}h4{font-size: 0.9rem !important}.prompt{font-size: 0.7rem}h1,h2,h3,h4,.prompt,.toc-label{break-after: avoid-page;break-inside: avoid}p,li,blockquote{orphans: 3;widows: 3}pre,figure,blockquote,tr,img,.eli5,.card-terminal{break-inside: avoid}svg{break-inside: auto}thead{display: table-header-group}.tablewrap,.table-scroll,pre,.diagram{overflow: visible !important;max-width: 100% !important}pre{white-space: pre-wrap !important;overflow-wrap: anywhere;font-size: 0.75rem !important;background: transparent !important}pre.mermaid[data-processed]{white-space: normal !important}code{background: transparent !important;overflow-wrap: anywhere}table{width: 100% !important;table-layout: auto;border-collapse: collapse;font-size: 0.75rem !important}th,td{overflow-wrap: break-word;white-space: normal !important}td code,th code,td a,th a{overflow-wrap: anywhere}a{color: inherit;text-decoration: underline;text-underline-offset: 2px}a.card-terminal,a[class*="card"]{text-decoration: none}.glow,.glow-lg{color: inherit}.btn-terminal{border: 1px solid var(--border);background: transparent;color: var(--foreground)}.mermaid svg{display: block;margin-inline: auto;width: auto !important;height: auto !important;max-width: 100% !important;max-height: 235mm !important}.mermaid svg .node rect,.mermaid svg .node polygon,.mermaid svg .node circle,.mermaid svg .node path,.mermaid svg .label-container,.mermaid svg .cluster rect,.mermaid svg .actor,.mermaid svg .note{fill: #ffffff !important;stroke: #333333 !important}.mermaid svg .edgePath path,.mermaid svg .flowchart-link,.mermaid svg line,.mermaid svg .messageLine0,.mermaid svg .messageLine1{stroke: #333333 !important}.mermaid svg .arrowheadPath,.mermaid svg marker path,.mermaid svg marker polygon{fill: #333333 !important;stroke: #333333 !important}.mermaid svg text,.mermaid svg .nodeLabel,.mermaid svg .edgeLabel,.mermaid svg .cluster-label,.mermaid svg .messageText,.mermaid svg foreignObject div,.mermaid svg foreignObject span,.mermaid svg p{fill: #111111 !important;color: #111111 !important;background: transparent !important}.mermaid svg .edgeLabel rect,.mermaid svg .edgeLabel foreignObject>div{fill: #ffffff !important;background: #ffffff !important}}
|
|
1
|
+
/*! danieldeusing-design v0.17.0 | MIT | https://github.com/danieldeusing/danieldeusing-design */
|
|
2
|
+
*,*::before,*::after{box-sizing: border-box}*{margin: 0}html{-webkit-text-size-adjust: 100%;text-size-adjust: 100%;tab-size: 4}body{min-height: 100vh;min-height: 100dvh;line-height: 1.5}img,picture,video,canvas,svg{display: block;max-width: 100%}input,button,textarea,select{font: inherit;color: inherit}p,h1,h2,h3,h4,h5,h6{overflow-wrap: break-word}ul,ol{list-style: none;padding: 0}a{color: inherit;text-decoration: none}table{border-collapse: collapse}:root{--background: #f5efe2;--foreground: #43352a;--card: #efe7d4;--card-foreground: #43352a;--popover: #efe7d4;--popover-foreground: #43352a;--primary: #8a4516;--primary-foreground: #f8f3e8;--secondary: #ece3cf;--secondary-foreground: #43352a;--muted: #ece3cf;--muted-foreground: #71614e;--accent: #8a4516;--accent-foreground: #f8f3e8;--destructive: #a02c2c;--success: #1a6b2e;--warning: #845600;--info: #1c5f9e;--pending: #5f3dc4;--border: #d9cdb6;--input: #d9cdb6;--ring: #8a4516;--glow: rgba(160,82,45,0.1);--glow-soft: rgba(160,82,45,0.05);--scanline-opacity: 0.15;--radius: 0rem;--font-mono: "JetBrains Mono Variable","JetBrains Mono","Menlo",monospace}html[data-theme="green"]{--background: #020604;--foreground: #4fdd7d;--card: #04110a;--card-foreground: #4fdd7d;--popover: #04110a;--popover-foreground: #4fdd7d;--primary: #33ff66;--primary-foreground: #02160a;--secondary: #071509;--secondary-foreground: #4fdd7d;--muted: #071509;--muted-foreground: #3da45e;--accent: #33ff66;--accent-foreground: #02160a;--destructive: #ff5c5c;--success: #4ade80;--warning: #f5b32b;--info: #4dabf7;--pending: #b197fc;--border: #1c4a2c;--input: #1c4a2c;--ring: #33ff66;--glow: rgba(51,255,102,0.35);--glow-soft: rgba(51,255,102,0.12);--scanline-opacity: 0.5}html[data-theme="mono"]{--background: #050505;--foreground: #d4d4d4;--card: #0d0d0d;--card-foreground: #d4d4d4;--popover: #0d0d0d;--popover-foreground: #d4d4d4;--primary: #ffffff;--primary-foreground: #050505;--secondary: #111111;--secondary-foreground: #d4d4d4;--muted: #111111;--muted-foreground: #8a8a8a;--accent: #ffffff;--accent-foreground: #050505;--destructive: #ff5c5c;--success: #4ade80;--warning: #f5b32b;--info: #4dabf7;--pending: #b197fc;--border: #333333;--input: #333333;--ring: #ffffff;--glow: rgba(255,255,255,0.25);--glow-soft: rgba(255,255,255,0.08);--scanline-opacity: 0.45}html[data-theme="paper"]{--background: #fafafa;--foreground: #1f1f1f;--card: #f1f1f1;--card-foreground: #1f1f1f;--popover: #f1f1f1;--popover-foreground: #1f1f1f;--primary: #000000;--primary-foreground: #fafafa;--secondary: #efefef;--secondary-foreground: #1f1f1f;--muted: #efefef;--muted-foreground: #595959;--accent: #000000;--accent-foreground: #fafafa;--destructive: #b3261e;--success: #1a7031;--warning: #8f5d00;--info: #1c5f9e;--pending: #5f3dc4;--border: #d4d4d4;--input: #d4d4d4;--ring: #000000;--glow: rgba(0,0,0,0.06);--glow-soft: rgba(0,0,0,0.04);--scanline-opacity: 0.12}:root{--content-w: 78rem;--content-pad: 1.5rem;--fs-xs: 0.625rem;--fs-sm: 0.6875rem;--fs-base: 0.75rem;--fs-md: 0.8125rem;--fs-lg: 0.9375rem;--fs-xl: 1.125rem;--fs-2xl: 1.5rem;--lh-tight: 1.3;--lh-base: 1.5;--field-label-w: 8.5rem}html{scroll-behavior: smooth}*,*::before,*::after{border-color: var(--border)}:focus-visible{outline: 2px solid var(--ring);outline-offset: 2px}body{background: var(--background);color: var(--foreground);font-family: var(--font-mono);font-size: var(--fs-base);line-height: var(--lh-base);overflow-x: hidden;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale}table{font-size: var(--fs-md);width: 100%}th,td{padding: 0.45rem 0.85rem;text-align: left;vertical-align: top;border-block-end: 1px solid color-mix(in srgb,var(--border) 55%,transparent)}thead th{border-block-end-color: var(--border);color: var(--muted-foreground);font-weight: 600}tbody tr:last-child>*{border-block-end: 0}tr>*:first-child{padding-inline-start: 0}tr>*:last-child{padding-inline-end: 0}button:not(:disabled),summary,[role="button"]{cursor: pointer}body::after{content: "";position: fixed;inset: 0;z-index: 40;pointer-events: none;background: repeating-linear-gradient( 0deg,rgba(0,0,0,0.25) 0px,rgba(0,0,0,0.25) 1px,transparent 1px,transparent 3px );opacity: var(--scanline-opacity)}::selection{background: var(--primary);color: var(--primary-foreground)}.glow{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.glow-lg{color: var(--primary);text-shadow: 0 0 12px var(--glow)}.field-row{display: grid;grid-template-columns: var(--field-label-w) minmax(0,1fr);align-items: center;gap: 0.5rem 0.75rem;margin: 0.35rem 0}.field-row>.lbl{color: var(--muted-foreground);font-size: var(--fs-sm);text-align: left}.field-row>.field-val{display: flex;flex-wrap: wrap;align-items: center;gap: 0.4rem 0.9rem;min-width: 0}@media (max-width: 40rem){.field-row{grid-template-columns: 1fr;gap: 0.2rem}}.prompt{font-size: 0.75rem;font-weight: 700;color: var(--muted-foreground)}.prompt::before{content: "$ ";color: var(--primary)}.comment::before{content: "# ";color: var(--border)}.cursor-block{display: inline-block;width: 0.55em;height: 1em;margin-left: 8px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em);animation: ddd-blink 1.1s step-end infinite}@keyframes ddd-blink{50%{opacity: 0}}.btn-terminal{display: inline-block;background: var(--primary);color: var(--primary-foreground);font-weight: 700;padding: 12px 24px;box-shadow: 0 0 16px var(--glow);transition: box-shadow 0.15s ease,transform 0.15s ease}.btn-terminal::before{content: "> "}.btn-terminal--ghost{background: transparent;color: var(--primary);border: 1px solid var(--border);box-shadow: none;font-weight: 400}.btn-terminal--ghost::before{content: ""}.btn-terminal--ghost:hover{border-color: var(--primary);background: color-mix(in srgb,var(--primary) 10%,transparent);box-shadow: none}.btn-terminal:hover{box-shadow: 0 0 28px var(--glow);transform: translateY(-2px)}.btn-terminal--compact{padding: 0.28rem 0.7rem;font-size: var(--fs-sm)}.btn-terminal--destructive{display: inline-flex;align-items: center;justify-content: center;padding: 0.3rem;color: var(--destructive);border-color: color-mix(in srgb,var(--destructive) 45%,var(--border))}.btn-terminal--destructive::before{content: ""}.btn-terminal--destructive::after{content: "";display: block;width: 0.875rem;height: 0.875rem;background: currentColor;-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 3h6v3H9zM4 6h16v2H4zM6 9h12l-1 12H7z'/%3E%3C/svg%3E") center / contain no-repeat;mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 3h6v3H9zM4 6h16v2H4zM6 9h12l-1 12H7z'/%3E%3C/svg%3E") center / contain no-repeat}.btn-terminal--destructive:hover{border-color: var(--destructive);background: color-mix(in srgb,var(--destructive) 12%,transparent);box-shadow: none}@media (pointer: coarse){.btn-terminal--destructive{min-width: 44px;min-height: 44px}}.link-quiet{color: var(--muted-foreground);text-decoration: underline;text-underline-offset: 4px;transition: color 0.15s ease}.link-quiet:hover{color: var(--primary)}.anim-toggle{display: inline-flex;align-items: center;gap: 6px;font: inherit;color: var(--muted-foreground);background: none;border: 0;cursor: pointer;transition: color 0.15s ease}.anim-toggle:hover{color: var(--primary)}.anim-toggle[aria-pressed="true"] [data-anim-box]{color: var(--primary)}.dd-dot{display: inline-block;width: 11px;height: 11px;flex: none;border-radius: 50%;background: currentColor}.dd-flag{display: inline-block;width: 15px;height: 10px;flex: none;border: 1px solid var(--border);background-size: cover;background-repeat: no-repeat}.dd-flag-de{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='4' fill='%23262626'/><rect y='4' width='18' height='4' fill='%23c83232'/><rect y='8' width='18' height='4' fill='%23e8be32'/></svg>")}.dd-flag-en{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%23b22234'/><rect y='4' width='18' height='4' fill='%23ececec'/><rect width='8' height='6' fill='%233c3b6e'/></svg>")}.dd-flag-pt{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='18' height='12' fill='%231c9148'/><polygon points='9,1.5 15.5,6 9,10.5 2.5,6' fill='%23e8c832'/><rect x='8' y='5' width='2' height='2' fill='%232c3f87'/></svg>")}.dd-flag-es{background-image: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 12'><rect width='6' height='12' fill='%2315734c'/><rect x='6' width='6' height='12' fill='%23ececec'/><rect x='12' width='6' height='12' fill='%23bf2233'/><rect x='8' y='5' width='2' height='2' fill='%237a5c3a'/></svg>")}.ascii-rule{margin: 1rem 0;border: 0;color: var(--border);line-height: 1;white-space: nowrap;overflow: hidden;user-select: none}.ascii-rule::before{content: "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────"}.card-terminal{background: var(--card);border: 1px solid var(--border);transition: border-color 0.15s ease,box-shadow 0.15s ease}.card-terminal:hover{border-color: var(--primary);box-shadow: 0 0 20px var(--glow-soft)}.dropdown{position: relative}.dropdown>summary{display: inline-flex;align-items: center;gap: 6px;cursor: pointer;user-select: none;list-style: none;color: var(--muted-foreground);transition: color 0.15s ease}.dropdown>summary::-webkit-details-marker{display: none}.dropdown>summary:hover,.dropdown[open]>summary{color: var(--primary)}.dropdown-panel{position: absolute;right: 0;bottom: calc(100% + 12px);z-index: 50;min-width: 128px;margin: 0;padding: 4px 0;list-style: none;background: var(--card);border: 1px solid var(--border);border-radius: var(--radius);box-shadow: 0 0 20px var(--glow-soft)}.dropdown-panel--down{top: calc(100% + 8px);bottom: auto;left: 0;right: auto}.dropdown-item{display: flex;align-items: center;gap: 8px;width: 100%;padding: 5px 14px;text-align: left;font: inherit;line-height: 1.5;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;white-space: nowrap;transition: color 0.15s ease}.dropdown-item:hover{color: var(--primary);background: var(--muted)}.dropdown-item[aria-current="true"],html:not([data-theme]) .dropdown-item[data-theme-value="warm"],html[data-theme="green"] .dropdown-item[data-theme-value="green"],html[data-theme="mono"] .dropdown-item[data-theme-value="mono"],html[data-theme="paper"] .dropdown-item[data-theme-value="paper"],html[data-theme="warm"] .dropdown-item[data-theme-value="warm"]{color: var(--primary);text-shadow: 0 0 8px var(--glow)}.eli5{margin: 1.25em 0;padding: 0.7em 1em;color: var(--foreground);background: color-mix(in srgb,var(--primary) 7%,var(--card));border: 1px solid var(--border);border-left: 3px solid var(--primary);border-radius: var(--radius);font-size: 0.92em;line-height: 1.6}.eli5::before{content: "ELI5";display: inline-flex;align-items: center;justify-content: center;margin-right: 0.6em;vertical-align: 0.08em;font-family: var(--font-mono);font-size: 0.72em;font-weight: 700;line-height: 1;letter-spacing: 0.04em;padding: 0.34em 0.6em;border-radius: var(--radius);background: var(--destructive);color: var(--primary-foreground)}.eli5-term{font-weight: 700;color: var(--primary)}html.anim-off *,html.anim-off *::before,html.anim-off *::after{animation: none !important}html.anim-off .cursor-block{display: none}@media (prefers-reduced-motion: no-preference){html.term-anim [data-term] .prompt:not(.term-live),html.term-anim [data-term] .prompt:not(.term-live)::before{color: transparent}html.term-anim [data-term] [data-term-out]:not(.term-show){visibility: hidden}html.term-anim [data-term] [data-term-out].term-show{animation: ddd-term-output 0.2s steps(3,end) both}@keyframes ddd-term-output{from{opacity: 0}}html.term-anim [data-term] [data-term-out].term-show>*{animation: ddd-term-output 0.25s steps(3,end) both}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(2){animation-delay: 0.09s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(3){animation-delay: 0.18s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(4){animation-delay: 0.27s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(5){animation-delay: 0.36s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(6){animation-delay: 0.45s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(7){animation-delay: 0.54s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(8){animation-delay: 0.63s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(9){animation-delay: 0.72s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(10){animation-delay: 0.81s}html.term-anim [data-term] [data-term-out].term-show>*:nth-child(n + 11){animation-delay: 0.9s}.term-caret{display: inline-block;width: 0.55em;height: 1em;margin-left: 2px;background: var(--primary);vertical-align: baseline;transform: translateY(0.12em)}}.tabs{display: flex;flex-wrap: wrap;gap: 0.15rem;margin: 1.35rem 0 0;border-bottom: 2px solid color-mix(in srgb,var(--border) 80%,transparent)}.tab{background: transparent;border: 0;margin-bottom: -2px;font: inherit;font-size: 0.86em;cursor: pointer;padding: 0.5rem 0.95rem;color: var(--muted-foreground);transition: background 0.12s ease,color 0.12s ease}.tab:hover{color: var(--primary);background: color-mix(in srgb,var(--primary) 10%,transparent)}.tab[aria-selected="true"]{background: var(--primary);color: var(--background);font-weight: 700}.tab:focus-visible{outline: 2px solid color-mix(in srgb,var(--primary) 55%,transparent);outline-offset: -2px}.tab--info{margin-inline-start: auto}@media (max-width: 40rem){.tab--info{margin-inline-start: 0}}@media (pointer: coarse),(max-width: 40rem){.tab{padding: 0.7rem 0.8rem;min-height: 44px}}section.doc.tab-panel{margin-top: 1.35rem}details.fold{border-top: 1px solid color-mix(in srgb,currentColor 15%,transparent)}details.fold>summary{display: flex;align-items: center;gap: 0.5rem;cursor: pointer;list-style: none;padding: 0.55rem 0;font-size: 0.85rem;color: var(--muted-foreground)}details.fold>summary::-webkit-details-marker{display: none}details.fold>summary::before{content: "\25B8";flex: none;opacity: 0.6}details.fold[open]>summary::before{content: "\25BE"}details.fold>summary:hover{color: var(--primary)}details.fold>summary:focus-visible{outline: 2px solid color-mix(in srgb,currentColor 45%,transparent);outline-offset: 2px}.fold-body{font-size: 0.9rem;padding: 0 0 0.7rem 1.1rem}.fold-body>* + *{margin-top: 0.6rem}.legend{list-style: none;padding: 0;margin: 0.7rem 0 0;display: grid;gap: 0.4rem 1.4rem;font-size: 0.86rem}@media (min-width: 52rem){.legend{grid-template-columns: repeat(2,minmax(0,1fr))}}.legend>li{line-height: 1.6}.legend>li>:first-child{margin-right: 0.45rem}.dgm-zoomable{position: relative;cursor: zoom-in}.dgm-zoomable::after{content: "⤢";position: absolute;top: 0.4rem;right: 0.5rem;font-size: 0.85rem;line-height: 1;opacity: 0.45;pointer-events: none;color: var(--muted-foreground)}.dgm-zoomable:hover::after,.dgm-zoomable:focus-visible::after{opacity: 1;color: var(--primary)}.dgm-zoomable:focus-visible{outline: 2px solid var(--primary);outline-offset: 3px}html.dgm-locked,html.dgm-locked body{overflow: hidden}.dgm-overlay{display: none;position: fixed;inset: 0;z-index: 90;background: color-mix(in srgb,var(--background) 96%,transparent);flex-direction: column}.dgm-overlay.open{display: flex}.dgm-bar{flex: none;display: flex;align-items: center;justify-content: flex-end;gap: 0.4rem;padding: 0.5rem 0.75rem;border-bottom: 1px solid var(--border);background: var(--card)}.dgm-btn{font: inherit;font-size: 0.82rem;cursor: pointer;padding: 0.3rem 0.7rem;min-height: 32px;background: transparent;border: 1px solid var(--border);color: var(--foreground)}.dgm-btn:hover{border-color: var(--primary);color: var(--primary)}.dgm-btn:focus-visible{outline: 2px solid var(--primary);outline-offset: 1px}.dgm-close{border-color: color-mix(in srgb,var(--destructive) 55%,transparent);color: var(--destructive)}.dgm-close:hover{border-color: var(--destructive);color: var(--destructive)}.dgm-stage{flex: 1;overflow: hidden;display: grid;place-items: center;cursor: grab;touch-action: none}.dgm-stage.is-grabbing{cursor: grabbing}.dgm-art{transform-origin: center center;will-change: transform}.dgm-art>svg,.dgm-art>img{display: block;max-width: none;max-height: none}@media print{.dgm-overlay,.dgm-zoomable::after{display: none !important}}.minimap{position: fixed;left: 0;top: var(--ls-nav-top,3rem);bottom: var(--ls-nav-bottom,2.2rem);z-index: 20;display: none;flex-direction: column;justify-content: center;gap: 0.5rem;width: 2rem;padding: 0.75rem 0 0.75rem 0.75rem;overflow-y: auto;overscroll-behavior: contain;scrollbar-width: none}.minimap::-webkit-scrollbar{display: none}@media (min-width: 64rem){.minimap{display: flex}}.minimap-bar{flex: 0 0 auto;width: var(--minimap-bar-w,100%);height: 2px;padding: 0;border: 0;border-radius: 1px;background: var(--border);cursor: pointer;transition: background 0.15s ease,transform 0.15s ease;transform-origin: left center}.minimap-bar:hover{background: var(--muted-foreground);transform: scaleY(2)}.minimap-bar[data-tip]{cursor: pointer}.minimap-bar:focus-visible{outline: 2px solid var(--ring);outline-offset: 3px}.minimap-bar.active{background: var(--primary);transform: scaleY(2)}@media print{.minimap{display: none !important}}.wrap{max-width: var(--content-w);margin-inline: auto;padding-inline: var(--content-pad)}.tablewrap{position: relative;overflow-x: auto;overflow-y: auto;max-block-size: var(--tablewrap-max-h,none)}.tablewrap::after{content: "";position: absolute;inset-block: 0;right: 0;width: 1.5rem;pointer-events: none;opacity: 0.9;background: linear-gradient(to right,transparent,var(--background,transparent))}.tablewrap thead th{position: sticky;inset-block-start: 0;z-index: 1;background: var(--background,#f5efe2)}.tickstrip:not(:empty){border: 1px solid var(--border);background: var(--card);margin: 1.6rem 0 1.5rem}.ticktable{width: 100%;border-collapse: collapse;font-size: 0.82rem}.ticktable td{padding: 0.5rem 0.75rem;vertical-align: baseline;border: 0;white-space: nowrap}.ticktable td.tick-stats{width: 100%;white-space: normal}.tick{border-bottom: 1px solid color-mix(in srgb,var(--border) 55%,transparent)}.tick:last-child{border-bottom: 0}.tick-dot{font-size: 0.7em;width: 1.5rem;padding-right: 0 !important;border-left: 3px solid transparent;padding-left: 0.6rem !important}.tick--ok .tick-dot{color: var(--success);border-left-color: color-mix(in srgb,var(--success) 45%,transparent)}.tick--stale .tick-dot{color: var(--destructive);border-left-color: var(--destructive)}.tick--never .tick-dot{color: var(--muted-foreground);border-left-color: color-mix(in srgb,var(--muted-foreground) 35%,transparent)}.tick-name{font-weight: 700;color: var(--foreground);letter-spacing: 0.01em}.tick-last,.tick-next{font-variant-numeric: tabular-nums;color: var(--muted-foreground)}.tick-next{opacity: 0.72}.tick--stale .tick-last{color: var(--destructive);font-weight: 700}.tick--never .tick-last{font-style: italic}.tick-stats{color: var(--muted-foreground)}.tick-stats b{font-weight: 700;color: var(--primary);font-variant-numeric: tabular-nums}.tick-sep{font-style: normal;opacity: 0.35;margin: 0 0.5rem}.tick--stale{background: color-mix(in srgb,var(--destructive) 8%,transparent)}@media (max-width: 40rem){.ticktable,.ticktable tbody,.tick,.ticktable td{display: block}.tick{padding: 0.4rem 0.5rem}.ticktable td{display: inline-block;padding: 0.1rem 0.5rem 0.1rem 0}.ticktable td.tick-stats{display: block;width: auto}}.skip-link{position: absolute;left: -999px;top: 0;z-index: 100;background: var(--card);border: 1px solid var(--primary);padding: 0.5rem 1rem;color: var(--primary)}.skip-link:focus{left: 0.5rem;top: 0.5rem}.visually-hidden{position: absolute;width: 1px;height: 1px;overflow: hidden;clip: rect(0 0 0 0);white-space: nowrap}header.bar{position: sticky;top: 0;z-index: 30;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.6rem 1.25rem;border-bottom: 1px solid var(--border);background: var(--card)}header.bar .brand{display: inline-flex;align-items: center;font-weight: 700;font-size: 1rem}header.bar .brand,header.bar .brand a{color: inherit;text-decoration: none}header.bar .dropdown summary{padding: 0.6rem 0.4rem}.bar-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}footer.status{position: fixed;inset-inline: 0;bottom: 0;z-index: 50;min-height: 2rem;display: flex;align-items: center;justify-content: space-between;gap: 1rem;padding: 0.35rem 1.25rem;border-top: 1px solid var(--border);background: var(--card);font-size: 0.7rem}footer.status .dropdown summary,footer.status .anim-toggle{padding: 0.55rem 0.4rem}.status-left{color: var(--muted-foreground);min-width: 0;overflow: hidden;text-overflow: ellipsis;white-space: nowrap}.status-right{display: flex;align-items: center;gap: 1rem;flex-shrink: 0}.sep{width: 1px;height: 0.9rem;background: var(--border)}.doc-link{color: var(--muted-foreground);text-decoration: none;transition: color 0.15s ease}.doc-link:hover{color: var(--primary)}.doc-link--forward{color: var(--primary);white-space: nowrap}.doc-link--forward:hover{color: var(--primary);text-decoration: underline}.ls-group{display: block;padding: 0.55rem 0 0.15rem;font-size: var(--fs-xs);letter-spacing: 0.08em;color: var(--muted-foreground);opacity: 0.75}.ls-panel>li:first-child .ls-group{padding-top: 0}.ls-row{display: flex;align-items: baseline;gap: 0.9rem}.ls-perm{color: var(--muted-foreground);font-size: 0.72rem;letter-spacing: 0}.ls-row--sub .ls-name{margin-left: 0.55rem;padding-left: 0.75rem;border-left: 1px solid color-mix(in srgb,var(--muted-foreground) 40%,transparent)}.ls-row--sub2 .ls-name{margin-left: 1.7rem}.ls-panel .ls-name{color: var(--muted-foreground)}.ls-panel .ls-row--dir .ls-name{color: var(--primary);font-weight: 700}.dropdown-panel.ls-panel{min-width: 17rem;left: auto !important;right: 0}:root{--ls-nav-w: 17rem;--ls-nav-top: 3rem;--ls-nav-bottom: 2.2rem}@media (min-width: 48.0625rem){html{--ls-nav-inset: 0rem}html:has(.ls-nav):not([data-ls-nav="off"]){--ls-nav-inset: var(--ls-nav-w)}body{padding-right: var(--ls-nav-inset)}header.bar,.bleed-rail{margin-right: calc(-1 * var(--ls-nav-inset))}.ls-nav{position: fixed;top: var(--ls-nav-top);right: 0;bottom: var(--ls-nav-bottom);width: var(--ls-nav-w);z-index: 25;display: flex;flex-direction: column;overflow: hidden;background: var(--card);border-left: 1px solid var(--border)}html:not(.anim-off) .ls-nav{transition: transform 0.18s ease}html[data-ls-nav="off"] .ls-nav{transform: translateX(100%)}.ls-nav-head{display: inline-flex;align-items: center;gap: 0.5rem;margin-left: 0.75rem}.ls-nav-title{font-weight: 700;font-size: 0.9rem}.ls-nav .ls-panel{flex: 1;min-height: 0;overflow-y: auto;list-style: none;margin: 0;padding: 0.5rem 0 1rem}.ls-nav-toggle{background: none;border: 0;font: inherit;cursor: pointer;line-height: 1;color: var(--muted-foreground);padding: 0.4rem 0.55rem}.ls-nav-toggle::after{content: "\00BB"}html[data-ls-nav="off"] .ls-nav-toggle::after{content: "\00AB"}.ls-nav-toggle:hover{color: var(--primary)}.ls-nav-toggle:focus-visible{outline: 2px solid color-mix(in srgb,var(--primary) 55%,transparent);outline-offset: -2px}}.nav-burger{display: none;background: none;border: 0;color: var(--muted-foreground);cursor: pointer;padding: 0.55rem;margin: -0.3rem -0.3rem -0.3rem 0}.nav-burger:hover{color: var(--primary)}.mobile-nav{display: none;list-style: none;margin: 0;padding: 0}.mobile-footer{display: none}@media (max-width: 48rem){.nav-burger{display: inline-flex;align-items: center}.site-nav{display: none;position: absolute;top: 100%;left: 0;right: 0;z-index: 40;background: var(--card);border-bottom: 1px solid var(--border);padding: 0.4rem 1.25rem 0.9rem;max-height: calc(100vh - 6rem);overflow-y: auto}.site-nav.open{display: block}.site-nav>.ls-nav,.mobile-nav{display: flex;flex-direction: column}.site-nav:has(>.ls-nav) .mobile-nav{display: none}.site-nav>.ls-nav .ls-row{align-items: center;min-height: 44px;border-bottom: 1px solid var(--border)}.site-nav>.ls-nav .ls-row .ls-name{display: flex;align-items: center;flex: 1;min-height: 44px}.site-nav>.ls-nav .ls-row:last-child{border-bottom: 0}.mobile-nav .mobile-item{display: flex;align-items: baseline;gap: 0.9rem;padding: 0.65rem 0;text-decoration: none;color: var(--foreground);font-size: 0.9rem;border-bottom: 1px solid var(--border)}.mobile-nav li:last-child .mobile-item{border-bottom: 0}.mobile-nav .mobile-item:active .ls-name,.mobile-nav .mobile-item:hover .ls-name{color: var(--primary)}.ls-nav-toggle{display: none}footer.status{display: none}.mobile-footer{display: flex;flex-direction: column;gap: 0.55rem;margin-top: 0.8rem;border-top: 1px solid var(--border);padding-top: 0.8rem;font-size: 0.85rem}.mobile-footer .doc-link{padding: 0.2rem 0}.mobile-footer .mobile-theme summary{list-style: none;display: flex;align-items: center;gap: 0.5rem;color: var(--muted-foreground);cursor: pointer;padding: 0.2rem 0}.mobile-footer .mobile-theme summary::-webkit-details-marker{display: none}.mobile-footer .mf-chev{margin-left: auto;opacity: 0.7}.mobile-footer .mf-panel{display: flex;flex-direction: column;margin-top: 0.3rem}.mobile-footer .mf-panel .dropdown-item{text-align: left;padding: 0.4rem 0.6rem}.mobile-footer .anim-toggle{display: inline-flex;gap: 0.5rem;align-items: center;background: none;border: 0;padding: 0.2rem 0;color: var(--muted-foreground);font: inherit;cursor: pointer}}[data-tip]{cursor: help}span[data-tip],th[data-tip]{border-bottom: 1px dotted var(--muted-foreground)}#ddtip{position: fixed;z-index: 9999;display: none;max-width: 340px;background: var(--background);color: var(--foreground);border: 1px solid var(--muted-foreground);border-radius: var(--radius);padding: 7px 10px;font-size: 0.72rem;line-height: 1.45;font-weight: 400;text-align: left;white-space: normal;pointer-events: none;box-shadow: 0 4px 14px rgba(0,0,0,0.25)}@media print{@page{margin: 14mm 12mm}:root,html,html[data-theme]{--background: #ffffff;--foreground: #111111;--card: #ffffff;--card-foreground: #111111;--popover: #ffffff;--popover-foreground: #111111;--primary: #000000;--primary-foreground: #ffffff;--secondary: #ffffff;--secondary-foreground: #111111;--muted: #ffffff;--muted-foreground: #444444;--accent: #000000;--accent-foreground: #ffffff;--destructive: #7a1c1c;--border: #9a9a9a;--input: #9a9a9a;--ring: #000000;--glow: transparent;--glow-soft: transparent;--scanline-opacity: 0}html{zoom: 1 !important;font-size: 16px;scroll-behavior: auto}body{background: #ffffff;color: var(--foreground);font-size: 12px;line-height: 1.45;overflow: visible}body::after{display: none !important}*,*::before,*::after{animation: none !important;transition: none !important;text-shadow: none !important;box-shadow: none !important}html.term-anim [data-term] [data-term-out],html.term-anim [data-term] [data-term-out]:not(.term-show),html.term-anim [data-term] [data-term-out]>*{visibility: visible !important;opacity: 1 !important}html.term-anim [data-term] .prompt:not(.term-live){color: var(--muted-foreground) !important}html.term-anim [data-term] .prompt:not(.term-live)::before{color: var(--primary) !important}header.bar,footer.status,.site-nav,.nav-burger,.mobile-nav,.mobile-footer,.skip-link,.dropdown,.dropdown-panel,.anim-toggle,.cursor-block,.term-caret,.ascii-rule,.toc,#ddtip{display: none !important}body{padding-right: 0 !important}[data-tip]{cursor: auto}span[data-tip],th[data-tip]{border-bottom: 0}.wrap{max-width: none !important;margin: 0 !important;padding: 0 !important}.layout{display: block !important}.content{min-width: 0}h1,.title{font-size: 1.5rem !important}h2{font-size: 1.15rem !important}h3,.sub{font-size: 1rem !important}h4{font-size: 0.9rem !important}.prompt{font-size: 0.7rem}h1,h2,h3,h4,.prompt,.toc-label{break-after: avoid-page;break-inside: avoid}p,li,blockquote{orphans: 3;widows: 3}pre,figure,blockquote,tr,img,.eli5,.card-terminal{break-inside: avoid}svg{break-inside: auto}thead{display: table-header-group}.tablewrap,.table-scroll,pre,.diagram{overflow: visible !important;max-width: 100% !important}pre{white-space: pre-wrap !important;overflow-wrap: anywhere;font-size: 0.75rem !important;background: transparent !important}pre.mermaid[data-processed]{white-space: normal !important}code{background: transparent !important;overflow-wrap: anywhere}table{width: 100% !important;table-layout: auto;border-collapse: collapse;font-size: 0.75rem !important}th,td{overflow-wrap: break-word;white-space: normal !important}td code,th code,td a,th a{overflow-wrap: anywhere}a{color: inherit;text-decoration: underline;text-underline-offset: 2px}a.card-terminal,a[class*="card"]{text-decoration: none}.glow,.glow-lg{color: inherit}.btn-terminal{border: 1px solid var(--border);background: transparent;color: var(--foreground)}.mermaid svg{display: block;margin-inline: auto;width: auto !important;height: auto !important;max-width: 100% !important;max-height: 235mm !important}.mermaid svg .node rect,.mermaid svg .node polygon,.mermaid svg .node circle,.mermaid svg .node path,.mermaid svg .label-container,.mermaid svg .cluster rect,.mermaid svg .actor,.mermaid svg .note{fill: #ffffff !important;stroke: #333333 !important}.mermaid svg .edgePath path,.mermaid svg .flowchart-link,.mermaid svg line,.mermaid svg .messageLine0,.mermaid svg .messageLine1{stroke: #333333 !important}.mermaid svg .arrowheadPath,.mermaid svg marker path,.mermaid svg marker polygon{fill: #333333 !important;stroke: #333333 !important}.mermaid svg text,.mermaid svg .nodeLabel,.mermaid svg .edgeLabel,.mermaid svg .cluster-label,.mermaid svg .messageText,.mermaid svg foreignObject div,.mermaid svg foreignObject span,.mermaid svg p{fill: #111111 !important;color: #111111 !important;background: transparent !important}.mermaid svg .edgeLabel rect,.mermaid svg .edgeLabel foreignObject>div{fill: #ffffff !important;background: #ffffff !important}}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danieldeusing/design",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "The danieldeusing terminal design system — framework-agnostic CSS tokens, components, and a vanilla-JS runtime for the CRT/JetBrains-Mono look used across danieldeusing.de, seedr, and briefs.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/src/chrome.css
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* chrome.css — the app chrome kit: sticky header bar, fixed status footer,
|
|
3
|
-
* and the responsive site navigation (desktop `ls -l` RAIL,
|
|
4
|
-
* the footer folded in). Extracted from danieldeusing.de and
|
|
5
|
-
* so every app ships the same chrome without rebuilding it.
|
|
3
|
+
* the ticker strip, and the responsive site navigation (desktop `ls -l` RAIL,
|
|
4
|
+
* mobile burger with the footer folded in). Extracted from danieldeusing.de and
|
|
5
|
+
* the cockpit portal so every app ships the same chrome without rebuilding it.
|
|
6
6
|
*
|
|
7
7
|
* Markup contract (see templates/documentation.html for the full example):
|
|
8
8
|
*
|
|
@@ -113,6 +113,83 @@
|
|
|
113
113
|
background: var(--background, #f5efe2);
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
/* ── ticker strip: one standard header for every poller ────────────────────────────────────────
|
|
117
|
+
Daniel: "For all pollers / tickers we should make a standard layout ... on top of the pages,
|
|
118
|
+
compact and like dashboard style."
|
|
119
|
+
|
|
120
|
+
Every poller answers the same four questions — what ran, when, when next, what did it count —
|
|
121
|
+
and each page was answering them in its own prose box, so "is anything stalled?" took four
|
|
122
|
+
paragraphs instead of one glance.
|
|
123
|
+
|
|
124
|
+
A real TABLE, not a grid per row. The first version made each row its own `display: grid`,
|
|
125
|
+
which cannot align anything across rows: every row sized its columns to its own content, so
|
|
126
|
+
`next` sat wherever that row's name happened to end and the layout moved when a label changed.
|
|
127
|
+
One table means one set of column widths for the whole strip, and scanning a column is the only
|
|
128
|
+
thing the strip is for. Borderless by design — rules between cells draw a grid nobody reads.
|
|
129
|
+
|
|
130
|
+
Colour comes only from --primary and --destructive, both per-theme. Hardcoded accents miss AA
|
|
131
|
+
on at least one theme (measured 2026-08-04), so a strip inventing its own greens and ambers
|
|
132
|
+
would have added five more.
|
|
133
|
+
|
|
134
|
+
IT LIVES IN CHROME, NOT COMPONENTS (0.17.0), and the move is what makes it reachable. The strip
|
|
135
|
+
is page-level status furniture — it sits above the content and reports whether the page's own
|
|
136
|
+
machinery is running — which is the same job as the header bar and the status footer, not the
|
|
137
|
+
job of a card or a button. The practical half: components.css is not separable in practice.
|
|
138
|
+
Taking it brings base.css's scanline overlay, its table type and its control styling, so a
|
|
139
|
+
surface with its own layout cannot load it for one component. netmon is the case — it is read
|
|
140
|
+
DURING an outage, so it ships tokens.css + chrome.css as a same-origin snapshot and nothing
|
|
141
|
+
else, and for two releases the estate's standard status strip was the one piece of shared
|
|
142
|
+
vocabulary it could not have. It had a bare timestamp in its header bar instead.
|
|
143
|
+
|
|
144
|
+
A tokens+chrome consumer therefore gets: the column, table scroll, the a11y helpers, the header
|
|
145
|
+
bar, the footer, the `ls -l` rail, the burger — AND the strip. Bundle consumers are unaffected;
|
|
146
|
+
dist/ concatenates both layers, and the rules reference only tokens, so source order cannot
|
|
147
|
+
change what they resolve to. */
|
|
148
|
+
/* Breathing room above: the strip follows the page's lede, and butted straight up against a
|
|
149
|
+
paragraph it read as part of the prose rather than as instrumentation. */
|
|
150
|
+
.tickstrip:not(:empty) { border: 1px solid var(--border); background: var(--card); margin: 1.6rem 0 1.5rem; }
|
|
151
|
+
.ticktable { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
|
|
152
|
+
.ticktable td { padding: 0.5rem 0.75rem; vertical-align: baseline; border: 0; white-space: nowrap; }
|
|
153
|
+
/* Only the last column may grow, so the four fixed columns keep the same width on every row. */
|
|
154
|
+
.ticktable td.tick-stats { width: 100%; white-space: normal; }
|
|
155
|
+
.tick { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
|
|
156
|
+
.tick:last-child { border-bottom: 0; }
|
|
157
|
+
/* State reads THREE ways, so it survives every context: the GLYPH (two themes are near-black and
|
|
158
|
+
a printout has no colour at all), the COLOUR, and a left edge-marker that makes a bad row
|
|
159
|
+
findable by shape alone when the strip is scanned rather than read. */
|
|
160
|
+
.tick-dot {
|
|
161
|
+
font-size: 0.7em; width: 1.5rem; padding-right: 0 !important;
|
|
162
|
+
border-left: 3px solid transparent; padding-left: 0.6rem !important;
|
|
163
|
+
}
|
|
164
|
+
/* --success is per-theme and AA-measured (0.3.0). `ok` used to borrow --primary — the BRAND
|
|
165
|
+
colour — so a healthy poller and the page heading were the same ink, and "everything is fine"
|
|
166
|
+
had to be read rather than seen. */
|
|
167
|
+
.tick--ok .tick-dot { color: var(--success); border-left-color: color-mix(in srgb, var(--success) 45%, transparent); }
|
|
168
|
+
.tick--stale .tick-dot { color: var(--destructive); border-left-color: var(--destructive); }
|
|
169
|
+
.tick--never .tick-dot { color: var(--muted-foreground); border-left-color: color-mix(in srgb, var(--muted-foreground) 35%, transparent); }
|
|
170
|
+
/* The NAME is an identifier, not an accent. Making it --primary put brand colour on every row of
|
|
171
|
+
a strip whose entire job is that the exceptions stand out. */
|
|
172
|
+
.tick-name { font-weight: 700; color: var(--foreground); letter-spacing: 0.01em; }
|
|
173
|
+
.tick-last, .tick-next { font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
|
|
174
|
+
/* "next 57s" is a prediction; the age beside it is an observation. It should not compete. */
|
|
175
|
+
.tick-next { opacity: 0.72; }
|
|
176
|
+
.tick--stale .tick-last { color: var(--destructive); font-weight: 700; }
|
|
177
|
+
.tick--never .tick-last { font-style: italic; }
|
|
178
|
+
/* The NUMBER is what gets scanned; its label is context. Weight and colour on the value alone
|
|
179
|
+
means a row reads as its numbers first and its wording second. */
|
|
180
|
+
.tick-stats { color: var(--muted-foreground); }
|
|
181
|
+
.tick-stats b { font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
|
|
182
|
+
.tick-sep { font-style: normal; opacity: 0.35; margin: 0 0.5rem; }
|
|
183
|
+
/* A stale row earns the only background tint in the strip — an all-tinted strip is one the eye
|
|
184
|
+
stops reading. */
|
|
185
|
+
.tick--stale { background: color-mix(in srgb, var(--destructive) 8%, transparent); }
|
|
186
|
+
@media (max-width: 40rem) {
|
|
187
|
+
.ticktable, .ticktable tbody, .tick, .ticktable td { display: block; }
|
|
188
|
+
.tick { padding: 0.4rem 0.5rem; }
|
|
189
|
+
.ticktable td { display: inline-block; padding: 0.1rem 0.5rem 0.1rem 0; }
|
|
190
|
+
.ticktable td.tick-stats { display: block; width: auto; }
|
|
191
|
+
}
|
|
192
|
+
|
|
116
193
|
/* ── a11y helpers ── */
|
|
117
194
|
.skip-link {
|
|
118
195
|
position: absolute; left: -999px; top: 0; z-index: 100;
|
|
@@ -153,7 +230,8 @@ footer.status .dropdown summary, footer.status .anim-toggle { padding: 0.55rem 0
|
|
|
153
230
|
`.doc-link` is deliberately quiet because it is footer furniture, and a row action inherited
|
|
154
231
|
that quietness: a column of grey `open →` reads as disabled text rather than as the way in.
|
|
155
232
|
It carries the accent from rest, not only on hover, because a row action is the reason the
|
|
156
|
-
row is interactive at all and hover cannot advertise itself.
|
|
233
|
+
row is interactive at all and hover cannot advertise itself.
|
|
234
|
+
|
|
157
235
|
THE ARROW IS PART OF THE LABEL, so this never wraps. Every `→` in the estate is an author-typed
|
|
158
236
|
U+2192 after an ordinary space — 86 of them in cockpit alone, not one using a no-break space —
|
|
159
237
|
so every forward link was one narrow column away from putting its arrow alone on the next line.
|
package/src/components.css
CHANGED
|
@@ -558,68 +558,6 @@ details.fold > summary:focus-visible {
|
|
|
558
558
|
.legend > li { line-height: 1.6; }
|
|
559
559
|
.legend > li > :first-child { margin-right: 0.45rem; }
|
|
560
560
|
|
|
561
|
-
/* ── ticker strip: one standard header for every poller ────────────────────────────────────────
|
|
562
|
-
Daniel: "For all pollers / tickers we should make a standard layout ... on top of the pages,
|
|
563
|
-
compact and like dashboard style."
|
|
564
|
-
|
|
565
|
-
Every poller answers the same four questions — what ran, when, when next, what did it count —
|
|
566
|
-
and each page was answering them in its own prose box, so "is anything stalled?" took four
|
|
567
|
-
paragraphs instead of one glance.
|
|
568
|
-
|
|
569
|
-
A real TABLE, not a grid per row. The first version made each row its own `display: grid`,
|
|
570
|
-
which cannot align anything across rows: every row sized its columns to its own content, so
|
|
571
|
-
`next` sat wherever that row's name happened to end and the layout moved when a label changed.
|
|
572
|
-
One table means one set of column widths for the whole strip, and scanning a column is the only
|
|
573
|
-
thing the strip is for. Borderless by design — rules between cells draw a grid nobody reads.
|
|
574
|
-
|
|
575
|
-
Colour comes only from --primary and --destructive, both per-theme. Hardcoded accents miss AA
|
|
576
|
-
on at least one theme (measured 2026-08-04), so a strip inventing its own greens and ambers
|
|
577
|
-
would have added five more. */
|
|
578
|
-
/* Breathing room above: the strip follows the page's lede, and butted straight up against a
|
|
579
|
-
paragraph it read as part of the prose rather than as instrumentation. */
|
|
580
|
-
.tickstrip:not(:empty) { border: 1px solid var(--border); background: var(--card); margin: 1.6rem 0 1.5rem; }
|
|
581
|
-
.ticktable { width: 100%; border-collapse: collapse; font-size: 0.82rem; }
|
|
582
|
-
.ticktable td { padding: 0.5rem 0.75rem; vertical-align: baseline; border: 0; white-space: nowrap; }
|
|
583
|
-
/* Only the last column may grow, so the four fixed columns keep the same width on every row. */
|
|
584
|
-
.ticktable td.tick-stats { width: 100%; white-space: normal; }
|
|
585
|
-
.tick { border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
|
|
586
|
-
.tick:last-child { border-bottom: 0; }
|
|
587
|
-
/* State reads THREE ways, so it survives every context: the GLYPH (two themes are near-black and
|
|
588
|
-
a printout has no colour at all), the COLOUR, and a left edge-marker that makes a bad row
|
|
589
|
-
findable by shape alone when the strip is scanned rather than read. */
|
|
590
|
-
.tick-dot {
|
|
591
|
-
font-size: 0.7em; width: 1.5rem; padding-right: 0 !important;
|
|
592
|
-
border-left: 3px solid transparent; padding-left: 0.6rem !important;
|
|
593
|
-
}
|
|
594
|
-
/* --success is per-theme and AA-measured (0.3.0). `ok` used to borrow --primary — the BRAND
|
|
595
|
-
colour — so a healthy poller and the page heading were the same ink, and "everything is fine"
|
|
596
|
-
had to be read rather than seen. */
|
|
597
|
-
.tick--ok .tick-dot { color: var(--success); border-left-color: color-mix(in srgb, var(--success) 45%, transparent); }
|
|
598
|
-
.tick--stale .tick-dot { color: var(--destructive); border-left-color: var(--destructive); }
|
|
599
|
-
.tick--never .tick-dot { color: var(--muted-foreground); border-left-color: color-mix(in srgb, var(--muted-foreground) 35%, transparent); }
|
|
600
|
-
/* The NAME is an identifier, not an accent. Making it --primary put brand colour on every row of
|
|
601
|
-
a strip whose entire job is that the exceptions stand out. */
|
|
602
|
-
.tick-name { font-weight: 700; color: var(--foreground); letter-spacing: 0.01em; }
|
|
603
|
-
.tick-last, .tick-next { font-variant-numeric: tabular-nums; color: var(--muted-foreground); }
|
|
604
|
-
/* "next 57s" is a prediction; the age beside it is an observation. It should not compete. */
|
|
605
|
-
.tick-next { opacity: 0.72; }
|
|
606
|
-
.tick--stale .tick-last { color: var(--destructive); font-weight: 700; }
|
|
607
|
-
.tick--never .tick-last { font-style: italic; }
|
|
608
|
-
/* The NUMBER is what gets scanned; its label is context. Weight and colour on the value alone
|
|
609
|
-
means a row reads as its numbers first and its wording second. */
|
|
610
|
-
.tick-stats { color: var(--muted-foreground); }
|
|
611
|
-
.tick-stats b { font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; }
|
|
612
|
-
.tick-sep { font-style: normal; opacity: 0.35; margin: 0 0.5rem; }
|
|
613
|
-
/* A stale row earns the only background tint in the strip — an all-tinted strip is one the eye
|
|
614
|
-
stops reading. */
|
|
615
|
-
.tick--stale { background: color-mix(in srgb, var(--destructive) 8%, transparent); }
|
|
616
|
-
@media (max-width: 40rem) {
|
|
617
|
-
.ticktable, .ticktable tbody, .tick, .ticktable td { display: block; }
|
|
618
|
-
.tick { padding: 0.4rem 0.5rem; }
|
|
619
|
-
.ticktable td { display: inline-block; padding: 0.1rem 0.5rem 0.1rem 0; }
|
|
620
|
-
.ticktable td.tick-stats { display: block; width: auto; }
|
|
621
|
-
}
|
|
622
|
-
|
|
623
561
|
/* ── zoomable diagrams ────────────────────────────────────────────────────────────────────────
|
|
624
562
|
An architecture diagram authored for a text column is unreadable at exactly the moment someone
|
|
625
563
|
needs it. Pair with `initDiagramZoom()`: every `.diagram` becomes a real button that opens
|
|
@@ -98,13 +98,13 @@
|
|
|
98
98
|
on docs.danieldeusing.de, NOT for a doc opened from disk over file://. -->
|
|
99
99
|
<link
|
|
100
100
|
rel="stylesheet"
|
|
101
|
-
href="https://cdn.jsdelivr.net/npm/@danieldeusing/design@0.
|
|
102
|
-
onerror="this.onerror=null;this.href='/_design/danieldeusing-design-0.
|
|
101
|
+
href="https://cdn.jsdelivr.net/npm/@danieldeusing/design@0.17.0/dist/danieldeusing-design.min.css"
|
|
102
|
+
onerror="this.onerror=null;this.href='/_design/danieldeusing-design-0.17.0.min.css'"
|
|
103
103
|
/>
|
|
104
104
|
<link
|
|
105
105
|
rel="stylesheet"
|
|
106
|
-
href="https://cdn.jsdelivr.net/npm/@danieldeusing/design@0.
|
|
107
|
-
onerror="this.onerror=null;this.href='/_design/danieldeusing-design-0.
|
|
106
|
+
href="https://cdn.jsdelivr.net/npm/@danieldeusing/design@0.17.0/src/fonts.css"
|
|
107
|
+
onerror="this.onerror=null;this.href='/_design/danieldeusing-design-0.17.0.fonts.css'"
|
|
108
108
|
/>
|
|
109
109
|
|
|
110
110
|
<style>
|
|
@@ -341,7 +341,7 @@ flowchart TD
|
|
|
341
341
|
|
|
342
342
|
<script type="module">
|
|
343
343
|
import { applyStoredTheme, initThemeSwitcher, initDropdowns, initTerminal, initAnimToggle, initBurgerNav, initLsNav, initTableScroll, initDiagramZoom, initMinimap, initTooltips } from
|
|
344
|
-
"https://cdn.jsdelivr.net/npm/@danieldeusing/design@0.
|
|
344
|
+
"https://cdn.jsdelivr.net/npm/@danieldeusing/design@0.17.0/runtime/index.js";
|
|
345
345
|
applyStoredTheme();
|
|
346
346
|
initThemeSwitcher();
|
|
347
347
|
initDropdowns();
|