feat(theme): SVOS retheme — concept-round candidate

Re-skins every Booth surface in the SVOS design system (design-systems
palettes/svos @ ed2f8d8). Visual and interaction layer only: no route,
no copy, no ordering and no information-architecture change.

- _svos_tokens.css: SVOS semantic tokens vendored by copy, with the four
  [data-theme] scopes re-scoped onto prefers-color-scheme and
  prefers-contrast (dark, light, dark-hc, light-hc). Included into
  base.html's <style>; cached at startup like every other template.
- base.html: the accreted Australis sheet is rewritten against semantic
  tokens only. It also fixes four undefined variables (--line, --bg,
  --fg, --muted) that the keep/blur/reveal controls had been reading.
  The three SVOS devices each have exactly one job: reticle = selection
  (grid cursor, :target, picked option), hazard = irreversible (Wipe
  now, armed bulk delete), glow = live power (service dot, live bench).
- The flag list renders as wrapped chips, so a large flag set no longer
  pushes the grid below the fold. The list order is unchanged.
- IBM Plex Sans + JetBrains Mono load via Google Fonts with
  display=swap and system fallbacks (approved by booth-dev).
- view.html, doc.html: inline styles moved onto tokens.
- embed.js: fragment palette as custom properties scoped to .bk-ask;
  `.bk-ask-opt:has(input:checked)` still appears exactly once.
- Favicon (base.html + app.FAVICON_HREF, kept in sync): graphite tile
  with reticle corners.

Verified: 642 passed, the same count as the pre-change baseline.
Visual order matches document order on 32 renders (4 booths x 4 widths
x 2 schemes). A positive control, one tile given `order:-1`, is
detected by the same check.
This commit is contained in:
vh
2026-09-23 08:12:54 -07:00
parent b46ac02be2
commit 744fa5263e
6 changed files with 928 additions and 552 deletions
+4 -3
View File
@@ -559,9 +559,10 @@ def _zip_filename(name: str) -> str:
# the same icon. Keep the two in sync if the Booth's icon ever changes.
FAVICON_HREF = (
"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'"
"%3E%3Crect width='32' height='32' rx='7' fill='%23171a23'/%3E%3Ccircle cx='16' "
"cy='16' r='6' fill='none' stroke='%2342dcd1' stroke-width='2.5'/%3E%3Ccircle "
"cx='16' cy='16' r='2.2' fill='%2342dcd1'/%3E%3C/svg%3E"
"%3E%3Crect width='32' height='32' rx='7' fill='%2315191d'/%3E%3Cpath d='M7 12V7h5"
"M20 7h5v5M7 20v5h5M25 20v5h-5' fill='none' stroke='%23b2cd12' stroke-width='2.5' "
"stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='16' cy='16' r='3' "
"fill='%23b2cd12'/%3E%3C/svg%3E"
)
# The seam a verbatim report declares to get the Booth's chrome. ONE line, and
+52 -36
View File
@@ -28,53 +28,69 @@
window.__boothEmbed = true;
var CSS = [
/* SVOS values, written as literals: this sheet lands in a page we did not
write, so it can lean on none of base.html's tokens. Hex equivalents of
the SVOS semantic tokens (design-systems palettes/svos @ ed2f8d8). */
/* ---- the way home, and the open-asks jump ---- */
".booth-nav-home,.booth-nav-asks{position:fixed;top:0;z-index:2147483647;",
"display:inline-block;margin:.6rem;padding:.34rem .72rem;border-radius:8px;",
"text-decoration:none;letter-spacing:.01em;box-shadow:0 2px 10px rgba(0,0,0,.35)}",
"display:inline-block;margin:.6rem;padding:.38rem .75rem;border-radius:8px;",
"text-decoration:none;letter-spacing:.01em;box-shadow:0 4px 14px rgba(0,0,0,.4)}",
/* top-right: a top-left chip clips the page title on left-aligned report
layouts, and this matches the zoom view's back affordance. */
".booth-nav-home{right:0;font:600 13px/1.25 ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;",
"color:#dfe7ef;background:rgba(20,23,32,.82);border:1px solid rgba(66,220,209,.35);",
"-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:background .18s,border-color .18s}",
".booth-nav-home:hover{background:rgba(28,33,46,.95);border-color:rgba(66,220,209,.75)}",
".booth-nav-asks{right:7.2rem;font:700 13px/1.25 ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;",
"color:#171a23;background:#ffe14e;border:1px solid #ffe14e;transition:filter .18s}",
".booth-nav-asks:hover{filter:brightness(1.08)}",
".booth-nav-home{right:0;font:600 13px/1.25 'IBM Plex Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;",
"color:#dce3e5;background:rgba(12,16,20,.86);border:1px solid rgba(255,255,255,.16);",
"-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);transition:background .12s,border-color .12s}",
".booth-nav-home:hover{background:rgba(31,35,40,.96);border-color:rgba(255,255,255,.34)}",
/* amber = needs you: the one chip that asks to be clicked */
".booth-nav-asks{right:7.4rem;font:600 13px/1.25 'IBM Plex Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;",
"color:#15191d;background:#fbc10f;border:1px solid #fbc10f;transition:filter .12s}",
".booth-nav-asks:hover{filter:brightness(1.06)}",
"@media print{.booth-nav-home,.booth-nav-asks{display:none}}",
/* ---- ask fragments. Self-contained: the host page carries its own CSS and
nothing here may inherit from it, so the palette adapts via
prefers-color-scheme rather than borrowing. ---- */
".bk-ask{margin:1.1rem 0;padding:.85rem .95rem;border:1px solid rgba(128,140,160,.34);",
"border-top:2px solid #e0b93c;border-radius:9px;background:rgba(128,140,160,.07);",
"font:15px/1.5 ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif}",
".bk-ask.bk-done{border-top-color:#3fae6a}",
".bk-ask.bk-skip{border-top-color:#6f7c8c}",
".bk-ask.bk-skip .bk-ask-tag{color:#8a97a6}",
".bk-ask-tag{display:block;margin-bottom:.5rem;font:700 10px/1 ui-monospace,SFMono-Regular,Menlo,monospace;",
"letter-spacing:.12em;text-transform:uppercase;color:#c9a227}",
".bk-ask.bk-done .bk-ask-tag{color:#3fae6a}",
".bk-ask-title{margin:0 0 .15rem;font-size:.72rem;letter-spacing:.07em;text-transform:uppercase;opacity:.62}",
nothing here may inherit from it. The palette is a set of custom
properties SCOPED TO .bk-ask, flipped by prefers-color-scheme — so each
rule below is written once and a host page cannot reach the values
without targeting our own class. Neutrals stay translucent so the
fragment sits on a light or a dark host alike. ---- */
".bk-ask{--bk-accent:#b2cd12;--bk-accent-line:rgba(178,205,18,.55);--bk-accent-soft:rgba(178,205,18,.12);",
"--bk-on-accent:#0c1014;--bk-open:#d29a02;--bk-open-text:#fbc10f;--bk-done:#71a166;--bk-done-text:#9bce90;",
"--bk-skip:#868d91;--bk-err:#fea47d}",
"@media (prefers-color-scheme: light){.bk-ask{--bk-accent:#586519;--bk-accent-line:rgba(88,101,25,.55);",
"--bk-accent-soft:rgba(88,101,25,.11);--bk-on-accent:#fff;--bk-open:#7c5500;--bk-open-text:#7c5500;",
"--bk-done:#486741;--bk-done-text:#486741;--bk-skip:#52595e;--bk-err:#a42e07}}",
".bk-ask{margin:1.1rem 0;padding:.9rem 1rem;border:1px solid rgba(128,140,160,.34);",
"border-top:2px solid var(--bk-open);border-radius:8px;background:rgba(128,140,160,.07);",
"font:15px/1.55 'IBM Plex Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif}",
".bk-ask.bk-done{border-top-color:var(--bk-done)}",
".bk-ask.bk-skip{border-top-color:var(--bk-skip)}",
".bk-ask-tag{display:inline-block;margin-bottom:.6rem;padding:2px 7px;border:1.5px solid currentColor;border-radius:3px;",
"font:600 10.5px/1.3 'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;",
"letter-spacing:.12em;text-transform:uppercase;color:var(--bk-open-text)}",
".bk-ask.bk-done .bk-ask-tag{color:var(--bk-done-text)}",
".bk-ask.bk-skip .bk-ask-tag{color:var(--bk-skip)}",
".bk-ask-title{margin:0 0 .15rem;font:500 11px/1.4 'JetBrains Mono',ui-monospace,SFMono-Regular,Menlo,monospace;",
"letter-spacing:.12em;text-transform:uppercase;opacity:.62}",
".bk-ask-prompt{margin:0 0 .6rem;font-weight:600}",
".bk-ask-opts{display:flex;flex-direction:column;gap:.3rem}",
".bk-ask-opt{display:flex;align-items:flex-start;gap:.55rem;padding:.45rem .6rem;cursor:pointer;",
"border:1px solid rgba(128,140,160,.3);border-radius:6px;background:rgba(128,140,160,.06)}",
".bk-ask-opts{display:flex;flex-direction:column;gap:.35rem}",
".bk-ask-opt{display:flex;align-items:flex-start;gap:.6rem;padding:.55rem .7rem;cursor:pointer;",
"border:1px solid rgba(128,140,160,.3);border-radius:8px;background:rgba(128,140,160,.06)}",
".bk-ask-opt:hover{border-color:rgba(128,140,160,.62)}",
".bk-ask-opt:has(input:checked){border-color:#2fa8a0;background:rgba(47,168,160,.13)}",
".bk-ask-opt input{margin:.25rem 0 0;flex:0 0 auto;accent-color:#2fa8a0}",
".bk-ask-opt:has(input:checked){border-color:var(--bk-accent-line);background:var(--bk-accent-soft)}",
".bk-ask-opt input{margin:.25rem 0 0;flex:0 0 auto;accent-color:var(--bk-accent)}",
".bk-ask-lab{display:flex;flex-direction:column;gap:.1rem;min-width:0}",
".bk-ask-det{font-size:.8rem;opacity:.68}",
".bk-ask-notes{display:block;width:100%;box-sizing:border-box;margin:.6rem 0 0;padding:.5rem .6rem;",
".bk-ask-det{font-size:.82rem;opacity:.68}",
".bk-ask-notes{display:block;width:100%;box-sizing:border-box;margin:.6rem 0 0;padding:.5rem .65rem;",
"font:inherit;font-size:.9rem;color:inherit;background:rgba(128,140,160,.09);",
"border:1px solid rgba(128,140,160,.34);border-radius:6px;resize:vertical}",
".bk-ask-go{margin-top:.7rem;cursor:pointer;font:700 12px/1 ui-monospace,SFMono-Regular,Menlo,monospace;",
"letter-spacing:.06em;padding:.6rem 1.1rem;border-radius:6px;border:1px solid #2fa8a0;",
"background:#2fa8a0;color:#08131a}",
".bk-ask-go:hover{filter:brightness(1.09)}",
".bk-ask-was{margin:.15rem 0 .55rem;font-size:.84rem;opacity:.8}",
"border:1px solid rgba(128,140,160,.34);border-radius:8px;resize:vertical}",
".bk-ask-notes:focus{outline:2px solid var(--bk-accent);outline-offset:1px}",
/* the primary — green, because submitting is what arms the answer */
".bk-ask-go{margin-top:.75rem;cursor:pointer;font:600 13px/1 'IBM Plex Sans',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;",
"padding:.7rem 1.1rem;border-radius:8px;border:1px solid var(--bk-accent);",
"background:var(--bk-accent);color:var(--bk-on-accent)}",
".bk-ask-go:hover{filter:brightness(1.06)}",
".bk-ask-was{margin:.15rem 0 .55rem;font-size:.86rem;opacity:.8}",
".bk-ask-was b{opacity:1}",
".bk-ask-err{color:#d6452a;font-size:.86rem}",
"@media (prefers-color-scheme: light){.bk-ask-tag{color:#8a6d10}.bk-ask-go{color:#fff}}",
".bk-ask-err{color:var(--bk-err);font-size:.86rem}",
"@media print{.bk-ask{break-inside:avoid}}"
].join("");
+273
View File
@@ -0,0 +1,273 @@
/* SVOS tokens — VENDORED BY COPY from design-systems
palettes/svos/colors.css + svos-theme.css @ ed2f8d8. Do not hand-edit values;
re-vendor from the source. The only transform: SVOS scopes its four themes
by [data-theme]; the Booth has no theme switch and follows the OS, so the
blocks are re-scoped onto prefers-color-scheme / prefers-contrast queries.
Semantic tokens only in the Booth layer below — never a primitive, never
a raw hex. */
:root {
--graphite-10: oklch(0.17 0.01 250);
--graphite-15: oklch(0.21 0.01 248);
--graphite-20: oklch(0.255 0.011 246);
--graphite-25: oklch(0.31 0.012 244);
--graphite-30: oklch(0.37 0.012 242);
--graphite-40: oklch(0.46 0.012 238);
--graphite-50: oklch(0.55 0.011 234);
--graphite-60: oklch(0.64 0.01 230);
--graphite-65: oklch(0.69 0.009 228);
--graphite-70: oklch(0.73 0.009 226);
--graphite-75: oklch(0.79 0.009 224);
--graphite-80: oklch(0.84 0.009 222);
--graphite-90: oklch(0.91 0.008 216);
--graphite-94: oklch(0.945 0.006 214);
--graphite-96: oklch(0.965 0.005 212);
--graphite-98: oklch(0.985 0.003 210);
--green-deep: oklch(0.48 0.1 119);
--green-base: oklch(0.66 0.15 119);
--green-bright: oklch(0.8 0.185 119);
--sage-deep: oklch(0.48 0.07 140);
--sage-base: oklch(0.66 0.1 140);
--sage-bright: oklch(0.8 0.1 140);
--amber-deep: oklch(0.48 0.1 78);
--amber-base: oklch(0.72 0.148 82);
--amber-bright: oklch(0.84 0.17 86);
--orange-deep: oklch(0.48 0.16 36);
--orange-base: oklch(0.66 0.213 38.5);
--orange-bright: oklch(0.8 0.12 44);
--intel-deep: oklch(0.48 0.09 235);
--intel-base: oklch(0.66 0.1 235);
--intel-bright: oklch(0.8 0.08 235);
--armed-green: var(--green-bright);
--hazard-orange: var(--orange-base);
--graphite-ink: var(--graphite-15);
}
/* dark — the lair default */
:root {
color-scheme: dark;
--surface-sunken: var(--graphite-10);
--surface-base: var(--graphite-15);
--surface-raised: var(--graphite-20);
--surface-overlay: oklch(0.31 0.012 244);
--surface-card: var(--graphite-20);
--surface-input: var(--graphite-10);
--surface-scrim: oklch(0.14 0.01 250 / 0.72);
--text-heading: var(--graphite-90);
--text-body: var(--graphite-75);
--text-muted: var(--graphite-70);
--text-faint: var(--graphite-60);
--text-inverse: var(--graphite-15);
--text-link: var(--intel-bright);
--text-link-hover: var(--graphite-90);
--border-subtle: var(--graphite-25);
--border-default: var(--graphite-25);
--border-strong: var(--graphite-40);
--border-focus: var(--green-bright);
--accent: var(--green-bright);
--accent-hover: oklch(0.845 0.185 119);
--accent-active: oklch(0.73 0.17 119);
--accent-text: var(--green-bright);
--accent-contrast: var(--graphite-10);
--accent-soft: color-mix(in oklab, var(--green-bright) 12%, transparent);
--accent-soft-hover: color-mix(in oklab, var(--green-bright) 20%, transparent);
--success: var(--sage-base);
--success-text: var(--sage-bright);
--success-soft: color-mix(in oklab, var(--sage-base) 14%, transparent);
--warning: var(--amber-base);
--warning-text: var(--amber-bright);
--warning-soft: color-mix(in oklab, var(--amber-base) 13%, transparent);
--danger: var(--orange-base);
--danger-hover: oklch(0.71 0.18 38.5);
--danger-text: var(--orange-bright);
--danger-contrast: var(--graphite-10);
--danger-soft: color-mix(in oklab, var(--orange-base) 14%, transparent);
--intel: var(--intel-base);
--intel-text: var(--intel-bright);
--intel-soft: color-mix(in oklab, var(--intel-base) 14%, transparent);
--selection-bg: var(--green-bright);
--selection-fg: var(--graphite-10);
}
/* art layer: voices, type, space, radii, motion, elevation, the devices */
:root {
/* voices — Plex speaks, mono records, Exan appears on the letterhead */
--font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
--font-brand: "Exan", "IBM Plex Sans", sans-serif;
/* type — 14px base, calm ladder */
--size-display: 38px; --size-h1: 25px; --size-h2: 18px; --size-h3: 15px;
--size-body: 14px; --size-sm: 13px; --size-caption: 12px;
--size-micro: 11px; --size-mono: 12.5px;
--tracking-display: -0.02em; --tracking-h: -0.01em; --tracking-caps: 0.12em;
--leading-body: 1.55; --leading-tight: 1.12;
/* spacing — 4px base, roomier than an ops console has any right to be */
--space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px;
--space-5: 20px; --space-6: 24px; --space-8: 32px; --space-12: 48px;
--space-16: 64px; --space-24: 96px;
/* radii — calm 8/12; the Bureau stamps square off at 3 */
--radius-sm: 3px; --radius-md: 6px; --radius-lg: 8px;
--radius-xl: 12px; --radius-pill: 999px;
/* motion — unhurried decel; nothing loops, nothing bounces */
--ease-out: cubic-bezier(0.16, 1, 0.3, 1);
--dur-1: 120ms; --dur-2: 200ms; --dur-3: 300ms;
/* elevation (dark default: heavier, cool) */
--shadow-sm: 0 1px 2px rgb(0 0 0 / 0.35);
--shadow-md: 0 4px 14px rgb(0 0 0 / 0.4);
--shadow-lg: 0 14px 36px rgb(0 0 0 / 0.5);
/* device 2 — the hazard stripe (irreversible actions ONLY) */
--hazard-alt: color-mix(in oklab, var(--danger) 25%, var(--surface-sunken));
--hazard-stripe: repeating-linear-gradient(-45deg,
var(--danger) 0 8px, var(--hazard-alt) 8px 16px);
/* device 3 — the armed glow (live power ONLY) */
--glow-armed: 0 0 12px color-mix(in oklab, var(--accent) 40%, transparent);
}
@media (prefers-color-scheme: light) {
:root {
color-scheme: light;
--surface-sunken: var(--graphite-94);
--surface-base: var(--graphite-96);
--surface-raised: var(--graphite-98);
--surface-overlay: #ffffff;
--surface-card: var(--graphite-98);
--surface-input: #ffffff;
--surface-scrim: oklch(0.21 0.01 248 / 0.4);
--text-heading: var(--graphite-15);
--text-body: var(--graphite-30);
--text-muted: var(--graphite-40);
--text-faint: var(--graphite-50);
--text-inverse: var(--graphite-90);
--text-link: oklch(0.455 0.097 235);
--text-link-hover: var(--graphite-15);
--border-subtle: oklch(0.89 0.006 218);
--border-default: oklch(0.85 0.008 220);
--border-strong: var(--graphite-75);
--border-focus: var(--green-deep);
--accent: var(--green-deep);
--accent-hover: oklch(0.44 0.1 119);
--accent-active: oklch(0.4 0.09 119);
--accent-text: oklch(0.44 0.1 119);
--accent-contrast: #ffffff;
--accent-soft: color-mix(in oklab, var(--green-deep) 11%, transparent);
--accent-soft-hover: color-mix(in oklab, var(--green-deep) 18%, transparent);
--success: var(--sage-deep);
--success-text: var(--sage-deep);
--success-soft: color-mix(in oklab, var(--sage-deep) 10%, transparent);
--warning: var(--amber-deep);
--warning-text: var(--amber-deep);
--warning-soft: color-mix(in oklab, var(--amber-base) 18%, transparent);
--danger: var(--orange-deep);
--danger-hover: oklch(0.44 0.15 36);
--danger-text: var(--orange-deep);
--danger-contrast: #ffffff;
--danger-soft: color-mix(in oklab, var(--orange-deep) 9%, transparent);
--intel: var(--intel-deep);
--intel-text: var(--intel-deep);
--intel-soft: color-mix(in oklab, var(--intel-deep) 9%, transparent);
--selection-bg: var(--green-deep);
--selection-fg: #ffffff;
--shadow-sm: 0 1px 2px rgb(23 31 38 / 0.07);
--shadow-md: 0 4px 14px rgb(23 31 38 / 0.1);
--shadow-lg: 0 14px 36px rgb(23 31 38 / 0.14);
--glow-armed: 0 0 10px color-mix(in oklab, var(--accent) 30%, transparent);
}
}
@media (prefers-contrast: more) {
:root {
--surface-sunken: var(--graphite-10);
--surface-base: var(--graphite-15);
--surface-raised: var(--graphite-20);
--surface-overlay: oklch(0.31 0.012 244);
--surface-card: var(--graphite-20);
--surface-input: var(--graphite-10);
--surface-scrim: oklch(0.14 0.01 250 / 0.72);
--text-heading: var(--graphite-90);
--text-body: var(--graphite-75);
--text-muted: var(--graphite-70);
--text-faint: oklch(0.7142 0.0085 230);
--text-inverse: var(--graphite-15);
--text-link: var(--intel-bright);
--text-link-hover: var(--graphite-90);
--border-subtle: var(--graphite-25);
--border-default: var(--graphite-40);
--border-strong: var(--graphite-50);
--border-focus: var(--green-bright);
--accent: var(--green-bright);
--accent-hover: oklch(0.845 0.185 119);
--accent-active: oklch(0.73 0.17 119);
--accent-text: var(--green-bright);
--accent-contrast: var(--graphite-10);
--accent-soft: color-mix(in oklab, var(--green-bright) 12%, transparent);
--accent-soft-hover: color-mix(in oklab, var(--green-bright) 20%, transparent);
--success: var(--sage-base);
--success-text: var(--sage-bright);
--success-soft: color-mix(in oklab, var(--sage-base) 14%, transparent);
--warning: var(--amber-base);
--warning-text: var(--amber-bright);
--warning-soft: color-mix(in oklab, var(--amber-base) 13%, transparent);
--danger: var(--orange-base);
--danger-hover: oklch(0.71 0.18 38.5);
--danger-text: var(--orange-bright);
--danger-contrast: var(--graphite-10);
--danger-soft: color-mix(in oklab, var(--orange-base) 14%, transparent);
--intel: var(--intel-base);
--intel-text: var(--intel-bright);
--intel-soft: color-mix(in oklab, var(--intel-base) 14%, transparent);
--selection-bg: var(--green-bright);
--selection-fg: var(--graphite-10);
}
}
@media (prefers-color-scheme: light) and (prefers-contrast: more) {
:root {
--surface-sunken: var(--graphite-94);
--surface-base: var(--graphite-96);
--surface-raised: var(--graphite-98);
--surface-overlay: #ffffff;
--surface-card: var(--graphite-98);
--surface-input: #ffffff;
--surface-scrim: oklch(0.21 0.01 248 / 0.4);
--text-heading: var(--graphite-15);
--text-body: var(--graphite-30);
--text-muted: oklch(0.4403 0.0102 238);
--text-faint: oklch(0.4403 0.00935 234);
--text-inverse: var(--graphite-90);
--text-link: oklch(0.4371 0.08245 235);
--text-link-hover: var(--graphite-15);
--border-subtle: oklch(0.89 0.006 218);
--border-default: var(--graphite-60);
--border-strong: var(--graphite-40);
--border-focus: var(--green-deep);
--accent: var(--green-deep);
--accent-hover: oklch(0.44 0.1 119);
--accent-active: oklch(0.4 0.09 119);
--accent-text: oklch(0.436 0.085 119);
--accent-contrast: #ffffff;
--accent-soft: color-mix(in oklab, var(--green-deep) 11%, transparent);
--accent-soft-hover: color-mix(in oklab, var(--green-deep) 18%, transparent);
--success: var(--sage-deep);
--success-text: oklch(0.4033 0.0595 140);
--success-soft: color-mix(in oklab, var(--sage-deep) 10%, transparent);
--warning: var(--amber-deep);
--warning-text: oklch(0.4103 0.085 78);
--warning-soft: color-mix(in oklab, var(--amber-base) 18%, transparent);
--danger: var(--orange-deep);
--danger-hover: oklch(0.44 0.15 36);
--danger-text: oklch(0.4225 0.136 36);
--danger-contrast: #ffffff;
--danger-soft: color-mix(in oklab, var(--orange-deep) 9%, transparent);
--intel: var(--intel-deep);
--intel-text: oklch(0.4373 0.0765 235);
--intel-soft: color-mix(in oklab, var(--intel-deep) 9%, transparent);
--selection-bg: var(--green-deep);
--selection-fg: #ffffff;
}
}
+583 -499
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -23,14 +23,14 @@
{% endif %}
</div>
<style>
/* .markdown-body and .textview now live in base.html (shared with the inline
/* .markdown-body and .textview live in base.html (shared with the inline
gallery view). Only the full-page layout wrapper is page-specific. */
.docview{max-width:52rem;margin:0 auto;padding:0 clamp(12px,3vw,20px) 4rem}
.docview{max-width:52rem;margin:0 auto;padding:0 clamp(12px,3vw,20px) 64px}
.docview .vbar{margin:0 calc(-1 * clamp(12px,3vw,20px)) 20px;border-radius:0}
.docview .textview{overflow-x:auto}
.doccap{margin:.9rem 0 1.2rem;padding:.6rem .85rem;font-size:.85rem;line-height:1.5;
color:var(--fg-1);background:var(--rk-surface,rgba(255,255,255,.04));
border-left:2px solid var(--aus-bright-cyan,#42dcd1);border-radius:0 6px 6px 0;
white-space:pre-wrap}
.doccap{margin:0 0 20px;padding:8px 14px;font-size:var(--size-body);line-height:var(--leading-body);
color:var(--text-body);border-left:3px solid var(--border-strong);white-space:pre-wrap}
.docmarks{display:flex;flex-direction:column;gap:8px;margin:0 0 20px}
</style>
<script>
(function () {
+10 -8
View File
@@ -47,17 +47,19 @@
</div>
<style>
.vnav{position:fixed;top:50%;transform:translateY(-50%);z-index:40;display:flex;
align-items:center;justify-content:center;width:2.6rem;height:3.4rem;font-size:2rem;
line-height:1;text-decoration:none;color:var(--fg-1);background:rgba(20,23,32,.55);
border:1px solid rgba(255,255,255,.10);border-radius:10px;margin:0 .5rem;user-select:none;
-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);transition:background .15s,border-color .15s}
.vnav:hover{background:rgba(28,33,46,.92);border-color:var(--aus-bright-cyan,#42dcd1)}
align-items:center;justify-content:center;width:40px;height:56px;font-size:28px;
line-height:1;text-decoration:none;color:oklch(0.91 0.008 216);background:oklch(0.17 0.01 250 / .6);
border:1px solid rgb(255 255 255 / .12);border-radius:var(--radius-lg);margin:0 8px;user-select:none;
-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
transition:background var(--dur-1) var(--ease-out),border-color var(--dur-1) var(--ease-out)}
.vnav:hover{background:oklch(0.21 0.01 248 / .92);border-color:rgb(255 255 255 / .3);text-decoration:none;
color:oklch(0.91 0.008 216)}
.vprev{left:0}.vnext{right:0}
/* Bottom bar rather than the top chrome: a caption can run to CAPTION_MAX
(800 chars), which would shove the filename and the Fit/1:1 toggle around. */
.vcap{flex:0 0 auto;max-height:22vh;overflow-y:auto;padding:.6rem clamp(12px,3vw,20px);
font-size:.85rem;line-height:1.5;color:var(--fg-1);background:var(--rk-surface,rgba(20,23,32,.92));
border-top:1px solid rgba(255,255,255,.10);white-space:pre-wrap}
.vcap{flex:0 0 auto;max-height:22vh;overflow-y:auto;padding:10px clamp(12px,3vw,20px);
font-size:var(--size-body);line-height:var(--leading-body);color:var(--text-body);background:var(--surface-base);
border-top:1px solid var(--border-subtle);white-space:pre-wrap}
@media print{.vcap{max-height:none;overflow:visible}}
@media print{.vnav{display:none}}
</style>