altitude-design 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -8
- package/dist/adapters/codemirror.cjs +88 -0
- package/dist/adapters/codemirror.cjs.map +7 -0
- package/dist/adapters/codemirror.js +67 -0
- package/dist/adapters/codemirror.js.map +7 -0
- package/dist/adapters/react-flow.css +102 -0
- package/dist/adapters/tiptap.css +71 -0
- package/dist/altitude.css +3165 -246
- package/dist/altitude.iife.js +33 -5
- package/dist/altitude.no-fonts.css +3165 -246
- package/dist/chart-themes.cjs +195 -0
- package/dist/chart-themes.cjs.map +7 -0
- package/dist/chart-themes.js +165 -0
- package/dist/chart-themes.js.map +7 -0
- package/dist/cli/altitude.mjs +134 -0
- package/dist/guidance/README.md +32 -0
- package/dist/guidance/agent-setup.md +22 -0
- package/dist/guidance/app-skeleton.md +17 -0
- package/dist/guidance/evidence.json +95 -0
- package/dist/guidance/index.json +493 -0
- package/dist/guidance/llms.txt +20 -0
- package/dist/guidance/manifest.json +92 -0
- package/dist/guidance/pattern.schema.json +181 -0
- package/dist/guidance/patterns/agent-action.json +77 -0
- package/dist/guidance/patterns/agent-action.md +39 -0
- package/dist/guidance/patterns/assistant-conversation.json +77 -0
- package/dist/guidance/patterns/assistant-conversation.md +50 -0
- package/dist/guidance/patterns/async-collection.json +71 -0
- package/dist/guidance/patterns/async-collection.md +29 -0
- package/dist/guidance/patterns/audit-log.json +75 -0
- package/dist/guidance/patterns/audit-log.md +27 -0
- package/dist/guidance/patterns/auth.json +86 -0
- package/dist/guidance/patterns/auth.md +29 -0
- package/dist/guidance/patterns/billing.json +80 -0
- package/dist/guidance/patterns/billing.md +29 -0
- package/dist/guidance/patterns/consequential-action.json +76 -0
- package/dist/guidance/patterns/consequential-action.md +27 -0
- package/dist/guidance/patterns/developer-settings.json +79 -0
- package/dist/guidance/patterns/developer-settings.md +29 -0
- package/dist/guidance/patterns/edit-record.json +74 -0
- package/dist/guidance/patterns/edit-record.md +51 -0
- package/dist/guidance/patterns/import.json +77 -0
- package/dist/guidance/patterns/import.md +31 -0
- package/dist/guidance/patterns/members.json +77 -0
- package/dist/guidance/patterns/members.md +27 -0
- package/dist/guidance/patterns/onboarding.json +78 -0
- package/dist/guidance/patterns/onboarding.md +31 -0
- package/dist/guidance/patterns/review-submit.json +72 -0
- package/dist/guidance/patterns/review-submit.md +27 -0
- package/dist/guidance/patterns/screen-layout.json +79 -0
- package/dist/guidance/patterns/screen-layout.md +40 -0
- package/dist/guidance/patterns/settings.json +78 -0
- package/dist/guidance/patterns/settings.md +32 -0
- package/dist/guidance/patterns/sync.json +77 -0
- package/dist/guidance/patterns/sync.md +31 -0
- package/dist/guidance/principles.md +23 -0
- package/dist/guidance/references/build/checks/agent-action-pattern.mjs +57 -0
- package/dist/guidance/references/build/checks/agent-setup.mjs +78 -0
- package/dist/guidance/references/build/checks/assistant-conversation-pattern.mjs +49 -0
- package/dist/guidance/references/build/checks/audit-log-pattern.mjs +63 -0
- package/dist/guidance/references/build/checks/auth-pattern.mjs +67 -0
- package/dist/guidance/references/build/checks/billing-pattern.mjs +63 -0
- package/dist/guidance/references/build/checks/developer-settings-pattern.mjs +76 -0
- package/dist/guidance/references/build/checks/guidance.mjs +71 -0
- package/dist/guidance/references/build/checks/import-pattern.mjs +69 -0
- package/dist/guidance/references/build/checks/members-pattern.mjs +71 -0
- package/dist/guidance/references/build/checks/onboarding-pattern.mjs +54 -0
- package/dist/guidance/references/build/checks/pattern-types.mjs +13 -0
- package/dist/guidance/references/build/checks/pattern-workflows.mjs +226 -0
- package/dist/guidance/references/build/checks/primary-scope.mjs +49 -0
- package/dist/guidance/references/build/checks/render-tells.mjs +72 -0
- package/dist/guidance/references/build/checks/screen-layout-pattern.mjs +111 -0
- package/dist/guidance/references/build/checks/semantics.mjs +72 -0
- package/dist/guidance/references/build/checks/settings-pattern.mjs +73 -0
- package/dist/guidance/references/build/checks/sync-pattern.mjs +62 -0
- package/dist/guidance/references/build/checks/tells-lint.mjs +164 -0
- package/dist/guidance/references/build/fixtures/pattern-workflows.tsx +83 -0
- package/dist/guidance/references/build/fixtures/patterns/agent-action.jsx +60 -0
- package/dist/guidance/references/build/fixtures/patterns/app-skeleton.jsx +94 -0
- package/dist/guidance/references/build/fixtures/patterns/assistant-conversation.jsx +79 -0
- package/dist/guidance/references/build/fixtures/patterns/audit-log.jsx +81 -0
- package/dist/guidance/references/build/fixtures/patterns/auth.jsx +150 -0
- package/dist/guidance/references/build/fixtures/patterns/billing.jsx +96 -0
- package/dist/guidance/references/build/fixtures/patterns/developer-settings.jsx +95 -0
- package/dist/guidance/references/build/fixtures/patterns/import.jsx +102 -0
- package/dist/guidance/references/build/fixtures/patterns/members.jsx +106 -0
- package/dist/guidance/references/build/fixtures/patterns/onboarding.jsx +70 -0
- package/dist/guidance/references/build/fixtures/patterns/screen-layout-decision.jsx +74 -0
- package/dist/guidance/references/build/fixtures/patterns/screen-layout-editor.jsx +56 -0
- package/dist/guidance/references/build/fixtures/patterns/screen-layout-report.jsx +42 -0
- package/dist/guidance/references/build/fixtures/patterns/settings.jsx +73 -0
- package/dist/guidance/references/build/fixtures/patterns/sync.jsx +78 -0
- package/dist/guidance/references/project/components/src/pattern-async-collection.tsx +57 -0
- package/dist/guidance/references/project/components/src/pattern-consequential-action.tsx +77 -0
- package/dist/guidance/references/project/components/src/pattern-edit-record.tsx +127 -0
- package/dist/guidance/references/project/components/src/pattern-review-submit.tsx +47 -0
- package/dist/guidance/references/project/components/src/settings.tsx +79 -0
- package/dist/guidance/references/scripts/build-framework-fixture.mjs +20 -0
- package/dist/guidance/rules.json +653 -0
- package/dist/guidance/visual/Elevation.md +194 -0
- package/dist/guidance/visual/Fundamentals.md +83 -0
- package/dist/guidance/visual/Research.md +1620 -0
- package/dist/index.cjs +19009 -1854
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +19009 -1854
- package/dist/index.js.map +4 -4
- package/dist/tokens.css +84 -84
- package/dist/tokens.json +301 -128
- package/dist/types/adapter-codemirror.d.ts +13 -0
- package/dist/types/agent-fleet.d.ts +166 -0
- package/dist/types/ai-label.d.ts +30 -0
- package/dist/types/app-shell.d.ts +83 -0
- package/dist/types/area-chart.d.ts +80 -0
- package/dist/types/artifact.d.ts +65 -0
- package/dist/types/bar-chart.d.ts +83 -0
- package/dist/types/bar-list.d.ts +35 -0
- package/dist/types/breadcrumb.d.ts +62 -0
- package/dist/types/chart-brush.d.ts +35 -0
- package/dist/types/chart-themes.d.ts +229 -0
- package/dist/types/chart.d.ts +570 -0
- package/dist/types/checklist.d.ts +71 -0
- package/dist/types/code-block.d.ts +32 -0
- package/dist/types/collections.d.ts +116 -5
- package/dist/types/color-picker.d.ts +38 -0
- package/dist/types/command.d.ts +6 -3
- package/dist/types/comment-thread.d.ts +48 -0
- package/dist/types/confirmation.d.ts +60 -0
- package/dist/types/context-menu.d.ts +17 -0
- package/dist/types/controls.d.ts +134 -22
- package/dist/types/conversation.d.ts +130 -0
- package/dist/types/copy-button.d.ts +19 -0
- package/dist/types/core.d.ts +139 -10
- package/dist/types/data-grid.d.ts +76 -0
- package/dist/types/date-picker.d.ts +96 -0
- package/dist/types/diff-view.d.ts +54 -0
- package/dist/types/dot-plot.d.ts +54 -0
- package/dist/types/edit-region.d.ts +121 -0
- package/dist/types/feature-gate.d.ts +22 -0
- package/dist/types/filter-bar.d.ts +65 -0
- package/dist/types/formatted-number.d.ts +38 -0
- package/dist/types/heatmap.d.ts +64 -0
- package/dist/types/in-place.d.ts +24 -0
- package/dist/types/index.d.ts +159 -14
- package/dist/types/inline-citation.d.ts +35 -0
- package/dist/types/inline-edit.d.ts +71 -0
- package/dist/types/input-otp.d.ts +37 -0
- package/dist/types/item-group.d.ts +104 -0
- package/dist/types/line-chart.d.ts +116 -0
- package/dist/types/link.d.ts +11 -0
- package/dist/types/markdown.d.ts +88 -0
- package/dist/types/meter.d.ts +43 -0
- package/dist/types/modal-state.d.ts +62 -0
- package/dist/types/nav.d.ts +8 -1
- package/dist/types/notifications.d.ts +42 -0
- package/dist/types/number-input.d.ts +30 -0
- package/dist/types/overlays.d.ts +56 -15
- package/dist/types/page-header.d.ts +27 -0
- package/dist/types/pagination.d.ts +29 -0
- package/dist/types/palette.d.ts +64 -0
- package/dist/types/password-input.d.ts +22 -0
- package/dist/types/pattern-assistant-conversation.d.ts +55 -0
- package/dist/types/pattern-async-collection.d.ts +34 -0
- package/dist/types/pattern-consequential-action.d.ts +53 -0
- package/dist/types/pattern-edit-record.d.ts +72 -0
- package/dist/types/pattern-review-submit.d.ts +43 -0
- package/dist/types/permission-matrix.d.ts +34 -0
- package/dist/types/plan-picker.d.ts +40 -0
- package/dist/types/prompt-input.d.ts +106 -0
- package/dist/types/property-list.d.ts +67 -0
- package/dist/types/question.d.ts +64 -0
- package/dist/types/relative-time.d.ts +21 -0
- package/dist/types/removal-receipt.d.ts +1180 -0
- package/dist/types/resizable.d.ts +48 -0
- package/dist/types/roving.d.ts +44 -0
- package/dist/types/save-bar.d.ts +38 -0
- package/dist/types/saved-views.d.ts +72 -0
- package/dist/types/scatter-chart.d.ts +60 -0
- package/dist/types/schedule.d.ts +80 -0
- package/dist/types/secret-field.d.ts +33 -0
- package/dist/types/select.d.ts +44 -2
- package/dist/types/separator.d.ts +11 -0
- package/dist/types/settings.d.ts +39 -0
- package/dist/types/sheet.d.ts +1 -1
- package/dist/types/sparkline.d.ts +46 -0
- package/dist/types/split-button.d.ts +21 -0
- package/dist/types/stat.d.ts +54 -0
- package/dist/types/stepper.d.ts +6 -3
- package/dist/types/suggestions.d.ts +29 -0
- package/dist/types/suspense.d.ts +85 -0
- package/dist/types/sync-indicator.d.ts +24 -0
- package/dist/types/tag-input.d.ts +65 -0
- package/dist/types/terminal.d.ts +33 -0
- package/dist/types/thread-list.d.ts +58 -0
- package/dist/types/time-input.d.ts +33 -0
- package/dist/types/timeline.d.ts +38 -0
- package/dist/types/toggle.d.ts +46 -0
- package/dist/types/toolbar.d.ts +34 -0
- package/dist/types/tour.d.ts +23 -0
- package/dist/types/trace.d.ts +65 -0
- package/dist/types/tree.d.ts +71 -0
- package/dist/types-cjs/adapter-codemirror.d.cts +13 -0
- package/dist/types-cjs/agent-fleet.d.cts +166 -0
- package/dist/types-cjs/ai-label.d.cts +30 -0
- package/dist/types-cjs/app-shell.d.cts +83 -0
- package/dist/types-cjs/area-chart.d.cts +80 -0
- package/dist/types-cjs/artifact.d.cts +65 -0
- package/dist/types-cjs/bar-chart.d.cts +83 -0
- package/dist/types-cjs/bar-list.d.cts +35 -0
- package/dist/types-cjs/breadcrumb.d.cts +62 -0
- package/dist/types-cjs/chart-brush.d.cts +35 -0
- package/dist/types-cjs/chart-themes.d.cts +229 -0
- package/dist/types-cjs/chart.d.cts +570 -0
- package/dist/types-cjs/checklist.d.cts +71 -0
- package/dist/types-cjs/code-block.d.cts +32 -0
- package/dist/types-cjs/collections.d.cts +246 -0
- package/dist/types-cjs/color-picker.d.cts +38 -0
- package/dist/types-cjs/command.d.cts +66 -0
- package/dist/types-cjs/comment-thread.d.cts +48 -0
- package/dist/types-cjs/confirmation.d.cts +60 -0
- package/dist/types-cjs/context-menu.d.cts +17 -0
- package/dist/types-cjs/controls.d.cts +360 -0
- package/dist/types-cjs/conversation.d.cts +130 -0
- package/dist/types-cjs/copy-button.d.cts +19 -0
- package/dist/types-cjs/core.d.cts +256 -0
- package/dist/types-cjs/data-grid.d.cts +76 -0
- package/dist/types-cjs/date-picker.d.cts +96 -0
- package/dist/types-cjs/diff-view.d.cts +54 -0
- package/dist/types-cjs/dot-plot.d.cts +54 -0
- package/dist/types-cjs/edit-region.d.cts +121 -0
- package/dist/types-cjs/empty.d.cts +24 -0
- package/dist/types-cjs/feature-gate.d.cts +22 -0
- package/dist/types-cjs/filter-bar.d.cts +65 -0
- package/dist/types-cjs/formatted-number.d.cts +38 -0
- package/dist/types-cjs/heatmap.d.cts +64 -0
- package/dist/types-cjs/in-place.d.cts +24 -0
- package/dist/types-cjs/index.d.cts +154 -0
- package/dist/types-cjs/inline-citation.d.cts +35 -0
- package/dist/types-cjs/inline-edit.d.cts +71 -0
- package/dist/types-cjs/input-otp.d.cts +37 -0
- package/dist/types-cjs/item-group.d.cts +104 -0
- package/dist/types-cjs/line-chart.d.cts +116 -0
- package/dist/types-cjs/link.d.cts +11 -0
- package/dist/types-cjs/markdown.d.cts +88 -0
- package/dist/types-cjs/meter.d.cts +43 -0
- package/dist/types-cjs/modal-state.d.cts +62 -0
- package/dist/types-cjs/nav.d.cts +25 -0
- package/dist/types-cjs/notifications.d.cts +42 -0
- package/dist/types-cjs/number-input.d.cts +30 -0
- package/dist/types-cjs/overlays.d.cts +170 -0
- package/dist/types-cjs/page-header.d.cts +27 -0
- package/dist/types-cjs/pagination.d.cts +29 -0
- package/dist/types-cjs/palette.d.cts +64 -0
- package/dist/types-cjs/password-input.d.cts +22 -0
- package/dist/types-cjs/pattern-assistant-conversation.d.cts +55 -0
- package/dist/types-cjs/pattern-async-collection.d.cts +34 -0
- package/dist/types-cjs/pattern-consequential-action.d.cts +53 -0
- package/dist/types-cjs/pattern-edit-record.d.cts +72 -0
- package/dist/types-cjs/pattern-review-submit.d.cts +43 -0
- package/dist/types-cjs/permission-matrix.d.cts +34 -0
- package/dist/types-cjs/pile.d.cts +27 -0
- package/dist/types-cjs/plan-picker.d.cts +40 -0
- package/dist/types-cjs/prompt-input.d.cts +106 -0
- package/dist/types-cjs/property-list.d.cts +67 -0
- package/dist/types-cjs/question.d.cts +64 -0
- package/dist/types-cjs/relative-time.d.cts +21 -0
- package/dist/types-cjs/removal-receipt.d.cts +1180 -0
- package/dist/types-cjs/resizable.d.cts +48 -0
- package/dist/types-cjs/roving.d.cts +44 -0
- package/dist/types-cjs/save-bar.d.cts +38 -0
- package/dist/types-cjs/saved-views.d.cts +72 -0
- package/dist/types-cjs/scatter-chart.d.cts +60 -0
- package/dist/types-cjs/schedule.d.cts +80 -0
- package/dist/types-cjs/secret-field.d.cts +33 -0
- package/dist/types-cjs/select.d.cts +109 -0
- package/dist/types-cjs/separator.d.cts +11 -0
- package/dist/types-cjs/settings.d.cts +39 -0
- package/dist/types-cjs/sheet.d.cts +27 -0
- package/dist/types-cjs/sparkline.d.cts +46 -0
- package/dist/types-cjs/split-button.d.cts +21 -0
- package/dist/types-cjs/stat.d.cts +54 -0
- package/dist/types-cjs/stepper.d.cts +26 -0
- package/dist/types-cjs/suggestions.d.cts +29 -0
- package/dist/types-cjs/suspense.d.cts +85 -0
- package/dist/types-cjs/sync-indicator.d.cts +24 -0
- package/dist/types-cjs/tag-input.d.cts +65 -0
- package/dist/types-cjs/terminal.d.cts +33 -0
- package/dist/types-cjs/thread-list.d.cts +58 -0
- package/dist/types-cjs/time-input.d.cts +33 -0
- package/dist/types-cjs/timeline.d.cts +38 -0
- package/dist/types-cjs/toggle.d.cts +46 -0
- package/dist/types-cjs/toolbar.d.cts +34 -0
- package/dist/types-cjs/tour.d.cts +23 -0
- package/dist/types-cjs/trace.d.cts +65 -0
- package/dist/types-cjs/tree.d.cts +71 -0
- package/package.json +90 -9
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# Altitude
|
|
2
2
|
|
|
3
|
-
A React component
|
|
3
|
+
A design and HCI framework for agent-built React web applications, with a component foundation where **height is the interface**. Its one idea: the ground is the record. Settled content sits on the ground; anything live rises above it; anything waiting to receive sinks below it.
|
|
4
4
|
|
|
5
|
-
- **
|
|
6
|
-
- **
|
|
5
|
+
- **Site:** https://richlaconte.github.io/altitude/
|
|
6
|
+
- **Storybook:** every component, with its guidelines and a live preview in both schemes: https://richlaconte.github.io/altitude/storybook/
|
|
7
|
+
- **The design guide:** [`project/README.md`](https://github.com/richlaconte/altitude/blob/main/project/README.md), then [Elevation](https://github.com/richlaconte/altitude/blob/main/project/Elevation.md), [Motion](https://github.com/richlaconte/altitude/blob/main/project/Motion.md), [Charts](https://github.com/richlaconte/altitude/blob/main/project/Charts.md), [Theming](https://github.com/richlaconte/altitude/blob/main/project/Theming.md), [Fundamentals](https://github.com/richlaconte/altitude/blob/main/project/Fundamentals.md), [Distinctiveness](https://github.com/richlaconte/altitude/blob/main/project/Distinctiveness.md) and [Research](https://github.com/richlaconte/altitude/blob/main/project/Research.md)
|
|
7
8
|
|
|
8
9
|
## Install
|
|
9
10
|
|
|
@@ -27,7 +28,7 @@ export function App() {
|
|
|
27
28
|
}
|
|
28
29
|
```
|
|
29
30
|
|
|
30
|
-
Render `AltitudeProvider` once around your app. Schemes are `daylight
|
|
31
|
+
Render `AltitudeProvider` once around your app. Schemes are `daylight` and `nightfall`; `accent="#0f8a6b"` swaps in your own colour. The components are client components (`"use client"`), so they work in frameworks with server components.
|
|
31
32
|
|
|
32
33
|
| Import | What it is |
|
|
33
34
|
|---|---|
|
|
@@ -44,17 +45,31 @@ Render `AltitudeProvider` once around your app. Schemes are `daylight`, `nightfa
|
|
|
44
45
|
project/ the design system itself: guides, tokens.json, components/src/*.tsx, bundle.css,
|
|
45
46
|
and the built bundle.js and previews (the same files as the design system on claude.ai)
|
|
46
47
|
build/ the kit that builds and checks project/ (see build/SETUP.md)
|
|
47
|
-
scripts/ the npm package build
|
|
48
|
+
scripts/ the npm package build, the Storybook story generator and the landing page build
|
|
49
|
+
site/ the landing page (React, built from the components' own sources into site-dist/)
|
|
48
50
|
.storybook/
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
There is one source for each thing. Components live in `project/components/src`, styles in `project/components/bundle.css`, tokens in `project/tokens.json`, and each component's preview in `build/previews.txt`. The npm package, the Storybook stories and the design system's own previews are all generated from those.
|
|
52
54
|
|
|
55
|
+
## Actions in place
|
|
56
|
+
|
|
57
|
+
[Actions in place](project/ActionsInPlace.md) covers single-value editing with `InlineEdit`, direct actions with real recovery, and targeted confirmation with `Dialog background="stationary"`.
|
|
58
|
+
|
|
59
|
+
After `npm run storybook`, open the generated examples:
|
|
60
|
+
|
|
61
|
+
- [Inline editing and its comparison baseline](http://localhost:6006/?path=/story/inputs-inlineedit--preview).
|
|
62
|
+
- [Default and stationary dialog presentation](http://localhost:6006/?path=/story/overlays-dialog--preview).
|
|
63
|
+
- [Act and recover](http://localhost:6006/?path=/story/patterns-actionsinplace--preview). “Open complete Files example” selects the same example's `#files` view.
|
|
64
|
+
|
|
65
|
+
The [validation record](project/ActionsInPlaceValidation.md) separates engineering checks from outstanding human evaluation.
|
|
66
|
+
|
|
53
67
|
## Working on it
|
|
54
68
|
|
|
55
69
|
```sh
|
|
56
70
|
npm install && npm install --prefix build
|
|
57
71
|
npm run storybook # http://localhost:6006
|
|
72
|
+
npm run build-site # the landing page, into site-dist/index.html
|
|
58
73
|
```
|
|
59
74
|
|
|
60
75
|
After changing a component, rebuild the design system's bundle and previews, and commit what they produce:
|
|
@@ -67,16 +82,16 @@ CI fails if `project/` doesn't match its sources, so the design system on claude
|
|
|
67
82
|
|
|
68
83
|
## What happens on push
|
|
69
84
|
|
|
70
|
-
Every push and pull request runs the checks: the bundle and previews are rebuilt and must match what's committed, every preview is rendered in
|
|
85
|
+
Every push and pull request runs the checks: the bundle and previews are rebuilt and must match what's committed, every preview is rendered in both schemes with no errors, the interaction checks run, the sources type-check against React 19, and the package and Storybook are built.
|
|
71
86
|
|
|
72
87
|
A push to `main` then also:
|
|
73
88
|
|
|
74
|
-
- deploys
|
|
89
|
+
- deploys the landing page to GitHub Pages, with Storybook under `/storybook/`;
|
|
75
90
|
- publishes to npm **if the version in `package.json` isn't published yet**, and tags the commit `v<version>`. To release, bump the version (`npm version patch`, `minor` or `major`) and push.
|
|
76
91
|
|
|
77
92
|
## Found a bug, or need something it doesn't do?
|
|
78
93
|
|
|
79
|
-
Open an issue: **https://github.com/richlaconte/altitude/issues/new/choose**. There are templates for a bug, a new feature for an existing component, and a new component, and [CONTRIBUTING.md](https://github.com/richlaconte/altitude/blob/main/CONTRIBUTING.md) says what makes each one useful.
|
|
94
|
+
Open an issue: **https://github.com/richlaconte/altitude/issues/new/choose**. There are templates for a bug, a new feature for an existing component, and a new component, and [CONTRIBUTING.md](https://github.com/richlaconte/altitude/blob/main/CONTRIBUTING.md) says what makes each one useful, and how work is organised (milestones, priorities, the `ready` label and claiming an issue with a draft pull request).
|
|
80
95
|
|
|
81
96
|
**If you're an agent using this package** in someone else's project, you're welcome to report problems with it here:
|
|
82
97
|
|
|
@@ -90,3 +105,26 @@ The full guidance for agents is in [AGENTS.md](https://github.com/richlaconte/al
|
|
|
90
105
|
## License
|
|
91
106
|
|
|
92
107
|
[MIT](https://github.com/richlaconte/altitude/blob/main/LICENSE)
|
|
108
|
+
|
|
109
|
+
## Design and HCI framework
|
|
110
|
+
|
|
111
|
+
Altitude now joins its component library with task guidance and small workflow APIs for forms, data and processes. The four initial patterns are **edit record**, **async collection**, **consequential action**, and **review and submit**. They are experimental: engineering fixtures cover their contracts; user-effectiveness studies remain outstanding.
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
npm install altitude-design
|
|
115
|
+
npx altitude patterns "edit settings"
|
|
116
|
+
npx altitude init --client codex # preview exact changes
|
|
117
|
+
npx altitude init --client codex --apply # apply after reviewing the preview
|
|
118
|
+
# Claude Code: --client claude. Both: --client all.
|
|
119
|
+
npx altitude doctor --json
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Setup preserves existing instructions and adds a small versioned pointer to the installed guidance. It never runs on package installation. Preview removal with `npx altitude init --client codex --remove`, then add `--apply` to remove only its managed content. Edited blocks are preserved and require reconciliation. Codex uses a nonempty root `AGENTS.override.md` when present; otherwise `AGENTS.md`. Claude Code uses `CLAUDE.md`. Restart the client after setup. See [setup details](docs/framework/AGENT-SETUP.md).
|
|
123
|
+
|
|
124
|
+
The compact entry is `node_modules/altitude-design/dist/guidance/README.md`; the public `altitude-design/guidance` export resolves its versioned JSON index, and `altitude-design/guidance/*` exposes focused resources. `altitude explain ALT-EDIT-001` explains a rule, its scope, evidence and verification. Guidance is local and version matched; no hosted service or MCP connection is required.
|
|
125
|
+
|
|
126
|
+
Import `useEditRecord`, `ErrorSummary`, `WorkflowStatus`, `useAsyncCollection`, `useConsequentialAction` and `useReviewSubmit` from the existing `altitude-design` entry. They share the existing provider/context. [Task contracts and examples](project/framework/README.md) explain application adapters and the corresponding [interactive previews](https://richlaconte.github.io/altitude/storybook/?path=/story/patterns-editrecord--preview).
|
|
127
|
+
|
|
128
|
+
Framework behavior protects drafts, coordinates applicable states, guards duplicate dispatch and stale responses, and supports accessible error navigation and status feedback. Applications still supply truthful persistence, permissions, business rules, query/history policy, durable recovery and actual undo. `doctor` diagnoses installation and setup; it does not certify accessibility or usability. [Manual review](docs/framework/MANUAL-VALIDATION.md), [migration notes](docs/framework/RELEASE-NOTES.md) and the [evaluation protocol](evals/framework/README.md) state the remaining work.
|
|
129
|
+
|
|
130
|
+
Run `npm run build && npm run check:framework` for deterministic semantics, workflow, guidance and packed-package consumer checks. Run agent comparisons separately using the evaluation harness; stochastic model behavior does not gate ordinary CI.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// project/components/src/adapter-codemirror.tsx
|
|
21
|
+
var adapter_codemirror_exports = {};
|
|
22
|
+
__export(adapter_codemirror_exports, {
|
|
23
|
+
altitudeEditorTheme: () => altitudeEditorTheme,
|
|
24
|
+
altitudeHighlightStyle: () => altitudeHighlightStyle,
|
|
25
|
+
altitudeTheme: () => altitudeTheme
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(adapter_codemirror_exports);
|
|
28
|
+
var import_view = require("@codemirror/view");
|
|
29
|
+
var import_language = require("@codemirror/language");
|
|
30
|
+
var import_highlight = require("@lezer/highlight");
|
|
31
|
+
var wall = "inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)";
|
|
32
|
+
var altitudeEditorTheme = import_view.EditorView.theme({
|
|
33
|
+
"&": {
|
|
34
|
+
color: "var(--ink)",
|
|
35
|
+
backgroundColor: "var(--surface-well)",
|
|
36
|
+
border: "1px solid var(--line-control)",
|
|
37
|
+
borderRadius: "var(--radius-md)",
|
|
38
|
+
boxShadow: wall,
|
|
39
|
+
outline: "1px solid transparent"
|
|
40
|
+
},
|
|
41
|
+
"&:hover": { borderColor: "var(--ink-muted)" },
|
|
42
|
+
"&.cm-focused": { outline: "1px solid transparent", backgroundColor: "var(--surface-raised)" },
|
|
43
|
+
"&:has(.cm-content:focus-visible)": { borderColor: "var(--alt-rim-held)", outlineColor: "var(--alt-rim-held)" },
|
|
44
|
+
".cm-scroller": { fontFamily: "var(--font-mono)", fontSize: "13px", lineHeight: "20px", paddingTop: "4px" },
|
|
45
|
+
".cm-content": { caretColor: "var(--ink)", padding: "var(--space-2) 0" },
|
|
46
|
+
".cm-line": { padding: "0 var(--space-3)" },
|
|
47
|
+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--ink)", borderLeftWidth: "2px" },
|
|
48
|
+
".cm-gutters": { backgroundColor: "transparent", color: "var(--ink-muted)", border: "none", borderRight: "1px solid var(--line)" },
|
|
49
|
+
".cm-lineNumbers .cm-gutterElement": { padding: "0 var(--space-2) 0 var(--space-3)" },
|
|
50
|
+
".cm-activeLine": { backgroundColor: "color-mix(in oklab, var(--accent-soft) 60%, transparent)" },
|
|
51
|
+
".cm-activeLineGutter": { backgroundColor: "transparent", color: "var(--ink)" },
|
|
52
|
+
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": { backgroundColor: "color-mix(in oklab, var(--accent-ink) 24%, transparent)" },
|
|
53
|
+
".cm-matchingBracket, &.cm-focused .cm-matchingBracket": { backgroundColor: "transparent", outline: "1px solid var(--accent-ink)", borderRadius: "2px" },
|
|
54
|
+
".cm-searchMatch": { backgroundColor: "color-mix(in oklab, var(--caution) 22%, transparent)", outline: "1px solid var(--caution)" },
|
|
55
|
+
".cm-placeholder": { color: "var(--ink-muted)" },
|
|
56
|
+
".cm-lintRange-error": { backgroundImage: "none", textDecoration: "underline wavy var(--critical)", textUnderlineOffset: "3px" },
|
|
57
|
+
".cm-lintRange-warning": { backgroundImage: "none", textDecoration: "underline wavy var(--caution)", textUnderlineOffset: "3px" },
|
|
58
|
+
".cm-lint-marker": { width: "12px", height: "12px", borderRadius: "3px", backgroundImage: "none !important" },
|
|
59
|
+
".cm-lint-marker-error": { backgroundColor: "var(--critical-soft)", boxShadow: "var(--trench), inset 0 0 0 1px var(--critical)" },
|
|
60
|
+
".cm-lint-marker-warning": { backgroundColor: "var(--caution-soft)", boxShadow: "inset 0 0 0 1px var(--caution)" },
|
|
61
|
+
".cm-diagnostic": { padding: "var(--space-1) var(--space-3)", font: "500 13px/18px var(--font-sans)", color: "var(--ink)" },
|
|
62
|
+
".cm-diagnostic-error": { borderLeft: "3px solid var(--critical)" },
|
|
63
|
+
".cm-diagnostic-warning": { borderLeft: "3px solid var(--caution)" },
|
|
64
|
+
".cm-tooltip": { border: "none", borderRadius: "var(--radius-md)", backgroundColor: "var(--surface-floating)", color: "var(--ink)", boxShadow: "var(--elev-3)", overflow: "hidden" },
|
|
65
|
+
".cm-tooltip-autocomplete > ul": { fontFamily: "var(--font-mono)", fontSize: "13px" },
|
|
66
|
+
".cm-tooltip-autocomplete > ul > li": { padding: "4px var(--space-2)" },
|
|
67
|
+
".cm-tooltip-autocomplete > ul > li[aria-selected]": { backgroundColor: "var(--accent-soft)", color: "var(--ink)" },
|
|
68
|
+
".cm-panels": { backgroundColor: "var(--surface-ground)", color: "var(--ink)" },
|
|
69
|
+
".cm-panels.cm-panels-bottom": { borderTop: "1px solid var(--line)" },
|
|
70
|
+
".cm-panels.cm-panels-top": { borderBottom: "1px solid var(--line)" },
|
|
71
|
+
".cm-foldPlaceholder": { backgroundColor: "var(--surface-raised)", border: "1px solid var(--line)", color: "var(--ink-muted)" },
|
|
72
|
+
// Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.
|
|
73
|
+
"@media (forced-colors: active)": { ".cm-lint-marker-error": { border: "2px dashed CanvasText" }, ".cm-tooltip": { border: "1px solid CanvasText" } }
|
|
74
|
+
});
|
|
75
|
+
var altitudeHighlightStyle = import_language.HighlightStyle.define([
|
|
76
|
+
{ tag: [import_highlight.tags.keyword, import_highlight.tags.operatorKeyword, import_highlight.tags.modifier, import_highlight.tags.controlKeyword], color: "var(--accent-ink)", fontWeight: "600" },
|
|
77
|
+
{ tag: [import_highlight.tags.number, import_highlight.tags.bool, import_highlight.tags.null, import_highlight.tags.atom], color: "var(--accent-ink)" },
|
|
78
|
+
{ tag: [import_highlight.tags.string, import_highlight.tags.special(import_highlight.tags.string), import_highlight.tags.regexp], color: "var(--ink)" },
|
|
79
|
+
{ tag: [import_highlight.tags.propertyName, import_highlight.tags.attributeName, import_highlight.tags.definition(import_highlight.tags.variableName), import_highlight.tags.function(import_highlight.tags.variableName)], color: "var(--ink)", fontWeight: "550" },
|
|
80
|
+
{ tag: [import_highlight.tags.comment, import_highlight.tags.lineComment, import_highlight.tags.blockComment, import_highlight.tags.docComment], color: "var(--ink-muted)", fontStyle: "italic" },
|
|
81
|
+
{ tag: [import_highlight.tags.punctuation, import_highlight.tags.bracket, import_highlight.tags.separator, import_highlight.tags.operator], color: "var(--ink-muted)" },
|
|
82
|
+
{ tag: [import_highlight.tags.typeName, import_highlight.tags.className, import_highlight.tags.tagName], color: "var(--accent-ink)" },
|
|
83
|
+
{ tag: import_highlight.tags.invalid, color: "var(--critical)" }
|
|
84
|
+
]);
|
|
85
|
+
function altitudeTheme() {
|
|
86
|
+
return [altitudeEditorTheme, (0, import_language.syntaxHighlighting)(altitudeHighlightStyle)];
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=codemirror.cjs.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../project/components/src/adapter-codemirror.tsx"],
|
|
4
|
+
"sourcesContent": ["import { EditorView } from '@codemirror/view';\nimport { HighlightStyle, syntaxHighlighting } from '@codemirror/language';\nimport { tags as t } from '@lezer/highlight';\nimport type { Extension } from '@codemirror/state';\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 CodeMirror adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/*\n * altitude-design/adapters/codemirror: Altitude readings for a CodeMirror 6 editor. Every value is one of the scheme's\n * custom properties, so the editor follows the active scheme, a custom accent and contrast=\"more\" without re-creating\n * it. It imports only CodeMirror (@codemirror/view, @codemirror/language, @lezer/highlight), which your app installs.\n */\nconst wall = 'inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)';\n\n/**\n * The editor is an opening: a well with its inside wall, the floor lit while focused and a 2px neutral rim for keyboard\n * focus. Gutter and lines are ground; the active line is a tint, never a height; the selection is accent. Lint errors\n * sink their gutter marker into a trench on critical-soft and say the problem in words. Tooltips and completion lists\n * float at level 3.\n */\nexport const altitudeEditorTheme: Extension = EditorView.theme({\n '&': { color: 'var(--ink)', backgroundColor: 'var(--surface-well)', border: '1px solid var(--line-control)', borderRadius: 'var(--radius-md)',\n boxShadow: wall, outline: '1px solid transparent' },\n '&:hover': { borderColor: 'var(--ink-muted)' },\n '&.cm-focused': { outline: '1px solid transparent', backgroundColor: 'var(--surface-raised)' },\n '&:has(.cm-content:focus-visible)': { borderColor: 'var(--alt-rim-held)', outlineColor: 'var(--alt-rim-held)' },\n '.cm-scroller': { fontFamily: 'var(--font-mono)', fontSize: '13px', lineHeight: '20px', paddingTop: '4px' },\n '.cm-content': { caretColor: 'var(--ink)', padding: 'var(--space-2) 0' },\n '.cm-line': { padding: '0 var(--space-3)' },\n '.cm-cursor, .cm-dropCursor': { borderLeftColor: 'var(--ink)', borderLeftWidth: '2px' },\n '.cm-gutters': { backgroundColor: 'transparent', color: 'var(--ink-muted)', border: 'none', borderRight: '1px solid var(--line)' },\n '.cm-lineNumbers .cm-gutterElement': { padding: '0 var(--space-2) 0 var(--space-3)' },\n '.cm-activeLine': { backgroundColor: 'color-mix(in oklab, var(--accent-soft) 60%, transparent)' },\n '.cm-activeLineGutter': { backgroundColor: 'transparent', color: 'var(--ink)' },\n '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': { backgroundColor: 'color-mix(in oklab, var(--accent-ink) 24%, transparent)' },\n '.cm-matchingBracket, &.cm-focused .cm-matchingBracket': { backgroundColor: 'transparent', outline: '1px solid var(--accent-ink)', borderRadius: '2px' },\n '.cm-searchMatch': { backgroundColor: 'color-mix(in oklab, var(--caution) 22%, transparent)', outline: '1px solid var(--caution)' },\n '.cm-placeholder': { color: 'var(--ink-muted)' },\n '.cm-lintRange-error': { backgroundImage: 'none', textDecoration: 'underline wavy var(--critical)', textUnderlineOffset: '3px' },\n '.cm-lintRange-warning': { backgroundImage: 'none', textDecoration: 'underline wavy var(--caution)', textUnderlineOffset: '3px' },\n '.cm-lint-marker': { width: '12px', height: '12px', borderRadius: '3px', backgroundImage: 'none !important' },\n '.cm-lint-marker-error': { backgroundColor: 'var(--critical-soft)', boxShadow: 'var(--trench), inset 0 0 0 1px var(--critical)' },\n '.cm-lint-marker-warning': { backgroundColor: 'var(--caution-soft)', boxShadow: 'inset 0 0 0 1px var(--caution)' },\n '.cm-diagnostic': { padding: 'var(--space-1) var(--space-3)', font: '500 13px/18px var(--font-sans)', color: 'var(--ink)' },\n '.cm-diagnostic-error': { borderLeft: '3px solid var(--critical)' },\n '.cm-diagnostic-warning': { borderLeft: '3px solid var(--caution)' },\n '.cm-tooltip': { border: 'none', borderRadius: 'var(--radius-md)', backgroundColor: 'var(--surface-floating)', color: 'var(--ink)', boxShadow: 'var(--elev-3)', overflow: 'hidden' },\n '.cm-tooltip-autocomplete > ul': { fontFamily: 'var(--font-mono)', fontSize: '13px' },\n '.cm-tooltip-autocomplete > ul > li': { padding: '4px var(--space-2)' },\n '.cm-tooltip-autocomplete > ul > li[aria-selected]': { backgroundColor: 'var(--accent-soft)', color: 'var(--ink)' },\n '.cm-panels': { backgroundColor: 'var(--surface-ground)', color: 'var(--ink)' },\n '.cm-panels.cm-panels-bottom': { borderTop: '1px solid var(--line)' },\n '.cm-panels.cm-panels-top': { borderBottom: '1px solid var(--line)' },\n '.cm-foldPlaceholder': { backgroundColor: 'var(--surface-raised)', border: '1px solid var(--line)', color: 'var(--ink-muted)' },\n // Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.\n '@media (forced-colors: active)': { '.cm-lint-marker-error': { border: '2px dashed CanvasText' }, '.cm-tooltip': { border: '1px solid CanvasText' } },\n});\n\n/** Syntax in ink, ink-muted and accent-ink only: code is text to read, not data to compare, so no data-* hues. */\nexport const altitudeHighlightStyle: HighlightStyle = HighlightStyle.define([\n { tag: [t.keyword, t.operatorKeyword, t.modifier, t.controlKeyword], color: 'var(--accent-ink)', fontWeight: '600' },\n { tag: [t.number, t.bool, t.null, t.atom], color: 'var(--accent-ink)' },\n { tag: [t.string, t.special(t.string), t.regexp], color: 'var(--ink)' },\n { tag: [t.propertyName, t.attributeName, t.definition(t.variableName), t.function(t.variableName)], color: 'var(--ink)', fontWeight: '550' },\n { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: 'var(--ink-muted)', fontStyle: 'italic' },\n { tag: [t.punctuation, t.bracket, t.separator, t.operator], color: 'var(--ink-muted)' },\n { tag: [t.typeName, t.className, t.tagName], color: 'var(--accent-ink)' },\n { tag: t.invalid, color: 'var(--critical)' },\n]);\n\n/** The whole adapter: `new EditorView({ extensions: [altitudeTheme(), \u2026] })`. */\nexport function altitudeTheme(): Extension {\n return [altitudeEditorTheme, syntaxHighlighting(altitudeHighlightStyle)];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["t"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// project/components/src/adapter-codemirror.tsx
|
|
2
|
+
import { EditorView } from "@codemirror/view";
|
|
3
|
+
import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
|
|
4
|
+
import { tags as t } from "@lezer/highlight";
|
|
5
|
+
var wall = "inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)";
|
|
6
|
+
var altitudeEditorTheme = EditorView.theme({
|
|
7
|
+
"&": {
|
|
8
|
+
color: "var(--ink)",
|
|
9
|
+
backgroundColor: "var(--surface-well)",
|
|
10
|
+
border: "1px solid var(--line-control)",
|
|
11
|
+
borderRadius: "var(--radius-md)",
|
|
12
|
+
boxShadow: wall,
|
|
13
|
+
outline: "1px solid transparent"
|
|
14
|
+
},
|
|
15
|
+
"&:hover": { borderColor: "var(--ink-muted)" },
|
|
16
|
+
"&.cm-focused": { outline: "1px solid transparent", backgroundColor: "var(--surface-raised)" },
|
|
17
|
+
"&:has(.cm-content:focus-visible)": { borderColor: "var(--alt-rim-held)", outlineColor: "var(--alt-rim-held)" },
|
|
18
|
+
".cm-scroller": { fontFamily: "var(--font-mono)", fontSize: "13px", lineHeight: "20px", paddingTop: "4px" },
|
|
19
|
+
".cm-content": { caretColor: "var(--ink)", padding: "var(--space-2) 0" },
|
|
20
|
+
".cm-line": { padding: "0 var(--space-3)" },
|
|
21
|
+
".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--ink)", borderLeftWidth: "2px" },
|
|
22
|
+
".cm-gutters": { backgroundColor: "transparent", color: "var(--ink-muted)", border: "none", borderRight: "1px solid var(--line)" },
|
|
23
|
+
".cm-lineNumbers .cm-gutterElement": { padding: "0 var(--space-2) 0 var(--space-3)" },
|
|
24
|
+
".cm-activeLine": { backgroundColor: "color-mix(in oklab, var(--accent-soft) 60%, transparent)" },
|
|
25
|
+
".cm-activeLineGutter": { backgroundColor: "transparent", color: "var(--ink)" },
|
|
26
|
+
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection": { backgroundColor: "color-mix(in oklab, var(--accent-ink) 24%, transparent)" },
|
|
27
|
+
".cm-matchingBracket, &.cm-focused .cm-matchingBracket": { backgroundColor: "transparent", outline: "1px solid var(--accent-ink)", borderRadius: "2px" },
|
|
28
|
+
".cm-searchMatch": { backgroundColor: "color-mix(in oklab, var(--caution) 22%, transparent)", outline: "1px solid var(--caution)" },
|
|
29
|
+
".cm-placeholder": { color: "var(--ink-muted)" },
|
|
30
|
+
".cm-lintRange-error": { backgroundImage: "none", textDecoration: "underline wavy var(--critical)", textUnderlineOffset: "3px" },
|
|
31
|
+
".cm-lintRange-warning": { backgroundImage: "none", textDecoration: "underline wavy var(--caution)", textUnderlineOffset: "3px" },
|
|
32
|
+
".cm-lint-marker": { width: "12px", height: "12px", borderRadius: "3px", backgroundImage: "none !important" },
|
|
33
|
+
".cm-lint-marker-error": { backgroundColor: "var(--critical-soft)", boxShadow: "var(--trench), inset 0 0 0 1px var(--critical)" },
|
|
34
|
+
".cm-lint-marker-warning": { backgroundColor: "var(--caution-soft)", boxShadow: "inset 0 0 0 1px var(--caution)" },
|
|
35
|
+
".cm-diagnostic": { padding: "var(--space-1) var(--space-3)", font: "500 13px/18px var(--font-sans)", color: "var(--ink)" },
|
|
36
|
+
".cm-diagnostic-error": { borderLeft: "3px solid var(--critical)" },
|
|
37
|
+
".cm-diagnostic-warning": { borderLeft: "3px solid var(--caution)" },
|
|
38
|
+
".cm-tooltip": { border: "none", borderRadius: "var(--radius-md)", backgroundColor: "var(--surface-floating)", color: "var(--ink)", boxShadow: "var(--elev-3)", overflow: "hidden" },
|
|
39
|
+
".cm-tooltip-autocomplete > ul": { fontFamily: "var(--font-mono)", fontSize: "13px" },
|
|
40
|
+
".cm-tooltip-autocomplete > ul > li": { padding: "4px var(--space-2)" },
|
|
41
|
+
".cm-tooltip-autocomplete > ul > li[aria-selected]": { backgroundColor: "var(--accent-soft)", color: "var(--ink)" },
|
|
42
|
+
".cm-panels": { backgroundColor: "var(--surface-ground)", color: "var(--ink)" },
|
|
43
|
+
".cm-panels.cm-panels-bottom": { borderTop: "1px solid var(--line)" },
|
|
44
|
+
".cm-panels.cm-panels-top": { borderBottom: "1px solid var(--line)" },
|
|
45
|
+
".cm-foldPlaceholder": { backgroundColor: "var(--surface-raised)", border: "1px solid var(--line)", color: "var(--ink-muted)" },
|
|
46
|
+
// Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.
|
|
47
|
+
"@media (forced-colors: active)": { ".cm-lint-marker-error": { border: "2px dashed CanvasText" }, ".cm-tooltip": { border: "1px solid CanvasText" } }
|
|
48
|
+
});
|
|
49
|
+
var altitudeHighlightStyle = HighlightStyle.define([
|
|
50
|
+
{ tag: [t.keyword, t.operatorKeyword, t.modifier, t.controlKeyword], color: "var(--accent-ink)", fontWeight: "600" },
|
|
51
|
+
{ tag: [t.number, t.bool, t.null, t.atom], color: "var(--accent-ink)" },
|
|
52
|
+
{ tag: [t.string, t.special(t.string), t.regexp], color: "var(--ink)" },
|
|
53
|
+
{ tag: [t.propertyName, t.attributeName, t.definition(t.variableName), t.function(t.variableName)], color: "var(--ink)", fontWeight: "550" },
|
|
54
|
+
{ tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: "var(--ink-muted)", fontStyle: "italic" },
|
|
55
|
+
{ tag: [t.punctuation, t.bracket, t.separator, t.operator], color: "var(--ink-muted)" },
|
|
56
|
+
{ tag: [t.typeName, t.className, t.tagName], color: "var(--accent-ink)" },
|
|
57
|
+
{ tag: t.invalid, color: "var(--critical)" }
|
|
58
|
+
]);
|
|
59
|
+
function altitudeTheme() {
|
|
60
|
+
return [altitudeEditorTheme, syntaxHighlighting(altitudeHighlightStyle)];
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
altitudeEditorTheme,
|
|
64
|
+
altitudeHighlightStyle,
|
|
65
|
+
altitudeTheme
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=codemirror.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../project/components/src/adapter-codemirror.tsx"],
|
|
4
|
+
"sourcesContent": ["import { EditorView } from '@codemirror/view';\nimport { HighlightStyle, syntaxHighlighting } from '@codemirror/language';\nimport { tags as t } from '@lezer/highlight';\nimport type { Extension } from '@codemirror/state';\n\n/* \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 CodeMirror adapter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n/*\n * altitude-design/adapters/codemirror: Altitude readings for a CodeMirror 6 editor. Every value is one of the scheme's\n * custom properties, so the editor follows the active scheme, a custom accent and contrast=\"more\" without re-creating\n * it. It imports only CodeMirror (@codemirror/view, @codemirror/language, @lezer/highlight), which your app installs.\n */\nconst wall = 'inset 0 4px 0 0 var(--alt-wall-in), inset 0 7px 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip)';\n\n/**\n * The editor is an opening: a well with its inside wall, the floor lit while focused and a 2px neutral rim for keyboard\n * focus. Gutter and lines are ground; the active line is a tint, never a height; the selection is accent. Lint errors\n * sink their gutter marker into a trench on critical-soft and say the problem in words. Tooltips and completion lists\n * float at level 3.\n */\nexport const altitudeEditorTheme: Extension = EditorView.theme({\n '&': { color: 'var(--ink)', backgroundColor: 'var(--surface-well)', border: '1px solid var(--line-control)', borderRadius: 'var(--radius-md)',\n boxShadow: wall, outline: '1px solid transparent' },\n '&:hover': { borderColor: 'var(--ink-muted)' },\n '&.cm-focused': { outline: '1px solid transparent', backgroundColor: 'var(--surface-raised)' },\n '&:has(.cm-content:focus-visible)': { borderColor: 'var(--alt-rim-held)', outlineColor: 'var(--alt-rim-held)' },\n '.cm-scroller': { fontFamily: 'var(--font-mono)', fontSize: '13px', lineHeight: '20px', paddingTop: '4px' },\n '.cm-content': { caretColor: 'var(--ink)', padding: 'var(--space-2) 0' },\n '.cm-line': { padding: '0 var(--space-3)' },\n '.cm-cursor, .cm-dropCursor': { borderLeftColor: 'var(--ink)', borderLeftWidth: '2px' },\n '.cm-gutters': { backgroundColor: 'transparent', color: 'var(--ink-muted)', border: 'none', borderRight: '1px solid var(--line)' },\n '.cm-lineNumbers .cm-gutterElement': { padding: '0 var(--space-2) 0 var(--space-3)' },\n '.cm-activeLine': { backgroundColor: 'color-mix(in oklab, var(--accent-soft) 60%, transparent)' },\n '.cm-activeLineGutter': { backgroundColor: 'transparent', color: 'var(--ink)' },\n '&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': { backgroundColor: 'color-mix(in oklab, var(--accent-ink) 24%, transparent)' },\n '.cm-matchingBracket, &.cm-focused .cm-matchingBracket': { backgroundColor: 'transparent', outline: '1px solid var(--accent-ink)', borderRadius: '2px' },\n '.cm-searchMatch': { backgroundColor: 'color-mix(in oklab, var(--caution) 22%, transparent)', outline: '1px solid var(--caution)' },\n '.cm-placeholder': { color: 'var(--ink-muted)' },\n '.cm-lintRange-error': { backgroundImage: 'none', textDecoration: 'underline wavy var(--critical)', textUnderlineOffset: '3px' },\n '.cm-lintRange-warning': { backgroundImage: 'none', textDecoration: 'underline wavy var(--caution)', textUnderlineOffset: '3px' },\n '.cm-lint-marker': { width: '12px', height: '12px', borderRadius: '3px', backgroundImage: 'none !important' },\n '.cm-lint-marker-error': { backgroundColor: 'var(--critical-soft)', boxShadow: 'var(--trench), inset 0 0 0 1px var(--critical)' },\n '.cm-lint-marker-warning': { backgroundColor: 'var(--caution-soft)', boxShadow: 'inset 0 0 0 1px var(--caution)' },\n '.cm-diagnostic': { padding: 'var(--space-1) var(--space-3)', font: '500 13px/18px var(--font-sans)', color: 'var(--ink)' },\n '.cm-diagnostic-error': { borderLeft: '3px solid var(--critical)' },\n '.cm-diagnostic-warning': { borderLeft: '3px solid var(--caution)' },\n '.cm-tooltip': { border: 'none', borderRadius: 'var(--radius-md)', backgroundColor: 'var(--surface-floating)', color: 'var(--ink)', boxShadow: 'var(--elev-3)', overflow: 'hidden' },\n '.cm-tooltip-autocomplete > ul': { fontFamily: 'var(--font-mono)', fontSize: '13px' },\n '.cm-tooltip-autocomplete > ul > li': { padding: '4px var(--space-2)' },\n '.cm-tooltip-autocomplete > ul > li[aria-selected]': { backgroundColor: 'var(--accent-soft)', color: 'var(--ink)' },\n '.cm-panels': { backgroundColor: 'var(--surface-ground)', color: 'var(--ink)' },\n '.cm-panels.cm-panels-bottom': { borderTop: '1px solid var(--line)' },\n '.cm-panels.cm-panels-top': { borderBottom: '1px solid var(--line)' },\n '.cm-foldPlaceholder': { backgroundColor: 'var(--surface-raised)', border: '1px solid var(--line)', color: 'var(--ink-muted)' },\n // Nothing here moves, so reduced motion needs no rule: the editor changes state without transitions.\n '@media (forced-colors: active)': { '.cm-lint-marker-error': { border: '2px dashed CanvasText' }, '.cm-tooltip': { border: '1px solid CanvasText' } },\n});\n\n/** Syntax in ink, ink-muted and accent-ink only: code is text to read, not data to compare, so no data-* hues. */\nexport const altitudeHighlightStyle: HighlightStyle = HighlightStyle.define([\n { tag: [t.keyword, t.operatorKeyword, t.modifier, t.controlKeyword], color: 'var(--accent-ink)', fontWeight: '600' },\n { tag: [t.number, t.bool, t.null, t.atom], color: 'var(--accent-ink)' },\n { tag: [t.string, t.special(t.string), t.regexp], color: 'var(--ink)' },\n { tag: [t.propertyName, t.attributeName, t.definition(t.variableName), t.function(t.variableName)], color: 'var(--ink)', fontWeight: '550' },\n { tag: [t.comment, t.lineComment, t.blockComment, t.docComment], color: 'var(--ink-muted)', fontStyle: 'italic' },\n { tag: [t.punctuation, t.bracket, t.separator, t.operator], color: 'var(--ink-muted)' },\n { tag: [t.typeName, t.className, t.tagName], color: 'var(--accent-ink)' },\n { tag: t.invalid, color: 'var(--critical)' },\n]);\n\n/** The whole adapter: `new EditorView({ extensions: [altitudeTheme(), \u2026] })`. */\nexport function altitudeTheme(): Extension {\n return [altitudeEditorTheme, syntaxHighlighting(altitudeHighlightStyle)];\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/* altitude-design/adapters/react-flow.css: Altitude readings for a React Flow (@xyflow/react 12) node-and-edge canvas.
|
|
2
|
+
Import it after altitude.css and after React Flow's own stylesheet (base.css or style.css). It sets React Flow's
|
|
3
|
+
--xy-* properties from the active scheme and styles its elements; it imports nothing.
|
|
4
|
+
- The canvas is ground, with a dot grid in line.
|
|
5
|
+
- Nodes are Cards at level 1; a node that can be selected lifts one level when pointed at; a dragged node is in your
|
|
6
|
+
hand at level 3. Selection is a rim, never extra height.
|
|
7
|
+
- Ports (handles) are small openings that deepen under an edge being drawn, and take the accent rim where it can
|
|
8
|
+
land. The edge being drawn is a dashed line-control stroke; edges are line-control, a selected edge accent-ink.
|
|
9
|
+
- Give a node className "alt-node-pending" while its work runs (it hovers, as a pending write) or "alt-node-failed"
|
|
10
|
+
when it failed (it drops into a trench). Say the state in the node's words too.
|
|
11
|
+
- The minimap is a well with a raised lens (the ChartBrush build); controls are a raised toolbar.
|
|
12
|
+
React Flow's keyboard support and ARIA are untouched. ── */
|
|
13
|
+
.react-flow {
|
|
14
|
+
--xy-background-color: var(--surface-ground);
|
|
15
|
+
--xy-background-pattern-dots-color: var(--line-control);
|
|
16
|
+
--xy-background-pattern-color: var(--line-control);
|
|
17
|
+
--xy-node-color: var(--ink);
|
|
18
|
+
--xy-node-background-color: var(--surface-raised);
|
|
19
|
+
--xy-node-border: 0;
|
|
20
|
+
--xy-node-border-radius: var(--radius-lg);
|
|
21
|
+
--xy-node-boxshadow-hover: var(--elev-2);
|
|
22
|
+
--xy-node-boxshadow-selected: var(--elev-1), 0 0 0 2px var(--accent-ink);
|
|
23
|
+
--xy-node-group-background-color: color-mix(in oklab, var(--surface-well) 60%, transparent);
|
|
24
|
+
--xy-edge-stroke: var(--line-control);
|
|
25
|
+
--xy-edge-stroke-width: 1.5;
|
|
26
|
+
--xy-edge-stroke-selected: var(--accent-ink);
|
|
27
|
+
--xy-connectionline-stroke: var(--ink-muted);
|
|
28
|
+
--xy-connectionline-stroke-width: 1.5;
|
|
29
|
+
--xy-edge-label-background-color: var(--surface-ground);
|
|
30
|
+
--xy-edge-label-color: var(--ink-muted);
|
|
31
|
+
--xy-handle-background-color: var(--surface-well);
|
|
32
|
+
--xy-handle-border-color: var(--line-control);
|
|
33
|
+
--xy-selection-background-color: color-mix(in oklab, var(--accent-soft) 50%, transparent);
|
|
34
|
+
--xy-selection-border: 1px dashed var(--accent-ink);
|
|
35
|
+
--xy-minimap-background-color: var(--surface-well);
|
|
36
|
+
--xy-minimap-mask-background-color: color-mix(in oklab, var(--surface-well) 72%, transparent);
|
|
37
|
+
--xy-minimap-mask-stroke-color: var(--line-control);
|
|
38
|
+
--xy-minimap-mask-stroke-width: 1;
|
|
39
|
+
--xy-minimap-node-background-color: var(--line-control);
|
|
40
|
+
--xy-controls-button-background-color: var(--surface-raised);
|
|
41
|
+
--xy-controls-button-background-color-hover: var(--surface-lifted);
|
|
42
|
+
--xy-controls-button-color: var(--ink);
|
|
43
|
+
--xy-controls-button-color-hover: var(--ink);
|
|
44
|
+
--xy-controls-button-border-color: var(--line);
|
|
45
|
+
--xy-controls-box-shadow: var(--elev-1);
|
|
46
|
+
--xy-attribution-background-color: transparent;
|
|
47
|
+
color: var(--ink); font-family: var(--font-sans);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/* Nodes: Cards at level 1. */
|
|
51
|
+
.react-flow .react-flow__node-default, .react-flow .react-flow__node-input, .react-flow .react-flow__node-output, .react-flow .alt-node {
|
|
52
|
+
padding: var(--space-2) var(--space-3); border: 0; border-radius: var(--radius-lg); background: var(--surface-raised); color: var(--ink);
|
|
53
|
+
max-width: 220px; box-shadow: var(--elev-1); font: 500 13px/18px var(--font-sans); text-align: start; overflow-wrap: break-word;
|
|
54
|
+
transition: box-shadow var(--dur-travel-1) var(--ease-rise), background-color var(--dur-travel-1) var(--ease-rise);
|
|
55
|
+
}
|
|
56
|
+
.react-flow .react-flow__node.selectable:hover:not(.dragging) { box-shadow: var(--elev-2); }
|
|
57
|
+
.react-flow .react-flow__node.selectable.selected, .react-flow .react-flow__node.selectable.selected:hover:not(.dragging) { box-shadow: var(--elev-1), 0 0 0 2px var(--accent-ink); }
|
|
58
|
+
.react-flow .react-flow__node.selectable:focus-visible { outline: 2px solid var(--alt-rim-held); outline-offset: 2px; box-shadow: var(--elev-1); }
|
|
59
|
+
/* Possession: a dragged node is in your hand. */
|
|
60
|
+
.react-flow .react-flow__node.dragging { box-shadow: var(--elev-3); cursor: grabbing; }
|
|
61
|
+
/* Status: running hovers as a pending write; failed drops into a trench. */
|
|
62
|
+
.react-flow .react-flow__node.alt-node-pending { box-shadow: var(--elev-2); animation: alt-flow-hover var(--dur-hover) ease-in-out var(--dur-grace) infinite alternate both; cursor: progress; }
|
|
63
|
+
@keyframes alt-flow-hover { from { box-shadow: var(--elev-2); } to { box-shadow: var(--elev-3); } }
|
|
64
|
+
.react-flow .react-flow__node.alt-node-failed { background: var(--critical-soft); box-shadow: var(--trench), inset 0 0 0 1px var(--critical); }
|
|
65
|
+
|
|
66
|
+
/* Ports: small openings that deepen to receive an edge. */
|
|
67
|
+
.react-flow .react-flow__handle {
|
|
68
|
+
width: 10px; height: 10px; border: 1px solid var(--line-control); border-radius: 50%; background: var(--surface-well);
|
|
69
|
+
box-shadow: inset 0 1.5px 0 0 var(--alt-wall-in); transition: box-shadow var(--dur-travel-1) var(--ease-settle), background-color var(--dur-travel-1);
|
|
70
|
+
}
|
|
71
|
+
.react-flow .react-flow__handle.connectionindicator:hover, .react-flow .react-flow__handle.connectingfrom { box-shadow: inset 0 3px 0 0 var(--alt-wall-in); }
|
|
72
|
+
.react-flow .react-flow__handle.connectingto { background: var(--surface-trench); box-shadow: var(--trench); }
|
|
73
|
+
.react-flow .react-flow__handle.connectingto.valid { border-color: var(--accent-ink); box-shadow: var(--trench), 0 0 0 2px var(--accent-ink); }
|
|
74
|
+
|
|
75
|
+
/* Edges */
|
|
76
|
+
.react-flow .react-flow__connection-path { stroke-dasharray: 5 4; }
|
|
77
|
+
.react-flow .react-flow__edge-text { font: 500 12px/16px var(--font-sans); fill: var(--ink-muted); }
|
|
78
|
+
.react-flow .react-flow__edge-textbg { fill: var(--surface-ground); }
|
|
79
|
+
.react-flow .react-flow__edge.alt-edge-failed .react-flow__edge-path { stroke: var(--critical); stroke-dasharray: 4 3; }
|
|
80
|
+
|
|
81
|
+
/* Minimap: a well with a raised lens. Controls: a raised toolbar. */
|
|
82
|
+
.react-flow .react-flow__minimap { border-radius: var(--radius-md); box-shadow: inset 0 2px 0 0 var(--alt-wall-in), 0 0 0 1px var(--line-control); overflow: hidden; }
|
|
83
|
+
.react-flow .react-flow__controls { border-radius: var(--radius-md); overflow: hidden; box-shadow: var(--elev-1); }
|
|
84
|
+
.react-flow .react-flow__controls-button { display: grid; place-items: center; width: 28px; height: 28px; padding: 0; border: 0; border-bottom: 1px solid var(--line); background: var(--surface-raised); color: var(--ink); cursor: pointer; }
|
|
85
|
+
.react-flow .react-flow__controls-button:last-child { border-bottom: 0; }
|
|
86
|
+
.react-flow .react-flow__controls-button:hover { background: var(--surface-lifted); }
|
|
87
|
+
.react-flow .react-flow__controls-button svg { width: 12px; height: 12px; }
|
|
88
|
+
.react-flow .react-flow__controls-button svg { fill: currentColor; }
|
|
89
|
+
.react-flow .react-flow__controls-button:focus-visible { outline: 2px solid var(--alt-rim-held); outline-offset: -2px; }
|
|
90
|
+
.react-flow .react-flow__attribution a { color: var(--ink-muted); }
|
|
91
|
+
|
|
92
|
+
@media (prefers-reduced-motion: reduce) { .react-flow .react-flow__node, .react-flow .react-flow__handle { transition: none; } .react-flow .react-flow__node.alt-node-pending { animation: none; } }
|
|
93
|
+
[data-motion="reduced"] .react-flow .react-flow__node, [data-motion="reduced"] .react-flow .react-flow__handle { transition: none; }
|
|
94
|
+
[data-motion="reduced"] .react-flow .react-flow__node.alt-node-pending { animation: none; }
|
|
95
|
+
@media (forced-colors: active) {
|
|
96
|
+
.react-flow .react-flow__node { border: 1px solid CanvasText; }
|
|
97
|
+
.react-flow .react-flow__node.selected { outline: 2px solid Highlight; }
|
|
98
|
+
.react-flow .react-flow__node.alt-node-pending { border-style: dotted; border-width: 2px; }
|
|
99
|
+
.react-flow .react-flow__node.alt-node-failed { border: 2px dashed CanvasText; }
|
|
100
|
+
.react-flow .react-flow__handle { border-color: CanvasText; }
|
|
101
|
+
.react-flow .react-flow__edge-path, .react-flow .react-flow__connection-path { stroke: CanvasText; }
|
|
102
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/* altitude-design/adapters/tiptap.css: Altitude readings for a Tiptap (ProseMirror) rich text editor.
|
|
2
|
+
Import it after altitude.css. It styles Tiptap's own elements; it doesn't import Tiptap, which your app installs.
|
|
3
|
+
- The editor is an opening, built like Textarea: an empty editor is a well showing its inside wall; once it holds
|
|
4
|
+
content the floor rises flush; focus lights the floor, and keyboard focus adds the 2px neutral rim.
|
|
5
|
+
- Content follows Altitude's type: links are .alt-link, inline code a mono plate, code blocks CodeBlock's ground,
|
|
6
|
+
mentions a flush Tag plate.
|
|
7
|
+
- The formatting bar is yours to render with Toolbar and ToolbarToggle (latched toggles). The mention list is yours
|
|
8
|
+
to render too: give it class "alt-rte-mentions" (role listbox, options with aria-selected) and it floats at level 3
|
|
9
|
+
like Combobox's list.
|
|
10
|
+
Tiptap's keyboard support and ARIA are untouched. ── */
|
|
11
|
+
.tiptap {
|
|
12
|
+
--w: 4px; --n: 0; --wc: var(--alt-wall-in); --wd: calc(var(--w) + var(--n) * 2px);
|
|
13
|
+
position: relative; min-height: 120px; padding: calc(var(--space-2) + var(--wd) * 0.5) var(--space-3) var(--space-2);
|
|
14
|
+
border: 1px solid var(--line-control); border-radius: var(--radius-md); background: var(--surface-well); color: var(--ink);
|
|
15
|
+
font: 400 15px/23px var(--font-sans); overflow-wrap: break-word; cursor: text;
|
|
16
|
+
box-shadow: inset 0 var(--wd) 0 0 var(--wc), inset 0 calc(var(--wd) + 3px) 3px -2px var(--alt-cast), 0 1px 0 0 var(--alt-lip);
|
|
17
|
+
outline: 1px solid transparent; outline-offset: 0;
|
|
18
|
+
transition: background-color var(--dur-travel-2) var(--ease-rise), box-shadow var(--dur-travel-2) var(--ease-settle), border-color var(--dur-travel-1) var(--ease-rise),
|
|
19
|
+
outline-color var(--dur-travel-1) var(--ease-rise), padding var(--dur-travel-2) var(--ease-settle);
|
|
20
|
+
}
|
|
21
|
+
.tiptap:hover { border-color: var(--ink-muted); }
|
|
22
|
+
/* Filled: anything but a single empty paragraph. The floor rises flush with the page. */
|
|
23
|
+
.tiptap:not(:has(> p:only-child > br.ProseMirror-trailingBreak:only-child)):not(:has(> p:only-child:empty)) { --w: 0px; background: var(--surface-raised); }
|
|
24
|
+
.tiptap.ProseMirror-focused, .tiptap:focus { background: var(--surface-raised); --n: var(--alt-travel); }
|
|
25
|
+
.tiptap:focus-visible { border-color: var(--alt-rim-held); outline-color: var(--alt-rim-held); }
|
|
26
|
+
.tiptap[contenteditable="false"] { --w: 0px; --n: 0; background: var(--surface-ground); border-color: var(--line); cursor: default; }
|
|
27
|
+
.tiptap[aria-invalid="true"] { --w: 6px; --n: 0; --wc: color-mix(in oklab, var(--critical-soft), var(--critical) 34%); background: var(--critical-soft); border-color: var(--critical); }
|
|
28
|
+
|
|
29
|
+
/* Placeholder (Tiptap's Placeholder extension): ink-muted, never the value. */
|
|
30
|
+
.tiptap p.is-editor-empty:first-child::before { content: attr(data-placeholder); float: left; height: 0; color: var(--ink-muted); pointer-events: none; }
|
|
31
|
+
|
|
32
|
+
/* Content */
|
|
33
|
+
.tiptap > :first-child { margin-top: 0; }
|
|
34
|
+
.tiptap > :last-child { margin-bottom: 0; }
|
|
35
|
+
.tiptap p { margin: 0 0 var(--space-2); }
|
|
36
|
+
.tiptap h1, .tiptap h2, .tiptap h3 { margin: var(--space-4) 0 var(--space-2); font-weight: 600; letter-spacing: -0.01em; }
|
|
37
|
+
.tiptap h1 { font-size: 21px; line-height: 28px; } .tiptap h2 { font-size: 18px; line-height: 25px; } .tiptap h3 { font-size: 16px; line-height: 23px; }
|
|
38
|
+
.tiptap ul, .tiptap ol { margin: 0 0 var(--space-2); padding-inline-start: 22px; }
|
|
39
|
+
.tiptap li > p { margin: 0; }
|
|
40
|
+
.tiptap li::marker { color: var(--ink-muted); }
|
|
41
|
+
.tiptap blockquote { margin: 0 0 var(--space-2); padding-inline-start: var(--space-3); border-inline-start: 2px solid var(--line-control); color: var(--ink-muted); }
|
|
42
|
+
.tiptap hr { margin: var(--space-3) 0; border: 0; border-top: 1px solid var(--line); }
|
|
43
|
+
.tiptap a { color: var(--accent-ink); text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
|
|
44
|
+
.tiptap code { padding: 1px 5px; border-radius: var(--radius-xs); background: var(--surface-well); box-shadow: inset 0 0 0 1px var(--line); font: 500 0.88em/1 var(--font-mono); }
|
|
45
|
+
.tiptap pre { margin: 0 0 var(--space-2); padding: var(--space-3) var(--space-4); border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface-ground); overflow-x: auto; }
|
|
46
|
+
.tiptap pre code { padding: 0; background: none; box-shadow: none; font: 400 13px/20px var(--font-mono); }
|
|
47
|
+
.tiptap strong { font-weight: 600; }
|
|
48
|
+
.tiptap ::selection { background: var(--accent-soft); }
|
|
49
|
+
.tiptap .mention, .tiptap [data-type="mention"] {
|
|
50
|
+
display: inline-flex; align-items: center; height: 22px; padding: 0 6px; border-radius: var(--radius-sm); vertical-align: baseline;
|
|
51
|
+
background: color-mix(in oklab, var(--surface-ground), var(--surface-well) 70%); color: var(--ink); font: 550 0.9em/1 var(--font-sans);
|
|
52
|
+
box-shadow: inset 0 1px 1.5px color-mix(in oklab, var(--ink) 16%, transparent), inset 0 0 0 1px color-mix(in oklab, var(--ink) 9%, transparent);
|
|
53
|
+
}
|
|
54
|
+
.tiptap .ProseMirror-selectednode { outline: 2px solid var(--accent-ink); outline-offset: 1px; }
|
|
55
|
+
.tiptap .ProseMirror-gapcursor::after { border-top-color: var(--ink); }
|
|
56
|
+
|
|
57
|
+
/* The mention list: your markup, floating at level 3 like Combobox's list. */
|
|
58
|
+
.alt-rte-mentions { min-width: 200px; max-height: 260px; padding: var(--space-1); overflow-y: auto; border-radius: var(--radius-lg); background: var(--surface-floating); box-shadow: var(--elev-3); }
|
|
59
|
+
.alt-rte-mentions [role="option"] { display: flex; align-items: center; gap: 8px; min-height: 34px; padding: 0 10px; border-radius: var(--radius-sm); font: 500 14px/20px var(--font-sans); color: var(--ink); cursor: pointer; }
|
|
60
|
+
.alt-rte-mentions [role="option"][aria-selected="true"] { background: var(--accent-soft); }
|
|
61
|
+
|
|
62
|
+
@media (prefers-reduced-motion: reduce) { .tiptap { transition: none; } }
|
|
63
|
+
[data-motion="reduced"] .tiptap { transition: none; }
|
|
64
|
+
@media (forced-colors: active) {
|
|
65
|
+
.tiptap { border: 1px solid CanvasText; }
|
|
66
|
+
.tiptap:has(> p:only-child > br.ProseMirror-trailingBreak:only-child) { border-style: dashed; }
|
|
67
|
+
.tiptap:focus-visible { outline: 2px solid Highlight; }
|
|
68
|
+
.tiptap .mention, .tiptap [data-type="mention"] { border: 1px solid CanvasText; }
|
|
69
|
+
.alt-rte-mentions { border: 1px solid CanvasText; }
|
|
70
|
+
.alt-rte-mentions [role="option"][aria-selected="true"] { outline: 2px solid Highlight; outline-offset: -2px; }
|
|
71
|
+
}
|