@inneranimalmedia/agentsam-sdk 2.6.5 → 2.6.7
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/AGENTSAM.md +29 -0
- package/apps/README.md +5 -0
- package/apps/cad-creator/README.md +4 -4
- package/apps/cad-creator/shared/cad/package.json +1 -1
- package/apps/client-cms-editor/AGENTS.md +12 -7
- package/apps/client-cms-editor/README.md +76 -48
- package/apps/client-cms-editor/agentsam.app.json +26 -9
- package/apps/client-cms-editor/backend/package.json +20 -3
- package/apps/client-cms-editor/backend/src/api/client.ts +134 -101
- package/apps/client-cms-editor/backend/src/index.ts +1 -1
- package/apps/client-cms-editor/backend/src/model.ts +11 -115
- package/apps/client-cms-editor/backend/src/preview/bridge.ts +1 -1
- package/apps/client-cms-editor/backend/tsconfig.json +6 -1
- package/apps/client-cms-editor/bin/agentsam-cms.js +262 -0
- package/apps/client-cms-editor/bin/agentsam-cms.mjs +2 -228
- package/apps/client-cms-editor/frontend/package.json +16 -7
- package/apps/client-cms-editor/frontend/src/AgentSamDrawer.tsx +9 -41
- package/apps/client-cms-editor/frontend/src/CmsAgentSurface.tsx +19 -174
- package/apps/client-cms-editor/frontend/src/adapters/heuristic.ts +29 -0
- package/apps/client-cms-editor/frontend/src/adapters/http.ts +628 -0
- package/apps/client-cms-editor/frontend/src/adapters/memory.ts +510 -0
- package/apps/client-cms-editor/frontend/src/editor/CmsEditor.tsx +213 -0
- package/apps/client-cms-editor/frontend/src/editor/CmsEditorProvider.tsx +20 -0
- package/apps/client-cms-editor/frontend/src/editor/canvas/PreviewCanvas.tsx +53 -0
- package/apps/client-cms-editor/frontend/src/{CmsEditor.tsx → editor/legacy/CmsEditorPrototype.tsx} +52 -23
- package/apps/client-cms-editor/frontend/src/editor/useCmsEditorController.ts +218 -0
- package/apps/client-cms-editor/frontend/src/index.ts +19 -5
- package/apps/client-cms-editor/frontend/src/lib/agent-host.ts +24 -0
- package/apps/client-cms-editor/frontend/src/main.tsx +82 -8
- package/apps/client-cms-editor/frontend/src/mount.tsx +92 -30
- package/apps/client-cms-editor/frontend/src/styles/agentsam-drawer.css +1 -1
- package/apps/client-cms-editor/frontend/src/styles/cmsShell.css +8 -8
- package/apps/client-cms-editor/frontend/src/styles/studio.css +55 -3
- package/apps/client-cms-editor/frontend/tsconfig.json +12 -1
- package/apps/client-cms-editor/frontend/vite.config.ts +12 -0
- package/apps/client-cms-editor/package-lock.json +973 -134
- package/apps/client-cms-editor/package.json +118 -6
- package/apps/client-cms-editor/reference/harvest/HARVEST_RECEIPT.json +201 -0
- package/apps/client-cms-editor/reference/harvest/PROVENANCE_HISTORY.txt +10 -0
- package/apps/client-cms-editor/reference/harvest/README.md +8 -0
- package/apps/client-cms-editor/reference/harvest/plans/ARCHIVE-INTAKE.md +135 -0
- package/apps/client-cms-editor/reference/harvest/plans/CHATGPT-IDENTITY-HARVEST.md +83 -0
- package/apps/client-cms-editor/reference/harvest/plans/CMS-EDITOR-HARVEST.md +166 -0
- package/apps/client-cms-editor/reference/harvest/plans/HARVEST-INDEX.md +196 -0
- package/apps/client-cms-editor/reference/harvest/plans/INNERANIMALS-CONTENT-001.md +137 -0
- package/apps/client-cms-editor/reference/harvest/plans/NO-IMPLICIT-SIDE-EFFECTS.md +87 -0
- package/apps/client-cms-editor/reference/harvest/plans/STOREFRONT-SURFACE-MAP.md +140 -0
- package/apps/client-cms-editor/reference/harvest/plans/THEME-INNERANIMALS-HARVEST.md +137 -0
- package/apps/client-cms-editor/reference/harvest/plans/TOOLING-LAB.md +63 -0
- package/apps/client-cms-editor/reference/harvest/plans/harvest-manifest.json +97 -0
- package/apps/client-cms-editor/reference/harvest/plans/local-cms-harvest-schema.sql +328 -0
- package/apps/client-cms-editor/shared/cms/package.json +17 -7
- package/apps/client-cms-editor/shared/cms/src/adapter.ts +204 -0
- package/apps/client-cms-editor/shared/cms/src/agent-context.ts +7 -5
- package/apps/client-cms-editor/shared/cms/src/editor-types.ts +32 -0
- package/apps/client-cms-editor/shared/cms/src/host.ts +82 -0
- package/apps/client-cms-editor/shared/cms/src/index.ts +4 -0
- package/apps/client-cms-editor/shared/cms/src/map.ts +115 -0
- package/apps/client-cms-editor/shared/cms/src/starter-pack.ts +158 -0
- package/contracts/source-types.v1.json +353 -0
- package/docs/CMS_CONTEXTUAL_COMPOSER.md +1 -1
- package/docs/PRODUCT_LIFECYCLE.md +566 -0
- package/docs/THEME_REFINERY.md +2 -2
- package/docs/architecture/AGENTSAM_RUNTIME_PROTOCOL.md +40 -20
- package/docs/content-studio/REVISION_GATE_2026-09-27.md +1 -1
- package/docs/plans/LOCAL_STUDIO_DESKTOP_RELEASE_2026-09-29.md +150 -0
- package/migrations/d1/0017_identity_native_oauth.sql +21 -0
- package/native/agentsam-machine/Cargo.lock +426 -0
- package/native/agentsam-machine/Cargo.toml +9 -0
- package/native/agentsam-machine/cli/Cargo.toml +14 -0
- package/native/agentsam-machine/cli/src/main.rs +77 -0
- package/native/agentsam-machine/core/Cargo.toml +15 -0
- package/native/agentsam-machine/core/src/assets.rs +790 -0
- package/native/agentsam-machine/core/src/bound.rs +298 -0
- package/native/agentsam-machine/core/src/enrich.rs +706 -0
- package/native/agentsam-machine/core/src/frontend.rs +442 -0
- package/native/agentsam-machine/core/src/lib.rs +1086 -0
- package/native/agentsam-machine/core/src/liquid.rs +528 -0
- package/native/agentsam-machine/core/src/source_types.rs +78 -0
- package/package.json +51 -21
- package/packages/agentsam-brand/README.md +1 -1
- package/packages/agentsam-brand/package.json +4 -4
- package/packages/agentsam-brand/src/index.js +1 -1
- package/packages/agentsam-contracts/package.json +13 -3
- package/packages/agentsam-contracts/src/tools.ts +22 -0
- package/packages/agentsam-errors/package.json +13 -3
- package/packages/agentsam-knowledge/package.json +18 -4
- package/packages/agentsam-knowledge/src/autorag/index.js +10 -3
- package/packages/agentsam-knowledge/src/backends/index.js +33 -1
- package/packages/agentsam-knowledge/test/autorag.test.mjs +60 -1
- package/packages/agentsam-nav/package.json +24 -6
- package/packages/agentsam-queue-control/README.md +1 -1
- package/packages/agentsam-queue-control/package.json +7 -2
- package/packages/agentsam-rapid-rust/src/main.rs +1 -1
- package/packages/agentsam-repository/package.json +13 -3
- package/packages/agentsam-repository/src/source-types.js +8 -0
- package/packages/agentsam-vault/package.json +14 -4
- package/packages/agentsam-workbench/package.json +15 -4
- package/packages/agentsam-workbench/src/agent/ToolPermissionRequest.tsx +94 -0
- package/packages/agentsam-workbench/src/agent/index.ts +2 -0
- package/packages/agentsam-workbench/src/agent/tool-permission.css +134 -0
- package/packages/connectors/cloudflare/package.json +13 -3
- package/packages/connectors/cloudflare/src/api-client.js +3 -2
- package/packages/connectors/cloudflare/src/families/vectorize.js +127 -0
- package/packages/connectors/cloudflare/src/index.js +1 -0
- package/packages/heuristic-theme/README.md +2 -2
- package/packages/heuristic-theme/package.json +8 -3
- package/packages/heuristic-theme/src/registry.js +2 -2
- package/packages/heuristic-theme/src/theme.js +1 -1
- package/packages/heuristic-theme/test/theme.test.mjs +1 -1
- package/packages/identity/.agentsam/features/oauth-login-portal/agentsam.feature.json +1 -1
- package/packages/identity/.agentsam/features/oauth-login-portal/providers.json +27 -7
- package/packages/identity/README.md +2 -2
- package/packages/identity/migrations/D1_SCHEMA_MAPPING.md +18 -15
- package/packages/identity/migrations/apply-portable.js +109 -0
- package/packages/identity/migrations/sqlite/004_identity_oauth_consent_catalog.sql +1 -1
- package/packages/identity/migrations/sqlite/005_identity_company_native.sql +52 -0
- package/packages/identity/package.json +27 -6
- package/packages/identity/schema/agentsam.identity/manifest.json +101 -0
- package/packages/identity/scripts/local-identity-bridge.mjs +13 -7
- package/packages/identity/scripts/preview-auth-portal.mjs +6 -6
- package/packages/identity/src/adapters/cloudflare-d1/index.js +8 -401
- package/packages/identity/src/adapters/iam-compat/index.js +540 -0
- package/packages/identity/src/adapters/portable-d1/index.js +18 -0
- package/packages/identity/src/adapters/portable-store.js +479 -0
- package/packages/identity/src/adapters/sqlite/index.js +13 -312
- package/packages/identity/src/contracts/auth-config.js +0 -1
- package/packages/identity/src/contracts/identity-store.js +56 -5
- package/packages/identity/src/contracts/provider.js +1 -0
- package/packages/identity/src/contracts/sign-in-options.js +104 -0
- package/packages/identity/src/core/constants.js +1 -1
- package/packages/identity/src/core/session-policy.js +31 -0
- package/packages/identity/src/frontend/auth-portal/pages/login.html +6 -6
- package/packages/identity/src/frontend/auth-portal/pages/reset.html +5 -5
- package/packages/identity/src/frontend/auth-portal/pages/signup.html +5 -5
- package/packages/identity/src/frontend/auth-portal/shared/company-branding.js +1 -1
- package/packages/identity/src/frontend/auth-portal/shared/desktop-identity-bridge.js +6 -37
- package/packages/identity/src/index.js +28 -1
- package/packages/identity/src/migrations/README.md +23 -23
- package/packages/identity/src/oauth/README.md +1 -1
- package/packages/identity/src/oauth/credentials.js +10 -11
- package/packages/identity/src/oauth/google-desktop-exchange.js +195 -27
- package/packages/identity/src/oauth/iam-platform.js +21 -9
- package/packages/identity/src/oauth/native-handoff.js +136 -0
- package/packages/identity/src/providers/chatgpt/headers.js +65 -0
- package/packages/identity/src/providers/chatgpt/index.js +86 -0
- package/packages/identity/src/providers/chatgpt/mapper.js +43 -0
- package/packages/identity/src/providers/chatgpt/paths.js +45 -0
- package/packages/identity/src/providers/github/oauth.js +1 -2
- package/packages/identity/src/providers/github/profile.js +16 -2
- package/packages/identity/src/providers/index.js +11 -3
- package/packages/identity/src/server/identity-service.js +2 -1
- package/packages/identity/src/server/worker-router.js +71 -18
- package/packages/identity/tests/chatgpt-provider.test.mjs +75 -0
- package/packages/identity/tests/google-desktop-identity-login.test.mjs +210 -0
- package/packages/identity/tests/identity-init-scaffold.test.mjs +15 -4
- package/packages/identity/tests/lane1-identity-store-parity.test.mjs +527 -0
- package/packages/identity/tests/lane1-packed-consumer.test.mjs +175 -0
- package/packages/identity/tests/native-oauth-handoff.test.mjs +292 -0
- package/packages/identity/tests/oauth-credentials.test.mjs +4 -4
- package/packages/identity/tests/preview-auth-portal.test.mjs +4 -2
- package/packages/identity/tests/session-routes-policy.test.mjs +13 -1
- package/packages/identity/tests/worker-runtime-boundary.test.mjs +11 -0
- package/packages/providers/completeful/package.json +7 -2
- package/packages/theme-church-site/package.json +17 -6
- package/packages/theme-church-site/src/harvest.json +4 -2
- package/packages/theme-church-site/src/index.js +7 -3
- package/packages/theme-church-site/test/theme.test.mjs +4 -2
- package/packages/theme-companions-site/package.json +17 -6
- package/packages/theme-companions-site/src/harvest.json +4 -2
- package/packages/theme-companions-site/src/index.js +7 -3
- package/packages/theme-companions-site/test/theme.test.mjs +4 -2
- package/packages/theme-floors-site/package.json +17 -6
- package/packages/theme-floors-site/src/harvest.json +4 -2
- package/packages/theme-floors-site/src/index.js +7 -3
- package/packages/theme-floors-site/test/theme.test.mjs +4 -2
- package/packages/theme-fuelnfree-site/package.json +17 -6
- package/packages/theme-fuelnfree-site/src/harvest.json +4 -2
- package/packages/theme-fuelnfree-site/src/index.js +7 -3
- package/packages/theme-fuelnfree-site/test/theme.test.mjs +4 -2
- package/packages/theme-handyman-site/package.json +17 -6
- package/packages/theme-handyman-site/src/harvest.json +4 -2
- package/packages/theme-handyman-site/src/index.js +7 -3
- package/packages/theme-handyman-site/test/theme.test.mjs +4 -2
- package/packages/theme-insurance-site/package.json +17 -6
- package/packages/theme-insurance-site/src/harvest.json +4 -2
- package/packages/theme-insurance-site/src/index.js +7 -3
- package/packages/theme-insurance-site/test/theme.test.mjs +4 -2
- package/packages/theme-scenes/README.md +1 -1
- package/packages/theme-scenes/package.json +4 -3
- package/packages/theme-scenes/src/registry.js +187 -0
- package/packages/theme-shinshu-site/package.json +17 -6
- package/packages/theme-shinshu-site/src/harvest.json +4 -2
- package/packages/theme-shinshu-site/src/index.js +7 -3
- package/packages/theme-shinshu-site/test/theme.test.mjs +4 -2
- package/packages/work-graph/package.json +14 -4
- package/protocol/FILEMETA_V1.md +2 -2
- package/protocol/capabilities/manifest.json +1 -1
- package/protocol/database/agentsam.schema-pack.v1.schema.json +72 -0
- package/protocol/presets/catalog.json +2 -2
- package/protocol/theme-refinery/lineage-registry.json +105 -0
- package/protocol/theme-refinery/product-metadata.schema.json +21 -1
- package/skills/grok-auth/SKILL.md +110 -0
- package/skills/grok-auth/agentsam.skill.json +25 -0
- package/skills/grok-auth/references/grok-identity.md +64 -0
- package/skills/grok-auth/references/per-user-data.md +49 -0
- package/skills/grok-auth/references/prewired-and-env.md +54 -0
- package/skills/grok-auth/references/session-ui.md +133 -0
- package/skills/grok-auth/references/sign-in-methods.md +55 -0
- package/skills/grok-auth/references/wiring.md +71 -0
- package/skills/grok-building-games/SKILL.md +213 -0
- package/skills/grok-building-games/agentsam.skill.json +25 -0
- package/skills/grok-building-games/references/3d-libs.md +64 -0
- package/skills/grok-building-games/references/ai-pathfinding.md +122 -0
- package/skills/grok-building-games/references/audio.md +129 -0
- package/skills/grok-building-games/references/babylon.md +202 -0
- package/skills/grok-building-games/references/collision-physics.md +122 -0
- package/skills/grok-building-games/references/ecs-architecture.md +111 -0
- package/skills/grok-building-games/references/game-feel-juice.md +110 -0
- package/skills/grok-building-games/references/genres/board-card-chess.md +89 -0
- package/skills/grok-building-games/references/genres/endless-runner.md +83 -0
- package/skills/grok-building-games/references/genres/fps.md +105 -0
- package/skills/grok-building-games/references/genres/platformer-2d.md +97 -0
- package/skills/grok-building-games/references/genres/puzzle-match3-tetris.md +131 -0
- package/skills/grok-building-games/references/genres/racing-kart.md +106 -0
- package/skills/grok-building-games/references/genres/topdown-twin-stick.md +97 -0
- package/skills/grok-building-games/references/genres/tower-defense.md +84 -0
- package/skills/grok-building-games/references/genres/voxel-minecraft.md +89 -0
- package/skills/grok-building-games/references/input.md +139 -0
- package/skills/grok-building-games/references/phaser.md +277 -0
- package/skills/grok-building-games/references/procedural-generation.md +141 -0
- package/skills/grok-building-games/references/save-persistence.md +108 -0
- package/skills/grok-building-games/references/threejs-foundational.md +148 -0
- package/skills/grok-controls/SKILL.md +274 -0
- package/skills/grok-controls/agentsam.skill.json +25 -0
- package/skills/grok-design-ui/SKILL.md +122 -0
- package/skills/grok-design-ui/agentsam.skill.json +25 -0
- package/skills/grok-design-ui/references/animations.md +379 -0
- package/skills/grok-design-ui/references/performance.md +88 -0
- package/skills/grok-design-ui/references/refined-ui.md +384 -0
- package/skills/grok-design-ui/references/surfaces.md +247 -0
- package/skills/grok-design-ui/references/typography.md +123 -0
- package/skills/grok-game-animation-frames/SKILL.md +84 -0
- package/skills/grok-game-animation-frames/agentsam.skill.json +25 -0
- package/skills/grok-game-asset-core/SKILL.md +69 -0
- package/skills/grok-game-asset-core/agentsam.skill.json +25 -0
- package/skills/grok-game-character-consistency/SKILL.md +69 -0
- package/skills/grok-game-character-consistency/agentsam.skill.json +25 -0
- package/skills/grok-game-tilesets/SKILL.md +65 -0
- package/skills/grok-game-tilesets/agentsam.skill.json +25 -0
- package/skills/grok-game-ui-icons/SKILL.md +56 -0
- package/skills/grok-game-ui-icons/agentsam.skill.json +25 -0
- package/skills/grok-generate2dmap/LICENSE +21 -0
- package/skills/grok-generate2dmap/SKILL.md +120 -0
- package/skills/grok-generate2dmap/SOURCE.md +6 -0
- package/skills/grok-generate2dmap/agentsam.skill.json +25 -0
- package/skills/grok-generate2dmap/references/deliverables.md +101 -0
- package/skills/grok-generate2dmap/references/layered-map-contract.md +209 -0
- package/skills/grok-generate2dmap/references/map-strategies.md +341 -0
- package/skills/grok-generate2dmap/references/object-production-gate.md +24 -0
- package/skills/grok-generate2dmap/references/pipeline.md +149 -0
- package/skills/grok-generate2dmap/references/prop-pack-contract.md +174 -0
- package/skills/grok-generate2dmap/references/side-scroll-stages.md +29 -0
- package/skills/grok-generate2dmap/scripts/compose_layered_preview.py +157 -0
- package/skills/grok-generate2dmap/scripts/extract_prop_pack.py +369 -0
- package/skills/grok-generate2dsprite/LICENSE +21 -0
- package/skills/grok-generate2dsprite/SKILL.md +313 -0
- package/skills/grok-generate2dsprite/SOURCE.md +6 -0
- package/skills/grok-generate2dsprite/agentsam.skill.json +25 -0
- package/skills/grok-generate2dsprite/references/modes.md +124 -0
- package/skills/grok-generate2dsprite/references/prompt-rules.md +315 -0
- package/skills/grok-generate2dsprite/scripts/generate2dsprite.py +1031 -0
- package/skills/grok-generate2dsprite/scripts/make_layout_guide.py +109 -0
- package/skills/grok-imagine/SKILL.md +201 -0
- package/skills/grok-imagine/agentsam.skill.json +25 -0
- package/skills/grok-multiplayer-p2p/SKILL.md +111 -0
- package/skills/grok-multiplayer-p2p/agentsam.skill.json +25 -0
- package/skills/grok-multiplayer-p2p/references/react-binding.md +144 -0
- package/skills/grok-multiplayer-p2p/references/signaling-relay.md +269 -0
- package/skills/grok-neon/SKILL.md +157 -0
- package/skills/grok-neon/agentsam.skill.json +25 -0
- package/skills/grok-og/SKILL.md +102 -0
- package/skills/grok-og/agentsam.skill.json +25 -0
- package/skills/grok-og/references/brand-pass.md +53 -0
- package/skills/grok-og/references/custom-card.md +107 -0
- package/skills/grok-og/references/favicon-and-icons.md +48 -0
- package/skills/grok-og/references/og-type-contract.md +18 -0
- package/skills/grok-og/references/placeholder-card.md +21 -0
- package/skills/grok-og/references/x-banner.md +41 -0
- package/skills/grok-threejs/SKILL.md +67 -0
- package/skills/grok-threejs/agentsam.skill.json +25 -0
- package/skills/grok-threejs/references/llms-full.txt +2780 -0
- package/skills/grok-video2dsprite/LICENSE +21 -0
- package/skills/grok-video2dsprite/SKILL.md +236 -0
- package/skills/grok-video2dsprite/SOURCE.md +6 -0
- package/skills/grok-video2dsprite/agentsam.skill.json +25 -0
- package/skills/grok-video2dsprite/references/pipeline.md +90 -0
- package/skills/grok-video2dsprite/references/prompt-rules.md +63 -0
- package/skills/grok-video2dsprite/scripts/video2dsprite.py +490 -0
- package/skills/grok-xai-api/SKILL.md +152 -0
- package/skills/grok-xai-api/agentsam.skill.json +25 -0
- package/src/cli/command-catalog.js +46 -4
- package/src/cli/dispatch.js +1 -0
- package/src/cli.js +10 -0
- package/src/cloudflare/runtime-status.js +2 -1
- package/src/commands/autorag.js +67 -13
- package/src/commands/cheat-sheet.js +29 -4
- package/src/commands/codebaseindex.js +45 -2
- package/src/commands/knowledge.js +59 -2
- package/src/commands/machine-binary.js +103 -0
- package/src/commands/machine.js +137 -0
- package/src/commands/security.js +67 -4
- package/src/commands/setup.js +33 -16
- package/src/commands/status.js +8 -1
- package/src/features/resolve.js +1 -0
- package/src/knowledge/engine.js +21 -2
- package/src/knowledge/runtime-discovery.js +127 -0
- package/src/lib/identity-scaffold.js +53 -13
- package/src/lib/setup/recipes.js +1 -1
- package/src/models/discovery.js +40 -22
- package/src/models/inventory-core.d.ts +105 -0
- package/src/models/inventory-core.js +54 -6
- package/src/security/logs.js +3 -0
- package/src/ui/cli/help.js +41 -0
- package/test/apps-scaffold-contract.test.mjs +3 -2
- package/test/cli/api-key-env-whoami.test.mjs +2 -2
- package/test/cli/catalog-authority.test.mjs +64 -0
- package/test/cli/machine-command.test.mjs +34 -0
- package/test/fixtures/project-authority/customer-app/.agentsam/app.json +5 -0
- package/test/fixtures/project-authority/customer-app/apps/my-product/index.ts +1 -0
- package/test/fixtures/project-authority/customer-app/wrangler.toml +17 -0
- package/test/integration/autorag-project-authority.integration.test.mjs +51 -0
- package/test/integration/autorag-runtime-discovery.test.mjs +107 -0
- package/test/integration/cms-app-scaffold.test.mjs +37 -31
- package/test/integration/cms-site-tenancy-contract.test.mjs +28 -17
- package/test/integration/codebaseindex-ingest.test.mjs +41 -0
- package/test/integration/database-hosted-honesty.test.mjs +49 -0
- package/test/integration/desktop-keychain-boundary.test.mjs +45 -0
- package/test/integration/hosted-work-host-authority.test.mjs +47 -0
- package/test/integration/inventory-eligibility.test.mjs +59 -0
- package/test/integration/local-provider-bridge.test.mjs +65 -0
- package/test/integration/local-studio-settings-production.test.mjs +40 -0
- package/test/integration/lockfile-sync.test.mjs +26 -0
- package/test/integration/provider-env-cli.test.mjs +13 -3
- package/test/integration/runtime-status.integration.test.mjs +16 -1
- package/test/integration/theme-package-registry.test.mjs +31 -0
- package/test/repository-snapshot-view.test.mjs +2 -2
- package/test/security.test.mjs +14 -0
- package/test/terminal-machine-identity.test.mjs +2 -2
- package/apps/client-cms-editor/backend/src/demo-bootstrap.ts +0 -145
- package/packages/agentsam-nav/dist/Nav.d.ts +0 -43
- package/packages/agentsam-nav/dist/NavCollapsible.d.ts +0 -10
- package/packages/agentsam-nav/dist/NavContent.d.ts +0 -2
- package/packages/agentsam-nav/dist/NavFooter.d.ts +0 -2
- package/packages/agentsam-nav/dist/NavGroup.d.ts +0 -3
- package/packages/agentsam-nav/dist/NavHeader.d.ts +0 -2
- package/packages/agentsam-nav/dist/NavMenu.d.ts +0 -22
- package/packages/agentsam-nav/dist/NavProvider.d.ts +0 -35
- package/packages/agentsam-nav/dist/NavTrigger.d.ts +0 -2
- package/packages/agentsam-nav/dist/Surfaces.d.ts +0 -41
- package/packages/agentsam-nav/dist/browser.d.ts +0 -11
- package/packages/agentsam-nav/dist/browser.global.js +0 -132
- package/packages/agentsam-nav/dist/browser.js +0 -613
- package/packages/agentsam-nav/dist/contracts.d.ts +0 -76
- package/packages/agentsam-nav/dist/index.d.ts +0 -11
- package/packages/agentsam-nav/dist/index.js +0 -614
- package/packages/agentsam-nav/dist/legacy.css +0 -83
- package/packages/agentsam-nav/dist/shell.css +0 -113
- package/packages/agentsam-nav/dist/theme.css +0 -113
- package/packages/agentsam-nav/dist/utils.d.ts +0 -1
- package/packages/agentsam-repository/src/goap.js.bak-20260922011251 +0 -670
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
# Refined UI (product chrome and overlays)
|
|
2
|
+
|
|
3
|
+
Build interfaces that feel **intentional, calm, and expensive** — tight typography, restrained color, concentric radii, and fluid spacing. Prefer systems over one-off styles.
|
|
4
|
+
|
|
5
|
+
## Scope
|
|
6
|
+
|
|
7
|
+
**In scope**
|
|
8
|
+
|
|
9
|
+
- Start / title / menu surfaces layered over a game or app
|
|
10
|
+
- Overlay HUD and status chrome (score, health, timers, objectives)
|
|
11
|
+
- Pause, settings, win/lose, modals, sheets, toasts, on-screen controls
|
|
12
|
+
- Marketing-adjacent panels, cards, nav, footers, and form chrome in Build outputs
|
|
13
|
+
- Design tokens, type scales, radius scales, spacing, borders, shadows, motion on those surfaces
|
|
14
|
+
|
|
15
|
+
**Out of scope**
|
|
16
|
+
|
|
17
|
+
- Gameplay systems, entities, physics, combat, progression logic
|
|
18
|
+
- WebGL / canvas scenes, 3D art, materials, VFX, level design
|
|
19
|
+
- Decorative illustration that fights the product chrome
|
|
20
|
+
|
|
21
|
+
When a task spans gameplay and UI, apply this skill **only** to the overlay / DOM chrome.
|
|
22
|
+
|
|
23
|
+
## Non-negotiable anti-slop rules
|
|
24
|
+
|
|
25
|
+
These are hard fails. Fix before polish.
|
|
26
|
+
|
|
27
|
+
| Ban | Instead |
|
|
28
|
+
| --- | --- |
|
|
29
|
+
| Emoji in UI chrome, buttons, empty states, headings, or labels | Plain typography, sparse SVG icons (monochrome or single accent), or nothing |
|
|
30
|
+
| Purple, violet, magenta, or yellow / gold as brand or accent fills | Near-neutral surfaces; one restrained accent (cool blue-gray, ink, or soft white on dark) |
|
|
31
|
+
| Loud multi-stop gradients on backgrounds, buttons, or cards | Flat or near-flat surfaces; at most a **barely** perceptible linear wash (≤8% lightness delta) on large hero fields |
|
|
32
|
+
| Rainbow borders, neon glows, glassmorphism soup | Thin neutral borders (`1px`, low-contrast), soft single-layer shadows or hairline dividers |
|
|
33
|
+
| Default Inter-everything with no hierarchy | Deliberate display + body pairing and weight steps (see Typography) |
|
|
34
|
+
| Identical radius on parent and child | **Concentric** radii (see Border radius) |
|
|
35
|
+
| Random spacing and magic numbers | Tokenized spacing scale |
|
|
36
|
+
| Random bounce on every control | Short, tokenized motion (see Motion); reserve overshoot for rare micro moments (badge pop only) |
|
|
37
|
+
|
|
38
|
+
## Visual language
|
|
39
|
+
|
|
40
|
+
Aim for a **frontier / editorial** product feel:
|
|
41
|
+
|
|
42
|
+
- Dark or light **near-black / near-white** fields with quiet gray steps — not pastel candy, not neon cyberpunk
|
|
43
|
+
- Large, confident headlines with generous tracking control; body copy that breathes
|
|
44
|
+
- Abundant negative space; fewer elements with stronger hierarchy
|
|
45
|
+
- Surfaces read as **planes and panels**, not stickers
|
|
46
|
+
- Motion is subtle and physical (fade + slight translate / scale), never carnival
|
|
47
|
+
|
|
48
|
+
## Design tokens (encode once, reuse)
|
|
49
|
+
|
|
50
|
+
Define CSS variables (or equivalent) at the root of the UI layer. Prefer semantic names over raw hues.
|
|
51
|
+
|
|
52
|
+
```css
|
|
53
|
+
:root {
|
|
54
|
+
/* Surfaces — near-neutral, low chroma */
|
|
55
|
+
--bg: #0a0a0b;
|
|
56
|
+
--bg-elevated: #121214;
|
|
57
|
+
--bg-subtle: #1a1a1e;
|
|
58
|
+
--fg: #f4f4f5;
|
|
59
|
+
--fg-muted: #a1a1aa;
|
|
60
|
+
--fg-subtle: #71717a;
|
|
61
|
+
--border: color-mix(in oklab, var(--fg) 12%, transparent);
|
|
62
|
+
--border-strong: color-mix(in oklab, var(--fg) 22%, transparent);
|
|
63
|
+
|
|
64
|
+
/* Single restrained accent — cool, not purple/yellow */
|
|
65
|
+
--accent: #c8ccd4;
|
|
66
|
+
--accent-fg: #0a0a0b;
|
|
67
|
+
|
|
68
|
+
/* Radius scale (px) — use concentrically */
|
|
69
|
+
--radius-xs: 4px;
|
|
70
|
+
--radius-sm: 8px;
|
|
71
|
+
--radius-md: 12px;
|
|
72
|
+
--radius-lg: 16px;
|
|
73
|
+
--radius-xl: 24px;
|
|
74
|
+
|
|
75
|
+
/* Spacing scale */
|
|
76
|
+
--space-1: 4px;
|
|
77
|
+
--space-2: 8px;
|
|
78
|
+
--space-3: 12px;
|
|
79
|
+
--space-4: 16px;
|
|
80
|
+
--space-5: 24px;
|
|
81
|
+
--space-6: 32px;
|
|
82
|
+
--space-7: 48px;
|
|
83
|
+
--space-8: 64px;
|
|
84
|
+
|
|
85
|
+
/* Type */
|
|
86
|
+
--font-display: "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
87
|
+
--font-body: "Segoe UI", system-ui, -apple-system, sans-serif;
|
|
88
|
+
--font-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
89
|
+
|
|
90
|
+
--text-xs: clamp(0.75rem, 0.7rem + 0.2vw, 0.8125rem);
|
|
91
|
+
--text-sm: clamp(0.875rem, 0.82rem + 0.25vw, 0.9375rem);
|
|
92
|
+
--text-base: clamp(1rem, 0.95rem + 0.25vw, 1.0625rem);
|
|
93
|
+
--text-lg: clamp(1.125rem, 1rem + 0.5vw, 1.25rem);
|
|
94
|
+
--text-xl: clamp(1.5rem, 1.2rem + 1vw, 2rem);
|
|
95
|
+
--text-2xl: clamp(2rem, 1.4rem + 2vw, 3rem);
|
|
96
|
+
--text-3xl: clamp(2.5rem, 1.6rem + 3vw, 4rem);
|
|
97
|
+
|
|
98
|
+
--leading-tight: 1.1;
|
|
99
|
+
--leading-snug: 1.25;
|
|
100
|
+
--leading-normal: 1.5;
|
|
101
|
+
|
|
102
|
+
--tracking-tight: -0.02em;
|
|
103
|
+
--tracking-display: -0.03em;
|
|
104
|
+
|
|
105
|
+
/* Motion — durations */
|
|
106
|
+
--motion-stagger: 40ms;
|
|
107
|
+
--motion-micro: 80ms;
|
|
108
|
+
--motion-quick: 150ms;
|
|
109
|
+
--motion-fast: 250ms;
|
|
110
|
+
--motion-medium: 350ms;
|
|
111
|
+
--motion-slow: 400ms;
|
|
112
|
+
--motion-emphasis: 500ms;
|
|
113
|
+
|
|
114
|
+
/* Motion — easings */
|
|
115
|
+
--ease-smooth-out: cubic-bezier(0.22, 1, 0.36, 1);
|
|
116
|
+
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
|
|
117
|
+
--ease-in-out: ease-in-out;
|
|
118
|
+
--ease-linear: linear;
|
|
119
|
+
--ease-pop: cubic-bezier(0.34, 1.36, 0.64, 1);
|
|
120
|
+
|
|
121
|
+
/* Motion — distances / scales / blur */
|
|
122
|
+
--motion-y-micro: 4px;
|
|
123
|
+
--motion-y-small: 6px;
|
|
124
|
+
--motion-y-base: 8px;
|
|
125
|
+
--motion-y-medium: 12px;
|
|
126
|
+
--motion-scale-modal: 0.96;
|
|
127
|
+
--motion-scale-menu: 0.97;
|
|
128
|
+
--motion-scale-tooltip: 0.98;
|
|
129
|
+
--motion-blur-sm: 2px;
|
|
130
|
+
--motion-blur-md: 3px;
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Light theme mirrors the same structure with inverted neutrals (warm-neutral off-whites, ink text). Keep chroma low.
|
|
135
|
+
|
|
136
|
+
**Rules**
|
|
137
|
+
|
|
138
|
+
- Never invent one-off hex in components if a token exists
|
|
139
|
+
- Borders use translucent mixes against `--fg` so they adapt on dark/light
|
|
140
|
+
- Accent is for **primary actions and focus**, not decorative fills on every card
|
|
141
|
+
|
|
142
|
+
## Color discipline
|
|
143
|
+
|
|
144
|
+
1. **Neutrals first.** 90%+ of UI area is background / elevated / text / border neutrals.
|
|
145
|
+
2. **One accent family.** Cool gray-blue or pure light-on-dark — never purple, violet, magenta, yellow, gold, or orange for brand chrome unless the user explicitly demands a brand palette.
|
|
146
|
+
3. **No emoji color.** Icons are stroke/fill monochrome or currentColor.
|
|
147
|
+
4. **Gradients only if nearly invisible** — e.g. vertical wash from `#0a0a0b` to `#101014`. No aurora, mesh, or “AI purple” backgrounds.
|
|
148
|
+
5. **Contrast.** Body text meets WCAG AA against its surface. Muted text is for secondary labels only.
|
|
149
|
+
6. **Semantic status** (success/warn/danger) may use restrained green / amber / red **only** on small badges/icons — not full panels.
|
|
150
|
+
|
|
151
|
+
## Border radius (concentric, mandatory)
|
|
152
|
+
|
|
153
|
+
Outer radius must equal **inner radius + padding** on that axis so curves nest optically.
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
outerRadius = innerRadius + padding
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Example: card with `padding: 16px` and inner control radius `8px` → card radius `24px` (`--radius-xl` if tokens map that way).
|
|
160
|
+
|
|
161
|
+
| Situation | Approach |
|
|
162
|
+
| --- | --- |
|
|
163
|
+
| Card containing buttons / inputs | Card uses larger radius; children use smaller from the scale |
|
|
164
|
+
| Nested panels | Each nesting level steps **down** one radius token |
|
|
165
|
+
| Pill controls | Full pill (`9999px`) only for small chips/buttons — not for large cards |
|
|
166
|
+
| Modals / sheets | `--radius-lg` or `--radius-xl` on the shell; inner sections `--radius-sm` / `--radius-md` |
|
|
167
|
+
|
|
168
|
+
Never set the same radius on parent and padded child.
|
|
169
|
+
|
|
170
|
+
## Typography pairing and weight
|
|
171
|
+
|
|
172
|
+
**Pairing**
|
|
173
|
+
|
|
174
|
+
- Prefer a **single family** with strong weight contrast for cohesion (system UI stacks are fine), **or** a restrained display + body pairing where display is used only for hero / title treatments
|
|
175
|
+
- Mono only for code, stats, and tabular IDs — not body paragraphs
|
|
176
|
+
|
|
177
|
+
**Weights (typical scale)**
|
|
178
|
+
|
|
179
|
+
| Role | Weight | Notes |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| Hero / display | 500–600 | Slightly tight tracking (`--tracking-display`) |
|
|
182
|
+
| Section titles | 500–600 | Snug leading |
|
|
183
|
+
| Body | 400 | Normal leading |
|
|
184
|
+
| Labels / meta | 500 | Smaller size, muted color |
|
|
185
|
+
| Buttons | 500–600 | Never ultra-black 900 on large type |
|
|
186
|
+
|
|
187
|
+
**Avoid**
|
|
188
|
+
|
|
189
|
+
- All-caps long sentences
|
|
190
|
+
- Pure black (`#000`) on pure white for large body blocks on marketing surfaces — prefer soft ink / soft paper
|
|
191
|
+
- More than **three** effective sizes on one screen chrome (excluding micro legal)
|
|
192
|
+
|
|
193
|
+
**Fluid type**
|
|
194
|
+
|
|
195
|
+
- Use `clamp()` tokens above so titles scale with viewport without jumping breakpoints
|
|
196
|
+
- Pair fluid type with fluid spacing (`clamp` or viewport-linked gaps) so rhythm stays consistent
|
|
197
|
+
|
|
198
|
+
## Layout and fluidness
|
|
199
|
+
|
|
200
|
+
- Prefer **fluid grids** (`minmax`, `auto-fit` / `auto-fill`) over rigid 12-column everything
|
|
201
|
+
- Max content width for readable text (~60–75ch); hero type can break wider
|
|
202
|
+
- Consistent vertical rhythm from the spacing scale (stack with `--space-4` / `--space-5`, not 13px / 27px)
|
|
203
|
+
- Align to edges and columns; avoid “almost aligned” optical noise
|
|
204
|
+
- Safe areas on overlays: respect notches with `env(safe-area-inset-*)`
|
|
205
|
+
- HUD floats in corners/edges with padding from `--space-4`+; don’t crowd the center except for intentional modals
|
|
206
|
+
|
|
207
|
+
## Surfaces, borders, depth
|
|
208
|
+
|
|
209
|
+
- Prefer **hairline borders** and slight elevation over heavy drop shadows
|
|
210
|
+
- One shadow recipe max, low opacity, large blur, minimal y-offset
|
|
211
|
+
- Dividers: `1px` using `--border`
|
|
212
|
+
- Panels on dark: elevated surface one step lighter than page bg, not a bright gray slab
|
|
213
|
+
- Avoid frosted blur stacks that obscure gameplay under overlays — if blurred, keep backdrop subtle and content readable
|
|
214
|
+
|
|
215
|
+
## Components (product chrome)
|
|
216
|
+
|
|
217
|
+
**Default to [shadcn/ui](https://ui.shadcn.com/).** Prefer official components from the registry over hand-rolled buttons, inputs, dialogs, menus, sheets, cards, tabs, badges, tooltips, selects, and form chrome. Docs and catalog: https://ui.shadcn.com/ and https://ui.shadcn.com/docs/components.
|
|
218
|
+
|
|
219
|
+
### Setup (when the project can use React + Tailwind)
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
npx shadcn@latest init -d --base radix
|
|
223
|
+
npx shadcn@latest add button card dialog input label select sheet tabs badge tooltip dropdown-menu separator skeleton alert-dialog
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
- Use non-interactive flags (`-d` / `--defaults`) so agents never block on prompts
|
|
227
|
+
- Prefer **new-york** style and theme tokens (`bg-background`, `text-foreground`, `border-border`, `text-muted-foreground`, `bg-card`, `ring-ring`) over ad-hoc hex
|
|
228
|
+
- Theme variables may be mapped to the token block above; do not invent a second parallel component kit
|
|
229
|
+
- Own the copied source under `components/ui` and restyle with tokens/anti-slop rules — still use the shadcn primitives and composition patterns
|
|
230
|
+
|
|
231
|
+
### Reach for shadcn first
|
|
232
|
+
|
|
233
|
+
| Need | Prefer (shadcn) | Notes |
|
|
234
|
+
| --- | --- | --- |
|
|
235
|
+
| Primary / secondary actions | `Button` | Variants for hierarchy; optional subtle `scale(0.98)` on press |
|
|
236
|
+
| Text fields | `Input` / `Textarea` + `Label` | Consistent height (~40–44px), focus ring via theme |
|
|
237
|
+
| Confirm / pause / win-lose | `Dialog` or `AlertDialog` | Destructive confirms use `AlertDialog` |
|
|
238
|
+
| Settings / side panels | `Sheet` | Edge panels over custom drawers when possible |
|
|
239
|
+
| Overflow menus | `DropdownMenu` / `Popover` | Origin-aware from trigger |
|
|
240
|
+
| Grouped content | `Card` + `Separator` | Concentric radii with inner controls |
|
|
241
|
+
| Status / filters | `Badge` / `Tabs` | Quiet variants; no emoji |
|
|
242
|
+
| Hover hints | `Tooltip` | Delayed first show; instant siblings when appropriate |
|
|
243
|
+
| Loading placeholders | `Skeleton` | Then cross-fade to content |
|
|
244
|
+
|
|
245
|
+
Do **not** ship raw `<button>` / `<input>` / ad-hoc `div rounded-xl border p-6` shells when a shadcn component covers the need.
|
|
246
|
+
|
|
247
|
+
### When shadcn is not available
|
|
248
|
+
|
|
249
|
+
Plain HTML/CSS overlays (or non-React stacks) may implement the same patterns with tokens below. Match shadcn structure (button variants, dialog/sheet roles, card hierarchy) so a later migration is trivial.
|
|
250
|
+
|
|
251
|
+
### Buttons (token overlay / fallback)
|
|
252
|
+
|
|
253
|
+
- Primary: solid near-white or accent-on-dark, dark label; clear hover/active (opacity or slight brightness), `scale(0.98)` on active optional
|
|
254
|
+
- Secondary: transparent or elevated with `--border`
|
|
255
|
+
- No gradient fills, no emoji, no purple glow
|
|
256
|
+
|
|
257
|
+
### Inputs (token overlay / fallback)
|
|
258
|
+
|
|
259
|
+
- Height consistent (e.g. 40–44px touch-friendly)
|
|
260
|
+
- Focus ring: 2px subtle accent or light ring, not rainbow
|
|
261
|
+
- Placeholder uses `--fg-subtle`
|
|
262
|
+
|
|
263
|
+
### Cards / menus (token overlay / fallback)
|
|
264
|
+
|
|
265
|
+
- Concentric radii; padding from spacing scale
|
|
266
|
+
- Title + muted description hierarchy
|
|
267
|
+
- Actions right-aligned or full-width stacked on small screens
|
|
268
|
+
|
|
269
|
+
### HUD chips
|
|
270
|
+
|
|
271
|
+
- Compact, high contrast, tabular numbers (`font-variant-numeric: tabular-nums`)
|
|
272
|
+
- Prefer `Badge` when on a shadcn stack; otherwise minimal chrome — no cartoon badges
|
|
273
|
+
|
|
274
|
+
## Motion and fluidity (production transitions)
|
|
275
|
+
|
|
276
|
+
Chrome motion should feel like a **small catalog of tuned recipes**, not ad-hoc timings. Prefer **CSS transitions** (interruptible) over keyframes unless the effect is a one-shot staged sequence (success check, error shake). Animate **inner pieces**, not a single wrapping box, when content swaps.
|
|
277
|
+
|
|
278
|
+
### Universal rules
|
|
279
|
+
|
|
280
|
+
- Enumerate properties — never `transition: all`
|
|
281
|
+
- Prefer `opacity` + `transform` (+ optional light `filter: blur` on crossfades)
|
|
282
|
+
- **Enter slower / exit quicker** when asymmetric (modal/menu close uses `--motion-quick`, open uses `--motion-fast`)
|
|
283
|
+
- Never enter from `scale(0)` — use `--motion-scale-modal` … `--motion-scale-tooltip` range
|
|
284
|
+
- Origin-aware surfaces (menus, popovers) scale from the **trigger**; centered modals stay center-origin
|
|
285
|
+
- Every recipe needs `@media (prefers-reduced-motion: reduce)` (opacity-only or instant)
|
|
286
|
+
- Keep durations on **CSS variables** so JS orchestration can `getComputedStyle` and stay in sync
|
|
287
|
+
- Replay animations with a reflow (`void el.offsetWidth`) between class remove and re-add when needed
|
|
288
|
+
- On close, use a closing class for the exit transition, then remove it after timeout — otherwise the next open jumps from the wrong scale
|
|
289
|
+
|
|
290
|
+
### Motion token usage (match by role, not by copying random ms)
|
|
291
|
+
|
|
292
|
+
| Role | Duration token | Easing | Notes |
|
|
293
|
+
| --- | --- | --- | --- |
|
|
294
|
+
| Per-item stagger | `--motion-stagger` (40ms) | — | Stacked text / list enter |
|
|
295
|
+
| Tooltip delay / shake segment | `--motion-micro` (80ms) | — | Small offsets |
|
|
296
|
+
| Menu/modal/tooltip **close**, in-place text swap | `--motion-quick` (150ms) | `--ease-smooth-out` or `--ease-out` | Snappy dismiss |
|
|
297
|
+
| Menu/modal **open**, icon swap, sliding tabs, page slide | `--motion-fast` (250ms) | `--ease-smooth-out` / `--ease-in-out` | Primary opens |
|
|
298
|
+
| Panel dismiss | `--motion-medium` (350ms) | `--ease-smooth-out` | Slightly heavier surfaces |
|
|
299
|
+
| Panel open, skeleton → content, clear dissolve | `--motion-slow` (400ms) | `--ease-smooth-out` / `--ease-in-out` | Contentful reveals |
|
|
300
|
+
| Badge appear, hero line reveal, rare success flourish | `--motion-emphasis` (500ms) | smooth-out or `--ease-pop` for badge only | Use sparingly on overlays |
|
|
301
|
+
|
|
302
|
+
**Blur on crossfade** (when two states overlap oddly): `--motion-blur-sm` (2px) for icon/text/number swaps; `--motion-blur-md` (3px) for page/panel slides. Keep blur off for simple opacity fades.
|
|
303
|
+
|
|
304
|
+
### Pattern → recipe (pick by what the user sees)
|
|
305
|
+
|
|
306
|
+
Match the **visible element + verb**, then implement with tokens above:
|
|
307
|
+
|
|
308
|
+
| If you see… | Use this transition recipe |
|
|
309
|
+
| --- | --- |
|
|
310
|
+
| Trigger + surface growing from it (settings, overflow) | **Origin-aware menu** — open `scale(--motion-scale-menu→1)` + opacity, `--motion-fast` / `--ease-smooth-out`; close faster (`--motion-quick`) with slightly higher scale floor (~0.99) |
|
|
311
|
+
| Centered pause / win / confirm dialog | **Modal** — open from `--motion-scale-modal`, `--motion-fast`; close `--motion-quick`; backdrop fades with opacity only |
|
|
312
|
+
| Sheet / drawer into an edge of the overlay | **Panel reveal** — translate on axis + optional `--motion-blur-sm` crossfade; open `--motion-slow`, close `--motion-medium` |
|
|
313
|
+
| List ↔ detail or step 1 ↔ step 2 in overlay | **Side-by-side page** — opposing translateX(`--motion-y-base`) + light blur; `--motion-fast` |
|
|
314
|
+
| Card / HUD cluster changing width or height | **Layout resize** — transition `width`/`height` or grid tracks with `--ease-smooth-out` and `--motion-fast` (avoid animating padding if possible) |
|
|
315
|
+
| Score / timer / counter updating | **Number pop-in** — per-digit re-enter with `--motion-y-micro` + `--motion-blur-sm`; stagger `--motion-stagger`; `tabular-nums` |
|
|
316
|
+
| Label / status text changing in one slot | **Text state swap** — outgoing slides/fades one way, incoming the other, light blur; `--motion-quick` |
|
|
317
|
+
| Two icons in one control (play/pause, mute) | **Icon swap** — cross-fade + scale + `--motion-blur-sm`; `--motion-fast` / `--ease-in-out`; keep both in DOM during swap |
|
|
318
|
+
| Small notification dot on a control | **Badge** — short diagonal/offset enter; optional `--ease-pop` once — not on every hover |
|
|
319
|
+
| Horizontal chips / avatar stack hover | **Distance falloff lift** — neighbors lift less; bouncy ease **only on mouseleave return**, set timing in JS before writing transform vars |
|
|
320
|
+
| Invalid field / failed action | **Error shake** — short segmented translateX with cubic segments; separate “error styling” class from “shake” class so shake can replay |
|
|
321
|
+
| Search/filter clear | **Clear dissolve** — control exits with motion; optional per-word streak; `--motion-slow` |
|
|
322
|
+
| Placeholder → loaded overlay content | **Skeleton reveal** — pulse with linear, then cross-fade + light blur to real content; `--motion-slow` |
|
|
323
|
+
| Loading / “thinking” status line | **Shimmer text** — masked highlight sweep, **linear**, loop; pure CSS; muted foreground |
|
|
324
|
+
| Segmented control / filter tabs | **Sliding pill** — move highlight with `transform` + width; first paint and resize with `transition: none` then restore |
|
|
325
|
+
| Hover hint on icon/control | **Tooltip** — delayed fade+scale in (`--motion-scale-tooltip`, `--motion-quick` / `--ease-out`); **instant or near-instant out**; subsequent siblings can skip delay (`data-instant`) |
|
|
326
|
+
| Title + subtitle entering a start screen | **Staggered text reveal** — blurred rise `--motion-y-medium`, stagger `--motion-stagger`–`--motion-micro`; quiet fade on exit |
|
|
327
|
+
|
|
328
|
+
**Tie-breakers:** prefer lower overhead (resize over panel, menu over modal, icon swap + checkmark over a full celebration modal). Don’t stack three recipes on one interaction.
|
|
329
|
+
|
|
330
|
+
### Overlay-specific guidance
|
|
331
|
+
|
|
332
|
+
- Pause menus open often — favor **modal/menu** recipes with **quick close**, not multi-second cinematic intros
|
|
333
|
+
- HUD counters use **number pop-in**, not full card animations every tick
|
|
334
|
+
- Start-screen copy uses **staggered text reveal** once; respect reduced motion
|
|
335
|
+
- Never animate the WebGL canvas with these recipes — only DOM overlay nodes
|
|
336
|
+
|
|
337
|
+
### Anti-patterns
|
|
338
|
+
|
|
339
|
+
| Avoid | Prefer |
|
|
340
|
+
| --- | --- |
|
|
341
|
+
| `transition: all` | Explicit `opacity, transform` (and blur only when needed) |
|
|
342
|
+
| One duration for open and close | Asymmetric open/close tokens |
|
|
343
|
+
| Keyframes for hover toggles | CSS transitions (interruptible) |
|
|
344
|
+
| Animating the outer page wrapper for a badge | Animate the badge/dot only |
|
|
345
|
+
| Hardcoded ms in JS timeouts that drift from CSS | Read `--motion-*` from computed styles |
|
|
346
|
+
| Success stroke `stroke-dasharray` guesses | `path.getTotalLength()` (+1) for your path |
|
|
347
|
+
| Mixing error styling + shake in one class | Orthogonal classes so shake can reflow-replay |
|
|
348
|
+
|
|
349
|
+
## Content tone in the UI
|
|
350
|
+
|
|
351
|
+
- Labels are **short, plain language**
|
|
352
|
+
- No emoji, no “✨ magic” marketing fluff in chrome
|
|
353
|
+
- Prefer verbs for actions: Continue, Resume, Settings, Quit
|
|
354
|
+
|
|
355
|
+
## Implementation checklist
|
|
356
|
+
|
|
357
|
+
Before calling UI done:
|
|
358
|
+
|
|
359
|
+
- [ ] No emoji in any chrome string or icon slot
|
|
360
|
+
- [ ] No purple / yellow / gold accent system
|
|
361
|
+
- [ ] No loud gradients on backgrounds or buttons
|
|
362
|
+
- [ ] Components default to shadcn/ui (https://ui.shadcn.com/) when React+Tailwind is available
|
|
363
|
+
- [ ] Tokens used for color, space, radius, type, motion
|
|
364
|
+
- [ ] Nested radii obey `outer = inner + padding`
|
|
365
|
+
- [ ] Clear type hierarchy (size + weight + color), ≤3 primary sizes
|
|
366
|
+
- [ ] Fluid type/spacing where layouts scale
|
|
367
|
+
- [ ] Tabular nums on live stats
|
|
368
|
+
- [ ] Focus visible; contrast AA for text
|
|
369
|
+
- [ ] Motion uses token durations/easings and a matching recipe (menu, modal, number pop-in, etc.)
|
|
370
|
+
- [ ] Open/close asymmetric where appropriate; no `transition: all`; reduced-motion guarded
|
|
371
|
+
- [ ] Gameplay / canvas untouched by these styles
|
|
372
|
+
|
|
373
|
+
## Review format
|
|
374
|
+
|
|
375
|
+
When reviewing UI against this skill, use a markdown table:
|
|
376
|
+
|
|
377
|
+
| Before | After | Why |
|
|
378
|
+
| --- | --- | --- |
|
|
379
|
+
| Purple gradient CTA | Flat near-white primary on dark | Removes slop accent; quieter hierarchy |
|
|
380
|
+
| Card and button both `12px` radius with 16px pad | Card `28px`, button `12px` | Concentric radii |
|
|
381
|
+
| Title with emoji | Title plain, weight 600 | No emoji in chrome |
|
|
382
|
+
| `transition: all 300ms` on menu | `opacity/transform` with `--motion-fast` open / `--motion-quick` close, `--ease-smooth-out` | Tokenized, asymmetric, interruptible |
|
|
383
|
+
| Score textContent swap with no motion | Per-digit pop-in, `--motion-y-micro`, tabular-nums | Matches counter recipe |
|
|
384
|
+
| Modal scales from `0` | From `--motion-scale-modal` (0.96) | Avoid zero-scale pop-in |
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# Surfaces
|
|
2
|
+
|
|
3
|
+
Border radius, optical alignment, shadows, and image outlines.
|
|
4
|
+
|
|
5
|
+
## Concentric Border Radius
|
|
6
|
+
|
|
7
|
+
When nesting rounded elements, the outer radius must equal the inner radius plus the padding between them:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
outerRadius = innerRadius + padding
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This rule is most useful when nested surfaces are close together. If padding is larger than `24px`, treat the layers as separate surfaces and choose each radius independently instead of forcing strict concentric math.
|
|
14
|
+
|
|
15
|
+
### Example
|
|
16
|
+
|
|
17
|
+
```css
|
|
18
|
+
/* Good — concentric radii */
|
|
19
|
+
.card {
|
|
20
|
+
border-radius: 20px; /* 12 + 8 */
|
|
21
|
+
padding: 8px;
|
|
22
|
+
}
|
|
23
|
+
.card-inner {
|
|
24
|
+
border-radius: 12px;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/* Bad — same radius on both */
|
|
28
|
+
.card {
|
|
29
|
+
border-radius: 12px;
|
|
30
|
+
padding: 8px;
|
|
31
|
+
}
|
|
32
|
+
.card-inner {
|
|
33
|
+
border-radius: 12px;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Tailwind Example
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
// Good — outer radius accounts for padding
|
|
41
|
+
<div className="rounded-2xl p-2"> {/* 16px radius, 8px padding */}
|
|
42
|
+
<div className="rounded-lg"> {/* 8px radius = 16 - 8 ✓ */}
|
|
43
|
+
...
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
// Bad — same radius on both
|
|
48
|
+
<div className="rounded-xl p-2">
|
|
49
|
+
<div className="rounded-xl"> {/* same radius, looks off */}
|
|
50
|
+
...
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Mismatched border radii on nested elements is one of the most common things that makes interfaces feel off. Always calculate concentrically.
|
|
56
|
+
|
|
57
|
+
## Optical Alignment
|
|
58
|
+
|
|
59
|
+
When geometric centering looks off, align optically instead.
|
|
60
|
+
|
|
61
|
+
### Buttons with Text + Icon
|
|
62
|
+
|
|
63
|
+
Use slightly less padding on the icon side to make the button feel balanced. A reliable rule of thumb is:
|
|
64
|
+
`icon-side padding = text-side padding - 2px`.
|
|
65
|
+
|
|
66
|
+
```css
|
|
67
|
+
/* Good — less padding on icon side */
|
|
68
|
+
.button-with-icon {
|
|
69
|
+
padding-left: 16px;
|
|
70
|
+
padding-right: 14px; /* icon side = text side - 2px */
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Bad — equal padding looks like icon is pushed too far right */
|
|
74
|
+
.button-with-icon {
|
|
75
|
+
padding: 0 16px;
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
```tsx
|
|
80
|
+
// Tailwind
|
|
81
|
+
<button className="pl-4 pr-3.5 flex items-center gap-2">
|
|
82
|
+
<span>Continue</span>
|
|
83
|
+
<ArrowRightIcon />
|
|
84
|
+
</button>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Play Button Triangles
|
|
88
|
+
|
|
89
|
+
Play icons are triangular and their geometric center is not their visual center. Shift slightly right:
|
|
90
|
+
|
|
91
|
+
```css
|
|
92
|
+
/* Good — optically centered */
|
|
93
|
+
.play-button svg {
|
|
94
|
+
margin-left: 2px; /* shift right to account for triangle shape */
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* Bad — geometrically centered but looks off */
|
|
98
|
+
.play-button svg {
|
|
99
|
+
/* no adjustment */
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Asymmetric Icons (Stars, Arrows, Carets)
|
|
104
|
+
|
|
105
|
+
Some icons have uneven visual weight. The best fix is adjusting the SVG directly so no extra margin/padding is needed in the component code.
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
// Best — fix in the SVG itself
|
|
109
|
+
// Adjust the viewBox or path to visually center the icon
|
|
110
|
+
|
|
111
|
+
// Fallback — adjust with margin
|
|
112
|
+
<span className="ml-px">
|
|
113
|
+
<StarIcon />
|
|
114
|
+
</span>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Shadows Instead of Borders
|
|
118
|
+
|
|
119
|
+
For **buttons, cards, and containers** that use a border for depth or elevation, prefer replacing it with a subtle `box-shadow`. Shadows adapt to any background since they use transparency; solid borders don't. This also helps when using images or multiple colors as backgrounds — solid border colors don't work well on backgrounds other than the ones they were designed for.
|
|
120
|
+
|
|
121
|
+
**Do not apply this to dividers** (`border-b`, `border-t`, side borders) or any border whose purpose is layout separation rather than element depth. Those should stay as borders.
|
|
122
|
+
|
|
123
|
+
### Shadow as Border (Light Mode)
|
|
124
|
+
|
|
125
|
+
The shadow is comprised of three layers. The first acts as a 1px border ring, the second adds subtle lift, and the third provides ambient depth:
|
|
126
|
+
|
|
127
|
+
```css
|
|
128
|
+
:root {
|
|
129
|
+
--shadow-border:
|
|
130
|
+
0px 0px 0px 1px rgba(0, 0, 0, 0.06),
|
|
131
|
+
0px 1px 2px -1px rgba(0, 0, 0, 0.06),
|
|
132
|
+
0px 2px 4px 0px rgba(0, 0, 0, 0.04);
|
|
133
|
+
--shadow-border-hover:
|
|
134
|
+
0px 0px 0px 1px rgba(0, 0, 0, 0.08),
|
|
135
|
+
0px 1px 2px -1px rgba(0, 0, 0, 0.08),
|
|
136
|
+
0px 2px 4px 0px rgba(0, 0, 0, 0.06);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Shadow as Border (Dark Mode)
|
|
141
|
+
|
|
142
|
+
In dark mode, simplify to a single white ring — layered depth shadows aren't visible on dark backgrounds:
|
|
143
|
+
|
|
144
|
+
```css
|
|
145
|
+
/* Dark mode — adapt to whatever setup the project uses
|
|
146
|
+
(prefers-color-scheme, class, data attribute, etc.) */
|
|
147
|
+
--shadow-border: 0 0 0 1px rgba(255, 255, 255, 0.08);
|
|
148
|
+
--shadow-border-hover: 0 0 0 1px rgba(255, 255, 255, 0.13);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Usage with Hover Transition
|
|
152
|
+
|
|
153
|
+
Apply the variable and add `transition-[box-shadow]` for a smooth hover:
|
|
154
|
+
|
|
155
|
+
```css
|
|
156
|
+
.card {
|
|
157
|
+
box-shadow: var(--shadow-border);
|
|
158
|
+
transition-property: box-shadow;
|
|
159
|
+
transition-duration: 150ms;
|
|
160
|
+
transition-timing-function: ease-out;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.card:hover {
|
|
164
|
+
box-shadow: var(--shadow-border-hover);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### When to Use Shadows vs. Borders
|
|
169
|
+
|
|
170
|
+
| Use shadows | Use borders |
|
|
171
|
+
| --- | --- |
|
|
172
|
+
| Cards, containers with depth | Dividers between list items |
|
|
173
|
+
| Buttons with bordered styles | Table cell boundaries |
|
|
174
|
+
| Elevated elements (dropdowns, modals) | Form input outlines (for accessibility) |
|
|
175
|
+
| Elements on varied backgrounds | Hairline separators in dense UI |
|
|
176
|
+
| Hover/focus states for lift effect | |
|
|
177
|
+
|
|
178
|
+
## Image Outlines
|
|
179
|
+
|
|
180
|
+
Add a subtle `1px` outline with low opacity to images. This creates consistent depth, especially in design systems where other elements use borders or shadows.
|
|
181
|
+
|
|
182
|
+
### Light Mode
|
|
183
|
+
|
|
184
|
+
```css
|
|
185
|
+
img {
|
|
186
|
+
outline: 1px solid rgba(0, 0, 0, 0.1);
|
|
187
|
+
outline-offset: -1px; /* inset so it doesn't add to layout */
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Dark Mode
|
|
192
|
+
|
|
193
|
+
```css
|
|
194
|
+
img {
|
|
195
|
+
outline: 1px solid rgba(255, 255, 255, 0.1);
|
|
196
|
+
outline-offset: -1px;
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Tailwind with Dark Mode
|
|
201
|
+
|
|
202
|
+
```tsx
|
|
203
|
+
<img
|
|
204
|
+
className="outline outline-1 -outline-offset-1 outline-black/10 dark:outline-white/10"
|
|
205
|
+
src={src}
|
|
206
|
+
alt={alt}
|
|
207
|
+
/>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
**Why outline instead of border?** `outline` doesn't affect layout (no added width/height), and `outline-offset: -1px` keeps it inset so images stay their intended size.
|
|
211
|
+
|
|
212
|
+
## Minimum Hit Area
|
|
213
|
+
|
|
214
|
+
Interactive elements should have a minimum hit area of 44×44px (WCAG) or at least 40×40px. If the visible element is smaller (e.g., a 20×20 checkbox), extend the hit area with a pseudo-element.
|
|
215
|
+
|
|
216
|
+
### CSS Example
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
/* Small checkbox with expanded hit area */
|
|
220
|
+
.checkbox {
|
|
221
|
+
position: relative;
|
|
222
|
+
width: 20px;
|
|
223
|
+
height: 20px;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.checkbox::after {
|
|
227
|
+
content: "";
|
|
228
|
+
position: absolute;
|
|
229
|
+
top: 50%;
|
|
230
|
+
left: 50%;
|
|
231
|
+
transform: translate(-50%, -50%);
|
|
232
|
+
width: 40px;
|
|
233
|
+
height: 40px;
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Tailwind Example
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
<button className="relative size-5 after:absolute after:top-1/2 after:left-1/2 after:size-10 after:-translate-1/2">
|
|
241
|
+
<CheckIcon />
|
|
242
|
+
</button>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Collision Rule
|
|
246
|
+
|
|
247
|
+
If the extended hit area overlaps another interactive element, shrink the pseudo-element — but make it as large as possible without colliding. Two interactive elements should never have overlapping hit areas.
|