Compare commits
144 commits
Author | SHA1 | Date | |
---|---|---|---|
|
15d487ec6f | ||
|
d716e192bb | ||
|
6aa34c1648 | ||
|
34823665c6 | ||
|
134e2c79cc | ||
|
b0abfd8311 | ||
|
61cd15fd5b | ||
|
f3f94be6ae | ||
|
61147be693 | ||
|
6a1474eb52 | ||
|
f4b1003801 | ||
|
5d94323bdd | ||
|
d2774e8150 | ||
|
89831a64a2 | ||
|
4c8d576f13 | ||
|
0c8a3b0348 | ||
|
0335006ee5 | ||
|
07bd197c29 | ||
|
a0b2062137 | ||
|
d5cf84e592 | ||
|
cd9c1d950d | ||
|
665f2c6b35 | ||
|
30a573e9cf | ||
|
ddde6df30b | ||
|
d5703cc274 | ||
|
778142c4c1 | ||
|
d984651fc8 | ||
|
9a529b62fb | ||
|
c143956e9f | ||
|
120a1a03e3 | ||
|
08e01502c5 | ||
|
314255dc31 | ||
|
1b036d3278 | ||
|
b450849075 | ||
|
f100c524af | ||
|
d196c1e680 | ||
|
f147510c04 | ||
|
6cf6e6d045 | ||
|
ff665a6cea | ||
|
a2e2c1f791 | ||
|
0b4813e285 | ||
|
4853e1ec63 | ||
|
de3862bf77 | ||
|
6094a2a559 | ||
|
939610ed61 | ||
|
5ef3d6c0f9 | ||
|
35562692e4 | ||
|
5f65a341a0 | ||
|
e3f2e0c256 | ||
|
51e72e2021 | ||
|
b8c9d8de17 | ||
|
cc664a764d | ||
|
d0f9434700 | ||
|
b9fe7113ed | ||
|
0e225f95c9 | ||
|
8e0756f166 | ||
|
e67a220223 | ||
|
dd70061798 | ||
|
c7444256f1 | ||
|
3c8b726d83 | ||
|
a670952e15 | ||
|
d6f94c26d4 | ||
|
62795740b3 | ||
|
6b0acce446 | ||
|
a0182fe447 | ||
|
fe785f6ed3 | ||
|
52d2f12b75 | ||
|
7a3a58d8fc | ||
|
21df633e9e | ||
|
014451ffa0 | ||
|
6ecba14f6f | ||
|
9893373a43 | ||
|
d84c415b22 | ||
|
c77854667b | ||
|
2c4c07441b | ||
|
c834b7c49e | ||
|
d000c4a4fb | ||
|
6d9515498f | ||
|
88e437d001 | ||
|
fb413a5fba | ||
|
9aa5579bde | ||
|
c7baf62833 | ||
|
092fc92658 | ||
|
ec9e975bda | ||
|
9dcda9d3dd | ||
|
05b8e0c410 | ||
|
9ddc4e5a8c | ||
|
7670634cda | ||
|
a9b6b815e8 | ||
|
3a1a5942df | ||
|
a78ad22578 | ||
|
40f5b32970 | ||
|
a729113b71 | ||
|
600a82d3f2 | ||
|
eb749e1796 | ||
|
267830b15d | ||
|
c1b7bdbbb4 | ||
|
6e2a633b45 | ||
|
4384759616 | ||
|
32c63efeaa | ||
|
81941a9e45 | ||
|
b37e067efd | ||
|
af4427cf3d | ||
|
e902589427 | ||
|
5cf33f6dfa | ||
|
3ba5e0aa2b | ||
|
97ff935b13 | ||
|
313d6f2302 | ||
|
7aeecdb656 | ||
|
baf6161d95 | ||
|
579e57f631 | ||
|
b63a14d8ce | ||
|
5b5c027ea6 | ||
|
6494354a6d | ||
|
90ef5eaf06 | ||
|
10f9ae340c | ||
|
c6bb436ad8 | ||
|
a649fdae0b | ||
|
fa7ff4ac89 | ||
|
81ba54ef10 | ||
|
3d2d876b98 | ||
|
c682e2b38b | ||
|
e693cf8812 | ||
|
bf06377cbd | ||
|
4a7d131b2e | ||
|
69bcfe77b6 | ||
|
da2f1822ae | ||
|
9a339722a4 | ||
|
c9396c3bed | ||
|
c783797a99 | ||
|
cbccf762bd | ||
|
2bb3abab52 | ||
|
fd3c8f6449 | ||
|
88361c95bf | ||
|
320e8e7589 | ||
|
bcac65ea8d | ||
|
f2463b6163 | ||
|
3eddad19c9 | ||
|
f92043e106 | ||
|
94d7295075 | ||
|
bf1aa929c1 | ||
|
a4fadab6ad | ||
|
96005f3a9c | ||
|
8d584f0e87 |
|
@ -1,3 +1,3 @@
|
|||
> 1%
|
||||
defaults
|
||||
>1% and not dead
|
||||
last 2 versions
|
||||
not dead
|
||||
|
|
15
.eslintrc.cjs
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* eslint-env node */
|
||||
require('@rushstack/eslint-patch/modern-module-resolution')
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'plugin:vue/vue3-essential',
|
||||
'eslint:recommended',
|
||||
'@vue/eslint-config-typescript',
|
||||
'@vue/eslint-config-prettier'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest'
|
||||
}
|
||||
}
|
14
.eslintrc.js
|
@ -1,14 +0,0 @@
|
|||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
},
|
||||
extends: ["plugin:vue/vue3-essential", "eslint:recommended", "@vue/prettier"],
|
||||
parserOptions: {
|
||||
parser: "babel-eslint",
|
||||
},
|
||||
rules: {
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
},
|
||||
};
|
29
.gitignore
vendored
|
@ -1,23 +1,30 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"esversion": 9
|
||||
}
|
8
.prettierrc.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"semi": false,
|
||||
"tabWidth": 2,
|
||||
"singleQuote": true,
|
||||
"printWidth": 100,
|
||||
"trailingComma": "none"
|
||||
}
|
7
.vscode/extensions.json
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"Vue.volar",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
15
.vscode/sftp.json
vendored
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"name": "sebin-reference",
|
||||
"protocol": "sftp",
|
||||
"port": 22,
|
||||
"host": "sebin-ref",
|
||||
"username": "sebin",
|
||||
"privateKeyPath": "~/.ssh/id_sebin",
|
||||
"passphrase": "HeyImGrump20!6",
|
||||
"remotePath": "sebin-ref",
|
||||
"watcher": {
|
||||
"files": "dist/**",
|
||||
"autoUpload": true,
|
||||
"autoDelete": true
|
||||
}
|
||||
}
|
57
README.md
|
@ -1,24 +1,55 @@
|
|||
# vue3-test
|
||||
# Sebin Reference Page
|
||||
|
||||
## Project setup
|
||||
```
|
||||
The official reference page of Sebin Nyshkim, the anthro dragon.
|
||||
|
||||
This page is primarily targeted at artists commissioned to draw Sebin. The idea is to have a single point of truth to easily point to.
|
||||
|
||||
The benefit of this is two-fold:
|
||||
|
||||
* Lack of attachments in Fur Affinity notes
|
||||
* Participating in art raffles on Twitter without cluttering up the media tab with the same image over and over again
|
||||
|
||||
Furthermore, this page serves both for the development of Sebin as an independent character as well as a training ground for learning various new web technologies fitting such a project.
|
||||
|
||||
## Recommended IDE Setup
|
||||
|
||||
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
|
||||
|
||||
## Type Support for `.vue` Imports in TS
|
||||
|
||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
|
||||
|
||||
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
|
||||
|
||||
1. Disable the built-in TypeScript Extension
|
||||
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
|
||||
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
|
||||
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
|
||||
|
||||
## Customize configuration
|
||||
|
||||
See [Vite Configuration Reference](https://vitejs.dev/config/).
|
||||
|
||||
## Project Setup
|
||||
|
||||
```sh
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
```sh
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
module.exports = {
|
||||
presets: ["@vue/cli-plugin-babel/preset"],
|
||||
};
|
44
card/header/furaffinity/index.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="flex">
|
||||
<div class="image">
|
||||
<img src="../../../src/assets/sebin-smug-icon.png" alt="Sebin Smug Icon" />
|
||||
</div>
|
||||
<div class="headings">
|
||||
<h1>Sebin Nyshkim</h1>
|
||||
<h2>
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M503.5 204.6L502.8 202.8L433.1 21.02C431.7 17.45 429.2 14.43 425.9 12.38C423.5 10.83 420.8 9.865 417.9 9.57C415 9.275 412.2 9.653 409.5 10.68C406.8 11.7 404.4 13.34 402.4 15.46C400.5 17.58 399.1 20.13 398.3 22.9L351.3 166.9H160.8L113.7 22.9C112.9 20.13 111.5 17.59 109.6 15.47C107.6 13.35 105.2 11.72 102.5 10.7C99.86 9.675 96.98 9.295 94.12 9.587C91.26 9.878 88.51 10.83 86.08 12.38C82.84 14.43 80.33 17.45 78.92 21.02L9.267 202.8L8.543 204.6C-1.484 230.8-2.72 259.6 5.023 286.6C12.77 313.5 29.07 337.3 51.47 354.2L51.74 354.4L52.33 354.8L158.3 434.3L210.9 474L242.9 498.2C246.6 500.1 251.2 502.5 255.9 502.5C260.6 502.5 265.2 500.1 268.9 498.2L300.9 474L353.5 434.3L460.2 354.4L460.5 354.1C482.9 337.2 499.2 313.5 506.1 286.6C514.7 259.6 513.5 230.8 503.5 204.6z"/></svg>
|
||||
<span class="handle">SebinNyshkim</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M248,8C111.033,8,0,119.033,0,256S111.033,504,248,504,496,392.967,496,256,384.967,8,248,8ZM362.952,176.66c-3.732,39.215-19.881,134.378-28.1,178.3-3.476,18.584-10.322,24.816-16.948,25.425-14.4,1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25,5.342-39.5,3.652-3.793,67.107-61.51,68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608,69.142-14.845,10.194-26.894,9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7,18.45-13.7,108.446-47.248,144.628-62.3c68.872-28.647,83.183-33.623,92.511-33.789,2.052-.034,6.639.474,9.61,2.885a10.452,10.452,0,0,1,3.53,6.716A43.765,43.765,0,0,1,362.952,176.66Z"/></svg>
|
||||
<span class="handle">@SebinNyshkim</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5zm-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"/></svg>
|
||||
<span class="handle">@SebinNyshkim@meow.social</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z"/></svg>
|
||||
<span class="handle">Sebin Nyshkim#8877</span>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
</main>
|
||||
<!-- Open in browser and set mobile view to 2048x1072 with DPR: 2 and take screenshot -->
|
||||
</body>
|
||||
</html>
|
139
card/header/furaffinity/style.css
Normal file
|
@ -0,0 +1,139 @@
|
|||
@import "../../../src/assets/fonts/exo/exo.css";
|
||||
|
||||
:root {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
|
||||
--theme-c-muted-blue: #22759d;
|
||||
--theme-c-amaranth: #e93f3f;
|
||||
--theme-c-deep-purple: #33124a;
|
||||
--theme-c-charcoal: #303030;
|
||||
|
||||
--container-box-shadow: 1vw 1vw 4vw rgba(0, 0, 0, 0.7);
|
||||
--welcome-header-mainline-font-size: 25vh;
|
||||
--welcome-header-subline-font-size: 10vh;
|
||||
|
||||
--icon-size: calc(var(--welcome-header-subline-font-size) * 1.25);
|
||||
|
||||
--page-background: radial-gradient(circle at bottom right,
|
||||
var(--theme-c-amaranth) 5%,
|
||||
transparent 50%),
|
||||
radial-gradient(circle at top left,
|
||||
var(--theme-c-muted-blue) 5%,
|
||||
var(--theme-c-deep-purple) 100%);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
/* line-height: 1.5; */
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main::before,
|
||||
main::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
main::before {
|
||||
background: url(../../../src/assets/subtle-prism.svg);
|
||||
mix-blend-mode: multiply;
|
||||
z-index: -1;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
main::after {
|
||||
background: var(--page-background);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
flex: 0 0 50vw;
|
||||
padding: 0 2vw;
|
||||
}
|
||||
|
||||
.flex > * {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex: 0 0 60vh;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 100%;
|
||||
border: 3vh solid #fff; box-shadow: var(--container-box-shadow);
|
||||
}
|
||||
|
||||
.headings {
|
||||
flex: 0 1 45vw;
|
||||
margin: 0;
|
||||
padding: 0 1vw;
|
||||
}
|
||||
|
||||
.headings :where(h1, h2) {
|
||||
font-family: "Exo", sans-serif;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings h1 {
|
||||
font-size: var(--welcome-header-mainline-font-size);
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.headings h2 {
|
||||
font-size: var(--welcome-header-subline-font-size);
|
||||
font-weight: 300;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-evenly;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.headings .contact {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.headings .icon,
|
||||
.headings .handle {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.headings .icon {
|
||||
flex: 0 0 var(--icon-size);
|
||||
width: var(--icon-size);
|
||||
height: var(--icon-size);
|
||||
margin: 0 0.375em 0 0;
|
||||
}
|
||||
|
||||
.headings .icon {
|
||||
fill: #fff;
|
||||
}
|
44
card/header/mastodon/index.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="flex">
|
||||
<div class="image">
|
||||
<img src="../../../src/assets/sebin-smug-icon.png" alt="Sebin Smug Icon" />
|
||||
</div>
|
||||
<div class="headings">
|
||||
<h1>Sebin Nyshkim</h1>
|
||||
<h2>
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M503.5 204.6L502.8 202.8L433.1 21.02C431.7 17.45 429.2 14.43 425.9 12.38C423.5 10.83 420.8 9.865 417.9 9.57C415 9.275 412.2 9.653 409.5 10.68C406.8 11.7 404.4 13.34 402.4 15.46C400.5 17.58 399.1 20.13 398.3 22.9L351.3 166.9H160.8L113.7 22.9C112.9 20.13 111.5 17.59 109.6 15.47C107.6 13.35 105.2 11.72 102.5 10.7C99.86 9.675 96.98 9.295 94.12 9.587C91.26 9.878 88.51 10.83 86.08 12.38C82.84 14.43 80.33 17.45 78.92 21.02L9.267 202.8L8.543 204.6C-1.484 230.8-2.72 259.6 5.023 286.6C12.77 313.5 29.07 337.3 51.47 354.2L51.74 354.4L52.33 354.8L158.3 434.3L210.9 474L242.9 498.2C246.6 500.1 251.2 502.5 255.9 502.5C260.6 502.5 265.2 500.1 268.9 498.2L300.9 474L353.5 434.3L460.2 354.4L460.5 354.1C482.9 337.2 499.2 313.5 506.1 286.6C514.7 259.6 513.5 230.8 503.5 204.6z"/></svg>
|
||||
<span class="handle">SebinNyshkim</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M248,8C111.033,8,0,119.033,0,256S111.033,504,248,504,496,392.967,496,256,384.967,8,248,8ZM362.952,176.66c-3.732,39.215-19.881,134.378-28.1,178.3-3.476,18.584-10.322,24.816-16.948,25.425-14.4,1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25,5.342-39.5,3.652-3.793,67.107-61.51,68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608,69.142-14.845,10.194-26.894,9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7,18.45-13.7,108.446-47.248,144.628-62.3c68.872-28.647,83.183-33.623,92.511-33.789,2.052-.034,6.639.474,9.61,2.885a10.452,10.452,0,0,1,3.53,6.716A43.765,43.765,0,0,1,362.952,176.66Z"/></svg>
|
||||
<span class="handle">@SebinNyshkim</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5zm-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"/></svg>
|
||||
<span class="handle">@SebinNyshkim@meow.social</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z"/></svg>
|
||||
<span class="handle">Sebin Nyshkim#8877</span>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
</main>
|
||||
<!-- Open in browser and set mobile view to 2048x1072 with DPR: 2 and take screenshot -->
|
||||
</body>
|
||||
</html>
|
139
card/header/mastodon/style.css
Normal file
|
@ -0,0 +1,139 @@
|
|||
@import "../../../src/assets/fonts/exo/exo.css";
|
||||
|
||||
:root {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
|
||||
--theme-c-muted-blue: #22759d;
|
||||
--theme-c-amaranth: #e93f3f;
|
||||
--theme-c-deep-purple: #33124a;
|
||||
--theme-c-charcoal: #303030;
|
||||
|
||||
--container-box-shadow: 1vw 1vw 4vw rgba(0, 0, 0, 0.7);
|
||||
--welcome-header-mainline-font-size: 6vw;
|
||||
--welcome-header-subline-font-size: 2vw;
|
||||
|
||||
--icon-size: calc(var(--welcome-header-subline-font-size) * 1.25);
|
||||
|
||||
--page-background: radial-gradient(circle at bottom right,
|
||||
var(--theme-c-amaranth) 5%,
|
||||
transparent 50%),
|
||||
radial-gradient(circle at top left,
|
||||
var(--theme-c-muted-blue) 5%,
|
||||
var(--theme-c-deep-purple) 100%);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
/* line-height: 1.5; */
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main::before,
|
||||
main::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
main::before {
|
||||
background: url(../../../src/assets/subtle-prism.svg);
|
||||
mix-blend-mode: multiply;
|
||||
z-index: -1;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
main::after {
|
||||
background: var(--page-background);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
flex: 0 0 72vw;
|
||||
}
|
||||
|
||||
.flex>* {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex: 0 0 60vh;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 100%;
|
||||
border: 1vw solid #fff;
|
||||
box-shadow: var(--container-box-shadow);
|
||||
}
|
||||
|
||||
.headings {
|
||||
flex: 0 0 50vw;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings :where(h1, h2) {
|
||||
font-family: "Exo", sans-serif;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings h1 {
|
||||
font-size: var(--welcome-header-mainline-font-size);
|
||||
font-weight: 900;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.headings h2 {
|
||||
font-size: var(--welcome-header-subline-font-size);
|
||||
font-weight: 300;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-evenly;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.headings .contact {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.headings .icon,
|
||||
.headings .handle {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.headings .icon {
|
||||
flex: 0 0 var(--icon-size);
|
||||
width: var(--icon-size);
|
||||
height: var(--icon-size);
|
||||
margin: 0 0.375em 0 0;
|
||||
}
|
||||
|
||||
.headings .icon {
|
||||
fill: #fff;
|
||||
}
|
44
card/header/twitter/index.html
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="flex">
|
||||
<div class="image">
|
||||
<img src="../../../src/assets/sebin-smug-icon.png" alt="Sebin Smug Icon" />
|
||||
</div>
|
||||
<div class="headings">
|
||||
<h1>Sebin Nyshkim</h1>
|
||||
<h2>
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M503.5 204.6L502.8 202.8L433.1 21.02C431.7 17.45 429.2 14.43 425.9 12.38C423.5 10.83 420.8 9.865 417.9 9.57C415 9.275 412.2 9.653 409.5 10.68C406.8 11.7 404.4 13.34 402.4 15.46C400.5 17.58 399.1 20.13 398.3 22.9L351.3 166.9H160.8L113.7 22.9C112.9 20.13 111.5 17.59 109.6 15.47C107.6 13.35 105.2 11.72 102.5 10.7C99.86 9.675 96.98 9.295 94.12 9.587C91.26 9.878 88.51 10.83 86.08 12.38C82.84 14.43 80.33 17.45 78.92 21.02L9.267 202.8L8.543 204.6C-1.484 230.8-2.72 259.6 5.023 286.6C12.77 313.5 29.07 337.3 51.47 354.2L51.74 354.4L52.33 354.8L158.3 434.3L210.9 474L242.9 498.2C246.6 500.1 251.2 502.5 255.9 502.5C260.6 502.5 265.2 500.1 268.9 498.2L300.9 474L353.5 434.3L460.2 354.4L460.5 354.1C482.9 337.2 499.2 313.5 506.1 286.6C514.7 259.6 513.5 230.8 503.5 204.6z"/></svg>
|
||||
<span class="handle">SebinNyshkim</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"/></svg>
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M248,8C111.033,8,0,119.033,0,256S111.033,504,248,504,496,392.967,496,256,384.967,8,248,8ZM362.952,176.66c-3.732,39.215-19.881,134.378-28.1,178.3-3.476,18.584-10.322,24.816-16.948,25.425-14.4,1.326-25.338-9.517-39.287-18.661-21.827-14.308-34.158-23.215-55.346-37.177-24.485-16.135-8.612-25,5.342-39.5,3.652-3.793,67.107-61.51,68.335-66.746.153-.655.3-3.1-1.154-4.384s-3.59-.849-5.135-.5q-3.283.746-104.608,69.142-14.845,10.194-26.894,9.934c-8.855-.191-25.888-5.006-38.551-9.123-15.531-5.048-27.875-7.717-26.8-16.291q.84-6.7,18.45-13.7,108.446-47.248,144.628-62.3c68.872-28.647,83.183-33.623,92.511-33.789,2.052-.034,6.639.474,9.61,2.885a10.452,10.452,0,0,1,3.53,6.716A43.765,43.765,0,0,1,362.952,176.66Z"/></svg>
|
||||
<span class="handle">@SebinNyshkim</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5zm-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"/></svg>
|
||||
<span class="handle">@SebinNyshkim@meow.social</span>
|
||||
</span>
|
||||
|
||||
<span class="contact">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z"/></svg>
|
||||
<span class="handle">Sebin Nyshkim#8877</span>
|
||||
</span>
|
||||
</h2>
|
||||
</div>
|
||||
</main>
|
||||
<!-- Open in browser and set mobile view to 2048x1072 with DPR: 2 and take screenshot -->
|
||||
</body>
|
||||
</html>
|
143
card/header/twitter/style.css
Normal file
|
@ -0,0 +1,143 @@
|
|||
@import "../../../src/assets/fonts/exo/exo.css";
|
||||
|
||||
:root {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
|
||||
--theme-c-muted-blue: #22759d;
|
||||
--theme-c-amaranth: #e93f3f;
|
||||
--theme-c-deep-purple: #33124a;
|
||||
--theme-c-charcoal: #303030;
|
||||
|
||||
--container-box-shadow: 1vw 1vw 4vw rgba(0, 0, 0, 0.7);
|
||||
--welcome-header-mainline-font-size: 8vw;
|
||||
--welcome-header-subline-font-size: 2.5vw;
|
||||
|
||||
--icon-size: calc(var(--welcome-header-subline-font-size) * 1.25);
|
||||
|
||||
--page-background: radial-gradient(
|
||||
circle at bottom right,
|
||||
var(--theme-c-amaranth) 5%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at top left,
|
||||
var(--theme-c-muted-blue) 5%,
|
||||
var(--theme-c-deep-purple) 100%
|
||||
);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
/* line-height: 1.5; */
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main::before,
|
||||
main::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
main::before {
|
||||
background: url(../../../src/assets/subtle-prism.svg);
|
||||
mix-blend-mode: multiply;
|
||||
z-index: -1;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
main::after {
|
||||
background: var(--page-background);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
||||
.flex > * {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex: 0 0 60vh;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 100%;
|
||||
border: 1vw solid #fff;
|
||||
box-shadow: var(--container-box-shadow);
|
||||
}
|
||||
|
||||
.headings {
|
||||
flex: 0 0 60vw;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings :where(h1, h2) {
|
||||
font-family: "Exo", sans-serif;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings h1 {
|
||||
font-size: var(--welcome-header-mainline-font-size);
|
||||
font-weight: 900;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.headings h2 {
|
||||
font-size: var(--welcome-header-subline-font-size);
|
||||
font-weight: 300;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-evenly;
|
||||
line-height: 1.75;
|
||||
}
|
||||
|
||||
.headings .contact {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.headings .icon,
|
||||
.headings .handle {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.headings .icon {
|
||||
flex: 0 0 var(--icon-size);
|
||||
width: var(--icon-size);
|
||||
height: var(--icon-size);
|
||||
margin: 0 0.375em 0 0;
|
||||
}
|
||||
|
||||
.headings .icon {
|
||||
fill: #fff;
|
||||
}
|
22
card/index.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<main class="flex">
|
||||
<div class="image">
|
||||
<img src="../src/assets/sebin-smug-icon.png" alt="Sebin Smug Icon" />
|
||||
</div>
|
||||
<div class="headings">
|
||||
<h1>Sebin Nyshkim</h1>
|
||||
<h2>Character Reference Page</h2>
|
||||
</div>
|
||||
</main>
|
||||
<!-- Open in browser and set mobile view to 2048x1072 with DPR: 2 and take screenshot -->
|
||||
</body>
|
||||
</html>
|
112
card/style.css
Normal file
|
@ -0,0 +1,112 @@
|
|||
@import "../src/assets/fonts/exo/exo.css";
|
||||
|
||||
:root {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
|
||||
--theme-c-muted-blue: #22759d;
|
||||
--theme-c-amaranth: #e93f3f;
|
||||
--theme-c-deep-purple: #33124a;
|
||||
--theme-c-charcoal: #303030;
|
||||
|
||||
--container-box-shadow: 1vw 1vw 4vw rgba(0, 0, 0, 0.7);
|
||||
--welcome-header-mainline-font-size: 8vw;
|
||||
--welcome-header-subline-font-size: 3.5vw;
|
||||
|
||||
--page-background: radial-gradient(
|
||||
circle at bottom right,
|
||||
var(--theme-c-amaranth) 5%,
|
||||
transparent 50%
|
||||
),
|
||||
radial-gradient(
|
||||
circle at top left,
|
||||
var(--theme-c-muted-blue) 5%,
|
||||
var(--theme-c-deep-purple) 100%
|
||||
);
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
main::before,
|
||||
main::after {
|
||||
content: "";
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
main::before {
|
||||
background: url(../src/assets/subtle-prism.svg);
|
||||
mix-blend-mode: multiply;
|
||||
z-index: -1;
|
||||
transform: scale(1.5);
|
||||
}
|
||||
|
||||
main::after {
|
||||
background: var(--page-background);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
|
||||
flex: 0 0 100%;
|
||||
}
|
||||
|
||||
.flex > * {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.image {
|
||||
flex: 0 0 60vh;
|
||||
max-height: 100vh;
|
||||
}
|
||||
|
||||
.image img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border-radius: 100%;
|
||||
border: 1vw solid #fff;
|
||||
box-shadow: var(--container-box-shadow);
|
||||
}
|
||||
|
||||
.headings {
|
||||
flex: 0 0 60vw;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings :where(h1, h2) {
|
||||
font-family: "Exo", sans-serif;
|
||||
text-align: center;
|
||||
font-style: italic;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.headings h1 {
|
||||
font-size: var(--welcome-header-mainline-font-size);
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.headings h2 {
|
||||
font-size: var(--welcome-header-subline-font-size);
|
||||
font-weight: 300;
|
||||
}
|
1
env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
30
index.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
||||
<link rel="favicon" href="favicon.png" type="image/png" />
|
||||
<link rel="icon" href="favicon.png" type="image/png" />
|
||||
<title>Sebin Nyshkim - Reference Page</title>
|
||||
|
||||
<meta name="theme-color" media="(prefers-color-scheme: light)" content="#22759d" />
|
||||
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#195673" />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@SebinNyshkim" />
|
||||
<meta name="twitter:creator" content="@SebinNyshkim" />
|
||||
<meta name="twitter:title" content="Sebin Nyshkim - Reference Page" />
|
||||
<meta name="twitter:description" content="The official reference page for Sebin Nyshkim with picture references and in-depth character descriptions" />
|
||||
<meta name="twitter:image" content="https://ref.sebin-nyshkim.net/sebin/preview.png" />
|
||||
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="Sebin Nyshkim - Reference Page" />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="og:url" content="https://ref.sebin-nyshkim.net/sebin/" />
|
||||
<meta property="og:image" content="https://ref.sebin-nyshkim.net/sebin/preview.png" />
|
||||
<meta property="og:description" content="The official reference page for Sebin Nyshkim with picture references and in-depth character descriptions" />
|
||||
</head>
|
||||
<body>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
34479
package-lock.json
generated
50
package.json
|
@ -1,32 +1,38 @@
|
|||
{
|
||||
"name": "sebin-reference",
|
||||
"version": "0.7.7",
|
||||
"version": "0.10.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
"dev": "vite --host",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --build --force",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.5",
|
||||
"normalize.css": "^8.0.1",
|
||||
"vue": "^3.0.0",
|
||||
"vue-router": "^4.0.0-0"
|
||||
"vue": "^3.4.38",
|
||||
"vue-router": "^4.4.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "~4.5.0",
|
||||
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||
"@vue/cli-plugin-router": "~4.5.0",
|
||||
"@vue/cli-service": "~4.5.0",
|
||||
"@vue/compiler-sfc": "^3.0.0",
|
||||
"@vue/eslint-config-prettier": "^6.0.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-prettier": "^3.3.1",
|
||||
"eslint-plugin-vue": "^7.0.0",
|
||||
"image-webpack-loader": "^8.0.1",
|
||||
"prettier": "^2.2.1",
|
||||
"sass": "^1.26.5",
|
||||
"sass-loader": "^8.0.2"
|
||||
"@rushstack/eslint-patch": "^1.10.4",
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/node": "^20.16.3",
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
"@vue/eslint-config-prettier": "^9.0.0",
|
||||
"@vue/eslint-config-typescript": "^13.0.0",
|
||||
"@vue/tsconfig": "^0.5.1",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-vue": "^9.28.0",
|
||||
"normalize.css": "^8.0.1",
|
||||
"npm-run-all2": "^6.2.2",
|
||||
"prettier": "^3.3.3",
|
||||
"sass": "^1.77.8",
|
||||
"typescript": "~5.5.0",
|
||||
"vite": "^5.4.2",
|
||||
"vite-imagetools": "^6.2.9",
|
||||
"vue-tsc": "^2.1.4"
|
||||
}
|
||||
}
|
||||
|
|
8
public/.htaccess
Normal file
|
@ -0,0 +1,8 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteRule ^index\.html$ - [L]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /sebin/index.html [L]
|
||||
</IfModule>
|
|
@ -1,19 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0,viewport-fit=cover">
|
||||
<link rel="<%= htmlWebpackPlugin.options.links.favicon.rel %>" href="<%= htmlWebpackPlugin.options.links.favicon.href %>" type="<%= htmlWebpackPlugin.options.links.favicon.type %>">
|
||||
<link rel="<%= htmlWebpackPlugin.options.links.icon.rel %>" href="<%= htmlWebpackPlugin.options.links.icon.href %>" type="<%= htmlWebpackPlugin.options.links.icon.type %>">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>Sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div class="bubbles"></div>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
Before Width: | Height: | Size: 377 KiB |
BIN
public/preview.png
Normal file
After Width: | Height: | Size: 2.7 MiB |
BIN
public/sebin-ref-full-NSFW-hires.jpg
Executable file → Normal file
Before Width: | Height: | Size: 9.7 MiB After Width: | Height: | Size: 3.3 MiB |
BIN
public/sebin-ref-full-SFW-hires.jpg
Executable file → Normal file
Before Width: | Height: | Size: 9.5 MiB After Width: | Height: | Size: 3.2 MiB |
248
src/App.vue
|
@ -1,177 +1,99 @@
|
|||
<template>
|
||||
<header>
|
||||
<img
|
||||
class="nav-logo"
|
||||
src="@/assets/sebin-smug-icon.png"
|
||||
alt="Sebin Avatar"
|
||||
/>
|
||||
<script setup lang="ts">
|
||||
import { ref, provide } from 'vue'
|
||||
import { RouterView } from 'vue-router'
|
||||
import { modalResultKey, nsfwKey, showModalKey } from '@/keys'
|
||||
import { version } from '../package.json'
|
||||
import RefModal from '@/components/RefModal.vue'
|
||||
import ButtonGroup from '@/components/ButtonGroup.vue'
|
||||
import Button from '@/components/RefButton.vue'
|
||||
import SiteHeader from '@/components/SiteHeader.vue'
|
||||
import SiteFooter from '@/components/SiteFooter.vue'
|
||||
import SiteNavigation from '@/components/SiteNavigation.vue'
|
||||
|
||||
<navigation :routes="routes" />
|
||||
</header>
|
||||
const isNsfw = ref(false)
|
||||
const isConfirmedHorny = ref(false)
|
||||
|
||||
<main>
|
||||
<router-view />
|
||||
</main>
|
||||
const nsfwmodal = ref<InstanceType<typeof RefModal>>()
|
||||
|
||||
<footer class="footer">
|
||||
<div class="footer__copyright">
|
||||
v{{ version }} © {{ new Date().getFullYear() }} Sebin Nyshkim
|
||||
</div>
|
||||
<ul class="footer__linklist">
|
||||
<li class="footer__linkitem" v-for="(link, idx) in links" :key="idx">
|
||||
<a :href="link.href" class="footer__link">
|
||||
{{ link.text }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</footer>
|
||||
</template>
|
||||
const showModal = (): void => {
|
||||
if (!isConfirmedHorny.value) {
|
||||
nsfwmodal.value?.showModal()
|
||||
|
||||
<script>
|
||||
import Navigation from "@/components/Navigation.vue";
|
||||
setTimeout(() => {
|
||||
isNsfw.value = false
|
||||
}, 1)
|
||||
} else {
|
||||
isNsfw.value = !isNsfw.value
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { Navigation },
|
||||
data() {
|
||||
return {
|
||||
nsfw: false,
|
||||
isConfirmedHorny: false,
|
||||
isWarn: false,
|
||||
version: require("../package.json").version,
|
||||
routes: [
|
||||
{ path: "/", name: "Home" },
|
||||
{ path: "/general", name: "General" },
|
||||
{ path: "/anatomy", name: "Anatomy" },
|
||||
{ path: "/clothing", name: "Clothing" },
|
||||
{ path: "/abilities", name: "Abilities" },
|
||||
{ path: "/overdrive", name: "Overdrive" },
|
||||
],
|
||||
links: [
|
||||
{ href: "https://twitter.com/SebinNyshkim", text: "Twitter" },
|
||||
{ href: "https://t.me/SebinNyshkim", text: "Telegram" },
|
||||
{
|
||||
href: "https://www.furaffinity.net/user/sonofdragons",
|
||||
text: "Fur Affinity",
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
showWarning() {
|
||||
if (!this.isConfirmedHorny) {
|
||||
this.isWarn = true;
|
||||
document.body.classList.toggle("scroll-lock");
|
||||
const modalResult = (value: boolean): void => {
|
||||
isNsfw.value = value
|
||||
isConfirmedHorny.value = value
|
||||
nsfwmodal.value?.close()
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.nsfw = false;
|
||||
}, 1);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
provide(modalResultKey, modalResult)
|
||||
provide(nsfwKey, isNsfw)
|
||||
provide(showModalKey, showModal)
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/base.scss";
|
||||
@import "~normalize.css";
|
||||
<template>
|
||||
<RefModal id="nsfw-warning" ref="nsfwmodal">
|
||||
<template #heading>
|
||||
⚠️⚠️⚠️<br />
|
||||
Whoa, Nelly!
|
||||
</template>
|
||||
|
||||
#app {
|
||||
padding: 5em 0 0 0;
|
||||
color: $copy-color;
|
||||
font-size: 1.125em;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
transition: all ease-in-out 0.25s;
|
||||
<template #message>
|
||||
By enabling NSFW mode you confirm that you are of legal age to view adult content.
|
||||
</template>
|
||||
|
||||
@include mq-desktop {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
<template #buttons>
|
||||
<ButtonGroup col>
|
||||
<Button positive @click.prevent="modalResult(true)"> Yes, show me the goods 👀 </Button>
|
||||
<Button negative @click.prevent="modalResult(false)"> NO, STAHP 😱 </Button>
|
||||
</ButtonGroup>
|
||||
</template>
|
||||
</RefModal>
|
||||
|
||||
@media (min-width: 60em) {
|
||||
padding: 5em 0 7em 0;
|
||||
}
|
||||
<SiteHeader>
|
||||
<!-- max 500px -->
|
||||
<picture>
|
||||
<source
|
||||
srcset="
|
||||
@/assets/sebin-smug-icon.png?w=36;40;48;56;72;80;96;112;108;120;144;168&format=avif&quality=75&as=srcset
|
||||
"
|
||||
sizes="(min-width: 120em) 56px, (min-width: 80em) 48px, (min-width: 35em) 40px, 36px"
|
||||
type="image/avif"
|
||||
/>
|
||||
<source
|
||||
srcset="
|
||||
@/assets/sebin-smug-icon.png?w=36;40;48;56;72;80;96;112;108;120;144;168&format=webp&quality=100&as=srcset
|
||||
"
|
||||
sizes="(min-width: 120em) 56px, (min-width: 80em) 48px, (min-width: 35em) 40px, 36px"
|
||||
type="image/webp"
|
||||
/>
|
||||
<img
|
||||
class="nav-logo"
|
||||
srcset="@/assets/sebin-smug-icon.png?w=36;40;48;56;72;80;96;112;108;120;144;168&format=png&as=srcset"
|
||||
sizes="(min-width: 120em) 56px, (min-width: 80em) 48px, (min-width: 35em) 40px, 36px"
|
||||
alt="Sebin Avatar"
|
||||
/>
|
||||
</picture>
|
||||
|
||||
@include mq-bigscreen {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
}
|
||||
<SiteNavigation />
|
||||
</SiteHeader>
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
<main>
|
||||
<RouterView />
|
||||
</main>
|
||||
|
||||
position: fixed;
|
||||
top: env(safe-area-inset-top);
|
||||
right: env(safe-area-inset-right);
|
||||
left: env(safe-area-inset-left);
|
||||
|
||||
z-index: 2;
|
||||
|
||||
max-width: 70em;
|
||||
margin: 1em;
|
||||
padding: 0.5em;
|
||||
border-radius: 0.5em;
|
||||
box-shadow: 0.125em 0.125em 0.5em rgba(0, 0, 0, 0.7);
|
||||
|
||||
background-color: darken($bg-color-dark, 5%);
|
||||
|
||||
@media (min-width: 90em) {
|
||||
margin: 1em auto;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-logo {
|
||||
display: block;
|
||||
margin: 0 0.5em 0 0.25em;
|
||||
height: 2em;
|
||||
border: 0.125em solid #fff;
|
||||
border-radius: 100%;
|
||||
box-shadow: 0.125em 0.125em 0.5em rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding: 0.75em 0;
|
||||
background-color: $bg-color-light;
|
||||
text-align: center;
|
||||
|
||||
@media (orientation: landscape) {
|
||||
padding: env(safe-area-inset-bottom) 0;
|
||||
}
|
||||
|
||||
@include mq-desktop {
|
||||
padding: 0.75em 0;
|
||||
}
|
||||
|
||||
@media (min-width: 60em) {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&__copyright {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&__linklist {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
&__linkitem {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&__link {
|
||||
color: $copy-color;
|
||||
padding: 0.5em 0.75em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<SiteFooter>
|
||||
<p>v{{ version }} © {{ new Date().getFullYear() }} Sebin Nyshkim</p>
|
||||
<p>
|
||||
Background Pattern ©
|
||||
<a href="https://www.svgbackgrounds.com/">SVG Backgrounds</a>
|
||||
</p>
|
||||
</SiteFooter>
|
||||
</template>
|
||||
|
|
BIN
src/assets/fonts/dosis/dosis-bold-latin.woff2
Normal file
BIN
src/assets/fonts/dosis/dosis-regular-latin.woff2
Normal file
19
src/assets/fonts/dosis/dosis.css
Normal file
|
@ -0,0 +1,19 @@
|
|||
/* dosis-regular-latin */
|
||||
@font-face {
|
||||
font-family: Dosis;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Dosis Regular"), local("Dosis-Regular"), url(dosis-regular-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
/* dosis-bold-latin */
|
||||
@font-face {
|
||||
font-family: Dosis;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Dosis Bold"), local("Dosis-Bold"), url(dosis-bold-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
|
BIN
src/assets/fonts/exo/exo-black-italic-latin.woff2
Normal file
BIN
src/assets/fonts/exo/exo-black-latin.woff2
Normal file
BIN
src/assets/fonts/exo/exo-light-italic-latin.woff2
Normal file
BIN
src/assets/fonts/exo/exo-light-latin.woff2
Normal file
37
src/assets/fonts/exo/exo.css
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* exo-light-latin */
|
||||
@font-face {
|
||||
font-family: Exo;
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
src: local("Exo Light"), local("Exo-Light"), url(exo-light-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
/* exo-black-latin */
|
||||
@font-face {
|
||||
font-family: Exo;
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
src: local("Exo Black"), local("Exo-Black"), url(exo-black-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
/* exo-light-italic-latin */
|
||||
@font-face {
|
||||
font-family: Exo;
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
src: local("Exo Light Italic"), local("Exo-LightItalic"), url(exo-light-italic-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
/* exo-black-italic-latin */
|
||||
@font-face {
|
||||
font-family: Exo;
|
||||
font-style: italic;
|
||||
font-weight: 900;
|
||||
src: local("Exo Black Italic"), local("Exo-BlackItalic"), url(exo-black-italic-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
|
10
src/assets/fonts/permanent-marker/permanent-marker.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* permanent-marker-regular-latin */
|
||||
@font-face {
|
||||
font-family: Permanent Marker;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local("Permanent Marker Regular"), local("PermanentMarker-Regular"), url(permanent-marker-regular-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
|
BIN
src/assets/fonts/zilla-slab/zilla-slab-bold-latin.woff2
Normal file
10
src/assets/fonts/zilla-slab/zilla-slab.css
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* zilla-slab-bold-latin */
|
||||
@font-face {
|
||||
font-family: Zilla Slab;
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local("Zilla Slab Bold"), local("ZillaSlab-Bold"), url(zilla-slab-bold-latin.woff2) format("woff2");
|
||||
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2212,U+2215;
|
||||
font-display: swap;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 551 KiB |
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 524 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 656 KiB |
0
src/assets/refs/clothes/casual/fullbody.png
Executable file → Normal file
Before Width: | Height: | Size: 784 KiB After Width: | Height: | Size: 784 KiB |
BIN
src/assets/refs/clothes/lazy/fullbody.png
Normal file
After Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 128 KiB |
Before Width: | Height: | Size: 42 KiB |
BIN
src/assets/refs/clothes/lazy/undies.png
Normal file
After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 734 KiB |
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 3.9 MiB |
Before Width: | Height: | Size: 717 KiB |
BIN
src/assets/refs/muscle/muscle-ref1.png
Normal file
After Width: | Height: | Size: 14 MiB |
Before Width: | Height: | Size: 432 KiB After Width: | Height: | Size: 9.2 MiB |
Before Width: | Height: | Size: 151 KiB |
BIN
src/assets/refs/muscle/muscle-ref11.png
Normal file
After Width: | Height: | Size: 2.4 MiB |
Before Width: | Height: | Size: 376 KiB |
BIN
src/assets/refs/muscle/muscle-ref12.png
Normal file
After Width: | Height: | Size: 3.6 MiB |
Before Width: | Height: | Size: 657 KiB |
BIN
src/assets/refs/muscle/muscle-ref2.png
Normal file
After Width: | Height: | Size: 8.3 MiB |
Before Width: | Height: | Size: 560 KiB |
BIN
src/assets/refs/muscle/muscle-ref3.png
Normal file
After Width: | Height: | Size: 17 MiB |
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 16 MiB |
Before Width: | Height: | Size: 393 KiB After Width: | Height: | Size: 589 KiB |
Before Width: | Height: | Size: 512 KiB |
BIN
src/assets/refs/muscle/muscle-ref6.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
Before Width: | Height: | Size: 867 KiB |
BIN
src/assets/refs/muscle/muscle-ref7.tiff
Normal file
Before Width: | Height: | Size: 378 KiB |
BIN
src/assets/refs/muscle/muscle-ref8.png
Normal file
After Width: | Height: | Size: 4 MiB |
Before Width: | Height: | Size: 619 KiB After Width: | Height: | Size: 1.4 MiB |
Before Width: | Height: | Size: 1.8 MiB |
BIN
src/assets/refs/upper-body-ref.png
Normal file
After Width: | Height: | Size: 14 MiB |
78
src/assets/subtle-prism.svg
Normal file
|
@ -0,0 +1,78 @@
|
|||
<svg xmlns='http://www.w3.org/2000/svg' width='100%'>
|
||||
<defs>
|
||||
<pattern patternUnits='userSpaceOnUse' id='b' width='540' height='450' x='0' y='0' viewBox='0 0 1080 900'>
|
||||
<g fill-opacity='0.1'>
|
||||
<polygon fill='#444' points='90 150 0 300 180 300'/>
|
||||
<polygon points='90 150 180 0 0 0'/>
|
||||
<polygon fill='#AAA' points='270 150 360 0 180 0'/>
|
||||
<polygon fill='#DDD' points='450 150 360 300 540 300'/>
|
||||
<polygon fill='#999' points='450 150 540 0 360 0'/>
|
||||
<polygon points='630 150 540 300 720 300'/>
|
||||
<polygon fill='#DDD' points='630 150 720 0 540 0'/>
|
||||
<polygon fill='#444' points='810 150 720 300 900 300'/>
|
||||
<polygon fill='#FFF' points='810 150 900 0 720 0'/>
|
||||
<polygon fill='#DDD' points='990 150 900 300 1080 300'/>
|
||||
<polygon fill='#444' points='990 150 1080 0 900 0'/>
|
||||
<polygon fill='#DDD' points='90 450 0 600 180 600'/>
|
||||
<polygon points='90 450 180 300 0 300'/>
|
||||
<polygon fill='#666' points='270 450 180 600 360 600'/>
|
||||
<polygon fill='#AAA' points='270 450 360 300 180 300'/>
|
||||
<polygon fill='#DDD' points='450 450 360 600 540 600'/>
|
||||
<polygon fill='#999' points='450 450 540 300 360 300'/>
|
||||
<polygon fill='#999' points='630 450 540 600 720 600'/>
|
||||
<polygon fill='#FFF' points='630 450 720 300 540 300'/>
|
||||
<polygon points='810 450 720 600 900 600'/>
|
||||
<polygon fill='#DDD' points='810 450 900 300 720 300'/>
|
||||
<polygon fill='#AAA' points='990 450 900 600 1080 600'/>
|
||||
<polygon fill='#444' points='990 450 1080 300 900 300'/>
|
||||
<polygon fill='#222' points='90 750 0 900 180 900'/>
|
||||
<polygon points='270 750 180 900 360 900'/>
|
||||
<polygon fill='#DDD' points='270 750 360 600 180 600'/>
|
||||
<polygon points='450 750 540 600 360 600'/>
|
||||
<polygon points='630 750 540 900 720 900'/>
|
||||
<polygon fill='#444' points='630 750 720 600 540 600'/>
|
||||
<polygon fill='#AAA' points='810 750 720 900 900 900'/>
|
||||
<polygon fill='#666' points='810 750 900 600 720 600'/>
|
||||
<polygon fill='#999' points='990 750 900 900 1080 900'/>
|
||||
<polygon fill='#999' points='180 0 90 150 270 150'/>
|
||||
<polygon fill='#444' points='360 0 270 150 450 150'/>
|
||||
<polygon fill='#FFF' points='540 0 450 150 630 150'/>
|
||||
<polygon points='900 0 810 150 990 150'/>
|
||||
<polygon fill='#222' points='0 300 -90 450 90 450'/>
|
||||
<polygon fill='#FFF' points='0 300 90 150 -90 150'/>
|
||||
<polygon fill='#FFF' points='180 300 90 450 270 450'/>
|
||||
<polygon fill='#666' points='180 300 270 150 90 150'/>
|
||||
<polygon fill='#222' points='360 300 270 450 450 450'/>
|
||||
<polygon fill='#FFF' points='360 300 450 150 270 150'/>
|
||||
<polygon fill='#444' points='540 300 450 450 630 450'/>
|
||||
<polygon fill='#222' points='540 300 630 150 450 150'/>
|
||||
<polygon fill='#AAA' points='720 300 630 450 810 450'/>
|
||||
<polygon fill='#666' points='720 300 810 150 630 150'/>
|
||||
<polygon fill='#FFF' points='900 300 810 450 990 450'/>
|
||||
<polygon fill='#999' points='900 300 990 150 810 150'/>
|
||||
<polygon points='0 600 -90 750 90 750'/>
|
||||
<polygon fill='#666' points='0 600 90 450 -90 450'/>
|
||||
<polygon fill='#AAA' points='180 600 90 750 270 750'/>
|
||||
<polygon fill='#444' points='180 600 270 450 90 450'/>
|
||||
<polygon fill='#444' points='360 600 270 750 450 750'/>
|
||||
<polygon fill='#999' points='360 600 450 450 270 450'/>
|
||||
<polygon fill='#666' points='540 600 630 450 450 450'/>
|
||||
<polygon fill='#222' points='720 600 630 750 810 750'/>
|
||||
<polygon fill='#FFF' points='900 600 810 750 990 750'/>
|
||||
<polygon fill='#222' points='900 600 990 450 810 450'/>
|
||||
<polygon fill='#DDD' points='0 900 90 750 -90 750'/>
|
||||
<polygon fill='#444' points='180 900 270 750 90 750'/>
|
||||
<polygon fill='#FFF' points='360 900 450 750 270 750'/>
|
||||
<polygon fill='#AAA' points='540 900 630 750 450 750'/>
|
||||
<polygon fill='#FFF' points='720 900 810 750 630 750'/>
|
||||
<polygon fill='#222' points='900 900 990 750 810 750'/>
|
||||
<polygon fill='#222' points='1080 300 990 450 1170 450'/>
|
||||
<polygon fill='#FFF' points='1080 300 1170 150 990 150'/>
|
||||
<polygon points='1080 600 990 750 1170 750'/>
|
||||
<polygon fill='#666' points='1080 600 1170 450 990 450'/>
|
||||
<polygon fill='#DDD' points='1080 900 1170 750 990 750'/>
|
||||
</g>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect x='0' y='0' fill='url(#b)' width='100%' height='100%'/>
|
||||
</svg>
|
67
src/components/AttackItem.vue
Normal file
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<figure class="attack">
|
||||
<div class="attack__illustration">
|
||||
<slot name="image"></slot>
|
||||
</div>
|
||||
|
||||
<figcaption class="attack__text">
|
||||
<div class="attack__name">
|
||||
<slot name="name"></slot>
|
||||
</div>
|
||||
|
||||
<div class="attack__description">
|
||||
<slot name="desc"></slot>
|
||||
</div>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.attack {
|
||||
flex: var(--attack-item-flex);
|
||||
|
||||
display: flex;
|
||||
flex-flow: var(--attack-item-flex-flow);
|
||||
align-items: center;
|
||||
|
||||
margin: 0;
|
||||
padding: 0.375em 0;
|
||||
|
||||
&:nth-child(even) {
|
||||
text-align: var(--attack-item-nth-child-even-text-align);
|
||||
}
|
||||
|
||||
&:nth-child(even) &__illustration,
|
||||
&:nth-child(even) &__text {
|
||||
&:first-child {
|
||||
order: var(--attack-item-first-child-order);
|
||||
}
|
||||
}
|
||||
|
||||
&__illustration {
|
||||
flex: var(--attack-item-illustration-flex);
|
||||
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&__text {
|
||||
flex: 1 1 auto;
|
||||
padding: var(--attack-item-text-padding);
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-weight: bold;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
}
|
||||
</style>
|
18
src/components/AttackList.vue
Normal file
|
@ -0,0 +1,18 @@
|
|||
<template>
|
||||
<div class="attacks">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.attacks {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
max-width: var(--attack-list-max-width);
|
||||
margin: auto;
|
||||
padding: 0 var(--container-spacing-right-safe) 0 var(--container-spacing-left-safe);
|
||||
}
|
||||
</style>
|
|
@ -1,53 +0,0 @@
|
|||
<template>
|
||||
<a
|
||||
class="btn"
|
||||
:href="href"
|
||||
:download="href.slice(href.lastIndexOf('/') + 1)"
|
||||
v-if="download"
|
||||
>
|
||||
<slot></slot>
|
||||
</a>
|
||||
<a class="btn" :href="href" v-else><slot></slot></a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
href: String,
|
||||
download: Boolean,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
@import "@/scss/_mixins.scss";
|
||||
|
||||
.btn {
|
||||
margin: 0.5em 0;
|
||||
padding: 0.5em 1em;
|
||||
|
||||
position: relative;
|
||||
top: 0;
|
||||
|
||||
border-radius: 0.25em;
|
||||
|
||||
transition: all 0.1s ease-out;
|
||||
|
||||
font-weight: bold;
|
||||
background-color: $bg-color-dark;
|
||||
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
|
||||
@include button($bg-color-dark);
|
||||
|
||||
&:hover {
|
||||
top: -0.25em;
|
||||
}
|
||||
|
||||
&:active {
|
||||
top: 0.25em;
|
||||
}
|
||||
}
|
||||
</style>
|
48
src/components/ButtonGroup.vue
Normal file
|
@ -0,0 +1,48 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
col?: boolean
|
||||
grid?: boolean
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="btn-group" :class="{ col: col, grid: grid }">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.btn-group {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-evenly;
|
||||
|
||||
&.col {
|
||||
flex-flow: column nowrap;
|
||||
gap: 1.5rem;
|
||||
margin: 1rem 0;
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
|
||||
> * {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> * {
|
||||
flex: var(--button-group-flex);
|
||||
margin: 1rem 0;
|
||||
}
|
||||
}
|
||||
</style>
|
53
src/components/ColorTable.vue
Normal file
|
@ -0,0 +1,53 @@
|
|||
<script setup lang="ts">
|
||||
import type { ColorDict } from '@/interfaces'
|
||||
|
||||
interface Props {
|
||||
colors: ColorDict[]
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="color-table">
|
||||
<thead class="color-table__head">
|
||||
<tr class="color-table__row">
|
||||
<th class="color-table__heading name">Body part</th>
|
||||
<th class="color-table__heading value">Value</th>
|
||||
<th class="color-table__heading color">Color</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="color-table__body">
|
||||
<tr class="color-table__row" v-for="(color, idx) in colors" :key="idx">
|
||||
<td class="color-table__cell name">{{ color.name }}</td>
|
||||
<td class="color-table__cell value">{{ color.value }}</td>
|
||||
<td class="color-table__cell color" :style="{ 'background-color': color.value }"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.color-table {
|
||||
&__heading {
|
||||
&.name {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
&__cell {
|
||||
&.name {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&.value {
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&.color {
|
||||
min-width: 10vw;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,139 +1,37 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
headings: string[]
|
||||
data: string[][]
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<table class="datatable">
|
||||
<thead class="datatable__head">
|
||||
<tr class="datatable__row datatable__row--head">
|
||||
<th
|
||||
class="datatable__heading"
|
||||
v-for="(header, idx) in dataset.headers"
|
||||
:key="idx"
|
||||
>
|
||||
{{ header }}
|
||||
<table class="data-table">
|
||||
<thead class="data-table__head">
|
||||
<tr class="data-table__row">
|
||||
<th class="data-table__heading" v-for="(heading, idx) in headings" :key="idx">
|
||||
{{ heading }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="datatable__body">
|
||||
<tr class="datatable__row" v-for="(row, idx) in dataset.data" :key="idx">
|
||||
<td
|
||||
class="datatable__cell"
|
||||
v-for="(cell, idx) in row"
|
||||
:key="idx"
|
||||
:colspan="idx === 1 && !isHexValue(row[1]) ? 2 : 1"
|
||||
>
|
||||
<template v-if="Array.isArray(cell)">
|
||||
<ul
|
||||
:class="[
|
||||
cell.length > 11 ? 'col-3' : cell.length > 4 ? 'col-2' : '',
|
||||
]"
|
||||
>
|
||||
<li v-for="(item, idx) in cell" :key="idx">
|
||||
{{ item }}
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
{{ cell }}
|
||||
</template>
|
||||
<tbody class="data-table__body">
|
||||
<tr class="data-table__row" v-for="(row, idx) in data" :key="idx">
|
||||
<td class="data-table__cell" v-for="(cell, idx) in row" :key="idx">
|
||||
{{ cell }}
|
||||
</td>
|
||||
<td
|
||||
v-if="isHexValue(row[1])"
|
||||
class="datatable__cell--colorpick"
|
||||
:style="`background-color: ${row[1]}`"
|
||||
></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "DataTable",
|
||||
props: {
|
||||
dataset: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isHexValue(value) {
|
||||
return /^#[0-9a-f]{6}$/i.test(value) ? value : false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
@import "@/scss/_mixins.scss";
|
||||
.data-table {
|
||||
table-layout: fixed;
|
||||
|
||||
.datatable {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
|
||||
@include mq-desktop {
|
||||
max-width: 45rem;
|
||||
}
|
||||
|
||||
@include mq-bigscreen {
|
||||
max-width: 55rem;
|
||||
}
|
||||
|
||||
&__heading,
|
||||
&__cell {
|
||||
padding: 0.25em 0.5em;
|
||||
|
||||
@media (min-width: 35em) {
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
@include mq-desktop {
|
||||
&.col-2 {
|
||||
columns: 2 auto;
|
||||
}
|
||||
|
||||
&.col-3 {
|
||||
columns: 3 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0 0 0 1em;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__body {
|
||||
.datatable__row {
|
||||
background-color: rgba($bg-color-dark, 0.7);
|
||||
|
||||
&:nth-child(odd) {
|
||||
background-color: rgba(lighten($bg-color-dark, 15%), 0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__row {
|
||||
&--head {
|
||||
background-color: $bg-color-light;
|
||||
color: $copy-color;
|
||||
}
|
||||
}
|
||||
|
||||
&__cell {
|
||||
&:first-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
&--colorpick {
|
||||
margin-top: 0.1em;
|
||||
border: 0.1em solid #fff;
|
||||
}
|
||||
&__cell:first-child {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
<template>
|
||||
<figure class="figure">
|
||||
<div
|
||||
class="figure__border"
|
||||
:class="{ 'figure__border--polaroid': polaroidBorder }"
|
||||
>
|
||||
<template v-if="!nsfw || $root.nsfw">
|
||||
<div class="figure__image"><slot name="img"></slot></div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="figure__cencor">
|
||||
<div class="hazard-tape"></div>
|
||||
<div class="hazard-tape"></div>
|
||||
<div class="hazard-tape"></div>
|
||||
<div class="hazard-tape"></div>
|
||||
|
||||
<div class="figure__reveal">
|
||||
<p>🔥 Here be spicy dragons 🌶</p>
|
||||
|
||||
<nsfw-switch
|
||||
:id="id"
|
||||
v-model="$root.nsfw"
|
||||
@change="$root.showWarning()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<figcaption class="figure__meta">
|
||||
<template v-if="!nsfw || $root.nsfw">
|
||||
<div class="caption"><slot name="caption"></slot></div>
|
||||
<div class="copyright">© <slot name="copyright"></slot></div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<p>😳 2 hot 4 u 🍆</p>
|
||||
</template>
|
||||
</figcaption>
|
||||
</div>
|
||||
</figure>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NsfwSwitch from "@/components/NsfwSwitch.vue";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
polaroidBorder: Boolean,
|
||||
nsfw: Boolean,
|
||||
id: String,
|
||||
},
|
||||
components: {
|
||||
NsfwSwitch,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
@import "@/scss/_mixins.scss";
|
||||
|
||||
.figure {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
|
||||
margin: 1em auto;
|
||||
padding: 0 1em;
|
||||
text-align: center;
|
||||
|
||||
&__border {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
|
||||
margin: auto;
|
||||
|
||||
&--polaroid {
|
||||
margin: 1em auto;
|
||||
padding: 1em;
|
||||
|
||||
box-shadow: inset 0 0 1em rgba(#000, 0.7), 0 0 1em rgba(#000, 0.7);
|
||||
border-radius: 0.325em;
|
||||
|
||||
background-color: #fff;
|
||||
|
||||
.figure__meta {
|
||||
margin: 0.5em 0;
|
||||
font-family: "Permanent Marker", fantasy;
|
||||
color: $copy-color-darkgrey;
|
||||
|
||||
* {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__image {
|
||||
flex: 1 0 auto;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 35em;
|
||||
}
|
||||
}
|
||||
|
||||
&__meta {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&__cencor {
|
||||
flex: 1 0 auto;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: 0;
|
||||
width: 50vw;
|
||||
height: 35vh;
|
||||
max-width: 35em;
|
||||
max-height: 70em;
|
||||
position: relative;
|
||||
|
||||
background-color: $bg-color-light;
|
||||
overflow: hidden;
|
||||
|
||||
@include mq-desktop {
|
||||
width: 20em;
|
||||
height: 20em;
|
||||
}
|
||||
|
||||
.figure__border & .nsfw-switch {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.hazard-tape {
|
||||
position: absolute;
|
||||
left: -1em;
|
||||
right: -1em;
|
||||
top: 0;
|
||||
transform: rotate(0deg);
|
||||
height: 1em;
|
||||
background-image: repeating-linear-gradient(
|
||||
-55deg,
|
||||
#000,
|
||||
#000 0.75em,
|
||||
#ffb101 0.75em,
|
||||
#ffb101 1.5em
|
||||
);
|
||||
|
||||
&:nth-child(1) {
|
||||
top: 10%;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
top: 15%;
|
||||
transform: rotate(-10deg);
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
top: 75%;
|
||||
transform: rotate(-15deg);
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
top: 85%;
|
||||
transform: translate(-5em, -2em) rotate(40deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
161
src/components/FilterButton.vue
Normal file
|
@ -0,0 +1,161 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Ratings } from '@/interfaces'
|
||||
|
||||
interface Props {
|
||||
modelValue: number[]
|
||||
name?: string
|
||||
value: Ratings
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: number[]): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const checked = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="filter-button">
|
||||
<input
|
||||
class="filter-button__input"
|
||||
type="checkbox"
|
||||
:name="name"
|
||||
:id="Ratings[value].toLowerCase()"
|
||||
:value="value"
|
||||
v-model="checked"
|
||||
/>
|
||||
<label
|
||||
:for="Ratings[value].toLowerCase()"
|
||||
class="filter-button__label"
|
||||
:class="[Ratings[value].toLowerCase()]"
|
||||
>
|
||||
{{ Ratings[value] }}
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.filter-button {
|
||||
flex: 1 1 0;
|
||||
|
||||
&__input {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__input:checked + &__label {
|
||||
top: 0.25rem;
|
||||
box-shadow: 0 0.25rem 0 0 var(--color-button-box-shadow);
|
||||
|
||||
&.love {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-love-dark);
|
||||
}
|
||||
|
||||
&.yes {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-yes-dark);
|
||||
}
|
||||
|
||||
&.maybe {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-maybe-dark);
|
||||
}
|
||||
|
||||
&.no {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-no-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: block;
|
||||
|
||||
position: relative;
|
||||
top: 0;
|
||||
|
||||
background-color: var(--color-button);
|
||||
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
|
||||
margin: 0.5rem 0;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
box-shadow: 0 0.5rem 0 0 var(--color-button-box-shadow);
|
||||
|
||||
transition: all 0.1s ease-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
top: -0.25rem;
|
||||
box-shadow: 0 0.75rem 0 0 var(--color-button-box-shadow);
|
||||
}
|
||||
|
||||
&:active {
|
||||
top: 0.25rem;
|
||||
box-shadow: 0 0.25rem 0 0 var(--color-button-box-shadow);
|
||||
}
|
||||
|
||||
&.love {
|
||||
background-color: var(--theme-c-love);
|
||||
box-shadow: 0 0.5rem 0 0 var(--theme-c-love-dark);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0.75rem 0 0 var(--theme-c-love-dark);
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-love-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&.yes {
|
||||
background-color: var(--theme-c-yes);
|
||||
box-shadow: 0 0.5rem 0 0 var(--theme-c-yes-dark);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0.75rem 0 0 var(--theme-c-yes-dark);
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-yes-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&.maybe {
|
||||
background-color: var(--theme-c-maybe);
|
||||
box-shadow: 0 0.5rem 0 0 var(--theme-c-maybe-dark);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0.75rem 0 0 var(--theme-c-maybe-dark);
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-maybe-dark);
|
||||
}
|
||||
}
|
||||
|
||||
&.no {
|
||||
background-color: var(--theme-c-no);
|
||||
box-shadow: 0 0.5rem 0 0 var(--theme-c-no-dark);
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0.75rem 0 0 var(--theme-c-no-dark);
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0.25rem 0 0 var(--theme-c-no-dark);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
77
src/components/FilterListTag.vue
Normal file
|
@ -0,0 +1,77 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
type: string
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<span class="filter-list__tag" :class="type.toLowerCase()">
|
||||
<span>{{ type }}</span>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.filter-list {
|
||||
&__tag {
|
||||
flex: 0 0 0;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
|
||||
font-size: 0.75rem;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
|
||||
background: rgba(#f5f5f5, 0.7);
|
||||
|
||||
border: 1px solid #f5f5f5;
|
||||
border-radius: 1em;
|
||||
padding: 0 0.5em;
|
||||
}
|
||||
|
||||
&.love span {
|
||||
background: var(--theme-c-love);
|
||||
border: 1px solid var(--theme-c-love-dark);
|
||||
}
|
||||
|
||||
&.yes span {
|
||||
background: var(--theme-c-yes);
|
||||
border: 1px solid var(--theme-c-yes-dark);
|
||||
}
|
||||
|
||||
&.maybe span {
|
||||
background: var(--theme-c-maybe);
|
||||
border: 1px solid var(--theme-c-maybe-dark);
|
||||
}
|
||||
|
||||
&.no span {
|
||||
background: var(--theme-c-no);
|
||||
border: 1px solid var(--theme-c-no-dark);
|
||||
}
|
||||
|
||||
&.category {
|
||||
flex: 0 0 3rem;
|
||||
}
|
||||
|
||||
&.receive {
|
||||
flex: 0 0 3.125rem;
|
||||
|
||||
span {
|
||||
background: var(--theme-c-receive);
|
||||
border: 1px solid var(--theme-c-receive);
|
||||
}
|
||||
}
|
||||
|
||||
&.give {
|
||||
flex: 0 0 2.125rem;
|
||||
|
||||
span {
|
||||
background: var(--theme-c-give);
|
||||
border: 1px solid var(--theme-c-give);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
127
src/components/FilteredList.vue
Normal file
|
@ -0,0 +1,127 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { Ratings, Role } from '@/interfaces'
|
||||
import type { Kink } from '@/interfaces'
|
||||
import FilterButton from '@/components/FilterButton.vue'
|
||||
import FilterListTag from '@/components/FilterListTag.vue'
|
||||
|
||||
interface Props {
|
||||
data: Kink[]
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const filterOptions = ref<number[]>([])
|
||||
|
||||
const filteredItems = computed(() =>
|
||||
[...props.data]
|
||||
.sort((a, b) => a.rating - b.rating)
|
||||
.filter((kink) => filterOptions.value.some((filterNum) => kink.rating === filterNum))
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="filter-list">
|
||||
<div class="filter-list__filters">
|
||||
<FilterButton name="rating" :value="Ratings.Love" v-model="filterOptions" />
|
||||
<FilterButton name="rating" :value="Ratings.Yes" v-model="filterOptions" />
|
||||
<FilterButton name="rating" :value="Ratings.Maybe" v-model="filterOptions" />
|
||||
<FilterButton name="rating" :value="Ratings.No" v-model="filterOptions" />
|
||||
</div>
|
||||
|
||||
<div class="filter-list__list-container">
|
||||
<template v-if="filterOptions.length > 0">
|
||||
<ul class="filter-list__list">
|
||||
<li v-for="(item, idx) in filteredItems" :key="idx" class="filter-list__item">
|
||||
<FilterListTag
|
||||
v-if="filterOptions.length > 1"
|
||||
class="category"
|
||||
:type="Ratings[item.rating]"
|
||||
/>
|
||||
<span class="filter-list__item-name">
|
||||
<span>{{ item.name }}</span>
|
||||
</span>
|
||||
<FilterListTag
|
||||
v-if="((item.role ?? 0) & Role.Receive) === Role.Receive"
|
||||
:type="Role[Role.Receive]"
|
||||
/>
|
||||
<FilterListTag
|
||||
v-if="((item.role ?? 0) & Role.Give) === Role.Give"
|
||||
:type="Role[Role.Give]"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<p class="filter-list__intro-msg">Select one of the categories above</p>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.filter-list {
|
||||
background: var(--quickfacts-background);
|
||||
border-radius: 1rem;
|
||||
box-shadow: var(--container-box-shadow);
|
||||
overflow: hidden;
|
||||
|
||||
&__options {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
&__filters {
|
||||
display: flex;
|
||||
gap: 0.75rem;
|
||||
|
||||
border-collapse: collapse;
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
|
||||
&__intro-msg {
|
||||
font-size: 2rem;
|
||||
font-weight: bold;
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
&__list-container {
|
||||
border-top: 0.125rem solid var(--color-quickfacts-border);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
&__list {
|
||||
max-height: 30rem;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
&__item {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
|
||||
padding: 0.25rem 0.875rem;
|
||||
|
||||
&:hover {
|
||||
background: rgba(#000, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
&__item-name {
|
||||
flex: 1 0 0;
|
||||
line-height: 2;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,188 +0,0 @@
|
|||
<template>
|
||||
<div class="gallery">
|
||||
<div class="gallery__images">
|
||||
<a
|
||||
href="#"
|
||||
class="gallery__prev"
|
||||
@click.prevent="prev()"
|
||||
v-show="activeImage > 0"
|
||||
></a>
|
||||
<a
|
||||
href="#"
|
||||
class="gallery__next"
|
||||
@click.prevent="next()"
|
||||
v-show="activeImage < images.length - 1"
|
||||
></a>
|
||||
|
||||
<div class="gallery__viewport" :style="offset">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="gallery__navigation">
|
||||
<ul>
|
||||
<li v-for="(image, idx) in images" :key="idx">
|
||||
<a
|
||||
href="#"
|
||||
:class="{ active: activeImage === idx }"
|
||||
@click.prevent="setActive(idx)"
|
||||
></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "gallery",
|
||||
data() {
|
||||
return {
|
||||
activeImage: 0,
|
||||
images: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
offset() {
|
||||
return `margin-left: -${this.activeImage * 100}%`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
setActive(index) {
|
||||
this.activeImage = index;
|
||||
},
|
||||
prev() {
|
||||
if (this.activeImage > 0) {
|
||||
this.activeImage -= 1;
|
||||
}
|
||||
},
|
||||
next() {
|
||||
if (this.activeImage < this.images.length - 1) {
|
||||
this.activeImage += 1;
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const sel = ".gallery__viewport .figure";
|
||||
const elements = this.$el.querySelectorAll(sel);
|
||||
const images = Array.from(elements);
|
||||
this.images = images;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
@import "@/scss/_mixins.scss";
|
||||
|
||||
.gallery {
|
||||
&__prev,
|
||||
&__next {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
|
||||
z-index: 1;
|
||||
|
||||
border: {
|
||||
top: 0.125em solid #fff;
|
||||
right: 0.125em solid #fff;
|
||||
}
|
||||
|
||||
@include mq-desktop {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
&__prev {
|
||||
left: 1.5em;
|
||||
transform: rotate(-135deg);
|
||||
|
||||
@include mq-desktop {
|
||||
left: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
&__next {
|
||||
right: 1.5em;
|
||||
transform: rotate(45deg);
|
||||
|
||||
@include mq-desktop {
|
||||
right: 2em;
|
||||
}
|
||||
}
|
||||
|
||||
&__images {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__viewport {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
transition: 0.3s all ease-in-out;
|
||||
}
|
||||
|
||||
.figure {
|
||||
margin: 0;
|
||||
padding: 0 3em;
|
||||
flex: 1 0 100%;
|
||||
|
||||
@include mq-desktop {
|
||||
padding: 0 3.5em;
|
||||
}
|
||||
|
||||
&__meta {
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
margin: 0.5em auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__navigation {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
|
||||
ul {
|
||||
flex: 0 1 auto;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
|
||||
list-style: none;
|
||||
margin: 1em 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
flex: 0 1 auto;
|
||||
padding: 0.375em;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
border-radius: 1em;
|
||||
background: rgba(#fff, 0.5);
|
||||
|
||||
&.active {
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,105 +0,0 @@
|
|||
<template>
|
||||
<nav class="nav">
|
||||
<ul class="nav__list flex flex--row flex--nowrap flex--center-v">
|
||||
<li class="nav__item" v-for="(route, idx) in routes" :key="idx">
|
||||
<router-link class="nav__link" :to="route.path">
|
||||
{{ route.name }}
|
||||
</router-link>
|
||||
<div class="nav__underline"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
routes: {
|
||||
required: true,
|
||||
type: Array,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
@import "@/scss/_mixins.scss";
|
||||
|
||||
.nav {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.nav__list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
list-style-type: none;
|
||||
|
||||
z-index: 1;
|
||||
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
|
||||
@include mq-desktop {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.nav__item {
|
||||
padding: 0.375em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nav__link {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
color: $copy-color;
|
||||
margin-bottom: 0.375em;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover ~ .nav__underline {
|
||||
&::before,
|
||||
&::after {
|
||||
width: 50%;
|
||||
background-color: $copy-color;
|
||||
}
|
||||
}
|
||||
|
||||
&.router-link-exact-active {
|
||||
color: $bg-color-light;
|
||||
|
||||
&:hover ~ .nav__underline {
|
||||
&::before,
|
||||
&::after {
|
||||
background-color: $bg-color-light;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav__underline {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
&::before,
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0.125em;
|
||||
bottom: 0;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 50%;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,113 +0,0 @@
|
|||
<template>
|
||||
<div class="nsfw-warning">
|
||||
<div class="nsfw-warning__background"></div>
|
||||
<div class="nsfw-warning__message">
|
||||
<div>
|
||||
<h2><slot name="heading"></slot></h2>
|
||||
<p><slot name="message"></slot></p>
|
||||
|
||||
<div class="btn-container">
|
||||
<btn href="#" class="positive" @click.prevent="confirmNsfw(true)">
|
||||
<slot name="yes"></slot>
|
||||
</btn>
|
||||
|
||||
<btn href="#" class="negative" @click.prevent="confirmNsfw(false)">
|
||||
<slot name="no"></slot>
|
||||
</btn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import btn from "@/components/Button.vue";
|
||||
|
||||
export default {
|
||||
components: { btn },
|
||||
methods: {
|
||||
confirmNsfw(input) {
|
||||
this.$root.nsfw = input;
|
||||
this.$root.isConfirmedHorny = input;
|
||||
this.$root.isWarn = false;
|
||||
document.body.classList.toggle("scroll-lock");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
@import "@/scss/_mixins.scss";
|
||||
|
||||
.nsfw-warning {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
|
||||
z-index: 9001;
|
||||
|
||||
backdrop-filter: blur(1em);
|
||||
background-color: rgba(#000, 0.5);
|
||||
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
|
||||
padding: 2em;
|
||||
text-align: center;
|
||||
overflow: auto;
|
||||
|
||||
&__background {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
&__message {
|
||||
flex: 0 1 30em;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
|
||||
margin: auto;
|
||||
border: 0.25em solid $bg-color-warning;
|
||||
border-radius: 1em;
|
||||
padding: 1em;
|
||||
|
||||
z-index: 9002;
|
||||
|
||||
background-color: $bg-color-dark;
|
||||
|
||||
> * {
|
||||
flex: 0 1 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn-container {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
flex: 0 1 100%;
|
||||
margin: 0.75em 0;
|
||||
|
||||
&.positive {
|
||||
@include button($btn-color-positive);
|
||||
}
|
||||
|
||||
&.negative {
|
||||
@include button($btn-color-negative);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,37 +0,0 @@
|
|||
<template>
|
||||
<div class="prose">
|
||||
<slot name="default"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_mixins.scss";
|
||||
|
||||
.prose {
|
||||
padding: 0 env(safe-area-inset-right) 0 env(safe-area-inset-left);
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
p,
|
||||
.quickfacts,
|
||||
.btn-group {
|
||||
margin: {
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
}
|
||||
|
||||
@include mq-desktop {
|
||||
max-width: 45rem;
|
||||
margin: {
|
||||
left: auto;
|
||||
right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@include mq-bigscreen {
|
||||
max-width: 55rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,92 +1,93 @@
|
|||
<template>
|
||||
<div class="quickfacts" :class="{ open: isExpanded }">
|
||||
<h4 class="quickfacts__head" @click.prevent="toggle">Quickfacts</h4>
|
||||
<script setup lang="ts">
|
||||
interface Props {
|
||||
cols?: number
|
||||
}
|
||||
|
||||
<div class="quickfacts__list">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
isExpanded: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
},
|
||||
},
|
||||
};
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
<template>
|
||||
<details class="quickfacts">
|
||||
<summary class="quickfacts__head">Quickfacts</summary>
|
||||
<div class="quickfacts__list" :class="[`cols-${cols}`]">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</details>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.quickfacts {
|
||||
border-radius: 1em;
|
||||
overflow: hidden;
|
||||
margin: 1em 0;
|
||||
position: relative;
|
||||
|
||||
background: var(--quickfacts-background);
|
||||
|
||||
margin: 1rem 0;
|
||||
border-radius: 1rem;
|
||||
|
||||
box-shadow: var(--container-box-shadow);
|
||||
|
||||
overflow: hidden;
|
||||
transition: 0.3s all ease-in-out;
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: "";
|
||||
display: block;
|
||||
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 1.375rem;
|
||||
right: 1.375rem;
|
||||
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s all ease-in-out;
|
||||
|
||||
border: {
|
||||
right: 0.625em solid transparent;
|
||||
bottom: 0.625em solid #fff;
|
||||
left: 0.625em solid transparent;
|
||||
right: 0.625rem solid transparent;
|
||||
bottom: 0.625rem solid #fff;
|
||||
left: 0.625rem solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
&.open:before {
|
||||
&[open]:before {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
&.open & {
|
||||
&__head {
|
||||
background-color: $bg-color-light;
|
||||
}
|
||||
|
||||
&__list {
|
||||
max-height: 25em;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__head {
|
||||
background-color: $bg-color-dark;
|
||||
font-family: var(--font-family-headings);
|
||||
font-size: 1.125rem;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
padding: 0.75rem 1.5rem;
|
||||
transition: 0.3s all ease-in-out;
|
||||
cursor: pointer;
|
||||
|
||||
&::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__list {
|
||||
background-color: rgba($bg-color-dark, 0.5);
|
||||
max-height: 0em;
|
||||
padding: 0 1.5rem;
|
||||
transition: 0.3s all ease-in-out;
|
||||
border-top: 0.125rem solid var(--color-quickfacts-border);
|
||||
padding: 1.5rem;
|
||||
|
||||
&.cols-2 ul {
|
||||
columns: var(--quickfacts-cols-double);
|
||||
}
|
||||
|
||||
&.cols-3 ul {
|
||||
columns: var(--quickfacts-cols-triple);
|
||||
}
|
||||
|
||||
&.cols-4 ul {
|
||||
columns: var(--quickfacts-cols-quadruple);
|
||||
}
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0 0.5em;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 0 0 0 1em;
|
||||
margin: 0 0 0 1rem;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
|
79
src/components/RefButton.vue
Normal file
|
@ -0,0 +1,79 @@
|
|||
<script setup lang="ts">
|
||||
interface Props {
|
||||
positive?: boolean
|
||||
negative?: boolean
|
||||
href?: string
|
||||
download?: boolean | any
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a
|
||||
class="btn"
|
||||
:class="{ positive: positive, negative: negative }"
|
||||
:href="href"
|
||||
:[download]="download"
|
||||
>
|
||||
<slot></slot>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.btn {
|
||||
position: relative;
|
||||
top: 0;
|
||||
|
||||
background-color: var(--color-button);
|
||||
|
||||
font-weight: 700;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
|
||||
margin: 0.5rem 0;
|
||||
border-radius: 0.25rem;
|
||||
padding: 0.5rem 1rem;
|
||||
|
||||
box-shadow: 0 0.5rem 0 0 var(--color-button-box-shadow);
|
||||
|
||||
transition: all 0.1s ease-out;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
top: -0.25rem;
|
||||
box-shadow: 0 0.75rem 0 0 var(--color-button-box-shadow);
|
||||
}
|
||||
|
||||
&:active {
|
||||
top: 0.25rem;
|
||||
box-shadow: 0 0.25rem 0 0 var(--color-button-box-shadow);
|
||||
}
|
||||
|
||||
&.positive {
|
||||
background-color: #259410;
|
||||
box-shadow: 0 0.5rem 0 0 #1a660b;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0.75rem 0 0 #1a660b;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0.25rem 0 0 #1a660b;
|
||||
}
|
||||
}
|
||||
|
||||
&.negative {
|
||||
background-color: #ae1414;
|
||||
box-shadow: 0 0.5rem 0 0 #800f0f;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0.75rem 0 0 #800f0f;
|
||||
}
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0.25rem 0 0 #800f0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
223
src/components/RefFigure.vue
Normal file
|
@ -0,0 +1,223 @@
|
|||
<script setup lang="ts">
|
||||
import { inject } from 'vue'
|
||||
import { nsfwKey, showModalKey } from '@/keys'
|
||||
import RefToggle from '@/components/RefToggle.vue'
|
||||
|
||||
interface Props {
|
||||
cornerText?: boolean
|
||||
polaroidBorder?: boolean
|
||||
dropshadow?: boolean
|
||||
nsfw?: boolean
|
||||
id: string
|
||||
}
|
||||
|
||||
const isNsfw = inject<boolean>(nsfwKey, false)
|
||||
const showModal = inject<Function>(showModalKey, Function)
|
||||
|
||||
defineProps<Props>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<figure class="figure">
|
||||
<div
|
||||
class="figure__border"
|
||||
:class="{
|
||||
'figure__border--polaroid': polaroidBorder,
|
||||
'figure__border--cornertext': cornerText
|
||||
}"
|
||||
>
|
||||
<template v-if="!nsfw || isNsfw">
|
||||
<div class="figure__image" :class="{ 'figure__image--dropshadow': dropshadow }">
|
||||
<slot name="img"></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<div class="figure__cencor">
|
||||
<div class="figure__tape"></div>
|
||||
<div class="figure__tape"></div>
|
||||
<div class="figure__tape"></div>
|
||||
<div class="figure__tape"></div>
|
||||
|
||||
<div class="figure__reveal">
|
||||
<p>🔥 Here be spicy dragons 🌶</p>
|
||||
|
||||
<RefToggle
|
||||
class="figure__toggle"
|
||||
:id="id"
|
||||
v-model="isNsfw"
|
||||
@click.prevent="showModal()"
|
||||
>
|
||||
<template #off>😇</template>
|
||||
<template #on>😈</template>
|
||||
</RefToggle>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-if="!nsfw || isNsfw">
|
||||
<figcaption class="figure__meta">
|
||||
<div class="caption">
|
||||
<slot name="caption"></slot>
|
||||
</div>
|
||||
<div class="copyright">© <slot name="copyright"></slot></div>
|
||||
</figcaption>
|
||||
</template>
|
||||
</div>
|
||||
</figure>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.figure {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
|
||||
text-align: center;
|
||||
|
||||
margin: 1em auto;
|
||||
padding: 0 var(--container-spacing-right-safe) 0 var(--container-spacing-left-safe);
|
||||
|
||||
&__border {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
|
||||
margin: auto;
|
||||
|
||||
&--polaroid {
|
||||
margin: 1em auto;
|
||||
padding: 1em;
|
||||
|
||||
box-shadow: inset 0 0 1em rgba(0, 0, 0, 0.7), 0 0 1em rgba(0, 0, 0, 0.7);
|
||||
border-radius: 0.325em;
|
||||
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__border--cornertext {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&__border--cornertext img,
|
||||
&__border--cornertext &__cencor {
|
||||
margin: 1rem 0;
|
||||
border-radius: 1rem;
|
||||
filter: drop-shadow(0 0 0.625rem black);
|
||||
}
|
||||
|
||||
&__border--cornertext &__meta {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
|
||||
font-size: 0.75rem;
|
||||
|
||||
margin: 0 0 1.35rem 0;
|
||||
border-radius: 1em 0 1rem 0;
|
||||
padding: 0.25rem 0.75rem;
|
||||
|
||||
.caption,
|
||||
.copyright {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.caption {
|
||||
margin: 0 0.125rem 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__border--polaroid &__meta {
|
||||
font-family: 'Permanent Marker', fantasy;
|
||||
color: var(--color-figure-polaroid-text);
|
||||
|
||||
max-width: 35rem;
|
||||
|
||||
margin: 0.5rem auto;
|
||||
|
||||
* {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
&__image {
|
||||
flex: 1 0 auto;
|
||||
|
||||
&--dropshadow {
|
||||
filter: drop-shadow(0.5rem 0.25rem 0.375rem #000);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 35rem;
|
||||
}
|
||||
}
|
||||
|
||||
&__meta {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&__cencor {
|
||||
flex: 1 0 auto;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
padding: 0;
|
||||
width: var(--figure-cencor-width);
|
||||
height: var(--figure-cencor-height);
|
||||
max-width: 35rem;
|
||||
max-height: 70rem;
|
||||
position: relative;
|
||||
|
||||
background-color: var(--figure-cencor-background-color);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__toggle {
|
||||
position: relative;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&__tape {
|
||||
position: absolute;
|
||||
left: -1rem;
|
||||
right: -1rem;
|
||||
top: 0;
|
||||
transform: rotate(0deg);
|
||||
height: 1rem;
|
||||
background-image: repeating-linear-gradient(
|
||||
-55deg,
|
||||
#000,
|
||||
#000 0.75rem,
|
||||
#ffb101 0.75rem,
|
||||
#ffb101 1.5rem
|
||||
);
|
||||
|
||||
&:nth-child(1) {
|
||||
top: 10%;
|
||||
transform: rotate(5deg);
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
top: 15%;
|
||||
transform: rotate(-10deg);
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
top: 75%;
|
||||
transform: rotate(-15deg);
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
top: 85%;
|
||||
transform: translate(-5rem, -2rem) rotate(40deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
197
src/components/RefGallery.vue
Normal file
|
@ -0,0 +1,197 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { debounce } from '@/helpers'
|
||||
|
||||
const activeImage = ref(0)
|
||||
const images = ref<Element[]>([])
|
||||
const element = document.createElement('div')
|
||||
const galleryViewport = ref<HTMLElement>(element)
|
||||
const galleryItemWidth = ref<number>(1)
|
||||
|
||||
const resizeObserverCallback = (entries: ResizeObserverEntry[]): void => {
|
||||
for (const entry of entries) {
|
||||
galleryItemWidth.value = entry.contentRect.width
|
||||
}
|
||||
}
|
||||
|
||||
const resizeObserver = new ResizeObserver(debounce(resizeObserverCallback, 1000))
|
||||
|
||||
const setActiveImage = (index: number): void => {
|
||||
activeImage.value = index
|
||||
galleryViewport.value.scrollTo({
|
||||
left: galleryItemWidth.value * index,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
|
||||
const getActiveImage = (gallery: HTMLElement, itemWidth: number): number => {
|
||||
return gallery.scrollLeft / itemWidth
|
||||
}
|
||||
|
||||
const prev = (): void => {
|
||||
if (activeImage.value > 0) {
|
||||
galleryViewport.value.scrollBy({
|
||||
left: galleryItemWidth.value * -1,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const next = (): void => {
|
||||
if (activeImage.value < images.value.length - 1) {
|
||||
galleryViewport.value.scrollBy({
|
||||
left: galleryItemWidth.value,
|
||||
behavior: 'smooth'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const onScroll = (): void => {
|
||||
const newImg = Math.floor(getActiveImage(galleryViewport.value, galleryItemWidth.value))
|
||||
setActiveImage(newImg)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
resizeObserver.observe(galleryViewport.value)
|
||||
images.value = Array.from(galleryViewport.value.children)
|
||||
galleryItemWidth.value = galleryViewport.value.scrollWidth / images.value.length
|
||||
galleryViewport.value.addEventListener('scroll', debounce(onScroll, 500))
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gallery">
|
||||
<div class="gallery__images">
|
||||
<a href="#" class="gallery__prev" @click.prevent="prev()" v-show="activeImage > 0"></a>
|
||||
<a
|
||||
href="#"
|
||||
class="gallery__next"
|
||||
@click.prevent="next()"
|
||||
v-show="activeImage < images.length - 1"
|
||||
></a>
|
||||
|
||||
<div class="gallery__viewport" ref="galleryViewport">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="gallery__navigation">
|
||||
<ul>
|
||||
<li v-for="(image, idx) in images" :key="idx">
|
||||
<a
|
||||
href="#"
|
||||
:class="{ active: activeImage === idx }"
|
||||
@click.prevent="setActiveImage(idx)"
|
||||
></a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.gallery {
|
||||
&__prev,
|
||||
&__next {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
width: var(--gallery-size);
|
||||
height: var(--gallery-size);
|
||||
|
||||
z-index: 1;
|
||||
|
||||
border: {
|
||||
top: 0.125rem solid #fff;
|
||||
right: 0.125rem solid #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&__prev {
|
||||
left: var(--gallery-arrow-position);
|
||||
transform: rotate(-135deg);
|
||||
}
|
||||
|
||||
&__next {
|
||||
right: var(--gallery-arrow-position);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
&__images {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__viewport {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
overflow: auto;
|
||||
scroll-snap-type: x mandatory;
|
||||
|
||||
scrollbar-width: none;
|
||||
|
||||
transition: 0.3s all ease-in-out;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.figure {
|
||||
margin: 0;
|
||||
padding: var(--gallery-image-padding);
|
||||
flex: 1 0 100%;
|
||||
|
||||
scroll-snap-align: center;
|
||||
|
||||
&__meta {
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
margin: 0.5rem auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__navigation {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
|
||||
ul {
|
||||
flex: 0 1 auto;
|
||||
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: center;
|
||||
|
||||
list-style: none;
|
||||
margin: 1rem 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
flex: 0 1 auto;
|
||||
padding: 0.375em;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
border-radius: 1em;
|
||||
background: rgba(#fff, 0.5);
|
||||
|
||||
&.active {
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
98
src/components/RefModal.vue
Normal file
|
@ -0,0 +1,98 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
interface Props {
|
||||
id: string
|
||||
}
|
||||
|
||||
defineProps<Props>()
|
||||
|
||||
const modal = ref<HTMLDialogElement>()
|
||||
|
||||
const showModal = () => {
|
||||
modal.value?.showModal()
|
||||
document.body.inert = true
|
||||
document.body.classList.add('scroll-lock')
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
modal.value?.close()
|
||||
document.body.inert = false
|
||||
document.body.classList.remove('scroll-lock')
|
||||
}
|
||||
|
||||
defineExpose({ showModal, close })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<dialog :id="id" class="modal" ref="modal">
|
||||
<form method="dialog" class="modal__content">
|
||||
<h2 class="modal__heading">
|
||||
<slot name="heading"></slot>
|
||||
</h2>
|
||||
|
||||
<div class="modal__message">
|
||||
<slot name="message"></slot>
|
||||
</div>
|
||||
|
||||
<div class="modal__buttons">
|
||||
<slot name="buttons"></slot>
|
||||
</div>
|
||||
</form>
|
||||
</dialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.modal {
|
||||
position: fixed;
|
||||
|
||||
background: var(--modal-background);
|
||||
color: var(--color-text);
|
||||
|
||||
width: var(--modal-width);
|
||||
|
||||
margin: auto;
|
||||
border: 0.25rem solid var(--color-modal-border);
|
||||
border-radius: 1rem;
|
||||
padding: 1rem;
|
||||
|
||||
overflow: auto;
|
||||
|
||||
animation: fade-in 1s;
|
||||
|
||||
&::backdrop {
|
||||
backdrop-filter: blur(1rem);
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
animation: fade-in 1s;
|
||||
}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
gap: 1.5rem;
|
||||
|
||||
> * {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
&__heading {
|
||||
margin: 1.875rem 0 0 0;
|
||||
}
|
||||
|
||||
&__message {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,36 +1,48 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
interface Props {
|
||||
modelValue: boolean
|
||||
id: string
|
||||
name?: string
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:modelValue', value: boolean): void
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const checked = computed({
|
||||
get() {
|
||||
return props.modelValue
|
||||
},
|
||||
set(value) {
|
||||
emit('update:modelValue', value)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<label class="nsfw-switch" :for="id">
|
||||
<div class="nsfw-switch__label">😇</div>
|
||||
<div class="nsfw-switch__toggle">
|
||||
<input
|
||||
:checked="modelValue"
|
||||
@change="$emit('update:modelValue', $event.target.checked)"
|
||||
type="checkbox"
|
||||
name="nsfw"
|
||||
:id="id"
|
||||
/>
|
||||
<div class="nsfw-switch__toggle-inner"></div>
|
||||
<label :for="id" class="toggle">
|
||||
<div class="toggle__label">
|
||||
<slot name="off"></slot>
|
||||
</div>
|
||||
<div class="toggle__input">
|
||||
<input type="checkbox" :name="name" :id="id" v-model="checked" />
|
||||
<div class="toggle__inner"></div>
|
||||
</div>
|
||||
<div class="toggle__label">
|
||||
<slot name="on"></slot>
|
||||
</div>
|
||||
<div class="nsfw-switch__label">😈</div>
|
||||
</label>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
modelValue: Boolean,
|
||||
id: { type: String, required: true },
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/scss/_variables.scss";
|
||||
|
||||
.nsfw-switch {
|
||||
font-family: "apple color emoji", "segoe ui emoji", "noto color emoji",
|
||||
"android emoji", "emojisymbols", "emojione mozilla", "twemoji mozilla",
|
||||
"segoe ui symbol";
|
||||
.toggle {
|
||||
font-family: 'apple color emoji', 'noto color emoji', 'segoe ui emoji', 'android emoji',
|
||||
'emojisymbols', 'emojione mozilla', 'twemoji mozilla', 'segoe ui symbol';
|
||||
|
||||
padding: 0.5em;
|
||||
|
||||
|
@ -47,23 +59,23 @@ export default {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
&__toggle {
|
||||
&__input {
|
||||
margin: 0 0.5em;
|
||||
}
|
||||
|
||||
& input:checked + &-inner {
|
||||
background-color: $bg-color-light;
|
||||
&__input input:checked + &__inner {
|
||||
background-color: var(--color-toggle);
|
||||
|
||||
&:before {
|
||||
transform: translate3d(0.9em, 0.1em, 0) scale3d(0, 0, 0);
|
||||
}
|
||||
&:before {
|
||||
transform: translate3d(0.9em, 0.1em, 0) scale3d(0, 0, 0);
|
||||
}
|
||||
|
||||
&:after {
|
||||
transform: translate3d(1.1em, 0.1em, 0);
|
||||
}
|
||||
&:after {
|
||||
transform: translate3d(1.1em, 0.1em, 0);
|
||||
}
|
||||
}
|
||||
|
||||
&__toggle-inner {
|
||||
&__inner {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 2.3em;
|
||||
|
@ -75,7 +87,7 @@ export default {
|
|||
|
||||
&:before,
|
||||
&:after {
|
||||
content: "";
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
height: 1.1em;
|
||||
|
@ -103,12 +115,12 @@ export default {
|
|||
pointer-events: none;
|
||||
}
|
||||
|
||||
&:active &__toggle-inner:after {
|
||||
&:active &__inner:after {
|
||||
width: 1.4em;
|
||||
transform: translate3d(0.1em, 0.1em, 0);
|
||||
}
|
||||
|
||||
&:active input:checked + &__toggle-inner:after {
|
||||
&:active input:checked + &__inner:after {
|
||||
transform: translate3d(0.8em, 0.1em, 0);
|
||||
}
|
||||
}
|
25
src/components/SiteFooter.vue
Normal file
|
@ -0,0 +1,25 @@
|
|||
<template>
|
||||
<footer class="footer">
|
||||
<slot></slot>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.footer {
|
||||
background: url(@/assets/subtle-prism.svg) var(--color-background-footer);
|
||||
background-blend-mode: multiply;
|
||||
|
||||
padding: var(--footer-padding);
|
||||
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
|
||||
+ p {
|
||||
margin: 0.5em auto 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
30
src/components/SiteHeader.vue
Normal file
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<header class="header">
|
||||
<slot></slot>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.header {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
position: sticky;
|
||||
top: var(--container-spacing-top-safe);
|
||||
right: var(--container-spacing-right-safe);
|
||||
left: var(--container-spacing-left-safe);
|
||||
|
||||
background: var(--header-background);
|
||||
|
||||
max-width: 70rem;
|
||||
|
||||
margin: var(--header-margin);
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
|
||||
box-shadow: var(--container-box-shadow);
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
93
src/components/SiteNavigation.vue
Normal file
|
@ -0,0 +1,93 @@
|
|||
<script setup lang="ts">
|
||||
import { RouterLink } from 'vue-router'
|
||||
import router from '@/router'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="nav">
|
||||
<ul class="nav__list">
|
||||
<li class="nav__item" v-for="(route, idx) in router.options.routes" :key="idx">
|
||||
<RouterLink class="nav__link" :to="route.path">
|
||||
{{ route.name }}
|
||||
</RouterLink>
|
||||
<div class="nav__underline"></div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.nav {
|
||||
overflow: auto;
|
||||
|
||||
&__list {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: var(--navigation-justify-content);
|
||||
align-items: center;
|
||||
|
||||
width: 100%;
|
||||
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
list-style-type: none;
|
||||
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
&__item {
|
||||
padding: 0.375rem;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__link {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
color: var(--color-text);
|
||||
margin-bottom: 0.375em;
|
||||
text-decoration: none;
|
||||
text-transform: capitalize;
|
||||
|
||||
&.router-link-exact-active {
|
||||
color: var(--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
&__link:hover ~ &__underline,
|
||||
&__link.router-link-exact-active ~ &__underline {
|
||||
&:before,
|
||||
&:after {
|
||||
width: 50%;
|
||||
background-color: var(--color-text);
|
||||
}
|
||||
}
|
||||
|
||||
&__underline {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
||||
width: 0;
|
||||
height: 0.125rem;
|
||||
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
|
||||
&:before {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
&:after {
|
||||
right: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,56 +0,0 @@
|
|||
<template>
|
||||
<div class="welcome flex flex--row flex--wrap flex--center flex--center-v">
|
||||
<div class="welcome__image-container col col-m-6 col-3">
|
||||
<img
|
||||
class="welcome__image"
|
||||
src="@/assets/sebin-smug-icon.png"
|
||||
alt="Sebin Avatar"
|
||||
/>
|
||||
</div>
|
||||
<div class="welcome__headings col col-m-12 col-7">
|
||||
<h1 class="welcome__main-heading">
|
||||
<slot name="main"></slot>
|
||||
</h1>
|
||||
<h2 class="welcome__sub-heading">
|
||||
<slot name="sub"></slot>
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.welcome {
|
||||
max-width: 40em;
|
||||
margin: 1em auto;
|
||||
|
||||
&__image {
|
||||
width: 100%;
|
||||
border-radius: 100%;
|
||||
border: 0.375em solid #fff;
|
||||
box-shadow: 0.125em 0.125em 0.5em rgba(#000, 0.7);
|
||||
}
|
||||
|
||||
&__main-heading,
|
||||
&__sub-heading {
|
||||
font-family: "Exo", sans-serif;
|
||||
margin: 1rem 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&__main-heading {
|
||||
font-size: 2.125em;
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
|
||||
@media (min-width: 35em) {
|
||||
font-size: 2.75em;
|
||||
}
|
||||
}
|
||||
|
||||
&__sub-heading {
|
||||
font-size: 1em;
|
||||
font-weight: 300;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
</style>
|