| name | web-frontend-build |
| description | 디자인 토큰 기반의 HTML 시맨틱 마크업, 모듈화된 CSS, Vanilla JS 인터랙션, 반응형 레이아웃, 다크/라이트 모드, 스크롤 기반 네비게이션을 구현하는 프론트엔드 빌드 스킬. 정적 사이트(no build step) HTML/CSS/JS 빌드 요청 시 반드시 사용. |
Web Frontend Build Skill
web/_design/*를 입력으로 받아 web/index.html, web/styles/*.css, web/scripts/main.js를 빌드하는 워크플로우. 빌드 도구 없이 정적 파일로 동작.
워크플로우
Step 1: 진입점 HTML 구조 (web/index.html)
<!DOCTYPE html>
<html lang="ko" data-theme="dark">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>SK하이닉스 다각도 분석 보고서 — 2026-05-12</title>
<meta name="description" content="..." />
<meta name="theme-color" content="#0a0e1a" />
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
<link rel="stylesheet" href="./styles/main.css">
<link rel="stylesheet" href="./styles/components.css">
<link rel="stylesheet" href="./styles/animations.css">
<link rel="stylesheet" href="./styles/responsive.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5"></script>
</head>
<body>
<canvas id="bg-canvas" aria-hidden="true"></canvas>
<header class="site-header" id="site-header">
<nav class="site-nav" aria-label="섹션 네비게이션">
<a href="#hero" class="logo">SK하이닉스 분석</a>
<ul class="nav-links">
<li><a href="#summary">요약</a></li>
<li><a href="#analysis">분석</a></li>
<li><a href="#scenarios">시나리오</a></li>
<li><a href="#monitoring">모니터링</a></li>
</ul>
<button class="theme-toggle" aria-label="테마 전환">🌙</button>
</nav>
</header>
<main>
<section id="hero" class="hero">
<h1 class="hero-title">
<span class="display-1">SK하이닉스</span>
<span class="hero-subtitle">다각도 분석 보고서 · 2026-05-12</span>
</h1>
<div class="meta-metrics" data-stagger>
<div class="metric-card">
<span class="metric-label">현재가</span>
<span class="metric-value" data-countup="1861000">1,861,000</span>
<span class="metric-unit">원</span>
<span class="metric-delta delta-down">▼1.01%</span>
</div>
</div>
<div class="scroll-indicator" aria-hidden="true">scroll</div>
</section>
<section id="summary" class="section">
<h2>Executive Summary</h2>
<p class="tldr">현재가 약 1,861,000원 · 시가총액 1,319조원 · 1Y +871% ...</p>
<div class="summary-grid">
<div class="summary-card strength">
<h3>핵심 강점 3</h3>
<ul>...</ul>
</div>
<div class="summary-card concern">
<h3>핵심 우려 3</h3>
<ul>...</ul>
</div>
</div>
</section>
<section id="analysis" class="section">
<h2>5개 분석 영역</h2>
<article class="analysis-block" id="analysis-market">
<header><h3>1. 시장 데이터</h3></header>
<div class="chart-container" data-chart>
<canvas id="chart-price"></canvas>
</div>
<p class="analysis-body">...</p>
</article>
</section>
<section id="scenarios" class="section">
<h2>시나리오 분석</h2>
</section>
<section id="monitoring" class="section">
<h2>모니터링 타임라인</h2>
</section>
<section id="appendix" class="section">
<h2>부록</h2>
<details>
<summary>데이터 출처</summary>
</details>
<details>
<summary>분석 한계 (Caveats)</summary>
</details>
</section>
</main>
<footer class="site-footer">
<p>작성: SK Hynix Analysis Team · 2026-05-12 · 정보 제공 목적이며 투자 자문이 아닙니다</p>
</footer>
<script type="module" src="./scripts/main.js"></script>
<script type="module" src="./scripts/background-animation.js"></script>
<script type="module" src="./scripts/scroll-animations.js"></script>
<script type="module" src="./scripts/microinteractions.js"></script>
<script type="module" src="./scripts/charts.js"></script>
</body>
</html>
Step 2: CSS 디자인 시스템 (web/styles/main.css)
:root[data-theme="dark"] {
--bg-primary: #0a0e1a;
--bg-secondary: #111827;
--bg-elevated: #1f2937;
--text-primary: #f8fafc;
--text-secondary: #cbd5e1;
--text-tertiary: #94a3b8;
--accent-primary: #06b6d4;
}
:root[data-theme="light"] {
--bg-primary: #ffffff;
--bg-secondary: #f8fafc;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
font-family: 'Inter', 'Pretendard', sans-serif;
background: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
overflow-x: hidden;
}
.display-1 { font-size: clamp(48px, 8vw, ); : ; : ; : -; }
{ : (, , ); : ; : ; }
{ : (, , ); : ; }
{ : (, , ); : ; : ; }
{ : ; : ; }
{ : ; : auto; : ; }
{ : ; }
{
: sticky; : ; : ;
: ();
: (in srgb, (--bg-primary) , transparent);
: solid (in srgb, (--text-tertiary) , transparent);
}
{
: fixed; : ; : -;
: none;
}
(: reduce) {
*, *, * {
: ;
: ;
}
}
Step 3: 컴포넌트 CSS (web/styles/components.css)
.metric-card {
padding: 24px;
background: color-mix(in srgb, var(--bg-secondary) 60%, transparent);
backdrop-filter: blur(8px);
border: 1px solid color-mix(in srgb, var(--text-tertiary) 15%, transparent);
border-radius: 20px;
transition: transform 300ms cubic-bezier(0.2, 0, 0, 1), box-shadow 300ms;
}
.metric-card:hover {
transform: translateY(-2px);
box-shadow: 0 16px 48px rgba(0,0,0,0.4), 0 0 32px rgba(6, 182, 212, 0.15);
}
.metric-value {
font-family: 'JetBrains Mono', monospace;
font-size: clamp(36px, , );
: ;
}
{ : (--bull); }
{ : (--bear); }
{
: ;
: (in srgb, (--bg-elevated) , transparent);
: ();
: ;
: solid (in srgb, (--accent-primary) , transparent);
}
{ : (in srgb, (--bull) , transparent); }
{ : (in srgb, (--bear) , transparent); }
{
: (--bg-secondary);
: ;
: ;
: ;
}
{ : solid (--bear); }
{ : solid (--accent-primary); }
{ : solid (--bull); }
{ : grid; : ; }
{
: grid;
: fr auto;
: ;
: ;
: solid (--accent-primary);
}
Step 4: 반응형 CSS (web/styles/responsive.css)
@media (min-width: 768px) {
.meta-metrics { grid-template-columns: repeat(3, 1fr); }
.summary-grid { grid-template-columns: 1fr 1fr; }
.nav-links { display: flex; gap: 32px; }
}
@media (min-width: 1280px) {
main { padding: 0 48px; }
.section { padding: 128px 0; }
}
@container (min-width: 600px) {
.chart-container { padding: 48px; }
}
Step 5: 진입 JS (web/scripts/main.js)
const toggle = document.querySelector('.theme-toggle');
const root = document.documentElement;
const stored = localStorage.getItem('theme');
if (stored) root.dataset.theme = stored;
toggle.addEventListener('click', () => {
const next = root.dataset.theme === 'dark' ? 'light' : 'dark';
root.dataset.theme = next;
localStorage.setItem('theme', next);
toggle.textContent = next === 'dark' ? '🌙' : '☀️';
});
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('.nav-links a');
const navObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
(entry.) {
navLinks.( a..(, a.() === ));
}
});
}, { : });
sections.( navObserver.(s));
{ initAllCharts } ;
{ populateData } ;
( () => {
data = ().( r.());
(data);
(data);
})();
Step 6: 데이터 로더 (web/scripts/data-loader.js)
data.json에서 텍스트·리스트·테이블 데이터를 DOM에 주입. 강점/우려/시나리오/타임라인 등.
작업 원칙
- No build step: ESM modules + CDN libs로 직접 로드
- 시맨틱 마크업:
<section>, <article>, <nav>, <main> 정확히. heading 위계 H1→H2→H3 일관성
- CSS Custom Properties로 토큰: 하드코딩 컬러·사이즈 금지
- 접근성: 키보드 focus visible, alt 텍스트, ARIA labels, prefers-reduced-motion
- 성능: 이미지 lazy loading, font-display: swap, 차트는 IntersectionObserver로 lazy init
- 모바일 우선: 320px 기준, breakpoint 768·1280
팀 통신
- design-lead로부터 토큰·IA·카탈로그 수신
- visualization-engineer로부터 차트 컨테이너 ID 명세 수신 → HTML에 정확히 배치
- motion-designer로부터 배경 캔버스·인터랙션 트리거 클래스 명세 수신
- web-qa로부터 마크업/접근성/반응형 검증 결과 수신 → 수정
후속 실행 시
이전 HTML/CSS/JS 보존, 변경 부분만 수정. 새 컴포넌트 추가 시 component-catalog 갱신 확인.