eleven / ocho Public

Clone
git clone https://amadan.net/eleven/ocho

Plain git — no account needed to clone.

Download

Download this file

1/* πŸ€– Shared stylesheet for the public status pages (web/status/*.html): fleet,
2 income & expenditure, tier economics, investing, security, carbon,
3 contributors, the prompt ledger, the SSH access ledger, and the fleet
4 hardening posture.
5 ONE design system β€” the design tokens, the reset, and every component the
6 pages share (the brand masthead, the grouped nav, tiles, the single-series
7 bar list, notes, the "couldn't load" alert, footer). Each page <link>s this
8 and keeps only a SMALL inline <style> for its own unique bits.
9
10 Same-origin: uploaded from the same status bucket as the pages, so the
11 privacy property still holds β€” a page pulls its styles from its own origin,
12 never a third-party host. Published by deploy/status-publish.sh, which uploads
13 this file BEFORE the html so a page is never served ahead of its stylesheet.
14
15 Palette: the dataviz-validated role set (six-checks, light + dark) already in
16 use across all seven pages β€” the violet slot (--series / --link) is the Eleven
17 brand family; --ink-2 carries ALL small text (>=4.5:1 in both modes). The
18 names are the ones every page already used; this file is simply their single
19 home (the union of every role any page referenced). */
20:root {
21 --plane: #f9f9f7; --surface: #fcfcfb;
22 --ink: #0b0b0b; --ink-2: #52514e;
23 --grid: #e1e0d9; --border: rgba(11,11,11,0.10);
24 --series: #4a3aa7;
25 --good: #006300; --good-mark: #0ca30c;
26 --warn: #7a4d00;
27 --bad: #b23030; --bad-mark: #d03b3b;
28 --link: #4a3aa7;
29 --redact-bg: #f3e9d8; --redact-ink: #7a5b16;
30}
31@media (prefers-color-scheme: dark) {
32 :root {
33 --plane: #0d0d0d; --surface: #1a1a19;
34 --ink: #ffffff; --ink-2: #c3c2b7;
35 --grid: #2c2c2a; --border: rgba(255,255,255,0.10);
36 --series: #9085e9;
37 --good: #0ca30c; --good-mark: #0ca30c;
38 --warn: #e0a33c;
39 --bad: #e66767; --bad-mark: #e66767;
40 --link: #9085e9;
41 --redact-bg: #3a3220; --redact-ink: #e0c274;
42 }
43}
44
45* { box-sizing: border-box; margin: 0; }
46/* Reserve the scrollbar gutter always, so a page short enough not to scroll
47 centers identically to one that does β€” the masthead/nav must not shift
48 between pages (they're pinned to one width for the same reason below). */
49html { scrollbar-gutter: stable; }
50body {
51 background: var(--plane); color: var(--ink);
52 font: 16px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
53 padding: 24px 16px 48px;
54}
55.wrap { max-width: 760px; margin: 0 auto; }
56a { color: var(--link); }
57a:focus-visible { outline: 2px solid var(--series); outline-offset: 2px; border-radius: 4px; }
58
59/* Masthead: the brand line + page title, identical on every page. Like the
60 nav below, it pins to the default 760px wrap width and centers, so it sits
61 at the exact same viewport position even on a page that widens its .wrap
62 (prompts.html, 860px) β€” the top of every page must never shift. */
63header { display: flex; align-items: center; gap: 14px; max-width: 760px; margin: 0 auto 6px; }
64header img { width: 44px; height: 44px; border-radius: 10px; }
65header h1 { font-size: 22px; font-weight: 650; }
66header .brand { color: var(--ink-2); font-size: 14px; }
67
68/* The status nav β€” one system, not a flat link list: the dashboards cluster
69 into four labelled groups (Operations = the machines, Money, Ledgers = the
70 public records, Plan), each a quiet chip cluster on a surface. The labels
71 encode what a page IS, so item names inside them stay short ("Access", not
72 "Access Ledger"). The current page is a filled non-link chip, still marked
73 aria-current + bolded so weight (not color alone) carries it. A 2Γ—2 grid,
74 not a wrapped flex row: intrinsic-width pills left the two rows ragged, and
75 Paul asked (2026-07-21) for both rows full width with equal-width pills β€”
76 1fr tracks give exactly that (rows also share a height, so the four read as
77 one block). */
78nav.status-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 14px; max-width: 760px; margin: 10px auto 18px; }
79.status-nav .group {
80 display: flex; flex-wrap: wrap; align-items: center; gap: 2px;
81 background: var(--surface); border: 1px solid var(--border);
82 border-radius: 10px; padding: 3px;
83}
84.status-nav .group-label {
85 font-size: 11px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase;
86 color: var(--ink-2); padding: 0 6px 0 9px;
87}
88.status-nav a, .status-nav [aria-current="page"] {
89 display: inline-block; padding: 2px 9px; border-radius: 7px;
90 color: var(--link); text-decoration: none;
91}
92.status-nav a:hover { background: var(--grid); text-decoration: underline; }
93.status-nav [aria-current="page"] { background: var(--series); color: var(--surface); font-weight: 650; }
94/* On narrow screens the four groups would fill the first viewport, so the
95 nav collapses behind a Menu disclosure (status-nav.js wires the toggle and
96 keeps aria-expanded true to the state). Desktop never shows the button. */
97.status-nav .menu-toggle {
98 display: none; font: inherit; font-weight: 650; cursor: pointer;
99 align-items: center; gap: 8px; color: var(--link);
100 background: var(--surface); border: 1px solid var(--border);
101 border-radius: 10px; padding: 6px 12px;
102}
103.status-nav .menu-toggle:hover { background: var(--grid); }
104.status-nav .menu-toggle:focus-visible { outline: 2px solid var(--series); outline-offset: 2px; }
105.status-nav .menu-toggle .glyph { color: var(--ink-2); }
106@media (max-width: 640px) {
107 /* One column: the open groups stack full-width; justify-self keeps the
108 Menu button intrinsic-width (a grid cell would otherwise stretch it). */
109 nav.status-nav { grid-template-columns: 1fr; }
110 .status-nav .menu-toggle { display: inline-flex; justify-self: start; }
111 nav.status-nav:not(.open) .group { display: none; }
112}
113
114.lede { color: var(--ink-2); margin: 6px 0 2px; }
115.asof { font-weight: 600; margin: 10px 0 24px; }
116.asof .stale { color: var(--bad); font-weight: 600; }
117
118/* Section rhythm + heading (pages built from <section> blocks). */
119section { margin-bottom: 28px; }
120section h2 { font-size: 15px; font-weight: 650; margin: 0 0 10px; }
121
122/* Muted body notes and the one-line design explainer under a section heading. */
123.note { color: var(--ink-2); font-size: 14px; }
124.explain { margin: -4px 0 12px; }
125
126/* Stat tiles. */
127.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; margin-bottom: 28px; }
128.tile { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 14px 16px; }
129.tile .label { font-size: 13px; color: var(--ink-2); }
130.tile .value { font-size: 30px; font-weight: 600; margin-top: 2px; }
131.tile .sub { color: var(--ink-2); font-size: 14px; margin-top: 6px; }
132
133/* Single-series horizontal bar list (fleet versions, book tiers, the carbon
134 ledger, contributors): every row is real text β€” its own table view β€” and the
135 bar is aria-hidden decoration. Thin 12px mark, 4px rounded data-end, square at
136 the baseline. Per-page first/last column widths override .bars li inline. */
137.bars { list-style: none; padding: 0; background: var(--surface); border: 1px solid var(--border); border-radius: 12px; }
138.bars li { display: grid; grid-template-columns: minmax(90px, 160px) 1fr 3.5em; align-items: center; gap: 12px; padding: 10px 16px; }
139.bars li + li { border-top: 1px solid var(--grid); }
140.bars .track { height: 12px; }
141.bars .bar { height: 12px; min-width: 2px; background: var(--series); border-radius: 0 4px 4px 0; display: block; }
142.bars .count { font-size: 14px; color: var(--ink-2); text-align: right; font-variant-numeric: tabular-nums; }
143.bars .empty { display: block; color: var(--ink-2); }
144
145/* The inline "couldn't load the feed" alert (retries every minute). */
146#error { display: none; background: var(--surface); border: 1px solid var(--bad-mark); border-radius: 12px; padding: 14px 16px; margin-bottom: 24px; }
147#error.show { display: block; }
148
149footer { margin-top: 36px; color: var(--ink-2); font-size: 14px; }
150footer p { margin-top: 6px; }
151