mirim-app/frontend/public/docs/cs-curriculum.html
AWESOMEDEV 5c9959ce08
All checks were successful
CI / backend-test (push) Successful in 3m25s
CI / frontend-build (push) Successful in 48s
CI / backend-dep-scan (push) Successful in 31s
feat(design): 디자인 시스템 — Pretendard 실적용·토큰·Lucide 아이콘 132개·/design
이모지 아이콘을 SVG로 바꾸다가, 더 큰 원인을 발견해 함께 고쳤다.

■ 폰트: 이름만 부르고 파일은 안 받아오고 있었다
  global.css에 font-family: "Pretendard"가 적혀 있었지만 @font-face도 CDN
  링크도 없었다. 그래서 이 글꼴이 따로 깔린 사람 외에는 전원 맑은 고딕으로
  보고 있었다 — 앱과 학습 문서 19개 전부. 에러가 안 나서 조용히 넘어간 케이스.
  - PretendardStdVariable.woff2(285KB)를 public/fonts에 self-host
    · CDN 의존 없음 → 외부 서비스가 죽어도, 오프라인에서도 안 깨진다
    · variable font → 파일 하나가 굵기 45~920을 전부 담는다
    · font-display: swap → 받는 동안 흰 화면(FOIT) 방지
  - 전체판(2MB) 대신 Std판(상용 한글 2,350자)을 골랐다. 앱이 쓰는 한글
    1,276자가 Std에 전부 있는지 브라우저에서 실측 확인했다(폴백 0자).
  - 학습 문서 19개에도 같은 @font-face 적용

■ 아이콘: 이모지 95종 → Lucide 132개
  이모지는 OS마다 다른 그림으로 렌더링되고, 굵기·색을 통제할 수 없고,
  스크린리더가 "bust in silhouette"처럼 읽는다.
  - 카탈로그의 icon: '📜'(문자) → Icon: ScrollText(컴포넌트)로 전환
  - strokeWidth={1.5}로 굵기 통일, aria-hidden으로 장식임을 명시
  - 개별 import만 사용(트리셰이킹) → gzip +14KB
  - slug: null인 '개발 환경 설치 가이드' 항목이 일괄 변환에서 누락돼
    Icon이 undefined가 될 뻔한 것을 정합성 검사(항목 수 vs Icon 수)로 잡았다

■ 토큰: 여백·글자 크기·굵기를 :root로 승격
  --space-1~7(4의 배수), --text-xs~2xl, --weight-*, --radius-sm/lg/full.
  값을 직접 박으면 다크 모드에서 깨지고 화면마다 미묘하게 어긋난다.
  CSS 프레임워크는 도입하지 않았다 — 손으로 쓴 global.css와 충돌하고,
  교재로서 "왜 이렇게 썼는지"가 사라지기 때문이다.

■ /design: 재료를 고르는 화면
  색·글자·여백·모서리를 실제 CSS 변수로 렌더링(다크 모드 자동 반영) +
  Lucide 아이콘 1,993개 검색·복사. lucide-react는 아이콘 하나를 이름 3개로
  내보내(Rocket/RocketIcon/LucideRocket) 5,981개처럼 보이므로 별칭을 걸렀다.
  아이콘 전체를 훑어야 해 무거운 화면이라 lazy로 분리했다
  → 첫 화면 번들은 1.9KB만 증가(575.57 → 577.44KB).

검증: ESLint 통과, Vitest 30개 통과, 프로덕션 빌드 성공, 콘솔 에러 0.
브라우저에서 수습 7카테고리 + 초급~특급 4과정 = 11개 화면 전수 확인
(각 12카드/12아이콘/이모지 0).

문서: DESIGN.md(폰트·토큰·비용), ICONS.md(규약·대응표 132행)
2026-07-22 21:10:28 +09:00

483 lines
29 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>CS 기본기 4주 커리큘럼</title>
<style>
/* 웹폰트: 앱과 같은 Pretendard를 문서에도 적용한다(선언만 있고 파일이 없던 문제 수정). */
@font-face {
font-family: "Pretendard";
src: url("/fonts/PretendardStdVariable.woff2") format("woff2-variations");
font-weight: 45 920;
font-display: swap;
}
:root {
--paper: #FAFBFD; --card: #FFFFFF; --ink: #101A28; --ink-soft: #46536A;
--ink-faint: #7B8798; --line: #E4E8F0; --line-soft: #EFF2F7;
--primary: #2159C5; --primary-soft: #E5EDFB; --primary-deep: #163F8F;
--amber: #B9772A; --amber-soft: #F6EBDA; --amber-line: #E4C79A;
--blue: #0E8C86; --blue-soft: #E0F1EF;
--code-bg: #F1F4F9;
--shadow: 0 1px 2px rgba(16,26,40,.05), 0 8px 24px -12px rgba(16,26,40,.16);
--radius: 14px;
}
@media (prefers-color-scheme: dark) {
:root {
--paper: #0B1017; --card: #131A24; --ink: #E8EDF4; --ink-soft: #A4B0C0;
--ink-faint: #74808F; --line: #263140; --line-soft: #1C242F;
--primary: #6AA0F0; --primary-soft: #172A44; --primary-deep: #AECBF8;
--amber: #DBA25C; --amber-soft: #2C2318; --amber-line: #4A3B23;
--blue: #4FC7BE; --blue-soft: #14302E;
--code-bg: #161E28;
--shadow: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.65);
}
}
:root[data-theme="light"] {
--paper: #FAFBFD; --card: #FFFFFF; --ink: #101A28; --ink-soft: #46536A;
--ink-faint: #7B8798; --line: #E4E8F0; --line-soft: #EFF2F7;
--primary: #2159C5; --primary-soft: #E5EDFB; --primary-deep: #163F8F;
--amber: #B9772A; --amber-soft: #F6EBDA; --amber-line: #E4C79A;
--blue: #0E8C86; --blue-soft: #E0F1EF; --code-bg: #F1F4F9;
--shadow: 0 1px 2px rgba(16,26,40,.05), 0 8px 24px -12px rgba(16,26,40,.16);
}
:root[data-theme="dark"] {
--paper: #0B1017; --card: #131A24; --ink: #E8EDF4; --ink-soft: #A4B0C0;
--ink-faint: #74808F; --line: #263140; --line-soft: #1C242F;
--primary: #6AA0F0; --primary-soft: #172A44; --primary-deep: #AECBF8;
--amber: #DBA25C; --amber-soft: #2C2318; --amber-line: #4A3B23;
--blue: #4FC7BE; --blue-soft: #14302E; --code-bg: #161E28;
--shadow: 0 1px 2px rgba(0,0,0,.35), 0 10px 30px -14px rgba(0,0,0,.65);
}
* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
margin: 0; background: var(--paper); color: var(--ink);
font-family: "Pretendard", "Apple SD Gothic Neo", "Malgun Gothic", "Noto Sans KR", system-ui, sans-serif;
line-height: 1.72; -webkit-font-smoothing: antialiased; letter-spacing: -0.01em;
}
.wrap { max-width: 860px; margin: 0 auto; padding: clamp(20px, 4vw, 48px); }
.eyebrow { font-size: 12px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--amber); display: flex; align-items: center; gap: 10px; }
.eyebrow::before { content: ""; width: 22px; height: 2px; background: var(--amber); border-radius: 2px; }
.eyebrow.green { color: var(--primary); } .eyebrow.green::before { background: var(--primary); }
.eyebrow.blue { color: var(--blue); } .eyebrow.blue::before { background: var(--blue); }
/* Masthead */
header.mast {
border: 1px solid var(--line); border-radius: var(--radius);
background: radial-gradient(120% 140% at 0% 0%, var(--amber-soft) 0%, transparent 55%), var(--card);
box-shadow: var(--shadow); padding: clamp(26px, 4vw, 42px);
}
.wordmark { font-size: 13px; font-weight: 800; letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-soft); }
.wordmark b { color: var(--amber); }
header.mast h1 { font-size: clamp(28px, 5.6vw, 42px); line-height: 1.14; margin: 16px 0 0; font-weight: 800; letter-spacing: -0.03em; text-wrap: balance; }
header.mast .lede { margin: 16px 0 0; font-size: clamp(15px, 2.4vw, 17px); color: var(--ink-soft); max-width: 56ch; }
.mast-meta { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 10px; }
.chip { font-size: 13px; font-weight: 600; color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line); padding: 6px 12px; border-radius: 999px; display: inline-flex; align-items: center; gap: 7px; }
.chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--amber); }
section { margin-top: clamp(34px, 6vw, 52px); scroll-margin-top: 20px; }
section > h2 { font-size: clamp(21px, 3.6vw, 27px); font-weight: 800; letter-spacing: -0.025em; margin: 14px 0 0; text-wrap: balance; }
section > .sub { color: var(--ink-soft); margin: 9px 0 0; font-size: 15.5px; max-width: 62ch; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(20px, 3vw, 28px); }
.mt { margin-top: 18px; } .mt-s { margin-top: 12px; }
p { margin: 0; } strong { font-weight: 700; }
/* How-we-run ops box */
.ops { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px,1fr)); gap: 0; }
.ops .o { padding: 6px 18px; border-left: 3px solid var(--amber); }
.ops .o:first-child { padding-left: 0; border-left: 0; }
.ops .o .k { font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--amber); }
.ops .o .v { margin-top: 5px; font-size: 14.5px; color: var(--ink); }
.ops .o .v b { font-weight: 700; }
@media (max-width:560px){ .ops .o { border-left: 0; border-top: 1px solid var(--line-soft); padding: 12px 0; } .ops .o:first-child { border-top:0; } }
/* Week block */
.week-head { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; margin-bottom: 4px; }
.week-badge { width: 62px; height: 62px; border-radius: 15px; background: var(--primary); color: #fff; display: grid; place-items: center; text-align: center; line-height: 1.05; box-shadow: var(--shadow); }
.week-badge .w { font-size: 11px; font-weight: 700; letter-spacing: 0.1em; opacity: .85; }
.week-badge .n { font-size: 24px; font-weight: 800; font-variant-numeric: tabular-nums; }
@media (prefers-color-scheme: dark){ .week-badge { color: #0E1512; } }
:root[data-theme="dark"] .week-badge { color: #0E1512; }
.w2 .week-badge { background: var(--amber); }
.w3 .week-badge { background: var(--blue); }
.w4 .week-badge { background: var(--primary-deep); }
.week-head h3 { margin: 0; font-size: clamp(19px,3.2vw,23px); font-weight: 800; letter-spacing: -0.02em; }
.week-head .goal { margin-top: 3px; color: var(--ink-soft); font-size: 14.5px; }
/* Daily rows */
.days { display: grid; gap: 0; margin-top: 6px; }
.day { display: grid; grid-template-columns: 66px 1fr; gap: 18px; padding: 18px 0; border-top: 1px solid var(--line-soft); }
.day:first-child { border-top: 0; }
.day .badge { font-size: 12px; font-weight: 800; letter-spacing: 0.03em; color: var(--primary); background: var(--primary-soft); border-radius: 8px; padding: 8px 4px; text-align: center; height: fit-content; white-space: nowrap; }
.w2 .day .badge { color: var(--amber); background: var(--amber-soft); }
.w3 .day .badge { color: var(--blue); background: var(--blue-soft); }
.w4 .day .badge { color: var(--primary-deep); background: var(--primary-soft); }
.day h4 { margin: 2px 0 0; font-size: 16px; font-weight: 800; letter-spacing: -0.01em; }
.meta { margin-top: 10px; display: grid; gap: 7px; }
.meta .m { display: grid; grid-template-columns: 74px 1fr; gap: 12px; font-size: 14px; align-items: start; }
.meta .m .lab { font-size: 11px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding-top: 3px; }
.meta .m.prac .lab { color: var(--amber); }
.meta .m.link .lab { color: var(--primary); }
.meta .m .txt { color: var(--ink-soft); }
.meta .m .txt b { color: var(--ink); font-weight: 600; }
code { font-family: "SF Mono","Cascadia Code","Consolas",ui-monospace,monospace; font-size: 0.9em; background: var(--code-bg); padding: 1px 6px; border-radius: 5px; letter-spacing: 0; }
.friday { background: var(--primary-soft); border-radius: 10px; padding: 4px 12px; }
.w2 .friday { background: var(--amber-soft); } .w3 .friday { background: var(--blue-soft); }
/* Designer track */
.dz { border: 1px dashed var(--blue); background: var(--blue-soft); border-radius: 12px; padding: 18px 20px; }
.dz .h { font-weight: 800; color: var(--blue); font-size: 14px; display: flex; align-items: center; gap: 8px; }
.dz p { color: var(--ink-soft); font-size: 14px; margin-top: 8px; }
.dz b { color: var(--ink); }
/* Check / assessment */
.assess { display: grid; gap: 12px; }
.assess .a { display: grid; grid-template-columns: 82px 1fr; gap: 16px; padding: 14px 0; border-top: 1px solid var(--line-soft); align-items: start; }
.assess .a:first-child { border-top: 0; }
.assess .a .wk { font-weight: 800; color: var(--primary); font-variant-numeric: tabular-nums; font-size: 14px; }
.assess .a .txt { font-size: 14.5px; color: var(--ink-soft); } .assess .a .txt b { color: var(--ink); font-weight: 600; }
.callout { margin-top:18px; border: 1px solid var(--amber-line); border-radius: var(--radius); background: var(--amber-soft); padding: 20px 24px; }
.callout h3 { margin: 0 0 6px; font-size: 16px; font-weight: 800; color: var(--ink); }
.callout p { color: var(--ink-soft); font-size: 14.5px; }
footer { margin-top: 48px; padding-top: 22px; border-top: 1px solid var(--line); color: var(--ink-faint); font-size: 13px; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 8px; }
@media (max-width: 560px) {
.day { grid-template-columns: 56px 1fr; gap: 12px; }
.meta .m { grid-template-columns: 60px 1fr; gap: 8px; }
.assess .a { grid-template-columns: 64px 1fr; }
}
@media print { body{background:#fff;} .card,header.mast,.week-badge{box-shadow:none;} section{break-inside:avoid;} }
</style>
</head>
<body>
<div class="wrap">
<header class="mast">
<div class="wordmark"><b>AWESOMEDEV</b> · 수습 교육 · Layer&nbsp;B</div>
<h1>컴퓨터 기본기<br>4주 커리큘럼</h1>
<p class="lede">개발 수습생 3명이 <strong>매일 아침 1시간</strong>씩, 4주 동안 컴퓨터의 뼈대를 잡는 과정이에요. 도구 사용법이 아니라 <strong>"컴퓨터가 어떻게 돌아가는가"</strong>를 배웁니다. 모든 주제는 마지막에 <strong>우리 회사 시스템</strong>으로 연결돼요.</p>
<div class="mast-meta">
<span class="chip"><span class="dot"></span>매일 아침 09:3010:30 · 20일</span>
<span class="chip"><span class="dot"></span>강의 20분 + 실습 40분</span>
</div>
</header>
<!-- How we run -->
<section id="how">
<div class="eyebrow">운영 방식</div>
<h2>이렇게 진행해요</h2>
<p class="sub">지루한 이론 통독은 안 해요. 짧게 배우고, 바로 손으로 확인하고, 우리 것에 붙입니다.</p>
<div class="card mt">
<div class="ops">
<div class="o"><div class="k">시간</div><div class="v"><b>매일 아침 1시간.</b> 하루를 가볍게 여는 루틴으로.</div></div>
<div class="o"><div class="k">구성</div><div class="v">강의 20분 → <b>실습 40분.</b> 듣기보다 해보기 위주.</div></div>
<div class="o"><div class="k">실습 언어</div><div class="v"><b>JavaScript</b>(React에서 쓰는 언어)로 개념 확인. 잡히면 <b>Java</b>(Spring Boot)로도 확인.</div></div>
<div class="o"><div class="k">마무리</div><div class="v">매일 <b>3줄 회고</b>, 금요일 <b>미니 퀴즈</b>로 이해도 확인.</div></div>
</div>
</div>
<div class="callout">
<h3>💡 멘토를 위한 한 가지 원칙</h3>
<p>모든 개념 끝에 꼭 <b>"그래서 우리 회사에선?"</b>을 붙여주세요. 학생이 배운 걸 우리 실제 스택(<b>React 웹 · Spring Boot · 클라우드 · React Native · Flutter</b>)에서 직접 보면, 죽은 지식이 살아 있는 이해가 됩니다.</p>
</div>
</section>
<!-- WEEK 1 -->
<section id="w1" class="w1">
<div class="eyebrow green">Week 1</div>
<div class="card mt">
<div class="week-head">
<div class="week-badge"><span class="w">WEEK</span><span class="n">1</span></div>
<div>
<h3>컴퓨터 구조 — 컴퓨터는 결국 뭘 하는 기계인가</h3>
<div class="goal">데이터가 0과 1로 저장되고, 부품들이 어떻게 협력해 프로그램을 실행하는지 이해해요.</div>
</div>
</div>
<div class="days">
<div class="day">
<div class="badge">1일차<br></div>
<div>
<h4>2진수 · 비트 · 바이트 — 모든 건 0과 1</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">10진수 ↔ 2진수 손으로 변환. 글자가 숫자로 바뀌는 것 보기(ASCII), <b>색이 숫자로</b>: <code>#15715A</code> 가 곧 RGB 숫자라는 것 확인.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">디자이너가 쓰는 색상 코드도, 사진 한 장도 전부 숫자 덩어리예요.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">2일차<br></div>
<div>
<h4>CPU · 메모리(RAM) · 저장장치 · 입출력</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">내 PC <b>작업 관리자</b>로 CPU·메모리 사용량 관찰. 비유로 정리: 책상=RAM(작업 공간), 책장=디스크(보관).</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 서비스를 올리는 <b>클라우드 서버</b>도 똑같은 부품 구성. 사양(vCPU·RAM)이 뭘 뜻하는지 함께 확인.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">3일차<br></div>
<div>
<h4>프로그램이 실행되면 벌어지는 일</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">소스코드 → 실행 과정 따라가기. 간단한 <b>JavaScript(Node)</b> 프로그램을 돌리며 <b>프로세스</b>가 메모리에 올라가는 것 관찰.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 만드는 <b>Spring Boot 서버 앱</b>도 이렇게 하나의 프로세스로 떠서 돌아가요.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">4일차<br></div>
<div>
<h4>네트워크 기초 — 컴퓨터끼리 대화하는 법</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">브라우저 <b>개발자도구 → Network 탭</b>으로 우리 사이트가 서버에 보내는 요청/응답 직접 보기. IP·포트·HTTP 개념.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리 <b>React 웹</b><b>REST API</b><b>Spring Boot 서버</b>에 요청을 보내는 흐름을 눈으로 확인.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">5일차<br></div>
<div>
<h4 class="friday">정리 &amp; 미니 퀴즈 &amp; 우리 시스템 세미나</h4>
<div class="meta">
<div class="m prac"><span class="lab">확인</span><span class="txt">한 주 개념 퀴즈(10문항). "왜 메모리가 부족하면 서버가 느려지나?"를 스스로 설명해보기.</span></div>
</div>
</div>
</div>
</div>
<div class="dz" style="margin-top:16px;">
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
<p><b>디자인 기본기 ①</b> — 색(색상·명도·채도, RGB/HEX), 타이포그래피 기초. + 컴퓨터가 색·이미지를 숫자로 다루는 원리는 개발자와 함께 들어요(협업 기반).</p>
</div>
</div>
</section>
<!-- WEEK 2 -->
<section id="w2" class="w2">
<div class="eyebrow">Week 2</div>
<div class="card mt">
<div class="week-head">
<div class="week-badge"><span class="w">WEEK</span><span class="n">2</span></div>
<div>
<h3>자료구조 — 데이터를 어떻게 담는가</h3>
<div class="goal">상황마다 왜 다른 그릇(구조)을 쓰는지 감을 잡고, 직접 만들어봐요.</div>
</div>
</div>
<div class="days">
<div class="day">
<div class="badge">6일차<br></div>
<div>
<h4>배열 · 리스트 — 순서대로 담기</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">JavaScript 배열로 <b>할 일 목록·상품 목록</b> 만들기 — 추가·삭제·인덱스로 꺼내기.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">화면에 목록을 뿌리는 모든 기능(<b>React의 리스트 렌더링</b>)이 결국 이 목록 데이터예요.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">7일차<br></div>
<div>
<h4>스택 · 큐 — 쌓기(LIFO)와 줄서기(FIFO)</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">스택·큐를 <b>직접 구현</b>. 스택=실행취소(Undo), 큐=먼저 온 순서대로 처리.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">알림·이벤트를 <b>들어온 순서대로 처리</b>하는 큐(Kafka) 개념의 씨앗.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">8일차<br></div>
<div>
<h4>해시 (맵 · 객체) — 열쇠로 한 번에 찾기</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">JavaScript 객체(Map)로 <b>아이디 → 사용자 정보</b> 캐시 흉내내기. 목록을 뒤지는 것 vs 바로 찾는 것 속도 비교.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">자주 쓰는 데이터를 빠르게 꺼내는 <b>캐시(Redis)가 왜 빠른가 = 해시</b> 덕분. 이 순간을 크게 강조!</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">9일차<br></div>
<div>
<h4>트리 — 계층으로 담기</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">폴더 구조·<b>JSON</b>을 트리로 그려보기. 부모-자식 관계 이해.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">웹 화면의 <b>HTML(DOM) 트리</b>, 서버가 주는 JSON 응답이 다 트리 구조.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">10일차<br></div>
<div>
<h4 class="friday">시간복잡도 맛보기 &amp; 미니 퀴즈</h4>
<div class="meta">
<div class="m prac"><span class="lab">확인</span><span class="txt">"왜 상황마다 다른 구조를 쓰나" = 빠른 것/순서 지키는 것의 차이. Big-O 감각만 가볍게. 퀴즈 10문항.</span></div>
</div>
</div>
</div>
</div>
<div class="dz" style="margin-top:16px;">
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
<p><b>디자인 기본기 ②</b> — 레이아웃·<b>그리드</b>·여백·정렬 원칙. 트리 개념은 함께 들어요(화면이 컴포넌트 트리로 구성된다는 이해 = 개발 협업의 핵심).</p>
</div>
</div>
</section>
<!-- WEEK 3 -->
<section id="w3" class="w3">
<div class="eyebrow blue">Week 3</div>
<div class="card mt">
<div class="week-head">
<div class="week-badge"><span class="w">WEEK</span><span class="n">3</span></div>
<div>
<h3>프로그램의 변화 — 지금 우리가 쓰는 것이 어디서 왔나</h3>
<div class="goal">언어와 소프트웨어가 어떻게 진화해 왔는지 큰 지도를 그리고, 우리 스택의 위치를 찾아요.</div>
</div>
</div>
<div class="days">
<div class="day">
<div class="badge">11일차<br></div>
<div>
<h4>언어의 진화 — 기계어에서 사람 말까지</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">같은 동작을 <b>저수준 vs 고수준</b>으로 비교. "왜 점점 사람 말에 가까워졌나" 이야기 나누기.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 Java·JavaScript 같은 고급 언어를 쓰는 이유.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">12일차<br></div>
<div>
<h4>프로그래밍 패러다임 — 절차 → 객체 → 함수</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">같은 문제를 <b>절차지향 vs 객체지향</b>으로 각각 짜보고 차이 느끼기.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리 백엔드(Java)가 <b>객체지향</b>인 이유, 프론트에 함수형 요소가 섞인 이유.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">13일차<br></div>
<div>
<h4>웹의 등장 — 클라이언트와 서버로 나뉘다</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">혼자 도는 프로그램 → 웹으로. <b>프론트엔드 / 백엔드</b>가 나뉜 이유와 역할 분담 정리.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리 <b>React 웹(프론트)</b><b>Spring Boot(백엔드)</b>가 딱 이 구도. 4일차 Network 탭과 이어짐.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">14일차<br></div>
<div>
<h4>아키텍처의 진화 — 모놀리식 → MSA → 클라우드 → AI</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">하나로 뭉친 프로그램 vs 잘게 나눈 <b>마이크로서비스</b>의 장단점 토론.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">우리가 <b>웹(React) · 앱(React Native·Flutter) · 서버(Spring Boot)</b>를 나눠 만들고 <b>클라우드</b>에 올리는 방식이 바로 이 진화의 결과.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">15일차<br></div>
<div>
<h4 class="friday">우리 서비스 구성도 그려보기 &amp; 미니 퀴즈</h4>
<div class="meta">
<div class="m prac"><span class="lab">확인</span><span class="txt">배운 흐름으로 우리 시스템 구성도를 <b>직접 그려보기</b>. 퀴즈 10문항.</span></div>
</div>
</div>
</div>
</div>
<div class="dz" style="margin-top:16px;">
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
<p><b>디자인 시스템 &amp; 핸드오프</b> — 컴포넌트·재사용 개념, 개발자에게 넘기는 스펙(간격·상태·인터랙션) 작성법. 웹의 프론트/백 구분은 함께 들어요.</p>
</div>
</div>
</section>
<!-- WEEK 4 -->
<section id="w4" class="w4">
<div class="eyebrow green">Week 4</div>
<div class="card mt">
<div class="week-head">
<div class="week-badge"><span class="w">WEEK</span><span class="n">4</span></div>
<div>
<h3>통합 · 복습 · 발표 — 배운 걸 내 말로</h3>
<div class="goal">3주간 배운 조각들을 하나로 잇고, "내가 이해한 것"을 발표로 증명해요.</div>
</div>
</div>
<div class="days">
<div class="day">
<div class="badge">1617일차<br>월·화</div>
<div>
<h4>한 요청의 여행 — 클릭에서 응답까지 따라가기</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">화면에서 버튼 하나 눌렀을 때: <b>React 웹/앱 → REST API → Spring Boot 서버 → DB → 응답</b>까지 전 과정을 추적하고 그림으로 정리.</span></div>
<div class="m link"><span class="lab">연결</span><span class="txt">1~3주 개념(네트워크·자료구조·아키텍처)이 여기서 전부 만나요.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">18일차<br></div>
<div>
<h4>발표 주제 정하고 깊게 파기</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">각자 가장 흥미로웠던 주제 하나 선택(예: "캐시는 왜 빠른가", "React와 서버는 어떻게 대화하나", "웹과 앱은 뭐가 다른가") — 자료 조사.</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">19일차<br></div>
<div>
<h4>발표 자료 만들기</h4>
<div class="meta">
<div class="m prac"><span class="lab">실습</span><span class="txt">10분 분량 슬라이드 작성. <b>어려운 말 없이, 내 말로</b> 설명하는 걸 목표로. (멘토가 1:1 코칭)</span></div>
</div>
</div>
</div>
<div class="day">
<div class="badge">20일차<br></div>
<div>
<h4 class="friday">미니 발표회 🎤 — Layer B의 졸업식</h4>
<div class="meta">
<div class="m prac"><span class="lab">발표</span><span class="txt">한 사람당 10분 "내가 이해한 컴퓨터 / 우리 시스템". 팀 앞에서 발표하고 질문받기.</span></div>
<div class="m link"><span class="lab">평가</span><span class="txt">이 발표가 <b>기본기 이해도의 핵심 평가 포인트</b>. (아래 평가 방법 참고)</span></div>
</div>
</div>
</div>
</div>
<div class="dz" style="margin-top:16px;">
<div class="h">🎨 디자이너 대체 트랙 (같은 시간)</div>
<p>디자이너도 함께 요청 흐름을 따라가고(협업 이해), 발표는 <b>"내가 다시 디자인한다면"</b> 주제로 — 우리가 다루는 서비스 화면 하나를 골라 개선안을 발표해요.</p>
</div>
</div>
</section>
<!-- Assessment -->
<section id="assess">
<div class="eyebrow green">이해도 확인</div>
<h2>어떻게 평가하나</h2>
<p class="sub">시험 점수가 목적이 아니에요. <strong>"이해했는지, 그리고 내 말로 설명할 수 있는지"</strong>를 봅니다.</p>
<div class="card mt assess">
<div class="a"><div class="wk">매일</div><div class="txt"><b>3줄 회고</b> — 오늘 배운 것 / 이해 안 된 것 / 궁금한 것. 이해가 막힌 지점을 멘토가 바로 캐치.</div></div>
<div class="a"><div class="wk">매주 금</div><div class="txt"><b>미니 퀴즈 10문항</b> — 맞고 틀림보다, 틀린 개념을 다음 주에 보완하는 용도.</div></div>
<div class="a"><div class="wk">4주차</div><div class="txt"><b>미니 발표 (가장 중요)</b> — 어려운 용어 없이 자기 말로 설명하면 진짜 이해한 것. 암기가 아니라 이해를 봐요.</div></div>
<div class="a"><div class="wk">상시</div><div class="txt"><b>"그래서 우리 회사에선?" 대답</b> — 배운 개념을 우리 실제 개발(React·Spring Boot·앱·클라우드)에 연결해 말할 수 있는지가 최종 목표.</div></div>
</div>
<div class="callout">
<h3>⚠️ 눈높이 주의</h3>
<p>고교생에게 Big-O 증명이나 CPU 파이프라인 같은 <b>깊은 이론은 목표가 아니에요.</b> "왜 이렇게 만들어졌고, 우리 시스템의 어디에 있는가"라는 <b>큰 그림과 직관</b>을 잡는 게 이 4주의 목적입니다. 못 따라오면 속도를 늦춰도 괜찮아요.</p>
</div>
</section>
<footer>
<span>AWESOMEDEV · 수습 교육 · Layer B 커리큘럼</span>
<span>2026 · 수습 가이드와 함께 사용</span>
</footer>
</div>
</body>
</html>