{ "$schema": "https://ui.shadcn.com/schema/registry-item.json", "name": "nav", "type": "registry:item", "title": "aesthetic Nav", "description": "Aesthetic Nav primitive, v0.25.0. Installs ae-nav, ae-nav-ind, ae-view without the full stylesheet. Recipes: nav.js.", "registryDependencies": [ "https://aesthetic.mistystep.io/r/aesthetic-base.json" ], "meta": { "version": "0.25.0", "tier": "primitive", "route": "nav", "classes": ["ae-nav", "ae-nav-ind", "ae-view"], "attributes": [], "tokens": [ "--ae-surface", "--ae-wash", "--ae-ink", "--ae-ink-faint", "--ae-accent", "--ae-surface-dark", "--ae-wash-dark", "--ae-ink-dark", "--ae-ink-faint-dark", "--ae-accent-dark", "--ae-font", "--ae-font-mono", "--ae-w-regular", "--ae-ease", "--ae-quick", "--ae-ink-muted", "--ae-ink-muted-dark", "--ae-w-medium", "--ae-space-6", "--ae-soft" ], "recipes": ["nav.js"] }, "files": [ { "path": "registry/nav/aesthetic.nav.css", "type": "registry:file", "target": "~/aesthetic.nav.css", "content": "/* aesthetic nav v0.25.0 — generated by scripts/build-registry.mjs. */\n@import './aesthetic.base.css';\n\n:root {\n --ae-ink-muted: #737373;\n --ae-ink-muted-dark: #8f8f8f;\n --ae-w-medium: 550;\n --ae-space-6: 2em;\n --ae-soft: 240ms;\n}\n\n@media (prefers-color-scheme: dark) {\n :root:not(.light):not([data-ae-mode='light']) {\n --ae-ink-muted: var(--ae-ink-muted-dark);\n }\n}\n\n.light,\n[data-ae-mode='light'] {\n color-scheme: light;\n}\n\n:root.dark,\n:root[data-ae-mode='dark'] {\n color-scheme: dark;\n --ae-ink-muted: var(--ae-ink-muted-dark);\n}\n\n.ae-view {\nanimation: ae-enter var(--ae-soft) var(--ae-ease) both;\n}\n\n.ae-nav {\nposition: relative;\n display: flex;\n gap: var(--ae-space-6);\n}\n\n.ae-nav a,\n.ae-nav button {\nbackground: transparent;\n border: 0;\n padding: 0 0 0.6em;\n margin-block: 0;\n cursor: pointer;\n color: var(--ae-ink-muted);\n font-weight: var(--ae-w-medium);\n text-decoration: none;\n transition: color var(--ae-quick) var(--ae-ease);\n}\n\n.ae-nav a:hover,\n.ae-nav button:hover {\ncolor: var(--ae-ink);\n}\n\n.ae-nav [aria-current],\n.ae-nav .is-active {\ncolor: var(--ae-ink);\n}\n\n.ae-nav-ind {\nposition: absolute;\n bottom: 0;\n height: 2px;\n background: var(--ae-ink);\n transition:\n left var(--ae-soft) var(--ae-ease),\n width var(--ae-soft) var(--ae-ease);\n}\n\n@keyframes ae-enter {\nfrom {\n opacity: 0;\n transform: translateY(6px);\n }\n}\n" }, { "path": "recipes/nav.js", "type": "registry:file", "target": "~/aesthetic.nav.js", "content": "/* the nav indicator: position the sliding ink underline under the\n active item on activation, resize, and font load (metrics shift\n when Geist arrives). Exposes window.aePlaceInds for page scripts\n that swap views and need the indicator re-placed after a display\n change. Works for .ae-nav and .ae-tabs alike. */\n(() => {\n if (window.aePlaceInds) return;\n const placeInd = (nav) => {\n const active = nav.querySelector(\n '[aria-current], [aria-selected=\"true\"], .is-active',\n );\n const ind = nav.querySelector('.ae-nav-ind');\n if (!active || !ind || !nav.offsetWidth) return;\n ind.style.left = active.offsetLeft + 'px';\n ind.style.width = active.offsetWidth + 'px';\n };\n const placeAllInds = () =>\n document.querySelectorAll('.ae-nav, .ae-tabs').forEach(placeInd);\n\n document.querySelectorAll('.ae-nav, .ae-tabs').forEach((nav) => {\n nav.querySelectorAll('a, button').forEach((item) => {\n item.addEventListener('click', () => {\n nav\n .querySelectorAll('a, button')\n .forEach((b) => b.classList.remove('is-active'));\n item.classList.add('is-active');\n placeInd(nav);\n });\n });\n });\n addEventListener('resize', placeAllInds);\n if (document.fonts) document.fonts.ready.then(placeAllInds);\n placeAllInds();\n\n window.aePlaceInds = placeAllInds;\n})();\n" } ] }