﻿/* 학습 화면(C# · ASP.NET Core) — 밝은 종이 테마.
   사이트의 다른 화면은 딥네이비 다크 테마(dark.css)이지만, 이 영역만 밝게 갑니다.
   긴 글을 오래 읽는 자리라 밝은 바탕이 눈이 덜 피로합니다. 그래서 _LearnLayout 은
   dark.css 를 싣지 않습니다(관리자 영역이 자체 레이아웃을 쓰는 것과 같은 방식).

   기획서 6장의 단원 공통 틀을 그대로 담습니다:
   개념 설명 → 최소 예제 → 상세 사용법 → 버전 배지 → 실습 문제 → 요약 → 앞뒤 이동 */

/* 글자로 쓰이는 색은 제가 놓이는 바탕에서 4.5:1 이상입니다(기획서 8장 — WCAG AA).
   재는 도구가 없어 눈으로 고르면 흐린 회색이 늘 모자랍니다. 색조는 그대로 두고
   밝기만 옮겨 통과선에 맞춘 값입니다. 여기를 고칠 때는 다시 재 보세요. */
:root {
	--paper: #ECEEF3;
	--paper-raise: #F5F6F9;
	--ink: #1B1F2B;					/* 종이 위 14.16:1 */
	--ink-soft: #5B6272;			/* 종이 위  5.27:1 */
	--ink-faint: #686C78;			/* 종이 위  4.52:1 */
	--line: #D3D7E0;
	--line-soft: #DFE2EA;
	--accent: #6E56CF;				/* 종이 위  4.64:1 */
	--accent-deep: #4C3A9E;			/* 옅은 보라 위 7.23:1 */
	--accent-soft: #ECE7FB;
	--accent-soft-line: #D9CFF7;
	--code-bg: #161A23;
	--code-bg-alt: #1E2330;
	--code-text: #E7E9F2;			/* 코드 바탕 위 14.37:1 */
	--code-keyword: #B7A4FF;		/* 코드 바탕 위  8.10:1 */
	--code-type: #6FD9C8;			/* 코드 바탕 위 10.31:1 */
	--code-string: #F2C879;			/* 코드 바탕 위 11.04:1 */
	--code-comment: #848A96;		/* 탭줄 위      4.53:1 */
	--code-num: #F2A65A;			/* 코드 바탕 위  8.60:1 */
	--good: #247B57;				/* 옅은 초록 위  4.53:1 */
	--good-soft: #E1F4EB;
	--gold: #916018;				/* 옅은 금색 위  4.58:1 */
	--gold-soft: #F7EBD8;
	--radius: 10px;
}

/* 이 화면은 사이트 차림표(GNB) 때문에 dark.css 를 함께 싣습니다. 그 파일이 전역으로
   칠하는 것은 body 하나뿐이라, 여기서 되돌려 놓습니다 — 이 파일은 학습 화면에서만
   실리므로 다른 화면의 다크 테마에는 닿지 않습니다.
   .learn-page 에 min-height 를 주지 않는 것도 이 때문입니다(차림표 높이만큼 넘쳐
   짧은 화면에도 스크롤이 생깁니다). */
body { background: var(--paper); }

.learn-page {
	background: var(--paper);
	color: var(--ink);
	font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Malgun Gothic", "Apple SD Gothic Neo", sans-serif;
	line-height: 1.7;
	-webkit-font-smoothing: antialiased;
}
.learn-page .mono { font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace; }
.learn-page a { color: inherit; text-decoration: none; }
.learn-page .wrap { max-width: 760px; margin: 0 auto; padding: 0 24px; }

/* ── 본문으로 건너뛰기 ──
   화면 밖에 두었다가 초점이 오면 왼쪽 위로 나옵니다. display: none 으로 감추면 초점이
   가지 않아 아예 쓸 수 없습니다. */
.learn-page .skip {
	position: absolute; left: -9999px; top: 0; z-index: 20;
	background: var(--accent-deep); color: #fff;
	font-size: 13px; font-weight: 700; padding: 10px 16px; border-radius: 0 0 8px 0;
}
.learn-page .skip:focus { left: 0; }

/* ── 상단 바 ── */
.learn-page .topbar {
	border-bottom: 1px solid var(--line);
	background: var(--paper-raise);
	position: sticky; top: 0; z-index: 10;
}
/* 머리는 사이트 차림표와 같은 자리에 섭니다. 바로 위에 그것이 놓이므로 폭이 다르면
   브랜드가 로고보다 한참 안쪽에서 시작해 두 머리가 어긋나 보입니다.
   폭은 부트스트랩 .container 가 정합니다(마크업에 함께 붙여 두었습니다) — 그것이
   단계로 바뀌는 값이라 여기에 max-width 를 적으면 그 사이 폭에서 어긋납니다.

   본문(.wrap)은 760px 그대로입니다 — 그쪽은 읽는 자리라 넓히면 한 줄이 63자에서
   95자가 되어 눈이 다음 줄을 놓칩니다. */
.learn-page .topbar-inner {
	padding-top: 14px; padding-bottom: 14px;
	display: flex; align-items: center; gap: 16px;
}

.learn-page .brand {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace;
	font-weight: 700; font-size: 16px; letter-spacing: -0.02em;
	display: flex; align-items: center; gap: 2px; flex-shrink: 0;
}
.learn-page .brand .cursor {
	display: inline-block; width: 8px; height: 16px; background: var(--accent);
	animation: learn-blink 1.1s step-end infinite;
}

/* ── 검색 ──
   머리에 붙는 것이라 개별 css 로 두지 않고 이 공용 파일에 담습니다.
   결과는 자리를 밀지 않고 위에 뜹니다 — 글을 읽던 자리가 움직이면 안 됩니다. */
.learn-page .search-box { position: relative; flex-shrink: 0; }
/* 감싸개는 넓은 화면에서 없는 것과 같습니다 — 입력 칸과 결과가 .search-box 의 자식처럼
   놓여야 결과의 position:absolute 가 지금처럼 잡힙니다. */
.learn-page .search-panel { display: contents; }
/* 아이콘 단추는 좁은 화면 전용입니다. */
.learn-page .search-toggle { display: none; }
/* 테두리에 --line 을 쓰지 않습니다. 그 색은 글을 가르는 선이라 머리줄 바탕 위에서
   1.33:1 이고, 입력 칸의 테두리는 그것이 곧 칸의 경계라 3:1 이 필요합니다
   (기획서 8장 · WCAG 1.4.11). 칸 바탕도 머리줄과 거의 같은 색이라 테두리 말고는
   여기가 입력 칸이라고 알릴 것이 없습니다. */
.learn-page .search-input {
	width: 180px; padding: 6px 10px; border-radius: 7px;
	border: 1px solid #8B8E94; background: var(--paper);
	font-family: inherit; font-size: 12.5px; color: var(--ink); outline: none;
	transition: width .18s ease, border-color .18s ease;
}
.learn-page .search-input::placeholder { color: var(--ink-faint); }
.learn-page .search-input:focus { width: 260px; border-color: var(--accent); background: #fff; }

.learn-page .search-results {
	display: none; position: absolute; right: 0; top: calc(100% + 6px);
	width: 420px; max-height: 60vh; overflow-y: auto; z-index: 20;
	margin: 0; padding: 6px; list-style: none;
	background: #fff; border: 1px solid var(--line); border-radius: 10px;
	box-shadow: 0 10px 30px rgba(27, 31, 43, 0.14);
}
.learn-page .search-box.open .search-results { display: block; }

.learn-page .search-hit a {
	display: block; padding: 9px 11px; border-radius: 7px; text-decoration: none;
}
/* 마우스로 올린 것과 키보드로 고른 것을 같은 모양으로 보입니다. 둘을 다르게 두면
   화살표로 옮기는 동안 마우스가 있던 자리가 함께 칠해져 어느 것이 골라졌는지
   알기 어렵습니다. */
.learn-page .search-hit.on > a { background: var(--accent-soft); }
.learn-page .sh-track {
	display: inline-block; font-family: "SFMono-Regular", Consolas, Menlo, monospace;
	font-size: 10.5px; color: var(--accent-deep); background: var(--accent-soft);
	border: 1px solid var(--accent-soft-line); border-radius: 4px;
	padding: 1px 5px; margin-right: 6px; vertical-align: 1px;
}
.learn-page .sh-title { font-size: 13.5px; font-weight: 700; color: var(--ink); }
.learn-page .sh-text {
	display: block; margin-top: 3px; font-size: 12px; line-height: 1.55;
	color: var(--ink-soft); word-break: break-all;
}
.learn-page .search-empty {
	padding: 12px; font-size: 12.5px; color: var(--ink-faint); text-align: center;
}

/* ── 좁은 화면의 검색 ──
   입력 칸을 그대로 두면 머리에서 한 줄을 통째로 차지합니다. 아이콘만 두고, 누르면
   머리 아래로 폭 전체가 내려오게 합니다.

   중단점은 991.98px 입니다 — 위의 사이트 차림표가 햄버거로 바뀌는 자리와 같습니다
   (부트스트랩 navbar-expand-lg = 992px). 머리가 둘인 화면이라 한쪽만 먼저 접히면
   같은 폭에서 위는 모바일, 아래는 데스크톱이 됩니다.

   .search-box 의 position 을 풀어 두는 것이 요령입니다. 그래야 내려오는 칸의
   position:absolute 가 붙박이 머리(.topbar)를 기준으로 잡혀 화면 폭을 다 씁니다. */
@media (max-width: 991.98px) {
	.learn-page .search-box { position: static; margin-left: auto; }

	.learn-page .search-toggle {
		display: flex; align-items: center; justify-content: center;
		width: 34px; height: 34px; padding: 0;
		border: 1px solid var(--line); border-radius: 8px;
		background: var(--paper); color: var(--ink-soft); cursor: pointer;
	}
	.learn-page .search-toggle:hover { border-color: var(--accent); color: var(--accent); }
	.learn-page .search-toggle[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }

	.learn-page .search-panel { display: none; }
	.learn-page .search-box.expanded .search-panel {
		display: block;
		position: absolute; left: 0; right: 0; top: 100%;
		padding: 10px 12px 12px;
		background: var(--paper-raise);
		border-bottom: 1px solid var(--line);
		box-shadow: 0 12px 28px rgba(27, 31, 43, 0.14);
	}

	/* 내려온 칸 안에서는 입력도 결과도 폭을 다 씁니다. 결과는 더 이상 떠 있지 않고
	   입력 아래에 그대로 이어집니다 — 이미 칸 자체가 떠 있기 때문입니다. */
	.learn-page .search-box.expanded .search-input,
	.learn-page .search-box.expanded .search-input:focus { width: 100%; }

	.learn-page .search-box.expanded .search-results {
		position: static; width: auto; max-height: 55vh; margin-top: 8px;
		border: 0; border-radius: 0; box-shadow: none; padding: 0;
	}
	.learn-page .search-box.expanded .search-hit a { border-radius: 8px; }
}
@keyframes learn-blink { 50% { opacity: 0; } }
/* 경로는 브랜드에 붙이고(margin-right:auto) 검색만 오른쪽 끝으로 보냅니다. 셋을 고르게
   벌리면 넓은 화면에서 경로가 한가운데 떠 어디에 딸린 것인지 알기 어렵습니다. */
.learn-page .crumbs {
	font-size: 13px; color: var(--ink-faint); margin-right: auto;
	display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
}
.learn-page .crumbs .sep { color: var(--line); }
.learn-page .crumbs .current { color: var(--ink-soft); }
.learn-page .crumbs a:hover { color: var(--accent-deep); }

/* ── 머리 ── */
.learn-page .hero { padding: 56px 0 40px; position: relative; }
.learn-page .hero-track {
	display: inline-flex; align-items: center; gap: 8px;
	background: var(--accent-soft); border: 1px solid var(--accent-soft-line);
	color: var(--accent-deep); font-size: 12.5px; font-weight: 700;
	padding: 5px 12px; border-radius: 20px; margin-bottom: 18px;
}
.learn-page .hero-track .num { font-family: "SFMono-Regular", Consolas, Menlo, monospace; }
.learn-page h1 {
	font-size: 34px; font-weight: 800; letter-spacing: -0.02em; margin: 0 0 12px;
	line-height: 1.25; color: var(--ink);
}
.learn-page .hero-sub { font-size: 16.5px; color: var(--ink-soft); margin: 0 0 24px; max-width: 520px; }
.learn-page .meta-row { display: flex; flex-wrap: wrap; gap: 10px; }
.learn-page .meta-chip {
	display: inline-flex; align-items: center; gap: 6px;
	font-size: 12.5px; color: var(--ink-soft);
	background: var(--paper-raise); border: 1px solid var(--line);
	padding: 6px 11px; border-radius: 8px;
}
.learn-page .meta-chip.run { color: var(--good); background: var(--good-soft); border-color: #C6E9D7; font-weight: 700; }
.learn-page .dot { width: 5px; height: 5px; border-radius: 50%; background: currentColor; }

/* 머리 오른쪽에 비스듬히 놓이는 코드 쪽지 */

/* 글과 쪽지를 가로로 나란히 둡니다.
   쪽지를 흐름 밖에 띄우고 제목 자리를 값으로 깎아 두던 때에는, 그 값보다 넓은 쪽지가
   그대로 잘렸습니다(60개 중 12개가 그랬습니다 — 죄다 ASP.NET Core 쪽입니다. C# 코드가
   형식 이름 때문에 한 줄이 깁니다). 여기서는 쪽지가 제 너비를 먼저 가져가고 남는 자리를
   글이 씁니다. 단원마다 쪽지 너비가 다르므로 값 하나로 맞출 수 없습니다. */
.learn-page .hero:has(.peek) { display: flex; align-items: flex-start; gap: 24px; }
.learn-page .hero-main { flex: 1 1 0; min-width: 0; }

.learn-page .peek {
	/* 쪽지가 제 너비를 먼저 가져갑니다(flex-basis: auto, 줄어들지 않음). 글 칸은
	   basis 가 0 이라 남는 만큼만 차지하므로, 둘을 더해도 넘치지 않습니다. */
	flex: 0 0 auto;
	/* 위로 조금 올려 눈높이를 예전과 맞춥니다(예전 top: 44px, 머리 padding-top 56px). */
	margin-top: -12px;
	/* 폭을 값으로 박지 않고 내용에 맞춥니다. 이 상자는 코드를 적힌 그대로 보이므로
	   (white-space: pre) 줄이 길어도 접히지 않고, 폭이 고정이면 그대로 오른쪽이
	   잘려 나갑니다. 상한 440px 은 지금 가장 긴 쪽지(418px)에 여유를 더한 값이고,
	   그 폭에서도 제목이 3줄이 되는 단원은 없습니다(62개 전부 실측). */
	width: max-content; min-width: 220px; max-width: 440px; overflow: hidden;
	background: var(--code-bg); border-radius: 10px; padding: 14px 16px;
	transform: rotate(3deg);
	box-shadow: 0 14px 30px -10px rgba(20,20,40,0.35);
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 11.5px;
	line-height: 1.65; color: var(--code-text);
	white-space: pre;
}

/* ── 절 ── */
.learn-page section { padding: 36px 0; }
.learn-page section.divider { border-top: 1px solid var(--line); }
.learn-page .eyebrow {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace;
	font-size: 12px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase;
	color: var(--accent); margin: 0 0 14px;
}
.learn-page h2 { font-size: 22px; font-weight: 800; margin: 0 0 14px; letter-spacing: -0.01em; }
.learn-page p { font-size: 15.5px; color: var(--ink); margin: 0 0 14px; }
.learn-page code.inline {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 0.88em;
	background: var(--accent-soft); color: var(--accent-deep);
	padding: 1.5px 6px; border-radius: 5px;
}
/* 긴 식별자는 줄바꿈할 자리가 없어 그것을 담은 칸의 최소 폭이 됩니다. 좁은 화면에서는
   그 최소 폭이 화면보다 넓어져 본문이 통째로 오른쪽으로 밀려 나갑니다 — 표가 벌어지고,
   배지 옆 글이 잘리는 것이 모두 같은 까닭입니다.

   마지막 수단으로 글자 사이에서 끊게 둡니다. break-word 가 아니라 anywhere 인 것은
   최소 폭 계산에 반영되는 쪽이 anywhere 뿐이기 때문입니다 — break-word 는 줄을 나눌
   뿐이라 표 칸과 grid 칸은 여전히 벌어집니다. 자리가 넉넉하면 끊지 않습니다.

   표는 td.tname 만 겁니다. td·th 전체에 걸면 오른쪽 칸의 한글 설명까지 대상이 되어
   낱말 한가운데서 끊깁니다. tname 은 이름을 담는 칸이라 그럴 일이 없습니다. */
.learn-page code.inline,
.learn-page .mono,
.learn-page .ex-reveal-inner,
.learn-page table.types td.tname { overflow-wrap: anywhere; }

.learn-page ul.plain { margin: 0 0 14px; padding-left: 20px; }
.learn-page ul.plain li { font-size: 15.5px; margin-bottom: 6px; }

/* ── 타입 표 ── */
.learn-page table.types { width: 100%; border-collapse: collapse; margin: 8px 0 20px; font-size: 14.5px; }
.learn-page table.types th {
	text-align: left; font-size: 12px; color: var(--ink-faint); font-weight: 700;
	text-transform: uppercase; letter-spacing: 0.04em;
	padding: 8px 10px; border-bottom: 1px solid var(--line);
}
.learn-page table.types td { padding: 10px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
.learn-page table.types td.tname {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace;
	color: var(--accent-deep); font-weight: 700;
}
.learn-page table.types tr:last-child td { border-bottom: none; }

/* ── 코드 놀이터 ── */
.learn-page .playground {
	border-radius: 12px; overflow: hidden; border: 1px solid #0C0F16;
	box-shadow: 0 1px 0 rgba(255,255,255,0.04) inset;
}
.learn-page .pg-tabs {
	background: var(--code-bg-alt); display: flex; align-items: center;
	justify-content: space-between; padding: 0 6px;
}
.learn-page .pg-tab {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12.5px;
	color: var(--code-text); padding: 11px 14px; border-bottom: 2px solid var(--accent);
}
.learn-page .run-btn {
	display: flex; align-items: center; gap: 7px;
	background: var(--accent); color: #fff; border: none;
	font-family: inherit; font-size: 12.5px; font-weight: 700;
	padding: 8px 14px; margin: 6px; border-radius: 7px; cursor: pointer;
}
.learn-page .run-btn:hover { background: var(--accent-deep); }
.learn-page .run-btn:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }
.learn-page .run-btn .tri {
	width: 0; height: 0; border-top: 4.5px solid transparent; border-bottom: 4.5px solid transparent;
	border-left: 6px solid #fff;
}
.learn-page pre.code {
	margin: 0; background: var(--code-bg); color: var(--code-text);
	font-family: "SFMono-Regular", Consolas, Menlo, monospace;
	font-size: 13.5px; line-height: 1.85; padding: 18px 20px; overflow-x: auto;
}
/* 홀로 놓이는 코드 블록입니다(.playground 안의 것과 달리 뒤에 문단이 이어집니다).
   같은 까닭으로 아래를 띄웁니다 — 실행 상자 안쪽의 pre 는 margin:0 그대로여야 하므로
   여기(.rounded)에만 답니다. */
.learn-page pre.code.rounded { border-radius: 8px; margin-bottom: 20px; }
.learn-page .kw { color: var(--code-keyword); }
.learn-page .ty { color: var(--code-type); }
.learn-page .str { color: var(--code-string); }
.learn-page .cm { color: var(--code-comment); }
.learn-page .num { color: var(--code-num); }
/* 보간 문자열($"...{식}...")의 중괄호 안쪽에는 따로 클래스를 두지 않습니다. 그 안은
   글자가 아니라 실행되는 식이라, 문자열 span 을 닫고 바깥 코드와 같은 규칙으로
   칠합니다(lesson.js 의 paintText). 중괄호와 서식 지정자만 문자열로 남습니다. */
/* 출력 칸도 같습니다 — 실제 높이는 스크립트가 재어 넣고, 아래 값은 그 전까지의 자리입니다. */
.learn-page .output {
	background: #10131A; border-top: 1px solid #262B38; padding: 0;
	max-height: 0; overflow: hidden; transition: max-height .3s ease;
}
.learn-page .output.open { max-height: 4000px; }
.learn-page .output-inner { padding: 14px 20px; }
.learn-page .output-label {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 10.5px;
	color: var(--code-comment); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 8px;
}
.learn-page .output-text {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 13.5px;
	color: #8FE3B5; white-space: pre-wrap;
}

/* 다른 엔진의 문구입니다.
   오류 메시지는 브라우저마다 다르게 적힙니다 — 같은 잘못인데 크롬은
   "Assignment to constant variable", 파이어폭스는 "invalid assignment to const 'x'"
   라고 냅니다. 적어 둔 것 하나만 두면 다른 브라우저로 보는 사람은 제가 무언가 잘못한
   줄 압니다. 그래서 함께 적고 흐리게 눕혀 둡니다(실행 결과가 아니라 참고입니다). */
.learn-page .output-label.alt { margin-top: 12px; }
.learn-page .output-text.alt { color: #7C8598; font-size: 12.5px; }

/* 줄마다 종류가 달려 오면 종류대로 칠합니다(기획서 C-3). 종류가 없는 결과는 위의
   .output-text 색 하나로 나옵니다 — C# 트랙이 그렇습니다. */
.learn-page .o-line { white-space: pre-wrap; }
.learn-page .o-info { color: #8FE3B5; }
.learn-page .o-warn { color: #E8C56B; }
.learn-page .o-error { color: #F08A8A; }
/* 마지막 표현식의 값입니다(C-5). 출력이 아니라 값이라는 것이 보이도록 흐리게 눕힙니다. */
.learn-page .o-value { color: #7C8598; font-style: italic; }
/* 오류 해설(C-4)과 잘림 안내입니다. 실행기가 붙인 말이라 코드 글꼴을 벗깁니다. */
.learn-page .o-hint,
.learn-page .o-note {
	font-family: inherit; font-size: 12.5px; color: var(--code-comment);
	margin-top: 6px; padding-left: 10px; border-left: 2px solid #2C3242;
}

/* 출력 / 미리보기 탭 (C-9). 라벨 자리를 대신하므로 아래 여백도 라벨과 같습니다. */
.learn-page .output-tabs { display: flex; gap: 4px; margin-bottom: 8px; }
.learn-page .output-tab {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 10.5px;
	text-transform: uppercase; letter-spacing: 0.06em;
	color: var(--code-comment); background: none; border: 0; border-radius: 5px;
	padding: 3px 8px; cursor: pointer;
}
.learn-page .output-tab:hover { color: #C7D0E0; }
.learn-page .output-tab.is-on { color: #10131A; background: #8FE3B5; }

.learn-page .output-text.is-off { display: none; }
.learn-page .output-preview { display: none; }
.learn-page .output-preview.is-on { display: block; }
.learn-page .output-preview iframe {
	width: 100%; min-height: 200px; border: 0; border-radius: 6px; background: #fff;
}
/* 여기에 display: flex 를 두면 안 됩니다. <p> 안의 글과 <code> 가 각각 flex 항목이 되어
   나란히 늘어서고, 글줄이 흐르지 않습니다 — 94개 가운데 30개가 안에 <code> 나 <a> 를
   담고 있어 그것들이 좁은 칸으로 찌그러집니다. 보통의 문단으로 둡니다. */
.learn-page .wasm-note {
	font-size: 11.5px; color: var(--ink-faint); margin-top: 8px;
	line-height: 1.7;
}

/* ── 예제 코드 편집 ──
   고칠 수 있다는 것이 보이지 않으면 아무도 손대지 않으므로, 글자 모양(cursor)과
   테두리로 알립니다. */
.learn-page pre.code[contenteditable] { cursor: text; outline: none; }
.learn-page pre.code[contenteditable]:focus {
	box-shadow: inset 0 0 0 2px var(--accent);
}
/* 실행 단추 옆에 되돌리기를 나란히 둡니다. 탭 줄은 자식이 둘일 때 양끝으로 벌어지는
   방식이라(justify-content: space-between), 단추 둘을 이 상자로 묶어 하나로 셉니다. */
.learn-page .pg-actions { display: flex; align-items: center; gap: 6px; }
.learn-page .reset-btn {
	background: none; color: var(--code-comment); border: 1px solid #2E3546;
	font-family: inherit; font-size: 12px; font-weight: 600;
	padding: 7px 11px; border-radius: 7px; cursor: pointer;
}
.learn-page .reset-btn:hover { color: var(--code-text); border-color: #47506A; }
/* Insert 로 덮어쓰기에 들어갔음을 알리는 표시입니다. 글자가 밀리지 않고 갈리는 까닭이
   보이지 않으면 고장으로 읽힙니다. */
.learn-page .pg-mode {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 11px; font-weight: 700;
	color: var(--accent); border: 1px solid var(--accent); border-radius: 5px;
	padding: 3px 7px; letter-spacing: 0.02em;
}
.learn-page .reset-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 코드를 고친 뒤의 출력 칸에 붙는 안내입니다. 고친 것과 결과가 어긋나 있음을 밝힙니다. */
.learn-page .output-stale {
	margin-top: 10px; padding-top: 10px; border-top: 1px solid #262B38;
	font-size: 11.5px; line-height: 1.6; color: var(--code-comment);
}

/* ── 버전 이력 목록 ──
   단원 목차(.toc-*)를 그대로 쓰되, 버전에만 있는 두 가지를 더합니다 — 언제 나왔는지와
   무엇이 더해졌는지입니다. */
.learn-page .v-when {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12px;
	font-weight: 500; color: var(--ink-faint); margin-left: 8px;
}
.learn-page .v-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.learn-page .v-tag {
	font-size: 12px; color: var(--accent-deep);
	background: var(--accent-soft); border: 1px solid var(--accent-soft-line);
	border-radius: 5px; padding: 3px 8px;
}
/* 아직 글이 없는 버전은 이름과 함께 이 표들도 가라앉혀, 눌리는 것과 구별되게 합니다. */
.learn-page .toc-item.coming .v-tag {
	color: var(--ink-faint); background: none; border-color: var(--line-soft);
}

/* ── 코드 좌우 비교 ──
   같은 것을 두 가지로 적었을 때 나란히 놓습니다(예전 문법과 지금 문법, 우리가 적는 것과
   컴파일러가 만들어 내는 것). 버전 이력 페이지의 Before/After 도 이 틀을 씁니다. */
/* 아래 여백은 이 틀이 집니다. 이 페이지의 요소들은 위쪽 여백을 두지 않는 방식이라
   (h2·p 모두 margin-top 이 0), 띄우는 몫을 앞선 요소가 지지 않으면 뒤따르는 소제목이
   상자에 그대로 붙습니다. 표(.types)와 같은 20px 로 맞춥니다. */
.learn-page .compare { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin: 0 0 20px; }
.learn-page .cmp-col {
	display: flex; flex-direction: column;
	border-radius: 12px; overflow: hidden; border: 1px solid #0C0F16;
	/* 격자 칸은 기본이 min-width:auto 라 안에 든 코드가 길면 칸이 그만큼 넓어집니다.
	   그러면 두 칸의 폭이 서로 달라지고 페이지 자체가 가로로 밀립니다. 0 으로 묶어 두면
	   칸은 제 몫만 차지하고, 넘치는 코드는 pre 안에서 가로로 넘깁니다. */
	min-width: 0;
}
.learn-page .cmp-label {
	background: var(--code-bg-alt); color: var(--code-text);
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12.5px;
	padding: 11px 14px; border-bottom: 2px solid var(--accent);
}
/* 한쪽이 짧아도 아래가 빈 채로 남지 않게 채웁니다 — 두 칸의 바탕이 같은 높이로 보입니다.
   글자는 한 단계 줄입니다. 칸 하나가 본문 폭의 절반이라 같은 크기로 두면 들여쓴 줄부터
   가로로 밀리는데, 나란히 놓고 견주는 자리에서 한쪽만 밀리면 비교가 되지 않습니다. */
.learn-page .cmp-col pre.code { flex: 1; border-radius: 0; font-size: 12.5px; padding: 16px 16px; }

/* ── 버전 타임라인 ── */
.learn-page .timeline-box {
	background: var(--paper-raise); border: 1px solid var(--line); border-radius: 12px;
	padding: 22px 24px 20px;
}
.learn-page .timeline-track { position: relative; height: 2px; background: var(--line); margin: 30px 6px 0; }
.learn-page .tl-node {
	position: absolute; top: 50%; transform: translate(-50%,-50%);
	width: 11px; height: 11px; border-radius: 50%; background: var(--line);
	border: 2px solid var(--paper-raise);
}
.learn-page .tl-node.active { background: var(--accent); width: 13px; height: 13px; }
.learn-page .tl-label {
	position: absolute; top: -24px; transform: translateX(-50%);
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 10.5px; color: var(--ink-faint);
	white-space: nowrap;
}
.learn-page .tl-label.active { color: var(--accent-deep); font-weight: 700; }
.learn-page .tl-legend { margin: 26px 0 0; padding: 0; list-style: none; }
.learn-page .tl-legend li {
	display: flex; align-items: baseline; gap: 10px;
	padding: 9px 0; border-top: 1px solid var(--line-soft);
}
.learn-page .tl-legend li:first-child { border-top: none; }
.learn-page .tl-legend .tl-ver {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12px; font-weight: 800;
	color: var(--accent-deep); background: var(--accent-soft); border-radius: 5px;
	padding: 2px 8px; flex-shrink: 0;
}
.learn-page .tl-legend .tl-feat { font-size: 13.5px; color: var(--ink-soft); }
/* 배지는 왼쪽 첫 줄에 두고, 글은 오른쪽 한 칸에 위에서 아래로 쌓습니다.
   flex 로 두면 <p> 하나하나가 항목이 되어 문단이 둘일 때 세 칸으로 벌어집니다. */
.learn-page .version-note {
	display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 10px; align-items: start; margin-top: 18px;
	background: var(--gold-soft); border: 1px solid #ECD9AE; border-radius: 8px; padding: 12px 14px;
}
.learn-page .version-note > * { grid-column: 2; }
.learn-page .version-note .badge {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 11px; font-weight: 800;
	color: var(--gold); background: #fff; border: 1px solid #ECD9AE; padding: 2px 7px; border-radius: 5px;
	grid-column: 1; grid-row: 1; justify-self: start;
}
.learn-page .version-note p { margin: 0; font-size: 13.5px; color: #6B4E15; }
.learn-page .version-note code.inline { background: #fff; }

/* ── 실습 문제 ── */
.learn-page .exercise {
	border: 1px solid var(--line); border-radius: 12px; padding: 20px 22px; margin-bottom: 16px;
	background: var(--paper-raise);
}
.learn-page .ex-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 10px; }
.learn-page .ex-title { font-size: 15.5px; font-weight: 700; }
.learn-page .ex-level { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 20px; flex-shrink: 0; }
.learn-page .ex-level.easy { background: var(--good-soft); color: var(--good); }
.learn-page .ex-level.mid { background: var(--gold-soft); color: var(--gold); }
.learn-page .ex-level.hard { background: #FBE4E4; color: #B03A3A; }
.learn-page .exercise p:last-of-type { margin-bottom: 0; }
.learn-page .ex-actions { display: flex; gap: 8px; margin-top: 12px; }
.learn-page .ex-btn {
	font-family: inherit; font-size: 12.5px; font-weight: 700;
	background: #fff; color: var(--accent-deep); border: 1px solid var(--accent-soft-line);
	padding: 7px 13px; border-radius: 7px; cursor: pointer;
}
.learn-page .ex-btn:hover { background: var(--accent-soft); }
.learn-page .ex-btn:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }
/* 열렸을 때의 높이는 여기서 정하지 않습니다. 값으로 박으면 그보다 긴 답이 잘려 나가는데,
   2부부터는 클래스가 통째로 들어가 어떤 값을 골라도 언젠가 넘습니다. 실제 높이를 재어
   넣는 일은 js/learn/lesson.js 가 하고(toggle), 아래 값은 그것이 닿기 전이나 스크립트가
   없을 때를 위한 넉넉한 자리입니다. */
.learn-page .ex-reveal { margin-top: 12px; max-height: 0; overflow: hidden; transition: max-height .25s ease; }
.learn-page .ex-reveal.open { max-height: 4000px; }
.learn-page .ex-reveal-inner {
	background: var(--code-bg); border-radius: 8px; padding: 12px 14px;
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12.5px; color: var(--code-text);
	white-space: pre-wrap;
}

/* ── 흔한 실수 ──
   JavaScript 트랙에만 있는 블록입니다. C# 트랙의 "버전 배지" 자리를 대신합니다
   (기획서 5.4) — 버전 이력은 C# 이야기라 이쪽에는 낼 것이 없습니다. */
.learn-page .pitfall {
	border: 1px solid #F0DADA; border-left: 3px solid #D98A8A; border-radius: 10px;
	background: #FDF6F6; padding: 16px 20px; margin-bottom: 12px;
}
.learn-page .pf-head { font-size: 14.5px; font-weight: 700; color: #8E3A3A; margin-bottom: 8px; }
.learn-page .pitfall p { font-size: 14.5px; margin-bottom: 10px; }
.learn-page .pitfall p:last-child { margin-bottom: 0; }
.learn-page .pitfall code.inline { background: #fff; }
/* 실제로 나오는 오류 메시지입니다. 고칠 것이 아니라 읽을 것이라 실행 단추를 달지 않습니다. */
.learn-page pre.code.err { color: #F0A0A0; margin-bottom: 0; }

/* ── 요약과 앞뒤 이동 ── */
.learn-page .summary-box {
	background: var(--accent-soft); border: 1px solid var(--accent-soft-line); border-radius: 12px;
	padding: 20px 22px;
}
.learn-page .summary-box li { color: var(--accent-deep); }
.learn-page .summary-box li::marker { color: var(--accent); }
.learn-page .summary-box code.inline { background: #fff; }
.learn-page .navrow { display: flex; gap: 14px; margin-top: 8px; }
.learn-page .navcard {
	flex: 1; border: 1px solid var(--line); border-radius: 10px; padding: 16px 18px;
	background: var(--paper-raise);
}
.learn-page .navcard:hover { border-color: var(--accent-soft-line); background: #fff; }
.learn-page .navcard .dir {
	font-size: 11px; color: var(--ink-faint); font-weight: 700;
	text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px;
}
.learn-page .navcard .lname { font-size: 14.5px; font-weight: 700; }
.learn-page .navcard.next { text-align: right; }
/* 앞 단원이 없을 때 다음 카드가 왼쪽으로 붙지 않도록 빈 자리를 둡니다. */
.learn-page .navcard.spacer { visibility: hidden; }

.learn-page footer { padding: 30px 0 60px; text-align: center; font-size: 12px; color: var(--ink-faint); }

/* ── 목차 ── */
/* 트랙 사용법 안내입니다. 단원이 아니라 화면 쓰는 법이라 목차 위에 한 번만 둡니다. */
.learn-page .howto {
	background: var(--paper-raise); border: 1px solid var(--line); border-radius: 10px;
	padding: 18px 22px; margin-top: 8px;
}
.learn-page .howto .eyebrow { margin-bottom: 10px; }
.learn-page .howto ul { margin: 0; padding-left: 18px; }
.learn-page .howto li { font-size: 14.5px; color: var(--ink-soft); margin-bottom: 4px; }
.learn-page .howto li:last-child { margin-bottom: 0; }

.learn-page .toc-part { border-top: 1px solid var(--line); padding: 30px 0; }
.learn-page .toc-part:first-of-type { border-top: none; }
.learn-page .toc-part-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 4px; }
.learn-page .toc-part-num {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12px; font-weight: 800;
	color: var(--accent-deep); background: var(--accent-soft); border-radius: 5px; padding: 2px 8px;
}
.learn-page .toc-part-name { font-size: 19px; font-weight: 800; }
.learn-page .toc-part-sub { font-size: 14px; color: var(--ink-soft); margin: 0 0 16px; }
.learn-page .toc-list { list-style: none; margin: 0; padding: 0; }
.learn-page .toc-item { border-top: 1px solid var(--line-soft); }
.learn-page .toc-item:first-child { border-top: none; }
.learn-page .toc-link {
	display: flex; align-items: baseline; gap: 12px; padding: 12px 10px; border-radius: 8px;
}
.learn-page a.toc-link:hover { background: var(--paper-raise); }
.learn-page .toc-num {
	font-family: "SFMono-Regular", Consolas, Menlo, monospace; font-size: 12.5px;
	color: var(--ink-faint); flex-shrink: 0; min-width: 34px;
}
.learn-page .toc-body { min-width: 0; }
.learn-page .toc-title { font-size: 15.5px; font-weight: 700; }
.learn-page .toc-sum { font-size: 13.5px; color: var(--ink-soft); }
/* 아직 쓰지 않은 단원 — 눌리지 않는다는 것이 보여야 합니다. */
.learn-page .toc-item.coming .toc-link { cursor: default; }
.learn-page .toc-item.coming .toc-title { color: var(--ink-faint); font-weight: 600; }
.learn-page .toc-item.coming .toc-sum { color: var(--ink-faint); }
.learn-page .toc-flag {
	margin-left: auto; flex-shrink: 0; font-size: 11px; font-weight: 700;
	color: var(--ink-faint); background: var(--paper); border: 1px solid var(--line);
	padding: 2px 8px; border-radius: 20px;
}

/* 트랙 잇기 카드 */
.learn-page .track-next {
	display: block; border: 1px solid var(--accent-soft-line); background: var(--accent-soft);
	border-radius: 12px; padding: 18px 20px; margin-top: 8px;
}
.learn-page .track-next .dir {
	font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
	color: var(--accent); margin-bottom: 6px;
}
.learn-page .track-next .tname { font-size: 16px; font-weight: 800; color: var(--accent-deep); }
.learn-page .track-next .tsum { font-size: 13.5px; color: var(--ink-soft); margin: 4px 0 0; }

@media (prefers-reduced-motion: reduce) {
	.learn-page .output, .learn-page .ex-reveal { transition: none; }
	.learn-page .brand .cursor { animation: none; }
}

/* 본문 폭(.wrap 760px + 좌우 여백)이 온전히 나오지 못하는 화면부터는 두 칸을 세로로
   쌓습니다. 나란히 두면 한 칸이 350px 아래로 떨어져, 코드가 조금만 길어도 양쪽 모두
   가로로 밀며 읽어야 합니다 — 비교하려고 나란히 놓은 뜻이 사라집니다. */
@media (max-width: 820px) {
	.learn-page .compare { grid-template-columns: 1fr; }
	/* 쪽지를 놓을 가로 자리가 남지 않는 폭입니다. 제목 위로 올라오느니 접습니다. */
	.learn-page .peek { display: none; }
}

/* 제목 자리를 값으로 깎아 두던 규칙은 걷어냈습니다. 쪽지가 흐름 안으로 들어와
   제목을 실제로 밀어내므로, 겹칠 일도 자리를 미리 재어 둘 일도 없습니다. */

/* ── 좁은 화면의 머리 배치 ──
   브랜드와 검색 아이콘이 한 줄, 경로가 그 아래입니다.

   중단점이 767.98px 인 것은 부트스트랩 .container 가 거기서 안쪽 폭을 720 에서 540 으로
   줄이기 때문입니다. 가장 긴 경로가 492px(2.2 MVC 와 라우팅)이고 브랜드 103 · 검색 아이콘
   34 · 간격 32 를 더하면 661px 이 필요한데, 540 안에는 들어가지 않습니다. 한 줄에 두면
   경로만 두 줄로 접히고 브랜드는 그 가운데에 떠서 어긋나 보입니다.

   경로에 한 줄을 통째로 주면 540 을 다 쓰므로 492 가 한 줄에 들어갑니다. 머리는 78px 에서
   90px 로 두꺼워지지만, 접힌 경로를 읽는 것보다 낫습니다. */
@media (max-width: 767.98px) {
	.learn-page .topbar-inner { flex-wrap: wrap; align-items: center; gap: 6px 12px; }
	.learn-page .brand { order: 1; }
	.learn-page .search-box { order: 2; }
	.learn-page .crumbs { order: 3; flex-basis: 100%; margin-right: 0; }
}

@media (max-width: 600px) {
	.learn-page h1 { font-size: 27px; }
	/* 배지 폭은 145px 로 고정이라 좁아지는 것은 글 칸뿐입니다. 이 폭 아래에서 글 칸이
	   300px 밑으로 떨어지고, 320px 화면에서는 22px 만 남아 한 글자씩 끊깁니다.
	   배지를 위로 올려 글이 카드 폭을 다 쓰게 합니다. */
	.learn-page .version-note { grid-template-columns: 1fr; }
	.learn-page .version-note > *,
	.learn-page .version-note .badge { grid-column: 1; }

	.learn-page .navrow { flex-direction: column; }
	.learn-page .navcard.next { text-align: left; }
	.learn-page .navcard.spacer { display: none; }
}
