Files
ProjectSS/client/src/core/components/DeskBar.css
T
kyoung5seoandClaude Sonnet 5 6398599199 규약 세부화(유형D·13석 표결·툴팁) + 밸런스 피드백 5건 반영
같은 날 두 차례 플레이테스트에서 나온 이슈를 이어서 처리했다.

**의회 세부화**
- 유형 D(이득 규약) 5종 신설 — 토큰 지급/게이지 완화/지출 가산 완화/
  주목도 한도 증가/실적 요구치 하향. 내부 명분("강제 상정")이 여태 불리한
  유형 A만 올릴 수 있어 실속 없던 문제를 해결 — 상정 풀에 D가 포함되는 게
  내부 명분이 존재하는 이유
- 13석 표결을 실제 표 수로 구현(tallyVotes, 최대잔여법 + 결정적 해시).
  혼합 명분이 "직접 통과 지정" 자리표시자에서 §7.3 스펙대로 실제 1표
  이동으로 교체 — 동점은 스윙 전 득표가 많던 쪽이 이겨 1표 차에서만 뒤집힘.
  의회 화면에 후보별 예상 득표·표 차·뒤집기 가능 여부를 미리 노출
- 공보 축 오염 선택지 1→7개로 보강(서사 기준 6개 재배정), 축 분포 균형화

**툴팁 신설 (InfoTooltip·ProtocolChip)**
- 규약·징벌·명분을 클릭하면 정확히 무엇이 막혔는지 설명이 뜬다. 문구는
  UI가 추측하지 않고 council.js의 protocolEffectDetail·justificationDetail이
  카탈로그에서 생성. 모바일 대상이라 hover가 아닌 클릭으로 연다

**크리티컬 버그: 주목도 미초기화**
- 라운드 종료 후 한도 판정에 총 주목도(이월 포함)를 쓰고 있어, 2라운드가
  시작하자마자 이미 한도를 넘어 버스트가 무한 반복되고 있었다. 한도 판정은
  "이번 라운드에 받은 카드"만 세도록 분리(roundAttention), 게이지·토큰
  가산은 기존대로 총계(이월 포함) 기준 유지

**밸런스 피드백 5건**
- 결재 카드가 고정으로 보인다는 지적 → 실제 버그였다. cardIndex를 그냥
  +1씩 돌려 CSV 순서 그대로 결정론적으로 반복되고 있었다. Fisher–Yates
  셔플 큐로 교체(큐 소진 시 재셔플)
- 위협 축도 거의 안 나온다 → 위 셔플 버그가 원인의 상당 부분. 명백한
  오배정 1건도 발견해 수정(id11 "군사 개입 지시": 고대 신 소환 저지가
  인사 축으로 잘못 들어가 있었음 → 위협 축)
- 게이지 상승이 너무 낮음 → 등급 합계(주목도) 단독 기준이 실제 카드
  등급 분포(대부분 1~4급)와 맞지 않아 3~4장을 쌓아도 최하 구간을 못
  벗어났다. 카드 장수를 1차 기준으로 되돌리고 등급 배율(평균등급/5)을
  곱하는 방식으로 재설계 — 3~4장 구간에서 6배 점프(0.5%→3.0%)
- 좌우 모두 오염 없는 완전 무행동 카드 1건(id15) 수정 — 좌측에 대외/6급
  부여(기존 tag_corruption과 정합)
- 오염 카드 한쪽만 있어 안전 선택 메리트가 없다는 지적은 카드 데이터가
  아니라 게이지 곡선 문제로 판단, 위 재설계로 해결(카드 재배분 안 함)

**문서**
- 결정 노트 2건: 2026-09-17-주목도-라운드-분리,
  2026-09-17-게이지상승-장수기준-복원(기각한 대안 포함)
- 기획서 §4.2-A/B, §7.3, §9.2, §17 갱신. DEVLOG 2건 기록

Playwright로 전 구간 검증: 셔플(3회 재접속 시 다른 카드, 15연속 무반복),
게이지 상승률 표시, 13석 표결 예상치, 규약/명분 툴팁, 2라운드 진입 시
주목도 0으로 리셋 확인. 콘솔 에러 0건, 빌드 클린.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-17 23:00:42 +09:00

174 lines
3.3 KiB
CSS

.desk-bar {
display: flex;
flex-direction: column;
gap: 6px;
padding: 10px 16px;
background: var(--color-surface);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
font-family: var(--font-typewriter);
}
/* 경고/한도초과(bust) 구간을 테두리로 알린다 (§4.2-B) — bust는 실제로 라운드를 강제 종료시킨다. */
.desk-bar.zone-warning { border-bottom-color: var(--color-risk-critical); }
.desk-bar.zone-bust { border-bottom-color: var(--color-entropy-critical); }
.desk-bar-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
flex-wrap: wrap;
}
.desk-total {
font-size: 13px;
}
.desk-attention {
font-weight: 700;
font-size: 14px;
}
.zone-warning .desk-attention { color: var(--color-risk-critical); }
.zone-bust .desk-attention { color: var(--color-entropy-critical); }
.desk-surcharge { color: var(--color-risk-critical); }
.desk-tokens { opacity: 0.8; }
.desk-zone-banner {
font-size: 11px;
padding: 4px 8px;
border-radius: 4px;
background: rgba(255, 215, 0, 0.1);
color: var(--color-risk-critical);
}
.zone-bust .desk-zone-banner {
background: rgba(139, 0, 0, 0.18);
color: #ff8a80;
}
.desk-bar-actions {
display: flex;
gap: 8px;
}
.desk-guide-btn,
.desk-combine-btn {
font-family: var(--font-typewriter);
border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 4px;
padding: 7px 12px;
font-weight: 700;
cursor: pointer;
white-space: nowrap;
font-size: 12px;
}
.desk-guide-btn {
background: transparent;
color: var(--color-text);
}
.desk-combine-btn {
background: var(--color-token-budget);
color: #0a0a0a;
border-color: transparent;
}
.desk-combine-btn:disabled {
background: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.35);
cursor: not-allowed;
}
.desk-bar-rows {
display: flex;
flex-direction: column;
gap: 3px;
}
.desk-row {
display: flex;
align-items: center;
gap: 8px;
background: none;
border: none;
color: var(--color-text);
padding: 3px 4px;
border-radius: 4px;
cursor: pointer;
text-align: left;
width: 100%;
font-family: var(--font-typewriter);
}
.desk-row:not(:disabled):hover {
background: rgba(255, 255, 255, 0.05);
}
.desk-row:disabled {
cursor: default;
opacity: 0.5;
}
.desk-row-name {
font-size: 11px;
width: 28px;
flex-shrink: 0;
opacity: 0.75;
}
/* 축별 주목도 — 이 숫자가 게이지 상승률을 결정하므로 장수보다 크게 보여야 한다.
등급 칩과 값이 같을 때 붙어 보이지 않도록 배경을 줘서 분리한다. */
.desk-row-attention {
font-size: 13px;
font-weight: 700;
min-width: 30px;
text-align: center;
flex-shrink: 0;
background: rgba(255, 255, 255, 0.1);
border-radius: 4px;
padding: 1px 4px;
}
.desk-row-chips {
display: flex;
gap: 4px;
flex: 1;
flex-wrap: wrap;
min-width: 0;
}
.desk-chip {
font-size: 11px;
background: rgba(255, 255, 255, 0.07);
padding: 1px 6px;
border-radius: 4px;
white-space: nowrap;
}
.desk-chip.more { opacity: 0.55; }
.desk-row-empty {
font-size: 11px;
opacity: 0.35;
}
.desk-row-gauge {
font-size: 11px;
opacity: 0.65;
white-space: nowrap;
flex-shrink: 0;
}
.desk-row-rate {
color: var(--color-risk-critical);
opacity: 1;
}
.desk-carried {
opacity: 0.55;
font-size: 11px;
}