프로젝트 소스 공개
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
node_modules/
|
||||
dist/
|
||||
.astro/
|
||||
.DS_Store
|
||||
@@ -0,0 +1,37 @@
|
||||
# ProjectQuint 사이트
|
||||
|
||||
ProjectQuint 소개, 사용 안내, 외부 BMS 자료 링크와 macOS 배포 정보를 제공하는 Astro 사이트입니다.
|
||||
|
||||
## 개발과 검증
|
||||
|
||||
저장소의 `Website/projectquint-site`에서 실행합니다.
|
||||
|
||||
```bash
|
||||
npm ci
|
||||
npm run check
|
||||
npm run build
|
||||
```
|
||||
|
||||
생성된 정적 파일은 `dist/`에 저장됩니다. 공개 사이트 주소는
|
||||
`https://projectquint.duckdns.org`입니다.
|
||||
|
||||
## 배포 설정
|
||||
|
||||
실제 서버 주소와 SSH 키 경로는 저장소 루트의 `.release.local.json` 또는
|
||||
`PROJECTQUINT_DEPLOY_HOST`, `PROJECTQUINT_DEPLOY_KEY`,
|
||||
`PROJECTQUINT_REMOTE_SOURCE` 환경 변수로 지정합니다. 설정 파일은 Git에서 제외합니다.
|
||||
설정 방법은 `Tools/RELEASE.md`를 참고합니다.
|
||||
|
||||
빌드를 확인한 뒤 `./ops/deploy-oci.sh`로 배포합니다. 기존 배포 대상과 다른
|
||||
디렉터리를 지정하기 전에 해당 디렉터리의 소유 서비스와 내용을 확인해야 합니다.
|
||||
스크립트는 정적 사이트 디렉터리를 동기화하고 Nginx 설정을 검증한 뒤 다시 로드합니다.
|
||||
|
||||
앱 배포 파일은 정적 사이트와 별도 경로에 보존합니다. 버전과 체크섬은
|
||||
`src/pages/download.astro`, `src/pages/changelog.astro`, `public/updates/`에서 관리합니다.
|
||||
|
||||
## 공개 자료의 범위
|
||||
|
||||
- 개인 이름, 개인 계정, 개인 GitHub 링크를 공개 페이지에 넣지 않습니다.
|
||||
- BMS 음원·재킷·BGA를 사이트에 복제하지 않습니다.
|
||||
- 외부 BMS 콘텐츠는 원 제작자 또는 커뮤니티 페이지로 연결합니다.
|
||||
- 배포 전에 소스맵과 이미지·HTML 메타데이터를 확인합니다.
|
||||
@@ -0,0 +1,15 @@
|
||||
import { defineConfig } from "astro/config";
|
||||
|
||||
export default defineConfig({
|
||||
site: "https://projectquint.duckdns.org",
|
||||
output: "static",
|
||||
trailingSlash: "always",
|
||||
build: {
|
||||
format: "directory"
|
||||
},
|
||||
vite: {
|
||||
build: {
|
||||
sourcemap: false
|
||||
}
|
||||
}
|
||||
});
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
readonly LOCAL_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
readonly PROJECT_ROOT="$(cd "$LOCAL_ROOT/../.." && pwd)"
|
||||
configuration_exports=$(/usr/bin/python3 "$PROJECT_ROOT/Tools/release_configuration.py" --shell)
|
||||
eval "$configuration_exports"
|
||||
readonly DEPLOY_HOST="$PROJECTQUINT_DEPLOY_HOST"
|
||||
readonly DEPLOY_KEY="$PROJECTQUINT_DEPLOY_KEY"
|
||||
readonly REMOTE_SOURCE="$PROJECTQUINT_REMOTE_SOURCE"
|
||||
readonly REMOTE_WEB_ROOT="/var/www/projectquint"
|
||||
readonly REMOTE_NGINX="/etc/nginx/sites-available/projectquint.conf"
|
||||
readonly SSH_ARGS=(-i "$DEPLOY_KEY" -o IdentitiesOnly=yes -o BatchMode=yes)
|
||||
readonly RSYNC_SSH=$(/usr/bin/python3 -c 'import shlex, sys; print(shlex.join(sys.argv[1:]))' ssh "${SSH_ARGS[@]}")
|
||||
|
||||
if [[ ! -f "$LOCAL_ROOT/package.json" || ! -d "$LOCAL_ROOT/dist" ]]; then
|
||||
printf 'ProjectQuint site build is missing. Run npm run build first.\n' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ssh "${SSH_ARGS[@]}" "$DEPLOY_HOST" \
|
||||
"mkdir -p '$REMOTE_SOURCE' '$REMOTE_SOURCE/.deploy'"
|
||||
|
||||
rsync -a --delete \
|
||||
--exclude node_modules \
|
||||
--exclude dist \
|
||||
--exclude .astro \
|
||||
--exclude .deploy \
|
||||
-e "$RSYNC_SSH" \
|
||||
"$LOCAL_ROOT/" "$DEPLOY_HOST:$REMOTE_SOURCE/"
|
||||
|
||||
ssh "${SSH_ARGS[@]}" "$DEPLOY_HOST" \
|
||||
"mkdir -p '$REMOTE_SOURCE/.deploy/dist'"
|
||||
|
||||
rsync -a --delete \
|
||||
-e "$RSYNC_SSH" \
|
||||
"$LOCAL_ROOT/dist/" "$DEPLOY_HOST:$REMOTE_SOURCE/.deploy/dist/"
|
||||
|
||||
ssh "${SSH_ARGS[@]}" "$DEPLOY_HOST" \
|
||||
"sudo mkdir -p '$REMOTE_WEB_ROOT' &&
|
||||
sudo rsync -a --delete '$REMOTE_SOURCE/.deploy/dist/' '$REMOTE_WEB_ROOT/' &&
|
||||
sudo install -m 0644 '$REMOTE_SOURCE/ops/nginx/projectquint.conf' '$REMOTE_NGINX' &&
|
||||
sudo ln -sfn '$REMOTE_NGINX' /etc/nginx/sites-enabled/projectquint.conf &&
|
||||
sudo nginx -t &&
|
||||
sudo systemctl reload nginx"
|
||||
@@ -0,0 +1,97 @@
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
|
||||
server_name _;
|
||||
root /var/www/projectquint;
|
||||
index index.html;
|
||||
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'none'" always;
|
||||
|
||||
location = /updates/latest.json {
|
||||
add_header Cache-Control "no-store" always;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ^~ /downloads/ {
|
||||
alias /srv/projectquint/releases/;
|
||||
autoindex off;
|
||||
default_type application/octet-stream;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable" always;
|
||||
add_header Content-Disposition "attachment" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
location ~* \.(?:css|js|otf|ttf|png|jpg|jpeg|webp|ico)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
try_files $uri =404;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
server_name projectquint.duckdns.org;
|
||||
root /var/www/projectquint;
|
||||
|
||||
location ^~ /.well-known/acme-challenge/ {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://projectquint.duckdns.org$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
|
||||
server_name projectquint.duckdns.org;
|
||||
root /var/www/projectquint;
|
||||
index index.html;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/projectquint.duckdns.org/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/projectquint.duckdns.org/privkey.pem;
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf;
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
||||
|
||||
add_header Strict-Transport-Security "max-age=15552000" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'none'" always;
|
||||
|
||||
location = /updates/latest.json {
|
||||
add_header Cache-Control "no-store" always;
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ^~ /downloads/ {
|
||||
alias /srv/projectquint/releases/;
|
||||
autoindex off;
|
||||
default_type application/octet-stream;
|
||||
add_header Cache-Control "public, max-age=31536000, immutable" always;
|
||||
add_header Content-Disposition "attachment" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
}
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
|
||||
location ~* \.(?:css|js|otf|ttf|png|jpg|jpeg|webp|ico)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
try_files $uri =404;
|
||||
}
|
||||
}
|
||||
+5263
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "projectquint-site",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "ASTRO_TELEMETRY_DISABLED=1 astro dev",
|
||||
"build": "ASTRO_TELEMETRY_DISABLED=1 astro build",
|
||||
"preview": "ASTRO_TELEMETRY_DISABLED=1 astro preview",
|
||||
"check": "ASTRO_TELEMETRY_DISABLED=1 astro check"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "7.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "0.9.10",
|
||||
"typescript": "6.0.3"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,104 @@
|
||||
Copyright (c) 2021, Kil Hyung-jin (https://github.com/orioncactus/pretendard),
|
||||
with Reserved Font Name 'Pretendard'.
|
||||
|
||||
Copyright 2014-2021 Adobe (http://www.adobe.com/),
|
||||
with Reserved Font Name 'Source'.
|
||||
Source is a trademark of Adobe in the United States and/or other countries.
|
||||
|
||||
Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter),
|
||||
with Reserved Font Name 'Inter'.
|
||||
|
||||
Copyright 2021 The M+ FONTS Project Authors (https://github.com/coz-m/MPLUS_FONTS),
|
||||
with Reserved Font Name 'M PLUS 1'.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
https://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,93 @@
|
||||
Copyright (c) 2014, Indian Type Foundry (info@indiantypefoundry.com).
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
@@ -0,0 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://projectquint.duckdns.org/sitemap.xml
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url><loc>https://projectquint.duckdns.org/</loc></url>
|
||||
<url><loc>https://projectquint.duckdns.org/download/</loc></url>
|
||||
<url><loc>https://projectquint.duckdns.org/guide/</loc></url>
|
||||
<url><loc>https://projectquint.duckdns.org/resources/</loc></url>
|
||||
<url><loc>https://projectquint.duckdns.org/changelog/</loc></url>
|
||||
<url><loc>https://projectquint.duckdns.org/privacy/</loc></url>
|
||||
</urlset>
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"schemaVersion": 1,
|
||||
"channel": "alpha",
|
||||
"available": true,
|
||||
"version": "0.1.0-alpha.4",
|
||||
"buildNumber": 4,
|
||||
"publishedAt": "2026-07-29T20:14:58+09:00",
|
||||
"downloadUrl": "https://projectquint.duckdns.org/downloads/0.1.0-alpha.4/ProjectQuint-0.1.0-alpha.4-macOS-universal.dmg",
|
||||
"notesUrl": "/changelog/",
|
||||
"sha256": "5b73e24bafae3a2593a53ef63dbbb8474e65e74d6b4b1f9818bb20b325ba4598",
|
||||
"sizeBytes": 77762536
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
const year = new Date().getFullYear();
|
||||
---
|
||||
|
||||
<footer class="site-footer">
|
||||
<div class="site-footer__inner">
|
||||
<div>
|
||||
<p class="site-footer__brand">PROJECT QUINT</p>
|
||||
<p class="site-footer__copy">A macOS-first BMS rhythm client.</p>
|
||||
</div>
|
||||
<nav aria-label="푸터">
|
||||
<a href="/privacy/">PRIVACY</a>
|
||||
<a href="/resources/">BMS RESOURCES</a>
|
||||
</nav>
|
||||
<p class="site-footer__legal">© {year} ProjectQuint</p>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,34 @@
|
||||
---
|
||||
const { pathname } = Astro.url;
|
||||
const nav = [
|
||||
{ href: "/", label: "HOME" },
|
||||
{ href: "/download/", label: "DOWNLOAD" },
|
||||
{ href: "/guide/", label: "GUIDE" },
|
||||
{ href: "/resources/", label: "BMS" },
|
||||
{ href: "/changelog/", label: "CHANGELOG" }
|
||||
];
|
||||
|
||||
const isCurrent = (href: string) =>
|
||||
href === "/" ? pathname === "/" : pathname.startsWith(href);
|
||||
---
|
||||
|
||||
<header class="site-header">
|
||||
<a class="brand" href="/" aria-label="ProjectQuint 홈">
|
||||
<span class="brand__mark" aria-hidden="true">Q</span>
|
||||
<span class="brand__name">PROJECT QUINT</span>
|
||||
</a>
|
||||
<nav class="site-nav" aria-label="주요 메뉴">
|
||||
{
|
||||
nav.map((item) => (
|
||||
<a
|
||||
class:list={["site-nav__link", { "is-current": isCurrent(item.href) }]}
|
||||
href={item.href}
|
||||
aria-current={isCurrent(item.href) ? "page" : undefined}
|
||||
>
|
||||
{item.label}
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</nav>
|
||||
<span class="alpha-tag">ALPHA</span>
|
||||
</header>
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
import SiteFooter from "../components/SiteFooter.astro";
|
||||
import SiteHeader from "../components/SiteHeader.astro";
|
||||
import "../styles/global.css";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
const { title, description } = Astro.props;
|
||||
const pageTitle = title === "ProjectQuint" ? title : `${title} — ProjectQuint`;
|
||||
const canonicalUrl = new URL(Astro.url.pathname, Astro.site);
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="color-scheme" content="light" />
|
||||
<meta name="theme-color" content="#f5f7fb" />
|
||||
<meta name="description" content={description} />
|
||||
<meta name="author" content="ProjectQuint" />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:site_name" content="ProjectQuint" />
|
||||
<meta property="og:title" content={pageTitle} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:url" content={canonicalUrl} />
|
||||
<link rel="icon" type="image/png" sizes="80x80" href="/favicon.png?v=2" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png?v=2" />
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
<title>{pageTitle}</title>
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip-link" href="#main">본문으로 이동</a>
|
||||
<div class="page-shell">
|
||||
<SiteHeader />
|
||||
<main id="main">
|
||||
<slot />
|
||||
</main>
|
||||
<SiteFooter />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="Changelog"
|
||||
description="ProjectQuint Alpha 개발 변경 내역."
|
||||
>
|
||||
<section class="page-hero">
|
||||
<p class="eyebrow">BUILD HISTORY</p>
|
||||
<h1>CHANGELOG</h1>
|
||||
<p class="page-hero__lead">
|
||||
공개 Alpha의 주요 변경 사항과 검증 상태를 기록합니다.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="timeline">
|
||||
<article class="timeline-entry">
|
||||
<div class="timeline-entry__date">
|
||||
<span>2026</span>
|
||||
<strong>07.29</strong>
|
||||
</div>
|
||||
<div class="timeline-entry__body">
|
||||
<p class="card-kicker">0.1.0-ALPHA.4</p>
|
||||
<h2>Clearer update installation guidance</h2>
|
||||
<ul>
|
||||
<li>Added a clear in-app DMG update flow: open the DMG, drag ProjectQuint to Applications, and choose Replace.</li>
|
||||
<li>Clarified that running ProjectQuint directly from the DMG does not replace the installed app.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="timeline-entry">
|
||||
<div class="timeline-entry__date">
|
||||
<span>2026</span>
|
||||
<strong>07.29</strong>
|
||||
</div>
|
||||
<div class="timeline-entry__body">
|
||||
<p class="card-kicker">0.1.0-ALPHA.3</p>
|
||||
<h2>Auto Scratch and 1+7K support</h2>
|
||||
<ul>
|
||||
<li>Added Auto Scratch with silent in-play assistance, green scratch feedback, result-only misses, and a dedicated clear lamp.</li>
|
||||
<li>Corrected 1+7K presentation and enabled Rating for Satellite and Stella level-zero charts.</li>
|
||||
<li>Rescaled note speed so the previous 7.0 feel is now 5.0, with automatic one-time settings migration.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="timeline-entry">
|
||||
<div class="timeline-entry__date">
|
||||
<span>2026</span>
|
||||
<strong>07.29</strong>
|
||||
</div>
|
||||
<div class="timeline-entry__body">
|
||||
<p class="card-kicker">0.1.0-ALPHA.2</p>
|
||||
<h2>첫 플레이 흐름과 macOS 기본 설정 개선</h2>
|
||||
<ul>
|
||||
<li>Pack Manager의 비차단 첫 라이브러리 연결 안내</li>
|
||||
<li>4UE·AERY·6UE 난이도표 추천과 직접 선택 경로</li>
|
||||
<li>신규 프로필 기본 노트 속도 6.0, 판정 오프셋 0ms, FULL 롱노트</li>
|
||||
<li>창을 다른 모니터로 옮길 때 주사율과 프레임 정책 재적용</li>
|
||||
<li>전체 EditMode 809개 중 805 통과, 실패 0, skip 4</li>
|
||||
</ul>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<article class="timeline-entry">
|
||||
<div class="timeline-entry__date">
|
||||
<span>2026</span>
|
||||
<strong>07.29</strong>
|
||||
</div>
|
||||
<div class="timeline-entry__body">
|
||||
<p class="card-kicker">0.1.0-ALPHA.1</p>
|
||||
<h2>첫 공개 Alpha</h2>
|
||||
<ul>
|
||||
<li>Apple Silicon과 Intel을 지원하는 macOS Universal 앱</li>
|
||||
<li>Applications 드래그 설치를 제공하는 macOS DMG 배포</li>
|
||||
<li>외부 BMS 폴더 직접 연결 및 팩별 인덱스 관리</li>
|
||||
<li>4·5·6·7키와 왼쪽 스크래치 입력 프로필</li>
|
||||
<li>선곡, 옵션, 팩 관리, 코스와 결과 화면의 Daylight Prism UI</li>
|
||||
<li>FMOD/CoreAudio 출력 장치, 버퍼와 오디오 싱크 설정</li>
|
||||
<li>전체 EditMode 791개 중 787 통과, 실패 0, skip 4</li>
|
||||
</ul>
|
||||
</div>
|
||||
</article>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="Download"
|
||||
description="ProjectQuint 0.1.0 Alpha macOS Universal 다운로드와 설치 안내."
|
||||
>
|
||||
<section class="page-hero page-hero--split">
|
||||
<div>
|
||||
<p class="eyebrow">ALPHA CHANNEL</p>
|
||||
<h1>DOWNLOAD</h1>
|
||||
<p class="page-hero__lead">
|
||||
ProjectQuint의 첫 공개 Alpha입니다. Apple Silicon과 Intel Mac을
|
||||
하나의 Universal 앱으로 지원합니다.
|
||||
</p>
|
||||
<div class="hero__actions">
|
||||
<a
|
||||
class="button button--primary"
|
||||
href="/downloads/0.1.0-alpha.4/ProjectQuint-0.1.0-alpha.4-macOS-universal.dmg"
|
||||
>
|
||||
<span>MACOS ALPHA 받기</span><span aria-hidden="true">↓</span>
|
||||
</a>
|
||||
<a class="button button--ghost" href="/changelog/">변경 내역</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="release-status">
|
||||
<span class="release-status__dot" aria-hidden="true"></span>
|
||||
<div>
|
||||
<small>CURRENT RELEASE</small>
|
||||
<strong>0.1.0 ALPHA 4</strong>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="content-grid">
|
||||
<article class="content-card content-card--wide">
|
||||
<p class="card-kicker">INSTALL</p>
|
||||
<h2>처음 실행하기</h2>
|
||||
<ol class="install-list">
|
||||
<li>
|
||||
<span>01</span>
|
||||
<div><strong>DMG 열기</strong><p>다운로드한 ProjectQuint DMG를 더블클릭합니다.</p></div>
|
||||
</li>
|
||||
<li>
|
||||
<span>02</span>
|
||||
<div><strong>Applications로 드래그</strong><p>ProjectQuint.app을 함께 보이는 <b>Applications</b> 바로가기로 끌어놓습니다.</p></div>
|
||||
</li>
|
||||
<li>
|
||||
<span>03</span>
|
||||
<div><strong>첫 실행 허용</strong><p>앱을 Control-click한 뒤 <b>Open</b>을 선택합니다. 차단되면 <b>System Settings → Privacy & Security → Open Anyway</b>에서 한 번 허용합니다.</p></div>
|
||||
</li>
|
||||
<li>
|
||||
<span>04</span>
|
||||
<div><strong>BMS 폴더 연결</strong><p>Pack Manager에서 보유한 BMS 폴더를 직접 추가합니다.</p></div>
|
||||
</li>
|
||||
</ol>
|
||||
</article>
|
||||
<aside class="content-card">
|
||||
<p class="card-kicker">ARTIFACT</p>
|
||||
<dl class="spec-list">
|
||||
<div><dt>VERSION</dt><dd>0.1.0-alpha.4</dd></div>
|
||||
<div><dt>PLATFORM</dt><dd>macOS</dd></div>
|
||||
<div><dt>ARCH</dt><dd>Apple Silicon / Intel</dd></div>
|
||||
<div><dt>FORMAT</dt><dd>DMG</dd></div>
|
||||
<div><dt>SIZE</dt><dd>77.8 MB</dd></div>
|
||||
<div><dt>CONTENT</dt><dd>BMS 미포함</dd></div>
|
||||
</dl>
|
||||
<div class="checksum">
|
||||
<small>SHA-256</small>
|
||||
<code>5b73e24bafae3a2593a53ef63dbbb8474e65e74d6b4b1f9818bb20b325ba4598</code>
|
||||
</div>
|
||||
</aside>
|
||||
</section>
|
||||
|
||||
<section class="notice-strip">
|
||||
<strong>ALPHA SOFTWARE</strong>
|
||||
<span>플레이 기록을 백업하고, 문제 발생 시 곡·채보명과 재현 절차를 함께 알려주세요.</span>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,59 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
|
||||
const steps = [
|
||||
{
|
||||
no: "01",
|
||||
title: "PROJECTQUINT 설치",
|
||||
copy: "공개 Alpha 패키지를 내려받아 macOS Applications 폴더로 옮깁니다. 정확한 첫 실행 절차는 배포 검증 후 함께 게시합니다."
|
||||
},
|
||||
{
|
||||
no: "02",
|
||||
title: "BMS 폴더 연결",
|
||||
copy: "PACK MANAGER에서 ADD SOURCE를 선택하고 보유한 BMS 폴더를 연결합니다. ProjectQuint는 원본 폴더를 다시 복사하지 않습니다."
|
||||
},
|
||||
{
|
||||
no: "03",
|
||||
title: "키와 오디오 설정",
|
||||
copy: "OPTIONS에서 KEY PROFILE, 노트 속도, 출력 장치와 오디오 싱크를 설정합니다."
|
||||
},
|
||||
{
|
||||
no: "04",
|
||||
title: "곡 선택과 플레이",
|
||||
copy: "4·5·6·7키 라이브러리를 탐색하고 난이도표, 필터, 코스와 개인 기록을 이용합니다."
|
||||
}
|
||||
];
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="Guide"
|
||||
description="ProjectQuint 시작 방법과 BMS 라이브러리 연결 안내."
|
||||
>
|
||||
<section class="page-hero">
|
||||
<p class="eyebrow">GETTING STARTED</p>
|
||||
<h1>GUIDE</h1>
|
||||
<p class="page-hero__lead">
|
||||
앱 설치부터 로컬 BMS 라이브러리 연결까지, 필요한 흐름만 간결하게
|
||||
정리합니다.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="step-list">
|
||||
{
|
||||
steps.map((step) => (
|
||||
<article class="step">
|
||||
<span class="step__number">{step.no}</span>
|
||||
<div>
|
||||
<h2>{step.title}</h2>
|
||||
<p>{step.copy}</p>
|
||||
</div>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</section>
|
||||
|
||||
<section class="notice-strip">
|
||||
<strong>BMS 콘텐츠는 앱에 포함되지 않습니다.</strong>
|
||||
<span>원 제작자와 배포처의 이용 조건을 확인한 콘텐츠를 직접 연결해 주세요.</span>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
|
||||
const features = [
|
||||
{
|
||||
index: "01",
|
||||
title: "YOUR LIBRARY",
|
||||
copy: "보유한 BMS 폴더를 직접 연결합니다. 음악 파일을 앱 내부에 다시 복사하지 않습니다."
|
||||
},
|
||||
{
|
||||
index: "02",
|
||||
title: "4 / 5 / 6 / 7 KEYS",
|
||||
copy: "키 모드와 왼쪽 스크래치를 지원하며, 팩과 난이도표를 분리해 관리합니다."
|
||||
},
|
||||
{
|
||||
index: "03",
|
||||
title: "MACOS FIRST",
|
||||
copy: "CoreAudio와 고주사율 환경을 중심으로 설계한 macOS 전용 리듬게임 경험입니다."
|
||||
}
|
||||
];
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="ProjectQuint"
|
||||
description="macOS-first 4·5·6·7키 BMS 리듬게임 클라이언트 ProjectQuint."
|
||||
>
|
||||
<section class="hero">
|
||||
<div class="hero__copy">
|
||||
<p class="eyebrow">BMS RHYTHM CLIENT / macOS</p>
|
||||
<h1>PLAY YOUR<br />OWN RHYTHM.</h1>
|
||||
<p class="hero__lead">
|
||||
보유한 BMS 라이브러리를 연결하고, 선곡부터 기록과 레이팅까지
|
||||
하나의 흐름으로 즐기세요.
|
||||
</p>
|
||||
<div class="hero__actions">
|
||||
<a class="button button--primary" href="/download/">
|
||||
<span>MACOS ALPHA 받기</span><span aria-hidden="true">→</span>
|
||||
</a>
|
||||
<a class="button button--ghost" href="/resources/">
|
||||
BMS 콘텐츠 찾기
|
||||
</a>
|
||||
</div>
|
||||
<ul class="hero__facts" aria-label="지원 정보">
|
||||
<li>UNIVERSAL macOS</li>
|
||||
<li>4K · 5K · 6K · 7K</li>
|
||||
<li>LOCAL LIBRARY</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="select-preview" aria-label="ProjectQuint 선곡 화면을 형상화한 미리보기">
|
||||
<div class="select-preview__top">
|
||||
<span>MUSIC SELECT</span>
|
||||
<div class="select-preview__tools" aria-hidden="true">
|
||||
<i></i><i></i><i></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="select-preview__body">
|
||||
<div class="select-preview__info">
|
||||
<div class="jacket-motif" aria-hidden="true">
|
||||
<span>Q</span>
|
||||
</div>
|
||||
<p>PROJECT QUINT</p>
|
||||
<strong>LV 18</strong>
|
||||
<small>6K · BPM 154</small>
|
||||
</div>
|
||||
<div class="track-list" aria-hidden="true">
|
||||
<div class="track"><b>14</b><span>Signal Path</span><em></em></div>
|
||||
<div class="track"><b>16</b><span>Daylight Prism</span><em></em></div>
|
||||
<div class="track is-selected"><b>18</b><span>Project Quint</span><em></em></div>
|
||||
<div class="track"><b>19</b><span>Afterimage</span><em></em></div>
|
||||
<div class="track"><b>20</b><span>Neon Archive</span><em></em></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="select-preview__bottom">
|
||||
<span>SEARCH 1</span><span>SORT 7</span><span>FILTER 8</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="feature-section">
|
||||
<div class="section-heading">
|
||||
<p class="eyebrow">DESIGNED FOR PLAY</p>
|
||||
<h2>라이브러리는 로컬에.<br />플레이는 선명하게.</h2>
|
||||
</div>
|
||||
<div class="feature-grid">
|
||||
{
|
||||
features.map((feature) => (
|
||||
<article class="feature-card">
|
||||
<span>{feature.index}</span>
|
||||
<h3>{feature.title}</h3>
|
||||
<p>{feature.copy}</p>
|
||||
</article>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="Privacy"
|
||||
description="ProjectQuint 웹사이트 개인정보 안내."
|
||||
>
|
||||
<section class="page-hero">
|
||||
<p class="eyebrow">SITE POLICY</p>
|
||||
<h1>PRIVACY</h1>
|
||||
<p class="page-hero__lead">
|
||||
이 사이트는 ProjectQuint 정보와 배포 안내만을 위해 최소한으로 운영됩니다.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section class="prose-card">
|
||||
<h2>수집 기능</h2>
|
||||
<p>
|
||||
별도의 방문자 분석 도구, 광고 추적기, 회원가입, 댓글 또는 문의 양식을
|
||||
사용하지 않습니다. 브라우저에 사용자 식별용 쿠키를 저장하지 않습니다.
|
||||
</p>
|
||||
<h2>서버 로그</h2>
|
||||
<p>
|
||||
서비스 보안과 장애 대응을 위해 웹서버가 접속 시각, 요청 주소, IP 주소,
|
||||
사용자 에이전트 등의 표준 접속 기록을 일시적으로 남길 수 있습니다.
|
||||
</p>
|
||||
<h2>외부 링크</h2>
|
||||
<p>
|
||||
BMS 제작자와 커뮤니티 사이트는 각자의 정책에 따라 운영됩니다. 외부
|
||||
페이지를 이용하기 전에 해당 사이트의 안내를 확인해 주세요.
|
||||
</p>
|
||||
<h2>운영 주체</h2>
|
||||
<p>
|
||||
공개 페이지에는 개인 계정이나 개인 프로필을 연결하지 않으며,
|
||||
운영 표기는 ProjectQuint로 통일합니다.
|
||||
</p>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
import BaseLayout from "../layouts/BaseLayout.astro";
|
||||
|
||||
const resources = [
|
||||
{
|
||||
kind: "4K / 6K PACK & TABLE",
|
||||
title: "U_E",
|
||||
copy: "4키·6키 BMS 팩과 난이도표를 제공하는 커뮤니티 프로젝트입니다.",
|
||||
href: "https://sites.google.com/view/6k4kbms",
|
||||
language: "KOREAN"
|
||||
},
|
||||
{
|
||||
kind: "5K PACK & TABLE",
|
||||
title: "AERY",
|
||||
copy: "5키 BMS 팩과 난이도표를 찾아볼 수 있는 커뮤니티 사이트입니다.",
|
||||
href: "https://asumatoki.kr/",
|
||||
language: "KOREAN"
|
||||
},
|
||||
{
|
||||
kind: "SEARCH & DISCOVERY",
|
||||
title: "BMS SEARCH",
|
||||
copy: "개별 BMS, 제작자, 이벤트와 플레이리스트를 탐색하는 검색 사이트입니다.",
|
||||
href: "https://bmssearch.net/",
|
||||
language: "JAPANESE"
|
||||
},
|
||||
{
|
||||
kind: "RESOURCE DIRECTORY",
|
||||
title: "BMS COMMUNITY RESOURCES",
|
||||
copy: "스타터팩, 이벤트팩, 난이도표, 플레이어와 도구를 정리한 종합 목록입니다.",
|
||||
href: "https://bms-community.github.io/resources/",
|
||||
language: "ENGLISH"
|
||||
},
|
||||
{
|
||||
kind: "PLAYER GUIDE",
|
||||
title: "BMS / BEATORAJA GUIDE",
|
||||
copy: "BMS 입문, 곡을 찾는 방법과 난이도표의 구조를 설명하는 종합 가이드입니다.",
|
||||
href: "https://wcko87.github.io/beatoraja-english-guide/",
|
||||
language: "ENGLISH"
|
||||
}
|
||||
];
|
||||
---
|
||||
|
||||
<BaseLayout
|
||||
title="BMS Resources"
|
||||
description="ProjectQuint에서 즐길 BMS 콘텐츠를 찾을 수 있는 외부 커뮤니티 사이트 안내."
|
||||
>
|
||||
<section class="page-hero page-hero--split">
|
||||
<div>
|
||||
<p class="eyebrow">COMMUNITY LINKS</p>
|
||||
<h1>BMS RESOURCES</h1>
|
||||
<p class="page-hero__lead">
|
||||
ProjectQuint가 파일을 다시 배포하는 대신, 제작자와 커뮤니티가
|
||||
관리하는 원래 페이지로 안내합니다.
|
||||
</p>
|
||||
</div>
|
||||
<div class="resource-count">
|
||||
<strong>{resources.length.toString().padStart(2, "0")}</strong>
|
||||
<span>CURATED<br />STARTING POINTS</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="resource-list" aria-label="BMS 외부 사이트">
|
||||
{
|
||||
resources.map((resource, index) => (
|
||||
<a
|
||||
class="resource-row"
|
||||
href={resource.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span class="resource-row__index">
|
||||
{(index + 1).toString().padStart(2, "0")}
|
||||
</span>
|
||||
<div class="resource-row__main">
|
||||
<small>{resource.kind}</small>
|
||||
<h2>{resource.title}</h2>
|
||||
<p>{resource.copy}</p>
|
||||
</div>
|
||||
<span class="resource-row__language">{resource.language}</span>
|
||||
<span class="resource-row__arrow" aria-hidden="true">↗</span>
|
||||
</a>
|
||||
))
|
||||
}
|
||||
</section>
|
||||
|
||||
<section class="legal-note">
|
||||
<h2>외부 콘텐츠 안내</h2>
|
||||
<p>
|
||||
ProjectQuint는 위 사이트와 팩을 운영하거나 보증하지 않으며, 음원·채보·이미지를
|
||||
이 사이트에 복제하지 않습니다. 다운로드와 이용 전 각 제작자 및 배포처의 최신
|
||||
조건을 확인해 주세요. 외부 페이지의 내용과 주소는 예고 없이 변경될 수 있습니다.
|
||||
</p>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict"
|
||||
}
|
||||
Reference in New Issue
Block a user