프로젝트 소스 공개

This commit is contained in:
2026-09-06 17:11:40 +09:00
commit 0f0431de5a
676 changed files with 106118 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
node_modules/
dist/
.astro/
.DS_Store
+37
View File
@@ -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
}
}
});
+45
View File
@@ -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;
}
}
File diff suppressed because it is too large Load Diff
+19
View File
@@ -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

@@ -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 &amp; 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
+3
View File
@@ -0,0 +1,3 @@
{
"extends": "astro/tsconfigs/strict"
}