feat(skill): 자율 검증 폐쇄 루프 내재화 — 0.6.0
Some checks failed
ci / build (push) Failing after 5s

- 핵심 규칙 6: 완료의 정의는 게이트 통과. 사용자를 QA로 쓰지 않는다
- 5단계 기계 검사 4번째: design-gate 실행 의무화
- references/audit-gate.md: 사고-검사 매핑, SEO/meta 체크리스트, OS/브라우저 특성, 하니스 규칙
- tools/design-gate.mjs: 범용 게이트(메타/SEO·대비·수축·리듬·트랙·스케일×폭 + 옵션 L0/L3/L4, checks 깊은 병합)
- 리듬·트랙 불변식: 숫자 라벨 등폭·빈 셀 트랙 균일·등간격 — 시간표 자동배치 결함 재현 픽스처 검출, 앱 15뷰 통과(오탐 0)

feat(site): 관리 앱 2종 프로덕션 콘솔(v6→v18)

- 가온 학적부 9뷰·두레 수강신청 6뷰: shadcn 문법, Pretendard/Noto Serif/IBM Plex 폰트 전략, 볼드 금지(400/500/600), WCAG AA 대비 전면 교정, 한글 keep-all 조판
- LMS 필수 요소(알림 센터·공지·진도·평가 유형·출결 사유·학점 경고), 12명 기준 데이터 정합, SEO 구조(h1 유일·OG/twitter·og.png)
- 시간표 자동배치 결함 수리(명시적 격자 좌표)
- QA 게이트: L0 stylelint/html-validate · L1 단위 30 · L2 감사 61+불변식 · L3 시각회귀 30화면 · L4 WebKit · L5 키보드 탐색 — npm run verify 실패 시 배포 금지 체인
This commit is contained in:
Yun Chan 2026-08-22 21:22:05 +09:00
parent 78ddc8b61a
commit 72337b7ee0
226 changed files with 18212 additions and 380 deletions

View file

@ -0,0 +1,322 @@
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>궤도 우주공학 · 75kN 메탄 엔진 사양서</title>
<meta
name="description"
content="75kN급 메탄-액체산소 재생냉각 엔진의 단면도와 지상 연소 시험 기록. 사양은 전부 지상 시험 실측값이다."
/>
<meta property="og:title" content="궤도 우주공학 · 75kN 메탄 엔진" />
<meta property="og:description" content="재생냉각 엔진의 단면도와 연소 시험 기록." />
<meta property="og:type" content="website" />
<meta name="theme-color" content="#081018" />
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
/>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
/>
<link rel="stylesheet" href="./styles/main.css?v=2" />
<link
rel="icon"
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23081018'/%3E%3Cpath d='M16 4l6 7v17h-12V11z' fill='none' stroke='%23C57A45' stroke-width='1.6'/%3E%3Cpath d='M13 11h6M12 18h8' stroke='%23C57A45'/%3E%3C/svg%3E"
/>
</head>
<body>
<a class="skip" href="#main">본문으로 건너뛰기</a>
<header class="site-head">
<div class="wrap head-inner">
<a class="wordmark" href="#main">궤도 우주공학 <span class="wordmark-en">ORBIT</span></a>
<nav class="nav" aria-label="섹션">
<a href="#engine">엔진</a>
<a href="#spec">사양</a>
<a href="#fires">시험 기록</a>
<a href="#contact">문의</a>
</nav>
</div>
</header>
<main id="main">
<!--
히어로 — 문구 대신 도면. 엔진 단면도가 첫 화면의 주인공이다.
이 도면은 장식이 아니라 사양서의 1페이지다: 라벨은 실제 부품 이름.
-->
<section class="hero" aria-labelledby="hero-h">
<div class="wrap hero-grid">
<div class="hero-text">
<p class="hero-kicker reveal">75kN 메탄-액체산소 · 재생냉각 · 2024</p>
<h1 id="hero-h" class="reveal" style="--delay: 60ms">
도면은 말하지 않는다.<br />측정만 한다
</h1>
<p class="lead reveal" style="--delay: 120ms">
이 페이지의 모든 수치는 지상 연소 시험에서 잰 값입니다. 홍보 문구에
쓸 수 없는 숫자는 사양서에도 넣지 않습니다. 추력, 비추력, 연소실
압력 — 어디서, 몇 초 동안 재었는지가 숫자와 함께 갑니다.
</p>
<a class="btn reveal" style="--delay: 180ms" href="#spec">사양 전문 보기</a>
</div>
<figure class="blueprint reveal" style="--delay: 100ms">
<svg
viewBox="0 0 460 560"
role="img"
aria-label="엔진 단면도: 상부 인젝터, 연소실, 중앙 스로트, 확장 노즐과 벽면의 재생냉각 유로"
>
<defs>
<g id="half">
<!-- 외벽: 연소실 → 스로트 → 노즐 -->
<path
class="bp-wall"
d="M 230 70
L 168 70
L 168 210
C 168 250 194 262 194 286
C 194 310 118 350 112 470
L 108 500"
/>
<!-- 내벽 -->
<path
class="bp-wall inner"
d="M 230 92
L 184 92
L 184 214
C 184 246 206 258 206 284
C 206 306 136 348 130 468
L 127 494"
/>
<!-- 재생냉각 유로 (내벽을 따라가는 가는 선 2줄) -->
<path
class="bp-cool"
d="M 176 100 L 176 212 C 176 248 198 262 198 286 C 198 308 126 350 121 468 L 118 492"
/>
<path
class="bp-cool"
d="M 170 100 L 170 210 C 170 244 192 260 192 288 C 192 312 120 352 114 470 L 111 496"
/>
<!-- 인젝터 매니폴드 -->
<rect class="bp-block" x="168" y="46" width="50" height="18" />
<path class="bp-wall thin" d="M 168 64 L 218 64" />
</g>
</defs>
<use href="#half" />
<use href="#half" transform="translate(460 0) scale(-1 1)" />
<!-- 중심선 -->
<path class="bp-axis" d="M 230 30 V 540" />
<!-- 유동 화살표 -->
<g class="bp-flow">
<path d="M 230 120 V 220" />
<path d="M 230 220 l -5 10 M 230 220 l 5 10" />
</g>
<!-- 라벨 -->
<g class="bp-label">
<path class="bp-lead" d="M 218 55 H 150" />
<text x="144" y="59" text-anchor="end">인젝터</text>
<path class="bp-lead" d="M 168 160 H 96" />
<text x="90" y="164" text-anchor="end">연소실</text>
<path class="bp-lead" d="M 200 275 H 78" />
<text x="72" y="279" text-anchor="end">스로트</text>
<path class="bp-lead" d="M 128 400 H 60" />
<text x="54" y="404" text-anchor="end">노즐</text>
<path class="bp-lead" d="M 186 180 H 120" />
<text x="114" y="196" text-anchor="end"></text>
<text x="242" y="150">재생냉각</text>
<text x="242" y="166">유로 (CH₄)</text>
</g>
<g class="bp-dim">
<path d="M 356 92 H 372 M 364 92 V 214" />
<text x="380" y="157"></text>
</g>
<g class="bp-dim">
<path d="M 60 500 H 96 M 78 500 V 520" />
<text x="60" y="542">Ø 460 — 노즐 출구</text>
</g>
</svg>
<figcaption>ORBIT-75 단면 · 재생냉각 벽면은 그림 2겹으로 단순화</figcaption>
</figure>
</div>
</section>
<!--
사양 — 표가 주인공. 전 항목 측정 조건이 붙는다(게이트 11의 해법).
-->
<section id="spec" class="section band" aria-labelledby="spec-h">
<div class="wrap">
<h2 id="spec-h" class="reveal">사양</h2>
<div class="table-wrap reveal" style="--delay: 80ms">
<table>
<caption class="sr-only">ORBIT-75 엔진 사양 — 항목, 값, 측정 조건</caption>
<thead>
<tr>
<th scope="col">항목</th>
<th scope="col" class="num"></th>
<th scope="col">측정 조건</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">추력 (해수면)</th>
<td class="num">75.4 kN</td>
<td>지상 시험 스탠드 · 정상 상태 30초 평균</td>
</tr>
<tr>
<th scope="row">비추력 Isp (진공)</th>
<td class="num">325.8 s</td>
<td>고도 모사 노즐 · 추진제 혼합비 3.4</td>
</tr>
<tr>
<th scope="row">연소실 압력</th>
<td class="num">12.5 MPa</td>
<td>피에조 계측 · 샘플링 1kHz</td>
</tr>
<tr>
<th scope="row">사이클</th>
<td class="num">다단연소</td>
<td>연료리치 프리버너 1기</td>
</tr>
<tr>
<th scope="row">냉각</th>
<td class="num">재생냉각</td>
<td>구리합금 채널 180개 · CH₄ 유량 92%</td>
</tr>
<tr>
<th scope="row">시동 신호→연소</th>
<td class="num">2.8 s</td>
<td>TEA-TEB 점화 · 12회 평균</td>
</tr>
</tbody>
</table>
</div>
<p class="measure-note reveal" style="--delay: 140ms">
모든 값은 나주 지상 시험장, 2026년 상반기 12회 시험의 평균입니다.
단일 최고값을 사양으로 적지 않습니다.
</p>
</div>
</section>
<!--
시험 기록 — 아카이브. 성공만 남기지 않는다: 3번의 보류가 있다.
-->
<section id="fires" class="section" aria-labelledby="fires-h">
<div class="wrap fires-grid">
<div class="fires-text">
<h2 id="fires-h">지상 연소 시험 기록</h2>
<p>
엔진은 도면으로 끝나지 않습니다. 우리는 보류된 시험도 지운 적이
없습니다 — 기록에서 실패가 사라지면 사양서는 광고가 됩니다.
</p>
</div>
<div class="table-wrap reveal">
<table>
<caption class="sr-only">지상 연소 시험 기록 — 번호, 날짜, 지속, 결과</caption>
<thead>
<tr>
<th scope="col">시험</th>
<th scope="col">날짜</th>
<th scope="col" class="num">지속</th>
<th scope="col">결과</th>
</tr>
</thead>
<tbody>
<tr><th scope="row">SF-31</th><td>2026-07-18</td><td class="num">62 s</td><td>완료 · 노즐 온도 상한 내</td></tr>
<tr><th scope="row">SF-30</th><td>2026-06-27</td><td class="num">31 s</td><td>보류 · 프리버너 시동 지연</td></tr>
<tr><th scope="row">SF-29</th><td>2026-06-02</td><td class="num">60 s</td><td>완료 · 추력 편차 0.4%</td></tr>
<tr><th scope="row">SF-28</th><td>2026-05-11</td><td class="num">12 s</td><td>보류 · 냉각유로 압력 강하</td></tr>
<tr><th scope="row">SF-27</th><td>2026-04-20</td><td class="num">58 s</td><td>완료</td></tr>
</tbody>
</table>
</div>
</div>
</section>
<!--
시험 사진 — 풀블리드 판. 마하 다이아몬드가 보일 때만 쓴다.
-->
<section class="section plate" aria-label="지상 연소 시험 사진">
<figure class="plate-fig reveal">
<img
src="./assets/static-fire.webp"
alt="야간 지상 연소 시험 — 구리 노즐이 열로 붉게 빛나고 배기 기둥에 마하 다이아몬드가 서 있다"
width="1440"
height="810"
loading="lazy"
/>
<figcaption class="wrap">SF-29 · 60초 연소 · 나주 시험장 3번 스탠드</figcaption>
</figure>
</section>
<!--
재생냉각 — 구리 유로 접사 + 설명.
-->
<section class="section cooling" aria-labelledby="cool-h">
<div class="wrap two">
<figure class="two-photo reveal">
<img
src="./assets/channel-macro.webp"
alt="구리합금 블록의 단면에 밀링된 가느다란 재생냉각 유로들"
width="900"
height="1200"
loading="lazy"
/>
<figcaption>연소실 유로 접사 · 밀링 후 청소 전</figcaption>
</figure>
<div class="two-text">
<h2 id="cool-h">추진제가 벽을<br />먼저 식힙니다</h2>
<p>
연소실 벽은 3,200°C의 가스를 견디는 게 아닙니다 — 견디게 두지
않습니다. 메탄 연료가 점화 전에 벽 속 180개 유로를 지나가며 실온에서
320°C까지 데워지고, 그 사이 벽은 900°C 아래로 머뭅니다. 냉각에 쓴
추진제는 그대로 연소실로 들어가니 버리는 열이 없습니다.
</p>
<p class="muted">
유로 하나의 폭은 0.9mm입니다. 이 숫자가 이 엔진의 수명을 결정합니다 —
도면에서 가장 작은 치수가 가장 중요한 치수입니다.
</p>
</div>
</div>
</section>
<!-- 문의 -->
<section id="contact" class="section band contact" aria-labelledby="contact-h">
<div class="wrap contact-grid">
<h2 id="contact-h">문의</h2>
<p>
발사체 통합·위성 투입 협의, 그리고 엔진 시험 데이터 전문은 아래로
보내주세요. 기술 자료 요청에는 소속과 용도를 적어주세요.
</p>
<a class="btn" href="mailto:engine@orbit.kr">engine@orbit.kr</a>
</div>
</section>
</main>
<footer class="site-foot">
<div class="wrap foot-inner">
<p>궤도 우주공학 · 나주 시험장 / 서울 사무실</p>
<p class="mono foot-meta">ORBIT AEROSPACE · EST. 2020</p>
</div>
</footer>
<script>
const io = new IntersectionObserver(
(entries) => {
for (const e of entries) {
if (!e.isIntersecting) continue;
e.target.classList.add("is-in");
io.unobserve(e.target);
}
},
{ rootMargin: "0px 0px -8% 0px", threshold: 0.05 },
);
for (const el of document.querySelectorAll(".reveal")) io.observe(el);
</script>
</body>
</html>