Add /contact and /photography
This commit is contained in:
parent
2863beed61
commit
18d65f5fe4
16 changed files with 771 additions and 418 deletions
|
@ -3,10 +3,8 @@
|
||||||
🔥 [**moritzruth.de**](https://moritzruth.de)
|
🔥 [**moritzruth.de**](https://moritzruth.de)
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
- Start
|
|
||||||
- Blog
|
- Blog
|
||||||
- Contact
|
|
||||||
- Photography
|
|
||||||
- Projects
|
- Projects
|
||||||
- Apps
|
|
||||||
- Libraries
|
- Libraries
|
||||||
|
- Legal Notice
|
||||||
|
- Terms
|
||||||
|
|
4
app.vue
4
app.vue
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="min-h-100vh w-100vw text-light-900 overflow-x-hidden">
|
<div class="h-100vh w-100vw text-light-100 overflow-x-hidden">
|
||||||
<NuxtPage/>
|
<NuxtPage/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style module>
|
<style module>
|
||||||
html, body {
|
html, body {
|
||||||
background: #070707;
|
@apply bg-background;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
|
|
14
assets/photos.ts
Normal file
14
assets/photos.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
export const photos = [
|
||||||
|
{
|
||||||
|
"file": "Late_afternoon.webp",
|
||||||
|
"title": "Late afternoon",
|
||||||
|
"date": "2019",
|
||||||
|
"description": "Taken in London during a sunny afternoon.\nSeems to be 65 Curzon St."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "Martyrdom.webp",
|
||||||
|
"title": "Martyrdom",
|
||||||
|
"date": "2020-10-19",
|
||||||
|
"description": "The Sankt-Laurentius church right by the Mosel river in Bremm (Germany)."
|
||||||
|
}
|
||||||
|
]
|
62
components/LinkCardList.vue
Normal file
62
components/LinkCardList.vue
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
<template>
|
||||||
|
<div class="relative flex flex-col justify-center space-y-4">
|
||||||
|
<component
|
||||||
|
:is="link.to ? 'router-link' : 'a'"
|
||||||
|
v-for="link in links"
|
||||||
|
:key="link.to"
|
||||||
|
:to="link.to"
|
||||||
|
:href="link.href"
|
||||||
|
class="px-5 sm:px-6 py-4 bg-light-300 bg-opacity-5 rounded-lg backdrop-blur-lg flex cursor-pointer
|
||||||
|
hover:bg-opacity-10 focus-visible:bg-opacity-10 transform hover:scale-104 transition duration-200 group"
|
||||||
|
>
|
||||||
|
<div class="flex items-center justify-center text-xl sm:text-2xl relative pr-4 sm:pr-5" :class="link.iconClasses">
|
||||||
|
<template v-if="typeof link.icon === 'string'">
|
||||||
|
{{ link.icon }}
|
||||||
|
</template>
|
||||||
|
<component :is="getSafeLinkIconComponent(link.icon)" v-else/>
|
||||||
|
</div>
|
||||||
|
<div class="flex-grow">
|
||||||
|
<div class="text-lg font-bold">
|
||||||
|
{{ link.label }}
|
||||||
|
</div>
|
||||||
|
<div class="opacity-60 -sm:text-sm">
|
||||||
|
{{ link.description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</component>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, ComponentCustomOptions, PropType } from "vue"
|
||||||
|
|
||||||
|
type Link = {
|
||||||
|
label: string
|
||||||
|
description: string
|
||||||
|
iconClasses?: string
|
||||||
|
icon: Component | string
|
||||||
|
} & ({
|
||||||
|
to: string
|
||||||
|
} | {
|
||||||
|
href: string
|
||||||
|
})
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "LinkCardList",
|
||||||
|
props: {
|
||||||
|
links: {
|
||||||
|
type: Array as PropType<Link[]>,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getSafeLinkIconComponent(icon: string | Component) {
|
||||||
|
return icon as ComponentCustomOptions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
44
components/TopBarLayout.vue
Normal file
44
components/TopBarLayout.vue
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<template>
|
||||||
|
<div class="w-full max-w-1000px mx-auto">
|
||||||
|
<div class="bg-background bg-opacity-70 backdrop-filter backdrop-blur-sm backdrop-saturate-200 shadow-2xl px-6 py-8 text-light-900 sticky top-0 z-10 flex items-center justify-between">
|
||||||
|
<div class="w-0">
|
||||||
|
<router-link :to="backTarget" class="w-8 flex items-center group relative">
|
||||||
|
<ArrowLeftIcon class="text-2xl"/>
|
||||||
|
<div class="text-lg absolute left-10 opacity-0 sm:can-hover:group-hover:opacity-100 pointer-events-none transition duration-200">
|
||||||
|
Back
|
||||||
|
</div>
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-2xl text-center transform -translate-y-2px">
|
||||||
|
{{ title }}
|
||||||
|
</div>
|
||||||
|
<div/>
|
||||||
|
</div>
|
||||||
|
<div class="pt-8 pb-10 px-5">
|
||||||
|
<slot/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ArrowLeftIcon from "~icons/ph/arrow-left"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TopBarLayout",
|
||||||
|
components: { ArrowLeftIcon },
|
||||||
|
props: {
|
||||||
|
backTarget: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,24 +1,17 @@
|
||||||
import { defineNuxtConfig } from "nuxt3"
|
import { defineNuxtConfig } from "nuxt3"
|
||||||
import Icons from "unplugin-icons/vite"
|
|
||||||
|
|
||||||
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
|
// https://v3.nuxtjs.org/docs/directory-structure/nuxt.config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
ssr: true,
|
ssr: true,
|
||||||
target: "static",
|
target: "static",
|
||||||
buildModules: [
|
buildModules: [
|
||||||
"nuxt-windicss"
|
"nuxt-windicss",
|
||||||
|
"unplugin-icons/nuxt"
|
||||||
],
|
],
|
||||||
css: [
|
css: [
|
||||||
"@fontsource/plus-jakarta-sans/400.css",
|
"@fontsource/plus-jakarta-sans/400.css",
|
||||||
"@fontsource/plus-jakarta-sans/700.css"
|
"@fontsource/plus-jakarta-sans/700.css"
|
||||||
],
|
],
|
||||||
vite: {
|
|
||||||
plugins: [
|
|
||||||
Icons({
|
|
||||||
autoInstall: true
|
|
||||||
})
|
|
||||||
]
|
|
||||||
},
|
|
||||||
build: {
|
build: {
|
||||||
loaders: {
|
loaders: {
|
||||||
css: {
|
css: {
|
||||||
|
|
|
@ -17,9 +17,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/plus-jakarta-sans": "^4.5.0",
|
"@fontsource/plus-jakarta-sans": "^4.5.0",
|
||||||
"@fontsource/syne": "^4.5.0",
|
"@iconify/json": "^1.1.441",
|
||||||
"@vueuse/core": "^7.2.2",
|
"@vueuse/core": "^7.2.2",
|
||||||
"@windicss/plugin-interaction-variants": "^1.0.0",
|
|
||||||
"blobs": "^2.2.1-beta.1",
|
"blobs": "^2.2.1-beta.1",
|
||||||
"unplugin-icons": "^0.12.23",
|
"unplugin-icons": "^0.12.23",
|
||||||
"vue": "^3.2.26"
|
"vue": "^3.2.26"
|
||||||
|
|
93
pages/contact.vue
Normal file
93
pages/contact.vue
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<template>
|
||||||
|
<TopBarLayout back-target="/" title="Contact">
|
||||||
|
<div class="text-lg p-5 max-w-130 mx-auto">
|
||||||
|
<div class="space-y-4 text-xl">
|
||||||
|
<p>For business inquiries, please use Matrix or Email.</p>
|
||||||
|
<p>Matrix should be used when encryption is desired.</p>
|
||||||
|
</div>
|
||||||
|
<div class="pt-6 relative flex items-center">
|
||||||
|
<div class="absolute w-full">
|
||||||
|
<BlurredBlobCanvas
|
||||||
|
:blur="30"
|
||||||
|
:size="200"
|
||||||
|
:randomness="80"
|
||||||
|
:minimum-duration="600"
|
||||||
|
:duration-variation="400"
|
||||||
|
:minimum-opacity="0.2"
|
||||||
|
:opacity-variation="0.5"
|
||||||
|
:colors="['#eb34cf', '#6577fc']"
|
||||||
|
class="mx-auto"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<LinkCardList :links="links" class="w-full"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TopBarLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import TopBarLayout from "../components/TopBarLayout.vue"
|
||||||
|
import LinkCardList from "../components/LinkCardList.vue"
|
||||||
|
import BlurredBlobCanvas from "../components/BlurredBlobCanvas.vue"
|
||||||
|
import MatrixIcon from "~icons/simple-icons/matrix"
|
||||||
|
import TwitterIcon from "~icons/simple-icons/twitter"
|
||||||
|
import EmailIcon from "~icons/carbon/email"
|
||||||
|
import { computed } from "vue"
|
||||||
|
import { useRoute } from "vue-router"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "ContactPage",
|
||||||
|
components: { BlurredBlobCanvas, LinkCardList, TopBarLayout },
|
||||||
|
setup() {
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
|
return {
|
||||||
|
links: computed(() => {
|
||||||
|
const l = []
|
||||||
|
|
||||||
|
if (route.query.ref === "jamrss") {
|
||||||
|
l.push({
|
||||||
|
icon: EmailIcon,
|
||||||
|
href: "mailto:apps@moritzruth.de",
|
||||||
|
label: "Email (regarding apps)",
|
||||||
|
description: "apps@moritzruth.de"
|
||||||
|
}, {
|
||||||
|
icon: EmailIcon,
|
||||||
|
href: "mailto:hey@deltaa.xyz",
|
||||||
|
label: "Email (everything else)",
|
||||||
|
description: "hey@deltaa.xyz"
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
l.push({
|
||||||
|
icon: EmailIcon,
|
||||||
|
href: "mailto:hey@deltaa.xyz",
|
||||||
|
label: "Email",
|
||||||
|
description: "hey@deltaa.xyz"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
l.push(
|
||||||
|
{
|
||||||
|
icon: MatrixIcon,
|
||||||
|
href: "https://moritzruth.de/matrix",
|
||||||
|
label: "Matrix",
|
||||||
|
description: "@moritz:moritzruth.de"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: TwitterIcon,
|
||||||
|
href: "https://twitter.com/moritzruth",
|
||||||
|
label: "Twitter",
|
||||||
|
description: "moritzruth"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return l
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="h-100vh w-full max-w-[1200px] mx-auto flex justify-between -lg:flex-col p-5 sm:p-10">
|
<div class="h-100vh w-full max-w-1200px mx-auto flex justify-between -lg:flex-col p-5 sm:p-10">
|
||||||
<section class="relative pt-20">
|
<section class="relative pt-20">
|
||||||
<div class="absolute top-60 -left-20 lg:-left-10">
|
<div class="absolute top-60 -left-20 lg:-left-10">
|
||||||
<BlurredBlobCanvas
|
<BlurredBlobCanvas
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
:colors="['#eb34cf', '#6577fc']"
|
:colors="['#eb34cf', '#6577fc']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative max-w-130 p-2 lg:pl-10">
|
<main class="relative max-w-130 p-2 lg:pl-10">
|
||||||
<div class="font-extrabold text-3xl sm:text-4xl">
|
<div class="font-extrabold text-3xl sm:text-4xl">
|
||||||
Moritz Ruth
|
Moritz Ruth
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
</div>
|
</div>
|
||||||
<XSpacer v="10"/>
|
<XSpacer v="10"/>
|
||||||
<router-link to="/contact" :class="$style.reachOut">Reach out</router-link>
|
<router-link to="/contact" :class="$style.reachOut">Reach out</router-link>
|
||||||
</div>
|
</main>
|
||||||
</section>
|
</section>
|
||||||
<section class="relative lg:pr-20 pt-20 pb-10 mt-0">
|
<section class="relative lg:pr-20 pt-20 pb-10 mt-0">
|
||||||
<div class="absolute w-full pt-20 flex justify-center">
|
<div class="absolute w-full pt-20 flex justify-center">
|
||||||
|
@ -49,23 +49,7 @@
|
||||||
:colors="['#eb34cf', '#6577fc']"
|
:colors="['#eb34cf', '#6577fc']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="relative flex flex-col justify-center space-y-4">
|
<LinkCardList :links="navigationLinks"/>
|
||||||
<router-link
|
|
||||||
v-for="link in navigationLinks"
|
|
||||||
:key="link.to"
|
|
||||||
:to="link.to"
|
|
||||||
class="px-5 sm:px-6 py-4 bg-light-300 bg-opacity-5 rounded-lg backdrop-blur-lg flex
|
|
||||||
hover:bg-opacity-10 focus-visible:bg-opacity-10 transform hover:scale-104 transition duration-200 group"
|
|
||||||
>
|
|
||||||
<div class="flex items-center justify-center text-xl sm:text-2xl relative pr-3 sm:pr-5" :class="link.emojiClasses">
|
|
||||||
{{ link.emoji }}
|
|
||||||
</div>
|
|
||||||
<div class="flex-grow">
|
|
||||||
<div class="text-lg font-bold">{{ link.label }}</div>
|
|
||||||
<div class="opacity-60 -sm:text-sm">{{ link.text }}</div>
|
|
||||||
</div>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -101,38 +85,40 @@
|
||||||
<script>
|
<script>
|
||||||
import BlurredBlobCanvas from "../components/BlurredBlobCanvas.vue"
|
import BlurredBlobCanvas from "../components/BlurredBlobCanvas.vue"
|
||||||
import XSpacer from "../components/XSpacer.vue"
|
import XSpacer from "../components/XSpacer.vue"
|
||||||
|
import LinkCardList from "../components/LinkCardList.vue"
|
||||||
|
|
||||||
const NAVIGATION_LINKS = [
|
const NAVIGATION_LINKS = [
|
||||||
{
|
{
|
||||||
emoji: "📝",
|
icon: "📝",
|
||||||
to: "/blog",
|
to: "/blog",
|
||||||
label: "Blog",
|
label: "Blog",
|
||||||
text: "My thoughts, mostly on dev things"
|
description: "My thoughts, mostly on dev things"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
emoji: "✨",
|
icon: "✨",
|
||||||
to: "/projects",
|
to: "/projects",
|
||||||
label: "Projects",
|
label: "Projects",
|
||||||
text: "Apps and open-source projects"
|
description: "Apps and open-source projects"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
emojiClasses: "top-[-0.25rem]",
|
iconClasses: "top-[-0.25rem]",
|
||||||
emoji: "📷",
|
icon: "📷",
|
||||||
to: "/photography",
|
to: "/photography",
|
||||||
label: "Photography",
|
label: "Photography",
|
||||||
text: "Some photos I’m proud of"
|
description: "Some photos I’m proud of"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
emoji: "💬",
|
icon: "💬",
|
||||||
to: "/contact",
|
to: "/contact",
|
||||||
label: "Contact me",
|
label: "Contact me",
|
||||||
text: "Email, Matrix, Twitter"
|
description: "Email, Matrix, Twitter"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "IndexPage",
|
name: "IndexPage",
|
||||||
components: {
|
components: {
|
||||||
|
LinkCardList,
|
||||||
XSpacer,
|
XSpacer,
|
||||||
BlurredBlobCanvas
|
BlurredBlobCanvas
|
||||||
},
|
},
|
||||||
|
|
48
pages/photography.vue
Normal file
48
pages/photography.vue
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<TopBarLayout title="Photography" back-target="/">
|
||||||
|
<div class="flex flex-col space-y-30 lg:space-y-20">
|
||||||
|
<div
|
||||||
|
v-for="photo in photos"
|
||||||
|
:key="photo.file"
|
||||||
|
class="flex -lg:space-y-10 lg:space-x-10 -lg:flex-col -lg:items-center"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:src="photo.file"
|
||||||
|
:alt="photo.title"
|
||||||
|
class="w-full lg:max-w-150 max-h-80vh block object-contain"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div class="uppercase opacity-70 text-sm pt-1">
|
||||||
|
{{ photo.date }}
|
||||||
|
</div>
|
||||||
|
<div class="font-bold text-2xl opacity-90">
|
||||||
|
{{ photo.title }}
|
||||||
|
</div>
|
||||||
|
<div class="opacity-90 max-w-100 space-y-1 pt-4 whitespace-pre-line">
|
||||||
|
{{ photo.description }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TopBarLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import TopBarLayout from "../components/TopBarLayout.vue"
|
||||||
|
import { photos } from "assets/photos"
|
||||||
|
import XSpacer from "~/components/XSpacer.vue"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "PhotographyPage",
|
||||||
|
components: { XSpacer, TopBarLayout },
|
||||||
|
setup() {
|
||||||
|
return {
|
||||||
|
photos
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
834
pnpm-lock.yaml
generated
834
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
BIN
public/photography/Late_afternoon.webp
Normal file
BIN
public/photography/Late_afternoon.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 MiB |
BIN
public/photography/Martyrdom.webp
Normal file
BIN
public/photography/Martyrdom.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 373 KiB |
|
@ -3,7 +3,8 @@
|
||||||
"extends": "./.nuxt/tsconfig.json",
|
"extends": "./.nuxt/tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"types": [
|
"types": [
|
||||||
"nuxt-windicss"
|
"nuxt-windicss",
|
||||||
|
"unplugin-icons/types/vue"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
webstorm-shims.d.ts
vendored
Normal file
7
webstorm-shims.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// Taken from https://github.com/antfu/unplugin-icons/issues/128#issuecomment-992718883
|
||||||
|
|
||||||
|
declare module "~icons/*" {
|
||||||
|
import { FunctionalComponent, SVGAttributes } from "vue"
|
||||||
|
const component: FunctionalComponent<SVGAttributes>
|
||||||
|
export default component
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
import { defineConfig } from "windicss/helpers"
|
import { defineConfig } from "windicss/helpers"
|
||||||
import colors from "windicss/colors"
|
import colors from "windicss/colors"
|
||||||
import interactionVariantsPlugin from "@windicss/plugin-interaction-variants"
|
import scrollSnapPlugin from "windicss/plugin/scroll-snap"
|
||||||
|
import plugin from "windicss/plugin"
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
darkMode: "media",
|
darkMode: "media",
|
||||||
|
@ -12,14 +13,19 @@ export default defineConfig({
|
||||||
green: colors.green,
|
green: colors.green,
|
||||||
blue: colors.blue,
|
blue: colors.blue,
|
||||||
dark: colors.dark,
|
dark: colors.dark,
|
||||||
light: colors.light
|
light: colors.light,
|
||||||
|
background: "#070707"
|
||||||
},
|
},
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
sans: ["Plus Jakarta Sans", "sans-serif"],
|
sans: ["Plus Jakarta Sans", "sans-serif"]
|
||||||
special: ["SyneVariable", "monospace"]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
interactionVariantsPlugin
|
scrollSnapPlugin,
|
||||||
|
plugin(({ addVariant }) => {
|
||||||
|
addVariant("can-hover", ({ atRule }) => {
|
||||||
|
return atRule("@media(hover: hover)")
|
||||||
|
})
|
||||||
|
})
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue