diff --git a/.github/workflows/contributors.yml b/.github/workflows/contributors.yml new file mode 100644 index 000000000..f09b5cd10 --- /dev/null +++ b/.github/workflows/contributors.yml @@ -0,0 +1,30 @@ +name: Contributors + +on: + schedule: + # Weekly, after the Monday star-history refresh, so the two publishers do not overlap. + - cron: '15 5 * * 1' + workflow_dispatch: + +permissions: + contents: write + +concurrency: + group: contributors-svg + cancel-in-progress: true + +jobs: + update: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0 + - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + with: + node-version: 22 + - name: Render contributors wall + env: + GH_TOKEN: ${{ github.token }} + run: node scripts/generate-contributors-svg.mjs --out "$RUNNER_TEMP/contributors.svg" + - name: Publish wall with linear history + run: bash scripts/publish-contributors-svg.sh contributors "$RUNNER_TEMP/contributors.svg" diff --git a/CHANGELOG.md b/CHANGELOG.md index cfe9dafb0..34e19b759 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,16 @@ All notable changes are documented here. Format loosely follows [Keep a Changelo > Development identity: `v3.2.1-dev.1`. Not a stable release. +### Added +- **Authored node explanations in the Semantic Passport.** Architecture, Workflow, Sequence, Dataflow and Lifecycle nodes may carry optional plain-text explanations up to1200 characters. Explain opens a viewport-bounded reading face with scrollable prose and a reachable Back action; Escape restores the Passport. Prose remains outside canonical SVG and visual exports, and existing diagram geometry is preserved. +- **Cross-diagram navigation.** Nodes may list sibling `.html` targets via `drilldowns` or a one-entry `href` shorthand. One child uses a native SVG link and visible mark (click follows, Alt-click focuses). Several children keep click-to-focus, with Passport listing every target and Ctrl/double-click opening the first. Child pages can author `meta.parentHref` for header Back; the Viewer also accepts `?from=`. + ### Fixed +- **WebP brand container bounds (#602).** Reject missing or out-of-bounds image chunks, including incomplete animation frames, before reporting capture or pinned validation success. Preserve valid lossy, lossless, extended and animated containers and original-byte digests. + +- **Architecture Delta translation changes (#600).** Compare reports additions, removals and edits to `meta.translations` as presentation changes; translation-key order and empty-versus-omitted catalogs do not affect presentation classification or entity-change counts. + - **Explainer chart data (#1008, #1011).** Preserve quotes and backslashes in labels, parse quoted multiline CSV records, and normalize ordinary display whitespace without rewriting source data. Malformed records, missing values and unsupported control characters still fail before replacing an existing delivery. - Viewer toolbar arrow-key and Home/End navigation includes visible Style and Export triggers (#899). diff --git a/README.md b/README.md index 1d323e133..01403442f 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,12 @@ Works with Cursor, Claude Code, Codex CLI, and OpenCode. See installation option npx skills add tt-a1i/archify -g ``` +**With an AI agent.** Paste this: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + Send this to your agent: ```text @@ -223,15 +229,31 @@ Open [`examples/web-app.html`](examples/web-app.html) locally to try the complet npx skills add tt-a1i/archify -g ``` -
-More installation options and update-check details +**With an AI agent** + +Paste this to your agent: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + +Or install without prompts. Pass one agent, or repeat `--agent` for every switcher target (`cursor`, `codex`, `claude-code`, `opencode`, `github-copilot`). `--copy` copies the skill instead of symlinking: -For an explicit, non-interactive Cursor install: +Cursor only: ```bash npx -y skills add tt-a1i/archify --skill archify --agent cursor --global --copy --yes ``` +Or, only if you want all five agents: + +```bash +npx -y skills add tt-a1i/archify --skill archify --agent cursor --agent codex --agent claude-code --agent opencode --agent github-copilot --global --copy --yes +``` + +
+More installation options and update-check details + To try without installing: ```bash @@ -240,7 +262,7 @@ npx skills use tt-a1i/archify@archify --agent codex [DSH community opt-in](integrations/deepseek-harness/README.md): `dsh plugin --profile web add @tt-a1i/archify-dsh@1.0.0` -The [agent switcher](https://archify.si/start.html?agent=cursor&type=architecture) covers `cursor`, `codex`, `claude-code`, and `opencode`. +The [agent switcher](https://archify.si/start.html?agent=cursor&type=architecture) covers `cursor`, `codex`, `claude-code`, `opencode`, and `github-copilot`. Archify may GET the fixed stable manifest solely to show an optional reminder; it never downloads or installs updates. Successful checks wait about 24 hours (±20%); active use retries failures after 6, then 24 hours. The server sees normal HTTP metadata (IP and time), but receives no version, Agent, project data, prompts, account/device ID, or ETag. You decide whether and when to update. Set `ARCHIFY_UPDATE_CHECK_DISABLED=1` to disable networking and reminder-state writes. @@ -522,6 +544,12 @@ Scan the QR code below with Alipay, or save it and open it in Alipay to scan. Using Archify, sharing it, reporting bugs, and contributing improvements are also ways to help. +## Contributors + +Thanks to everyone who helped build Archify. [Go follow them.](https://github.com/tt-a1i/archify/graphs/contributors) ❤️ + +

Archify contributors

+ ## Star History

Star History

diff --git a/README_EN.md b/README_EN.md index 1d323e133..01403442f 100644 --- a/README_EN.md +++ b/README_EN.md @@ -64,6 +64,12 @@ Works with Cursor, Claude Code, Codex CLI, and OpenCode. See installation option npx skills add tt-a1i/archify -g ``` +**With an AI agent.** Paste this: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + Send this to your agent: ```text @@ -223,15 +229,31 @@ Open [`examples/web-app.html`](examples/web-app.html) locally to try the complet npx skills add tt-a1i/archify -g ``` -
-More installation options and update-check details +**With an AI agent** + +Paste this to your agent: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + +Or install without prompts. Pass one agent, or repeat `--agent` for every switcher target (`cursor`, `codex`, `claude-code`, `opencode`, `github-copilot`). `--copy` copies the skill instead of symlinking: -For an explicit, non-interactive Cursor install: +Cursor only: ```bash npx -y skills add tt-a1i/archify --skill archify --agent cursor --global --copy --yes ``` +Or, only if you want all five agents: + +```bash +npx -y skills add tt-a1i/archify --skill archify --agent cursor --agent codex --agent claude-code --agent opencode --agent github-copilot --global --copy --yes +``` + +
+More installation options and update-check details + To try without installing: ```bash @@ -240,7 +262,7 @@ npx skills use tt-a1i/archify@archify --agent codex [DSH community opt-in](integrations/deepseek-harness/README.md): `dsh plugin --profile web add @tt-a1i/archify-dsh@1.0.0` -The [agent switcher](https://archify.si/start.html?agent=cursor&type=architecture) covers `cursor`, `codex`, `claude-code`, and `opencode`. +The [agent switcher](https://archify.si/start.html?agent=cursor&type=architecture) covers `cursor`, `codex`, `claude-code`, `opencode`, and `github-copilot`. Archify may GET the fixed stable manifest solely to show an optional reminder; it never downloads or installs updates. Successful checks wait about 24 hours (±20%); active use retries failures after 6, then 24 hours. The server sees normal HTTP metadata (IP and time), but receives no version, Agent, project data, prompts, account/device ID, or ETag. You decide whether and when to update. Set `ARCHIFY_UPDATE_CHECK_DISABLED=1` to disable networking and reminder-state writes. @@ -522,6 +544,12 @@ Scan the QR code below with Alipay, or save it and open it in Alipay to scan. Using Archify, sharing it, reporting bugs, and contributing improvements are also ways to help. +## Contributors + +Thanks to everyone who helped build Archify. [Go follow them.](https://github.com/tt-a1i/archify/graphs/contributors) ❤️ + +

Archify contributors

+ ## Star History

Star History

diff --git a/README_JA.md b/README_JA.md index fdb72d34e..4a96e3216 100644 --- a/README_JA.md +++ b/README_JA.md @@ -62,6 +62,12 @@ Cursor、Claude Code、Codex CLI、OpenCode で利用できます。その他の npx skills add tt-a1i/archify -g ``` +**AI エージェントに任せる。** 次の文をそのまま貼り付けてください: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + エージェントにこう送ってください: ```text @@ -197,15 +203,31 @@ Export メニューから PNG をクリップボードにコピーしたり、 npx skills add tt-a1i/archify -g ``` -
-その他のインストール方法と更新チェックの詳細 +**AI エージェントに任せる** + +次の文をそのまま貼り付けてください: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + +確認なしでインストールすることもできます。`--agent` は 1 つ、または切り替え対象ごとに繰り返します(`cursor`、`codex`、`claude-code`、`opencode`、`github-copilot`)。`--copy` はシンボリックリンクではなくファイルをコピーします: -Cursor に明示的・非対話的にインストールする場合: +Cursor のみにインストールする場合: ```bash npx -y skills add tt-a1i/archify --skill archify --agent cursor --global --copy --yes ``` +または、5 つすべてのエージェントが必要な場合のみ: + +```bash +npx -y skills add tt-a1i/archify --skill archify --agent cursor --agent codex --agent claude-code --agent opencode --agent github-copilot --global --copy --yes +``` + +
+その他のインストール方法と更新チェックの詳細 + インストールせずに試す場合: ```bash @@ -214,7 +236,7 @@ npx skills use tt-a1i/archify@archify --agent codex [DSH コミュニティ版(任意)](integrations/deepseek-harness/README.md): `dsh plugin --profile web add @tt-a1i/archify-dsh@1.0.0` -[エージェント切り替え](https://archify.si/start.html?agent=cursor&type=architecture)は `cursor`、`codex`、`claude-code`、`opencode` に対応しています。 +[エージェント切り替え](https://archify.si/start.html?agent=cursor&type=architecture)は `cursor`、`codex`、`claude-code`、`opencode`、`github-copilot` に対応しています。 Archify は固定の安定版マニフェストを GET して任意の更新リマインダーを表示することがありますが、更新をダウンロードしたりインストールしたりすることはありません。チェックに成功すると次回まで約 24 時間(±20%)待機し、失敗した場合はアクティブに使用していれば 6 時間後、その後は 24 時間後に再試行します。サーバーが受け取るのは通常の HTTP メタデータ(IP と時刻)だけで、バージョン、Agent、プロジェクトデータ、プロンプト、アカウント/デバイス ID、ETag は送信されません。更新するかどうか、いつ更新するかは常にあなたが決めます。`ARCHIFY_UPDATE_CHECK_DISABLED=1` を設定すると、ネットワーク通信とリマインダー状態の書き込みを無効化できます。 @@ -486,6 +508,12 @@ Alipay で下の QR コードをスキャンするか、画像を保存して Al 利用、共有、不具合の報告、改善への貢献も、プロジェクトの支えになります。 +## コントリビューター + +Archify の開発を支えてくれたすべての人に感謝します。[フォローしてみてください。](https://github.com/tt-a1i/archify/graphs/contributors) ❤️ + +

Archify のコントリビューター

+ ## Star History

Star History

diff --git a/README_KO.md b/README_KO.md index 906375954..8f5b22be5 100644 --- a/README_KO.md +++ b/README_KO.md @@ -44,6 +44,12 @@ Cursor, Claude Code, Codex CLI, OpenCode에서 사용할 수 있습니다. npx skills add tt-a1i/archify -g ``` +**AI 에이전트에게 맡기기.** 다음 문장을 그대로 붙여 넣으세요. + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + 에이전트에게 다음과 같이 요청하세요. ```text @@ -98,15 +104,31 @@ Archify로 한 페이지로 답해 줘: API P99가 80 ms에서 600 ms로 올랐 npx skills add tt-a1i/archify -g ``` -
-다른 설치 방법과 업데이트 확인 동작 +**AI 에이전트에게 맡기기** + +다음 문장을 그대로 붙여 넣으세요. + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + +확인 없이 설치할 수도 있습니다. `--agent`는 하나, 또는 전환 대상마다 반복합니다 (`cursor`, `codex`, `claude-code`, `opencode`, `github-copilot`). `--copy`는 심볼릭 링크 대신 파일을 복사합니다. -비대화형 Cursor 설치: +Cursor에만 설치: ```bash npx -y skills add tt-a1i/archify --skill archify --agent cursor --global --copy --yes ``` +또는 다섯 에이전트가 모두 필요한 경우에만: + +```bash +npx -y skills add tt-a1i/archify --skill archify --agent cursor --agent codex --agent claude-code --agent opencode --agent github-copilot --global --copy --yes +``` + +
+다른 설치 방법과 업데이트 확인 동작 + 설치하지 않고 사용해 보기: ```bash @@ -227,6 +249,12 @@ node bin/archify.mjs validate workflow examples/agent-tool-call.workflow.json -- Issue, Pull Request, 실제 사용 사례 다이어그램을 환영합니다. [기여 가이드](CONTRIBUTING.md)에서 시작하세요. 실패는 재현 가능한 버그 양식으로 제보하고, 검증된 다이어그램은 [커뮤니티 Showcase 양식](https://github.com/tt-a1i/archify/issues/new?template=showcase.yml)으로 제출할 수 있습니다. +## 기여자 + +Archify를 함께 만들어 준 모든 분께 감사합니다. [팔로우해 보세요.](https://github.com/tt-a1i/archify/graphs/contributors) ❤️ + +

Archify 기여자

+ ## Star History

Star History

diff --git a/README_ZH.md b/README_ZH.md index a982e6f60..46643d0a7 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -64,6 +64,12 @@ https://github.com/user-attachments/assets/88cff7dd-bdf3-4b97-950c-37cc079898b1 npx skills add tt-a1i/archify -g ``` +**让 AI Agent 安装。** 把下面这句原样发给 Agent: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + 把这句话发给你的 Agent: ```text @@ -223,22 +229,38 @@ Export 菜单支持复制 PNG,并下载静态或动态格式: npx skills add tt-a1i/archify -g ``` -
-更多安装方式与更新检查说明 +**让 AI Agent 安装** + +把下面这句原样发给 Agent: + +```text +Install Archify for me by reading https://raw.githubusercontent.com/tt-a1i/archify/main/llms.txt +``` + +也可以直接非交互安装。`--agent` 写一个,或为每个切换器目标各写一次(`cursor`、`codex`、`claude-code`、`opencode`、`github-copilot`)。`--copy` 会复制 Skill,而不是创建符号链接: -显式、非交互地安装到 Cursor: +只安装到 Cursor: ```bash npx -y skills add tt-a1i/archify --skill archify --agent cursor --global --copy --yes ``` +或者,仅在需要全部五个 Agent 时运行: + +```bash +npx -y skills add tt-a1i/archify --skill archify --agent cursor --agent codex --agent claude-code --agent opencode --agent github-copilot --global --copy --yes +``` + +
+更多安装方式与更新检查说明 + 如果只想临时体验: ```bash npx skills use tt-a1i/archify@archify --agent codex ``` -DeepSeek Harness(社区集成、显式启用):运行 `dsh plugin --profile web add @tt-a1i/archify-dsh@1.0.0`;参见[兼容范围、限制与安全说明](integrations/deepseek-harness/README.md)。[Agent 切换器](https://archify.si/zh/start?agent=cursor&type=architecture)只为 `cursor`、`codex`、`claude-code` 和 `opencode` 生成命令。 +DeepSeek Harness(社区集成、显式启用):运行 `dsh plugin --profile web add @tt-a1i/archify-dsh@1.0.0`;参见[兼容范围、限制与安全说明](integrations/deepseek-harness/README.md)。[Agent 切换器](https://archify.si/zh/start?agent=cursor&type=architecture)为 `cursor`、`codex`、`claude-code`、`opencode` 和 `github-copilot` 生成命令。 安装后的 Skill 包含一个低频、失败静默的发布检查,它最多只显示可选更新提醒,绝不会自行下载或安装更新。一次成功检查后,下次网络请求通常约在 24 小时(±20%)后发出;检查失败后,活跃使用可能在首次 6 小时、后续 24 小时退避到期时重试。请求只访问 `https://archify.si/skill-updates/archify/stable.json`。服务端会自然获得 IP、请求时间和常规 HTTP 元数据;检查器不会发送本地版本、Agent、项目数据、用户输入、账户/设备标识,也不会保存或回传 ETag。是否更新以及何时更新始终由你决定。如需完全关闭检查(包括网络请求和提醒状态写入),请在 Agent 环境中设置 `ARCHIFY_UPDATE_CHECK_DISABLED=1`。 @@ -528,6 +550,12 @@ node bin/archify.mjs deliver workflow examples/agent-tool-call.workflow.json /tm 使用、分享、反馈问题和贡献改进,也都是对项目的支持。 +## 贡献者 + +感谢每一位参与构建 Archify 的人。[欢迎关注他们。](https://github.com/tt-a1i/archify/graphs/contributors) ❤️ + +

Archify 贡献者

+ ## Star History

Star History

diff --git a/archify.zip b/archify.zip index 32880a8bc..09bef9ee0 100644 Binary files a/archify.zip and b/archify.zip differ diff --git a/archify/SKILL.md b/archify/SKILL.md index 3ce4618ca..0175a177c 100644 --- a/archify/SKILL.md +++ b/archify/SKILL.md @@ -105,8 +105,21 @@ When reporting verification details, distinguish artifact checks, browser eviden ## Optional viewer capabilities +Architecture, Workflow, Sequence, Dataflow and Lifecycle nodes may carry optional plain-text `explanation` (1–1200 characters). The focused Semantic Passport offers Explain; prose stays outside canonical SVG and visual exports. Omit the field when the existing label, sublabel and sources are sufficient. + Live motion is enabled by default for every rendered diagram; omit `meta.animation`. The Viewer’s Live/Still button controls playback. +### Cross-diagram navigation + +When the user wants overview → module → detail navigation across multiple HTML artifacts: + +- Targets are same-directory `filename.html` only (optional `?` / `#`). No `../`, `/`, or schemes. +- Node `href` is sugar for a one-entry list (label defaults to the node label). `drilldowns` wins if both are present. +- One child: native SVG `` + corner mark; click follows the link; Alt-click focuses Passport. +- Several children: Passport lists every target; click focuses; Ctrl+click / double-click opens the first entry. +- Child diagrams may set `meta.parentHref`. The header Back control appears when `parentHref` or URL `?from=` is present. +- Examples: sibling pair `examples/drilldown-platform.architecture.json` ↔ `examples/drilldown-integrations.architecture.json`; multi-child `examples/drilldown-overview.architecture.json`. + Read `references/viewer-runtime.md` only when the user explicitly asks for Share Cards, Route/Reach cards, motion, deep links, presentation, search/focus, or another Viewer Runtime feature. ## Setup and fallback diff --git a/archify/assets/template.html b/archify/assets/template.html index 2c4278bfc..ffa98b3dc 100644 --- a/archify/assets/template.html +++ b/archify/assets/template.html @@ -1875,6 +1875,121 @@ .semantic-passport-meta [hidden] { display: none; } html[data-preset="blueprint"] .semantic-passport-meta span, html[data-preset="blueprint"] .semantic-passport-meta code { border-radius: 0.1rem; } + /* 跨图下钻:Passport 列出全部子图;首项即 Ctrl/双击默认目标 */ + .semantic-passport-drilldowns { + display: grid; + gap: 0.28rem; + margin-top: 0.52rem; + padding-top: 0.48rem; + border-top: 1px solid color-mix(in srgb, var(--toolbar-border) 76%, transparent); + } + .semantic-passport-drilldowns[hidden] { display: none; } + .semantic-passport-drilldowns-label { + color: var(--text-faint); + font-size: 0.5rem; + font-weight: 800; + letter-spacing: 0.1em; + text-transform: uppercase; + } + .semantic-passport-drilldowns-list { + display: grid; + gap: 0.22rem; + } + .semantic-passport-drilldown { + display: flex; + align-items: center; + justify-content: space-between; + gap: 0.5rem; + min-height: 2rem; + padding: 0.32rem 0.5rem; + border: 1px solid color-mix(in srgb, var(--toolbar-border) 86%, transparent); + border-radius: 0.35rem; + background: color-mix(in srgb, var(--panel) 70%, transparent); + color: var(--text-muted); + text-decoration: none; + font-size: 0.6875rem; + font-weight: 600; + } + .semantic-passport-drilldown:hover, + .semantic-passport-drilldown:focus-visible { + color: var(--backend-stroke); + border-color: color-mix(in srgb, var(--backend-stroke) 42%, var(--toolbar-border)); + } + .semantic-passport-drilldown:focus-visible { + outline: 2px solid color-mix(in srgb, var(--backend-stroke) 55%, transparent); + outline-offset: 1px; + } + .semantic-passport-drilldown small { + color: var(--text-faint); + font-size: 0.5625rem; + font-weight: 700; + letter-spacing: 0.04em; + text-transform: uppercase; + } + .semantic-passport-drilldowns-hint { + color: var(--text-faint); + font-size: 0.5625rem; + line-height: 1.35; + } + /* 返回上一级:放在页眉显眼位置,不进 Passport */ + .parent-back-bar { + display: flex; + align-items: center; + gap: 0.65rem; + margin: 0 0 0.85rem; + } + .parent-back-bar[hidden] { display: none !important; } + .parent-back-bar button { + display: inline-flex; + align-items: center; + gap: 0.45rem; + min-height: 2.35rem; + padding: 0.4rem 0.9rem 0.4rem 0.7rem; + border: 1px solid color-mix(in srgb, var(--backend-stroke) 48%, var(--toolbar-border)); + border-radius: 0.55rem; + background: color-mix(in srgb, var(--backend-stroke) 14%, var(--panel)); + color: var(--backend-stroke); + font-size: 0.8125rem; + font-weight: 700; + letter-spacing: 0.01em; + cursor: pointer; + box-shadow: 0 0 0 1px color-mix(in srgb, var(--backend-stroke) 12%, transparent); + } + .parent-back-bar button:hover, + .parent-back-bar button:focus-visible { + background: color-mix(in srgb, var(--backend-stroke) 22%, var(--panel)); + border-color: color-mix(in srgb, var(--backend-stroke) 68%, var(--toolbar-border)); + color: var(--text); + } + .parent-back-bar button:focus-visible { + outline: 2px solid color-mix(in srgb, var(--backend-stroke) 55%, transparent); + outline-offset: 2px; + } + .parent-back-bar button .parent-back-arrow { + font-size: 1rem; + line-height: 1; + opacity: 0.92; + } + html[data-preset="blueprint"] .parent-back-bar button { border-radius: 0.15rem; } + svg [data-node-id][data-node-drilldowns] { cursor: pointer; } + /* 单目标下钻:原生 SVG 不画下划线;角标必须跟 SVG 一起导出 */ + svg a.archify-drilldown-link { + text-decoration: none; + color: inherit; + cursor: pointer; + } + svg .archify-drilldown-mark-disc { + fill: color-mix(in srgb, var(--backend-stroke) 88%, var(--panel)); + stroke: color-mix(in srgb, var(--backend-stroke) 55%, var(--toolbar-border)); + stroke-width: 1; + } + svg .archify-drilldown-mark-arrow { + stroke: var(--panel); + stroke-width: 1.6; + stroke-linecap: round; + stroke-linejoin: round; + } + .semantic-passport-evidence { margin-top: 0.52rem; padding: 0.5rem; @@ -4631,7 +4746,7 @@ html[data-embed="true"] .relationship-pulse-overlay { display: none; } /* Intent Trace is a temporary, pre-click exploration layer. Related - topology stays readable while a short viewer-only signal runs over + topology stays readable while a viewer-only signal follows the active trace over cloned edge geometry; the authored edge remains untouched underneath. */ /* Keep the node's opaque backing mask intact while its visible ink dims. Fading the whole group also fades that mask and briefly exposes arrows @@ -4656,7 +4771,7 @@ stroke-dashoffset: 0; vector-effect: non-scaling-stroke; opacity: 0.94; - animation: archify-intent-trace-flow 1.15s linear 1 both; + animation: archify-intent-trace-flow 1.15s linear infinite; } /* Direction names describe each edge relative to the focused node only. The cloned geometry already runs from the authored source to target, so @@ -5018,9 +5133,8 @@ } @keyframes archify-intent-trace-flow { - 0% { opacity: 0.28; stroke-dashoffset: 0; } - 12%, 78% { opacity: 0.94; } - 100% { opacity: 0; stroke-dashoffset: -1; } + 0% { opacity: 0.94; stroke-dashoffset: 0; } + 100% { opacity: 0.94; stroke-dashoffset: -1; } } @keyframes archify-route-probe-flow { 0% { stroke-dashoffset: 0; opacity: 0.96; } @@ -5099,6 +5213,74 @@ } .relationship-pulse-overlay { display: none !important; } svg [data-node-id], svg [data-edge-from], svg [data-detail], svg [data-detail-anchor], svg [data-legend-hit], svg { transition: none !important; } + } + + /* Authored explanation face. It overlays the passport's own footprint so + the placement beside the focused node is untouched; the passport may + grow within the visible stage while its prose scrolls independently. */ + .focus-chip[data-explaining="true"] > :not(.semantic-passport-explanation) { visibility: hidden; } + .semantic-passport-explanation { + position: absolute; + inset: 0; + display: none; + flex-direction: column; + gap: 0.35rem; + padding: 0.7rem 0.75rem; + overflow: hidden; + scrollbar-width: thin; + color: var(--text); + } + .focus-chip[data-explaining="true"] .semantic-passport-explanation { + display: flex; + animation: passport-explanation-in 240ms cubic-bezier(0.16, 1, 0.3, 1); + } + .semantic-passport-explanation > :not(.semantic-passport-explanation-body) { flex: none; } + .semantic-passport-explanation-eyebrow { + display: block; + color: var(--reader-accent, var(--text)); + font-size: 0.5rem; + letter-spacing: 0.08em; + text-transform: uppercase; + } + .semantic-passport-explanation-title { display: block; font-size: 0.8rem; line-height: 1.35; } + .semantic-passport-explanation-body { display: grid; align-content: start; flex: 1 1 auto; min-height: 0; gap: 0.35rem; overflow: auto; overscroll-behavior: contain; scrollbar-width: thin; } + .semantic-passport-explanation-body:focus-visible { outline: 2px solid var(--reader-accent, var(--text)); outline-offset: 2px; } + .semantic-passport-explanation-body p { margin: 0; color: var(--text-muted); font-size: 0.6875rem; line-height: 1.5; overflow-wrap: anywhere; } + .semantic-passport-explanation-back { + align-self: flex-start; + margin-top: auto; + padding: 0.15rem 0; + border: 0; + background: none; + color: var(--reader-accent, var(--text)); + font: inherit; + font-size: 0.625rem; + text-decoration: underline; + cursor: pointer; + } + .semantic-passport-explanation-back:hover { color: var(--text); } + .semantic-passport-explanation-back:focus-visible { outline: 2px solid var(--frontend-stroke); outline-offset: 2px; } + @keyframes passport-explanation-in { + from { transform: rotateY(-90deg); opacity: 0; } + to { transform: rotateY(0); opacity: 1; } + } + @media (prefers-reduced-motion: reduce) { + .focus-chip[data-explaining="true"] .semantic-passport-explanation { animation: none; } + } + + /* A short mobile viewport cannot fit the Passport below the page header. + Keep its controls in the viewport without shrinking the drawing or prose. */ + @media (max-width: 720px) and (max-height: 480px) { + .focus-chip { + position: fixed; + left: 8px !important; + top: var(--passport-viewport-top, 8px) !important; + width: min(22rem, calc(100vw - 16px)); + max-width: calc(100vw - 16px); + max-height: calc(100vh - var(--passport-viewport-top, 8px) - 8px); + overflow-y: auto; + } + .focus-chip[data-explaining="true"] { overflow: hidden; } } @@ -5206,6 +5388,12 @@
+
[PROJECT NAME] Architecture

[Subtitle description]

+ @@ -5447,6 +5636,11 @@

[PROJECT NAME] Architecture

+
+