diff --git a/.cursor/rules/architecture-docs.mdc b/.cursor/rules/architecture-docs.mdc index 441e1409..0298a097 100644 --- a/.cursor/rules/architecture-docs.mdc +++ b/.cursor/rules/architecture-docs.mdc @@ -9,10 +9,10 @@ Before non-trivial code changes, read the repository architecture context: - `AGENTS.md` - `ARCHITECTURE.md` -- `docs/architecture/architecture.json` -- `docs/architecture/architecture.html` when a visual overview helps +- `docs/architecture/architecture.html` when a visual graph or traversal overview helps - Relevant files under `docs/architecture/` +- `source-research/research-index.md` and relevant source-research artifacts for architecture, dependency, public API, hook, transport, runtime-flow, build-variant, or broad code-generation work -When a change affects module boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, or build/test strategy, update the closest relevant architecture docs in the same change. Keep the Markdown, JSON, and HTML architecture maps synchronized when applicable. +When a change affects module boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, or build/test strategy, update the closest relevant architecture docs in the same change. Keep the Markdown docs and `docs/architecture/architecture.html` synchronized when applicable. Update `source-research/` when the same change affects source-derived behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims. If no architecture doc update is needed, say so explicitly in the final response or PR notes. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 38fb0282..abe1da5a 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -4,10 +4,10 @@ Before making non-trivial code changes in this repository, read: - `AGENTS.md` - `ARCHITECTURE.md` -- `docs/architecture/architecture.json` -- `docs/architecture/architecture.html` when a visual overview helps +- `docs/architecture/architecture.html` when a visual graph or traversal overview helps - Relevant files under `docs/architecture/` +- `source-research/research-index.md` and relevant source-research artifacts for architecture, dependency, public API, hook, transport, runtime-flow, build-variant, or broad code-generation work -Keep architecture documentation current with code changes. Update the closest relevant architecture file when a change affects boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, or build/test strategy. Keep the Markdown, JSON, and HTML architecture maps synchronized when applicable. +Keep architecture documentation current with code changes. Update the closest relevant architecture file when a change affects boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, or build/test strategy. Keep the Markdown docs and `docs/architecture/architecture.html` synchronized when applicable. Update `source-research/` when the same change affects source-derived behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims. If a change is implementation-only and does not require architecture doc updates, mention that explicitly in PR notes. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 383fbd1b..16a17c12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,10 +75,16 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - - name: Check embedded architecture graph data + - name: Check architecture docs do not reference removed JSON map run: | - node docs/architecture/embed-architecture-json.mjs - git diff --exit-code docs/architecture/architecture.html + architecture_json_pattern='architecture[.]''json' + embed_script_pattern='embed-architecture''-json' + for pattern in "$architecture_json_pattern" "$embed_script_pattern"; do + ! grep -R "$pattern" \ + AGENTS.md ARCHITECTURE.md CLAUDE.md GEMINI.md \ + .github/copilot-instructions.md .cursor/rules/architecture-docs.mdc \ + docs + done build_docs: runs-on: ubuntu-latest diff --git a/AGENTS.md b/AGENTS.md index fe12bb69..de55123b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,17 +5,53 @@ This repository uses living architecture documentation. Treat architecture docs Before non-trivial code changes: 1. Read `ARCHITECTURE.md`. -2. Read `docs/architecture/architecture.json` for the structured map. -3. Read `docs/architecture/architecture.html` when a visual overview helps. -4. Read any other relevant files under `docs/architecture/`. +2. Read `docs/architecture/architecture.html` when a visual graph or traversal overview helps. +3. Read any other relevant files under `docs/architecture/`. +4. Read `source-research/research-index.md` and the relevant source-research artifacts described below when the change involves architecture, inter-module dependencies, public APIs, hooks, transports, build variants, runtime flow, or broad code generation. 5. Check `README.md` and tests relevant to the behavior being changed. +After every non-trivial code change, explicitly evaluate both maintenance surfaces: + +1. Architecture docs: update `ARCHITECTURE.md` and `docs/architecture/` when the change affects system shape, flow, boundaries, dependencies, public APIs, runtime model, or testing strategy. +2. Source research: update `source-research/` when the change affects source-derived behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims. + +If either surface is not affected, say so explicitly in the final response or PR notes. + +## Source Research Artifacts + +This repository includes durable source-derived research under `source-research/`. Use these artifacts as required orientation and impact-analysis context for architecture questions, dependency analysis, public API changes, hook/transport changes, runtime-flow changes, build/test strategy changes, and broad code-generation or refactoring work. + +Start with: + +1. `source-research/research-index.md` +2. `source-research/overview.md` +3. `source-research/inventory/symbol-index.json` +4. `source-research/inventory/dependency-graph.json` +5. `source-research/inventory/claims-ledger.json` +6. Relevant node artifacts under `source-research/artifacts/` + +Use `source-research` to identify relevant symbols, callers, callees, aliases/macros, module boundaries, public surfaces, finalized claims, and known build/configuration variants. Then read the implementation source before making or asserting behavior changes. + +Source files remain authoritative. If source and `source-research` disagree, trust source and update or mark the affected research artifacts stale. If source-research prose and machine-readable JSON disagree, prefer the current JSON and repair stale prose. Use only finalized/source-backed claims as established facts; treat preliminary, stale, or inferred claims as leads to verify in source. + +When code changes affect behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims, update the relevant `source-research` artifacts in the same change. Prefer the `source-first-repo-research` SKILL tools when available: + +- Run lifecycle and evidence refreshes after artifact updates: + - `research_lifecycle.py analyze source-research --write` + - `research_lifecycle.py evidence source-research --write` + - `validate_research.py source-research` +- For finalized create-complete validation, run `validate_research.py source-research --final-response`. +- For C/C++ graph-impacting changes, rerun `cmake_ast_validate.py` against the relevant compile database, review unresolved edge candidates, and merge source-confirmed repairs with `graph_edge_upsert.py`. +- Do not edit dependency graph facts only in prose. Update canonical JSON artifacts and validate them. +- If the SKILL tools are unavailable, make the source-research update manually from source evidence and state the validation limitation in the final response or PR notes. + When you change architecture-relevant behavior: - Update the closest relevant `ARCHITECTURE.md` or `docs/architecture/*.md` file. -- Keep `docs/architecture/architecture.json` and `docs/architecture/architecture.html` synchronized with the Markdown architecture docs. +- Keep `docs/architecture/architecture.html` synchronized with the Markdown architecture docs and the current source-research evidence. - Add or update an ADR under `docs/architecture/decisions/` when the change records a durable design decision or tradeoff. +- Update `source-research/` when the same change affects source-derived behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims. - Keep docs factual and current. Remove stale statements instead of adding contradictory notes. -- If no architecture doc update is needed, mention that explicitly in your final response or PR notes. +- Apply the two-surface maintenance check above after every non-trivial code change. `note-c` is a portable C SDK. Keep platform-specific behavior behind hooks or in adapter libraries unless the public architecture intentionally changes. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 5c92ea64..9be6e6f4 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -4,8 +4,22 @@ This file is the architecture entrypoint for `note-c`. Keep it current when code Companion architecture artifacts: -- `docs/architecture/architecture.html`: human-readable visual architecture map. -- `docs/architecture/architecture.json`: structured architecture map for AI agents and tooling. +- `docs/architecture/architecture.html`: human-readable graph traversal view. +- `source-research/`: source-derived structured evidence for symbols, dependencies, claims, and build variants. + +## How To Use This File + +`ARCHITECTURE.md` is the curated architecture entrypoint. It describes the intended system shape, durable boundaries, public contracts, runtime model, portability constraints, and testing strategy that maintainers should preserve when changing `note-c`. + +For source-backed implementation evidence, use `source-research/`: + +- `source-research/research-index.md`: re-entry point and validation status. +- `source-research/overview.md`: source-derived system summary. +- `source-research/inventory/dependency-graph.json`: caller/callee and dependency graph. +- `source-research/inventory/symbol-index.json`: symbol and artifact lookup. +- `source-research/inventory/claims-ledger.json`: finalized source-backed claims. + +Use this file to understand what the architecture is meant to be. Use `source-research/` to verify how the current source implements it and to scope impact before code changes. Source remains authoritative: if implementation, `source-research/`, and architecture docs disagree, inspect the source, then update the stale architecture or research artifact in the same change. ## Purpose @@ -17,10 +31,10 @@ Companion architecture artifacts: - `note.h`: public SDK API, version constants, hook typedefs, request helpers, and compatibility surface. - `n_lib.h`: internal declarations shared across implementation files. -- `n_request.c`: request/response lifecycle, transaction orchestration, and high-level Notecard communication behavior. -- `n_serial.c`: serial transport implementation and chunked serial transmit/receive behavior. -- `n_i2c.c`: I2C transport implementation and chunked I2C transmit/receive behavior. -- `n_hooks.c`: registration and invocation of platform hooks for memory, time, mutexes, debug output, and transports. +- `n_request.c`: request/response lifecycle, transaction orchestration, retry/timeout behavior, and request ownership boundaries. +- `n_serial.c`: serial transport implementation and chunked newline-framed serial transmit/receive behavior. +- `n_i2c.c`: I2C transport implementation and chunked newline-framed I2C transmit/receive behavior. +- `n_hooks.c`: global function-pointer hook registry, active-interface dispatch, and invocation of platform hooks for memory, time, mutexes, debug output, and transports. - `n_cjson.c`, `n_cjson.h`, `n_cjson_helpers.c`: bundled JSON representation and helper APIs. - `n_helpers.c`, `n_str.c`, `n_printf.c`, `n_atof.c`, `n_ftoa.c`, `n_b64.c`, `n_cobs.c`, `n_md5.c`, `n_const.c`, `n_ua.c`: portability helpers, encoding, formatting, constants, and utility behavior. - `test/`: unit tests and mocks for protecting SDK behavior without requiring real hardware. @@ -50,7 +64,9 @@ platform driver / hardware bus Notecard ``` -Applications normally build requests as `J` objects, send them through `NoteRequest`, `NoteRequestResponse`, or higher-level helpers, then release responses through the JSON/delete APIs. Transport and platform behavior is supplied through hooks so the same core code can run on microcontrollers, embedded Linux, tests, and other C/C++ environments. +Applications normally build requests as `J` objects, send them through `NoteRequest`, `NoteRequestResponse`, retrying variants, or higher-level helpers, then release returned responses through the JSON/delete APIs. The consuming request wrappers delete the input request object after transaction; lower-level `NoteTransaction` paths leave request ownership with the caller. `NoteRequestResponseJSON` is a separate raw newline-delimited JSON string path with caller-owned request and response strings. + +Transport and platform behavior is supplied through hooks so the same core code can run on microcontrollers, embedded Linux, tests, and other C/C++ environments. Serial and I2C transports move raw newline-framed bytes through hook dispatch. Binary payload helpers, not the transport implementations, own COBS framing and MD5 verification. ## Public Contracts @@ -58,8 +74,10 @@ The main compatibility contracts are: - Public functions, typedefs, constants, and macros in `note.h`. - JSON object behavior exposed through `J` and helper functions. +- Request/response ownership semantics for public transaction APIs. - Hook signatures for serial, I2C, memory, mutex, time, and debug output. - Notecard request/response semantics and timeout/retry behavior. +- Build configuration behavior for low-memory, single-precision, user-agent, CRC, and portability-helper variants. - Version constants and release expectations documented in `README.md`. Breaking changes to these contracts require deliberate versioning, migration notes, and architecture documentation updates. @@ -68,10 +86,14 @@ Breaking changes to these contracts require deliberate versioning, migration not `note-c` is intentionally self-contained and portable. It vendors the JSON implementation and avoids mandatory platform runtime dependencies. Adapter repositories may embed or wrap this repository, including `note-arduino`, `note-zephyr`, `note-espidf`, and POSIX-focused integrations. +Build configuration is part of the portability model. CMake detects platform `strlcpy`/`strlcat` support and only includes bundled `n_str.c` helpers when needed. Low-memory builds disable user-agent support and request CRC paths, omit `n_ua.c`, use compact error/log constants, and reduce allocation chunk size. + ## Runtime Model At runtime, host code initializes the relevant hooks, constructs Notecard requests, and calls `note-c` APIs. `note-c` serializes requests, sends bytes through the selected hook-backed transport, parses responses, and returns JSON objects or status to the caller. +Hook state is global to the SDK instance. Hook registration stores caller-owned function pointers, and `_noteSetActiveInterface` selects the active serial or I2C dispatch table. Mutex hooks are optional: many hook setters/getters and transport paths use the internal lock macros when available, but not every hook accessor is lock-protected. + Unit tests use mocks to validate behavior without hardware. Hardware validation may be performed through adapter libraries or Notestation-backed workflows when bus-level or device-level behavior matters. ## Testing Strategy @@ -91,4 +113,4 @@ Update this file or `docs/architecture/` when a change affects: - Cross-repo expectations for adapter libraries. - Build, test, CI, release, or versioning strategy. -When updating architecture, keep this Markdown overview, `docs/architecture/architecture.html`, and `docs/architecture/architecture.json` consistent. +When updating architecture, keep this Markdown overview, `docs/architecture/architecture.html`, and relevant `source-research/` artifacts consistent with the source. diff --git a/CLAUDE.md b/CLAUDE.md index 2bb07514..de3defb8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,15 +1,19 @@ # Claude Instructions -This repository uses living architecture documentation. Treat these files as required context, the same way you would treat README files. +`AGENTS.md` is the canonical repository instruction file. Read it first and follow its architecture-documentation and `source-research/` requirements. Before non-trivial code changes: 1. Read `AGENTS.md` for repository operating rules. 2. Read `ARCHITECTURE.md`. -3. Read `docs/architecture/architecture.json` for the structured map. -4. Read `docs/architecture/architecture.html` when a visual overview helps. -5. Read relevant files under `docs/architecture/`. +3. Read `docs/architecture/architecture.html` when a visual graph or traversal overview helps. +4. Read relevant files under `docs/architecture/`. +5. Read `source-research/research-index.md` and the relevant source-research artifacts named in `AGENTS.md` when the task involves architecture, dependencies, public APIs, hooks, transports, runtime flow, build variants, or broad code generation. -When a change affects architecture, update the docs in the same change, including `ARCHITECTURE.md`, `docs/architecture/architecture.json`, and `docs/architecture/architecture.html` when applicable. Architecture-relevant changes include module boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, and build/test strategy. +When a change affects architecture, update the docs in the same change, including `ARCHITECTURE.md`, `docs/architecture/architecture.html`, and relevant files under `docs/architecture/` when applicable. Architecture-relevant changes include module boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, and build/test strategy. -If no architecture doc update is needed, say that explicitly in your final response or PR notes. +When a change affects source-derived behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims, update `source-research/` and validate it with the `source-first-repo-research` SKILL tools when available. + +After every non-trivial code change, explicitly evaluate both maintenance surfaces: architecture docs and `source-research/`. + +If no architecture doc or source-research update is needed, say that explicitly in your final response or PR notes. diff --git a/GEMINI.md b/GEMINI.md index bff8c1c2..b956319a 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -1,13 +1,19 @@ # Gemini Instructions -This repository uses living architecture documentation. Treat these files as required context before non-trivial code changes: +`AGENTS.md` is the canonical repository instruction file. Read it first and follow its architecture-documentation and `source-research/` requirements. + +Before non-trivial code changes, required context includes: 1. `AGENTS.md` 2. `ARCHITECTURE.md` -3. `docs/architecture/architecture.json` -4. `docs/architecture/architecture.html` when a visual overview helps -5. Relevant files under `docs/architecture/` +3. `docs/architecture/architecture.html` when a visual graph or traversal overview helps +4. Relevant files under `docs/architecture/` +5. `source-research/research-index.md` and the relevant source-research artifacts named in `AGENTS.md` when the task involves architecture, dependencies, public APIs, hooks, transports, runtime flow, build variants, or broad code generation + +When a change affects module boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, or build/test strategy, update the architecture docs in the same change, including the Markdown docs, `docs/architecture/architecture.html`, and relevant files under `docs/architecture/` when applicable. + +When a change affects source-derived behavior, dependencies, public APIs, hooks, runtime flow, build variants, or architecture claims, update `source-research/` and validate it with the `source-first-repo-research` SKILL tools when available. -When a change affects module boundaries, public APIs, hook signatures, dependencies, data/control flow, transport behavior, runtime assumptions, or build/test strategy, update the architecture docs in the same change, including the Markdown, JSON, and HTML architecture maps when applicable. +After every non-trivial code change, explicitly evaluate both maintenance surfaces: architecture docs and `source-research/`. -If no architecture doc update is needed, say so explicitly in the final response or PR notes. +If no architecture doc or source-research update is needed, say so explicitly in the final response or PR notes. diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt index e20c6eb9..576768d4 100644 --- a/docs/CMakeLists.txt +++ b/docs/CMakeLists.txt @@ -25,9 +25,6 @@ add_custom_target( COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DOCS_SRC_DIR}/architecture/architecture.html ${DOCS_BUILD_DIR}/architecture/architecture.html - COMMAND ${CMAKE_COMMAND} -E copy_if_different - ${DOCS_SRC_DIR}/architecture/architecture.json - ${DOCS_BUILD_DIR}/architecture/architecture.json USES_TERMINAL COMMENT "Running Sphinx HTML build..." ) diff --git a/docs/architecture.rst b/docs/architecture.rst index c55335e3..df0597a4 100644 --- a/docs/architecture.rst +++ b/docs/architecture.rst @@ -5,11 +5,11 @@ The note-c architecture documentation is maintained with the repository so module boundaries, public contracts, runtime flow, and update triggers stay visible as the SDK evolves. -Open the `interactive architecture map`_ for the visual graph, or inspect the -`structured architecture data`_ used to generate the map. +Open the `interactive architecture map`_ for the visual graph. For structured +source-backed dependency and claim evidence, use the repository's +``source-research/`` artifacts. .. _interactive architecture map: architecture/architecture.html -.. _structured architecture data: architecture/architecture.json For the narrative overview, see the repository-level `ARCHITECTURE.md`_ file. diff --git a/docs/architecture/README.md b/docs/architecture/README.md index fabc86c5..ddb92c52 100644 --- a/docs/architecture/README.md +++ b/docs/architecture/README.md @@ -21,10 +21,9 @@ After code changes: ## File Types - `../../ARCHITECTURE.md`: repository-level architecture entrypoint. -- `architecture.html`: single-file visual map for humans. It embeds data from `architecture.json` so it can be opened directly from disk. -- `architecture.json`: structured map for AI agents and tooling. -- `embed-architecture-json.mjs`: refreshes the embedded JSON block in `architecture.html` from `architecture.json`. -- `../architecture.rst`: Sphinx documentation page that links to the published architecture map and JSON artifact. +- `architecture.html`: single-file graph traversal view for humans and agents. It should summarize architecture at component level and point back to source-backed evidence in `../../source-research/`. +- `../../source-research/`: structured source-derived symbol, dependency, claim, and build-variant evidence for agents and tooling. +- `../architecture.rst`: Sphinx documentation page that links to the published architecture map. - `decisions/*.md`: architecture decision records. - `templates/repo-architecture.md`: template for future architecture docs. - `../../AGENTS.md`, `../../CLAUDE.md`, `../../GEMINI.md`, `../../.github/copilot-instructions.md`, and `../../.cursor/rules/architecture-docs.mdc`: AI entrypoints that point future tools back to these docs. @@ -40,13 +39,7 @@ Architecture docs should capture: - Testing strategy for behavior that crosses module boundaries. - Important tradeoffs, especially when there were plausible alternatives. -Keep `../../ARCHITECTURE.md`, `architecture.html`, and `architecture.json` synchronized when architecture changes. When changing graph data, edit `architecture.json`, then run: - -```bash -node docs/architecture/embed-architecture-json.mjs -``` - -The CI pipeline runs the same embed script and fails if `docs/architecture/architecture.html` changes afterward. Treat `architecture.json` as the hand-edited graph source and commit the refreshed HTML artifact with it. +Keep `../../ARCHITECTURE.md`, `architecture.html`, and relevant `../../source-research/` artifacts synchronized when architecture changes. Treat `source-research/` as the structured source-backed evidence layer, not a replacement for reading implementation source. When graph facts or architecture claims change, update the nearest architecture doc and the canonical source-research JSON artifacts, then run the source-research validation tools described in `../../AGENTS.md`. Architecture docs should not become: diff --git a/docs/architecture/architecture.html b/docs/architecture/architecture.html index b594e10a..8c7e1dcd 100644 --- a/docs/architecture/architecture.html +++ b/docs/architecture/architecture.html @@ -413,207 +413,689 @@ .modal-body { overflow: auto; } + body { + min-width: 0; + background: #f2f5f7; + } + .app-head { + grid-template-columns: minmax(280px, 1fr) auto; + padding: 14px 18px; + } + .app-head h1 { + font-size: 21px; + } + .meta-line { + color: var(--muted); + font-size: 12px; + margin-top: 3px; + } + .statbar { + display: grid; + grid-auto-flow: column; + gap: 8px; + } + .stat { + min-width: 82px; + padding: 7px 9px; + border: 1px solid var(--line); + border-radius: 7px; + background: var(--surface-2); + text-align: right; + } + .stat strong { + display: block; + font-size: 17px; + line-height: 1; + } + .stat span { + color: var(--muted); + font-size: 11px; + } + .graph-workbench { + display: grid; + grid-template-columns: 320px minmax(540px, 1fr) 360px; + grid-template-areas: "left graph right"; + gap: 12px; + min-height: calc(100vh - 70px); + padding: 12px; + align-items: stretch; + } + .left-rail { + grid-area: left; + min-width: 0; + display: grid; + grid-template-rows: auto 1fr; + gap: 12px; + background: transparent; + border: 0; + border-radius: 0; + overflow: visible; + } + .graph-shell { + grid-area: graph; + min-width: 0; + display: grid; + grid-template-rows: auto 1fr; + border: 1px solid var(--line); + border-radius: 8px; + background: var(--surface); + overflow: hidden; + } + .context-rail { + grid-area: right; + min-width: 0; + display: grid; + grid-template-rows: auto auto 1fr; + gap: 12px; + background: transparent; + border: 0; + border-radius: 0; + overflow: visible; + } + .panel { + border: 1px solid var(--line); + border-radius: 8px; + background: var(--surface); + overflow: hidden; + min-width: 0; + } + .panel-title { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + padding: 10px 12px; + border-bottom: 1px solid var(--line); + background: var(--surface-2); + } + .panel-title h2 { + font-size: 13px; + text-transform: uppercase; + letter-spacing: 0.04em; + color: #33424c; + } + .panel-content { + padding: 10px; + overflow: auto; + } + .control-grid { + display: grid; + gap: 9px; + } + label { + display: grid; + gap: 4px; + color: var(--muted); + font-size: 11px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.04em; + } + input, + select { + width: 100%; + min-height: 34px; + border: 1px solid var(--line); + border-radius: 7px; + background: #fff; + color: var(--ink); + font: inherit; + font-size: 13px; + padding: 6px 8px; + } + .segmented { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 4px; + } + .segmented button { + min-height: 32px; + padding: 5px 6px; + font-size: 12px; + } + .segmented button.active { + background: var(--blue); + color: #fff; + border-color: var(--blue); + } + .node-list { + display: grid; + gap: 4px; + max-height: calc(100vh - 308px); + overflow: auto; + padding: 8px; + } + .node-row, + .edge-row, + .link-row, + .hotspot-row { + width: 100%; + display: grid; + grid-template-columns: 8px 1fr auto; + gap: 8px; + align-items: center; + padding: 7px 8px; + border: 1px solid transparent; + border-radius: 7px; + background: transparent; + text-align: left; + } + .node-row:hover, + .node-row.active, + .edge-row:hover, + .link-row:hover, + .hotspot-row:hover, + .hotspot-row.active { + border-color: var(--line); + background: var(--surface-2); + } + .node-row .name, + .link-row .name, + .edge-row .name, + .hotspot-row .name { + display: block; + font-weight: 700; + font-size: 13px; + line-height: 1.2; + } + .node-row .sub, + .link-row .sub, + .edge-row .sub, + .hotspot-row .sub { + display: block; + color: var(--muted); + font-size: 11px; + line-height: 1.25; + margin-top: 2px; + } + .kind-bar { + width: 8px; + align-self: stretch; + min-height: 28px; + border-radius: 999px; + background: var(--blue); + } + .kind-bar.consumer { background: var(--violet); } + .kind-bar.contract { background: var(--red); } + .kind-bar.core { background: var(--blue); } + .kind-bar.hook { background: var(--green); } + .kind-bar.transport { background: var(--cyan); } + .kind-bar.external { background: var(--amber); } + .kind-bar.test { background: #4b5563; } + .degree { + display: inline-grid; + grid-auto-flow: column; + gap: 4px; + color: var(--muted); + font-size: 11px; + white-space: nowrap; + } + .graph-toolbar { + display: grid; + grid-template-columns: 1fr auto; + gap: 10px; + align-items: center; + padding: 9px 11px; + border-bottom: 1px solid var(--line); + background: var(--surface-2); + } + .legend-dense { + display: flex; + flex-wrap: wrap; + gap: 6px 10px; + align-items: center; + } + .legend-chip { + display: inline-flex; + align-items: center; + gap: 5px; + color: var(--muted); + font-size: 11px; + } + .graph-actions { + display: flex; + gap: 6px; + } + .graph-actions button { + min-height: 30px; + padding: 5px 8px; + font-size: 12px; + } + .graph-canvas-wrap { + min-height: 520px; + overflow: auto; + background: + linear-gradient(rgba(255,255,255,0.9), rgba(255,255,255,0.9)), + linear-gradient(90deg, rgba(203,215,223,0.44) 1px, transparent 1px), + linear-gradient(rgba(203,215,223,0.44) 1px, transparent 1px); + background-size: auto, 28px 28px, 28px 28px; + } + .graph-view { + display: block; + width: 100%; + min-width: 760px; + height: 100%; + min-height: 620px; + } + .graph-edge { + stroke: #7b8a95; + stroke-width: 1.6; + fill: none; + marker-end: url(#dense-arrow); + opacity: 0.56; + } + .graph-edge.active { + stroke: var(--blue); + stroke-width: 3; + opacity: 1; + marker-end: url(#dense-arrow-active); + } + .graph-edge.path { + stroke: var(--green); + stroke-width: 3.2; + opacity: 1; + marker-end: url(#dense-arrow-path); + } + .graph-edge.dimmed { + opacity: 0.1; + } + .edge-text { + fill: #42515c; + font-size: 10px; + paint-order: stroke; + stroke: #fff; + stroke-width: 4px; + stroke-linejoin: round; + } + .edge-text.dimmed { + opacity: 0.16; + } + .graph-node { + cursor: pointer; + } + .graph-node rect { + fill: #fff; + stroke: var(--line); + stroke-width: 1; + rx: 7; + filter: drop-shadow(0 6px 10px rgba(23, 32, 38, 0.08)); + } + .graph-node .stripe { + stroke-width: 5; + } + .graph-node text { + fill: var(--ink); + font-size: 12px; + font-weight: 700; + pointer-events: none; + } + .graph-node .node-meta { + fill: var(--muted); + font-size: 10px; + font-weight: 600; + } + .graph-node.active rect { + stroke: var(--blue); + stroke-width: 2; + } + .graph-node.focus rect { + stroke: var(--red); + stroke-width: 2.4; + } + .graph-node.path rect { + stroke: var(--green); + stroke-width: 2.4; + } + .graph-node.dimmed { + opacity: 0.24; + } + .summary-block { + display: grid; + gap: 8px; + color: var(--ink); + font-size: 13px; + } + .summary-block p { + color: var(--muted); + } + .tags { + display: flex; + flex-wrap: wrap; + gap: 5px; + } + .tag { + display: inline-flex; + align-items: center; + min-height: 22px; + padding: 3px 7px; + border: 1px solid var(--line); + border-radius: 999px; + background: var(--surface-2); + color: #24323c; + font-size: 11px; + line-height: 1.2; + } + .path-result { + min-height: 30px; + padding: 7px 8px; + border: 1px solid var(--line); + border-radius: 7px; + background: var(--surface-2); + color: var(--muted); + font-size: 12px; + } + .two-col { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + } + .edge-list, + .relation-list, + .hotspot-list { + display: grid; + gap: 4px; + } + .context-rail .panel-content { + max-height: 280px; + } + .context-rail .panel:last-child .panel-content { + max-height: calc(100vh - 540px); + min-height: 180px; + } + .empty-state { + color: var(--muted); + font-size: 12px; + padding: 6px 0; + } + @media (max-width: 1100px) { + .app-head { + grid-template-columns: 1fr; + } + .statbar { + grid-auto-flow: row; + grid-template-columns: repeat(4, minmax(80px, 1fr)); + } + .graph-workbench { + grid-template-columns: 1fr; + grid-template-areas: + "left" + "graph" + "right"; + } + .node-list, + .context-rail .panel-content, + .context-rail .panel:last-child .panel-content { + max-height: none; + } + }
-