docs: present AI strategy as a diagram-first story
Build and publish Eldorado documentation / build (pull_request) Successful in 40s

This commit is contained in:
jarvis-at-skic committed 2026-10-04 12:23:41 +00:00
1 parent 7f40de708c
commit 794f2aa2d6
30 files changed
+2496 -4

No files matched your search

+30 -3
View File
@@ -1,13 +1,37 @@
import React, {useEffect, useId, useRef, useState} from 'react';
import useBaseUrl from '@docusaurus/useBaseUrl';
import {useLocation} from '@docusaurus/router';
export default function ArchifyDiagram({name, title, compact = false}: {name: string; title: string; compact?: boolean}): React.ReactElement {
export default function ArchifyDiagram({name, title, compact = false, story = false}: {name: string; title: string; compact?: boolean; story?: boolean}): React.ReactElement {
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(name)) throw new Error('Invalid diagram name');
const source = useBaseUrl(`/diagrams/${name}/`);
const mobileSource = useBaseUrl(`/diagrams/${name}-mobile/`);
const dialog = useRef<HTMLDialogElement>(null);
const opener = useRef<HTMLButtonElement>(null);
const headingId = useId();
const [expanded, setExpanded] = useState(false);
const {pathname, hash} = useLocation();
useEffect(() => {
if (!story || !hash) return;
let id: string;
try {id = decodeURIComponent(hash.slice(1));} catch {return;}
const frame = requestAnimationFrame(() => {
const target = document.getElementById(id);
if (!target?.closest('.strategy-content')) return;
let detail = target.closest('details');
if (!detail) return;
while (detail) {
if (detail.dataset.collapsed === 'true') {
detail.querySelector<HTMLElement>(':scope > summary')?.click();
} else if (!detail.hasAttribute('data-collapsed')) {
detail.open = true;
}
detail = detail.parentElement?.closest('details') ?? null;
}
target.scrollIntoView();
});
return () => cancelAnimationFrame(frame);
}, [story, pathname, hash]);
useEffect(() => {
if (!expanded) return;
dialog.current?.showModal();
@@ -16,9 +40,12 @@ export default function ArchifyDiagram({name, title, compact = false}: {name: st
return () => {document.body.style.overflow = previousOverflow;};
}, [expanded]);
const close = () => {dialog.current?.close();};
return <section className={`archify-panel${compact ? ' archify-panel--compact' : ''}`} aria-label={title}>
return <section className={`archify-panel${compact ? ' archify-panel--compact' : ''}${story ? ' archify-panel--story' : ''}`} data-diagram={name} aria-label={title}>
<div className="archify-toolbar"><button ref={opener} type="button" className="archify-expand" aria-label={`Expand ${title}`} title="Expand diagram" onClick={() => setExpanded(true)}><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" aria-hidden="true"><path d="M8 3H3v5M16 3h5v5M21 16v5h-5M8 21H3v-5" /></svg></button></div>
<iframe src={source} title={title} sandbox="allow-scripts allow-downloads" loading="lazy" referrerPolicy="no-referrer" />
{story ? <>
<iframe className="story-desktop" src={`${source}?embed=1&theme=light`} title={title} sandbox="allow-scripts" loading="lazy" referrerPolicy="no-referrer" />
<iframe className="story-mobile" src={`${mobileSource}?embed=1&theme=light`} title={`${title} — narrow layout`} sandbox="allow-scripts" loading="lazy" referrerPolicy="no-referrer" />
</> : <iframe src={source} title={title} sandbox="allow-scripts allow-downloads" loading="lazy" referrerPolicy="no-referrer" />}
<dialog ref={dialog} className="archify-modal" aria-labelledby={headingId} onClose={() => {setExpanded(false); opener.current?.focus();}}>
<div className="archify-modal-toolbar"><strong id={headingId}>{title}</strong><button type="button" onClick={close} autoFocus aria-label="Close full-screen diagram"><span aria-hidden="true">×</span></button></div>
{expanded && <iframe src={source} title={`${title} — expanded`} sandbox="allow-scripts allow-downloads" referrerPolicy="no-referrer" />}
+18
View File
@@ -107,7 +107,25 @@ a:focus-visible, button:focus-visible {outline: 3px solid #b88719; outline-offse
.archify-toolbar {display: flex; justify-content: flex-end; padding: 4px; background: var(--surface);}
.archify-panel iframe {width: 100%; height: 720px; border: 0; display: block; background: #f6f6f6;}
.archify-panel--compact > iframe {height: 500px;}
.archify-panel--story {max-width: 740px;}
.archify-panel--story > iframe {height: auto; aspect-ratio: 480 / 408;}
.archify-panel--story > .story-mobile {display: none;}
.archify-panel--story[data-diagram="strategy-target"] > iframe {aspect-ratio: 480 / 628;}
.archify-panel--story[data-diagram="strategy-adoption"] > iframe {aspect-ratio: 545 / 408;}
.archify-panel--story[data-diagram="strategy-maintenance"] > iframe {aspect-ratio: 524 / 408;}
.strategy-content > details {margin: .65rem 0; border: 1px solid var(--line); padding: .8rem 1rem; background: var(--surface);}
.strategy-content summary {cursor: pointer; font-weight: 700;}
.strategy-content summary:focus-visible {outline: 3px solid #b88719; outline-offset: 4px;}
.strategy-content > details[open] > summary {margin-bottom: 1rem;}
@media (max-width: 700px) {.archify-panel iframe {height: 650px;}}
@media (max-width: 700px) {
.archify-panel--story > .story-desktop {display: none;}
.archify-panel--story > .story-mobile {display: block; height: auto; aspect-ratio: 240 / 748;}
.archify-panel--story[data-diagram="strategy-roadmap"] > .story-mobile {aspect-ratio: 240 / 628;}
.archify-panel--story[data-diagram="strategy-adoption"] > .story-mobile {aspect-ratio: 305 / 748;}
.archify-panel--story[data-diagram="strategy-maintenance"] > .story-mobile {aspect-ratio: 284 / 748;}
.archify-panel--story[data-diagram="strategy-target"] > .story-mobile {aspect-ratio: 301 / 868;}
}
.archify-expand {display: grid; place-items: center; width: 44px; height: 44px; border: 0; padding: 0; background: transparent; color: var(--ifm-link-color); cursor: pointer;}
.archify-expand:hover {background: var(--ifm-hover-overlay);}
.archify-modal {position: fixed; inset: 0; margin: 0; padding: 0; width: 100vw; height: 100dvh; max-width: none; max-height: none; border: 0; background: var(--surface); color: var(--ifm-color-content);}