/*
 * 모베레 LMS와 같은 톤앤매너: 토큰과 컨트롤 규격은 LMS의 app/globals.css, src/styles/ui.css를 따른다.
 * 주 버튼은 네이비, 켜짐·활성은 청록, 경고·알림은 코랄. 컨트롤 모서리 8px, 표면 모서리 12px.
 */
:root {
	color-scheme: light;
	--canvas: #f4f6f9;
	--surface: #ffffff;
	--ink: #111827;
	--muted: #6b7280;
	--line: #e7eaf0;
	--accent: #0b6b60;
	--accent-bright: #0e9f8e;
	--accent-soft: #e6f6f3;
	--navy: #0f172a;
	--danger: #c2410c;
	--danger-soft: #fdeee6;
	--coral: #f0573a;
	--video: #0b0f19;
	--live: #22c55e;
	--radius-control: 8px;
	--radius-surface: 12px;
	--control-h: 36px;
	--control-h-sm: 30px;
	--control-h-lg: 44px;
	--shell-top-h: 56px;
	--motion-fast: 180ms;
}
* {
	box-sizing: border-box;
}
[hidden] {
	display: none !important;
}
html,
body {
	margin: 0;
	min-height: 100%;
}
body {
	min-width: 320px;
	background: var(--canvas);
	color: var(--ink);
	font-family: Pretendard, "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", system-ui, sans-serif;
	font-size: 14px;
	line-height: 1.5;
}
button,
input,
select {
	font: inherit;
}
a {
	color: var(--accent);
}
h2 {
	margin: 0 0 12px;
	font-size: 15px;
	letter-spacing: -0.2px;
}
.muted {
	color: var(--muted);
}
.status {
	margin: 0;
	color: var(--muted);
	font-size: 12px;
}
.pill {
	display: inline-flex;
	align-items: center;
	padding: 2px 8px;
	border: 1px solid var(--line);
	border-radius: 10px;
	background: var(--canvas);
	color: var(--muted);
	font-size: 11px;
	line-height: 16px;
	white-space: nowrap;
}

/* ---------- 틀: 상단 바 + 본문 ---------- */
.shell {
	display: flex;
	flex-direction: column;
	min-height: 100dvh;
}
.topbar {
	display: flex;
	flex: none;
	flex-wrap: wrap;
	align-items: center;
	gap: 4px 12px;
	min-height: var(--shell-top-h);
	padding: 8px 16px;
	border-bottom: 1px solid var(--line);
	background: var(--surface);
}
.topbar h1 {
	margin: 0;
	font-size: 14px;
	font-weight: 700;
	letter-spacing: -0.2px;
	white-space: nowrap;
}
.topbar .muted {
	font-size: 12px;
}
.panel {
	padding: 18px;
	border: 1px solid var(--line);
	border-radius: var(--radius-surface);
	background: var(--surface);
	box-shadow: 0 1px 2px rgb(20 26 43 / 4%);
}
.row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
}
.row > h2 {
	flex: 1;
	margin: 0;
}

/* ---------- 컨트롤 ---------- */
button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 6px;
	height: var(--control-h);
	padding: 0 14px;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	background: var(--surface);
	color: var(--ink);
	font-size: 13px;
	font-weight: 600;
	line-height: 1;
	white-space: nowrap;
	cursor: pointer;
	transition: background var(--motion-fast), border-color var(--motion-fast), color var(--motion-fast);
}
button:hover {
	border-color: #d3d9e3;
	background: #f8fafc;
}
button:disabled {
	opacity: 0.45;
	cursor: not-allowed;
}
button.primary {
	border-color: var(--navy);
	background: var(--navy);
	color: #fff;
}
button.primary:hover {
	border-color: #1e293b;
	background: #1e293b;
}
button.danger {
	border-color: #f2c7b6;
	color: var(--danger);
}
button.danger:hover {
	border-color: #e9a98f;
	background: var(--danger-soft);
}
button:focus-visible,
input:focus-visible,
select:focus-visible {
	outline: 2px solid var(--accent-bright);
	outline-offset: 2px;
}
input,
select {
	width: 100%;
	height: var(--control-h);
	padding: 0 12px;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	background: var(--surface);
	color: var(--ink);
	font-size: 13px;
}
input::placeholder {
	color: #9ca3af;
}
input[type="range"] {
	height: auto;
	padding: 0;
	border: 0;
	background: none;
	accent-color: var(--accent-bright);
}
label {
	display: grid;
	gap: 6px;
	color: var(--muted);
	font-size: 12px;
	font-weight: 600;
}
form {
	display: grid;
	gap: 12px;
}

/* ---------- 입장 화면 ---------- */
.lobby {
	width: min(440px, calc(100% - 32px));
	margin: 32px auto 0;
	padding: 28px;
	box-shadow: 0 18px 50px #173d3012;
}
.lobby h2 {
	margin: 0 0 4px;
	font-size: 20px;
	letter-spacing: -0.4px;
}
.lobby > .muted {
	margin: 0 0 16px;
	font-size: 13px;
}
.lobby input,
.lobby select {
	height: var(--control-h-lg);
	font-size: 14px;
}
.lobby form button {
	width: 100%;
	height: var(--control-h-lg);
	margin-top: 4px;
	font-size: 15px;
}
.lobby .status {
	margin: 8px 0 12px;
}
.desktop-next h3 {
	margin: 16px 0 6px;
	font-size: 15px;
}
.desktop-next ol {
	margin: 0;
	padding-left: 20px;
}
.desktop-next h3 + p {
	margin: 0 0 18px;
}
.desktop-next li + li {
	margin-top: 6px;
}
/* 앱의 첫 화면(대기 화면)은 창 전체를 채운다(대표님 11/5 "가로 세로 100% 차도록"). 안내 글은 가로를 다 써서 줄바꿈을 줄이고,
   수업 녹화를 올리는 동안만 안내 60% · 올리는 목록 40%로 나눈다. 로비 상자의 폭(440px)은 풀어야 창을 채운다. */
.desktop-app .desktop-next {
	position: fixed;
	inset: 0;
	z-index: 30;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	align-items: center;
	gap: clamp(24px, 4vw, 64px);
	width: auto;
	max-width: none;
	margin: 0;
	padding: 48px clamp(24px, 6vw, 96px);
	border: 0;
	border-radius: 0;
	box-shadow: none;
	overflow: auto;
}
.desktop-app .desktop-next.uploading {
	grid-template-columns: minmax(0, 3fr) minmax(0, 2fr);
}
.desktop-app .desktop-next[hidden] {
	display: none;
}
.desktop-app .desktop-next h2 {
	font-size: clamp(28px, 3vw, 40px);
}
.desktop-app .desktop-next-text > .muted {
	font-size: clamp(15px, 1.4vw, 18px);
}
.desktop-app .desktop-next ol {
	font-size: clamp(18px, 1.7vw, 22px);
	line-height: 1.7;
}
.desktop-app .desktop-next .row {
	margin-top: 28px;
}
.desktop-uploads {
	align-self: stretch;
	display: flex;
	flex-direction: column;
	justify-content: center;
	min-width: 0;
	padding-left: clamp(20px, 3vw, 48px);
	border-left: 1px solid var(--line);
}
.desktop-uploads[hidden] {
	display: none;
}
.desktop-uploads h3 {
	margin: 0 0 16px;
	font-size: 20px;
}
.desktop-upload-list {
	display: grid;
	gap: 14px;
	margin: 0 0 16px;
	padding: 0;
	list-style: none;
}
.desktop-upload {
	padding: 14px 16px;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
}
.desktop-upload strong {
	display: block;
	overflow: hidden;
	font-size: 16px;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.desktop-upload-when {
	color: var(--muted, #64748b);
	font-size: 14px;
}
.desktop-upload .upload-bar {
	margin: 10px 0 6px;
}
.desktop-upload-detail {
	font-size: 15px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}
/* 다 올라가면 PC 끄기(앱 1.7.0부터). */
.desktop-shutdown {
	display: flex;
	align-items: center;
	gap: 8px;
	margin-top: 4px;
	font-size: 15px;
	font-weight: 600;
	cursor: pointer;
}
.desktop-shutdown input {
	width: 18px;
	height: 18px;
}
.desktop-shutdown-note {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 8px;
	margin: 0;
	padding: 10px 12px;
	border-radius: 10px;
	background: #fef3c7;
	color: #78350f;
	font-size: 15px;
	font-weight: 600;
}
.desktop-shutdown-note button {
	padding: 4px 12px;
	border: 1px solid #b45309;
	border-radius: 8px;
	background: #fff;
	color: #78350f;
	font: inherit;
	cursor: pointer;
}
.desktop-upload.done .upload-bar span {
	background: var(--live);
}
/* 수업 녹화를 마저 올리는 화면: 수업 화면 위로 창 전체를 덮는다. */
.upload-screen {
	position: fixed;
	inset: 0;
	z-index: 40;
	display: flex;
	flex-direction: column;
	justify-content: center;
	width: auto;
	max-width: none;
	margin: 0;
	padding: 48px clamp(24px, 8vw, 120px);
	border: 0;
	border-radius: 0;
	box-shadow: none;
}
.upload-screen[hidden] {
	display: none;
}
.upload-screen h2 {
	font-size: 26px;
}
.upload-bar {
	overflow: hidden;
	height: 14px;
	margin: 18px 0 12px;
	border-radius: 999px;
	background: var(--line);
}
.upload-bar span {
	display: block;
	width: 0;
	height: 100%;
	border-radius: inherit;
	background: var(--accent);
	transition: width 0.4s ease;
}
.upload-screen.done .upload-bar span {
	background: var(--live);
}
.upload-detail {
	margin: 0 0 8px;
	font-size: 17px;
	font-weight: 600;
	font-variant-numeric: tabular-nums;
}
.upload-screen .row {
	margin-top: 28px;
}
.desktop-next + .lobby {
	margin-top: 16px;
}
.room-list,
.participant-list,
.class-recording-player {
	width: 100%;
	margin-top: 10px;
	border-radius: var(--radius-control);
	background: #000;
}
.recording-list {
	display: grid;
	gap: 8px;
}
.room-card,
.participant-card,
.recording-card {
	padding: 12px;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	background: var(--surface);
}
.room-card {
	display: grid;
	justify-items: start;
	gap: 8px;
	height: auto;
	font-weight: 400;
	line-height: 1.5;
	text-align: left;
	white-space: normal;
}
.room-card.active {
	border-color: var(--accent-bright);
	background: var(--accent-soft);
}

/* ---------- 관제 화면 ---------- */
.layout {
	display: grid;
	grid-template-columns: minmax(0, 1fr) 330px;
	gap: 16px;
	padding: 22px 26px 28px;
}
.layout .panel + .panel {
	margin-top: 16px;
}
.stage {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
	gap: 12px;
	margin-top: 12px;
}
.side {
	display: grid;
	gap: 16px;
	align-content: start;
}
.side .panel + .panel {
	margin-top: 0;
}

/* ---------- 영상 타일 ---------- */
.tile {
	position: relative;
	/* 안의 큰 손·트로피 크기를 타일 폭에 맞춘다(cqi = 타일 폭의 1%). */
	container-type: inline-size;
	min-height: 180px;
	aspect-ratio: 16 / 9;
	overflow: hidden;
	isolation: isolate;
	border: 1px solid var(--line);
	border-radius: var(--radius-surface);
	background: var(--video);
	color: #fff;
}
.tile-placeholder {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	color: rgb(255 255 255 / 55%);
}
.tile-placeholder svg {
	width: 48px;
	height: 48px;
}
.tile video {
	position: relative;
	z-index: 1;
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
.tile strong {
	position: absolute;
	inset: auto 10px 10px;
	z-index: 2;
	text-shadow: 0 1px 3px #000;
}
.tile-footer {
	position: absolute;
	inset: auto 8px 6px;
	z-index: 4;
	display: flex;
	align-items: center;
	gap: 6px;
	min-width: 0;
	font-size: 12px;
	font-weight: 600;
	text-shadow: 0 1px 3px #000;
}
.tile-name {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
/* 마이크 상태: 꺼짐은 코랄 음소거 아이콘, 조용하면 테두리만 있는 마이크, 말하는 중이면 초록으로 채운 마이크. */
.tile-mic {
	display: grid;
	place-items: center;
	flex: none;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: rgb(15 23 42 / 55%);
	color: #fff;
}
.tile-mic[data-state="muted"] {
	background: var(--coral);
}
.tile-mic[data-state="speaking"] {
	color: var(--live);
	box-shadow: 0 0 0 2px rgb(34 197 94 / 55%);
}
.tile-mic[data-state="speaking"] svg rect {
	fill: currentColor;
}
.tile-mic svg {
	width: 13px;
	height: 13px;
}
.tile.screen .tile-placeholder,
.tile.screen .tile-mic {
	display: none;
}

/* ---------- 통화 창: 위 썸네일 줄 · 큰 화면 · 아래 버튼 그룹 · 오른쪽 채팅 ---------- */
.call-mode .shell {
	height: 100dvh;
}
.call {
	position: relative;
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	grid-template-rows: minmax(0, 1fr);
	gap: 10px;
	flex: 1;
	min-height: 0;
	padding: 12px 16px 16px;
	/* 채팅창이 차지하는 오른쪽 폭. 떠 있는 패널의 처음 위치를 큰 화면 가운데로 잡는 데 쓴다. */
	--chat-width: 0px;
}
/* 채팅창을 펼치면 오른쪽 열을 채팅창이 쓰고 큰 화면은 그만큼 줄어든다. 접으면 큰 화면이 전체 폭이 된다. */
.call.chat-open {
	grid-template-columns: minmax(0, 1fr) 320px;
	--chat-width: 330px;
}
/* 썸네일 그룹과 버튼 그룹: 큰 화면 위에 떠 있는 어두운 패널. 손잡이를 끌어 옮기고, 접으면 손잡이 줄만 남는다. */
.float-panel {
	position: absolute;
	z-index: 8;
	left: calc((100% - var(--chat-width)) / 2);
	transform: translateX(-50%);
	/* 가운데(left 50%)에 놓으면 브라우저는 오른쪽 절반만 폭으로 쳐서 버튼이 일찍 두 줄로 접혔다.
	   내용 폭 그대로 두고, 화면이 그보다 좁을 때만 접는다. */
	width: max-content;
	max-width: calc(100% - var(--chat-width) - 32px);
	border-radius: var(--radius-surface);
	background: rgb(15 23 42 / 88%);
	color: #fff;
	box-shadow: 0 12px 32px rgb(15 23 42 / 35%);
	backdrop-filter: blur(8px);
}
/* 한 번 끌어 옮긴 뒤에는 옮긴 자리(left, top)를 그대로 쓴다. */
.float-panel.moved {
	right: auto;
	transform: none;
}
/* 참가자 묶음은 큰 화면 오른쪽 위(대표님 11/4: 가운데 위에 있으면 수업 자료 윗부분을 가렸다), 버튼 묶음은 맨 아래 가운데. */
.thumbs-panel {
	top: 16px;
	left: auto;
	right: calc(var(--chat-width) + 16px);
	transform: none;
}
/* 아래 버튼 묶음은 독(Aceternity FloatingDock): 높이 64px 어두운 판에 둥근 버튼이 바닥에 맞춰 놓이고,
   마우스가 다가가면 버튼이 커지며(스크립트) 올린 버튼 위에 이름이 뜬다. */
.controls-panel {
	bottom: 20px;
	display: flex;
	align-items: flex-end;
	gap: 8px;
	min-height: 64px;
	padding: 0 16px 12px;
	border-radius: 16px;
	background: rgb(23 23 23 / 94%);
}
.controls-panel > .float-grip,
.controls-panel > .float-button {
	align-self: center;
	margin-top: 12px;
}
.controls-panel.moved {
	bottom: auto;
}
/* 막대 어디를 잡아도 패널을 옮긴다(버튼 빼고). */
.float-bar {
	display: flex;
	align-items: center;
	gap: 6px;
	padding: 4px 6px;
	cursor: grab;
	touch-action: none;
}
.float-panel.dragging .float-bar {
	cursor: grabbing;
}
.float-title {
	flex: 1;
	cursor: pointer;
	color: rgb(255 255 255 / 75%);
	font-size: 12px;
	font-weight: 600;
	white-space: nowrap;
}
.float-grip {
	display: grid;
	place-items: center;
	flex: none;
	width: 26px;
	height: 26px;
	border-radius: 6px;
	color: rgb(255 255 255 / 65%);
	cursor: grab;
	touch-action: none;
}
.float-grip:hover {
	background: rgb(255 255 255 / 12%);
	color: #fff;
}
.float-panel.dragging .float-grip {
	cursor: grabbing;
}
.float-grip svg,
.float-button svg {
	width: 16px;
	height: 16px;
}
.float-button {
	flex: none;
	width: 26px;
	height: 26px;
	padding: 0;
	border-color: transparent;
	border-radius: 6px;
	background: transparent;
	color: rgb(255 255 255 / 75%);
}
.float-button:hover {
	border-color: transparent;
	background: rgb(255 255 255 / 12%);
	color: #fff;
}
.float-actions {
	display: flex;
	gap: 2px;
	padding-right: 6px;
	margin-right: 2px;
	border-right: 1px solid rgb(255 255 255 / 18%);
}
.float-panel.collapsed .thumbs,
.float-panel.collapsed .controls,
.float-panel.collapsed .ink-tools,
.float-panel.collapsed .roster {
	display: none;
}
/* 휴대폰(스크립트가 .phone을 붙인다): 참가자 묶음은 맨 위, 버튼 묶음은 맨 아래에 붙박아 옮길 수 없고 접기만 된다.
   참가자 묶음은 제목 줄을 따로 두지 않고 썸네일 한 줄 오른쪽 끝에 접기 버튼만 둔다(접으면 "참가자 N명"과 펼치기 버튼).
   반 전체 버튼(전체 음소거 등)은 출석부 맨 위 줄에도 있어 여기서는 뺀다. */
.call.phone .thumbs-panel .float-grip,
.call.phone .controls-panel > .float-grip {
	display: none;
}
.call.phone .thumbs-panel {
	top: 8px;
	right: auto;
	left: calc((100% - var(--chat-width)) / 2);
	max-width: calc(100% - var(--chat-width) - 16px);
	transform: translateX(-50%);
}
.call.phone .controls-panel {
	bottom: 8px;
}
.call.phone .thumbs-panel:not(.collapsed) {
	display: flex;
	align-items: center;
}
.call.phone .thumbs-panel:not(.collapsed) > .thumbs {
	flex: 1 1 auto;
	min-width: 0;
	gap: 6px;
	padding: 6px;
}
.call.phone .thumbs-panel:not(.collapsed) > .float-bar {
	order: 1;
	padding: 0 4px 0 0;
}
.call.phone .thumbs-panel:not(.collapsed) .float-title,
.call.phone .thumbs-panel .float-actions {
	display: none;
}
.call.phone .thumbs .tile {
	flex-basis: 112px;
}
/* 출석부: 학생 한 줄에 상태와 버튼. 맨 위 "반 전체" 줄은 모든 학생에게 한 번에 적용한다. */
.roster-panel {
	top: 96px;
	z-index: 9;
}
.roster {
	max-height: min(60vh, 520px);
	padding: 0 8px 8px;
	overflow: auto;
}
.roster table {
	border-collapse: collapse;
	font-size: 13px;
	white-space: nowrap;
}
.roster th {
	position: sticky;
	top: 0;
	padding: 6px 8px;
	background: rgb(15 23 42);
	color: rgb(255 255 255 / 60%);
	font-size: 12px;
	font-weight: 600;
	text-align: center;
}
.roster th:first-child,
.roster td:first-child {
	text-align: left;
}
.roster td {
	padding: 3px 8px;
	border-top: 1px solid rgb(255 255 255 / 10%);
	color: rgb(255 255 255 / 80%);
	text-align: center;
}
/* 이탈 경고: 옐로카드 ×N, 강사의 − 버튼, 지금 벗어나 있으면 노란 글씨. */
.roster-warnings {
	display: inline-flex;
	align-items: center;
	gap: 6px;
}
.roster-cards {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	color: #fde68a;
	font-size: 12px;
	font-weight: 700;
}
.roster .roster-warnings button {
	min-width: 22px;
	height: 22px;
	padding: 0 3px;
	border-color: rgb(255 255 255 / 18%);
}
.roster-away-now {
	color: #fbbf24;
	font-size: 12px;
	font-weight: 600;
}
.roster-all td {
	background: rgb(255 255 255 / 6%);
	font-weight: 600;
}
.roster-empty {
	padding: 16px 24px;
	color: rgb(255 255 255 / 60%);
}
.roster button {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 3px;
	min-width: 28px;
	height: 28px;
	padding: 0 5px;
	border: 1px solid transparent;
	border-radius: 6px;
	background: transparent;
	color: rgb(255 255 255 / 80%);
	font-size: 12px;
}
.roster button:hover:not(:disabled) {
	border-color: transparent;
	background: rgb(255 255 255 / 14%);
	color: #fff;
}
.roster button.on {
	background: var(--accent-bright);
	color: #fff;
}
.roster button[data-action="hand"].on {
	background: transparent;
	color: #facc15;
}
.roster button:disabled {
	opacity: 0.55;
	cursor: default;
}
.roster button svg,
.roster-state svg {
	width: 15px;
	height: 15px;
}
.roster .roster-name {
	max-width: 160px;
	padding: 0 4px;
	overflow: hidden;
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	text-overflow: ellipsis;
}
.roster-state {
	display: inline-flex;
	color: rgb(255 255 255 / 40%);
}
.roster-state.on {
	color: #4ade80;
}
/* 주석 도구 패널: 펜을 켠 동안 큰 화면 왼쪽에 뜬다. 한 줄에 세 개씩, 묶음(도구, 굵기, 색, 모두 지우기) 사이에 선. */
.ink-panel {
	top: 50%;
	left: 16px;
	transform: translateY(-50%);
}
.ink-panel .float-bar {
	justify-content: space-between;
}
.ink-tools {
	display: grid;
	gap: 6px;
	padding: 2px 6px 8px;
}
.ink-group {
	display: grid;
	grid-template-columns: repeat(3, 30px);
	gap: 2px;
}
.ink-group + .ink-group {
	padding-top: 6px;
	border-top: 1px solid rgb(255 255 255 / 18%);
}
.ink-group button {
	display: grid;
	place-items: center;
	width: 30px;
	height: 30px;
	padding: 0;
	border: 1px solid transparent;
	border-radius: 6px;
	background: transparent;
	color: rgb(255 255 255 / 80%);
}
.ink-group button:hover {
	border-color: transparent;
	background: rgb(255 255 255 / 12%);
	color: #fff;
}
.ink-group button.on {
	background: var(--accent-bright);
	color: #fff;
}
.ink-group button svg {
	width: 16px;
	height: 16px;
}
.ink-dot {
	border-radius: 50%;
	background: currentColor;
}
/* 글 크기 고르기("가" 네 크기)와 스티커. 패널에서는 크기 네 개가 한 줄에 들어가게 칸을 좁힌다. */
.ink-panel .ink-sizes {
	grid-template-columns: repeat(4, 22px);
}
.ink-panel .ink-sizes button {
	width: 22px;
}
.ink-glyph {
	font-weight: 700;
	line-height: 1;
}
.ink-sticker {
	font-family: "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;
	font-size: 18px;
	line-height: 1;
}
/* 원형 색 고르기: 무지개 테두리 안의 어두운 원에 흰색·연한 색 6·진한 색 12개 점. 색을 고르면 테두리가 그 색이 되며 살짝 커진다. */
.color-wheel {
	position: relative;
	display: grid;
	place-items: center;
	width: 140px;
	height: 140px;
	--wheel-layer: #171717;
}
.wheel-rainbow,
.wheel-solid {
	position: absolute;
	inset: 0;
	border-radius: 50%;
}
.wheel-rainbow {
	background: conic-gradient(from 0deg, hsl(0 90% 60%), hsl(30 90% 60%), hsl(60 90% 60%), hsl(90 90% 60%), hsl(120 90% 60%), hsl(150 90% 60%), hsl(180 90% 60%), hsl(210 90% 60%), hsl(240 90% 60%), hsl(270 90% 60%), hsl(300 90% 60%), hsl(330 90% 60%), hsl(360 90% 60%));
	transition: transform 0.35s cubic-bezier(0.34, 1.8, 0.64, 1);
}
.color-wheel.chosen .wheel-rainbow {
	background: var(--chosen);
	transform: scale(1.1);
}
.wheel-solid {
	background: var(--wheel-layer);
	transform: scale(0.98);
	transition: transform 0.3s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.color-wheel.chosen .wheel-solid {
	transform: scale(0.9);
}
.wheel-picker {
	position: relative;
	width: calc(100% - 5px);
	height: calc(100% - 5px);
	border-radius: 50%;
}
.wheel-glow {
	position: absolute;
	top: 50%;
	left: 50%;
	width: 150px;
	height: 150px;
	border-radius: 50%;
	background: radial-gradient(circle, hsl(var(--hue) 90% 60% / 100%) 0%, hsl(var(--hue) 90% 60% / 0%) 66%);
	mix-blend-mode: color-burn;
	opacity: calc(0.15 + var(--near, 0) * 0.2);
	transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(calc(1 + var(--near, 0) * 0.2));
	transition: opacity 0.3s ease, transform 0.3s ease;
	pointer-events: none;
}
/* 패널의 버튼 규칙(.ink-group button: 네모, 30px)보다 앞서도록 .color-wheel 아래로 묶는다. */
.color-wheel .wheel-dot {
	position: absolute;
	top: 50%;
	left: 50%;
	display: block;
	width: 32px;
	height: 32px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	cursor: pointer;
	transform: translate(calc(-50% + var(--x) + var(--push-x, 0px)), calc(-50% + var(--y) + var(--push-y, 0px)));
	transition: transform 0.35s cubic-bezier(0.25, 1.2, 0.5, 1);
}
/* 가운데 검정: 어두운 바탕에서도 보이게 흰 테두리를 두른다. */
.color-wheel .wheel-dot.center {
	z-index: 1;
	box-shadow: 0 0 0 2px rgb(255 255 255 / 80%);
}

.wheel-dot::after {
	content: "";
	position: absolute;
	inset: 0;
	border: 2px solid #fff;
	border-radius: 50%;
	mix-blend-mode: overlay;
	opacity: 0;
	transition: opacity 0.13s;
}
.color-wheel .wheel-dot:hover {
	z-index: 2;
	transform: translate(calc(-50% + var(--x) + var(--push-x, 0px)), calc(-50% + var(--y) + var(--push-y, 0px))) scale(1.5);
	transition-duration: 0.13s;
}
.wheel-dot:hover::after,
.wheel-dot.on::after {
	opacity: 0.4;
}
.color-wheel .wheel-dot:active {
	transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(1.2);
}
/* 주석 도구 패널 안에서는 패널 폭에 맞춰 작게. */
.ink-panel .color-wheel {
	zoom: 0.68;
}
.ink-panel .ink-colors {
	grid-template-columns: 1fr;
	justify-items: center;
}
/* 원형 우클릭 메뉴: 누른 자리를 둘러싸고 둥근 아이콘이 스프링처럼 튀어나온다. 버튼은 아이콘만, 이름은 마우스를 올리면 뜬다. */
.radial-menu {
	position: absolute;
	z-index: 15;
	width: 0;
	height: 0;
}
.radial-item,
.radial-wheel {
	position: absolute;
	top: 0;
	left: 0;
	opacity: 0;
	transform: translate(var(--from-x, 0px), var(--from-y, 0px)) scale(0.3);
	transition: transform 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) var(--delay, 0s), opacity 0.2s ease var(--delay, 0s), background-color 0.15s, border-color 0.15s;
}
.radial-menu.open > .radial-item,
.radial-sub.open > .radial-item,
.radial-sub.open > .radial-wheel {
	opacity: 1;
	transform: translate(var(--x), var(--y)) scale(1);
}
.radial-item {
	display: grid;
	place-items: center;
	width: 48px;
	height: 48px;
	margin: -24px 0 0 -24px;
	padding: 0;
	border: 1px solid rgb(255 255 255 / 12%);
	border-radius: 50%;
	background: rgb(23 23 23 / 95%);
	color: #fff;
	box-shadow: 0 6px 18px rgb(0 0 0 / 35%);
	cursor: pointer;
}
.radial-item.small {
	width: 40px;
	height: 40px;
	margin: -20px 0 0 -20px;
}
.radial-item:hover {
	border-color: rgb(255 255 255 / 20%);
	background: rgb(38 38 38 / 98%);
}
/* 마우스를 올린(키보드로 옮겨 간) 버튼의 이름표: 버튼에서 8px 떨어져 원의 방향(--dx, --dy)으로 붙는다. 바로 뜨고 클릭을 막지 않는다. */
.radial-item:hover,
.radial-item:focus-visible {
	z-index: 1;
}
.radial-label {
	position: absolute;
	top: 50%;
	left: 50%;
	padding: 4px 8px;
	border-radius: 6px;
	background: rgb(15 23 42 / 92%);
	color: #fff;
	font-family: inherit;
	font-size: 12px;
	font-weight: 600;
	line-height: 1.3;
	white-space: nowrap;
	pointer-events: none;
	opacity: 0;
	transform: translate(calc(var(--lx) - 50% + var(--dx) * 50%), calc(var(--ly) - 50% + var(--dy) * 50%));
	transition: opacity 0.12s ease;
}
.radial-item:hover > .radial-label,
.radial-item:focus-visible > .radial-label {
	opacity: 1;
}
.radial-item.on {
	border-color: transparent;
	background: var(--accent-bright);
}
.radial-item svg {
	width: 24px;
	height: 24px;
}
.radial-item.small svg {
	width: 21px;
	height: 21px;
}
.radial-glyph {
	font-family: "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", Pretendard, sans-serif;
	font-weight: 700;
	line-height: 1;
}
.radial-swatch {
	width: 24px;
	height: 24px;
	border-radius: 50%;
	background: var(--swatch);
	box-shadow: inset 0 0 0 1.5px rgb(255 255 255 / 60%);
}
.radial-wheel {
	margin: -70px 0 0 -70px;
}
.radial-wheel.color-wheel {
	filter: drop-shadow(0 8px 20px rgb(0 0 0 / 40%));
}
/* 수업 창이 뜨기 전 로딩: 번개 모양 선이 그려지며 노랗게 채워지고, 2초마다 되돌아간다(Aceternity LoaderThree). */
.call-loading {
	position: fixed;
	inset: 0;
	z-index: 40;
	display: grid;
	place-items: center;
	background: var(--canvas);
}
/* 로딩 화면의 수업 정보(LMS 입장권): 번개 아래 수업 이름, 날짜·시간, 강사. */
.call-loading-body {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 18px;
	padding: 16px;
	text-align: center;
}
.call-loading-info {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
}
.call-loading-info[hidden] {
	display: none;
}
.call-loading-info strong {
	font-size: 20px;
}
.call-loading-info span {
	color: var(--muted);
	font-size: 14px;
}
.call-loading-info span:empty {
	display: none;
}
.call-loading svg {
	stroke: #737373;
}
.call-loading path {
	fill: #fafafa;
	stroke-dasharray: 1;
	stroke-dashoffset: 1;
	animation: loader-bolt 2s ease-in-out infinite alternate;
}
@keyframes loader-bolt {
	to {
		fill: #fde047;
		stroke-dashoffset: 0;
	}
}
.thumbs {
	display: flex;
	gap: 8px;
	min-height: 0;
	/* 선택 테두리의 빛이 스크롤 영역에 잘리지 않게 여백을 둔다. */
	padding: 4px 8px 8px;
	overflow-x: auto;
}
.thumbs .tile {
	flex: 0 0 176px;
	min-height: 0;
	border-radius: var(--radius-control);
}
.thumbs .tile-placeholder svg {
	width: 32px;
	height: 32px;
}
.thumbs .tile.selectable {
	cursor: pointer;
	transition: border-color var(--motion-fast);
}
.thumbs .tile.selectable:hover {
	border-color: var(--accent-bright);
}
/* 큰 화면에 올라가 있는 썸네일은 초록색으로 빛나는 테두리. */
.thumbs .tile.selected {
	border-color: var(--live);
	box-shadow: 0 0 0 2px var(--live), 0 0 10px 1px rgb(34 197 94 / 70%);
}
.main-stage {
	grid-row: 1;
	grid-column: 1;
	position: relative;
	min-height: 0;
	overflow: hidden;
	isolation: isolate;
	border: 1px solid var(--line);
	border-radius: var(--radius-surface);
	background: var(--video);
}
.main-stage .tile {
	position: absolute;
	inset: 0;
	min-height: 0;
	aspect-ratio: auto;
	border: 0;
	border-radius: 0;
}
.main-stage .tile video {
	object-fit: contain;
}
.main-stage .tile-placeholder svg {
	width: 72px;
	height: 72px;
}
.main-stage .tile-footer {
	inset: auto 68px 12px 14px;
	font-size: 14px;
}
.main-stage .tile-mic {
	width: 26px;
	height: 26px;
}
.main-stage .tile-mic svg {
	width: 15px;
	height: 15px;
}
/* 전체 화면은 수업 창 전체(큰 화면, 떠 있는 패널, 채팅)를 키운다. */
.call:fullscreen {
	padding: 0;
	background: var(--navy);
}
.call:fullscreen .main-stage {
	border: 0;
	border-radius: 0;
}
/* 큰 화면 오른쪽 아래의 전체 화면 버튼. 영상 위에 놓이므로 어두운 반투명 바탕을 쓴다. */
.main-stage .stage-action {
	position: absolute;
	right: 12px;
	bottom: 10px;
	z-index: 6;
	border-color: transparent;
	background: rgb(15 23 42 / 55%);
	color: #fff;
}
.main-stage .stage-action:hover {
	border-color: transparent;
	background: rgb(15 23 42 / 80%);
}
/* 수업 자료의 쪽 넘기기: 큰 화면 위쪽 가운데. */
/* 큰 화면 아래 가운데, 버튼 묶음 바로 위(자리는 placeMaterialBar가 bottom으로 정한다). */
.material-bar {
	position: absolute;
	bottom: 100px;
	left: 50%;
	z-index: 7;
	display: flex;
	align-items: center;
	gap: 4px;
	padding: 4px 6px;
	border-radius: 999px;
	background: rgb(15 23 42 / 78%);
	color: #fff;
	translate: -50% 0;
	box-shadow: 0 6px 18px rgb(0 0 0 / 30%);
}
.material-bar button {
	display: grid;
	place-items: center;
	width: 34px;
	height: 34px;
	padding: 0;
	border: 0;
	border-radius: 50%;
	background: transparent;
	color: #fff;
}
.material-bar button:hover:not(:disabled) {
	background: rgb(255 255 255 / 16%);
}
.material-bar button:disabled {
	opacity: 0.35;
}
.material-bar button svg {
	width: 20px;
	height: 20px;
}
.material-pages,
.material-video,
.material-zoom {
	display: flex;
	align-items: center;
	gap: 2px;
}
/* 파일 이름(확장자 없이). 길면 말줄임. */
.material-title {
	max-width: min(36vw, 320px);
	padding: 0 8px 0 10px;
	overflow: hidden;
	font-size: 14px;
	font-weight: 700;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.material-where {
	display: none;
	padding-right: 10px;
	color: rgb(255 255 255 / 75%);
	font-size: 13px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}
/* 다른 사람(강사)이 띄운 자료: 이름과 쪽만, 버튼은 없다. */
.material-bar.viewer {
	padding: 6px 4px;
}
.material-bar.viewer .material-where {
	display: inline;
}
.material-bar.viewer .material-pages,
.material-bar.viewer .material-video,
.material-bar.viewer .material-zoom,
.material-bar.viewer #material-close {
	display: none;
}
/* 접은 막대: 쪽 넘기기(영상이면 재생)만. 보는 사람은 쪽 번호만. */
.material-bar.folded .material-title,
.material-bar.folded .material-zoom,
.material-bar.folded #material-close {
	display: none;
}
.material-bar.viewer.folded .material-title {
	display: none;
}
.material-bar.viewer.folded .material-where {
	padding-left: 4px;
}
.material-pages[hidden],
.material-video[hidden] {
	display: none;
}
.material-zoom {
	padding-left: 4px;
	border-left: 1px solid rgb(255 255 255 / 22%);
}
.material-video input[type="range"] {
	width: clamp(90px, 22vw, 260px);
	accent-color: #facc15;
}
.material-time,
.material-zoom-label {
	min-width: 44px;
	font-size: 13px;
	font-weight: 700;
	text-align: center;
	font-variant-numeric: tabular-nums;
	white-space: nowrap;
}
.material-time {
	min-width: 84px;
}
/* 확대한 수업 자료를 끌어서 옮기는 중. */
.main-stage.panning {
	cursor: grabbing;
}
.material-page {
	min-width: 64px;
	font-size: 14px;
	font-weight: 700;
	text-align: center;
	font-variant-numeric: tabular-nums;
}
/* 주석 이름표 켜고 끄기: 전체 화면 버튼 왼쪽. 끄면 흐리게. */
.main-stage .stage-action.name-tags {
	right: 62px;
}
/* 꺼진 이름표: 카메라·마이크 꺼짐처럼 코랄 바탕에 흰 아이콘. */
.main-stage .stage-action.off,
.main-stage .stage-action.off:hover {
	border-color: transparent;
	background: var(--coral);
	color: #fff;
}
.stage-empty {
	position: absolute;
	inset: 0;
	display: grid;
	place-items: center;
	margin: 0;
	padding: 0 24px;
	color: rgb(255 255 255 / 60%);
	text-align: center;
	white-space: pre-line;
	line-height: 1.6;
}
.controls {
	position: relative;
	display: flex;
	flex-wrap: wrap;
	align-items: flex-end;
	justify-content: center;
	gap: 16px;
}
/* 어두운 패널 위의 버튼: 켜짐·꺼짐·활성 색은 그대로 두고 바탕만 어둡게 맞춘다. 아이들이 쓰므로 동글동글하게, 누를 수 있으면 살짝 떠오른다. */
.controls .icon-button {
	width: 40px;
	height: 40px;
	border-color: transparent;
	border-radius: 50%;
	background: #262626;
	color: #d4d4d4;
	transform: scale(var(--dock-scale, 1));
	transform-origin: 50% 100%;
	transition: background-color 0.15s ease;
}
.controls .icon-button svg,
.controls .icon-button .emoji {
	width: 20px;
	height: 20px;
	font-size: 20px;
	line-height: 1;
}
.controls .icon-button:active:not(:disabled) {
	filter: brightness(0.9);
}
/* 올린 버튼 위의 이름표. */
@media (hover: hover) {
	.controls .icon-button::after {
		content: attr(aria-label);
		position: absolute;
		bottom: calc(100% + 8px);
		left: 50%;
		padding: 2px 8px;
		border: 1px solid #171717;
		border-radius: 6px;
		background: #262626;
		color: #fff;
		font-size: 12px;
		font-weight: 500;
		line-height: 1.5;
		white-space: pre;
		opacity: 0;
		/* 버튼과 함께 커지지 않게 버튼 배율만큼 줄여 둔다. */
		transform: translate(-50%, 10px) scale(calc(1 / var(--dock-scale, 1)));
		transform-origin: 50% 100%;
		transition: opacity 0.15s ease, transform 0.15s ease;
		pointer-events: none;
	}
	.controls .icon-button:hover::after {
		opacity: 1;
		transform: translate(-50%, 0) scale(calc(1 / var(--dock-scale, 1)));
	}
}
/* 손을 든 동안의 손들기 버튼: 노란 바탕에서 손을 흔든다. */
.controls #hand.active {
	background: #facc15;
}
.controls #hand.active .emoji {
	display: inline-block;
	transform-origin: 50% 90%;
	animation: hand-wave 0.9s ease-in-out infinite;
}
.controls .icon-button:hover {
	border-color: transparent;
	background: #333;
	color: #fff;
}
.controls .icon-button.off,
.controls .icon-button.recording {
	background: var(--coral);
	color: #fff;
}
/* 선생님이 끈 학생 마이크: 잠금 표시, 선생님이 풀기 전에는 켤 수 없다. */
.controls .icon-button.locked {
	position: relative;
	cursor: not-allowed;
}
/* 자물쇠는 작은 흰 원 안 가운데에, 버튼 오른쪽 아래에 걸친다(대표님 11/6 "자물쇠 표시 센터정렬 안맞음"). */
.controls .icon-button.locked::after {
	content: "🔒";
	position: absolute;
	right: -4px;
	bottom: -4px;
	display: grid;
	place-items: center;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: #fff;
	box-shadow: 0 1px 3px rgb(0 0 0 / 35%);
	font-size: 10px;
	line-height: 18px;
	text-align: center;
}
.controls .icon-button.active,
.controls .icon-button[aria-expanded="true"] {
	background: var(--accent-bright);
	color: #fff;
}
.controls .icon-button.danger {
	background: var(--danger);
	color: #fff;
}
/* 독 버튼 위의 작은 창: 마이크·스피커 음량, 배경 효과 고르기.
   마우스는 버튼에 올리면(마이크·스피커는 켜져 있을 때만, data-pop) 뜨고, 손가락으로 누르면 열린다(open). */
.dock-item {
	position: relative;
	display: flex;
}
.dock-pop {
	position: absolute;
	left: 50%;
	/* 커진 버튼(최대 1.6배)과 그 이름표 위에 뜬다. */
	bottom: calc(100% + 34px);
	z-index: 12;
	display: none;
	flex-direction: column;
	align-items: stretch;
	gap: 8px;
	padding: 10px 12px;
	border: 1px solid rgb(255 255 255 / 10%);
	border-radius: 14px;
	background: #262626;
	color: #fff;
	box-shadow: 0 12px 30px rgb(0 0 0 / 35%);
	transform: translateX(-50%);
	white-space: nowrap;
}
/* 버튼에서 창으로 마우스를 옮기는 동안 사이의 빈 곳에서도 창이 닫히지 않게 한다. */
.dock-pop::after {
	content: "";
	position: absolute;
	left: 0;
	right: 0;
	top: 100%;
	height: 36px;
}
@media (hover: hover) {
	.dock-item[data-pop]:hover > .dock-pop {
		display: flex;
	}
	/* 창이 뜨면 버튼 이름표는 감춘다(같은 자리에 겹친다). */
	.dock-item[data-pop]:hover > .icon-button::after {
		display: none;
	}
}
.dock-item.open > .dock-pop {
	display: flex;
}
/* PC의 파일 고르는 창이 떠 있는 동안은 마우스가 버튼 위에 있어도 메뉴를 감춘다. */
.dock-item.picking > .dock-pop {
	display: none !important;
}
.dock-item.open > .icon-button::after {
	display: none;
}
/* 켜기/끄기는 손가락으로 연 창에만(마우스는 버튼을 누르면 된다). */
.dock-switch {
	display: none;
	align-items: center;
	justify-content: center;
	gap: 6px;
	min-height: 36px;
	padding: 0 12px;
	border: 0;
	border-radius: 999px;
	background: #333;
	color: #fff;
	font-size: 13px;
	font-weight: 700;
}
.dock-switch svg {
	width: 18px;
	height: 18px;
}
.dock-item.open .dock-switch {
	display: flex;
}
.dock-volume {
	display: grid;
	grid-template-columns: auto 120px 44px;
	align-items: center;
	gap: 8px;
	font-size: 12px;
	font-weight: 600;
}
.dock-volume-name {
	color: rgb(255 255 255 / 70%);
}
.dock-volume input[type="range"] {
	width: 120px;
	accent-color: var(--accent-bright);
}
.dock-volume > span:last-child {
	font-variant-numeric: tabular-nums;
	text-align: right;
}
/* 수업 자료 고르기: PC에서 불러오기, 그리고 등록된 수업 자료 목록. */
.material-menu {
	width: 260px;
	gap: 4px;
	padding: 8px;
	white-space: normal;
}
.material-choice,
.dock-action {
	display: flex;
	align-items: center;
	gap: 10px;
	width: 100%;
	min-height: 38px;
	padding: 6px 10px;
	border: 0;
	border-radius: 8px;
	background: transparent;
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	text-align: left;
}
.material-choice:hover:not(:disabled),
.dock-action:hover:not(:disabled) {
	background: rgb(255 255 255 / 10%);
}
.material-choice svg,
.dock-action svg {
	flex: none;
	width: 18px;
	height: 18px;
	color: rgb(255 255 255 / 70%);
}
.material-choice span {
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.material-menu-title {
	margin: 6px 10px 2px;
	padding-top: 8px;
	border-top: 1px solid rgb(255 255 255 / 12%);
	color: rgb(255 255 255 / 55%);
	font-size: 11px;
	font-weight: 700;
}
.material-library {
	display: grid;
	gap: 2px;
	max-height: 240px;
	overflow-y: auto;
}
.material-library-note {
	margin: 4px 10px 6px;
	color: rgb(255 255 255 / 55%);
	font-size: 12px;
}
/* 펜 스타일(기본·붓·연필·파선·점선): 그 스타일로 그은 짧은 선. */
.ink-style-sample {
	display: block;
	width: 24px;
	height: 14px;
}
.radial-item .ink-style-sample {
	width: 26px;
	height: 15px;
}
.ink-group.ink-dashes {
	grid-template-columns: repeat(3, 1fr);
}
/* 배경 효과: 끄기·흐리게·이미지 세 버튼을 가로로. 아이콘 아래에 이름. */
.dock-choices {
	flex-direction: row;
	gap: 6px;
	padding: 6px;
	border-radius: 16px;
}
.dock-choices button {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 3px;
	width: 60px;
	height: 56px;
	padding: 0;
	border: 0;
	border-radius: 12px;
	background: #333;
	color: #d4d4d4;
	font-size: 11px;
	font-weight: 600;
}
.dock-choices button:hover:not(:disabled) {
	background: #404040;
	color: #fff;
}
.dock-choices button.on {
	background: var(--accent-bright);
	color: #fff;
}
.dock-choices button svg {
	width: 20px;
	height: 20px;
}
.icon-button {
	position: relative;
	display: inline-grid;
	place-items: center;
	flex: none;
	width: var(--control-h-lg);
	height: var(--control-h-lg);
	padding: 0;
	color: #374151;
}
.icon-button svg {
	width: 20px;
	height: 20px;
}
.icon-button.small {
	width: var(--control-h-sm);
	height: var(--control-h-sm);
	border-color: transparent;
	background: transparent;
	color: var(--muted);
}
.icon-button.small:hover {
	border-color: transparent;
	background: var(--canvas);
	color: var(--ink);
}
.icon-button.small svg {
	width: 18px;
	height: 18px;
}
/* 꺼진 카메라·마이크는 코랄 계열 경고색, 켜진 화면 공유·배경 효과는 청록 활성색. */
.icon-button.off {
	border-color: #f2c7b6;
	background: var(--danger-soft);
	color: var(--danger);
}
.icon-button.recording {
	border-color: var(--coral);
	background: var(--coral);
	color: #fff;
}
.icon-button.active,
.icon-button[aria-expanded="true"] {
	border-color: var(--accent-soft);
	background: var(--accent-soft);
	color: var(--accent);
}
/* 채팅을 접어 둔 동안 새 채팅이 오면 펼치기 버튼에 점(숫자 없음)을 단다. */
.icon-button.unread::after {
	content: "";
	position: absolute;
	top: -3px;
	right: -3px;
	width: 13px;
	height: 13px;
	border: 2px solid var(--surface);
	border-radius: 50%;
	background: var(--coral);
	animation: unread-pop 0.3s ease-out;
}
@keyframes unread-pop {
	from {
		transform: scale(0);
	}
}
.chat-panel {
	grid-row: 1;
	grid-column: 2;
	z-index: 5;
	display: grid;
	grid-template-rows: auto minmax(0, 1fr) auto;
	min-height: 0;
	overflow: hidden;
	border: 1px solid var(--line);
	border-radius: var(--radius-surface);
	background: rgb(255 255 255 / 86%);
	backdrop-filter: blur(10px);
}
.chat-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 8px 8px 8px 14px;
	border-bottom: 1px solid var(--line);
}
.chat-panel h2 {
	margin: 0;
	font-size: 14px;
}
.chat {
	display: flex;
	flex-direction: column;
	gap: 10px;
	min-height: 0;
	overflow-y: auto;
	padding: 14px;
	background: rgb(244 246 249 / 70%);
}
.message {
	align-self: flex-start;
	max-width: 86%;
	padding: 8px 12px;
	border-radius: 12px 12px 12px 2px;
	background: var(--surface);
	font-size: 13px;
	line-height: 1.5;
	overflow-wrap: anywhere;
}
.message small {
	display: block;
	margin-bottom: 2px;
	color: var(--muted);
	font-size: 11px;
}
.message.me {
	align-self: flex-end;
	border-radius: 12px 12px 2px 12px;
	background: var(--navy);
	color: #fff;
}
.message.me small {
	color: rgb(255 255 255 / 70%);
}
.message.me a {
	color: #fff;
}
.composer {
	display: flex;
	align-items: center;
	gap: 4px;
	padding: 10px 12px;
	border-top: 1px solid var(--line);
	background: var(--surface);
}
.composer input {
	flex: 1;
	min-width: 0;
	margin: 0 4px;
	border: 0;
	background: var(--canvas);
}
.composer .icon-button.small {
	width: var(--control-h);
	height: var(--control-h);
}
/* 채팅창을 접었을 때 큰 화면 오른쪽 위에 남는 펼치기 버튼. */
.call-notice {
	position: absolute;
	inset: 0;
	z-index: 20;
	display: grid;
	place-items: center;
	padding: 16px;
	background: rgb(20 24 34 / 45%);
}
.dialog {
	width: min(420px, 100%);
	padding: 22px;
	border-radius: var(--radius-surface);
	background: var(--surface);
	box-shadow: 0 24px 60px rgb(15 23 42 / 20%);
	text-align: center;
}
.dialog p {
	margin: 0 0 16px;
	font-size: 15px;
	font-weight: 600;
}
.dialog .row {
	justify-content: center;
}
/* 확인 창: 아이콘, 제목, 설명, 나란한 두 버튼. 지우기·내보내기처럼 되돌리기 어려운 것은 코랄 버튼. */
.confirm-dialog {
	z-index: 40;
	background: rgb(15 23 42 / 55%);
	backdrop-filter: blur(3px);
	animation: confirm-fade 0.16s ease-out;
}
.confirm-card {
	width: min(360px, 100%);
	padding: 26px 24px 20px;
	border-radius: 20px;
	box-shadow: 0 30px 80px rgb(15 23 42 / 35%);
	animation: confirm-pop 0.2s cubic-bezier(0.34, 1.4, 0.64, 1);
}
.confirm-icon {
	display: grid;
	place-items: center;
	width: 52px;
	height: 52px;
	margin: 0 auto 14px;
	border-radius: 50%;
	background: var(--accent-soft);
	color: var(--accent);
}
.confirm-icon:empty {
	display: none;
}
.confirm-icon svg {
	width: 26px;
	height: 26px;
}
.confirm-dialog.danger .confirm-icon {
	background: var(--danger-soft);
	color: var(--danger);
}
.confirm-title {
	margin: 0 0 8px;
	font-size: 18px;
	font-weight: 800;
}
.confirm-card .confirm-text {
	margin: 0 0 22px;
	color: var(--muted);
	font-size: 14px;
	font-weight: 500;
	line-height: 1.6;
}
.confirm-buttons {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: 10px;
}
.confirm-buttons button {
	min-height: 44px;
	border-radius: 12px;
	font-size: 15px;
	font-weight: 700;
}
/* 옐로카드 주기: 큰 카드 아이콘, 사유 버튼들, 사유 칸. */
.card-icon {
	background: #fef9c3;
}
.card-icon .yellow-card {
	width: 22px;
	height: 29px;
	border-radius: 4px;
	border-width: 3px;
}
.card-reasons {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 6px;
	margin-bottom: 10px;
}
.card-reasons button {
	min-height: 32px;
	padding: 0 12px;
	border-radius: 16px;
	font-size: 13px;
	font-weight: 600;
}
.card-reason {
	width: 100%;
	min-height: 40px;
	margin-bottom: 18px;
	padding: 0 12px;
	border: 1px solid var(--line);
	border-radius: 10px;
	font: inherit;
	font-size: 14px;
}
/* 출석부의 초대 링크 손님: 이름 아래 작은 줄(링크로 들어옴 · 학생 연결, 또는 → 연결된 학생 · 연결 해제). */
.roster-guest {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px;
	margin-top: 2px;
	color: var(--muted);
	font-size: 12px;
}
.roster-guest button {
	min-height: 24px;
	padding: 0 8px;
	font-size: 12px;
}
.link-students {
	max-height: 50vh;
	overflow-y: auto;
}
.confirm-dialog.danger #confirm-ok {
	border-color: var(--coral);
	background: var(--coral);
	color: #fff;
}
@keyframes confirm-fade {
	from { opacity: 0; }
}
@keyframes confirm-pop {
	from { opacity: 0; transform: translateY(8px) scale(0.96); }
}

/* 녹화 서버가 여는 화면(/record): 학생이 보는 배치에서 상단 바·버튼·채팅·알림을 뺀다. */
.record-mode,
.record-mode .shell {
	background: var(--navy);
}
.record-mode .topbar,
.record-mode .controls,
.record-mode .chat-panel,
.record-mode .stage-action,
.record-mode .tile-actions,
.record-mode .toast,
.record-mode .call-notice {
	display: none !important;
}
.record-mode .call {
	padding: 0;
	gap: 0;
}
.record-mode .main-stage {
	border: 0;
	border-radius: 0;
}
.record-mode .material-bar,
.record-mode .controls-panel,
.record-mode .roster-panel,
.record-mode .ink-panel,
.record-mode .float-bar {
	display: none !important;
}
/* 녹화 화면의 참가자 썸네일: 수업 화면처럼 오른쪽 위에 이름과 함께 둔다(큰 화면에 올라간 사람과 화면 공유 타일은 뺀다). */
.record-mode .thumbs-panel {
	top: 16px;
	right: 16px;
	left: auto;
	bottom: auto;
	z-index: 6;
	transform: none;
}
.record-mode .thumbs .tile.selected,
.record-mode .thumbs .tile.screen {
	display: none;
}
/* 녹화에는 스크롤이 없으니 전원이 보이게 여러 줄로 놓고, 사람이 많을수록 썸네일을 작게 한다(대표님 11/5: 가로 스크롤이라 다 안 보였다). */
.record-mode .thumbs-panel {
	max-width: 48%;
}
.record-mode .thumbs {
	--thumb: 168px;
	flex-wrap: wrap;
	justify-content: flex-end;
	overflow: visible;
}
.record-mode .thumbs:has(> .tile:nth-child(7)) {
	--thumb: 140px;
}
.record-mode .thumbs:has(> .tile:nth-child(10)) {
	--thumb: 124px;
}
.record-mode .thumbs:has(> .tile:nth-child(16)) {
	--thumb: 100px;
}
.record-mode .thumbs:has(> .tile:nth-child(25)) {
	--thumb: 84px;
}
.record-mode .thumbs .tile {
	flex: 0 0 var(--thumb);
}
/* 브라우저 수업 창에는 위쪽 막대가 없다(Windows 앱은 창을 옮기고 닫는 막대로만 둔다). 안내는 알림으로 뜬다. */
html:not(.desktop-app) .call-mode .topbar {
	display: none;
}
.call-mode .topbar #connection {
	display: none;
}
/* 큰 화면 왼쪽 위: 강사에게만 녹화 중 아이콘(빨간 점), 녹화가 꺼져 있으면 녹화 시작 버튼. */
.call-status {
	position: absolute;
	top: 24px;
	left: 30px;
	z-index: 9;
	display: flex;
	align-items: center;
	gap: 8px;
}
.call-status .status {
	color: #fff;
}
/* 강사의 인터넷이 불안정할 때의 안내: 큰 화면 왼쪽 위, 녹화 표시 아래. */
.net-warning {
	position: absolute;
	top: 68px;
	left: 30px;
	z-index: 9;
	display: flex;
	align-items: center;
	gap: 10px;
	max-width: calc(100% - var(--chat-width) - 60px);
	padding: 10px 12px;
	border-radius: var(--radius-control);
	background: #fef3c7;
	color: #78350f;
	box-shadow: 0 8px 24px rgb(0 0 0 / 30%);
	font-size: 13px;
	line-height: 1.5;
}
.net-warning p {
	margin: 0;
	font-weight: 700;
}
.net-warning button {
	flex: none;
	padding: 4px 10px;
	border: 0;
	border-radius: 999px;
	background: #78350f;
	color: #fff;
	font-size: 12px;
}
.record-mode .net-warning {
	display: none !important;
}
/* 선생님의 인터넷·PC 사용량: 큰 화면 왼쪽 아래, 이름표 위에 작게. 누를 수 없다. */
.pc-stats {
	position: absolute;
	left: 30px;
	bottom: 48px;
	z-index: 9;
	padding: 4px 8px;
	border-radius: 6px;
	background: rgb(15 23 42 / 62%);
	color: rgb(255 255 255 / 88%);
	font-size: 11px;
	line-height: 1.5;
	font-variant-numeric: tabular-nums;
	white-space: pre;
	cursor: grab;
	touch-action: none;
	user-select: none;
}
.pc-stats.moved {
	bottom: auto;
}
.pc-stats.dragging {
	cursor: grabbing;
}
.pc-stats[hidden],
.record-mode .pc-stats {
	display: none;
}
.class-recording {
	display: grid;
	place-items: center;
	width: 26px;
	height: 26px;
	border-radius: 50%;
	background: rgb(15 23 42 / 70%);
}
.class-recording::before {
	content: "";
	width: 10px;
	height: 10px;
	border-radius: 50%;
	background: var(--coral);
	animation: recording-blink 1.6s ease-in-out infinite;
}
@keyframes recording-blink {
	50% {
		opacity: 0.35;
	}
}
/* 강사 화면 그대로 녹화 표시. 꺼져 있으면 눈에 띄게 하고 눌러서 켠다. */
.window-recording {
	height: auto;
	padding: 2px 10px;
	border-color: transparent;
	border-radius: 999px;
	background: transparent;
	color: var(--coral);
	font-size: 12px;
	font-weight: 700;
}
.window-recording:disabled {
	opacity: 1;
	cursor: default;
}
.window-recording.off {
	border-color: var(--coral);
	background: var(--coral);
	color: #fff;
}
/* ---------- 수업 도구: 타일 표시, 학생 관리 메뉴, 주석, 트로피, 태그, 알림 ---------- */
/* 타일 왼쪽 위 표시: 손들기, 트로피 수, 펜 권한, 채팅 금지, 수업 창 이탈. */
.tile-badges {
	position: absolute;
	top: 6px;
	left: 6px;
	z-index: 4;
	display: flex;
	gap: 4px;
}
.tile-badge {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	height: 20px;
	padding: 0 5px;
	border-radius: 10px;
	background: rgb(15 23 42 / 62%);
	color: #fff;
	font-size: 11px;
	font-weight: 700;
	font-variant-numeric: tabular-nums;
}
.tile-badge svg {
	width: 12px;
	height: 12px;
}
.tile-badge.pen {
	background: var(--accent-bright);
}
.tile-badge.away {
	background: var(--coral);
}
/* 큰 화면 왼쪽 위에는 녹화 중 아이콘이 있으므로 그 아래에 둔다(겹쳐서 아이콘이 안 보였다). */
.main-stage .tile-badges {
	top: 60px;
	left: 14px;
}
.main-stage .tile-badge {
	height: 26px;
	padding: 0 8px;
	border-radius: 13px;
	font-size: 13px;
}
.main-stage .tile-badge svg {
	width: 15px;
	height: 15px;
}
/* 아이들이 보는 표시(손들기, 트로피, 축하)는 이모지로 그린다. 기기마다 이모지 모양은 조금씩 다르다. */
.emoji {
	font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif;
	font-weight: 400;
	line-height: 1;
}
.icon-button .emoji {
	font-size: 21px;
}
/* 손들기: 타일 한가운데에서 크게 흔드는 손. 10초 뒤 저절로 내려가고, 강사는 눌러서 먼저 내려 줄 수 있다. */
.tile-hand {
	position: absolute;
	top: 50%;
	left: 50%;
	z-index: 5;
	display: grid;
	place-items: center;
	width: clamp(56px, 42cqi, 200px);
	aspect-ratio: 1;
	height: auto;
	padding: 0;
	border: clamp(3px, 1.6cqi, 6px) solid #facc15;
	border-radius: 50%;
	background: rgb(255 251 235 / 92%);
	box-shadow: 0 0 0 0 rgb(250 204 21 / 60%), 0 6px 18px rgb(0 0 0 / 35%);
	translate: -50% -50%;
	animation: hand-ring 1.4s ease-out infinite;
}
.tile-hand:hover {
	border-color: #f59e0b;
	background: #fef3c7;
}
.tile-hand .emoji {
	display: inline-block;
	font-size: clamp(30px, 24cqi, 120px);
	transform-origin: 50% 90%;
	animation: hand-wave 0.9s ease-in-out infinite;
}
@keyframes hand-wave {
	0%, 100% { transform: rotate(-16deg); }
	50% { transform: rotate(16deg) scale(1.08); }
}
/* 손 둘레로 노란 고리가 퍼져 나간다. */
@keyframes hand-ring {
	0% { box-shadow: 0 0 0 0 rgb(250 204 21 / 60%), 0 6px 18px rgb(0 0 0 / 35%); }
	100% { box-shadow: 0 0 0 clamp(10px, 8cqi, 36px) rgb(250 204 21 / 0%), 0 6px 18px rgb(0 0 0 / 35%); }
}
/* 수업 창을 벗어난 학생의 썸네일(강사·관리자 화면): 노란 테두리가 숨 쉬고 옐로카드가 계속 흔들린다. 학생이 돌아와
   경고의 닫기를 누르면 사라진다. 경고가 쌓인 순간의 카드 효과(아래 card-pop)가 끝날 즈음 나타난다. */
.tile-away {
	position: absolute;
	inset: 0;
	z-index: 3;
	display: grid;
	place-items: center;
	border-radius: inherit;
	background: rgb(250 204 21 / 12%);
	pointer-events: none;
	container-type: size;
	animation: tile-away-in 0.3s both, tile-away-glow 1s ease-in-out infinite alternate;
}
.tile-away-card {
	width: clamp(22px, 18cqi, 90px);
	aspect-ratio: 3 / 4;
	border-radius: 18% / 14%;
	border-width: clamp(2px, 1.6cqi, 8px);
	box-shadow: 0 0 0 1px rgb(0 0 0 / 12%), 0 8px 20px rgb(0 0 0 / 45%);
	transform-origin: 50% 100%;
	animation: tile-away-swing 0.9s ease-in-out infinite alternate;
}
@keyframes tile-away-in {
	from { opacity: 0; }
}
@keyframes tile-away-glow {
	from { box-shadow: inset 0 0 0 2px rgb(250 204 21 / 50%); }
	to { box-shadow: inset 0 0 0 5px #facc15; }
}
@keyframes tile-away-swing {
	from { transform: rotate(-14deg); }
	to { transform: rotate(10deg) scale(1.06); }
}
/* 이탈 경고가 쌓인 순간 타일에 내려오는 큰 옐로카드(트로피 효과와 같은 틀). */
.tile-pop.card-pop {
	animation: trophy-pop 2.4s ease-out both;
}
.pop-card {
	grid-area: 1 / 1;
	width: clamp(26px, 15cqi, 100px);
	aspect-ratio: 3 / 4;
	border-radius: 18% / 14%;
	border-width: clamp(3px, 1.6cqi, 9px);
	box-shadow: 0 0 0 1px rgb(0 0 0 / 12%), 0 10px 24px rgb(0 0 0 / 40%);
	animation: card-drop 1.2s cubic-bezier(0.34, 1.5, 0.64, 1) both;
}
/* 강사·관리자 화면의 옐로카드: 썸네일 밖에서 날아와 그 학생 썸네일 가운데에 내려앉는다(flyCardToTile). 썸네일에 잘리지 않게 화면 위에
   띄우고, 썸네일에서 흔들리는 카드와 같은 크기·모양·회전축이다. */
.flying-card {
	position: fixed;
	z-index: 60;
	aspect-ratio: auto;
	border-radius: 18% / 14%;
	box-shadow: 0 0 0 1px rgb(0 0 0 / 12%), 0 8px 20px rgb(0 0 0 / 45%);
	transform-origin: 50% 100%;
	pointer-events: none;
	animation: none;
}
/* 내려오는 동안과 선생님이 준 카드가 흔들리는 동안: 이탈 때와 같은 노란 테두리. */
.tile.card-incoming,
.tile.carded {
	animation: tile-away-glow 1s ease-in-out infinite alternate;
}
.tile.card-incoming .tile-away-card {
	visibility: hidden;
}
/* 선생님의 인사 손: 큰 화면에서는 가운데를 가리지 않게 왼쪽 위 귀퉁이에 작게. */
.tile-hand.corner {
	top: 12px;
	left: 12px;
	width: clamp(44px, 8cqi, 72px);
	translate: 0 0;
}
.tile-hand.corner .emoji {
	font-size: clamp(24px, 4.5cqi, 44px);
}
@keyframes card-drop {
	0% { transform: translateY(-60cqi) rotate(-35deg) scale(0.6); }
	55% { transform: translateY(0) rotate(10deg) scale(1.08); }
	70% { transform: rotate(-8deg); }
	85% { transform: rotate(5deg); }
	100% { transform: rotate(-6deg); }
}
/* 이탈이 세어진 학생에게: 화면 가운데의 큰 노란 경고(돌아와서 닫기를 누를 때까지 계속 흔들리고 카드가 펄럭인다). */
.away-warning {
	position: absolute;
	top: 38%;
	left: 50%;
	z-index: 35;
	display: flex;
	align-items: center;
	gap: 18px;
	/* left: 50% leaves only half the stage for an automatic width, which squeezed the text to a letter per line on phones. */
	width: max-content;
	max-width: calc(100% - 32px);
	padding: 18px 26px 18px 20px;
	border: 3px solid #facc15;
	border-radius: 20px;
	background: #1f2937;
	color: #fff;
	box-shadow: 0 0 0 6px rgb(250 204 21 / 25%), 0 24px 60px rgb(0 0 0 / 45%);
	transform: translate(-50%, -50%);
	animation: away-pop 0.5s cubic-bezier(0.34, 1.6, 0.64, 1) both, away-nag 2s 0.5s ease-in-out infinite, away-glow 1s ease-in-out infinite alternate;
}
.away-card {
	flex: none;
	width: 46px;
	height: 62px;
	border-radius: 18% / 14%;
	border-width: 4px;
	box-shadow: 0 0 0 1px rgb(0 0 0 / 12%), 0 8px 18px rgb(0 0 0 / 40%);
	transform: rotate(-10deg);
	animation: away-card-wave 0.8s ease-in-out infinite alternate;
}
.away-close {
	flex: none;
	padding: 10px 20px;
	border: 0;
	border-radius: 12px;
	background: #facc15;
	color: #1f2937;
	font-size: 16px;
	font-weight: 800;
	cursor: pointer;
}
.away-close:hover {
	background: #fde047;
}
/* 강사가 파일을 끌어오는 동안: 놓으면 수업 자료로 띄운다는 안내(수업 창 전체). */
.drop-hint {
	position: fixed;
	inset: 12px;
	z-index: 60;
	display: grid;
	place-items: center;
	border: 3px dashed var(--accent-bright);
	border-radius: var(--radius-surface);
	background: rgb(11 15 25 / 72%);
	color: #fff;
	font-size: 20px;
	font-weight: 700;
	pointer-events: none;
}
.away-text {
	display: grid;
	gap: 4px;
	min-width: 0;
}
/* 휴대폰: 카드와 닫기를 글 아래로 내려 글이 한 줄 폭을 다 쓰게 한다. */
@media (max-width: 560px) {
	.away-warning {
		flex-wrap: wrap;
		justify-content: center;
		gap: 12px 16px;
		padding: 16px;
		text-align: center;
	}
	.away-text {
		flex: 1 1 100%;
		order: -1;
	}
	.away-text strong {
		font-size: 20px;
	}
}
.away-text strong {
	color: #fde047;
	font-size: 22px;
	font-weight: 800;
}
.away-text span {
	color: rgb(255 255 255 / 85%);
	font-size: 14px;
	font-weight: 600;
}
@keyframes away-pop {
	from { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
}
@keyframes away-nag {
	0%, 30%, 100% { transform: translate(-50%, -50%) rotate(0); }
	7.5%, 22.5% { transform: translate(-50%, -50%) rotate(-3deg); }
	15% { transform: translate(-50%, -50%) rotate(3deg); }
}
@keyframes away-glow {
	to { box-shadow: 0 0 0 12px rgb(250 204 21 / 40%), 0 24px 60px rgb(0 0 0 / 45%); }
}
@keyframes away-card-wave {
	from { transform: rotate(-14deg) scale(1); }
	to { transform: rotate(6deg) scale(1.08); }
}
/* 선생님이 수업을 끝낼 때 학생 화면 가운데: 남은 초와 안내. */
.class-ending {
	position: absolute;
	top: 38%;
	left: 50%;
	z-index: 36;
	display: flex;
	align-items: center;
	gap: 18px;
	max-width: calc(100% - 32px);
	padding: 18px 26px 18px 20px;
	border: 3px solid var(--coral);
	border-radius: 20px;
	background: #1f2937;
	color: #fff;
	box-shadow: 0 0 0 6px color-mix(in srgb, var(--coral) 25%, transparent), 0 24px 60px rgb(0 0 0 / 45%);
	transform: translate(-50%, -50%);
	animation: away-pop 0.5s cubic-bezier(0.34, 1.6, 0.64, 1) both;
}
.class-ending-count {
	flex: none;
	display: grid;
	place-items: center;
	width: 58px;
	height: 58px;
	border-radius: 50%;
	background: var(--coral);
	color: #fff;
	font-size: 28px;
	font-weight: 800;
	font-variant-numeric: tabular-nums;
}
.class-ending-text {
	display: grid;
	gap: 4px;
}
.class-ending-text strong {
	font-size: 22px;
	font-weight: 800;
}
.class-ending-text span {
	color: rgb(255 255 255 / 85%);
	font-size: 14px;
	font-weight: 600;
}
/* 손을 든 순간 퍼지는 반짝이(트로피 효과와 같은 모양, 손은 위의 큰 손이 맡는다). */
.tile-pop.hand-pop {
	animation: none;
}
/* 화면 공유 요청(강사): 아래 버튼 묶음 바로 위 가운데에 학생마다 한 줄(위쪽은 참가자 묶음이 있다). */
.share-requests {
	position: absolute;
	bottom: 110px;
	left: 50%;
	z-index: 21;
	display: grid;
	gap: 8px;
	transform: translateX(-50%);
}
.share-request {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 8px 8px 8px 16px;
	border-radius: 999px;
	background: var(--navy);
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	white-space: nowrap;
	box-shadow: 0 12px 32px rgb(15 23 42 / 30%);
}
.share-request button {
	min-height: 32px;
	padding: 0 14px;
	border-radius: 999px;
	font-size: 13px;
}
/* 학원이 선생님에게만 보낸 메시지: 오른쪽 아래(채팅 왼쪽)에 작은 카드로, 확인을 누를 때까지. */
.whispers {
	position: absolute;
	right: calc(var(--chat-width) + 16px);
	bottom: 110px;
	z-index: 21;
	display: grid;
	gap: 8px;
	width: min(320px, calc(100% - var(--chat-width) - 32px));
}
.whisper {
	display: grid;
	gap: 6px;
	padding: 12px 14px;
	border-radius: 14px;
	background: var(--navy);
	color: #fff;
	box-shadow: 0 12px 32px rgb(15 23 42 / 30%);
	animation: whisper-in 0.25s ease-out both;
}
.whisper-head {
	display: flex;
	align-items: baseline;
	gap: 8px;
	min-width: 0;
	font-size: 12px;
}
.whisper-head strong {
	overflow: hidden;
	color: #fde047;
	font-weight: 700;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.whisper-head span {
	flex: none;
	color: rgb(255 255 255 / 60%);
}
.whisper-text {
	margin: 0;
	font-size: 14px;
	line-height: 1.45;
	overflow-wrap: anywhere;
	white-space: pre-wrap;
}
.whisper-close {
	justify-self: end;
	min-height: 30px;
	padding: 0 14px;
	border: 0;
	border-radius: 999px;
	background: rgb(255 255 255 / 14%);
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	cursor: pointer;
}
.whisper-close:hover {
	background: rgb(255 255 255 / 24%);
}
@keyframes whisper-in {
	from { opacity: 0; transform: translateY(8px); }
}
/* 화면 공유를 요청해 둔 학생의 버튼: 노랗게. */
.controls .icon-button.asking {
	background: #facc15;
	color: #1f2937;
}
/* 내 카메라는 거울처럼 보인다(내 화면에서만). */
.mirror-self video.self-camera {
	transform: scaleX(-1);
}
/* 참가자의 인터넷 연결 막대(오른쪽 위). 바탕 없이 막대 색으로만(대표님 11/5), 나빠질수록 칸도 줄고 색도 바뀐다: 좋음 초록 4칸,
   보통 노랑 3칸, 불안정 주황 2칸, 끊김 빨강 1칸. 밝은 영상 위에서도 보이게 막대에 옅은 그림자. 큰 화면에는 없다. */
.tile-signal {
	--signal: #22c55e;
	position: absolute;
	top: 7px;
	right: 8px;
	z-index: 4;
	display: inline-flex;
	align-items: flex-end;
	gap: 2px;
	height: 14px;
	filter: drop-shadow(0 0 1px rgb(0 0 0 / 70%));
}
.tile-signal i {
	width: 3px;
	border-radius: 1px;
	background: var(--signal);
}
.tile-signal i:nth-child(1) {
	height: 25%;
}
.tile-signal i:nth-child(2) {
	height: 50%;
}
.tile-signal i:nth-child(3) {
	height: 75%;
}
.tile-signal i:nth-child(4) {
	height: 100%;
}
.tile-signal[data-bars="3"] {
	--signal: #facc15;
}
.tile-signal[data-bars="2"] {
	--signal: #f97316;
}
.tile-signal[data-bars="1"] {
	--signal: #ef4444;
}
.tile-signal[data-bars="3"] i:nth-child(n + 4),
.tile-signal[data-bars="2"] i:nth-child(n + 3),
.tile-signal[data-bars="1"] i:nth-child(n + 2) {
	background: rgb(255 255 255 / 45%);
}
.main-stage .tile-signal {
	display: none !important;
}
/* 터치 화면에서는 내 타일의 좌우 반전 버튼이 늘 오른쪽 위에 있으므로 그 왼쪽에. */
@media (hover: none) {
	.tile:has(.tile-flip) .tile-signal {
		right: 36px;
	}
}
/* 내 카메라 타일의 좌우 반전 버튼: 마우스를 올리면 오른쪽 위에. */
.tile-flip {
	position: absolute;
	top: 4px;
	right: 4px;
	z-index: 5;
	display: none;
	place-items: center;
	width: 26px;
	height: 26px;
	padding: 0;
	border: 0;
	border-radius: 6px;
	background: rgb(15 23 42 / 78%);
	color: #fff;
}
.tile:hover .tile-flip,
.tile:focus-within .tile-flip {
	display: grid;
}
@media (hover: none) {
	.tile-flip {
		display: grid;
	}
}
.tile-flip svg {
	width: 15px;
	height: 15px;
}
.record-mode .tile-flip,
.main-stage .tile-flip {
	display: none !important;
}
/* 수업 창 이탈 경고(옐로카드): 트로피처럼 카드 한 장과 ×횟수. 트로피가 있으면 그 바로 위(above), 없으면 트로피 자리. */
.tile-cards {
	position: absolute;
	right: 8px;
	bottom: 6px;
	z-index: 4;
	display: inline-flex;
	align-items: center;
	gap: 3px;
	height: 18px;
	padding: 0 6px;
	border-radius: 10px;
	background: rgb(15 23 42 / 62%);
	color: #fde047;
	font-size: 12px;
	font-weight: 600;
	text-shadow: 0 1px 3px #000;
	font-variant-numeric: tabular-nums;
}
.tile-cards.above {
	bottom: 28px;
}
.tile-cards[hidden] {
	display: none;
}
.main-stage .tile-cards {
	right: 68px;
	bottom: 12px;
	font-size: 14px;
}
.main-stage .tile-cards.above {
	bottom: 38px;
}
/* 옐로카드(시안 B, 대표님·톡톡잉글리쉬 11/5): 두꺼운 흰 테두리(스티커)를 두른 기울어진 노란 카드에 둥근 흰 느낌표.
   느낌표는 글꼴이 아니라 그림이라 어느 크기에서나 같은 모양이다. 크기마다 테두리 두께만 맞춘다. */
/* 옐로카드는 어디서나 같은 모양(흰 테두리, 느낌표, 노란 그라데이션): 수, 날아드는 카드, 이탈 중 흔들리는 카드(대표님 11/6
   "옐로카드 흔들리는건 왜 카드 모양 안바꿈?"). */
.yellow-card,
.pop-card,
.tile-away-card,
.away-card {
	display: inline-block;
	box-sizing: border-box;
	border-style: solid;
	border-color: #fff;
	background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 30'%3E%3Cg fill='%23b45309' fill-opacity='.35'%3E%3Cpath d='M2 5.4Q2 2.6 5 2.6T8 5.4L6.9 18Q6.7 20 5 20T3.1 18Z'/%3E%3Ccircle cx='5' cy='26.2' r='3'/%3E%3C/g%3E%3Cg fill='%23fff'%3E%3Cpath d='M2 4.4Q2 1.6 5 1.6T8 4.4L6.9 17Q6.7 19 5 19T3.1 17Z'/%3E%3Ccircle cx='5' cy='25.2' r='3'/%3E%3C/g%3E%3C/svg%3E") center / auto 62% no-repeat, linear-gradient(160deg, #ffe680 0%, #fcd34d 45%, #f5a70a 100%);
}
.yellow-card {
	width: 9px;
	height: 12px;
	border-width: 1.5px;
	border-radius: 2px;
	box-shadow: 0 0 0 0.5px rgb(0 0 0 / 18%), 0 1px 2px rgb(0 0 0 / 30%);
	transform: rotate(-8deg);
}
/* 버튼 안의 옐로카드(카드 주기): 아이콘 크기에 맞춰 조금 크게. */
.yellow-card.as-icon {
	width: 12px;
	height: 16px;
	border-width: 2px;
	border-radius: 2.5px;
}
/* 내 화면 전체(학생은 창도)를 공유하는 동안 내 창에서는 그 영상 대신 안내만(화면 속 화면이 끝없이 이어지지 않게). */
.tile.self-capture video {
	visibility: hidden;
}
.tile.self-capture::after {
	content: "내 화면을 공유하는 중";
	position: absolute;
	inset: 0;
	z-index: 1;
	display: grid;
	place-items: center;
	padding: 8px;
	color: #cbd5e1;
	font-size: 12px;
	font-weight: 700;
	text-align: center;
	white-space: pre-line;
	pointer-events: none;
}
.main-stage .tile.self-capture::after {
	content: "내 화면을 공유하고 있어요\A다른 참가자에게는 공유한 화면이 그대로 보여요";
	font-size: 18px;
	line-height: 1.6;
}
/* 받은 트로피 수: 이름 줄의 오른쪽 끝. */
.tile-trophies {
	display: inline-flex;
	align-items: center;
	gap: 2px;
	margin-left: auto;
	padding: 0 6px;
	border-radius: 10px;
	background: rgb(15 23 42 / 62%);
	color: #fde047;
	font-variant-numeric: tabular-nums;
}
.tile-trophies .emoji {
	font-size: 13px;
}
.tile-trophies .emoji:not(:first-child) {
	margin-left: 4px;
}
/* 트로피를 받은 순간 그 타일에 뜨는 효과. */
.tile-pop {
	position: absolute;
	inset: 0;
	z-index: 6;
	display: grid;
	place-items: center;
	pointer-events: none;
	/* 안의 트로피와 반짝이 크기를 타일 크기에 맞춘다(cqi = 이 상자 폭의 1%). */
	container-type: size;
	animation: trophy-pop 2.6s ease-out both;
}
.pop-trophy {
	grid-area: 1 / 1;
	font-size: clamp(40px, 22cqi, 150px);
	filter: drop-shadow(0 6px 18px rgb(0 0 0 / 45%));
}
/* 트로피 둘레로 퍼지는 반짝이. 각자 --angle 방향으로 날아간다. */
.pop-spark {
	grid-area: 1 / 1;
	font-size: clamp(16px, 8cqi, 48px);
	animation: spark-fly 1.6s ease-out both;
}
@keyframes spark-fly {
	0% { opacity: 0; transform: rotate(var(--angle)) translateY(0) rotate(calc(var(--angle) * -1)) scale(0.4); }
	20% { opacity: 1; }
	100% { opacity: 0; transform: rotate(var(--angle)) translateY(-38cqi) rotate(calc(var(--angle) * -1)) scale(1.1); }
}
@keyframes trophy-pop {
	0% { opacity: 0; transform: scale(0.5); }
	12% { opacity: 1; transform: scale(1.12); }
	22% { transform: scale(1); }
	80% { opacity: 1; }
	100% { opacity: 0; transform: scale(1.04); }
}
/* 강사 화면의 학생 타일에 뜨는 개별 버튼(펜 권한, 마이크 끄기, 트로피, 채팅 금지). 타일에 마우스를 올리면 보인다. */
.tile-actions {
	position: absolute;
	top: 4px;
	right: 4px;
	z-index: 5;
	display: none;
	gap: 3px;
	padding: 3px;
	border-radius: 8px;
	background: rgb(15 23 42 / 78%);
}
.tile.manageable:hover .tile-actions,
.tile.manageable:focus-within .tile-actions {
	display: flex;
}
@media (hover: none) {
	/* 손가락으로 누르기 쉽게 떠 있는 패널의 손잡이와 접기 버튼을 키운다. */
	.float-grip,
	.float-button {
		width: 36px;
		height: 36px;
	}
	.tile.manageable .tile-actions {
		display: flex;
	}
}
.tile-actions button {
	width: 26px;
	height: 26px;
	padding: 0;
	border-color: transparent;
	border-radius: 6px;
	background: transparent;
	color: #fff;
}
.tile-actions button:hover {
	border-color: transparent;
	background: rgb(255 255 255 / 20%);
}
.tile-actions button.on {
	background: var(--accent-bright);
}
.tile-actions button svg {
	width: 15px;
	height: 15px;
}
/* 공유 화면 위 주석. 펜을 켠 동안에만 입력을 받는다. */
.ink {
	position: absolute;
	inset: 0;
	z-index: 5;
	width: 100%;
	height: 100%;
	pointer-events: none;
}
.ink.drawing {
	pointer-events: auto;
	cursor: crosshair;
	touch-action: none;
}
.ink.drawing[data-tool="move"] {
	cursor: move;
}
.ink.drawing[data-tool="text"] {
	cursor: text;
}
.ink.drawing[data-tool="erase"] {
	cursor: cell;
}
/* 글상자를 입력하는 동안의 입력창. 글자가 주석과 같은 자리에 오도록 테두리와 안쪽 여백만큼 당겨 놓는다. */
.ink-editor {
	position: absolute;
	z-index: 6;
	min-width: 140px;
	max-width: 60%;
	margin: -1px 0 0 -3px;
	padding: 0 2px;
	overflow: hidden;
	border: 1px dashed currentColor;
	border-radius: 2px;
	background: rgb(148 163 184 / 35%);
	font-family: inherit;
	font-weight: 600;
	line-height: 1.25;
	white-space: pre;
	resize: none;
}
.toast {
	position: absolute;
	top: 12px;
	left: 50%;
	z-index: 20;
	max-width: calc(100% - 32px);
	padding: 10px 16px;
	transform: translateX(-50%);
	border-radius: 999px;
	background: var(--navy);
	color: #fff;
	font-size: 13px;
	font-weight: 600;
	box-shadow: 0 12px 32px rgb(15 23 42 / 28%);
}
.chat-actions {
	display: flex;
	gap: 2px;
}
.chat-actions .icon-button.small.off {
	background: var(--danger-soft);
	color: var(--danger);
}
.composer {
	position: relative;
}
.mention-list {
	position: absolute;
	right: 12px;
	bottom: calc(100% + 4px);
	left: 12px;
	z-index: 6;
	display: grid;
	gap: 2px;
	padding: 6px;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
	background: var(--surface);
	box-shadow: 0 12px 32px rgb(15 23 42 / 16%);
}
.mention-list button {
	justify-content: flex-start;
	height: var(--control-h-sm);
	padding: 0 8px;
	border-color: transparent;
	font-weight: 500;
}
.mention-list button.active {
	background: var(--accent-soft);
	color: var(--accent);
}
mark.mention {
	padding: 0 3px;
	border-radius: 4px;
	background: var(--accent-soft);
	color: var(--accent);
	font-weight: 700;
}
.message.me mark.mention {
	background: rgb(255 255 255 / 20%);
	color: #fff;
}
/* 나를 지목한 말풍선. */
.message.mentioned {
	box-shadow: 0 0 0 2px var(--accent-bright);
}

@media (max-width: 900px) {
	.layout {
		grid-template-columns: 1fr;
		padding: 16px;
	}
	.side {
		order: -1;
	}
	/* 좁은 창에서는 열을 나누지 않고 채팅이 큰 화면 위에 반투명으로 겹친다. */
	.call.chat-open {
		grid-template-columns: minmax(0, 1fr);
	}
	.chat-panel {
		grid-row: 1;
		grid-column: 1;
		justify-self: end;
		width: min(320px, 100%);
	}
	.call.chat-open {
		--chat-width: 0px;
	}
}
@media (prefers-reduced-motion: reduce) {
	button,
	.thumbs .tile.selectable {
		transition: none;
	}
}

/* ---------- 강사용 Windows 앱 ---------- */
/* 입장 화면 아래: 앱 받기. */
.app-download {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 6px 12px;
	margin-top: auto;
	padding: 14px 18px;
	border-top: 1px solid var(--line);
	font-size: 13px;
}
.app-download a {
	font-weight: 700;
}
/* Windows 프로그램 받기(/download/windows): 받기 안내와 확인 창 넘기는 순서, 화면 그대로. */
.install {
	width: min(720px, calc(100% - 32px));
	margin: 24px auto;
}
.install p {
	margin: 0 0 8px;
}
.install-steps {
	margin: 18px 0;
	padding-left: 22px;
}
.install-steps li + li {
	margin-top: 22px;
}
.install-steps h3 {
	margin: 0 0 6px;
	font-size: 14px;
}
.install-steps img {
	display: block;
	max-width: 100%;
	height: auto;
	margin: 8px 0 12px;
	border: 1px solid var(--line);
	border-radius: var(--radius-control);
}
/* 안내 사진 위에 누를 곳(노란 칸)과 누르지 말 곳(빨간 점선)을 그린다. 사진 파일은 그대로 두고, 칸은 사진 크기의 비율로 놓는다. */
.install-steps .shot {
	position: relative;
	width: fit-content;
	max-width: 100%;
	margin: 8px 0 12px;
}
.install-steps .shot img {
	margin: 0;
}
.install-steps .mark {
	position: absolute;
	left: var(--x);
	top: var(--y);
	width: var(--w);
	height: var(--h);
	border: 3px solid #f5b800;
	border-radius: 6px;
	pointer-events: none;
}
.install-steps .mark.no {
	border: 2px dashed #d92d20;
}
.install-steps .mark[data-label]::after {
	content: attr(data-label);
	position: absolute;
	top: 50%;
	right: calc(100% + 6px);
	transform: translateY(-50%);
	padding: 2px 8px;
	border-radius: 999px;
	background: #f5b800;
	color: #1a1a1a;
	font-size: 12px;
	font-weight: 700;
	white-space: nowrap;
}
.install-steps .mark.no[data-label]::after {
	background: #d92d20;
	color: #fff;
}
.install-steps .mark.right[data-label]::after {
	right: auto;
	left: calc(100% + 6px);
}
.install-steps .mark.above[data-label]::after {
	top: auto;
	right: auto;
	bottom: calc(100% + 4px);
	left: 50%;
	transform: translateX(-50%);
}
.install .key {
	padding: 0 4px;
	border: 2px solid #f5b800;
	border-radius: 4px;
}
.install .key.no {
	border: 2px dashed #d92d20;
}
.install-path {
	padding: 10px 12px;
	border-radius: var(--radius-control);
	background: var(--canvas);
	line-height: 1.8;
}
/* 앱의 수업 창은 테두리가 없어서 위쪽 막대를 끌어 창을 옮기고, 창 버튼은 오른쪽 끝에 둔다. */
.desktop-app .call-mode .topbar {
	-webkit-app-region: drag;
	user-select: none;
}
.desktop-app .call-mode .topbar button {
	-webkit-app-region: no-drag;
}
.desktop-window {
	display: flex;
	gap: 2px;
	margin-left: auto;
}
.desktop-window button {
	display: grid;
	place-items: center;
	width: 34px;
	height: 30px;
	padding: 0;
	border: 0;
	border-radius: var(--radius-control);
	background: transparent;
	color: var(--muted);
}
.desktop-window button:hover {
	background: var(--canvas);
	color: var(--ink);
}
.desktop-window button:last-child:hover {
	background: var(--coral);
	color: #fff;
}
.desktop-window svg {
	width: 16px;
	height: 16px;
}
/* 칠판 모드: 수업 창이 공유 중인 모니터 전체를 덮는 투명 창이 된다. 큰 화면(공유 영상)은 보이지 않게 두고(녹화에는 쓴다),
   그 자리에 실제 원래 화면이 보이며 주석 캔버스만 그 위에 그린다. 떠 있는 패널은 그대로 쓴다. */
.desktop-overlay,
.desktop-overlay body {
	background: transparent;
}
.desktop-overlay .topbar,
.desktop-overlay .stage-empty,
.desktop-overlay #fullscreen {
	display: none;
}
.desktop-overlay .call,
.desktop-overlay .call.chat-open {
	grid-template-columns: minmax(0, 1fr);
	padding: 0;
	--chat-width: 0px;
}
.desktop-overlay .main-stage {
	border: 0;
	border-radius: 0;
	background: transparent;
}
.desktop-overlay .main-stage > .tile {
	opacity: 0;
	pointer-events: none;
}
/* 칠판이 화면 밖이나 작업 표시줄 밑으로 가려지면(앱이 --hide-* 로 알려 준다) 패널을 보이는 곳 가운데 위·아래에 둔다. */
.desktop-overlay .thumbs-panel,
.desktop-overlay .controls-panel {
	left: calc(var(--hide-left, 0px) + (100% - var(--hide-left, 0px) - var(--hide-right, 0px)) / 2);
}
.desktop-overlay .thumbs-panel {
	top: calc(16px + var(--hide-top, 0px));
}
.desktop-overlay .thumbs-panel:not(.moved) {
	right: auto;
	transform: translateX(-50%);
}
.desktop-overlay .controls-panel {
	bottom: calc(20px + var(--hide-bottom, 0px));
}
/* 끌어 옮긴 버튼 묶음은 옮긴 자리(top)만 쓴다. 이 규칙이 없으면 위의 bottom이 함께 걸려 패널이 위아래로 늘어났다. */
.desktop-overlay .controls-panel.moved {
	bottom: auto;
}
.desktop-overlay .call-status {
	top: calc(24px + var(--hide-top, 0px));
	left: calc(30px + var(--hide-left, 0px));
}
/* 썸네일 줄의 "내 화면 공유"는 원래 화면을 한 번 더 보여 줄 뿐이라 뺀다. */
.desktop-overlay .thumbs .tile.screen {
	display: none;
}
.desktop-overlay .chat-panel {
	position: fixed;
	top: calc(16px + var(--hide-top, 0px));
	right: calc(16px + var(--hide-right, 0px));
	bottom: calc(110px + var(--hide-bottom, 0px));
	width: 320px;
}
/* 공유 중인 화면이라는 표시: 모니터 가장자리에 초록 테두리(줌과 같은 방식). */
.desktop-overlay body::after {
	content: "";
	position: fixed;
	inset: 0;
	z-index: 30;
	border: 3px solid var(--live);
	pointer-events: none;
}
