ReviewOS

also looking at this

stacks/wildloop

feat: native trail maps and complete native mobile screens

#1017
Draft chris wants to merge codex/trail-experience into main
60 files +2505 -823

Review threads live on the whole diff, not on one commit, so none are shown here - a thread's line means something in the branch's final form, and painting it into an intermediate step would put it on code it is not about.

storage/framework/api/package.jsonmodified+5-5
Changes to storage/framework/api/package.json
@@ -8,11 +8,11 @@
88 "prod": "bun --hot run dist/dev.js"
99 },
1010 "dependencies": {
11 "@stacksjs/logging": "^0.75.219",
12 "@stacksjs/queue": "^0.75.219",
13 "@stacksjs/router": "^0.75.219",
14 "@stacksjs/storage": "^0.75.219",
15 "@stacksjs/utils": "^0.75.219"
11 "@stacksjs/logging": "^0.75.221",
12 "@stacksjs/queue": "^0.75.221",
13 "@stacksjs/router": "^0.75.221",
14 "@stacksjs/storage": "^0.75.221",
15 "@stacksjs/utils": "^0.75.221"
1616 },
1717 "workspaces": [
1818 "../core/*"
storage/framework/auto-imports/functions.tsmodified+2-1
Changes to storage/framework/auto-imports/functions.ts
@@ -73,6 +73,7 @@ export { nativeDestination, nativeShortcutDestination } from '../../../resources
7373export { exportNativeGpx } from '../../../resources/functions/native-export'
7474export { nativeMapParts, nativeRouteRegion, nativeZoomRegion } from '../../../resources/functions/native-map'
7575export { nativeOAuthCallback } from '../../../resources/functions/native-oauth'
76export { createNativeRecordingCheckpoint } from '../../../resources/functions/native-recording-checkpoint'
7677export { nativeRecordingDuration, movingSeconds, recordingSamples, recordingFigures, recordingPayload } from '../../../resources/functions/native-recording'
7778export type { NativeRecording } from '../../../resources/functions/native-recording'
7879export { returnToServerFromBundledCopy, serverPath, serverURLFor, holdOnBundledPage, NATIVE_REMOTE_FILE, NATIVE_REMOTE_RETRY_MS, NATIVE_REMOTE_PROBE_TIMEOUT_MS } from '../../../resources/functions/native-remote'
@@ -136,7 +137,7 @@ export { normalizeTagKey, readTags, featureFromTag, trailFeatures, trailHighligh
136137export type { TrailFeature, TrailNotice, FeatureTrail } from '../../../resources/functions/trail-features'
137138export { routePartsFromSegments, lineLengthMeters, encodeRouteParts, decodeRouteParts, primaryRoutePart, ROUTE_SNAP_METERS } from '../../../resources/functions/trail-geometry'
138139export type { RoutePair, RouteNetwork } from '../../../resources/functions/trail-geometry'
139export { trailSegmentMiles, trailDirectionSigns, trailSurfaceTypes, trailGpx } from '../../../resources/functions/trail-map'
140export { trailheadPosition, trailSegmentMiles, trailDirectionSigns, trailSurfaceTypes, trailGpx, trailRouteStyle } from '../../../resources/functions/trail-map'
140141export { placeOfLocation, whereLocation, wholeTrailFigures, trailFacts, countryLabel, trailBreadcrumbs, trailFaq, exploreNearLinks, ratingSummary, forecastDayLabel, forecastBar, NEAR_PLACE_PREFIX } from '../../../resources/functions/trail-page'
141142export type { PageTrail, TrailFigures, Crumb, FaqEntry, LinkGroup, RatingSummary } from '../../../resources/functions/trail-page'
142143export { parsePhotoList, trailGallery } from '../../../resources/functions/trail-photos'
storage/framework/auto-imports/globals.tsmodified+3-0
Changes to storage/framework/auto-imports/globals.ts
@@ -295,6 +295,7 @@ declare global {
295295 const nativeRouteRegion: typeof autoImports.nativeRouteRegion
296296 const nativeZoomRegion: typeof autoImports.nativeZoomRegion
297297 const nativeOAuthCallback: typeof autoImports.nativeOAuthCallback
298 const createNativeRecordingCheckpoint: typeof autoImports.createNativeRecordingCheckpoint
298299 const nativeRecordingDuration: typeof autoImports.nativeRecordingDuration
299300 const movingSeconds: typeof autoImports.movingSeconds
300301 const recordingSamples: typeof autoImports.recordingSamples
@@ -475,10 +476,12 @@ declare global {
475476 const decodeRouteParts: typeof autoImports.decodeRouteParts
476477 const primaryRoutePart: typeof autoImports.primaryRoutePart
477478 const ROUTE_SNAP_METERS: typeof autoImports.ROUTE_SNAP_METERS
479 const trailheadPosition: typeof autoImports.trailheadPosition
478480 const trailSegmentMiles: typeof autoImports.trailSegmentMiles
479481 const trailDirectionSigns: typeof autoImports.trailDirectionSigns
480482 const trailSurfaceTypes: typeof autoImports.trailSurfaceTypes
481483 const trailGpx: typeof autoImports.trailGpx
484 const trailRouteStyle: typeof autoImports.trailRouteStyle
482485 const placeOfLocation: typeof autoImports.placeOfLocation
483486 const whereLocation: typeof autoImports.whereLocation
484487 const wholeTrailFigures: typeof autoImports.wholeTrailFigures
storage/framework/cloud/package.jsonmodified+11-11
Changes to storage/framework/cloud/package.json
@@ -46,19 +46,19 @@
4646 "dev": "./dev local"
4747 },
4848 "dependencies": {
49 "@stacksjs/config": "^0.75.219",
50 "@stacksjs/dns": "^0.75.219",
51 "@stacksjs/logging": "^0.75.219",
52 "@stacksjs/path": "^0.75.219",
53 "@stacksjs/queue": "^0.75.219",
54 "@stacksjs/router": "^0.75.219",
55 "@stacksjs/storage": "^0.75.219",
56 "@stacksjs/utils": "^0.75.219",
57 "@stacksjs/validation": "^0.75.219"
49 "@stacksjs/config": "^0.75.221",
50 "@stacksjs/dns": "^0.75.221",
51 "@stacksjs/logging": "^0.75.221",
52 "@stacksjs/path": "^0.75.221",
53 "@stacksjs/queue": "^0.75.221",
54 "@stacksjs/router": "^0.75.221",
55 "@stacksjs/storage": "^0.75.221",
56 "@stacksjs/utils": "^0.75.221",
57 "@stacksjs/validation": "^0.75.221"
5858 },
5959 "devDependencies": {
60 "@stacksjs/cli": "^0.75.219",
60 "@stacksjs/cli": "^0.75.221",
6161 "better-dx": "^0.2.25",
62 "@stacksjs/env": "^0.75.219"
62 "@stacksjs/env": "^0.75.221"
6363 }
6464}
storage/framework/defaults/.stacks-sync.jsonmodified+2-2
Changes to storage/framework/defaults/.stacks-sync.json
@@ -1,4 +1,4 @@
11{
2 "version": "0.75.219",
3 "syncedAt": "2026-10-17T20:08:47.667Z"
2 "version": "0.75.221",
3 "syncedAt": "2026-10-18T12:28:01.000Z"
44}
storage/framework/defaults/ai/skills/stacks-env/SKILL.mdmodified+6-0
Changes to storage/framework/defaults/ai/skills/stacks-env/SKILL.md
@@ -233,6 +233,12 @@ buddy env:check # validate env configuration
233233buddy env:check --file .env.production # check a specific environment's file
234234```
235235
236`getEnv()` fails a whole-file read if any encrypted entry cannot be decrypted.
237Restore the environment's matching private key through `.env.keys` or its
238`DOTENV_PRIVATE_KEY_<ENVIRONMENT>` process secret. A request for one plaintext
239key remains readable independently. `buddy deploy` stops on an incomplete or
240unreadable environment instead of deploying a partial map.
241
236242## Tenant isolation on a shared box
237243
238244When several projects share one server - one owns it, the rest attach with
storage/framework/defaults/ai/skills/stacks-git/SKILL.mdmodified+22-0
Changes to storage/framework/defaults/ai/skills/stacks-git/SKILL.md
@@ -83,6 +83,28 @@ Based on `cz-git` UserConfig:
8383
8484## Git Utilities
8585
86`gitCredentialEnvironment({ url, username, password })` from `@stacksjs/git`
87returns environment variables for a child Git process. Pass the caller's base
88environment as its second argument, then merge the result after that base.
89Existing runtime Git configuration is preserved. The HTTP(S) URL must identify one repository without
90userinfo, query or fragment. The helper supplies credentials only for that
91protocol, host and repository path, refuses redirects for that URL, disables
92interactive prompts, and writes no credential or Git config file. Never log
93the returned environment. Use a credential scoped to the repository and the
94operation; this helper does not grant server permissions.
95
96```typescript
97import { gitCredentialEnvironment } from '@stacksjs/git'
98
99const child = Bun.spawn(['git', 'ls-remote', 'origin'], {
100 cwd: workspace,
101 env: { ...process.env, ...gitCredentialEnvironment({ url: repositoryUrl, username: 'x-access-token', password: jobToken }, process.env) },
102})
103```
104
105The child and its descendants receive the credential. Use this for trusted
106job steps, never to transfer a host credential into an isolated guest.
107
86108`buddy release` atomically pushes its commit and version tag to the branch's
87109configured upstream remote and branch. A worktree on `codex/example` tracking
88110`origin/main` releases to `origin/main`; it does not create a remote feature
storage/framework/defaults/ai/skills/stacks-native/CATALOG.mdmodified+10-8
Changes to storage/framework/defaults/ai/skills/stacks-native/CATALOG.md
@@ -21,7 +21,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
2121| `@stacksjs/auth` | [`stacks-auth`](../stacks-auth/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/auth/src/index.ts) | 115 |
2222| `@stacksjs/browser` | [`stacks-browser`](../stacks-browser/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser/src/index.ts) | 8 |
2323| `@stacksjs/browser-extension` | [`stacks-browser-extension`](../stacks-browser-extension/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/browser-extension/src/index.ts) | 7 |
24| `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) | 149 |
24| `@stacksjs/buddy` | [`stacks-buddy`](../stacks-buddy/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/index.ts) | 150 |
2525| `@stacksjs/build` | [`stacks-build`](../stacks-build/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/build/src/index.ts) | 2 |
2626| `@stacksjs/cache` | [`stacks-cache`](../stacks-cache/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/cache/src/index.ts) | 11 |
2727| `@stacksjs/calendar-api` | [`stacks-calendar`](../stacks-calendar/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/calendar-api/src/index.ts) | 2 |
@@ -45,14 +45,14 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
4545| `@stacksjs/docs` | [`stacks-docs`](../stacks-docs/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/docs/src/index.ts) | 2 |
4646| `@stacksjs/email` | [`stacks-email`](../stacks-email/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/email/src/index.ts) | 21 |
4747| `@stacksjs/enums` | [`stacks-enums`](../stacks-enums/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/enums/src/index.ts) | 3 |
48| `@stacksjs/env` | [`stacks-env`](../stacks-env/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/index.ts) | 27 |
48| `@stacksjs/env` | [`stacks-env`](../stacks-env/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/index.ts) | 28 |
4949| `@stacksjs/error-handling` | [`stacks-error-handling`](../stacks-error-handling/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/error-handling/src/index.ts) | 10 |
5050| `@stacksjs/events` | [`stacks-events`](../stacks-events/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/events/src/index.ts) | 12 |
5151| `@stacksjs/faker` | [`stacks-faker`](../stacks-faker/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/faker/src/index.ts) | 1 |
5252| `@stacksjs/feature-flags` | [`stacks-feature-flags`](../stacks-feature-flags/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/feature-flags/src/index.ts) | 7 |
5353| `@stacksjs/features` | [`stacks-features`](../stacks-features/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/features/src/index.ts) | 1 |
5454| `@stacksjs/forms` | [`stacks-forms`](../stacks-forms/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/forms/src/index.ts) | 4 |
55| `@stacksjs/git` | [`stacks-git`](../stacks-git/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/git/src/index.ts) | 1 |
55| `@stacksjs/git` | [`stacks-git`](../stacks-git/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/git/src/index.ts) | 2 |
5656| `@stacksjs/github` | [`stacks-git`](../stacks-git/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/github/src/index.ts) | 7 |
5757| `@stacksjs/health` | [`stacks-health`](../stacks-health/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/health/src/index.ts) | 2 |
5858| `@stacksjs/http` | [`stacks-http`](../stacks-http/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/http/src/index.ts) | 2 |
@@ -92,7 +92,7 @@ Browser runtime bindings are documented separately in `stacks-auto-imports`.
9292| `@stacksjs/tinker` | [`stacks-repl`](../stacks-repl/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tinker/src/index.ts) | 1 |
9393| `@stacksjs/tunnel` | [`stacks-tunnel`](../stacks-tunnel/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/tunnel/src/index.ts) | 1 |
9494| `@stacksjs/types` | [`stacks-types`](../stacks-types/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/types/src/index.ts) | 2 |
95| `@stacksjs/ui` | [`stacks-ui`](../stacks-ui/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ui/src/index.ts) | 5 |
95| `@stacksjs/ui` | [`stacks-ui`](../stacks-ui/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ui/src/index.ts) | 6 |
9696| `@stacksjs/utils` | [`stacks-utils`](../stacks-utils/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/utils/src/index.ts) | 15 |
9797| `@stacksjs/validation` | [`stacks-validation`](../stacks-validation/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/validation/src/index.ts) | 17 |
9898| `@stacksjs/video` | [`stacks-video`](../stacks-video/SKILL.md) | [entrypoint](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/video/src/index.ts) | 3 |
@@ -215,7 +215,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
215215
216216Local source modules: [src/commands/index.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/src/commands/index.ts).
217217
218Evidence directory: [149 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
218Evidence directory: [150 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/buddy/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
219219
220220### @stacksjs/build
221221
@@ -443,7 +443,7 @@ Read the entrypoint and package export map for re-exported or type-only surfaces
443443
444444Local source modules: [src/cli.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/cli.ts), [src/crypto.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/crypto.ts), [src/deployment.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/deployment.ts), [src/integrations.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/integrations.ts), [src/numeric-keys.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/numeric-keys.ts), [src/parser.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/parser.ts), [src/plaintext.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/plaintext.ts), [src/plugin.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/plugin.ts), [src/runtime.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/runtime.ts), [src/tenants.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/tenants.ts), [src/types.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/types.ts), [src/utils.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/src/utils.ts).
445445
446Evidence directory: [27 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
446Evidence directory: [28 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/env/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
447447
448448### @stacksjs/error-handling
449449
@@ -509,7 +509,9 @@ Guidance: [`stacks-git`](../stacks-git/SKILL.md). Source: [storage/framework/cor
509509
510510Read the entrypoint and package export map for re-exported or type-only surfaces.
511511
512Evidence directory: [1 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/git/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
512Local source modules: [src/credentials.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/git/src/credentials.ts).
513
514Evidence directory: [2 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/git/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
513515
514516### @stacksjs/github
515517
@@ -887,7 +889,7 @@ Declared runtime exports: `CssEngine`, `buildPageSequence`, `paginatorVariant`,
887889
888890Local source modules: [src/fonts.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ui/src/fonts.ts), [src/pagination.ts](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ui/src/pagination.ts).
889891
890Evidence directory: [5 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ui/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
892Evidence directory: [6 retained tests](https://github.com/stacksjs/stacks/blob/main/storage/framework/core/ui/tests). These files are evidence pointers, not a claim that all tests were run for this catalog.
891893
892894### @stacksjs/utils
893895
storage/framework/defaults/ide/vscode/package.jsonmodified+1-1
Changes to storage/framework/defaults/ide/vscode/package.json
@@ -2,7 +2,7 @@
22 "publisher": "Stacks",
33 "name": "vscode-stacks",
44 "displayName": "Stacks",
5 "version": "0.75.219",
5 "version": "0.75.221",
66 "description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
77 "license": "MIT",
88 "funding": "https://github.com/sponsors/chrisbbreuer",
storage/framework/defaults/resources/components/MembershipCard.stxmodified+80-23
Changes to storage/framework/defaults/resources/components/MembershipCard.stx
@@ -12,40 +12,93 @@
1212 const mcReplay = useReactiveProp<number>('replay', 0)
1313 const mcReveals = derived(() => [mcReplay()])
1414 const mcCelebrate = useReactiveProp<boolean>('celebrate', true)
15 const mcSurface = useRef('membershipSurface')
16 const mcCanHover = useMediaQuery('(hover: hover) and (pointer: fine)')
17 const mcReduceMotion = usePreferredReducedMotion()
18 let mcStopHover: (() => void) | undefined
19
20 onMount(() => {
21 const surface = mcSurface.current as HTMLElement | null
22 if (!surface) return
23
24 // Measure the stationary hit area, never the rotating card, to avoid feedback jitter.
25 const reset = () => {
26 surface.style.setProperty('--mc-rotate-x', '0deg')
27 surface.style.setProperty('--mc-rotate-y', '0deg')
28 surface.style.setProperty('--mc-light-x', '50%')
29 surface.style.setProperty('--mc-light-y', '50%')
30 surface.style.setProperty('--mc-hover', '0')
31 }
32 mcStopHover = effect(() => {
33 reset()
34 if (!mcCanHover() || mcReduceMotion()) return
35 const mouse = useMouse({ target: surface, touch: false, resetOnLeave: true })
36 const unsubscribe = mouse.subscribe(({ clientX, clientY, isInside }) => {
37 if (!isInside) return reset()
38 const bounds = surface.getBoundingClientRect()
39 if (!bounds.width || !bounds.height) return reset()
40 const x = Math.max(0, Math.min(1, (clientX - bounds.left) / bounds.width))
41 const y = Math.max(0, Math.min(1, (clientY - bounds.top) / bounds.height))
42 surface.style.setProperty('--mc-rotate-x', `${(0.5 - y) * 12}deg`)
43 surface.style.setProperty('--mc-rotate-y', `${(x - 0.5) * 16}deg`)
44 surface.style.setProperty('--mc-light-x', `${x * 100}%`)
45 surface.style.setProperty('--mc-light-y', `${y * 100}%`)
46 surface.style.setProperty('--mc-hover', '1')
47 })
48 return () => {
49 unsubscribe()
50 mouse.stop()
51 reset()
52 }
53 })
54 })
55 onDestroy(() => mcStopHover?.())
56
1557 const mcPieces = [...Array(32).keys()].map(id => ({
1658 id,
1759 style: `--mc-x:${(id * 37 + 11) % 100}%;--mc-drift:${(id * 29 % 160) - 80}px;--mc-delay:${id % 8 * 65}ms;--mc-turn:${180 + id * 47}deg;--mc-color:var(--membership-card-confetti-${id % 4 + 1},${['#99f6e4', '#e2e8f0', '#5eead4', '#94a3b8'][id % 4]})`,
1860 }))
1961</script>
2062
21<div :for="reveal in mcReveals" :key="reveal" class="relative mx-auto w-full mc-stage" :class="mcCelebrate ? 'mc-celebrate' : ''" data-membership-reveal>
22 <div :if="mcCelebrate" class="absolute inset-0 overflow-hidden pointer-events-none mc-confetti" aria-hidden="true">
23 <span :for="piece in mcPieces" :key="piece.id" class="mc-piece" :style="piece.style"></span>
24 </div>
25 <article class="overflow-hidden relative mx-auto w-full mc-metal" :aria-label="mcLabel" data-membership-card>
26 <div class="absolute inset-0 pointer-events-none mc-grain" aria-hidden="true"></div>
27 <div class="absolute inset-0 pointer-events-none mc-shine" aria-hidden="true"></div>
28 <div class="flex relative gap-4 items-start justify-between">
29 <img :if="mcLogo" class="mc-logo" :src="mcLogo" :alt="mcBrand" width="96" height="38" />
30 <span :if="!mcLogo" class="font-bold mc-wordmark" :text="mcBrand"></span>
31 </div>
32 <p class="relative mt-3 text-xs mc-label" :text="mcLabel"></p>
33 <div class="relative mc-holder">
34 <div class="mc-person">
35 <p class="mb-2 text-xs mc-label" :text="mcNameLabel"></p>
36 <p class="mc-engraving" :style="{ fontFamily: mcNameFont }" :text="mcName" data-membership-name></p>
63<div class="relative mx-auto w-full mc-stage" data-membership-reveal>
64 <div ref="membershipSurface" class="mc-surface">
65 <div :for="reveal in mcReveals" :key="reveal" :class="mcCelebrate ? 'mc-celebrate' : ''">
66 <div :if="mcCelebrate" class="absolute inset-0 overflow-hidden pointer-events-none mc-confetti" aria-hidden="true">
67 <span :for="piece in mcPieces" :key="piece.id" class="mc-piece" :style="piece.style"></span>
3768 </div>
38 <div :if="mcMemberId" class="mc-identity">
39 <p class="text-xs mc-label" :text="mcMemberIdLabel"></p>
40 <p class="font-semibold mc-serial" :text="mcMemberId" data-membership-id></p>
69 <div class="mc-tilt">
70 <article class="overflow-hidden relative mx-auto w-full mc-metal" :aria-label="mcLabel" data-membership-card>
71 <div class="absolute inset-0 pointer-events-none mc-grain" aria-hidden="true"></div>
72 <div class="absolute inset-0 pointer-events-none mc-reflection" aria-hidden="true"></div>
73 <div class="absolute inset-0 pointer-events-none mc-shine" aria-hidden="true"></div>
74 <div class="flex relative gap-4 items-start justify-between">
75 <img :if="mcLogo" class="mc-logo" :src="mcLogo" :alt="mcBrand" width="96" height="38" />
76 <span :if="!mcLogo" class="font-bold mc-wordmark" :text="mcBrand"></span>
77 </div>
78 <p class="relative mt-3 text-xs mc-label" :text="mcLabel"></p>
79 <div class="relative mc-holder">
80 <div class="mc-person">
81 <p class="mb-2 text-xs mc-label" :text="mcNameLabel"></p>
82 <p class="mc-engraving" :style="{ fontFamily: mcNameFont }" :text="mcName" data-membership-name></p>
83 </div>
84 <div :if="mcMemberId" class="mc-identity">
85 <p class="text-xs mc-label" :text="mcMemberIdLabel"></p>
86 <p class="font-semibold mc-serial" :text="mcMemberId" data-membership-id></p>
87 </div>
88 </div>
89 <p :if="mcDetail" class="relative mt-5 text-xs mc-detail" :text="mcDetail"></p>
90 </article>
4191 </div>
4292 </div>
43 <p :if="mcDetail" class="relative mt-5 text-xs mc-detail" :text="mcDetail"></p>
44 </article>
93 </div>
4594</div>
4695
4796<style>
4897 .mc-stage { max-width: 28rem; padding: 2rem 0 2.5rem; perspective: 1000px; }
98 .mc-surface { isolation: isolate; }
99 .mc-tilt { transform: perspective(1000px) rotateX(var(--mc-rotate-x, 0deg)) rotateY(var(--mc-rotate-y, 0deg)) translateY(calc(var(--mc-hover, 0) * -3px)); transition: transform 450ms cubic-bezier(0.2, 0.75, 0.25, 1); }
100 .mc-surface:hover .mc-tilt { transition-duration: 160ms; }
101 .mc-reflection { opacity: calc(var(--mc-hover, 0) * 0.65); background: radial-gradient(ellipse at var(--mc-light-x, 50%) var(--mc-light-y, 50%), #ffffff38, #ffffff0a 42%, transparent 72%); transition: opacity 350ms ease; }
49102 .mc-metal {
50103 box-sizing: border-box; min-height: 15.5rem; padding: clamp(1.25rem, 5vw, 2rem); border-radius: 1.25rem;
51104 color: var(--membership-card-color, #e2e8f0); border: 1px solid var(--membership-card-border, #87939d);
@@ -79,10 +132,14 @@
79132 .mc-celebrate .mc-metal { animation: mc-arrive 1100ms cubic-bezier(0.16, 1, 0.3, 1) both; }
80133 .mc-celebrate .mc-shine { animation: mc-polish 1700ms ease-in-out 650ms both; }
81134 .mc-celebrate .mc-piece { animation: mc-fall 2400ms cubic-bezier(0.2, 0.65, 0.45, 1) var(--mc-delay) both; }
82 .mc-metal:hover .mc-shine { transform: translateX(150%) skewX(-20deg); transition: transform 1400ms ease; }
135 }
136 @media (hover: none), (pointer: coarse) {
137 .mc-tilt { transform: none; transition: none; }
138 .mc-reflection { display: none; }
83139 }
84140 @media (prefers-reduced-motion: reduce) {
85 .mc-confetti, .mc-shine { display: none; }
141 .mc-confetti, .mc-shine, .mc-reflection { display: none; }
142 .mc-tilt { transform: none; transition: none; }
86143 }
87144 @keyframes mc-arrive { from { opacity: 0; transform: translateY(32px) rotateX(16deg) rotateY(-12deg) scale(0.92); } to { opacity: 1; transform: none; } }
88145 @keyframes mc-polish { from { transform: translateX(-150%) skewX(-20deg); } to { transform: translateX(150%) skewX(-20deg); } }
storage/framework/defaults/views/dashboard/.discovered-models.jsonmodified+5-229
Changes to storage/framework/defaults/views/dashboard/.discovered-models.json
@@ -1,22 +1,5 @@
11{
22 "models": [
3 {
4 "id": "achievement",
5 "name": "Achievement",
6 "icon": "tablecells.fill",
7 "hasDedicatedPage": false,
8 "category": "userland",
9 "dashboard": {
10 "highlight": true
11 }
12 },
13 {
14 "id": "activity-comment",
15 "name": "ActivityComment",
16 "icon": "tablecells.fill",
17 "hasDedicatedPage": false,
18 "category": "userland"
19 },
203 {
214 "id": "analytics-event",
225 "name": "AnalyticsEvent",
@@ -132,13 +115,6 @@
132115 "enabled": false
133116 }
134117 },
135 {
136 "id": "card-attachment",
137 "name": "CardAttachment",
138 "icon": "tablecells.fill",
139 "hasDedicatedPage": false,
140 "category": "data"
141 },
142118 {
143119 "id": "card-comment",
144120 "name": "CardComment",
@@ -186,40 +162,6 @@
186162 "highlight": true
187163 }
188164 },
189 {
190 "id": "challenge",
191 "name": "Challenge",
192 "icon": "tablecells.fill",
193 "hasDedicatedPage": false,
194 "category": "userland",
195 "dashboard": {
196 "highlight": true
197 }
198 },
199 {
200 "id": "club",
201 "name": "Club",
202 "icon": "tablecells.fill",
203 "hasDedicatedPage": false,
204 "category": "userland",
205 "dashboard": {
206 "highlight": true
207 }
208 },
209 {
210 "id": "club-invite",
211 "name": "ClubInvite",
212 "icon": "tablecells.fill",
213 "hasDedicatedPage": false,
214 "category": "userland"
215 },
216 {
217 "id": "club-member",
218 "name": "ClubMember",
219 "icon": "tablecells.fill",
220 "hasDedicatedPage": false,
221 "category": "userland"
222 },
223165 {
224166 "id": "comment",
225167 "name": "Comment",
@@ -241,13 +183,6 @@
241183 "hasDedicatedPage": false,
242184 "category": "data"
243185 },
244 {
245 "id": "content-report",
246 "name": "ContentReport",
247 "icon": "tablecells.fill",
248 "hasDedicatedPage": false,
249 "category": "userland"
250 },
251186 {
252187 "id": "coupon",
253188 "name": "Coupon",
@@ -285,13 +220,6 @@
285220 "highlight": true
286221 }
287222 },
288 {
289 "id": "custom-route",
290 "name": "CustomRoute",
291 "icon": "tablecells.fill",
292 "hasDedicatedPage": false,
293 "category": "userland"
294 },
295223 {
296224 "id": "delivery-route",
297225 "name": "DeliveryRoute",
@@ -322,13 +250,6 @@
322250 "highlight": true
323251 }
324252 },
325 {
326 "id": "device-push-token",
327 "name": "DevicePushToken",
328 "icon": "tablecells.fill",
329 "hasDedicatedPage": false,
330 "category": "userland"
331 },
332253 {
333254 "id": "digital-delivery",
334255 "name": "DigitalDelivery",
@@ -383,44 +304,6 @@
383304 "enabled": false
384305 }
385306 },
386 {
387 "id": "event",
388 "name": "Event",
389 "icon": "tablecells.fill",
390 "hasDedicatedPage": false,
391 "category": "userland",
392 "dashboard": {
393 "highlight": true
394 }
395 },
396 {
397 "id": "event-entrant",
398 "name": "EventEntrant",
399 "icon": "tablecells.fill",
400 "hasDedicatedPage": false,
401 "category": "userland"
402 },
403 {
404 "id": "event-lap",
405 "name": "EventLap",
406 "icon": "tablecells.fill",
407 "hasDedicatedPage": false,
408 "category": "userland"
409 },
410 {
411 "id": "feedback-token",
412 "name": "FeedbackToken",
413 "icon": "tablecells.fill",
414 "hasDedicatedPage": false,
415 "category": "data"
416 },
417 {
418 "id": "follow",
419 "name": "Follow",
420 "icon": "tablecells.fill",
421 "hasDedicatedPage": false,
422 "category": "userland"
423 },
424307 {
425308 "id": "form",
426309 "name": "Form",
@@ -466,13 +349,6 @@
466349 "hasDedicatedPage": true,
467350 "category": "system"
468351 },
469 {
470 "id": "kudos",
471 "name": "Kudos",
472 "icon": "tablecells.fill",
473 "hasDedicatedPage": false,
474 "category": "userland"
475 },
476352 {
477353 "id": "label",
478354 "name": "Label",
@@ -772,28 +648,11 @@
772648 "name": "Review",
773649 "icon": "star.fill",
774650 "hasDedicatedPage": true,
775 "category": "userland",
776 "dashboard": {
777 "highlight": true
778 }
779 },
780 {
781 "id": "route-effort",
782 "name": "RouteEffort",
783 "icon": "tablecells.fill",
784 "hasDedicatedPage": false,
785 "category": "userland",
651 "category": "commerce",
786652 "dashboard": {
787653 "highlight": true
788654 }
789655 },
790 {
791 "id": "saved-trail",
792 "name": "SavedTrail",
793 "icon": "tablecells.fill",
794 "hasDedicatedPage": false,
795 "category": "userland"
796 },
797656 {
798657 "id": "sender-domain",
799658 "name": "SenderDomain",
@@ -957,50 +816,6 @@
957816 "enabled": false
958817 }
959818 },
960 {
961 "id": "territory",
962 "name": "Territory",
963 "icon": "tablecells.fill",
964 "hasDedicatedPage": false,
965 "category": "userland",
966 "dashboard": {
967 "highlight": true
968 }
969 },
970 {
971 "id": "territory-history",
972 "name": "TerritoryHistory",
973 "icon": "tablecells.fill",
974 "hasDedicatedPage": false,
975 "category": "userland"
976 },
977 {
978 "id": "territory-stats",
979 "name": "TerritoryStats",
980 "icon": "tablecells.fill",
981 "hasDedicatedPage": false,
982 "category": "userland"
983 },
984 {
985 "id": "trail",
986 "name": "Trail",
987 "icon": "tablecells.fill",
988 "hasDedicatedPage": false,
989 "category": "userland",
990 "dashboard": {
991 "highlight": true
992 }
993 },
994 {
995 "id": "trail-ingest-shard",
996 "name": "TrailIngestShard",
997 "icon": "tablecells.fill",
998 "hasDedicatedPage": false,
999 "category": "userland",
1000 "dashboard": {
1001 "highlight": false
1002 }
1003 },
1004819 {
1005820 "id": "transaction",
1006821 "name": "Transaction",
@@ -1011,13 +826,6 @@
1011826 "highlight": true
1012827 }
1013828 },
1014 {
1015 "id": "trip-plan",
1016 "name": "TripPlan",
1017 "icon": "tablecells.fill",
1018 "hasDedicatedPage": false,
1019 "category": "userland"
1020 },
1021829 {
1022830 "id": "usage-event",
1023831 "name": "UsageEvent",
@@ -1030,42 +838,10 @@
1030838 "name": "User",
1031839 "icon": "person.fill",
1032840 "hasDedicatedPage": true,
1033 "category": "userland"
1034 },
1035 {
1036 "id": "user-achievement",
1037 "name": "UserAchievement",
1038 "icon": "tablecells.fill",
1039 "hasDedicatedPage": false,
1040 "category": "userland"
1041 },
1042 {
1043 "id": "user-block",
1044 "name": "UserBlock",
1045 "icon": "tablecells.fill",
1046 "hasDedicatedPage": false,
1047 "category": "userland"
1048 },
1049 {
1050 "id": "user-notification",
1051 "name": "UserNotification",
1052 "icon": "tablecells.fill",
1053 "hasDedicatedPage": false,
1054 "category": "userland"
1055 },
1056 {
1057 "id": "user-privacy-setting",
1058 "name": "UserPrivacySetting",
1059 "icon": "tablecells.fill",
1060 "hasDedicatedPage": false,
1061 "category": "userland"
1062 },
1063 {
1064 "id": "user-stats",
1065 "name": "UserStats",
1066 "icon": "tablecells.fill",
1067 "hasDedicatedPage": false,
1068 "category": "userland"
841 "category": "data",
842 "dashboard": {
843 "highlight": true
844 }
1069845 },
1070846 {
1071847 "id": "waitlist-product",
storage/framework/docs/package.jsonmodified+7-7
Changes to storage/framework/docs/package.json
@@ -8,12 +8,12 @@
88 "preview": "bunpress preview"
99 },
1010 "dependencies": {
11 "@stacksjs/alias": "^0.75.219",
12 "@stacksjs/cli": "^0.75.219",
13 "@stacksjs/config": "^0.75.219",
14 "@stacksjs/env": "^0.75.219",
15 "@stacksjs/path": "^0.75.219",
16 "@stacksjs/server": "^0.75.219",
17 "@stacksjs/storage": "^0.75.219"
11 "@stacksjs/alias": "^0.75.221",
12 "@stacksjs/cli": "^0.75.221",
13 "@stacksjs/config": "^0.75.221",
14 "@stacksjs/env": "^0.75.221",
15 "@stacksjs/path": "^0.75.221",
16 "@stacksjs/server": "^0.75.221",
17 "@stacksjs/storage": "^0.75.221"
1818 }
1919}
storage/framework/libs/components/stx/package.jsonmodified+1-1
Changes to storage/framework/libs/components/stx/package.json
@@ -42,6 +42,6 @@
4242 "prepublishOnly": "bun run build"
4343 },
4444 "devDependencies": {
45 "stacks": "^0.75.219"
45 "stacks": "^0.75.221"
4646 }
4747}
storage/framework/libs/components/web/package.jsonmodified+1-1
Changes to storage/framework/libs/components/web/package.json
@@ -45,6 +45,6 @@
4545 "prepublishOnly": "bun run build"
4646 },
4747 "devDependencies": {
48 "stacks": "^0.75.219"
48 "stacks": "^0.75.221"
4949 }
5050}
storage/framework/libs/functions/package.jsonmodified+1-1
Changes to storage/framework/libs/functions/package.json
@@ -41,6 +41,6 @@
4141 "prepublishOnly": "bun run build"
4242 },
4343 "devDependencies": {
44 "stacks": "^0.75.219"
44 "stacks": "^0.75.221"
4545 }
4646}
storage/framework/orm/package.jsonmodified+3-3
Changes to storage/framework/orm/package.json
@@ -45,9 +45,9 @@
4545 "prepublishOnly": "bun run build"
4646 },
4747 "dependencies": {
48 "@stacksjs/cache": "^0.75.219",
49 "@stacksjs/database": "^0.75.219",
50 "@stacksjs/error-handling": "^0.75.219"
48 "@stacksjs/cache": "^0.75.221",
49 "@stacksjs/database": "^0.75.221",
50 "@stacksjs/error-handling": "^0.75.221"
5151 },
5252 "devDependencies": {
5353 "better-dx": "^0.2.5"
storage/framework/server/package.jsonmodified+5-5
Changes to storage/framework/server/package.json
@@ -48,10 +48,10 @@
4848 },
4949 "devDependencies": {
5050 "better-dx": "^0.2.5",
51 "@stacksjs/logging": "^0.75.219",
52 "@stacksjs/path": "^0.75.219",
53 "@stacksjs/router": "^0.75.219",
54 "@stacksjs/storage": "^0.75.219",
55 "@stacksjs/utils": "^0.75.219"
51 "@stacksjs/logging": "^0.75.221",
52 "@stacksjs/path": "^0.75.221",
53 "@stacksjs/router": "^0.75.221",
54 "@stacksjs/storage": "^0.75.221",
55 "@stacksjs/utils": "^0.75.221"
5656 }
5757}