diff --git a/components/Btn.vue b/components/Btn.vue
new file mode 100644
index 0000000..0ce38ca
--- /dev/null
+++ b/components/Btn.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/Lenis.vue b/components/Lenis.vue
new file mode 100644
index 0000000..66c2250
--- /dev/null
+++ b/components/Lenis.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
diff --git a/components/svg/BtnOutline.vue b/components/svg/BtnOutline.vue
new file mode 100644
index 0000000..7fcfa3a
--- /dev/null
+++ b/components/svg/BtnOutline.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
diff --git a/composables/useDetectOS.js b/composables/useDetectOS.js
new file mode 100644
index 0000000..f2e64f6
--- /dev/null
+++ b/composables/useDetectOS.js
@@ -0,0 +1,42 @@
+import { ref } from 'vue'
+
+export default () => {
+ const os = ref('Unknown')
+ const isMobile = ref(false)
+ const isAndroid = ref(false)
+ const isIOS = ref(false)
+ const isMacOS = ref(false)
+ const isWindows = ref(false)
+ const isLinux = ref(false)
+
+ if (typeof navigator !== 'undefined') {
+ const userAgent = navigator.userAgent.toLowerCase()
+ const platform = navigator.platform.toLowerCase()
+
+ const detectedAndroid = /android/.test(userAgent)
+ const detectedIOS = /iphone|ipad|ipod/.test(userAgent)
+ const detectedMacOS = /mac/.test(platform) && !detectedIOS
+ const detectedWindows = /win/.test(platform)
+ const detectedLinux = /linux/.test(platform) && !detectedAndroid
+
+ os.value = detectedAndroid
+ ? 'Android'
+ : detectedIOS
+ ? 'iOS'
+ : detectedMacOS
+ ? 'macOS'
+ : detectedWindows
+ ? 'Windows'
+ : detectedLinux
+ ? 'Linux'
+ : 'Unknown'
+ isMobile.value = detectedAndroid || detectedIOS
+ isAndroid.value = detectedAndroid
+ isIOS.value = detectedIOS
+ isMacOS.value = detectedMacOS
+ isWindows.value = detectedWindows
+ isLinux.value = detectedLinux
+ }
+
+ return { os, isMobile, isAndroid, isIOS, isMacOS, isWindows, isLinux }
+}
diff --git a/composables/useLenis.js b/composables/useLenis.js
new file mode 100644
index 0000000..f5ef24c
--- /dev/null
+++ b/composables/useLenis.js
@@ -0,0 +1,14 @@
+import { inject, onBeforeUnmount } from 'vue'
+
+export default (callback = () => {}, instanceId) => {
+ const instanceKey = `lenis${instanceId ? `-${instanceId}` : ''}`
+ const lenis = inject(instanceKey)
+
+ if (lenis.value) {
+ lenis.value.on('scroll', callback)
+ }
+
+ onBeforeUnmount(() => lenis.value?.off('scroll', callback))
+
+ return lenis
+}
diff --git a/composables/useRelativeSize.js b/composables/useRelativeSize.js
new file mode 100644
index 0000000..89f0172
--- /dev/null
+++ b/composables/useRelativeSize.js
@@ -0,0 +1,29 @@
+import { useWindowSize } from '@vueuse/core'
+import { viewports } from '@/libs/theme'
+
+const { width: wWidth, height: wHeight } = useWindowSize()
+
+export default () => {
+ // Desktop
+ const dvw = (pixels) => {
+ return (pixels / viewports.desktop.width) * wWidth.value
+ }
+ const dvh = (pixels) => {
+ return (pixels / viewports.desktop.height) * wHeight.value
+ }
+
+ // Mobile
+ const mvw = (pixels) => {
+ return (pixels / viewports.mobile.width) * wWidth.value
+ }
+ const mvh = (pixels) => {
+ return (pixels / viewports.mobile.height) * wHeight.value
+ }
+
+ return {
+ dvw,
+ dvh,
+ mvw,
+ mvh,
+ }
+}
diff --git a/composables/useScrollProgress.js b/composables/useScrollProgress.js
new file mode 100644
index 0000000..670498a
--- /dev/null
+++ b/composables/useScrollProgress.js
@@ -0,0 +1,46 @@
+import {
+ useElementBounding,
+ useIntersectionObserver,
+ useWindowSize,
+} from '@vueuse/core'
+import { ref } from 'vue'
+import { mapRange, clamp } from '@/libs/math'
+import useLenis from '@/composables/useLenis'
+
+const { height: wHeight } = useWindowSize()
+
+export const useScrollProgress = (el, callback, entry = 0.5, exit = 0.5) => {
+ const isActive = ref(true)
+ const smoothProgress = ref(0)
+
+ const { height, top } = useElementBounding(el)
+
+ const isIntersected = ref(false)
+ const { stop } = useIntersectionObserver(el, ([{ isIntersecting }]) => {
+ isIntersected.value = isIntersecting
+ })
+
+ useLenis(({ scroll }) => {
+ if (!isActive.value) return
+ if (!height.value || !wHeight.value) return
+ if (!isIntersected.value) return
+
+ const pageTop = scroll + top.value
+
+ const start = pageTop - wHeight.value * entry
+ const end = pageTop + height.value - wHeight.value * exit
+
+ let rawProgress = mapRange(start, end, scroll, 0, 1)
+ rawProgress = clamp(0, rawProgress, 1)
+
+ smoothProgress.value += (rawProgress - smoothProgress.value) * 0.1
+ callback?.(smoothProgress.value)
+ })
+
+ const destroy = () => {
+ isActive.value = false
+ stop?.()
+ }
+
+ return { destroy }
+}
diff --git a/composables/useSmoothMouse.js b/composables/useSmoothMouse.js
new file mode 100644
index 0000000..6a6606e
--- /dev/null
+++ b/composables/useSmoothMouse.js
@@ -0,0 +1,89 @@
+import gsap from 'gsap'
+import { ref, onMounted, onBeforeUnmount } from 'vue'
+import { useWindowSize, useEventListener } from '@vueuse/core'
+
+/**
+ * Shared global raw mouse state (only set up once)
+ */
+const rawMouse = {
+ x: ref(0),
+ y: ref(0),
+ initialized: false,
+ cleanup: null,
+}
+
+const useGlobalMouseListener = () => {
+ if (!rawMouse.initialized && !import.meta.env.SSR) {
+ rawMouse.initialized = true
+ rawMouse.cleanup = useEventListener(window, 'mousemove', (e) => {
+ rawMouse.x.value = e.clientX
+ rawMouse.y.value = e.clientY
+ })
+ }
+}
+
+/**
+ * Composable for smoothed mouse position with customizable smoothing and normalization.
+ */
+export default (options) => {
+ const smoothFactor = options?.smoothFactor ?? 0.1
+ const normalize = options?.normalize ?? false
+ const callback = options?.onUpdate
+
+ const { width: wWidth, height: wHeight } = useWindowSize()
+
+ const sx = ref(0)
+ const sy = ref(0)
+
+ useGlobalMouseListener()
+
+ const getTargetX = () =>
+ normalize ? rawMouse.x.value / wWidth.value : rawMouse.x.value
+ const getTargetY = () =>
+ normalize ? rawMouse.y.value / wHeight.value : rawMouse.y.value
+
+ let tween
+ onMounted(() => {
+ if (tween) tween.kill
+
+ // Start smoothing tween
+ tween = gsap.to(
+ { x: sx.value, y: sy.value },
+ {
+ duration: 1,
+ ease: 'linear',
+ repeat: -1,
+ onUpdate: () => {
+ const newX = gsap.utils.interpolate(
+ sx.value,
+ getTargetX(),
+ smoothFactor,
+ )
+ const newY = gsap.utils.interpolate(
+ sy.value,
+ getTargetY(),
+ smoothFactor,
+ )
+
+ sx.value = newX
+ sy.value = newY
+
+ callback?.({ sx: sx.value, sy: sy.value })
+ },
+ },
+ )
+ })
+
+ onBeforeUnmount(() => {
+ tween?.kill()
+ rawMouse.cleanup()
+ rawMouse.initialized = false
+ })
+
+ return {
+ sx,
+ sy,
+ rawX: rawMouse.x,
+ rawY: rawMouse.y,
+ }
+}
diff --git a/libs/math.js b/libs/math.js
new file mode 100644
index 0000000..9f2dddd
--- /dev/null
+++ b/libs/math.js
@@ -0,0 +1,22 @@
+export function clamp(min, input, max) {
+ return Math.max(min, Math.min(input, max))
+}
+
+export function mapRange(in_min, in_max, input, out_min, out_max) {
+ return (
+ ((input - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
+ )
+}
+
+export function lerp(start, end, amt) {
+ return (1 - amt) * start + amt * end
+}
+
+export function truncate(value, decimals) {
+ return parseFloat(value.toFixed(decimals))
+}
+
+export function wrapValue(value, lowBound, highBound) {
+ const range = highBound - lowBound
+ return ((((value - lowBound) % range) + range) % range) + lowBound
+}
diff --git a/libs/sass-utils/index.js b/libs/sass-utils/index.js
new file mode 100644
index 0000000..1103538
--- /dev/null
+++ b/libs/sass-utils/index.js
@@ -0,0 +1,220 @@
+// https://github.com/dawaltconley/sass-cast/blob/main/index.js
+
+import * as sass from 'sass-embedded'
+import { isQuoted, unquoteString, parseString, getAttr } from './utils'
+import { List, OrderedMap } from 'immutable'
+
+/**
+ * Converts any Javascript object to an equivalent Sass value.
+ *
+ * This method is recursive and will convert the values of any array or object,
+ * as well as the array or object itself.
+ *
+ * @example
+ * const { toSass } = require('sass-cast');
+ *
+ * const string = toSass('a simple string');
+ * // quoted SassString => '"a simple string"'
+ *
+ * const map = toSass({
+ * key: 'value',
+ * nested: {
+ * 'complex//:key': [ null, 4 ],
+ * }
+ * });
+ * // SassMap => '("key": "value", "nested": ("complex//:key": (null, 4)))'
+ *
+ * @param {*} value - the value to be converted
+ * @param {Object} options
+ * @param {boolean} [options.parseUnquotedStrings=false] - whether to parse unquoted strings for colors or numbers with units
+ * @param {boolean|*[]} [options.resolveFunctions=false] - if true, resolve functions and attempt to cast their return values. if an array, pass as arguments when resolving
+ * @param {boolean} [options.quotes=true] - controls whether returned SassStrings are quoted. input strings that contain quotes will always return a quoted SassString even if this flag is false.
+ * @return {Value} - a {@link https://sass-lang.com/documentation/js-api/classes/Value Sass value}
+ */
+
+export const toSass = (value, options = {}) => {
+ let {
+ parseUnquotedStrings = false,
+ resolveFunctions = false,
+ quotes = true,
+ } = options
+ if (value instanceof sass.Value) {
+ return value
+ } else if (value === null || value === undefined) {
+ return sass.sassNull
+ } else if (typeof value === 'boolean') {
+ return value ? sass.sassTrue : sass.sassFalse
+ } else if (typeof value === 'number') {
+ return new sass.SassNumber(value)
+ } else if (typeof value === 'string') {
+ const valueIsQuoted = isQuoted(value)
+ if (parseUnquotedStrings && !valueIsQuoted) {
+ let parsed = parseString(value)
+ if (
+ parsed instanceof sass.SassColor ||
+ parsed instanceof sass.SassNumber
+ )
+ return parsed
+ }
+ return new sass.SassString(value, {
+ quotes: valueIsQuoted || quotes,
+ })
+ } else if (typeof value === 'object') {
+ if (Array.isArray(value)) {
+ let sassList = value.map((value) => toSass(value, options))
+ return new sass.SassList(sassList)
+ } else {
+ let sassMap = OrderedMap(value).mapEntries(([key, value]) => [
+ new sass.SassString(key, { quotes: true }),
+ toSass(value, options),
+ ])
+ return new sass.SassMap(sassMap)
+ }
+ } else if (resolveFunctions && typeof value === 'function') {
+ const args = Array.isArray(resolveFunctions) ? resolveFunctions : []
+ return toSass(value(...args), options)
+ }
+ return sass.sassNull
+}
+
+const colorProperties = [
+ 'red',
+ 'green',
+ 'blue',
+ 'hue',
+ 'lightness',
+ 'saturation',
+ 'whiteness',
+ 'blackness',
+ 'alpha',
+]
+
+/**
+ * Converts Sass values to their Javascript equivalents.
+ *
+ * @example
+ * const { fromSass, toSass } = require('sass-cast');
+ *
+ * const sassString = toSass('a sass string object');
+ * const string = fromSass(sassString);
+ * // 'a sass string object'
+ *
+ * @param {Value} object - a {@link https://sass-lang.com/documentation/js-api/classes/Value Sass value}
+ * @param {Object} options
+ * @param {boolean} [options.preserveUnits=false] - By default, only the values of numbers are returned, not their units. If true, `fromSass` will return numbers as a two-item Array, i.e. [ value, unit ]
+ * @param {boolean} [options.rgbColors=false] - By default, colors are returned as strings. If true, `fromSass` will return colors as an object with `r`, `g`, `b`, and `a`, properties.
+ * @param {boolean} [options.preserveQuotes=false] - By default, quoted Sass strings return their inner text as a string. If true, `fromSass` will preserve the quotes in the returned string value.
+ * @return {*} - a Javascript value corresponding to the Sass input
+ */
+
+export const fromSass = (object, options = {}) => {
+ let {
+ preserveUnits = false,
+ rgbColors = false,
+ preserveQuotes = false,
+ } = options
+ if (object instanceof sass.SassBoolean) {
+ return object.value
+ } else if (object instanceof sass.SassNumber) {
+ if (preserveUnits) {
+ return [
+ object.value,
+ object.numeratorUnits.toArray(),
+ object.denominatorUnits.toArray(),
+ ]
+ } else if (object.numeratorUnits.size || object.denominatorUnits.size) {
+ return object.toString()
+ }
+ return object.value
+ } else if (object instanceof sass.SassColor) {
+ if (rgbColors) {
+ return colorProperties.reduce((colorObj, p) => {
+ colorObj[p] = object[p]
+ return colorObj
+ }, {})
+ }
+ return object.toString()
+ } else if (object instanceof sass.SassString) {
+ return preserveQuotes ? object.text : unquoteString(object.text)
+ } else if (object instanceof sass.SassList || List.isList(object)) {
+ let list = []
+ for (
+ let i = 0, value = object.get(i);
+ value !== undefined;
+ i++, value = object.get(i)
+ ) {
+ list.push(fromSass(value, options))
+ }
+ return list
+ } else if (object instanceof sass.SassMap) {
+ return object.contents
+ .mapEntries(([k, v]) => [k.text, fromSass(v, options)])
+ .toObject()
+ } else {
+ return object.realNull
+ }
+}
+
+/**
+ * An object defining Sass utility functions.
+ *
+ * @example
Pass to sass using the JS API
+ * const { sassFunctions } = require('sass-cast');
+ * const sass = require('sass');
+ *
+ * sass.compile('main.scss', { functions: sassFunctions });
+ */
+export const sassFunctions = {
+ /**
+ * Sass function for importing data from Javascript or JSON files.
+ * Calls the CommonJS `require` function under the hood.
+ *
+ * #### Examples
+ *
+ * ```scss
+ * // import config info from tailwindcss
+ * $tw: require('./tailwind.config.js', $parseUnquotedStrings: true);
+ * $tw-colors: map.get($tw, theme, extend, colors);
+ * ```
+ * @name require
+ * @memberof sassFunctions
+ * @param {SassString} $module - Path to the file or module. Relative paths are relative to the Node process running Sass compilation.
+ * @param {SassList} [$properties=()] - List of properties, if you only want to parse part of the module data.
+ * @param {SassBoolean} [$parseUnquotedStrings=false] - Passed as an option to {@link #tosass toSass}.
+ * @param {SassBoolean} [$resolveFunctions=false] - Passed as an option to {@link #tosass toSass}.
+ * @param {SassBoolean} [$quotes=true] - Passed as an option to {@link #tosass toSass}.
+ * @return {Value} - a {@link https://sass-lang.com/documentation/js-api/classes/Value Sass value}
+ */
+ 'require($module, $properties: (), $parseUnquotedStrings: false, $resolveFunctions: false, $quotes: true)':
+ (args) => {
+ const moduleName = args[0].assertString('module').text
+ const properties = args[1].realNull && fromSass(args[1].asList)
+ const parseUnquotedStrings = args[2].isTruthy
+ const resolveFunctions = args[3].isTruthy
+ const quotes = args[4].isTruthy
+ const options = {
+ parseUnquotedStrings,
+ resolveFunctions,
+ quotes,
+ }
+ const convert = (data) =>
+ toSass(properties ? getAttr(data, properties) : data, options)
+
+ let mod,
+ paths = [moduleName, `${process.cwd()}/${moduleName}`]
+ for (let path of paths) {
+ try {
+ mod = require(path)
+ break
+ } catch (e) {
+ if (e.code !== 'MODULE_NOT_FOUND') throw e
+ continue
+ }
+ }
+ if (!mod) throw new Error(`Couldn't find module: ${moduleName}`)
+
+ if (resolveFunctions && typeof mod === 'function') mod = mod()
+ if (mod instanceof Promise) return mod.then(convert)
+ return convert(mod)
+ },
+}
diff --git a/libs/sass-utils/utils.js b/libs/sass-utils/utils.js
new file mode 100644
index 0000000..658ce3e
--- /dev/null
+++ b/libs/sass-utils/utils.js
@@ -0,0 +1,108 @@
+// https://github.com/dawaltconley/sass-cast/blob/main/utils.js
+
+import * as sass from 'sass-embedded'
+
+/**
+ * Check if string is quoted
+ * @private
+ * @param {string} str
+ * @return {boolean}
+ */
+export const isQuoted = (str) => /^['"].*['"]$/.test(str)
+
+/**
+ * Surrounds a string with quotes
+ * @private
+ * @param {string} str
+ * @param {string} q - quotes, double or single
+ * @return {string}
+ */
+export const quoteString = (str, q) => {
+ if (!q) return str
+ if (isQuoted(str)) {
+ q = str[0]
+ str = str.slice(1, -1)
+ }
+ let r = new RegExp(q, 'g')
+ return q + str.replace(r, '\\' + q) + q
+}
+
+/**
+ * Unquotes a string
+ * @private
+ * @param {string} str
+ * @return {string}
+ */
+export const unquoteString = (str) => (isQuoted(str) ? str.slice(1, -1) : str)
+
+/**
+ * Parse a string as a Sass object
+ * cribbed from davidkpiano/sassport
+ *
+ * @private
+ * @param {string} str
+ * @return {Value}
+ */
+export const parseString = (str) => {
+ let result
+
+ try {
+ sass.compileString(`$_: ___(${str});`, {
+ functions: {
+ '___($value)': (args) => {
+ result = args[0]
+ return result
+ },
+ },
+ })
+ } catch (e) {
+ return str
+ }
+
+ return result
+}
+
+/**
+ * Parse a string as a legacy Sass object
+ * cribbed from davidkpiano/sassport
+ *
+ * @private
+ * @param {string} str
+ * @return {LegacyObject}
+ */
+export const parseStringLegacy = (str) => {
+ let result
+
+ try {
+ sass.renderSync({
+ data: `$_: ___((${str}));`,
+ functions: {
+ '___($value)': (value) => {
+ result = value
+ return value
+ },
+ },
+ })
+ } catch (e) {
+ return str
+ }
+
+ return result
+}
+
+/**
+ * Function to handle 'toString()' methods with legacy API.
+ *
+ * @private
+ * @param {LegacyObject} obj
+ * @return {string}
+ */
+export const legacyToString = (obj) => (obj.dartValue || obj).toString()
+
+/**
+ * Return a value from an object and a list of keys.
+ * @private
+ * @param {Object|Array} obj
+ * @param {*[]} attrs
+ */
+export const getAttr = (obj, attrs) => attrs.reduce((o, attr) => o[attr], obj)
diff --git a/libs/theme.js b/libs/theme.js
new file mode 100644
index 0000000..f3d11dc
--- /dev/null
+++ b/libs/theme.js
@@ -0,0 +1,48 @@
+const colors = {
+ black: '#181818',
+ white: '#D5D5D5',
+ 'grey-100': '#747474',
+ green: '#87FF5B',
+ blue: '#5B92FF',
+ purple: '#94079E',
+ red: '#D40202',
+}
+
+const themes = {
+ dark: {
+ bg: colors.black,
+ fg: colors.white,
+ accent: colors.green,
+ link: colors.blue,
+ },
+ light: {
+ bg: colors.white,
+ fg: colors.black,
+ accent: colors.purple,
+ link: colors.blue,
+ },
+}
+
+const breakpoints = {
+ mobile: 800,
+}
+
+const viewports = {
+ mobile: {
+ width: 440,
+ height: 956,
+ },
+ desktop: {
+ width: 1728,
+ height: 1117,
+ },
+}
+
+export { colors, themes, breakpoints, viewports }
+
+export default {
+ colors,
+ themes,
+ breakpoints,
+ viewports,
+}
diff --git a/package-lock.json b/package-lock.json
index 02cc150..76ca5a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,6 +5,13 @@
"packages": {
"": {
"dependencies": {
+ "@fuzzco/font-loader": "^1.0.2",
+ "@vueuse/core": "^14.3.0",
+ "lenis": "^1.3.23",
+ "lodash": "^4.18.1",
+ "sass": "^1.99.0",
+ "sass-embedded": "^1.99.0",
+ "tempus": "^1.0.0-dev.17",
"vike": "^0.4.255",
"vike-vue": "^0.9.11",
"vue": "^3.5.30"
@@ -286,6 +293,12 @@
"@brillout/picocolors": "^1.0.26"
}
},
+ "node_modules/@bufbuild/protobuf": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.12.0.tgz",
+ "integrity": "sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==",
+ "license": "(Apache-2.0 AND BSD-3-Clause)"
+ },
"node_modules/@emnapi/core": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.0.tgz",
@@ -733,6 +746,15 @@
"node": ">=18"
}
},
+ "node_modules/@fuzzco/font-loader": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@fuzzco/font-loader/-/font-loader-1.0.2.tgz",
+ "integrity": "sha512-ztpjEYxdkL0pQjvq7GVeXUkIISe4akhMJ7G/DKqVhAZ++cKu25WSnVevQ7JbXGqG5PGiexzGUKMMJjWleTL+1w==",
+ "license": "ISC",
+ "dependencies": {
+ "fontfaceobserver": "^2.1.0"
+ }
+ },
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -1043,6 +1065,302 @@
"url": "https://github.com/sponsors/Boshen"
}
},
+ "node_modules/@parcel/watcher": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
+ "integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.3",
+ "is-glob": "^4.0.3",
+ "node-addon-api": "^7.0.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher-android-arm64": "2.5.6",
+ "@parcel/watcher-darwin-arm64": "2.5.6",
+ "@parcel/watcher-darwin-x64": "2.5.6",
+ "@parcel/watcher-freebsd-x64": "2.5.6",
+ "@parcel/watcher-linux-arm-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm-musl": "2.5.6",
+ "@parcel/watcher-linux-arm64-glibc": "2.5.6",
+ "@parcel/watcher-linux-arm64-musl": "2.5.6",
+ "@parcel/watcher-linux-x64-glibc": "2.5.6",
+ "@parcel/watcher-linux-x64-musl": "2.5.6",
+ "@parcel/watcher-win32-arm64": "2.5.6",
+ "@parcel/watcher-win32-ia32": "2.5.6",
+ "@parcel/watcher-win32-x64": "2.5.6"
+ }
+ },
+ "node_modules/@parcel/watcher-android-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
+ "integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
+ "integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-darwin-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
+ "integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-freebsd-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
+ "integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
+ "integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
+ "integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
+ "integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-arm64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
+ "integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-glibc": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
+ "integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-linux-x64-musl": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
+ "integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-arm64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
+ "integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-ia32": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
+ "integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
+ "node_modules/@parcel/watcher-win32-x64": {
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
+ "integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">= 10.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/parcel"
+ }
+ },
"node_modules/@polka/url": {
"version": "1.0.0-next.29",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
@@ -1397,6 +1715,12 @@
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
+ "node_modules/@types/web-bluetooth": {
+ "version": "0.0.21",
+ "resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
+ "integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
+ "license": "MIT"
+ },
"node_modules/@vitejs/plugin-vue": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.5.tgz",
@@ -1526,6 +1850,44 @@
"integrity": "sha512-YXgQ7JjaO18NeK2K9VTbDHaFy62WrObMa6XERNfNOkAhD1F1oDSf3ZJ7K6GqabZ0BvSDHajp8qfS5Sa2I9n8uQ==",
"license": "MIT"
},
+ "node_modules/@vueuse/core": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-14.3.0.tgz",
+ "integrity": "sha512-aHfz47g0ZhMtTVHmIzMVpJy8ePhhOy68GY5bv110+5DVtZ+W7BsOx+m61UNQqfrWyPztIHIanWa3E2tib3NFIw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.21",
+ "@vueuse/metadata": "14.3.0",
+ "@vueuse/shared": "14.3.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ },
+ "node_modules/@vueuse/metadata": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-14.3.0.tgz",
+ "integrity": "sha512-BwxmbAzwAVF50+MW57GXOUEV61nFBGnlBvrTqj49PqWJu3uw7hdu72ztXeZ33RdZtDY6kO+bfCAE1PCn88Tktw==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@vueuse/shared": {
+ "version": "14.3.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-14.3.0.tgz",
+ "integrity": "sha512-bZpge9eSXwa4ToSiqJ7j6KRwhAsneMFoSz3LMWKQDkqimm3D/tbFlrklrs/IOqC8tEcYmXQZJ6N0UrjhBirVCg==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "vue": "^3.5.0"
+ }
+ },
"node_modules/acorn": {
"version": "8.16.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
@@ -1618,6 +1980,27 @@
],
"license": "CC-BY-4.0"
},
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/colorjs.io": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/colorjs.io/-/colorjs.io-0.5.2.tgz",
+ "integrity": "sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==",
+ "license": "MIT"
+ },
"node_modules/confbox": {
"version": "0.1.8",
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
@@ -1653,6 +2036,16 @@
}
}
},
+ "node_modules/detect-libc": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
+ "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
+ "license": "Apache-2.0",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.313",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz",
@@ -1753,6 +2146,12 @@
}
}
},
+ "node_modules/fontfaceobserver": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
+ "integrity": "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg==",
+ "license": "BSD-2-Clause"
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -1776,6 +2175,44 @@
"node": ">=6.9.0"
}
},
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/immutable": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz",
+ "integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==",
+ "license": "MIT"
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -1806,6 +2243,43 @@
"node": ">=6"
}
},
+ "node_modules/lenis": {
+ "version": "1.3.23",
+ "resolved": "https://registry.npmjs.org/lenis/-/lenis-1.3.23.tgz",
+ "integrity": "sha512-YxYq3TJqj9sJNv0V9SkyQHejt14xwyIwgDaaMK89Uf9SxQfIszu+gTQSSphh6BWlLTNVKvvXAGkg+Zf+oFIevg==",
+ "license": "MIT",
+ "workspaces": [
+ "packages/*",
+ "playground",
+ "playground/*"
+ ],
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/darkroomengineering"
+ },
+ "peerDependencies": {
+ "@nuxt/kit": ">=3.0.0",
+ "react": ">=17.0.0",
+ "vue": ">=3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@nuxt/kit": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "vue": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
"node_modules/lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -1884,6 +2358,13 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
+ "node_modules/node-addon-api": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
+ "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/node-releases": {
"version": "2.0.36",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz",
@@ -2013,6 +2494,19 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/regexp-tree": {
"version": "0.1.27",
"resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz",
@@ -2066,6 +2560,364 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/rxjs": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/sass": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass/-/sass-1.99.0.tgz",
+ "integrity": "sha512-kgW13M54DUB7IsIRM5LvJkNlpH+WhMpooUcaWGFARkF1Tc82v9mIWkCbCYf+MBvpIUBSeSOTilpZjEPr2VYE6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^4.0.0",
+ "immutable": "^5.1.5",
+ "source-map-js": ">=0.6.2 <2.0.0"
+ },
+ "bin": {
+ "sass": "sass.js"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ },
+ "optionalDependencies": {
+ "@parcel/watcher": "^2.4.1"
+ }
+ },
+ "node_modules/sass-embedded": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded/-/sass-embedded-1.99.0.tgz",
+ "integrity": "sha512-gF/juR1aX02lZHkvwxdF80SapkQeg2fetoDF6gIQkNbSw5YEUFspMkyGTjPjgZSgIHuZpy+Wz4PlebKnLXMjdg==",
+ "license": "MIT",
+ "dependencies": {
+ "@bufbuild/protobuf": "^2.5.0",
+ "colorjs.io": "^0.5.0",
+ "immutable": "^5.1.5",
+ "rxjs": "^7.4.0",
+ "supports-color": "^8.1.1",
+ "sync-child-process": "^1.0.2",
+ "varint": "^6.0.0"
+ },
+ "bin": {
+ "sass": "dist/bin/sass.js"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "optionalDependencies": {
+ "sass-embedded-all-unknown": "1.99.0",
+ "sass-embedded-android-arm": "1.99.0",
+ "sass-embedded-android-arm64": "1.99.0",
+ "sass-embedded-android-riscv64": "1.99.0",
+ "sass-embedded-android-x64": "1.99.0",
+ "sass-embedded-darwin-arm64": "1.99.0",
+ "sass-embedded-darwin-x64": "1.99.0",
+ "sass-embedded-linux-arm": "1.99.0",
+ "sass-embedded-linux-arm64": "1.99.0",
+ "sass-embedded-linux-musl-arm": "1.99.0",
+ "sass-embedded-linux-musl-arm64": "1.99.0",
+ "sass-embedded-linux-musl-riscv64": "1.99.0",
+ "sass-embedded-linux-musl-x64": "1.99.0",
+ "sass-embedded-linux-riscv64": "1.99.0",
+ "sass-embedded-linux-x64": "1.99.0",
+ "sass-embedded-unknown-all": "1.99.0",
+ "sass-embedded-win32-arm64": "1.99.0",
+ "sass-embedded-win32-x64": "1.99.0"
+ }
+ },
+ "node_modules/sass-embedded-all-unknown": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.99.0.tgz",
+ "integrity": "sha512-qPIRG8Uhjo6/OKyAKixTnwMliTz+t9K6Duk0mx5z+K7n0Ts38NSJz2sjDnc7cA/8V9Lb3q09H38dZ1CLwD+ssw==",
+ "cpu": [
+ "!arm",
+ "!arm64",
+ "!riscv64",
+ "!x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "sass": "1.99.0"
+ }
+ },
+ "node_modules/sass-embedded-android-arm": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-arm/-/sass-embedded-android-arm-1.99.0.tgz",
+ "integrity": "sha512-EHvJ0C7/VuP78Qr6f8gIUVUmCqIorEQpw2yp3cs3SMg02ZuumlhjXvkTcFBxHmFdFR23vTNk1WnhY6QSeV1nFQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-android-arm64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.99.0.tgz",
+ "integrity": "sha512-fNHhdnP23yqqieCbAdym4N47AleSwjbNt6OYIYx4DdACGdtERjQB4iOX/TaKsW034MupfF7SjnAAK8w7Ptldtg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-android-riscv64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.99.0.tgz",
+ "integrity": "sha512-4zqDFRvgGDTL5vTHuIhRxUpXFoh0Cy7Gm5Ywk19ASd8Settmd14YdPRZPmMxfgS1GH292PofV1fq1ifiSEJWBw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-android-x64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-android-x64/-/sass-embedded-android-x64-1.99.0.tgz",
+ "integrity": "sha512-Uk53k/dGYt04RjOL4gFjZ0Z9DH9DKh8IA8WsXUkNqsxerAygoy3zqRBS2zngfE9K2jiOM87q+1R1p87ory9oQQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-darwin-arm64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.99.0.tgz",
+ "integrity": "sha512-u61/7U3IGLqoO6gL+AHeiAtlTPFwJK1+964U8gp45ZN0hzh1yrARf5O1mivXv8NnNgJvbG2wWJbiNZP0lG/lTg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-darwin-x64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.99.0.tgz",
+ "integrity": "sha512-j/kkk/NcXdIameLezSfXjgCiBkVcA+G60AXrX768/3g0miK1g7M9dj7xOhCb1i7/wQeiEI3rw2LLuO63xRIn4A==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-arm": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.99.0.tgz",
+ "integrity": "sha512-d4IjJZrX2+AwB2YCy1JySwdptJECNP/WfAQLUl8txI3ka8/d3TUI155GtelnoZUkio211PwIeFvvAeZ9RXPQnw==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-arm64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.99.0.tgz",
+ "integrity": "sha512-btNcFpItcB56L40n8hDeL7sRSMLDXQ56nB5h2deddJx1n60rpKSElJmkaDGHtpkrY+CTtDRV0FZDjHeTJddYew==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-arm": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.99.0.tgz",
+ "integrity": "sha512-2gvHOupgIw3ytatXT4nFUow71LFbuOZPEwG+HUzcNQDH8ue4Ez8cr03vsv5MDv3lIjOKcXwDvWD980t18MwkoQ==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-arm64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.99.0.tgz",
+ "integrity": "sha512-Hi2bt/IrM5P4FBKz6EcHAlniwfpoz9mnTdvSd58y+avA3SANM76upIkAdSayA8ZGwyL3gZokru1AKDPF9lJDNw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-riscv64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.99.0.tgz",
+ "integrity": "sha512-mKqGvVaJ9rHMqyZsF0kikQe4NO0f4osb67+X6nLhBiVDKvyazQHJ3zJQreNefIE36yL2sjHIclSB//MprzaQDg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-musl-x64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.99.0.tgz",
+ "integrity": "sha512-huhgOMmOc30r7CH7qbRbT9LerSEGSnWuS4CYNOskr9BvNeQp4dIneFufNRGZ7hkOAxUM8DglxIZJN/cyAT95Ew==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-riscv64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.99.0.tgz",
+ "integrity": "sha512-mevFPIFAVhrH90THifxLfOntFmHtcEKOcdWnep2gJ0X4DVva4AiVIRlQe/7w9JFx5+gnDRE1oaJJkzuFUuYZsA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-linux-x64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.99.0.tgz",
+ "integrity": "sha512-9k7IkULqIZdCIVt4Mboryt6vN8Mjmm3EhI1P3mClU5y5i3wLK5ExC3cbVWk047KsID/fvB1RLslqghXJx5BoxA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-unknown-all": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.99.0.tgz",
+ "integrity": "sha512-P7MxiUtL/XzGo3PX0CaB8lNNEFLQWKikPA8pbKytx9ZCLZSDkt2NJcdAbblB/sqMs4AV3EK2NadV8rI/diq3xg==",
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "!android",
+ "!darwin",
+ "!linux",
+ "!win32"
+ ],
+ "dependencies": {
+ "sass": "1.99.0"
+ }
+ },
+ "node_modules/sass-embedded-win32-arm64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.99.0.tgz",
+ "integrity": "sha512-8whpsW7S+uO8QApKfQuc36m3P9EISzbVZOgC79goob4qGy09u8Gz/rYvw8h1prJDSjltpHGhOzBE6LDz7WvzVw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/sass-embedded-win32-x64": {
+ "version": "1.99.0",
+ "resolved": "https://registry.npmjs.org/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.99.0.tgz",
+ "integrity": "sha512-ipuOv1R2K4MHeuCEAZGpuUbAgma4gb0sdacyrTjJtMOy/OY9UvWfVlwErdB09KIkp4fPDpQJDJfvYN6bC8jeNg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
"node_modules/semver": {
"version": "7.7.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
@@ -2120,6 +2972,60 @@
"source-map": "^0.6.0"
}
},
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/sync-child-process": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/sync-child-process/-/sync-child-process-1.0.2.tgz",
+ "integrity": "sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==",
+ "license": "MIT",
+ "dependencies": {
+ "sync-message-port": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/sync-message-port": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/sync-message-port/-/sync-message-port-1.2.0.tgz",
+ "integrity": "sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/tempus": {
+ "version": "1.0.0-dev.17",
+ "resolved": "https://registry.npmjs.org/tempus/-/tempus-1.0.0-dev.17.tgz",
+ "integrity": "sha512-Umj1ILQ+4Shq84SmCR24VrVjBjfHMCVMAawI1v+BO0GEsXpNfhULl1V8zt6v6d1voDiaqXH61DUG5nquGC9Kag==",
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/darkroomengineering"
+ },
+ "peerDependencies": {
+ "react": ">=17.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
@@ -2149,8 +3055,7 @@
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
- "license": "0BSD",
- "optional": true
+ "license": "0BSD"
},
"node_modules/type-level-regexp": {
"version": "0.1.17",
@@ -2223,6 +3128,12 @@
"browserslist": ">= 4.21.0"
}
},
+ "node_modules/varint": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
+ "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==",
+ "license": "MIT"
+ },
"node_modules/vike": {
"version": "0.4.255",
"resolved": "https://registry.npmjs.org/vike/-/vike-0.4.255.tgz",
diff --git a/package.json b/package.json
index 7e5c912..572a5d7 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,13 @@
"preview": "vike build && vike preview"
},
"dependencies": {
+ "@fuzzco/font-loader": "^1.0.2",
+ "@vueuse/core": "^14.3.0",
+ "lenis": "^1.3.23",
+ "lodash": "^4.18.1",
+ "sass": "^1.99.0",
+ "sass-embedded": "^1.99.0",
+ "tempus": "^1.0.0-dev.17",
"vike": "^0.4.255",
"vike-vue": "^0.9.11",
"vue": "^3.5.30"
diff --git a/pages/+Layout.vue b/pages/+Layout.vue
index c4a51ef..dc785c1 100644
--- a/pages/+Layout.vue
+++ b/pages/+Layout.vue
@@ -1,34 +1,61 @@
-
-
-
-
-
+
+
+
+
+
-
+
+
+