/* IBA Scoring Machine — 본문 페이지(제출·리더보드·미니게임·마이페이지 등).
   색 토큰·메뉴·하단 바는 chrome.css에서 받는다. 랜딩과 같은 따뜻한 오프화이트 바탕에
   세리프 페이지 제목을 얹고, 내용은 선 하나로 두른 흰 카드에 담는다. */

:root {
  --card: #ffffff;
  --line-soft: #efede8;   /* 카드 안 구분선. 바탕과 같은 따뜻한 쪽으로 */
  --ok: #1f7a4d;
  --warn: #9a6400;
  --danger: #c8372d;
  --radius-card: 12px;
}

[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; }
a { color: var(--accent); }
a:hover { text-decoration: underline; }
code { font-family: var(--mono); font-size: 0.92em; background: var(--subtle); border-radius: 4px; padding: 1px 4px; }
.num { font-variant-numeric: tabular-nums; }
.icon { width: 16px; height: 16px; flex: none; fill: currentColor; }

.avatar { width: 34px; height: 34px; border-radius: 50%; background: var(--subtle); display: grid; place-items: center; color: var(--muted); flex: none; }

/* ── 본문 틀 ──────────────────────────────────────────────
   좌우 여백을 88px 이상 두어 고정된 메뉴 버튼(오른쪽 끝 64px)과 내용이 겹치지 않게 한다.
   위쪽은 메뉴 버튼·오른쪽 위 두 줄이 앉는 자리. */
main.page {
  flex: 1;
  width: 100%; max-width: 1200px;
  margin: 0 auto;
  padding: 112px 88px 72px;
}
/* 본문 페이지는 내려 읽으므로 오른쪽 위 두 줄은 화면에 고정하지 않고 함께 올라가게 둔다.
   메뉴 버튼은 어디서든 닿도록 고정 그대로. */
.corner-links { position: absolute; top: 24px; }   /* 워드마크가 메뉴 버튼과 같은 높이에 서도록 */

/* 오른쪽 위 IBA: 랜딩 워드마크를 작게 줄인 것. 누르면 랜딩으로 돌아간다 */
.corner-links .home-mark {
  margin-bottom: 6px;
  font-family: var(--display); font-weight: 900;
  font-size: 28px; line-height: 36px; letter-spacing: -0.01em;
  color: var(--accent);
  border-bottom: 0;
}
.corner-links .home-mark:hover { color: #2749c7; }

.page-head { margin-bottom: 36px; }
.page-head.centered { text-align: center; }
.page-eyebrow {
  margin: 0 0 6px;
  font-family: var(--sub);
  font-size: 17px; letter-spacing: 0.03em;
  color: var(--muted);
}
/* How to use 카드: 관리자 페이지처럼 흰색 대신 페이지 바탕(#faf9f6)에 가까운 따뜻한 색 */
/* 표 머리 줄은 카드보다 한 톤 진하게, 양옆 여백(88px×2)을 빼면 박스 폭은 최대 800px */
main.howto-page { max-width: 976px; --card: #f4f2ec; --subtle: #ebe8e0; }
.page-eyebrow.service-line { font-size: 34px; }   /* How to use: 큰 제목 대신 서비스 이름을 크게 */
.page-title {
  margin: 0;
  font-family: var(--display); font-weight: 900;
  font-size: 60px; line-height: 1; letter-spacing: -0.015em;
  color: var(--ink);
}
main.page.compact { padding-top: 92px; }
.page-head.compact { margin-bottom: 20px; }
.page-head.compact .page-title { font-size: 40px; }

/* 카드 */
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  padding: 20px;
}
.card + .card { margin-top: 20px; }
.card-head { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 12px; }
.card-head h1, .card-head h2 { flex: 1; white-space: nowrap; }
.card.flush { padding: 0; overflow: hidden; }
.card-head .more { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; font-weight: 600; white-space: nowrap; }
.card-head .more .icon { width: 14px; height: 14px; }
.card.flush > .card-head { padding: 16px 20px 12px; margin: 0; }
.card-foot { padding: 11px 20px; font-size: 12px; color: var(--muted); }

h1 { font-size: 22px; line-height: 30px; font-weight: 700; letter-spacing: -0.5px; margin: 0; }
h2 { font-size: 16px; font-weight: 700; letter-spacing: -0.3px; margin: 0; }
h3 { font-size: 14px; font-weight: 600; margin: 20px 0 8px; }
p { margin: 0 0 10px; }
p:last-child { margin-bottom: 0; }
.lead { color: var(--ink-2); font-size: 13px; line-height: 20px; }
ul, ol { padding-left: 20px; margin: 0; }
li { margin-bottom: 6px; color: var(--ink-2); }
li strong, li code { color: var(--ink); }
.small { font-size: 12px; color: var(--muted); }

.status { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--ok); }
.status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.status.idle { color: var(--muted); }

/* 버튼 */
.btn, button {
  font: inherit; font-size: 14px; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 40px; padding: 0 16px;
  border-radius: var(--radius-ctl);
  border: 1px solid var(--line);
  background: var(--card); color: var(--ink);
  cursor: pointer; white-space: nowrap;
}
.btn .icon, button .icon { color: var(--ink-2); }
.btn:hover, button:hover { background: var(--subtle); text-decoration: none; }
.btn.primary, button.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); padding: 0 18px; }
.btn.primary .icon, button.primary .icon { color: var(--accent-ink); }
.btn.primary:hover, button.primary:hover { background: #2749c7; }
.btn.block, button.block { width: 100%; height: 40px; font-size: 13px; }
.btn.sm, button.sm { height: 34px; padding: 0 12px; font-size: 13px; }
button:disabled { opacity: 0.5; cursor: default; }
input:focus-visible, button:focus-visible, .btn:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px;
}

/* 정의 목록: 규칙·수치 나열 */
dl.facts { display: grid; grid-template-columns: max-content 1fr; gap: 8px 20px; margin: 0; }
dl.facts dt { color: var(--muted); font-weight: 500; }
dl.facts dd { margin: 0; }
/* How to use: 채점 방식 표의 글자를 아래 목록(li)과 같은 색으로, 굵은 글자만 진하게 */
.howto-page dl.facts { row-gap: 12px; }   /* 채점 방식 표: 행 사이를 조금 더 띄운다(기본 8px) */
.howto-page dl.facts dd { color: var(--ink-2); }
.howto-page dl.facts dd strong { color: var(--ink); }
.howto-page code { background: none; padding: 0; border-radius: 0; }   /* 코드 글자의 회색 상자 표시 없이 글꼴만 */
.howto-page #rules h3 { margin-top: 28px; }   /* 채점 방식 박스 안 섹션 사이를 조금 더 띄운다 */
.howto-page thead th { background: none; font-size: 13px; font-weight: 700; border-top-color: #e6e3db; border-bottom-color: #e6e3db; }   /* 표 머리 줄도 본문과 같은 카드 색(회색 배경은 버튼 호버 색과 같아 마우스를 올린 것처럼 보였다) */

/* 대회 정보 카드 */
.chip { display: inline-flex; align-items: center; height: 24px; padding: 0 9px; border: 1px solid var(--line); border-radius: 6px; font-size: 11.5px; font-weight: 600; color: var(--ink-2); }
.progress { border-top: 1px solid var(--line-soft); margin-top: 14px; padding-top: 14px; }
.progress .row { display: flex; font-size: 12px; margin-bottom: 8px; }
.progress .row span:first-child { flex: 1; color: var(--ink-2); font-weight: 500; }
.progress .row span:last-child { font-weight: 600; }
.bar { height: 6px; border-radius: 3px; background: var(--subtle); overflow: hidden; }
.bar > i { display: block; height: 100%; background: var(--accent); border-radius: 3px; }
.kv { list-style: none; padding: 5px 0 0; margin: 14px 0; border-top: 1px solid var(--line-soft); }
.kv li { display: flex; align-items: center; gap: 8px; padding: 9px 0; margin: 0; font-size: 12.5px; }
.kv li .icon { width: 15px; height: 15px; color: var(--muted); }
.kv li .k { flex: 1; color: var(--ink-2); font-weight: 500; }
.kv li .v { color: var(--ink); font-weight: 600; white-space: nowrap; }

/* 표 */
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
th:first-child, td:first-child { padding-left: 20px; }
th:last-child, td:last-child { padding-right: 20px; }
thead th {
  background: var(--subtle);
  border-top: 1px solid var(--line-soft);
  padding-top: 8px; padding-bottom: 8px;
  font-size: 11.5px; font-weight: 600; letter-spacing: 0.2px; color: var(--muted);
}
td.num, th.num { text-align: right; }
td.num { font-variant-numeric: tabular-nums; }
.table-wrap { overflow-x: auto; }
.card:not(.flush) .table-wrap { margin: 0 -20px; }

/* 리더보드 */
#board th, #board td, #gameBoard th, #gameBoard td { white-space: nowrap; }
.rank-badge {
  width: 24px; height: 24px; border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--subtle); border: 1px solid var(--line);
  font-size: 12px; font-weight: 700;
}
.rank-badge.first { color: var(--accent); }
.team { display: flex; align-items: center; gap: 10px; }
.team .avatar { width: 30px; height: 30px; }
.team .avatar .icon { width: 15px; height: 15px; }
.team .name { font-size: 13.5px; font-weight: 600; line-height: 1.35; }
.team .sub { font-size: 11.5px; color: var(--muted); line-height: 1.35; }
tr.mine td { background: #f3f5fd; }
.tag { display: inline-flex; align-items: center; height: 19px; padding: 0 6px; margin-left: 4px; border: 1px solid var(--accent); border-radius: 5px; font-size: 10.5px; font-weight: 600; color: var(--accent); vertical-align: 1px; }
td.score-main { font-size: 14.5px; font-weight: 700; letter-spacing: -0.2px; color: var(--ink); }
td.soft { color: var(--ink-2); font-size: 13px; }
td.faint { color: var(--muted); font-size: 12.5px; }
.empty { color: var(--muted); padding: 24px 20px; margin: 0; }

/* 로그인·회원가입 */
.auth-card { max-width: 420px; margin: 0 auto; padding: 28px; }
/* 로그인: 제목·안내 문장·흰 박스 없이 입력 칸과 버튼만, 화면 가운데에 */
.auth-main .page-head { display: none; }
/* 왼쪽 절반 가운데에 입력 폼, 오른쪽 절반 가운데에 IBA 표지 사진 */
main.page.auth-main {
  width: 50vw; max-width: none; margin: 0;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  padding: 72px 8px 32px 88px;   /* 왼쪽을 더 띄워 폼을 사진 쪽으로 40px 옮긴다 */
}
/* 로그인·회원가입 화면에서는 우측 상단 링크를 표시하지 않는다. */
body:has(.auth-main) .corner-links { display: none; }
/* 사진: 화면 위아래에 똑같이 20px씩 띄우고 그 사이 높이를 꽉 채운다(하단 바와는 좌우로 겹치지 않는다).
   오른쪽 절반의 가운데에 서고, 창이 좁아 그 높이로는 오른쪽 절반을 넘치면 오른쪽 절반 폭에 맞춰 줄어든다 */
.auth-visual {
  --photo-w: min((100vh - 40px) * 3 / 4, 50vw - 48px);
  position: fixed; z-index: 1;
  width: var(--photo-w); top: calc(50vh - var(--photo-w) * 2 / 3);
  right: calc(25vw - var(--photo-w) / 2);
  aspect-ratio: 3 / 4; margin: 0;
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 0 0 1px rgba(21, 24, 29, 0.08), 0 24px 56px rgba(21, 24, 29, 0.16);
}
/* 사진 가장자리에 찍힌 바탕을 살짝 잘라 표지만 보이게 */
.auth-visual img { display: block; width: 100%; height: 100%; object-fit: cover; transform: scale(1.05); }
.auth-main .auth-card { width: 100%; max-width: 360px; padding: 0; }
/* 줄 간격은 gap 대신 위 여백으로 준다. 그래야 접힌 가입 줄은 간격까지 0이 된다 */
.auth-main form.stack { gap: 0; }
.auth-main form.stack > * + * { margin-top: 20px; }
/* 이름표 줄 높이(32px) 위쪽 여백만큼 덜 띄워, 입력 칸 → 다음 이름표 간격이 입력 칸 → Sign in 버튼(24px)과 같아 보이게 */
.auth-main form.stack > label + label { margin-top: 16px; }
.auth-main label { gap: 8px; }
/* 영문 글자(ID·Password·Sign in·Don't have account?)는 랜딩 소제목과 같은 Instrument Serif */
.auth-main label { font-family: var(--sub); font-size: 20px; font-weight: 400; letter-spacing: 0.02em; color: var(--ink-2); }
.auth-main button.primary {
  height: 46px; margin-top: 24px; font-family: var(--sub);   /* 줄 간격 20px + 4px */ font-size: 21px; font-weight: 400; letter-spacing: 0.04em;
  /* Instrument Serif는 굵기가 하나뿐이라 bold를 주면 브라우저가 억지로 뭉갠다. 같은 색 윤곽선을 얇게 덧그려 획만 두껍게 */
  -webkit-text-stroke: 0.55px currentColor;
}
.auth-main .auth-card .switch { margin-top: 12px; font-family: var(--sub); font-size: 19px; letter-spacing: 0.02em; }   /* 아래 .auth-card .switch보다 앞서도록 한 단계 구체적으로 */
/* 입력 칸: 흰색 대신 바탕보다 아주 조금 짙은 색으로 구분. 누르면 파란 테두리 대신 한 단계 더 짙어진다 */
.auth-main input[type="text"], .auth-main input[type="password"] {
  height: 46px; padding: 0 14px;
  font-family: var(--sans); font-size: 15px;   /* 라벨의 세리프가 입력 글자로 번지지 않게 */
  background: #f3f0ea; border-color: transparent;   /* 바탕(#faf9f6)에서 아주 조금만 짙게 */
  transition: background 160ms ease-out;
}
/* 가입 모드로 바뀔 때: 이름표는 타이핑되는 동안 끝에 커서가 깜빡이고, 입력 칸은 이름표가 다 쳐진 뒤 살짝 떠오른다 */
.auth-main .field-name { min-height: 1.2em; }
.typing::after {
  content: ""; display: inline-block; width: 1px; height: 0.95em; margin-left: 2px;
  background: currentColor; vertical-align: -0.1em;
  animation: caret-blink 0.9s steps(1) infinite;
}
@keyframes caret-blink { 50% { opacity: 0; } }
/* 가입 줄은 높이 0으로 접혀 있다가(grid 행 0fr → 1fr) 부드럽게 열린다. 폼이 세로 가운데 정렬이라
   한 번에 늘어나면 폼 전체가 툭 튀므로, 높이와 위 간격(0 → 20px)을 함께 천천히 늘린다. */
.auth-main form.stack > .signup-field {
  display: grid; grid-template-rows: 0fr;
  margin-top: 0;   /* 접혀 있을 때는 줄 간격도 없다 */
  opacity: 0;
  transition: grid-template-rows 0.52s cubic-bezier(0.4, 0, 0.2, 1), margin-top 0.52s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.4s ease;
}
.auth-main form.stack > .signup-field.open { grid-template-rows: 1fr; margin-top: 16px; opacity: 1; }
.auth-main .sf-inner { min-height: 0; overflow: hidden; gap: 0; }
/* 입력 칸 자리도 이름표가 다 쳐진 뒤 같은 방식으로 열리고, 칸은 살짝 내려오며 나타난다 */
.auth-main .sf-input { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.52s cubic-bezier(0.4, 0, 0.2, 1); }
.auth-main .signup-field.input-open .sf-input { grid-template-rows: 1fr; }
.auth-main .sf-input-inner { display: block; min-height: 0; overflow: hidden; }
.auth-main .sf-input-inner input {
  width: 100%; margin-top: 8px;
  opacity: 0; transform: translateY(-6px);
  transition: opacity 0.45s ease 0.12s, transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1) 0.12s, background 160ms ease-out;
}
.auth-main .signup-field.input-open .sf-input-inner input { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .auth-main .signup-field, .auth-main .sf-input, .auth-main .sf-input-inner input { transition: none; }
}
.auth-main input[type="text"]:focus, .auth-main input[type="password"]:focus,
.auth-main input[type="text"]:focus-visible, .auth-main input[type="password"]:focus-visible {
  outline: none; background: #ece8e0;
}
.auth-card .lead { margin-bottom: 18px; }
.auth-card .switch { margin-top: 16px; font-size: 13px; color: var(--ink-2); text-align: center; }

/* 폼 */
form.stack { display: grid; gap: 16px; }
label { display: grid; gap: 6px; font-weight: 600; font-size: 13px; }
label .hint { font-weight: 400; font-size: 12px; color: var(--muted); }
input[type="text"], input[type="password"], input[type="number"] {
  font: inherit; font-size: 14px;
  height: 40px; padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: var(--radius-ctl);
  background: var(--card);
  color: var(--ink);
}
input[type="file"] {
  font: inherit; font-size: 13px;
  padding: 8px; border: 1px dashed var(--line); border-radius: var(--radius-ctl); background: var(--subtle);
}
input[type="file"]::file-selector-button {
  font: inherit; font-weight: 600; margin-right: 10px;
  height: 30px; padding: 0 12px; border: 1px solid var(--line); border-radius: 7px; background: var(--card); cursor: pointer;
}
.row { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }

/* 상태 표시 */
.quota { color: var(--muted); font-size: 13px; min-height: 1.5em; }
.quota strong { color: var(--ink); }
.score { display: flex; gap: 0; flex-wrap: wrap; margin: 12px 0; }
.score > div { padding: 2px 20px; border-left: 1px solid var(--line-soft); }
.score > div:first-child { padding-left: 0; border-left: 0; }
.score .label { color: var(--muted); font-size: 12px; font-weight: 500; }
.score .value { font-size: 28px; line-height: 1.2; font-weight: 700; letter-spacing: -0.5px; font-variant-numeric: tabular-nums; }
.score .value.sub { font-size: 21px; }
.msg-error { color: var(--danger); }
.msg-warn { color: var(--warn); }
.msg-ok { color: var(--ok); }

/* 미니게임 */
.game-stats { display: flex; flex-wrap: wrap; }
.game-stats > div { padding: 2px 20px; border-left: 1px solid var(--line-soft); }
.game-stats > div:first-child { padding-left: 0; border-left: 0; }
.game-stats .value { font-size: 21px; font-weight: 700; letter-spacing: -0.5px; font-variant-numeric: tabular-nums; }
.game-stats .label { color: var(--muted); font-size: 12px; font-weight: 500; }

/* ── 미니게임 화면 ─────────────────────────────────────────────
   macOS 화면을 그림 없이 색과 음영만으로 구분한 둥근 판. 사이트 바탕보다 조금 짙고 푸른 기가 도는 색에,
   안쪽 위 가장자리 그늘과 바깥 그림자를 준다. 위쪽 바탕에 게임 아이콘, 아래쪽에 Dock(desktop.js). */
.desk-main .page-head { display: none; }   /* 제목 없이 화면만 둔다 */
body:has(.desk-main) .corner-links > :not(.home-mark) { display: none; }   /* 계정 줄과 Sign in·Sign out을 숨겨 화면 위와 겹치지 않게 한다 */
/* 화면은 메뉴 버튼·IBA 줄 바로 아래(68px)에서 시작해, 양옆은 그 버튼들에 가리지 않으므로 넓게 쓴다 */
main.page.desk-main { max-width: none; padding: 68px 40px 0; }
.screen {
  position: relative;
  /* 가로로 긴 화면. 높이는 위 68px + 하단 바 53px + 숨 쉴 틈 12px = 133px를 뺀 만큼,
     폭은 좌우 40px씩을 뺀 만큼(아주 넓은 모니터에서는 높이의 1.9배까지) */
  height: calc(100vh - 133px);
  width: min(calc(100vw - 80px), calc((100vh - 133px) * 1.9));
  margin: 0 auto;
  container-type: inline-size;   /* Dock 아이콘 크기를 화면 폭에 맞춘다 */
  border-radius: 18px; overflow: hidden;
  background:
    radial-gradient(120% 90% at 50% 0%, #f4f2ee 0%, #e9e6e0 55%, #dedbd4 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    inset 0 18px 40px -24px rgba(21, 24, 29, 0.18),   /* 위 가장자리 안쪽 그늘 */
    0 0 0 1px rgba(21, 24, 29, 0.10),
    0 24px 60px rgba(21, 24, 29, 0.16);
}

/* 켜지는 모션: 페이지에 들어오면 화면이 검게 꺼진 상태에서 백라이트가 올라오듯 밝아지고,
   그다음 아이콘과 Dock이 살짝 떠오르며 나타난다. 검은 막은 누르기를 막지 않는다. */
.screen::after {
  content: ""; position: absolute; inset: 0; z-index: 3;
  background: #0b0b0d;
  pointer-events: none;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .screen::after { animation: screen-on 1.2s cubic-bezier(0.4, 0, 0.2, 1) 0.2s both; }
  .screen .desk-icon, .screen .dock { animation: screen-content-in 0.6s cubic-bezier(0.2, 0.8, 0.2, 1) 1s both; }
  @keyframes screen-on {
    0%   { opacity: 1; }
    25%  { opacity: 0.92; }   /* 백라이트가 막 들어오는 순간 */
    100% { opacity: 0; }
  }
  @keyframes screen-content-in {
    from { opacity: 0; translate: 0 6px; }
    to   { opacity: 1; translate: 0 0; }
  }
}

/* 게임 아이콘: 그림은 Dock 아이콘과 같은 44px. 한 번 누르면 선택(회색 틀 + 그림이 살짝 떠오름), 두 번 누르면 창, 끌면 옮겨진다 */
.desk-icon {
  position: absolute; left: var(--x); top: var(--y);
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  width: 88px; height: auto; padding: 0;
  border: 0; border-radius: 0; background: none;   /* style.css의 전역 button 모양을 걷어낸다 */
  font: inherit; color: var(--ink);
  cursor: grab; user-select: none;
  transform: translateX(-50%);   /* --x는 아이콘 가운데 기준 */
}
.desk-icon:hover { background: none; }
/* 포인터는 아이콘 단추가 직접 받는다. 안쪽 SVG가 받으면 끌기 포인터 캡처가 이어지지 않는다 */
.desk-icon > * { pointer-events: none; }
.desk-icon:active { cursor: grabbing; }
.desk-icon:focus-visible { outline: none; }
.desk-thumb {
  display: grid; place-items: center;
  width: 60px; height: 60px; padding: 7px;   /* 테두리 1px + 여백 7px을 빼면 그림이 Dock 아이콘과 같은 44px */
  border: 1px solid transparent; border-radius: 10px;
}
.desk-thumb svg {
  width: 100%; height: 100%; display: block;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.18)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.12));
}
.desk-label {
  max-width: 100%; padding: 1px 7px; border-radius: 5px;
  font-size: 11.5px; font-weight: 600; line-height: 1.5; letter-spacing: -0.1px;
  color: var(--ink);
}
.desk-icon:hover .desk-thumb { background: rgba(21, 24, 29, 0.05); }
.desk-icon.selected .desk-thumb, .desk-icon:focus-visible .desk-thumb {
  background: rgba(21, 24, 29, 0.08); border-color: rgba(21, 24, 29, 0.14);
}
.desk-icon.selected .desk-label, .desk-icon:focus-visible .desk-label {
  background: #0a64d8;
  color: #fff;
}

/* Dock: 화면 아래 가운데의 반투명 유리 막대. 앱 아이콘은 장식이고, 커서 가까운 것일수록 커진다(--s).
   화면이 좁으면 아홉 칸이 화면 안에 들어오도록 아이콘을 줄인다 */
.dock {
  --icon: min(44px, (100cqw - 120px) / 9);
  position: absolute; left: 50%; bottom: 12px;
  transform: translateX(-50%);
  display: flex; align-items: flex-end; gap: 7px;
  height: calc(var(--icon) + 12px);
  padding: 6px 9px;
  background: rgba(255, 255, 255, 0.5);
  -webkit-backdrop-filter: blur(24px) saturate(1.6);
  backdrop-filter: blur(24px) saturate(1.6);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 17px;
  box-shadow: 0 0 0 1px rgba(21, 24, 29, 0.08), 0 12px 30px rgba(21, 24, 29, 0.14);
}
.dock-item {
  --s: 1;
  position: relative; flex: none;
  width: calc(var(--icon) * var(--s)); height: calc(var(--icon) * var(--s));
  transition: width 140ms ease-out, height 140ms ease-out;
}
.dock-item svg { display: block; width: 100%; height: 100%; filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.18)) drop-shadow(0 3px 6px rgba(0, 0, 0, 0.12)); }   /* 짧고 또렷한 그림자 */
.dock-sep { align-self: stretch; width: 1px; margin: 4px 2px; background: rgba(21, 24, 29, 0.14); }
/* 이름 말풍선: 올리면 아이콘 위에 뜬다 */
.dock-tip {
  position: absolute; left: 50%; bottom: calc(100% + 10px);
  transform: translateX(-50%);
  padding: 3px 10px; border-radius: 6px;
  background: rgba(40, 42, 46, 0.86); color: #fff;
  font-size: 12px; font-weight: 500; white-space: nowrap;
  opacity: 0; pointer-events: none;
  transition: opacity 120ms ease-out;
}
.dock-item:hover .dock-tip { opacity: 1; }
@media (prefers-reduced-motion: reduce) {
  .dock-item { transition: none; }
}

/* 창: 제목 줄(신호등 세 개 + 가운데 제목) 아래에 게임 페이지를 iframe으로 담는다.
   앞에 있지 않은 창은 신호등을 회색으로 죽이고 그림자를 줄인다(macOS 비활성 창). */
.win-layer { position: fixed; inset: 0; z-index: 15; pointer-events: none; }
.win {
  position: absolute; pointer-events: auto;
  display: flex; flex-direction: column;
  background: var(--card);
  border: 1px solid rgba(21, 24, 29, 0.14);
  border-radius: 10px; overflow: hidden;
  box-shadow: 0 22px 60px rgba(21, 24, 29, 0.22), 0 2px 8px rgba(21, 24, 29, 0.08);
}
.win.inactive { box-shadow: 0 10px 30px rgba(21, 24, 29, 0.12); }
.win-bar {
  position: relative; flex: none;
  display: flex; align-items: center; justify-content: center;
  height: 34px; padding: 0 76px;
  background: #efece6; border-bottom: 1px solid var(--line);
  cursor: grab; user-select: none;
}
.win-bar:active { cursor: grabbing; }
.win-title { font-size: 13px; font-weight: 600; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.win.inactive .win-title { color: var(--muted); }
.win-lights { position: absolute; left: 13px; top: 50%; transform: translateY(-50%); display: flex; gap: 8px; }
.win-lights > * { display: block; width: 12px; height: 12px; padding: 0; border-radius: 50%; border: 0; }
.win-close { background: #e06551; cursor: pointer; }
.win-close:hover { background: #c94f3c; }
.win-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.win-lights i:nth-child(2) { background: #ecb944; }
.win-lights i:nth-child(3) { background: #62bb4b; }
.win.inactive .win-lights > * { background: #d6d3cd; }
.win iframe { display: block; width: 100%; height: 480px; border: 0; background: var(--card); }
/* 창이나 아이콘을 끄는 동안 iframe이 포인터를 가로채지 않게 */
.desk-dragging .win iframe { pointer-events: none; }
.desk-dragging, .desk-dragging * { cursor: grabbing !important; }

.win.closing { pointer-events: none; }   /* 여닫는 움직임은 desktop.js가 Web Animations로 준다 */

/* 창 안(iframe)에 들어간 게임 페이지(?embed=1): 메뉴·제목·하단 바 없이 본문만.
   카드 테두리를 걷어 창이 곧 카드가 되게 하고, 목록으로 돌아가는 링크는 숨긴다. */
body.embed { min-height: 0; background: var(--card); }
body.embed main { padding: 18px 20px 20px; }
.embed .card { border: 0; border-radius: 0; padding: 0; background: none; }
.embed .card + .card { margin-top: 28px; }
.embed .card.flush > .card-head { padding: 0 0 12px; }
.embed .card.flush th:first-child, .embed .card.flush td:first-child { padding-left: 0; }
.embed .card.flush th:last-child, .embed .card.flush td:last-child { padding-right: 0; }
.embed .card-foot { padding: 11px 0 0; }
.embed .empty { padding: 16px 0; }
.embed .card-head .more { display: none; }
.embed main > .card:first-child > .card-head { display: none; }   /* 게임 이름은 창 제목 줄에 이미 있다 */

/* 캔버스 게임 공통 */
.game-layout { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.game-stage { position: relative; line-height: 0; border-radius: 12px; overflow: hidden; background: #0b1a2e; flex: none; }
.game-stage canvas { display: block; }
.game-overlay {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  background: rgba(6, 16, 32, 0.78); color: #fff; line-height: 1.5; text-align: center; padding: 20px;
}
.game-overlay .big { font-size: 22px; font-weight: 700; letter-spacing: -0.5px; }
.game-overlay .small { color: rgba(255, 255, 255, 0.72); }
.game-side { flex: 1; min-width: 220px; max-width: 300px; display: flex; flex-direction: column; gap: 16px; }
.game-side .game-stage { display: inline-block; }
.game-side .game-stats { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 0; }
.game-side .game-stats > div:nth-child(odd) { padding-left: 0; border-left: 0; }
.keys { display: grid; grid-template-columns: max-content 1fr; gap: 6px 12px; font-size: 12.5px; margin: 0; }
.keys dt { margin: 0; }
.keys dd { margin: 0; color: var(--ink-2); }
kbd {
  font-family: var(--mono); font-size: 11.5px;
  display: inline-block; min-width: 22px; padding: 1px 6px; text-align: center;
  border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 5px; background: var(--subtle); color: var(--ink);
}
.time-bar { margin-top: 10px; }
/* 통계 칸 옆의 단추(사과게임의 처음부터 다시): 통계 값과 같은 줄 높이에 세운다 */
.game-stats > .stat-action { display: flex; align-items: flex-end; }
.game-stats > .stat-action button { width: 100%; }

/* 게임 옆 칸에 넣은 순위(사과게임). 칸이 좁아 표 여백을 줄이고 기록 시각 열은 숨기며,
   기록이 많으면 표만 스크롤한다. */
/* 사과게임: 게임판(674px) 오른쪽에 좁은 칸 하나만 두고 여백을 줄여 창을 작게 만든다 */
/* 오른쪽 칸은 게임판 높이에 맞춰 늘어나고(contain: size로 칸 내용이 줄 높이를 키우지 못하게),
   순위가 그 높이를 채워 칸 아래가 비지 않게 한다. 기록이 많으면 표만 스크롤. */
.apple-layout { gap: 16px; flex-wrap: nowrap; align-items: stretch; }
.apple-layout .game-side { flex: 0 0 210px; min-width: 0; max-width: none; gap: 14px; contain: size; }
.apple-layout .side-board { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.apple-layout .side-board .table-wrap { max-height: none; min-height: 0; flex: 0 1 auto; }
.apple-layout .side-board > .small { margin-top: auto; padding-top: 8px; }
.apple-layout .game-stats > div { padding-left: 14px; padding-right: 0; border-left: 0; }   /* 칸 사이 세로 구분선 없이 */
.apple-layout .game-stats > div:nth-child(odd) { padding-left: 0; }
.apple-layout .game-stats > .stat-action { padding-left: 4px; }
.apple-layout .game-stats > .stat-action button { width: auto; }
body.embed main:has(.apple-layout) { padding: 16px; }
.side-board h3 { margin: 0 0 8px; font-size: 13px; }
.side-board .table-wrap { max-height: 204px; overflow-y: auto; margin: 0 !important; }   /* 카드 안 표를 양옆으로 늘리는 규칙을 끈다 */
.side-board th, .side-board td { padding: 7px 6px; }
.side-board th:first-child, .side-board td:first-child { padding-left: 0; }
.side-board th:last-child, .side-board td:last-child { padding-right: 0; }
.side-board th:nth-child(4), .side-board td:nth-child(4) { display: none; }
.side-board th:nth-child(3), .side-board td:nth-child(3) { padding-right: 0; }
.side-board .team .avatar { display: none; }
.side-board .empty { padding: 10px 0; }
.side-board .small { margin: 8px 0 0; line-height: 1.55; }
/* 나머지 게임의 순위 칸. 게임 창 안에서는 게임판 오른쪽에 두고 사과게임처럼 게임판 높이에 맞춘다.
   창 밖에서 연 게임 페이지는 폭이 모자랄 수 있어 게임 아래 한 줄을 다 쓴다. */
.game-layout > .side-board { flex: 1 0 100%; }
.game-layout > .side-board .table-wrap { max-height: none; }
.embed .game-layout:has(> .side-board) { flex-wrap: nowrap; align-items: stretch; }
.embed .game-layout > .side-board { flex: 0 0 210px; min-height: 0; display: flex; flex-direction: column; contain: size; }
.embed .game-layout > .side-board .table-wrap { min-height: 0; flex: 0 1 auto; overflow-y: auto; }
.embed .game-layout > .side-board > .small { margin-top: auto; padding-top: 8px; }

@media (prefers-reduced-motion: no-preference) {
  .result { animation: rise 160ms ease-out; }
  @keyframes rise { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
}

/* ── 소개 페이지 ─────────────────────────────────────────────
   만든 사람 두 명을 나란히. 좁은 PC 창에서는 한 칸으로 내려온다. */
.people { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 20px; }
.people .card + .card { margin-top: 0; }   /* 격자 간격이 이미 있으므로 카드끼리의 세로 여백은 끈다 */
.people + .card { margin-top: 20px; }
.person .who { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.person .name { font-size: 17px; font-weight: 700; letter-spacing: -0.3px; }
.person .role { font-size: 12px; font-weight: 500; color: var(--muted); }
.person .links { list-style: none; margin: 12px 0 0; padding: 0; display: flex; gap: 14px; }
.person .links a { font-size: 13px; font-weight: 600; }

@media (max-width: 900px) {
  .people { grid-template-columns: 1fr; }
}

/* 좁은 PC 창: 사진을 빼고 폼만 화면 가운데에 둔다 */
@media (max-width: 820px) {
  main.page.auth-main { width: auto; padding: 72px 24px 32px; }
  .auth-visual { display: none; }
}

/* 가입·로그인 처리 중 버튼 전체를 반투명하게 표시한다. */
.auth-main #submitBtn {
  display: flex; align-items: center; justify-content: center;
  transition: opacity 220ms ease;
}
.auth-main #submitBtn:disabled { opacity: 1; }
.auth-main #submitBtn.is-loading { opacity: 0.55; }
@media (prefers-reduced-motion: reduce) {
  .auth-main #submitBtn { transition: none; }
}
