Add Plugins page and more (#48)
* some progress, updating packages * migrate to SvelteKit 2 * progress * more stuff * hy3 banner * add links to features * fix distro option extra image * update community section * add plugins page link to plugins slice * community more profiles * add more community profiles * fix RSS not showing in prod (#45) * plugin page: better banner hover playback * improve community slice intro timing * remove fillter texts * improve command button * plugin install command wording improvment * footer adjustments * add dwindle-autogroup * stuff * community profile pictures hosted by Discord :P * fix autoplay previewRice Chrome * navbar: no entry delay * small community profile changes * optimize plugins layout * fix sorting * improve card performance * clean up test content from .md files * did more stuff * change desc of some plugins * work on design and layout * make main bg darker Creates less banding and looks a bit better, while also providing better contrast * nicer trim text * more stuff * fix messup * update plugins readme * add a profile picture * plugins: add gradient bg * remove placeholder plugins * plugins: improve mobile layout * community: small stuff * remove csgo vulkan fix logo * plugins: fix bg jumping on Firefox * plugin slug: improve animation staggering * small css fixes * pluginsSlice: animate only with slide Opacity change looks a bit off here * community: hide errored images --------- Co-authored-by: Vaxry <vaxry@vaxry.net>
2
.gitignore
vendored
|
@ -2,6 +2,8 @@ old
|
||||||
.svelte-kit
|
.svelte-kit
|
||||||
build
|
build
|
||||||
|
|
||||||
|
**/scratch.js
|
||||||
|
|
||||||
|
|
||||||
# For the generated blurred images
|
# For the generated blurred images
|
||||||
**/generated_*
|
**/generated_*
|
||||||
|
|
|
@ -29,4 +29,3 @@ Feel free
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
- [VDawg](https://github.com/Visual-Dawg) - for the new site and design.
|
- [VDawg](https://github.com/Visual-Dawg) - for the new site and design.
|
||||||
- [System-x64](https://github.com/System-x64) - for the original site code
|
|
||||||
|
|
55
package.json
|
@ -8,7 +8,7 @@
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"format": "prettier --plugin-search-dir . --write .",
|
"format": "prettier --plugin-search-dir . --write .",
|
||||||
"postinstall": "./scripts/generate-blurred-images.sh"
|
"postinstall": "node ./scripts/generate-blurred-images.mjs"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"hyprland"
|
"hyprland"
|
||||||
|
@ -24,41 +24,44 @@
|
||||||
"node": ">=16.0.0"
|
"node": ">=16.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify/json": "^2.2.140",
|
"@iconify/json": "^2.2.185",
|
||||||
"@interactjs/types": "^1.10.20",
|
"@interactjs/types": "^1.10.26",
|
||||||
"@sveltejs/adapter-static": "^2.0.3",
|
"@sveltejs/adapter-static": "^3.0.1",
|
||||||
"@sveltejs/kit": "^1.27.4",
|
"@sveltejs/kit": "^2.5.0",
|
||||||
"autoprefixer": "^10.4.16",
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||||
"eslint": "^8.53.0",
|
"autoprefixer": "^10.4.17",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-plugin-svelte": "^2.35.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
|
"eslint-plugin-svelte": "^2.35.1",
|
||||||
"mdsvex": "^0.11.0",
|
"mdsvex": "^0.11.0",
|
||||||
"postcss": "^8.4.31",
|
"postcss": "^8.4.35",
|
||||||
"prettier": "^3.0.3",
|
"prettier": "^3.2.5",
|
||||||
"prettier-plugin-svelte": "^3.1.0",
|
"prettier-plugin-svelte": "^3.2.1",
|
||||||
"simplex-noise": "^4.0.1",
|
"simplex-noise": "^4.0.1",
|
||||||
"svelte": "^4.2.3",
|
"svelte": "^4.2.11",
|
||||||
"svelte-check": "^3.6.0",
|
"svelte-check": "^3.6.4",
|
||||||
"tailwindcss": "^3.3.5",
|
"tailwindcss": "^3.4.1",
|
||||||
"tailwindcss-animate": "^1.0.7",
|
"tailwindcss-animate": "^1.0.7",
|
||||||
"typescript": "^5.2.2",
|
"typescript": "^5.3.3",
|
||||||
"unplugin-icons": "^0.17.3",
|
"unplugin-icons": "^0.18.5",
|
||||||
"vite": "^4.5.0"
|
"vite": "^5.1.4"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource-variable/work-sans": "^5.0.16",
|
"@fontsource-variable/work-sans": "^5.0.17",
|
||||||
"@fontsource/ibm-plex-mono": "^5.0.8",
|
"@fontsource/ibm-plex-mono": "^5.0.8",
|
||||||
|
"@tailwindcss/container-queries": "^0.1.1",
|
||||||
"@tailwindcss/typography": "^0.5.10",
|
"@tailwindcss/typography": "^0.5.10",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.1.0",
|
||||||
"interactjs": "^1.10.20",
|
"globby": "^14.0.1",
|
||||||
"prettier-plugin-tailwindcss": "^0.5.7",
|
"interactjs": "^1.10.26",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.5.11",
|
||||||
"rehype-slug": "^6.0.0",
|
"rehype-slug": "^6.0.0",
|
||||||
"remark-unwrap-images": "^4.0.0",
|
"remark-unwrap-images": "^4.0.0",
|
||||||
"remeda": "^1.29.0",
|
"remeda": "^1.43.0",
|
||||||
"rxjs": "^7.8.1",
|
"rxjs": "^7.8.1",
|
||||||
"shiki": "^0.14.7",
|
"shiki": "^1.1.6",
|
||||||
"svelte-inview": "^4.0.1",
|
"svelte-inview": "^4.0.2",
|
||||||
"ts-pattern": "^5.0.5"
|
"ts-pattern": "^5.0.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1029
pnpm-lock.yaml
98
scripts/generate-blurred-images.mjs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import { globby } from 'globby'
|
||||||
|
import { spawnSync } from 'node:child_process'
|
||||||
|
import { getFileNameWithoutExtension } from '../src/lib/Helper.mjs'
|
||||||
|
|
||||||
|
// This script should be run from the root of the application
|
||||||
|
const root = new URL('..', import.meta.url)
|
||||||
|
|
||||||
|
const imageDirectories = ['static/imgs/ricing_competitions', 'static/imgs/plugins/logos']
|
||||||
|
const generatedPrefix = 'generated_'
|
||||||
|
// This value seems to work well
|
||||||
|
const maxBrightness = 65535
|
||||||
|
|
||||||
|
const brightnessThreshold = maxBrightness * 0.5
|
||||||
|
|
||||||
|
/** All files which have no `generated_` version */
|
||||||
|
const filePaths = await globby(imageDirectories, {
|
||||||
|
cwd: root,
|
||||||
|
expandDirectories: {
|
||||||
|
extensions: ['svg', 'webp', 'jpg', 'png', 'gif', 'bmp', 'jpeg']
|
||||||
|
},
|
||||||
|
gitignore: false
|
||||||
|
}).then((filePaths) => {
|
||||||
|
const fileNames = filePaths.map(getFileNameWithoutExtension)
|
||||||
|
|
||||||
|
return filePaths
|
||||||
|
.filter(
|
||||||
|
(file) =>
|
||||||
|
!getFileNameWithoutExtension(file).startsWith(generatedPrefix) &&
|
||||||
|
!fileNames.includes(generatedPrefix + getFileNameWithoutExtension(file))
|
||||||
|
)
|
||||||
|
.map((filePath) => new URL(filePath, root))
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const filePath of filePaths) {
|
||||||
|
const extension = filePath.pathname.split('.').at(-1)
|
||||||
|
const generatedFileName = generatedPrefix + getFileNameWithoutExtension(filePath.href) + '.webp'
|
||||||
|
const outPath = new URL('.', filePath).pathname + generatedFileName
|
||||||
|
|
||||||
|
const currentBrightness = Number(
|
||||||
|
exec(`convert "${filePath.pathname}" -colorspace Gray -format "%[mean]" info: `)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Boost the brightness if the image is very dark
|
||||||
|
const brightnessIncrease = Math.max(1 - (currentBrightness / brightnessThreshold) * 50, 0)
|
||||||
|
|
||||||
|
// Nessecary to do it like that for Zx
|
||||||
|
const svgCommands = extension === 'svg' ? '-background none -resize 2500x2500' : ''
|
||||||
|
|
||||||
|
exec(
|
||||||
|
`magick convert ${svgCommands} -brightness-contrast ${brightnessIncrease}x40 -modulate 100,1000,100 ${filePath.pathname} ${outPath}`
|
||||||
|
)
|
||||||
|
|
||||||
|
// Modify colors with LUT
|
||||||
|
// spawnSync(`magick "${outPath}" "./scripts/hald-clut.color.io.png" -hald-clut "${outPath}"`)
|
||||||
|
// Also make them smaller to reduce file size
|
||||||
|
exec(
|
||||||
|
`magick convert -modulate 100,250,100 -scale 10% -gaussian-blur 0x20 -resize 500% -quality 50 "${outPath}" "${outPath}" `
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(`Blurred ${filePath.pathname}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function exec(command) {
|
||||||
|
const { stdout, error } = spawnSync(command, { shell: true })
|
||||||
|
if (error) throw error
|
||||||
|
|
||||||
|
return stdout
|
||||||
|
}
|
||||||
|
|
||||||
|
// // parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
|
||||||
|
|
||||||
|
// // cd "$parent_path"
|
||||||
|
|
||||||
|
// find "../static/imgs/ricing_competitions/" -type f \
|
||||||
|
// \( -iname "*.jpg" -o -iname "*.png" -o -iname "*.gif" -o -iname "*.bmp" -o -iname "*.jpeg" -o -iname "*.webp" \) -not -name "generated_*" -print0 |
|
||||||
|
// while IFS= read -r -d '' filepath; do
|
||||||
|
// echo "$filepath" gets blurred
|
||||||
|
|
||||||
|
// directory=$(dirname "$filepath")
|
||||||
|
// filename=$(basename "$filepath")
|
||||||
|
// generated_filename="${directory}/generated_${filename}"
|
||||||
|
// brightness=$( convert $filepath -colorspace Gray -format "%[mean]" info: )
|
||||||
|
// max_brightness="65535" # The possible maximum brightness possible from the previous command
|
||||||
|
// brightness_threshold=$( python -c "print( $max_brightness * 0.5 )" )
|
||||||
|
|
||||||
|
// # Boost the brightness if the image is very dark
|
||||||
|
// brightness_boost=$( python -c "print( max( (1 - ($brightness / $brightness_threshold)) * 50 , 0) )" )
|
||||||
|
|
||||||
|
// # Modify colors with LUT
|
||||||
|
// magick convert -brightness-contrast ${brightness_boost}x40 -modulate 100,1000,100 "$filepath" "$generated_filename"
|
||||||
|
// magick "$generated_filename" "./hald-clut.color.io.png" -hald-clut "$generated_filename"
|
||||||
|
// # Also make them smaller to reduce file size
|
||||||
|
// magick convert -modulate 100,250,100 -scale 10% -gaussian-blur 0x20 -resize 500% -quality 50 "$generated_filename" "$generated_filename"
|
||||||
|
|
||||||
|
// # magick convert -scale 10% -brightness-contrast ${brightness_boost}x25 -modulate 100,500,100 -gaussian-blur 0x20 -resize 1000% "$filepath" "$generated_filename"
|
||||||
|
// done
|
|
@ -1,30 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
|
|
||||||
|
|
||||||
cd "$parent_path"
|
|
||||||
|
|
||||||
find "../static/imgs/ricing_competitions/" -type f \
|
|
||||||
\( -iname "*.jpg" -o -iname "*.png" -o -iname "*.gif" -o -iname "*.bmp" -o -iname "*.jpeg" -o -iname "*.webp" \) -not -name "generated_*" -print0 |
|
|
||||||
while IFS= read -r -d '' filepath; do
|
|
||||||
echo "$filepath" gets blurred
|
|
||||||
|
|
||||||
directory=$(dirname "$filepath")
|
|
||||||
filename=$(basename "$filepath")
|
|
||||||
generated_filename="${directory}/generated_${filename}"
|
|
||||||
brightness=$( convert $filepath -colorspace Gray -format "%[mean]" info: )
|
|
||||||
max_brightness="65535" # The possible maximum brightness possible from the previous command
|
|
||||||
brightness_threshold=$( python -c "print( $max_brightness * 0.5 )" )
|
|
||||||
|
|
||||||
# Boost the brightness if the image is very dark
|
|
||||||
brightness_boost=$( python -c "print( max( (1 - ($brightness / $brightness_threshold)) * 50 , 0) )" )
|
|
||||||
|
|
||||||
# Modify colors with LUT
|
|
||||||
magick convert -brightness-contrast ${brightness_boost}x40 -modulate 100,1000,100 "$filepath" "$generated_filename"
|
|
||||||
magick "$generated_filename" "./hald-clut.color.io.png" -hald-clut "$generated_filename"
|
|
||||||
# Also make them smaller to reduce file size
|
|
||||||
magick convert -modulate 100,250,100 -scale 10% -gaussian-blur 0x20 -resize 500% -quality 50 "$generated_filename" "$generated_filename"
|
|
||||||
|
|
||||||
|
|
||||||
# magick convert -scale 10% -brightness-contrast ${brightness_boost}x25 -modulate 100,500,100 -gaussian-blur 0x20 -resize 1000% "$filepath" "$generated_filename"
|
|
||||||
done
|
|
10
src/content/plugins/borders-plus-plus.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
name: Borders++
|
||||||
|
url: https://github.com/hyprwm/hyprland-plugins
|
||||||
|
category: Design
|
||||||
|
tagline: Extra window borders
|
||||||
|
logo: /plugins-data/logos/Borders-plus-plus-logo.svg
|
||||||
|
featured: true
|
||||||
|
# banner: /imgs/profile_pictures/chan_1.webp
|
||||||
|
# weight: 100
|
||||||
|
---
|
6
src/content/plugins/csgo-vulkan-fix.md
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
name: CSGO Vulkan Fix
|
||||||
|
url: https://github.com/hyprwm/hyprland-plugins
|
||||||
|
category: Miscellaneous
|
||||||
|
tagline: CSGO custom resolutions fix
|
||||||
|
---
|
7
src/content/plugins/dwindle-autogroup.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
name: dwindle-autogroup
|
||||||
|
url: https://github.com/ItsDrike/hyprland-dwindle-autogroup
|
||||||
|
category: Layout
|
||||||
|
tagline: Auto-grouping for dwindle mode
|
||||||
|
featured: false
|
||||||
|
---
|
22
src/content/plugins/hy3.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
name: hy3
|
||||||
|
url: https://github.com/outfoxxed/hy3
|
||||||
|
category: Layout
|
||||||
|
tagline: i3 / Sway like layout
|
||||||
|
logo: /plugins-data/logos/hy3-logo.svg
|
||||||
|
banner: /plugins-data/hy3_banner.mp4
|
||||||
|
featured: true
|
||||||
|
---
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
- i3 like tiling
|
||||||
|
- Node based window manipulation (you can interact with multiple windows at once)
|
||||||
|
- Greatly improved tabbed node groups over base hyprland
|
||||||
|
- Optional autotiling
|
||||||
|
|
||||||
|
Additional features may be suggested in the repo issues or the [matrix room](https://matrix.to/#/#hy3:outfoxxed.me).
|
||||||
|
|
||||||
|
### Demo
|
||||||
|
|
||||||
|
<video controls="controls" src="https://user-images.githubusercontent.com/83010835/255322916-85ae8196-8b12-4e15-b060-9872db10839f.mp4"></video>
|
8
src/content/plugins/hyprbars.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: Hyprbars
|
||||||
|
url: https://github.com/hyprwm/hyprland-plugins
|
||||||
|
category: Design
|
||||||
|
tagline: Bring back title bars
|
||||||
|
logo: /plugins-data/logos/hyprbars-logo.svg
|
||||||
|
featured: true
|
||||||
|
---
|
8
src/content/plugins/hyprtrails.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: Hyprtrails
|
||||||
|
url: https://github.com/hyprwm/hyprland-plugins
|
||||||
|
category: Design
|
||||||
|
tagline: Smooth window trails
|
||||||
|
logo: /plugins-data/logos/hyprtrails-logo.svg
|
||||||
|
featured: true
|
||||||
|
---
|
8
src/content/plugins/hyprwinwrap.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
name: Hyprwinwrap
|
||||||
|
url: https://github.com/hyprwm/hyprland-plugins
|
||||||
|
category: Quality of Life
|
||||||
|
tagline: Any app as wallpaper
|
||||||
|
logo: /plugins-data/logos/hyprwinwrap-logo.svg
|
||||||
|
featured: true
|
||||||
|
---
|
18
src/content/plugins/readme.md
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Frontmatter
|
||||||
|
|
||||||
|
The `.md` files can have the following meta data:
|
||||||
|
|
||||||
|
- name: Name of the plugin
|
||||||
|
- tagline: Very concise description of the plugin
|
||||||
|
- url: Link to the Github repository
|
||||||
|
- docs: Link to the documentation. Optional
|
||||||
|
- website: Link to the website. Optional
|
||||||
|
- logo: Relative link to the logo placed in the `/static/plugins-data/logos/` directory (without the `/static/` though)
|
||||||
|
- tags: Tags for the plugin. Capitalized
|
||||||
|
- featured: Whether the plugin is featured at the top. A maximum of 4 is shown
|
||||||
|
- weight: Determines the sort order. A higher weight comes first.
|
||||||
|
|
||||||
|
## Banner
|
||||||
|
|
||||||
|
Please only use darkmode images/videos.
|
||||||
|
Do not use yellow and yellowish colors, unless nesssecary.
|
|
@ -93,9 +93,11 @@ export function getIsMobile() {
|
||||||
return check
|
return check
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the `generated_<filename>` if blurredThumbnail is not set manually **/
|
/** Get the `generated_<filename>` for the provided path **/
|
||||||
export function getBlurredPath(path) {
|
export function getGeneratedPath(path, extension = 'webp') {
|
||||||
return `${path.substring(0, path.lastIndexOf('/'))}/generated_${path.split('/').at(-1)}`
|
const directory = path.substring(0, path.lastIndexOf('/'))
|
||||||
|
const filename = getFileNameWithoutExtension(path)
|
||||||
|
return `${directory}/generated_${filename}.${extension}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get a random item from an array */
|
/** Get a random item from an array */
|
||||||
|
@ -110,3 +112,22 @@ export function formatDate(date, dateStyle = 'medium', locales = 'en') {
|
||||||
|
|
||||||
return dateFormatter.format(dateToFormat)
|
return dateFormatter.format(dateToFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {string} text
|
||||||
|
* @param {number} maxLenght
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function trimText(text, maxLenght) {
|
||||||
|
if (text.length < maxLenght - 1) return text
|
||||||
|
|
||||||
|
const lastSpace = text.slice(0, maxLenght).lastIndexOf(' ')
|
||||||
|
|
||||||
|
return text.slice(0, lastSpace ?? maxLenght) + '…'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Get the filename of a filepath without its extension */
|
||||||
|
export function getFileNameWithoutExtension(filePath) {
|
||||||
|
return filePath.split('/').at(-1).replace(/\..*$/, '')
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
export let type = 'primary'
|
export let type = 'primary'
|
||||||
|
|
||||||
$: classes = clsx(
|
$: classes = clsx(
|
||||||
'animate rounded text-sm font-bold hover:scale-[1.03] active:scale-95',
|
'animate rounded text-sm font-bold hover:scale-[1.01] active:scale-100',
|
||||||
'primary' == type && 'bg-slate-200 text-black',
|
'primary' == type && 'bg-slate-200 text-black',
|
||||||
'outline' == type && 'bg-transparent text-white outline outline-2 outline-slate-200',
|
'outline' == type && 'bg-transparent text-white outline outline-2 outline-slate-200',
|
||||||
'fancyOutline' == type && 'fancy',
|
'fancyOutline' == type && 'fancy',
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if type === 'fancyOutline'}
|
{#if type === 'fancyOutline'}
|
||||||
<div class="relative">
|
<div class="relative max-w-max">
|
||||||
<button class={classes} on:click><slot>NO LABEL PROVIDED</slot></button>
|
<button class={classes} on:click><slot>NO LABEL PROVIDED</slot></button>
|
||||||
<span
|
<span
|
||||||
class="fancy-bg absolute inset-0 -z-10 h-full w-[110%] min-w-[5rem] scale-y-75 bg-cyan-500/90 px-4 py-2 blur-xl"
|
class="fancy-bg absolute inset-0 -z-10 h-full w-[110%] min-w-[5rem] scale-y-75 bg-cyan-500/90 px-4 py-2 blur-xl"
|
||||||
|
|
83
src/routes/FeatureCard.svelte → src/lib/components/Card.svelte
Executable file → Normal file
|
@ -1,13 +1,15 @@
|
||||||
<script>
|
<script>
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { getContext, onMount } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
import { mouseContext } from './FeaturesSlice.svelte'
|
import { cardsContext } from '$lib/components/CardsContainer.svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
import { getIsMobile } from '$lib/Helper.mjs'
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
export let title
|
/** @type {'cyan' | 'purple'}*/
|
||||||
export let color = 'cyan'
|
export let color = 'cyan'
|
||||||
|
/** @type {number | number}*/
|
||||||
|
export let gradientOpacity = undefined
|
||||||
|
|
||||||
const { x: mouseX, y: mouseY, isHoverCards } = getContext(mouseContext)
|
const { mouseCoordinates$, isHoverCards, enableBorders = true } = getContext(cardsContext)
|
||||||
|
|
||||||
/** @type HTMLDivElement */
|
/** @type HTMLDivElement */
|
||||||
let container
|
let container
|
||||||
|
@ -15,10 +17,10 @@
|
||||||
|
|
||||||
const damping = 0.2
|
const damping = 0.2
|
||||||
|
|
||||||
const fillX = spring(999, { damping, stiffness: 0.021, precision: 0.3 })
|
const fillX = spring(0, { damping, stiffness: 0.021, precision: 0.3 })
|
||||||
const fillY = spring(999, { damping, stiffness: 0.021, precision: 0.3 })
|
const fillY = spring(0, { damping, stiffness: 0.021, precision: 0.3 })
|
||||||
const borderX = spring(999, { damping, stiffness: 0.03, precision: 0.3 })
|
const borderX = spring(0, { damping, stiffness: 0.03, precision: 0.3 })
|
||||||
const borderY = spring(999, { damping, stiffness: 0.03, precision: 0.3 })
|
const borderY = spring(0, { damping, stiffness: 0.03, precision: 0.3 })
|
||||||
|
|
||||||
const bounceBack = 2
|
const bounceBack = 2
|
||||||
const soft = 0.8
|
const soft = 0.8
|
||||||
|
@ -28,7 +30,7 @@
|
||||||
let hasMouseEntered = false
|
let hasMouseEntered = false
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (container && $mouseX !== undefined) {
|
if (container && $mouseCoordinates$?.x !== undefined) {
|
||||||
updateGradient()
|
updateGradient()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,11 +44,13 @@
|
||||||
|
|
||||||
const { x: rectX, y: rectY, width, height } = container.getBoundingClientRect()
|
const { x: rectX, y: rectY, width, height } = container.getBoundingClientRect()
|
||||||
|
|
||||||
const normX = $mouseX - rectX
|
const normX = $mouseCoordinates$.x - rectX
|
||||||
const normY = $mouseY - rectY
|
const normY = $mouseCoordinates$.y - rectY
|
||||||
|
|
||||||
|
if (enableBorders) {
|
||||||
$borderX = normX
|
$borderX = normX
|
||||||
$borderY = normY
|
$borderY = normY
|
||||||
|
}
|
||||||
|
|
||||||
if (!isMouseOver) {
|
if (!isMouseOver) {
|
||||||
hasMouseEntered = false
|
hasMouseEntered = false
|
||||||
|
@ -55,29 +59,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Instantly update the blob positon without easing when the mouse has just entered
|
// Instantly update the blob positon without easing when the mouse has just entered
|
||||||
if (hasMouseEntered === false) {
|
/* if (hasMouseEntered === false) {
|
||||||
fillX.set(normX, { hard: true })
|
fillX.set(normX, { hard: true })
|
||||||
fillY.set(normY, { hard: true })
|
fillY.set(normY, { hard: true })
|
||||||
hasMouseEntered = true
|
hasMouseEntered = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if ($mouseX < rectX) fillX.set(rectX + bounceBack, { soft })
|
if ($mouseCoordinates$.x < rectX) fillX.set(rectX + bounceBack, { soft })
|
||||||
else if ($mouseX > rectX + width) fillX.set(rectX + width - bounceBack, { soft })
|
else if ($mouseCoordinates$.x > rectX + width) fillX.set(rectX + width - bounceBack, { soft })
|
||||||
else fillX.set(normX)
|
else fillX.set(normX)
|
||||||
|
|
||||||
if ($mouseY < rectY) fillY.set(rectY + bounceBack, { soft: 1 })
|
if ($mouseCoordinates$.y < rectY) fillY.set(rectY + bounceBack, { soft: 1 })
|
||||||
if ($mouseY > rectY + height) fillX.set(rectY - height - bounceBack, { soft })
|
if ($mouseCoordinates$.y > rectY + height) fillX.set(rectY - height - bounceBack, { soft })
|
||||||
else fillY.set(normY)
|
else fillY.set(normY)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={clsx('card group min-h-[20rem]', $$restProps.class)}
|
class={clsx('card group ', $$restProps.class)}
|
||||||
style:--x={$fillX}
|
style:--x={$fillX}
|
||||||
style:--y={$fillY}
|
style:--y={$fillY}
|
||||||
style:--borderX={$borderX}
|
style:--borderX={enableBorders && $borderX}
|
||||||
style:--borderY={$borderY}
|
style:--borderY={enableBorders && $borderY}
|
||||||
class:isHoverCards={$isHoverCards}
|
class:isHoverCards={$isHoverCards}
|
||||||
bind:this={container}
|
bind:this={container}
|
||||||
on:mouseenter={() => (isMouseOver = true)}
|
on:mouseenter={() => (isMouseOver = true)}
|
||||||
|
@ -87,20 +92,22 @@
|
||||||
}}
|
}}
|
||||||
class:purpleGradient={color === 'purple'}
|
class:purpleGradient={color === 'purple'}
|
||||||
role="contentinfo"
|
role="contentinfo"
|
||||||
|
on:mouseenter
|
||||||
|
on:mouseleave
|
||||||
>
|
>
|
||||||
<div class="z-10 flex h-full w-full flex-col justify-end p-8 sm:p-12">
|
<div class="z-10 h-full w-full">
|
||||||
<h1 class="mb-6 text-5xl font-bold text-white">{title}</h1>
|
|
||||||
|
|
||||||
<slot>Nothing in the slot here</slot>
|
<slot>Nothing in the slot here</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="gradient max-sm:hidden" />
|
<div class="gradient max-sm:hidden" style:opacity={gradientOpacity} />
|
||||||
<div class="gradient_black max-sm:hidden" />
|
<div class="gradient_black max-sm:hidden" />
|
||||||
|
{#if enableBorders}
|
||||||
<div class="border-gradient max-sm:hidden" />
|
<div class="border-gradient max-sm:hidden" />
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.card {
|
.card {
|
||||||
@apply relative flex h-full w-full items-end justify-end rounded-3xl transition-colors duration-300;
|
@apply relative flex items-end justify-end rounded-3xl transition-colors duration-300;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
contain: paint style layout;
|
contain: paint style layout;
|
||||||
|
|
||||||
|
@ -112,7 +119,7 @@
|
||||||
|
|
||||||
/* The card border */
|
/* The card border */
|
||||||
@media screen(md) {
|
@media screen(md) {
|
||||||
background: theme(colors.slate.900);
|
background: theme(colors.slate.800);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: theme(colors.blue.900);
|
background: theme(colors.blue.900);
|
||||||
|
@ -125,13 +132,7 @@
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
contain: strict;
|
contain: strict;
|
||||||
background: black
|
background: black;
|
||||||
radial-gradient(
|
|
||||||
circle at bottom right,
|
|
||||||
theme(colors.neutral.900 / 80%),
|
|
||||||
theme(colors.neutral.500 / 10%),
|
|
||||||
black
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This gradient is visible on the borders when hovering */
|
/* This gradient is visible on the borders when hovering */
|
||||||
|
@ -143,12 +144,10 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
opacity: 0%;
|
opacity: 0%;
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
transition: opacity 120ms ease-in-out;
|
transition: opacity 240ms ease-in-out;
|
||||||
left: 0%;
|
left: 0%;
|
||||||
top: 0%;
|
top: 0%;
|
||||||
content: '';
|
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
filter: brightness(1.5) saturate(4);
|
|
||||||
contain: strict;
|
contain: strict;
|
||||||
background: radial-gradient(
|
background: radial-gradient(
|
||||||
620px circle at calc(var(--borderX) * 1px) calc(var(--borderY) * 1px),
|
620px circle at calc(var(--borderX) * 1px) calc(var(--borderY) * 1px),
|
||||||
|
@ -180,27 +179,27 @@
|
||||||
min-width: 200%;
|
min-width: 200%;
|
||||||
min-height: 200%;
|
min-height: 200%;
|
||||||
aspect-ratio: 1 / 1;
|
aspect-ratio: 1 / 1;
|
||||||
scale: 0.5 0.5;
|
|
||||||
translate: -25% 0%;
|
translate: -25% 0%;
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
opacity: 0%;
|
opacity: 50%;
|
||||||
transition: all 820ms;
|
transition: all 120ms ease-in-out;
|
||||||
content: '';
|
content: '';
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
background: radial-gradient(
|
opacity: 0%;
|
||||||
|
contain: strict;
|
||||||
|
|
||||||
|
background: url('/imgs/grain.webp'),
|
||||||
|
radial-gradient(
|
||||||
ellipse at calc(var(--x) * 1px) calc(var(--y) * 1px),
|
ellipse at calc(var(--x) * 1px) calc(var(--y) * 1px),
|
||||||
var(--color1, theme(colors.cyan.500 / 100%)),
|
var(--color1, theme(colors.cyan.500 / 100%)),
|
||||||
var(--color2, theme(colors.blue.700 / 40%)) 25%,
|
var(--color2, theme(colors.blue.700 / 40%)) 25%,
|
||||||
var(--color3, theme(colors.blue.900 / 15%)) 50%
|
var(--color3, theme(colors.blue.900 / 15%)) 50%
|
||||||
);
|
);
|
||||||
|
|
||||||
.card:hover & {
|
|
||||||
scale: 1 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group:hover & {
|
.group:hover & {
|
||||||
opacity: 100%;
|
opacity: 100%;
|
||||||
|
transition: all 820ms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
53
src/lib/components/CardsContainer.svelte
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
<script context="module">
|
||||||
|
export const cardsContext = Symbol('mouseContext')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
|
import { BehaviorSubject, Subject, throttle, throttleTime } from 'rxjs'
|
||||||
|
|
||||||
|
import { onMount, setContext } from 'svelte'
|
||||||
|
import { writable } from 'svelte/store'
|
||||||
|
|
||||||
|
export let enableBorders = true
|
||||||
|
|
||||||
|
const fps = 1000 / 60
|
||||||
|
|
||||||
|
/** @type {HTMLElement}*/
|
||||||
|
let containerElement
|
||||||
|
let isMobile = false
|
||||||
|
|
||||||
|
const context = setContext(cardsContext, {
|
||||||
|
mouseCoordinates$: new BehaviorSubject({ x: 0, y: 0 }).pipe(throttleTime(fps)),
|
||||||
|
isHoverCards: writable(false),
|
||||||
|
enableBorders
|
||||||
|
})
|
||||||
|
|
||||||
|
function onMouseEnter() {
|
||||||
|
containerElement.addEventListener('mousemove', trackMouse)
|
||||||
|
context.isHoverCards.set(true)
|
||||||
|
}
|
||||||
|
function onMouseLeave() {
|
||||||
|
containerElement.removeEventListener('mousemove', trackMouse)
|
||||||
|
context.isHoverCards.set(false)
|
||||||
|
}
|
||||||
|
function trackMouse({ clientX, clientY }) {
|
||||||
|
context.mouseCoordinates$.next({ x: clientX, y: clientY })
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
isMobile = getIsMobile()
|
||||||
|
|
||||||
|
return () => containerElement.removeEventListener('mousemove', trackMouse)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={$$restProps.class}
|
||||||
|
bind:this={containerElement}
|
||||||
|
role="contentinfo"
|
||||||
|
on:mouseenter={!isMobile && onMouseEnter}
|
||||||
|
on:mouseleave={!isMobile && onMouseLeave}
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
75
src/lib/components/CommandButton.svelte
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<script>
|
||||||
|
import { onDestroy } from 'svelte'
|
||||||
|
import ClipboardIcon from '~icons/mingcute/copy-2-line'
|
||||||
|
|
||||||
|
/** @type {string} */
|
||||||
|
export let command
|
||||||
|
/** @type {string | undefined }*/
|
||||||
|
export let commandClass = undefined
|
||||||
|
/** @type {string | undefined }*/
|
||||||
|
export let containerClass = undefined
|
||||||
|
|
||||||
|
let isShowingCopied = false
|
||||||
|
let timeoutId
|
||||||
|
|
||||||
|
async function copyCommand() {
|
||||||
|
await navigator.clipboard.writeText(command).then(() => (isShowingCopied = true))
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => (isShowingCopied = false), 1400)
|
||||||
|
}
|
||||||
|
|
||||||
|
onDestroy(() => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="relative flex grow flex-col font-mono {containerClass ?? ''}">
|
||||||
|
<button
|
||||||
|
class="group flex min-w-[18rem] items-center justify-center gap-4 rounded-lg border border-primary py-3 pl-6 pr-6 text-base font-medium transition-transform active:scale-[1.01] sm:rounded-full"
|
||||||
|
on:click={$$slots.default ? undefined : copyCommand}
|
||||||
|
on:click
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<div class="relative flex w-full justify-between gap-4">
|
||||||
|
<div class="flex gap-4">
|
||||||
|
<div class="select-none font-bold text-primary">></div>
|
||||||
|
<span class={commandClass}>{command}</span>
|
||||||
|
</div>
|
||||||
|
<ClipboardIcon
|
||||||
|
class="hidden h-6 w-6 text-white opacity-50 transition-opacity duration-100 hover:!opacity-100 group-hover:opacity-80 group-active:opacity-100 md:block"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</slot>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="pointer-events-none absolute left-1/2 z-20 hidden w-full max-w-max select-none rounded-full bg-black/10 px-2 text-green-400 backdrop-blur [translate:-50%_0px] max-md:-bottom-6 md:-top-8"
|
||||||
|
class:copy={isShowingCopied}
|
||||||
|
>
|
||||||
|
Copied to clipboard ✔
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{#if $$slots.extra}
|
||||||
|
<div class="mt-3 flex w-full font-sans text-xs opacity-80">
|
||||||
|
<slot name="extra" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.copy {
|
||||||
|
animation: 80ms cubic-bezier(0.5, 0.2, 0, 1.5) 1 copy;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes copy {
|
||||||
|
from {
|
||||||
|
opacity: 0.8;
|
||||||
|
scale: 0.98;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
scale: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2,7 +2,7 @@
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { createEventDispatcher, getContext, onDestroy, onMount } from 'svelte'
|
import { createEventDispatcher, getContext, onDestroy, onMount } from 'svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
import { contextId as ctxId } from '../../routes/CommunitySlice.svelte'
|
import { contextId as ctxId } from '../../routes/home-slices/CommunitySlice.svelte'
|
||||||
import { lerp } from '$lib/Helper.mjs'
|
import { lerp } from '$lib/Helper.mjs'
|
||||||
import { inview } from 'svelte-inview'
|
import { inview } from 'svelte-inview'
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
const relativeSize = size / biggestSize
|
const relativeSize = size / biggestSize
|
||||||
const delay = (biggestSize - size) * 5
|
const delay = Math.pow(1 - size / biggestSize, 4) * 4654
|
||||||
const dragCoordinates = spring([0, 0], {
|
const dragCoordinates = spring([0, 0], {
|
||||||
damping: lerp(0.2, 0.03, relativeSize),
|
damping: lerp(0.2, 0.03, relativeSize),
|
||||||
stiffness: lerp(0.2, 0.01, relativeSize),
|
stiffness: lerp(0.2, 0.01, relativeSize),
|
||||||
|
@ -48,6 +48,8 @@
|
||||||
let interactionjs
|
let interactionjs
|
||||||
|
|
||||||
function onViewEnter() {
|
function onViewEnter() {
|
||||||
|
if (imageElement.__error) return
|
||||||
|
|
||||||
setTimeout(() => (hasEnteredView = true), 550)
|
setTimeout(() => (hasEnteredView = true), 550)
|
||||||
|
|
||||||
// Only load the library if the element entered the view, to improve performance
|
// Only load the library if the element entered the view, to improve performance
|
||||||
|
@ -106,7 +108,7 @@
|
||||||
)}
|
)}
|
||||||
style:translate={`calc( ${$dragCoordinates[0]}px ) ${$dragCoordinates[1]}px`}
|
style:translate={`calc( ${$dragCoordinates[0]}px ) ${$dragCoordinates[1]}px`}
|
||||||
use:inview={{ unobserveOnEnter: true, threshold: 0.2 }}
|
use:inview={{ unobserveOnEnter: true, threshold: 0.2 }}
|
||||||
class:_animate={isAnimating && hasEnteredView}
|
class:_animate={hasImageLoaded && isAnimating && hasEnteredView}
|
||||||
on:inview_enter={onViewEnter}
|
on:inview_enter={onViewEnter}
|
||||||
>
|
>
|
||||||
<div class="" bind:this={imageWrapper}>
|
<div class="" bind:this={imageWrapper}>
|
||||||
|
@ -120,6 +122,11 @@
|
||||||
on:mouseenter={(event) => dispatch('hover', event)}
|
on:mouseenter={(event) => dispatch('hover', event)}
|
||||||
class:hover:scale-125={!!quote}
|
class:hover:scale-125={!!quote}
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
crossorigin="anonymous"
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
onerror="this.__error = true"
|
||||||
/>
|
/>
|
||||||
<slot />
|
<slot />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -8,8 +8,7 @@
|
||||||
let team = [
|
let team = [
|
||||||
['Fufexan', 'Supporting Developer', 'cyan', 'https://github.com/fufexan'],
|
['Fufexan', 'Supporting Developer', 'cyan', 'https://github.com/fufexan'],
|
||||||
['NotAShelf', 'Real Chad', 'teal', 'https://github.com/NotAShelf'],
|
['NotAShelf', 'Real Chad', 'teal', 'https://github.com/NotAShelf'],
|
||||||
['VDawg', 'Webdesign-and dev', 'emerald', 'https://github.com/Visual-Dawg'],
|
['VDawg', 'Webdesign-and dev', 'emerald', 'https://github.com/Visual-Dawg']
|
||||||
['System-x64', 'Webdev', 'green', 'https://github.com/System-x64']
|
|
||||||
]
|
]
|
||||||
function createRole(role, color) {
|
function createRole(role, color) {
|
||||||
return `<span class='text-${color}-500'><span class='text-${color}-600'>[ </span>${role}<span class='text-${color}-600'> ]</span></span>`
|
return `<span class='text-${color}-500'><span class='text-${color}-600'>[ </span>${role}<span class='text-${color}-600'> ]</span></span>`
|
||||||
|
@ -20,7 +19,7 @@
|
||||||
class="max-w-screen relative mt-16 flex items-center justify-center border-t border-blue-400/50 bg-black/50 md:mt-24 lg:mt-32"
|
class="max-w-screen relative mt-16 flex items-center justify-center border-t border-blue-400/50 bg-black/50 md:mt-24 lg:mt-32"
|
||||||
>
|
>
|
||||||
<div class="footer-inner">
|
<div class="footer-inner">
|
||||||
<div class="flex flex-col gap-4 rounded-lg">
|
<div class="flex grow flex-col gap-4 rounded-lg">
|
||||||
<div class="pretitle">Humans</div>
|
<div class="pretitle">Humans</div>
|
||||||
<ul class="flex flex-col gap-3 font-medium">
|
<ul class="flex flex-col gap-3 font-medium">
|
||||||
<li>
|
<li>
|
||||||
|
@ -99,7 +98,7 @@
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.footer-inner {
|
.footer-inner {
|
||||||
@apply flex max-w-5xl flex-wrap items-start justify-between gap-12 px-8 py-14 text-slate-300;
|
@apply flex max-w-screen-2xl flex-wrap items-start justify-between gap-12 px-8 py-14 text-slate-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pretitle {
|
.pretitle {
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
<Navbar />
|
<Navbar />
|
||||||
|
|
||||||
<main class="mx-auto flex min-h-screen w-full flex-col overflow-hidden">
|
<main class="mx-auto flex min-h-screen w-full flex-col">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,20 @@
|
||||||
<script>
|
<script>
|
||||||
import Community from './CommunitySlice.svelte'
|
import Community from './home-slices/CommunitySlice.svelte'
|
||||||
import FeaturesSlice from './FeaturesSlice.svelte'
|
import FeaturesSlice from './home-slices/FeaturesSlice.svelte'
|
||||||
import HallOfFameSlice from './HallOfFameSlice.svelte'
|
import HallOfFameSlice from './home-slices/HallOfFameSlice.svelte'
|
||||||
import Hero from './Hero.svelte'
|
import Hero from './home-slices/Hero.svelte'
|
||||||
import InstallSlice from './InstallSlice.svelte'
|
import InstallSlice from './home-slices/InstallSlice.svelte'
|
||||||
import PreviewRiceSlice from './PreviewRiceSlice.svelte'
|
import PreviewRiceSlice from './home-slices/PreviewRiceSlice.svelte'
|
||||||
import PluginsSlice from './PluginsSlice.svelte'
|
import PluginsSlice from './home-slices/PluginsSlice.svelte'
|
||||||
import NewsSlice from './NewsSlice.svelte'
|
import NewsSlice from './home-slices/NewsSlice.svelte'
|
||||||
|
|
||||||
export let data
|
export let data
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Hero backgroundData={data.backgroundData} />
|
<div class="overflow-hidden">
|
||||||
|
<Hero backgroundData={data.backgroundData} />
|
||||||
|
|
||||||
<div class="-mt-8 flex flex-col items-center gap-20 md:gap-[16rem]">
|
<div class="-mt-8 flex flex-col items-center gap-20 md:gap-[16rem]">
|
||||||
<PreviewRiceSlice class="mb-12" />
|
<PreviewRiceSlice class="mb-12" />
|
||||||
|
|
||||||
<FeaturesSlice />
|
<FeaturesSlice />
|
||||||
|
@ -27,6 +28,7 @@
|
||||||
<NewsSlice news={data.news} />
|
<NewsSlice news={data.news} />
|
||||||
|
|
||||||
<InstallSlice />
|
<InstallSlice />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
|
@ -38,6 +40,3 @@
|
||||||
/>
|
/>
|
||||||
<meta property="og:title" content="Hyprland: Dynamic tiling window compositor with the looks" />
|
<meta property="og:title" content="Hyprland: Dynamic tiling window compositor with the looks" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -1,282 +0,0 @@
|
||||||
<script context="module">
|
|
||||||
export const contextId = Symbol('community context')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Button from '$lib/components/Button.svelte'
|
|
||||||
import DiscordIcon from '~icons/prime/discord'
|
|
||||||
import DiscordProfilePicture from '$lib/components/DiscordProfilePicture.svelte'
|
|
||||||
import { setContext } from 'svelte'
|
|
||||||
import Title from '$lib/components/Title.svelte'
|
|
||||||
import background from '$lib/images/community-bg.webp'
|
|
||||||
import amongUsGreenImage from '$lib/images/amongus/green.webp'
|
|
||||||
import { discordLink } from '$lib/constants.mjs'
|
|
||||||
|
|
||||||
let sectionElement
|
|
||||||
let isDraggingChan = false
|
|
||||||
|
|
||||||
/** @type {{image: string coordinates: [number, number] containerClass: string}[], size: number, quote?: string } */
|
|
||||||
const profiles = [
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/vaxry.webp',
|
|
||||||
coordinates: [187, 296],
|
|
||||||
size: 172,
|
|
||||||
class: 'outline-red-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/fufexan.webp',
|
|
||||||
coordinates: [735, 441],
|
|
||||||
size: 164,
|
|
||||||
class: 'outline-yellow-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/raf-notashelf.webp',
|
|
||||||
coordinates: [391, 615],
|
|
||||||
size: 149,
|
|
||||||
class: 'outline-orange-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/Mathisbuilder.webp',
|
|
||||||
coordinates: [568, 594],
|
|
||||||
size: 120,
|
|
||||||
class: 'outline-amber-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/dani_666..webp',
|
|
||||||
coordinates: [525, 764],
|
|
||||||
size: 80,
|
|
||||||
class: 'outline-red-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/end_4.webp',
|
|
||||||
coordinates: [648, 709],
|
|
||||||
size: 128,
|
|
||||||
class: 'outline-cyan-400'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/ardishco.webp',
|
|
||||||
coordinates: [65, 208],
|
|
||||||
size: 100,
|
|
||||||
class: 'outline-slate-200'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/kcrmson.webp',
|
|
||||||
coordinates: [53, 399],
|
|
||||||
size: 75,
|
|
||||||
class: 'outline-sky-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/loseardes77.webp',
|
|
||||||
coordinates: [24, 341],
|
|
||||||
size: 49,
|
|
||||||
class: 'outline-green-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/captainiveau.webp',
|
|
||||||
coordinates: [47, 86],
|
|
||||||
size: 48,
|
|
||||||
class: 'outline-red-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/etrigan63.webp',
|
|
||||||
coordinates: [824, 738],
|
|
||||||
size: 58,
|
|
||||||
class: 'outline-amber-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/jsw.webp',
|
|
||||||
coordinates: [41, 566],
|
|
||||||
size: 49,
|
|
||||||
class: 'outline-sky-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: 'imgs/chan/joy.svg',
|
|
||||||
coordinates: [284, 533],
|
|
||||||
size: 90,
|
|
||||||
class: 'outline-cyan-500 bg-blue-300',
|
|
||||||
onDragStart: ({ detail: { currentTarget } }) => {
|
|
||||||
isDraggingChan = true
|
|
||||||
currentTarget.src = 'imgs/chan/surprise.svg'
|
|
||||||
},
|
|
||||||
onDragEnd: ({ detail: { currentTarget } }) => {
|
|
||||||
isDraggingChan = false
|
|
||||||
currentTarget.src = 'imgs/chan/tongueout.svg'
|
|
||||||
},
|
|
||||||
onHover: ({ detail: { srcElement } }) =>
|
|
||||||
!isDraggingChan && (srcElement.src = 'imgs/chan/wink.svg')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/7.webp',
|
|
||||||
coordinates: [273, 760],
|
|
||||||
size: 52,
|
|
||||||
quote: '"meds"',
|
|
||||||
class: 'outline-cyan-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/outfoxxed.webp',
|
|
||||||
coordinates: [648, 364],
|
|
||||||
size: 80,
|
|
||||||
class: 'outline-orange-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/kirottum.webp',
|
|
||||||
coordinates: [772, 651],
|
|
||||||
size: 62,
|
|
||||||
class: 'outline-purple-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/beardwarrior.webp',
|
|
||||||
coordinates: [736, 277],
|
|
||||||
size: 87,
|
|
||||||
class: 'outline-amber-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/neoney.webp',
|
|
||||||
coordinates: [898, 364],
|
|
||||||
size: 68,
|
|
||||||
class: 'outline-green-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: amongUsGreenImage,
|
|
||||||
coordinates: [873, 224],
|
|
||||||
size: 79,
|
|
||||||
class: 'outline-green-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/SimplyKyle!.webp',
|
|
||||||
coordinates: [859, 159],
|
|
||||||
size: 39,
|
|
||||||
class: 'outline-rose-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/sioodmy.webp',
|
|
||||||
coordinates: [974, 107],
|
|
||||||
size: 48,
|
|
||||||
class: 'outline-amber-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/flafy.webp',
|
|
||||||
coordinates: [147, 553],
|
|
||||||
size: 87,
|
|
||||||
class: 'outline-pink-500'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/vagahbond.webp',
|
|
||||||
coordinates: [65, 643],
|
|
||||||
size: 74,
|
|
||||||
class: 'outline-amber-500 '
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/flick0.webp',
|
|
||||||
coordinates: [263, 653],
|
|
||||||
size: 65,
|
|
||||||
class: 'outline-stone-500 '
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/jacekpoz.svg',
|
|
||||||
coordinates: [893, 622],
|
|
||||||
size: 80,
|
|
||||||
class: 'outline-yellow-500 bg-black ',
|
|
||||||
quote: '"piss blob"'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/aylur.webp',
|
|
||||||
coordinates: [354, 798],
|
|
||||||
size: 80,
|
|
||||||
class: 'outline-amber-500 bg-black '
|
|
||||||
},
|
|
||||||
{
|
|
||||||
image: '/imgs/profile_pictures/aleph.nought.webp',
|
|
||||||
coordinates: [583, 824],
|
|
||||||
size: 40,
|
|
||||||
class: 'outline-blue-500 bg-black '
|
|
||||||
}
|
|
||||||
].sort(({ size: a }, { size: b }) => b - a)
|
|
||||||
|
|
||||||
setContext(contextId, {
|
|
||||||
biggestSize: profiles.reduce(
|
|
||||||
(previousSize, { size }) => (size > previousSize ? size : previousSize),
|
|
||||||
1
|
|
||||||
),
|
|
||||||
smallestSize: profiles.reduce(
|
|
||||||
(previousSize, { size }) => (size < previousSize ? size : previousSize),
|
|
||||||
Number.POSITIVE_INFINITY
|
|
||||||
),
|
|
||||||
getSectionElement: () => sectionElement
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<section
|
|
||||||
class="relative -mb-[200px] flex h-[1100px] min-h-max w-screen flex-col items-center"
|
|
||||||
bind:this={sectionElement}
|
|
||||||
>
|
|
||||||
<Title>
|
|
||||||
<span slot="title">Join a great<br />community</span>
|
|
||||||
|
|
||||||
<span slot="subtitle">
|
|
||||||
Get help from Distro Hoppers, Haiku writers,<br />Hydrohomies, and human_(probably)
|
|
||||||
</span>
|
|
||||||
</Title>
|
|
||||||
|
|
||||||
<div class="group mt-16 flex flex-col items-center">
|
|
||||||
<a
|
|
||||||
class="discord p-4"
|
|
||||||
href={discordLink}
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener"
|
|
||||||
aria-label="Join us on Discord"
|
|
||||||
>
|
|
||||||
<DiscordIcon class="h-full w-full " />
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a href={discordLink}>
|
|
||||||
<Button type="fancyOutline">Join us on Discord</Button>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="absolute w-[1024px] select-none">
|
|
||||||
<div class="flex h-full origin-bottom-right select-none flex-wrap gap-4">
|
|
||||||
{#each profiles as { onDragEnd, onDragStart, onHover, ...props }}
|
|
||||||
<DiscordProfilePicture
|
|
||||||
{...props}
|
|
||||||
on:dragStart={onDragStart}
|
|
||||||
on:dragEnd={onDragEnd}
|
|
||||||
on:hover={onHover}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<img
|
|
||||||
src={background}
|
|
||||||
class="absolute top-0 -z-10 min-w-[1400px] select-none"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
.discord {
|
|
||||||
width: 9rem;
|
|
||||||
height: 9rem;
|
|
||||||
transition:
|
|
||||||
rotate 500ms cubic-bezier(0.5, 0, 0.5, 1),
|
|
||||||
scale 420ms cubic-bezier(0.5, 0.1, 0, 1),
|
|
||||||
filter 840ms;
|
|
||||||
transition-delay: 240ms, 180ms, 20ms;
|
|
||||||
transform: translateY(-25%);
|
|
||||||
filter: drop-shadow(0px 0px 0px cyan) drop-shadow(0px 0px 0px blue);
|
|
||||||
|
|
||||||
&:hover,
|
|
||||||
.group:hover & {
|
|
||||||
scale: 1.2 1.2;
|
|
||||||
rotate: 360deg;
|
|
||||||
filter: drop-shadow(4px 4px 14px #0fffef7a) drop-shadow(-4px -4px 12px purple);
|
|
||||||
animation: bounce 0.7s infinite 180ms both;
|
|
||||||
}
|
|
||||||
&:active {
|
|
||||||
scale: 1;
|
|
||||||
transition: scale 80ms;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,213 +0,0 @@
|
||||||
<script context="module">
|
|
||||||
export const mouseContext = Symbol('mouseContext')
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import FeatureCard from './FeatureCard.svelte'
|
|
||||||
import { setContext, onMount } from 'svelte'
|
|
||||||
import { writable } from 'svelte/store'
|
|
||||||
import PluginsIcon from '~icons/gg/arrange-back'
|
|
||||||
import ShortcutsIcon from '~icons/gg/push-chevron-right-o'
|
|
||||||
import TouchpadIcon from '~icons/gg/touchpad'
|
|
||||||
import Title from '$lib/components/Title.svelte'
|
|
||||||
import Hypractive from './Hypractive.svelte'
|
|
||||||
import { getIsMobile } from '$lib/Helper.mjs'
|
|
||||||
import configDefaultImage from '$lib/images/features/config_default.webp'
|
|
||||||
import configHoverImage from '$lib/images/features/config_hover.webp'
|
|
||||||
import smoothDefaultImage from '$lib/images/features/smooth_default.webp'
|
|
||||||
import smoothHoverImage from '$lib/images/features/smooth_hover.webp'
|
|
||||||
import tileDefaultImage from '$lib/images/features/tiling_default.webp'
|
|
||||||
import tileHoverImage from '$lib/images/features/tiling_hover.webp'
|
|
||||||
|
|
||||||
let isMobile = false
|
|
||||||
|
|
||||||
const context = setContext(mouseContext, {
|
|
||||||
x: writable(0),
|
|
||||||
y: writable(0),
|
|
||||||
isHoverCards: writable(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
/** @type HTMLDivElement */
|
|
||||||
let featuresContainer
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
isMobile = getIsMobile()
|
|
||||||
})
|
|
||||||
|
|
||||||
function onMouseEnter() {
|
|
||||||
featuresContainer.addEventListener('mousemove', trackMouse)
|
|
||||||
context.isHoverCards.set(true)
|
|
||||||
}
|
|
||||||
function onMouseLeave() {
|
|
||||||
featuresContainer.removeEventListener('mousemove', trackMouse)
|
|
||||||
context.isHoverCards.set(false)
|
|
||||||
}
|
|
||||||
function trackMouse({ clientX, clientY }) {
|
|
||||||
context.x.set(clientX)
|
|
||||||
context.y.set(clientY)
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<section class="relative flex flex-col items-center px-3 md:px-8">
|
|
||||||
<Title>
|
|
||||||
<span slot="pre">TLDR</span>
|
|
||||||
<span slot="title">Features</span>
|
|
||||||
</Title>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="group grid w-full flex-wrap gap-6 text-lg font-medium text-white/70 lg:grid-cols-2 lg:grid-rows-2"
|
|
||||||
role="contentinfo"
|
|
||||||
on:mouseenter={!isMobile && onMouseEnter}
|
|
||||||
on:mouseleave={!isMobile && onMouseLeave}
|
|
||||||
bind:this={featuresContainer}
|
|
||||||
>
|
|
||||||
<FeatureCard title="Smooth" class="row-span-2" color="purple">
|
|
||||||
<p class="max-w-[60ch]">
|
|
||||||
Smooth transitions. Great animations. High performance. Instant input.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="_wrapper absolute inset-0 select-none" aria-hidden="true">
|
|
||||||
<div class="feature-image">
|
|
||||||
<img
|
|
||||||
src={smoothDefaultImage}
|
|
||||||
class="feature-image_inner"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src={smoothHoverImage}
|
|
||||||
class="feature-image_inner-hover"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FeatureCard>
|
|
||||||
<FeatureCard title="Easy to configure" color="purple">
|
|
||||||
<p class="max-w-[60ch]">
|
|
||||||
Live reloading config. Easy plain-text format. Sensible defaults. Great documentation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="_wrapper absolute inset-0 select-none" aria-hidden="true">
|
|
||||||
<div class="feature-image">
|
|
||||||
<img
|
|
||||||
src={configDefaultImage}
|
|
||||||
class="feature-image_inner"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src={configHoverImage}
|
|
||||||
class="feature-image_inner-hover"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FeatureCard>
|
|
||||||
<FeatureCard class="" title="Dynamic tiling" color="purple">
|
|
||||||
<p class="max-w-[60ch]">
|
|
||||||
Automatic tiling that just works. Supports multiple fine-tuneable layouts.
|
|
||||||
</p>
|
|
||||||
<div class="_wrapper absolute inset-0 select-none" aria-hidden="true">
|
|
||||||
<div class="feature-image">
|
|
||||||
<img
|
|
||||||
src={tileDefaultImage}
|
|
||||||
class="feature-image_inner"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src={tileHoverImage}
|
|
||||||
class="feature-image_inner-hover"
|
|
||||||
alt=""
|
|
||||||
aria-hidden="true"
|
|
||||||
loading="lazy"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</FeatureCard>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="z-10 mt-14 flex flex-col flex-wrap justify-center gap-8 text-lg sm:flex-row">
|
|
||||||
<a
|
|
||||||
href="https://github.com/hyprland-community/awesome-hyprland#plugins"
|
|
||||||
target="_blank"
|
|
||||||
class="icon-feature hover:underline"
|
|
||||||
>
|
|
||||||
<PluginsIcon class="h-8 w-8" />
|
|
||||||
Plugin system
|
|
||||||
</a>
|
|
||||||
<Hypractive />
|
|
||||||
<a
|
|
||||||
href="https://wiki.hyprland.org/Configuring/Binds/#global-keybinds"
|
|
||||||
target="_blank"
|
|
||||||
class="icon-feature hover:underline"
|
|
||||||
>
|
|
||||||
<ShortcutsIcon class="h-8 w-8" />
|
|
||||||
Global shortcuts for apps
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://wiki.hyprland.org/Configuring/Variables/#gestures"
|
|
||||||
class="icon-feature hover:underline"
|
|
||||||
target="_blank"
|
|
||||||
>
|
|
||||||
<TouchpadIcon class="h-8 w-8" />Touchpad gestures
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
.icon-feature {
|
|
||||||
@apply flex items-center justify-center gap-3 font-bold text-slate-400;
|
|
||||||
}
|
|
||||||
|
|
||||||
.feature-image {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0 0 0 0;
|
|
||||||
opacity: 0.5;
|
|
||||||
z-index: -10;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
transition: opacity 180ms ease-in-out;
|
|
||||||
|
|
||||||
._wrapper:hover & {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
& img {
|
|
||||||
position: absolute;
|
|
||||||
transition: opacity 1500ms ease-in-out;
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
width: 400px;
|
|
||||||
aspect-ratio: 1;
|
|
||||||
right: -80px;
|
|
||||||
top: 50%;
|
|
||||||
translate: 0px -50%;
|
|
||||||
|
|
||||||
@media screen(md) {
|
|
||||||
width: 600px;
|
|
||||||
right: -80px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.feature-image_inner-hover {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
._wrapper:hover {
|
|
||||||
& .feature-image_inner {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
& .feature-image_inner-hover {
|
|
||||||
opacity: 1 !important;
|
|
||||||
filter: saturate(1.3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,83 +0,0 @@
|
||||||
<script>
|
|
||||||
import { onDestroy } from 'svelte'
|
|
||||||
import ClipboardIcon from '~icons/mingcute/copy-2-line'
|
|
||||||
|
|
||||||
/** @type {string} */
|
|
||||||
export let command
|
|
||||||
/** @type {string} */
|
|
||||||
export let image
|
|
||||||
/** @type {string} */
|
|
||||||
export let name
|
|
||||||
|
|
||||||
let isShowingCopied = false
|
|
||||||
let timeoutId
|
|
||||||
|
|
||||||
async function copyCommand() {
|
|
||||||
await navigator.clipboard.writeText(command).then(() => (isShowingCopied = true))
|
|
||||||
clearTimeout(timeoutId)
|
|
||||||
timeoutId = setTimeout(() => (isShowingCopied = false), 1400)
|
|
||||||
}
|
|
||||||
|
|
||||||
onDestroy(() => {
|
|
||||||
clearTimeout(timeoutId)
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="group flex flex-col items-center gap-2 md:flex-row md:gap-4">
|
|
||||||
<div
|
|
||||||
class="relative flex h-32 w-32 flex-col items-center justify-center gap-3 rounded-full text-lg font-medium text-primary transition-transform group-focus-within:-translate-y-1"
|
|
||||||
>
|
|
||||||
<img src={image} class="h-20 w-32 object-contain" alt="{name} Logo" loading="lazy" />{name}
|
|
||||||
<slot name="imageExtra" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="relative mb-2 flex grow flex-col font-mono md:mb-6">
|
|
||||||
<button
|
|
||||||
class="flex min-w-[18rem] items-center justify-center gap-4 rounded-full border border-primary py-3 pl-6 pr-6 text-base font-medium transition-transform active:scale-[1.01]"
|
|
||||||
on:click={$$slots.default ? undefined : copyCommand}
|
|
||||||
>
|
|
||||||
<slot>
|
|
||||||
<div class="relative flex w-full justify-between gap-4">
|
|
||||||
<div class="flex gap-4">
|
|
||||||
<div class="select-none font-bold text-primary">></div>
|
|
||||||
<span>{command}</span>
|
|
||||||
</div>
|
|
||||||
<ClipboardIcon
|
|
||||||
class="hidden h-6 w-6 text-white opacity-0 transition-opacity duration-100 hover:!opacity-100 group-hover:opacity-80 group-active:opacity-100 sm:block"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</slot>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="pointer-events-none absolute left-1/2 z-20 hidden w-full max-w-max select-none rounded-full bg-black/10 px-2 text-green-400 backdrop-blur [translate:-50%_0px] max-md:-bottom-6 md:-top-8"
|
|
||||||
class:copy={isShowingCopied}
|
|
||||||
>
|
|
||||||
Copied to clipboard ✔
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{#if $$slots.extra}
|
|
||||||
<div class="absolute -bottom-6 flex w-full justify-center font-sans text-xs opacity-80">
|
|
||||||
<slot name="extra" />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
.copy {
|
|
||||||
animation: 80ms cubic-bezier(0.5, 0.2, 0, 1.5) 1 copy;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes copy {
|
|
||||||
from {
|
|
||||||
opacity: 0.8;
|
|
||||||
scale: 0.98;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
scale: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -17,7 +17,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header
|
<header
|
||||||
class="fixed inset-x-0 top-0 z-50 flex items-center justify-between rounded-full px-6 pt-2 duration-1000 animate-in fade-in-0 slide-in-from-top-1 fill-mode-backwards [animation-delay:0ms] lg:[animation-delay:1250ms]"
|
class="fixed inset-x-0 top-0 z-50 flex items-center justify-between rounded-full px-6 pt-2 duration-1000 animate-in fade-in-0 slide-in-from-top-1 fill-mode-backwards [animation-delay:0ms]"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
|
@ -59,6 +59,9 @@
|
||||||
<li aria-current={$page.url.pathname === '/news' ? 'page' : undefined}>
|
<li aria-current={$page.url.pathname === '/news' ? 'page' : undefined}>
|
||||||
<a href="/news">News</a>
|
<a href="/news">News</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li aria-current={$page.url.pathname === '/plugins' ? 'page' : undefined}>
|
||||||
|
<a href="/plugins">Plugins</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="flex flex-row items-center gap-3 px-4">
|
<ul class="flex flex-row items-center gap-3 px-4">
|
||||||
<li>
|
<li>
|
||||||
|
|
33
src/routes/api/plugins/+server.js
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
import { json } from '@sveltejs/kit'
|
||||||
|
|
||||||
|
/** Get the plugins of the `content/plugins/` directory */
|
||||||
|
async function getPlugins() {
|
||||||
|
const plugins = Object.entries(import.meta.glob('/src/content/plugins/*.md', { eager: true }))
|
||||||
|
.flatMap(([path, { metadata }]) => {
|
||||||
|
const slug = path.split('/').at(-1)?.replace('.md', '')
|
||||||
|
|
||||||
|
// Filter out the `readme.md`
|
||||||
|
if (slug === 'readme') return []
|
||||||
|
|
||||||
|
if (!slug || !path) {
|
||||||
|
console.error(`Invalid file ${path} ${JSON.stringify({ ...metadata, slug })}`)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
return { slug, ...metadata }
|
||||||
|
})
|
||||||
|
.sort(
|
||||||
|
(a, b) =>
|
||||||
|
(b.featured ?? 0) - (a.featured ?? 0) ||
|
||||||
|
(b.weight ?? 0) - (a.weight ?? 0) ||
|
||||||
|
((b.logo && 1) ?? 0) - ((a.logo && 1) ?? 0) ||
|
||||||
|
((b.banner && 1) ?? 0) - ((a.banner && 1) ?? 0)
|
||||||
|
)
|
||||||
|
|
||||||
|
return plugins
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET() {
|
||||||
|
const news = await getPlugins()
|
||||||
|
return json(news)
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { getBlurredPath } from '$lib/Helper.mjs'
|
import { getGeneratedPath } from '$lib/Helper.mjs'
|
||||||
import { inview } from 'svelte-inview'
|
import { inview } from 'svelte-inview'
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
|
@ -20,7 +20,7 @@
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
export let pretitel
|
export let pretitel
|
||||||
|
|
||||||
let background = blurredThumbnail ?? getBlurredPath(thumbnail)
|
let background = blurredThumbnail ?? getGeneratedPath(thumbnail)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|
473
src/routes/home-slices/CommunitySlice.svelte
Normal file
|
@ -0,0 +1,473 @@
|
||||||
|
<script context="module">
|
||||||
|
export const contextId = Symbol('community context')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Button from '$lib/components/Button.svelte'
|
||||||
|
import DiscordIcon from '~icons/prime/discord'
|
||||||
|
import DiscordProfilePicture from '$lib/components/DiscordProfilePicture.svelte'
|
||||||
|
import { setContext } from 'svelte'
|
||||||
|
import Title from '$lib/components/Title.svelte'
|
||||||
|
import background from '$lib/images/community-bg.webp'
|
||||||
|
import amongUsGreenImage from '$lib/images/amongus/green.webp'
|
||||||
|
import { discordLink } from '$lib/constants.mjs'
|
||||||
|
|
||||||
|
let sectionElement
|
||||||
|
let isDraggingChan = false
|
||||||
|
|
||||||
|
// Okay everything multiplied by 24
|
||||||
|
const validSizes = [16, 20, 24, 32, 40, 48, 64, 80, 96, 100, 128, 160, 240, 320, 640]
|
||||||
|
|
||||||
|
/** @type {{image: string coordinates: [number, number] containerClass: string}[], size: number, quote?: string } */
|
||||||
|
const profiles = [
|
||||||
|
{
|
||||||
|
// vaxry
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/372809091208445953/a_33fd25e26c0ba17c05566bc3179c6476.gif?size=48',
|
||||||
|
coordinates: [187, 296],
|
||||||
|
size: 172,
|
||||||
|
class: 'outline-red-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// fufexan
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/444952344308744203/9ee39cd422568dad9e70319df27b2560.webp',
|
||||||
|
coordinates: [735, 441],
|
||||||
|
size: 164,
|
||||||
|
class: 'outline-yellow-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// notashelf
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/419880181101232129/2f57c8e5e681c5d8608d07c83053815f.webp',
|
||||||
|
coordinates: [391, 615],
|
||||||
|
size: 149,
|
||||||
|
class: 'outline-orange-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Mathisbuilder
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/378704069726044170/415dcb2ef8d1ef635e35e1d04d523cba.webp',
|
||||||
|
coordinates: [568, 594],
|
||||||
|
size: 120,
|
||||||
|
class: 'outline-amber-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// dani_2048
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/623781003382751243/abea149ded923e8f4cd6f56bff016368.webp',
|
||||||
|
coordinates: [525, 764],
|
||||||
|
size: 80,
|
||||||
|
class: 'outline-orange-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// end_4
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/862314649307054080/2dd9cbd31f5c53811ece2f5abdeab2bf.webp',
|
||||||
|
coordinates: [648, 709],
|
||||||
|
size: 128,
|
||||||
|
class: 'outline-cyan-400'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// liquidovski
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/283259320802476042/7aa4969a2ce25638da49b54dcd862a35.webp',
|
||||||
|
coordinates: [65, 208],
|
||||||
|
size: 100,
|
||||||
|
class: 'outline-lime-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// roasted.cheese
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/967764496527532083/5dc06d112653a529ecbae3b6f4225a93.webp',
|
||||||
|
coordinates: [53, 399],
|
||||||
|
size: 75,
|
||||||
|
class: 'outline-sky-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// donnan
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/163678036401586177/0930f3f6f0839b4f9c59846e185aa8ad.webp?size=128',
|
||||||
|
coordinates: [24, 341],
|
||||||
|
size: 49,
|
||||||
|
class: 'outline-yellow-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// captainiveau
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/223160360461402122/c6552a1c768613bffb83bf88e4ce2632.webp?size=128',
|
||||||
|
coordinates: [47, 86],
|
||||||
|
size: 48,
|
||||||
|
class: 'outline-red-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// sioodmy
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/979473046404476998/c9a4af31050a785d896f7880f9d268e3.webp',
|
||||||
|
coordinates: [1038, 446],
|
||||||
|
size: 52,
|
||||||
|
class: 'outline-amber-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: '/imgs/profile_pictures/_anon.webp',
|
||||||
|
coordinates: [-85, 566],
|
||||||
|
size: 40,
|
||||||
|
class: 'outline-sky-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Angry snow man
|
||||||
|
// psidotdiamparenthesis4pt5tol4poi
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/486802226577276929/4c1cd003e9c7b7c19a858b38cca7104a.webp',
|
||||||
|
coordinates: [273, 760],
|
||||||
|
size: 52,
|
||||||
|
quote: '"meds"',
|
||||||
|
class: 'outline-cyan-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// outfoxxed
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/837425748435796060/248cd938377647404e3d8d1c53b639cf.webp',
|
||||||
|
coordinates: [648, 364],
|
||||||
|
size: 80,
|
||||||
|
class: 'outline-orange-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// kirottum
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/480024733535174668/5453c57e69ff16f495d8dcbd597070e9.webp',
|
||||||
|
coordinates: [772, 651],
|
||||||
|
size: 62,
|
||||||
|
class: 'outline-purple-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// beardwarrior
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/544368824842190861/1fbf29ea7ca9c2109b97af2ede3806fa.webp',
|
||||||
|
coordinates: [736, 277],
|
||||||
|
size: 101,
|
||||||
|
class: 'outline-lime-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// heisfer
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/344854021166727180/0c8dd04188df26093164406cc1367f58.webp',
|
||||||
|
coordinates: [898, 364],
|
||||||
|
size: 68,
|
||||||
|
class: 'outline-yellow-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: amongUsGreenImage,
|
||||||
|
coordinates: [873, 224],
|
||||||
|
size: 79,
|
||||||
|
class: 'outline-green-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// SimplyKyle!
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/579120037034721281/c7b4341806d515f5d92bb53e322a4728.webp',
|
||||||
|
coordinates: [887, 159],
|
||||||
|
size: 39,
|
||||||
|
class: 'outline-rose-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// thesuncat
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/246125351464337418/10c8bb5456d1ca1cebf2edff62b7001f.webp',
|
||||||
|
coordinates: [1023, 552],
|
||||||
|
size: 48,
|
||||||
|
class: 'outline-amber-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// flafy
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/143031299152674816/4a143f00b0e014e9c3da37cd8599b106.webp',
|
||||||
|
coordinates: [147, 553],
|
||||||
|
size: 87,
|
||||||
|
class: 'outline-pink-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// vagahbond
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/194157962498015232/ab11cc35bd9d057769254d1d3e29e468.webp',
|
||||||
|
coordinates: [65, 643],
|
||||||
|
size: 74,
|
||||||
|
class: 'outline-amber-500 '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// flick0
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/482139697796349953/ce63690cf5adb8e096b4472bc0c175e8.webp',
|
||||||
|
coordinates: [263, 653],
|
||||||
|
size: 65,
|
||||||
|
class: 'outline-stone-500 '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// jacekpoz
|
||||||
|
image: '/imgs/profile_pictures/jacekpoz.svg',
|
||||||
|
coordinates: [893, 622],
|
||||||
|
size: 80,
|
||||||
|
class: 'outline-yellow-500 bg-black ',
|
||||||
|
quote: '"piss blob"'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// aylur
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/231040215085481984/7f378337240110b76e6e9baa31f83670.webp',
|
||||||
|
coordinates: [354, 798],
|
||||||
|
size: 80,
|
||||||
|
class: 'outline-amber-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// aleph.nought
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/784153590595321876/04cbb92b7fe3fea8a6cdb4e2fd8562c5.webp',
|
||||||
|
coordinates: [583, 824],
|
||||||
|
size: 69,
|
||||||
|
class: 'outline-white',
|
||||||
|
quote: 'Perfect being'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// jappie3
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/408513270916579338/bac966d3bae8ad01546ee32584917be9.webp',
|
||||||
|
coordinates: [275, 844],
|
||||||
|
size: 40,
|
||||||
|
class: 'outline-rose-300'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// nwg.piotr
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/860670651026767942/7122b752fa6097472f8c76cc4458e33b.webp',
|
||||||
|
coordinates: [939, 552],
|
||||||
|
size: 48,
|
||||||
|
class: 'outline-orange-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// xsty_
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/520860407720837131/3e73c777553fcd67f2f17bc119b79f15.webp',
|
||||||
|
coordinates: [458, 913],
|
||||||
|
size: 35,
|
||||||
|
class: 'outline-orange-500 '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// petingoso
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/390226958241366016/513b77487a9fa01b1256c4dc8e1b0c55.webp',
|
||||||
|
coordinates: [858, 707],
|
||||||
|
size: 45,
|
||||||
|
class: 'outline-blue-500 '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// eriedaberrie
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/594256188422488069/1e532709dbd756c172c54add8536e558.webp',
|
||||||
|
coordinates: [8, 477],
|
||||||
|
size: 54,
|
||||||
|
class: 'outline-blue-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// errornointernet
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/531392146767347712/0b5e5671e7e8eb0e4f6ec547c686667b.webp',
|
||||||
|
coordinates: [950, 277],
|
||||||
|
size: 47,
|
||||||
|
class: 'outline-orange-500 bg-stone-800'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// kosslan
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/194584980922433536/7bb58205667ad9a6bf2791b59b32c109.webp',
|
||||||
|
coordinates: [69, 561],
|
||||||
|
size: 54,
|
||||||
|
class: 'outline-blue-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// lassebq
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/561863734264594452/e9d1b128f8a32849ae4e2a0d86d16fdb.webp',
|
||||||
|
coordinates: [908, 463],
|
||||||
|
size: 54,
|
||||||
|
class: 'outline-orange-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// poutineburgerman
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/426690378830184448/09181b1b476f221b7850702158778c1a.webp',
|
||||||
|
coordinates: [823, 184],
|
||||||
|
size: 44,
|
||||||
|
class: 'outline-blue-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// visualdawg
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/219573494713810945/5202607a6cf5e34ed705308459d0115c.webp',
|
||||||
|
coordinates: [133, 493],
|
||||||
|
size: 49,
|
||||||
|
class: 'outline-stone-900 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// wickedlyhost
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/317785409763541002/279527807f4263888fa75b2d7e68daf7.webp',
|
||||||
|
coordinates: [119, 202],
|
||||||
|
size: 49,
|
||||||
|
class: 'outline-blue-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// yavko
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/guilds/961691461554950145/users/465960044094160908/avatars/11672d8e456e31a85a3d89b31fff913b.webp',
|
||||||
|
coordinates: [179, 671],
|
||||||
|
size: 69,
|
||||||
|
class: 'outline-yellow-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// mcgoth
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/706672850907430942/9330c50f778f6d3776da15335dfb5b3f.webp',
|
||||||
|
coordinates: [771, 818],
|
||||||
|
size: 49,
|
||||||
|
class: 'outline-stone-500 bg-black '
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// brainless.bitch
|
||||||
|
image:
|
||||||
|
'https://cdn.discordapp.com/avatars/708440359587414067/2bcdf703f69ee35c4cf39b2a89c429e8.webp',
|
||||||
|
coordinates: [1018, 123],
|
||||||
|
size: 28,
|
||||||
|
class: 'outline-lime-500 bg-black '
|
||||||
|
},
|
||||||
|
|
||||||
|
//
|
||||||
|
// Extras
|
||||||
|
{
|
||||||
|
image: 'imgs/chan/joy.svg',
|
||||||
|
coordinates: [284, 533],
|
||||||
|
size: 90,
|
||||||
|
class: 'outline-cyan-500 bg-blue-300',
|
||||||
|
onDragStart: ({ detail: { currentTarget } }) => {
|
||||||
|
isDraggingChan = true
|
||||||
|
currentTarget.src = 'imgs/chan/surprise.svg'
|
||||||
|
},
|
||||||
|
onDragEnd: ({ detail: { currentTarget } }) => {
|
||||||
|
isDraggingChan = false
|
||||||
|
currentTarget.src = 'imgs/chan/tongueout.svg'
|
||||||
|
},
|
||||||
|
onHover: ({ detail: { srcElement } }) =>
|
||||||
|
!isDraggingChan && (srcElement.src = 'imgs/chan/wink.svg')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: '/imgs/profile_pictures/chan_1.webp',
|
||||||
|
coordinates: [91, 799],
|
||||||
|
size: 55,
|
||||||
|
class: 'outline-sky-500'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: '/imgs/profile_pictures/chan_cat.webp',
|
||||||
|
coordinates: [-10, 844],
|
||||||
|
size: 32,
|
||||||
|
class: 'outline-blue-800'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: '/imgs/profile_pictures/chan_cat_2.webp',
|
||||||
|
coordinates: [1000, 744],
|
||||||
|
size: 32,
|
||||||
|
class: 'outline-cyan-500'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
.map(({ image, size, ...profile }) => ({
|
||||||
|
...profile,
|
||||||
|
size,
|
||||||
|
image: image + '?size=' + validSizes.find((_, index) => size <= validSizes[index])
|
||||||
|
}))
|
||||||
|
.sort(({ size: a }, { size: b }) => b - a)
|
||||||
|
|
||||||
|
setContext(contextId, {
|
||||||
|
biggestSize: profiles.reduce(
|
||||||
|
(previousSize, { size }) => (size > previousSize ? size : previousSize),
|
||||||
|
1
|
||||||
|
),
|
||||||
|
smallestSize: profiles.reduce(
|
||||||
|
(previousSize, { size }) => (size < previousSize ? size : previousSize),
|
||||||
|
Number.POSITIVE_INFINITY
|
||||||
|
),
|
||||||
|
getSectionElement: () => sectionElement
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="relative -mb-[200px] flex h-[1100px] min-h-max w-screen flex-col items-center"
|
||||||
|
bind:this={sectionElement}
|
||||||
|
>
|
||||||
|
<Title>
|
||||||
|
<span slot="title">Join a great<br />community</span>
|
||||||
|
|
||||||
|
<span slot="subtitle">
|
||||||
|
Get help from Distro Hoppers, Haiku writers,<br />Hydrohomies, and human_(probably)
|
||||||
|
</span>
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<div class="group mt-16 flex flex-col items-center">
|
||||||
|
<a
|
||||||
|
class="discord p-4"
|
||||||
|
href={discordLink}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
aria-label="Join us on Discord"
|
||||||
|
>
|
||||||
|
<DiscordIcon class="h-full w-full " />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href={discordLink}>
|
||||||
|
<Button type="fancyOutline">Join us on Discord</Button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="absolute w-[1024px] select-none">
|
||||||
|
<div class="flex h-full origin-bottom-right select-none flex-wrap gap-4">
|
||||||
|
{#each profiles as { onDragEnd, onDragStart, onHover, ...props }}
|
||||||
|
<DiscordProfilePicture
|
||||||
|
{...props}
|
||||||
|
on:dragStart={onDragStart}
|
||||||
|
on:dragEnd={onDragEnd}
|
||||||
|
on:hover={onHover}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<img
|
||||||
|
src={background}
|
||||||
|
class="absolute top-0 -z-10 min-w-[1400px] select-none"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.discord {
|
||||||
|
width: 9rem;
|
||||||
|
height: 9rem;
|
||||||
|
transition:
|
||||||
|
rotate 500ms cubic-bezier(0.5, 0, 0.5, 1),
|
||||||
|
scale 420ms cubic-bezier(0.5, 0.1, 0, 1),
|
||||||
|
filter 840ms;
|
||||||
|
transition-delay: 240ms, 180ms, 20ms;
|
||||||
|
transform: translateY(-25%);
|
||||||
|
filter: drop-shadow(0px 0px 0px cyan) drop-shadow(0px 0px 0px blue);
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
.group:hover & {
|
||||||
|
scale: 1.2 1.2;
|
||||||
|
rotate: 360deg;
|
||||||
|
filter: drop-shadow(4px 4px 14px #0fffef7a) drop-shadow(-4px -4px 12px purple);
|
||||||
|
animation: bounce 0.7s infinite 180ms both;
|
||||||
|
}
|
||||||
|
&:active {
|
||||||
|
scale: 1;
|
||||||
|
transition: scale 80ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
27
src/routes/home-slices/DistroOption.svelte
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<script>
|
||||||
|
/** @type {string | undefined} */
|
||||||
|
export let image = undefined
|
||||||
|
/** @type {string | undefined} */
|
||||||
|
export let name = undefined
|
||||||
|
/**
|
||||||
|
* @type {string | undefined }
|
||||||
|
* Classes for the command text
|
||||||
|
*/
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="group relative flex flex-col items-center gap-2 md:flex-row md:gap-4">
|
||||||
|
{#if image && name}
|
||||||
|
<div
|
||||||
|
class="relative flex h-32 w-32 flex-col items-center justify-center gap-3 rounded-full text-lg font-medium text-primary transition-transform group-focus-within:-translate-y-1"
|
||||||
|
>
|
||||||
|
<img src={image} class="h-20 w-32 object-contain" alt="{name} Logo" loading="lazy" />{name}
|
||||||
|
|
||||||
|
<slot name="imageExtra" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- Command button slot -->
|
||||||
|
<div class="mb-2 w-full">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
4
src/routes/FameRicePreview.svelte → src/routes/home-slices/FameRicePreview.svelte
Executable file → Normal file
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { animateIn, getBlurredPath } from '$lib/Helper.mjs'
|
import { animateIn, getGeneratedPath } from '$lib/Helper.mjs'
|
||||||
|
|
||||||
/** @type {string}
|
/** @type {string}
|
||||||
* The path to the image. Usually the file within `static`, but can also be an URL
|
* The path to the image. Usually the file within `static`, but can also be an URL
|
||||||
|
@ -24,7 +24,7 @@
|
||||||
/>
|
/>
|
||||||
<div class="rice-blurred">
|
<div class="rice-blurred">
|
||||||
<img
|
<img
|
||||||
src={blurredBackground ?? getBlurredPath(image)}
|
src={blurredBackground ?? getGeneratedPath(image)}
|
||||||
alt="Rice desktop"
|
alt="Rice desktop"
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
class="h-full w-full object-cover"
|
class="h-full w-full object-cover"
|
213
src/routes/home-slices/FeaturesSlice.svelte
Normal file
|
@ -0,0 +1,213 @@
|
||||||
|
<script>
|
||||||
|
import Card from '$lib/components/Card.svelte'
|
||||||
|
import GameIcon from '~icons/gg/games'
|
||||||
|
import SpecialWorkspaceIcon from '~icons/gg/shutterstock'
|
||||||
|
import ShortcutsIcon from '~icons/gg/push-chevron-right-o'
|
||||||
|
import TabIcon from '~icons/gg/tab'
|
||||||
|
import IpcIcon from '~icons/gg/media-podcast'
|
||||||
|
import TouchpadIcon from '~icons/gg/touchpad'
|
||||||
|
import Title from '$lib/components/Title.svelte'
|
||||||
|
import Hypractive from './Hypractive.svelte'
|
||||||
|
import configDefaultImage from '$lib/images/features/config_default.webp'
|
||||||
|
import configHoverImage from '$lib/images/features/config_hover.webp'
|
||||||
|
import smoothDefaultImage from '$lib/images/features/smooth_default.webp'
|
||||||
|
import smoothHoverImage from '$lib/images/features/smooth_hover.webp'
|
||||||
|
import tileDefaultImage from '$lib/images/features/tiling_default.webp'
|
||||||
|
import tileHoverImage from '$lib/images/features/tiling_hover.webp'
|
||||||
|
import CardsContainer from '$lib/components/CardsContainer.svelte'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<section class="relative flex flex-col items-center px-3 md:px-8">
|
||||||
|
<Title>
|
||||||
|
<span slot="pre">TLDR</span>
|
||||||
|
<span slot="title">Features</span>
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<CardsContainer
|
||||||
|
class="group grid w-full flex-wrap gap-6 text-lg font-medium text-white/70 lg:grid-cols-2 lg:grid-rows-2 lg:gap-4"
|
||||||
|
>
|
||||||
|
<Card class="row-span-2 min-h-[20rem]" color="purple">
|
||||||
|
<div class="flex h-full flex-col justify-end p-8 sm:p-12">
|
||||||
|
<h2 class="mb-6 text-5xl font-bold text-white lg:text-8xl">Smooth</h2>
|
||||||
|
<p class="max-w-[60ch]">
|
||||||
|
Smooth transitions. Great animations. High performance. Instant input.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="_wrapper absolute inset-0 select-none" aria-hidden="true">
|
||||||
|
<div class="feature-image">
|
||||||
|
<img
|
||||||
|
src={smoothDefaultImage}
|
||||||
|
class="feature-image_inner"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src={smoothHoverImage}
|
||||||
|
class="feature-image_inner-hover"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<Card class="min-h-[20rem]" color="purple">
|
||||||
|
<div class="flex h-full flex-col justify-end p-8 sm:p-12">
|
||||||
|
<h2 class="mb-6 text-5xl font-bold text-white">Easy to configure</h2>
|
||||||
|
<p class="max-w-[60ch]">
|
||||||
|
Live reloading config. Easy plain-text format. Sensible defaults. Great documentation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div class="_wrapper absolute inset-0 select-none" aria-hidden="true">
|
||||||
|
<div class="feature-image">
|
||||||
|
<img
|
||||||
|
src={configDefaultImage}
|
||||||
|
class="feature-image_inner"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src={configHoverImage}
|
||||||
|
class="feature-image_inner-hover"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
<Card class="min-h-[20rem]" color="purple">
|
||||||
|
<div class="flex h-full flex-col justify-end p-8 sm:p-12">
|
||||||
|
<h2 class="mb-6 text-5xl font-bold text-white">Dynamic tiling</h2>
|
||||||
|
<p class="max-w-[60ch]">
|
||||||
|
Automatic tiling that just works. Supports multiple fine-tuneable layouts.
|
||||||
|
</p>
|
||||||
|
<div class="_wrapper absolute inset-0 select-none" aria-hidden="true">
|
||||||
|
<div class="feature-image">
|
||||||
|
<img
|
||||||
|
src={tileDefaultImage}
|
||||||
|
class="feature-image_inner"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
<img
|
||||||
|
src={tileHoverImage}
|
||||||
|
class="feature-image_inner-hover"
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</CardsContainer>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="z-10 mt-14 flex max-w-screen-xl flex-col flex-wrap justify-center gap-8 text-lg sm:flex-row"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://wiki.hyprland.org/Configuring/Tearing/"
|
||||||
|
target="_blank"
|
||||||
|
class="icon-feature hover:underline"
|
||||||
|
>
|
||||||
|
<GameIcon class="h-8 w-8" />
|
||||||
|
Tearing support
|
||||||
|
</a>
|
||||||
|
<a href="https://wiki.hyprland.org/IPC/" target="_blank" class="icon-feature hover:underline">
|
||||||
|
<IpcIcon class="h-8 w-8" />
|
||||||
|
Socket-based IPC
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://github.com/hyprland-community/awesome-hyprland#plugins"
|
||||||
|
target="_blank"
|
||||||
|
class="icon-feature hover:underline"
|
||||||
|
>
|
||||||
|
<TabIcon class="h-8 w-8" />
|
||||||
|
Window groups
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://wiki.hyprland.org/Configuring/Dispatchers/#special-workspace"
|
||||||
|
target="_blank"
|
||||||
|
class="icon-feature hover:underline"
|
||||||
|
>
|
||||||
|
<SpecialWorkspaceIcon class="h-8 w-8" />
|
||||||
|
Special workspaces
|
||||||
|
</a>
|
||||||
|
<Hypractive />
|
||||||
|
<a
|
||||||
|
href="https://wiki.hyprland.org/Configuring/Binds/#global-keybinds"
|
||||||
|
target="_blank"
|
||||||
|
class="icon-feature hover:underline"
|
||||||
|
>
|
||||||
|
<ShortcutsIcon class="h-8 w-8" />
|
||||||
|
Global shortcuts for apps
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://wiki.hyprland.org/Configuring/Variables/#gestures"
|
||||||
|
class="icon-feature hover:underline"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<TouchpadIcon class="h-8 w-8" />Touchpad gestures
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.icon-feature {
|
||||||
|
@apply flex items-center justify-center gap-3 font-bold text-slate-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-image {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0 0 0 0;
|
||||||
|
opacity: 0.5;
|
||||||
|
z-index: -10;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
transition: opacity 180ms ease-in-out;
|
||||||
|
|
||||||
|
._wrapper:hover & {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
& img {
|
||||||
|
position: absolute;
|
||||||
|
transition: opacity 1500ms ease-in-out;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
width: 400px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
right: -80px;
|
||||||
|
top: 50%;
|
||||||
|
translate: 0px -50%;
|
||||||
|
|
||||||
|
@media screen(md) {
|
||||||
|
width: 600px;
|
||||||
|
right: -80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.feature-image_inner-hover {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
._wrapper:hover {
|
||||||
|
& .feature-image_inner {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
& .feature-image_inner-hover {
|
||||||
|
opacity: 1 !important;
|
||||||
|
filter: saturate(1.3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
word-break: pretty;
|
||||||
|
}
|
||||||
|
</style>
|
0
src/routes/Hero.svelte → src/routes/home-slices/Hero.svelte
Executable file → Normal file
0
src/routes/HeroBackground.svelte → src/routes/home-slices/HeroBackground.svelte
Executable file → Normal file
0
src/routes/Hypractive.svelte → src/routes/home-slices/Hypractive.svelte
Executable file → Normal file
40
src/routes/InstallSlice.svelte → src/routes/home-slices/InstallSlice.svelte
Executable file → Normal file
|
@ -4,11 +4,11 @@
|
||||||
import nixLogo from '$lib/images/logos/nixos.svg'
|
import nixLogo from '$lib/images/logos/nixos.svg'
|
||||||
import bsdLogo from '$lib/images/logos/freebsd.svg'
|
import bsdLogo from '$lib/images/logos/freebsd.svg'
|
||||||
import suseLogo from '$lib/images/logos/opensuse.svg'
|
import suseLogo from '$lib/images/logos/opensuse.svg'
|
||||||
import LinkOutIcon from '~icons/akar-icons/link-out'
|
import DistroOption from './DistroOption.svelte'
|
||||||
import InstallButton from './InstallButton.svelte'
|
|
||||||
import Button from '$lib/components/Button.svelte'
|
import Button from '$lib/components/Button.svelte'
|
||||||
import Title from '$lib/components/Title.svelte'
|
import Title from '$lib/components/Title.svelte'
|
||||||
import amongus from '$lib/images/amongus/green.webp'
|
import amongus from '$lib/images/amongus/green.webp'
|
||||||
|
import CommandButton from '$lib/components/CommandButton.svelte'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section class="pb-6">
|
<section class="pb-6">
|
||||||
|
@ -20,26 +20,38 @@
|
||||||
<div
|
<div
|
||||||
class="links_ flex flex-col gap-12 px-4 md:gap-6 md:rounded-3xl md:bg-gradient-to-tr md:from-blue-500/40 md:to-transparent md:p-8 md:shadow-xl md:outline md:outline-1 md:outline-blue-500"
|
class="links_ flex flex-col gap-12 px-4 md:gap-6 md:rounded-3xl md:bg-gradient-to-tr md:from-blue-500/40 md:to-transparent md:p-8 md:shadow-xl md:outline md:outline-1 md:outline-blue-500"
|
||||||
>
|
>
|
||||||
<InstallButton name="Arch" command="pacman -S hyprland" image={archLogo}
|
<DistroOption name="Arch" image={archLogo}>
|
||||||
><div slot="extra">
|
<CommandButton command="pacman -S hyprland">
|
||||||
|
<div slot="extra" class="absolute -bottom-4 left-1/2 min-w-max -translate-x-1/2">
|
||||||
AUR git version: <a
|
AUR git version: <a
|
||||||
class=" "
|
class=" "
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://aur.archlinux.org/packages/hyprland-git/">hyprland-git</a
|
href="https://aur.archlinux.org/packages/hyprland-git/">hyprland-git</a
|
||||||
>
|
>
|
||||||
</div></InstallButton
|
</div>
|
||||||
>
|
</CommandButton>
|
||||||
<InstallButton name="NixOS" command="programs.hyprland.enable" image={nixLogo}
|
</DistroOption>
|
||||||
><div slot="extra">
|
|
||||||
|
<DistroOption name="NixOS" image={nixLogo}>
|
||||||
|
<CommandButton command="programs.hyprland.enable">
|
||||||
|
<div slot="extra" class="absolute -bottom-4 left-1/2 min-w-max -translate-x-1/2">
|
||||||
<a href="https://wiki.hyprland.org/Nix/" target="_blank"
|
<a href="https://wiki.hyprland.org/Nix/" target="_blank"
|
||||||
>See more details and git version</a
|
>See more details and git version ↗</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</InstallButton>
|
</CommandButton>
|
||||||
<InstallButton name="FreeBSD" command="pkg install hyprland" image={bsdLogo} />
|
</DistroOption>
|
||||||
<InstallButton name="openSUSE" command="zypper in hyprland" image={suseLogo}
|
|
||||||
><div slot="extra">or install “hyprland” via YaST2 Software.</div>
|
|
||||||
|
|
||||||
|
<DistroOption name="FreeBSD" image={bsdLogo}>
|
||||||
|
<CommandButton command="pkg install hyprland" />
|
||||||
|
</DistroOption>
|
||||||
|
|
||||||
|
<DistroOption name="openSUSE" image={suseLogo}>
|
||||||
|
<CommandButton command="zypper in hyprland">
|
||||||
|
<div slot="extra" class="absolute -bottom-4 left-1/2 min-w-max -translate-x-1/2">
|
||||||
|
or install “hyprland” via YaST2 Software.
|
||||||
|
</div>
|
||||||
|
</CommandButton>
|
||||||
<img
|
<img
|
||||||
class=" absolute inset-0 -z-10 translate-y-1 rotate-0 scale-90 opacity-0 transition-all duration-700 [transition-delay:2s] group-hover:-translate-x-3 group-hover:-translate-y-0 group-hover:-rotate-12 group-hover:scale-100 group-hover:opacity-90"
|
class=" absolute inset-0 -z-10 translate-y-1 rotate-0 scale-90 opacity-0 transition-all duration-700 [transition-delay:2s] group-hover:-translate-x-3 group-hover:-translate-y-0 group-hover:-rotate-12 group-hover:scale-100 group-hover:opacity-90"
|
||||||
src={amongus}
|
src={amongus}
|
||||||
|
@ -47,7 +59,7 @@
|
||||||
alt=""
|
alt=""
|
||||||
srcset=""
|
srcset=""
|
||||||
/>
|
/>
|
||||||
</InstallButton>
|
</DistroOption>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a
|
<a
|
|
@ -10,6 +10,7 @@
|
||||||
import { Subject, debounceTime, map, tap, throttle, throttleTime } from 'rxjs'
|
import { Subject, debounceTime, map, tap, throttle, throttleTime } from 'rxjs'
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { fade } from 'svelte/transition'
|
import { fade } from 'svelte/transition'
|
||||||
|
import Button from '$lib/components/Button.svelte'
|
||||||
|
|
||||||
/** @type {HTMLVideoElement[]}*/
|
/** @type {HTMLVideoElement[]}*/
|
||||||
const videos = []
|
const videos = []
|
||||||
|
@ -82,7 +83,7 @@
|
||||||
<section class="relative z-0 flex min-h-max w-full flex-col items-center py-20">
|
<section class="relative z-0 flex min-h-max w-full flex-col items-center py-20">
|
||||||
<div
|
<div
|
||||||
class="mx-auto grid max-w-7xl grid-cols-1 gap-8 transition-all lg:grid-cols-2 lg:gap-12"
|
class="mx-auto grid max-w-7xl grid-cols-1 gap-8 transition-all lg:grid-cols-2 lg:gap-12"
|
||||||
use:animateIn={{ fade: 0.0, slide: 24 }}
|
use:animateIn={{ slide: 24 }}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class={clsx(
|
class={clsx(
|
||||||
|
@ -122,6 +123,10 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<Button type="fancyOutline" size="lg" class="max-w-max"
|
||||||
|
><a href="/plugins/">Checkout more plugins</a></Button
|
||||||
|
>
|
||||||
|
|
||||||
<div class="-mt-5 hidden gap-1 lg:mt-12 lg:flex lg:flex-col">
|
<div class="-mt-5 hidden gap-1 lg:mt-12 lg:flex lg:flex-col">
|
||||||
<a
|
<a
|
||||||
class="txt-shadow_ flex w-max max-w-max shrink-0 items-center gap-3 rounded font-bold text-slate-400 hover:underline"
|
class="txt-shadow_ flex w-max max-w-max shrink-0 items-center gap-3 rounded font-bold text-slate-400 hover:underline"
|
||||||
|
@ -129,8 +134,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
Check out <span class="text-cyan-500">Awesome Hyprland</span>
|
Also see <span class="text-cyan-500">Awesome Hyprland</span>
|
||||||
for more
|
|
||||||
</div>
|
</div>
|
||||||
<IconLinkOut />
|
<IconLinkOut />
|
||||||
</a>
|
</a>
|
11
src/routes/PreviewRiceSlice.svelte → src/routes/home-slices/PreviewRiceSlice.svelte
Executable file → Normal file
|
@ -8,13 +8,15 @@
|
||||||
|
|
||||||
let isVisible = false
|
let isVisible = false
|
||||||
let isManuallyPaused = false
|
let isManuallyPaused = false
|
||||||
|
let isChrome = false
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
|
isChrome = navigator.userAgent.toLowerCase().includes('chrome')
|
||||||
// Only autoplay on Chrome, because Firefox struggles with decoding the video
|
// Only autoplay on Chrome, because Firefox struggles with decoding the video
|
||||||
if (navigator.userAgent.toLowerCase().includes('chrome')) {
|
if (isChrome) {
|
||||||
// The inview_leave event fires at the start and Chromium reports the video as paused, even with autoplay on.
|
// The inview_leave event fires at the start and Chromium reports the video as paused, even with autoplay on.
|
||||||
// This fixes it. Catch in case autoplay is blocked
|
// This fixes it. Catch in case autoplay is blocked
|
||||||
videoElement.play().catch(() => {})
|
videoElement.play().catch(console.error)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -26,7 +28,7 @@
|
||||||
use:inview={{ threshold: 0.5 }}
|
use:inview={{ threshold: 0.5 }}
|
||||||
on:inview_enter={() => {
|
on:inview_enter={() => {
|
||||||
isVisible = true
|
isVisible = true
|
||||||
if (!isManuallyPaused) {
|
if (!isManuallyPaused && isChrome) {
|
||||||
videoElement.play().catch(() => {})
|
videoElement.play().catch(() => {})
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
@ -44,6 +46,7 @@
|
||||||
poster={'/videos/end_4_thumbnail.webp'}
|
poster={'/videos/end_4_thumbnail.webp'}
|
||||||
videoClass="!rounded-2xl overflow-hidden"
|
videoClass="!rounded-2xl overflow-hidden"
|
||||||
on:play={() => (isManuallyPaused = false)}
|
on:play={() => (isManuallyPaused = false)}
|
||||||
|
autoplay={undefined}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -58,7 +61,7 @@
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
section {
|
section {
|
||||||
@apply animate-in fade-in-0 slide-in-from-bottom-10 fill-mode-backwards relative z-10 -mb-4 w-full max-w-[1400px] px-1 [animation-delay:1700ms] [animation-duration:2000ms] md:-mt-8 lg:px-8;
|
@apply relative z-10 -mb-4 w-full max-w-[1400px] px-1 animate-in fade-in-0 slide-in-from-bottom-10 fill-mode-backwards [animation-delay:1700ms] [animation-duration:2000ms] md:-mt-8 lg:px-8;
|
||||||
|
|
||||||
contain: layout style content;
|
contain: layout style content;
|
||||||
}
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { error } from '@sveltejs/kit'
|
||||||
|
|
||||||
export async function load({ params, fetch }) {
|
export async function load({ params, fetch }) {
|
||||||
try {
|
try {
|
||||||
const post = await import(`../../../content/news/${params.slug}.md`)
|
const post = await import(`../../../content/news/${params.slug}.md`)
|
||||||
|
@ -10,8 +12,8 @@ export async function load({ params, fetch }) {
|
||||||
meta: post.metadata,
|
meta: post.metadata,
|
||||||
other
|
other
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error_) {
|
||||||
console.error(error)
|
console.error(error_)
|
||||||
throw error(404, `Could not find ${params.slug}`)
|
error(404, `Could not find ${params.slug}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
5
src/routes/plugins/+page.js
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
export async function load({ fetch }) {
|
||||||
|
const response = await fetch('/api/plugins')
|
||||||
|
const plugins = await response.json()
|
||||||
|
return { plugins }
|
||||||
|
}
|
172
src/routes/plugins/+page.svelte
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
<script>
|
||||||
|
import Title from '$lib/components/Title.svelte'
|
||||||
|
import CardsContainer from '$lib/components/CardsContainer.svelte'
|
||||||
|
import PluginCard from './PluginCard.svelte'
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import * as R from 'remeda'
|
||||||
|
import { getGeneratedPath } from '$lib/Helper.mjs'
|
||||||
|
|
||||||
|
export let data
|
||||||
|
|
||||||
|
const { plugins } = data
|
||||||
|
const featuredPlugins = plugins.filter(({ featured }) => featured).slice(0, 4)
|
||||||
|
const pluginsByCategory = R.pipe(
|
||||||
|
plugins,
|
||||||
|
R.groupBy(({ category }) => category),
|
||||||
|
R.mapValues(
|
||||||
|
R.sort(
|
||||||
|
(a, b) =>
|
||||||
|
(b.weight ?? 0) - (a.weight ?? 0) ||
|
||||||
|
Boolean(b.logo) - Boolean(a.logo) ||
|
||||||
|
b.name.localeCompare(a.name)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
R.toPairs,
|
||||||
|
R.tap((x) => console.log({ x })),
|
||||||
|
R.sort(([a], [b]) => a.localeCompare(b))
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{'Plugins'}</title>
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="flex min-h-screen w-full flex-col items-center justify-center gap-14 px-6 md:pr-8
|
||||||
|
|
||||||
|
lg:pl-0
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="top-light"></div>
|
||||||
|
|
||||||
|
<header class="header mt-24 md:mt-32">
|
||||||
|
<Title class="mb-0 duration-1000 animate-in fade-in-0">
|
||||||
|
<span slot="pre">Plugins</span>
|
||||||
|
<span slot="title">Unlock full power</span><span slot="subtitle">
|
||||||
|
Easily load up plugins and customize everything
|
||||||
|
</span>
|
||||||
|
</Title>
|
||||||
|
|
||||||
|
<!-- <div class="absolute top-0">
|
||||||
|
{#each plugins.filter(({ logo }) => logo) as { logo }, index}
|
||||||
|
<img
|
||||||
|
src={getGeneratedPath(logo)}
|
||||||
|
alt=""
|
||||||
|
width={index * 50}
|
||||||
|
height={index * 50}
|
||||||
|
class="bg-logo"
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div> -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<section
|
||||||
|
class="m-0 mx-auto flex w-full max-w-screen-3xl
|
||||||
|
animate-in fade-in-0 slide-in-from-bottom-6 fill-mode-backwards [animation-delay:800ms] [animation-duration:1500ms]
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<!-- Secondary navigation -->
|
||||||
|
<div class="hidden lg:block">
|
||||||
|
<nav class="sticky top-32 z-40 max-h-max min-w-52 shrink-0 grow-0 flex-col gap-2 px-8">
|
||||||
|
<ul class="flex flex-col gap-4 text-sm font-medium text-slate-400">
|
||||||
|
{#each pluginsByCategory as category}
|
||||||
|
<li>
|
||||||
|
<a href={'#' + category[0]} class=" px-2 py-1 transition-colors hover:text-white"
|
||||||
|
>{category[0]}</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex grow flex-col items-start gap-6 md:gap-16">
|
||||||
|
<div class="flex w-full flex-col gap-3">
|
||||||
|
<h2 class="text-4xl font-bold text-slate-300">Featured</h2>
|
||||||
|
<CardsContainer
|
||||||
|
class="
|
||||||
|
flex w-full grid-flow-dense grid-cols-12 flex-col gap-3 md:grid "
|
||||||
|
>
|
||||||
|
{#each featuredPlugins as plugin, index}
|
||||||
|
<PluginCard
|
||||||
|
{plugin}
|
||||||
|
class={clsx(
|
||||||
|
plugin.banner &&
|
||||||
|
featuredPlugins
|
||||||
|
.slice(0, index)
|
||||||
|
.reduce((total, { banner }) => (banner ? total + 1 : total), 0) < 2
|
||||||
|
? 'col-span-8 h-[18rem] md:col-span-6 lg:col-span-8 '
|
||||||
|
: 'col-span-6 h-[16rem] lg:col-span-4 ',
|
||||||
|
|
||||||
|
' md:min-h-full '
|
||||||
|
)}
|
||||||
|
color={index % 3 === 0 ? 'purple' : 'cyan'}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</CardsContainer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<CardsContainer
|
||||||
|
class="md:flotherex-row flex w-full grow flex-col flex-wrap items-start justify-start gap-12 animate-in fade-in-0 "
|
||||||
|
enableBorders={false}
|
||||||
|
>
|
||||||
|
{#each pluginsByCategory as [category, plugins]}
|
||||||
|
<div class="flex w-full flex-col gap-2">
|
||||||
|
<h3 id={category} class="scroll-mt-32 text-lg font-medium text-slate-300">
|
||||||
|
{category}
|
||||||
|
</h3>
|
||||||
|
<div class="flex w-full flex-wrap gap-4">
|
||||||
|
{#each plugins as plugin, index}
|
||||||
|
<PluginCard
|
||||||
|
{plugin}
|
||||||
|
class="max-h-48 min-h-[14rem] w-full max-w-96 @sm:h-[18rem] sm:w-52 3xl:w-64 "
|
||||||
|
color={index % 3 === 0 ? 'purple' : 'cyan'}
|
||||||
|
taglineMaxLength={38}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</CardsContainer>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.top-light {
|
||||||
|
background: url('/imgs/grain.webp'),
|
||||||
|
radial-gradient(
|
||||||
|
100% 80% at top,
|
||||||
|
theme(colors.cyan.500 / 50%) 0%,
|
||||||
|
theme(colors.sky.500 / 10%),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
|
||||||
|
mask-image: radial-gradient(
|
||||||
|
100% 80% at top,
|
||||||
|
white,
|
||||||
|
rgba(0, 0, 0, 1),
|
||||||
|
rgba(0, 0, 0, 1),
|
||||||
|
transparent
|
||||||
|
);
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
z-index: -10;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
contain: strict;
|
||||||
|
|
||||||
|
animation: parallax ease-in-out 500ms;
|
||||||
|
animation-duration: 1ms;
|
||||||
|
animation-timeline: scroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes parallax {
|
||||||
|
to {
|
||||||
|
translate: 0px 1000px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
160
src/routes/plugins/PluginCard.svelte
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
<script>
|
||||||
|
import { getGeneratedPath, trimText } from '$lib/Helper.mjs'
|
||||||
|
import Card from '$lib/components/Card.svelte'
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import Tag from './Tag.svelte'
|
||||||
|
|
||||||
|
// Dont forget to put this component inside of CardsContainer.svelte
|
||||||
|
// Also pass a hight class to the element, as otherwise the banner might not align properly,
|
||||||
|
// due to the parent container being unable to use height: full as there wont be a reference
|
||||||
|
|
||||||
|
export let plugin
|
||||||
|
export let color = undefined
|
||||||
|
export let showCategory = false
|
||||||
|
export let taglineMaxLength = 0
|
||||||
|
|
||||||
|
/** @type {HTMLVideoElement}*/
|
||||||
|
let videoElement
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Card
|
||||||
|
on:mouseenter={() => videoElement && videoElement.play().catch(console.error)}
|
||||||
|
on:mouseleave={() => videoElement && videoElement.pause()}
|
||||||
|
{color}
|
||||||
|
class={$$restProps.class}
|
||||||
|
gradientOpacity={0.5}
|
||||||
|
><a
|
||||||
|
href="/plugins/{plugin.slug}"
|
||||||
|
class="relative flex size-full min-h-max items-stretch @container"
|
||||||
|
>
|
||||||
|
<!-- Main content -->
|
||||||
|
<div
|
||||||
|
class="flex min-h-max min-w-0 shrink grow-[3] flex-col justify-end p-5 @xs:p-6 @md:p-8 @2xl:max-w-max @4xl:min-w-20"
|
||||||
|
>
|
||||||
|
<!-- Logo -->
|
||||||
|
<div
|
||||||
|
class="logo-container relative mb-4 transition-transform
|
||||||
|
group-hover:scale-[1.02]"
|
||||||
|
>
|
||||||
|
{#if plugin.logo}
|
||||||
|
<div
|
||||||
|
class={clsx(
|
||||||
|
'logo relative rounded shadow-black ',
|
||||||
|
plugin.banner
|
||||||
|
? 'size-20 @md:size-28 max-2xl:@2xl:after:hidden'
|
||||||
|
: 'size-24 @md:size-28'
|
||||||
|
)}
|
||||||
|
style:--background={`url("${getGeneratedPath(plugin.logo)}")`}
|
||||||
|
>
|
||||||
|
<img class="size-full" src={plugin.logo} alt={'Logo of ' + plugin.name} />
|
||||||
|
</div>
|
||||||
|
{:else}
|
||||||
|
<!-- Placeholder logo -->
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
class="letter-logo -ml-4 flex items-center justify-center bg-gradient-to-tr from-primary via-sky-400 to-blue-400 bg-clip-text text-center text-6xl font-bold leading-none text-transparent"
|
||||||
|
>
|
||||||
|
{plugin.name[0]}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Texts -->
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<h2
|
||||||
|
class="min-w-[8ch] max-w-full text-pretty text-base font-bold text-white [overflow-wrap:break-word] @xl:mb-3 @xl:text-5xl"
|
||||||
|
>
|
||||||
|
{plugin.name}
|
||||||
|
</h2>
|
||||||
|
<p
|
||||||
|
class="overflow-hiddenx text-nowrapx max-w-[60ch] text-ellipsis text-sm font-medium text-slate-400 @xl:overflow-auto @xl:text-pretty @xl:text-base"
|
||||||
|
>
|
||||||
|
{trimText(plugin.tagline, taglineMaxLength || Number.POSITIVE_INFINITY)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Category -->
|
||||||
|
{#if showCategory}
|
||||||
|
<div
|
||||||
|
class="relative mt-3 flex min-h-max items-center gap-2 overflow-hidden @xl:min-w-0 @xl:flex-wrap"
|
||||||
|
>
|
||||||
|
<Tag tag={plugin.category} />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Banner -->
|
||||||
|
{#if plugin.banner}
|
||||||
|
<div class="banner-container hidden @xs:flex">
|
||||||
|
{#if plugin.banner.split('.').at(-1) === 'mp4'}
|
||||||
|
<video
|
||||||
|
src={plugin.banner}
|
||||||
|
class="absolute inset-0 z-50 size-full object-cover"
|
||||||
|
bind:this={videoElement}
|
||||||
|
playsinline
|
||||||
|
muted
|
||||||
|
loop
|
||||||
|
></video>
|
||||||
|
{:else}
|
||||||
|
<img src={plugin.banner} class="absolute inset-0 size-full object-cover" alt="" />
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</a>
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.logo {
|
||||||
|
contain: layout size;
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
left: 0%;
|
||||||
|
bottom: -2rem;
|
||||||
|
background-image: var(--background);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
height: 150%;
|
||||||
|
width: 120%;
|
||||||
|
translate: -12% 15%;
|
||||||
|
z-index: -1;
|
||||||
|
opacity: 50%;
|
||||||
|
/* filter: brightness(2); */
|
||||||
|
mask-image: radial-gradient(closest-side, black 0%, transparent 99%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.logo-container:not(.banner) {
|
||||||
|
@container (max-width: theme(screens.md)) {
|
||||||
|
@apply flex shrink-[2] grow items-center justify-center max-2xl:@2xl:mx-0 max-2xl:@2xl:block max-2xl:@2xl:h-auto max-2xl:@2xl:grow-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.banner-container {
|
||||||
|
position: absolute;
|
||||||
|
inset: 2px;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -20;
|
||||||
|
/* translate: 0 -2px; */
|
||||||
|
mask-image: radial-gradient(450% 120% at 0% 100%, black 18%, white);
|
||||||
|
mask-mode: luminance;
|
||||||
|
@apply rounded-3xl;
|
||||||
|
contain: strict;
|
||||||
|
|
||||||
|
@container (min-width: theme(screens.md)) {
|
||||||
|
position: relative;
|
||||||
|
/* width: 100%; */
|
||||||
|
height: 100%;
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-right: 3px;
|
||||||
|
max-height: calc(100% - 4px);
|
||||||
|
clip-path: polygon(0 0, 100% 0, 100% 100%, 4rem 100%);
|
||||||
|
@apply rounded-l-none rounded-r-3xl;
|
||||||
|
flex-shrink: 2;
|
||||||
|
mask-image: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.letter-logo {
|
||||||
|
text-shadow: 0 8px 24px theme(colors.primary / 60%);
|
||||||
|
}
|
||||||
|
</style>
|
18
src/routes/plugins/Tag.svelte
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<script>
|
||||||
|
/** @type {string}*/
|
||||||
|
export let tag
|
||||||
|
|
||||||
|
const colors = {
|
||||||
|
Design: 'text-pink-200 bg-pink-500/15',
|
||||||
|
'Quality of Life': 'text-orange-200 bg-orange-500/15',
|
||||||
|
Layout: 'text-blue-200 bg-blue-500/15',
|
||||||
|
Miscellaneous: 'text-purple-200 bg-purple-500/15',
|
||||||
|
Official: 'text-cyan-200 bg-cyan-500/15'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class={'min-w-max rounded-full p-1 px-2.5 text-xs font-bold ' + colors[tag] ?? 'bg-slate-100/5'}
|
||||||
|
>
|
||||||
|
{tag}
|
||||||
|
</div>
|
19
src/routes/plugins/[slug]/+page.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { error } from '@sveltejs/kit'
|
||||||
|
|
||||||
|
export async function load({ params, fetch }) {
|
||||||
|
try {
|
||||||
|
const post = await import(`../../../content/plugins/${params.slug}.md`)
|
||||||
|
const other = await fetch('/api/plugins')
|
||||||
|
.then((response) => response.json())
|
||||||
|
.then((news) => news.filter((entry) => entry.slug !== params.slug).slice(0, 4))
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: post.default,
|
||||||
|
meta: post.metadata,
|
||||||
|
other
|
||||||
|
}
|
||||||
|
} catch (errorMessage) {
|
||||||
|
console.error(errorMessage)
|
||||||
|
error(404, `Could not find ${params.slug}`)
|
||||||
|
}
|
||||||
|
}
|
188
src/routes/plugins/[slug]/+page.svelte
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
<script>
|
||||||
|
import CardsContainer from '$lib/components/CardsContainer.svelte'
|
||||||
|
import Title from '$lib/components/Title.svelte'
|
||||||
|
import clsx from 'clsx'
|
||||||
|
import PluginCard from '../PluginCard.svelte'
|
||||||
|
import Tag from '../Tag.svelte'
|
||||||
|
import { getGeneratedPath } from '$lib/Helper.mjs'
|
||||||
|
import GithubIcon from '~icons/ri/github-fill'
|
||||||
|
import BackIcon from '~icons/gg/arrow-left-r'
|
||||||
|
import InstallButton from '$lib/components/CommandButton.svelte'
|
||||||
|
import Button from '$lib/components/Button.svelte'
|
||||||
|
|
||||||
|
export let data
|
||||||
|
$: ({ meta } = data)
|
||||||
|
$: title = meta.name + ' Hyprland Plugin'
|
||||||
|
|
||||||
|
/** @type {HTMLVideoElement}*/
|
||||||
|
let videoElement
|
||||||
|
|
||||||
|
function playVideo() {
|
||||||
|
videoElement && videoElement.play().catch(console.error)
|
||||||
|
}
|
||||||
|
function pauseVideo() {
|
||||||
|
videoElement && videoElement.pause()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>{title}</title>
|
||||||
|
<meta property="og:type" content="article" />
|
||||||
|
<meta property="og:title" content={title} />
|
||||||
|
{#if meta.logo}
|
||||||
|
<meta property="og:image" content={meta.logo} />
|
||||||
|
{/if}
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<article
|
||||||
|
class={clsx(
|
||||||
|
'mx-auto mt-navbar flex min-h-[min(100vh,900px)] w-full max-w-screen-lg flex-col pt-8 transition-none delay-500 animate-in fade-in-0 fill-mode-backwards [animation-duration:400ms] lg:px-0',
|
||||||
|
meta.banner | meta.logo ? 'md:pt-12' : 'mt-12'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<!-- Back button -->
|
||||||
|
<a
|
||||||
|
href="/plugins"
|
||||||
|
class="mb-2 ml-2 flex items-center gap-3 text-slate-400 hover:text-slate-100 lg:ml-0"
|
||||||
|
><BackIcon />Back to all plugins</a
|
||||||
|
>
|
||||||
|
<!-- Banner -->
|
||||||
|
{#if meta.banner || meta.logo}
|
||||||
|
<div
|
||||||
|
class="relative flex aspect-video w-full min-w-full items-center justify-center overflow-hidden bg-neutral-950 animate-in fade-in-0 fill-mode-backwards [animation-delay:0.4s] [animation-duration:1.2s] sm:rounded-3xl md:h-[28rem]"
|
||||||
|
on:mouseenter={playVideo}
|
||||||
|
on:mouseleave={pauseVideo}
|
||||||
|
role="banner"
|
||||||
|
>
|
||||||
|
{#if meta.banner?.split('.').at(-1) === 'mp4'}
|
||||||
|
<video
|
||||||
|
src={meta.banner}
|
||||||
|
class="absolute left-1/2 top-1/2 z-10 size-full min-h-[44rem] min-w-full -translate-x-1/2 -translate-y-1/2"
|
||||||
|
bind:this={videoElement}
|
||||||
|
playsinline
|
||||||
|
muted
|
||||||
|
loop
|
||||||
|
></video>
|
||||||
|
{:else if meta.banner}
|
||||||
|
<img src={meta.banner} class="absolute inset-0 size-full object-cover" alt="" />
|
||||||
|
{:else if meta.logo}
|
||||||
|
<div class="grain absolute inset-0 flex size-full items-center justify-center">
|
||||||
|
<img src={meta.logo} class="z-30 size-48" alt="" />
|
||||||
|
<img
|
||||||
|
src={getGeneratedPath(meta.logo)}
|
||||||
|
class="absolute inset-0 object-cover opacity-30"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- ( Logo, Heading, Install buttons ) and tags -->
|
||||||
|
<div
|
||||||
|
class={clsx(
|
||||||
|
'relative z-20 mx-6 mb-24 mt-6 flex flex-col flex-wrap justify-between gap-4 duration-1000 animate-in fade-in-0 slide-in-from-bottom-4 md:mx-8 md:gap-8 lg:flex-nowrap',
|
||||||
|
!meta.banner && !meta.logo && 'mt-24 lg:mt-44',
|
||||||
|
!meta.banner && meta.logo && 'sm:-mt-16 md:-mt-20 lg:-mt-32',
|
||||||
|
meta.banner && meta.logo && 'sm:-mt-24 md:-mt-52 lg:-mt-64 '
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<hgroup
|
||||||
|
class="flex w-full flex-col gap-4"
|
||||||
|
on:mouseenter={playVideo}
|
||||||
|
on:mouseleave={pauseVideo}
|
||||||
|
role="heading"
|
||||||
|
aria-level="1"
|
||||||
|
>
|
||||||
|
<!-- Logo -->
|
||||||
|
{#if meta.logo && meta.banner}
|
||||||
|
<img src={meta.logo} class="size-20 md:size-28 lg:size-40" alt={'Logo ' + meta.name} />
|
||||||
|
{/if}
|
||||||
|
<h1
|
||||||
|
class="_text-shadow max-w-max text-pretty bg-gradient-to-br from-white via-white to-white/50 bg-clip-text py-2 text-5xl font-bold text-transparent md:text-7xl xl:text-8xl"
|
||||||
|
>
|
||||||
|
{meta.name}
|
||||||
|
</h1>
|
||||||
|
</hgroup>
|
||||||
|
|
||||||
|
<div class="flex w-full flex-wrap gap-16 md:flex-nowrap md:gap-8">
|
||||||
|
<div class="flex w-full grow-[4] flex-col justify-between gap-8 md:gap-12">
|
||||||
|
<p class="font-medium text-slate-300 sm:text-lg">
|
||||||
|
{meta.tagline}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<InstallButton
|
||||||
|
containerClass="max-w-max"
|
||||||
|
commandClass="text-left break-all md:break-normal text-slate-300 group-hover:text-white"
|
||||||
|
command={`hyprpm add ${meta.url}`}
|
||||||
|
>
|
||||||
|
<div class="self-start justify-self-start" slot="extra">
|
||||||
|
<span class="text-red-200">Trust the plugin source before installing!</span>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://wiki.hyprland.org/Plugins/Using-Plugins/"
|
||||||
|
target="_blank"
|
||||||
|
class="w-full text-left hover:underline"
|
||||||
|
>Installation is done via hyprpm ↗
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</InstallButton>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tags, Github button -->
|
||||||
|
<div class="flex shrink-0 flex-col items-start gap-8 md:items-end lg:shrink-[2]">
|
||||||
|
<a href={meta.url} target="_blank">
|
||||||
|
<GithubIcon class="size-10" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<Tag tag={meta.category} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Markdown -->
|
||||||
|
<section
|
||||||
|
class="prose prose-slate prose-invert mx-auto px-6 lg:prose-xl prose-a:text-cyan-400 prose-img:rounded-lg sm:px-8"
|
||||||
|
>
|
||||||
|
<svelte:component this={data.content} />
|
||||||
|
</section>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<!-- More plugins -->
|
||||||
|
{#if data.other.length > 0}
|
||||||
|
<section
|
||||||
|
class="relative mx-auto mt-64 flex w-full max-w-screen-xl flex-col items-center px-0 delay-1000 duration-1000 animate-in fade-in-0 fill-mode-backwards sm:px-4 md:px-8"
|
||||||
|
>
|
||||||
|
<Title class="mb-6"><span slot="title">More plugins</span></Title>
|
||||||
|
<CardsContainer class="flex w-full grid-cols-2 flex-col gap-8 md:grid">
|
||||||
|
{#each data.other as plugin}
|
||||||
|
<PluginCard showCategory={true} {plugin} class="h-96 min-h-96" />
|
||||||
|
{/each}
|
||||||
|
</CardsContainer>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="m-4 mt-16 max-w-max rounded-xl bg-slate-900/20 px-12 py-8 outline outline-cyan-100/5"
|
||||||
|
>
|
||||||
|
<Button type="fancyOutline"><a href="/plugins">Back to all plugins</a></Button>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.grain {
|
||||||
|
&::after {
|
||||||
|
content: ' ';
|
||||||
|
background: url('/imgs/grain.webp');
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 21;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
._text-shadow {
|
||||||
|
filter: drop-shadow(0 0 20px theme(colors.black / 50%));
|
||||||
|
}
|
||||||
|
</style>
|
Before Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 14 KiB |
0
static/imgs/profile_pictures/jsw.webp → static/imgs/profile_pictures/_anon.webp
Executable file → Normal file
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 678 B |
Before Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 5.6 KiB |
BIN
static/imgs/profile_pictures/chan_1.webp
Normal file
After Width: | Height: | Size: 4.5 KiB |
BIN
static/imgs/profile_pictures/chan_cat.webp
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
static/imgs/profile_pictures/chan_cat_2.webp
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 9.2 KiB |
Before Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 2.3 KiB |
|
@ -1,88 +1 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg fill="none" height="32" width="32" xmlns="http://www.w3.org/2000/svg"><clipPath id="prefix__a"><path d="M0 0h32v32H0z"/></clipPath><g clip-path="url(#prefix__a)"><path d="M31.103 20.992c0 2.01-.525 3.436-1.345 4.475-.827 1.05-2.016 1.784-3.476 2.29-2.961 1.029-6.772 1.039-10.182 1.039s-7.273-.01-10.287-1.04c-1.487-.508-2.701-1.244-3.546-2.296-.835-1.04-1.37-2.463-1.37-4.468 0-3.748.807-8.31 3.108-11.903 2.267-3.541 6.013-6.2 12.095-6.2 5.765 0 9.469 2.664 11.771 6.232 2.331 3.613 3.232 8.18 3.232 11.871z" fill="#fbc546" stroke="#000" stroke-width="1.794"/><g clip-rule="evenodd" fill-rule="evenodd"><path d="M19.454 22.413a.853.853 0 010 1.706H12.63a.853.853 0 010-1.706z" fill="#593604"/><path d="M27.133 19.853c0-.943-.764-1.706-1.706-1.706h-3.413a1.706 1.706 0 100 3.412h3.413c.942 0 1.706-.763 1.706-1.706zM11.776 19.853c0-.943-.764-1.706-1.706-1.706H6.657a1.706 1.706 0 100 3.412h3.413c.942 0 1.706-.763 1.706-1.706z" fill="#ed6b44"/><path d="M6.498 19a3.84 3.84 0 003.837-3.838v-.855a3.84 3.84 0 00-3.839-3.839h-.001a3.84 3.84 0 00-3.838 3.838v.855A3.84 3.84 0 006.497 19z" fill="#fff"/><path d="M5.217 14.726c0-.938.76-1.698 1.697-1.698h.017c.938 0 1.698.76 1.698 1.698v.002c0 .938-.76 1.698-1.698 1.698h-.017c-.937 0-1.697-.76-1.697-1.698v-.002z" fill="#000"/><path d="M25.586 19a3.84 3.84 0 01-3.837-3.838v-.856a3.84 3.84 0 013.837-3.838h.003a3.84 3.84 0 013.837 3.838v.855A3.84 3.84 0 0125.588 19h-.001z" fill="#fff"/><path d="M26.867 14.726c0-.938-.76-1.698-1.698-1.698h-.017c-.937 0-1.698.76-1.698 1.698v.002c0 .938.76 1.698 1.698 1.698h.017c.938 0 1.698-.76 1.698-1.698v-.002z" fill="#000"/></g></g></svg>
|
||||||
<svg
|
|
||||||
fill="none"
|
|
||||||
height="32"
|
|
||||||
viewBox="0 0 32 32"
|
|
||||||
width="32"
|
|
||||||
version="1.1"
|
|
||||||
id="svg113"
|
|
||||||
sodipodi:docname="jacekpoz revolt.svg"
|
|
||||||
inkscape:version="1.2 (dc2aedaf03, 2022-05-15)"
|
|
||||||
inkscape:export-filename="jacekpoz revolt.png"
|
|
||||||
inkscape:export-xdpi="1800"
|
|
||||||
inkscape:export-ydpi="1800"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg">
|
|
||||||
<defs
|
|
||||||
id="defs117" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="namedview115"
|
|
||||||
pagecolor="#505050"
|
|
||||||
bordercolor="#ffffff"
|
|
||||||
borderopacity="1"
|
|
||||||
inkscape:showpageshadow="0"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pagecheckerboard="1"
|
|
||||||
inkscape:deskcolor="#505050"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="37.28125"
|
|
||||||
inkscape:cx="9.0796312"
|
|
||||||
inkscape:cy="16"
|
|
||||||
inkscape:window-width="2560"
|
|
||||||
inkscape:window-height="1399"
|
|
||||||
inkscape:window-x="1920"
|
|
||||||
inkscape:window-y="41"
|
|
||||||
inkscape:window-maximized="1"
|
|
||||||
inkscape:current-layer="g111" />
|
|
||||||
<clipPath
|
|
||||||
id="a">
|
|
||||||
<path
|
|
||||||
d="m0 0h32v32h-32z"
|
|
||||||
id="path90" />
|
|
||||||
</clipPath>
|
|
||||||
<g
|
|
||||||
clip-path="url(#a)"
|
|
||||||
id="g111">
|
|
||||||
<path
|
|
||||||
d="m31.1028 20.9925c0 2.0091-.5252 3.4351-1.3444 4.4745-.8271 1.0495-2.0166 1.7841-3.4762 2.2907-2.9616 1.0282-6.7719 1.0379-10.1824 1.0379-3.4093 0-7.27255-.0094-10.28664-1.0393-1.48698-.5081-2.7015-1.2447-3.54601-2.2958-.83532-1.0397-1.370401-2.4634-1.370401-4.468 0-3.748.807291-8.3097 3.108411-11.90376 2.26699-3.54072 6.01294-6.19919 12.09464-6.19919 5.7647 0 9.4692 2.66321 11.7712 6.23125 2.3312 3.6131 3.2318 8.1799 3.2318 11.8717z"
|
|
||||||
fill="#fbc546"
|
|
||||||
stroke="#000"
|
|
||||||
stroke-width="1.7935"
|
|
||||||
id="path93" />
|
|
||||||
<g
|
|
||||||
clip-rule="evenodd"
|
|
||||||
fill-rule="evenodd"
|
|
||||||
id="g109">
|
|
||||||
<path
|
|
||||||
d="m19.4545 22.4125c.4709 0 .8531.3822.8531.8531 0 .471-.3822.8532-.8531.8532h-6.8253c-.4709 0-.8531-.3822-.8531-.8532 0-.4709.3822-.8531.8531-.8531z"
|
|
||||||
fill="#593604"
|
|
||||||
id="path95" />
|
|
||||||
<path
|
|
||||||
d="m27.1329 19.853c0-.9427-.7636-1.7063-1.7063-1.7063-1.0426 0-2.3701 0-3.4126 0-.9428 0-1.7064.7636-1.7064 1.7063 0 .9428.7636 1.7064 1.7064 1.7064h3.4126c.9427 0 1.7063-.7636 1.7063-1.7064z"
|
|
||||||
fill="#ed6b44"
|
|
||||||
id="path97" />
|
|
||||||
<path
|
|
||||||
d="m11.7761 19.853c0-.9427-.7636-1.7063-1.7064-1.7063-1.04251 0-2.37002 0-3.41258 0-.94274 0-1.70631.7636-1.70631 1.7063 0 .9428.76357 1.7064 1.70631 1.7064h3.41258c.9428 0 1.7064-.7636 1.7064-1.7064z"
|
|
||||||
fill="#ed6b44"
|
|
||||||
id="path99" />
|
|
||||||
<path
|
|
||||||
d="m 6.498,18.9998 c 1.0178,0 1.9938,-0.4044 2.7139,-1.1236 0.7192,-0.72 1.1236,-1.696 1.1236,-2.7139 0,-0.2841 0,-0.5707 0,-0.8548 0,-2.1201 -1.7191,-3.8392 -3.8392,-3.8392 -8e-4,0 -8e-4,0 -0.0017,0 -1.01781,0 -1.99382,0.4044 -2.71389,1.1236 -0.71921,0.72 -1.12361,1.696 -1.12361,2.7139 v 0.8548 c 0,2.1201 1.71912,3.8392 3.8392,3.8392 z"
|
|
||||||
fill="#ffffff"
|
|
||||||
id="path101" />
|
|
||||||
<path
|
|
||||||
d="m 5.21658,14.7256 c 0,-0.9376 0.76017,-1.6978 1.69782,-1.6978 h 0.017 c 0.9376,0 1.6978,0.7602 1.6978,1.6978 v 0.0026 c 0,0.9376 -0.7602,1.6978 -1.6978,1.6978 -0.0059,0 -0.0111,0 -0.017,0 -0.93765,0 -1.69782,-0.7602 -1.69782,-1.6978 0,-9e-4 0,-0.0017 0,-0.0026 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path103" />
|
|
||||||
<path
|
|
||||||
d="m 25.5857,18.9998 c -1.0178,0 -1.9939,-0.4044 -2.7139,-1.1236 -0.7192,-0.72 -1.1236,-1.696 -1.1236,-2.7139 0,-0.2849 0,-0.5716 0,-0.8565 0,-1.0179 0.4044,-1.9939 1.1236,-2.7139 0.72,-0.7192 1.6961,-1.1236 2.7139,-1.1236 h 0.0034 c 1.0178,0 1.9938,0.4044 2.7139,1.1236 0.7192,0.72 1.1236,1.696 1.1236,2.7139 v 0.8548 c 0,2.1201 -1.7191,3.8392 -3.8392,3.8392 -9e-4,0 -9e-4,0 -0.0017,0 z"
|
|
||||||
fill="#ffffff"
|
|
||||||
id="path105" />
|
|
||||||
<path
|
|
||||||
d="m 26.8671,14.7256 c 0,-0.9376 -0.7602,-1.6978 -1.6978,-1.6978 -0.006,0 -0.0111,0 -0.017,0 -0.9377,0 -1.6978,0.7602 -1.6978,1.6978 v 0.0026 c 0,0.9376 0.7601,1.6978 1.6978,1.6978 h 0.017 c 0.9376,0 1.6978,-0.7602 1.6978,-1.6978 0,-9e-4 0,-0.0017 0,-0.0026 z"
|
|
||||||
fill="#000000"
|
|
||||||
id="path107" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 377 KiB |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 222 KiB |
BIN
static/plugins-data/hy3_banner.mp4
Normal file
BIN
static/plugins-data/hyprwinwrap.webp
Normal file
After Width: | Height: | Size: 1.2 MiB |
48
static/plugins-data/logos/Borders-plus-plus-logo.svg
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
<svg width="88" height="88" viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="3" y="14" width="81.7647" height="60.0692" rx="24" fill="#0057FF" />
|
||||||
|
<rect x="10.0374" y="21.0374" width="67.6899" height="45.9944" rx="16.9626" fill="url(#paint0_radial_1823_494)" />
|
||||||
|
<rect x="10.0374" y="21.0374" width="67.6899" height="45.9944" rx="16.9626" stroke="url(#paint1_radial_1823_494)"
|
||||||
|
stroke-width="6.07474" />
|
||||||
|
<g filter="url(#filter0_i_1823_494)">
|
||||||
|
<path d="M31.2793 51.8893V36.1798H35.2511V51.8893H31.2793ZM25.4105 46.0204V42.0487H41.12V46.0204H25.4105Z"
|
||||||
|
fill="url(#paint2_linear_1823_494)" />
|
||||||
|
<path d="M52.5138 51.8893V36.1798H56.4855V51.8893H52.5138ZM46.6449 46.0204V42.0487H62.3544V46.0204H46.6449Z"
|
||||||
|
fill="url(#paint3_linear_1823_494)" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_i_1823_494" x="23.6748" y="34.4442" width="38.6796" height="17.4451"
|
||||||
|
filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||||
|
result="hardAlpha" />
|
||||||
|
<feOffset dx="-1.73564" dy="-1.73564" />
|
||||||
|
<feGaussianBlur stdDeviation="1.73564" />
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.0730794 0 0 0 0 0.610693 0 0 0 0 1 0 0 0 0.5 0" />
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1823_494" />
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_1823_494" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(36.0222 35.0719) rotate(34.7051) scale(38.9801 36.4968)">
|
||||||
|
<stop stop-color="#0085E6" />
|
||||||
|
<stop offset="1" stop-color="#003BD4" />
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint1_radial_1823_494" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="translate(78.0753 51.628) rotate(-162.865) scale(69.9544 53.6959)">
|
||||||
|
<stop stop-color="#2F76FF" />
|
||||||
|
<stop offset="1" stop-color="#00F0FF" />
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint2_linear_1823_494" x1="53.8894" y1="34.8966" x2="57.5442" y2="59.7195"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white" />
|
||||||
|
<stop offset="0.615" stop-color="#00B3FF" stop-opacity="0.455" />
|
||||||
|
<stop offset="1" stop-color="#1D84DA" stop-opacity="0" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint3_linear_1823_494" x1="53.8894" y1="34.8966" x2="57.5442" y2="59.7195"
|
||||||
|
gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white" />
|
||||||
|
<stop offset="0.615" stop-color="#00B3FF" stop-opacity="0.455" />
|
||||||
|
<stop offset="1" stop-color="#1D84DA" stop-opacity="0" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
154
static/plugins-data/logos/hy3-logo.svg
Normal file
|
@ -0,0 +1,154 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="100mm"
|
||||||
|
height="100mm"
|
||||||
|
viewBox="0 0 100 100"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
sodipodi:docname="hy3.svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview7"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#505050"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="true"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:zoom="1.3202441"
|
||||||
|
inkscape:cx="187.08662"
|
||||||
|
inkscape:cy="183.29944"
|
||||||
|
inkscape:window-width="1761"
|
||||||
|
inkscape:window-height="1413"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g1739"><inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid9"
|
||||||
|
spacingx="2.5"
|
||||||
|
spacingy="2.5"
|
||||||
|
units="mm"
|
||||||
|
visible="true" /><sodipodi:guide
|
||||||
|
position="40,60"
|
||||||
|
orientation="0.70710678,0.70710678"
|
||||||
|
id="guide65"
|
||||||
|
inkscape:locked="false"
|
||||||
|
inkscape:label=""
|
||||||
|
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||||
|
position="5,60"
|
||||||
|
orientation="0.70710678,0.70710678"
|
||||||
|
id="guide69"
|
||||||
|
inkscape:locked="false"
|
||||||
|
inkscape:label=""
|
||||||
|
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||||
|
position="40,94.999999"
|
||||||
|
orientation="0.70710678,0.70710678"
|
||||||
|
id="guide71"
|
||||||
|
inkscape:locked="false"
|
||||||
|
inkscape:label=""
|
||||||
|
inkscape:color="rgb(0,134,229)" /><sodipodi:guide
|
||||||
|
position="17.5,82.499999"
|
||||||
|
orientation="0.70710678,-0.70710678"
|
||||||
|
id="guide75"
|
||||||
|
inkscape:locked="false"
|
||||||
|
inkscape:label=""
|
||||||
|
inkscape:color="rgb(0,134,229)" /></sodipodi:namedview><defs
|
||||||
|
id="defs2"><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
id="linearGradient1833"><stop
|
||||||
|
style="stop-color:#009ff9;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop1829" /><stop
|
||||||
|
style="stop-color:#00e7cd;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop1831" /></linearGradient><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1833"
|
||||||
|
id="linearGradient1835"
|
||||||
|
x1="0"
|
||||||
|
y1="62.5"
|
||||||
|
x2="100"
|
||||||
|
y2="25"
|
||||||
|
gradientUnits="userSpaceOnUse" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1833"
|
||||||
|
id="linearGradient882"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="0"
|
||||||
|
y1="62.5"
|
||||||
|
x2="100"
|
||||||
|
y2="25" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1833"
|
||||||
|
id="linearGradient884"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="0"
|
||||||
|
y1="62.5"
|
||||||
|
x2="100"
|
||||||
|
y2="25" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1833"
|
||||||
|
id="linearGradient886"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="0"
|
||||||
|
y1="62.5"
|
||||||
|
x2="100"
|
||||||
|
y2="25" /><linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient1833"
|
||||||
|
id="linearGradient888"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
x1="0"
|
||||||
|
y1="62.5"
|
||||||
|
x2="100"
|
||||||
|
y2="25" /></defs><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="g1741"
|
||||||
|
inkscape:label="logo"
|
||||||
|
style="fill:url(#linearGradient1835);fill-opacity:1"><g
|
||||||
|
inkscape:label="i3"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="g1731"
|
||||||
|
transform="translate(3.0000001,3.0000001)"
|
||||||
|
style="fill-opacity:1;fill:url(#linearGradient1835)"><g
|
||||||
|
id="g1727"
|
||||||
|
inkscape:label="inner"
|
||||||
|
style="fill-opacity:1;fill:url(#linearGradient1835)"><path
|
||||||
|
style="stroke-width:13;stroke-linecap:round;-inkscape-stroke:none;fill-opacity:1;fill:url(#linearGradient1835)"
|
||||||
|
d="m 44.999999,44.999999 20,20"
|
||||||
|
id="path1723" /><path
|
||||||
|
style="stroke-linecap:round;-inkscape-stroke:none;fill-opacity:1;fill:url(#linearGradient1835)"
|
||||||
|
d="m 45,38.5 a 6.5,6.5 0 0 0 -4.595703,1.904297 6.5,6.5 0 0 0 0,9.191406 l 20,20 a 6.5,6.5 0 0 0 9.191406,0 6.5,6.5 0 0 0 0,-9.191406 l -20,-20 A 6.5,6.5 0 0 0 45,38.5 Z"
|
||||||
|
id="path1725" /></g><path
|
||||||
|
style="stroke-linecap:round;stroke-miterlimit:3.9;-inkscape-stroke:none;fill-opacity:1;fill:url(#linearGradient1835)"
|
||||||
|
d="m 62.5,21 a 6.5,6.5 0 0 0 -4.595703,1.904297 6.5,6.5 0 0 0 0,9.191406 l 20,20 c 0,0 3.352817,3.478374 4.992187,8.396484 1.639371,4.918111 2.22574,10.194182 -4.992187,17.41211 -7.217928,7.217927 -12.493998,6.631558 -17.41211,4.992187 -4.918111,-1.63937 -8.396484,-4.992187 -8.396484,-4.992187 l -20,-20 a 6.5,6.5 0 0 0 -9.191406,0 6.5,6.5 0 0 0 0,9.191406 l 20,20 c 0,0 5.271639,5.397187 13.478515,8.132813 8.206877,2.735625 20.430837,2.149241 30.712891,-8.132813 C 97.377757,76.813649 97.964142,64.589688 95.228516,56.382812 92.492889,48.175937 87.095703,42.904297 87.095703,42.904297 l -20,-20 A 6.5,6.5 0 0 0 62.5,21 Z"
|
||||||
|
id="path1729" /></g><g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="g1739"
|
||||||
|
inkscape:label="hyprland"
|
||||||
|
style="fill:url(#linearGradient888);fill-opacity:1"
|
||||||
|
transform="translate(2.5,2.5)"><path
|
||||||
|
d="m 1.807378,35.000035 2.191099,2.191098 0.630899,0.630901 c 0.08347,0.08347 0.18178,0.225239 0.292093,0.270611 0.09905,0.0406 0.215786,0.04969 0.319879,0.07229 0.259866,0.05628 0.521263,0.103675 0.781808,0.156022 0.859731,0.172563 1.725088,0.315621 2.59215,0.445898 1.458315,0.219022 2.927802,0.350315 4.382627,0.59347 2.17703,0.363792 4.352779,1.013617 6.160824,2.313695 0.300116,0.215693 0.611972,0.434982 0.884713,0.684021 0.207102,0.188992 0.398866,0.398116 0.597168,0.596417 0.143064,0.143065 0.304712,0.279986 0.43419,0.435439 0.542354,0.653629 0.967321,1.412358 1.303574,2.191948 0.421001,0.976188 0.629969,2.024936 0.704395,3.081014 0.158063,2.241573 -0.715136,4.469325 -2.152826,6.158351 -0.167668,0.196891 -0.370666,0.371915 -0.553544,0.554793 -0.182879,0.18288 -0.35809,0.38569 -0.554794,0.553545 -1.037907,0.883435 -2.266806,1.552699 -3.590499,1.900036 C 14.142856,58.377615 11.86709,58.055937 9.952143,57.087335 9.197967,56.705898 8.532698,56.218481 7.93761,55.623393 7.743136,55.428919 7.52981,55.242568 7.34996,55.034493 6.855831,54.46206 6.418019,53.830074 6.039816,53.173086 4.77324,50.972777 4.368186,48.37645 4.063224,45.89369 3.890155,44.484736 3.710343,43.077742 3.446049,41.682431 3.374179,41.302774 3.302136,40.923473 3.227029,40.544502 3.190539,40.359669 3.175529,40.136807 3.102209,39.963058 3.055899,39.853681 2.913899,39.755265 2.830599,39.671964 L 2.191176,39.032542 0.0086,36.849966 0,36.858566 c 0.149003,0.416712 0.200276,0.89887 0.287053,1.332822 0.17415,0.871034 0.338302,1.743335 0.483921,2.619431 0.67481,4.059158 0.743697,8.347414 2.47927,12.150796 0.368561,0.80764 0.804999,1.576403 1.30639,2.308498 0.356122,0.519988 0.767826,0.989327 1.180378,1.462588 0.240228,0.27557 0.492006,0.558695 0.768814,0.799909 2.122385,1.848882 4.977891,2.930875 7.807987,2.830528 1.339735,-0.04757 2.658059,-0.322528 3.893601,-0.846686 1.211838,-0.514267 2.266804,-1.259589 3.252459,-2.118721 2.388721,-2.082309 3.903991,-5.148567 3.903997,-8.338884 -6e-6,-1.474088 -0.285698,-2.969065 -0.850951,-4.33266 C 24.018859,43.534195 23.353854,42.451778 22.507,41.480272 22.210847,41.14041 21.855617,40.855368 21.527395,40.550124 19.903004,39.03963 17.810791,38.050148 15.701625,37.423932 12.888576,36.588672 9.961704,36.409809 7.075251,35.972947 5.923346,35.798597 4.77434,35.603617 3.631902,35.37513 3.253949,35.2995 2.874627,35.228631 2.498412,35.144513 2.274938,35.094433 2.035841,35.015629 1.807403,35 Z"
|
||||||
|
id="path1733"
|
||||||
|
inkscape:label="3"
|
||||||
|
style="fill:url(#linearGradient882);fill-opacity:1" /><path
|
||||||
|
d="m 19.307378,17.500035 2.191099,2.191098 0.630899,0.630901 c 0.08347,0.08347 0.18178,0.225239 0.292093,0.270611 0.09905,0.0406 0.215786,0.04969 0.319879,0.07229 0.259866,0.05628 0.521263,0.103675 0.781808,0.156022 0.859731,0.172563 1.725088,0.315621 2.59215,0.445898 1.458315,0.219022 2.927802,0.350315 4.382627,0.59347 2.17703,0.363792 4.352779,1.013617 6.160824,2.313695 0.300116,0.215693 0.611972,0.434982 0.884713,0.684021 0.207102,0.188992 0.398866,0.398116 0.597168,0.596417 0.143064,0.143065 0.304712,0.279986 0.43419,0.435439 0.542354,0.653629 0.967321,1.412358 1.303574,2.191948 0.421001,0.976188 0.629969,2.024936 0.704395,3.081014 0.158063,2.241573 -0.715136,4.469325 -2.152826,6.158351 -0.167668,0.196891 -0.370666,0.371915 -0.553544,0.554793 -0.182879,0.18288 -0.35809,0.38569 -0.554794,0.553545 -1.037907,0.883435 -2.266806,1.552699 -3.590499,1.900036 -2.088278,0.548031 -4.364044,0.226353 -6.278991,-0.742249 -0.754176,-0.381437 -1.419445,-0.868854 -2.014533,-1.463942 -0.194474,-0.194474 -0.4078,-0.380825 -0.58765,-0.5889 -0.494129,-0.572433 -0.931941,-1.204419 -1.310144,-1.861407 -1.266576,-2.200309 -1.67163,-4.796636 -1.976592,-7.279396 -0.173069,-1.408954 -0.352881,-2.815948 -0.617175,-4.211259 -0.07187,-0.379657 -0.143913,-0.758958 -0.21902,-1.137929 -0.03649,-0.184833 -0.0515,-0.407695 -0.12482,-0.581444 -0.04631,-0.109377 -0.18831,-0.207793 -0.27161,-0.291094 L 19.691176,21.532542 17.5086,19.349966 17.5,19.358566 c 0.149003,0.416712 0.200276,0.89887 0.287053,1.332822 0.17415,0.871034 0.338302,1.743335 0.483921,2.619431 0.67481,4.059158 0.743697,8.347414 2.47927,12.150796 0.368561,0.80764 0.804999,1.576403 1.30639,2.308498 0.356122,0.519988 0.767826,0.989327 1.180378,1.462588 0.240228,0.27557 0.492006,0.558695 0.768814,0.799909 2.122385,1.848882 4.977891,2.930875 7.807987,2.830528 1.339735,-0.04757 2.658059,-0.322528 3.893601,-0.846686 1.211838,-0.514267 2.266804,-1.259589 3.252459,-2.118721 2.388721,-2.082309 3.903991,-5.148567 3.903997,-8.338884 -6e-6,-1.474088 -0.285698,-2.969065 -0.850951,-4.33266 C 41.518859,26.034195 40.853854,24.951778 40.007,23.980272 39.710847,23.64041 39.355617,23.355368 39.027395,23.050124 37.403004,21.53963 35.310791,20.550148 33.201625,19.923932 30.388576,19.088672 27.461704,18.909809 24.575251,18.472947 23.423346,18.298597 22.27434,18.103617 21.131902,17.87513 20.753949,17.7995 20.374627,17.728631 19.998412,17.644513 19.774938,17.594433 19.535841,17.515629 19.307403,17.5 Z"
|
||||||
|
id="path1735"
|
||||||
|
inkscape:label="2"
|
||||||
|
style="fill:url(#linearGradient884);fill-opacity:1" /><path
|
||||||
|
d="m 36.807378,3.5e-5 2.191099,2.191098 0.630899,0.630901 c 0.08347,0.08347 0.18178,0.225239 0.292093,0.270611 0.09905,0.0406 0.215786,0.04969 0.319879,0.07229 0.259866,0.05628 0.521263,0.103675 0.781808,0.156022 0.859731,0.172563 1.725088,0.315621 2.59215,0.4458979 1.458315,0.219022 2.927802,0.350315 4.382627,0.59347 2.17703,0.363792 4.352779,1.013617 6.160824,2.313695 0.300116,0.215693 0.611972,0.434982 0.884713,0.684021 0.207102,0.188992 0.398866,0.398116 0.597168,0.596417 0.143064,0.143065 0.304712,0.279986 0.43419,0.435439 0.542354,0.653629 0.967321,1.4123581 1.303574,2.1919481 0.421001,0.976188 0.629969,2.024936 0.704395,3.081014 0.158063,2.241573 -0.715136,4.469325 -2.152826,6.158351 -0.167668,0.196891 -0.370666,0.371915 -0.553544,0.554793 -0.182879,0.18288 -0.35809,0.38569 -0.554794,0.553545 -1.037907,0.883435 -2.266806,1.552699 -3.590499,1.900036 -2.088278,0.548031 -4.364044,0.226353 -6.278991,-0.742249 -0.754176,-0.381437 -1.419445,-0.868854 -2.014533,-1.463942 -0.194474,-0.194474 -0.4078,-0.380825 -0.58765,-0.5889 C 41.855831,19.46206 41.418019,18.830074 41.039816,18.173086 39.77324,15.972777 39.368186,13.37645 39.063224,10.89369 38.890155,9.4847359 38.710343,8.0777419 38.446049,6.6824309 c -0.07187,-0.379657 -0.143913,-0.758958 -0.21902,-1.137929 -0.03649,-0.184833 -0.0515,-0.407695 -0.12482,-0.581444 -0.04631,-0.109377 -0.18831,-0.207793 -0.27161,-0.291094 L 37.191176,4.0325419 35.0086,1.849966 35,1.858566 c 0.149003,0.416712 0.200276,0.89887 0.287053,1.332822 0.17415,0.8710339 0.338302,1.7433349 0.483921,2.6194309 0.67481,4.0591581 0.743697,8.3474141 2.47927,12.1507961 0.368561,0.80764 0.804999,1.576403 1.30639,2.308498 0.356122,0.519988 0.767826,0.989327 1.180378,1.462588 0.240228,0.27557 0.492006,0.558695 0.768814,0.799909 2.122385,1.848882 4.977891,2.930875 7.807987,2.830528 1.339735,-0.04757 2.658059,-0.322528 3.893601,-0.846686 1.211838,-0.514267 2.266804,-1.259589 3.252459,-2.118721 2.388721,-2.082309 3.903991,-5.148567 3.903997,-8.338884 -6e-6,-1.474088 -0.285698,-2.969065 -0.850951,-4.33266 C 59.018859,8.5341949 58.353854,7.4517779 57.507,6.4802719 57.210847,6.1404099 56.855617,5.8553679 56.527395,5.5501239 54.903004,4.0396299 52.810791,3.050148 50.701625,2.423932 47.888576,1.5886719 44.961704,1.4098089 42.075251,0.97294691 40.923346,0.79859691 39.77434,0.60361695 38.631902,0.37513 38.253949,0.2995 37.874627,0.228631 37.498412,0.144513 37.274938,0.094433 37.035841,0.015629 36.807403,0 Z"
|
||||||
|
id="path1737"
|
||||||
|
inkscape:label="1"
|
||||||
|
style="fill:url(#linearGradient886);fill-opacity:1" /></g></g></svg>
|
After Width: | Height: | Size: 13 KiB |
68
static/plugins-data/logos/hyprbars-logo.svg
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<svg width="88" height="88" viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="3.22175" y="22.8962" width="80.5565" height="41.2076" rx="16.9634" fill="url(#paint0_radial_1823_1834)"/>
|
||||||
|
<rect x="3.22175" y="22.8962" width="80.5565" height="41.2076" rx="16.9634" stroke="url(#paint1_radial_1823_1834)" stroke-width="5.79238"/>
|
||||||
|
<g filter="url(#filter0_i_1823_1834)">
|
||||||
|
<circle cx="21.5778" cy="43.5" r="7.65116" fill="url(#paint2_linear_1823_1834)"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter1_i_1823_1834)">
|
||||||
|
<circle cx="43.5" cy="43.5" r="7.65116" fill="url(#paint3_linear_1823_1834)"/>
|
||||||
|
</g>
|
||||||
|
<g filter="url(#filter2_i_1823_1834)">
|
||||||
|
<circle cx="65.4222" cy="43.5" r="7.65116" fill="url(#paint4_linear_1823_1834)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<filter id="filter0_i_1823_1834" x="12.2717" y="34.1939" width="16.9573" height="16.9573" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-1.65497" dy="-1.65497"/>
|
||||||
|
<feGaussianBlur stdDeviation="1.65497"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.0730794 0 0 0 0 0.610693 0 0 0 0 1 0 0 0 0.5 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1823_1834"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter1_i_1823_1834" x="34.1939" y="34.1939" width="16.9573" height="16.9573" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-1.65497" dy="-1.65497"/>
|
||||||
|
<feGaussianBlur stdDeviation="1.65497"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.0730794 0 0 0 0 0.610693 0 0 0 0 1 0 0 0 0.5 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1823_1834"/>
|
||||||
|
</filter>
|
||||||
|
<filter id="filter2_i_1823_1834" x="56.116" y="34.1939" width="16.9573" height="16.9573" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||||
|
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||||
|
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
|
||||||
|
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||||
|
<feOffset dx="-1.65497" dy="-1.65497"/>
|
||||||
|
<feGaussianBlur stdDeviation="1.65497"/>
|
||||||
|
<feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1"/>
|
||||||
|
<feColorMatrix type="matrix" values="0 0 0 0 0.0730794 0 0 0 0 0.610693 0 0 0 0 1 0 0 0 0.5 0"/>
|
||||||
|
<feBlend mode="normal" in2="shape" result="effect1_innerShadow_1823_1834"/>
|
||||||
|
</filter>
|
||||||
|
<radialGradient id="paint0_radial_1823_1834" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(34.2989 35.4098) rotate(28.1037) scale(42.5262 35.3481)">
|
||||||
|
<stop stop-color="#0085E6"/>
|
||||||
|
<stop offset="1" stop-color="#003BD4"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint1_radial_1823_1834" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(83.5263 50.3542) rotate(-166.627) scale(80.4347 49.3444)">
|
||||||
|
<stop stop-color="#2F76FF"/>
|
||||||
|
<stop offset="1" stop-color="#00F0FF"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint2_linear_1823_1834" x1="25.7227" y1="34.5989" x2="33.3607" y2="56.6579" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="0.615" stop-color="#00B3FF" stop-opacity="0.455"/>
|
||||||
|
<stop offset="1" stop-color="#1D84DA" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint3_linear_1823_1834" x1="47.6449" y1="34.5989" x2="55.2828" y2="56.6579" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="0.615" stop-color="#00B3FF" stop-opacity="0.455"/>
|
||||||
|
<stop offset="1" stop-color="#1D84DA" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint4_linear_1823_1834" x1="69.5671" y1="34.5989" x2="77.205" y2="56.6579" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="white"/>
|
||||||
|
<stop offset="0.615" stop-color="#00B3FF" stop-opacity="0.455"/>
|
||||||
|
<stop offset="1" stop-color="#1D84DA" stop-opacity="0"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 4.3 KiB |
24
static/plugins-data/logos/hyprtrails-logo.svg
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<svg width="88" height="88" viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_1824_23)">
|
||||||
|
<path d="M30.6529 48.4957C42.4614 48.4149 36.7708 73.354 78.05 37.297C81.3825 34.3861 83.0488 32.9306 83.0703 32.4895C83.0918 32.0484 81.7097 30.5803 78.9454 27.6441C74.9936 23.4465 67.4717 19.6656 52.5343 29.3582C22.489 48.854 43.7731 16.11 14.8695 30.557C-8.76737 42.3715 6.27442 60.5648 12.8474 61.5578C14.312 61.7791 10.6977 59.9456 11.7726 56.7211C14.2839 49.187 18.3871 48.5796 30.6529 48.4957Z" fill="url(#paint0_radial_1824_23)"/>
|
||||||
|
<circle cx="46.4304" cy="45.8792" r="27.0079" fill="url(#paint1_radial_1824_23)"/>
|
||||||
|
<path d="M57.195 37.8283C45.3805 37.9091 46.9205 34.8742 5.26469 72.6271C4.64135 73.192 4.32968 73.4745 4.85261 74.2244C5.37553 74.9743 5.71333 74.7978 6.38893 74.4447C11.7349 71.6509 20.8663 66.3404 35.3137 56.9657C65.3589 37.47 44.0748 70.214 72.9784 55.767C96.6153 43.9525 81.5735 25.7591 75.0006 24.7661C73.536 24.5449 77.1502 26.3784 76.0754 29.6029C73.5641 37.1369 69.4608 37.7444 57.195 37.8283Z" fill="url(#paint2_radial_1824_23)"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="paint0_radial_1824_23" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(38.6435 26.0881) rotate(135.659) scale(33.0633 23.4711)">
|
||||||
|
<stop stop-color="#5EFFFF"/>
|
||||||
|
<stop offset="1" stop-color="#014FE6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint1_radial_1824_23" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(28.6052 26.9737) rotate(22.8645) scale(48.6562 48.6492)">
|
||||||
|
<stop offset="0.57" stop-color="#00E6CF"/>
|
||||||
|
<stop offset="1" stop-color="#014FE6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint2_radial_1824_23" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(49.2044 60.2358) rotate(-44.3415) scale(33.0633 23.4711)">
|
||||||
|
<stop stop-color="#9CEDFF"/>
|
||||||
|
<stop offset="1" stop-color="#014FE6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<clipPath id="clip0_1824_23">
|
||||||
|
<rect width="88" height="88" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2 KiB |
29
static/plugins-data/logos/hyprwinwrap-logo.svg
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<svg width="88" height="88" viewBox="0 0 88 88" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="10" y="10" width="68" height="68" rx="12.75" fill="url(#paint0_radial_1824_34)"/>
|
||||||
|
<rect x="14.25" y="73.75" width="59.5" height="59.5" rx="12.75" transform="rotate(-90 14.25 73.75)" fill="url(#paint1_radial_1824_34)"/>
|
||||||
|
<rect x="18.5" y="63.125" width="38.25" height="51" rx="8.5" transform="rotate(-90 18.5 63.125)" fill="url(#paint2_linear_1824_34)"/>
|
||||||
|
<rect x="22.75" y="58.875" width="29.75" height="42.5" rx="8.5" transform="rotate(-90 22.75 58.875)" fill="url(#paint3_linear_1824_34)"/>
|
||||||
|
<rect x="25.9375" y="54.625" width="21.25" height="36.125" rx="6.375" transform="rotate(-90 25.9375 54.625)" fill="url(#paint4_linear_1824_34)"/>
|
||||||
|
<defs>
|
||||||
|
<radialGradient id="paint0_radial_1824_34" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(12.6562 11.0625) rotate(45.7192) scale(89.7875 76.8117)">
|
||||||
|
<stop offset="0.45" stop-color="#00BCDA"/>
|
||||||
|
<stop offset="0.855" stop-color="#014FE6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient id="paint1_radial_1824_34" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(18.5 127.406) rotate(-42.8789) scale(71.0466 65.0439)">
|
||||||
|
<stop offset="0.23" stop-color="#017FDA"/>
|
||||||
|
<stop offset="0.87" stop-color="#014FE6"/>
|
||||||
|
</radialGradient>
|
||||||
|
<linearGradient id="paint2_linear_1824_34" x1="37.625" y1="63.125" x2="37.625" y2="114.125" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#5EE9FF"/>
|
||||||
|
<stop offset="1" stop-color="#014FE6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint3_linear_1824_34" x1="25.8125" y1="83.8207" x2="51.3741" y2="63.9353" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#53E8FF"/>
|
||||||
|
<stop offset="1" stop-color="#014FE6"/>
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient id="paint4_linear_1824_34" x1="25.9375" y1="66.2174" x2="47.1875" y2="66.2174" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop stop-color="#0084E3"/>
|
||||||
|
<stop offset="1" stop-color="#014FE6"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -1,7 +1,7 @@
|
||||||
import adapter from '@sveltejs/adapter-static'
|
import adapter from '@sveltejs/adapter-static'
|
||||||
import { vitePreprocess } from '@sveltejs/kit/vite'
|
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
|
||||||
import { mdsvex, escapeSvelte } from 'mdsvex'
|
import { mdsvex, escapeSvelte } from 'mdsvex'
|
||||||
import shiki from 'shiki'
|
import {getHighlighter} from 'shiki'
|
||||||
import remarkUnwrapImages from 'remark-unwrap-images'
|
import remarkUnwrapImages from 'remark-unwrap-images'
|
||||||
import rehypeSlug from 'rehype-slug'
|
import rehypeSlug from 'rehype-slug'
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ const mdsvexOptions = {
|
||||||
extensions: ['.md'],
|
extensions: ['.md'],
|
||||||
highlight: {
|
highlight: {
|
||||||
highlighter: async (code, lang = 'text') => {
|
highlighter: async (code, lang = 'text') => {
|
||||||
const highlighter = await shiki.getHighlighter({ theme: 'github-dark' })
|
const highlighter = await getHighlighter({ theme: 'github-dark' })
|
||||||
const html = escapeSvelte(highlighter.codeToHtml(code, { lang }))
|
const html = escapeSvelte(highlighter.codeToHtml(code, { lang }))
|
||||||
return `{@html \`${html}\` }`
|
return `{@html \`${html}\` }`
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ export default {
|
||||||
content: ['./src/**/**/*.{html,js,svelte,ts}'],
|
content: ['./src/**/**/*.{html,js,svelte,ts}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
colors: { black: '#0b0d0e', primary: '#58E1FF', secondary: '#00A2F8' },
|
colors: { black: '#090b0c', primary: '#58E1FF', secondary: '#00A2F8' },
|
||||||
fontFamily: {
|
fontFamily: {
|
||||||
...fontFamily,
|
...fontFamily,
|
||||||
sans: ['Work Sans Variable', ...fontFamily['sans']],
|
sans: ['Work Sans Variable', ...fontFamily['sans']],
|
||||||
|
@ -17,6 +17,9 @@ export default {
|
||||||
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))'
|
'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))'
|
||||||
},
|
},
|
||||||
margin: { navbar: '3.5rem' },
|
margin: { navbar: '3.5rem' },
|
||||||
|
|
||||||
|
screens: { '3xl': '2560px' },
|
||||||
|
|
||||||
typography: {
|
typography: {
|
||||||
DEFAULT: {
|
DEFAULT: {
|
||||||
css: {
|
css: {
|
||||||
|
@ -37,7 +40,11 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [require('tailwindcss-animate'), require('@tailwindcss/typography')],
|
plugins: [
|
||||||
|
require('tailwindcss-animate'),
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
|
require('@tailwindcss/container-queries')
|
||||||
|
],
|
||||||
safelist: [
|
safelist: [
|
||||||
'animate-bounce',
|
'animate-bounce',
|
||||||
'outline-amber-500',
|
'outline-amber-500',
|
||||||
|
|