@vibefield/rosetta-room 0.0.0-stage → 0.1.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 +247 -2
- package/dist/HistoryRoom.d.ts +98 -0
- package/dist/HistoryRoom.js +440 -0
- package/dist/TranscriptReader.d.ts +22 -0
- package/dist/TranscriptReader.js +72 -0
- package/dist/components/ColdStart.d.ts +4 -0
- package/dist/components/ColdStart.js +5 -0
- package/dist/components/FilterChips.d.ts +4 -0
- package/dist/components/FilterChips.js +5 -0
- package/dist/components/HostAct.d.ts +9 -0
- package/dist/components/HostAct.js +16 -0
- package/dist/components/HostMenu.d.ts +41 -0
- package/dist/components/HostMenu.js +216 -0
- package/dist/components/IngestStatus.d.ts +4 -0
- package/dist/components/IngestStatus.js +20 -0
- package/dist/components/ListActivityNotice.d.ts +5 -0
- package/dist/components/ListActivityNotice.js +4 -0
- package/dist/components/ListSections.d.ts +20 -0
- package/dist/components/ListSections.js +39 -0
- package/dist/components/RenameHeading.d.ts +9 -0
- package/dist/components/RenameHeading.js +75 -0
- package/dist/components/SearchStrip.d.ts +5 -0
- package/dist/components/SearchStrip.js +8 -0
- package/dist/components/SummaryMetrics.d.ts +13 -0
- package/dist/components/SummaryMetrics.js +9 -0
- package/dist/components/SummaryPanels.d.ts +35 -0
- package/dist/components/SummaryPanels.js +117 -0
- package/dist/components/Transcript.d.ts +46 -0
- package/dist/components/Transcript.js +358 -0
- package/dist/components/charts/ActivityChartDetail.d.ts +13 -0
- package/dist/components/charts/ActivityChartDetail.js +78 -0
- package/dist/components/charts/CalendarHeatmap.d.ts +16 -0
- package/dist/components/charts/CalendarHeatmap.js +55 -0
- package/dist/components/charts/DayActivityChart.d.ts +8 -0
- package/dist/components/charts/DayActivityChart.js +71 -0
- package/dist/components/charts/ModelsChartDetail.d.ts +7 -0
- package/dist/components/charts/ModelsChartDetail.js +19 -0
- package/dist/components/charts/ProjectChartDialog.d.ts +19 -0
- package/dist/components/charts/ProjectChartDialog.js +39 -0
- package/dist/components/charts/Streamgraph.d.ts +16 -0
- package/dist/components/charts/Streamgraph.js +94 -0
- package/dist/components/charts/Treemap.d.ts +26 -0
- package/dist/components/charts/Treemap.js +81 -0
- package/dist/components/charts/index.d.ts +9 -0
- package/dist/components/charts/index.js +4 -0
- package/dist/components/charts/streamgraph-layout.d.ts +23 -0
- package/dist/components/charts/streamgraph-layout.js +114 -0
- package/dist/components/charts/treemap-layout.d.ts +32 -0
- package/dist/components/charts/treemap-layout.js +140 -0
- package/dist/components/charts/types.d.ts +65 -0
- package/dist/components/charts/types.js +8 -0
- package/dist/components/file-viewer/FileViewerBrowsers.d.ts +10 -0
- package/dist/components/file-viewer/FileViewerBrowsers.js +65 -0
- package/dist/components/file-viewer/FileViewerDialog.d.ts +33 -0
- package/dist/components/file-viewer/FileViewerDialog.js +82 -0
- package/dist/components/file-viewer/FileViewerHeader.d.ts +26 -0
- package/dist/components/file-viewer/FileViewerHeader.js +17 -0
- package/dist/components/file-viewer/ImageGalleryDialog.d.ts +14 -0
- package/dist/components/file-viewer/ImageGalleryDialog.js +98 -0
- package/dist/components/file-viewer/diff/index.d.ts +2 -0
- package/dist/components/file-viewer/diff/index.js +2 -0
- package/dist/components/file-viewer/diff/parse.d.ts +2 -0
- package/dist/components/file-viewer/diff/parse.js +164 -0
- package/dist/components/file-viewer/diff/types.d.ts +44 -0
- package/dist/components/file-viewer/diff/types.js +7 -0
- package/dist/components/file-viewer/gallery-source.d.ts +11 -0
- package/dist/components/file-viewer/gallery-source.js +75 -0
- package/dist/components/file-viewer/image-resource.d.ts +19 -0
- package/dist/components/file-viewer/image-resource.js +60 -0
- package/dist/components/file-viewer/index.d.ts +5 -0
- package/dist/components/file-viewer/index.js +8 -0
- package/dist/components/file-viewer/markdown/blocks.d.ts +2 -0
- package/dist/components/file-viewer/markdown/blocks.js +277 -0
- package/dist/components/file-viewer/markdown/index.d.ts +4 -0
- package/dist/components/file-viewer/markdown/index.js +35 -0
- package/dist/components/file-viewer/markdown/inline.d.ts +10 -0
- package/dist/components/file-viewer/markdown/inline.js +178 -0
- package/dist/components/file-viewer/markdown/render.d.ts +9 -0
- package/dist/components/file-viewer/markdown/render.js +78 -0
- package/dist/components/file-viewer/markdown/types.d.ts +57 -0
- package/dist/components/file-viewer/markdown/types.js +11 -0
- package/dist/components/file-viewer/minimap/CodeMinimap.d.ts +10 -0
- package/dist/components/file-viewer/minimap/CodeMinimap.js +296 -0
- package/dist/components/file-viewer/minimap/layout.d.ts +60 -0
- package/dist/components/file-viewer/minimap/layout.js +117 -0
- package/dist/components/file-viewer/minimap/palette.d.ts +2 -0
- package/dist/components/file-viewer/minimap/palette.js +73 -0
- package/dist/components/file-viewer/minimap/raster.d.ts +19 -0
- package/dist/components/file-viewer/minimap/raster.js +122 -0
- package/dist/components/file-viewer/registry.d.ts +25 -0
- package/dist/components/file-viewer/registry.js +182 -0
- package/dist/components/file-viewer/syntax/grammars.d.ts +16 -0
- package/dist/components/file-viewer/syntax/grammars.js +221 -0
- package/dist/components/file-viewer/syntax/index.d.ts +8 -0
- package/dist/components/file-viewer/syntax/index.js +9 -0
- package/dist/components/file-viewer/syntax/languages.d.ts +14 -0
- package/dist/components/file-viewer/syntax/languages.js +115 -0
- package/dist/components/file-viewer/syntax/tokenize-config.d.ts +2 -0
- package/dist/components/file-viewer/syntax/tokenize-config.js +132 -0
- package/dist/components/file-viewer/syntax/tokenize-css.d.ts +2 -0
- package/dist/components/file-viewer/syntax/tokenize-css.js +169 -0
- package/dist/components/file-viewer/syntax/tokenize-markup.d.ts +2 -0
- package/dist/components/file-viewer/syntax/tokenize-markup.js +124 -0
- package/dist/components/file-viewer/syntax/tokenize.d.ts +9 -0
- package/dist/components/file-viewer/syntax/tokenize.js +289 -0
- package/dist/components/file-viewer/syntax/types.d.ts +74 -0
- package/dist/components/file-viewer/syntax/types.js +13 -0
- package/dist/components/file-viewer/types.d.ts +111 -0
- package/dist/components/file-viewer/types.js +8 -0
- package/dist/components/file-viewer/use-file-content.d.ts +26 -0
- package/dist/components/file-viewer/use-file-content.js +144 -0
- package/dist/components/file-viewer/views/BinaryView.d.ts +2 -0
- package/dist/components/file-viewer/views/BinaryView.js +34 -0
- package/dist/components/file-viewer/views/CodeView.d.ts +2 -0
- package/dist/components/file-viewer/views/CodeView.js +46 -0
- package/dist/components/file-viewer/views/DiffBody.d.ts +7 -0
- package/dist/components/file-viewer/views/DiffBody.js +77 -0
- package/dist/components/file-viewer/views/DiffView.d.ts +2 -0
- package/dist/components/file-viewer/views/DiffView.js +11 -0
- package/dist/components/file-viewer/views/ImageView.d.ts +9 -0
- package/dist/components/file-viewer/views/ImageView.js +28 -0
- package/dist/components/file-viewer/views/MarkdownView.d.ts +9 -0
- package/dist/components/file-viewer/views/MarkdownView.js +20 -0
- package/dist/components/file-viewer/views/SvgView.d.ts +9 -0
- package/dist/components/file-viewer/views/SvgView.js +10 -0
- package/dist/components/git/ChangeTree.d.ts +20 -0
- package/dist/components/git/ChangeTree.js +35 -0
- package/dist/components/git/CommitViewer.d.ts +12 -0
- package/dist/components/git/CommitViewer.js +85 -0
- package/dist/components/git/GitChanges.d.ts +17 -0
- package/dist/components/git/GitChanges.js +70 -0
- package/dist/components/git/GitHistory.d.ts +9 -0
- package/dist/components/git/GitHistory.js +58 -0
- package/dist/components/git/co-author.d.ts +14 -0
- package/dist/components/git/co-author.js +55 -0
- package/dist/components/git/git-file-source.d.ts +18 -0
- package/dist/components/git/git-file-source.js +53 -0
- package/dist/components/git/git-host.d.ts +24 -0
- package/dist/components/git/git-host.js +130 -0
- package/dist/components/git/index.d.ts +10 -0
- package/dist/components/git/index.js +12 -0
- package/dist/components/git/path-tree.d.ts +23 -0
- package/dist/components/git/path-tree.js +73 -0
- package/dist/components/git/session-files.d.ts +9 -0
- package/dist/components/git/session-files.js +50 -0
- package/dist/components/git/types.d.ts +92 -0
- package/dist/components/git/types.js +9 -0
- package/dist/components/projects/ProjectActivitySparkline.d.ts +6 -0
- package/dist/components/projects/ProjectActivitySparkline.js +12 -0
- package/dist/components/projects/ProjectList.d.ts +25 -0
- package/dist/components/projects/ProjectList.js +43 -0
- package/dist/components/projects/ProjectListItem.d.ts +19 -0
- package/dist/components/projects/ProjectListItem.js +78 -0
- package/dist/components/projects/ProjectsColumn.d.ts +19 -0
- package/dist/components/projects/ProjectsColumn.js +36 -0
- package/dist/components/projects/index.d.ts +8 -0
- package/dist/components/projects/index.js +4 -0
- package/dist/components/search/MatchStepper.d.ts +9 -0
- package/dist/components/search/MatchStepper.js +14 -0
- package/dist/components/search/SearchLauncher.d.ts +12 -0
- package/dist/components/search/SearchLauncher.js +13 -0
- package/dist/components/search/SearchSheet.d.ts +29 -0
- package/dist/components/search/SearchSheet.js +230 -0
- package/dist/components/search/index.d.ts +8 -0
- package/dist/components/search/index.js +4 -0
- package/dist/components/search/shortcut.d.ts +25 -0
- package/dist/components/search/shortcut.js +32 -0
- package/dist/components/sessions/SessionList.d.ts +24 -0
- package/dist/components/sessions/SessionList.js +76 -0
- package/dist/components/sessions/SessionListItem.d.ts +13 -0
- package/dist/components/sessions/SessionListItem.js +58 -0
- package/dist/components/sessions/SessionsColumn.d.ts +26 -0
- package/dist/components/sessions/SessionsColumn.js +32 -0
- package/dist/components/sessions/index.d.ts +9 -0
- package/dist/components/sessions/index.js +4 -0
- package/dist/components/sessions/session-display.d.ts +8 -0
- package/dist/components/sessions/session-display.js +18 -0
- package/dist/components/sessions/types.d.ts +7 -0
- package/dist/components/sessions/types.js +1 -0
- package/dist/components/transcript/Activity.d.ts +45 -0
- package/dist/components/transcript/Activity.js +75 -0
- package/dist/components/transcript/Anchor.d.ts +8 -0
- package/dist/components/transcript/Anchor.js +23 -0
- package/dist/components/transcript/Attachments.d.ts +21 -0
- package/dist/components/transcript/Attachments.js +138 -0
- package/dist/components/transcript/AuthoredMessage.d.ts +19 -0
- package/dist/components/transcript/AuthoredMessage.js +17 -0
- package/dist/components/transcript/Compaction.d.ts +9 -0
- package/dist/components/transcript/Compaction.js +50 -0
- package/dist/components/transcript/DayPill.d.ts +38 -0
- package/dist/components/transcript/DayPill.js +68 -0
- package/dist/components/transcript/Document.d.ts +32 -0
- package/dist/components/transcript/Document.js +503 -0
- package/dist/components/transcript/Favicon.d.ts +32 -0
- package/dist/components/transcript/Favicon.js +71 -0
- package/dist/components/transcript/HeadOfDocument.d.ts +19 -0
- package/dist/components/transcript/HeadOfDocument.js +44 -0
- package/dist/components/transcript/Ledger.d.ts +53 -0
- package/dist/components/transcript/Ledger.js +182 -0
- package/dist/components/transcript/LineDetail.d.ts +24 -0
- package/dist/components/transcript/LineDetail.js +81 -0
- package/dist/components/transcript/Marker.d.ts +33 -0
- package/dist/components/transcript/Marker.js +21 -0
- package/dist/components/transcript/MessagePreview.d.ts +12 -0
- package/dist/components/transcript/MessagePreview.js +58 -0
- package/dist/components/transcript/Prompt.d.ts +20 -0
- package/dist/components/transcript/Prompt.js +55 -0
- package/dist/components/transcript/Prose.d.ts +19 -0
- package/dist/components/transcript/Prose.js +109 -0
- package/dist/components/transcript/ReceiptPill.d.ts +10 -0
- package/dist/components/transcript/ReceiptPill.js +10 -0
- package/dist/components/transcript/ResponseHead.d.ts +9 -0
- package/dist/components/transcript/ResponseHead.js +36 -0
- package/dist/components/transcript/Subthread.d.ts +19 -0
- package/dist/components/transcript/Subthread.js +96 -0
- package/dist/components/transcript/Team.d.ts +53 -0
- package/dist/components/transcript/Team.js +185 -0
- package/dist/components/transcript/Thinking.d.ts +24 -0
- package/dist/components/transcript/Thinking.js +50 -0
- package/dist/components/transcript/TimelineMeta.d.ts +9 -0
- package/dist/components/transcript/TimelineMeta.js +161 -0
- package/dist/components/transcript/TranscriptLoading.d.ts +10 -0
- package/dist/components/transcript/TranscriptLoading.js +10 -0
- package/dist/components/transcript/WebDetail.d.ts +8 -0
- package/dist/components/transcript/WebDetail.js +29 -0
- package/dist/components/transcript/Workflow.d.ts +12 -0
- package/dist/components/transcript/Workflow.js +208 -0
- package/dist/components/transcript/activity-plan.d.ts +84 -0
- package/dist/components/transcript/activity-plan.js +209 -0
- package/dist/components/transcript/attachment-file-source.d.ts +23 -0
- package/dist/components/transcript/attachment-file-source.js +103 -0
- package/dist/components/transcript/attachment-gallery.d.ts +12 -0
- package/dist/components/transcript/attachment-gallery.js +33 -0
- package/dist/components/transcript/detail-parts.d.ts +50 -0
- package/dist/components/transcript/detail-parts.js +295 -0
- package/dist/components/transcript/disclosure-state.d.ts +6 -0
- package/dist/components/transcript/disclosure-state.js +32 -0
- package/dist/components/transcript/disclosure-store.d.ts +8 -0
- package/dist/components/transcript/disclosure-store.js +31 -0
- package/dist/components/transcript/document-model.d.ts +15 -0
- package/dist/components/transcript/document-model.js +104 -0
- package/dist/components/transcript/document-plan.d.ts +28 -0
- package/dist/components/transcript/document-plan.js +145 -0
- package/dist/components/transcript/fold-preference.d.ts +17 -0
- package/dist/components/transcript/fold-preference.js +63 -0
- package/dist/components/transcript/glyphs.d.ts +15 -0
- package/dist/components/transcript/glyphs.js +47 -0
- package/dist/components/transcript/index.d.ts +23 -0
- package/dist/components/transcript/index.js +22 -0
- package/dist/components/transcript/message-file-source.d.ts +15 -0
- package/dist/components/transcript/message-file-source.js +31 -0
- package/dist/components/transcript/message-preview.d.ts +9 -0
- package/dist/components/transcript/message-preview.js +46 -0
- package/dist/components/transcript/read-file-source.d.ts +7 -0
- package/dist/components/transcript/read-file-source.js +34 -0
- package/dist/components/transcript/reader-context.d.ts +13 -0
- package/dist/components/transcript/reader-context.js +55 -0
- package/dist/components/transcript/reading-identity.d.ts +2 -0
- package/dist/components/transcript/reading-identity.js +52 -0
- package/dist/components/transcript/scroll-to-row.d.ts +2 -0
- package/dist/components/transcript/scroll-to-row.js +13 -0
- package/dist/components/transcript/thread-index.d.ts +14 -0
- package/dist/components/transcript/thread-index.js +40 -0
- package/dist/components/transcript/thread-navigation.d.ts +5 -0
- package/dist/components/transcript/thread-navigation.js +3 -0
- package/dist/components/transcript/timeline-meta-file-source.d.ts +6 -0
- package/dist/components/transcript/timeline-meta-file-source.js +55 -0
- package/dist/components/transcript/timeline-meta-state.d.ts +12 -0
- package/dist/components/transcript/timeline-meta-state.js +24 -0
- package/dist/components/ui/ColumnHeading.d.ts +27 -0
- package/dist/components/ui/ColumnHeading.js +7 -0
- package/dist/components/ui/ConfirmDialog.d.ts +14 -0
- package/dist/components/ui/ConfirmDialog.js +22 -0
- package/dist/components/ui/DialogShell.d.ts +18 -0
- package/dist/components/ui/DialogShell.js +40 -0
- package/dist/components/ui/EmptyState.d.ts +10 -0
- package/dist/components/ui/EmptyState.js +6 -0
- package/dist/components/ui/ListSummaryHeader.d.ts +9 -0
- package/dist/components/ui/ListSummaryHeader.js +6 -0
- package/dist/components/ui/ListToolbar.d.ts +6 -0
- package/dist/components/ui/ListToolbar.js +5 -0
- package/dist/components/ui/ResultGroupHeader.d.ts +9 -0
- package/dist/components/ui/ResultGroupHeader.js +5 -0
- package/dist/components/ui/SegmentedControl.d.ts +16 -0
- package/dist/components/ui/SegmentedControl.js +9 -0
- package/dist/components/ui/SummaryMetric.d.ts +13 -0
- package/dist/components/ui/SummaryMetric.js +10 -0
- package/dist/components/ui/Veil.d.ts +7 -0
- package/dist/components/ui/Veil.js +5 -0
- package/dist/components/ui/index.d.ts +20 -0
- package/dist/components/ui/index.js +10 -0
- package/dist/components/worktree/WorktreeColumn.d.ts +22 -0
- package/dist/components/worktree/WorktreeColumn.js +170 -0
- package/dist/components/worktree/WorktreeFileTree.d.ts +19 -0
- package/dist/components/worktree/WorktreeFileTree.js +60 -0
- package/dist/components/worktree/WorktreeHeader.d.ts +32 -0
- package/dist/components/worktree/WorktreeHeader.js +81 -0
- package/dist/components/worktree/WorktreeList.d.ts +8 -0
- package/dist/components/worktree/WorktreeList.js +12 -0
- package/dist/components/worktree/index.d.ts +12 -0
- package/dist/components/worktree/index.js +7 -0
- package/dist/components/worktree/types.d.ts +17 -0
- package/dist/components/worktree/types.js +3 -0
- package/dist/components/worktree/use-worktree-guest.d.ts +21 -0
- package/dist/components/worktree/use-worktree-guest.js +92 -0
- package/dist/components/worktree/worktree-file-commands.d.ts +19 -0
- package/dist/components/worktree/worktree-file-commands.js +112 -0
- package/dist/components/worktree/worktree-file-source.d.ts +15 -0
- package/dist/components/worktree/worktree-file-source.js +75 -0
- package/dist/components/worktree/worktree-host.d.ts +31 -0
- package/dist/components/worktree/worktree-host.js +242 -0
- package/dist/fixtures/index.d.ts +24 -0
- package/dist/fixtures/index.js +292 -0
- package/dist/host-inputs.d.ts +231 -0
- package/dist/host-inputs.js +35 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +14 -0
- package/dist/lib/activity-details.d.ts +23 -0
- package/dist/lib/activity-details.js +78 -0
- package/dist/lib/activity-order.d.ts +32 -0
- package/dist/lib/activity-order.js +86 -0
- package/dist/lib/agent-paths.d.ts +6 -0
- package/dist/lib/agent-paths.js +19 -0
- package/dist/lib/agents.d.ts +15 -0
- package/dist/lib/agents.js +60 -0
- package/dist/lib/catalog-status.d.ts +3 -0
- package/dist/lib/catalog-status.js +10 -0
- package/dist/lib/chart-data.d.ts +14 -0
- package/dist/lib/chart-data.js +151 -0
- package/dist/lib/day-activity.d.ts +21 -0
- package/dist/lib/day-activity.js +56 -0
- package/dist/lib/format.d.ts +24 -0
- package/dist/lib/format.js +116 -0
- package/dist/lib/hooks.d.ts +118 -0
- package/dist/lib/hooks.js +608 -0
- package/dist/lib/icons.d.ts +21 -0
- package/dist/lib/icons.js +49 -0
- package/dist/lib/image-media.d.ts +6 -0
- package/dist/lib/image-media.js +30 -0
- package/dist/lib/ingest-activity.d.ts +50 -0
- package/dist/lib/ingest-activity.js +151 -0
- package/dist/lib/ingest.d.ts +25 -0
- package/dist/lib/ingest.js +70 -0
- package/dist/lib/model-labels.d.ts +5 -0
- package/dist/lib/model-labels.js +28 -0
- package/dist/lib/model.d.ts +73 -0
- package/dist/lib/model.js +141 -0
- package/dist/lib/motion.d.ts +13 -0
- package/dist/lib/motion.js +80 -0
- package/dist/lib/room-storage.d.ts +13 -0
- package/dist/lib/room-storage.js +40 -0
- package/dist/lib/search-results.d.ts +27 -0
- package/dist/lib/search-results.js +83 -0
- package/dist/lib/search-sheet.d.ts +119 -0
- package/dist/lib/search-sheet.js +282 -0
- package/dist/lib/sections.d.ts +19 -0
- package/dist/lib/sections.js +36 -0
- package/dist/lib/session-activity.d.ts +5 -0
- package/dist/lib/session-activity.js +15 -0
- package/dist/lib/session-leases.d.ts +15 -0
- package/dist/lib/session-leases.js +61 -0
- package/dist/lib/spend.d.ts +42 -0
- package/dist/lib/spend.js +112 -0
- package/dist/lib/tint.d.ts +9 -0
- package/dist/lib/tint.js +53 -0
- package/dist/lib/transcript/collaboration.d.ts +97 -0
- package/dist/lib/transcript/collaboration.js +423 -0
- package/dist/lib/transcript/families.d.ts +212 -0
- package/dist/lib/transcript/families.js +906 -0
- package/dist/lib/transcript/favicons.d.ts +54 -0
- package/dist/lib/transcript/favicons.js +183 -0
- package/dist/lib/transcript/head-of-document.d.ts +27 -0
- package/dist/lib/transcript/head-of-document.js +274 -0
- package/dist/lib/transcript/head-state.d.ts +182 -0
- package/dist/lib/transcript/head-state.js +305 -0
- package/dist/lib/transcript/history-window.d.ts +13 -0
- package/dist/lib/transcript/history-window.js +52 -0
- package/dist/lib/transcript/images.d.ts +8 -0
- package/dist/lib/transcript/images.js +60 -0
- package/dist/lib/transcript/index.d.ts +15 -0
- package/dist/lib/transcript/index.js +8 -0
- package/dist/lib/transcript/ledger.d.ts +143 -0
- package/dist/lib/transcript/ledger.js +513 -0
- package/dist/lib/transcript/protocol.d.ts +23 -0
- package/dist/lib/transcript/protocol.js +1 -0
- package/dist/lib/transcript/sittings.d.ts +75 -0
- package/dist/lib/transcript/sittings.js +147 -0
- package/dist/lib/transcript/tail-scroll.d.ts +36 -0
- package/dist/lib/transcript/tail-scroll.js +167 -0
- package/dist/lib/transcript/tail-state.d.ts +17 -0
- package/dist/lib/transcript/tail-state.js +30 -0
- package/dist/lib/transcript/turns.d.ts +192 -0
- package/dist/lib/transcript/turns.js +576 -0
- package/dist/lib/transcript/use-transcript-opening.d.ts +12 -0
- package/dist/lib/transcript/use-transcript-opening.js +31 -0
- package/dist/lib/transcript/use-transcript-tail.d.ts +25 -0
- package/dist/lib/transcript/use-transcript-tail.js +158 -0
- package/dist/lib/transcript/vocabulary.d.ts +119 -0
- package/dist/lib/transcript/vocabulary.js +293 -0
- package/dist/lib/transcript/web-address.d.ts +6 -0
- package/dist/lib/transcript/web-address.js +18 -0
- package/dist/lib/transcript/workflow.d.ts +31 -0
- package/dist/lib/transcript/workflow.js +133 -0
- package/dist/lib/use-activity-order.d.ts +2 -0
- package/dist/lib/use-activity-order.js +23 -0
- package/dist/lib/use-day-usage.d.ts +8 -0
- package/dist/lib/use-day-usage.js +31 -0
- package/dist/lib/use-deferred-list-order.d.ts +26 -0
- package/dist/lib/use-deferred-list-order.js +142 -0
- package/dist/lib/use-ingest-activity.d.ts +2 -0
- package/dist/lib/use-ingest-activity.js +49 -0
- package/dist/lib/use-list-motion.d.ts +4 -0
- package/dist/lib/use-list-motion.js +67 -0
- package/dist/ports.d.ts +222 -0
- package/dist/ports.js +3 -0
- package/dist/room-context.d.ts +60 -0
- package/dist/room-context.js +87 -0
- package/dist/styles/activity-chart.css +127 -0
- package/dist/styles/attachments.css +29 -0
- package/dist/styles/favicon.css +73 -0
- package/dist/styles/history-room.css +18 -0
- package/dist/styles/host-inputs.css +250 -0
- package/dist/styles/image-gallery.css +30 -0
- package/dist/styles/ingest.css +51 -0
- package/dist/styles/message-preview.css +34 -0
- package/dist/styles/models-chart.css +66 -0
- package/dist/styles/project-chart.css +19 -0
- package/dist/styles/reader.css +33 -0
- package/dist/styles/room.css +1411 -0
- package/dist/styles/search.css +252 -0
- package/dist/styles/transcript-activity.css +70 -0
- package/dist/styles/transcript-head.css +220 -0
- package/dist/styles/transcript-loading.css +57 -0
- package/dist/styles/transcript.css +1226 -0
- package/package.json +61 -4
|
@@ -0,0 +1,1411 @@
|
|
|
1
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
2
|
+
THE ROOM — ported from protos/agent-history-proto/index.html §03, class
|
|
3
|
+
names and all: the proto is the fidelity reference, and renaming its
|
|
4
|
+
vocabulary would only make the two harder to diff. App-shell adaptations
|
|
5
|
+
live in the clearly marked section at the end.
|
|
6
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
7
|
+
|
|
8
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
9
|
+
THE ROOM. History is depth 1 on the materiality ladder, and its material is
|
|
10
|
+
PAPER: opaque sheet, no ground bleed. Reading is the job, and translucency
|
|
11
|
+
taxes it. (four-views §3.)
|
|
12
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
13
|
+
.ah-frame {
|
|
14
|
+
position: relative; height: 760px; min-height: 760px;
|
|
15
|
+
border-radius: 22px; overflow: hidden;
|
|
16
|
+
border: 1px solid var(--vf-hairline-strong);
|
|
17
|
+
background: var(--vf-canvas-bg);
|
|
18
|
+
box-shadow: var(--vf-shadow-card);
|
|
19
|
+
/* the ground the room sits over — always underneath, per the ladder */
|
|
20
|
+
background-image: radial-gradient(var(--vf-canvas-dot) 1.2px, transparent 1.2px);
|
|
21
|
+
background-size: 25px 25px;
|
|
22
|
+
--composer-h: 196px;
|
|
23
|
+
color: var(--vf-text-primary);
|
|
24
|
+
}
|
|
25
|
+
.ah-frame.is-tall { height: 860px; min-height: 860px; }
|
|
26
|
+
|
|
27
|
+
.ah-room {
|
|
28
|
+
position: absolute; inset: 0;
|
|
29
|
+
display: flex; flex-direction: column;
|
|
30
|
+
background: var(--ah-plate);
|
|
31
|
+
backdrop-filter: blur(40px);
|
|
32
|
+
border-top: 1px solid var(--vf-hairline);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Five columns and two guests: projects · sessions · the project's WORKTREE ·
|
|
36
|
+
the messages · what THIS SESSION touched. Each tree opens from the head of
|
|
37
|
+
the column it describes and sits immediately to that column's right, so a
|
|
38
|
+
tree is always beside its owner rather than across the room from it. The
|
|
39
|
+
measure keeps the middle and takes back whatever a closed guest gives up.
|
|
40
|
+
H-3 is unchanged and now has two subjects: guests yield, the measure never
|
|
41
|
+
does — and when both guests want a room that seats one, the newer takes the
|
|
42
|
+
seat and the room says so. */
|
|
43
|
+
.ah-cols {
|
|
44
|
+
display: grid; height: 100%;
|
|
45
|
+
grid-template-columns: 260px 300px 280px minmax(0, 1fr);
|
|
46
|
+
transition: grid-template-columns 240ms var(--vf-ease-island);
|
|
47
|
+
}
|
|
48
|
+
.ah-cols[data-rail="off"] { grid-template-columns: 260px 300px 0px minmax(0, 1fr); }
|
|
49
|
+
/* Four tracks, not the record's five. The design draws the worktree and the
|
|
50
|
+
session's git as two guests opening from two heads; they are one column
|
|
51
|
+
here — three tabs over one checkout — so the fifth track has nothing to
|
|
52
|
+
hold and a closed guest is the third track at 0px.
|
|
53
|
+
A closed guest leaves nothing behind, including its own hairline, which
|
|
54
|
+
would otherwise stand beside its neighbour's as a second line. */
|
|
55
|
+
.ah-cols[data-rail="off"] .ah-col--rail,
|
|
56
|
+
.ah-col--measure { border-right: 0; }
|
|
57
|
+
/* the transcript head carries a range and an act, so they travel together */
|
|
58
|
+
.ah-headacts { display: flex; align-items: center; gap: 8px; flex: none; }
|
|
59
|
+
|
|
60
|
+
.ah-col { min-width: 0; display: flex; flex-direction: column; border-right: 1px solid var(--vf-hairline); overflow: hidden; }
|
|
61
|
+
.ah-col:last-child { border-right: 0; }
|
|
62
|
+
/* One band across all four columns. The padding is horizontal only and the
|
|
63
|
+
height is the band's: a header holding a 26px segmented control used to
|
|
64
|
+
stand 1px taller than one holding a 15px eyebrow, which put a visible
|
|
65
|
+
step in the line that is supposed to run the width of the room. */
|
|
66
|
+
.ah-col > header {
|
|
67
|
+
display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
68
|
+
min-height: 46px; padding: 0 14px;
|
|
69
|
+
border-bottom: 1px solid var(--vf-hairline);
|
|
70
|
+
}
|
|
71
|
+
.ah-col > header > div { min-width: 0; }
|
|
72
|
+
.ah-eyebrow {
|
|
73
|
+
display: block; color: var(--vf-text-tertiary);
|
|
74
|
+
font-size: 10px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.07em;
|
|
75
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
76
|
+
}
|
|
77
|
+
.ah-caption { color: var(--vf-text-faint); font-size: 10px; white-space: nowrap; }
|
|
78
|
+
/* CB-4 — every room's scroll container reserves the capsule's height plus 16. */
|
|
79
|
+
.ah-scroll {
|
|
80
|
+
flex: 1; overflow-y: auto; scrollbar-width: none;
|
|
81
|
+
padding: 6px 6px calc(var(--composer-h) + 16px);
|
|
82
|
+
}
|
|
83
|
+
.ah-scroll::-webkit-scrollbar { display: none; }
|
|
84
|
+
.ah-scroll[data-flush] { padding-left: 0; padding-right: 0; }
|
|
85
|
+
/* FLIP owns row displacement; browser anchoring must not jump the viewport
|
|
86
|
+
halfway through a sort. Scrolling itself never starts an animation. */
|
|
87
|
+
.ah-motion-list { position: relative; overflow-anchor: none; }
|
|
88
|
+
.ah-list-view { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
89
|
+
.ah-list-update-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
/* ── Projects ─────────────────────────────────────────────────────────────
|
|
93
|
+
The tint wash is scaled to the busiest project in the complete collection,
|
|
94
|
+
so filtering never changes the visual meaning of a project's width. */
|
|
95
|
+
.ah-project-list-item {
|
|
96
|
+
position: relative; isolation: isolate;
|
|
97
|
+
display: grid; grid-template-columns: 3px minmax(0, 1fr); gap: 0 11px;
|
|
98
|
+
width: 100%; padding: 11px 12px 12px; margin-bottom: 3px;
|
|
99
|
+
border: 0; border-radius: 12px; background: transparent; text-align: left;
|
|
100
|
+
transition: background-color 160ms ease;
|
|
101
|
+
}
|
|
102
|
+
.ah-project-list-item > * { position: relative; z-index: 1; }
|
|
103
|
+
.ah-project-list-item::before {
|
|
104
|
+
content: ""; position: absolute; z-index: 0; inset: 0 auto 0 0;
|
|
105
|
+
width: max(3px, var(--spend-share)); border-radius: 12px;
|
|
106
|
+
background: linear-gradient(90deg,
|
|
107
|
+
color-mix(in srgb, var(--project-color) 15%, transparent) 0%,
|
|
108
|
+
color-mix(in srgb, var(--project-color) 8%, transparent) 64%,
|
|
109
|
+
color-mix(in srgb, var(--project-color) 0%, transparent) 100%);
|
|
110
|
+
transition: width 300ms var(--vf-ease-island);
|
|
111
|
+
}
|
|
112
|
+
.ah-project-list-item:hover { background: color-mix(in srgb, var(--vf-foreground) 5%, transparent); }
|
|
113
|
+
.ah-project-list-item.is-selected { background: color-mix(in srgb, var(--vf-foreground) 7%, transparent); }
|
|
114
|
+
.ah-project-list-item__accent {
|
|
115
|
+
grid-column: 1; grid-row: 1 / span 3; align-self: stretch;
|
|
116
|
+
width: 3px; border-radius: 999px; background: var(--project-color);
|
|
117
|
+
opacity: 0.45; transition: opacity 160ms ease;
|
|
118
|
+
}
|
|
119
|
+
.ah-project-list-item.is-selected .ah-project-list-item__accent { opacity: 1; }
|
|
120
|
+
.ah-project-list-item__header { grid-column: 2; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; }
|
|
121
|
+
.ah-project-list-item__path { grid-column: 2; margin-top: 3px; min-width: 0; }
|
|
122
|
+
.ah-project-list-item__footer { grid-column: 2; display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 6px; }
|
|
123
|
+
.ah-project-list-item__metrics { display: flex; align-items: center; gap: 9px; min-width: 0; }
|
|
124
|
+
.ah-project-list-item strong { display: block; min-width: 0; font-size: 12.5px; font-weight: 500; color: var(--vf-text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
125
|
+
.ah-project-list-item small {
|
|
126
|
+
display: block; min-width: 0; padding-top: 1px; color: var(--vf-text-faint);
|
|
127
|
+
font-size: 10px; font-family: var(--vf-font-mono);
|
|
128
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
129
|
+
}
|
|
130
|
+
.ah-last {
|
|
131
|
+
color: var(--vf-text-faint); font-size: 9.5px; line-height: 1;
|
|
132
|
+
font-variant-numeric: tabular-nums; white-space: nowrap;
|
|
133
|
+
}
|
|
134
|
+
.ah-project-list-item.is-selected .ah-last,
|
|
135
|
+
.ah-project-list-item:hover .ah-last { color: var(--vf-text-tertiary); }
|
|
136
|
+
.ah-project-list-item .ah-last[data-live] { color: var(--vf-green); font-weight: 500; }
|
|
137
|
+
|
|
138
|
+
.ah-project-list-item__token-figure { display: inline-flex; align-items: baseline; gap: 1px; flex: none; font-variant-numeric: tabular-nums; }
|
|
139
|
+
.ah-project-list-item__token-figure b { min-width: 29px; text-align: right; color: var(--vf-text-secondary); font-size: 11px; font-weight: 500; }
|
|
140
|
+
.ah-project-list-item__token-figure i { width: 7px; color: var(--vf-text-faint); font-size: 9.5px; font-style: normal; }
|
|
141
|
+
.ah-project-list-item.is-selected .ah-project-list-item__token-figure b { color: var(--vf-text-primary); }
|
|
142
|
+
|
|
143
|
+
/* The activity shape: 30 days in 15 two-day buckets, normalised to this
|
|
144
|
+
project's own peak. It answers "when", never "how much". */
|
|
145
|
+
.ah-project-activity-sparkline { display: flex; align-items: flex-end; gap: 1px; width: 96px; height: 14px; flex: none; }
|
|
146
|
+
.ah-project-activity-sparkline i {
|
|
147
|
+
flex: 1 1 0; min-width: 0; height: var(--h); border-radius: 1px;
|
|
148
|
+
background: var(--project-color); opacity: 0.38; transition: opacity 160ms ease;
|
|
149
|
+
}
|
|
150
|
+
.ah-project-list-item:hover .ah-project-activity-sparkline i,
|
|
151
|
+
.ah-project-list-item.is-selected .ah-project-activity-sparkline i { opacity: 0.72; }
|
|
152
|
+
/* A bucket with nothing in it is drawn as a hairline rather than as nothing,
|
|
153
|
+
so a dead stretch reads as measured-and-empty instead of as missing. */
|
|
154
|
+
.ah-project-activity-sparkline i[data-zero] { height: 1px; opacity: 0.28; }
|
|
155
|
+
|
|
156
|
+
/* ── the agent marks ──────────────────────────────────────────────────────
|
|
157
|
+
lobehub marks, monochrome on the row's ramp. Opacity ranks them by share
|
|
158
|
+
against this project's lead agent, so the leftmost mark is also the darkest
|
|
159
|
+
and the row reads as an ordering rather than as a set. */
|
|
160
|
+
.ah-agents { display: inline-flex; align-items: center; justify-content: flex-end; gap: 4px; flex: 0 0 58px; }
|
|
161
|
+
.ah-agent { display: inline-flex; width: 12px; height: 12px; flex: none; color: var(--vf-text-primary); }
|
|
162
|
+
.ah-agent svg { width: 100%; height: 100%; display: block; }
|
|
163
|
+
.ah-agent--generic {
|
|
164
|
+
align-items: center; justify-content: center; border: 1px solid currentColor;
|
|
165
|
+
border-radius: 999px; font-size: 5.5px; font-weight: 700; line-height: 1;
|
|
166
|
+
letter-spacing: -0.02em;
|
|
167
|
+
}
|
|
168
|
+
.ah-more { color: var(--vf-text-faint); font-size: 8.5px; font-variant-numeric: tabular-nums; }
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
/* ── search lives in styles/search.css: a launcher in the strip, a sheet
|
|
172
|
+
over the room (search record, 2026-09-09). The key cap stays here because
|
|
173
|
+
every surface that names a shortcut wears it. */
|
|
174
|
+
.ah-kbd {
|
|
175
|
+
flex: none; padding: 2px 6px;
|
|
176
|
+
border: 1px solid var(--vf-hairline-strong); border-radius: 6px;
|
|
177
|
+
color: var(--vf-text-faint); font-family: var(--vf-font-sans); font-size: 10px; line-height: 1.4;
|
|
178
|
+
}
|
|
179
|
+
/* the rank control sits with the list it ranks, not in the header band: the
|
|
180
|
+
band names what a column holds, and ordering is not part of the name. */
|
|
181
|
+
.ah-listbar { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 12px 3px; }
|
|
182
|
+
.ah-sortseg { flex: none; margin-left: auto; }
|
|
183
|
+
.ah-seg.ah-sortseg button { height: 19px; padding: 0 8px; font-size: 9.5px; }
|
|
184
|
+
|
|
185
|
+
/* ── the treemap ──────────────────────────────────────────────────────────
|
|
186
|
+
Area is quantity and hue is identity. Layout uses the measured container
|
|
187
|
+
ratio, and tiny interactive targets receive a documented minimum area. */
|
|
188
|
+
.ah-treemap { width: 100%; }
|
|
189
|
+
.ah-treemap__plot { position: relative; width: 100%; }
|
|
190
|
+
.ah-treemap__item { position: absolute; border: 0; padding: 0; background: transparent; }
|
|
191
|
+
.ah-treemap__item-content {
|
|
192
|
+
position: absolute; inset: 0 2px 2px 0; border-radius: 4px;
|
|
193
|
+
overflow: hidden;
|
|
194
|
+
background: color-mix(in srgb, var(--treemap-item-color) 26%, transparent);
|
|
195
|
+
transition: background-color 160ms ease, box-shadow 160ms ease;
|
|
196
|
+
}
|
|
197
|
+
.ah-treemap__item:hover .ah-treemap__item-content {
|
|
198
|
+
background: color-mix(in srgb, var(--treemap-item-color) 42%, transparent);
|
|
199
|
+
}
|
|
200
|
+
.ah-treemap__item.is-selected .ah-treemap__item-content {
|
|
201
|
+
background: color-mix(in srgb, var(--treemap-item-color) 58%, transparent);
|
|
202
|
+
box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--treemap-item-color) 90%, transparent);
|
|
203
|
+
}
|
|
204
|
+
.ah-treemap__item b {
|
|
205
|
+
position: absolute; left: 6px; right: 6px; top: 5px;
|
|
206
|
+
font-size: 9px; font-weight: 500; line-height: 11px; color: var(--vf-text-secondary);
|
|
207
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left;
|
|
208
|
+
}
|
|
209
|
+
.ah-treemap__item em {
|
|
210
|
+
position: absolute; right: 6px; bottom: 4px;
|
|
211
|
+
font-style: normal; font-size: 9.5px; line-height: 11px; font-variant-numeric: tabular-nums;
|
|
212
|
+
color: var(--vf-text-primary);
|
|
213
|
+
}
|
|
214
|
+
.ah-treemap__item:focus-visible { outline: 2px solid var(--vf-select); outline-offset: 1px; border-radius: 5px; }
|
|
215
|
+
.ah-treemap__empty, .ah-streamgraph__empty {
|
|
216
|
+
display: grid; place-items: center; height: 100%; margin: 0;
|
|
217
|
+
color: var(--vf-text-faint); font-size: 8.5px; text-align: center;
|
|
218
|
+
}
|
|
219
|
+
.ah-treemap__footer {
|
|
220
|
+
display: flex; align-items: center; justify-content: space-between; gap: 10px;
|
|
221
|
+
margin-top: 8px; color: var(--vf-text-faint); font-size: 9px;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/* ═══════════════════════════════════════════════════════════════════════
|
|
225
|
+
THE SUMMARY PANEL — what the ledger row's figure decomposes into.
|
|
226
|
+
A READER: no cards, no material, hairlines and the ramp doing the
|
|
227
|
+
hierarchy (§8's file-tree law, one surface over).
|
|
228
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
229
|
+
/* The block now heads its own column — there is no separate column header
|
|
230
|
+
above it — so its head takes the header band's metrics (46px, hairline
|
|
231
|
+
beneath) and the room's header line runs unbroken across all four columns.
|
|
232
|
+
Collapsed, only the head and that one hairline remain. */
|
|
233
|
+
.ah-meta { flex: none; }
|
|
234
|
+
.ah-meta__head {
|
|
235
|
+
display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
236
|
+
min-height: 46px; padding: 0 12px;
|
|
237
|
+
border-bottom: 1px solid var(--vf-hairline);
|
|
238
|
+
}
|
|
239
|
+
.ah-meta__body { padding: 10px 12px 12px; border-bottom: 1px solid var(--vf-hairline); }
|
|
240
|
+
/* ── the column head ──────────────────────────────────────────────────────
|
|
241
|
+
Two columns name the thing they are showing — ② a project, ③ a session —
|
|
242
|
+
and they are the same object at different depths, so they are one component:
|
|
243
|
+
tint marker, name, count. Nothing about them may drift apart. */
|
|
244
|
+
.ah-colhead { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
245
|
+
.ah-colhead > i { flex: none; width: 3px; height: 14px; border-radius: 999px; background: var(--tint); }
|
|
246
|
+
.ah-colhead > strong {
|
|
247
|
+
font-size: 11.5px; font-weight: 500; color: var(--vf-text-primary);
|
|
248
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
249
|
+
}
|
|
250
|
+
/* a path and a branch are ids, so they set in mono — the same rule the sha
|
|
251
|
+
follows. The head keeps its size and weight; only the face changes. */
|
|
252
|
+
.ah-colhead > strong.ah-idname { font-family: var(--vf-font-mono); font-size: 11px; letter-spacing: -0.01em; }
|
|
253
|
+
/* the count is a fact about the name, so it travels with it rather than
|
|
254
|
+
sitting at the far end of the band. Neutral fill, never the tint: the
|
|
255
|
+
marker two elements over already says which project this is. */
|
|
256
|
+
.ah-bubble {
|
|
257
|
+
flex: none; display: inline-flex; align-items: center; justify-content: center;
|
|
258
|
+
min-width: 19px; height: 16px; padding: 0 5px; border-radius: 999px;
|
|
259
|
+
background: var(--vf-fill); color: var(--vf-text-tertiary);
|
|
260
|
+
font-size: 9.5px; font-weight: 500; letter-spacing: 0; font-variant-numeric: tabular-nums;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/* two acts, standing on the fill at rest so the head reads as two controls
|
|
264
|
+
rather than two glyphs. The pressed step is the segmented control's own —
|
|
265
|
+
thumb over track — so a thing that is ON looks the same everywhere here. */
|
|
266
|
+
.ah-meta__acts { display: flex; align-items: center; gap: 4px; flex: none; }
|
|
267
|
+
.ah-iconbtn {
|
|
268
|
+
display: grid; place-items: center; width: 26px; height: 26px; flex: none;
|
|
269
|
+
border: 0; border-radius: 8px; background: var(--vf-fill); color: var(--vf-text-tertiary);
|
|
270
|
+
transition: color 160ms ease, background-color 160ms ease;
|
|
271
|
+
}
|
|
272
|
+
.ah-iconbtn:hover { color: var(--vf-text-primary); background: var(--vf-fill-hover); }
|
|
273
|
+
.ah-iconbtn[aria-pressed="true"] {
|
|
274
|
+
color: var(--vf-foreground); background: var(--vf-chrome-solid); box-shadow: 0 1px 3px rgb(0 0 0 / 8%);
|
|
275
|
+
}
|
|
276
|
+
.dark .ah-iconbtn[aria-pressed="true"] {
|
|
277
|
+
background: color-mix(in srgb, var(--vf-foreground) 20%, transparent); box-shadow: none;
|
|
278
|
+
}
|
|
279
|
+
.ah-iconbtn svg { width: 14px; height: 14px; }
|
|
280
|
+
|
|
281
|
+
/* The two views use the segmented control the ledger already uses to rank
|
|
282
|
+
itself. Mutually exclusive pressed buttons keep the interaction explicit
|
|
283
|
+
without claiming the full keyboard contract of ARIA tabs. */
|
|
284
|
+
.ah-seg.ah-tabseg { margin-bottom: 9px; }
|
|
285
|
+
.ah-seg.ah-tabseg button { height: 21px; padding: 0 11px; font-size: 10px; }
|
|
286
|
+
|
|
287
|
+
/* The switch and the chart it switches are one object, so they share one
|
|
288
|
+
fill — the same step the four chips stand on. Inside the card the seg's
|
|
289
|
+
track would vanish into it, so the track takes a further step up the ramp;
|
|
290
|
+
the thumb keeps its own. Three steps, and each one still reads. */
|
|
291
|
+
.ah-chartcard { padding: 9px; border-radius: 12px; background: var(--vf-fill); }
|
|
292
|
+
.ah-chartcard .ah-seg { background: color-mix(in srgb, var(--vf-foreground) 7%, transparent); }
|
|
293
|
+
|
|
294
|
+
/* four chips, not four cards: a fill on the same surface, no border and no
|
|
295
|
+
shadow — they group the figures without pretending to float (§5). */
|
|
296
|
+
/* Four equal quarters of a 260px column leave 46px for a label that needs 54,
|
|
297
|
+
so the tracks are floored at their own content and share what is left. The
|
|
298
|
+
chips come out slightly unequal in the narrow column and equal in the wide
|
|
299
|
+
one — which is the honest way round: the width follows the word, and no
|
|
300
|
+
label is ever cut to keep a grid tidy. */
|
|
301
|
+
.ah-stats { margin-bottom: 10px; display: grid; grid-template-columns: repeat(4, minmax(min-content, 1fr)); gap: 3px; }
|
|
302
|
+
.ah-stat { min-width: 0; padding: 7px 3px 6px; border-radius: 9px; background: var(--vf-fill); }
|
|
303
|
+
.ah-stat b {
|
|
304
|
+
display: block; font-size: 15px; font-weight: 300; line-height: 1.05;
|
|
305
|
+
letter-spacing: -0.015em; font-variant-numeric: tabular-nums; color: var(--vf-text-primary);
|
|
306
|
+
white-space: nowrap;
|
|
307
|
+
}
|
|
308
|
+
.ah-stat b small { font-size: 10px; color: var(--vf-text-faint); margin-left: 1px; font-weight: 400; }
|
|
309
|
+
.ah-stat span {
|
|
310
|
+
display: block; margin-top: 4px; color: var(--vf-text-faint);
|
|
311
|
+
font-size: 8px; font-weight: 500; text-transform: uppercase;
|
|
312
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/* ── the calendar heatmap ─────────────────────────────────────────────────
|
|
316
|
+
53 weeks across, days down. The scale is the project's own §2.6 accent at
|
|
317
|
+
four steps of alpha — never a hue ramp: colour in this room means *which*,
|
|
318
|
+
and a heat scale that ignored that would be the one thing on screen using
|
|
319
|
+
hue for quantity. An empty day is a faint square rather than nothing: the
|
|
320
|
+
day was measured and was empty, which is not the same as missing. */
|
|
321
|
+
.ah-calendar-heatmap__axis { margin: 10px 0 3px; height: 10px; position: relative; }
|
|
322
|
+
.ah-calendar-heatmap__axis span {
|
|
323
|
+
position: absolute; top: 0; color: var(--vf-text-faint);
|
|
324
|
+
font-size: 8px; letter-spacing: 0.02em; white-space: nowrap;
|
|
325
|
+
}
|
|
326
|
+
.ah-calendar-heatmap__grid { display: flex; gap: 1px; }
|
|
327
|
+
.ah-calendar-heatmap__week { display: flex; flex-direction: column; gap: 1px; flex: 1 1 0; min-width: 0; }
|
|
328
|
+
.ah-calendar-heatmap__cell {
|
|
329
|
+
display: block; width: 100%; aspect-ratio: 1; border-radius: 1px;
|
|
330
|
+
background: color-mix(in srgb, var(--heatmap-color) calc(var(--heatmap-intensity) * 25%), transparent);
|
|
331
|
+
}
|
|
332
|
+
.ah-calendar-heatmap__cell[data-empty] { background: color-mix(in srgb, var(--vf-foreground) 7%, transparent); }
|
|
333
|
+
.ah-calendar-heatmap__cell[data-unavailable] { visibility: hidden; }
|
|
334
|
+
.ah-calendar-heatmap__footer {
|
|
335
|
+
display: flex; align-items: center; justify-content: space-between; gap: 10px;
|
|
336
|
+
margin-top: 8px; color: var(--vf-text-faint); font-size: 9px;
|
|
337
|
+
}
|
|
338
|
+
.ah-calendar-heatmap__legend { display: flex; align-items: center; gap: 3px; }
|
|
339
|
+
.ah-calendar-heatmap__legend i {
|
|
340
|
+
width: 7px; height: 7px; border-radius: 2px;
|
|
341
|
+
background: color-mix(in srgb, var(--heatmap-color) calc(var(--heatmap-intensity) * 25%), transparent);
|
|
342
|
+
}
|
|
343
|
+
.ah-calendar-heatmap__legend i[data-empty] { background: color-mix(in srgb, var(--vf-foreground) 7%, transparent); }
|
|
344
|
+
|
|
345
|
+
/* ── the streamgraph ──────────────────────────────────────────────────────
|
|
346
|
+
A model is an object being grouped, which is precisely what §2.6's accents
|
|
347
|
+
are for — so each model takes one, assigned stably by id. The project tint
|
|
348
|
+
and the model tints never share a chart; the legend names every line. */
|
|
349
|
+
/* Both tabs draw into one box of fixed height, so switching between them
|
|
350
|
+
never moves the session list below. */
|
|
351
|
+
.ah-tabbody { height: 106px; display: flex; flex-direction: column; justify-content: space-between; }
|
|
352
|
+
.ah-chart-header { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
|
|
353
|
+
.ah-chart-header__title { margin: 0; color: var(--vf-text-tertiary); font-size: 9px; font-weight: 500; }
|
|
354
|
+
.ah-chart-header__note { color: var(--vf-text-faint); font-size: 8.5px; }
|
|
355
|
+
.ah-streamgraph { display: flex; flex: 1; min-height: 0; flex-direction: column; }
|
|
356
|
+
.ah-streamgraph__plot { flex: 1; min-height: 0; }
|
|
357
|
+
.ah-streamgraph__plot svg { display: block; width: 100%; height: 100%; }
|
|
358
|
+
.ah-streamgraph__plot path { opacity: 0.72; }
|
|
359
|
+
.ah-streamgraph__axis { position: relative; height: 10px; margin-top: 3px; color: var(--vf-text-faint); font-size: 8px; font-variant-numeric: tabular-nums; }
|
|
360
|
+
.ah-streamgraph__axis span { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
|
|
361
|
+
.ah-streamgraph__axis span[data-first] { transform: none; }
|
|
362
|
+
.ah-streamgraph__axis span[data-last] { transform: translateX(-100%); }
|
|
363
|
+
.ah-streamgraph__legend { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 11px; margin-top: 3px; }
|
|
364
|
+
.ah-streamgraph__legend span { display: inline-flex; align-items: center; gap: 5px; color: var(--vf-text-tertiary); font-size: 9.5px; }
|
|
365
|
+
.ah-streamgraph__legend i { width: 6px; height: 6px; border-radius: 999px; background: var(--series-color); flex: none; }
|
|
366
|
+
.ah-streamgraph__legend b { color: var(--vf-text-secondary); font-weight: 500; font-variant-numeric: tabular-nums; }
|
|
367
|
+
|
|
368
|
+
.ah-meta__facts { margin: 9px 0 0; color: var(--vf-text-tertiary); font-size: 10px; line-height: 1.5; }
|
|
369
|
+
.ah-meta__facts b { color: var(--vf-text-secondary); font-weight: 500; font-variant-numeric: tabular-nums; }
|
|
370
|
+
|
|
371
|
+
/* ── Sessions ───────────────────────────────────────────────────────────── */
|
|
372
|
+
/* The list already sits beneath its own toolbar. The shared scroll inset
|
|
373
|
+
would hold a sticky day header below that bar and expose the row behind it. */
|
|
374
|
+
.ah-session-list { padding-top: 0; }
|
|
375
|
+
.ah-session-list > .ah-day:first-child { margin-top: 0; }
|
|
376
|
+
/* A 128-session list without day breaks is undifferentiated, so the days are
|
|
377
|
+
drawn — sticky, quiet, and never a card. */
|
|
378
|
+
.ah-day {
|
|
379
|
+
position: sticky; top: 0; z-index: 2;
|
|
380
|
+
padding: 10px 10px 5px; margin-top: 4px;
|
|
381
|
+
background: linear-gradient(var(--ah-plate) 72%, transparent);
|
|
382
|
+
color: var(--vf-text-faint); font-size: 9.5px; font-weight: 500;
|
|
383
|
+
text-transform: uppercase; letter-spacing: 0.08em;
|
|
384
|
+
}
|
|
385
|
+
/* The session row answers the same four questions the ledger row does, in the
|
|
386
|
+
same corners: state and title on the first line, the agent top-right, the
|
|
387
|
+
facts in the middle, the branch bottom-left and the time bottom-right. */
|
|
388
|
+
.ah-session-list-item {
|
|
389
|
+
display: grid; grid-template-columns: 8px minmax(0, 1fr); gap: 0 9px;
|
|
390
|
+
width: 100%; padding: 8px 10px 9px; border: 0; border-radius: 11px;
|
|
391
|
+
background: transparent; text-align: left;
|
|
392
|
+
transition: background-color 160ms ease, box-shadow 160ms ease;
|
|
393
|
+
}
|
|
394
|
+
.ah-session-list-item:hover { background: var(--vf-fill); }
|
|
395
|
+
/* location, not interaction — the same law the tree states (§8 file tree) */
|
|
396
|
+
.ah-session-list-item.is-selected {
|
|
397
|
+
background: var(--vf-fill);
|
|
398
|
+
box-shadow: inset 0 0 0 1.5px var(--vf-select);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* The state is the dot and only the dot — the word it replaced was saying the
|
|
402
|
+
same thing twice. §2.5's meanings, unchanged: green working, orange needs
|
|
403
|
+
attention, red failed, muted done or idle. */
|
|
404
|
+
.ah-session-list-item__status {
|
|
405
|
+
grid-column: 1; grid-row: 1; align-self: center; width: 8px; height: 8px;
|
|
406
|
+
border-radius: 999px; background: var(--vf-text-faint);
|
|
407
|
+
}
|
|
408
|
+
.ah-session-list-item__status[data-tone="green"] { background: var(--vf-green); }
|
|
409
|
+
.ah-session-list-item__status[data-tone="orange"] { background: var(--vf-orange); }
|
|
410
|
+
.ah-session-list-item__status[data-tone="red"] { background: var(--vf-red); }
|
|
411
|
+
/* live is the one state that is still happening, so it also breathes */
|
|
412
|
+
.ah-session-list-item__status[data-live] { box-shadow: 0 0 0 3px color-mix(in srgb, var(--vf-green) 22%, transparent); }
|
|
413
|
+
|
|
414
|
+
.ah-session-list-item__header { grid-column: 2; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-width: 0; min-height: 16px; }
|
|
415
|
+
.ah-session-list-item__footer { grid-column: 2; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; min-width: 0; }
|
|
416
|
+
.ah-session-list-item strong { display: block; min-width: 0; font-size: 12px; font-weight: 500; color: var(--vf-text-primary); line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
417
|
+
.ah-session-list-item__metadata {
|
|
418
|
+
grid-column: 2; display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 3px;
|
|
419
|
+
color: var(--vf-text-faint); font-size: 10px; font-variant-numeric: tabular-nums;
|
|
420
|
+
}
|
|
421
|
+
/* the branch is an id, so it is mono (§3) */
|
|
422
|
+
.ah-session-list-item__native-id {
|
|
423
|
+
display: inline-flex; align-items: center; gap: 4px; min-width: 0;
|
|
424
|
+
color: var(--vf-text-tertiary); font-family: var(--vf-font-mono); font-size: 9.5px;
|
|
425
|
+
}
|
|
426
|
+
.ah-session-list-item__native-id span { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
427
|
+
.ah-session-list-item .ah-last { flex: none; }
|
|
428
|
+
.ah-session-list-item:hover .ah-last,
|
|
429
|
+
.ah-session-list-item.is-selected .ah-last { color: var(--vf-text-tertiary); }
|
|
430
|
+
.ah-session-list-item .ah-last[data-live] { color: var(--vf-green); font-weight: 500; }
|
|
431
|
+
.ah-session-list-item .ah-agent { width: 12px; height: 12px; opacity: 0.5; }
|
|
432
|
+
.ah-session-list-item:hover .ah-agent,
|
|
433
|
+
.ah-session-list-item.is-selected .ah-agent { opacity: 0.7; }
|
|
434
|
+
.ah-session-list-item[data-role="subagent"] .ah-session-list-item__status,
|
|
435
|
+
.ah-session-list-item[data-role="team"] .ah-session-list-item__status { transform: scale(0.72); }
|
|
436
|
+
|
|
437
|
+
/* the only control in its row, so it takes the row: the same track and the
|
|
438
|
+
same thumb, stretched — a switch's shape is its material, not its width */
|
|
439
|
+
/* the two change groups head themselves like search's result groups do */
|
|
440
|
+
/* Scoped to the rail because the record's fifth column is gone — files,
|
|
441
|
+
changes and history are three tabs of column ③ now. */
|
|
442
|
+
.ah-col--rail .ah-group { padding-top: 10px; }
|
|
443
|
+
.ah-col--rail .ah-group:first-child { padding-top: 6px; }
|
|
444
|
+
|
|
445
|
+
/* ── the Transcript — a document, not a chat log ─────────────────────────── */
|
|
446
|
+
.ah-transcript { max-width: 68ch; margin: 0 auto; padding: 20px 28px 30px; font-size: 14px; }
|
|
447
|
+
/* the landing ring: a search hit or a focused row is ringed, then the ring
|
|
448
|
+
goes — kept here because both the ledger line and the prose segment take it. */
|
|
449
|
+
@keyframes ah-land {
|
|
450
|
+
0%, 62% { box-shadow: inset 0 0 0 1.5px var(--vf-select); border-radius: 10px; }
|
|
451
|
+
100% { box-shadow: inset 0 0 0 1.5px transparent; border-radius: 10px; }
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/* A quiet return to the live tail, available anywhere above it. Keep the
|
|
455
|
+
control mounted so both arrival and departure can settle without a pop. */
|
|
456
|
+
.ah-newpill {
|
|
457
|
+
position: absolute; left: 50%; bottom: calc(var(--composer-h) + 26px); z-index: 6;
|
|
458
|
+
transform: translate(-50%, 8px) scale(0.96); opacity: 0; visibility: hidden;
|
|
459
|
+
pointer-events: none;
|
|
460
|
+
display: flex; align-items: center; justify-content: center; gap: 8px;
|
|
461
|
+
min-height: 36px; max-width: calc(100% - 32px); padding: 0 14px;
|
|
462
|
+
border: 1px solid var(--vf-hairline-strong); border-radius: 999px;
|
|
463
|
+
background: var(--vf-chrome-surface); backdrop-filter: blur(24px) saturate(1.25);
|
|
464
|
+
box-shadow: var(--vf-shadow-island);
|
|
465
|
+
color: var(--vf-text-secondary); font-size: 11px; font-weight: 500;
|
|
466
|
+
font-variant-numeric: tabular-nums; white-space: nowrap;
|
|
467
|
+
transition: opacity 180ms ease, transform 280ms cubic-bezier(0.22, 1, 0.36, 1),
|
|
468
|
+
background-color 160ms ease, color 160ms ease, visibility 0s linear 180ms;
|
|
469
|
+
}
|
|
470
|
+
.ah-newpill[data-visible] {
|
|
471
|
+
opacity: 1; visibility: visible; pointer-events: auto;
|
|
472
|
+
transform: translate(-50%, 0) scale(1); transition-delay: 0s;
|
|
473
|
+
}
|
|
474
|
+
.ah-newpill:hover { background: var(--vf-chrome-solid); color: var(--vf-text-primary); }
|
|
475
|
+
.ah-newpill[data-unread] { color: var(--vf-text-primary); }
|
|
476
|
+
.ah-newpill:active { transform: translate(-50%, 1px) scale(0.97); }
|
|
477
|
+
.ah-newpill svg { flex: none; }
|
|
478
|
+
.ah-newpill span { overflow: hidden; text-overflow: ellipsis; }
|
|
479
|
+
.ah-newpill i { flex: none; width: 6px; height: 6px; border-radius: 999px; background: var(--vf-green); }
|
|
480
|
+
.ah-tail-announcement {
|
|
481
|
+
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
|
482
|
+
overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
|
|
483
|
+
}
|
|
484
|
+
@keyframes ah-pop { from { opacity: 0; transform: translateX(-50%) translateY(6px) scale(0.92); } to { opacity: 1; transform: translateX(-50%); } }
|
|
485
|
+
|
|
486
|
+
/* ── result groups — the rail's change groups head themselves this way ──── */
|
|
487
|
+
.ah-group {
|
|
488
|
+
display: flex; align-items: center; gap: 8px;
|
|
489
|
+
padding: 12px 10px 6px; margin-top: 2px;
|
|
490
|
+
color: var(--vf-text-faint); font-size: 9.5px; font-weight: 500;
|
|
491
|
+
text-transform: uppercase; letter-spacing: 0.08em;
|
|
492
|
+
}
|
|
493
|
+
.ah-group i { width: 3px; height: 11px; border-radius: 999px; background: var(--tint); flex: none; }
|
|
494
|
+
.ah-hitcount { margin-left: auto; font-variant-numeric: tabular-nums; letter-spacing: 0; }
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
/* ── honest states ──────────────────────────────────────────────────────── */
|
|
499
|
+
.ah-empty {
|
|
500
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
501
|
+
gap: 9px; height: 100%; min-height: 190px; padding: 30px 26px; text-align: center;
|
|
502
|
+
}
|
|
503
|
+
.ah-empty svg { width: 22px; height: 22px; color: var(--vf-text-faint); }
|
|
504
|
+
.ah-empty strong { font-size: 12.5px; font-weight: 500; color: var(--vf-text-secondary); }
|
|
505
|
+
.ah-empty p { margin: 0; max-width: 44ch; color: var(--vf-text-faint); font-size: 11px; line-height: 1.6; }
|
|
506
|
+
.ah-empty code { font-size: 10.5px; }
|
|
507
|
+
/* Loading is colourless — the veil's rule: loading is not a §2.5 state. */
|
|
508
|
+
.ah-meter { width: 132px; height: 3px; border-radius: 999px; background: var(--vf-fill-hover); overflow: hidden; }
|
|
509
|
+
.ah-meter i { display: block; height: 100%; border-radius: 999px; background: var(--vf-text-tertiary); }
|
|
510
|
+
|
|
511
|
+
.ah-seg {
|
|
512
|
+
display: inline-flex; padding: 2px; border-radius: 999px; background: var(--vf-fill);
|
|
513
|
+
}
|
|
514
|
+
.ah-seg button {
|
|
515
|
+
height: 22px; padding: 0 9px; border: 0; border-radius: 999px; background: transparent;
|
|
516
|
+
color: var(--vf-text-tertiary); font-size: 10.5px;
|
|
517
|
+
transition: color 160ms ease, background-color 300ms var(--vf-ease-island);
|
|
518
|
+
}
|
|
519
|
+
.ah-seg button.is-on { color: var(--vf-foreground); background: var(--vf-chrome-solid); box-shadow: 0 1px 3px rgb(0 0 0 / 8%); font-weight: 500; }
|
|
520
|
+
.dark .ah-seg button.is-on { background: color-mix(in srgb, var(--vf-foreground) 20%, transparent); box-shadow: none; }
|
|
521
|
+
|
|
522
|
+
/* DESIGN.md §7 — a visible focus ring, always. Both surfaces are named:
|
|
523
|
+
the file viewer is portalled out of `.ah-room`, and the first thing to
|
|
524
|
+
leave the room fell back to the browser's own ring, in the browser's own
|
|
525
|
+
colour. A focus rule scoped to one container is a rule with a hole in it. */
|
|
526
|
+
.ah-room button:focus-visible,
|
|
527
|
+
.ah-fileview button:focus-visible,
|
|
528
|
+
.ah-fileview a:focus-visible,
|
|
529
|
+
.ah-sheet button:focus-visible { outline: 2px solid var(--vf-select); outline-offset: 2px; }
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
533
|
+
THE ROOM IN ITS HOST — where the specimen page's frame becomes whatever
|
|
534
|
+
holds it: rosetta's window, or another app's slot. Everything above is the
|
|
535
|
+
proto verbatim; everything below is the port. The page itself (html, body,
|
|
536
|
+
the window's drag region, the global motion floor) is the host's:
|
|
537
|
+
rosetta's app keeps it in styles/app.css.
|
|
538
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
539
|
+
|
|
540
|
+
/* The room's own assumptions, scoped to its root and to the layers it
|
|
541
|
+
portals out (`.ah-layer`), at zero specificity so every rule above still
|
|
542
|
+
wins as it did when these were the page's. */
|
|
543
|
+
:where(.ah-frame, .ah-layer), :where(.ah-frame, .ah-layer) * { box-sizing: border-box; }
|
|
544
|
+
:where(.ah-frame, .ah-layer) :where(button, input) { font: inherit; color: inherit; }
|
|
545
|
+
:where(.ah-frame, .ah-layer) :where(button) { cursor: pointer; }
|
|
546
|
+
:where(.ah-frame, .ah-layer) :where(code, .mono) { font-family: var(--vf-font-mono); }
|
|
547
|
+
:where(.ah-frame, .ah-layer) .tnum { font-variant-numeric: tabular-nums; }
|
|
548
|
+
|
|
549
|
+
/* The room's own tokens. `--ah-plate` is the colour its surface reads as —
|
|
550
|
+
the paper it paints, and what its fades and cut-out rings are drawn in. The
|
|
551
|
+
project band (`--tint-*`) is the room's identity system; both themes. */
|
|
552
|
+
:where(.ah-frame, .ah-layer) {
|
|
553
|
+
--ah-plate: var(--vf-sheet-surface);
|
|
554
|
+
--tint-l: 0.60;
|
|
555
|
+
--tint-c: 0.15;
|
|
556
|
+
}
|
|
557
|
+
.dark :where(.ah-frame, .ah-layer) { --tint-l: 0.74; }
|
|
558
|
+
|
|
559
|
+
/* the frame fills what holds it: no radius, no shadow, no fixed height */
|
|
560
|
+
.ah-frame, .ah-frame.is-tall {
|
|
561
|
+
height: 100%; min-height: 0;
|
|
562
|
+
border: 0; border-radius: 0; box-shadow: none;
|
|
563
|
+
font-family: var(--vf-font-sans); -webkit-font-smoothing: antialiased;
|
|
564
|
+
--composer-h: 0px;
|
|
565
|
+
--ah-scroll-foot: calc(32px + env(safe-area-inset-bottom, 0px));
|
|
566
|
+
--ah-floating-foot: calc(24px + env(safe-area-inset-bottom, 0px));
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/* The edges a host keeps clear for its own chrome (HistoryRoom's
|
|
570
|
+
`edgeInset`): the room sits inside its frame by that much. */
|
|
571
|
+
.ah-room {
|
|
572
|
+
inset: var(--ah-inset-top, 0px) var(--ah-inset-right, 0px) var(--ah-inset-bottom, 0px) var(--ah-inset-left, 0px);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/* A host that paints its own surface beneath the room (`surface="host"`):
|
|
576
|
+
no ground, no plate, and the paper fades become frost — a blur of whatever
|
|
577
|
+
passes beneath, feathered by its own mask, under the chrome it grounds.
|
|
578
|
+
A mask on the scroller itself would fade the pinned chrome with the rows. */
|
|
579
|
+
.ah-frame[data-ah-surface="host"] { background: none; }
|
|
580
|
+
.ah-frame[data-ah-surface="host"] .ah-room { background: none; backdrop-filter: none; }
|
|
581
|
+
.ah-frame[data-ah-surface="host"] .tr-frost::before {
|
|
582
|
+
background: none;
|
|
583
|
+
-webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
|
|
584
|
+
-webkit-mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0 / 88%) 38%, transparent 100%);
|
|
585
|
+
mask-image: linear-gradient(to bottom, #000 0%, rgb(0 0 0 / 88%) 38%, transparent 100%);
|
|
586
|
+
}
|
|
587
|
+
.ah-frame[data-ah-surface="host"] .ah-day { background: none; }
|
|
588
|
+
.ah-frame[data-ah-surface="host"] .ah-day::before {
|
|
589
|
+
content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
|
|
590
|
+
-webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
|
|
591
|
+
-webkit-mask-image: linear-gradient(#000 72%, transparent);
|
|
592
|
+
mask-image: linear-gradient(#000 72%, transparent);
|
|
593
|
+
}
|
|
594
|
+
/* The search strip takes its own height. The grid fills only what remains:
|
|
595
|
+
a 100% height with an automatic minimum pushed every column's foot below
|
|
596
|
+
the window, including the transcript's absolutely positioned control. */
|
|
597
|
+
.ah-cols { flex: 1; height: auto; min-height: 0; grid-template-rows: minmax(0, 1fr); }
|
|
598
|
+
.ah-col { min-height: 0; }
|
|
599
|
+
/* Real scrollable space after the last row, also respected by keyboard
|
|
600
|
+
reveals. The fallback keeps standalone component previews comfortable. */
|
|
601
|
+
.ah-scroll {
|
|
602
|
+
min-height: 0;
|
|
603
|
+
padding-bottom: var(--ah-scroll-foot, 32px);
|
|
604
|
+
scroll-padding-bottom: var(--ah-scroll-foot, 32px);
|
|
605
|
+
}
|
|
606
|
+
.ah-newpill { bottom: var(--ah-floating-foot, 24px); }
|
|
607
|
+
.ah-list-updates { bottom: 16px; }
|
|
608
|
+
.ah-list-updates[hidden] { display: none; }
|
|
609
|
+
/* Four columns: the worktree rail is real now (the proto's base grid rules
|
|
610
|
+
above already carry the rail track and its H-3 close); the footprint
|
|
611
|
+
guest still waits on Q4, so its 0px fifth track stays empty. */
|
|
612
|
+
|
|
613
|
+
/* `ah-rail*` throughout is the design record's vocabulary, not the app's:
|
|
614
|
+
this file is a port of the proto §03 class names and all, and the two are
|
|
615
|
+
diffed against each other. The React side calls the column what it shows
|
|
616
|
+
— `components/worktree` — and leaves the stylesheet speaking the record's
|
|
617
|
+
language.
|
|
618
|
+
|
|
619
|
+
Files take 70% of the area below the tabs and worktrees take 30%, including
|
|
620
|
+
their heading. Both scroll independently; expanding a folder never moves
|
|
621
|
+
the divider. With no sibling worktrees, files take the whole area. */
|
|
622
|
+
.ah-railbody { flex: 1; min-height: 0; display: grid; grid-template-rows: minmax(0, 1fr); }
|
|
623
|
+
.ah-railbody[data-split] { grid-template-rows: minmax(0, 7fr) minmax(0, 3fr); }
|
|
624
|
+
.ah-railtree { height: 100%; min-height: 0; padding: 6px 6px 0; }
|
|
625
|
+
.ah-railtree[data-mille-theme] [role="tree"] {
|
|
626
|
+
padding-bottom: var(--ah-scroll-foot, 32px);
|
|
627
|
+
scroll-padding-bottom: var(--ah-scroll-foot, 32px);
|
|
628
|
+
overscroll-behavior-y: contain;
|
|
629
|
+
}
|
|
630
|
+
/* the engine lags a project switch: the old tree dims rather than lies */
|
|
631
|
+
.ah-railtree[data-stale] { opacity: 0.45; transition: opacity 160ms; }
|
|
632
|
+
/* Keep the worktree heading fixed above its scrollable list. */
|
|
633
|
+
.ah-railfoot { display: flex; flex-direction: column; min-height: 0; }
|
|
634
|
+
.ah-railfoot__list {
|
|
635
|
+
flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior-y: contain; scrollbar-width: thin;
|
|
636
|
+
padding: 0 6px var(--ah-scroll-foot, 32px);
|
|
637
|
+
scroll-padding-bottom: var(--ah-scroll-foot, 32px);
|
|
638
|
+
}
|
|
639
|
+
.ah-railfoot__list:focus-visible { outline: 2px solid var(--vf-select); outline-offset: -2px; }
|
|
640
|
+
.ah-railsplit { flex: none; margin: 12px 12px 6px; padding-top: 12px; border-top: 1px solid var(--vf-hairline); }
|
|
641
|
+
.ah-worktree {
|
|
642
|
+
display: flex; align-items: center; justify-content: space-between; gap: 8px;
|
|
643
|
+
width: 100%; padding: 7px 9px; border: 0; border-radius: 9px; background: transparent;
|
|
644
|
+
color: var(--vf-text-secondary); font-size: 11.5px; text-align: left;
|
|
645
|
+
}
|
|
646
|
+
.ah-worktree code { font-size: 10px; color: var(--vf-text-faint); font-variant-numeric: tabular-nums; }
|
|
647
|
+
.ah-worktree code[data-dirty] { color: var(--vf-cyan); }
|
|
648
|
+
|
|
649
|
+
/* a receipt, so a copy or an act is never silent */
|
|
650
|
+
.ah-receipt {
|
|
651
|
+
position: absolute; left: 50%; bottom: 26px; z-index: 45;
|
|
652
|
+
transform: translateX(-50%);
|
|
653
|
+
display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 14px;
|
|
654
|
+
border: 1px solid var(--vf-hairline); border-radius: 999px;
|
|
655
|
+
background: var(--vf-chrome-surface); backdrop-filter: blur(20px);
|
|
656
|
+
box-shadow: var(--vf-shadow-island);
|
|
657
|
+
color: var(--vf-text-secondary); font-size: 11px;
|
|
658
|
+
animation: ah-pop 280ms var(--vf-ease-pop);
|
|
659
|
+
}
|
|
660
|
+
.ah-receipt[hidden] { display: none; }
|
|
661
|
+
|
|
662
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
663
|
+
THE COLD START — the veil system (design record supplement "The Cold
|
|
664
|
+
Start"). Readiness is data, never a timer; only the ready may claim
|
|
665
|
+
emptiness; a veil overlays and never changes geometry (H-2).
|
|
666
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
667
|
+
|
|
668
|
+
/* the veil's host: any section that can frost over. The content beneath
|
|
669
|
+
keeps rendering and updating — that motion IS the progress animation. */
|
|
670
|
+
.ah-veilhost { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
671
|
+
.ah-veilhost > .ah-scroll { flex: 1; }
|
|
672
|
+
/* a panel body is its own host: it keeps its size and only frosts */
|
|
673
|
+
.ah-meta__body.ah-veilhost { flex: none; display: block; }
|
|
674
|
+
|
|
675
|
+
.ah-veil {
|
|
676
|
+
position: absolute; inset: 0; z-index: 5;
|
|
677
|
+
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
|
|
678
|
+
background: color-mix(in srgb, var(--ah-plate) 55%, transparent);
|
|
679
|
+
backdrop-filter: blur(5px);
|
|
680
|
+
animation: ah-veil-in 240ms ease;
|
|
681
|
+
}
|
|
682
|
+
.ah-veil__label {
|
|
683
|
+
color: var(--vf-text-tertiary); font-size: 10px;
|
|
684
|
+
font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
|
|
685
|
+
}
|
|
686
|
+
.ah-veil .ah-meter i { transition: width 600ms var(--vf-ease-island); }
|
|
687
|
+
@keyframes ah-veil-in { from { opacity: 0; } to { opacity: 1; } }
|
|
688
|
+
|
|
689
|
+
/* the cooking card's figure slots: a shimmer where the numbers will land.
|
|
690
|
+
Loading is colourless — the sweep is the ramp, never a hue. */
|
|
691
|
+
.ah-cook {
|
|
692
|
+
display: inline-block; width: 54px; height: 8px; border-radius: 4px;
|
|
693
|
+
background: linear-gradient(90deg,
|
|
694
|
+
var(--vf-fill-hover) 0%, var(--vf-fill) 45%, var(--vf-fill-hover) 90%);
|
|
695
|
+
background-size: 200% 100%;
|
|
696
|
+
animation: ah-cook-sweep 1.6s ease-in-out infinite;
|
|
697
|
+
}
|
|
698
|
+
.ah-project-list-item__metrics[data-cooking] { position: relative; }
|
|
699
|
+
.ah-project-list-item__metrics[data-cooking]::after {
|
|
700
|
+
content: ""; position: absolute; inset: -2px -4px; border-radius: 6px;
|
|
701
|
+
background: linear-gradient(100deg,
|
|
702
|
+
transparent 20%,
|
|
703
|
+
color-mix(in srgb, var(--ah-plate) 55%, transparent) 50%,
|
|
704
|
+
transparent 80%);
|
|
705
|
+
background-size: 200% 100%;
|
|
706
|
+
animation: ah-cook-sweep 1.6s ease-in-out infinite;
|
|
707
|
+
pointer-events: none;
|
|
708
|
+
}
|
|
709
|
+
@keyframes ah-cook-sweep { from { background-position: 160% 0; } to { background-position: -60% 0; } }
|
|
710
|
+
|
|
711
|
+
/* a cooking project's accent breathes in its own tint — on the stove */
|
|
712
|
+
.ah-project-list-item[data-cooking] .ah-project-list-item__accent {
|
|
713
|
+
animation: ah-stove 1.8s ease-in-out infinite;
|
|
714
|
+
}
|
|
715
|
+
@keyframes ah-stove { 0%, 100% { opacity: 0.45; } 50% { opacity: 0.9; } }
|
|
716
|
+
|
|
717
|
+
/* …and once the daemon's per-project fold names a figure, the stove turns
|
|
718
|
+
determinate: the same accent becomes the meter, filled from the floor in
|
|
719
|
+
the project's own tint over an ember of itself. Geometry never moves —
|
|
720
|
+
the bar was always there — and the fill eases on the veil's clock. */
|
|
721
|
+
.ah-project-list-item[data-cooking][data-fill] .ah-project-list-item__accent {
|
|
722
|
+
animation: none;
|
|
723
|
+
opacity: 0.9;
|
|
724
|
+
background:
|
|
725
|
+
linear-gradient(var(--project-color), var(--project-color))
|
|
726
|
+
bottom / 100% var(--ingest-fill) no-repeat,
|
|
727
|
+
color-mix(in srgb, var(--project-color) 24%, transparent);
|
|
728
|
+
transition: background-size 600ms var(--vf-ease-island), opacity 160ms ease;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/* the first run's honest room: per-runtime meters, no fiction */
|
|
732
|
+
.ah-coldstart { display: flex; flex-direction: column; gap: 9px; width: min(340px, 84%); margin-top: 4px; }
|
|
733
|
+
.ah-coldstart__row { display: grid; grid-template-columns: 86px 1fr; gap: 3px 10px; align-items: center; text-align: left; }
|
|
734
|
+
.ah-coldstart__row .ah-meter { width: 100%; }
|
|
735
|
+
.ah-coldstart__kind {
|
|
736
|
+
color: var(--vf-text-secondary); font-size: 10px;
|
|
737
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
738
|
+
}
|
|
739
|
+
.ah-coldstart__caption {
|
|
740
|
+
grid-column: 2; color: var(--vf-text-faint); font-size: 9px;
|
|
741
|
+
font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
742
|
+
}
|
|
743
|
+
.ah-coldstart__row[data-state="done"] .ah-meter i { background: var(--vf-green); }
|
|
744
|
+
.ah-coldstart__row[data-state="queued"] .ah-coldstart__kind { color: var(--vf-text-faint); }
|
|
745
|
+
|
|
746
|
+
|
|
747
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
748
|
+
THE FILE VIEWER — new vocabulary.
|
|
749
|
+
|
|
750
|
+
Everything above this line is a port of protos/agent-history-proto, class
|
|
751
|
+
names and all, and the two are diffed against each other. The design record
|
|
752
|
+
has no file viewer, so `ah-fileview*` and `ah-code/md/image/hex` are the
|
|
753
|
+
app's own names and must NOT be diffed against the proto.
|
|
754
|
+
|
|
755
|
+
What it does not invent is material. DESIGN.md §5 already specifies a
|
|
756
|
+
dialog and tokens.css already carries `--vf-shadow-dialog`,
|
|
757
|
+
`--vf-backdrop-dim` and the sheet surface — and until now nothing in this
|
|
758
|
+
room spent them. This is their first user. No new colour tokens, and the
|
|
759
|
+
one new measurement (`--ah-code-line`) is declared in CodeView.tsx, which
|
|
760
|
+
owns it because the virtualizer scrolls by it.
|
|
761
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
762
|
+
|
|
763
|
+
/* M5, the stage recedes: a dialog is focus made physical, so the room behind
|
|
764
|
+
it steps back rather than merely dimming. The room marks its own root while
|
|
765
|
+
one of its dialogs is open, because the dialog is portalled out of it. */
|
|
766
|
+
.ah-room { transition: transform 240ms var(--vf-ease-island); }
|
|
767
|
+
.ah-frame[data-ah-overlay] .ah-room { transform: scale(0.98); }
|
|
768
|
+
|
|
769
|
+
.ah-fileview__backdrop {
|
|
770
|
+
position: fixed; inset: 0; z-index: 60;
|
|
771
|
+
background: var(--vf-backdrop-dim);
|
|
772
|
+
backdrop-filter: blur(2px);
|
|
773
|
+
-webkit-app-region: no-drag;
|
|
774
|
+
animation: ah-fade-in 200ms ease;
|
|
775
|
+
}
|
|
776
|
+
.ah-fileview__backdrop[data-state="closed"] { animation: ah-fade-out 160ms ease forwards; }
|
|
777
|
+
|
|
778
|
+
.ah-fileview {
|
|
779
|
+
position: fixed; z-index: 61;
|
|
780
|
+
top: 50%; left: 50%;
|
|
781
|
+
transform: translate(-50%, -50%);
|
|
782
|
+
display: flex; flex-direction: column;
|
|
783
|
+
width: min(1080px, 92%); height: min(760px, 86%);
|
|
784
|
+
border-radius: var(--vf-radius-card);
|
|
785
|
+
/* Opaque, not the sheet's glass: this frame's job is to be read through by
|
|
786
|
+
nobody. Code at 12.5px over a blurred room is a legibility tax the room
|
|
787
|
+
is not asking anyone to pay. */
|
|
788
|
+
background: var(--vf-chrome-solid);
|
|
789
|
+
box-shadow: var(--vf-shadow-dialog);
|
|
790
|
+
overflow: hidden;
|
|
791
|
+
-webkit-app-region: no-drag;
|
|
792
|
+
animation: ah-fileview-in 240ms var(--vf-ease-island);
|
|
793
|
+
}
|
|
794
|
+
.ah-fileview[data-state="closed"] { animation: ah-fileview-out 160ms ease forwards; }
|
|
795
|
+
.ah-fileview:focus-visible, .ah-fileview:focus { outline: none; }
|
|
796
|
+
.ah-fileview[data-fullscreen] {
|
|
797
|
+
inset: 0;
|
|
798
|
+
width: 100%; height: 100%;
|
|
799
|
+
border-radius: 0;
|
|
800
|
+
transform: none;
|
|
801
|
+
animation: none;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
@keyframes ah-fade-in { from { opacity: 0; } to { opacity: 1; } }
|
|
805
|
+
@keyframes ah-fade-out { to { opacity: 0; } }
|
|
806
|
+
@keyframes ah-fileview-in {
|
|
807
|
+
from { opacity: 0; transform: translate(-50%, -50%) scale(0.985); }
|
|
808
|
+
to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
|
809
|
+
}
|
|
810
|
+
@keyframes ah-fileview-out {
|
|
811
|
+
to { opacity: 0; transform: translate(-50%, -50%) scale(0.99); }
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/* M6 is a quality floor, not a preference: morphs become fades, and the
|
|
815
|
+
stage stops travelling. */
|
|
816
|
+
@media (prefers-reduced-motion: reduce) {
|
|
817
|
+
.ah-room { transition: none; }
|
|
818
|
+
.ah-frame[data-ah-overlay] .ah-room { transform: none; }
|
|
819
|
+
.ah-fileview, .ah-fileview__backdrop { animation-duration: 1ms; }
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
/* ── the band ──────────────────────────────────────────────────────────── */
|
|
823
|
+
|
|
824
|
+
.ah-fileview__head {
|
|
825
|
+
flex: none;
|
|
826
|
+
display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center;
|
|
827
|
+
gap: 2px 12px;
|
|
828
|
+
padding: 12px 12px 11px 16px;
|
|
829
|
+
border-bottom: 1px solid var(--vf-hairline);
|
|
830
|
+
}
|
|
831
|
+
.ah-fileview__title { display: flex; align-items: center; gap: 8px; min-width: 0; }
|
|
832
|
+
.ah-fileview__title .ah-colhead { min-width: 0; flex: 0 1 auto; }
|
|
833
|
+
.ah-fileview__title .ah-colhead > strong { font-size: 12px; }
|
|
834
|
+
/* The kind chip is the neutral badge the column head already uses for a
|
|
835
|
+
count — same weight, same ground — because it is doing the same job: one
|
|
836
|
+
fact, travelling beside the name it is about. */
|
|
837
|
+
.ah-fileview__kind {
|
|
838
|
+
flex: none; padding: 1px 7px; border-radius: 999px;
|
|
839
|
+
background: var(--vf-fill); color: var(--vf-text-tertiary);
|
|
840
|
+
font-size: 9.5px; letter-spacing: 0.02em; white-space: nowrap;
|
|
841
|
+
}
|
|
842
|
+
.ah-fileview__acts { grid-column: 2; grid-row: 1 / span 2; display: flex; align-items: center; gap: 4px; }
|
|
843
|
+
.ah-fileview__browsers {
|
|
844
|
+
display: flex; align-items: center; gap: 3px; flex: none;
|
|
845
|
+
padding-right: 7px; margin-right: 3px; border-right: 1px solid var(--vf-hairline);
|
|
846
|
+
}
|
|
847
|
+
.ah-fileview__browser img { display: block; width: 20px; height: 20px; object-fit: contain; }
|
|
848
|
+
.ah-fileview__browser[aria-busy="true"] { opacity: .55; }
|
|
849
|
+
.ah-fileview__browser-fallback { font-size: 12px; font-weight: 600; }
|
|
850
|
+
.ah-fileview__browser-status { color: var(--vf-text-faint); font-size: 10px; white-space: nowrap; padding: 0 4px; }
|
|
851
|
+
@media (max-width: 680px) {
|
|
852
|
+
.ah-fileview__acts { grid-column: 1 / -1; grid-row: 3; justify-content: flex-end; flex-wrap: wrap; padding-top: 6px; }
|
|
853
|
+
.ah-fileview__browsers { flex-wrap: wrap; max-width: 100%; }
|
|
854
|
+
}
|
|
855
|
+
.ah-fileview__acts .ah-seg { margin: 0 6px 0 0; }
|
|
856
|
+
.ah-fileview__acts .ah-iconbtn:disabled {
|
|
857
|
+
cursor: default; opacity: .38; color: var(--vf-text-tertiary); background: var(--vf-fill);
|
|
858
|
+
}
|
|
859
|
+
/* A long path truncates at its HEAD: the folder you are in is the end of the
|
|
860
|
+
string, and it is the end that identifies the file. `direction: rtl` is
|
|
861
|
+
what moves the ellipsis there — and the `<bdi>` inside is not optional,
|
|
862
|
+
because without an isolate the same rule also walks the leading `/` around
|
|
863
|
+
to the far end and prints a path that does not exist. */
|
|
864
|
+
.ah-fileview__path {
|
|
865
|
+
grid-column: 1; grid-row: 2; margin: 0; min-width: 0;
|
|
866
|
+
color: var(--vf-text-faint); font-size: 10px; direction: rtl; text-align: left;
|
|
867
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.ah-visually-hidden {
|
|
871
|
+
position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
|
|
872
|
+
overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
/* ── the body, and the states that are not a document ──────────────────── */
|
|
876
|
+
|
|
877
|
+
.ah-fileview__body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
|
|
878
|
+
.ah-fileview__scroll { flex: 1; min-height: 0; overflow: auto; }
|
|
879
|
+
.ah-fileview__scroll::-webkit-scrollbar { width: 9px; height: 9px; }
|
|
880
|
+
.ah-fileview__scroll::-webkit-scrollbar-thumb {
|
|
881
|
+
border: 3px solid transparent; border-radius: 999px;
|
|
882
|
+
background: var(--vf-hairline-strong); background-clip: content-box;
|
|
883
|
+
}
|
|
884
|
+
.ah-fileview__scroll::-webkit-scrollbar-corner { background: var(--vf-chrome-solid); }
|
|
885
|
+
|
|
886
|
+
.ah-fileview__state {
|
|
887
|
+
flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
888
|
+
gap: 7px; padding: 30px 40px; text-align: center;
|
|
889
|
+
}
|
|
890
|
+
.ah-fileview__state b { color: var(--vf-text-secondary); font-size: 12.5px; font-weight: 500; }
|
|
891
|
+
.ah-fileview__state span { max-width: 44ch; color: var(--vf-text-faint); font-size: 11px; line-height: 1.55; }
|
|
892
|
+
/* A local read lands in single-digit milliseconds. Announcing it would be a
|
|
893
|
+
flash of text, so the wait only appears once it is long enough to be worth
|
|
894
|
+
a word — the loading veil's own rule (DESIGN.md §8 B4), one surface down. */
|
|
895
|
+
.ah-fileview__state[data-waiting] { opacity: 0; animation: ah-fade-in 140ms ease 280ms forwards; }
|
|
896
|
+
|
|
897
|
+
/* ── the code view ─────────────────────────────────────────────────────── */
|
|
898
|
+
|
|
899
|
+
.ah-code-shell {
|
|
900
|
+
--ah-code-minimap-width: 72px;
|
|
901
|
+
position: relative; flex: 1; min-width: 0; min-height: 0; display: flex;
|
|
902
|
+
}
|
|
903
|
+
.ah-code-shell > .ah-code { min-width: 0; }
|
|
904
|
+
.ah-code-shell:has(> .ah-code-minimap) .ah-code__line {
|
|
905
|
+
padding-right: var(--ah-code-minimap-width);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
.ah-code-minimap {
|
|
909
|
+
position: absolute; z-index: 2; top: 0; right: 0; bottom: 0;
|
|
910
|
+
width: var(--ah-code-minimap-width); overflow: hidden;
|
|
911
|
+
background: var(--vf-chrome-solid); user-select: none; touch-action: none;
|
|
912
|
+
contain: paint;
|
|
913
|
+
}
|
|
914
|
+
.ah-code-minimap__stage {
|
|
915
|
+
position: relative; width: 100%; overflow: hidden; cursor: pointer;
|
|
916
|
+
}
|
|
917
|
+
.ah-code-minimap__text {
|
|
918
|
+
position: absolute; inset: 0; display: block; width: 100%; height: 100%;
|
|
919
|
+
pointer-events: none; image-rendering: pixelated;
|
|
920
|
+
}
|
|
921
|
+
.ah-code-minimap__slider {
|
|
922
|
+
position: absolute; z-index: 1; top: 0; left: 0; right: 0;
|
|
923
|
+
border: 1px solid color-mix(in srgb, var(--vf-text-primary) 22%, transparent);
|
|
924
|
+
background: color-mix(in srgb, var(--vf-text-primary) 12%, transparent);
|
|
925
|
+
opacity: 0.4; cursor: ns-resize; will-change: transform;
|
|
926
|
+
transition: opacity 90ms linear;
|
|
927
|
+
}
|
|
928
|
+
.ah-code-minimap:hover .ah-code-minimap__slider,
|
|
929
|
+
.ah-code-minimap__slider.is-dragging { opacity: 1; }
|
|
930
|
+
|
|
931
|
+
@media (prefers-reduced-motion: reduce) {
|
|
932
|
+
.ah-code-minimap__slider { transition: none; }
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
.ah-code {
|
|
936
|
+
padding: 8px 0 16px;
|
|
937
|
+
overflow-x: hidden;
|
|
938
|
+
font-family: var(--vf-font-mono); font-size: 12.5px;
|
|
939
|
+
/* Must equal LINE_HEIGHT in CodeView.tsx. It is the estimate and minimum
|
|
940
|
+
pitch; wrapped rows are measured by the virtualizer at their real height. */
|
|
941
|
+
--ah-code-line: 19px;
|
|
942
|
+
/* The gutter's digits come from the view (`--ah-code-digits`, widest line
|
|
943
|
+
number); the space around them is the stylesheet's. */
|
|
944
|
+
--ah-code-gutter: calc(var(--ah-code-digits, 3ch) + 30px);
|
|
945
|
+
--ah-code-trail: 24px;
|
|
946
|
+
line-height: var(--ah-code-line);
|
|
947
|
+
tab-size: 2;
|
|
948
|
+
}
|
|
949
|
+
.ah-code__sizer { position: relative; width: 100%; }
|
|
950
|
+
.ah-code__line {
|
|
951
|
+
position: absolute; top: 0; left: 0; display: flex; width: 100%;
|
|
952
|
+
min-height: var(--ah-code-line);
|
|
953
|
+
}
|
|
954
|
+
.ah-code__num {
|
|
955
|
+
position: sticky; left: 0; z-index: 1; flex: none;
|
|
956
|
+
width: var(--ah-code-gutter); padding: 0 14px 0 16px; text-align: right;
|
|
957
|
+
background: var(--vf-chrome-solid);
|
|
958
|
+
color: var(--vf-text-faint); font-size: 11px; font-variant-numeric: tabular-nums;
|
|
959
|
+
user-select: none;
|
|
960
|
+
}
|
|
961
|
+
.ah-code__line code {
|
|
962
|
+
flex: 1; min-width: 0; padding-right: var(--ah-code-trail);
|
|
963
|
+
white-space: pre-wrap; overflow-wrap: anywhere; color: var(--vf-text-secondary);
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
/* ── the syntax palette ────────────────────────────────────────────────────
|
|
967
|
+
DESIGN.md §2.6's curated eight, spent on a closed set of token kinds —
|
|
968
|
+
"these group and label; they never signal state", which is exactly what a
|
|
969
|
+
token kind does. Six of the eight; red and pink are left alone, because red
|
|
970
|
+
means failure everywhere else in this room.
|
|
971
|
+
|
|
972
|
+
Only lightness moves between themes, the way `--tint-l` already does for
|
|
973
|
+
project identity: the same six hues in both, mixed toward the ground so
|
|
974
|
+
neither theme has to invent a colour. */
|
|
975
|
+
.ah-fileview, .ah-syntax {
|
|
976
|
+
--ah-syn-keyword: color-mix(in oklab, var(--vf-accent-6) 88%, black);
|
|
977
|
+
--ah-syn-type: color-mix(in oklab, var(--vf-accent-4) 84%, black);
|
|
978
|
+
--ah-syn-function: color-mix(in oklab, var(--vf-accent-8) 92%, black);
|
|
979
|
+
--ah-syn-string: color-mix(in oklab, var(--vf-accent-3) 82%, black);
|
|
980
|
+
--ah-syn-value: color-mix(in oklab, var(--vf-accent-5) 88%, black);
|
|
981
|
+
--ah-syn-property: color-mix(in oklab, var(--vf-accent-1) 94%, black);
|
|
982
|
+
}
|
|
983
|
+
.dark .ah-fileview, .dark .ah-syntax {
|
|
984
|
+
--ah-syn-keyword: color-mix(in oklab, var(--vf-accent-6) 72%, white);
|
|
985
|
+
--ah-syn-type: color-mix(in oklab, var(--vf-accent-4) 88%, white);
|
|
986
|
+
--ah-syn-function: color-mix(in oklab, var(--vf-accent-8) 74%, white);
|
|
987
|
+
--ah-syn-string: color-mix(in oklab, var(--vf-accent-3) 82%, white);
|
|
988
|
+
--ah-syn-value: color-mix(in oklab, var(--vf-accent-5) 76%, white);
|
|
989
|
+
--ah-syn-property: color-mix(in oklab, var(--vf-accent-1) 64%, white);
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
/* Scoped to the two syntax hosts. Unscoped, `[data-t=…]` is nine global
|
|
993
|
+
selectors waiting for the first component that picks the same attribute. */
|
|
994
|
+
:is(.ah-fileview, .ah-syntax) [data-t="comment"] { color: var(--vf-text-faint); font-style: italic; }
|
|
995
|
+
:is(.ah-fileview, .ah-syntax) [data-t="operator"] { color: var(--vf-text-tertiary); }
|
|
996
|
+
:is(.ah-fileview, .ah-syntax) [data-t="keyword"] { color: var(--ah-syn-keyword); }
|
|
997
|
+
/* A markup tag is the keyword of its language, and an attribute is a
|
|
998
|
+
property. Two syntaxes, the same two roles — so the same two colours,
|
|
999
|
+
rather than a second palette for a reader to learn. */
|
|
1000
|
+
:is(.ah-fileview, .ah-syntax) [data-t="tag"] { color: var(--ah-syn-keyword); }
|
|
1001
|
+
:is(.ah-fileview, .ah-syntax) [data-t="type"] { color: var(--ah-syn-type); }
|
|
1002
|
+
:is(.ah-fileview, .ah-syntax) [data-t="function"] { color: var(--ah-syn-function); }
|
|
1003
|
+
:is(.ah-fileview, .ah-syntax) [data-t="string"] { color: var(--ah-syn-string); }
|
|
1004
|
+
/* Numbers and named literals are one idea — a value the language spells for
|
|
1005
|
+
you — and they share an accent to say so. */
|
|
1006
|
+
:is(.ah-fileview, .ah-syntax) [data-t="number"],
|
|
1007
|
+
:is(.ah-fileview, .ah-syntax) [data-t="constant"] { color: var(--ah-syn-value); }
|
|
1008
|
+
:is(.ah-fileview, .ah-syntax) [data-t="property"] { color: var(--ah-syn-property); }
|
|
1009
|
+
|
|
1010
|
+
/* ── the markdown view ─────────────────────────────────────────────────── */
|
|
1011
|
+
|
|
1012
|
+
.ah-md { padding: 4px 0 40px; }
|
|
1013
|
+
/* The transcript's own setting, one surface over: 68ch at 14px/1.55, declared
|
|
1014
|
+
on the box that carries the font size, because `ch` resolves against the
|
|
1015
|
+
element's own font (design record §10, delta 3's implementation note). */
|
|
1016
|
+
.ah-md__measure {
|
|
1017
|
+
max-width: 68ch; margin: 0 auto; padding: 18px 28px 0;
|
|
1018
|
+
color: var(--vf-text-secondary); font-size: 14px; line-height: 1.55;
|
|
1019
|
+
}
|
|
1020
|
+
.ah-markdown > :first-child { margin-top: 0; }
|
|
1021
|
+
.ah-markdown h1, .ah-markdown h2, .ah-markdown h3,
|
|
1022
|
+
.ah-markdown h4, .ah-markdown h5, .ah-markdown h6 {
|
|
1023
|
+
margin: 26px 0 9px; color: var(--vf-text-primary); font-weight: 600; line-height: 1.3;
|
|
1024
|
+
}
|
|
1025
|
+
.ah-markdown h1 { font-size: 20px; }
|
|
1026
|
+
.ah-markdown h2 { font-size: 16.5px; padding-bottom: 6px; border-bottom: 1px solid var(--vf-hairline); }
|
|
1027
|
+
.ah-markdown h3 { font-size: 14.5px; }
|
|
1028
|
+
.ah-markdown h4, .ah-markdown h5, .ah-markdown h6 {
|
|
1029
|
+
font-size: 13px; color: var(--vf-text-secondary);
|
|
1030
|
+
}
|
|
1031
|
+
.ah-markdown p { margin: 0 0 12px; }
|
|
1032
|
+
.ah-markdown strong { color: var(--vf-text-primary); font-weight: 600; }
|
|
1033
|
+
.ah-markdown s { color: var(--vf-text-faint); }
|
|
1034
|
+
.ah-markdown a { color: var(--vf-cyan); text-decoration: none; }
|
|
1035
|
+
.ah-markdown a:hover { text-decoration: underline; }
|
|
1036
|
+
.ah-markdown code {
|
|
1037
|
+
padding: 1px 4px; border-radius: 4px; background: var(--vf-fill);
|
|
1038
|
+
font-family: var(--vf-font-mono); font-size: 12px; color: var(--vf-text-primary);
|
|
1039
|
+
}
|
|
1040
|
+
.ah-markdown ul, .ah-markdown ol { margin: 0 0 12px; padding-left: 22px; }
|
|
1041
|
+
.ah-markdown li { margin-bottom: 5px; }
|
|
1042
|
+
.ah-markdown li > ul, .ah-markdown li > ol { margin: 5px 0 0; }
|
|
1043
|
+
/* A tight list is one the author wrote without blank lines, and it should
|
|
1044
|
+
read as one block rather than as a column of paragraphs. */
|
|
1045
|
+
.ah-markdown [data-tight] > li > p { margin: 0; }
|
|
1046
|
+
.ah-markdown blockquote {
|
|
1047
|
+
margin: 0 0 12px; padding: 2px 0 2px 14px;
|
|
1048
|
+
border-left: 2px solid var(--vf-hairline-strong); color: var(--vf-text-tertiary);
|
|
1049
|
+
}
|
|
1050
|
+
.ah-markdown blockquote > :last-child { margin-bottom: 0; }
|
|
1051
|
+
.ah-markdown hr { margin: 22px 0; border: 0; border-top: 1px solid var(--vf-hairline); }
|
|
1052
|
+
.ah-md__code {
|
|
1053
|
+
margin: 0 0 14px; padding: 10px 13px; border-radius: 10px;
|
|
1054
|
+
background: var(--vf-fill); overflow-x: auto;
|
|
1055
|
+
font-family: var(--vf-font-mono); font-size: 12px; line-height: 1.5;
|
|
1056
|
+
color: var(--vf-text-secondary);
|
|
1057
|
+
}
|
|
1058
|
+
.ah-md__code code { padding: 0; border-radius: 0; background: none; font-size: inherit; }
|
|
1059
|
+
/* A wide table scrolls inside its own box: the document's measure is a rule
|
|
1060
|
+
about the prose, and a table is not allowed to overrule it. */
|
|
1061
|
+
.ah-md__tablebox { margin: 0 0 14px; overflow-x: auto; }
|
|
1062
|
+
.ah-markdown table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
|
|
1063
|
+
.ah-markdown th, .ah-markdown td {
|
|
1064
|
+
padding: 6px 10px; border-bottom: 1px solid var(--vf-hairline); text-align: left;
|
|
1065
|
+
vertical-align: top;
|
|
1066
|
+
}
|
|
1067
|
+
.ah-markdown th { color: var(--vf-text-primary); font-weight: 500; white-space: nowrap; }
|
|
1068
|
+
.ah-markdown thead tr { border-bottom: 1px solid var(--vf-hairline-strong); }
|
|
1069
|
+
/* An embedded image is named, not fetched — see markdown/render.tsx. */
|
|
1070
|
+
.ah-md__image {
|
|
1071
|
+
display: inline-flex; align-items: center; gap: 5px;
|
|
1072
|
+
padding: 1px 7px; border: 1px dashed var(--vf-hairline-strong); border-radius: 6px;
|
|
1073
|
+
color: var(--vf-text-faint); font-size: 11px;
|
|
1074
|
+
}
|
|
1075
|
+
.ah-md__image::before { content: "▨"; opacity: 0.6; }
|
|
1076
|
+
/* A link this viewer cannot follow keeps its text and loses its promise. */
|
|
1077
|
+
.ah-md__deadlink { color: var(--vf-text-tertiary); border-bottom: 1px dotted var(--vf-hairline-strong); }
|
|
1078
|
+
|
|
1079
|
+
/* ── the image view ────────────────────────────────────────────────────── */
|
|
1080
|
+
|
|
1081
|
+
.ah-image { position: relative; flex: 1; min-height: 0; display: flex; }
|
|
1082
|
+
.ah-image__frame { display: flex; align-items: center; justify-content: center; padding: 18px; }
|
|
1083
|
+
.ah-image__loading { position: absolute; inset: 50% 0 auto; text-align: center; color: var(--vf-text-tertiary); pointer-events: none; }
|
|
1084
|
+
.ah-image img { display: block; border-radius: 4px; }
|
|
1085
|
+
.ah-image[data-mode="fit"] img { max-width: 100%; max-height: 100%; object-fit: contain; }
|
|
1086
|
+
/* At 1:1 a picture larger than the frame is scrolled from its top-left, the
|
|
1087
|
+
way an image is read, rather than from its middle. */
|
|
1088
|
+
.ah-image[data-mode="actual"] .ah-image__frame { align-items: flex-start; justify-content: flex-start; }
|
|
1089
|
+
.ah-image[data-mode="actual"] img { max-width: none; max-height: none; }
|
|
1090
|
+
/* Over the frame, never inside its flow: as a sibling of the picture this
|
|
1091
|
+
was laid out beside it and wrapped into the middle of a wide one. */
|
|
1092
|
+
.ah-image__facts {
|
|
1093
|
+
position: absolute; left: 15px; bottom: 13px;
|
|
1094
|
+
padding: 2px 8px; border-radius: 999px;
|
|
1095
|
+
background: var(--vf-chrome-surface); backdrop-filter: blur(12px);
|
|
1096
|
+
color: var(--vf-text-faint); font-size: 10px;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
/* ── the hex view ──────────────────────────────────────────────────────── */
|
|
1100
|
+
|
|
1101
|
+
.ah-hex {
|
|
1102
|
+
padding: 0 0 20px;
|
|
1103
|
+
font-family: var(--vf-font-mono); font-size: 11px; line-height: 1.65;
|
|
1104
|
+
}
|
|
1105
|
+
.ah-hex__note {
|
|
1106
|
+
position: sticky; top: 0; z-index: 1; margin: 0 0 8px;
|
|
1107
|
+
padding: 11px 18px; border-bottom: 1px solid var(--vf-hairline);
|
|
1108
|
+
background: var(--vf-chrome-solid);
|
|
1109
|
+
color: var(--vf-text-faint); font-family: var(--vf-font-sans); font-size: 11px;
|
|
1110
|
+
}
|
|
1111
|
+
.ah-hex__row { display: flex; gap: 16px; padding: 0 18px; white-space: pre; }
|
|
1112
|
+
.ah-hex__offset { color: var(--vf-text-faint); }
|
|
1113
|
+
.ah-hex__bytes { color: var(--vf-text-secondary); }
|
|
1114
|
+
.ah-hex__text { color: var(--vf-text-tertiary); }
|
|
1115
|
+
|
|
1116
|
+
/* ═══════════════════════════════════════════════════════════════════════════
|
|
1117
|
+
COLUMN ⑤ — THE REPOSITORY'S GIT (design record §8)
|
|
1118
|
+
|
|
1119
|
+
`.ah-commit`, `.ah-gitseg` and `.ah-push` are the proto's own vocabulary
|
|
1120
|
+
and ARE diffed against it. `.ah-changerow` and `.ah-diff*` are the app's:
|
|
1121
|
+
the record draws the change groups as mille subtrees, which mille cannot
|
|
1122
|
+
serve over a filtered set, so they are the room's own rows wearing mille's
|
|
1123
|
+
geometry — the same row height and indent, so the two columns read as one
|
|
1124
|
+
repository rather than as two components that happen to be adjacent.
|
|
1125
|
+
═══════════════════════════════════════════════════════════════════════ */
|
|
1126
|
+
|
|
1127
|
+
/* the switch is the only thing in its row, so it takes the row: "a switch's
|
|
1128
|
+
shape is its material, not its width" (§8) */
|
|
1129
|
+
.ah-seg.ah-gitseg { display: flex; flex: 1; }
|
|
1130
|
+
.ah-seg.ah-gitseg button { flex: 1; height: 20px; padding: 0 9px; font-size: 10px; }
|
|
1131
|
+
|
|
1132
|
+
/* ── the change rows ───────────────────────────────────────────────────── */
|
|
1133
|
+
|
|
1134
|
+
.ah-changetree { padding: 0 6px 2px; }
|
|
1135
|
+
.ah-changerow {
|
|
1136
|
+
display: flex; align-items: center; gap: 6px;
|
|
1137
|
+
height: var(--vf-tree-row-height); border-radius: 7px;
|
|
1138
|
+
padding-right: 4px;
|
|
1139
|
+
}
|
|
1140
|
+
.ah-changerow:hover { background: var(--vf-fill); }
|
|
1141
|
+
/* the active entry wears `--vf-fill` and nothing else uses that fill —
|
|
1142
|
+
DESIGN.md §8, and the reason the open diff is legible at a glance */
|
|
1143
|
+
.ah-changerow[data-selected] { background: var(--vf-fill-hover); }
|
|
1144
|
+
.ah-changerow__name {
|
|
1145
|
+
display: flex; align-items: center; gap: 5px; min-width: 0; flex: 1;
|
|
1146
|
+
border: 0; background: transparent; padding: 0;
|
|
1147
|
+
color: var(--vf-text-secondary); font-size: 11.5px; text-align: left;
|
|
1148
|
+
}
|
|
1149
|
+
.ah-changerow__name > span {
|
|
1150
|
+
min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1151
|
+
}
|
|
1152
|
+
.ah-changerow[data-kind="directory"] .ah-changerow__name {
|
|
1153
|
+
color: var(--vf-text-faint); font-size: 10.5px;
|
|
1154
|
+
}
|
|
1155
|
+
.ah-changerow[data-selected] .ah-changerow__name { color: var(--vf-text-primary); }
|
|
1156
|
+
|
|
1157
|
+
/* the session mark: the one fact a git client cannot show. A dot, in the
|
|
1158
|
+
project's own §2.6 tint — it says WHICH session, and hue means which.
|
|
1159
|
+
The slot is always there, so a marked row and an unmarked one line up
|
|
1160
|
+
their glyphs; only the dot itself comes and goes. */
|
|
1161
|
+
.ah-changerow__mark { flex: none; width: 5px; height: 5px; border-radius: 999px; }
|
|
1162
|
+
.ah-changerow__mark[data-touched] { background: var(--tint, var(--vf-text-tertiary)); }
|
|
1163
|
+
|
|
1164
|
+
/* mille's own glyph, at column ③'s size: one repository, one icon set */
|
|
1165
|
+
.ah-changerow__icon { flex: none; width: 13px; height: 13px; }
|
|
1166
|
+
.ah-changerow__icon svg { width: 100%; height: 100%; display: block; }
|
|
1167
|
+
|
|
1168
|
+
/* git's own letter, in the §2.5 hue its meaning earns — added is a positive
|
|
1169
|
+
delta, deleted a negative one. Everything else is a state the ramp carries
|
|
1170
|
+
without spending a colour on it. The slot holds its width when empty so
|
|
1171
|
+
the names align down the column. */
|
|
1172
|
+
.ah-changerow__letter {
|
|
1173
|
+
flex: none; width: 9px; text-align: center;
|
|
1174
|
+
font-family: var(--vf-font-mono); font-size: 10px; font-weight: 500;
|
|
1175
|
+
color: var(--vf-text-tertiary);
|
|
1176
|
+
}
|
|
1177
|
+
.ah-changerow__letter[data-letter="A"] { color: var(--vf-green); }
|
|
1178
|
+
.ah-changerow__letter[data-letter="D"] { color: var(--vf-red); }
|
|
1179
|
+
.ah-changerow__letter[data-letter="U"] { color: var(--vf-orange); }
|
|
1180
|
+
.ah-changerow__letter[data-letter="?"] { color: var(--vf-text-faint); }
|
|
1181
|
+
|
|
1182
|
+
/* the acts appear on hover: a reading column does not carry two buttons per
|
|
1183
|
+
row at rest, and a row you are not pointing at is not one you are staging */
|
|
1184
|
+
.ah-changerow__acts { display: flex; align-items: center; gap: 2px; flex: none; opacity: 0; }
|
|
1185
|
+
.ah-changerow:hover .ah-changerow__acts,
|
|
1186
|
+
.ah-changerow:focus-within .ah-changerow__acts { opacity: 1; }
|
|
1187
|
+
.ah-changerow__acts button {
|
|
1188
|
+
width: 18px; height: 18px; border: 0; border-radius: 5px; padding: 0;
|
|
1189
|
+
background: transparent; color: var(--vf-text-tertiary); font-size: 12px; line-height: 1;
|
|
1190
|
+
}
|
|
1191
|
+
.ah-changerow__acts button:hover { background: var(--vf-fill-hover); color: var(--vf-text-primary); }
|
|
1192
|
+
|
|
1193
|
+
/* ── the commit row: the session row, one object down ──────────────────── */
|
|
1194
|
+
|
|
1195
|
+
.ah-commit {
|
|
1196
|
+
display: grid; grid-template-columns: 8px minmax(0, 1fr); gap: 0 9px;
|
|
1197
|
+
width: 100%; padding: 9px 10px 10px; border: 0; background: transparent; text-align: left;
|
|
1198
|
+
}
|
|
1199
|
+
.ah-commit + .ah-commit { border-top: 1px solid var(--vf-hairline); }
|
|
1200
|
+
/* The proto draws the boundary BECAUSE it has no hover to spend — its row is
|
|
1201
|
+
not pressable, since it had no diff view to open. This one does, so it
|
|
1202
|
+
earns the fill as well as the hairline. */
|
|
1203
|
+
.ah-commit:hover { background: var(--vf-fill); }
|
|
1204
|
+
.ah-commit[data-selected] { background: var(--vf-fill-hover); }
|
|
1205
|
+
.ah-commit__l1 { grid-column: 2; display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; min-width: 0; }
|
|
1206
|
+
.ah-commit__l3 { grid-column: 2; display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; min-width: 0; }
|
|
1207
|
+
.ah-commit strong {
|
|
1208
|
+
display: block; min-width: 0; color: var(--vf-text-primary);
|
|
1209
|
+
font-size: 11.5px; font-weight: 500; line-height: 1.35;
|
|
1210
|
+
}
|
|
1211
|
+
/* The proto calls this `ah-sessmeta` and the app renamed it to
|
|
1212
|
+
`ah-session-list-item__metadata`, so the proto's name resolved to nothing
|
|
1213
|
+
here and the line inherited the row's own font — twice the size it should
|
|
1214
|
+
be, with its separators unspaced. Named for the row it belongs to, like
|
|
1215
|
+
`__l1` and `__l3`, and carrying the values the proto sets. */
|
|
1216
|
+
.ah-commit__meta {
|
|
1217
|
+
grid-column: 2; display: flex; align-items: center; flex-wrap: wrap; gap: 5px; margin-top: 3px;
|
|
1218
|
+
color: var(--vf-text-faint); font-size: 10px; font-variant-numeric: tabular-nums;
|
|
1219
|
+
}
|
|
1220
|
+
.ah-commit code { font-family: var(--vf-font-mono); font-size: 9.5px; color: var(--vf-text-faint); }
|
|
1221
|
+
.ah-commit .ah-last { flex: none; }
|
|
1222
|
+
/* the ONE git state the row draws, because it is the one still actionable */
|
|
1223
|
+
.ah-push {
|
|
1224
|
+
grid-column: 1; grid-row: 1; align-self: start; margin-top: 3px;
|
|
1225
|
+
display: grid; place-items: center; width: 8px; height: 8px; color: var(--vf-text-tertiary);
|
|
1226
|
+
}
|
|
1227
|
+
.ah-push svg { width: 8px; height: 8px; display: block; }
|
|
1228
|
+
|
|
1229
|
+
/* ── the diff ──────────────────────────────────────────────────────────────
|
|
1230
|
+
Two gutters, then the mark, then the line. The line hues are §2.5's own
|
|
1231
|
+
and need no exception: DESIGN.md defines `--vf-green` as "positive delta"
|
|
1232
|
+
and `--vf-red` as "negative delta". What stays neutral is the diffstat
|
|
1233
|
+
FIGURE — §8's rule that hue says which project or which state. */
|
|
1234
|
+
|
|
1235
|
+
/* A diff's rows are as wide as the column, not as wide as their longest
|
|
1236
|
+
line: the ground behind an added line says "this whole line is new", and a
|
|
1237
|
+
ground that stops at the text says it about the text only. The code itself
|
|
1238
|
+
still scrolls sideways inside the row. */
|
|
1239
|
+
.ah-diff .ah-code__sizer { width: 100%; }
|
|
1240
|
+
.ah-diff .ah-code__line { width: 100%; }
|
|
1241
|
+
.ah-diff .ah-code__line code { flex: 1; min-width: 0; }
|
|
1242
|
+
|
|
1243
|
+
/* the file's own figure, above its hunks */
|
|
1244
|
+
.ah-diff__stat {
|
|
1245
|
+
position: sticky; top: 0; z-index: 2; margin: 0;
|
|
1246
|
+
display: flex; align-items: center; gap: 10px;
|
|
1247
|
+
padding: 9px 16px; border-bottom: 1px solid var(--vf-hairline);
|
|
1248
|
+
background: var(--vf-chrome-solid);
|
|
1249
|
+
color: var(--vf-text-tertiary); font-family: var(--vf-font-sans); font-size: 11px;
|
|
1250
|
+
}
|
|
1251
|
+
.ah-diff__renamed {
|
|
1252
|
+
color: var(--vf-text-faint); min-width: 0;
|
|
1253
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
.ah-diff .ah-code__num:first-of-type { padding-right: 6px; padding-left: 12px; }
|
|
1257
|
+
.ah-diff .ah-code__num {
|
|
1258
|
+
width: calc(var(--ah-code-digits, 3ch) + 18px);
|
|
1259
|
+
padding: 0 6px 0 0; background: transparent;
|
|
1260
|
+
}
|
|
1261
|
+
.ah-diff__mark {
|
|
1262
|
+
flex: none; width: 16px; text-align: center; user-select: none;
|
|
1263
|
+
color: var(--vf-text-faint);
|
|
1264
|
+
}
|
|
1265
|
+
.ah-diff .ah-code__line { align-items: center; }
|
|
1266
|
+
.ah-diff .ah-code__line[data-diff="add"] { background: color-mix(in srgb, var(--vf-green) 11%, transparent); }
|
|
1267
|
+
.ah-diff .ah-code__line[data-diff="del"] { background: color-mix(in srgb, var(--vf-red) 11%, transparent); }
|
|
1268
|
+
.ah-diff .ah-code__line[data-diff="add"] .ah-diff__mark { color: var(--vf-green); }
|
|
1269
|
+
.ah-diff .ah-code__line[data-diff="del"] .ah-diff__mark { color: var(--vf-red); }
|
|
1270
|
+
.ah-diff .ah-code__line[data-diff="note"] code { color: var(--vf-text-faint); }
|
|
1271
|
+
.ah-diff .ah-code__line[data-diff="note"] em { font-style: italic; }
|
|
1272
|
+
|
|
1273
|
+
/* the hunk header: git's own `@@` plus the enclosing function it names */
|
|
1274
|
+
.ah-diff .ah-code__line[data-diff="hunk"] { background: var(--vf-fill); }
|
|
1275
|
+
.ah-diff__hunk { display: flex; align-items: center; gap: 10px; padding: 0 12px; min-width: 0; }
|
|
1276
|
+
.ah-diff__range { color: var(--vf-text-faint); font-size: 10.5px; flex: none; }
|
|
1277
|
+
.ah-diff__context {
|
|
1278
|
+
color: var(--vf-text-tertiary); font-size: 11px; min-width: 0;
|
|
1279
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
/* ── the confirm: the one thing this room asks before doing ─────────────── */
|
|
1283
|
+
|
|
1284
|
+
.ah-confirm {
|
|
1285
|
+
position: fixed; z-index: 61; top: 50%; left: 50%;
|
|
1286
|
+
transform: translate(-50%, -50%);
|
|
1287
|
+
width: min(420px, 88%); padding: 20px 22px 18px;
|
|
1288
|
+
border-radius: 18px; background: var(--vf-chrome-solid);
|
|
1289
|
+
box-shadow: var(--vf-shadow-dialog);
|
|
1290
|
+
animation: ah-fileview-in 200ms var(--vf-ease-island);
|
|
1291
|
+
}
|
|
1292
|
+
.ah-confirm__title { margin: 0 0 8px; color: var(--vf-text-primary); font-size: 13.5px; font-weight: 600; }
|
|
1293
|
+
.ah-confirm__body p { margin: 0; color: var(--vf-text-tertiary); font-size: 12px; line-height: 1.55; }
|
|
1294
|
+
.ah-confirm__list {
|
|
1295
|
+
margin: 10px 0 0; padding: 8px 10px; max-height: 148px; overflow: auto;
|
|
1296
|
+
border-radius: 9px; background: var(--vf-fill); list-style: none;
|
|
1297
|
+
font-family: var(--vf-font-mono); font-size: 10.5px; color: var(--vf-text-secondary);
|
|
1298
|
+
}
|
|
1299
|
+
.ah-confirm__list li { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
1300
|
+
.ah-confirm__list li[data-more] { color: var(--vf-text-faint); font-family: var(--vf-font-sans); }
|
|
1301
|
+
.ah-confirm__acts { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
|
|
1302
|
+
.ah-confirm__acts button {
|
|
1303
|
+
height: 28px; padding: 0 14px; border: 0; border-radius: 999px; font-size: 12px;
|
|
1304
|
+
transition: opacity 140ms ease, transform 120ms ease;
|
|
1305
|
+
}
|
|
1306
|
+
.ah-confirm__acts button:active { transform: scale(0.97); }
|
|
1307
|
+
.ah-confirm__cancel { background: var(--vf-fill); color: var(--vf-text-secondary); }
|
|
1308
|
+
.ah-confirm__cancel:hover { background: var(--vf-fill-hover); }
|
|
1309
|
+
.ah-confirm__go { background: var(--vf-foreground); color: var(--vf-canvas-bg); font-weight: 500; }
|
|
1310
|
+
/* red is §2.5's "destructive", which is exactly what this button is */
|
|
1311
|
+
.ah-confirm__go[data-destructive] { background: var(--vf-red); color: var(--vf-state-on-solid); }
|
|
1312
|
+
.ah-confirm__go:hover { opacity: 0.9; }
|
|
1313
|
+
.ah-confirm button:focus-visible { outline: 2px solid var(--vf-select); outline-offset: 2px; }
|
|
1314
|
+
|
|
1315
|
+
/* ── inside one commit ─────────────────────────────────────────────────── */
|
|
1316
|
+
|
|
1317
|
+
/* The head still names the object the column is showing — which, while a
|
|
1318
|
+
commit is open, is the commit. The way back names the branch it returns
|
|
1319
|
+
to rather than just pointing at it. */
|
|
1320
|
+
.ah-backhead { display: flex; align-items: center; gap: 2px; min-width: 0; }
|
|
1321
|
+
.ah-backhead .ah-colhead { min-width: 0; }
|
|
1322
|
+
.ah-back {
|
|
1323
|
+
flex: none; width: 18px; height: 18px; margin-left: -4px; padding: 0;
|
|
1324
|
+
border: 0; border-radius: 6px; background: transparent;
|
|
1325
|
+
color: var(--vf-text-tertiary); font-size: 15px; line-height: 1;
|
|
1326
|
+
}
|
|
1327
|
+
.ah-back:hover { background: var(--vf-fill-hover); color: var(--vf-text-primary); }
|
|
1328
|
+
|
|
1329
|
+
/* The row above had to truncate a long subject; this is the surface that
|
|
1330
|
+
does not, so the message is given in full before its files. */
|
|
1331
|
+
.ah-commitmsg {
|
|
1332
|
+
margin: 0; padding: 11px 12px 3px;
|
|
1333
|
+
color: var(--vf-text-secondary); font-size: 12px; line-height: 1.45;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
/* A commit's byline can name two or three people; it truncates rather than
|
|
1337
|
+
pushing the diffstat off the row. */
|
|
1338
|
+
.ah-commit__who { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1339
|
+
|
|
1340
|
+
/* who git says wrote it, on the surface with room to name all of them */
|
|
1341
|
+
.ah-commitwho {
|
|
1342
|
+
display: flex; align-items: center; flex-wrap: wrap; gap: 4px 6px;
|
|
1343
|
+
margin: 0; padding: 0 12px 9px;
|
|
1344
|
+
color: var(--vf-text-faint); font-size: 10px;
|
|
1345
|
+
}
|
|
1346
|
+
.ah-commitwho span { color: var(--vf-text-tertiary); }
|
|
1347
|
+
/* a co-author is named, not badged: the glyph is what §8 rules out, and a
|
|
1348
|
+
dot before the name says "and" without spending a second vocabulary */
|
|
1349
|
+
.ah-commitwho span[data-co]::before { content: "· "; color: var(--vf-text-faint); }
|
|
1350
|
+
.ah-commitwho time { margin-left: auto; font-variant-numeric: tabular-nums; }
|
|
1351
|
+
|
|
1352
|
+
/* three tabs over one checkout, so the track holds three */
|
|
1353
|
+
.ah-seg.ah-gitseg button { padding: 0 6px; }
|
|
1354
|
+
|
|
1355
|
+
/* The agent that co-signed the commit, at the end of the message line.
|
|
1356
|
+
§2.6's rule for provider identity: monochrome at `currentColor`, carrying
|
|
1357
|
+
no hue of its own — the row's tint is the project's and this is not a
|
|
1358
|
+
second colour competing with it. */
|
|
1359
|
+
.ah-commit__agents { flex: none; gap: 3px; margin-top: 1px; }
|
|
1360
|
+
.ah-commit__agents .ah-agent { width: 11px; height: 11px; opacity: 0.5; }
|
|
1361
|
+
.ah-commit:hover .ah-commit__agents .ah-agent,
|
|
1362
|
+
.ah-commit[data-selected] .ah-commit__agents .ah-agent { opacity: 0.75; }
|
|
1363
|
+
|
|
1364
|
+
/* ── the commit, opened over the room ──────────────────────────────────────
|
|
1365
|
+
The shape a commit wanted and a 280px column could not give it: the files
|
|
1366
|
+
on the left, the change on the right, both at once. Same shell as the file
|
|
1367
|
+
viewer, one size wider, because two panes need the room. */
|
|
1368
|
+
|
|
1369
|
+
.ah-fileview[data-wide] { width: min(1320px, 94%); height: min(820px, 90%); }
|
|
1370
|
+
|
|
1371
|
+
.ah-commitview__head { grid-template-columns: minmax(0, 1fr) auto; padding-bottom: 9px; }
|
|
1372
|
+
.ah-commitview__subject {
|
|
1373
|
+
min-width: 0; color: var(--vf-text-primary); font-size: 13px; font-weight: 600;
|
|
1374
|
+
line-height: 1.35; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1375
|
+
}
|
|
1376
|
+
/* Everyone and everything git says about it, on one line under the message:
|
|
1377
|
+
the people it does not draw as marks, the agents it does, the sha, the
|
|
1378
|
+
neutral diffstat, and the date. */
|
|
1379
|
+
.ah-commitview__meta {
|
|
1380
|
+
grid-column: 1 / -1; margin: 5px 0 0;
|
|
1381
|
+
display: flex; align-items: center; flex-wrap: wrap; gap: 4px 9px;
|
|
1382
|
+
color: var(--vf-text-faint); font-size: 10.5px;
|
|
1383
|
+
}
|
|
1384
|
+
.ah-commitview__meta > span { color: var(--vf-text-tertiary); }
|
|
1385
|
+
.ah-commitview__meta code { font-family: var(--vf-font-mono); font-size: 10px; }
|
|
1386
|
+
.ah-commitview__meta .ah-agent { width: 12px; height: 12px; opacity: 0.6; }
|
|
1387
|
+
.ah-commitview__meta time { margin-left: auto; }
|
|
1388
|
+
|
|
1389
|
+
.ah-commitview { flex: 1; min-height: 0; display: grid; grid-template-columns: 300px minmax(0, 1fr); }
|
|
1390
|
+
.ah-commitview__files {
|
|
1391
|
+
display: flex; flex-direction: column; min-height: 0;
|
|
1392
|
+
border-right: 1px solid var(--vf-hairline);
|
|
1393
|
+
}
|
|
1394
|
+
.ah-commitview__files .ah-group { padding: 11px 12px 7px; }
|
|
1395
|
+
.ah-commitview__list { flex: 1; min-height: 0; overflow: auto; padding-bottom: 10px; }
|
|
1396
|
+
.ah-commitview__list::-webkit-scrollbar { width: 9px; }
|
|
1397
|
+
.ah-commitview__list::-webkit-scrollbar-thumb {
|
|
1398
|
+
border: 3px solid transparent; border-radius: 999px;
|
|
1399
|
+
background: var(--vf-hairline-strong); background-clip: content-box;
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
.ah-commitview__diff { display: flex; flex-direction: column; min-height: 0; }
|
|
1403
|
+
/* The pane names the file it is showing, because the list beside it can be
|
|
1404
|
+
scrolled away from the selection. */
|
|
1405
|
+
.ah-commitview__path {
|
|
1406
|
+
flex: none; margin: 0; padding: 9px 16px; border-bottom: 1px solid var(--vf-hairline);
|
|
1407
|
+
color: var(--vf-text-tertiary); font-size: 10.5px;
|
|
1408
|
+
direction: rtl; text-align: left;
|
|
1409
|
+
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
|
1410
|
+
}
|
|
1411
|
+
.ah-commitview__diff .ah-diff__stat { padding-top: 8px; padding-bottom: 8px; }
|