Initial commit

This commit is contained in:
Damillora 2021-01-25 01:21:43 +07:00
commit 9c03ba9f54
72 changed files with 5954 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.DS_Store
/node_modules/
/src/node_modules/@sapper/
yarn-error.log
/__sapper__/

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "static/images"]
path = static/images
url = https://github.com/Damillora/nanaomoe-images.git
branch = main

152
README.md Normal file
View File

@ -0,0 +1,152 @@
# sapper-template
The default template for setting up a [Sapper](https://github.com/sveltejs/sapper) project. Can use either Rollup or webpack as bundler.
## Getting started
### Using `degit`
To create a new Sapper project based on Rollup locally, run
```bash
npx degit "sveltejs/sapper-template#rollup" my-app
```
For a webpack-based project, instead run
```bash
npx degit "sveltejs/sapper-template#webpack" my-app
```
[`degit`](https://github.com/Rich-Harris/degit) is a scaffolding tool that lets you create a directory from a branch in a repository.
Replace `my-app` with the path where you wish to create the project.
### Using GitHub templates
Alternatively, you can create the new project as a GitHub repository using GitHub's template feature.
Go to either [sapper-template-rollup](https://github.com/sveltejs/sapper-template-rollup) or [sapper-template-webpack](https://github.com/sveltejs/sapper-template-webpack) and click on "Use this template" to create a new project repository initialized by the template.
### Running the project
Once you have created the project, install dependencies and run the project in development mode:
```bash
cd my-app
npm install # or yarn
npm run dev
```
This will start the development server on [localhost:3000](http://localhost:3000). Open it and click around.
You now have a fully functional Sapper project! To get started developing, consult [sapper.svelte.dev](https://sapper.svelte.dev).
### Using TypeScript
By default, the template uses plain JavaScript. If you wish to use TypeScript instead, you need some changes to the project:
* Add `typescript` as well as typings as dependences in `package.json`
* Configure the bundler to use [`svelte-preprocess`](https://github.com/sveltejs/svelte-preprocess) and transpile the TypeScript code.
* Add a `tsconfig.json` file
* Update the project code to TypeScript
The template comes with a script that will perform these changes for you by running
```bash
node scripts/setupTypeScript.js
```
`@sapper` dependencies are resolved through `src/node_modules/@sapper`, which is created during the build. You therefore need to run or build the project once to avoid warnings about missing dependencies.
The script does not support webpack at the moment.
## Directory structure
Sapper expects to find two directories in the root of your project — `src` and `static`.
### src
The [src](src) directory contains the entry points for your app — `client.js`, `server.js` and (optionally) a `service-worker.js` — along with a `template.html` file and a `routes` directory.
#### src/routes
This is the heart of your Sapper app. There are two kinds of routes — *pages*, and *server routes*.
**Pages** are Svelte components written in `.svelte` files. When a user first visits the application, they will be served a server-rendered version of the route in question, plus some JavaScript that 'hydrates' the page and initialises a client-side router. From that point forward, navigating to other pages is handled entirely on the client for a fast, app-like feel. (Sapper will preload and cache the code for these subsequent pages, so that navigation is instantaneous.)
**Server routes** are modules written in `.js` files, that export functions corresponding to HTTP methods. Each function receives Express `request` and `response` objects as arguments, plus a `next` function. This is useful for creating a JSON API, for example.
There are three simple rules for naming the files that define your routes:
* A file called `src/routes/about.svelte` corresponds to the `/about` route. A file called `src/routes/blog/[slug].svelte` corresponds to the `/blog/:slug` route, in which case `params.slug` is available to the route
* The file `src/routes/index.svelte` (or `src/routes/index.js`) corresponds to the root of your app. `src/routes/about/index.svelte` is treated the same as `src/routes/about.svelte`.
* Files and directories with a leading underscore do *not* create routes. This allows you to colocate helper modules and components with the routes that depend on them — for example you could have a file called `src/routes/_helpers/datetime.js` and it would *not* create a `/_helpers/datetime` route.
#### src/node_modules/images
Images added to `src/node_modules/images` can be imported into your code using `import 'images/<filename>'`. They will be given a dynamically generated filename containing a hash, allowing for efficient caching and serving the images on a CDN.
See [`index.svelte`](src/routes/index.svelte) for an example.
#### src/node_modules/@sapper
This directory is managed by Sapper and generated when building. It contains all the code you import from `@sapper` modules.
### static
The [static](static) directory contains static assets that should be served publicly. Files in this directory will be available directly under the root URL, e.g. an `image.jpg` will be available as `/image.jpg`.
The default [service-worker.js](src/service-worker.js) will preload and cache these files, by retrieving a list of `files` from the generated manifest:
```js
import { files } from '@sapper/service-worker';
```
If you have static files you do not want to cache, you should exclude them from this list after importing it (and before passing it to `cache.addAll`).
Static files are served using [sirv](https://github.com/lukeed/sirv).
## Bundler configuration
Sapper uses Rollup or webpack to provide code-splitting and dynamic imports, as well as compiling your Svelte components. With webpack, it also provides hot module reloading. As long as you don't do anything daft, you can edit the configuration files to add whatever plugins you'd like.
## Production mode and deployment
To start a production version of your app, run `npm run build && npm start`. This will disable live reloading, and activate the appropriate bundler plugins.
You can deploy your application to any environment that supports Node 10 or above. As an example, to deploy to [Vercel Now](https://vercel.com) when using `sapper export`, run these commands:
```bash
npm install -g vercel
vercel
```
If your app can't be exported to a static site, you can use the [vercel-sapper](https://github.com/thgh/vercel-sapper) builder. You can find instructions on how to do so in its [README](https://github.com/thgh/vercel-sapper#basic-usage).
## Using external components
When using Svelte components installed from npm, such as [@sveltejs/svelte-virtual-list](https://github.com/sveltejs/svelte-virtual-list), Svelte needs the original component source (rather than any precompiled JavaScript that ships with the component). This allows the component to be rendered server-side, and also keeps your client-side app smaller.
Because of that, it's essential that the bundler doesn't treat the package as an *external dependency*. You can either modify the `external` option under `server` in [rollup.config.js](rollup.config.js) or the `externals` option in [webpack.config.js](webpack.config.js), or simply install the package to `devDependencies` rather than `dependencies`, which will cause it to get bundled (and therefore compiled) with your app:
```bash
npm install -D @sveltejs/svelte-virtual-list
```
## Bugs and feedback
Sapper is in early development, and may have the odd rough edge here and there. Please be vocal over on the [Sapper issue tracker](https://github.com/sveltejs/sapper/issues).

40
package.json Normal file
View File

@ -0,0 +1,40 @@
{
"name": "@damillora/rinze",
"description": "nanao.moe website, now in Svelte",
"version": "0.1.0",
"scripts": {
"dev": "sapper dev",
"build": "sapper build --legacy",
"export": "sapper export --legacy",
"start": "node __sapper__/build"
},
"dependencies": {
"compression": "^1.7.1",
"modern-normalize": "^1.0.0",
"polka": "next",
"sirv": "^1.0.0"
},
"devDependencies": {
"@babel/core": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-transform-runtime": "^7.0.0",
"@babel/preset-env": "^7.0.0",
"@babel/runtime": "^7.0.0",
"@rollup/plugin-alias": "^3.1.1",
"@rollup/plugin-babel": "^5.0.0",
"@rollup/plugin-commonjs": "^14.0.0",
"@rollup/plugin-node-resolve": "^8.0.0",
"@rollup/plugin-replace": "^2.2.0",
"@rollup/plugin-url": "^5.0.0",
"autoprefixer": "^10.2.3",
"node-sass": "^5.0.0",
"postcss": "^8.2.4",
"rollup": "^2.3.4",
"rollup-plugin-svelte": "^7.0.0",
"rollup-plugin-terser": "^7.0.0",
"sapper": "^0.28.0",
"svelte": "^3.17.3",
"svelte-preprocess": "^4.6.3"
},
"license": "MIT"
}

139
rollup.config.js Normal file
View File

@ -0,0 +1,139 @@
import path from 'path';
import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import commonjs from '@rollup/plugin-commonjs';
import url from '@rollup/plugin-url';
import svelte from 'rollup-plugin-svelte';
import babel from '@rollup/plugin-babel';
import alias from '@rollup/plugin-alias';
import { terser } from 'rollup-plugin-terser';
import config from 'sapper/config/rollup.js';
import pkg from './package.json';
import sveltePreprocess from 'svelte-preprocess';
const mode = process.env.NODE_ENV;
const dev = mode === 'development';
const legacy = !!process.env.SAPPER_LEGACY_BUILD;
const onwarn = (warning, onwarn) =>
(warning.code === 'MISSING_EXPORT' && /'preload'/.test(warning.message)) ||
(warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) ||
onwarn(warning);
const preprocess = sveltePreprocess({
scss: {
includePaths: ['src'],
},
postcss: {
plugins: [require('autoprefixer')],
},
});
export default {
client: {
input: config.client.input(),
output: config.client.output(),
plugins: [
alias({
resolve: ['.jpg', '.js', '.svelte','.scss'], // optional, by default this will just look for .js files or folders
entries: [
{ find: '@', replacement: path.resolve(__dirname, 'src') },
]
}),
replace({
'process.browser': true,
'process.env.NODE_ENV': JSON.stringify(mode)
}),
svelte({
compilerOptions: {
dev,
hydratable: true,
},
preprocess,
}),
url({
sourceDir: path.resolve(__dirname, 'src/node_modules/images'),
publicPath: '/client/'
}),
resolve({
browser: true,
dedupe: ['svelte']
}),
commonjs(),
legacy && babel({
extensions: ['.js', '.mjs', '.html', '.svelte'],
babelHelpers: 'runtime',
exclude: ['node_modules/@babel/**'],
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead'
}]
],
plugins: [
'@babel/plugin-syntax-dynamic-import',
['@babel/plugin-transform-runtime', {
useESModules: true
}]
]
}),
!dev && terser({
module: true
})
],
preserveEntrySignatures: false,
onwarn,
},
server: {
input: config.server.input(),
output: config.server.output(),
plugins: [
replace({
'process.browser': false,
'process.env.NODE_ENV': JSON.stringify(mode)
}),
svelte({
compilerOptions: {
dev,
generate: 'ssr',
hydratable: true
},
emitCss: false,
preprocess,
}),
url({
sourceDir: path.resolve(__dirname, 'src/node_modules/images'),
publicPath: '/client/',
emitFiles: false // already emitted by client build
}),
resolve({
dedupe: ['svelte']
}),
commonjs()
],
external: Object.keys(pkg.dependencies).concat(require('module').builtinModules),
preserveEntrySignatures: 'strict',
onwarn,
},
serviceworker: {
input: config.serviceworker.input(),
output: config.serviceworker.output(),
plugins: [
resolve(),
replace({
'process.browser': true,
'process.env.NODE_ENV': JSON.stringify(mode)
}),
commonjs(),
!dev && terser()
],
preserveEntrySignatures: false,
onwarn,
}
};

306
scripts/setupTypeScript.js Normal file
View File

@ -0,0 +1,306 @@
/**
* Run this script to convert the project to TypeScript. This is only guaranteed to work
* on the unmodified default template; if you have done code changes you are likely need
* to touch up the generated project manually.
*/
// @ts-check
const fs = require('fs');
const path = require('path');
const { argv } = require('process');
const projectRoot = argv[2] || path.join(__dirname, '..');
const isRollup = fs.existsSync(path.join(projectRoot, "rollup.config.js"));
function warn(message) {
console.warn('Warning: ' + message);
}
function replaceInFile(fileName, replacements) {
if (fs.existsSync(fileName)) {
let contents = fs.readFileSync(fileName, 'utf8');
let hadUpdates = false;
replacements.forEach(([from, to]) => {
const newContents = contents.replace(from, to);
const isAlreadyApplied = typeof to !== 'string' || contents.includes(to);
if (newContents !== contents) {
contents = newContents;
hadUpdates = true;
} else if (!isAlreadyApplied) {
warn(`Wanted to update "${from}" in ${fileName}, but did not find it.`);
}
});
if (hadUpdates) {
fs.writeFileSync(fileName, contents);
} else {
console.log(`${fileName} had already been updated.`);
}
} else {
warn(`Wanted to update ${fileName} but the file did not exist.`);
}
}
function createFile(fileName, contents) {
if (fs.existsSync(fileName)) {
warn(`Wanted to create ${fileName}, but it already existed. Leaving existing file.`);
} else {
fs.writeFileSync(fileName, contents);
}
}
function addDepsToPackageJson() {
const pkgJSONPath = path.join(projectRoot, 'package.json');
const packageJSON = JSON.parse(fs.readFileSync(pkgJSONPath, 'utf8'));
packageJSON.devDependencies = Object.assign(packageJSON.devDependencies, {
...(isRollup ? { '@rollup/plugin-typescript': '^6.0.0' } : { 'ts-loader': '^8.0.4' }),
'@tsconfig/svelte': '^1.0.10',
'@types/compression': '^1.7.0',
'@types/node': '^14.11.1',
'@types/polka': '^0.5.1',
'svelte-check': '^1.0.46',
'svelte-preprocess': '^4.3.0',
tslib: '^2.0.1',
typescript: '^4.0.3'
});
// Add script for checking
packageJSON.scripts = Object.assign(packageJSON.scripts, {
validate: 'svelte-check --ignore src/node_modules/@sapper'
});
// Write the package JSON
fs.writeFileSync(pkgJSONPath, JSON.stringify(packageJSON, null, ' '));
}
function changeJsExtensionToTs(dir) {
const elements = fs.readdirSync(dir, { withFileTypes: true });
for (let i = 0; i < elements.length; i++) {
if (elements[i].isDirectory()) {
changeJsExtensionToTs(path.join(dir, elements[i].name));
} else if (elements[i].name.match(/^[^_]((?!json).)*js$/)) {
fs.renameSync(path.join(dir, elements[i].name), path.join(dir, elements[i].name).replace('.js', '.ts'));
}
}
}
function updateSingleSvelteFile({ view, vars, contextModule }) {
replaceInFile(path.join(projectRoot, 'src', `${view}.svelte`), [
[/(?:<script)(( .*?)*?)>/gm, (m, attrs) => `<script${attrs}${!attrs.includes('lang="ts"') ? ' lang="ts"' : ''}>`],
...(vars ? vars.map(({ name, type }) => [`export let ${name};`, `export let ${name}: ${type};`]) : []),
...(contextModule ? contextModule.map(({ js, ts }) => [js, ts]) : [])
]);
}
// Switch the *.svelte file to use TS
function updateSvelteFiles() {
[
{
view: 'components/Nav',
vars: [{ name: 'segment', type: 'string' }]
},
{
view: 'routes/_layout',
vars: [{ name: 'segment', type: 'string' }]
},
{
view: 'routes/_error',
vars: [
{ name: 'status', type: 'number' },
{ name: 'error', type: 'Error' }
]
},
{
view: 'routes/blog/index',
vars: [{ name: 'posts', type: '{ slug: string; title: string, html: any }[]' }],
contextModule: [
{
js: '.then(r => r.json())',
ts: '.then((r: { json: () => any; }) => r.json())'
},
{
js: '.then(posts => {',
ts: '.then((posts: { slug: string; title: string, html: any }[]) => {'
}
]
},
{
view: 'routes/blog/[slug]',
vars: [{ name: 'post', type: '{ slug: string; title: string, html: any }' }]
}
].forEach(updateSingleSvelteFile);
}
function updateRollupConfig() {
// Edit rollup config
replaceInFile(path.join(projectRoot, 'rollup.config.js'), [
// Edit imports
[
/'rollup-plugin-terser';\n(?!import sveltePreprocess)/,
`'rollup-plugin-terser';
import sveltePreprocess from 'svelte-preprocess';
import typescript from '@rollup/plugin-typescript';
`
],
// Edit inputs
[
/(?<!THIS_IS_UNDEFINED[^\n]*\n\s*)onwarn\(warning\);/,
`(warning.code === 'THIS_IS_UNDEFINED') ||\n\tonwarn(warning);`
],
[/input: config.client.input\(\)(?!\.replace)/, `input: config.client.input().replace(/\\.js$/, '.ts')`],
[
/input: config.server.input\(\)(?!\.replace)/,
`input: { server: config.server.input().server.replace(/\\.js$/, ".ts") }`
],
[
/input: config.serviceworker.input\(\)(?!\.replace)/,
`input: config.serviceworker.input().replace(/\\.js$/, '.ts')`
],
// Add preprocess
[/compilerOptions/g, 'preprocess: sveltePreprocess(),\n\t\t\t\tcompilerOptions'],
// Add TypeScript
[/commonjs\(\)(?!,\n\s*typescript)/g, 'commonjs(),\n\t\t\ttypescript({ sourceMap: dev })']
]);
}
function updateWebpackConfig() {
// Edit webpack config
replaceInFile(path.join(projectRoot, 'webpack.config.js'), [
// Edit imports
[
/require\('webpack-modules'\);\n(?!const sveltePreprocess)/,
`require('webpack-modules');\nconst sveltePreprocess = require('svelte-preprocess');\n`
],
// Edit extensions
[
/\['\.mjs', '\.js', '\.json', '\.svelte', '\.html'\]/,
`['.mjs', '.js', '.ts', '.json', '.svelte', '.html']`
],
// Edit entries
[
/entry: config\.client\.entry\(\)/,
`entry: { main: config.client.entry().main.replace(/\\.js$/, '.ts') }`
],
[
/entry: config\.server\.entry\(\)/,
`entry: { server: config.server.entry().server.replace(/\\.js$/, '.ts') }`
],
[
/entry: config\.serviceworker\.entry\(\)/,
`entry: { 'service-worker': config.serviceworker.entry()['service-worker'].replace(/\\.js$/, '.ts') }`
],
// Add preprocess to the svelte config, this is tricky because there's no easy signifier.
// Instead we look for 'hydratable: true,'
[
/hydratable: true(?!,\n\s*preprocess)/g,
'hydratable: true,\n\t\t\t\t\t\t\tpreprocess: sveltePreprocess()'
],
// Add TypeScript rules for client and server
[
/module: {\n\s*rules: \[\n\s*(?!{\n\s*test: \/\\\.ts\$\/)/g,
`module: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader'\n\t\t\t\t},\n\t\t\t\t`
],
// Add TypeScript rules for serviceworker
[
/output: config\.serviceworker\.output\(\),\n\s*(?!module)/,
`output: config.serviceworker.output(),\n\t\tmodule: {\n\t\t\trules: [\n\t\t\t\t{\n\t\t\t\t\ttest: /\\.ts$/,\n\t\t\t\t\tloader: 'ts-loader'\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t`
],
// Edit outputs
[
/output: config\.serviceworker\.output\(\),\n\s*(?!resolve)/,
`output: config.serviceworker.output(),\n\t\tresolve: { extensions: ['.mjs', '.js', '.ts', '.json'] },\n\t\t`
]
]);
}
function updateServiceWorker() {
replaceInFile(path.join(projectRoot, 'src', 'service-worker.ts'), [
[`shell.concat(files);`, `(shell as string[]).concat(files as string[]);`],
[`self.skipWaiting();`, `((self as any) as ServiceWorkerGlobalScope).skipWaiting();`],
[`self.clients.claim();`, `((self as any) as ServiceWorkerGlobalScope).clients.claim();`],
[`fetchAndCache(request)`, `fetchAndCache(request: Request)`],
[`self.addEventListener('activate', event =>`, `self.addEventListener('activate', (event: ExtendableEvent) =>`],
[`self.addEventListener('install', event =>`, `self.addEventListener('install', (event: ExtendableEvent) =>`],
[`addEventListener('fetch', event =>`, `addEventListener('fetch', (event: FetchEvent) =>`],
]);
}
function createTsConfig() {
const tsconfig = `{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"lib": ["DOM", "ES2017", "WebWorker"]
},
"include": ["src/**/*", "src/node_modules/**/*"],
"exclude": ["node_modules/*", "__sapper__/*", "static/*"]
}`;
createFile(path.join(projectRoot, 'tsconfig.json'), tsconfig);
}
// Adds the extension recommendation
function configureVsCode() {
const dir = path.join(projectRoot, '.vscode');
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}
createFile(path.join(projectRoot, '.vscode', 'extensions.json'), `{"recommendations": ["svelte.svelte-vscode"]}`);
}
function deleteThisScript() {
fs.unlinkSync(path.join(__filename));
// Check for Mac's DS_store file, and if it's the only one left remove it
const remainingFiles = fs.readdirSync(path.join(__dirname));
if (remainingFiles.length === 1 && remainingFiles[0] === '.DS_store') {
fs.unlinkSync(path.join(__dirname, '.DS_store'));
}
// Check if the scripts folder is empty
if (fs.readdirSync(path.join(__dirname)).length === 0) {
// Remove the scripts folder
fs.rmdirSync(path.join(__dirname));
}
}
console.log(`Adding TypeScript with ${isRollup ? "Rollup" : "webpack" }...`);
addDepsToPackageJson();
changeJsExtensionToTs(path.join(projectRoot, 'src'));
updateSvelteFiles();
if (isRollup) {
updateRollupConfig();
} else {
updateWebpackConfig();
}
updateServiceWorker();
createTsConfig();
configureVsCode();
// Delete this script, but not during testing
if (!argv[2]) {
deleteThisScript();
}
console.log('Converted to TypeScript.');
if (fs.existsSync(path.join(projectRoot, 'node_modules'))) {
console.log(`
Next:
1. run 'npm install' again to install TypeScript dependencies
2. run 'npm run build' for the @sapper imports in your project to work
`);
}

39
src/ambient.d.ts vendored Normal file
View File

@ -0,0 +1,39 @@
/**
* These declarations tell TypeScript that we allow import of images, e.g.
* ```
<script lang='ts'>
import successkid from 'images/successkid.jpg';
</script>
<img src="{successkid}">
```
*/
declare module "*.gif" {
const value: string;
export = value;
}
declare module "*.jpg" {
const value: string;
export = value;
}
declare module "*.jpeg" {
const value: string;
export = value;
}
declare module "*.png" {
const value: string;
export = value;
}
declare module "*.svg" {
const value: string;
export = value;
}
declare module "*.webp" {
const value: string;
export = value;
}

5
src/client.js Normal file
View File

@ -0,0 +1,5 @@
import * as sapper from '@sapper/app';
sapper.start({
target: document.querySelector('#sapper')
});

25
src/node_modules/components/GalleryImage.svelte generated vendored Normal file
View File

@ -0,0 +1,25 @@
<script>
export let src, alt;
let shown;
function open() {
if(shown) {
window.open(src, "_blank");
}
}
</script>
<div class="gallery__image">
<img {src} {alt} on:click={() => (shown = !shown)} />
<div
class:gallery__popup={true}
class:hidden={!shown}
>
<img {src} {alt} on:click={open} draggable="false" />
<div
class="gallery__exit"
on:click={() => (shown = !shown)}
>x</div>
</div>
</div>

13
src/node_modules/components/GameListItem.svelte generated vendored Normal file
View File

@ -0,0 +1,13 @@
<script>
export let name, link, gameid, playername;
</script>
<div class="media-item">
<div class="media-item__title">
<p class="media-item__caption"><a href={link}>{name}</a></p>
</div>
<div class="media-item__content">
<p>Player Name: {playername}</p>
<p>ID: {gameid}</p>
</div>
</div>

61
src/node_modules/components/Header.svelte generated vendored Normal file
View File

@ -0,0 +1,61 @@
<script>
import NavItem from "./NavItem.svelte";
let menu_shown = false;
let detached = false;
let scrollY = 0;
function handleScroll (e) {
detached = scrollY > 64;
}
</script>
<svelte:window on:scroll={handleScroll} bind:scrollY="{scrollY}" />
<div>
<div class:site-header={true} class:enabled={menu_shown} class:detached>
<div class:site-header__background={true} class:enabled={menu_shown} />
<div class="site-header__inner">
<header class="header">
<div class="header__top">
<div
class="header__nav-button"
on:click={() => (menu_shown = !menu_shown)}
>
<span class="header__icon material-icons" alt="menu"
>menu</span
>
</div>
<div
class="header__title"
on:click={() =>
(menu_shown = menu_shown
? !menu_shown
: menu_shown)}
>
<a href="/"><h1>Damillora</h1></a>
</div>
</div>
<div
class:menu={true}
class:enabled={menu_shown}
on:click={() => (menu_shown = !menu_shown)}
>
<NavItem link="/about" icon="person" text="About" />
<NavItem link="/projects" icon="work" text="Projects" />
<NavItem
link="/games"
icon="videogame_asset"
text="Game Profile"
/>
<NavItem link="/links" icon="share" text="Links" />
<NavItem link="/contact" icon="contacts" text="Contact" />
<NavItem
link="//blog.nanao.moe"
icon="rss_feed"
text="Blog"
/>
</div>
</header>
</div>
</div>
</div>

12
src/node_modules/components/MediaItem.svelte generated vendored Normal file
View File

@ -0,0 +1,12 @@
<script>
export let title, link;
</script>
<div class="media-item">
<div class="media-item__title">
<p class="media-item__caption"><a href={link}>{title}</a></p>
</div>
<div class="media-item__content">
<slot />
</div>
</div>

10
src/node_modules/components/NavItem.svelte generated vendored Normal file
View File

@ -0,0 +1,10 @@
<script>
export let link, text, icon;
</script>
<div class="menu__item">
<a href={link}>
<i class="material-icons md-24">{icon}</i>
<p class="menu__text">{text}</p>
</a>
</div>

13
src/node_modules/components/PageHeader.svelte generated vendored Normal file
View File

@ -0,0 +1,13 @@
<script>
</script>
<div class="page-header">
<div class="page-header__background">
<div class="page-header__overlay" />
</div>
<div class="page-header__contents">
<div class="container mx-auto main">
<slot />
</div>
</div>
</div>

17
src/node_modules/components/ProjectItem.svelte generated vendored Normal file
View File

@ -0,0 +1,17 @@
<script>
export let codename, name, description;
</script>
<div class="project-item">
<div class="project-item__image">
<img src={"/images/projects/" + codename + "/1.png"} alt={name} />
</div>
<div class="project-item__text">
<div class="project-item__title">
<h1><a href={"/projects/" + codename}>{name}</a></h1>
</div>
<div class="project-item__content">
<p>{description}</p>
</div>
</div>
</div>

28
src/routes/_error.svelte Normal file
View File

@ -0,0 +1,28 @@
<script>
import PageHeader from 'components/PageHeader.svelte';
export let status;
export let error;
const dev = process.env.NODE_ENV === 'development';
</script>
<style>
</style>
<svelte:head>
<title>{status}</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>{status}</h1>
<p>{error.message}</p>
</PageHeader>
{#if dev && error.stack}
<pre>{error.stack}</pre>
{/if}
</div>

12
src/routes/_layout.svelte Normal file
View File

@ -0,0 +1,12 @@
<script>
import Header from 'components/Header.svelte';
</script>
<style lang="scss" global>
@import '../style/app.scss';
</style>
<Header></Header>
<main>
<slot></slot>
</main>

28
src/routes/about.svelte Normal file
View File

@ -0,0 +1,28 @@
<script>
import PageHeader from "components/PageHeader.svelte";
import GalleryImage from "components/GalleryImage.svelte";
</script>
<svelte:head>
<title>Damillora: About</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>About Damillora</h1>
</PageHeader>
<main class="container main">
<p>Hello! My name is Damillora.</p>
<p>
I'm currently reconstructing my about page for new things, but I'm a
web developer, rhythm game player and music enthusiast!
</p>
<h2>GPG public key</h2>
<p>My public key is accessible <a href="/damillora.asc">here</a>.</p>
<h2>Producer Meishi</h2>
<div class="gallery">
<GalleryImage src="/images/meishi/front.png" alt="Meishi front"/>
<GalleryImage src="/images/meishi/back.png" alt="Meishi back"/>
</div>
</main>
</div>

80
src/routes/contact.svelte Normal file
View File

@ -0,0 +1,80 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Contact</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>Contact</h1>
</PageHeader>
<main class="container mx-auto main">
<p>You can contact me via various channels.</p>
<h2>Common channels</h2>
<p>
Those are the ones I use for interacting with the wider community!
</p>
<ul>
<li>
<p>Email</p>
<p>damillora(at)damillora.com</p>
</li>
<li>
<p>Twitter:</p>
<p><a href="/twitter">Damillora</a></p>
</li>
</ul>
<h2>Publishing media</h2>
<p>I publish content mainly in those sites</p>
<ul>
<li>
<p>YouTube:</p>
<p><a href="/channel">Damillora</a></p>
</li>
<li>
<p>Twitch:</p>
<p><a href="/twitch">Damillora</a></p>
</li>
<li>
<p>SoundCloud:</p>
<p><a href="/soundcloud">damillora</a></p>
</li>
<li>
<p>GitHub:</p>
<p><a href="/github">Damillora</a></p>
</li>
</ul>
<h2>Alternative technologies</h2>
<p>
Mainstream platforms control what you can post, and you can lose
access to data rightfully yours.
<br />
I maintain presence in several altenative platforms and technologies
to ensure I have control of data I post, to contribute to a possible
future, and as a backup when mainstream platforms go down.
<br />
If you have a presence in those platforms, I encourage you to use these
instead, you will help the adoption of those technologies!
</p>
<ul>
<li>
<p>Fediverse:</p>
<p><a href="/fediverse">Damillora@fed.nanao.moe</a></p>
</li>
<li>
<p>Video Channel:</p>
<p><a href="/fedichan">damillora@live.nanao.moe</a></p>
</li>
<li>
<p>Matrix</p>
<p>@damillora:matrix.nanao.moe</p>
</li>
<li>
<p>Gemini</p>
<p><a href="gemini://gemini.nanao.moe">gemini.nanao.moe</a></p>
</li>
</ul>
</main>
</div>

View File

@ -0,0 +1,24 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader imageType="cue-mei2">
<h1 class="title">Game Profile: ARGONAVIS from BanG Dream! AAside</h1>
<p><a href="https://aaside.bushimo.jp">Game Website</a></p>
</PageHeader>
<main class="container main">
<h2>My Review</h2>
<blockquote>
My take on it? Give it some time. AAside is actually quite
aesthetically polished, it has stand-out features, and the rhythm
gameplay is okay. However, there are definitely valid concerns and
missing features that I understand can be a game-breaker for some.
</blockquote>
<p><a href="https://blog.nanao.moe/game-reviews/argonavis-from-bang-dream-aaside/">Read more</a></p>
</main>
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Arcaea</h1>
<p><a href="https://arcaea.lowiro.com">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,27 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Arknights</h1>
<p><a href="https://www.arknights.global">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main">
<h2>My Review</h2>
<blockquote>
The strength of this game is in its complexities, getting you
invested into the game. If you like tower defenses and also like to
think about tactics and strategies, this game is for you.
</blockquote>
<p>
<a href="https://blog.nanao.moe/game-reviews/arknights/"
>Read more</a
>
</p>
</main>
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Azur Lane (EN)</h1>
<p><a href="https://azurlane.yo-star.com">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: BanG Dream! Girls Band Party (JP)</h1>
<p><a href="https://bang-dream.bushimo.jp/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,46 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: CUE!</h1>
<p><a href="https://www.cue-liber.jp/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main">
<h2>My Review</h2>
<h3>One Year of CUE!</h3>
<blockquote>
Overall, since the game was released, CUE! has improved a lot, with
some areas receiving a welcome UX improvement, convenience features
that make CUE!'s idle aspect not feel like wasting time, and an
entirely new mode for those who want something that feels more like
actual gameplay. Here's to hoping that CUE! will continue to improve
and move forward.
<br /><br />
For those who haven't played CUE! yet, there's no better time than now!
It's one of the games that will take just a little bit of your time.
It also requires no significant time investments for those who doesn't
play to rank in events or Compe, so adding CUE! to your daily tasks list
doesn't hurt. As with my first review, I recommend to try it out, you
will appreciate it.
</blockquote>
<p>
<a href="https://blog.nanao.moe/game-reviews/one-year-of-cue/"
>Read more</a
>
</p>
<h3>Original Release Date Review</h3>
<blockquote>
Despite the similarities and the amount of grinding, CUE! manages to
stand out for me. I recommend to try it sometimes, and get to the
point where you can change casts in the anime. You will appreciate
it.
</blockquote>
<p><a href="https://blog.nanao.moe/game-reviews/cue/">Read more</a></p>
</main>
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Fate/Grand Order (JP)</h1>
<p><a href="https://www.fate-go.jp">Game Website</a></p>
</PageHeader>
<main class="container main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Genshin Impact</h1>
<p><a href="https://genshin.mihoyo.com">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Honkai Impact 3rd</h1>
<p><a href="https://honkaiimpact3.mihoyo.com">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,161 @@
<script>
import PageHeader from "components/PageHeader.svelte";
import GameListItem from "components/GameListItem.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile</h1>
</PageHeader>
<main class="container mx-auto main">
<p>
I play arcade and mobile games mostly, not all are recorded /
streamed.
</p>
<p>
My most frequently played genre is rhythm games, but sometimes I try
other genres too
</p>
<h2>Game IDs</h2>
<div class="card-list">
<GameListItem
name="SOUND VOLTEX VIVID WAVE"
link="/games/sdvx"
playername="YUIKA283"
gameid="SV-6457-6694"
/>
<GameListItem
name="maimai DX"
link="/games/maimai"
playername="YUIKA283"
gameid="6027059823123"
/>
<GameListItem
name="The IDOLM@STER Million Live: Theater Days"
link="/games/mirishita"
playername="Damillora"
gameid="CGTEDUQ4"
/>
<GameListItem
name="Arcaea"
link="/games/arcaea"
playername="Damillora"
gameid="264202217"
/>
<GameListItem
name="Tokyo 7th Sisters"
link="/games/t7s"
playername="Damillora"
gameid="M2mXkWk"
/>
<GameListItem
name="BanG Dream! Girls Band Party (JP)"
link="/games/bandori"
playername="Damillora"
gameid="106205253"
/>
<GameListItem
name="Love Live! School Idol Festival (JP)"
link="/games/llsif"
playername="Damillora"
gameid="755897396"
/>
<GameListItem
name="Revue Starlight Re LIVE (EN)"
link="/games/starira"
playername="[RS]Damillora"
gameid="2490812618"
/>
<GameListItem
name="Shadowverse"
link="/games/shadowverse"
playername="Damillora"
gameid="778908673"
/>
<GameListItem
name="Nogikoi"
link="/games/nogikoi"
playername="-"
gameid="1673068678"
/>
<GameListItem
name="THE IDOLM@STER: Shiny Colors"
link="/games/shinymas"
playername="Damillora"
gameid="ePmtJyTwzn"
/>
<GameListItem
name="欅坂46・日向坂46 UNI'S ON AIR"
link="games/unison"
playername="Damillora"
gameid="y2medy4d"
/>
<GameListItem
name="CUE!"
link="/games/cue"
playername="Damillora"
gameid="37132287893"
/>
<GameListItem
name="Love Live! School idol festival ALL STARS"
link="/games/llsifas"
playername="-"
gameid="-"
/>
<GameListItem
name="Arknights"
link="/games/arknights"
playername="Damillora"
gameid="Damillora#0835"
/>
<GameListItem
name="Azur Lane (EN)"
link="/games/azurlane"
playername="Damillora"
gameid="204960914"
/>
<GameListItem
name="Fate/Grand Order (JP)"
link="/games/fgo"
playername="Damillora"
gameid="744497723"
/>
<GameListItem
name="Project SEKAI COLORFUL STAGE"
link="/games/puroseka"
playername="Damillora"
gameid="5121608293470214"
/>
<GameListItem
name="Honkai Impact 3rd"
link="/games/honkai"
playername="Damillora"
gameid="17918429"
/>
<GameListItem
name="Genshin Impact"
link="/games/genshin"
playername="Damillora"
gameid="804547223"
/>
<GameListItem
name="ARGONAVIS from BanG Dream! AAside"
link="/games/aaside"
playername="Damilora"
gameid="3BUWJibt"
/>
<!--
<GameListItem
name=""
link=""
playername=""
gameid=""
/>
-->
</div>
</main>
</div>

View File

@ -0,0 +1,17 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">
Game Profile: Love Live! School Idol Festival (JP)
</h1>
<p><a href="https://lovelive-sif.bushimo.jp/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,17 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">
Game Profile: Love Live! School idol festival ALL STARS
</h1>
<p><a href="https://lovelive-as.bushimo.jp/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: maimai DX</h1>
<p><a href="https://maimai.sega.com/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,21 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">
Game Profile: The IDOLM@STER Million Live: Theater Days
</h1>
<p>
<a href="https://millionlive.idolmaster.jp/theaterdays/"
>Game Website</a
>
</p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Nogikoi</h1>
<p><a href="https://nogikoi.jp">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,29 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Project SEKAI COLORFUL STAGE!</h1>
<p><a href="https://pjsekai.sega.jp/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main">
<h2>My Review</h2>
<blockquote>
Overall, I've gotten what I wanted to see in a mobile rhythm game.
Virtual Lives are also very interesting with many possibilities that
can happen. The other aspects are cherry on top, and they're also
not bad too. Project SEKAI is great.
</blockquote>
<p>
<a
href="https://blog.nanao.moe/game-reviews/project-sekai-colorful-stage/"
>Read more</a
>
</p>
</main>
</div>

View File

@ -0,0 +1,19 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: SOUND VOLTEX VIVID WAVE</h1>
<p>
<a href="https://p.eagate.573.jp/game/sdvx/v/p/index.html"
>Game Website</a
>
</p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Shadowverse</h1>
<p><a href="https://shadowverse.com/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: THE IDOLM@STER: Shiny Colors</h1>
<p><a href="https://shinycolors.idolmaster.jp">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,17 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Revue Starlight Re LIVE (EN)</h1>
<p>
<a href="https://www.en.revuestarlight-relive.com/">Game Website</a>
</p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,15 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: Tokyo 7th Sisters</h1>
<p><a href="https://t7s.jp">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main" />
</div>

View File

@ -0,0 +1,19 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile:</h1>
<p><a href="/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main">
<h2>My Review</h2>
<blockquote />
<p><a href="/">Read more</a></p>
</main>
</div>

View File

@ -0,0 +1,27 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora: Game Profile</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1 class="title">Game Profile: 欅坂46・日向坂46 UNI'S ON AIR</h1>
<p><a href="https://keyahina-unisonair.com/">Game Website</a></p>
</PageHeader>
<main class="container mx-auto main">
<h2>My Review</h2>
<blockquote>
Suffice to say, I enjoy this game more than Nogizaka46's rhythm
game, which requires memorization of songs a bit too much.
</blockquote>
<p>
<a
href="https://blog.nanao.moe/game-reviews/keyakizaka46-hinatazaka46-unis-on-air/"
>Read more</a
>
</p>
</main>
</div>

16
src/routes/index.svelte Normal file
View File

@ -0,0 +1,16 @@
<script>
import PageHeader from "components/PageHeader.svelte";
</script>
<svelte:head>
<title>Damillora</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>Damillora</h1>
<p>A curious technologist, a web programmer, and a future EN Vtuber</p>
<p>EN/ID OK, JP read only</p>
</PageHeader>
<main class="container main" />
</div>

30
src/routes/links.svelte Normal file
View File

@ -0,0 +1,30 @@
<script>
import PageHeader from "components/PageHeader.svelte";
import MediaItem from "components/MediaItem.svelte";
</script>
<svelte:head>
<title>Damillora: Links</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>Links</h1>
</PageHeader>
<main class="container mx-auto main">
<p>
Here, I post links that is of my interest, and might be for you too!
</p>
<div class="card-list">
<MediaItem
title="Damillora's Favorite Music Playlist"
link="/favmusiclist"
>
<p>
This playlist contains some of the music I listen to
frequently.
</p>
</MediaItem>
</div>
</main>
</div>

View File

@ -0,0 +1,41 @@
<script>
import PageHeader from 'components/PageHeader.svelte';
import GalleryImage from 'components/GalleryImage.svelte';
</script>
<svelte:head>
<title>Damillora: Altessimo</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>Altessimo</h1>
<p>
<a href="https://altessimo.nanao.moe">live</a>
&bull;
<a href="https://github.com/Damillora/Altessimo">source code</a>
</p>
</PageHeader>
<main class="container mx-auto main">
<h2>Description</h2>
<p>
Altessimo is a web application I built to catalogue and put in context Idolmaster lyricists, composers, and arrangers.
</p>
<p>
The database itself is definitely still a work-in-progress.
</p>
<h2>Technologies</h2>
<ul>
<li>Django</li>
<li>Bootstrap</li>
</ul>
<h2>Screenshots</h2>
<div class="gallery">
<GalleryImage src="/images/projects/altessimo/1.png" />
<GalleryImage src="/images/projects/altessimo/2.png" />
<GalleryImage src="/images/projects/altessimo/3.png" />
<GalleryImage src="/images/projects/altessimo/4.png" />
</div>
</main>
</div>

View File

@ -0,0 +1,42 @@
<script>
import PageHeader from "components/PageHeader.svelte";
import ProjectItem from "components/ProjectItem.svelte";
</script>
<svelte:head>
<title>Project Portfolio</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>Project Portfolio</h1>
</PageHeader>
<main class="container mx-auto main">
<p>
I build applications in my spare time, but currently only some are
published / live right now
</p>
<div class="card-list">
<ProjectItem
name="nanao.moe"
codename="rinze"
description="The home page for my online identity"
/>
<ProjectItem
name="nanao.moe (legacy)"
codename="miracle"
description="Former codebase of nanao.moe"
/>
<ProjectItem
name="Damillora's Virtual Memoir"
codename="yuika"
description="The blog for my hobbies"
/>
<ProjectItem
name="Altessimo"
codename="altessimo"
description="Web database of Idolmaster composers"
/>
</div>
</main>
</div>

View File

@ -0,0 +1,42 @@
<script>
import PageHeader from "components/PageHeader.svelte";
import GalleryImage from "components/GalleryImage.svelte";
</script>
<svelte:head>
<title>Damillora: nanao.moe (legacy)</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>nanao.moe (legacy)</h1>
<p>
<a href="https://nanao.moe">former live</a>
&bull;
<a href="https://github.com/Damillora/miracle">source code</a>
</p>
</PageHeader>
<main class="container main">
<h2>Description</h2>
<p>
A domain carves a person's place in the Internet. This is the
codebase that formerly serves nanao.moe. It is named miracle, which
is named after a Madeon song (Good Faith is great, btw).
</p>
<p>
Originally, it is styled in pure CSS. However, it later used
Tailwind.
</p>
<h2>Technologies</h2>
<ul>
<li>Vue.js</li>
<li>Nuxt.js</li>
<li>Tailwind CSS</li>
</ul>
<h2>Screenshots</h2>
<div class="gallery">
<GalleryImage src="/images/projects/miracle/1.png" />
<GalleryImage src="/images/projects/miracle/2.png" />
</div>
</main>
</div>

View File

@ -0,0 +1,42 @@
<script>
import PageHeader from 'components/PageHeader.svelte';
import GalleryImage from 'components/GalleryImage.svelte';
</script>
<svelte:head>
<title>Damillora: nanao.moe</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>nanao.moe</h1>
<p>
<a href="https://nanao.moe">live</a>
&bull;
<a href="https://github.com/Damillora/rinze">source code</a>
</p>
</PageHeader>
<main class="container main">
<h2>Description</h2>
<p>
A domain carves a person's place in the Internet. nanao.moe now
serves as my primary web page. The website contains information
about my projects and interests.
</p>
<p>
The new codebase uses the same design as previous.
However, it adopts new technologies and rewrites the stylesheet in SASS.
</p>
<h2>Technologies</h2>
<ul>
<li>Svelte</li>
<li>Sapper</li>
<li>SASS</li>
</ul>
<h2>Screenshots</h2>
<div class="gallery">
<GalleryImage src="/images/projects/rinze/1.png" />
<GalleryImage src="/images/projects/miracle/2.png" />
</div>
</main>
</div>

View File

@ -0,0 +1,44 @@
<script>
import PageHeader from 'components/PageHeader.svelte';
import GalleryImage from 'components/GalleryImage.svelte';
</script>
<svelte:head>
<title>Damillora: Damillora's Virtual Memoir</title>
</svelte:head>
<div class="page">
<PageHeader>
<h1>Damillora's Virtual Memoir</h1>
<p>
<a href="https://blog.nanao.moe">live</a>
&bull;
<a href="https://github.com/Damillora/Yuika">source code</a>
</p>
</PageHeader>
<main class="container mx-auto main">
<h2>Description</h2>
<p>
Damillora's Virtual Memoir is my hobby-related blog, writing about games and idols.
</p>
<p>
The blog runs on Ghost, a publication-focused CMS, while the theme uses Tailwind CSS for its CSS framework.
</p>
<h2>Technologies</h2>
<ul>
<li>Ghost</li>
<li>Tailwind CSS</li>
<li>jQuery</li>
</ul>
<h2>Screenshots</h2>
<div class="gallery">
<GalleryImage src="/images/projects/yuika/1.png" />
<GalleryImage src="/images/projects/yuika/2.png" />
<GalleryImage src="/images/projects/yuika/3.png" />
<GalleryImage src="/images/projects/yuika/4.png" />
<GalleryImage src="/images/projects/yuika/5.png" />
<GalleryImage src="/images/projects/yuika/6.png" />
</div>
</main>
</div>

17
src/server.js Normal file
View File

@ -0,0 +1,17 @@
import sirv from 'sirv';
import polka from 'polka';
import compression from 'compression';
import * as sapper from '@sapper/server';
const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';
polka() // You can also use Express
.use(
compression({ threshold: 0 }),
sirv('static', { dev }),
sapper.middleware()
)
.listen(PORT, err => {
if (err) console.log('error', err);
});

86
src/service-worker.js Normal file
View File

@ -0,0 +1,86 @@
import { timestamp, files, shell } from '@sapper/service-worker';
const ASSETS = `cache${timestamp}`;
// `shell` is an array of all the files generated by the bundler,
// `files` is an array of everything in the `static` directory
const to_cache = shell.concat(files);
const staticAssets = new Set(to_cache);
self.addEventListener('install', event => {
event.waitUntil(
caches
.open(ASSETS)
.then(cache => cache.addAll(to_cache))
.then(() => {
self.skipWaiting();
})
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(async keys => {
// delete old caches
for (const key of keys) {
if (key !== ASSETS) await caches.delete(key);
}
self.clients.claim();
})
);
});
/**
* Fetch the asset from the network and store it in the cache.
* Fall back to the cache if the user is offline.
*/
async function fetchAndCache(request) {
const cache = await caches.open(`offline${timestamp}`)
try {
const response = await fetch(request);
cache.put(request, response.clone());
return response;
} catch (err) {
const response = await cache.match(request);
if (response) return response;
throw err;
}
}
self.addEventListener('fetch', event => {
if (event.request.method !== 'GET' || event.request.headers.has('range')) return;
const url = new URL(event.request.url);
// don't try to handle e.g. data: URIs
const isHttp = url.protocol.startsWith('http');
const isDevServerRequest = url.hostname === self.location.hostname && url.port !== self.location.port;
const isStaticAsset = url.host === self.location.host && staticAssets.has(url.pathname);
const skipBecauseUncached = event.request.cache === 'only-if-cached' && !isStaticAsset;
if (isHttp && !isDevServerRequest && !skipBecauseUncached) {
event.respondWith(
(async () => {
// always serve static files and bundler-generated assets from cache.
// if your application has other URLs with data that will never change,
// set this variable to true for them and they will only be fetched once.
const cachedAsset = isStaticAsset && await caches.match(event.request);
// for pages, you might want to serve a shell `service-worker-index.html` file,
// which Sapper has generated for you. It's not right for every
// app, but if it's right for yours then uncomment this section
/*
if (!cachedAsset && url.origin === self.origin && routes.find(route => route.pattern.test(url.pathname))) {
return caches.match('/service-worker-index.html');
}
*/
return cachedAsset || fetchAndCache(event.request);
})()
);
}
});

15
src/style/app.scss Normal file
View File

@ -0,0 +1,15 @@
@import './utilities/normalize';
@import './utilities/responsive';
@import './utilities/transition';
@import './utilities/spacing';
@import './utilities/backgrounds/283-yuika';
@import './common/theme';
@import './common/base';
@import './components/pageheader';
@import './components/header';
@import './components/menu';
@import './components/gallery';
@import './components/mediaitem';
@import './components/projectitem';

View File

@ -0,0 +1,87 @@
html {
font-family: 'Exo 2',-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
}
.main {
padding: 1rem;
@include screen(md) {
@include px(2rem);
}
@include screen(lg) {
@include px(4rem);
}
@include screen(xl) {
@include px(4rem);
}
}
.page {
width: 100%;
}
.main {
margin-left: auto;
margin-right: auto;
p, h1, h2, h3, h4, h5, h6 {
@include my(1rem);
}
h1, h2, h3, h4, h5, h6 {
font-weight: 300;
}
h1 {
font-size: $text-4xl;
}
h2 {
font-size: $text-3xl;
}
h3 {
font-size: $text-2xl;
}
h4 {
font-size: $text-xl;
}
h5 {
font-size: $text-lg;
}
h6 {
font-size: $text-base;
}
a {
color: $accent-primary;
&:hover {
text-decoration: underline;
}
}
ul {
list-style-type: disc;
li p {
@include my(0rem);
}
}
ol {
list-style-type: decimal;
}
code {
background-color: $bg-primary;
color: $accent-primary;
white-space: pre-wrap;
}
blockquote {
border-left: 0.5rem solid $accent-primary;
@include my(2rem);
padding: 0.5rem 0 0.5rem 2rem;
}
pre {
background: $bg-primary;
color: $accent-primary;
padding: 0.5rem;
border: 1px solid $accent-primary;
}
}
.card-list {
display: flex;
flex-direction: column;
}

View File

@ -0,0 +1,20 @@
$text-4xl: 2.25rem;
$text-3xl: 1.875rem;
$text-2xl: 1.5rem;
$text-xl: 1.25rem;
$text-lg: 1.125rem;
$text-base: 1rem;
$text-sm: 0.875rem;
$text-xs: 0.75rem;
$font-light: 300;
$font-base: 400;
$font-medium: 500;
$white: #FFFFFF;
$black: #000000;
$accent-primary: #22558C;
$bg-primary: #E5E7EB;
$bg-secondary: #9FD3F0;

View File

@ -0,0 +1,51 @@
.gallery {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
&__image {
width: 100%;
padding: 1rem;
}
&__popup {
position: fixed;
height: 100vh;
width: 100vw;
visibility: visible;
@include transition;
left: 0;
top: 0;
padding: 4rem;
z-index: 20;
background-color: rgba(0,0,0,0.7);
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
&.hidden {
height: 0;
opacity: 0;
visibility: hidden;
}
img {
max-height: 100%;
}
}
&__exit {
position: fixed;
right: 0;
top: 0;
margin: 1rem 2rem;
font-size: $text-2xl;
color: $white;
z-index: 30;
cursor: pointer;
}
}

View File

@ -0,0 +1,96 @@
.site-header {
position: fixed;
z-index: 10;
height: 4rem;
width: 100vw;
overflow: hidden;
@include transition;
&.enabled {
height: 100vh;
width: 100vw;
}
&__background {
z-index: -1;
width: 100vw;
height: 100vh;
position: absolute;
@include transition;
@include bg-283-yuika;
opacity: 0%;
top: -23vh;
&.enabled {
opacity: 100%;
top: 0;
}
}
&__overlay {
opacity: 50%;
background-color: $black;
}
&__inner {
z-index: 1;
width: 100%;
height: 100%;
@include transition;
}
&.enabled &__inner {
background: rgba(0,0,0,0.5);
}
&.detached &__inner {
background: rgba(0,0,0,0.5);
}
}
.header {
display: flex;
flex-direction: column;
@include transition;
&__top {
display: flex;
flex-direction: row;
}
&__title {
flex-grow: 1;
@include transition;
a {
display: flex;
flex-direction: row;
align-items: center;
@include py(1rem);
color: $white;
font-size: $text-lg;
padding-left: 1rem;
height: 100%;
}
&:hover {
background-color: $accent-primary;
}
}
&__nav-button {
width: 4rem;
height: 4rem;
position: relative;
cursor: pointer;
padding: 0.5rem;
text-align: center;
white-space: nowrap;
@include transition;
&:hover {
background-color: $accent-primary;
}
}
&__icon {
width: 3rem;
height: 3rem;
color: $white;
@include px(0.50rem);
@include py(0.75rem);
}
}

View File

@ -0,0 +1,24 @@
.media-item {
padding: 0.25rem 1rem;
width: 100%;
@include transition;
&:hover {
background-color: $bg-secondary;
}
&__caption {
font-size: $text-2xl;
@include my(0.25rem);
}
&__content {
width: 100%;
@include my(0.5rem);
display: block;
p {
@include my(0.25rem);
}
}
}

View File

@ -0,0 +1,39 @@
.menu {
max-height: 0px;
display: block;
@include transition;
overflow: hidden;
margin-left: 4rem;
&.enabled {
max-height: 100vh;
}
&__item {
color: $white;
height: 3rem;
display: flex;
flex-direction: row;
align-items: center;
@include transition;
&:hover {
background-color: $accent-primary;
}
a {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
height: 100%;
i {
@include px(1rem);
}
p {
display: inline-block;
flex-grow: 1;
}
}
}
}

View File

@ -0,0 +1,34 @@
.page-header {
position: relative;
width: 100%;
min-height: 200px;
height: 70vh;
color: $white;
font-weight: 300;
min-height: 300px;
height: 70vh;
&__background {
width: 100%;
height: 100%;
@include bg-283-yuika;
}
&__overlay {
width: 100%;
height: 100%;
background-color: $black;
opacity: 50%;
}
&__contents {
position: absolute;
bottom: 0;
left: 0;
right: 0;
@include py(0.5rem);
a {
color: $white;
}
}
}

View File

@ -0,0 +1,25 @@
.project-item {
padding: 1rem;
width: 100%;
display: flex;
flex-direction: row;
@include transition;
min-height: 12rem;
&:hover {
background-color: $bg-secondary;
}
&__image {
width: 25%;
display: flex;
flex-direction: col;
align-items: center;
justify-content: center;
margin-right: 2rem;
}
&__text {
width: 75%;
}
}

View File

@ -0,0 +1,537 @@
/*! modern-normalize v1.0.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
/*
Document
========
*/
/**
Use a better box model (opinionated).
*/
*,
*::before,
*::after {
box-sizing: border-box;
}
/**
Use a more readable tab size (opinionated).
*/
:root {
-moz-tab-size: 4;
tab-size: 4;
}
/**
1. Correct the line height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/*
Sections
========
*/
/**
Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
*/
body {
font-family:
system-ui,
-apple-system, /* Firefox supports this but not yet `system-ui` */
'Segoe UI',
Roboto,
Helvetica,
Arial,
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji';
}
/*
Grouping content
================
*/
/**
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
*/
hr {
height: 0; /* 1 */
color: inherit; /* 2 */
}
/*
Text-level semantics
====================
*/
/**
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr[title] {
-webkit-text-decoration: underline dotted;
text-decoration: underline dotted;
}
/**
Add the correct font weight in Edge and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
2. Correct the odd 'em' font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-family:
ui-monospace,
SFMono-Regular,
Consolas,
'Liberation Mono',
Menlo,
monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
Tabular data
============
*/
/**
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
*/
table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
}
/*
Forms
=====
*/
/**
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
Remove the inheritance of text transform in Edge and Firefox.
1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type='button'],
[type='reset'],
[type='submit'] {
-webkit-appearance: button;
}
/**
Remove the inner border and padding in Firefox.
*/
::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
Restore the focus styles unset by the previous rule.
*/
:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
Remove the additional ':invalid' styles in Firefox.
See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737
*/
:-moz-ui-invalid {
box-shadow: none;
}
/**
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
*/
legend {
padding: 0;
}
/**
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/**
Correct the cursor style of increment and decrement buttons in Safari.
*/
::-webkit-inner-spin-button,
::-webkit-outer-spin-button {
height: auto;
}
/**
1. Correct the odd appearance in Chrome and Safari.
2. Correct the outline style in Safari.
*/
[type='search'] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
Remove the inner padding in Chrome and Safari on macOS.
*/
::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
1. Correct the inability to style clickable types in iOS and Safari.
2. Change font properties to 'inherit' in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/*
Interactive
===========
*/
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}
/**
* Manually forked from SUIT CSS Base: https://github.com/suitcss/base
* A thin layer on top of normalize.css that provides a starting point more
* suitable for web applications.
*/
/**
* Removes the default spacing and border for appropriate elements.
*/
blockquote,
dl,
dd,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
figure,
p,
pre {
margin: 0;
}
button {
background-color: transparent;
background-image: none;
}
/**
* Work around a Firefox/IE bug where the transparent `button` background
* results in a loss of the default `button` focus styles.
*/
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
fieldset {
margin: 0;
padding: 0;
}
ol,
ul {
list-style: none;
margin: 0;
padding: 0;
}
/**
* Tailwind custom reset styles
*/
/**
* 1. Use the user's configured `sans` font-family (with Tailwind's default
* sans-serif font stack as a fallback) as a sane default.
* 2. Use Tailwind's default "normal" line-height so the user isn't forced
* to override it to ensure consistency even when using the default theme.
*/
html {
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; /* 1 */
line-height: 1.5; /* 2 */
}
/**
* Inherit font-family and line-height from `html` so users can set them as
* a class directly on the `html` element.
*/
body {
font-family: inherit;
line-height: inherit;
}
/**
* 1. Prevent padding and border from affecting element width.
*
* We used to set this in the html element and inherit from
* the parent element for everything else. This caused issues
* in shadow-dom-enhanced elements like <details> where the content
* is wrapped by a div with box-sizing set to `content-box`.
*
* https://github.com/mozdevs/cssremedy/issues/4
*
*
* 2. Allow adding a border to an element by just adding a border-width.
*
* By default, the way the browser specifies that an element should have no
* border is by setting it's border-style to `none` in the user-agent
* stylesheet.
*
* In order to easily add borders to elements by just setting the `border-width`
* property, we change the default border-style for all elements to `solid`, and
* use border-width to hide them instead. This way our `border` utilities only
* need to set the `border-width` property instead of the entire `border`
* shorthand, making our border utilities much more straightforward to compose.
*
* https://github.com/tailwindcss/tailwindcss/pull/116
*/
*,
::before,
::after {
box-sizing: border-box; /* 1 */
border-width: 0; /* 2 */
border-style: solid; /* 2 */
border-color: #e5e7eb; /* 2 */
}
/*
* Ensure horizontal rules are visible by default
*/
hr {
border-top-width: 1px;
}
/**
* Undo the `border-style: none` reset that Normalize applies to images so that
* our `border-{width}` utilities have the expected effect.
*
* The Normalize reset is unnecessary for us since we default the border-width
* to 0 on all elements.
*
* https://github.com/tailwindcss/tailwindcss/issues/362
*/
img {
border-style: solid;
}
textarea {
resize: vertical;
}
input::placeholder,
textarea::placeholder {
color: #9ca3af;
}
button,
[role="button"] {
cursor: pointer;
}
table {
border-collapse: collapse;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: inherit;
font-weight: inherit;
}
/**
* Reset links to optimize for opt-in styling instead of
* opt-out.
*/
a {
color: inherit;
text-decoration: inherit;
}
/**
* Reset form element properties that are easy to forget to
* style explicitly so you don't inadvertently introduce
* styles that deviate from your design system. These styles
* supplement a partial reset that is already applied by
* normalize.css.
*/
button,
input,
optgroup,
select,
textarea {
padding: 0;
line-height: inherit;
color: inherit;
}
/**
* Use the configured 'mono' font family for elements that
* are expected to be rendered with a monospace font, falling
* back to the system monospace stack if there is no configured
* 'mono' font family.
*/
pre,
code,
kbd,
samp {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}
/**
* Make replaced elements `display: block` by default as that's
* the behavior you want almost all of the time. Inspired by
* CSS Remedy, with `svg` added as well.
*
* https://github.com/mozdevs/cssremedy/issues/14
*/
img,
svg,
video,
canvas,
audio,
iframe,
embed,
object {
display: block;
}
/**
* Constrain images and videos to the parent width and preserve
* their instrinsic aspect ratio.
*
* https://github.com/mozdevs/cssremedy/issues/14
*/
img,
video {
max-width: 100%;
height: auto;
}

View File

@ -0,0 +1,14 @@
@mixin screen($point) {
@if $point == xl {
@media screen and (min-width: 1280px) { @content ; }
}
@else if $point == lg {
@media (min-width: 1024px) { @content ; }
}
@else if $point == md {
@media (min-width: 768px) { @content ; }
}
@else if $point == sm {
@media (min-width: 640px) { @content ; }
}
}

View File

@ -0,0 +1,35 @@
@mixin px($size) {
padding-left: $size;
padding-right: $size;
}
@mixin py($size) {
padding-top: $size;
padding-bottom: $size;
}
@mixin mx($size) {
margin-left: $size;
margin-right: $size;
}
@mixin my($size) {
margin-top: $size;
margin-bottom: $size;
}
.container {
width: 100%;
@include screen(sm) {
max-width: 640px;
}
@include screen(md) {
max-width: 768px;
}
@include screen(lg) {
max-width: 1024px;
}
@include screen(xl) {
max-width: 1280px;
}
}

View File

@ -0,0 +1,5 @@
@mixin transition {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 300ms;
transition-property: all;
}

View File

@ -0,0 +1,17 @@
@mixin bg-283-yuika() {
background-image: url('/images/bg/283-yuika/bg-sm.jpg');
background-size: cover;
background-position: right 25% top 20%;
@include screen(sm) {
background-image: url('/images/bg/283-yuika/bg-md.jpg');
}
@include screen(md) {
background-image: url('/images/bg/283-yuika/bg-lg.jpg');
}
@include screen(lg) {
background-image: url('/images/bg/283-yuika/bg-xl.jpg');
}
@include screen(xl) {
background-image: url('/images/bg/283-yuika/bg-xxl.jpg')
}
}

37
src/template.html Normal file
View File

@ -0,0 +1,37 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="theme-color" content="#333333">
%sapper.base%
<link rel="manifest" href="manifest.json" crossorigin="use-credentials">
<link rel="icon" type="image/png" href="favicon.png">
<link rel="prefetch" href="https://fonts.googleapis.com/css?family=Exo+2:300,400,500&display=swap">
<link rel="prefetch" href="https://fonts.googleapis.com/css?family=M+PLUS+1p:300,400,500&display=swap">
<link rel="prefetch" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Exo+2:300,400,500&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=M+PLUS+1p:300,400,500&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<!-- Sapper creates a <script> tag containing `src/client.js`
and anything else it needs to hydrate the app and
initialise the router -->
%sapper.scripts%
<!-- Sapper generates a <style> tag containing critical CSS
for the current page. CSS for the rest of the app is
lazily loaded when it precaches secondary pages -->
%sapper.styles%
<!-- This contains the contents of the <svelte:head> component, if
the current page has one -->
%sapper.head%
</head>
<body>
<!-- The application will be rendered inside this element,
because `src/client.js` references it -->
<div id="sapper">%sapper.html%</div>
</body>
</html>

BIN
static/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

1
static/images Submodule

@ -0,0 +1 @@
Subproject commit 505b3b835776802b7f940cd5dbc47b34340eecf7

BIN
static/logo-192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
static/logo-512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

20
static/manifest.json Normal file
View File

@ -0,0 +1,20 @@
{
"background_color": "#ffffff",
"theme_color": "#333333",
"name": "TODO",
"short_name": "TODO",
"display": "minimal-ui",
"start_url": "/",
"icons": [
{
"src": "logo-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "logo-512.png",
"sizes": "512x512",
"type": "image/png"
}
]
}

2959
yarn.lock Normal file

File diff suppressed because it is too large Load Diff