Task-first instead of app-first: start here, pick what you want to do, open the door. Every door gets its exact address, the button to press, and the failure the household actually hits. Screenshots are files now (img/onboarding/*.webp, 14 of them, all captured logged in as a standard user) instead of inline data URIs: the page is 23 KB of prose instead of 30 KB of base64, and the images cache on their own. Zero-JS kept. Facts re-checked against the live services rather than against the old page: the front door is www.franksdank.cloud (the apex 308s there); the standard user's Open WebUI account sees all three models and opens on frank-dragoon (read from /api/models as that user); WebDAV answers only on the house network (207 on 192.168.0.235:3923, a guard challenge through the public door); Audiobookshelf iOS is a limited-seat TestFlight beta, Android is the Play release.
347 lines
14 KiB
CSS
347 lines
14 KiB
CSS
/* The homepage theme: StarCraft Protoss console — flat deep-space navy,
|
|
warp-blue/cyan accents used sparingly, Share Tech Mono body with
|
|
Rajdhani headings (Google Fonts CDN), soft-radius panels on crisp
|
|
1px steel borders, quiet section headers. Motion is reserved for
|
|
state (speaking voice). A ?bare=1 toggle strips the page to bare,
|
|
unstyled HTML (Q27). The page never sets a custom or hidden cursor,
|
|
so the user's cursor is untouched (Q28). */
|
|
|
|
:root {
|
|
--bg: #050d16;
|
|
--fg: #bfe3ff;
|
|
--dim: #5d87a8;
|
|
--down: #ff4d5e;
|
|
--wip: #ffd24d;
|
|
--link: #4fd8ff;
|
|
--head: #eaf7ff;
|
|
--border: #1d4a6e;
|
|
--panel: #0a1826;
|
|
--proto-blue: #3fa9ff; /* warp-blade blue */
|
|
--proto-cyan: #7fe7ff; /* psychic-light cyan */
|
|
--font-mono: "Share Tech Mono", "DejaVu Sans Mono", "Consolas", monospace;
|
|
--font-head: "Rajdhani", "Share Tech Mono", sans-serif;
|
|
}
|
|
|
|
* { box-sizing: border-box; }
|
|
|
|
html { background: var(--bg); }
|
|
|
|
body {
|
|
background: var(--bg);
|
|
color: var(--fg);
|
|
font-family: var(--font-mono);
|
|
font-size: 18px;
|
|
line-height: 1.45;
|
|
margin: 0;
|
|
padding: 24px;
|
|
}
|
|
|
|
/* One quiet pylon glow above the horizon; the navy stays flat. */
|
|
body::after {
|
|
content: "";
|
|
position: fixed;
|
|
inset: 0;
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
background: radial-gradient(1200px 500px at 50% -10%,
|
|
rgba(63, 169, 255, 0.07), transparent 65%);
|
|
}
|
|
|
|
.top {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: baseline;
|
|
border-bottom: 2px solid var(--proto-blue);
|
|
padding-bottom: 8px;
|
|
}
|
|
.title { color: var(--head); text-shadow: 0 0 10px color-mix(in srgb, var(--proto-blue) 30%, transparent); }
|
|
.summary { color: var(--dim); margin: 12px 0; letter-spacing: 0.05em; }
|
|
|
|
/* Sections stack vertically; each section's panels fill a horizontal
|
|
auto-fill row (as many panels per row as the viewport allows). */
|
|
.section { margin-bottom: 20px; }
|
|
.section-title {
|
|
color: var(--head);
|
|
font-size: 1.05rem;
|
|
font-weight: 600;
|
|
letter-spacing: 0.16em;
|
|
text-transform: uppercase;
|
|
margin: 0 0 12px;
|
|
padding: 0 0 6px 24px;
|
|
position: relative;
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.section-title::before { content: "\25C7"; display: inline-block; width: 18px;
|
|
margin-left: -24px; color: var(--proto-cyan); }
|
|
|
|
.grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
|
|
gap: 12px;
|
|
}
|
|
|
|
.panel { border: 1px solid var(--border); background: var(--panel); padding: 12px 14px;
|
|
border-radius: 6px; display: flex; flex-direction: column; }
|
|
.panel.clickable { cursor: pointer; transition: border-color 0.15s, filter 0.15s, transform 0.15s; }
|
|
.panel.clickable:hover {
|
|
border-color: var(--proto-cyan);
|
|
transform: translateY(-2px);
|
|
filter: drop-shadow(0 0 6px color-mix(in srgb, var(--proto-blue) 45%, transparent));
|
|
}
|
|
.panel.down {
|
|
border-color: color-mix(in srgb, var(--down) 70%, var(--border));
|
|
background: linear-gradient(180deg,
|
|
color-mix(in srgb, var(--down) 10%, var(--panel)), var(--panel));
|
|
}
|
|
.mi-card:has(.badge.down) {
|
|
border-color: color-mix(in srgb, var(--down) 70%, var(--mi));
|
|
background: linear-gradient(180deg,
|
|
color-mix(in srgb, var(--down) 10%, var(--panel)), var(--panel));
|
|
}
|
|
.panel-head { display: flex; align-items: center; gap: 8px; }
|
|
.panel-head .name { flex: 1; }
|
|
.app-art {
|
|
width: 40px;
|
|
height: 40px;
|
|
flex: 0 0 auto;
|
|
object-fit: contain;
|
|
padding: 4px;
|
|
clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0% 50%);
|
|
border: 1px solid var(--dim);
|
|
background: color-mix(in srgb, var(--fg) 8%, transparent);
|
|
filter: saturate(1.15) brightness(1.05);
|
|
}
|
|
.name { color: var(--head); }
|
|
.badge { border: 1px solid currentColor; padding: 0 6px; font-size: 12px;
|
|
border-radius: 3px; }
|
|
.badge.up { color: var(--fg); }
|
|
.badge.down { color: var(--down); }
|
|
.badge.wip-open { color: var(--wip); }
|
|
.badge.wip-closed { color: var(--dim); }
|
|
/* Closed WIP items grey out: darker type, desaturated art. */
|
|
.panel:has(.badge.wip-closed) { border-color: color-mix(in srgb, var(--dim) 45%, var(--border)); }
|
|
.panel:has(.badge.wip-closed) .name,
|
|
.panel:has(.badge.wip-closed) .desc,
|
|
.panel:has(.badge.wip-closed) .desc-role,
|
|
.panel:has(.badge.wip-closed) .desc-spec,
|
|
.panel:has(.badge.wip-closed) .desc-use { color: var(--dim); }
|
|
.panel:has(.badge.wip-closed) .app-art { filter: grayscale(0.75) brightness(0.7); }
|
|
.badge.wip-down { color: var(--down); }
|
|
.desc { color: var(--fg); margin: 8px 0; }
|
|
.desc-role { color: var(--dim); font-weight: bold; }
|
|
.desc-spec { color: var(--fg); }
|
|
.desc-equiv { color: var(--head); font-style: italic; }
|
|
.desc-inputs { color: var(--dim); }
|
|
.desc-use { color: var(--fg); margin-top: 4px; }
|
|
.links a { color: var(--link); text-decoration: underline; margin-right: 12px; }
|
|
/* Privacy disclosures: collapsed chip pinned to the panel bottom. */
|
|
.svc-warn { margin-top: auto; padding-top: 8px; color: var(--down); }
|
|
.svc-warn summary, .mi-warn summary { cursor: pointer; color: var(--down);
|
|
list-style: none; user-select: none; }
|
|
.svc-warn summary::-webkit-details-marker,
|
|
.mi-warn summary::-webkit-details-marker { display: none; }
|
|
.svc-warn summary::after, .mi-warn summary::after { content: " \25B8"; }
|
|
.svc-warn[open] summary::after, .mi-warn[open] summary::after { content: " \25BE"; }
|
|
.warn-body { margin-top: 6px; color: var(--down); }
|
|
|
|
.foot {
|
|
margin-top: 24px;
|
|
border-top: 1px solid var(--border);
|
|
padding-top: 12px;
|
|
color: var(--dim);
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
.foot a { color: var(--link); text-decoration: none; }
|
|
.top-links { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
|
|
.top .foot-btn { color: var(--link); text-decoration: none; }
|
|
.foot-links { display: flex; gap: 10px; flex-wrap: wrap; }
|
|
.foot-btn {
|
|
border: 1px solid var(--link);
|
|
padding: 2px 14px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
border-radius: 4px;
|
|
}
|
|
.foot-btn:hover {
|
|
background: color-mix(in srgb, var(--link) 14%, transparent);
|
|
}
|
|
|
|
/* The user docs page (static prose). */
|
|
.docs { max-width: 780px; }
|
|
.docs h1 { color: var(--head); font-size: 1.7rem; border-bottom: 1px solid var(--border); padding-bottom: 4px; }
|
|
.docs h2 { color: var(--head); font-size: 1.35rem; margin-top: 20px; }
|
|
.docs a { color: var(--link); }
|
|
.docs code { color: var(--head); }
|
|
.docs pre { background: var(--panel); border: 1px solid var(--border); border-radius: 2px; padding: 10px 12px; overflow-x: auto; }
|
|
.docs pre code { color: var(--fg); }
|
|
.docs img { display: block; max-width: 100%; border: 1px solid var(--border); border-radius: 2px; margin: 10px 0; }
|
|
.docs .key-warn { color: var(--down); }
|
|
.docs details.key-warn summary { cursor: pointer; list-style: none; user-select: none; }
|
|
.docs details.key-warn summary::-webkit-details-marker { display: none; }
|
|
.docs details.key-warn summary::after { content: " \25B8"; }
|
|
.docs details.key-warn[open] summary::after { content: " \25BE"; }
|
|
.docs details.key-warn .warn-body { margin-top: 4px; }
|
|
.docs .foot-note { color: var(--dim); }
|
|
.docs h3 { color: var(--head); font-size: 1.05rem; margin-top: 16px; }
|
|
.docs figure { margin: 14px 0; }
|
|
.docs figcaption { color: var(--dim); font-size: .85rem; }
|
|
.docs table { border-collapse: collapse; width: 100%; margin: 10px 0; }
|
|
.docs th, .docs td { border: 1px solid var(--border); padding: 6px 8px; text-align: left; vertical-align: top; }
|
|
.docs th { color: var(--head); }
|
|
.docs .toc { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 4px; margin: 12px 0; }
|
|
.docs .toc a { display: block; border: 1px solid var(--border); padding: 6px 8px; text-decoration: none; }
|
|
.docs .kicker { color: var(--dim); text-transform: uppercase; letter-spacing: .12em; font-size: .72rem; }
|
|
html[data-bare="1"] .docs h1, html[data-bare="1"] .docs h2 { color: #000; border-color: #000; }
|
|
html[data-bare="1"] .docs a, html[data-bare="1"] .docs code { color: #000; }
|
|
html[data-bare="1"] .docs pre { background: none; border-color: #000; }
|
|
html[data-bare="1"] .docs pre code { color: #000; }
|
|
html[data-bare="1"] .docs img { border-color: #000; }
|
|
html[data-bare="1"] .docs .key-warn { color: #000; }
|
|
html[data-bare="1"] .docs h3, html[data-bare="1"] .docs th { color: #000; }
|
|
html[data-bare="1"] .docs th, html[data-bare="1"] .docs td, html[data-bare="1"] .docs .toc a { border-color: #000; }
|
|
|
|
/* Bare mode (Q27): strip to default browser rendering. */
|
|
html[data-bare="1"] body { background: #fff; color: #000; font-family: serif; text-shadow: none; font-size: 16px; }
|
|
html[data-bare="1"] body::before { display: none; }
|
|
html[data-bare="1"] .panel, html[data-bare="1"] .top, html[data-bare="1"] .foot { border-color: #000; background: none; }
|
|
html[data-bare="1"] .badge, html[data-bare="1"] .name, html[data-bare="1"] .desc, html[data-bare="1"] .summary, html[data-bare="1"] .section-title { color: #000; }
|
|
html[data-bare="1"] .desc-role, html[data-bare="1"] .desc-spec, html[data-bare="1"] .desc-inputs, html[data-bare="1"] .desc-use, html[data-bare="1"] .desc-equiv { color: #000; font-weight: normal; }
|
|
html[data-bare="1"] .section-title { border-color: #000; padding: 0 0 6px 2px; }
|
|
html[data-bare="1"] .links a, html[data-bare="1"] .toggle, html[data-bare="1"] .foot a { color: #000; }
|
|
html[data-bare="1"] .foot-btn { border-color: #000; text-shadow: none; }
|
|
html[data-bare="1"] .panel, html[data-bare="1"] .mi-card, html[data-bare="1"] .badge, html[data-bare="1"] .foot-btn, html[data-bare="1"] .model-info { clip-path: none; border-radius: 0; filter: none; animation: none; box-shadow: none; }
|
|
html[data-bare="1"] body::after { display: none; }
|
|
html[data-bare="1"] .section-title::before, html[data-bare="1"] .section-title::after, html[data-bare="1"] .title::after { content: none; }
|
|
html[data-bare="1"] .top { border-image: none; }
|
|
|
|
/* Model Information: one fused panel for the fleet models. Informational
|
|
panels, so the type is smaller than the app panels; each model wears its
|
|
StarCraft Protoss unit's colours and art. */
|
|
.model-info {
|
|
grid-column: 1 / -1;
|
|
background: var(--panel);
|
|
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--proto-cyan) 25%, transparent);
|
|
border-radius: 8px;
|
|
}
|
|
.mi-title {
|
|
color: var(--proto-cyan);
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.14em;
|
|
border-bottom: 1px solid var(--border);
|
|
margin-bottom: 10px;
|
|
padding-bottom: 4px;
|
|
display: flex;
|
|
align-items: baseline;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
}
|
|
.mi-docs-link {
|
|
color: var(--link);
|
|
text-decoration: none;
|
|
text-transform: none;
|
|
letter-spacing: 0.06em;
|
|
font-size: 13px;
|
|
white-space: nowrap;
|
|
}
|
|
.mi-docs-link:hover { text-decoration: underline; }
|
|
.mi-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
gap: 12px;
|
|
}
|
|
.mi-card {
|
|
font-size: 15px;
|
|
line-height: 1.35;
|
|
border: 1px solid var(--mi);
|
|
background: var(--mi-bg);
|
|
padding: 10px 12px;
|
|
border-radius: 6px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
.mi-zealot { --mi: #4fb4ff; } /* Zealot: Khai's blue blades */
|
|
.mi-archon { --mi: #a8ecff; } /* Archon: pure psychic light */
|
|
.mi-dragoon { --mi: #5fe0d0; } /* Dragoon: phase-crystal teal */
|
|
.mi-top { display: flex; align-items: center; gap: 10px; }
|
|
.mi-art {
|
|
width: 56px;
|
|
height: 56px;
|
|
object-fit: cover;
|
|
flex: 0 0 auto;
|
|
clip-path: polygon(25% 3%, 75% 3%, 100% 50%, 75% 97%, 25% 97%, 0% 50%);
|
|
border: 1px solid var(--mi);
|
|
filter: saturate(0.9) brightness(0.95);
|
|
}
|
|
.mi-id { display: flex; align-items: baseline; gap: 8px; }
|
|
.mi-name { color: var(--mi); font-size: 19px; }
|
|
.mi-role { color: var(--dim); margin: 6px 0 2px; }
|
|
.mi-hf { display: inline-block; margin: 1px 0 2px; font-size: 12px; color: var(--proto-cyan); text-decoration: none; }
|
|
.mi-hf:hover { text-decoration: underline; }
|
|
.mi-voice {
|
|
display: block;
|
|
appearance: none;
|
|
background: none;
|
|
border: none;
|
|
padding: 2px 0;
|
|
margin: 4px 0;
|
|
text-align: left;
|
|
font: inherit;
|
|
color: var(--mi);
|
|
cursor: pointer;
|
|
text-decoration: underline dotted color-mix(in srgb, var(--mi) 60%, transparent);
|
|
}
|
|
.mi-voice:hover { text-shadow: 0 0 8px var(--mi); }
|
|
.mi-voice.mi-speaking { animation: mi-pulse 0.7s ease-in-out infinite; }
|
|
@keyframes mi-pulse { 50% { text-shadow: 0 0 12px var(--mi); } }
|
|
.mi-equiv { color: var(--head); font-style: italic; margin: 4px 0; }
|
|
.mi-spec { color: var(--fg); margin: 4px 0; }
|
|
.mi-inputs { color: var(--dim); }
|
|
.mi-use { color: var(--fg); margin-top: 4px; }
|
|
.mi-super { color: var(--link); margin-top: 6px; }
|
|
.mi-warn { margin-top: auto; padding-top: 8px; }
|
|
.mi-perm {
|
|
margin-top: 8px;
|
|
padding: 6px 8px;
|
|
border: 1px solid var(--down);
|
|
color: var(--down);
|
|
font-weight: bold;
|
|
border-radius: 4px;
|
|
}
|
|
.mi-comp {
|
|
margin-top: 8px;
|
|
padding: 6px 8px;
|
|
border: 1px solid var(--head);
|
|
color: var(--head);
|
|
background: color-mix(in srgb, var(--head) 8%, transparent);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* Bare mode strips the model component to plain prose too. */
|
|
html[data-bare="1"] .mi-card { border-color: #000; box-shadow: none; background: none; }
|
|
html[data-bare="1"] .mi-art { display: none; }
|
|
html[data-bare="1"] .mi-name { color: #000; text-shadow: none; }
|
|
html[data-bare="1"] .mi-voice { color: #000; text-decoration: underline; }
|
|
html[data-bare="1"] .mi-role, html[data-bare="1"] .mi-spec, html[data-bare="1"] .mi-use, html[data-bare="1"] .mi-comp,
|
|
html[data-bare="1"] .mi-inputs, html[data-bare="1"] .mi-equiv, html[data-bare="1"] .mi-super,
|
|
html[data-bare="1"] .mi-warn, html[data-bare="1"] .mi-hf { color: #000; }
|
|
html[data-bare="1"] .svc-warn summary, html[data-bare="1"] .mi-warn summary,
|
|
html[data-bare="1"] .warn-body { color: #000; }
|
|
html[data-bare="1"] .app-art { display: none; }
|
|
html[data-bare="1"] .svc-warn, html[data-bare="1"] .mi-perm, html[data-bare="1"] .mi-comp { color: #000; border: none; text-shadow: none; padding: 0; }
|
|
html[data-bare="1"] .mi-perm, html[data-bare="1"] .mi-comp { border: 1px solid #000; }
|
|
html[data-bare="1"] .mi-docs-link { color: #000; }
|
|
|
|
/* Protoss layer: selection + scrollbar. */
|
|
::selection { background: color-mix(in srgb, var(--proto-blue) 45%, transparent); color: #fff; }
|
|
::-webkit-scrollbar { width: 10px; }
|
|
::-webkit-scrollbar-track { background: var(--bg); }
|
|
::-webkit-scrollbar-thumb { background: var(--dim); border: 1px solid var(--border); }
|
|
::-webkit-scrollbar-thumb:hover { background: var(--fg); }
|
|
|
|
/* Headings wear the console face. */
|
|
.title, .section-title, .mi-title, .name, .mi-name, .docs h1, .docs h2 {
|
|
font-family: var(--font-head);
|
|
font-weight: 600;
|
|
}
|