diff --git a/base/serve.mjs b/base/serve.mjs index 26a3d56..98af5f4 100644 --- a/base/serve.mjs +++ b/base/serve.mjs @@ -22,7 +22,7 @@ export default class ServeHandler { } let indexFile = fsSync.readFileSync(path.join(this.root, 'index.html')) - this.template = dot.template(indexFile.toString(), { argName: ['headerDescription', 'headerImage', 'headerTitle', 'headerUrl', 'payloadData', 'payloadTree', 'version', 'nonce', 'type', 'banner'] }) + this.template = dot.template(indexFile.toString(), { argName: ['headerDescription', 'headerImage', 'headerTitle', 'headerUrl', 'payloadData', 'payloadTree', 'version', 'nonce', 'type', 'banner', 'media', 'in_debug'] }) // console.log(indexFile.toString()) } diff --git a/nfp_moe/api/serve.mjs b/nfp_moe/api/serve.mjs index 9b4636a..b0b5b74 100644 --- a/nfp_moe/api/serve.mjs +++ b/nfp_moe/api/serve.mjs @@ -1,7 +1,9 @@ import path from 'path' +import striptags from 'striptags' import Parent from '../base/serve.mjs' import fs from 'fs/promises' import dot from 'dot' +import config from '../base/config.mjs' export default class ServeHandler extends Parent { traverseTree(set, tree) { @@ -13,9 +15,42 @@ export default class ServeHandler extends Parent { } } + getDescriptionFromBlocks(blocks) { + return encodeURI(blocks + .filter(x => x.type === 'header' + || x.type === 'paragraph' + || x.type === 'quote' + || x.type === 'list' + || x.type === 'code' + || x.type === 'htmlraw') + .map(x => { + if (x.type === 'htmlraw') { + return striptags(x.data.html) + } + if (x.type === 'quote') { + return `"${x.data.text}"` + (x.data.caption ? ` - ${x.data.caption}` : '') + } + if (x.type === 'list') { + return x.data.items.join('. ') + } + return x.data.code ? `"${x.data.code}"` : x.data.text + }) + .map(x => striptags(x)) + .map(x => { + console.log(x) + return x + }) + .filter(x => x) + .join('. ') + .replace('/\.+/g', '.') + ) + } + async serveIndex(ctx) { - let indexFile = await fs.readFile(path.join(this.root, 'index.html')) - this.template = dot.template(indexFile.toString(), { argName: ['headerDescription', 'headerImage', 'headerTitle', 'headerUrl', 'payloadData', 'payloadTree', 'version', 'nonce', 'type', 'banner', 'media'] }) + if (config.get('NODE_ENV') === 'development') { + let indexFile = await fs.readFile(path.join(this.root, 'index.html')) + this.template = dot.template(indexFile.toString(), { argName: ['headerDescription', 'headerImage', 'headerTitle', 'headerUrl', 'payloadData', 'payloadTree', 'version', 'nonce', 'type', 'banner', 'media', 'in_debug'] }) + } let payload = { headerDescription: 'Small fansubbing and scanlation group translating and encoding our favourite shows from Japan.', @@ -29,6 +64,7 @@ export default class ServeHandler extends Parent { type: 'page', banner: false, media: false, + in_debug: config.get('NODE_ENV') === 'development' && false, } try { @@ -45,16 +81,36 @@ export default class ServeHandler extends Parent { let data = await this.pageRoutes.getPage(ctx, true) if (!data.page) { payload.type = 'frontpage' - } - else if (setOfBranches.has(data.page.id)) { + } else if (setOfBranches.has(data.page.id)) { payload.type = 'page_with_children' } + + if (data.page) { + payload.headerTitle = data.page.name + ' - NFP Moe' + if (data.page.content.blocks.length) { + payload.headerDescription = this.getDescriptionFromBlocks(data.page.content.blocks) || payload.headerDescription + } + if (data.page.media_alt_prefix) { + payload.headerImage = data.page.media_alt_prefix + '_small.jpg' + } + } payload.media = data.page?.media_avif_preview || false payload.banner = data.featured?.banner_avif_preview || data.page?.banner_avif_preview || false payload.payloadData = JSON.stringify(data) } else if (ctx.url.startsWith('/article/') && ctx.url.lastIndexOf('/') === 8) { ctx.params.path = ctx.url.slice(ctx.url.lastIndexOf('/') + 1) let data = await this.articleRoutes.getArticle(ctx, true) + + if (data.article) { + payload.headerTitle = data.article.name + ' - NFP Moe' + if (data.article.content.blocks.length) { + payload.headerDescription = this.getDescriptionFromBlocks(data.article.content.blocks) || payload.headerDescription + } + if (data.article.media_alt_prefix) { + payload.headerImage = data.article.media_alt_prefix + '_small.jpg' + } + } + payload.media = data.article?.media_avif_preview || false payload.payloadData = JSON.stringify(data) payload.type = 'article' diff --git a/nfp_moe/app/media.js b/nfp_moe/app/media.js index fcb8541..93eea4f 100644 --- a/nfp_moe/app/media.js +++ b/nfp_moe/app/media.js @@ -16,52 +16,6 @@ export function generatePictureSource(item, cover) { } } -let loadingImage = null -let loader = null - -function cancelLoader() { - if (loader) { - loader.src = '' - } - loader = null -} - -export function smartBanner(item) { - if (!item) { - if (loader) { - cancelLoader() - } - loadingImage = null - return null - } - - if (!item.preview) { - loadingImage = null - cancelLoader() - return item.banner - } - if (loadingImage !== item.banner && loader) { - cancelLoader() - } - if (loadingImage === item.banner && !loader) { - return item.banner - } - if (loadingImage === item.banner) { - return item.preview - } - - loadingImage = item.banner - loader = new Image(); - - loader.src = item.banner; - loader.onload = loader.onerror = function() { - loader = null - m.redraw() - } - - return item.preview -} - export function getBannerImage(item, prefix) { if (!item || !item.banner_alt_prefix) return null @@ -97,12 +51,12 @@ export function getArticlePicture(pictureData, useRouteLink, path, altText, fall if (!pictureData) return fallback || null return m(useRouteLink ? m.route.Link : 'a', { - class: 'cover ' + (pictureData.preview ? 'haspreview' : ''), + class: 'cover ' + (pictureData.preview && window.supportsavif ? 'haspreview' : ''), rel: useRouteLink ? null : 'noopener', target: useRouteLink ? null : '_blank', href: path, }, [ - pictureData.preview ? m('img', { src: pictureData.preview }) : null, + pictureData.preview && window.supportsavif ? m('img', { src: pictureData.preview }) : null, m('picture', [ m('source', { srcset: pictureData.avif, diff --git a/nfp_moe/app/site_page.js b/nfp_moe/app/site_page.js index 96fde77..7a36233 100644 --- a/nfp_moe/app/site_page.js +++ b/nfp_moe/app/site_page.js @@ -228,7 +228,7 @@ const SitePage = { ? m(m.route.Link, { class: 'page-banner', href: featuredBanner.path, - style: { 'background-image': 'url("' + featuredBanner.preview + '")' }, + style: window.supportsavif ? { 'background-image': 'url("' + featuredBanner.preview + '")' } : null, }, [ m('div.page-banner-real', { style: { 'background-image': 'url("' + featuredBanner.banner + '")' }, @@ -240,7 +240,7 @@ const SitePage = { ? m('a.page-banner', { href: pageBanner.original, target: '_blank', - style: { 'background-image': 'url("' + pageBanner.preview + '")' }, + style: window.supportsavif ? { 'background-image': 'url("' + pageBanner.preview + '")' } : null, }, m('div.page-banner-real', { style: { 'background-image': 'url("' + pageBanner.banner + '")' }, diff --git a/nfp_moe/package.json b/nfp_moe/package.json index 9a3e02b..20be34a 100644 --- a/nfp_moe/package.json +++ b/nfp_moe/package.json @@ -56,7 +56,8 @@ "flaska": "^1.3.0", "formidable": "^1.2.6", "msnodesqlv8": "^2.4.7", - "nconf-lite": "^2.0.0" + "nconf-lite": "^2.0.0", + "striptags": "^3.2.0" }, "devDependencies": { "asbundle": "^2.6.1", diff --git a/nfp_moe/public/assets/app.css b/nfp_moe/public/assets/app.css index d65fbff..4d22401 100644 --- a/nfp_moe/public/assets/app.css +++ b/nfp_moe/public/assets/app.css @@ -19,5 +19,5 @@ } .jpegonly .spritesheet { - background-image: url("/assets/img/combined.png") + background-image: url("/assets/img/combined.webp") } diff --git a/nfp_moe/public/assets/app_body.css b/nfp_moe/public/assets/app_body.css deleted file mode 100644 index 38e6cb8..0000000 --- a/nfp_moe/public/assets/app_body.css +++ /dev/null @@ -1,1039 +0,0 @@ -/* - ===================== Variables ===================== -*/ -:root { - --content-max-width: 1280px; - --primary-darker-bg: #002f6c; - --primary-darker-fg: #fff; - --primary-darker-fg-light: #999; - --primary-darker-link: #ffad42; - - --primary-bg: #3d77c7; - --primary-fg: #fff; - --primary-fg-light: #999; - --primary-link: #f57c00; - - --bg: #fff; - --bg-content-alt: #eee; - --color: #000; - --light: #757575; - --link: #bb4d00; - --title-bg: #f57c00; - --title-fg: #000; - --seperator: #ccc; - --content-bg: #fff; - --content-border: 0px solid transparent; - - --alt-bg: #ccc; - --alt-inside-bg: #fff; - --alt-inside-border: 1px solid #555; - --alt-color: #555; - - --footer-bg: #ccc; - --footer-color: #000; - --footer-seperator: #fff; - --footer-link: #8F3C00; - - --button-border: 1px solid #f57c00; - --button-bg: #ffad42; - --button-fg: #000; - - --error-bg: red; - --error-fg: white; -} - -.nightmode { - --content-max-width: 1280px; - --primary-darker-bg: #002f6c; - --primary-darker-fg: #fff; - --primary-darker-fg-light: #999; - --primary-darker-link: #ffad42; - - --primary-bg: #28518b; - --primary-fg: #fff; - --primary-fg-light: #999; - --primary-link: #f57c00; - - --bg: black; - --bg-content-alt: #333; - --color: #d7dadc; - --light: #bbb; - --link: #e05e00; - --title-bg: #e05e00; - --title-fg: #000; - --title-sublink: #27159C; - --seperator: #ccc; - --content-bg: #1a1a1b; - --content-border: 1px solid #343536; - - --alt-bg: #000; - --alt-inside-bg: #343536; - --alt-inside-border: 1px solid #808080; - --alt-color: #d7dadc; - - --footer-bg: #343536; - --footer-color: #d7dadc; - --footer-seperator: #666; - --footer-link: #fe791b; - - --button-border: 1px solid #f57c00; - --button-bg: #ffad42; - --button-fg: #000; - - --error-bg: red; - --error-fg: white; -} - -/* - ===================== Reset ===================== -*/ - -/* Box sizing rules */ -*, *::before, *::after { box-sizing: border-box; -} - -/* Remove default margin */ -body, h1, h2, h3, h4, p, figure, blockquote, dl, dd { - margin: 0; -} - -body { - min-height: 100vh; - text-rendering: optimizeSpeed; - line-height: 1.5; - font-size: 16px; - font-family: 'Inter var', sans-serif; - font-variation-settings: "slnt" 0; - font-feature-settings: "case", "frac", "tnum", "ss02", "calt", "ccmp", "kern"; - background: var(--bg); - color: var(--color); -} - -.italic { font-variation-settings: "slnt" 10deg; } - -a { - text-decoration-skip-ink: auto; -} - -img { - max-width: 100%; - margin: 0 auto; - display: block; -} - -input, button, textarea, select { - font: inherit; -} - -@media (prefers-reduced-motion: reduce) { - *, *::before, *::after { - animation-play-state: paused !important; - transition: none !important; - scroll-behavior: auto !important; - } -} - -h1 { - font-size: 2.488rem; -} -h2 { - font-size: 2.074rem; -} -h3 { - font-size: 1.728rem; -} -h4 { - font-size: 1.44rem; -} -h5 { - font-size: 1.0rem; -} - -a, a:visited, button { - text-decoration: none; - border: none; - padding: 0; - margin: 0; - font-weight: bold; - cursor: pointer; -} - -input[type=text], -input[type=password], -select { - border: 1px solid var(--color); - background: var(--bg); - color: var(--color); - border-radius: 0; - padding: 0.25rem; - line-height: 1rem; -} - -label { - font-size: 0.75rem; - font-weight: 500; - margin-top: 1rem; - margin-bottom: 0.25rem; - display: block; -} - -input[type=text]:hover, -input[type=text]:active, -input[type=password]:hover, -input[type=password]:active, -select:hover, -select:active { - border-color: var(--link); -} - -button { - background: transparent; -} - - -/* - ===================== Loading bar ===================== -*/ - -.lb, -.lb-main, -.lb-link { - width: 100px; - background: var(--color); - opacity: 0.35; - height: 1rem; - border-radius: 20px; - align-self: center; - position: relative; -} - -.lb-main, -.lb-link { - display: inline-block; -} - -.lb-link { - background: var(--link); -} - -.lb:after, -.lb-main:after, -.lb-link:after { - content: ''; - background: repeating-linear-gradient(to right, transparent 0%, transparent 25%, #00000044 75%, transparent 100%); - background-size: 300% auto; - background-position: 0 -300%; - border-radius: 20px; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - animation: lbgradient 10s infinite; - animation-fill-mode: forwards; - animation-timing-function: linear; -} - -.lb-main:after { - background: repeating-linear-gradient(to right, transparent 0%, transparent 25%, #ffffff44 75%, transparent 100%); - background-size: 300% auto; - background-position: 0 -300%; -} - -.lb-link:after { - background: repeating-linear-gradient(to right, transparent 0%, transparent 25%, #ffffff44 75%, transparent 100%); - background-size: 300% auto; - background-position: 0 -300%; -} - -@keyframes lbgradient { - 0% { background-position: 300% 0; } - 100% { background-position: -300% 0; } -} - -main aside .lb-main { - height: 0.875rem; -} - -.actions .lb-link { - margin: 0.25rem 0; -} - -article .row div .lb-main { - display: block; - margin-bottom: 0.75rem; - opacity: 0.2; -} - -.page-banner.lb, -.page-banner.lb:after { - border-radius: 0; - opacity: 1; - background-color: var(--seperator); -} - -footer .lb { - background: var(--footer-link); - display: inline-block; - margin-top: 0.25rem; - margin-bottom: 0.15rem; - bottom: -4px; - height: 0.625rem; -} - -.lb--large { - height:40px; - width: 200px; -} - -.lb--long { - width: 200px; -} - -.lb--longest { - width: 300px; -} - -.lb--medium { - width: 150px; -} -.lb--slim { - height: 0.675rem; -} - -main .cover picture.lb, -main .cover.haspreview > img { - display: block; - width: 100%; - height: auto; - opacity: 1; - border-radius: 0; -} - -main .cover picture.lb.nobg { - padding-top: 50%; - background: var(--seperator); - margin-bottom: 1rem; -} - -article.fullsize .row .cover { - width: 100%; -} - -article .description .lb-main { - display: block; - margin: 0 0 0.75rem; -} - -article .description fileinfo ul .lb-main { - bottom: -4px; -} - -main .cover picture.lb:after { - border-radius: 0; -} - -.lb--imgmini { - width: 400px; - height: 225px; - margin-right: 1rem; - opacity: 0.2; -} - -@media (prefers-reduced-motion), only screen and (hover: none) and (pointer: coarse), (prefers-reduced-motion) { - .lb:after { - background: transparent !important; - display: none !important; - animation: none !important; - } -} - -/* - ===================== Common ===================== -*/ - -.inside { - width: 100%; - max-width: var(--content-max-width); - display: flex; - margin: 0 auto; -} - -.inside.vertical { - flex-direction: column; -} - -.error { - background: var(--error-bg); - color: var(--error-fg); - cursor: pointer; - text-align: center; - padding: 0.5rem; -} - -.wrapper { - background: var(--alt-bg); - color: var(--alt-color); - display: flex; - justify-content: center; - align-items: center; - min-height: calc(100vh - 200px); - padding: 1rem; -} - -.filler { - flex: 2 1 auto; -} - -.wrapper .inside { - flex-direction: column; - color: var(--alt-color); - background: var(--alt-inside-bg); - border: var(--alt-inside-border); -} - -.wrapper .error { - border: 1px solid var(--error-bg); - color: var(--error-bg); - background: transparent; -} - -.notfound { - color: var(--light); -} - -@media screen and (max-width: 639px){ - main .inside { - flex-direction: column; - } - - .wrapper { - flex-direction: column; - } -} - -/* - ===================== Header ===================== -*/ - -header { - background: var(--primary-darker-bg); - color: var(--primary-darker-fg); -} - -header a, -header a:visited, -header button { - color: var(--primary-darker-link); -} - -header p { - color: var(--primary-darker-fg-light); -} - -header .title, -header .title:visited { - min-height: 100px; - padding-left: 10px; - display: flex; - align-items: center; - background: 25px center no-repeat; - background-size: auto 91px; - flex: 0 0 auto; -} - -header .logo { - background-position: -119px 0px; - width: 81px; - height: 100px; - transform: scale(0.9); - margin-right: 1rem; -} - -header .lb { - background: var(--primary-darker-fg); -} - -header .logo.lb { - background: #eaad81; -} - -header .title h1 { - font-weight: 500; - color: var(--primary-darker-fg); -} - -header aside { - flex: 2 1 auto; - display: flex; - flex-direction: column; - align-items: flex-end; - font-size: 0.8rem; - padding: 0.5rem 0.5rem; -} - -header aside a, -header aside button { - margin-left: 0.5rem; -} - -header aside p button { - margin-left: 0; -} - -/* - ===================== Nav ===================== -*/ - -nav { - background: var(--primary-bg); -} - -nav a, nav a:visited { - flex: 2 0 auto; - text-align: center; - font-weight: 300; - padding: 10px 10px 7px 10px; - border-bottom: 3px solid var(--primary-bg); - color: var(--primary-fg); -} - -nav a .lb { - background: var(--primary-fg); - display: inline-block; -} - -nav a.active { - border-bottom-color: var(--primary-link); -} - -@media screen and (max-width: 639px){ - nav { - font-size: 0.8em; - } -} - -/* - ===================== main ===================== -*/ - -main { - min-height: calc(100vh - 294px); -} - -.page-banner, -.page-banner .page-banner-real { - background-size: cover; - background-repeat: no-repeat; - background-position: center; - height: 150px; - width: 100%; - display: block; - position: relative; -} - -.page-banner-real { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -.page-banner-title { - color: white; - text-align: right; - padding: 0.5rem 1rem; - font-size: 1.6rem; - flex: 2 1 auto; - text-shadow: 0 0 .3em #000; -} - -.actions { - padding: 0.5rem 1rem; - display: flex; -} - -.actions a { - margin-left: 0.375rem; -} - -main a, -main a:visited { - color: var(--link); -} - -main h5 { - padding: 0 0.5rem 0.5rem; - margin: 0 0 0.75rem; - border-bottom: 1px solid var(--seperator); - font-size: 1rem; -} - -main h2.title, -.main h2.title { - font-size: 1.4rem; - background: var(--title-bg); - color: var(--title-fg); - text-align: center; - font-weight: 400; - padding: 0.375rem; - line-height: 1.4rem; -} - -main .container { - flex: 2 1 auto; - margin: 1rem; -} - -main .cover { - position: relative; - display: block; -} - -main .cover.haspreview > img { - margin-bottom: 1rem; -} - -main .cover.haspreview picture { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} - -main .cover picture img { - margin-bottom: 1rem; - width: 100%; -} - -main button, -main input[type=submit] { - border: var(--button-border); - background: #ffad42; - color: #000; - align-self: center; - padding: 0.25rem 1rem; - margin: 1rem 0 2rem; -} - -@media screen and (max-width: 639px){ - main .container { - margin: 1rem 0.25rem; - } -} - -/* ************** aside ************** */ - -main aside { - padding: 0.375rem 1rem 0.5rem; - margin: 1rem; - font-size: 0.875rem; - flex: 0 0 250px; - background: var(--content-bg); - border: var(--content-border); -} - -main aside a { - display: block; -} - -main aside h5 { - margin: 0 -0.5rem 0.25rem; - font-size: 0.9em; -} - -main aside ul { - margin: 0 0 0.5rem; - padding-left: 1.5rem; -} - -main aside .asuna { - margin-top: 2rem; - width: 200px; - height: 461px; - background-position: 0 -150px; -} - -.nightmode main aside .asuna { - background-position: -200px -150px; -} - -.daymode .day { - display: block; -} - -@media screen and (max-width: 1000px){ - main aside { - flex: 0 0 200px; - } -} - -@media screen and (max-width: 639px){ - main aside { - margin: 1rem 0.25rem; - flex: 0 0 auto; - } - - main aside.frontpage { - order: 2; - } -} - - -/* ************** paginator ************** */ - -paginator { - display: flex; - justify-content: center; - width: 100%; -} - -paginator a { - color: var(--link); - cursor: pointer; -} - -paginator a, -paginator div { - display: block; - font-size: 0.8rem; - max-width: 80px; - flex-grow: 2; - text-align: center; - padding: 0.5rem; - margin-top: 1rem; -} - -/* ************** articleslim ************** */ - -articleslim { - display: flex; - margin-bottom: 0.75rem; - padding-right: 0.5rem; -} - -articleslim p.description { - font-size: 0.75rem; -} - -articleslim .cover { - flex: 0 0 124px; - margin-right: 0.75rem; -} - -articleslim .cover picture img, -articleslim .cover.haspreview > img { - margin-bottom: 0; -} - -articleslim a.nobg { - height: 70px; - background: var(--seperator); - display: block; -} - -articleslim a.title { - display: block; - margin-bottom: 0.375rem; -} - -/* ************** article ************** */ - -article { - background: var(--content-bg); - border: var(--content-border); - margin-bottom: 1rem; -} - -article .row { - margin: 1rem 0; - display: flex; -} - -article .cover { - flex: 0 0 auto; - margin-right: 1rem; - align-self: flex-start; -} - -article a.title { - flex: 0 0 100%; - margin-bottom: 0.5rem; -} - -article .description { - font-size: 0.875rem; - margin-bottom: 1rem; - padding: 0 0.25rem; -} - -article .meta { - font-size: 0.625rem; - line-height: 0.75rem; - color: var(--light); - font-weight: 500; - padding: 1.25rem 0.25rem 0; -} - -article:not(.fullsize) .cover.haspreview > img { - width: 400px; -} - -article.fullsize .row { - margin: 1rem; - flex-direction: column; -} - -article.fullsize .cover { - margin-right: 0; -} - -@media screen and (max-width: 1000px){ - article:not(.fullsize) .cover.haspreview > img { - width: calc(100vw - 265px); - } - - article .row { - flex-direction: column; - } - - article.fullsize .row { - margin: 1rem 0.25rem; - } - - article .cover { - margin-right: 0; - } -} - -@media screen and (max-width: 639px){ - article:not(.fullsize) .cover.haspreview > img { - width: calc(100vw - 10px); - } -} - -/* ************** fileinfo ************** */ - -fileinfo { - padding-left: 0.25rem; - margin-bottom: 0.5rem; - color: var(--light); - line-height: 1rem; - font-size: 0.75rem; - display: block; - position: relative; -} - -fileinfo.slim { - padding: 0; - margin: 0; -} - -fileinfo p span, -fileinfo p a { - margin-right: 0.25rem; -} - -fileinfo p a { - font-weight: 550; - padding-right: 0.25rem; - border-right: 1px solid var(--seperator); - display: inline-block; -} - -fileinfo p span { - font-weight: 700; -} - -fileinfo .trimmed { - padding: 0.25rem 0 0.25rem 1rem; -} - -fileinfo ul { - margin: 0.5rem 0; - padding-left: 1.5rem; -} - -/* - ===================== login ===================== -*/ - -.login--first { - flex: 0 0 170px; -} - -.login { - align-items: center; - font-size: 1rem; - padding: 1rem 1rem 2rem; - margin: 1rem; - max-width: 400px; -} - -.login .title { - font-size: 1.4rem; - font-weight: 200; - margin-bottom: 2rem; - text-align: center; -} - -.login input, -.login label { - width: 100%; - max-width: 300px; -} - -.login input[type=submit] { - min-width: 150px; - margin-top: 1rem; -} - -.login--asuna { - flex: 0 0 auto; - width: 180px; - height: 494px; - background-position: -400px 0; -} - -.nightmode .login--asuna { - background-position: -580px 0; -} - - -@media screen and (max-width: 1000px){ - .login--first { - display: none; - } -} - - -@media screen and (max-width: 639px){ - .login { - order: 2; - } - - .login--asuna { - max-width: 120px; - } -} - -/* - ===================== content ===================== -*/ - -.content :is(h1, h2, h3, h4, h5, ul, ol, blockquote, p) { - margin: 0 0 0.75rem; -} - -.content :is(h1, h2, h3, h4, h5) { - padding: 0 0.5rem 0.5rem; - border-bottom: 1px solid var(--seperator); -} - -.content :is(blockquote, pre) { - background: var(--bg-content-alt); - padding: 0.5rem; -} - -.content blockquote p { - margin: 0; -} - -/* - ===================== footer ===================== -*/ - -footer { - background: var(--footer-bg); - color: var(--footer-color); - min-height: 150px; - text-align: center; - padding: 1rem; - display: flex; - align-items: center; - font-weight: 500; - font-size: 0.625rem; -} - -footer .first { - flex: 0 0 119px; -} - -footer .middle { - display: flex; - flex-direction: column; - align-items: center; - flex: 2 1 auto; - padding: 0 2rem; -} - -footer .asuna { - flex: 0 0 119px; - height: 150px; - width: 119px; - background-position: 0px 0px; -} - -footer ul { - margin: 0 0 0.25rem; - padding: 0 0 0.25rem; - border-bottom: 1px solid var(--footer-seperator); - display: flex; - justify-content: center; - flex-wrap: wrap; - min-width: 300px; -} - -footer ul li { - padding: 0 0.25rem; - list-style-position: inside; -} - -footer a { - color: var(--footer-link); - margin: 0 0 0.25rem; -} - - -@media screen and (max-width: 1000px){ - footer .first { - display: none; - } -} - - -@media screen and (max-width: 639px){ - footer{ - flex-direction: column; - } - - footer .middle { - padding: 0 0 2rem; - } - - footer .asuna { - flex: 0 0 150px; - } -} - -/* - ===================== 404 page ===================== -*/ - -.not_found { - flex-direction: column; - text-align: center; -} - -.not_found .asuna { - width: 120px; - height: 444px; - margin: 2rem 0 0rem; - background-position: -760px 0; -} - -.nightmode .not_found .asuna { - background-position: -880px 0; -} diff --git a/nfp_moe/public/assets/img/combined.webp b/nfp_moe/public/assets/img/combined.webp new file mode 100644 index 0000000..fd2ca9f Binary files /dev/null and b/nfp_moe/public/assets/img/combined.webp differ diff --git a/nfp_moe/public/assets/img/heart.png b/nfp_moe/public/assets/img/heart.png new file mode 100644 index 0000000..8732988 Binary files /dev/null and b/nfp_moe/public/assets/img/heart.png differ diff --git a/nfp_moe/public/index.html b/nfp_moe/public/index.html index 898bf18..c55e81f 100644 --- a/nfp_moe/public/index.html +++ b/nfp_moe/public/index.html @@ -12,18 +12,1089 @@ - {{? headerImage === '/assets/img/heart.jpg' }} - - - {{? }} - - + +