/* space — Pay2win CTF
 *
 * core 의 번들 위에 얹는다. core 를 고치지 않고 토큰과 표면만 덮어쓴다.
 * 외부 CDN 을 쓰지 않는다(HTTP 평문 서빙이라 혼합 콘텐츠가 된다). 폰트는 시스템 폰트만.
 */

:root {
  /* 바탕 — 우주 */
  --sp-void:        #05060e;
  --sp-deep:        #0a0d1c;
  --sp-panel:       #111528;
  --sp-line:        #1f2742;

  /* 글자 */
  --sp-text:        #dfe5f5;
  --sp-dim:         #8b96b8;
  --sp-faint:       #5a6386;

  /* 항성 색 — 분야별. 명도를 맞춰 색각 이상에서도 형태로 구분되게 한다 */
  --sp-crypto:      #7ab8ff;
  --sp-web:         #ff8fa3;
  --sp-rev:         #ffc46b;
  --sp-pwn:         #ff6b6b;
  --sp-forensic:    #6ee7c7;
  --sp-misc:        #c89bff;
  --sp-scenario:    #b8e986;   /* 시나리오 체인 — 여섯 분야와 겹치지 않는 색 */

  --sp-solved:      #ffe9a8;   /* 점화된 별 */
  --sp-blood:       #ff4d6d;   /* 퍼스트 블러드 */

  --sp-glow:        0 0 12px rgba(255, 233, 168, .55), 0 0 28px rgba(255, 233, 168, .22);
}

/* ── 바탕 하늘 ───────────────────────────────────────────────────────────── */
body.space-body {
  background: var(--sp-void);
  color: var(--sp-text);
  min-height: 100vh;
}

.space-sky {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  background:
    radial-gradient(1200px 800px at 15% -10%, #121a3a 0%, transparent 60%),
    radial-gradient(900px 700px at 85% 110%, #1a1030 0%, transparent 60%),
    var(--sp-void);
}

.space-nebula {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: .32;
}
.space-nebula--a { width: 46vw; height: 46vw; left: -8vw;  top: -10vw;  background: #2b4cff; }
.space-nebula--b { width: 38vw; height: 38vw; right: -6vw; bottom: -8vw; background: #8b2bff; }

/* 별가루 — 이미지가 아니라 그라디언트라 요청이 0개다 */
.space-stars { position: absolute; inset: 0; }
.space-stars--far {
  opacity: .5;
  background-image:
    radial-gradient(1px 1px at 12% 22%, #fff, transparent),
    radial-gradient(1px 1px at 68% 14%, #fff, transparent),
    radial-gradient(1px 1px at 36% 71%, #fff, transparent),
    radial-gradient(1px 1px at 88% 58%, #fff, transparent),
    radial-gradient(1px 1px at 52% 44%, #fff, transparent),
    radial-gradient(1px 1px at 22% 88%, #fff, transparent),
    radial-gradient(1px 1px at 78% 92%, #fff, transparent);
  background-size: 100% 100%;
}
.space-stars--near {
  opacity: .75;
  background-image:
    radial-gradient(1.6px 1.6px at 29% 36%, #cfe0ff, transparent),
    radial-gradient(1.6px 1.6px at 72% 68%, #cfe0ff, transparent),
    radial-gradient(1.6px 1.6px at 46% 12%, #cfe0ff, transparent),
    radial-gradient(1.6px 1.6px at 8% 62%, #cfe0ff, transparent);
  animation: sp-drift 140s linear infinite;
}
@keyframes sp-drift { to { transform: translate3d(-2%, 1.5%, 0); } }

/* 움직임을 줄여 달라고 한 사람에게는 전부 멈춘다 */
@media (prefers-reduced-motion: reduce) {
  .space-stars--near { animation: none; }
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important;
      transition-duration: .001ms !important; }
}

/* ── core 표면 덮어쓰기 ──────────────────────────────────────────────────── */
.navbar, .footer { background: rgba(10, 13, 28, .72) !important; backdrop-filter: blur(10px); }
.navbar { border-bottom: 1px solid var(--sp-line); }
.footer { border-top: 1px solid var(--sp-line); }

.jumbotron {
  background: transparent !important;
  border-bottom: 1px solid var(--sp-line);
  padding: 3rem 0 2rem;
}
.jumbotron h1 {
  letter-spacing: .14em;
  text-transform: uppercase;
  font-weight: 600;
  text-shadow: 0 0 24px rgba(122, 184, 255, .35);
}

/* 문제 모달. core 가 .modal-dialog 에 크기 클래스를 안 붙여서 부트스트랩 기본 500px 로
   나온다 — 제목이 두 줄로 쪼개지고 본문이 한 줄에 열 몇 글자밖에 안 들어간다.
   인스턴스 패널(접속 정보·버튼)도 이 안에 그려지므로 넓은 쪽이 맞다. */
#challenge-window .modal-dialog { max-width: min(920px, calc(100vw - 3rem)); }

/* 배점은 숫자만 나온다 — 0점 브리핑에서는 제목 밑에 '0' 하나만 떠서 오타처럼 보인다.
   단위를 붙여 의도된 표기로 만든다. */
#challenge-window .challenge-value::after {
  content: " pts"; font-size: .6em; opacity: .65; letter-spacing: .06em;
}

.modal-content, .card, .list-group-item {
  background: rgba(17, 21, 40, .92) !important;
  border: 1px solid var(--sp-line) !important;
  backdrop-filter: blur(6px);
}

/* ── 성도(星圖) 보드 ─────────────────────────────────────────────────────── */
.sp-board { padding: 1rem 0 4rem; }

.sp-board-bar {
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
  margin: 0 0 1.25rem; padding-bottom: .75rem;
  border-bottom: 1px solid var(--sp-line);
}
.sp-board-bar .sp-count { color: var(--sp-dim); font-size: 1.05rem; letter-spacing: .02em; }
.sp-board-bar .sp-spacer { margin-left: auto; }

.sp-viewtoggle { display: inline-flex; border: 1px solid var(--sp-line); border-radius: 999px; overflow: hidden; }
.sp-viewtoggle button {
  background: transparent; border: 0; color: var(--sp-faint);
  padding: .42rem 1.15rem; font-size: .95rem; letter-spacing: .08em; text-transform: uppercase;
}
.sp-viewtoggle button[aria-pressed="true"] { background: rgba(122, 184, 255, .16); color: var(--sp-text); }
.sp-viewtoggle button:focus-visible { outline: 2px solid var(--sp-crypto); outline-offset: -2px; }

/* 별자리 하나 = 분야 하나 */
.sp-constellations {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(540px, 1fr));
  gap: 1.5rem;
}
.sp-constellation {
  position: relative;
  border: 1px solid var(--sp-line);
  border-radius: 14px;
  background: rgba(10, 13, 28, .55);
  padding: 1.1rem 1.25rem 1.3rem;
  min-height: 250px;
}
.sp-constellation:focus-within { border-color: var(--sp-faint); }

.sp-con-head {
  display: flex; align-items: baseline; gap: .6rem;
  margin-bottom: .25rem;
}
.sp-con-name {
  font-size: 1.02rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--sp-cat, var(--sp-dim)); font-weight: 600;
}
.sp-con-progress { font-size: .95rem; color: var(--sp-faint); margin-left: auto; font-variant-numeric: tabular-nums; }

.sp-con-svg { display: block; width: 100%; height: auto; overflow: visible; }

/* 별자리 선 — 아직 안 푼 구간은 흐리게, 이어진 구간은 밝게 */
.sp-link { stroke: var(--sp-line); stroke-width: 1; }
.sp-link.is-lit { stroke: var(--sp-cat, var(--sp-dim)); stroke-opacity: .55; }

/* 별 하나 = 문제 하나 — 실사형(중심핵 + 회절 십자 + 광륜) */
.sp-star { cursor: pointer; }
.sp-star:focus { outline: none; }
.sp-star-hit { fill: transparent; }
.sp-star:focus-visible .sp-star-hit {
  stroke: var(--sp-text); stroke-width: 1.5; stroke-dasharray: 3 3;
}

/* color 는 JS 가 분광형에 따라 넣는다. 조각들이 그 색을 따라간다. */
.sp-realstar   { transition: opacity .18s ease; }
.sp-star-core  { fill: currentColor; }
.sp-star-spikes{ fill: currentColor; opacity: .72; }
.sp-star-diag  { fill: currentColor; opacity: .45; }
.sp-star-glow  { pointer-events: none; }

/* 미해결 — 식별은 되지만 가라앉아 보인다 */
.sp-star:not(.is-solved) .sp-realstar { opacity: .6; }
.sp-star:hover .sp-realstar { opacity: 1; }

/* 점화 — 내가 푼 문제. 색만으로 구분하지 않도록 고리를 같이 준다 */
.sp-star.is-solved .sp-realstar { opacity: 1; }
.sp-star.is-solved .sp-star-core { filter: drop-shadow(0 0 4px currentColor); }
.sp-star-ring { fill: none; stroke: currentColor; stroke-opacity: .45; stroke-width: 1; }

/* 방금 공개된 문제 — 회차 공개 순간의 연출 */
.sp-star.is-new .sp-star-core { animation: sp-ignite 1.6s ease-out 2; }
@keyframes sp-ignite {
  0%   { filter: drop-shadow(0 0 0 rgba(223, 229, 245, 0)); }
  40%  { filter: drop-shadow(0 0 10px rgba(223, 229, 245, .9)); }
  100% { filter: drop-shadow(0 0 0 rgba(223, 229, 245, 0)); }
}

.sp-star-label {
  fill: var(--sp-dim); font-size: 10.5px; letter-spacing: .02em;
  pointer-events: none; text-anchor: middle;
}
.sp-star.is-solved .sp-star-label { fill: var(--sp-text); }
.sp-star-value {
  fill: var(--sp-faint); font-size: 9px; text-anchor: middle;
  font-variant-numeric: tabular-nums; pointer-events: none;
}

/* ── 조밀 목록 뷰 — 성도가 부담스러울 때 한 번에 전환 ──────────────────────── */
.sp-list { width: 100%; border-collapse: collapse; }
.sp-list th, .sp-list td {
  padding: .62rem .75rem; border-bottom: 1px solid var(--sp-line); font-size: 1.02rem; text-align: left;
}
.sp-list th {
  color: var(--sp-faint); font-size: .86rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 600;
}
.sp-list tbody tr:hover { background: rgba(122, 184, 255, .07); }
.sp-list .sp-list-name { background: none; border: 0; color: var(--sp-text); padding: 0; text-align: left; }
.sp-list .sp-list-name:hover { text-decoration: underline; }
.sp-list tr.is-solved .sp-list-name { color: var(--sp-solved); }
.sp-list .sp-cat-dot {
  display: inline-block; width: .55rem; height: .55rem; border-radius: 50%;
  background: var(--sp-cat, var(--sp-dim)); margin-right: .5rem; vertical-align: baseline;
}
.sp-list .sp-num { font-variant-numeric: tabular-nums; color: var(--sp-dim); }

/* JS 가 죽었을 때 — Alpine 이 못 뜨면 이 안내가 남는다 */
.sp-nojs { border: 1px dashed var(--sp-line); border-radius: 10px; padding: 1rem; color: var(--sp-dim); }

@media (max-width: 991.98px) {
  .sp-constellations { grid-template-columns: 1fr; }
}
@media (max-width: 575.98px) {
  .sp-constellations { grid-template-columns: 1fr; }
  .sp-constellation { min-height: 0; }
}

/* ── 분광형 범례 ─────────────────────────────────────────────────────────── */
.sp-legend { display: flex; align-items: center; gap: .5rem; font-size: .74rem; color: var(--sp-faint); }
.sp-legend-bar {
  width: 120px; height: .5rem; border-radius: 999px;
  background: linear-gradient(90deg,#9bb0ff,#aabfff,#cad8ff,#f6f3ff,#fff4e8,#ffd2a1,#ff9d5c);
}

/* 스코어보드 매트릭스의 별은 matrix.css 가 소유한다 — 이 파일은 전 페이지에 걸리므로 분리한다. */

/* 목록 뷰 — 분야 경계를 선으로 끊는다 */
.sp-list tbody tr.sp-group-top td { border-top: 2px solid var(--sp-cat, var(--sp-line)); padding-top: .7rem; }
.sp-list tbody tr.sp-group-top:first-child td { border-top: 0; }
.sp-list .sp-list-cat {
  white-space: nowrap; color: var(--sp-cat, var(--sp-dim));
  font-size: .85rem; letter-spacing: .12em; text-transform: uppercase; font-weight: 600;
  vertical-align: top; width: 11rem;
}
.sp-list tbody tr:not(.sp-group-top) td { border-bottom-color: rgba(31,39,66,.45); }
