feat: 코스 도해 완성 — 디자인·부록 23종 추가, 71개 전 코스 도해 완비

- 디자인 12: F패턴 시선 흐름·색상환·크기 위계·8pt 그리드·비트맵vs벡터·
  와이어프레임 3단계·오토레이아웃·디자인시스템 계층·엄지 도달범위·리서치 순환도·무드보드·STAR
- 부록 도구 11: 창 스냅·터미널 삼형제·VS Code/IntelliJ 구역도·개발자도구 탭 지도·
  PR 흐름도·Docker 대시보드·DBeaver 연결 경로·Postman 해부·버그 캡처·TIL 구조

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
AWESOMEDEV 2026-07-17 07:24:17 +09:00
parent 8486c7e656
commit 241b784e1e
23 changed files with 1023 additions and 0 deletions

View File

@ -264,6 +264,57 @@ export default function FigmaPage() {
그래서 오토레이아웃으로 만든 시안은 개발자가 CSS로 옮기기도 훨씬 쉬워요
직군이 같은 언어로 대화하게 되는 거죠.
</p>
<svg className="diagram" viewBox="0 0 640 340" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="오토레이아웃 버튼 하나에 패딩·아이템 간격·정렬이 어떻게 적용되는지 치수선으로 보여 주는 도해">
<text x="20" y="28" fontSize="14" fontWeight="600" fill="var(--ink)">오토레이아웃 버튼 우측 패널의 숫자가 붙는 자리</text>
<text x="60" y="62" fontSize="12.5" fill="var(--muted)">버튼(오토레이아웃 프레임)</text>
<line x1="152" y1="118" x2="176" y2="118" stroke="var(--teal)" strokeWidth="1.5" />
<line x1="152" y1="112" x2="152" y2="124" stroke="var(--teal)" strokeWidth="1.5" />
<line x1="176" y1="112" x2="176" y2="124" stroke="var(--teal)" strokeWidth="1.5" />
<text x="164" y="106" fontSize="12" textAnchor="middle" fill="var(--teal)">8</text>
<rect x="60" y="140" width="340" height="100" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<rect x="116" y="170" width="228" height="40" rx="8" fill="none" stroke="var(--muted)" strokeWidth="1" strokeDasharray="4 4" />
<line x1="60" y1="190" x2="400" y2="190" stroke="var(--primary)" strokeWidth="1" strokeDasharray="6 5" />
<rect x="124" y="176" width="28" height="28" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<circle cx="138" cy="190" r="6" fill="var(--muted)" />
<rect x="176" y="176" width="168" height="28" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="260" y="195" fontSize="14" textAnchor="middle" fill="var(--ink)">로그인</text>
<line x1="372" y1="140" x2="372" y2="170" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="366" y1="140" x2="378" y2="140" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="366" y1="170" x2="378" y2="170" stroke="var(--amber)" strokeWidth="1.5" />
<text x="384" y="159" fontSize="12" textAnchor="start" fill="var(--amber)">12</text>
<line x1="372" y1="210" x2="372" y2="240" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="366" y1="210" x2="378" y2="210" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="366" y1="240" x2="378" y2="240" stroke="var(--amber)" strokeWidth="1.5" />
<text x="384" y="229" fontSize="12" textAnchor="start" fill="var(--amber)">12</text>
<line x1="60" y1="262" x2="116" y2="262" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="60" y1="256" x2="60" y2="268" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="116" y1="256" x2="116" y2="268" stroke="var(--amber)" strokeWidth="1.5" />
<text x="88" y="282" fontSize="12" textAnchor="middle" fill="var(--amber)">24</text>
<line x1="344" y1="262" x2="400" y2="262" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="344" y1="256" x2="344" y2="268" stroke="var(--amber)" strokeWidth="1.5" />
<line x1="400" y1="256" x2="400" y2="268" stroke="var(--amber)" strokeWidth="1.5" />
<text x="372" y="282" fontSize="12" textAnchor="middle" fill="var(--amber)">24</text>
<line x1="432" y1="146" x2="452" y2="146" stroke="var(--amber)" strokeWidth="3" strokeLinecap="round" />
<text x="462" y="150" fontSize="13" fill="var(--ink)">패딩(Padding)</text>
<text x="462" y="168" fontSize="12.5" fill="var(--muted)">padding: 12px 24px</text>
<line x1="432" y1="196" x2="452" y2="196" stroke="var(--teal)" strokeWidth="3" strokeLinecap="round" />
<text x="462" y="200" fontSize="13" fill="var(--ink)">간격(Spacing)</text>
<text x="462" y="218" fontSize="12.5" fill="var(--muted)">gap: 8px</text>
<line x1="432" y1="246" x2="452" y2="246" stroke="var(--primary)" strokeWidth="3" strokeDasharray="6 5" strokeLinecap="round" />
<text x="462" y="250" fontSize="13" fill="var(--ink)">정렬(Alignment)</text>
<text x="462" y="268" fontSize="12.5" fill="var(--muted)">align-items: center</text>
<text x="60" y="316" fontSize="12.5" fill="var(--muted)">글자가 길어지면 점선 안쪽이 넓어지고, 패딩 값은 그대로 유지된 버튼이 늘어난다.</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 버튼 하나에 붙는 패딩·아이템 간격·정렬 우측 패널 숫자와 CSS 값의 대응</p>
<div className="tip">
<b>직접 확인해 보기</b> 섹션 3에서 만든 로그인 버튼(사각형+글자) 선택하고
<span className="kbd">Shift</span>+<span className="kbd">A</span> 누르세요.

View File

@ -214,6 +214,38 @@ export default function UiUxPage() {
<strong>스캔</strong>합니다. 눈길이 움직이는 대표적인 모양이 <strong>F패턴</strong>이에요.
</p>
<Code>{CODE_F_PATTERN}</Code>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="화면 위를 눈이 F자로 훑는 경로 도해. 제목에서 시작해 맨 윗줄을 끝까지 가로로 읽고, 그 아래를 짧게 훑은 뒤 왼쪽 가장자리를 세로로 스캔한다.">
<rect x="40" y="30" width="360" height="300" rx="8" fill="var(--card)" stroke="var(--line)" />
<rect x="60" y="52" width="240" height="18" rx="8" fill="var(--ink)" opacity="0.75" />
<rect x="60" y="96" width="320" height="10" rx="8" fill="var(--muted)" opacity="0.45" />
<rect x="60" y="116" width="300" height="10" rx="8" fill="var(--muted)" opacity="0.45" />
<rect x="60" y="156" width="200" height="10" rx="8" fill="var(--muted)" opacity="0.45" />
<rect x="60" y="176" width="170" height="10" rx="8" fill="var(--muted)" opacity="0.45" />
<rect x="60" y="216" width="90" height="10" rx="8" fill="var(--muted)" opacity="0.3" />
<rect x="60" y="246" width="80" height="10" rx="8" fill="var(--muted)" opacity="0.3" />
<rect x="60" y="276" width="70" height="10" rx="8" fill="var(--muted)" opacity="0.3" />
<rect x="60" y="306" width="60" height="10" rx="8" fill="var(--muted)" opacity="0.3" />
<polyline points="66,61 300,61 66,61 66,101 380,101 66,101 66,161 260,161 66,161 66,310" fill="none" stroke="var(--primary)" strokeWidth="2.5" strokeLinecap="round" />
<circle cx="66" cy="61" r="6" fill="var(--primary)" />
<circle cx="66" cy="310" r="6" fill="var(--rose)" />
<text x="308" y="66" fontSize="12.5" fill="var(--primary)"> 제목</text>
<text x="390" y="105" fontSize="12.5" fill="var(--primary)"> 가로 스캔</text>
<text x="270" y="165" fontSize="12.5" fill="var(--primary)"> 점점 짧게</text>
<text x="82" y="336" fontSize="12.5" fill="var(--rose)"> 왼쪽 세로 스캔</text>
<line x1="40" y1="30" x2="40" y2="330" stroke="var(--teal)" strokeWidth="3" />
<line x1="40" y1="30" x2="400" y2="30" stroke="var(--teal)" strokeWidth="3" />
<text x="430" y="60" fontSize="14" fontWeight="600" fill="var(--ink)">눈길이 그리는 F</text>
<text x="430" y="88" fontSize="12.5" fill="var(--muted)">청록 = 눈이 가장 오래</text>
<text x="430" y="106" fontSize="12.5" fill="var(--muted)">머무는 ·왼쪽 </text>
<rect x="430" y="130" width="176" height="52" rx="8" fill="var(--card)" stroke="var(--amber)" />
<text x="444" y="152" fontSize="12.5" fill="var(--ink)">여기 = 중요한 </text>
<text x="444" y="171" fontSize="12.5" fill="var(--muted)">제목 · 진행률 · 주요 버튼</text>
<rect x="430" y="240" width="176" height="52" rx="8" fill="var(--card)" stroke="var(--line)" strokeDasharray="5 4" />
<text x="444" y="262" fontSize="12.5" fill="var(--muted)">오른쪽 아래 = 거의 </text>
<text x="444" y="281" fontSize="12.5" fill="var(--muted)">놓쳐도 되는 것만</text>
<line x1="412" y1="200" x2="412" y2="232" stroke="var(--line)" strokeWidth="2" strokeDasharray="4 4" />
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 제목 가로 스캔 점점 짧게 왼쪽 세로 스캔. 그래서 중요한 것은 ·왼쪽에.</p>
<p>
그래서 화면에는 <strong>시각적 위계</strong>(visual hierarchy) 필요해요
중요한 것부터 눈에 들어오도록 <strong>크기·굵기··위치</strong> 순서를 매기는 .

View File

@ -242,6 +242,57 @@ export default function ColorPage() {
<strong> 유사색</strong> 단짝 친구들 나란히 있어도 튀지 않아서 배경·카드·그래프처럼
<strong> 넓은 면적</strong> 채울 좋아요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="12색 색상환. 마주보는 색은 보색, 이웃한 색은 유사색 관계임을 선으로 표시한 그림">
<circle cx="210" cy="180" r="115" fill="none" stroke="var(--line)" strokeWidth="1" strokeDasharray="3 4" />
<line x1="152.5" y1="279.6" x2="267.5" y2="80.4" stroke="var(--ink)" strokeWidth="2" strokeDasharray="6 5" strokeLinecap="round" />
<line x1="210" y1="295" x2="152.5" y2="279.6" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<line x1="152.5" y1="279.6" x2="110.4" y2="237.5" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<circle cx="210" cy="65" r="17" fill="hsl(0, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="267.5" cy="80.4" r="17" fill="hsl(30, 70%, 50%)" stroke="var(--ink)" strokeWidth="3" />
<circle cx="309.6" cy="122.5" r="17" fill="hsl(60, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="325" cy="180" r="17" fill="hsl(90, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="309.6" cy="237.5" r="17" fill="hsl(120, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="267.5" cy="279.6" r="17" fill="hsl(150, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="210" cy="295" r="17" fill="hsl(180, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="152.5" cy="279.6" r="17" fill="hsl(210, 70%, 50%)" stroke="var(--ink)" strokeWidth="3" />
<circle cx="110.4" cy="237.5" r="17" fill="hsl(240, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="95" cy="180" r="17" fill="hsl(270, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="110.4" cy="122.5" r="17" fill="hsl(300, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<circle cx="152.5" cy="80.4" r="17" fill="hsl(330, 70%, 50%)" stroke="var(--line)" strokeWidth="1" />
<text x="210" y="30" textAnchor="middle" fontSize="12" fill="var(--muted)">0° 빨강</text>
<text x="282.5" y="49" textAnchor="middle" fontSize="12" fill="var(--ink)" fontWeight="bold">30° 주황</text>
<text x="335.7" y="102" textAnchor="middle" fontSize="12" fill="var(--muted)">60°</text>
<text x="370" y="184" textAnchor="middle" fontSize="12" fill="var(--muted)">90° 연두</text>
<text x="335.7" y="266" textAnchor="middle" fontSize="12" fill="var(--muted)">120°</text>
<text x="282.5" y="319" textAnchor="middle" fontSize="12" fill="var(--muted)">150°</text>
<text x="210" y="338" textAnchor="middle" fontSize="12" fill="var(--muted)">180° 청록</text>
<text x="122" y="322" textAnchor="middle" fontSize="12" fill="var(--ink)" fontWeight="bold">210° 파랑</text>
<text x="84.3" y="266" textAnchor="middle" fontSize="12" fill="var(--muted)">240°</text>
<text x="50" y="184" textAnchor="middle" fontSize="12" fill="var(--muted)">270° 보라</text>
<text x="84.3" y="102" textAnchor="middle" fontSize="12" fill="var(--muted)">300°</text>
<text x="137.5" y="49" textAnchor="middle" fontSize="12" fill="var(--muted)">330°</text>
<line x1="404" y1="70" x2="444" y2="70" stroke="var(--ink)" strokeWidth="2" strokeDasharray="6 5" strokeLinecap="round" />
<text x="454" y="74" fontSize="14" fill="var(--ink)" fontWeight="bold">보색 마주보는 </text>
<text x="454" y="96" fontSize="13" fill="var(--muted)">180° 차이 · 대비가 강렬</text>
<text x="454" y="115" fontSize="13" fill="var(--muted)">강조 곳에만 작게</text>
<line x1="404" y1="160" x2="444" y2="160" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<text x="454" y="164" fontSize="14" fill="var(--ink)" fontWeight="bold">유사색 옆자리 </text>
<text x="454" y="186" fontSize="13" fill="var(--muted)">±30° 안팎 · 차분하고 조화</text>
<text x="454" y="205" fontSize="13" fill="var(--muted)">넓은 면적(배경·카드)</text>
<rect x="404" y="240" width="216" height="76" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="418" y="264" fontSize="13" fill="var(--ink)">우리 블루 219° 보색 주황 39°</text>
<text x="418" y="286" fontSize="13" fill="var(--muted)">싸울 맞은편(보색),</text>
<text x="418" y="305" fontSize="13" fill="var(--muted)">친할 옆자리(유사색)</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 12 색상환 마주보면 보색(강조), 이웃하면 유사색(조화)</p>
<div className="warn">
<b>주의</b> 보색을 글자와 배경으로 쓰는 금물이에요. 예를 들어 파란 배경에
주황 글자는 경계가 아른아른 떨리는 <strong>진동 현상</strong> 생겨 읽기 괴롭습니다.

View File

@ -252,6 +252,68 @@ export default function DesignRefsPage() {
단어라도 붙이는 습관 이게 무드보드의 절반입니다. 그리고 <strong>출처 URL</strong>
함께 섹션 3에서 배웠듯, 어디서 이미지인지 모르면 나중에 라이선스 확인도 해요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="무드보드 구성 3단계: 여러 레퍼런스를 수집하고, 태그로 분류해 프레임으로 묶고, 한 줄 분석을 붙인다">
<text x="100" y="26" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--ink)"> 수집</text>
<text x="320" y="26" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--teal)"> 태그 분류</text>
<text x="545" y="26" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--amber)"> 분석</text>
<rect x="24" y="46" width="152" height="72" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="100" y="74" textAnchor="middle" fontSize="13" fill="var(--ink)">스크린샷 A</text>
<text x="100" y="98" textAnchor="middle" fontSize="12" fill="var(--muted)">출처 URL 함께</text>
<rect x="24" y="132" width="152" height="72" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="100" y="160" textAnchor="middle" fontSize="13" fill="var(--ink)">스크린샷 B</text>
<text x="100" y="184" textAnchor="middle" fontSize="12" fill="var(--muted)">출처 URL 함께</text>
<rect x="24" y="218" width="152" height="72" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="100" y="246" textAnchor="middle" fontSize="13" fill="var(--ink)">스크린샷 C</text>
<text x="100" y="270" textAnchor="middle" fontSize="12" fill="var(--muted)">출처 URL 함께</text>
<text x="100" y="316" textAnchor="middle" fontSize="12" fill="var(--muted)">피그마 캔버스에 붙여넣기</text>
<line x1="186" y1="168" x2="234" y2="168" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<polyline points="226,161 234,168 226,175" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<rect x="244" y="46" width="152" height="112" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="320" y="70" textAnchor="middle" fontSize="12.5" fill="var(--teal)">Frame "따뜻한 색감"</text>
<rect x="258" y="82" width="60" height="26" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="288" y="99" textAnchor="middle" fontSize="12" fill="var(--ink)">[색감]</text>
<rect x="326" y="82" width="60" height="26" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="356" y="99" textAnchor="middle" fontSize="12" fill="var(--ink)">[색감]</text>
<text x="320" y="134" textAnchor="middle" fontSize="12" fill="var(--muted)">A · C 묶음</text>
<rect x="244" y="176" width="152" height="112" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="320" y="200" textAnchor="middle" fontSize="12.5" fill="var(--teal)">Frame "카드 레이아웃"</text>
<rect x="258" y="212" width="60" height="26" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="288" y="229" textAnchor="middle" fontSize="12" fill="var(--ink)">[카드UI]</text>
<rect x="326" y="212" width="60" height="26" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="356" y="229" textAnchor="middle" fontSize="12" fill="var(--ink)">[여백]</text>
<text x="320" y="264" textAnchor="middle" fontSize="12" fill="var(--muted)">B 묶음</text>
<text x="320" y="316" textAnchor="middle" fontSize="12" fill="var(--muted)">저장하는 순간 태그 단어</text>
<line x1="406" y1="168" x2="454" y2="168" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<polyline points="446,161 454,168 446,175" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<rect x="464" y="46" width="152" height="112" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="540" y="70" textAnchor="middle" fontSize="12.5" fill="var(--amber)"> 분석</text>
<text x="540" y="94" textAnchor="middle" fontSize="12" fill="var(--ink)">"완료 표시에만</text>
<text x="540" y="112" textAnchor="middle" fontSize="12" fill="var(--ink)">색을 줘서 시선이</text>
<text x="540" y="130" textAnchor="middle" fontSize="12" fill="var(--ink)">모인다"</text>
<rect x="464" y="176" width="152" height="112" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="540" y="200" textAnchor="middle" fontSize="12.5" fill="var(--amber)"> 분석</text>
<text x="540" y="224" textAnchor="middle" fontSize="12" fill="var(--ink)">"제목-부제 크기</text>
<text x="540" y="242" textAnchor="middle" fontSize="12" fill="var(--ink)">차이가 커서</text>
<text x="540" y="260" textAnchor="middle" fontSize="12" fill="var(--ink)">위계가 산다"</text>
<text x="540" y="316" textAnchor="middle" fontSize="12" fill="var(--muted)">우리 플랫폼 적용까지 문장</text>
<text x="320" y="344" textAnchor="middle" fontSize="12.5" fill="var(--muted)">무드보드는 '전시' 아니라 빨리 찾는 '작업 도구'</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 수집 태그 분류(프레임 묶기) 분석으로 이어지는 무드보드 구성</p>
<div className="tip">
<b>직접 확인해 보기</b> 지금 바로 피그마에 파일을 만들고, 우리 학습 플랫폼의
지금 페이지를 <span className="kbd">Win</span>+<span className="kbd">Shift</span>+

View File

@ -250,6 +250,50 @@ export default function DesignSystemPage() {
지금 여러분이 보고 있는 페이지의 카드· 박스·코드 블록 색이 전부 거기서
출발합니다. 파일이 우리 플랫폼 디자인 시스템의 <strong>1</strong> 셈이에요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="3단 계층도: 1층 토큰(색·간격)이 모여 2층 컴포넌트(버튼·카드)를 만들고, 그것이 3층 화면을 구성한다">
<text x="320" y="24" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--ink)">아래가 위를 구성한다</text>
<text x="30" y="66" fontSize="12.5" fill="var(--muted)">3</text>
<rect x="80" y="46" width="480" height="86" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="320" y="72" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--ink)">화면</text>
<rect x="104" y="86" width="150" height="32" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="179" y="107" textAnchor="middle" fontSize="12" fill="var(--muted)">로그인 페이지</text>
<rect x="266" y="86" width="150" height="32" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="341" y="107" textAnchor="middle" fontSize="12" fill="var(--muted)">과제 제출</text>
<rect x="428" y="86" width="110" height="32" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="483" y="107" textAnchor="middle" fontSize="12" fill="var(--muted)">마이페이지</text>
<line x1="320" y1="176" x2="320" y2="140" stroke="var(--line)" strokeWidth="2" strokeDasharray="5 4" strokeLinecap="round" />
<path d="M 320 132 L 314 144 L 326 144 Z" fill="var(--line)" />
<text x="336" y="164" fontSize="12" fill="var(--muted)">조립하면 화면이 된다</text>
<text x="30" y="200" fontSize="12.5" fill="var(--muted)">2</text>
<rect x="80" y="176" width="480" height="86" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="320" y="202" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--ink)">컴포넌트</text>
<rect x="128" y="216" width="130" height="32" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="193" y="237" textAnchor="middle" fontSize="12" fill="var(--muted)">버튼 Button</text>
<rect x="278" y="216" width="110" height="32" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="333" y="237" textAnchor="middle" fontSize="12" fill="var(--muted)">카드 Card</text>
<rect x="408" y="216" width="110" height="32" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="463" y="237" textAnchor="middle" fontSize="12" fill="var(--muted)">배지 Badge</text>
<line x1="320" y1="306" x2="320" y2="270" stroke="var(--line)" strokeWidth="2" strokeDasharray="5 4" strokeLinecap="round" />
<path d="M 320 262 L 314 274 L 326 274 Z" fill="var(--line)" />
<text x="336" y="294" fontSize="12" fill="var(--muted)">조합하면 부품이 된다</text>
<text x="30" y="330" fontSize="12.5" fill="var(--muted)">1</text>
<rect x="80" y="306" width="480" height="44" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" />
<text x="150" y="334" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--ink)">토큰</text>
<circle cx="238" cy="328" r="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<text x="292" y="333" textAnchor="middle" fontSize="12" fill="var(--muted)"> --color-primary</text>
<line x1="368" y1="320" x2="368" y2="336" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<line x1="392" y1="320" x2="392" y2="336" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<text x="452" y="333" textAnchor="middle" fontSize="12" fill="var(--muted)">간격 --space-2</text>
<text x="524" y="333" textAnchor="middle" fontSize="12" fill="var(--muted)">글꼴 --font-md</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 1 토큰이 2 컴포넌트를, 컴포넌트가 3 화면을 구성한다 global.css의 :root가 건물의 1</p>
<div className="tip">
<b>직접 확인해 보기 </b> 페이지에서 <span className="kbd">F12</span> 눌러
개발자 도구를 열고, <span className="kbd">Elements</span> 탭에서 위의

View File

@ -192,6 +192,49 @@ export default function IconsImagesPage() {
네모 (픽셀) 드러나면서 계단처럼 깨지고, 벡터는 아무리 확대해도 매끈해요.
설계도는 크게 지어도 설계도니까요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="비트맵을 확대하면 픽셀 칸이 드러나 계단처럼 깨지고, 벡터를 확대하면 다시 계산되어 매끈한 곡선이 유지되는 좌우 비교 그림">
<text x="160" y="28" textAnchor="middle" fill="var(--ink)" fontSize="15" fontWeight="600">비트맵 (PNG · JPG)</text>
<text x="160" y="48" textAnchor="middle" fill="var(--muted)" fontSize="12.5">칸마다 색을 기록</text>
<text x="480" y="28" textAnchor="middle" fill="var(--ink)" fontSize="15" fontWeight="600">벡터 (SVG)</text>
<text x="480" y="48" textAnchor="middle" fill="var(--muted)" fontSize="12.5">그리는 법을 기록</text>
<line x1="320" y1="20" x2="320" y2="340" stroke="var(--line)" strokeWidth="1" strokeDasharray="5 5" />
<rect x="100" y="66" width="120" height="60" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<path d="M 130 110 Q 160 74 190 110" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<text x="160" y="144" textAnchor="middle" fill="var(--muted)" fontSize="12">원래 크기</text>
<rect x="420" y="66" width="120" height="60" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<path d="M 450 110 Q 480 74 510 110" fill="none" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<text x="480" y="144" textAnchor="middle" fill="var(--muted)" fontSize="12">원래 크기</text>
<text x="160" y="170" textAnchor="middle" fill="var(--muted)" fontSize="12"> 확대</text>
<text x="480" y="170" textAnchor="middle" fill="var(--muted)" fontSize="12"> 확대</text>
<rect x="60" y="184" width="200" height="120" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<line x1="100" y1="184" x2="100" y2="304" stroke="var(--line)" strokeWidth="1" />
<line x1="140" y1="184" x2="140" y2="304" stroke="var(--line)" strokeWidth="1" />
<line x1="180" y1="184" x2="180" y2="304" stroke="var(--line)" strokeWidth="1" />
<line x1="220" y1="184" x2="220" y2="304" stroke="var(--line)" strokeWidth="1" />
<line x1="60" y1="224" x2="260" y2="224" stroke="var(--line)" strokeWidth="1" />
<line x1="60" y1="264" x2="260" y2="264" stroke="var(--line)" strokeWidth="1" />
<rect x="60" y="264" width="40" height="40" fill="var(--rose)" />
<rect x="100" y="224" width="40" height="40" fill="var(--rose)" />
<rect x="140" y="184" width="40" height="40" fill="var(--rose)" />
<rect x="180" y="224" width="40" height="40" fill="var(--rose)" />
<rect x="220" y="264" width="40" height="40" fill="var(--rose)" />
<text x="160" y="326" textAnchor="middle" fill="var(--rose)" fontSize="13" fontWeight="600">칸이 커져 계단 현상</text>
<text x="160" y="346" textAnchor="middle" fill="var(--muted)" fontSize="12">없는 정보는 만들어 없다</text>
<rect x="380" y="184" width="200" height="120" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" />
<path d="M 400 288 Q 480 168 560 288" fill="none" stroke="var(--teal)" strokeWidth="4" strokeLinecap="round" />
<circle cx="400" cy="288" r="4" fill="var(--teal)" />
<circle cx="560" cy="288" r="4" fill="var(--teal)" />
<circle cx="480" cy="208" r="4" fill="var(--amber)" />
<text x="480" y="326" textAnchor="middle" fill="var(--teal)" fontSize="13" fontWeight="600">다시 계산해 그림 매끈</text>
<text x="480" y="346" textAnchor="middle" fill="var(--muted)" fontSize="12">설계도는 크게 지어도 설계도</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 확대하면 정체가 드러난다 비트맵은 픽셀 칸이 커져 계단이 되고, 벡터는 좌표를 다시 계산해 언제나 매끈하다</p>
<Code>{CODE_FORMAT_TABLE}</Code>
<div className="tip">
<b>직접 확인해 보기</b> 우리 학습 플랫폼을 상태에서

View File

@ -323,6 +323,69 @@ export default function LayoutPage() {
디자인 원리(근접성·정렬) 코드 구조(컴포넌트 재사용) 카드라는 지점에서
만나는 셈이죠.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="8pt 그리드 위에 카드 세 장이 놓인 그림. 점선 격자와 왼쪽·윗변 정렬선이 보이고, 카드 안 간격 8과 카드 사이 간격 24가 표시되어 있다.">
<line x1="40" y1="56" x2="600" y2="56" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="80" x2="600" y2="80" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="104" x2="600" y2="104" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="128" x2="600" y2="128" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="152" x2="600" y2="152" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="176" x2="600" y2="176" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="200" x2="600" y2="200" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="224" x2="600" y2="224" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="248" x2="600" y2="248" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="40" y1="272" x2="600" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="64" y1="56" x2="64" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="112" y1="56" x2="112" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="160" y1="56" x2="160" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="208" y1="56" x2="208" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="256" y1="56" x2="256" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="304" y1="56" x2="304" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="352" y1="56" x2="352" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="400" y1="56" x2="400" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="448" y1="56" x2="448" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="496" y1="56" x2="496" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="544" y1="56" x2="544" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<line x1="592" y1="56" x2="592" y2="272" stroke="var(--line)" strokeWidth="1" strokeDasharray="2 6" />
<text x="40" y="28" fontSize="13" fill="var(--muted)">보이지 않는 8pt 모눈종이 모든 간격이 8 배수</text>
<line x1="24" y1="80" x2="616" y2="80" stroke="var(--primary)" strokeWidth="1.5" strokeDasharray="6 4" />
<line x1="40" y1="40" x2="40" y2="300" stroke="var(--primary)" strokeWidth="1.5" strokeDasharray="6 4" />
<text x="20" y="48" fontSize="12" fill="var(--primary)">정렬선</text>
<rect x="40" y="80" width="160" height="160" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<rect x="224" y="80" width="160" height="160" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<rect x="408" y="80" width="160" height="160" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="64" y="118" fontSize="14" fontWeight="600" fill="var(--ink)">네트워크</text>
<text x="64" y="142" fontSize="12" fill="var(--muted)">코스 설명</text>
<rect x="64" y="184" width="88" height="32" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="76" y="205" fontSize="12" fill="var(--teal)">시작하기</text>
<text x="248" y="118" fontSize="14" fontWeight="600" fill="var(--ink)">디자인</text>
<text x="248" y="142" fontSize="12" fill="var(--muted)">코스 설명</text>
<rect x="248" y="184" width="88" height="32" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="260" y="205" fontSize="12" fill="var(--teal)">시작하기</text>
<text x="432" y="118" fontSize="14" fontWeight="600" fill="var(--ink)">코딩 기초</text>
<text x="432" y="142" fontSize="12" fill="var(--muted)">코스 설명</text>
<rect x="432" y="184" width="88" height="32" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="444" y="205" fontSize="12" fill="var(--teal)">시작하기</text>
<line x1="176" y1="126" x2="176" y2="134" stroke="var(--amber)" strokeWidth="2" strokeLinecap="round" />
<text x="186" y="132" fontSize="12" fill="var(--amber)">8</text>
<line x1="176" y1="150" x2="176" y2="182" stroke="var(--rose)" strokeWidth="2" strokeLinecap="round" />
<text x="186" y="172" fontSize="12" fill="var(--rose)">24</text>
<line x1="200" y1="260" x2="224" y2="260" stroke="var(--rose)" strokeWidth="2" strokeLinecap="round" />
<text x="196" y="280" fontSize="12" fill="var(--rose)">24</text>
<text x="256" y="280" fontSize="12" fill="var(--muted)">카드 사이는 넓게 카드 하나가 팀으로 보인다</text>
<text x="40" y="322" fontSize="12" fill="var(--amber)">좁은 간격 8 = 제목과 설명은 </text>
<text x="320" y="322" fontSize="12" fill="var(--rose)">넓은 간격 24 = 다음 팀과는 남남</text>
<text x="40" y="344" fontSize="12" fill="var(--muted)"> 카드의 윗변·왼쪽이 같은 선에 올라앉아 있어서 그리드를 꺼도 정돈돼 보인다</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 8pt 그리드 위의 카드 정렬선이 뼈대를 잡고, 간격 차이(8 vs 24) 그룹을 만든다</p>
<div className="tip">
<b>직접 확인해 보기</b> 학습 센터 허브로 돌아가서 코스 카드들을 관찰해 보세요.
카드 사이 간격은 일정한가요? 카드 안에서 제목·설명·버튼의 위치는 카드마다 같은가요?

View File

@ -233,6 +233,38 @@ export default function MobileDesignPage() {
버스 손잡이를 잡은 반대 손으로 폰을 쓰는 자신을 떠올려 보세요.
</p>
<Code>{CODE_THUMB_ZONE}</Code>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="한 손으로 폰을 쥐었을 때 엄지가 닿는 영역을 폰 화면 위에 세 구간으로 나눈 그림. 하단은 편한 영역, 중간은 애매한 영역, 상단 모서리는 힘든 영역.">
<rect x="200" y="20" width="200" height="320" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="2" />
<rect x="212" y="40" width="176" height="93" rx="8" fill="var(--card)" stroke="var(--rose)" strokeWidth="2" strokeDasharray="5 4" />
<rect x="212" y="137" width="176" height="90" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" strokeDasharray="5 4" />
<rect x="212" y="231" width="176" height="89" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="300" y="80" textAnchor="middle" fontSize="14" fill="var(--ink)">힘든 영역</text>
<text x="300" y="100" textAnchor="middle" fontSize="12" fill="var(--muted)">엄지를 뻗어야 닿음</text>
<text x="300" y="118" textAnchor="middle" fontSize="12" fill="var(--muted)">가끔 쓰는 버튼 자리</text>
<text x="300" y="178" textAnchor="middle" fontSize="14" fill="var(--ink)">애매한 영역</text>
<text x="300" y="198" textAnchor="middle" fontSize="12" fill="var(--muted)">본문·콘텐츠</text>
<text x="300" y="258" textAnchor="middle" fontSize="14" fill="var(--ink)">편한 영역</text>
<text x="300" y="278" textAnchor="middle" fontSize="12" fill="var(--muted)">엄지의 홈그라운드</text>
<rect x="224" y="292" width="48" height="20" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<rect x="276" y="292" width="48" height="20" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<rect x="328" y="292" width="48" height="20" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="300" y="332" textAnchor="middle" fontSize="12" fill="var(--teal)">하단 탭바 = 자주 쓰는 내비게이션</text>
<circle cx="230" cy="58" r="9" fill="var(--card)" stroke="var(--rose)" strokeWidth="2" />
<text x="230" y="63" textAnchor="middle" fontSize="12" fill="var(--rose)"></text>
<line x1="196" y1="58" x2="120" y2="58" stroke="var(--rose)" strokeWidth="2" strokeLinecap="round" />
<text x="116" y="54" textAnchor="end" fontSize="13" fill="var(--ink)">상단 모서리 버튼</text>
<text x="116" y="72" textAnchor="end" fontSize="12" fill="var(--muted)">폰을 고쳐 잡아야 </text>
<line x1="404" y1="275" x2="500" y2="275" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<text x="508" y="271" fontSize="13" fill="var(--ink)">화면 아래쪽 1/3</text>
<text x="508" y="289" fontSize="12" fill="var(--muted)"> 손으로 닿는 구간</text>
<text x="508" y="120" fontSize="13" fill="var(--ink)">터치 타깃</text>
<rect x="508" y="132" width="44" height="44" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="530" y="159" textAnchor="middle" fontSize="12" fill="var(--primary)">44px</text>
<text x="562" y="159" fontSize="12" fill="var(--muted)">누르기 쉬움</text>
<rect x="508" y="190" width="24" height="24" rx="8" fill="var(--card)" stroke="var(--muted)" strokeWidth="2" />
<text x="540" y="206" fontSize="12" fill="var(--muted)">24px 빗나감</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 엄지 도달 범위 아래쪽 1/3 편하고, 위쪽 모서리로 갈수록 힘들어진다</p>
<p>
번째 법칙은 <strong>과녁의 크기</strong>예요. 마우스 커서는 바늘 끝이지만,
엄지는 도장입니다. 도장으로 바늘구멍을 맞출 수는 없죠. 그래서 눌리는 모든 것은

View File

@ -224,6 +224,60 @@ export default function PortfolioPage() {
읽는 사람이 <em></em> 있어요. 프로젝트일수록 그래요
단체 사진 속에서 나를 찾으려면 내가 어디 있는지 표시해 줘야 하니까요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="STAR 구조 도해 — 상황, 과제, 행동, 결과의 흐름과 각 칸에 쓸 내용">
<text x="20" y="26" fontSize="14" fontWeight="600" fill="var(--ink)">STAR 프로젝트 개를 담는 4 흐름</text>
<rect x="20" y="48" width="130" height="70" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="85" y="74" fontSize="14" fontWeight="600" textAnchor="middle" fill="var(--primary)">S · 상황</text>
<text x="85" y="96" fontSize="12" textAnchor="middle" fill="var(--muted)">어떤 프로젝트,</text>
<text x="85" y="111" fontSize="12" textAnchor="middle" fill="var(--muted)">나는 무슨 역할</text>
<rect x="180" y="48" width="130" height="70" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="245" y="74" fontSize="14" fontWeight="600" textAnchor="middle" fill="var(--teal)">T · 과제</text>
<text x="245" y="96" fontSize="12" textAnchor="middle" fill="var(--muted)">내가 맡은</text>
<text x="245" y="111" fontSize="12" textAnchor="middle" fill="var(--muted)">문제와 목표</text>
<rect x="340" y="48" width="130" height="70" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="3" />
<text x="405" y="74" fontSize="14" fontWeight="600" textAnchor="middle" fill="var(--amber)">A · 행동</text>
<text x="405" y="96" fontSize="12" textAnchor="middle" fill="var(--muted)">내가 구체적으로</text>
<text x="405" y="111" fontSize="12" textAnchor="middle" fill="var(--muted)"> (제일 길게)</text>
<rect x="500" y="48" width="120" height="70" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="560" y="74" fontSize="14" fontWeight="600" textAnchor="middle" fill="var(--rose)">R · 결과</text>
<text x="560" y="96" fontSize="12" textAnchor="middle" fill="var(--muted)">뭐가 달라졌나</text>
<text x="560" y="111" fontSize="12" textAnchor="middle" fill="var(--muted)">+ 배웠나</text>
<line x1="152" y1="83" x2="176" y2="83" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polyline points="170,78 177,83 170,88" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<line x1="312" y1="83" x2="336" y2="83" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polyline points="330,78 337,83 330,88" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<line x1="472" y1="83" x2="496" y2="83" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polyline points="490,78 497,83 490,88" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<text x="85" y="146" fontSize="12" textAnchor="middle" fill="var(--muted)">무대를 깐다</text>
<text x="245" y="146" fontSize="12" textAnchor="middle" fill="var(--muted)">목표를 세운다</text>
<text x="405" y="146" fontSize="12" textAnchor="middle" fill="var(--amber)">주인공이 움직인다</text>
<text x="560" y="146" fontSize="12" textAnchor="middle" fill="var(--muted)">막을 내린다</text>
<rect x="340" y="170" width="280" height="130" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="360" y="194" fontSize="13" fontWeight="600" fill="var(--amber)">A 칸을 채우는 재료</text>
<text x="360" y="220" fontSize="12" fill="var(--ink)">· 무엇을 시도했나</text>
<text x="360" y="242" fontSize="12" fill="var(--ink)">· 어떤 방법들을 비교했나</text>
<text x="360" y="264" fontSize="12" fill="var(--ink)">· 방법을 골랐나</text>
<text x="360" y="286" fontSize="12" fill="var(--ink)">· 시도했다가 버린 것은</text>
<line x1="405" y1="122" x2="405" y2="166" stroke="var(--amber)" strokeWidth="2" strokeDasharray="4 4" strokeLinecap="round" />
<rect x="20" y="170" width="290" height="130" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="40" y="194" fontSize="13" fontWeight="600" fill="var(--ink)">흔한 함정</text>
<text x="40" y="220" fontSize="12" fill="var(--muted)">S와 R만 길게 쓰고</text>
<text x="40" y="242" fontSize="12" fill="var(--muted)">A를 줄로 끝낸다</text>
<text x="40" y="270" fontSize="12" fill="var(--rose)">읽는 사람이 궁금한 A </text>
<text x="40" y="288" fontSize="12" fill="var(--rose)">"너는 뭘 했는데?"</text>
<text x="320" y="332" fontSize="12.5" textAnchor="middle" fill="var(--muted)">S · T · A · R 길이의 절반은 A가 가져가야 한다</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: STAR 4칸의 흐름 무대(S·T) 주인공의 행동(A) 결말(R), 승부처는 A</p>
<div className="tip">
<b>직접 확인해 보기</b> 가장 최근에 끝낸 과제 하나를 골라, 종이에 S/T/A/R 줄만
보세요. 5분이면 됩니다. A가 줄밖에 나온다면 과제를 하며

View File

@ -255,6 +255,62 @@ export default function ToolCapturePage() {
거죠?"</strong> 화면엔 버튼이 스무 개인데 문제는 하나거든요. 주석은 캡처에
자막을 다는 일입니다. 시선을 문제 지점으로 데려다주는 내비게이션이에요.
</p>
<svg
className="diagram"
viewBox="0 0 640 360"
xmlns="http://www.w3.org/2000/svg"
role="img"
aria-label="주석이 달린 버그 리포트 캡처 예시 — 문제 영역을 두른 빨간 박스, 정확한 지점을 가리키는 화살표, 기대와 실제를 적은 텍스트 주석"
>
<rect x="24" y="46" width="360" height="270" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<line x1="24" y1="78" x2="384" y2="78" stroke="var(--line)" strokeWidth="1.5" />
<circle cx="42" cy="62" r="4" fill="var(--muted)" />
<circle cx="56" cy="62" r="4" fill="var(--muted)" />
<circle cx="70" cy="62" r="4" fill="var(--muted)" />
<text x="90" y="66" fontSize="12" fill="var(--muted)">캡처한 화면</text>
<text x="44" y="104" fontSize="13" fill="var(--ink)">주문서 작성</text>
<rect x="44" y="118" width="320" height="26" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="56" y="136" fontSize="12" fill="var(--muted)">수량 입력</text>
<rect x="44" y="154" width="320" height="26" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="56" y="172" fontSize="12" fill="var(--muted)">배송지 입력</text>
<rect x="44" y="200" width="150" height="34" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="60" y="222" fontSize="12" fill="var(--muted)">취소</text>
<rect x="214" y="200" width="150" height="34" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="230" y="222" fontSize="12" fill="var(--ink)">저장하기</text>
<rect x="204" y="190" width="170" height="54" rx="8" fill="none" stroke="var(--rose)" strokeWidth="2.5" />
<text x="44" y="268" fontSize="12" fill="var(--rose)">500 Internal Server Error</text>
<text x="44" y="290" fontSize="12" fill="var(--muted)">저장 결과가 화면에 반영되지 않음</text>
<text x="404" y="66" fontSize="13" fontWeight="600" fill="var(--ink)">주석 3 세트</text>
<line x1="470" y1="120" x2="380" y2="205" stroke="var(--rose)" strokeWidth="2.5" strokeLinecap="round" />
<polyline points="380,205 396,203 388,190" fill="none" stroke="var(--rose)" strokeWidth="2.5" strokeLinecap="round" />
<circle cx="416" cy="112" r="9" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
<text x="412" y="117" fontSize="12" fill="var(--rose)">1</text>
<text x="434" y="117" fontSize="13" fill="var(--ink)">화살표 정확한 지점 지시</text>
<circle cx="416" cy="150" r="9" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
<text x="412" y="155" fontSize="12" fill="var(--rose)">2</text>
<text x="434" y="155" fontSize="13" fill="var(--ink)">빨간 박스 문제 영역 강조</text>
<circle cx="416" cy="188" r="9" fill="none" stroke="var(--rose)" strokeWidth="1.5" />
<text x="412" y="193" fontSize="12" fill="var(--rose)">3</text>
<text x="434" y="193" fontSize="13" fill="var(--ink)">텍스트 기대 / 실제 </text>
<rect x="404" y="212" width="212" height="86" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="418" y="236" fontSize="12" fill="var(--muted)">여백에 적는 </text>
<text x="418" y="258" fontSize="12.5" fill="var(--ink)">기대: 저장 목록으로 이동</text>
<text x="418" y="280" fontSize="12.5" fill="var(--ink)">실제: 500 에러, 화면 그대로</text>
<text x="24" y="336" fontSize="12" fill="var(--muted)">색은 빨강 하나로 통일 · PNG로 저장</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>
그림: 빨간 박스 · 화살표 · 기대/실제 되묻지 않아도 되는 캡처
</p>
<Code>{CODE_ANNOTATE}</Code>
<p>주석 달기의 순서는 같아요.</p>
<ol className="olist">

View File

@ -209,6 +209,36 @@ export default function ToolDbeaverPage() {
(host) (port) 걸어서, 어떤 (database), 누구(user)라고 밝히고
들어갈지 네트워크 코스에서 배운 IP·포트가 여기서 그대로 쓰입니다.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="내 PC의 DBeaver가 localhost 5432 포트를 통해 도커 PostgreSQL 컨테이너에 연결되는 경로">
<rect x="20" y="40" width="600" height="290" rx="8" fill="none" stroke="var(--line)" strokeDasharray="6 4" />
<text x="34" y="62" fontSize="13" fill="var(--muted)"> PC (localhost)</text>
<rect x="50" y="120" width="170" height="90" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="135" y="152" fontSize="15" textAnchor="middle" fill="var(--ink)" fontWeight="600">DBeaver</text>
<text x="135" y="174" fontSize="12" textAnchor="middle" fill="var(--muted)">GUI 클라이언트</text>
<text x="135" y="192" fontSize="12" textAnchor="middle" fill="var(--muted)">보여주기만 </text>
<line x1="220" y1="165" x2="292" y2="165" stroke="var(--teal)" strokeWidth="2" />
<line x1="348" y1="165" x2="418" y2="165" stroke="var(--teal)" strokeWidth="2" />
<polyline points="410,159 418,165 410,171" fill="none" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<rect x="292" y="145" width="56" height="40" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="320" y="170" fontSize="12" textAnchor="middle" fill="var(--ink)">5432</text>
<text x="320" y="130" fontSize="12" textAnchor="middle" fill="var(--muted)">포트( 번호)</text>
<text x="320" y="205" fontSize="12" textAnchor="middle" fill="var(--muted)">SQL 요청 · 응답</text>
<rect x="418" y="100" width="180" height="130" rx="8" fill="none" stroke="var(--amber)" strokeWidth="2" />
<text x="508" y="122" fontSize="12" textAnchor="middle" fill="var(--amber)">Docker 컨테이너</text>
<rect x="438" y="136" width="140" height="76" rx="8" fill="var(--card)" stroke="var(--line)" />
<text x="508" y="164" fontSize="14" textAnchor="middle" fill="var(--ink)" fontWeight="600">PostgreSQL</text>
<text x="508" y="186" fontSize="12" textAnchor="middle" fill="var(--muted)">mirim-postgres</text>
<text x="508" y="202" fontSize="12" textAnchor="middle" fill="var(--muted)">DB: mirim</text>
<text x="60" y="270" fontSize="12" fill="var(--muted)">Host: localhost DB가 PC에서 돌고 있으니까</text>
<text x="60" y="292" fontSize="12" fill="var(--muted)">Port: 5432 · Database/User: mirim</text>
<text x="60" y="314" fontSize="12" fill="var(--rose)">컨테이너가 꺼져 있으면 연결 실패 docker compose up -d</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: DBeaver localhost:5432 도커 PostgreSQL 컨테이너로 이어지는 연결 경로</p>
<ol className="olist">
<li>먼저 DB가 켜져 있는지 확인 프로젝트 폴더에서 <span className="icode">docker compose up -d</span>.</li>
<li>DBeaver에서 왼쪽 <strong>플러그 모양( 연결)</strong> 아이콘 클릭 <strong>PostgreSQL</strong> 선택.</li>

View File

@ -235,6 +235,50 @@ export default function ToolDevtoolsPage() {
<strong> 어떻게 만들어졌고, 지금 무슨 일이 벌어지는지</strong> 전부 보여요.
자동차로 치면 겉모습만 보다가 처음으로 보닛을 열어 보는 순간입니다.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="개발자도구 탭 지도: Elements는 HTML과 CSS, Console은 JS 실행과 에러, Network는 서버 요청 기록을 보여 준다">
<rect x="20" y="16" width="600" height="48" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="40" y="46" fontSize="14" fill="var(--ink)">지금 보는 웹페이지</text>
<text x="200" y="46" fontSize="13" fill="var(--muted)">F12를 누르면 아래 탭들이 열립니다</text>
<text x="588" y="47" fontSize="15" fill="var(--primary)" fontWeight="bold" textAnchor="middle">F12</text>
<line x1="150" y1="64" x2="150" y2="92" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="4 4" />
<line x1="320" y1="64" x2="320" y2="92" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="4 4" />
<line x1="490" y1="64" x2="490" y2="92" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="4 4" />
<rect x="30" y="92" width="180" height="200" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="120" y="120" fontSize="15" fill="var(--primary)" fontWeight="bold" textAnchor="middle">Elements</text>
<line x1="46" y1="132" x2="194" y2="132" stroke="var(--line)" strokeWidth="1" />
<text x="120" y="154" fontSize="13" fill="var(--ink)" textAnchor="middle">화면의 HTML / CSS</text>
<text x="120" y="180" fontSize="12.5" fill="var(--muted)" textAnchor="middle">왼쪽: HTML 트리</text>
<text x="120" y="200" fontSize="12.5" fill="var(--muted)" textAnchor="middle">오른쪽: Styles 패널</text>
<text x="120" y="220" fontSize="12.5" fill="var(--muted)" textAnchor="middle"> 자리에서 수정 가능</text>
<text x="120" y="250" fontSize="12.5" fill="var(--ink)" textAnchor="middle">보닛 열고 엔진 구경</text>
<text x="120" y="274" fontSize="12" fill="var(--muted)" textAnchor="middle">F5 누르면 원상복구</text>
<rect x="230" y="92" width="180" height="200" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="320" y="120" fontSize="15" fill="var(--teal)" fontWeight="bold" textAnchor="middle">Console</text>
<line x1="246" y1="132" x2="394" y2="132" stroke="var(--line)" strokeWidth="1" />
<text x="320" y="154" fontSize="13" fill="var(--ink)" textAnchor="middle">JS 실행 / 에러</text>
<text x="320" y="180" fontSize="12.5" fill="var(--muted)" textAnchor="middle">즉석 JS 계산기</text>
<text x="320" y="200" fontSize="12.5" fill="var(--muted)" textAnchor="middle">console.log 출력</text>
<text x="320" y="220" fontSize="12.5" fill="var(--rose)" textAnchor="middle">빨간 에러 메시지</text>
<text x="320" y="250" fontSize="12.5" fill="var(--ink)" textAnchor="middle">계기판 경고등 판독기</text>
<text x="320" y="274" fontSize="12" fill="var(--muted)" textAnchor="middle">파일:줄번호가 범인 위치</text>
<rect x="430" y="92" width="180" height="200" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" />
<text x="520" y="120" fontSize="15" fill="var(--amber)" fontWeight="bold" textAnchor="middle">Network</text>
<line x1="446" y1="132" x2="594" y2="132" stroke="var(--line)" strokeWidth="1" />
<text x="520" y="154" fontSize="13" fill="var(--ink)" textAnchor="middle">서버와 주고받은 요청</text>
<text x="520" y="180" fontSize="12.5" fill="var(--muted)" textAnchor="middle">Status · Size · Time</text>
<text x="520" y="200" fontSize="12.5" fill="var(--muted)" textAnchor="middle">Headers / Payload</text>
<text x="520" y="220" fontSize="12.5" fill="var(--muted)" textAnchor="middle">Response = 진짜 JSON</text>
<text x="520" y="250" fontSize="12.5" fill="var(--ink)" textAnchor="middle">블랙박스 영상</text>
<text x="520" y="274" fontSize="12" fill="var(--muted)" textAnchor="middle">React ? 서버 ?</text>
<rect x="30" y="308" width="580" height="38" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="320" y="332" fontSize="12.5" fill="var(--muted)" textAnchor="middle"> 셋이 기본 3 세트 · 반응형 모드 · Lighthouse · Sources는 섹션에서</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 개발자도구 지도 Elements는 화면(HTML/CSS), Console은 실행과 에러, Network는 서버와의 대화를 보여 준다</p>
<Code>{CODE_TAB_TOUR}</Code>
<p>
여는 방법부터 손에 익혀 둡시다. 특히 3(우클릭 검사) "지금 눈에 보이는

View File

@ -215,6 +215,52 @@ export default function ToolDockerPage() {
지웠다 다시 만드는 일상이라, DB 데이터처럼 잃으면 되는 것은 컨테이너
바깥의 볼륨에 보관합니다.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Docker Desktop 대시보드의 Containers, Images, Volumes 세 탭과 각 탭에서 하는 일, 그리고 이미지에서 컨테이너를 만들고 볼륨에 데이터를 보관하는 관계">
<text x="20" y="24" fontSize="14" fontWeight="600" fill="var(--ink)">Docker Desktop 왼쪽 메뉴 개만 알면 90%</text>
<rect x="20" y="44" width="140" height="286" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="36" y="68" fontSize="12" fill="var(--muted)">왼쪽 메뉴</text>
<rect x="32" y="82" width="116" height="34" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
<text x="46" y="104" fontSize="13" fill="var(--ink)">Containers</text>
<rect x="32" y="128" width="116" height="34" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="46" y="150" fontSize="13" fill="var(--ink)">Images</text>
<rect x="32" y="174" width="116" height="34" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="46" y="196" fontSize="13" fill="var(--ink)">Volumes</text>
<text x="36" y="234" fontSize="12" fill="var(--muted)"> 밖의 메뉴는</text>
<text x="36" y="252" fontSize="12" fill="var(--muted)">수습 기간엔</text>
<text x="36" y="270" fontSize="12" fill="var(--muted)">거의 써요</text>
<line x1="148" y1="99" x2="196" y2="99" stroke="var(--primary)" strokeWidth="1.5" />
<line x1="148" y1="145" x2="196" y2="177" stroke="var(--teal)" strokeWidth="1.5" />
<line x1="148" y1="191" x2="196" y2="255" stroke="var(--amber)" strokeWidth="1.5" />
<rect x="196" y="66" width="424" height="66" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
<text x="212" y="88" fontSize="13" fontWeight="600" fill="var(--ink)">Containers · 지금 돌아가는 기계</text>
<text x="212" y="108" fontSize="12" fill="var(--muted)">시작 / 중지 / 재시작, 로그 보기, 포트 확인</text>
<text x="212" y="124" fontSize="12" fill="var(--muted)">초록 = 살아 있음, 회색 = 멈춰 있음</text>
<rect x="196" y="144" width="424" height="66" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="212" y="166" fontSize="13" fontWeight="600" fill="var(--ink)">Images · 기계의 설계도 창고</text>
<text x="212" y="186" fontSize="12" fill="var(--muted)">받아 이미지 목록, 용량 확인, 삭제</text>
<text x="212" y="202" fontSize="12" fill="var(--muted)">: postgres:16 (붕어빵 )</text>
<rect x="196" y="222" width="424" height="66" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="212" y="244" fontSize="13" fontWeight="600" fill="var(--ink)">Volumes · 기계 데이터 금고</text>
<text x="212" y="264" fontSize="12" fill="var(--muted)">DB 데이터처럼 지워지면 되는 </text>
<text x="212" y="280" fontSize="12" fill="var(--muted)">컨테이너를 지워도 볼륨은 남아요</text>
<path d="M 604 144 L 604 132" stroke="var(--teal)" strokeWidth="1.5" fill="none" />
<text x="384" y="308" fontSize="12.5" fill="var(--ink)">이미지(설계도) 컨테이너(기계) 찍어내고,</text>
<text x="384" y="326" fontSize="12.5" fill="var(--ink)">소중한 데이터는 볼륨(금고) 따로 보관</text>
<line x1="212" y1="300" x2="212" y2="330" stroke="var(--rose)" strokeWidth="1.5" strokeLinecap="round" />
<text x="228" y="308" fontSize="12.5" fill="var(--rose)">볼륨을 지우면</text>
<text x="228" y="326" fontSize="12.5" fill="var(--rose)">DB 데이터도 사라짐</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 대시보드 컨테이너(기계) · 이미지(설계도) · 볼륨(금고)</p>
<div className="warn">
<b>여기서 사고가 납니다</b> "컨테이너 지워도 다시 만들면 되지" 맞는 말이지만,
<strong> 볼륨까지 지우면 DB 데이터가 통째로 사라져요.</strong> Volumes 탭에서

View File

@ -294,6 +294,55 @@ export default function ToolGiteaPage() {
요청) 선택합니다. 승인이 모이면 <strong>Merge</strong> 버튼으로 정본에 합쳐지고,
PR은 보라색 "Merged" 상태가 돼요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="PR 흐름도: 브랜치 생성, 커밋, 푸시, PR 생성, 멘토 리뷰, 머지의 여섯 단계">
<rect x="24" y="40" width="168" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="108" y="66" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">1. 브랜치 생성</text>
<text x="108" y="88" textAnchor="middle" fontSize="12" fill="var(--muted)">feature/signup 우주 열기</text>
<rect x="236" y="40" width="168" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="320" y="66" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">2. 커밋</text>
<text x="320" y="88" textAnchor="middle" fontSize="12" fill="var(--muted)">일기 = 변경 묶음</text>
<rect x="448" y="40" width="168" height="64" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="532" y="66" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">3. 푸시</text>
<text x="532" y="88" textAnchor="middle" fontSize="12" fill="var(--muted)">Gitea 서버로 올리기</text>
<line x1="192" y1="72" x2="228" y2="72" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<polyline points="220,66 228,72 220,78" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<line x1="404" y1="72" x2="440" y2="72" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<polyline points="432,66 440,72 432,78" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<path d="M 532 104 L 532 140 L 108 140 L 108 176" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<polyline points="102,168 108,176 114,168" fill="none" stroke="var(--primary)" strokeWidth="2" strokeLinecap="round" />
<text x="320" y="132" textAnchor="middle" fontSize="12" fill="var(--muted)">푸시하면 "New Pull Request" 안내가 뜬다</text>
<rect x="24" y="180" width="168" height="64" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="108" y="206" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">4. PR 생성</text>
<text x="108" y="228" textAnchor="middle" fontSize="12" fill="var(--muted)">base compare 확인</text>
<rect x="236" y="180" width="168" height="64" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="320" y="206" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">5. 멘토 리뷰</text>
<text x="320" y="228" textAnchor="middle" fontSize="12" fill="var(--muted)">Files Changed에 코멘트</text>
<rect x="448" y="180" width="168" height="64" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="532" y="206" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">6. 머지</text>
<text x="532" y="228" textAnchor="middle" fontSize="12" fill="var(--muted)">main에 합류 · Merged</text>
<line x1="192" y1="212" x2="228" y2="212" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<polyline points="220,206 228,212 220,218" fill="none" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<line x1="404" y1="212" x2="440" y2="212" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<polyline points="432,206 440,212 432,218" fill="none" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
<text x="422" y="200" textAnchor="middle" fontSize="12" fill="var(--muted)">Approve</text>
<path d="M 320 244 L 320 276 L 108 276 L 108 250" fill="none" stroke="var(--amber)" strokeWidth="2" strokeDasharray="5 4" strokeLinecap="round" />
<polyline points="102,258 108,250 114,258" fill="none" stroke="var(--amber)" strokeWidth="2" strokeLinecap="round" />
<text x="214" y="296" textAnchor="middle" fontSize="12" fill="var(--amber)">Request changes 고쳐서 다시 커밋·푸시</text>
<circle cx="532" cy="308" r="7" fill="none" stroke="var(--teal)" strokeWidth="2" />
<text x="524" y="313" textAnchor="end" fontSize="12" fill="var(--muted)">병합되면 main이 정본</text>
<line x1="532" y1="244" x2="532" y2="301" stroke="var(--teal)" strokeWidth="2" strokeLinecap="round" />
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: PR 흐름 브랜치 생성부터 머지까지, 수정 요청이 오면 커밋 단계로 되돌아간다</p>
<div className="tip">
<b>리뷰는 사람 검사가 아니라 코드 검사</b> 코멘트를 받으면 "내가 혼났다" 아니라
"코드가 더 좋아질 기회" 읽으세요. 어썸데브의 시니어들도 매일 서로의 PR에

View File

@ -316,6 +316,54 @@ export default function ToolIntellijPage() {
코드 옆에서 바로 테이블을 열어 있습니다. 코드와 데이터를 <strong> 화면에서</strong>
이게 통합(I)개발(D)환경(E)이라는 이름값이에요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="IntelliJ 화면 구역도: 좌측 프로젝트 트리, 중앙 에디터, 우측 도구창(Database), 하단 실행 디버그 패널, 상단 우측 실행 구성">
<rect x="20" y="20" width="600" height="320" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<line x1="20" y1="58" x2="620" y2="58" stroke="var(--line)" strokeWidth="1.5" />
<text x="34" y="44" fontSize="13" fill="var(--muted)">상단 </text>
<rect x="380" y="29" width="228" height="22" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
<text x="392" y="44" fontSize="12" fill="var(--ink)">BackendApplication </text>
<text x="540" y="44" fontSize="12" fill="var(--teal)"> Run</text>
<text x="580" y="44" fontSize="12" fill="var(--rose)">Debug</text>
<rect x="30" y="70" width="132" height="192" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="42" y="92" fontSize="13" fontWeight="600" fill="var(--ink)">좌측 · 프로젝트</text>
<text x="42" y="110" fontSize="12" fill="var(--muted)">파일 트리</text>
<line x1="42" y1="126" x2="120" y2="126" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<line x1="52" y1="146" x2="130" y2="146" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<line x1="52" y1="166" x2="112" y2="166" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<line x1="62" y1="186" x2="140" y2="186" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<line x1="62" y1="206" x2="124" y2="206" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<text x="42" y="240" fontSize="12" fill="var(--muted)">Shift Shift </text>
<text x="42" y="256" fontSize="12" fill="var(--muted)">어디든 검색</text>
<rect x="174" y="70" width="292" height="192" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
<text x="188" y="92" fontSize="13" fontWeight="600" fill="var(--ink)">중앙 · 에디터 (코드)</text>
<circle cx="192" cy="126" r="5" fill="var(--rose)" />
<text x="208" y="131" fontSize="12" fill="var(--muted)">브레이크포인트는 번호 거터</text>
<line x1="208" y1="152" x2="440" y2="152" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<line x1="208" y1="172" x2="400" y2="172" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<line x1="208" y1="192" x2="430" y2="192" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<text x="188" y="228" fontSize="12" fill="var(--muted)">Ctrl + 클릭 정의로 이동</text>
<text x="188" y="248" fontSize="12" fill="var(--muted)">Ctrl + Alt + 왔던 길로</text>
<rect x="478" y="70" width="132" height="192" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="490" y="92" fontSize="13" fontWeight="600" fill="var(--ink)">우측 · 도구창</text>
<text x="490" y="114" fontSize="12" fill="var(--teal)">Database</text>
<line x1="490" y1="130" x2="598" y2="130" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<text x="490" y="150" fontSize="12" fill="var(--muted)">users 테이블</text>
<text x="490" y="170" fontSize="12" fill="var(--muted)">SQL 콘솔</text>
<text x="490" y="190" fontSize="12" fill="var(--muted)">Diagram</text>
<line x1="490" y1="206" x2="598" y2="206" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="4 4" />
<text x="490" y="230" fontSize="12" fill="var(--muted)">Alt + 9 </text>
<text x="490" y="248" fontSize="12" fill="var(--muted)">Git 도구창</text>
<rect x="30" y="274" width="580" height="56" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="42" y="296" fontSize="13" fontWeight="600" fill="var(--ink)">하단 · 실행 / 디버그 패널</text>
<text x="42" y="318" fontSize="12" fill="var(--muted)">Tomcat started on port 8080</text>
<text x="300" y="296" fontSize="12" fill="var(--muted)">Variables · Watches</text>
<text x="300" y="318" fontSize="12" fill="var(--muted)">F8 줄씩 · F7 안으로 · F9 다음 빨간 </text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: IntelliJ 화면 구역도 좌측 프로젝트 트리, 중앙 에디터, 우측 도구창(Database·Git), 하단 실행/디버그 패널, 상단 우측 실행 구성</p>
<Code>{CODE_DB_TOOL}</Code>
<p>
특히 <strong>Diagram 기능</strong> 한번 열어 보세요. 테이블끼리 어떤 외래키로

View File

@ -336,6 +336,45 @@ export default function ToolNotionPage() {
여러분만의 TIL 페이지를 만들고, <strong>바로 오늘, 코스에서 배운 </strong>
기록으로 남겨 보세요.
</p>
<svg className="diagram" viewBox="0 0 640 340" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="TIL 페이지 구조 도해: 날짜 제목 아래 오늘 배운 것, 오늘 막힌 것, 내일 할 것 세 블록이 놓이고 각 블록에 알맞은 노션 블록 종류가 짝지어져 있다">
<rect x="150" y="16" width="340" height="42" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="1.5" />
<text x="320" y="42" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">📅 2026-07-16 () 오늘의 TIL 페이지</text>
<line x1="320" y1="58" x2="320" y2="76" stroke="var(--line)" strokeWidth="1.5" />
<line x1="100" y1="76" x2="540" y2="76" stroke="var(--line)" strokeWidth="1.5" />
<line x1="100" y1="76" x2="100" y2="94" stroke="var(--line)" strokeWidth="1.5" />
<line x1="320" y1="76" x2="320" y2="94" stroke="var(--line)" strokeWidth="1.5" />
<line x1="540" y1="76" x2="540" y2="94" stroke="var(--line)" strokeWidth="1.5" />
<rect x="16" y="94" width="168" height="130" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="100" y="120" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">오늘 배운 </text>
<text x="100" y="142" textAnchor="middle" fontSize="12" fill="var(--muted)">Today I Learned</text>
<line x1="36" y1="158" x2="164" y2="158" stroke="var(--line)" strokeWidth="1" />
<text x="100" y="180" textAnchor="middle" fontSize="12" fill="var(--ink)">새로 개념 </text>
<text x="100" y="200" textAnchor="middle" fontSize="12" fill="var(--muted)">텍스트 블록</text>
<rect x="236" y="94" width="168" height="130" rx="8" fill="var(--card)" stroke="var(--rose)" strokeWidth="1.5" />
<text x="320" y="120" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">오늘 막힌 </text>
<text x="320" y="142" textAnchor="middle" fontSize="12" fill="var(--muted)"> 해결 과정</text>
<line x1="256" y1="158" x2="384" y2="158" stroke="var(--line)" strokeWidth="1" />
<text x="320" y="180" textAnchor="middle" fontSize="12" fill="var(--ink)">제목만 보고 셀프 퀴즈</text>
<text x="320" y="200" textAnchor="middle" fontSize="12" fill="var(--muted)">토글 블록 + 코드 블록</text>
<rect x="456" y="94" width="168" height="130" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="540" y="120" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">내일 </text>
<text x="540" y="142" textAnchor="middle" fontSize="12" fill="var(--muted)">다음 걸음</text>
<line x1="476" y1="158" x2="604" y2="158" stroke="var(--line)" strokeWidth="1" />
<text x="540" y="180" textAnchor="middle" fontSize="12" fill="var(--ink)">체크박스로 남기기</text>
<text x="540" y="200" textAnchor="middle" fontSize="12" fill="var(--muted)"> 목록 블록</text>
<line x1="184" y1="159" x2="236" y2="159" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="4 4" />
<line x1="404" y1="159" x2="456" y2="159" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="4 4" />
<rect x="16" y="252" width="608" height="70" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="320" y="278" textAnchor="middle" fontSize="13" fill="var(--ink)"> 3블록을 템플릿으로 만들고 매일 복제 하루 3</text>
<text x="320" y="302" textAnchor="middle" fontSize="12" fill="var(--muted)">100 검색되는 나만의 성장 기록</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: TIL 페이지의 3블록 구조 배운 ·막힌 ·내일 것과 각각에 어울리는 노션 블록</p>
<Code>{CODE_TIL_TEMPLATE}</Code>
<ol className="olist">
<li>노션에 <strong>"TIL 일지"</strong> 페이지를 만들어요. (섹션 3 구조 참고)</li>

View File

@ -243,6 +243,56 @@ export default function ToolPostmanPage() {
Send를 누른다</strong> 이게 Postman 사용법의 전부입니다. 나머지 (Params,
Headers, Body) 요청에 딸려 보낼 짐이고, 아래 응답 영역은 서버의 답장이에요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Postman 요청 구성 해부: 위쪽 요청 영역의 메서드·URL·Send 버튼과 헤더·바디 탭, 아래쪽 응답 영역의 상태코드와 본문">
<text x="20" y="22" fontSize="13" fontWeight="bold" fill="var(--ink)">요청 (내가 만드는 )</text>
<rect x="20" y="34" width="600" height="150" rx="8" fill="var(--card)" stroke="var(--line)" />
<rect x="36" y="52" width="80" height="32" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="76" y="73" fontSize="13" textAnchor="middle" fill="var(--primary)" fontWeight="bold">POST </text>
<rect x="126" y="52" width="376" height="32" rx="8" fill="var(--card)" stroke="var(--line)" />
<text x="140" y="73" fontSize="12.5" fill="var(--ink)">https://edu.awesomedevapp.com/api/auth/login</text>
<rect x="512" y="52" width="92" height="32" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="558" y="73" fontSize="13" textAnchor="middle" fill="var(--teal)" fontWeight="bold">Send</text>
<text x="76" y="102" fontSize="12" textAnchor="middle" fill="var(--muted)"> 메서드</text>
<text x="314" y="102" fontSize="12" textAnchor="middle" fill="var(--muted)"> 주소(URL)</text>
<text x="558" y="102" fontSize="12" textAnchor="middle" fill="var(--muted)"> 보내기</text>
<line x1="36" y1="114" x2="604" y2="114" stroke="var(--line)" />
<text x="46" y="133" fontSize="12.5" fill="var(--muted)">Params</text>
<text x="112" y="133" fontSize="12.5" fill="var(--ink)" fontWeight="bold">Headers</text>
<text x="186" y="133" fontSize="12.5" fill="var(--ink)" fontWeight="bold">Body</text>
<line x1="106" y1="140" x2="166" y2="140" stroke="var(--amber)" strokeWidth="2" strokeLinecap="round" />
<line x1="182" y1="140" x2="216" y2="140" stroke="var(--amber)" strokeWidth="2" strokeLinecap="round" />
<text x="46" y="160" fontSize="12" fill="var(--muted)">Headers: Content-Type: application/json</text>
<text x="46" y="176" fontSize="12" fill="var(--muted)">Body(raw · JSON): {'{ "email": ..., "password": ... }'}</text>
<line x1="320" y1="184" x2="320" y2="216" stroke="var(--line)" strokeWidth="2" strokeDasharray="5 4" />
<text x="332" y="206" fontSize="12" fill="var(--muted)">Send 누르면 서버로</text>
<text x="20" y="238" fontSize="13" fontWeight="bold" fill="var(--ink)">응답 (서버의 답장)</text>
<rect x="20" y="250" width="600" height="96" rx="8" fill="var(--card)" stroke="var(--line)" />
<text x="38" y="274" fontSize="13" fill="var(--teal)" fontWeight="bold">Status: 200 OK</text>
<text x="180" y="274" fontSize="12.5" fill="var(--muted)">Time: 120ms</text>
<text x="290" y="274" fontSize="12.5" fill="var(--muted)">Size</text>
<text x="366" y="274" fontSize="12.5" fill="var(--rose)">틀리면 401 Unauthorized</text>
<line x1="38" y1="286" x2="602" y2="286" stroke="var(--line)" />
<text x="38" y="308" fontSize="12.5" fill="var(--muted)">Body</text>
<text x="90" y="308" fontSize="12.5" fill="var(--ink)">{'{ "name": "홍길동", "role": "INTERN" }'}</text>
<text x="38" y="332" fontSize="12" fill="var(--muted)">먼저 Status(도장) 그다음 Body(내용) Time(속도) 순으로 읽습니다</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>
그림: Postman 요청 구성 해부 메서드·주소·Send와 헤더/바디, 그리고 아래 응답 영역
</p>
<div className="tip">
<b>메서드 복습</b> GET은 "보여 줘"(조회), POST는 "새로 만들어 줘/처리해 줘",
PUT/PATCH는 "고쳐 줘", DELETE는 "지워 줘". 백엔드 코스에서 배운

View File

@ -239,6 +239,49 @@ export default function ToolShortcutsPage() {
창들을 마우스로 끌어서 배치하는 대신, <span className="kbd">Win</span> 키와
화살표로 <strong>착착 스냅</strong>시키는 것부터 시작합니다.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="Win 키와 화살표로 창이 좌우 절반 또는 4분할로 배치되는 스냅 도해">
<text x="150" y="26" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">/ 절반 Win + / </text>
<rect x="30" y="42" width="240" height="150" rx="8" fill="none" stroke="var(--line)" strokeWidth="2" />
<rect x="38" y="50" width="112" height="134" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<rect x="158" y="50" width="104" height="134" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="94" y="112" textAnchor="middle" fontSize="13" fill="var(--ink)">에디터</text>
<text x="94" y="132" textAnchor="middle" fontSize="12" fill="var(--muted)">Win + </text>
<text x="210" y="112" textAnchor="middle" fontSize="13" fill="var(--ink)">브라우저</text>
<text x="210" y="132" textAnchor="middle" fontSize="12" fill="var(--muted)">Win + </text>
<line x1="154" y1="50" x2="154" y2="184" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 4" />
<text x="150" y="212" textAnchor="middle" fontSize="12" fill="var(--muted)"> 하나를 화면 절반에 붙이기</text>
<text x="480" y="26" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">4분할 절반 Win + / </text>
<rect x="360" y="42" width="240" height="150" rx="8" fill="none" stroke="var(--line)" strokeWidth="2" />
<rect x="368" y="50" width="112" height="63" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<rect x="488" y="50" width="104" height="63" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<rect x="368" y="121" width="112" height="63" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" />
<rect x="488" y="121" width="104" height="63" rx="8" fill="var(--card)" stroke="var(--rose)" strokeWidth="2" />
<text x="424" y="86" textAnchor="middle" fontSize="12" fill="var(--ink)">에디터</text>
<text x="540" y="86" textAnchor="middle" fontSize="12" fill="var(--ink)">브라우저</text>
<text x="424" y="157" textAnchor="middle" fontSize="12" fill="var(--ink)">터미널</text>
<text x="540" y="157" textAnchor="middle" fontSize="12" fill="var(--ink)">문서</text>
<text x="480" y="212" textAnchor="middle" fontSize="12" fill="var(--muted)">Win + Z 스냅 레이아웃으로도 같은 배치</text>
<line x1="290" y1="117" x2="340" y2="117" stroke="var(--muted)" strokeWidth="2" strokeLinecap="round" />
<polyline points="330,110 340,117 330,124" fill="none" stroke="var(--muted)" strokeWidth="2" strokeLinecap="round" />
<text x="320" y="262" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)">누르는 순서</text>
<circle cx="120" cy="300" r="14" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="120" y="305" textAnchor="middle" fontSize="12" fill="var(--ink)">1</text>
<text x="120" y="332" textAnchor="middle" fontSize="12.5" fill="var(--muted)">Win + (왼쪽 절반)</text>
<circle cx="320" cy="300" r="14" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="320" y="305" textAnchor="middle" fontSize="12" fill="var(--ink)">2</text>
<text x="320" y="332" textAnchor="middle" fontSize="12.5" fill="var(--muted)">이어서 Win + (왼쪽 1/4)</text>
<circle cx="520" cy="300" r="14" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" />
<text x="520" y="305" textAnchor="middle" fontSize="12" fill="var(--ink)">3</text>
<text x="520" y="332" textAnchor="middle" fontSize="12.5" fill="var(--muted)">남은 칸에 다음 고르기</text>
<line x1="140" y1="300" x2="300" y2="300" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 4" />
<line x1="340" y1="300" x2="500" y2="300" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 4" />
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: Win+화살표로 / 절반 4분할까지, 마우스 없이 배치하기</p>
<Code>{CODE_WINDOW}</Code>
<p>
<strong>가상 데스크톱</strong> "책상을 여러 개 쓰는" 기능이에요. 공부 책상 위에

View File

@ -217,6 +217,43 @@ export default function ToolTerminalPage() {
<strong> 같은 컴퓨터에게 말을 거는 가지 통역사</strong>라고 생각하면 됩니다.
컴퓨터라는 외국인은 같지만, 어떤 통역사를 쓰느냐에 따라 통하는 말이 달라요.
</p>
<svg className="diagram" viewBox="0 0 640 330" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="cmd, PowerShell, Git Bash 세 셸의 정체와 쓰임새를 비교한 도해">
<text x="320" y="24" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--ink)">검은 삼형제 같은 컴퓨터, 다른 통역사</text>
<rect x="24" y="46" width="184" height="176" rx="8" fill="var(--card)" stroke="var(--muted)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="116" y="72" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--muted)">cmd</text>
<line x1="44" y1="84" x2="188" y2="84" stroke="var(--line)" strokeWidth="1" />
<text x="116" y="104" textAnchor="middle" fontSize="12" fill="var(--muted)">윈도우 원조 명령창</text>
<text x="116" y="122" textAnchor="middle" fontSize="12" fill="var(--muted)">MS-DOS의 후손</text>
<text x="116" y="148" textAnchor="middle" fontSize="12.5" fill="var(--ink)">기능이 적음</text>
<text x="116" y="172" textAnchor="middle" fontSize="12" fill="var(--muted)">옛날 .bat 실행 정도</text>
<text x="116" y="200" textAnchor="middle" fontSize="12.5" fontWeight="bold" fill="var(--muted)">요즘은 거의 </text>
<rect x="228" y="46" width="184" height="176" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2.5" />
<text x="320" y="72" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--primary)">PowerShell</text>
<line x1="248" y1="84" x2="392" y2="84" stroke="var(--line)" strokeWidth="1" />
<text x="320" y="104" textAnchor="middle" fontSize="12" fill="var(--muted)">MS가 만든 현대식 </text>
<text x="320" y="122" textAnchor="middle" fontSize="12" fill="var(--muted)">파란 배경이 상징</text>
<text x="320" y="148" textAnchor="middle" fontSize="12.5" fill="var(--ink)">ls·cd는 별명(alias)</text>
<text x="320" y="172" textAnchor="middle" fontSize="12" fill="var(--muted)">파일·실행·개발 전반</text>
<text x="320" y="200" textAnchor="middle" fontSize="12.5" fontWeight="bold" fill="var(--primary)">윈도우 기본 선택지</text>
<rect x="432" y="46" width="184" height="176" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="524" y="72" textAnchor="middle" fontSize="14" fontWeight="bold" fill="var(--teal)">Git Bash</text>
<line x1="452" y1="84" x2="596" y2="84" stroke="var(--line)" strokeWidth="1" />
<text x="524" y="104" textAnchor="middle" fontSize="12" fill="var(--muted)">Git 설치 딸려 </text>
<text x="524" y="122" textAnchor="middle" fontSize="12" fill="var(--muted)">리눅스 흉내 </text>
<text x="524" y="148" textAnchor="middle" fontSize="12.5" fill="var(--ink)">경로도 /c/... 리눅스식</text>
<text x="524" y="172" textAnchor="middle" fontSize="12" fill="var(--muted)">rm -rf 같은 옵션 OK</text>
<text x="524" y="200" textAnchor="middle" fontSize="12.5" fontWeight="bold" fill="var(--teal)">리눅스 명령 그대로</text>
<text x="320" y="252" textAnchor="middle" fontSize="12.5" fill="var(--muted)"> 하나의 Windows Terminal 창에 탭으로 함께 있어요</text>
<rect x="120" y="270" width="400" height="44" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="1.5" />
<text x="320" y="288" textAnchor="middle" fontSize="12.5" fill="var(--ink)">평소엔 PowerShell, 리눅스 명령이 필요하면 Git Bash</text>
<text x="320" y="306" textAnchor="middle" fontSize="12" fill="var(--muted)">cmd는 "아, 옛날 거구나" 하고 알아만 두면 됩니다</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 삼형제 포지셔닝 cmd는 유물, PowerShell은 기본, Git Bash는 리눅스 통로</p>
<Code>{CODE_THREE_SHELLS}</Code>
<p>
여기서 용어 하나만 정리해요. <strong>터미널</strong> 글자가 표시되는

View File

@ -229,6 +229,47 @@ export default function ToolVscodePage() {
"그 기능 메뉴 어디 있더라?" 그냥 이름을 쳐서 실행하면 됩니다.
단축키를 까먹어도 팔레트만 기억하면 살아남아요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="VS Code 화면 구역도: 왼쪽 사이드바, 가운데 에디터, 아래 통합 터미널, 위쪽에서 내려오는 명령 팔레트">
<rect x="20" y="70" width="600" height="256" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<rect x="20" y="70" width="44" height="256" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<circle cx="42" cy="98" r="6" fill="var(--muted)" />
<circle cx="42" cy="124" r="6" fill="var(--primary)" />
<circle cx="42" cy="150" r="6" fill="var(--muted)" />
<circle cx="42" cy="176" r="6" fill="var(--muted)" />
<rect x="64" y="70" width="126" height="256" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="76" y="94" fontSize="12" fill="var(--muted)">탐색기 · 확장</text>
<text x="76" y="116" fontSize="12" fill="var(--muted)">소스 제어</text>
<line x1="76" y1="132" x2="176" y2="132" stroke="var(--line)" strokeWidth="1" />
<text x="76" y="152" fontSize="12" fill="var(--ink)">좌측 사이드바</text>
<text x="76" y="172" fontSize="12" fill="var(--primary)" fontWeight="600">Ctrl+B 접기/펴기</text>
<rect x="190" y="70" width="430" height="180" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="210" y="100" fontSize="14" fill="var(--ink)" fontWeight="600">중앙 에디터</text>
<text x="210" y="122" fontSize="12" fill="var(--muted)">코드를 읽고 고치는 </text>
<line x1="210" y1="146" x2="440" y2="146" stroke="var(--line)" strokeWidth="1" />
<line x1="210" y1="166" x2="520" y2="166" stroke="var(--line)" strokeWidth="1" />
<line x1="210" y1="186" x2="400" y2="186" stroke="var(--line)" strokeWidth="1" />
<line x1="210" y1="206" x2="480" y2="206" stroke="var(--line)" strokeWidth="1" />
<text x="210" y="234" fontSize="12" fill="var(--primary)" fontWeight="600">Ctrl+P 파일 열기 · Ctrl+D 멀티커서</text>
<rect x="190" y="250" width="430" height="76" fill="var(--card)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="210" y="276" fontSize="14" fill="var(--ink)" fontWeight="600">하단 통합 터미널</text>
<text x="210" y="298" fontSize="12" fill="var(--muted)">npm run dev · git status</text>
<text x="210" y="318" fontSize="12" fill="var(--teal)" fontWeight="600">Ctrl+` 열기/닫기</text>
<rect x="230" y="18" width="330" height="40" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" />
<text x="246" y="43" fontSize="13" fill="var(--muted)">&gt;</text>
<text x="264" y="43" fontSize="13" fill="var(--ink)">상단 명령 팔레트 모든 기능 검색</text>
<line x1="395" y1="58" x2="395" y2="70" stroke="var(--amber)" strokeWidth="2" strokeDasharray="4 3" strokeLinecap="round" />
<text x="576" y="43" fontSize="12" fill="var(--amber)" fontWeight="600" textAnchor="middle">Ctrl+Shift+P</text>
<text x="320" y="348" fontSize="12" fill="var(--muted)" textAnchor="middle">사이드바 · 에디터 · 터미널 · 팔레트 구역만 알면 </text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: VS Code 화면 구역과 구역을 부르는 단축키</p>
<div className="tip">
<b>직접 확인해 보기</b> 지금 VS Code에서 <span className="kbd">Ctrl+Shift+P</span>
누르고 <span className="icode">theme</span>이라고 보세요. "색 테마" 항목을 고르면

View File

@ -271,6 +271,34 @@ export default function TypographyPage() {
. 매번 "이건 17px? 18px?" 고민하는 대신, 정해 계단에서 고르기만 하면
화면 전체가 저절로 통일됩니다. 이게 바로 디자인 시스템의 출발점이에요.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="제목 28px, 부제 20px, 본문 15px, 캡션 12px의 크기 위계를 실제 크기 차이로 비교하고 각 줄의 행간 상자를 점선으로 표시한 도해">
<text x="20" y="26" fontSize="13" fill="var(--muted)">크기 계단 크기 차이가 &apos;읽는 순서&apos;</text>
<rect x="112" y="52" width="380" height="35" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 3" />
<text x="100" y="74" fontSize="12" fill="var(--muted)" textAnchor="end">제목</text>
<text x="124" y="80" fontSize="28" fontWeight="700" fill="var(--primary)">페이지 제목</text>
<text x="504" y="74" fontSize="12" fill="var(--muted)">28px · 행간 1.25</text>
<rect x="112" y="126" width="380" height="27" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 3" />
<text x="100" y="144" fontSize="12" fill="var(--muted)" textAnchor="end">부제</text>
<text x="124" y="147" fontSize="20" fontWeight="600" fill="var(--teal)">섹션 제목</text>
<text x="504" y="144" fontSize="12" fill="var(--muted)">20px · 행간 1.35</text>
<rect x="112" y="198" width="380" height="24" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 3" />
<text x="100" y="214" fontSize="12" fill="var(--muted)" textAnchor="end">본문</text>
<text x="124" y="215" fontSize="15" fill="var(--ink)">본문 텍스트입니다 기준점!</text>
<text x="504" y="214" fontSize="12" fill="var(--amber)">15px · 행간 1.6</text>
<rect x="112" y="261" width="380" height="18" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 3" />
<text x="100" y="274" fontSize="12" fill="var(--muted)" textAnchor="end">캡션</text>
<text x="124" y="274" fontSize="12" fill="var(--muted)">캡션·보조 텍스트 (12px 아래로는 금지)</text>
<text x="504" y="274" fontSize="12" fill="var(--muted)">12px · 행간 1.5</text>
<line x1="20" y1="298" x2="620" y2="298" stroke="var(--line)" strokeWidth="1" />
<text x="320" y="320" fontSize="12" fill="var(--muted)" textAnchor="middle">점선 상자 = 행간( 상자) 높이 글자 크기의 배수로 지정</text>
<text x="320" y="342" fontSize="12.5" fill="var(--ink)" textAnchor="middle">계단은 개만, 간격은 일정하게 본문을 먼저 정하고 위아래로 벌린다</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 제목·부제·본문·캡션의 실제 크기 차이와 단계의 행간</p>
<div className="tip">
<b>기억할 숫자 하나</b> 본문은 <strong>14~16px</strong>, 그리고 어떤 글씨도{' '}
<strong>12px 아래로 내려가지 않기</strong>. 여러분 눈은 괜찮아도, 모든 사용자의

View File

@ -223,6 +223,40 @@ export default function UserResearchPage() {
쓰는 사람(수습생) 아는 것도, 익숙한 용어도 달라요. 틈을 메우는 유일한
방법이 <strong>직접 묻고 지켜보는 </strong>, 사용자 리서치입니다.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="관찰에서 가설, 테스트, 배움을 거쳐 다시 관찰로 돌아오는 리서치 순환도">
<circle cx="320" cy="180" r="110" fill="none" stroke="var(--line)" strokeWidth="1" strokeDasharray="4 5" />
<path d="M 400 95 A 110 110 0 0 1 445 155" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polygon points="445,155 433.8,148.4 441.8,142.4" fill="var(--line)" />
<path d="M 445 205 A 110 110 0 0 1 400 265" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polygon points="400,265 403.2,251.8 411.2,259" fill="var(--line)" />
<path d="M 240 265 A 110 110 0 0 1 195 205" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polygon points="195,205 206.2,211 198.2,218.2" fill="var(--line)" />
<path d="M 195 155 A 110 110 0 0 1 240 95" fill="none" stroke="var(--line)" strokeWidth="2" strokeLinecap="round" />
<polygon points="240,95 236.8,108.2 228.8,101" fill="var(--line)" />
<rect x="252" y="46" width="136" height="48" rx="8" fill="var(--card)" stroke="var(--primary)" strokeWidth="2" />
<text x="320" y="67" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">관찰</text>
<text x="320" y="84" textAnchor="middle" fontSize="11.5" fill="var(--muted)">묻고 지켜보기</text>
<rect x="362" y="156" width="136" height="48" rx="8" fill="var(--card)" stroke="var(--teal)" strokeWidth="2" />
<text x="430" y="177" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">가설</text>
<text x="430" y="194" textAnchor="middle" fontSize="11.5" fill="var(--muted)">아마 여기서 막힐 </text>
<rect x="252" y="266" width="136" height="48" rx="8" fill="var(--card)" stroke="var(--amber)" strokeWidth="2" />
<text x="320" y="287" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">테스트</text>
<text x="320" y="304" textAnchor="middle" fontSize="11.5" fill="var(--muted)">과제 주고 다물기</text>
<rect x="142" y="156" width="136" height="48" rx="8" fill="var(--card)" stroke="var(--rose)" strokeWidth="2" />
<text x="210" y="177" textAnchor="middle" fontSize="14" fontWeight="600" fill="var(--ink)">배움</text>
<text x="210" y="194" textAnchor="middle" fontSize="11.5" fill="var(--muted)">사실과 해석 분리</text>
<text x="320" y="174" textAnchor="middle" fontSize="13" fontWeight="600" fill="var(--ink)"> 감이 아니라</text>
<text x="320" y="194" textAnchor="middle" fontSize="12" fill="var(--muted)"> 바퀴 때마다 확신 대신 근거</text>
<text x="320" y="340" textAnchor="middle" fontSize="12" fill="var(--muted)">배움은 끝이 아니라 다음 관찰의 출발점입니다</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 리서치 순환도 관찰 가설 테스트 배움, 그리고 다시 관찰로</p>
<div className="tip">
<b>기억할 문장</b> 회의에서 "사용자들이 이걸 좋아할 거예요"라는 말이 나오면
속으로 물어보세요 <strong>"그건 물어본 결과인가요, 내 감인가요?"</strong>

View File

@ -224,6 +224,52 @@ export default function WireframePage() {
와이어프레임은 번에 완성하는 아니라 <strong>3단계로 해상도를 올려</strong> 가요.
흐릿한 사진의 초점이 점점 맞아 가는 것처럼, 단계마다 확정하는 것이 다릅니다.
</p>
<svg className="diagram" viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="와이어프레임 3단계 진화: 손그림 Lo-Fi, 회색 박스 Mid-Fi, 디자인 시안 Hi-Fi 순으로 완성도가 올라가는 흐름">
<text x="320" y="22" textAnchor="middle" fontSize="14" fontWeight="700" fill="var(--ink)">완성도가 올라가는 3단계</text>
<rect x="20" y="44" width="170" height="200" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" strokeDasharray="5 4" />
<text x="105" y="66" textAnchor="middle" fontSize="13" fontWeight="700" fill="var(--primary)">1단계 · 손그림</text>
<text x="105" y="83" textAnchor="middle" fontSize="12" fill="var(--muted)">Lo-Fi · 종이+</text>
<line x1="42" y1="100" x2="168" y2="100" stroke="var(--muted)" strokeWidth="2" strokeLinecap="round" />
<line x1="42" y1="118" x2="120" y2="118" stroke="var(--muted)" strokeWidth="2" strokeLinecap="round" />
<rect x="42" y="132" width="56" height="42" rx="8" fill="none" stroke="var(--muted)" strokeWidth="1.5" strokeDasharray="4 3" />
<rect x="110" y="132" width="58" height="42" rx="8" fill="none" stroke="var(--muted)" strokeWidth="1.5" strokeDasharray="4 3" />
<line x1="42" y1="188" x2="150" y2="188" stroke="var(--muted)" strokeWidth="2" strokeLinecap="round" />
<text x="105" y="216" textAnchor="middle" fontSize="12" fill="var(--ink)">1장에 1~2</text>
<text x="105" y="233" textAnchor="middle" fontSize="12" fill="var(--muted)">아이디어 골라내기</text>
<rect x="235" y="44" width="170" height="200" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="320" y="66" textAnchor="middle" fontSize="13" fontWeight="700" fill="var(--teal)">2단계 · 회색 박스</text>
<text x="320" y="83" textAnchor="middle" fontSize="12" fill="var(--muted)">Mid-Fi · 피그마</text>
<rect x="257" y="94" width="126" height="16" rx="8" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
<rect x="257" y="120" width="60" height="54" rx="8" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
<rect x="323" y="120" width="60" height="54" rx="8" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
<rect x="257" y="182" width="126" height="14" rx="7" fill="none" stroke="var(--teal)" strokeWidth="1.5" />
<text x="320" y="216" textAnchor="middle" fontSize="12" fill="var(--ink)">·사진 아직 금지</text>
<text x="320" y="233" textAnchor="middle" fontSize="12" fill="var(--muted)">배치와 흐름 확정</text>
<rect x="450" y="44" width="170" height="200" rx="8" fill="var(--card)" stroke="var(--line)" strokeWidth="1.5" />
<text x="535" y="66" textAnchor="middle" fontSize="13" fontWeight="700" fill="var(--amber)">3단계 · 디자인 시안</text>
<text x="535" y="83" textAnchor="middle" fontSize="12" fill="var(--muted)">Hi-Fi · 완성 예상도</text>
<rect x="472" y="94" width="126" height="16" rx="8" fill="var(--primary)" stroke="var(--primary)" strokeWidth="1.5" />
<rect x="472" y="120" width="60" height="54" rx="8" fill="var(--amber)" stroke="var(--amber)" strokeWidth="1.5" />
<rect x="538" y="120" width="60" height="54" rx="8" fill="var(--rose)" stroke="var(--rose)" strokeWidth="1.5" />
<rect x="472" y="182" width="126" height="14" rx="7" fill="var(--teal)" stroke="var(--teal)" strokeWidth="1.5" />
<text x="535" y="216" textAnchor="middle" fontSize="12" fill="var(--ink)">·폰트·이미지</text>
<text x="535" y="233" textAnchor="middle" fontSize="12" fill="var(--muted)">개발 최종 확인</text>
<line x1="196" y1="144" x2="228" y2="144" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<polyline points="220,138 229,144 220,150" fill="none" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<line x1="411" y1="144" x2="443" y2="144" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<polyline points="435,138 444,144 435,150" fill="none" stroke="var(--ink)" strokeWidth="2" strokeLinecap="round" />
<line x1="20" y1="278" x2="620" y2="278" stroke="var(--line)" strokeWidth="1.5" />
<polyline points="612,272 621,278 612,284" fill="none" stroke="var(--line)" strokeWidth="1.5" strokeLinecap="round" />
<text x="20" y="300" fontSize="12" fill="var(--muted)">완성도 낮음 · 버리기 쉬움</text>
<text x="620" y="300" textAnchor="end" fontSize="12" fill="var(--muted)">완성도 높음 · 고치기 비쌈</text>
<text x="320" y="330" textAnchor="middle" fontSize="12.5" fill="var(--rose)">1단계를 건너뛰고 3단계부터 시작하면 예쁘지만 구조가 이상한 화면</text>
</svg>
<p className="muted" style={{ fontSize: 12.5, textAlign: 'center', marginTop: 2 }}>그림: 손그림 회색 박스 시안, 단계마다 완성도가 올라가고 수정 비용도 함께 올라간다</p>
<Code>{CODE_3STEPS}</Code>
<p>
단계마다 <strong>결정하는 사람의 질문</strong> 달라진다는 포인트예요.