kmcom-nuxt-layers 1.0.1
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/.claude/rules/nuxt-layers.md +23 -0
- package/.claude/rules/typescript.md +16 -0
- package/.claude/rules/vue-components.md +34 -0
- package/.claude/settings.local.json +81 -0
- package/.editorconfig +27 -0
- package/.github/workflows/npm-publish.yml +33 -0
- package/.oxlintrc.json +10 -0
- package/.prettierignore +87 -0
- package/CLAUDE.md +71 -0
- package/apps/playground/README.md +75 -0
- package/apps/playground/app/app.config.ts +10 -0
- package/apps/playground/app/app.vue +12 -0
- package/apps/playground/app/components/AmbientBackground.client.vue +795 -0
- package/apps/playground/app/components/ShaderDemoCanvas.client.vue +636 -0
- package/apps/playground/app/components/ShaderImageDemo.client.vue +211 -0
- package/apps/playground/app/pages/ambient.vue +387 -0
- package/apps/playground/app/pages/content.vue +200 -0
- package/apps/playground/app/pages/core.vue +560 -0
- package/apps/playground/app/pages/forms.vue +645 -0
- package/apps/playground/app/pages/index.vue +257 -0
- package/apps/playground/app/pages/layout.vue +591 -0
- package/apps/playground/app/pages/locomotive-scroll.vue +738 -0
- package/apps/playground/app/pages/motion.vue +848 -0
- package/apps/playground/app/pages/shader.vue +1701 -0
- package/apps/playground/app/pages/theme.vue +115 -0
- package/apps/playground/app/pages/ui.vue +656 -0
- package/apps/playground/content/blog/hello-world.md +127 -0
- package/apps/playground/content/blog/second-post.md +99 -0
- package/apps/playground/content/blog/third-post.md +33 -0
- package/apps/playground/content/gallery/autumn-collection.md +57 -0
- package/apps/playground/content/gallery/summer-collection.md +52 -0
- package/apps/playground/content/pages/index.md +132 -0
- package/apps/playground/content/portfolio/project-one.md +90 -0
- package/apps/playground/content/portfolio/project-two.md +96 -0
- package/apps/playground/content.config.ts +93 -0
- package/apps/playground/nuxt.config.ts +99 -0
- package/apps/playground/package.json +17 -0
- package/apps/playground/public/favicon.ico +0 -0
- package/apps/playground/public/robots.txt +2 -0
- package/apps/playground/tsconfig.json +25 -0
- package/eslint.config.mjs +223 -0
- package/eslint.configCOPY.mjs +216 -0
- package/eslintconfigCURRENT.mjs +244 -0
- package/eslintconfigOLD.mjs +178 -0
- package/files for claude/Scroller.vue +31 -0
- package/files for claude/TextMarquee.vue +255 -0
- package/files for claude/gsap.client.ts +18 -0
- package/files for claude/gsap.ts +10 -0
- package/files for claude/scroll.ts +28 -0
- package/layers/content/app/assets/css/main.css +1 -0
- package/layers/content/app/components/Blog/Article.vue +29 -0
- package/layers/content/app/components/Blog/Card.vue +40 -0
- package/layers/content/app/components/Blog/List.vue +35 -0
- package/layers/content/app/components/Gallery/AmbientImage.vue +52 -0
- package/layers/content/app/components/Gallery/Card.vue +39 -0
- package/layers/content/app/components/Gallery/Detail.vue +76 -0
- package/layers/content/app/components/Gallery/Grid.vue +48 -0
- package/layers/content/app/components/Gallery/ImageDetail.vue +92 -0
- package/layers/content/app/components/Gallery/Lightbox.vue +102 -0
- package/layers/content/app/components/NuxtContent/Detail.vue +53 -0
- package/layers/content/app/components/NuxtContent/List.vue +21 -0
- package/layers/content/app/components/NuxtContent/Renderer.vue +14 -0
- package/layers/content/app/components/NuxtContent/Surround.vue +15 -0
- package/layers/content/app/components/NuxtContent/Toc.vue +18 -0
- package/layers/content/app/components/Portfolio/Card.vue +39 -0
- package/layers/content/app/components/Portfolio/ColorPalette.vue +39 -0
- package/layers/content/app/components/Portfolio/Detail.vue +49 -0
- package/layers/content/app/components/Portfolio/List.vue +44 -0
- package/layers/content/app/components/Portfolio/Typography.vue +37 -0
- package/layers/content/app/components/content/Figure.vue +31 -0
- package/layers/content/app/composables/useBlogPost.ts +3 -0
- package/layers/content/app/composables/useBlogPosts.ts +23 -0
- package/layers/content/app/composables/useCollectionItem.ts +5 -0
- package/layers/content/app/composables/useCollectionSurround.ts +9 -0
- package/layers/content/app/composables/useContentPage.ts +3 -0
- package/layers/content/app/composables/useGalleryItem.ts +3 -0
- package/layers/content/app/composables/useGalleryItems.ts +19 -0
- package/layers/content/app/composables/usePortfolioItem.ts +3 -0
- package/layers/content/app/composables/usePortfolioItems.ts +23 -0
- package/layers/content/app/pages/blog/[slug].vue +10 -0
- package/layers/content/app/pages/blog/index.vue +15 -0
- package/layers/content/app/pages/gallery/[slug]/[imageId].vue +11 -0
- package/layers/content/app/pages/gallery/[slug]/index.vue +10 -0
- package/layers/content/app/pages/gallery/index.vue +15 -0
- package/layers/content/app/pages/portfolio/[slug].vue +10 -0
- package/layers/content/app/pages/portfolio/index.vue +15 -0
- package/layers/content/app/types/content.ts +84 -0
- package/layers/content/app.config.ts +12 -0
- package/layers/content/content.config.ts +93 -0
- package/layers/content/nuxt.config.ts +31 -0
- package/layers/content/package.json +31 -0
- package/layers/content/tsconfig.json +6 -0
- package/layers/core/app/assets/css/base.css +88 -0
- package/layers/core/app/assets/css/layout.css +36 -0
- package/layers/core/app/assets/css/main.css +7 -0
- package/layers/core/app/assets/css-backup.zip +0 -0
- package/layers/core/app/components/ErrorBoundary.vue +102 -0
- package/layers/core/app/components/LoadingScreen.vue +137 -0
- package/layers/core/app/composables/useBrowser.ts +161 -0
- package/layers/core/app/composables/useCache.ts +138 -0
- package/layers/core/app/composables/useDevice.ts +36 -0
- package/layers/core/app/composables/useEnv.ts +23 -0
- package/layers/core/app/composables/useErrorLog.ts +158 -0
- package/layers/core/app/composables/useFeatures.ts +269 -0
- package/layers/core/app/composables/useLoading.ts +109 -0
- package/layers/core/app/composables/useNetworkInfo.ts +83 -0
- package/layers/core/app/composables/usePWAInfo.ts +104 -0
- package/layers/core/app/composables/useRendering.ts +97 -0
- package/layers/core/app/composables/useScreen.ts +95 -0
- package/layers/core/app/composables/useScrollGuard.ts +266 -0
- package/layers/core/app/error.vue +103 -0
- package/layers/core/app/layouts/default.vue +4 -0
- package/layers/core/app/pages/[...slug].vue +168 -0
- package/layers/core/app/pages/diagnostics.vue +228 -0
- package/layers/core/app/plugins/error-handler.ts +47 -0
- package/layers/core/app/plugins/feature-detection.client.ts +32 -0
- package/layers/core/app/plugins/init.ts +188 -0
- package/layers/core/app/plugins/loading.client.ts +54 -0
- package/layers/core/app/plugins/scroll-guard.client.ts +53 -0
- package/layers/core/app/types/detection.ts +117 -0
- package/layers/core/app/types/index.ts +10 -0
- package/layers/core/app/types/loading.ts +47 -0
- package/layers/core/app/types/runtime-config.ts +31 -0
- package/layers/core/app/types/scroll-guard.ts +25 -0
- package/layers/core/app/utils/helpers.ts +246 -0
- package/layers/core/app/utils/index.ts +8 -0
- package/layers/core/app/utils/regex.ts +6 -0
- package/layers/core/app.config.ts +193 -0
- package/layers/core/nuxt.config.ts +84 -0
- package/layers/core/package.json +25 -0
- package/layers/core/tailwind.config.js +28 -0
- package/layers/core/tsconfig.json +6 -0
- package/layers/forms/app/components/Form/Contact.vue +78 -0
- package/layers/forms/app/components/Form/Field.vue +85 -0
- package/layers/forms/app/composables/useFormSchema.ts +35 -0
- package/layers/forms/app/config/fields.ts +104 -0
- package/layers/forms/app/types/fields.ts +60 -0
- package/layers/forms/app.config.ts +12 -0
- package/layers/forms/nuxt.config.ts +17 -0
- package/layers/forms/package.json +17 -0
- package/layers/forms/tsconfig.json +6 -0
- package/layers/layout/.nuxtrc +1 -0
- package/layers/layout/CLAUDE.MD +186 -0
- package/layers/layout/GRID_SYSTEM.md +993 -0
- package/layers/layout/README.md +73 -0
- package/layers/layout/app/assets/css/layout/grids.css +180 -0
- package/layers/layout/app/assets/css/main.css +1 -0
- package/layers/layout/app/components/Layout/Grid/Debug.vue +79 -0
- package/layers/layout/app/components/Layout/Grid/Item.vue +180 -0
- package/layers/layout/app/components/Layout/Page/Container.vue +100 -0
- package/layers/layout/app/components/Layout/Page/Header.vue +33 -0
- package/layers/layout/app/components/Layout/Section/Gallery.vue +68 -0
- package/layers/layout/app/components/Layout/Section/Hero.vue +71 -0
- package/layers/layout/app/components/Layout/Section/Split.vue +56 -0
- package/layers/layout/app/components/Layout/Section/index.vue +39 -0
- package/layers/layout/app/composables/GridPlacement.ts +31 -0
- package/layers/layout/app/composables/useGridConfig.ts +27 -0
- package/layers/layout/app/types/layouts.ts +37 -0
- package/layers/layout/app.config.ts +97 -0
- package/layers/layout/nuxt.config.ts +14 -0
- package/layers/layout/package.json +14 -0
- package/layers/layout/tailwind.config.js +28 -0
- package/layers/layout/tsconfig.json +6 -0
- package/layers/motion/README.md +107 -0
- package/layers/motion/TASKS.MD +16 -0
- package/layers/motion/app/assets/css/main.css +111 -0
- package/layers/motion/app/components/Motion/Marquee.vue +171 -0
- package/layers/motion/app/components/Motion/Parallax.vue +75 -0
- package/layers/motion/app/components/Motion/ScrollLink.vue +49 -0
- package/layers/motion/app/components/Motion/ScrollProgress.vue +127 -0
- package/layers/motion/app/components/Motion/ScrollStats.vue +102 -0
- package/layers/motion/app/components/Motion/Staggered.vue +73 -0
- package/layers/motion/app/components/Motion/TextReveal.vue +101 -0
- package/layers/motion/app/components/Motion/Transition.vue +89 -0
- package/layers/motion/app/components/Motion/VelocityEffect.vue +139 -0
- package/layers/motion/app/components/Motion/index.vue +16 -0
- package/layers/motion/app/composables/useGsap.ts +21 -0
- package/layers/motion/app/composables/useMotion.ts +137 -0
- package/layers/motion/app/composables/useSmoothScroll.ts +154 -0
- package/layers/motion/app/plugins/gsap.client.ts +15 -0
- package/layers/motion/app/plugins/locomotive-scroll.client.ts +49 -0
- package/layers/motion/app/utils/gsapAnimations.ts +122 -0
- package/layers/motion/app.config.ts +30 -0
- package/layers/motion/nuxt.config.ts +19 -0
- package/layers/motion/package.json +17 -0
- package/layers/motion/tsconfig.json +6 -0
- package/layers/shader/AGENTS.MD +195 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/.prettierignore +6 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/.prettierrc +18 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/LICENSE +21 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/README.md +100 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/index.html +13 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/jsconfig.json +30 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/package.json +18 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/pnpm-lock.yaml +633 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/public/vite.svg +1 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketch/webgpu_sketch.js +128 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketches_dropdown/index.css +87 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/components/sketches_dropdown/sketches_dropdown.js +169 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/index.css +25 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/main.js +93 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/router.js +43 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/sketches/flare-1.js +68 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/sketches/noise/dawn-1.js +56 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/bulge_distortion.js +35 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/swirl_distortion.js +35 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/distortion/wave_distortion.js +43 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/common.js +145 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/curl_noise_3d.js +53 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/curl_noise_4d.js +55 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/fbm.js +163 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/perlin_noise_3d.js +70 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/simplex_noise_3d.js +59 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/simplex_noise_4d.js +72 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/noise/turbulence.js +41 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/canvas_weave_pattern.js +26 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/grain_texture_pattern.js +10 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/led_pattern.js +45 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/pixellation_pattern.js +15 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/speckled_noise_pattern.js +34 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/patterns/vignette_pattern.js +21 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/bulge_distortion_effect.js +27 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/chromatic_aberration_effect.js +45 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/crt_scanline_effect.js +45 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/dither_effect.js +126 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/grain_texture_effect.js +21 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/halftone_effect.js +44 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/led_effect.js +31 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/pixellation_effect.js +29 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/swirl_distortion_effect.js +25 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/vignette_effect.js +22 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/post_processing/wave_distortion_effect.js +27 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/color/cosine_palette.js +15 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/color/tonemapping.js +151 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/bloom.js +13 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/bloom_edge_pattern.js +20 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/domain_index.js +11 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/median3.js +22 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/repeating_pattern.js +13 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/function/screen_aspect_uv.js +14 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/lighting.js +60 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/math/complex.js +86 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/math/coordinates.js +119 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/sdf/operations.js +24 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/tsl/utils/sdf/shapes.js +182 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/src/utils/math.js +33 -0
- package/layers/shader/additional-modular-tsl-shaders-for-claude/vite.config.js +23 -0
- package/layers/shader/app/assets/css/main.css +41 -0
- package/layers/shader/app/components/Effect/Bloom.vue +8 -0
- package/layers/shader/app/components/Effect/ChromaticAberration.vue +8 -0
- package/layers/shader/app/components/Effect/PostProcessing.vue +20 -0
- package/layers/shader/app/components/Material/AmbientAurora.vue +172 -0
- package/layers/shader/app/components/Material/AmbientFlow.vue +175 -0
- package/layers/shader/app/components/Material/AmbientGradientMesh.vue +173 -0
- package/layers/shader/app/components/Material/AmbientNebula.vue +181 -0
- package/layers/shader/app/components/Material/AmbientOcean.vue +161 -0
- package/layers/shader/app/components/Material/Fresnel.vue +89 -0
- package/layers/shader/app/components/Material/Gradient.vue +185 -0
- package/layers/shader/app/components/Material/Image.vue +232 -0
- package/layers/shader/app/components/Material/Node.vue +79 -0
- package/layers/shader/app/components/Material/Noise.vue +141 -0
- package/layers/shader/app/components/Mesh/Plane.vue +27 -0
- package/layers/shader/app/components/Shader/Background.vue +159 -0
- package/layers/shader/app/components/Shader/Canvas.vue +97 -0
- package/layers/shader/app/components/Shader/Debug.vue +66 -0
- package/layers/shader/app/components/WebGPUCanvas.client.vue +245 -0
- package/layers/shader/app/composables/useAmbientMaterials.ts +452 -0
- package/layers/shader/app/composables/useMousePosition.ts +94 -0
- package/layers/shader/app/composables/useRendererCapabilities.ts +111 -0
- package/layers/shader/app/composables/useShader.ts +148 -0
- package/layers/shader/app/composables/useShaderTime.ts +146 -0
- package/layers/shader/app/composables/useTSLNodes.ts +112 -0
- package/layers/shader/app/composables/useUniforms.ts +188 -0
- package/layers/shader/app/plugins/shader.client.ts +30 -0
- package/layers/shader/app/shaders/common/blend.ts +255 -0
- package/layers/shader/app/shaders/common/effects.ts +299 -0
- package/layers/shader/app/shaders/common/grain.ts +453 -0
- package/layers/shader/app/shaders/common/index.ts +22 -0
- package/layers/shader/app/shaders/common/lighting.ts +146 -0
- package/layers/shader/app/shaders/common/math.ts +250 -0
- package/layers/shader/app/shaders/common/noise.ts +823 -0
- package/layers/shader/app/shaders/common/noiseHelpers.ts +114 -0
- package/layers/shader/app/shaders/common/palette.ts +319 -0
- package/layers/shader/app/shaders/common/patterns.ts +216 -0
- package/layers/shader/app/shaders/common/sdf.ts +224 -0
- package/layers/shader/app/shaders/common/shapes.ts +366 -0
- package/layers/shader/app/shaders/common/tonemapping.ts +172 -0
- package/layers/shader/app/shaders/common/uv.ts +396 -0
- package/layers/shader/app/shaders/createMaterial.ts +314 -0
- package/layers/shader/app/shaders/index.ts +282 -0
- package/layers/shader/app/shaders/layers/aurora.ts +146 -0
- package/layers/shader/app/shaders/layers/index.ts +19 -0
- package/layers/shader/app/shaders/layers/meshGradient.ts +152 -0
- package/layers/shader/app/shaders/layers/paperShading.ts +148 -0
- package/layers/shader/app/shaders/layers/shaderGradient.ts +152 -0
- package/layers/shader/app/shaders/layers/stripe.ts +137 -0
- package/layers/shader/app/shaders/types.ts +12 -0
- package/layers/shader/app/types/index.ts +4 -0
- package/layers/shader/app/types/materials.ts +45 -0
- package/layers/shader/app/types/renderer.ts +50 -0
- package/layers/shader/app/types/tsl.ts +39 -0
- package/layers/shader/app/types/uniforms.ts +21 -0
- package/layers/shader/app/utils/tsl/animation.ts +251 -0
- package/layers/shader/app/utils/tsl/color.ts +189 -0
- package/layers/shader/app/utils/tsl/index.ts +84 -0
- package/layers/shader/app/utils/tsl/math.ts +111 -0
- package/layers/shader/app/utils/tsl/noise.ts +195 -0
- package/layers/shader/app/utils/tsl/patterns.ts +183 -0
- package/layers/shader/app/utils/tsl/uv.ts +145 -0
- package/layers/shader/app.config.ts +18 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/blend.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/noise.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/shapes.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/vertexFresnel.tsl +9 -0
- package/layers/shader/modular-tsl-shaders-for-claude/common/vertexPlane.tsl +6 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/background.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/gradient.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/gradientLegend.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/effects/simpleGradient.tsl +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/aurora.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/fragmentsTech.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/fresnel.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/linearGradient.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/meshGradient.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/noise.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/paperShading.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/radial.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/shaderGradient.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/layers/stripe.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/materials/createMaterial.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/utils/glslUtils.ts +1 -0
- package/layers/shader/modular-tsl-shaders-for-claude/utils/palette.ts +1 -0
- package/layers/shader/nuxt.config.ts +48 -0
- package/layers/shader/package.json +17 -0
- package/layers/shader/tsconfig.json +6 -0
- package/layers/theme/app/assets/css/theme.css +47 -0
- package/layers/theme/app/components/ThemePicker/AccentButton.vue +51 -0
- package/layers/theme/app/components/ThemePicker/Colors.vue +22 -0
- package/layers/theme/app/components/ThemePicker/Menu.vue +108 -0
- package/layers/theme/app/components/ThemePicker/MenuButton.vue +9 -0
- package/layers/theme/app/composables/useThemePreferences.ts +158 -0
- package/layers/theme/app/plugins/theme.client.ts +5 -0
- package/layers/theme/app/types/theme.ts +34 -0
- package/layers/theme/app.config.ts +14 -0
- package/layers/theme/nuxt.config.ts +46 -0
- package/layers/theme/package.json +14 -0
- package/layers/theme/server/plugins/theme-fouc.ts +51 -0
- package/layers/theme/tsconfig.json +7 -0
- package/layers/ui/CLAUDE.MD +325 -0
- package/layers/ui/app/assets/css/main.css +4 -0
- package/layers/ui/app/components/Links/Group.vue +38 -0
- package/layers/ui/app/components/Links/Named.vue +32 -0
- package/layers/ui/app/components/Media/Picture.vue +41 -0
- package/layers/ui/app/components/Site/Title.vue +15 -0
- package/layers/ui/app/components/Typography/CodeBlock.vue +37 -0
- package/layers/ui/app/components/Typography/Headline.vue +73 -0
- package/layers/ui/app/components/Typography/QuoteBlock.vue +13 -0
- package/layers/ui/app/components/Typography/TextStroke.vue +109 -0
- package/layers/ui/app/components/Typography/index.vue +49 -0
- package/layers/ui/app/composables/color.ts +36 -0
- package/layers/ui/app/composables/picture.ts +145 -0
- package/layers/ui/app/composables/typography.ts +77 -0
- package/layers/ui/app/layouts/default.vue +4 -0
- package/layers/ui/app/pages/index.vue +236 -0
- package/layers/ui/app/types/breakpoints.ts +179 -0
- package/layers/ui/app/types/colors.ts +29 -0
- package/layers/ui/app/types/media.ts +185 -0
- package/layers/ui/app/types/typography.ts +108 -0
- package/layers/ui/app/utils/regex.ts +6 -0
- package/layers/ui/app.config.ts +12 -0
- package/layers/ui/nuxt.config.ts +38 -0
- package/layers/ui/package.json +14 -0
- package/layers/ui/tsconfig.json +6 -0
- package/package.json +128 -0
- package/playgroundOLD/app.config.ts +5 -0
- package/playgroundOLD/nuxt.config.ts +12 -0
- package/pnpm-workspace.yaml +6 -0
- package/prettier.config.cjs +19 -0
- package/stylelint.config.mjs +111 -0
- package/turbo.json +16 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// composables/useLoading.ts
|
|
2
|
+
|
|
3
|
+
interface LoadingState {
|
|
4
|
+
isLoading: Ref<boolean>
|
|
5
|
+
progress: Ref<number>
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Shared state across all calls (singleton pattern)
|
|
9
|
+
const state: LoadingState = {
|
|
10
|
+
isLoading: ref(true), // Start as true for initial app load
|
|
11
|
+
progress: ref(0),
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let progressInterval: ReturnType<typeof setInterval> | null = null
|
|
15
|
+
let progressTimeout: ReturnType<typeof setTimeout> | null = null
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Loading state composable for app initialization and async operations
|
|
19
|
+
*
|
|
20
|
+
* Features:
|
|
21
|
+
* - Simulated progress (0-90% auto, then waits)
|
|
22
|
+
* - Shared state across all component instances
|
|
23
|
+
* - Can be disabled via app.config
|
|
24
|
+
* - Works without UI component (headless)
|
|
25
|
+
*
|
|
26
|
+
* @param id - Optional scoped loading ID (for future multi-loading support)
|
|
27
|
+
* @returns Loading state and control methods
|
|
28
|
+
*/
|
|
29
|
+
export function useLoading() {
|
|
30
|
+
/**
|
|
31
|
+
* Start loading with simulated progress
|
|
32
|
+
* Progress will automatically increment from 0 to ~90
|
|
33
|
+
*/
|
|
34
|
+
function startLoading(): void {
|
|
35
|
+
state.isLoading.value = true
|
|
36
|
+
state.progress.value = 0
|
|
37
|
+
|
|
38
|
+
// Clear any existing intervals
|
|
39
|
+
if (progressInterval) clearInterval(progressInterval)
|
|
40
|
+
if (progressTimeout) clearTimeout(progressTimeout)
|
|
41
|
+
|
|
42
|
+
// Simulate progress: increment randomly to 90%, then wait
|
|
43
|
+
progressInterval = setInterval(() => {
|
|
44
|
+
if (state.progress.value < 90) {
|
|
45
|
+
// Random increment between 3-8%
|
|
46
|
+
const increment = Math.random() * 5 + 3
|
|
47
|
+
state.progress.value = Math.min(state.progress.value + increment, 90)
|
|
48
|
+
} else {
|
|
49
|
+
// Stop at 90, wait for manual completion
|
|
50
|
+
if (progressInterval) {
|
|
51
|
+
clearInterval(progressInterval)
|
|
52
|
+
progressInterval = null
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}, 150) // Update every 150ms
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Stop loading and jump to 100%
|
|
60
|
+
*/
|
|
61
|
+
function stopLoading(): void {
|
|
62
|
+
// Clear any running intervals
|
|
63
|
+
if (progressInterval) {
|
|
64
|
+
clearInterval(progressInterval)
|
|
65
|
+
progressInterval = null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Jump to 100%
|
|
69
|
+
state.progress.value = 100
|
|
70
|
+
|
|
71
|
+
// Mark as not loading after a brief delay (allows 100% to be visible)
|
|
72
|
+
progressTimeout = setTimeout(() => {
|
|
73
|
+
state.isLoading.value = false
|
|
74
|
+
}, 100)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Manually update progress (0-100)
|
|
79
|
+
* @param value - Progress percentage (0-100)
|
|
80
|
+
*/
|
|
81
|
+
function updateProgress(value: number): void {
|
|
82
|
+
state.progress.value = Math.min(Math.max(value, 0), 100)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Execute async function with loading state
|
|
87
|
+
* @param fn - Async function to execute
|
|
88
|
+
*/
|
|
89
|
+
async function withLoading(fn: () => Promise<void>): Promise<void> {
|
|
90
|
+
startLoading()
|
|
91
|
+
try {
|
|
92
|
+
await fn()
|
|
93
|
+
} finally {
|
|
94
|
+
stopLoading()
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
// State (reactive refs)
|
|
100
|
+
isLoading: readonly(state.isLoading),
|
|
101
|
+
progress: readonly(state.progress),
|
|
102
|
+
|
|
103
|
+
// Actions
|
|
104
|
+
startLoading,
|
|
105
|
+
stopLoading,
|
|
106
|
+
updateProgress,
|
|
107
|
+
withLoading,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// composables/useNetworkInfo.ts
|
|
2
|
+
import { useNetwork } from '@vueuse/core'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Network information composable
|
|
6
|
+
*
|
|
7
|
+
* Wraps VueUse's useNetwork with additional helper computed values
|
|
8
|
+
* for adaptive loading patterns.
|
|
9
|
+
*
|
|
10
|
+
* @returns Network state and connection information
|
|
11
|
+
*/
|
|
12
|
+
export function useNetworkInfo() {
|
|
13
|
+
const { isOnline, offlineAt, downlink, downlinkMax, effectiveType, saveData, type } = useNetwork()
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Connection is slow (2G or slower)
|
|
17
|
+
*/
|
|
18
|
+
const isSlow = computed(() => {
|
|
19
|
+
return (
|
|
20
|
+
effectiveType.value === 'slow-2g' ||
|
|
21
|
+
effectiveType.value === '2g' ||
|
|
22
|
+
(downlink.value !== undefined && downlink.value < 1.5)
|
|
23
|
+
)
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Connection is fast (4G or better)
|
|
28
|
+
*/
|
|
29
|
+
const isFast = computed(() => {
|
|
30
|
+
return effectiveType.value === '4g' || (downlink.value !== undefined && downlink.value > 5)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Connection type is cellular (mobile data)
|
|
35
|
+
*/
|
|
36
|
+
const isCellular = computed(() => {
|
|
37
|
+
return type.value === 'cellular'
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Connection type is WiFi
|
|
42
|
+
*/
|
|
43
|
+
const isWiFi = computed(() => {
|
|
44
|
+
return type.value === 'wifi'
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Should limit bandwidth usage
|
|
49
|
+
* (slow connection, data saver mode, or cellular)
|
|
50
|
+
*/
|
|
51
|
+
const shouldLimitBandwidth = computed(() => {
|
|
52
|
+
return isSlow.value || saveData.value || isCellular.value
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Connection quality description
|
|
57
|
+
*/
|
|
58
|
+
const connectionQuality = computed<'excellent' | 'good' | 'poor' | 'offline'>(() => {
|
|
59
|
+
if (!isOnline.value) return 'offline'
|
|
60
|
+
if (isFast.value) return 'excellent'
|
|
61
|
+
if (isSlow.value) return 'poor'
|
|
62
|
+
return 'good'
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
// Raw network state (from VueUse)
|
|
67
|
+
isOnline,
|
|
68
|
+
offlineAt,
|
|
69
|
+
downlink,
|
|
70
|
+
downlinkMax,
|
|
71
|
+
effectiveType,
|
|
72
|
+
saveData,
|
|
73
|
+
type,
|
|
74
|
+
|
|
75
|
+
// Computed helpers
|
|
76
|
+
isSlow,
|
|
77
|
+
isFast,
|
|
78
|
+
isCellular,
|
|
79
|
+
isWiFi,
|
|
80
|
+
shouldLimitBandwidth,
|
|
81
|
+
connectionQuality,
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PWA composable for managing Progressive Web App functionality
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Install prompt handling
|
|
6
|
+
* - Installation state detection
|
|
7
|
+
*
|
|
8
|
+
* Note: Full PWA features (service worker) are only available in production.
|
|
9
|
+
* In development, this composable provides install prompt handling only.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const {
|
|
14
|
+
* isInstalled, // Is PWA installed?
|
|
15
|
+
* canInstall, // Can show install prompt?
|
|
16
|
+
* install, // Trigger install prompt
|
|
17
|
+
* } = usePWAInfo()
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export function usePWAInfo() {
|
|
21
|
+
// Install prompt event
|
|
22
|
+
const deferredPrompt = ref<BeforeInstallPromptEvent | null>(null)
|
|
23
|
+
|
|
24
|
+
// Track if PWA is installed
|
|
25
|
+
const isInstalled = ref(false)
|
|
26
|
+
|
|
27
|
+
// Service worker state - only meaningful in production with PWA module
|
|
28
|
+
const needRefresh = ref(false)
|
|
29
|
+
|
|
30
|
+
// Can show install prompt
|
|
31
|
+
const canInstall = computed(() => {
|
|
32
|
+
return !isInstalled.value && deferredPrompt.value !== null
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Update service worker - no-op, handled by PWA module in production
|
|
36
|
+
const updateServiceWorker = async () => {
|
|
37
|
+
// Service worker updates are handled automatically by @vite-pwa/nuxt in production
|
|
38
|
+
// This is a no-op placeholder for API consistency
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Initialize PWA detection (client-side only)
|
|
42
|
+
onMounted(() => {
|
|
43
|
+
if (!import.meta.client) return
|
|
44
|
+
|
|
45
|
+
// Listen for beforeinstallprompt event
|
|
46
|
+
window.addEventListener('beforeinstallprompt', (e) => {
|
|
47
|
+
e.preventDefault()
|
|
48
|
+
deferredPrompt.value = e as BeforeInstallPromptEvent
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Listen for app installed event
|
|
52
|
+
window.addEventListener('appinstalled', () => {
|
|
53
|
+
isInstalled.value = true
|
|
54
|
+
deferredPrompt.value = null
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// Check if already installed (standalone mode)
|
|
58
|
+
if (window.matchMedia('(display-mode: standalone)').matches) {
|
|
59
|
+
isInstalled.value = true
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Check for iOS standalone mode
|
|
63
|
+
if ((window.navigator as Navigator & { standalone?: boolean }).standalone) {
|
|
64
|
+
isInstalled.value = true
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Trigger the install prompt
|
|
70
|
+
*/
|
|
71
|
+
const install = async () => {
|
|
72
|
+
if (!deferredPrompt.value) {
|
|
73
|
+
return false
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
deferredPrompt.value.prompt()
|
|
77
|
+
const { outcome } = await deferredPrompt.value.userChoice
|
|
78
|
+
deferredPrompt.value = null
|
|
79
|
+
|
|
80
|
+
return outcome === 'accepted'
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
// Installation state
|
|
85
|
+
isInstalled: readonly(isInstalled),
|
|
86
|
+
canInstall: readonly(canInstall),
|
|
87
|
+
install,
|
|
88
|
+
|
|
89
|
+
// Service worker updates (production only via PWA module)
|
|
90
|
+
needRefresh: readonly(needRefresh),
|
|
91
|
+
updateServiceWorker,
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Type definition for beforeinstallprompt event
|
|
97
|
+
*/
|
|
98
|
+
interface BeforeInstallPromptEvent extends Event {
|
|
99
|
+
prompt(): Promise<void>
|
|
100
|
+
userChoice: Promise<{
|
|
101
|
+
outcome: 'accepted' | 'dismissed'
|
|
102
|
+
platform: string
|
|
103
|
+
}>
|
|
104
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// composables/useRendering.ts
|
|
2
|
+
|
|
3
|
+
type RenderMode = 'ssr' | 'ssg' | 'csr' | 'hybrid'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Rendering mode detection composable
|
|
7
|
+
*
|
|
8
|
+
* Detects the current rendering mode and provides helpers
|
|
9
|
+
* for server/client-specific logic and hydration state.
|
|
10
|
+
*
|
|
11
|
+
* Note: This DETECTS the mode, it does NOT choose it.
|
|
12
|
+
* The mode is chosen by Nuxt via routeRules in nuxt.config.ts.
|
|
13
|
+
*
|
|
14
|
+
* @returns Rendering state and mode information
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const { mode, isClient, isHydrated } = useRendering()
|
|
19
|
+
*
|
|
20
|
+
* // Wait for hydration before interactive elements
|
|
21
|
+
* <button :disabled="!isHydrated">Click me</button>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function useRendering() {
|
|
25
|
+
const nuxtApp = useNuxtApp()
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Is code running on the server (Node.js)?
|
|
29
|
+
*/
|
|
30
|
+
const isServer = computed(() => import.meta.server)
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Is code running in the browser?
|
|
34
|
+
*/
|
|
35
|
+
const isClient = computed(() => import.meta.client)
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Is Vue currently taking control of the server-rendered HTML?
|
|
39
|
+
*/
|
|
40
|
+
const isHydrating = computed(() => nuxtApp.isHydrating)
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Has hydration completed? Is the page fully interactive?
|
|
44
|
+
*/
|
|
45
|
+
const isHydrated = computed(() => {
|
|
46
|
+
// On server, never hydrated
|
|
47
|
+
if (import.meta.server) return false
|
|
48
|
+
|
|
49
|
+
// On client, check if hydration is complete
|
|
50
|
+
return !nuxtApp.isHydrating
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Detect the current rendering mode
|
|
55
|
+
*
|
|
56
|
+
* - SSR: Server-Side Rendering (HTML generated per request)
|
|
57
|
+
* - SSG: Static Site Generation (HTML pre-built at build time)
|
|
58
|
+
* - CSR: Client-Side Rendering (SPA, no server HTML)
|
|
59
|
+
* - Hybrid: Mix of above per route
|
|
60
|
+
*/
|
|
61
|
+
const mode = computed<RenderMode>(() => {
|
|
62
|
+
// Check if we have SSR/SSG by looking at payload
|
|
63
|
+
const payload = nuxtApp.payload
|
|
64
|
+
|
|
65
|
+
// If running on server, it's SSR or SSG
|
|
66
|
+
if (import.meta.server) {
|
|
67
|
+
// Check if prerendering (SSG)
|
|
68
|
+
if (nuxtApp.ssrContext?.event?.context?.prerender) {
|
|
69
|
+
return 'ssg'
|
|
70
|
+
}
|
|
71
|
+
return 'ssr'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// On client, check if we have server-rendered content
|
|
75
|
+
if (payload.serverRendered) {
|
|
76
|
+
// Could be SSR or SSG - check if we have build-time data
|
|
77
|
+
// SSG typically has static payload, SSR has fresh data
|
|
78
|
+
return payload.prerendered ? 'ssg' : 'ssr'
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// No server rendering = CSR
|
|
82
|
+
return 'csr'
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
// Mode detection
|
|
87
|
+
mode,
|
|
88
|
+
|
|
89
|
+
// Environment flags
|
|
90
|
+
isServer,
|
|
91
|
+
isClient,
|
|
92
|
+
|
|
93
|
+
// Hydration state
|
|
94
|
+
isHydrating,
|
|
95
|
+
isHydrated,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// composables/useScreen.ts
|
|
2
|
+
import { breakpointsTailwind, useBreakpoints, useScreenOrientation } from '@vueuse/core'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Screen size and orientation composable
|
|
6
|
+
*
|
|
7
|
+
* Wraps VueUse's useBreakpoints (Tailwind) and useScreenOrientation
|
|
8
|
+
* with additional helper computed values.
|
|
9
|
+
*
|
|
10
|
+
* Tailwind breakpoints:
|
|
11
|
+
* - sm: 640px
|
|
12
|
+
* - md: 768px
|
|
13
|
+
* - lg: 1024px
|
|
14
|
+
* - xl: 1280px
|
|
15
|
+
* - 2xl: 1536px
|
|
16
|
+
*
|
|
17
|
+
* @returns Screen state and breakpoint information
|
|
18
|
+
*/
|
|
19
|
+
export function useScreen() {
|
|
20
|
+
const breakpoints = useBreakpoints(breakpointsTailwind)
|
|
21
|
+
const { orientation, angle, isSupported } = useScreenOrientation()
|
|
22
|
+
|
|
23
|
+
// Breakpoint helpers
|
|
24
|
+
const isMobile = breakpoints.smaller('md') // < 768px
|
|
25
|
+
const isTablet = breakpoints.between('md', 'lg') // 768px - 1023px
|
|
26
|
+
const isDesktop = breakpoints.greaterOrEqual('lg') // >= 1024px
|
|
27
|
+
const isLargeDesktop = breakpoints.greaterOrEqual('xl') // >= 1280px
|
|
28
|
+
const isExtraLargeDesktop = breakpoints.greaterOrEqual('2xl') // >= 1536px
|
|
29
|
+
|
|
30
|
+
// Current breakpoint name
|
|
31
|
+
const breakpoint = computed<'mobile' | 'tablet' | 'desktop' | 'xl' | '2xl'>(() => {
|
|
32
|
+
if (isExtraLargeDesktop.value) return '2xl'
|
|
33
|
+
if (isLargeDesktop.value) return 'xl'
|
|
34
|
+
if (isDesktop.value) return 'desktop'
|
|
35
|
+
if (isTablet.value) return 'tablet'
|
|
36
|
+
return 'mobile'
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
// Orientation helpers
|
|
40
|
+
const isPortrait = computed(() => orientation.value === 'portrait-primary')
|
|
41
|
+
const isLandscape = computed(() => orientation.value === 'landscape-primary')
|
|
42
|
+
|
|
43
|
+
// Device pixel ratio (retina detection)
|
|
44
|
+
const pixelRatio = computed(() => {
|
|
45
|
+
if (import.meta.client) {
|
|
46
|
+
return window.devicePixelRatio || 1
|
|
47
|
+
}
|
|
48
|
+
return 1
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const isRetina = computed(() => pixelRatio.value >= 2)
|
|
52
|
+
|
|
53
|
+
// Screen dimensions (client-only)
|
|
54
|
+
const width = computed(() => {
|
|
55
|
+
if (import.meta.client) {
|
|
56
|
+
return window.innerWidth
|
|
57
|
+
}
|
|
58
|
+
return 0
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const height = computed(() => {
|
|
62
|
+
if (import.meta.client) {
|
|
63
|
+
return window.innerHeight
|
|
64
|
+
}
|
|
65
|
+
return 0
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
// Breakpoint state
|
|
70
|
+
breakpoint,
|
|
71
|
+
isMobile,
|
|
72
|
+
isTablet,
|
|
73
|
+
isDesktop,
|
|
74
|
+
isLargeDesktop,
|
|
75
|
+
isExtraLargeDesktop,
|
|
76
|
+
|
|
77
|
+
// Orientation state
|
|
78
|
+
orientation,
|
|
79
|
+
angle,
|
|
80
|
+
isPortrait,
|
|
81
|
+
isLandscape,
|
|
82
|
+
isOrientationSupported: isSupported,
|
|
83
|
+
|
|
84
|
+
// Display quality
|
|
85
|
+
pixelRatio,
|
|
86
|
+
isRetina,
|
|
87
|
+
|
|
88
|
+
// Dimensions
|
|
89
|
+
width,
|
|
90
|
+
height,
|
|
91
|
+
|
|
92
|
+
// Raw breakpoints instance (for advanced usage)
|
|
93
|
+
breakpoints,
|
|
94
|
+
}
|
|
95
|
+
}
|