Remove legacy infrastructure, keep only shared rule contracts
Deleted: demo app, designsync/exports bundle system, bible meta-docs, theme CSS, scaffolds, examples, empty pattern placeholders, go.mod, CHANGELOG, VERSIONING Kept: kit/patterns/*/contract.md (all engineering rules), kit/ai/claude/CLAUDE.template.md, CLAUDE.md, AGENTS.md, README.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
# {{ .project_name }} — Agent Instructions
|
||||
|
||||
Read and follow `bible/README.md` as the architecture source of truth.
|
||||
|
||||
## Rules
|
||||
|
||||
- Keep architecture documentation in English.
|
||||
- Update Bible docs in the same change set as architecture/code contract changes.
|
||||
- Keep README and agent docs minimal; avoid duplicating Bible architecture content.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Architecture Documentation Policy
|
||||
|
||||
This project uses a Bible-style architecture documentation folder as the single source of truth.
|
||||
|
||||
## Mandatory Rules
|
||||
|
||||
- Record architecture decisions before or together with implementation.
|
||||
- Use English for architecture documentation.
|
||||
- Remove or update obsolete architectural guidance in the same change.
|
||||
- Keep non-Bible docs concise and reference the Bible instead of duplicating it.
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# Project Bible
|
||||
|
||||
The Bible is the single source of truth for this project's architecture.
|
||||
|
||||
## Documentation Rules
|
||||
|
||||
- All architecture decisions must be recorded in this Bible.
|
||||
- The documentation language is English only.
|
||||
- If a decision is superseded, update the Bible immediately and remove or mark obsolete content.
|
||||
- Do not duplicate architecture documentation in `README.md`, `CLAUDE.md`, or other files.
|
||||
|
||||
## Structure
|
||||
|
||||
- `governance/documentation-policy.md` - mandatory rules for maintaining architecture docs.
|
||||
- `architecture/system-overview.md` - current scope, boundaries, and high-level system composition.
|
||||
- `architecture/api-surface.md` - HTTP API and UI route contracts.
|
||||
- `architecture/runtime-flows.md` - critical runtime behavior and failure invariants.
|
||||
- `architecture/ui-information-architecture.md` - required UI structure and semantics.
|
||||
- `decisions/README.md` - how to capture new and updated architecture decisions.
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
# API Surface
|
||||
|
||||
Document all HTTP endpoints and UI routes that are part of the active contract.
|
||||
|
||||
## Rules
|
||||
|
||||
- Keep request/response shapes explicit.
|
||||
- Record compatibility aliases and deprecations.
|
||||
- Update this file when route behavior changes.
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# Runtime Flows
|
||||
|
||||
Document the critical runtime flows and failure invariants.
|
||||
|
||||
Recommended sections:
|
||||
|
||||
- Startup flow
|
||||
- Request handling flow
|
||||
- Background tasks
|
||||
- Failure / retry / cancellation behavior
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
# System Overview
|
||||
|
||||
## Product
|
||||
|
||||
Describe the product in one paragraph.
|
||||
|
||||
## Active Scope
|
||||
|
||||
- List current in-scope modules/features
|
||||
- List user-visible surfaces
|
||||
- List operational responsibilities
|
||||
|
||||
## Explicitly Removed / Out of Scope
|
||||
|
||||
- List legacy or excluded modules to avoid accidental restoration
|
||||
|
||||
## Runtime Composition
|
||||
|
||||
- HTTP server package(s)
|
||||
- Domain/service orchestration
|
||||
- Persistence layer(s)
|
||||
- Migrations / background workers (if any)
|
||||
|
||||
## Local Execution
|
||||
|
||||
- `make run`
|
||||
- `go run ./cmd/<binary>`
|
||||
|
||||
## Verification
|
||||
|
||||
- `go test ./...`
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# UI Information Architecture
|
||||
|
||||
Document page structure, required section order, UI interaction contracts, and list/filter/
|
||||
pagination behavior.
|
||||
|
||||
Use explicit route names and action contracts so AI agents can implement changes consistently.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Architecture Decision Records
|
||||
|
||||
Use this directory to capture architecture decisions and significant updates.
|
||||
|
||||
## Required
|
||||
|
||||
- Every architecture decision must be recorded in the Bible.
|
||||
- If a decision replaces an older one, update the older document in the same change.
|
||||
- Keep entries short, explicit, and linked to the affected architecture files.
|
||||
|
||||
## Minimal Entry Template
|
||||
|
||||
- Date (`YYYY-MM-DD`)
|
||||
- Decision
|
||||
- Context
|
||||
- Consequences
|
||||
- Supersedes (if any)
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# Documentation Policy
|
||||
|
||||
## Purpose
|
||||
|
||||
This policy defines how architectural knowledge is captured and maintained.
|
||||
|
||||
## Mandatory Rules
|
||||
|
||||
- Record every architecture decision in the Bible before or together with implementation.
|
||||
- Use English for all architecture documentation.
|
||||
- Keep only current architecture in active sections.
|
||||
- When a solution is replaced, update or remove obsolete guidance in the same change.
|
||||
- Keep architecture details centralized in `bible/`; other top-level docs should only reference it.
|
||||
|
||||
## Change Workflow
|
||||
|
||||
1. Update the relevant file(s) in `bible/architecture/`.
|
||||
2. If behavior changed, add or update a decision note in `bible/decisions/`.
|
||||
3. Remove duplicated or outdated statements from non-Bible docs.
|
||||
4. Validate consistency against current code paths.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Gin Admin App Integration Notes (Example)
|
||||
|
||||
Suggested use:
|
||||
|
||||
- use `ai-rules` templates only if they do not conflict with existing agent instructions
|
||||
- reuse UI pattern bundles for admin tables and modal workflows
|
||||
- keep domain-specific hard rules in project-local Bible docs
|
||||
@@ -1,10 +0,0 @@
|
||||
# Greenfield App Integration Notes (Example)
|
||||
|
||||
Suggested use:
|
||||
|
||||
- apply `ai-rules`
|
||||
- apply `bible-core` (or merge selectively if a Bible already exists)
|
||||
- apply `ui-theme-vapor` for active visual baseline (CSS + icon sprite)
|
||||
- copy selected UI patterns into new modules/pages
|
||||
|
||||
Keep domain-specific business rules in the host project's own Bible.
|
||||
@@ -1,9 +0,0 @@
|
||||
# net/http Enterprise App Integration Notes (Example)
|
||||
|
||||
This example assumes the host repo already has a mature Bible structure and detailed UI contracts.
|
||||
|
||||
Use this kit primarily for:
|
||||
|
||||
- shared AI instruction wording
|
||||
- pattern bundles that codify existing host UI contracts
|
||||
- future cross-project standardization docs
|
||||
@@ -1,13 +0,0 @@
|
||||
# Operator Tools Pattern
|
||||
|
||||
Universal pattern for complex operator/admin dashboards in Go web applications.
|
||||
|
||||
This pattern standardizes:
|
||||
|
||||
- scope tabs and queue/status filters
|
||||
- operations queue tables with row actions
|
||||
- batch actions with explicit selection
|
||||
- import/export shortcuts near operator workflows
|
||||
- safety checklists and confirmation routing
|
||||
|
||||
See `contract.md` for behavior rules.
|
||||
@@ -1,43 +0,0 @@
|
||||
# Contract: Operator Tools Dashboard
|
||||
|
||||
## Shared Base
|
||||
|
||||
- This pattern inherits the shared `table-management` contract:
|
||||
`kit/patterns/table-management/contract.md`.
|
||||
- Reuse shared toolbar/table/icon geometry from the base contract first, then define only
|
||||
operator-specific behavior.
|
||||
|
||||
## Purpose
|
||||
|
||||
Provide a canonical structure for high-density operator/admin screens without encoding
|
||||
domain-specific terminology or business rules.
|
||||
|
||||
## Required UI Regions
|
||||
|
||||
- Scope tabs (or equivalent segmented navigation)
|
||||
- Queue/status filters
|
||||
- Batch action bar with explicit selection count
|
||||
- Primary queue table/list with stable row actions
|
||||
- Safety/guardrail region (checklist, warnings, runbook notes)
|
||||
|
||||
## Selection and Batch Actions
|
||||
|
||||
- Batch actions must require explicit selection; never infer hidden rows by default.
|
||||
- The UI must display selection counts for the current view and, if applicable, outside the current view/filter.
|
||||
- Destructive or high-impact actions must route through an explicit confirmation step (modal or dedicated confirm state).
|
||||
|
||||
## Status and Queue Semantics
|
||||
|
||||
- Queue/status labels must be consistent across filters, row badges, and summaries.
|
||||
- Failed items must remain easy to filter and retry without losing current scope context.
|
||||
- Running/queued states should be visually distinct from done/failed states.
|
||||
|
||||
## Import / Export Placement
|
||||
|
||||
- Import preview and export actions should be discoverable near operator workflows.
|
||||
- Export scope must remain explicit (`selected`, `filtered`, `all`) when ambiguity exists.
|
||||
|
||||
## Reuse Boundary
|
||||
|
||||
- Keep the pattern generic: host projects provide their own tool names, domain fields, and backend execution logic.
|
||||
- This contract standardizes interaction semantics and layout zones, not business workflows.
|
||||
@@ -1,4 +0,0 @@
|
||||
# Status Indicators Pattern (Planned)
|
||||
|
||||
Reserved for health badges, sync status indicators, and severity labels.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Table + Pagination Pattern
|
||||
|
||||
This pattern package captures a shared contract for table-based UI pages with server-side
|
||||
filters and pagination.
|
||||
|
||||
It is derived from mature server-rendered admin UIs and list-page conventions across multiple
|
||||
Go web codebases.
|
||||
@@ -1,3 +0,0 @@
|
||||
// Placeholder template for pagination helpers.
|
||||
// Adapt from existing host codebase conventions (net/http or Gin).
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
# Contract: Table + Server-Side Filters + Pagination
|
||||
|
||||
## Required Behavior
|
||||
|
||||
- Filters apply to the full query scope before pagination (not page-local filtering).
|
||||
- Pagination state is controlled by URL query parameters.
|
||||
- Changing a filter resets the page parameter to page `1`.
|
||||
- UI shows a summary (`Showing X–Y of N`) and an explicit active page state in pagination controls.
|
||||
- Canonical demo visual style uses a centered dot pager while preserving page semantics via URL parameters and accessible labels.
|
||||
- Demo/base contract includes a `rows per page` control.
|
||||
- Status badge columns should be centered when the column semantics are status-only values.
|
||||
- Small modules (no internal scroll, no more than 2 actions) should place actions in the module header row.
|
||||
- Shared table/filter controls should inherit the repository baseline component theme
|
||||
(currently Vapor Soft / Vapor Night in the canonical demo/scaffold) rather than redefining
|
||||
per-pattern primitives.
|
||||
|
||||
## Recommended Query Parameters
|
||||
|
||||
- `page` for single-list pages
|
||||
- `per_page` when the page-size control is user-visible
|
||||
- section-specific params (for example `active_page`, `chronology_page`) for multi-list pages
|
||||
|
||||
## Interaction Guardrails
|
||||
|
||||
- Same-page filter/pagination interactions should preserve user reading position (for example via module anchors such as `#table-filters` / `#table-list`).
|
||||
- Table status badges should remain readable under the shared theme baseline (including tinted badge variants when a host project opts into a legacy or alternate visual preset).
|
||||
- Dot pager interactions should remain keyboard accessible and expose page meaning via labels/`aria-current`, even if numbers are visually hidden.
|
||||
@@ -1,2 +0,0 @@
|
||||
/* Placeholder styles for table pagination pattern. */
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<!-- Placeholder table + pager partial. -->
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Aqua Theme Module (Legacy Archive Layer)
|
||||
|
||||
Status: legacy archive/reference layer (not the active demo/scaffold baseline).
|
||||
|
||||
This directory preserves the Aqua visual language archive for the design code:
|
||||
|
||||
- global visual tokens and component surfaces
|
||||
- reusable control geometry (buttons, segmented controls, table chrome)
|
||||
- icon rendering baseline (stroke style + sprite integration)
|
||||
|
||||
Active pattern contracts should target the current baseline and may reference this module only
|
||||
for migration/comparison purposes.
|
||||
|
||||
Contents:
|
||||
|
||||
- `demo-aqua-freeze.css` — frozen Aqua stylesheet snapshot
|
||||
- `templates/icon_sprite.html` — canonical icon sprite for reusable action semantics
|
||||
- `notes.md` — scope and usage policy for this theme module
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,23 +0,0 @@
|
||||
# Aqua Theme Notes
|
||||
|
||||
This module is a reusable Aqua style archive for design-code consumers.
|
||||
|
||||
## What it captures
|
||||
|
||||
- Aqua-style control surfaces and button hierarchy
|
||||
- segmented controls and grouped tab geometry
|
||||
- table/filter/toolbars visual primitives
|
||||
- icon rendering baseline and shared icon sprite usage
|
||||
- modal and status component style language
|
||||
|
||||
## How to use
|
||||
|
||||
- Treat this module as a legacy reference snapshot, not the active baseline.
|
||||
- Pattern contracts should inherit the active baseline first and use this module only when a host
|
||||
project explicitly opts into Aqua-like styling.
|
||||
- Do not move new baseline decisions here.
|
||||
|
||||
## Boundary
|
||||
|
||||
- This module standardizes visual language only.
|
||||
- Domain behavior, labels, and business workflow semantics belong to pattern contracts.
|
||||
@@ -1,103 +0,0 @@
|
||||
<!-- Canonical Aqua icon sprite for shared UI actions -->
|
||||
<svg class="icon-sprite" aria-hidden="true" focusable="false" width="0" height="0">
|
||||
<symbol id="ico-select-visible" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" rx="2"></rect>
|
||||
<path d="M5 8.2l2 2.1 4-4.3"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-select-filtered" viewBox="0 0 16 16">
|
||||
<path d="M2.5 3h11l-4.2 4.6v3.1l-2.6 1.5V7.6L2.5 3z"></path>
|
||||
<path d="M11.4 10.2h3M12.9 8.7v3"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-clear-visible" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" rx="2"></rect>
|
||||
<path d="M5 8h6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-clear-filtered" viewBox="0 0 16 16">
|
||||
<path d="M2.5 3h11L9.3 7.6v3.1l-2.6 1.5V7.6L2.5 3z"></path>
|
||||
<path d="M10.5 10.2l3 3M13.5 10.2l-3 3"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-clear-selection" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" rx="2"></rect>
|
||||
<path d="M5 5l6 6M11 5l-6 6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-run" viewBox="0 0 16 16">
|
||||
<path d="M5 3.5l7 4.5-7 4.5z"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-edit" viewBox="0 0 16 16">
|
||||
<path d="M3 13l1.2-3.6L10 3.6l2.4 2.4-5.8 5.8L3 13z"></path>
|
||||
<path d="M8.8 4.8l2.4 2.4"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-remove" viewBox="0 0 16 16">
|
||||
<path d="M4.2 4.2l7.6 7.6M11.8 4.2l-7.6 7.6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-cancel" viewBox="0 0 16 16">
|
||||
<circle cx="8" cy="8" r="5.5"></circle>
|
||||
<path d="M5.5 5.5l5 5M10.5 5.5l-5 5"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-archive" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="3" width="11" height="2.8" rx="1"></rect>
|
||||
<path d="M3.5 5.8V13h9V5.8"></path>
|
||||
<path d="M6.2 8h3.6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-import" viewBox="0 0 16 16">
|
||||
<path d="M3 4.2v8.6h10V4.2"></path>
|
||||
<path d="M8 1.8v6.2"></path>
|
||||
<path d="M5.8 5.8L8 8l2.2-2.2"></path>
|
||||
<path d="M5 10.2h6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-export" viewBox="0 0 16 16">
|
||||
<path d="M3 4.2v8.6h10V4.2"></path>
|
||||
<path d="M8 8V1.8"></path>
|
||||
<path d="M5.8 4L8 1.8 10.2 4"></path>
|
||||
<path d="M5 10.2h6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-export-filtered" viewBox="0 0 16 16">
|
||||
<path d="M2 4.2v8.6h10.8"></path>
|
||||
<path d="M7 8V1.8"></path>
|
||||
<path d="M4.8 4L7 1.8 9.2 4"></path>
|
||||
<path d="M10 5.1h5.2L13.1 7.5v3.1l-1.3.7V7.5z"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-export-selected" viewBox="0 0 16 16">
|
||||
<path d="M2 4.2v8.6h10.8"></path>
|
||||
<path d="M7 8V1.8"></path>
|
||||
<path d="M4.8 4L7 1.8 9.2 4"></path>
|
||||
<rect x="10.1" y="5.2" width="5" height="5" rx="0.6"></rect>
|
||||
<path d="M11.2 6.3l2.8 2.8M14 6.3l-2.8 2.8"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-retry" viewBox="0 0 16 16">
|
||||
<path d="M12.2 6A4.8 4.8 0 0 0 4.8 4.4"></path>
|
||||
<path d="M5.6 2.9L4.1 4.6 5.9 5.8"></path>
|
||||
<path d="M3.8 10A4.8 4.8 0 0 0 11.2 11.6"></path>
|
||||
<path d="M10.4 13.1L11.9 11.4 10.1 10.2"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-review" viewBox="0 0 16 16">
|
||||
<circle cx="8" cy="8" r="5.5"></circle>
|
||||
<path d="M8 7.2v3.6"></path>
|
||||
<path d="M8 5.1h.01"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-mark-review" viewBox="0 0 16 16">
|
||||
<path d="M8 2.6l5.2 2v3.7c0 2.3-1.5 4.4-5.2 5.7-3.7-1.3-5.2-3.4-5.2-5.7V4.6l5.2-2z"></path>
|
||||
<path d="M8 6.1v3.2"></path>
|
||||
<path d="M8 11.1h.01"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-confirm" viewBox="0 0 16 16">
|
||||
<path d="M8 2.5l5 2v3.8c0 2.2-1.3 4.1-5 5.3-3.7-1.2-5-3.1-5-5.3V4.5l5-2z"></path>
|
||||
<path d="M5.7 8.3l1.6 1.7 3-3.1"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-inspect" viewBox="0 0 16 16">
|
||||
<circle cx="7" cy="7" r="3.8"></circle>
|
||||
<path d="M9.8 9.8l3.2 3.2"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-scope" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="4.2" height="4.2"></rect>
|
||||
<rect x="9.3" y="2.5" width="4.2" height="4.2"></rect>
|
||||
<rect x="2.5" y="9.3" width="4.2" height="4.2"></rect>
|
||||
<rect x="9.3" y="9.3" width="4.2" height="4.2"></rect>
|
||||
</symbol>
|
||||
<symbol id="ico-queue" viewBox="0 0 16 16">
|
||||
<path d="M5.4 4h8.1M5.4 8h8.1M5.4 12h8.1"></path>
|
||||
<circle cx="3.2" cy="4" r="0.7"></circle>
|
||||
<circle cx="3.2" cy="8" r="0.7"></circle>
|
||||
<circle cx="3.2" cy="12" r="0.7"></circle>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB |
@@ -1,17 +0,0 @@
|
||||
# Vapor Theme Module (Active Design Layer)
|
||||
|
||||
Status: active visual baseline for reusable UI primitives.
|
||||
|
||||
This module defines the shared Vapor visual language used by the demo and intended host-project
|
||||
integration:
|
||||
|
||||
- baseline tokens and surface treatment
|
||||
- reusable component geometry (buttons, segmented controls, table chrome)
|
||||
- shared icon sprite for table-management and operator workflows
|
||||
|
||||
Contents:
|
||||
|
||||
- `static/vapor.css` - active stylesheet baseline
|
||||
- `templates/icon_sprite.html` - active icon sprite
|
||||
- `notes.md` - usage boundaries and integration rules
|
||||
- `palette-catalog.md` - preset list for app-shell header and accent colors
|
||||
@@ -1,28 +0,0 @@
|
||||
# Vapor Theme Notes
|
||||
|
||||
This module is the active reusable theme source for design-code consumers.
|
||||
|
||||
## What it captures
|
||||
|
||||
- Vapor control surfaces and button hierarchy
|
||||
- segmented controls and grouped tab geometry
|
||||
- table/filter/toolbar primitives
|
||||
- icon rendering baseline and shared sprite usage
|
||||
- modal and status component style language
|
||||
- app-shell color/height presets for host-level branding fit within Vapor aesthetics
|
||||
|
||||
## How to use
|
||||
|
||||
- Use this module as the visual baseline for host projects that adopt the canonical demo style.
|
||||
- Pattern contracts should reference shared behavior contracts and rely on this module for visual primitives.
|
||||
- When baseline visuals change, update this module first to keep downstream integration deterministic.
|
||||
- For shell color selection, use `palette-catalog.md` and set `data-vapor-shell` on `<html>`.
|
||||
- For runtime switching, the recommended query key is `vapor_shell` (same IDs as the catalog).
|
||||
- Keep host-specific brand overrides outside this module unless they are reusable presets.
|
||||
|
||||
## Boundary
|
||||
|
||||
- This module standardizes visual language only.
|
||||
- Domain behavior, labels, and business workflow semantics belong to pattern contracts.
|
||||
- Preset palette IDs are part of the reusable contract; host projects may choose one, but should not
|
||||
rename/remove preset IDs in downstream copies without migration notes.
|
||||
@@ -1,50 +0,0 @@
|
||||
# Vapor Shell Palette Catalog
|
||||
|
||||
This catalog defines reusable `app-shell` presets for host projects that consume `theme-vapor`.
|
||||
|
||||
Apply a preset on the root element:
|
||||
|
||||
```html
|
||||
<html data-vapor-shell="miami-sunset">
|
||||
```
|
||||
|
||||
Optional: host project can override shell height without changing preset IDs:
|
||||
|
||||
```css
|
||||
:root { --shell-height: 72px; }
|
||||
```
|
||||
|
||||
## Selection Approach
|
||||
|
||||
Recommended precedence for host integration:
|
||||
|
||||
1. `?vapor_shell=<preset-id>` query parameter (preview/share links)
|
||||
2. `localStorage["vapor_shell"]` (remembered user choice)
|
||||
3. `<html data-vapor-shell="...">` static default from server/templates
|
||||
4. fallback preset: `miami-sunset`
|
||||
|
||||
The scaffold and demo JavaScript implement this precedence.
|
||||
|
||||
## Presets (Header + Accent)
|
||||
|
||||
| Preset ID | Header core | Accent core | Default shell height |
|
||||
|---|---|---|---|
|
||||
| `miami-sunset` | `#fbe5f8` | `#ff7ec7` | `66px` |
|
||||
| `neon-grid` | `#f5eeff` | `#ff4fd8` | `64px` |
|
||||
| `laser-flamingo` | `#ffe8f4` | `#ff6fae` | `70px` |
|
||||
| `synth-lagoon` | `#e8f6ff` | `#67d7ff` | `62px` |
|
||||
| `mall-soft` | `#fff1f8` | `#ffb5d7` | `68px` |
|
||||
| `hologram-sky` | `#edf9ff` | `#5ce4ff` | `64px` |
|
||||
| `peach-drive` | `#fff0e6` | `#ff9a6a` | `72px` |
|
||||
| `ultraviolet-plaza` | `#f0e8ff` | `#b26dff` | `66px` |
|
||||
| `cyber-mint` | `#ebfff7` | `#57f0c1` | `62px` |
|
||||
|
||||
## Token Surface
|
||||
|
||||
Each preset resolves these tokens in `static/vapor.css`:
|
||||
|
||||
- `--shell-height`
|
||||
- `--shell-bg-light`, `--shell-bg-dark`
|
||||
- `--shell-border-light`, `--shell-border-dark`
|
||||
- `--shell-accent-light`, `--shell-accent-dark`
|
||||
- `--shell-accent-line-light`, `--shell-accent-line-dark`
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,102 +0,0 @@
|
||||
<svg class="icon-sprite" aria-hidden="true" focusable="false" width="0" height="0">
|
||||
<symbol id="ico-select-visible" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" rx="2"></rect>
|
||||
<path d="M5 8.2l2 2.1 4-4.3"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-select-filtered" viewBox="0 0 16 16">
|
||||
<path d="M2.5 3h11l-4.2 4.6v3.1l-2.6 1.5V7.6L2.5 3z"></path>
|
||||
<path d="M11.4 10.2h3M12.9 8.7v3"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-clear-visible" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" rx="2"></rect>
|
||||
<path d="M5 8h6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-clear-filtered" viewBox="0 0 16 16">
|
||||
<path d="M2.5 3h11L9.3 7.6v3.1l-2.6 1.5V7.6L2.5 3z"></path>
|
||||
<path d="M10.5 10.2l3 3M13.5 10.2l-3 3"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-clear-selection" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" rx="2"></rect>
|
||||
<path d="M5 5l6 6M11 5l-6 6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-run" viewBox="0 0 16 16">
|
||||
<path d="M5 3.5l7 4.5-7 4.5z"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-edit" viewBox="0 0 16 16">
|
||||
<path d="M3 13l1.2-3.6L10 3.6l2.4 2.4-5.8 5.8L3 13z"></path>
|
||||
<path d="M8.8 4.8l2.4 2.4"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-remove" viewBox="0 0 16 16">
|
||||
<path d="M4.2 4.2l7.6 7.6M11.8 4.2l-7.6 7.6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-cancel" viewBox="0 0 16 16">
|
||||
<circle cx="8" cy="8" r="5.5"></circle>
|
||||
<path d="M5.5 5.5l5 5M10.5 5.5l-5 5"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-archive" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="3" width="11" height="2.8" rx="1"></rect>
|
||||
<path d="M3.5 5.8V13h9V5.8"></path>
|
||||
<path d="M6.2 8h3.6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-import" viewBox="0 0 16 16">
|
||||
<path d="M3 4.2v8.6h10V4.2"></path>
|
||||
<path d="M8 1.8v6.2"></path>
|
||||
<path d="M5.8 5.8L8 8l2.2-2.2"></path>
|
||||
<path d="M5 10.2h6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-export" viewBox="0 0 16 16">
|
||||
<path d="M3 4.2v8.6h10V4.2"></path>
|
||||
<path d="M8 8V1.8"></path>
|
||||
<path d="M5.8 4L8 1.8 10.2 4"></path>
|
||||
<path d="M5 10.2h6"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-export-filtered" viewBox="0 0 16 16">
|
||||
<path d="M2 4.2v8.6h10.8"></path>
|
||||
<path d="M7 8V1.8"></path>
|
||||
<path d="M4.8 4L7 1.8 9.2 4"></path>
|
||||
<path d="M10 5.1h5.2L13.1 7.5v3.1l-1.3.7V7.5z"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-export-selected" viewBox="0 0 16 16">
|
||||
<path d="M2 4.2v8.6h10.8"></path>
|
||||
<path d="M7 8V1.8"></path>
|
||||
<path d="M4.8 4L7 1.8 9.2 4"></path>
|
||||
<rect x="10.1" y="5.2" width="5" height="5" rx="0.6"></rect>
|
||||
<path d="M11.2 6.3l2.8 2.8M14 6.3l-2.8 2.8"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-retry" viewBox="0 0 16 16">
|
||||
<path d="M12.2 6A4.8 4.8 0 0 0 4.8 4.4"></path>
|
||||
<path d="M5.6 2.9L4.1 4.6 5.9 5.8"></path>
|
||||
<path d="M3.8 10A4.8 4.8 0 0 0 11.2 11.6"></path>
|
||||
<path d="M10.4 13.1L11.9 11.4 10.1 10.2"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-review" viewBox="0 0 16 16">
|
||||
<circle cx="8" cy="8" r="5.5"></circle>
|
||||
<path d="M8 7.2v3.6"></path>
|
||||
<path d="M8 5.1h.01"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-mark-review" viewBox="0 0 16 16">
|
||||
<path d="M8 2.6l5.2 2v3.7c0 2.3-1.5 4.4-5.2 5.7-3.7-1.3-5.2-3.4-5.2-5.7V4.6l5.2-2z"></path>
|
||||
<path d="M8 6.1v3.2"></path>
|
||||
<path d="M8 11.1h.01"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-confirm" viewBox="0 0 16 16">
|
||||
<path d="M8 2.5l5 2v3.8c0 2.2-1.3 4.1-5 5.3-3.7-1.2-5-3.1-5-5.3V4.5l5-2z"></path>
|
||||
<path d="M5.7 8.3l1.6 1.7 3-3.1"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-inspect" viewBox="0 0 16 16">
|
||||
<circle cx="7" cy="7" r="3.8"></circle>
|
||||
<path d="M9.8 9.8l3.2 3.2"></path>
|
||||
</symbol>
|
||||
<symbol id="ico-scope" viewBox="0 0 16 16">
|
||||
<rect x="2.5" y="2.5" width="4.2" height="4.2"></rect>
|
||||
<rect x="9.3" y="2.5" width="4.2" height="4.2"></rect>
|
||||
<rect x="2.5" y="9.3" width="4.2" height="4.2"></rect>
|
||||
<rect x="9.3" y="9.3" width="4.2" height="4.2"></rect>
|
||||
</symbol>
|
||||
<symbol id="ico-queue" viewBox="0 0 16 16">
|
||||
<path d="M5.4 4h8.1M5.4 8h8.1M5.4 12h8.1"></path>
|
||||
<circle cx="3.2" cy="4" r="0.7"></circle>
|
||||
<circle cx="3.2" cy="8" r="0.7"></circle>
|
||||
<circle cx="3.2" cy="12" r="0.7"></circle>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.3 KiB |
@@ -1,12 +0,0 @@
|
||||
# Timeline Cards Pattern
|
||||
|
||||
Canonical timeline UX for operational history views:
|
||||
|
||||
- cards grouped by day
|
||||
- summary chips for aggregated actions
|
||||
- source labels (`ingest`, `manual`, `system`, etc.)
|
||||
- single drilldown modal (no nested modals)
|
||||
- in-card search/filtering for event lists
|
||||
|
||||
This pattern is intended for history/audit/timeline surfaces in server-rendered Go web UIs.
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# Contract: Timeline Cards + Drilldown
|
||||
|
||||
## Card Grouping
|
||||
|
||||
- Render timeline as grouped cards (typically by day), not raw event rows.
|
||||
- Correlated or visually equivalent events may be collapsed into one card with counts.
|
||||
- Card summaries should be human-readable and avoid repeating page-scope identity labels.
|
||||
|
||||
## Filters
|
||||
|
||||
- Timeline filters are server-side when timeline is paginated or large.
|
||||
- Filters should preserve grouping semantics and timezone behavior.
|
||||
- Scope-invariant filters may be hidden on entity detail pages.
|
||||
|
||||
## Drilldown
|
||||
|
||||
- One card opens one drilldown modal/panel.
|
||||
- Drilldown contains:
|
||||
- event list (left/top)
|
||||
- selected event details (right/bottom)
|
||||
- No nested modal inside drilldown.
|
||||
- Card-local search/filter may be applied within the drilldown.
|
||||
|
||||
## UX Rules
|
||||
|
||||
- Use human-readable source labels.
|
||||
- Prefer action-oriented card titles (`Installed N components`, `Removed N components`).
|
||||
- Empty states must explain whether filters removed all results.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
run:
|
||||
go run ./cmd/demo-server
|
||||
|
||||
build:
|
||||
go build ./cmd/demo-server
|
||||
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
fmt:
|
||||
gofmt -w $$(find . -name '*.go' -type f)
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Go net/http Web Skeleton
|
||||
|
||||
Minimal starter skeleton for a Go web app using:
|
||||
|
||||
- `net/http`
|
||||
- `html/template`
|
||||
- embedded templates and static assets
|
||||
|
||||
This scaffold is intended as a starting point that host repositories can adapt.
|
||||
|
||||
Vapor shell preset integration is included:
|
||||
|
||||
- default preset via `<html data-vapor-shell="miami-sunset">`
|
||||
- runtime override via `?vapor_shell=<preset-id>`
|
||||
- persisted selection via `localStorage["vapor_shell"]`
|
||||
@@ -1,23 +0,0 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type IndexViewData struct {
|
||||
Title string
|
||||
}
|
||||
|
||||
func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
_ = s.render(w, "base.html", IndexViewData{Title: "Home"})
|
||||
}
|
||||
|
||||
func (s *Server) handleHealthz(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write([]byte("ok"))
|
||||
}
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
|
||||
appweb "{{ .module_path }}/web"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
mux *http.ServeMux
|
||||
tmpl *template.Template
|
||||
}
|
||||
|
||||
func NewServer() (*Server, error) {
|
||||
tmpl, err := parseTemplates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &Server{
|
||||
mux: http.NewServeMux(),
|
||||
tmpl: tmpl,
|
||||
}
|
||||
s.registerRoutes()
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) Handler() http.Handler { return s.mux }
|
||||
|
||||
func (s *Server) registerRoutes() {
|
||||
s.mux.HandleFunc("/", s.handleIndex)
|
||||
s.mux.HandleFunc("/healthz", s.handleHealthz)
|
||||
staticFS, _ := fs.Sub(appweb.Assets, "static")
|
||||
s.mux.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(staticFS))))
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
appweb "{{ .module_path }}/web"
|
||||
)
|
||||
|
||||
func parseTemplates() (*template.Template, error) {
|
||||
t, err := template.ParseFS(appweb.Assets, "templates/*.html")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse templates: %w", err)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
func (s *Server) render(w http.ResponseWriter, name string, data any) error {
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if err := s.tmpl.ExecuteTemplate(w, name, data); err != nil {
|
||||
http.Error(w, "template error", http.StatusInternalServerError)
|
||||
return fmt.Errorf("render %s: %w", name, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package web
|
||||
|
||||
import "embed"
|
||||
|
||||
// Assets contains templates and static files.
|
||||
//
|
||||
//go:embed templates/* static/*
|
||||
var Assets embed.FS
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
:root {
|
||||
--bg: #e6e8ee;
|
||||
--ink: #1f2023;
|
||||
--muted: #5d646f;
|
||||
--card: linear-gradient(180deg, rgba(252,252,253,0.99), rgba(240, 244, 249, 0.97) 44%, rgba(228, 238, 248, 0.96) 78%, rgba(221, 234, 248, 0.96));
|
||||
--line: #b9cbe0;
|
||||
--accent: linear-gradient(180deg, #85b8ef 0%, #93c6fb 26%, #abd8ff 55%, #c7e8ff 82%, #def2ff 100%);
|
||||
--accent-line: #88a4d4;
|
||||
}
|
||||
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Lucida Grande", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
background:
|
||||
radial-gradient(760px 360px at 14% 6%, rgba(255,255,255,0.82), transparent 72%),
|
||||
radial-gradient(760px 360px at 88% 8%, rgba(154, 203, 247, 0.16), transparent 74%),
|
||||
repeating-linear-gradient(to bottom, rgba(255,255,255,0.05) 0 1px, rgba(170,182,198,0.03) 1px 3px),
|
||||
linear-gradient(#eef1f6, #dde2ea);
|
||||
color: var(--ink);
|
||||
}
|
||||
.shell {
|
||||
max-width: 880px;
|
||||
margin: 0 auto;
|
||||
padding: 24px 16px 48px;
|
||||
}
|
||||
.hero { margin-bottom: 16px; }
|
||||
.eyebrow {
|
||||
margin: 0;
|
||||
color: #5f6772;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
font-size: 12px;
|
||||
}
|
||||
h1 { margin: 6px 0 0; font-size: 32px; }
|
||||
.card {
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,0.70), rgba(255,255,255,0.18) 28%, rgba(255,255,255,0.0) 29%),
|
||||
repeating-linear-gradient(to bottom, rgba(255,255,255,0.26) 0 1px, rgba(188,205,223,0.10) 1px 3px),
|
||||
var(--card);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 14px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 10px 20px rgba(78, 107, 139, 0.09), inset 0 1px 0 rgba(255,255,255,0.96);
|
||||
}
|
||||
code { background: #eef3fb; padding: 1px 5px; border-radius: 6px; }
|
||||
@@ -1,65 +0,0 @@
|
||||
(() => {
|
||||
const root = document.documentElement;
|
||||
const storageKey = "vapor_shell";
|
||||
const queryKey = "vapor_shell";
|
||||
const fallbackPreset = "miami-sunset";
|
||||
const allowed = new Set([
|
||||
"miami-sunset",
|
||||
"neon-grid",
|
||||
"laser-flamingo",
|
||||
"synth-lagoon",
|
||||
"mall-soft",
|
||||
"hologram-sky",
|
||||
"peach-drive",
|
||||
"ultraviolet-plaza",
|
||||
"cyber-mint",
|
||||
]);
|
||||
|
||||
const normalizePreset = (value) => {
|
||||
const trimmed = (value || "").trim().toLowerCase();
|
||||
if (!trimmed || !allowed.has(trimmed)) {
|
||||
return "";
|
||||
}
|
||||
return trimmed;
|
||||
};
|
||||
|
||||
const setPreset = (value) => {
|
||||
const preset = normalizePreset(value);
|
||||
if (!preset) {
|
||||
return false;
|
||||
}
|
||||
root.setAttribute("data-vapor-shell", preset);
|
||||
return true;
|
||||
};
|
||||
|
||||
root.classList.add("js");
|
||||
|
||||
const url = new URL(window.location.href);
|
||||
const fromQuery = normalizePreset(url.searchParams.get(queryKey));
|
||||
if (fromQuery) {
|
||||
setPreset(fromQuery);
|
||||
try {
|
||||
window.localStorage.setItem(storageKey, fromQuery);
|
||||
} catch (_err) {
|
||||
// Keep behavior deterministic even when storage is blocked.
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const fromMarkup = normalizePreset(root.getAttribute("data-vapor-shell"));
|
||||
if (fromMarkup) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const fromStorage = normalizePreset(window.localStorage.getItem(storageKey));
|
||||
if (fromStorage) {
|
||||
setPreset(fromStorage);
|
||||
return;
|
||||
}
|
||||
} catch (_err) {
|
||||
// Fallback handled below.
|
||||
}
|
||||
|
||||
setPreset(fallbackPreset);
|
||||
})();
|
||||
@@ -1,21 +0,0 @@
|
||||
{{ define "base.html" }}
|
||||
<!doctype html>
|
||||
<html lang="en" data-vapor-shell="miami-sunset">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{{ .Title }}</title>
|
||||
<link rel="stylesheet" href="/static/css/app.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="shell">
|
||||
<header class="hero">
|
||||
<p class="eyebrow">Go Web Scaffold</p>
|
||||
<h1>{{ .Title }}</h1>
|
||||
</header>
|
||||
{{ template "content" . }}
|
||||
</main>
|
||||
<script src="/static/js/app.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
{{ end }}
|
||||
@@ -1,11 +0,0 @@
|
||||
{{ define "content" }}
|
||||
<section class="card">
|
||||
<p>Minimal net/http + html/template scaffold.</p>
|
||||
<ul>
|
||||
<li><code>GET /</code> page</li>
|
||||
<li><code>GET /healthz</code> healthcheck</li>
|
||||
<li><code>/static/*</code> embedded assets</li>
|
||||
</ul>
|
||||
</section>
|
||||
{{ end }}
|
||||
|
||||
Reference in New Issue
Block a user