:root {
  color-scheme: dark;             /* 네이티브 select·checkbox·스크롤바를 다크로. 없으면 라이트 모드로 렌더된다 */

  --bg: #0B0A14;
  --panel: rgba(255, 255, 255, 0.055);
  --panel-solid: #15131F;
  --edge: rgba(255, 255, 255, 0.12);
  --edge-soft: rgba(255, 255, 255, 0.07);   /* 패널 외곽 — 목업의 유리 테두리 */
  --ink: #EDEBF5;                 /* --bg 대비 16.67:1 */
  --sub: #9A96B5;                 /*  6.9:1 */
  --quiet: #C7C3DA;               /* 11.47:1 — 비활성 탭·라벨 */
  /* --sub 아래의 세 번째 텍스트 단계는 두지 않는다. 지면에서 5.66:1 인 색은 이 화면의
     반투명 흰 리프트(선택 탭·내 자리 0.085, hover 0.045~0.105) 위에서 4.1~4.3 으로
     떨어져 AA 를 넘지 못하고, 넘기려면 --sub 와 구분되지 않는 값이 된다(T14 리뷰 I-3·M-2).
     더 흐린 단계가 필요해 보이면 색이 아닌 다른 축(배경·테두리)을 쓸 것. */
  --ether: #6BE3F5;               /* 13.05:1 — 이 지면에서는 12px 텍스트에 써도 AA를 넘는다 */
  --amethyst: #A66BF5;            /*  5.66:1 */
  /* 직업색 9종. 명단·구성표·포스 카드·캡처가 전부 이 토큰을 쓴다.
     괄호 안은 지면(#0B0A14) 대비다. 세 배경(지면·내 자리 흰 0.085·hover 흰 0.105) 전부에서
     AA 를 넘도록 골랐고, 가장 빡빡한 정령성이 hover 에서 5.17:1 이다.
     값을 바꾸는 사람은 세 배경 전부에서 다시 재라 — shared/rules.js 의 CLASSES 와 짝이다. */
  --cls-guardian: #6BA8F5;        /*  8.00:1  수호성 파랑 */
  --cls-sword:    #5FD8F0;        /* 11.77:1  검성 하늘 */
  --cls-assassin: #B6E86A;        /* 13.80:1  살성 연두 */
  --cls-sorcerer: #CBAEFF;        /* 10.34:1  마도성 연보라 */
  --cls-spirit:   #B07CF7;        /*  6.62:1  정령성 보라 */
  --cls-ranger:   #5CE39A;        /* 12.09:1  궁성 초록 */
  --cls-fighter:  #FF8A85;        /*  8.64:1  권성 빨강 */
  --cls-chanter:  #FFAE5C;        /* 10.73:1  호법성 주황 */
  --cls-cleric:   #FFDF6B;        /* 15.00:1  치유성 노랑 */
  --cls-etc:      #C7C3DA;        /* 11.47:1  표에 없는 직업 — 중립 */
  --radius-panel: 16px;
  --radius-slot: 10px;
  --shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  --display: 'Sora', 'Pretendard', system-ui, sans-serif;
  --body: 'Pretendard', system-ui, -apple-system, 'Malgun Gothic', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, Consolas, monospace;
}

* { box-sizing: border-box; }

html { background: var(--bg); }

body {
  margin: 0;
  color: var(--ink);
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.5;
  min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* 대각 광원 한 겹 + 미세 노이즈(2.6%). position: fixed 가 중요하다 —
   body 배경에 두면 100칸 보드에서 문서가 수천 px 로 늘어나 광원이 페이지 전체에 퍼진 얼룩이 된다. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    radial-gradient(58% 46% at 6% -6%, rgba(166, 107, 245, 0.20), rgba(166, 107, 245, 0) 68%),
    linear-gradient(147deg, rgba(140, 150, 255, 0.085) 0%, rgba(107, 227, 245, 0.035) 22%, rgba(11, 10, 20, 0) 46%);
}
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.026;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 140px 140px;
}

.mono {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

h1, h2, h3 { font-family: var(--display); font-weight: 600; margin: 0; }
/* --sub 를 opacity 로 흐리면(구: rgba(154,150,181,.5)) 2.52:1 로 AA 미달이 된다 — 위 --dim 의
   원칙("opacity 로 흐리게 하지 않는다")과 같은 이유로 불투명한 --sub 를 그대로 쓴다. */
.sep { color: var(--sub); font-size: 12px; }

/* ── 유리 재질 ── */
.panel {
  position: relative;
  background: var(--panel);
  -webkit-backdrop-filter: blur(20px) saturate(125%);
  backdrop-filter: blur(20px) saturate(125%);
  border: 1px solid var(--edge-soft);
  border-radius: var(--radius-panel);
  box-shadow: 0 32px 64px -32px rgba(0, 0, 0, 0.9);
}
/* 1px 광택 — 유리 상단 모서리에 걸린 빛. 이것이 없으면 반투명 사각형으로만 보인다. */
.panel::after {
  content: '';
  position: absolute;
  left: 16px;
  right: 16px;
  top: 0;
  height: 1px;
  pointer-events: none;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.30) 26%, rgba(255, 255, 255, 0.10) 66%, rgba(255, 255, 255, 0));
}

/* ── 컨트롤 ── */
button { font: inherit; color: inherit; cursor: pointer; }
input, select, textarea { font: inherit; color: var(--ink); }
input[type="checkbox"] { accent-color: var(--ether); }

/* 열린 select 목록의 바탕은 반드시 직접 칠한다.
   :root 의 color-scheme: dark 로 충분해 보이지만 아니다 — 닫힌 컨트롤은 우리 CSS 가
   그리는 반면 펼쳐진 목록은 브라우저가 자기 창으로 그리고, 브라우저·OS 테마가 밝으면
   그 창은 흰 바탕으로 나온다. 그런데 글자색은 위 줄의 var(--ink) 가 상속되므로
   흰 바탕에 흰 글자가 되어 서버 목록이 통째로 안 읽혔다(실제 배포에서 그랬다).
   바탕을 못 박아 브라우저 테마와 무관하게 같은 대비를 만든다. */
select option,
select optgroup {
  background-color: var(--panel-solid);   /* #15131F — --ink 대비 14.3:1 */
  color: var(--ink);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 34px;
  padding: 0 14px;
  border: 1px solid var(--edge);
  border-radius: var(--radius-slot);
  background: rgba(255, 255, 255, 0.085);
  color: var(--ink);
  font-family: var(--body);
  font-size: 13px;
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14);
  transition: background 160ms ease, border-color 160ms ease;
}
.btn:hover { background: rgba(255, 255, 255, 0.125); }

/* 미참여·긍정 동작 = 솔리드. 기본형보다 한 단 밝은 면만 쓰고 액센트는 쓰지 않는다. */
.btn-primary { background: rgba(255, 255, 255, 0.11); }

/* 결정 14 — 미참여는 솔리드(.btn-primary), 참여 중은 외곽선 + 시안 틴트 + 점.
   글자를 읽지 않고도 내 참여 여부가 보여야 한다. */
.btn-joined {
  border-color: rgba(107, 227, 245, 0.42);
  background: rgba(107, 227, 245, 0.085);
}
.btn-joined::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ether);
  box-shadow: 0 0 8px rgba(107, 227, 245, 0.9);
}
.btn-joined .mono { color: var(--ether); font-weight: 500; }

/* .btn 과 함께 쓴다(class="btn btn-quiet"). 뒤에 선언해 배경·그림자를 덮는다. */
.btn-quiet {
  padding: 0 12px;
  border-color: var(--edge-soft);
  background: transparent;
  box-shadow: none;
  color: var(--sub);
  font-size: 12px;
  font-weight: 500;
  transition: color 160ms ease, border-color 160ms ease;
}
.btn-quiet:hover { background: transparent; color: var(--ink); border-color: var(--edge); }
.btn:disabled { opacity: 0.55; cursor: default; }
.btn:disabled:hover { background: rgba(255, 255, 255, 0.085); }
/* .btn:disabled:hover 와 특이성이 같아(0,3,0) 소스 순서로 이겨야 한다 — 없으면 비활성 quiet
   버튼(T17 운영 화면)에 마우스를 올릴 때 투명이어야 할 배경이 오히려 밝아진다. */
.btn-quiet:disabled:hover { background: transparent; }

/* ── 토스트 ── */
.toasts {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  z-index: 60;
  display: grid;
  gap: 8px;
  justify-items: center;
  pointer-events: none;
}
.toast {
  padding: 10px 16px;
  border: 1px solid var(--edge);
  border-radius: var(--radius-slot);
  background: var(--panel-solid);
  color: var(--ink);
  font-size: 13px;
  box-shadow: var(--shadow);
}
.toast-error { border-color: rgba(166, 107, 245, 0.45); }
/* toast(msg, kind) 의 kind 값을 새로 늘리는 태스크는 .toast-<kind> 정의를 함께 넣는다.
   .toast 베이스가 이미 완전히 스타일하므로 정의가 없어도 깨지지는 않지만(예: 기본값 'info'),
   새 kind 에 색 구분이 필요하면 여기 옆에 추가한다. */

/* ── 셸 ── */
.layout {
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr);
  gap: 16px;
  /* 1216px 이면 216px 사이드바를 빼고 .view 가 어느 폭에서든 944px 로 고정돼, 레이드 컬럼
     3열에 필요한 988px(3×320+28)에 44px 모자라 세 번째 컬럼이 아래로 내려갔다(T14 리뷰 I-1).
     스펙 8-2 는 데스크톱 가로 나열을 요구한다. 1366px 이상에서 3열 1행이 되는 폭으로 넓힌다. */
  max-width: 1560px;
  margin: 0 auto;
  padding: 20px;
}
.side {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: 16px;
  align-self: start;
  position: sticky;
  top: 20px;
}
/* ── 브랜드 ──
   표식은 사이드바 맨 위와 로그인 카드, 딱 두 곳에만 둔다. 같은 문양을 화면 여기저기
   반복하는 순간 문양은 배경이 되고 아무도 보지 않는다. */
.brand {
  margin: 0;
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 10px;
  row-gap: 1px;
  padding: 4px 0 14px;
  border-bottom: 1px solid var(--edge-soft);
}
.brand .tree-mark { grid-row: 1 / span 2; }

.tree-mark {
  width: var(--mark-size, 30px);
  height: calc(var(--mark-size, 30px) * 30 / 24);   /* viewBox 24×30 비율 */
  overflow: visible;                                 /* 뿌리 끝이 잘리지 않게 */
  /* 선만 있는 그림은 유리 패널 위에서 떠 보이지 않는다. 아주 옅은 후광 한 겹만. */
  filter: drop-shadow(0 0 10px rgba(107, 227, 245, 0.22));
}

.brand-name { font-family: var(--display); font-weight: 600; font-size: 19px; letter-spacing: 0.26em; line-height: 1.1; }
/* 조직 이름이 커진 만큼 서비스 이름은 한 단 내린다 — 둘 다 크면 무엇이 이름인지 알 수 없다. */
.brand-sub { font-size: 11px; font-weight: 500; color: var(--sub); letter-spacing: 0.01em; }
.tabs { display: flex; flex-direction: column; gap: 4px; }
.tab {
  height: 36px;
  padding: 0 12px;
  text-align: left;
  border: 1px solid transparent;
  border-radius: var(--radius-slot);
  background: transparent;
  color: var(--quiet);
  font-size: 13px;
  font-weight: 500;
  transition: background 160ms ease, color 160ms ease;
}
.tab:hover { background: rgba(255, 255, 255, 0.045); }
.tab.is-on {
  background: rgba(255, 255, 255, 0.085);
  border-color: var(--edge);
  color: var(--ink);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16);
}
.side-foot { margin-top: auto; display: grid; gap: 8px; }
.who { margin: 0; font-size: 13px; font-weight: 600; }
.view { min-width: 0; }
/* .panel 로 감싸이지 않고 지면에 직접 놓인다. body::before 의 radial 중심(6% -6%, 좌상단)과
   겹치는 위치라 이 파일에서 대비가 가장 타이트한 조합이다(실측 4.78:1, 통과). 광원 알파를
   올리는 변경이 생기면 이 조합을 다시 재야 한다. */
.loading, .fatal { color: var(--sub); padding: 28px 4px; font-size: 13px; }

/* ── 로그인 ── */
.login { min-height: 100vh; display: grid; place-items: center; padding: 24px; }
.login-card { width: min(400px, 100%); padding: 28px 26px 24px; display: grid; gap: 14px; }
/* 로그인 카드는 이 서비스의 첫 화면이라 표식이 한 번 더 나온다. 셸의 사이드바와는
   다른 화면이므로 문양이 두 번 보이는 일은 없다. 여기서는 세로로 세워 중앙에 놓는다. */
.login-brand { display: grid; justify-items: center; gap: 10px; padding-top: 4px; }
.login-brand .tree-mark { --mark-size: 46px; }
.login-title { font-size: 26px; letter-spacing: 0.3em; text-indent: 0.3em; }   /* 자간 때문에 오른쪽으로 쏠리는 것을 되돌린다 */
.login-sub { margin: -4px 0 4px; color: var(--sub); font-size: 13px; text-align: center; }
.login-races { display: flex; gap: 8px; }
.race {
  flex: 1;
  height: 40px;
  border: 1px solid var(--edge);
  border-radius: var(--radius-slot);
  background: transparent;
  color: var(--sub);
  font-size: 13px;
  font-weight: 600;
  transition: background 160ms ease, color 160ms ease;
}
.race.is-on {
  background: rgba(107, 227, 245, 0.085);
  border-color: rgba(107, 227, 245, 0.42);
  color: var(--ink);
}
.field { display: grid; gap: 6px; font-size: 12px; color: var(--sub); }
.field input, .field select {
  height: 40px;
  padding: 0 10px;
  border: 1px solid var(--edge);
  border-radius: var(--radius-slot);
  background: rgba(255, 255, 255, 0.04);
  font-size: 14px;
}
.login-error { margin: 0; color: #F5A6A6; font-size: 12.5px; }   /* #0B0A14 대비 10.20:1 */
.login-card .btn { width: 100%; height: 40px; }

/* ── 직업색 ──
   .cls-<slug> 하나가 그 요소와 후손의 --cls 를 정한다. 색을 쓰는 쪽(명단 글자·광선·포스 카드·
   구성표)은 전부 var(--cls) 를 읽으므로, 화면마다 9줄씩 베끼지 않는다. */
.cls-guardian { --cls: var(--cls-guardian); }
.cls-sword    { --cls: var(--cls-sword); }
.cls-assassin { --cls: var(--cls-assassin); }
.cls-sorcerer { --cls: var(--cls-sorcerer); }
.cls-spirit   { --cls: var(--cls-spirit); }
.cls-ranger   { --cls: var(--cls-ranger); }
.cls-fighter  { --cls: var(--cls-fighter); }
.cls-chanter  { --cls: var(--cls-chanter); }
.cls-cleric   { --cls: var(--cls-cleric); }
.cls-etc      { --cls: var(--cls-etc); }

/* 구성표·포스 카드의 직업 배지는 이 한 규칙을 공유한다. */
.col-classes b, .fc-card-classes b { color: var(--cls); }

/* ── 접근성 ── */
:focus-visible { outline: 2px solid var(--ether); outline-offset: 2px; }

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ── 모바일: 사이드바를 하단 고정 탭바로 (스펙 8-0) ── */
@media (max-width: 720px) {
  .layout { grid-template-columns: minmax(0, 1fr); padding: 14px 14px 78px; }
  .side {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 50;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border-radius: var(--radius-panel) var(--radius-panel) 0 0;
    border-bottom: 0;
    background: rgba(21, 19, 31, 0.92);
  }
  .brand { display: none; }
  .tabs { flex: 1; flex-direction: row; }
  .tab { flex: 1; height: 44px; text-align: center; }
  .side-foot { margin: 0; }
  .side-foot .who { display: none; }   /* 유저 이름은 보드 상단 주차 스트립에 이미 있다 */
}
