From 820df9a196411ab75af49b835a56a8c5a98bfc92 Mon Sep 17 00:00:00 2001 From: archipelago Date: Fri, 9 Oct 2026 07:31:06 -0400 Subject: [PATCH] feat: add Archipelago agent skills and app starter --- .agents/skills/archipelago-app/SKILL.md | 49 ++++++++++++++ .../skills/archipelago-app/agents/openai.yaml | 7 ++ .../references/app-contract.md | 17 +++++ .agents/skills/archipelago-design/SKILL.md | 41 ++++++++++++ .../archipelago-design/agents/openai.yaml | 7 ++ .../references/component-map.md | 15 +++++ .../references/design-contract.md | 18 +++++ .agents/skills/archipelago/SKILL.md | 53 +++++++++++++++ .agents/skills/archipelago/agents/openai.yaml | 7 ++ .../skills/archipelago/references/routing.md | 10 +++ .../archipelago/references/system-map.md | 19 ++++++ examples/archipelago-app-starter/.gitignore | 5 ++ examples/archipelago-app-starter/Dockerfile | 16 +++++ examples/archipelago-app-starter/README.md | 11 +++ examples/archipelago-app-starter/index.html | 13 ++++ examples/archipelago-app-starter/manifest.yml | 48 +++++++++++++ examples/archipelago-app-starter/package.json | 18 +++++ examples/archipelago-app-starter/src/App.vue | 67 +++++++++++++++++++ examples/archipelago-app-starter/src/main.ts | 5 ++ .../archipelago-app-starter/src/styles.css | 54 +++++++++++++++ .../archipelago-app-starter/vite.config.ts | 4 ++ 21 files changed, 484 insertions(+) create mode 100644 .agents/skills/archipelago-app/SKILL.md create mode 100644 .agents/skills/archipelago-app/agents/openai.yaml create mode 100644 .agents/skills/archipelago-app/references/app-contract.md create mode 100644 .agents/skills/archipelago-design/SKILL.md create mode 100644 .agents/skills/archipelago-design/agents/openai.yaml create mode 100644 .agents/skills/archipelago-design/references/component-map.md create mode 100644 .agents/skills/archipelago-design/references/design-contract.md create mode 100644 .agents/skills/archipelago/SKILL.md create mode 100644 .agents/skills/archipelago/agents/openai.yaml create mode 100644 .agents/skills/archipelago/references/routing.md create mode 100644 .agents/skills/archipelago/references/system-map.md create mode 100644 examples/archipelago-app-starter/.gitignore create mode 100644 examples/archipelago-app-starter/Dockerfile create mode 100644 examples/archipelago-app-starter/README.md create mode 100644 examples/archipelago-app-starter/index.html create mode 100644 examples/archipelago-app-starter/manifest.yml create mode 100644 examples/archipelago-app-starter/package.json create mode 100644 examples/archipelago-app-starter/src/App.vue create mode 100644 examples/archipelago-app-starter/src/main.ts create mode 100644 examples/archipelago-app-starter/src/styles.css create mode 100644 examples/archipelago-app-starter/vite.config.ts diff --git a/.agents/skills/archipelago-app/SKILL.md b/.agents/skills/archipelago-app/SKILL.md new file mode 100644 index 00000000..3af28e91 --- /dev/null +++ b/.agents/skills/archipelago-app/SKILL.md @@ -0,0 +1,49 @@ +--- +name: archipelago-app +description: Build, package, test, and update a manifest-driven Archipelago app using the real app developer contract, rootless runtime, and lifecycle acceptance flow. +metadata: + short-description: Build a real Archipelago app +--- + +# Archipelago app development + +Use this skill when creating or changing an Archipelago app, manifest, container +build, app integration, credentials, signer flow, or app preview. Always load +`archipelago-design` for newly authored UI. + +Read [app-contract.md](references/app-contract.md), +`docs/app-developer-guide.md`, and `docs/app-manifest-spec.md` before coding. + +## Required loop + +1. Create a dedicated worktree or project directory and choose the smallest + useful app scope. Prefer the maintained starter and its pinned dependencies. +2. Implement the app as a manifest, rootless container, persistent data path, + truthful health/readiness check, declared interface, and tests. Never add a + per-app Rust installer or rootful/Docker-socket shortcut. +3. Use generated secrets or declared secret files; never put credentials in a + manifest, image, logs, URL, or frontend bundle. Keep production wallets and + app databases outside development fixtures. +4. Validate the manifest and build context, then run the app through install, + start, stop, restart, manager restart, uninstall with data preservation, and + reinstall. Verify the real My Apps/Services launch path, not only a direct + port. +5. For UI, exercise standalone and embedded modes at 320, 390, 768, and 1440px + plus phone landscape, keyboard navigation, loading/empty/error/retry/success, + safe areas, and reduced motion. +6. Report source, disposable-node, actual-node, and release-artifact evidence + separately. Catalog publication is a separate request. + +Important runtime facts: + +- `/opt/archipelago/apps` is rebuilt from the runtime payload at backend start; + staging only there will be lost. Follow the developer guide's payload path. +- Signed catalog entries take precedence over disk manifests for catalog apps. +- Installed does not mean ready or launchable; use health and readiness evidence. +- App interfaces describe the service behind the gate. Do not hard-code a node + IP, scheme, app path, or host frame URL into app code. + +## References + +- [app contract and acceptance](references/app-contract.md) +- [design routing](../archipelago-design/SKILL.md) diff --git a/.agents/skills/archipelago-app/agents/openai.yaml b/.agents/skills/archipelago-app/agents/openai.yaml new file mode 100644 index 00000000..55c93594 --- /dev/null +++ b/.agents/skills/archipelago-app/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Archipelago app" + short_description: "Build a real Archipelago app" + brand_color: "#F7931A" + default_prompt: "Use $archipelago-app to build and validate this Archipelago app." +policy: + allow_implicit_invocation: true diff --git a/.agents/skills/archipelago-app/references/app-contract.md b/.agents/skills/archipelago-app/references/app-contract.md new file mode 100644 index 00000000..823235d5 --- /dev/null +++ b/.agents/skills/archipelago-app/references/app-contract.md @@ -0,0 +1,17 @@ +# App contract + +Start with `docs/app-developer-guide.md` and `docs/app-manifest-spec.md`; those +files are authoritative for fields and launch behavior. Validate with: + +```bash +./scripts/validate-app-manifest.sh apps//manifest.yml +python3 scripts/generate-app-catalog.py +python3 scripts/check-app-catalog-drift.py --release --strict +``` + +Use pinned image versions, read-only root, no-new-privileges, minimal +capabilities, rootless Podman, declared persistent data under +`/var/lib/archipelago/`, health checks, generated/declared secrets, and +truthful interfaces. Test install/start/stop/restart/manager-restart/uninstall +with data preservation/reinstall on a disposable node. Do not replace the +signed catalog to make a local test app appear. diff --git a/.agents/skills/archipelago-design/SKILL.md b/.agents/skills/archipelago-design/SKILL.md new file mode 100644 index 00000000..e6926f77 --- /dev/null +++ b/.agents/skills/archipelago-design/SKILL.md @@ -0,0 +1,41 @@ +--- +name: archipelago-design +description: Create or change Archipelago UI using the shared semantic tokens, components, responsive patterns, accessibility states, and embedded/standalone host contract. +metadata: + short-description: Keep Archipelago UI consistent +--- + +# Archipelago design system + +Use this skill for any new or changed Archipelago UI, including app screens, +Terminal, setup flows, dialogs, dashboards, and app wrappers. Read +[design-contract.md](references/design-contract.md) before implementation. + +## Rules + +- Find and reuse the closest shared component and pattern before creating one. +- Use semantic `--archy-*` tokens and the pinned kit version. A bespoke color, + font, radius, shadow, or z-index needs a documented reason. +- Preserve the dark baseline, readable surfaces, 4px spacing rhythm, bottom + action placement, 44px touch targets, visible focus, and safe-area behavior. +- Keep terminal/editor/tmux keys inside the terminal focus boundary; generic + modal Escape/arrow handlers must not consume them. +- Implement loading, empty, offline, denied, validation-error, retry, disabled, + and confirmed-success states. Status color must have text or icon support. +- Test standalone and embedded modes. Embedded apps do not duplicate the host + wallpaper or navigation and must work without a host handshake. + +## Workflow + +1. Read the reference screen and source; choose the matching component/pattern. +2. Build with the shared kit and local assets, not runtime dashboard CSS or CDN + fonts. Keep host RPC, signer, and credential bridges behind typed adapters. +3. Render the gallery/preview at required viewports and inspect screenshots and + keyboard behavior. Check contrast on the real composited surface. +4. Record deliberate exceptions and update the kit only when a reusable need is + demonstrated. Do not silently accept visual-diff changes. + +## References + +- [design contract](references/design-contract.md) +- [existing component map](references/component-map.md) diff --git a/.agents/skills/archipelago-design/agents/openai.yaml b/.agents/skills/archipelago-design/agents/openai.yaml new file mode 100644 index 00000000..4d113931 --- /dev/null +++ b/.agents/skills/archipelago-design/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Archipelago design" + short_description: "Keep Archipelago UI consistent" + brand_color: "#F7931A" + default_prompt: "Use $archipelago-design to implement this UI in Archipelago's design system." +policy: + allow_implicit_invocation: true diff --git a/.agents/skills/archipelago-design/references/component-map.md b/.agents/skills/archipelago-design/references/component-map.md new file mode 100644 index 00000000..53e4068f --- /dev/null +++ b/.agents/skills/archipelago-design/references/component-map.md @@ -0,0 +1,15 @@ +# Existing component map + +Reuse these first: + +- Structure: `BaseModal.vue`, `BackButton.vue`, `EmptyState.vue`, + `SkeletonCard.vue`. +- Controls: `ToggleSwitch.vue`, `PasswordRevealInput.vue`, + `AppSearchField.vue`, `CopyButton.vue`. +- Feedback: `ToastStack.vue`, `ContainerStatus.vue`, existing upload/progress + components. +- Completion: `PaymentSuccessPane.vue`, `IdentitySuccessPane.vue`. +- App flows: `AppLauncherOverlay.vue`, `AppCredentialInterstitial.vue`. + +The terminal must have an explicit keyboard ownership boundary and must not be +wrapped in the generic arrow-key modal behavior without adapting it. diff --git a/.agents/skills/archipelago-design/references/design-contract.md b/.agents/skills/archipelago-design/references/design-contract.md new file mode 100644 index 00000000..4809b62f --- /dev/null +++ b/.agents/skills/archipelago-design/references/design-contract.md @@ -0,0 +1,18 @@ +# Design contract + +The current baseline is defined by `neode-ui/src/style.css`, +`neode-ui/tailwind.config.js`, `BaseModal.vue`, `AppSearchField.vue`, +`EmptyState.vue`, `SkeletonCard.vue`, and `PaymentSuccessPane.vue`. Preserve the +dark canvas, glass-card surface, 4px spacing scale, semantic orange accent, +local licensed fonts, bottom card actions, 40px desktop/52px mobile search, +44px touch targets, visible focus, dynamic viewport, safe-area and embedded +canvas rules while the shared kit is extracted. + +Use semantic tokens, not raw values. New controls must document keyboard, +focus, disabled, loading, validation, error, retry, success, responsive, and +reduced-motion behavior. No essential action may be hover-only. Use the existing +dialog footer/content split and restore focus after close. + +Visual acceptance covers 320/390/768/1440px, phone landscape, enlarged text, +standalone/embedded modes, dark native controls, no-blur fallback, and actual +Companion WebView behavior where applicable. diff --git a/.agents/skills/archipelago/SKILL.md b/.agents/skills/archipelago/SKILL.md new file mode 100644 index 00000000..f5ccabba --- /dev/null +++ b/.agents/skills/archipelago/SKILL.md @@ -0,0 +1,53 @@ +--- +name: archipelago +description: Configure, troubleshoot, and safely modify an Archipelago node or its developer environment using the repository's typed operations, ownership rules, and recovery workflow. +metadata: + short-description: Work safely on Archipelago systems +--- + +# Archipelago system work + +Use this skill for node configuration, terminal/developer setup, service +diagnosis, network and SSH work, supported app operations, and system changes. +For app implementation load `archipelago-app`; for any new or changed UI also +load `archipelago-design`. + +Read [system-map.md](references/system-map.md) before acting. Read `AGENTS.md` +and the relevant project documentation in the current checkout. + +## Workflow + +1. Identify the node, repository/worktree, owner, and whether the request is + planning, source work, a disposable test, or a live-node operation. +2. Inspect current state before changing it. Prefer `archy`/Archipelago RPC + operations and existing scripts over direct edits or ad-hoc service commands. +3. Preserve wallets, app data, credentials, user uninstall decisions, and + unrelated services. Back up only the scoped state before a mutation. +4. Make the smallest reversible change. Keep generated state separate from + user overrides; never edit generated or packaged files when an owned source + or managed override exists. +5. Verify the actual result and report source tests, disposable integration, + live-node acceptance, and packaged-artifact checks separately. + +For repository work, use a dedicated worktree and focused branch. For backend +unit tests use `scripts/test-backend-isolated.sh`; do not run unrestricted +`cargo test` on a node with installed apps. Do not publish OTA, ISO, catalog, +or Git mirrors from this skill unless that publication is explicitly requested +and every release gate is satisfied. + +## Terminal and sessions + +Treat terminal close as detach. Resume the existing named session; never create +a duplicate shell or replay a lost command. A reboot can restore workspace and +Codex conversation metadata but cannot restore the old process. Distinguish +running, detached, ended, and interrupted states in user-facing output. + +Keep credentials, wallet material, terminal output, and command contents out of +diagnostics and support bundles. A terminal is a privileged capability: verify +the authenticated owner, origin, attachment grant, and account boundary before +any PTY bytes flow. + +## References + +- [system map and safe recipes](references/system-map.md) +- [app and design routing](references/routing.md) diff --git a/.agents/skills/archipelago/agents/openai.yaml b/.agents/skills/archipelago/agents/openai.yaml new file mode 100644 index 00000000..6bbb6078 --- /dev/null +++ b/.agents/skills/archipelago/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "Archipelago system" + short_description: "Work safely on Archipelago systems" + brand_color: "#F7931A" + default_prompt: "Use $archipelago to inspect and safely change this Archipelago node." +policy: + allow_implicit_invocation: true diff --git a/.agents/skills/archipelago/references/routing.md b/.agents/skills/archipelago/references/routing.md new file mode 100644 index 00000000..ef303ea6 --- /dev/null +++ b/.agents/skills/archipelago/references/routing.md @@ -0,0 +1,10 @@ +# Skill routing + +Load `archipelago-app` for manifests, containers, app previews, lifecycle, +credentials, signer integration, or app packaging. Load `archipelago-design` for +any newly authored or changed UI. For backend-only work, use only the system +skill and the relevant project docs. + +Planning stays planning. A source change, node mutation, deployment, or +publication requires that explicit scope from the user. A skill supplies +workflow knowledge; it does not grant additional privileges. diff --git a/.agents/skills/archipelago/references/system-map.md b/.agents/skills/archipelago/references/system-map.md new file mode 100644 index 00000000..c6fc230b --- /dev/null +++ b/.agents/skills/archipelago/references/system-map.md @@ -0,0 +1,19 @@ +# System map and safe recipes + +The native backend is `core/archipelago`; the Vue dashboard is `neode-ui`; ISO +and first-boot material lives under `image-recipe` and `scripts`; app manifests +are under `apps//manifest.yml`. Read `CLAUDE.md`, `AGENTS.md`, and the current +release checklist before release work. + +Use the existing typed RPC and orchestration layers for app lifecycle, network, +wallet, identity, and service operations. Inspect a matching handler before +adding an endpoint. Preserve the existing session cookie, CSRF, Origin, and +app-gate protections. + +For source tests, run frontend checks from `neode-ui`. Backend unit tests run +only through `scripts/test-backend-isolated.sh`; live host checks must be named +and explicit. Do not touch real wallet/payment/channel state for a test fixture. + +Developer changes belong in a dedicated worktree. Keep generated catalog, +runtime payload, release artifacts, and local node state separate until the +request explicitly includes packaging or deployment. diff --git a/examples/archipelago-app-starter/.gitignore b/examples/archipelago-app-starter/.gitignore new file mode 100644 index 00000000..c744b43a --- /dev/null +++ b/examples/archipelago-app-starter/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +.env +.env.* +!.env.example diff --git a/examples/archipelago-app-starter/Dockerfile b/examples/archipelago-app-starter/Dockerfile new file mode 100644 index 00000000..0940ea5f --- /dev/null +++ b/examples/archipelago-app-starter/Dockerfile @@ -0,0 +1,16 @@ +FROM node:22-alpine AS build +WORKDIR /src +COPY package.json vite.config.ts index.html ./ +COPY src ./src +RUN npm install --ignore-scripts && npm run build + +FROM nginx:1.27-alpine +COPY --from=build /src/dist /usr/share/nginx/html +COPY <<'EOF' /etc/nginx/conf.d/default.conf +server { + listen 8080; + root /usr/share/nginx/html; + index index.html; + location / { try_files $uri $uri/ /index.html; } +} +EOF diff --git a/examples/archipelago-app-starter/README.md b/examples/archipelago-app-starter/README.md new file mode 100644 index 00000000..443616f1 --- /dev/null +++ b/examples/archipelago-app-starter/README.md @@ -0,0 +1,11 @@ +# Archipelago app starter + +This is a small standalone Vue/Vite app that demonstrates Archipelago's initial +design contract: semantic `--archy-*` tokens, dark native controls, responsive +cards, bottom actions, visible focus, 44px targets, and loading/empty/error/ +success states. It intentionally has no dashboard dependency or host handshake. + +Run `npm install && npm run dev` from this directory. Before packaging, copy the +source into a project, replace the demo state with a real API, pin dependencies, +and validate the manifest using the repository app developer guide. The Docker +file is a starter build example; it is not a substitute for lifecycle acceptance. diff --git a/examples/archipelago-app-starter/index.html b/examples/archipelago-app-starter/index.html new file mode 100644 index 00000000..5cdc4f16 --- /dev/null +++ b/examples/archipelago-app-starter/index.html @@ -0,0 +1,13 @@ + + + + + + + Archipelago app + + +
+ + + diff --git a/examples/archipelago-app-starter/manifest.yml b/examples/archipelago-app-starter/manifest.yml new file mode 100644 index 00000000..2bce05fa --- /dev/null +++ b/examples/archipelago-app-starter/manifest.yml @@ -0,0 +1,48 @@ +app: + id: archipelago-app-starter + name: Archipelago App Starter + version: 0.1.0 + description: A minimal Archipelago design-system starter with responsive states. + container: + build: + context: . + dockerfile: Dockerfile + tag: localhost/archipelago-app-starter:0.1.0 + resources: + cpu_limit: 1 + memory_limit: 128Mi + disk_limit: 256Mi + security: + capabilities: [] + readonly_root: true + no_new_privileges: true + network_policy: isolated + ports: + - host: 8180 + container: 8080 + protocol: tcp + bind: 127.0.0.1 + auth: gated + volumes: + - type: bind + source: /var/lib/archipelago/archipelago-app-starter + target: /data + options: [rw] + health_check: + type: http + endpoint: http://127.0.0.1:8080 + path: / + interval: 30s + timeout: 5s + retries: 3 + interfaces: + main: + name: Archipelago App Starter + description: Responsive design-system starter + type: ui + port: 8180 + protocol: http + path: / + metadata: + category: development + tier: optional diff --git a/examples/archipelago-app-starter/package.json b/examples/archipelago-app-starter/package.json new file mode 100644 index 00000000..f6b6d955 --- /dev/null +++ b/examples/archipelago-app-starter/package.json @@ -0,0 +1,18 @@ +{ + "name": "archipelago-app-starter", + "private": true, + "version": "0.1.0", + "type": "module", + "scripts": { + "dev": "vite --host 127.0.0.1", + "build": "vite build", + "preview": "vite preview --host 127.0.0.1" + }, + "dependencies": { + "@vitejs/plugin-vue": "^6.0.1", + "vite": "^7.2.2", + "typescript": "~5.9.3", + "vue": "^3.5.24" + }, + "devDependencies": {} +} diff --git a/examples/archipelago-app-starter/src/App.vue b/examples/archipelago-app-starter/src/App.vue new file mode 100644 index 00000000..949198ee --- /dev/null +++ b/examples/archipelago-app-starter/src/App.vue @@ -0,0 +1,67 @@ + + + diff --git a/examples/archipelago-app-starter/src/main.ts b/examples/archipelago-app-starter/src/main.ts new file mode 100644 index 00000000..fdbdce56 --- /dev/null +++ b/examples/archipelago-app-starter/src/main.ts @@ -0,0 +1,5 @@ +import { createApp } from 'vue' +import App from './App.vue' +import './styles.css' + +createApp(App).mount('#app') diff --git a/examples/archipelago-app-starter/src/styles.css b/examples/archipelago-app-starter/src/styles.css new file mode 100644 index 00000000..bca42b4c --- /dev/null +++ b/examples/archipelago-app-starter/src/styles.css @@ -0,0 +1,54 @@ +:root { + color-scheme: dark; + --archy-canvas: #0a0a0a; + --archy-surface: rgba(0, 0, 0, 0.65); + --archy-surface-muted: rgba(255, 255, 255, 0.06); + --archy-border: rgba(255, 255, 255, 0.18); + --archy-text: rgba(255, 255, 255, 0.92); + --archy-muted: rgba(255, 255, 255, 0.58); + --archy-accent: #fb923c; + --archy-success: #4ade80; + --archy-danger: #f87171; + --archy-radius-card: 16px; + --archy-radius-control: 12px; + --archy-shadow: 0 8px 24px rgba(0, 0, 0, 0.45); + --archy-space-1: 4px; + --archy-space-2: 8px; + --archy-space-3: 12px; + --archy-space-4: 16px; + --archy-space-6: 24px; + --archy-space-8: 32px; + font-family: Avenir Next, system-ui, sans-serif; + background: var(--archy-canvas); + color: var(--archy-text); +} + +* { box-sizing: border-box; } +body { margin: 0; min-width: 320px; background: var(--archy-canvas); } +button { font: inherit; } +button:focus-visible { outline: 2px solid var(--archy-accent); outline-offset: 3px; } + +.archy-shell { width: min(100% - 32px, 960px); margin: 0 auto; padding: 40px 0 56px; } +.archy-header, .archy-section-heading { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--archy-space-4); } +.archy-header { margin-bottom: var(--archy-space-8); } +.archy-eyebrow { margin: 0 0 var(--archy-space-2); color: var(--archy-accent); font-size: 0.72rem; font-weight: 800; letter-spacing: 0.12em; } +h1, h2 { margin: 0; line-height: 1.15; } +h1 { font-size: clamp(1.8rem, 5vw, 2.8rem); } +h2 { font-size: 1.25rem; } +.archy-muted, .archy-footnote { color: var(--archy-muted); } +.archy-card { padding: var(--archy-space-6); background: var(--archy-surface); border: 1px solid var(--archy-border); border-radius: var(--archy-radius-card); box-shadow: var(--archy-shadow); } +.archy-section-heading { align-items: center; margin-bottom: var(--archy-space-6); } +.archy-button { min-height: 44px; padding: 10px 18px; border: 1px solid rgba(251, 146, 60, 0.35); border-radius: var(--archy-radius-control); background: rgba(251, 146, 60, 0.2); color: #fed7aa; cursor: pointer; } +.archy-button:hover { background: rgba(251, 146, 60, 0.3); } +.archy-button-secondary { border-color: var(--archy-border); background: var(--archy-surface-muted); color: var(--archy-text); } +.archy-state { display: grid; gap: var(--archy-space-3); padding: var(--archy-space-6); border-radius: var(--archy-radius-control); background: var(--archy-surface-muted); color: var(--archy-muted); } +.archy-state strong { color: var(--archy-text); } +.archy-state-error { border: 1px solid rgba(248, 113, 113, 0.35); } +.archy-state-error strong { color: var(--archy-danger); } +.archy-list { display: grid; gap: var(--archy-space-2); padding: 0; margin: 0; list-style: none; } +.archy-list-row { display: flex; align-items: center; justify-content: space-between; gap: var(--archy-space-4); padding: var(--archy-space-4); border-radius: var(--archy-radius-control); background: var(--archy-surface-muted); } +.archy-list-row div { display: grid; gap: var(--archy-space-1); min-width: 0; } +.archy-status { color: var(--archy-success); font-size: 0.8rem; } +.archy-footnote { margin: var(--archy-space-4) 0 0; font-size: 0.8rem; } +@media (max-width: 560px) { .archy-shell { width: min(100% - 24px, 960px); padding-top: 24px; } .archy-header { flex-direction: column; } .archy-header .archy-button { width: 100%; } .archy-card { padding: var(--archy-space-4); } .archy-section-heading { align-items: stretch; flex-direction: column; } .archy-section-heading .archy-button { width: 100%; } } +@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } } diff --git a/examples/archipelago-app-starter/vite.config.ts b/examples/archipelago-app-starter/vite.config.ts new file mode 100644 index 00000000..2d575c4c --- /dev/null +++ b/examples/archipelago-app-starter/vite.config.ts @@ -0,0 +1,4 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' + +export default defineConfig({ plugins: [vue()] })