mirim-app/frontend/public/docs/week2-detailed.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

841 lines
51 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>2주차 상세 강의안 — 기초 다지기 · AWESOMEDEV 수습 교육</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;
--teal: #0E8C86; --teal-soft: #E0F1EF;
--rose: #B4463C; --rose-soft: #F7E7E4;
--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;
--teal: #4FC7BE; --teal-soft: #14302E; --rose: #E08A80; --rose-soft: #331E1B;
--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;
--teal: #0E8C86; --teal-soft: #E0F1EF; --rose: #B4463C; --rose-soft: #F7E7E4;
--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;
--teal: #4FC7BE; --teal-soft: #14302E; --rose: #E08A80; --rose-soft: #331E1B;
--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.7; -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(--primary); display: flex; align-items: center; gap: 10px; }
.eyebrow::before { content:""; width: 22px; height: 2px; background: currentColor; border-radius: 2px; }
header.mast { border: 1px solid var(--line); border-radius: var(--radius);
background: radial-gradient(120% 140% at 100% 0%, var(--primary-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(--primary); }
header.mast h1 { font-size: clamp(27px,5.4vw,40px); line-height: 1.15; 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: 58ch; }
.mast-meta { margin-top: 22px; 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(--primary); }
nav.toc { margin-top: 22px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); padding: 18px 22px; box-shadow: var(--shadow); }
nav.toc .t { font-size: 12px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-faint); }
nav.toc ol { margin: 12px 0 0; padding: 0; list-style: none; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; }
nav.toc a { display: flex; gap: 10px; text-decoration: none; color: var(--ink-soft); font-size: 14px; padding: 3px 0; }
nav.toc a b { color: var(--primary); font-weight: 800; min-width: 40px; }
nav.toc a:hover { color: var(--primary); }
@media (max-width:560px){ nav.toc ol { grid-template-columns: 1fr; } }
section { margin-top: clamp(30px,5vw,46px); scroll-margin-top: 20px; }
section > h2 { font-size: clamp(20px,3.4vw,25px); font-weight: 800; letter-spacing: -0.025em; margin: 12px 0 0; text-wrap: balance; }
section > .sub { color: var(--ink-soft); margin: 9px 0 0; font-size: 15px; max-width: 64ch; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: clamp(18px,3vw,26px); }
.mt { margin-top: 16px; }
p { margin: 0; } strong { font-weight: 700; }
.day-div { margin-top: clamp(38px,6vw,56px); display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; }
.day-badge { width: 58px; height: 58px; border-radius: 14px; background: var(--primary); color: #fff; display: grid; place-items: center; text-align: center; line-height: 1.05; box-shadow: var(--shadow); }
@media (prefers-color-scheme: dark){ .day-badge { color:#0B1017; } }
:root[data-theme="dark"] .day-badge { color:#0B1017; }
.day-badge .w { font-size: 10px; font-weight: 700; letter-spacing: 0.08em; opacity: .85; }
.day-badge .n { font-size: 22px; font-weight: 800; }
.day-div h2 { margin: 0; font-size: clamp(21px,3.6vw,27px); font-weight: 800; letter-spacing: -0.025em; }
.day-div .dm { margin-top: 3px; color: var(--ink-soft); font-size: 14px; }
.session { margin-top: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); box-shadow: var(--shadow); overflow: hidden; }
.s-head { padding: 16px 20px; border-bottom: 1px solid var(--line-soft); background: var(--primary-soft); }
.s-head .tag { font-size: 11px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--primary); font-variant-numeric: tabular-nums; }
.s-head h3 { margin: 5px 0 0; font-size: 18px; font-weight: 800; letter-spacing: -0.015em; }
.s-head .dur { margin-top: 5px; font-size: 12.5px; color: var(--ink-soft); font-weight: 600; }
.s-body { padding: 18px 20px; display: grid; gap: 16px; }
.block > .bt { font-size: 12px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-faint); margin-bottom: 8px; display: flex; align-items: center; gap: 7px; }
.block .bt .ic { width: 20px; height: 20px; border-radius: 6px; display: grid; place-items: center; font-size: 12px; }
.bt .ic.obj { background: var(--primary-soft); } .bt .ic.run { background: var(--line-soft); }
.bt .ic.script { background: var(--primary-soft); } .bt .ic.act { background: var(--teal-soft); }
.bt .ic.check { background: var(--amber-soft); } .bt .ic.pit { background: var(--rose-soft); }
.obj-list { margin: 0; padding: 0; display: grid; gap: 6px; }
.obj-list li { list-style: none; padding-left: 24px; position: relative; font-size: 14.5px; color: var(--ink); }
.obj-list li::before { content: "✓"; position: absolute; left: 2px; color: var(--primary); font-weight: 800; }
.prep { font-size: 13.5px; color: var(--ink-soft); background: var(--code-bg); border-radius: 9px; padding: 10px 14px; }
.run { display: grid; gap: 0; }
.run .r { display: grid; grid-template-columns: 66px 1fr; gap: 14px; padding: 9px 0; border-top: 1px solid var(--line-soft); align-items: baseline; }
.run .r:first-child { border-top: 0; }
.run .r .tm { font-size: 12.5px; font-weight: 700; color: var(--primary); font-variant-numeric: tabular-nums; white-space: nowrap; }
.run .r .ac { font-size: 14px; color: var(--ink-soft); } .run .r .ac b { color: var(--ink); font-weight: 600; }
.script { border: 1px solid var(--primary-soft); border-left: 3px solid var(--primary); border-radius: 9px; background: color-mix(in srgb, var(--primary-soft) 40%, transparent); padding: 12px 15px; }
.script .who { font-size: 12px; font-weight: 800; color: var(--primary); margin-bottom: 5px; }
.script p { font-size: 14px; color: var(--ink); line-height: 1.6; }
.script p + p { margin-top: 8px; }
.script em { color: var(--ink-soft); font-style: normal; font-size: 13px; }
.tpl { border: 1px solid var(--amber-line); background: var(--code-bg); border-radius: 10px; overflow: hidden; }
.tpl .cap { font-size: 11.5px; font-weight: 800; letter-spacing: 0.04em; color: var(--amber); background: var(--amber-soft); padding: 7px 15px; border-bottom: 1px solid var(--amber-line); text-transform: uppercase; }
.tpl pre { margin: 0; padding: 14px 16px; font-family: "SF Mono","Cascadia Code","Consolas",ui-monospace,monospace; font-size: 13px; line-height: 1.65; color: var(--ink); white-space: pre-wrap; word-break: break-word; letter-spacing: 0; }
.tpl .hl { color: var(--primary); font-weight: 600; }
.act-box { border: 1px solid color-mix(in srgb,var(--teal) 30%,transparent); background: var(--teal-soft); border-radius: 10px; padding: 13px 16px; }
.act-box p { font-size: 14px; color: var(--ink); } .act-box p b { font-weight: 700; }
.act-box ol, .act-box ul { margin: 8px 0 0; padding-left: 20px; font-size: 14px; color: var(--ink-soft); display: grid; gap: 5px; }
.check-box { border: 1px solid var(--amber-line); background: var(--amber-soft); border-radius: 10px; padding: 13px 16px; }
.check-box p { font-size: 13.5px; color: var(--ink-soft); } .check-box b { color: var(--ink); }
.check-box ul { margin: 8px 0 0; padding-left: 20px; display: grid; gap: 5px; font-size: 13.5px; color: var(--ink); }
.pit-box { border: 1px solid color-mix(in srgb,var(--rose) 30%,transparent); background: var(--rose-soft); border-radius: 10px; padding: 13px 16px; }
.pit-box .row { font-size: 13.5px; color: var(--ink-soft); } .pit-box .row + .row { margin-top: 8px; }
.pit-box b { color: var(--rose); }
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; }
footer { margin-top: 46px; 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; }
.next { margin-top: 22px; border: 1px dashed var(--primary); border-radius: var(--radius); padding: 18px 22px; background: var(--primary-soft); }
.next b { color: var(--primary-deep); }
@media (max-width:560px){ .run .r { grid-template-columns: 58px 1fr; gap: 10px; } }
@media print { body{background:#fff;} .card,header.mast,.session,nav.toc,.day-badge{box-shadow:none;} .session{break-inside:avoid;} nav.toc{display:none;} }
</style>
</head>
<body>
<div class="wrap">
<header class="mast">
<div class="wordmark"><b>AWESOMEDEV</b> · 수습 상세 강의안 · 2 / 8</div>
<h1>2주차 상세 강의안<br>기초 다지기 — 읽는 눈 만들기</h1>
<p class="lede">이번 주의 목표는 두 가지예요. 하나, 코드와 화면을 "읽는" 눈을 만드는 것. 우리 React 웹과 Spring Boot 서버가 어떻게 생겼고, 화면이 서버에 어떻게 말을 거는지 눈으로 확인해요. 둘, 지난주에 배운 예절과 질문법을 매일 반복해서 몸에 붙이는 것. 아직 뭔가를 "만들지" 않아도 괜찮아요. 잘 읽는 사람이 결국 잘 만듭니다.</p>
<div class="mast-meta">
<span class="chip"><span class="dot"></span>대상 · 미림마이스터고 3학년 수습생 4명</span>
<span class="chip"><span class="dot"></span>개발 3 · 디자인 1</span>
<span class="chip"><span class="dot"></span>주 5일 · 아침 기본기 + 실무 트랙</span>
</div>
<nav class="toc">
<div class="t">이번 주 목차</div>
<ol>
<li><a href="#d1"><b></b>코드베이스 구조 훑기</a></li>
<li><a href="#d2"><b></b>요청 흐름 추적 (Network 탭)</a></li>
<li><a href="#d3"><b></b>기능 읽기 과제</a></li>
<li><a href="#d4"><b></b>Git 실전 연습</a></li>
<li><a href="#d5"><b></b>주간 회고 · 1:1 · 미니 퀴즈</a></li>
</ol>
</nav>
</header>
<section>
<div class="card">
<p><strong>6블록 틀(학습목표 · 진행표 · 멘토 스크립트 · 실습 · 이해 확인 · 흔한 실수)은 1주차 강의안과 동일합니다.</strong> 각 세션 카드를 위에서 아래로 그대로 읽어 내려가며 진행하세요.</p>
</div>
</section>
<!-- ===================== 월 ===================== -->
<div class="day-div" id="d1">
<div class="day-badge"><div class="w">MON</div><div class="n"></div></div>
<div>
<h2>코드베이스 구조 훑기</h2>
<div class="dm">목표 · 우리 React 폴더와 Spring Boot 프로젝트가 "어떻게 생겼는지" 큰 지도를 함께 그린다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 1 · 세션 1 · 오전</div>
<h3>기본기(B) — 컴퓨터 구조 마무리 → 자료구조 시작</h3>
<div class="dur">09:30 10:30 · 60분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>지난주 컴퓨터 구조(CPU·메모리·저장장치)를 한 장으로 마무리한다.</li>
<li>자료구조의 문을 연다 — 배열·리스트, 스택·큐가 "무엇을 담는 통"인지 감을 잡는다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 진행 안내</div>
<div class="act-box">
<p><b>「CS 기본기 4주 커리큘럼」 문서의 2주차 1~2일차를 그대로 진행합니다.</b></p>
<ul>
<li>이 강의안은 시간 슬롯만 잡아두는 포인터예요. 상세 내용·예제·퀴즈는 CS 커리큘럼 문서를 여세요.</li>
<li>디자이너 수습생도 함께 듣습니다 — 자료구조는 "화면이 데이터를 어떻게 줄 세우는가"의 기초라 UI에도 쓸모가 있어요.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 1 · 세션 2 · 오전</div>
<h3>지도를 펼치자 — 프로젝트 폴더 구조 함께 열기</h3>
<div class="dur">10:40 12:00 · 80분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>React 웹 프로젝트에서 "폴더가 왜 이렇게 나뉘어 있는지" 역할을 말할 수 있다.</li>
<li>Spring Boot 프로젝트의 큰 덩어리(컨트롤러·서비스·설정)가 어디 있는지 손가락으로 짚을 수 있다.</li>
<li>"어디에 무엇이 있나"를 스스로 찾는 습관의 첫 발을 뗀다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">010분</div><div class="ac"><b>워밍업.</b> "지도 없이 처음 간 건물에서 화장실 찾기" 비유로 시작. 코드도 지도가 있으면 안 헤맨다고 연결.</div></div>
<div class="r"><div class="tm">1040분</div><div class="ac"><b>React 웹 투어.</b> 멘토가 에디터를 띄우고 폴더를 하나씩 열며 설명. 각자 자기 화면으로 똑같이 따라 연다.</div></div>
<div class="r"><div class="tm">4065분</div><div class="ac"><b>Spring Boot 투어.</b> 서버 프로젝트를 열고 컨트롤러 → 서비스 → 설정 순서로 큰 덩어리만 짚는다.</div></div>
<div class="r"><div class="tm">6580분</div><div class="ac"><b>실습 안내 + 질문.</b> 오후 구조도 실습을 예고하고 궁금한 폴더를 자유롭게 질문받는다.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"자, 오늘은 코드를 고치지 않아요. 그냥 <b>구경</b>만 할 거예요. 새 학교 첫날 건물 한 바퀴 도는 거랑 똑같아요. 어디가 교실이고 어디가 급식실인지만 알면 돼요."</p>
<p>"React 웹부터 볼게요. <code>src</code> 폴더 안에 <code>components</code>, <code>pages</code>, <code>api</code> 이런 게 보이죠? <code>components</code>는 버튼·카드처럼 화면 조각이고요, <code>pages</code>는 그 조각을 모아 만든 한 화면이에요. 레고 블록(components)이랑 완성품(pages) 관계라고 생각하면 돼요."</p>
<p>"이제 서버 쪽. Spring Boot는 <code>controller</code>가 손님을 맞는 안내데스크예요. <code>service</code>는 실제로 일을 처리하는 주방이고요. 안내데스크가 주문을 받아 주방에 넘기는 거예요. 지금은 이 두 개만 기억해도 충분해요."</p>
<p><em>수습생이 "이게 다 뭔지 모르겠어요"라고 하면 — "당연해요! 오늘은 이름이랑 위치만 익히는 날이에요. 뜻은 이번 주 내내 천천히 붙일 거예요." 라고 안심시킨다.</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 — 구조도 직접 그리기</div>
<div class="act-box">
<p><b>손으로 그리는 게 핵심입니다.</b> 종이·화이트보드·아이패드 무엇이든 좋아요. 오후에 각자 자기 지도를 완성해 서로에게 30초씩 설명합니다.</p>
<ol>
<li>React 웹의 최상위 폴더 3~5개를 상자로 그린다.</li>
<li>각 상자 옆에 "무엇을 담는 곳"인지 한 줄로 적는다.</li>
<li>Spring Boot도 같은 방식으로 controller · service · config를 그린다.</li>
<li>화면(React)에서 서버(Spring)로 화살표 하나를 긋고 "여기서 요청이 간다"라고 적는다.</li>
</ol>
</div>
<div class="tpl mt">
<div class="cap">워크시트 · 빈칸을 채우세요</div>
<pre>[ 나의 코드베이스 지도 ]
■ React 웹
<span class="hl">components/</span> → ( ) 을(를) 담는 곳
<span class="hl">pages/</span> → ( ) 을(를) 담는 곳
<span class="hl">( )/</span> → API 호출을 모아둔 곳
■ Spring Boot 서버
<span class="hl">controller</span> → ( ) 역할
<span class="hl">service</span> → ( ) 역할
■ 화살표: 화면이 서버에게 ( ) 를 보낸다.</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인</div>
<div class="check-box">
<p>다음을 각자 말로 답하면 통과예요.</p>
<ul>
<li>"버튼 하나를 새로 만들면 <b>React의 어느 폴더</b>에 파일이 생길까요?"</li>
<li>"서버에서 손님 요청을 <b>가장 먼저 받는</b> 곳 이름은?"</li>
<li>자기 구조도를 보지 않고 폴더 3개의 역할을 설명한다.</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> · 모든 폴더를 완벽히 이해하려다 지쳐버린다.</div>
<div class="row"><b>대처</b> · "오늘은 상위 폴더 5개면 충분해요. 하위 폴더는 필요할 때 열어보면 돼요"라고 범위를 좁혀준다.</div>
<div class="row"><b>실수</b> · 파일 이름을 외우려고 한다.</div>
<div class="row"><b>대처</b> · 외우는 게 아니라 "찾는 습관"이 목표임을 강조. 지도는 언제든 다시 열 수 있다.</div>
</div>
</div>
</div>
</div>
<!-- ===================== 화 ===================== -->
<div class="day-div" id="d2">
<div class="day-badge"><div class="w">TUE</div><div class="n"></div></div>
<div>
<h2>요청 흐름 추적</h2>
<div class="dm">목표 · 화면이 서버에 "말을 거는" 순간을 개발자도구 Network 탭으로 직접 눈으로 본다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 2 · 세션 1 · 오전</div>
<h3>기본기(B) — 자료구조 이어가기 (배열·리스트)</h3>
<div class="dur">09:30 10:30 · 60분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>배열과 리스트가 데이터를 "줄 세우는" 방식의 차이를 한 문장으로 말한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 진행 안내</div>
<div class="act-box">
<p><b>「CS 기본기 4주 커리큘럼」 문서의 2주차 3일차를 그대로 진행합니다.</b></p>
<ul>
<li>예제 코드는 JavaScript(배열)를 우선 사용하고, 필요하면 Java를 보조로 보여주세요.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 2 · 세션 2 · 오후</div>
<h3>화면이 서버에 말을 건다 — Network 탭 열기</h3>
<div class="dur">13:00 14:40 · 100분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>브라우저 개발자도구의 Network 탭을 열고 요청 목록을 볼 수 있다.</li>
<li>요청 하나에서 method(GET/POST) · URL · 응답(Response)을 짚어낼 수 있다.</li>
<li>"React 화면 → REST API → Spring Boot 서버"라는 흐름을 자기 말로 설명한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">015분</div><div class="ac"><b>도구 열기.</b> 크롬에서 <code>F12</code> → Network 탭. 다 함께 열고 화면을 새로고침해 요청이 주르륵 뜨는 걸 본다.</div></div>
<div class="r"><div class="tm">1545분</div><div class="ac"><b>한 줄 뜯어보기.</b> 멘토가 요청 하나를 클릭해 Headers(method·URL)와 Response를 함께 읽는다.</div></div>
<div class="r"><div class="tm">4575분</div><div class="ac"><b>따라하기.</b> 각자 우리 서비스 화면을 조작하며 자기 Network 탭에 뜨는 요청을 관찰한다.</div></div>
<div class="r"><div class="tm">75100분</div><div class="ac"><b>워크시트 작성 + 공유.</b> 각자 요청 하나를 골라 표를 채우고 한 명씩 발표한다.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"어제는 코드가 어디 있는지 지도를 그렸죠? 오늘은 그 지도 위에서 <b>편지가 오가는 걸</b> 직접 볼 거예요. 화면이 서버한테 '이 데이터 좀 주세요' 하고 편지를 보내거든요."</p>
<p>"키보드에서 <code>F12</code> 눌러보세요. 창이 하나 뜨죠? 위에 <b>Network</b>라고 적힌 탭을 눌러요. 그리고 화면을 새로고침. 자, 줄이 좍 뜨죠? 이게 전부 방금 오간 편지예요. 하나하나가 화면과 서버의 대화예요."</p>
<p>"아무거나 하나 클릭해볼게요. <b>Request URL</b> — 이게 편지를 보낸 주소예요. <b>Request Method</b><code>GET</code>이면 '주세요', <code>POST</code>면 '이거 저장해주세요'라는 뜻이에요. 밑에 <b>Response</b>는 서버가 보낸 답장이고요."</p>
<p><em>수습생이 요청이 너무 많아 혼란스러워하면 — "필터 칸에 'Fetch/XHR'를 눌러보세요. 진짜 데이터 편지만 남아요. 이미지·폰트 같은 건 잠깐 무시해도 돼요." 라고 안내한다.</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 — 요청 하나 골라 관찰하기</div>
<div class="act-box">
<p><b>요청 하나를 골라 아래 표를 채우면 끝입니다.</b> 어려운 요청 말고, 목록 조회처럼 답이 눈에 잘 보이는 GET 요청을 고르라고 안내하세요.</p>
<ul>
<li>우리 서비스 화면에서 목록/조회 화면을 하나 연다.</li>
<li>Network 탭에서 방금 뜬 요청 하나를 클릭한다.</li>
<li>method · URL · 응답의 첫 줄을 워크시트에 옮겨 적는다.</li>
</ul>
</div>
<div class="tpl mt">
<div class="cap">워크시트 · 요청 관찰 카드</div>
<pre>[ 내가 관찰한 요청 ]
이 요청은 (어떤 화면 / 버튼) 에서 발생했나요?
<span class="hl">___________________________</span>
Request Method : <span class="hl">GET</span> / POST (동그라미)
Request URL : <span class="hl">_______________________</span>
Status(상태코드): <span class="hl">___</span> (200이면 성공!)
Response(답장)에서 눈에 띄는 값 하나:
<span class="hl">___________________________</span>
한 줄 소감: 이 요청은 서버에게 무엇을 부탁한 걸까?
<span class="hl">___________________________</span></pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인</div>
<div class="check-box">
<p>발표할 때 다음이 담기면 통과예요.</p>
<ul>
<li>"내가 고른 요청은 <b>GET/POST 중 무엇</b>이고 왜 그렇게 판단했는지"</li>
<li>"이 요청의 <b>URL</b><b>상태코드</b>가 무엇이었는지"</li>
<li>"이 편지가 <b>어느 화면 동작</b> 때문에 발생했는지"</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> · 요청 목록이 수십 개라 어디를 봐야 할지 몰라 얼어붙는다.</div>
<div class="row"><b>대처</b> · 'Fetch/XHR' 필터를 켜서 진짜 데이터 요청만 남기고, 목록을 위에서 하나만 고르게 한다.</div>
<div class="row"><b>실수</b> · 응답(JSON)을 전부 이해하려 한다.</div>
<div class="row"><b>대처</b> · "지금은 값 하나만 짚으면 돼요. 전체 해석은 다음 단계예요"라고 범위를 정해준다.</div>
</div>
</div>
</div>
</div>
<!-- ===================== 수 ===================== -->
<div class="day-div" id="d3">
<div class="day-badge"><div class="w">WED</div><div class="n"></div></div>
<div>
<h2>기능 읽기 과제</h2>
<div class="dm">목표 · 화면/기능 하나를 골라 "어떻게 동작하는지" 분석해 문서로 정리하고 멘토와 리뷰한다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 3 · 세션 1 · 오전</div>
<h3>기본기(B) — 자료구조 (스택 · 큐)</h3>
<div class="dur">09:30 10:30 · 60분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>스택(쌓기)과 큐(줄서기)의 차이를 일상 비유로 설명한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 진행 안내</div>
<div class="act-box">
<p><b>「CS 기본기 4주 커리큘럼」 문서의 2주차 4일차를 그대로 진행합니다.</b></p>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 3 · 세션 2 · 오전</div>
<h3>기능 하나를 통째로 읽기 — 분석 과제 착수</h3>
<div class="dur">10:40 12:00 · 80분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>화면 기능 하나를 골라 "사용자 동작 → 화면 변화 → 서버 요청"의 순서를 적을 수 있다.</li>
<li>어제 배운 Network 탭 관찰을 분석 근거로 활용한다.</li>
<li>모르는 부분을 "질문 리스트"로 남기는 습관을 익힌다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">015분</div><div class="ac"><b>과제 소개.</b> "기능 하나를 탐정처럼 관찰해 리포트를 쓴다." 좋은 예시 리포트 1개를 함께 읽는다.</div></div>
<div class="r"><div class="tm">1530분</div><div class="ac"><b>기능 고르기.</b> 각자 분석할 기능을 하나 정한다 (예: 로그인, 목록 검색, 좋아요 버튼).</div></div>
<div class="r"><div class="tm">3075분</div><div class="ac"><b>관찰·기록.</b> 화면을 눌러보고 Network 탭을 확인하며 워크시트를 채운다. 멘토는 순회하며 막힌 곳을 돕는다.</div></div>
<div class="r"><div class="tm">7580분</div><div class="ac"><b>오후 리뷰 예고.</b> "완벽 말고 솔직하게. 모르는 건 물음표로 남기세요"라고 안내.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"오늘은 여러분이 <b>탐정</b>이에요. 기능 하나를 골라서 '얘가 대체 어떻게 움직이는 거지?'를 캐내는 거예요. 코드를 고치는 게 아니라 <b>설명</b>하는 게 목표예요."</p>
<p>"기능은 작은 걸 고르는 게 좋아요. '좋아요 버튼', '검색창', '로그인' 이런 거요. 화려한 화면 말고, 눌렀을 때 뭔가 딱 벌어지는 단순한 걸로요."</p>
<p>"순서는 세 칸이에요. ①내가 무엇을 눌렀나 → ②화면이 어떻게 변했나 → ③그때 Network 탭에 어떤 편지가 갔나. 이 세 칸만 채우면 훌륭한 분석이에요."</p>
<p><em>"막히면 물음표로 남기세요"를 반복 강조. 모르는 걸 솔직히 적는 게 감점이 아니라 오히려 좋은 리포트라고 알려준다.</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 — 기능 분석 리포트 (이번 주 산출물 ①)</div>
<div class="act-box">
<p><b>이 리포트가 이번 주 공식 산출물입니다.</b> 오전에 초안, 오후 리뷰 후 보완해 완성하세요.</p>
<ol>
<li>분석할 기능 하나를 정한다.</li>
<li>동작을 ①동작 → ②화면변화 → ③서버요청 세 칸으로 적는다.</li>
<li>모르는 부분은 "질문" 항목에 물음표로 남긴다.</li>
</ol>
</div>
<div class="tpl mt">
<div class="cap">템플릿 · 기능 분석 리포트</div>
<pre># 기능 분석 리포트
분석한 기능 : <span class="hl">_______________________</span>
작성자 : <span class="hl">_______________________</span>
## 1. 내가 한 동작
- <span class="hl">(예: 검색창에 "KT"를 입력하고 엔터를 눌렀다)</span>
## 2. 화면에서 벌어진 일
- <span class="hl">(예: 목록이 KT 관련 항목으로 바뀌었다)</span>
## 3. 그때 오간 요청 (Network 탭)
- Method / URL : <span class="hl">___________________</span>
- 서버가 준 답 : <span class="hl">___________________</span>
## 4. 아직 모르는 것 (물음표 환영!)
- <span class="hl">? ___________________________</span></pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인 — 오후 멘토 리뷰</div>
<div class="check-box">
<p>오후 1:1 리뷰에서 다음을 확인합니다.</p>
<ul>
<li>①②③ 세 칸이 <b>순서대로 이어지는지</b> (동작이 화면 변화로, 화면 변화가 요청으로 연결)</li>
<li>물음표(모르는 부분)를 <b>솔직하게 남겼는지</b> — 남겼으면 칭찬</li>
<li>어제 배운 Network 관찰이 근거로 들어갔는지</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> · 너무 크고 복잡한 기능을 골라 첫 칸부터 막힌다.</div>
<div class="row"><b>대처</b> · "버튼 하나짜리로 바꿔봐요"라고 스케일을 줄여준다.</div>
<div class="row"><b>실수</b> · 모르는 걸 감추려고 아는 척 문장을 지어낸다.</div>
<div class="row"><b>대처</b> · "물음표가 많은 리포트가 정직한 리포트예요"라고 심리적 안전감을 준다.</div>
</div>
</div>
</div>
</div>
<!-- ===================== 목 ===================== -->
<div class="day-div" id="d4">
<div class="day-badge"><div class="w">THU</div><div class="n"></div></div>
<div>
<h2>Git 실전 연습</h2>
<div class="dm">목표 · 연습용 저장소에서 브랜치 → 수정 → 커밋 → PR까지 한 바퀴를 직접 돌려본다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 4 · 세션 1 · 오전</div>
<h3>기본기(B) — 자료구조 복습 · 미니 문제</h3>
<div class="dur">09:30 10:30 · 60분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>이번 주 배운 배열·리스트·스택·큐를 미니 문제로 스스로 점검한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 진행 안내</div>
<div class="act-box">
<p><b>「CS 기본기 4주 커리큘럼」 문서의 2주차 5일차(복습·문제)를 그대로 진행합니다.</b></p>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 4 · 세션 2 · 오전</div>
<h3>Git 한 바퀴 — 브랜치에서 PR까지</h3>
<div class="dur">10:40 12:00 · 80분</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>연습용 저장소에서 브랜치를 만들고 파일을 수정할 수 있다.</li>
<li>커밋 컨벤션(<code>feat:</code> · <code>fix:</code> · <code>docs:</code>)에 맞춰 커밋 메시지를 쓴다.</li>
<li>PR(Pull Request)을 올려 "리뷰해 주세요" 상태까지 만든다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">010분</div><div class="ac"><b>비유 워밍업.</b> 브랜치 = 원본을 건드리지 않는 "연습용 복사본". 왜 바로 고치지 않는지 설명.</div></div>
<div class="r"><div class="tm">1035분</div><div class="ac"><b>함께 한 바퀴.</b> 멘토가 화면 공유로 브랜치 생성 → 파일 수정 → 커밋을 시연. 학생은 눈으로 먼저 본다.</div></div>
<div class="r"><div class="tm">3565분</div><div class="ac"><b>각자 한 바퀴.</b> 연습용 저장소에서 각자 같은 순서를 따라 한다. 멘토 순회 지원.</div></div>
<div class="r"><div class="tm">6580분</div><div class="ac"><b>PR 올리기 + 컨벤션 복습.</b> PR을 만들고 제목을 커밋 컨벤션에 맞춘다. 서로의 PR을 열어본다.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"Git은 게임의 <b>세이브 파일</b>이랑 비슷해요. 실수해도 이전 세이브로 돌아갈 수 있어요. 그래서 하나도 안 무서워요. 오늘 마음껏 실수해도 돼요 — 연습용 저장소니까요."</p>
<p>"먼저 <b>브랜치</b>를 만들어요. 이건 원본을 안 건드리는 '나만의 연습장'이에요. 여기서 파일을 고치고, 다 됐으면 <b>커밋</b>으로 '여기까지 저장!' 도장을 찍어요."</p>
<p>"커밋 메시지에는 규칙이 있어요. 새 기능이면 <code>feat:</code>, 고친 거면 <code>fix:</code>, 문서면 <code>docs:</code>를 앞에 붙여요. 지난주에 봤던 그 규칙이에요. 예: <code>docs: 내 소개 파일 추가</code>."</p>
<p>"마지막은 <b>PR</b>. '제가 이렇게 고쳤어요, 봐주세요'라고 손드는 거예요. PR을 올리면 리뷰어가 확인하고 합쳐줘요. 오늘은 올리는 것까지가 목표예요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 — 연습 PR 올리기 (이번 주 산출물 ②)</div>
<div class="act-box">
<p><b>이 PR이 이번 주 공식 산출물입니다.</b> 아래 순서를 그대로 따라오게 하세요. 명령어는 멘토가 화면에 크게 띄워둡니다.</p>
<ol>
<li>연습용 저장소를 받아 브랜치를 만든다.</li>
<li>자기 소개를 담은 파일 하나를 추가/수정한다.</li>
<li>커밋 컨벤션에 맞춰 커밋한다.</li>
<li>PR을 올리고 제목을 컨벤션대로 쓴다.</li>
</ol>
</div>
<div class="tpl mt">
<div class="cap">따라 치는 명령 · 빈칸을 채우세요</div>
<pre># 1) 내 연습용 브랜치 만들기
git checkout -b <span class="hl">practice/이름-week2</span>
# 2) 파일 수정 후, 바뀐 걸 담기
git add <span class="hl">파일이름</span>
# 3) 도장 찍기 (컨벤션 지키기!)
git commit -m "<span class="hl">docs: __________ 추가</span>"
# 4) 내 브랜치를 원격으로 밀어올리기
git push -u origin <span class="hl">practice/이름-week2</span>
# 5) 브라우저에서 "Pull Request" 버튼을 눌러 PR 생성
# PR 제목도 컨벤션으로! 예) docs: 수습 자기소개 추가</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인</div>
<div class="check-box">
<p>PR 링크를 멘토에게 공유하며 다음을 확인합니다.</p>
<ul>
<li>브랜치 이름이 <code>main</code>이 아닌 <b>연습용 브랜치</b>인지</li>
<li>커밋 메시지가 <b>컨벤션 접두어</b>로 시작하는지</li>
<li>PR이 실제로 열려 "리뷰 대기" 상태인지</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> · 브랜치를 안 만들고 <code>main</code>에서 바로 작업한다.</div>
<div class="row"><b>대처</b> · 첫 단계 <code>git checkout -b</code>를 다 함께 소리 내어 확인하고 시작한다.</div>
<div class="row"><b>실수</b> · 커밋 메시지를 "수정함", "ㅇㅇ"처럼 대충 쓴다.</div>
<div class="row"><b>대처</b> · "미래의 내가 읽는 편지예요"라고 상기시키고 컨벤션 예시를 다시 보여준다.</div>
</div>
</div>
</div>
</div>
<!-- ===================== 디자이너 트랙 ===================== -->
<div class="session">
<div class="s-head">
<div class="tag">주중 병행 · 디자이너 트랙 · 오후</div>
<h3>디자이너 — UI 인벤토리 작성 + 개선점 5개 리포트</h3>
<div class="dur">주중 오후 시간 분산 · 총 4~5시간</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>우리 서비스 화면의 색·타이포·컴포넌트를 목록으로 정리(UI 인벤토리)할 수 있다.</li>
<li>일관성이 깨진 곳·개선 여지를 5개 찾아 근거와 함께 리포트한다.</li>
<li>예절과 질문법은 개발자 트랙과 <b>동일하게 상시 관찰</b> 대상이다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"개발자 친구들이 코드를 '읽는' 동안, 디자이너는 화면을 '읽어요'. 우리 서비스에 쓰인 색이 몇 개인지, 글자 크기가 몇 종류인지, 버튼 모양이 제각각인지 하나하나 세어보는 거예요."</p>
<p>"세다 보면 '어? 이 버튼만 색이 다르네?' 같은 게 보여요. 그게 바로 개선점이에요. 5개만 찾아서 '어디가, 왜 아쉽고, 어떻게 바꾸면 좋을지'를 적어주면 훌륭한 리포트예요."</p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 — UI 인벤토리 & 개선 리포트</div>
<div class="act-box">
<p><b>화면을 눈으로 훑으며 빈칸을 채웁니다.</b> 스크린샷을 붙여두면 근거가 더 명확해져요.</p>
<ul>
<li>색: 실제 쓰인 색을 모아 목록으로.</li>
<li>타이포: 글자 크기·굵기 종류를 정리.</li>
<li>컴포넌트: 버튼·카드·입력창 등 반복되는 조각 정리.</li>
</ul>
</div>
<div class="tpl mt">
<div class="cap">템플릿 · UI 인벤토리 + 개선점</div>
<pre># UI 인벤토리
## 색 (Colors)
- <span class="hl">주 색 : #______ / 보조 : #______</span>
## 타이포 (Typography)
- <span class="hl">제목 __px / 본문 __px / 캡션 __px</span>
## 컴포넌트 (Components)
- <span class="hl">버튼 종류 __개, 카드 __종류 ...</span>
# 개선점 5가지
1. 어디가? → <span class="hl">______</span>
왜 아쉽나? → <span class="hl">______</span>
어떻게? → <span class="hl">______</span>
(2~5 동일 형식)</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> · "그냥 예쁘다/별로다"처럼 취향으로만 평가한다.</div>
<div class="row"><b>대처</b> · "일관성·가독성처럼 <b>근거</b>를 붙여요"라고 방향을 잡아준다.</div>
<div class="row"><b>실수</b> · 개선점을 20개씩 나열해 초점이 흐려진다.</div>
<div class="row"><b>대처</b> · "가장 눈에 띄는 5개만. 깊게 쓰는 게 나아요"라고 범위를 좁힌다.</div>
</div>
</div>
</div>
</div>
<!-- ===================== 금 ===================== -->
<div class="day-div" id="d5">
<div class="day-badge"><div class="w">FRI</div><div class="n"></div></div>
<div>
<h2>주간 회고 · 1:1 · 미니 퀴즈</h2>
<div class="dm">목표 · 한 주를 스스로 돌아보고(잘한 것 1 / 개선 1), 기본기를 퀴즈로 점검한다.</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 5 · 세션 1 · 오전</div>
<h3>기본기(B) 미니 퀴즈</h3>
<div class="dur">09:30 10:30 · 60분 (포인터 세션)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>이번 주 자료구조 개념을 짧은 퀴즈로 스스로 확인하고, 약한 부분을 안다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 / 진행 안내</div>
<div class="act-box">
<p><b>「CS 기본기 4주 커리큘럼」 문서의 2주차 미니 퀴즈를 진행합니다.</b></p>
<ul>
<li>점수용이 아니라 "어디가 약한지 확인용"임을 분명히 알려주세요. 틀린 문항은 함께 다시 봅니다.</li>
</ul>
</div>
</div>
</div>
</div>
<div class="session">
<div class="s-head">
<div class="tag">Day 5 · 세션 2 · 오후</div>
<h3>주간 회고 & 1:1 — 잘한 것 1 · 개선 1</h3>
<div class="dur">13:00 15:00 · 120분 (회고 40분 + 1:1 순차)</div>
</div>
<div class="s-body">
<div class="block">
<div class="bt"><span class="ic obj">🎯</span>학습목표</div>
<ul class="obj-list">
<li>한 주를 돌아보며 "잘한 것 1개 / 개선할 것 1개"를 구체적으로 적는다.</li>
<li>1:1에서 멘토와 다음 주 목표 한 가지를 합의한다.</li>
<li>이번 주 산출물(기능 분석 문서 · 연습 PR)을 함께 점검한다.</li>
</ul>
</div>
<div class="block">
<div class="bt"><span class="ic run">🕘</span>진행표</div>
<div class="run">
<div class="r"><div class="tm">020분</div><div class="ac"><b>개인 회고 작성.</b> 각자 조용히 회고 시트를 채운다. 멘토는 방해하지 않는다.</div></div>
<div class="r"><div class="tm">2040분</div><div class="ac"><b>돌아가며 공유.</b> 한 명씩 "잘한 것 1 / 개선 1"을 말한다. 서로 박수·격려.</div></div>
<div class="r"><div class="tm">40110분</div><div class="ac"><b>1:1 (1인당 약 15분).</b> 산출물 점검 + 다음 주 목표 합의. 나머지는 회고 보완·자율 정리.</div></div>
<div class="r"><div class="tm">110120분</div><div class="ac"><b>마무리.</b> 다음 주 예고와 격려로 한 주를 닫는다.</div></div>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic script">💬</span>멘토 스크립트</div>
<div class="script">
<div class="who">멘토</div>
<p>"한 주 정말 고생했어요. 오늘은 '내가 뭘 했지?'를 정리하는 날이에요. 딱 두 가지만 적어요 — <b>잘한 것 하나</b>, <b>다음에 더 잘하고 싶은 것 하나</b>. 많이 안 적어도 돼요."</p>
<p>"'잘한 것'은 아주 작아도 좋아요. '처음으로 Network 탭을 열어봤다'도 훌륭한 성취예요. 개선점도 자책이 아니라 '다음 주엔 이걸 해보자' 같은 방향이면 돼요."</p>
<p><em>1:1에서는 이번 주 산출물 두 개(기능 분석 문서, 연습 PR)를 함께 열어보고, 이해력·질문의 질(30분 룰·질문 3요소)·예절 정착도를 부드럽게 피드백한다. 지적보다 성장을 먼저 짚는다.</em></p>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic act">✍️</span>실습 — 주간 회고 시트</div>
<div class="act-box">
<p><b>두 칸이면 충분합니다.</b> 다음 주 1:1에서 이 시트를 이어서 봅니다.</p>
</div>
<div class="tpl mt">
<div class="cap">템플릿 · 2주차 주간 회고</div>
<pre># 2주차 회고 — 이름: <span class="hl">______</span>
■ 이번 주 잘한 것 1가지
<span class="hl">___________________________</span>
■ 다음 주 더 해보고 싶은 것 1가지
<span class="hl">___________________________</span>
■ 멘토와 합의한 다음 주 목표
<span class="hl">___________________________</span>
[ 산출물 체크 ]
□ 기능 분석 문서 1개
□ 연습 PR 1개</pre>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic check"></span>이해 확인 — 이번 주 평가 체크포인트</div>
<div class="check-box">
<p>멘토는 1:1에서 세 가지 축으로 관찰 기록을 남깁니다.</p>
<ul>
<li><b>이해력</b> · 구조·요청 흐름·기능 분석을 자기 말로 설명하는가</li>
<li><b>질문의 질</b> · 30분 룰을 지키고, 질문 3요소(무엇을·무엇을 시도·무엇이 막힘)를 담는가</li>
<li><b>예절 정착도</b> · 인사·경청·피드백 수용이 일상으로 자리잡았는가</li>
</ul>
</div>
</div>
<div class="block">
<div class="bt"><span class="ic pit">⚠️</span>흔한 실수</div>
<div class="pit-box">
<div class="row"><b>실수</b> · 회고에 "그냥 열심히 했다"처럼 뭉뚱그려 적는다.</div>
<div class="row"><b>대처</b> · "어떤 순간에, 무엇을 했는지 하나만 콕 집어요"라고 구체화를 돕는다.</div>
<div class="row"><b>실수</b> · 개선점을 자기 비난으로 적어 위축된다.</div>
<div class="row"><b>대처</b> · 개선은 "다음 행동"으로 바꿔 쓰게 한다. 우리는 함께 더 나은 세상을 만드는 팀이라는 톤을 유지한다.</div>
</div>
</div>
</div>
</div>
<section>
<div class="next">
<p><b>다음 주 예고 · 3주차 —</b> 읽는 눈에서 <b>손으로 바꾸는 힘</b>으로. 아주 작은 이슈 하나를 골라 직접 코드를 고치고 진짜 PR을 올리는 "첫 기여" 주간이 시작됩니다. (KT엠모바일·KT알파·핀업과 함께 만드는 실제 화면을 소재로.)</p>
</div>
</section>
<footer>
<span>AWESOMEDEV · 2주차 상세 강의안 (멘토용) · 8부작 중 2</span>
<span>2026 · 수습 가이드·CS 커리큘럼·평가 루브릭과 함께 사용</span>
</footer>
</div>
</body>
</html>