/* ==========================================================================
   Design tokens
   ========================================================================== */
:root {
    --color-bg: #f5f6f8;
    --color-surface: #ffffff;
    --color-text: #212529;
    --color-muted: #6b7280;
    --color-border: #e5e7eb;
    --color-primary: #2f3542;
    --color-primary-hover: #1e232c;
    --color-accent: #4f7cff;
    --color-danger: #e74c3c;
    --radius: 8px;
    --spacing-1: 4px;
    --spacing-2: 8px;
    --spacing-3: 16px;
    --spacing-4: 24px;
    --spacing-5: 32px;
    --max-width: 1080px;
}

* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: 'Malgun Gothic', 'Apple SD Gothic Neo', sans-serif;
    font-size: 16px;
    line-height: 1.5;
    /* Safety net: vertical scrolling is fine, but nothing should ever be able to push the
       page itself wider than the viewport - any element that would have now just clips/
       scrolls locally instead (tables already do this via .table-wrapper).
       "clip" (not "hidden") specifically because overflow:hidden turns body into a scroll
       container, which silently breaks position:sticky for every descendant (the header). */
    overflow-x: clip;
}

a { color: inherit; }

img { max-width: 100%; display: block; }

/* ==========================================================================
   Layout
   ========================================================================== */
.container {
    width: 100%;
    max-width: var(--max-width);
    margin: 0 auto;
    padding: var(--spacing-4) var(--spacing-3);
}

.site-main {
    min-height: calc(100vh - 60px);
}

/* ==========================================================================
   Nav
   ========================================================================== */
.site-nav {
    position: sticky;
    top: 0;
    z-index: 1001;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--spacing-3);
    padding: var(--spacing-2) var(--spacing-4);
    background: var(--color-primary);
    /* 진영 1등 색으로 테마가 바뀔 때 스냅되지 않고 서서히 넘어가게 - 바뀌는 게 눈에 띄어야
       "표시가 된다"는 느낌이 산다. */
    transition: background-color 1.5s ease;
}

.site-nav a, .site-nav .nav-btn {
    color: #fff;
    text-decoration: none;
    font-size: 14px;
    white-space: nowrap;
}

.site-nav a:hover, .site-nav .nav-btn:hover { text-decoration: underline; }

.site-nav .brand {
    font-weight: 700;
    font-size: 17px;
    margin-right: var(--spacing-2);
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.brand-icon { font-size: 19px; }

.nav-profile-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.nav-avatar {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.site-nav .spacer { flex: 1; }

.site-nav .nav-group {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    flex-wrap: wrap;
}

.nav-btn {
    background: none;
    border: none;
    cursor: pointer;
    font-family: inherit;
    padding: 0;
}

/* Nickname/logout stay on their existing single line; 후원하기 sits on its own row right
   below so it reads as a distinct action, not just another nav link. */
.nav-group-account {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
}
.nav-group-account-row {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
}
.nav-donate-btn {
    display: inline-block;
    background: #fff;
    color: var(--color-primary);
    border: none;
    border-radius: 4px;
    padding: 3px 10px;
    font-size: 13px;
    font-weight: 700;
    font-family: inherit;
    cursor: pointer;
}
.nav-donate-btn:hover { background: #f0f0f0; }

/* ==========================================================================
   Buttons / Forms
   ========================================================================== */
.btn {
    display: inline-block;
    padding: 10px 18px;
    border-radius: var(--radius);
    border: 1px solid var(--color-primary);
    background: var(--color-primary);
    color: #fff;
    font-size: 14px;
    cursor: pointer;
    text-decoration: none;
    text-align: center;
    transition: background-color 1.5s ease, border-color 1.5s ease;
}

.btn:hover { background: var(--color-primary-hover); }
.btn:disabled, .form-control:disabled { opacity: 0.5; cursor: not-allowed; }

.btn-outline {
    background: transparent;
    color: var(--color-primary);
}

.btn-danger {
    background: var(--color-danger);
    border-color: var(--color-danger);
}

.btn-social {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-2);
    width: 100%;
    padding: 10px 18px;
    border-radius: var(--radius);
    border: 1px solid var(--color-border);
    background: #fff;
    font-size: 14px;
    text-decoration: none;
    color: var(--color-text);
}

.btn-social.google { border-color: #dadce0; }
.btn-social.naver { background: #03c75a; color: #fff; border-color: #03c75a; }

.form-group {
    margin-bottom: var(--spacing-3);
}

.form-group label {
    display: block;
    margin-bottom: var(--spacing-1);
    font-size: 14px;
    color: var(--color-muted);
}

.form-control {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
}

.form-control.input-error {
    border-color: var(--color-danger);
    background: #fff5f5;
}

.field-error {
    color: var(--color-danger);
    font-size: 12px;
    margin: 4px 0 0;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: 400;
    cursor: pointer;
}
.checkbox-label input[type="checkbox"] { width: auto; flex-shrink: 0; }
.checkbox-label a { color: var(--color-accent); text-decoration: underline; }

.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--spacing-4);
}

/* 마이페이지의 4개 목록(내 글/내 댓글/좋아요한 글/좋아요한 댓글)이 그냥 이어붙어서 어디부터
   어디까지가 한 섹션인지 흐릿하다는 피드백 - 카드마다 위쪽에 진한 강조선을 얹어서 확실히
   구분되는 블록으로 보이게 한다. */
.mypage-section {
    margin-top: 20px;
    border-top: 3px solid var(--color-primary);
}

/* 파일 첨부 + "선택 취소" 버튼이 나란히 붙는 자리 - 게시글/댓글 작성/수정/답글 폼 전부 공용
   (동작은 footer.jsp의 전역 change/click 위임 스크립트 하나로 처리됨). */
.file-input-row {
    display: flex;
    gap: 8px;
    align-items: center;
}
.file-input-row .form-control { flex: 1 1 auto; }

/* 게시글 작성 - "뉴스 링크로 채우기"가 그냥 다른 입력칸들 사이에 묻히지 않고 눈에 띄는
   별도 유틸리티 영역으로 보이게. 노란(3초요약/법적고지)과 헷갈리지 않게 파란 계열로. */
.link-preview-section {
    background: #EFF6FF;
    border: 1px solid var(--color-accent);
    border-radius: var(--radius);
    padding: 12px 14px;
}

/* 게시글 작성 - "가져오기" 버튼으로 뉴스 링크 OG 정보를 긁어온 결과 미리보기 카드 */
.link-preview-card {
    display: flex;
    gap: 10px;
    margin-top: 8px;
    padding: 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
}
.link-preview-card img { width: 80px; height: 80px; object-fit: cover; border-radius: 6px; flex-shrink: 0; }
.link-preview-title { font-weight: 700; margin-bottom: 4px; }

.form-card {
    max-width: 420px;
    margin: var(--spacing-5) auto;
}

/* 이용약관/개인정보처리방침 - 좁은 .form-card 기본폭(420px)은 긴 문단을 읽기 힘드니 넓힌다. */
.legal-doc {
    max-width: 720px;
    line-height: 1.7;
}
.legal-doc h3 { margin-top: 28px; margin-bottom: 6px; }
.legal-doc ul { padding-left: 20px; margin: 6px 0; }
.legal-doc li { margin-bottom: 4px; }
.legal-disclaimer {
    background: #FFF6DA;
    border: 1px solid #F5C518;
    border-radius: 6px;
    padding: 10px 14px;
    font-size: 13px;
}

.form-actions { margin-top: var(--spacing-3); }

.text-muted { color: var(--color-muted); font-size: 13px; }
.text-danger { color: var(--color-danger); font-size: 13px; }

.divider {
    display: flex;
    align-items: center;
    text-align: center;
    color: var(--color-muted);
    font-size: 12px;
    margin: var(--spacing-3) 0;
}
.divider::before, .divider::after {
    content: "";
    flex: 1;
    border-bottom: 1px solid var(--color-border);
}
.divider span { padding: 0 var(--spacing-2); }

/* ==========================================================================
   Table (board list) - horizontally scrollable on narrow screens
   ========================================================================== */
.table-wrapper {
    overflow-x: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}

table.data-table {
    /* No forced min-width: the table must always fit inside the viewport (title column just
       shrinks/ellipsizes) rather than triggering horizontal scroll - see .col-narrow below. */
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

table.data-table th, table.data-table td {
    padding: 12px 16px;
    text-align: left;
    border-bottom: 1px solid var(--color-border);
    font-size: 14px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

table.data-table th {
    color: var(--color-muted);
    font-weight: 600;
    background: #fafafa;
}

/* Title gets most of the row's width; every other column is squeezed down to just-visible. */
table.data-table .col-xnarrow { width: 64px; }
table.data-table .col-narrow { width: 90px; }
table.data-table .col-medium { width: 160px; }
/* "yyyy-MM-dd HH:mm" 형식(16자)이 .col-narrow(90px)에서 잘려 보인다는 피드백을 받아서 만든
   전용 폭 - 작성일 컬럼에만 쓴다. */
table.data-table .col-date { width: 128px; white-space: nowrap; }
table.data-table .col-title { width: auto; }

@media (max-width: 600px) {
    table.data-table th, table.data-table td { padding: 8px 6px; font-size: 13px; }
    table.data-table .col-medium { width: 110px; }
    table.data-table .col-narrow { width: 56px; }
    table.data-table .col-xnarrow { width: 40px; }
    table.data-table .col-date { width: 96px; }
}

.title-link {
    display: block;
    padding: 4px 0;
    font-size: 16px;
    font-weight: 600;
    color: var(--color-text);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.title-link:hover { color: var(--color-accent); text-decoration: underline; }

/* 게시판 목록 - 뉴스 링크로 채운 글의 og:image 썸네일 (BoardController.list()가 imageUrl을 채워줌) */
.board-list-title { display: flex; align-items: center; gap: 8px; white-space: normal; }
.board-list-title span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.board-list-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; flex-shrink: 0; }

/* ==========================================================================
   List search box (board list, mypage sections)
   ========================================================================== */
.list-search-form {
    display: flex;
    gap: 8px;
    margin-bottom: var(--spacing-3);
}
.list-search-form .form-control { flex: 1 1 auto; }

/* ==========================================================================
   Pagination (board list)
   ========================================================================== */
.pagination {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    gap: 4px;
    margin: var(--spacing-4) 0;
}
.pagination a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 32px;
    height: 32px;
    padding: 0 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    text-decoration: none;
    color: var(--color-text);
    font-size: 14px;
}
.pagination a:hover { background: #f5f6f8; }
.pagination a.active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: #fff;
}

table.data-table tr.clickable-row { cursor: pointer; }
table.data-table tr.clickable-row:hover { background: #f5f6f8; }

/* ==========================================================================
   Home page "최근 게시글" row - narrowed list + static (non-floating) rank column
   ========================================================================== */
.recent-row {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-3);
}

.recent-row-main { flex: 2; min-width: 0; }

.recent-row-side {
    flex: 1 1 260px;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: var(--spacing-3);
}

.recent-side-card { padding: var(--spacing-3); }
.recent-side-card h4 { margin: 0 0 8px; font-size: 13px; color: var(--color-muted); }

@media (max-width: 900px) {
    /* align-items:flex-start above is what keeps .recent-row-main/.recent-row-side from being
       stretched to equal height side by side - but in column mode that same "flex-start" applies
       to the (now horizontal) cross axis too, shrinking each stacked item down to its content
       width instead of filling the row. Override back to stretch once we're stacked. */
    .recent-row { flex-direction: column; align-items: stretch; }
    .recent-row-side { min-width: 0; }
}

/* ==========================================================================
   Hero / Home page
   ========================================================================== */
.hero {
    background: linear-gradient(135deg, var(--color-primary), #4a5568);
    color: #fff;
    border-radius: var(--radius);
    padding: var(--spacing-5);
    margin-bottom: var(--spacing-4);
}

.hero h1 { margin: 0 0 var(--spacing-2); font-size: 28px; }
.hero p { margin: 0 0 var(--spacing-4); color: #e2e8f0; }
.hero .hero-actions { display: flex; gap: var(--spacing-3); flex-wrap: wrap; }

.feature-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--spacing-3);
    margin-bottom: var(--spacing-4);
}

.feature-grid .card h3 { margin-top: 0; }

.section-title {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: var(--spacing-2);
}

/* "글쓰기" etc. - keep it modest-sized so it doesn't dominate the header row, especially on phones. */
.section-title .btn {
    padding: 6px 14px;
    font-size: 13px;
}

@media (max-width: 480px) {
    .section-title .btn { padding: 5px 10px; font-size: 12px; }
}

/* ==========================================================================
   Tabs (home page TOP10) + ranking list
   ========================================================================== */
.tab-buttons {
    display: flex;
    gap: var(--spacing-2);
    margin-bottom: var(--spacing-3);
    border-bottom: 1px solid var(--color-border);
}

.tab-btn {
    display: inline-block;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 8px 4px;
    margin-bottom: -1px;
    font-size: 15px;
    color: var(--color-muted);
    text-decoration: none;
    cursor: pointer;
}
.tab-btn.active { color: var(--color-primary); border-bottom-color: var(--color-primary); font-weight: 600; }
.tab-btn.passed.active { color: var(--color-accent); border-bottom-color: var(--color-accent); }
.tab-btn.rejected.active { color: var(--color-danger); border-bottom-color: var(--color-danger); }

.rank-list { list-style: none; margin: 0; padding: 0; }
.rank-list li {
    border-bottom: 1px solid var(--color-border);
}
.rank-list li:last-child { border-bottom: none; }

.rank-list a, .rank-list .rank-row {
    display: flex;
    align-items: center;
    gap: var(--spacing-3);
    padding: 10px 4px;
    text-decoration: none;
    color: var(--color-text);
}

.rank-empty { padding: 10px 4px; }

.rank-no {
    flex: 0 0 24px;
    font-weight: 700;
    color: var(--color-primary);
}

.rank-title {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.rank-writer { flex: 0 0 auto; font-size: 13px; }
.rank-like { flex: 0 0 auto; color: var(--color-danger); font-size: 13px; white-space: nowrap; }

@media (max-width: 480px) {
    .rank-writer { display: none; }
    /* Same idea as .recent-row on the "최근 게시글" table: drop the padding so the row's
       content (rank number + title + count) uses the full card width edge-to-edge. */
    .recent-side-card { padding: 12px; }
    .rank-list a, .rank-list .rank-row { padding: 8px 2px; gap: var(--spacing-2); }
    .rank-no { flex-basis: 18px; font-size: 13px; }
}

/* ==========================================================================
   Comments
   ========================================================================== */
.comment-list { list-style: none; padding-left: 0; margin: 0; }

.comment-item {
    border-top: 1px solid var(--color-border);
    padding: var(--spacing-2) 0;
}

.comment-writer { font-weight: 600; }
.comment-meta { font-size: 12px; color: var(--color-muted); }
.comment-meta a { margin-left: var(--spacing-2); }

/* ==========================================================================
   Attached images (board post / comment)
   ========================================================================== */
.attachment-image {
    max-width: 100%;
    max-height: 480px;
    width: auto;
    border-radius: var(--radius);
    margin-top: var(--spacing-3);
    border: 1px solid var(--color-border);
}

.attachment-image-comment {
    max-height: 240px;
    margin-top: var(--spacing-2);
}

/* ==========================================================================
   Like buttons (board detail + comments)
   ========================================================================== */
.btn-like {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-1);
    padding: 8px 16px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    font-size: 14px;
}
.btn-like .like-icon { color: var(--color-danger); }
.btn-like.liked { border-color: var(--color-danger); background: #fff5f5; }
.btn-like.liked-display { cursor: default; color: var(--color-muted); }

.comment-like-btn {
    text-decoration: none;
    color: var(--color-muted);
    margin-left: var(--spacing-2);
}
.comment-like-btn .comment-like-icon { color: var(--color-danger); }
.comment-like-btn.liked { color: var(--color-danger); }
.comment-like-btn.liked-display { cursor: default; }

/* ==========================================================================
   Left rail (ad slot) - fixed so it follows scroll on every page, like the chat widget.
   ========================================================================== */
.left-rail {
    /* top+bottom (no explicit height) on a fixed element stretches it to fill the space
       between them, so the slot tracks the viewport height instead of a fixed min-height. */
    position: fixed;
    left: 20px;
    top: 76px;
    bottom: 20px;
    z-index: 1000;
}

.ad-slot {
    width: 160px;
    height: 100%;
    background: var(--color-surface);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
}
.ad-slot-label {
    font-size: 11px;
    letter-spacing: 0.05em;
    color: var(--color-muted);
    border: 1px solid var(--color-border);
    border-radius: 4px;
    padding: 1px 6px;
}
.ad-slot-placeholder { margin: 0; font-size: 12px; }

/* In-content horizontal banner ad slot (board list/detail, etc.) */
.ad-banner {
    min-height: 90px;
    background: var(--color-surface);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius);
    display: flex;
    align-items: center;
    justify-content: center;
    margin: var(--spacing-4) 0;
    color: var(--color-muted);
    font-size: 13px;
}

/* Compact, non-floating rank list - reused in the home page's "최근 게시글" row (see .recent-row) */
.mini-rank-list {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 13px;
}
.mini-rank-list li {
    padding: 3px 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.mini-rank-list a { color: var(--color-text); text-decoration: none; }
.mini-rank-list a:hover { text-decoration: underline; }

/* ==========================================================================
   Policy votes (home page preview list + agree/disagree cast buttons)
   ========================================================================== */
/* 안건 하나하나가 노란 3초 요약 하이라이트 때문에 시각적 무게가 커져서, 얇은 밑줄 하나로는
   "이게 어디서 끝나고 다음 안건이 어디서 시작하는지" 경계가 흐려 보인다는 피드백을 받았다 -
   각 행을 흰 카드 위에 얹힌 회색 "카드"로 분리해서 확실히 눈에 구분되게 한다. */
.vote-mini-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }

/* "오늘의 핫 배틀" - 찬반이 가장 팽팽한 안건 하나를 자동 선정해서 홈 맨 위에 강조 노출 */
.hot-battle-card {
    border: 2px solid var(--color-danger);
    box-shadow: 0 0 0 3px rgba(220, 53, 69, 0.12);
}

.vote-row {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-2);
    padding: 14px 16px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.vote-row-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    flex-wrap: wrap;
    gap: var(--spacing-3);
}
.vote-row-title {
    flex: 1 1 auto;
    min-width: 220px;
    font-weight: 700;
    font-size: 17px;
    color: var(--color-text);
    /* Titles are long Korean bill names and there's no click-through anymore, so let them
       wrap over 2 lines instead of single-line ellipsis truncating the whole thing to nothing. */
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.vote-row-meta {
    flex: 0 0 auto;
    font-size: 13px;
    text-align: right;
}
.vote-row-link { font-size: 14px; font-weight: 700; color: var(--color-accent); }

/* "3초 요약" (BillSummaryClient/Gemini API) - 그냥 굵은 텍스트로는 제목/메타 사이에 묻혀서
   "확 들어오지" 않는다는 피드백을 받고, 노란 하이라이트 카드로 다시 만든 버전. 사이트 전체
   테마 색(--color-primary)은 진영 1등에 따라 10분마다 계속 바뀌므로 여기 색을 거기 묶어두면
   콜아웃이 눈에 띄었다 안 띄었다 하게 된다 - 요약 카드만큼은 항상 같은 고정 강조색을 쓴다. */
.vote-row-summary {
    flex-basis: 100%;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 17px;
    font-weight: 800;
    line-height: 1.3;
    margin: 6px 0 2px;
    padding: 10px 14px;
    background: linear-gradient(135deg, #FFF6DA, #FFEBB0);
    border: 1px solid #F5C518;
    border-left: 5px solid #F5C518;
    border-radius: 8px;
    color: #4a3b00;
}
.vote-row-summary-badge {
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
    font-size: 11px;
    font-weight: 800;
    color: #fff;
    background: #E8A400;
    border-radius: 20px;
    padding: 3px 10px;
    white-space: nowrap;
}
.vote-featured-badge {
    display: inline-block;
    font-size: 12px;
    font-weight: 700;
    color: #b8860b;
    border: 1px solid #b8860b;
    border-radius: 4px;
    padding: 0 4px;
    margin-right: 4px;
    vertical-align: middle;
}

.vote-row-actions { display: flex; gap: var(--spacing-2); }

@media (max-width: 480px) {
    .vote-row-top { flex-direction: column; align-items: flex-start; }
    .vote-row-meta { text-align: left; }
}

.btn-vote-choice {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-1);
    padding: 8px 16px;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    font-size: 14px;
    margin-right: var(--spacing-2);
}
.btn-vote-choice.agree.active { border-color: var(--color-accent); background: #eef2ff; color: var(--color-accent); }
.btn-vote-choice.disagree.active { border-color: var(--color-danger); background: #fff5f5; color: var(--color-danger); }

/* Large inline cast buttons - one right in the list row, no detail-page click-through needed. */
.btn-vote-choice-lg {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 14px 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    font-size: 15px;
    font-weight: 600;
}
.btn-vote-choice-lg .vote-count { font-size: 18px; font-weight: 700; }
.btn-vote-choice-lg.agree.active { border-color: var(--color-accent); background: #eef2ff; color: var(--color-accent); }
.btn-vote-choice-lg.disagree.active { border-color: var(--color-danger); background: #fff5f5; color: var(--color-danger); }
.btn-vote-choice-lg.liked-display { cursor: default; color: var(--color-muted); }

@media (max-width: 420px) {
    .vote-row-actions { flex-direction: column; }
}

.vote-comments-toggle {
    display: inline-block;
    margin-top: var(--spacing-2);
    background: none;
    border: none;
    padding: 4px 0;
    font-size: 13px;
    color: var(--color-muted);
    cursor: pointer;
}
.vote-comments-toggle:hover { color: var(--color-text); }
.vote-comments-container {
    margin-top: var(--spacing-2);
    padding-top: var(--spacing-2);
    border-top: 1px dashed var(--color-border);
}
.vote-comments-container .vote-comment-form { margin-bottom: var(--spacing-2); }

.vote-status-badge {
    display: inline-block;
    font-size: 12px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    padding: 1px 6px;
}
.vote-status-badge.pending { color: var(--color-muted); border-color: var(--color-border); }
.vote-status-badge.passed { color: var(--color-accent); border-color: var(--color-accent); }
.vote-status-badge.rejected { color: var(--color-danger); border-color: var(--color-danger); }

/* "끝장토론방" 강제 뱃지 - 이 안건에 실제로 찬성/반대를 던진 사람만 색이 들어가고, 투표
   없이 댓글만 단 사람은 회색 "미투표"로 표시된다. */
.voter-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 700;
    border-radius: 4px;
    padding: 1px 6px;
    margin-right: 4px;
}
.voter-badge.agree { color: #fff; background: var(--color-accent); }
.voter-badge.disagree { color: #fff; background: var(--color-danger); }
.voter-badge.none { color: var(--color-muted); background: var(--color-border); }

/* 진영 컬러 벼슬 (마이페이지에서 설정) - footer.jsp의 CAMP_COLORS와 같은 팔레트를
   클래스로 고정해둔 것. 클래스 이름 매핑은 voteCommentNode.tag 참고. */
.camp-nickname.camp-dp { color: #152484; font-weight: 700; }
.camp-nickname.camp-ppp { color: #E61E2B; font-weight: 700; }
.camp-nickname.camp-rk { color: #0DA6D0; font-weight: 700; }
.camp-nickname.camp-rp { color: #FF7210; font-weight: 700; }
.camp-nickname.camp-jp { color: #8B1FA9; font-weight: 700; }
.camp-nickname.camp-ind { color: #888888; font-weight: 700; }

/* ==========================================================================
   Floating camp supporter widget (bottom-right, stacked above the chat
   widget - same collapsible pattern, own localStorage open/closed state)
   ========================================================================== */
.camp-widget {
    position: fixed;
    right: 20px;
    bottom: 76px;
    width: min(340px, 33vw, 90vw); /* matches .chat-widget's width so the two read as one stack */
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    z-index: 999;
    overflow: hidden;
}
.camp-widget-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--color-primary);
    color: #fff;
    padding: 10px 14px;
    font-size: 14px;
    cursor: pointer;
    user-select: none;
    transition: background-color 1.5s ease;
}
/* Fixed height (not just hugging the chart) so the panel reads as one solid block stacked on
   the chat widget below it - the chart flex-grows to fill everything above the pinned 후원하기
   button instead of leaving dead space under a short, fixed-height chart. */
.camp-widget-body {
    display: none;
    flex-direction: column;
    padding: var(--spacing-3);
    height: 260px;
}
.camp-widget.open .camp-widget-body { display: flex; }

.camp-chart {
    display: flex;
    align-items: flex-end;
    gap: 6px;
    flex: 1;
    min-height: 0;
}
.camp-theme-countdown {
    font-size: 11px;
    text-align: center;
    margin: 6px 0 0;
}
.camp-chart-col {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    min-width: 0;
}
.camp-chart-amount { font-size: 10px; color: var(--color-muted); white-space: nowrap; }
.camp-chart-bar-track {
    flex: 1;
    width: 100%;
    display: flex;
    align-items: flex-end;
    background: var(--color-border);
    border-radius: 4px 4px 0 0;
    overflow: hidden;
}
/* height starts at 0 in markup and gets set to its real value a frame later (see footer.jsp) -
   the transition is what makes the bar animate upward ("솟는" effect) instead of just appearing. */
.camp-chart-bar-fill { width: 100%; transition: height 0.6s ease; }
.camp-chart-label {
    font-size: 11px;
    font-weight: 600;
    margin-top: 4px;
    text-align: center;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
/* 마이페이지에서 그 진영 벼슬을 고른 회원 수 - 후원 순위(%)랑은 별개의 보조 정보라 살짝 더 흐리게. */
.camp-chart-members {
    font-size: 10px;
    color: var(--color-muted);
    text-align: center;
    white-space: nowrap;
}

@media (max-width: 900px) {
    .camp-widget { bottom: 118px; }
}
@media (max-width: 480px) {
    .camp-widget { right: 10px; bottom: 118px; width: min(78vw, 300px); }
}

/* ==========================================================================
   Donate modal (triggered by .donate-trigger anywhere - header button,
   camp widget CTA)
   ========================================================================== */
.modal-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--spacing-3);
}
.modal-box {
    position: relative;
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: var(--spacing-4);
    width: min(400px, 100%);
    max-height: 90vh;
    overflow-y: auto;
}
.modal-close {
    position: absolute;
    top: 12px;
    right: 12px;
    background: none;
    border: none;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    color: var(--color-muted);
}

@media (max-width: 900px) {
    /* Chat widget stays exactly as-is (bottom-right, untouched). The ad becomes a slim
       horizontal bar fixed along the very bottom edge of the screen - lower z-index than the
       chat widget so chat still renders in front of/above it in the corner where they'd overlap. */
    .left-rail {
        left: 0;
        right: 0;
        top: auto;
        bottom: 0;
        transform: none;
        z-index: 999;
    }
    .ad-slot {
        width: 100%;
        height: 52px;
        flex-direction: row;
        border-radius: 0;
        border-width: 1px 0 0;
        gap: 8px;
    }
    .ad-slot-label { font-size: 10px; }
    .ad-slot-placeholder { display: inline; margin: 0; font-size: 12px; }
    .site-main { padding-bottom: 120px; }

    /* Ad bar's position/height never changes regardless of chat being logged in, minimized,
       or maximized - it's the chat widget (below) that shifts up out of its way instead, since
       "bottom" is a fixed anchor point that stays put whether the widget's body is open or not. */
    .chat-widget { bottom: 62px; }
}

/* ==========================================================================
   Floating chat widget (bottom-right, all pages except login/join)
   ========================================================================== */
.chat-widget {
    position: fixed;
    right: 20px;
    bottom: 20px;
    /* Roughly a third of the viewport on tablet/laptop screens, capped so it never gets
       oversized on large monitors. */
    width: min(340px, 33vw, 90vw);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    z-index: 1000;
    overflow: hidden;
}

.chat-widget-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--color-primary);
    color: #fff;
    padding: 10px 14px;
    font-size: 14px;
    cursor: pointer;
    user-select: none;
    transition: background-color 1.5s ease;
}

.chat-widget-toggle-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    color: #fff;
    font-size: 16px;
    line-height: 1;
    flex-shrink: 0;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
}

.chat-room-label { font-size: 11px; font-weight: 400; opacity: 0.85; }

.chat-widget-header-actions {
    display: flex;
    align-items: center;
    gap: var(--spacing-2);
}

.chat-room-panel {
    border-bottom: 1px solid var(--color-border);
    background: #fafafa;
    max-height: 220px;
    overflow-y: auto;
}

.chat-room-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    font-size: 12px;
    color: var(--color-muted);
    border-bottom: 1px solid var(--color-border);
}
.chat-room-panel-header .chat-widget-toggle-btn { color: var(--color-muted); }

.chat-room-list { list-style: none; margin: 0; padding: 0; }

.chat-room-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    font-size: 13px;
    cursor: pointer;
    border-bottom: 1px solid var(--color-border);
}
.chat-room-item:last-child { border-bottom: none; }
.chat-room-item:hover { background: #f0f1f3; }
.chat-room-item.current { background: #eef2ff; cursor: default; font-weight: 600; }
.chat-room-item.full { opacity: 0.5; cursor: not-allowed; }

.chat-widget-body {
    display: none;
    flex-direction: column;
    height: min(60vh, 420px);
}

.chat-widget.open .chat-widget-body { display: flex; }

.chat-widget-messages {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: var(--spacing-3);
}

/* A long unbroken run of characters (URL, spam string, long word) with no natural break point
   was overflowing the widget's fixed width and forcing a horizontal scrollbar. break-word only
   breaks a word mid-character as a last resort - it tries to keep the whole word intact first,
   which is why a long English run got shoved entirely onto its own new line (nothing left of it
   to share the line with) while Korean, whose characters are line-breakable one-by-one by
   default regardless of this property, just flowed normally after "닉네임 : ". break-all makes
   every script wrap character-by-character the same way, so the two no longer behave differently.
   overflow: hidden contains the floated timestamp below (see .chat-message-time) so this box's
   height still grows to fit it. */
.chat-widget-messages .chat-message {
    margin-bottom: 6px;
    font-size: 14px;
    overflow: hidden;
    word-break: break-all;
}

/* Trails the end of the message's last line, pinned to the right edge - since it's the final
   child in the DOM (see appendMessage()/history rendering), the float just settles wherever the
   text flow ends instead of needing a fixed position that would ignore how many lines wrapped. */
.chat-message-time {
    float: right;
    margin-left: 6px;
    font-size: 11px;
}

.chat-widget-form {
    display: flex;
    align-items: stretch;
    gap: var(--spacing-2);
    padding: var(--spacing-2);
    border-top: 1px solid var(--color-border);
}

/* min-width: 0 overrides the flex-item default (min-width: auto), which otherwise stops an
   <input> from shrinking below its intrinsic content width and starves the button's space. */
.chat-input-wrapper {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
}
.chat-widget-form input {
    width: 100%;
    padding: 8px 50px 8px 10px;
}
.chat-byte-counter {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 11px;
    color: var(--color-muted);
    pointer-events: none;
}
.chat-byte-counter.at-limit { color: var(--color-danger); }

.chat-widget-form .btn {
    flex: 0 0 auto;
    width: auto;
    padding: 8px 14px;
    font-size: 13px;
}

/* ==========================================================================
   Responsive breakpoints
   ========================================================================== */
@media (max-width: 768px) {
    .feature-grid { grid-template-columns: 1fr; }
    .site-nav { padding: var(--spacing-2) var(--spacing-3); }
    .hero { padding: var(--spacing-4); }
    .hero h1 { font-size: 22px; }
}

@media (max-width: 480px) {
    .container { padding: var(--spacing-3) var(--spacing-2); }
    .site-nav .nav-group { gap: var(--spacing-2); }
    /* Secondary nav (게시판/결제 - both reachable from the home page anyway) makes way so the
       logged-in state (avatar + nickname + logout) has room to stay on one line like the
       logged-out state (로그인/회원가입) already does. */
    .nav-group-primary { display: none; }
    .nav-avatar { width: 20px; height: 20px; }
    .btn { width: 100%; }
    .hero .hero-actions .btn { width: auto; flex: 1; }
    /* "글쓰기" etc. stay an inline, right-aligned pill instead of stretching full width. */
    .section-title .btn { width: auto; }

    /* Stays a corner widget (not a full-bleed sheet) - just a bit wider than the desktop
       33vw cap so the input/button remain usable on a narrow phone screen. bottom matches the
       max-width:900px override above (clears the fixed ad bar) - repeated here because this
       block comes later in the cascade and would otherwise win it back down to 10px. */
    .chat-widget {
        right: 10px;
        bottom: 62px;
        width: min(78vw, 300px);
    }
    .chat-widget-body { height: min(50vh, 380px); }
}
