/*
 * custom.css
 * 여기에 직접 수정하세요. style.css(구매한 템플릿 원본)는 건드리지 않습니다.
 * 이 파일은 style.css보다 나중에 로드되므로 여기 적은 규칙이 우선 적용됩니다.
 */

.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
    color: var(--bs-nav-pills-link-active-color);
    /* background-color: var(--bs-nav-pills-link-active-bg); */
    background-color: lightblue;
}

body > main {
    min-height: 78vh;
}

.btn-kakao {
    background-color: #FEE500;
    border-color: #FEE500;
    color: #191919;
}

.btn-kakao:hover,
.btn-kakao:focus {
    background-color: #f5dc00;
    border-color: #f5dc00;
    color: #191919;
}

.btn-google {
    background-color: #fff;
    border-color: var(--bs-border-color);
    color: #3c4043;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.btn-google:hover,
.btn-google:focus {
    background-color: #f8f9fa;
    border-color: var(--bs-border-color);
    color: #3c4043;
}

.js-lightbox {
    cursor: zoom-in;
    display: block;
}

.lightbox-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.85);
    z-index: 2000;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}

.lightbox-overlay.active {
    display: flex;
}

.lightbox-overlay .lightbox-img {
    max-width: 100%;
    max-height: 100%;
    border-radius: 6px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}

.lightbox-overlay .lightbox-close {
    position: absolute;
    top: 1.5rem;
    right: 2rem;
    color: #fff;
    font-size: 2.5rem;
    line-height: 1;
    cursor: pointer;
    font-weight: 300;
}

/* 그룹 서브도메인(그룹 홈/커뮤니티/포스트 등)의 상단 메뉴 배경 — 메인 사이트 메뉴와
   구분되도록 파란색 계열 톤을 살짝 얹는다. */
.header-group {
    background-color: #eff6ff;
}

/* 글쓰기 폼의 그룹/공개범위 select — 단체명이 길면 select가 내용 너비만큼 늘어나서
   flex-nowrap 줄을 깨고 넘치던 문제. 줄임표로 잘라서 폭을 고정한다. */
.select-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

[data-bs-theme="dark"] .header-group {
    background-color: #172554;
}

/* 사이드바(타임라인 왼쪽 "가입한 그룹", 그룹 홈 오른쪽 일정·태그·그룹정보) —
   스크롤해도 화면에 붙어있게 sticky 처리. top 값은 상단 헤더 높이만큼 띄워서
   스크롤 중 헤더에 가려지지 않게 한다. 사이드바가 화면보다 길면 안쪽에서 스크롤된다.

   PC(≥992px)에서만 적용한다 — 모바일에서는 사이드바가 본문 아래로 한 줄씩 쌓이는데,
   거기서 sticky가 걸리면 스크롤 중에 카드가 화면에 붙어 따라다녀 거슬린다. */
@media (min-width: 992px) {
    .sidebar-sticky {
        position: sticky;
        top: 90px;
        max-height: calc(100vh - 110px);
        overflow-y: auto;
    }
}

/* 상단 로고 — 그룹 서브도메인에서는 [그룹 로고 이미지] + [그룹 이름] 두 조각이라,
   이름이 길면 로고 아래로 접혀 두 줄이 됐다. 한 줄로 고정하고(nowrap), 폭이 모자라면
   로고는 그대로 두고 이름만 말줄임(…)으로 줄인다. 좁은 화면에서는 글자도 줄인다. */
.navbar-brand {
    display: inline-flex;
    align-items: center;
    flex-wrap: nowrap;
    min-width: 0;
    max-width: 100%;
}

.navbar-brand img.navbar-brand-item {
    flex-shrink: 0;
}

.navbar-brand span.navbar-brand-item {
    min-width: 0;
    flex-shrink: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (max-width: 575.98px) {
    .navbar-brand span.navbar-brand-item {
        font-size: 1.05rem !important;
    }
}

/* 담소/포스트 카드(.card.hstack 안의 .card-body)가 가로 flex의 자식인데 기본
   min-width:auto 때문에 본문이 길면 모바일에서 카드가 화면 밖으로 넘쳐버렸다.
   줄어들 수 있게(min-width:0) 하고, 혹시 남는 긴 단어/URL도 강제로 줄바꿈한다. */
.hstack > .card-body {
    flex: 1 1 auto;
    min-width: 0;
    overflow-wrap: anywhere;
}

/* 담소 카드 왼쪽 투표칸(추천/비추천 화살표 + 점수 + 북마크) — flex-column으로 세로
   가운데 정렬해서 화살표와 숫자가 폭 기준으로 정확히 일직선에 오게 한다. 화살표
   버튼은 Bootstrap 기본 .btn 패딩을 지우고 고정 크기로 통일해야 폭이 서로 달라
   틀어지는 문제가 안 생긴다. 모바일에서는 폭·패딩·아이콘 크기를 더 촘촘하게 줄인다. */
.vote-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.btn-vote-arrow {
    width: 32px;
    height: 26px;
    padding: 0;
    line-height: 1;
    border: none;
    background: transparent;
    color: var(--bs-secondary-color);
    display: flex;
    align-items: center;
    justify-content: center;
}

.btn-vote-arrow:hover {
    color: var(--bs-primary);
}

@media (max-width: 576px) {
    .btn-vote-arrow {
        width: 36px;
        height: 32px;
        font-size: 1rem;
    }
}

/* ============================================================
   모바일(≤575px) 담소/포스트/의견 카드(.feed-card) — 페이스북 앱처럼 "본문에만
   집중"되는 레이아웃으로 바꾼다.

   (1) 세로로 서서 본문 폭을 48~70px 잡아먹던 추천/비추천·북마크 칸(.vote-cell,
       .user-vote)을 카드 맨 위 왼쪽에 가로 한 줄로 눕히고, 그 아래에 본문이
       오게 한다. 세로 구분선(.vr)은 감춘다.
   (2) 카드를 화면 좌우 끝까지 늘리고(full-bleed) 모서리 둥글기·테두리·그림자를
       없앤다. 카드 사이 간격만 회색 배경(--bs-body-bg)으로 남아 구분된다.

   full-bleed 공식(margin: calc(50% - 50vw))은 카드가 화면 가운데 정렬된 컨테이너
   안에 있을 때 부모의 좌우 패딩이 몇이든 정확히 화면 끝에 맞춰준다. 모바일에서는
   모든 컬럼이 100% 폭이라 이 전제가 항상 성립한다.
   ============================================================ */
@media (max-width: 575.98px) {
    .feed-card {
        margin-left: calc(50% - 50vw);
        margin-right: calc(50% - 50vw);
        margin-bottom: 0.5rem !important;
        border: 0 !important;
        border-radius: 0 !important;
        box-shadow: none !important;
    }

    /* 가로 배치(투표칸 | 구분선 | 본문)를 세로로 바꾼다. */
    .feed-card.hstack {
        flex-direction: column;
        align-items: stretch !important;
    }

    .feed-card.hstack > .vr {
        display: none;
    }

    /* 투표칸은 카드 맨 위, 왼쪽 정렬 가로 한 줄(▲ 0 ▼ 북마크). */
    .feed-card .vote-cell,
    .feed-card .user-vote {
        order: 1;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        gap: 0.75rem;
        width: 100% !important;
        padding: 0.5rem 1rem 0 !important;
        text-align: left !important;
    }

    /* 세로 배치용 상하 여백(mb-1/mt-1/mt-2)은 가로 한 줄에서 줄을 어긋나게 한다. */
    .feed-card .vote-cell > *,
    .feed-card .user-vote > * {
        margin: 0 !important;
    }

    /* 본문은 투표 줄 아래에서 화면 폭을 100% 쓴다. */
    .feed-card.hstack > .card-body {
        order: 2;
        width: 100%;
        padding-top: 0.5rem !important;
    }

    /* 본문 좌우 여백은 읽기 편한 최소치(1rem)만 남긴다(.p-4 등 유틸리티를 덮어씀). */
    .feed-card > .card-body {
        padding-left: 1rem !important;
        padding-right: 1rem !important;
    }

    /* 본문 이미지는 화면 폭을 꽉 채운다. 여러 장이어도 2열(col-6)로 쪼개지 않고
       한 장씩 100% 폭으로 쌓고, 본문 좌우 여백(1rem)은 음수 마진으로 상쇄해
       화면 끝까지 닿게 한다. 이미지에 인라인으로 박혀 있는
       style="max-width:100%;max-height:45vh"는 !important로 덮어야 한다.
       (max-height를 없애므로 세로로 긴 이미지도 잘리지 않고 전부 보인다.) */
    .feed-card .post-image-grid {
        --bs-gutter-x: 0;
        --bs-gutter-y: 0.25rem;
        margin-left: -1rem;
        margin-right: -1rem;
    }

    .feed-card .post-image-grid > [class*="col-"] {
        flex: 0 0 100%;
        width: 100%;
        max-width: 100%;
    }

    .feed-card .post-image-grid img {
        display: block;
        width: 100% !important;
        max-width: none !important;
        max-height: none !important;
        height: auto !important;
        border-radius: 0 !important;
    }
}

/* 담소/화제/공감/팔로잉 탭 메뉴 — 좁은 화면에서 4개가 다 안 들어가면 줄바꿈(2줄)
   되던 문제. 줄바꿈 대신 가로 스크롤 한 줄로 유지한다(스크롤바는 숨김). */
.tab-scroll-x {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.tab-scroll-x::-webkit-scrollbar {
    display: none;
}

/* 피드 이미지를 페이스북처럼 크게 — 예전엔 인라인 max-height:45vh로 (특히 세로 포스터가)
   화면에서 작게 눌렸다. 사진 한 장짜리 글은 높이 상한을 넉넉히 키워 비중을 키운다
   (인라인 style을 덮으려면 !important). 모바일(≤575px)은 이미 풀사이즈라 이 규칙은 태블릿·PC용.
   여러 장(그리드)은 2열 배치를 유지하려 그대로 둔다. */
@media (min-width: 576px) {
    .post-image-grid:not(.post-image-masonry) .post-image {
        max-height: 80vh !important;
    }
}

.tab-scroll-x .nav-item {
    flex-shrink: 0;
}

/* ============================================================
   홈("새로운 기능" 슬라이드, whats-new/index.blade.php) — 마크업만 있고
   CSS/JS가 아예 없어서 스타일 없는 상태였다. 여기서부터 전체 신규 작성.
   ============================================================ */
.whats-new {
    --wn-tint-1-bg: #eff6ff; --wn-tint-1-ic: #2563eb;
    --wn-tint-2-bg: #ecfdf5; --wn-tint-2-ic: #059669;
    --wn-tint-3-bg: #fffbeb; --wn-tint-3-ic: #d97706;
    --wn-tint-4-bg: #f5f3ff; --wn-tint-4-ic: #7c3aed;
    --wn-tint-5-bg: #ecfeff; --wn-tint-5-ic: #0891b2;
    --wn-tint-6-bg: #fdf2f8; --wn-tint-6-ic: #db2777;
}

[data-bs-theme="dark"] .whats-new {
    --wn-tint-1-bg: rgba(37, 99, 235, 0.15); --wn-tint-1-ic: #60a5fa;
    --wn-tint-2-bg: rgba(5, 150, 105, 0.15); --wn-tint-2-ic: #34d399;
    --wn-tint-3-bg: rgba(217, 119, 6, 0.15); --wn-tint-3-ic: #fbbf24;
    --wn-tint-4-bg: rgba(124, 58, 237, 0.15); --wn-tint-4-ic: #a78bfa;
    --wn-tint-5-bg: rgba(8, 145, 178, 0.15); --wn-tint-5-ic: #22d3ee;
    --wn-tint-6-bg: rgba(219, 39, 119, 0.15); --wn-tint-6-ic: #f472b6;
}

.wn-page-eyebrow {
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--bs-primary);
    text-align: center;
    margin-bottom: 1.5rem;
}

.wn-stage {
    position: relative;
}

.wn-slide {
    display: none;
    grid-template-columns: 1fr 1fr;
    gap: 2.5rem;
    align-items: center;
    background: var(--wn-tint-bg);
    border-radius: 1.5rem;
    padding: 2.5rem;
}

.wn-slide.is-active {
    display: grid;
}

.wn-eyebrow {
    display: inline-block;
    color: var(--wn-tint-ic);
    font-weight: 700;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 0.5rem;
}

.wn-copy h1 {
    font-size: 1.75rem;
    margin-bottom: 0.75rem;
}

.wn-lede {
    color: var(--bs-secondary-color);
    margin-bottom: 1rem;
}

.wn-steps {
    list-style: none;
    padding: 0;
    margin: 0 0 1rem;
}

.wn-steps li {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}

.wn-num {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--wn-tint-ic);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
}

.wn-tip {
    background: rgba(255, 255, 255, 0.6);
    border-radius: 0.5rem;
    padding: 0.6rem 0.85rem;
    font-size: 0.9rem;
    margin-bottom: 1rem;
}

[data-bs-theme="dark"] .wn-tip {
    background: rgba(0, 0, 0, 0.25);
}

.wn-btn-next {
    display: inline-block;
    background: var(--wn-tint-ic);
    color: #fff;
    border: none;
    border-radius: 999px;
    padding: 0.5rem 1.5rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
}

.wn-btn-next:hover {
    filter: brightness(0.92);
    color: #fff;
}

/* 데모 "브라우저 창" 목업 */
.wn-window {
    background: var(--bs-body-bg);
    border-radius: 1rem;
    box-shadow: 0 20px 40px rgba(0, 0, 0, 0.12);
    overflow: hidden;
}

.wn-window-chrome {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0.6rem 0.85rem;
    background: var(--bs-tertiary-bg);
    border-bottom: 1px solid var(--bs-border-color);
}

.wn-dot {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--bs-secondary-color);
    opacity: 0.4;
}

.wn-url {
    margin-left: 0.5rem;
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
    background: var(--bs-body-bg);
    border-radius: 999px;
    padding: 0.15rem 0.75rem;
}

.wn-window-body {
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.wn-card {
    background: var(--bs-tertiary-bg);
    border-radius: 0.75rem;
    padding: 0.85rem;
}

.wn-row {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-bottom: 0.5rem;
}

.wn-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--wn-tint-ic, var(--bs-secondary-color));
    opacity: 0.7;
    flex-shrink: 0;
    display: inline-block;
}

.wn-name {
    font-weight: 700;
    font-size: 0.9rem;
}

.wn-meta {
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
}

.wn-badge {
    background: var(--bs-body-bg);
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
}

.wn-text {
    font-size: 0.88rem;
    margin: 0.4rem 0;
}

.wn-actions {
    display: flex;
    gap: 1rem;
    font-size: 0.82rem;
    color: var(--bs-secondary-color);
}

.wn-progress-track {
    height: 8px;
    border-radius: 999px;
    background: var(--bs-body-bg);
    overflow: hidden;
    margin: 0.5rem 0 0.35rem;
}

.wn-progress-fill {
    height: 100%;
    background: var(--wn-tint-ic);
    border-radius: 999px;
}

.wn-progress-label {
    display: flex;
    justify-content: space-between;
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
}

.wn-group-tabs {
    display: flex;
    gap: 0.75rem;
    font-size: 0.8rem;
    color: var(--bs-secondary-color);
    border-bottom: 1px solid var(--bs-border-color);
    padding-bottom: 0.5rem;
    margin-bottom: 0.5rem;
}

.wn-group-tabs .active {
    color: var(--wn-tint-ic);
    font-weight: 700;
}

.wn-kakao-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    background: #fee500;
    color: #391b1b;
    border-radius: 0.5rem;
    padding: 0.55rem;
    font-size: 0.85rem;
    font-weight: 600;
}

.wn-divider {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.75rem 0;
    font-size: 0.75rem;
    color: var(--bs-secondary-color);
}

.wn-divider hr {
    flex: 1;
    margin: 0;
}

.wn-fake-input {
    background: var(--bs-body-bg);
    border-radius: 0.5rem;
    padding: 0.5rem 0.75rem;
    font-size: 0.82rem;
    color: var(--bs-secondary-color);
    margin-bottom: 0.5rem;
}

.wn-avatar-stack {
    display: flex;
    align-items: center;
    margin: 0.6rem 0;
}

.wn-avatar-stack .wn-avatar {
    margin-left: -8px;
    border: 2px solid var(--bs-tertiary-bg);
}

.wn-avatar-stack .wn-avatar:first-child {
    margin-left: 0;
}

.wn-more {
    margin-left: 0.5rem;
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
}

.wn-btn-mini {
    display: inline-block;
    background: var(--wn-tint-ic);
    color: #fff;
    border-radius: 999px;
    padding: 0.4rem 1rem;
    font-size: 0.82rem;
    font-weight: 600;
}

.wn-poll-option {
    margin-bottom: 0.6rem;
}

.wn-poll-head {
    display: flex;
    justify-content: space-between;
    font-size: 0.85rem;
    margin-bottom: 0.25rem;
}

.wn-poll-bar {
    height: 8px;
    border-radius: 999px;
    background: var(--bs-body-bg);
    overflow: hidden;
}

.wn-poll-bar i {
    display: block;
    height: 100%;
    background: var(--wn-tint-ic);
    border-radius: 999px;
    font-style: normal;
}

.wn-poll-total {
    font-size: 0.78rem;
    color: var(--bs-secondary-color);
    margin-top: 0.5rem;
}

.wn-proposal-block {
    margin-bottom: 0.6rem;
}

.wn-proposal-label {
    display: inline-block;
    background: var(--wn-tint-bg);
    color: var(--wn-tint-ic);
    font-size: 0.75rem;
    font-weight: 700;
    border-radius: 999px;
    padding: 0.1rem 0.6rem;
    margin-bottom: 0.3rem;
}

.wn-proposal-block p {
    font-size: 0.85rem;
    margin: 0;
}

.wn-best-badge {
    display: inline-block;
    background: #fef3c7;
    color: #92400e;
    font-size: 0.78rem;
    font-weight: 700;
    border-radius: 999px;
    padding: 0.25rem 0.75rem;
}

/* 하단 화살표 + 썸네일 레일 */
/* 화면에 고정(fixed)하지 않고, main 영역 맨 아래(footer 바로 위)에 자연스럽게
   놓이는 일반 배치 — 페이지와 함께 스크롤된다. */
.wn-rail {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-top: 1.5rem;
}

.wn-arrow {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.wn-arrow:hover {
    background: var(--bs-tertiary-bg);
}

.wn-thumbs {
    flex: 1;
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.wn-thumbs::-webkit-scrollbar {
    display: none;
}

.wn-thumb {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    border: 1px solid var(--bs-border-color);
    background: var(--bs-body-bg);
    border-radius: 999px;
    padding: 0.4rem 0.9rem;
    font-size: 0.82rem;
    color: var(--bs-secondary-color);
    white-space: nowrap;
}

.wn-thumb-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--wn-tint-ic);
    opacity: 0.4;
}

.wn-thumb.is-active {
    border-color: var(--wn-tint-ic);
    color: var(--wn-tint-ic);
    font-weight: 700;
}

.wn-thumb.is-active .wn-thumb-dot {
    opacity: 1;
}

@media (max-width: 767px) {
    .wn-slide {
        grid-template-columns: 1fr;
        padding: 1.5rem;
        gap: 1.5rem;
    }
}

/* 담소/댓글/의견/공지 본문 — 마크다운 렌더링 결과(제목·굵게·목록·인용·구분선 등)가
   카드/댓글처럼 좁고 압축된 공간에서도 과하게 크지 않고 자연스럽게 보이도록 축소. */
.markdown-body {
    overflow-wrap: anywhere;
}

.markdown-body > :first-child {
    margin-top: 0;
}

.markdown-body > :last-child {
    margin-bottom: 0;
}

.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
    font-size: 1.05rem;
    font-weight: 700;
    margin: 0.75rem 0 0.4rem;
}

.markdown-body p {
    margin: 0 0 0.6rem;
}

.markdown-body ul,
.markdown-body ol {
    margin: 0 0 0.6rem;
    padding-left: 1.25rem;
}

.markdown-body li {
    margin-bottom: 0.2rem;
}

/* 인용구(> ) — 외부 사이트(언론 기사·블로그·AI 답변)에서 그대로 옮겨온 내용임을
   말풍선처럼 둥글고 배경이 채워진 박스로 표시해 본문 글과 시각적으로 구분한다. */
.markdown-body blockquote {
    margin: 0.5rem 0;
    padding: 0.6rem 1rem;
    border-radius: 0.75rem;
    border-left: 3px solid var(--bs-border-color);
    background-color: var(--bs-tertiary-bg);
    color: var(--bs-secondary-color);
}

.markdown-body hr {
    margin: 0.75rem 0;
}

.markdown-body code {
    background: var(--bs-tertiary-bg);
    border-radius: 0.25rem;
    padding: 0.1rem 0.35rem;
    font-size: 0.85em;
}

.markdown-body pre {
    background: var(--bs-tertiary-bg);
    border-radius: 0.5rem;
    padding: 0.75rem;
    overflow-x: auto;
}

.markdown-body pre code {
    background: none;
    padding: 0;
}

.markdown-body table {
    width: 100%;
    font-size: 0.9rem;
    margin-bottom: 0.6rem;
}

.markdown-body table th,
.markdown-body table td {
    border: 1px solid var(--bs-border-color);
    padding: 0.35rem 0.6rem;
}

/* 비공개(private) 담소 카드 — 본인만 보이는 글이라는 걸 배경색으로 한눈에
   구분되게 한다(글쓴이 본인 화면에서만 이 카드가 렌더링됨). */
.post-card-private {
    background-color: #fff8e6;
}

[data-bs-theme="dark"] .post-card-private {
    background-color: rgba(217, 119, 6, 0.12);
}

/* 붙여넣기 인용 자동 감지 배지 — custom.js의 showQuoteToggleBadge()가 만든다. */
.quote-toggle-badge {
    font-size: 0.8rem;
}

/* 블로그 글쓰기/수정 본문 에디터(TipTap) — tiptap-editor.js가 마운트하는 컨테이너와
   툴바 스타일. Filament RichEditor(TipTap 기반)와 비슷한 느낌으로. */
.tiptap-toolbar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem;
}

.tiptap-btn.active {
    background-color: var(--bs-primary);
    color: #fff;
    border-color: var(--bs-primary);
}

.tiptap-editor {
    min-height: 220px;
    padding: 0.75rem 1rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.375rem;
    background-color: var(--bs-body-bg);
}

.tiptap-editor:focus-within {
    border-color: #2563eb;
    box-shadow: 0 0 0 0.2rem rgba(37, 99, 235, 0.15);
}

.tiptap-editor .ProseMirror {
    outline: none;
    min-height: 190px;
}

.tiptap-editor p:last-child {
    margin-bottom: 0;
}

/* 사용자 얼굴 사진 아바타는 흑백으로 — 담소 카드·댓글·계정 메뉴에서 사진마다 색이
   달라 시선을 뺏지 않도록. 인물(정치인) 사진·그룹 로고는 대상이 아니다. */
.avatar-img.avatar-mono {
    filter: grayscale(1);
}

/* 여러 장 사진 — 2열 그리드는 사진 높이가 제각각이라 짧은 쪽 아래로 빈 칸이 크게
   남았다(세로 포스터 옆에 가로 사진이 오는 경우). CSS 다단(column-count)으로 바꿔
   벽돌 쌓듯(메이슨리) 세로 빈틈 없이 채운다. flex(.row)를 block으로 되돌리고,
   각 칸은 단 중간에서 잘리지 않게 break-inside: avoid 로 묶는다. */
.post-image-masonry {
    display: block;
    column-count: 2;
    column-gap: 0.5rem;
}

.post-image-masonry > [class*="col-"] {
    width: 100%;
    max-width: 100%;
    padding: 0;
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    margin-bottom: 0.5rem;
}

.post-image-masonry img {
    width: 100%;
    height: auto;
    max-height: none;
    object-fit: contain;
}

/* 모바일: 여러 장을 세로로 쌓으면 카드가 너무 길어진다 — 좌우로 넘겨 보는 슬라이드로 바꾼다.
   다음 사진이 살짝 보여(85%) 넘길 수 있음을 알리고, 탭하면 라이트박스로 원본을 본다(scroll-snap).
   ⚠ 위의 .feed-card .post-image-grid img {height:auto!important} 규칙이 명시도가 더 높아
   그동안 이 슬라이더의 높이·폭을 덮어써서 사진이 세로로 길게 나왔다 — 두 클래스(.post-image-grid
   .post-image-masonry)로 명시도를 맞추고 !important로 확실히 이긴다(상세/카드 공통 적용). */
@media (max-width: 575.98px) {
    .post-image-grid.post-image-masonry {
        column-count: unset !important;
        display: flex !important;
        flex-wrap: nowrap !important;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        gap: 0.5rem;
        scrollbar-width: none;
        margin-left: 0 !important;
        margin-right: 0 !important;
    }

    .post-image-grid.post-image-masonry::-webkit-scrollbar {
        display: none;
    }

    .post-image-grid.post-image-masonry > [class*="col-"] {
        flex: 0 0 86% !important;
        width: 86% !important;
        max-width: 86% !important;
        margin-bottom: 0;
        scroll-snap-align: start;
    }

    .post-image-grid.post-image-masonry img {
        width: 100% !important;
        height: 60vw !important;
        max-height: 50vh !important;
        object-fit: cover !important;
        border-radius: 0.5rem !important;
    }
}

/* 라이트박스 좌우 이동 — 사진이 두 장 이상일 때만 보인다(JS가 hidden 토글). */
.lightbox-overlay .lightbox-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 48px;
    height: 48px;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.45);
    color: #fff;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.lightbox-overlay .lightbox-nav:hover {
    background: rgba(0, 0, 0, 0.7);
}

.lightbox-overlay .lightbox-nav[hidden] {
    display: none;
}

.lightbox-overlay .lightbox-prev { left: 1rem; }
.lightbox-overlay .lightbox-next { right: 1rem; }

.lightbox-overlay .lightbox-counter {
    position: absolute;
    bottom: 1.25rem;
    left: 50%;
    transform: translateX(-50%);
    color: #fff;
    font-size: 0.875rem;
    background: rgba(0, 0, 0, 0.45);
    border-radius: 999px;
    padding: 0.15rem 0.75rem;
}

.lightbox-overlay .lightbox-counter[hidden] {
    display: none;
}

@media (max-width: 575.98px) {
    .lightbox-overlay .lightbox-nav {
        width: 40px;
        height: 40px;
        font-size: 1.15rem;
    }

    .lightbox-overlay .lightbox-prev { left: 0.25rem; }
    .lightbox-overlay .lightbox-next { right: 0.25rem; }
}

/* 탭 줄의 "검색" — 다른 탭(a.nav-link)과 글자 크기·여백·색을 똑같이 맞춘다. 버튼 요소라
   기본 테두리·배경만 지우면 나머지는 .nav-link 규칙을 그대로 따른다. */
.nav-search-link {
    border: 0;
    background: none;
    display: inline-flex;
    align-items: center;
}

/* 가로 슬라이더(인물 등) — 스크롤바는 숨기고 좌우 화살표로 넘긴다. 스크롤 자체는 살아 있어
   터치·트랙패드로도 그대로 넘어간다. */
.hscroller-track {
    overflow-x: auto;
    scroll-behavior: smooth;
    scrollbar-width: none;
    -ms-overflow-style: none;
}

.hscroller-track::-webkit-scrollbar { display: none; }

.hscroller-nav {
    position: absolute;
    top: 42%;
    transform: translateY(-50%);
    z-index: 2;
    width: 34px;
    height: 34px;
    border: 1px solid var(--bs-border-color-translucent);
    border-radius: 50%;
    background: var(--bs-body-bg);
    color: var(--bs-secondary-color);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    display: flex;
    align-items: center;
    justify-content: center;
}

.hscroller-nav:hover { color: var(--bs-primary); }
.hscroller-nav[hidden] { display: none; }
.hscroller-prev { left: -8px; }
.hscroller-next { right: -8px; }

/* 지역 탭 줄 — 스크롤해도 화면 위에 붙어 있게. 상단 헤더 높이만큼 아래에서 멈춘다. */
.region-tabs,
.sticky-tabs {
    position: sticky;
    /* 헤더는 모바일(<1200px)에서 고정이 아니라 스크롤로 사라진다(header-sticky-on JS는 ≥1200px만).
       그래서 top을 70px로 두면 헤더가 없어진 자리에 70px 빈 공간이 생겨 탭이 화면 위가 아니라
       "조금 밑"에 붙었다. 헤더가 자리를 안 지키므로 탭은 화면 맨 위(0)에 붙는 게 맞다. */
    top: 0;
    z-index: 3;
    /* 카드 배경(흰색)을 유지해야 아래 목록이 비쳐 보이지 않는다. */
    background: var(--bs-card-bg, #fff);
}

/* 지역 화면 — 오른쪽 사이드(일정·인기 그룹·최근 회원)를 붙여 둔다. 가운데 담소·민원
   목록이 훨씬 길어서, 그대로 두면 스크롤하는 내내 오른쪽이 빈 여백으로 남는다.

   민원 상세 본문과 같은 방식이다 — 화면보다 길면 이 칸 안에서 스크롤되게 해서
   아래쪽 카드에도 닿을 수 있게 한다(조건을 걸어 "짧을 때만 붙이면" 대부분 안 붙는다).
   모바일(<992px)에서는 아래 규칙이 사이드를 display:contents 로 풀어 위아래로 쌓으므로
   붙이지 않는다. */
@media (min-width: 992px) {
    .region-side {
        position: sticky;
        top: calc(var(--hm-header-h, 56px) + .75rem);
        align-self: flex-start;
        max-height: calc(100vh - var(--hm-header-h, 56px) - 1.5rem);
        overflow-y: auto;
        overscroll-behavior: contain;
        padding-right: .25rem;
    }
}

/* 지역 화면 모바일 배치 — 일정을 글쓰기 상자 위로, 인기 그룹·최근 회원은 담소 아래로.
   사이드 칼럼을 display:contents 로 풀어 안쪽 두 블록이 행의 순서를 직접 갖게 한다. */
@media (max-width: 991.98px) {
    .region-body-row { display: flex; flex-direction: column; }
    .region-body-row > .region-side { display: contents; }
    .region-body-row > .region-main { order: 2; }
    .region-side-events { order: 1; }
    .region-side-rest { order: 3; }
}

/* === 2단 스틱: 상단 헤더 고정 → 담소 탭 줄이 헤더를 밀어내고 상단 차지 ===
   예전에는 헤더를 안 붙이고 탭 줄만 붙였는데, 이제 (1) 상단 메뉴(헤더)가 먼저 화면 맨 위에
   붙고 (2) 담소 탭 줄이 스크롤로 올라와 상단에 닿으면 헤더를 위로 밀어내고 그 자리를 차지한다.
   "붙었는지"는 CSS가 스스로 알 수 없어 custom.js가 .is-stuck / .header-pushed 를 토글한다. */
header.header-sticky {
    position: sticky;
    top: 0;
    z-index: 1030;
    transition: transform .22s ease;
}
/* 템플릿 JS가 스크롤 중 붙이는 .header-sticky-on(fixed·fadeInDown·상단밴드 숨김)은
   sticky 방식과 충돌하므로 무력화해 헤더 높이를 일정하게 유지한다. */
header.header-sticky-on {
    position: sticky !important;
    animation: none !important;
}
header.header-sticky-on .navbar-top { display: block !important; }
/* 템플릿 JS는 스크롤 400px에서 로고를 22px로, 브랜드 패딩을 14px로 줄여 헤더 높이를 확 바꾼다.
   그 경계에서 헤더가 커졌다 작아졌다 하며 "떨리던" 원인 — 메인 사이트 헤더(그룹 헤더 제외)는
   붙든 안 붙든 항상 같은 크기가 되게 로고 높이·브랜드 패딩을 고정한다. */
header.header-sticky:not(.header-group) .navbar-brand {
    padding-top: 0.3125rem !important;
    padding-bottom: 0.3125rem !important;
}
header.header-sticky:not(.header-group) .navbar-brand .navbar-brand-item {
    height: auto !important;
}
/* 담소 탭 줄이 상단에 붙는 순간 헤더를 위로 밀어낸다. */
header.header-pushed {
    transform: translateY(-100%);
}

/* 탭 줄은 계속 top:0에 붙는다 — 붙는 순간 헤더가 밀려나므로 화면 맨 위를 차지한다. */
.region-tabs,
.sticky-tabs {
    top: 0;
}

/* 담소 카드가 "자석처럼 붙되 살짝 튀던" 원인 제거.
   템플릿 JS(functions.js stickyHeader)는 스크롤 400px에서 헤더 높이만큼의 빈
   스페이서(#sticky-space)를 갑자기 끼워 넣는다 — 원래 헤더가 fixed로 빠질 때 자리를
   메우려는 것. 그런데 이 사이트는 어느 폭에서도 헤더를 fixed로 두지 않으므로(위 규칙들)
   이 스페이서는 순전히 잉여이고, 400px 지점에서 피드 전체를 헤더 높이만큼 "툭" 밀어
   스냅이 튀어 보이게 만든다. 높이를 0으로 눌러 그 반동을 없앤다. */
#sticky-space { height: 0 !important; }

/* 탭 줄이 붙어 있는 동안 아래 목록과 경계가 분명하도록 은은한 그림자 — 붙는 순간이
   더 자연스럽게 읽힌다. */
.sticky-tabs { box-shadow: 0 2px 6px rgba(0, 0, 0, .04); }

/* 탭 줄이 상단에 붙으면(is-stuck) 화면 가로 전체를 차지하도록 최상단에 fixed로 고정한다.
   left:0 / right:0 은 세로 스크롤바 폭을 존중하므로, 100vw full-bleed처럼 가로 오버플로를
   만들지 않는다. (100vw는 세로 스크롤바가 있는 데스크톱에서 가로 스크롤바를 껌뻑껌뻑 만들고,
   그 반동으로 is-stuck과 헤더 translateY가 왕복하며 "떨리던" 원인이었다.)
   fixed로 빠져나간 자리는 custom.js가 같은 높이의 스페이서로 메워 목록이 튀지 않게 한다. */
.sticky-tabs.is-stuck,
.region-tabs.is-stuck {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1035;
    margin: 0;
    border-radius: 0;
    box-shadow: 0 3px 12px rgba(0, 0, 0, .10);
}


/* 대한민국 시/도 지도 — 인라인 SVG(외부 지도 서비스 없음). 색은 테마 변수를 따른다. */
.region-map { position: relative; }

.region-map svg {
    display: block;
    width: 100%;
    height: auto;
    max-height: 62vh;
    margin: 0 auto;
}

.region-map .rm-area {
    fill: var(--bs-tertiary-bg, #eef1f5);
    stroke: var(--bs-body-bg, #fff);
    stroke-width: 1;
    cursor: pointer;
    transition: fill .12s ease;
    outline: none;
}

.region-map .rm-area:hover,
.region-map .rm-area:focus-visible {
    fill: var(--bs-primary, #2563eb);
}

/* 고른 지역은 계속 눌린 상태로 보여야 한다 — 날짜 선택기와 같은 느낌. */
.region-map .rm-area.is-selected {
    fill: var(--bs-primary, #2563eb);
}

.region-map .rm-label {
    text-align: center;
    font-size: .9rem;
    color: var(--bs-secondary-color, #6c757d);
    margin-top: .25rem;
    min-height: 1.4em;
}

[data-bs-theme="dark"] .region-map .rm-area {
    fill: #2a2f36;
    stroke: #16181c;
}


/* 지역 한 곳의 경계 지도(민원 상세 등) — 인라인 SVG, 외부 지도 서비스 없음. */
.area-map svg {
    display: block;
    width: 100%;
    max-width: 220px;
    height: auto;
    margin: 0 auto;
}

.area-map .am-shape {
    fill: var(--bs-primary, #2563eb);
    fill-opacity: .14;
    stroke: var(--bs-primary, #2563eb);
    stroke-width: 1.2;
}

.area-map .am-name {
    text-align: center;
    font-size: .85rem;
    font-weight: 600;
    color: var(--bs-secondary-color, #6c757d);
    margin-top: .25rem;
}

/* 모바일: 알림 드롭다운이 종 아이콘 기준 왼쪽으로 삐져나가 화면 밖으로 나가던 것 —
   화면 오른쪽에 고정(fixed)해 항상 뷰포트 안에 들어오게 한다. */
@media (max-width: 575.98px) {
    .notif-dropdown.dropdown-menu.show {
        position: fixed !important;
        inset: 58px 8px auto auto !important;
        left: auto !important;
        transform: none !important;
        width: min(360px, calc(100vw - 16px)) !important;
        max-width: calc(100vw - 16px) !important;
    }
}

/* ============================================================
   모바일 담소 피드(.feed-snap) — 카드 하나가 한 화면을 넘지 않게 하고,
   스크롤하면 카드가 화면 맨 위에 자석처럼 붙게 한다. 카드를 누르면 상세로 간다.

   ⚠ 잘림 표시(.feed-clipped)와 댓글 펼침 예외(.feed-uncapped)는 CSS가 스스로
   판단할 수 없어 custom.js가 클래스로 붙여 준다.
   ============================================================ */
@media (max-width: 991.98px) {
    /* 스냅은 "스크롤하는 요소"에 걸어야 한다 — 이 사이트는 문서 전체가 스크롤한다.
       proximity라서 가까이 갔을 때만 붙는다. mandatory로 하면 목록 위아래(탭 줄,
       "더 보기" 버튼)에 멈추기가 어려워진다. */
    /* ⛔ 자석(스크롤 스냅) 중지 — 2026-08-27 요청으로 껐다. 되살리려면 아래
       두 줄(html의 scroll-snap-type, .feed-snap > .card 의 scroll-snap-align)의
       주석만 풀면 된다. 높이 제한·눌러서 상세는 스냅과 무관하게 그대로 동작한다. */
    html {
        /* scroll-snap-type: y proximity; */
    }

    /* 모바일(<1200px)에서는 상단 헤더가 고정이 아니라 스크롤로 사라지므로
       (위 .sticky-tabs 주석 참고) 붙는 위치를 헤더 높이만큼 내릴 필요가 없다. */
    /* 탭 줄(.sticky-tabs)이 top:0으로 붙어 있어서, 그냥 붙이면 카드 윗부분이 그 아래로
       숨는다. 탭 줄 높이만큼 내려서 붙이고 최대 높이도 그만큼 뺀다 — 높이는 글꼴·줄바꿈에
       따라 달라지므로 custom.js가 재서 --feed-snap-offset에 넣어 준다. */
    .feed-snap > .card {
        /* scroll-snap-align: start;  ← 자석 중지 */
        scroll-margin-top: var(--feed-snap-offset, 0px);
        max-height: calc(100vh - var(--feed-snap-offset, 0px));
        overflow: hidden;
        position: relative;
    }

    /* 댓글을 펼친 카드는 자르지 않는다 — 자르면 펼친 내용이 안 보인다. */
    .feed-snap > .card.feed-uncapped {
        max-height: none;
        overflow: visible;
    }

    /* 실제로 잘린 카드에만 아래쪽을 흐리게 해서 "더 있다"는 것을 알린다. */
    .feed-snap > .card.feed-clipped::after {
        content: '';
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 4.5rem;
        background: linear-gradient(to bottom, transparent, var(--bs-card-bg, #fff));
        pointer-events: none;
    }

    .feed-snap > .card[data-post-url] {
        cursor: pointer;
    }
}

/* 담소 상세를 오른쪽에서 밀어 넣는 패널 — 목록에서 카드를 누르면 페이지를 떠나지 않고
   여기에 상세가 뜬다(뒤로 가기가 번거롭다는 요청). 주소창은 상세 주소로 바뀌므로
   새로고침·공유·뒤로 가기가 모두 정상 동작한다. */
/* ⚠ width를 직접 주면 안 된다 — 부트스트랩의 `.offcanvas.offcanvas-end`가 클래스 2개라
   `.feed-panel` 하나보다 우선해서 기본값 400px이 그대로 이긴다(아이폰에서 화면의 약 90%만
   차지해 오른쪽이 잘려 보였다). 부트스트랩이 읽는 변수 자체를 바꾼다. */
.feed-panel {
    --bs-offcanvas-width: min(760px, 100%);
}

@media (max-width: 991.98px) {
    .feed-panel {
        --bs-offcanvas-width: 100vw;
        --bs-offcanvas-border-width: 0;
    }
}

/* 패널 안에서는 상세 페이지의 좌우 여백을 줄여 본문이 넓게 보이게 한다. */
.feed-panel .offcanvas-body > main,
.feed-panel .offcanvas-body .container {
    padding-left: 0;
    padding-right: 0;
    max-width: 100%;
}

/* PC에서 패널은 넓은데(760px) 상세 본문은 `col-lg-7 mx-auto`로 가운데 좁은 칼럼이라,
   패널 안에서 좌우 여백이 크게 남고 본문·비슷한담소 리스트가 모바일처럼 좁아 보였다.
   패널 안에서는 컨테이너 바로 아래 본문 칼럼을 100% 폭으로 펴 패널을 꽉 채운다
   (안쪽 이미지 그리드 등 중첩 컬럼 `.row > .col-*`은 직속 자식이 아니라 영향 없음). */
.feed-panel .offcanvas-body .container > [class*="col-"] {
    max-width: 100% !important;
    flex: 0 0 100% !important;
    width: 100% !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* 네이티브 앱(Capacitor) 전용 안전영역 — iOS는 상태바가 항상 웹뷰를 덮는다
   (StatusBar 플러그인의 overlaysWebView는 안드로이드에만 먹는다). 그대로 두면 사이트
   로고가 시계·노치와 겹친다. body.app-native는 서버가 앱 요청일 때만 붙이므로
   일반 브라우저 레이아웃에는 영향이 없다(뷰포트 viewport-fit=cover도 그때만 붙는다). */
body.app-native header.header-sticky {
    padding-top: env(safe-area-inset-top);
}

/* 좌우 노치(가로 모드)와 하단 홈 인디케이터도 피한다. */
body.app-native {
    padding-left: env(safe-area-inset-left);
    padding-right: env(safe-area-inset-right);
}

body.app-native footer {
    padding-bottom: env(safe-area-inset-bottom);
}

/* ============================================================
   우리 동네 의견 슬라이더 — 가로로 넘기는 카드 목록(한 칸씩 이동).

   slick을 쓰지 않은 이유: slick은 jQuery가 필수인데 이 사이트엔 jQuery가 없다.
   한 블록 때문에 jQuery(90KB)를 모든 페이지에 얹는 건 손해라, 같은 동작을
   CSS 스크롤 스냅으로 만든다(요즘 브라우저는 이게 더 부드럽고 터치도 자연스럽다).

   보이는 개수: PC 4 · 태블릿 3 · 큰폰 2 · 폰 1.
   주 이용자가 30~40대라 글자를 작게 두지 않는다 — 본문 1rem, 메타 .875rem.
   ============================================================ */
.opinion-slider {
    position: relative;
    /* 화살표가 카드 위에 겹치므로 좌우에 자리를 비워 둔다(PC만). */
    margin: 0 -0.25rem;
}

.opinion-slider .slider-track {
    display: flex;
    gap: 0.75rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    padding: 0.25rem;
    /* 스크롤바는 감춘다 — 화살표와 점으로 움직인다. */
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
}

.opinion-slider .slider-track::-webkit-scrollbar {
    display: none;
}

/* 한 칸의 폭이 "몇 개 보이는가"를 정한다. gap을 뺀 값으로 계산해야 딱 떨어진다. */
.opinion-slider .slider-item {
    flex: 0 0 calc((100% - 0.75rem * 3) / 4);
    scroll-snap-align: start;
}

.opinion-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 1rem;
    border: 1px solid var(--bs-border-color);
    border-radius: 0.75rem;
    background: var(--bs-body-bg);
    transition: box-shadow .15s ease, transform .15s ease;
}

.opinion-card:hover {
    box-shadow: 0 4px 14px rgba(0, 0, 0, .07);
    transform: translateY(-2px);
}

/* 공감 수 — 눈에 먼저 들어와야 하는 값이라 크게. */
.opinion-count {
    display: inline-flex;
    align-items: baseline;
    gap: 0.2rem;
    padding: 0.15rem 0.5rem;
    border-radius: 999px;
    background: var(--bs-secondary-bg);
    color: var(--bs-secondary-color);
}

.opinion-count strong { font-size: 1.05rem; line-height: 1; }
.opinion-count span { font-size: .75rem; }

.opinion-count.is-hot {
    background: var(--bs-primary);
    color: #fff;
}

/* 본문 — 4줄까지 보여주고 자른다. 글자는 키운다(주 이용자 30~40대). */
.opinion-text {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 1rem;
    line-height: 1.6;
    word-break: keep-all;
}

.opinion-meta {
    font-size: .875rem;
    color: var(--bs-body-color);
    border-top: 1px solid var(--bs-border-color-translucent);
}

/* 좌우 화살표 — 카드 위에 겹쳐 둔다. 끝에 닿으면 custom.js가 감춘다. */
.opinion-slider .slider-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 40px;
    height: 40px;
    border: 0;
    border-radius: 50%;
    background: var(--bs-body-bg);
    color: var(--bs-body-color);
    box-shadow: 0 2px 10px rgba(0, 0, 0, .18);
    font-size: 1.15rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.opinion-slider .slider-prev { left: -6px; }
.opinion-slider .slider-next { right: -6px; }

/* 위치 점 — 지금 어디쯤인지 알려 준다. */
.opinion-slider .slider-dots {
    display: flex;
    justify-content: center;
    gap: 0.35rem;
    margin-top: 0.75rem;
}

.opinion-slider .slider-dots button {
    width: 8px;
    height: 8px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--bs-border-color);
}

.opinion-slider .slider-dots button.is-active {
    background: var(--bs-primary);
    width: 20px;
    border-radius: 999px;
}

@media (max-width: 1199.98px) {
    .opinion-slider .slider-item { flex-basis: calc((100% - 0.75rem * 2) / 3); }
}

@media (max-width: 767.98px) {
    .opinion-slider .slider-item { flex-basis: calc((100% - 0.75rem) / 2); }
}

@media (max-width: 575.98px) {
    /* 폰에서는 한 장씩. 다음 카드가 살짝 보이게 해서 넘길 수 있다는 걸 알린다. */
    .opinion-slider .slider-item { flex-basis: 88%; }
    /* 손가락으로 넘기는 화면이라 화살표는 숨긴다. */
    .opinion-slider .slider-nav { display: none; }
    .opinion-text { font-size: 1.05rem; }
}

/* ============================================================
   지역 목록의 지역명이 한 글자씩 세로로 깨지던 문제.

   원인: 한 줄에 둘씩(col-6) 놓고 오른쪽 숫자 묶음에 flex-shrink-0 을 줬는데,
   민원·회원·방문자가 다 있는 지역(예: 서울 강서구 🔥56 👤1 👁165)은 그 묶음이 넓어
   왼쪽 이름 칸이 0에 가깝게 눌린다. 폭이 한 글자보다 좁아지면 브라우저는
   "서/울/강/서/구"처럼 글자마다 줄을 바꾼다.

   고침: 모바일은 한 줄에 하나(col-12)로 두고, 이름 칸이 남는 폭을 차지하게 한다.
   ============================================================ */
.region-child-name {
    flex: 1 1 auto;
    min-width: 0;          /* 이게 없으면 flex 칸이 내용보다 작아지지 않는다 */
    word-break: keep-all;  /* 한글은 낱말 단위로 끊는다 */
    overflow-wrap: break-word;
}

/* 오른쪽 숫자 묶음은 줄바꿈 없이 한 줄로. */
.region-child > span:last-child {
    white-space: nowrap;
}

/* 지역 목록 가독성 — 이 페이지는 글자가 작아 40~50대가 읽기 힘들다는 지적이 있었다.
   지역 이름을 본문보다 키우고 굵게 해서 먼저 눈에 들어오게 하고, 옆의 통계 숫자는
   한 단계 작게·연하게 눌러 이름과 구분한다(다 키우면 오히려 안 읽힌다). */
.region-child {
    font-size: 1.0625rem;   /* 17px */
    line-height: 1.5;
}

.region-child .region-child-name {
    font-weight: 600;
}

.region-child-stat {
    font-size: 0.875rem;
}

.region-child .badge {
    font-size: 0.8125rem;   /* 13px — 배지 안 숫자가 너무 작으면 세는 의미가 없다 */
}

/* 배지 안의 아이콘과 숫자가 붙어 보이지 않게 한 칸 띄운다. */
.region-child .badge i,
.region-child-stat .badge i {
    margin-right: 0.2em;
}

/* 눌렀을 때/올렸을 때 어느 줄인지 확실히 보이게 — 줄이 촘촘해 놓치기 쉽다. */
.region-child:hover,
.region-child:focus-visible {
    background-color: var(--bs-secondary-bg);
}

/* ============================================================
   모바일에서 로그인하면 상단 메뉴가 두 줄이 되던 문제.

   원인: 로고 + 알림종 + 아바타 + 햄버거가 한 줄에 안 들어가 햄버거가 밀려났다.
   (로그아웃 상태에선 알림종이 없어 겨우 들어갔다.)

   고침: 한 줄 유지(nowrap)하고 로고를 조금 줄여 자리를 만든다.
   공식 조직 모드(header-official)는 일부러 2단 밴드라 건드리지 않는다.
   ============================================================ */
@media (max-width: 991.98px) {
    header.header-sticky:not(.header-official) .navbar > .container {
        flex-wrap: nowrap;
    }

    header.header-sticky:not(.header-official) .navbar-brand {
        min-width: 0;
        flex-shrink: 1;
        overflow: hidden;
    }

    /* 로고를 40px → 30px 로. 이 10px이 햄버거가 들어갈 자리를 만든다. */
    header.header-sticky:not(.header-official) .navbar-brand .navbar-brand-item {
        max-height: 30px !important;
        width: auto;
    }

    header.header-sticky:not(.header-official) .navbar-toggler,
    header.header-sticky:not(.header-official) .nav.dropdown-hover {
        flex-shrink: 0;
    }

    header.header-sticky:not(.header-official) .nav.dropdown-hover {
        flex-wrap: nowrap;
    }
}

/* ============================================================
   지도 검색창 붙이기 — 스크롤해서 지도가 화면 밖으로 나가도 검색은 손에 닿게.
   목록이 245곳이라 아래로 내려가면 검색창이 저 위에 남아 다시 올라와야 했다.

   상단 메뉴(header.header-sticky)가 top:0 에 붙어 있으므로 그 높이만큼 내려서 붙인다.
   높이는 화면 폭·로그인 여부에 따라 달라져 CSS 로 고정할 수 없다 —
   custom.js 가 재서 --hm-header-h 에 넣어 준다(없을 때를 대비해 기본값 56px).
   ============================================================ */
.hm-sticky-search {
    position: sticky;
    top: var(--hm-header-h, 56px);
    /* 상단 메뉴(1030)보다는 아래, 본문보다는 위. */
    z-index: 1020;
    /* 배경이 없으면 아래 목록이 글자 사이로 비쳐 보인다. */
    background: var(--bs-body-bg);
    padding-top: .5rem;
    /* 좌우 여백까지 덮어야 카드 모서리가 검색창 옆으로 비집고 올라오지 않는다. */
    margin-left: -.25rem;
    margin-right: -.25rem;
    padding-left: .25rem;
    padding-right: .25rem;
}

/* 붙어 있는 동안만 아래에 옅은 그림자 — 떠 있다는 것이 보여야 한다.
   custom.js 가 .is-stuck 을 붙인다(CSS 만으로는 붙었는지 알 수 없다). */
.hm-sticky-search.is-stuck {
    box-shadow: 0 .25rem .5rem rgba(0, 0, 0, .06);
    padding-bottom: .5rem;
}

/* ============================================================
   "실제로 나간 메일" 속보 자막 — 건수가 많아 다 늘어놓으면 사이드바가 한없이 길어진다.
   창을 6줄 높이로 정해 두고 위로 흐르게 한다. 마우스를 올리면 멈춰 읽을 수 있고,
   움직임을 싫어하는 설정(prefers-reduced-motion)이면 흐르지 않고 그냥 스크롤된다.
   ============================================================ */
.delivery-ticker {
    /* 한 줄이 제목·날짜·얼굴 3단이라 약 5.5rem 이다(예전 3.25rem 기준으로 두면
       4줄이 잘려 보인다 — 2026-09-06 배치 변경). 4줄쯤 보이게 잡는다. */
    max-height: 22rem;
    overflow: hidden;
    position: relative;
}

/* 위아래 끝을 흐리게 — 잘린 것이 아니라 흐르는 중임이 보인다. */
.delivery-ticker::before,
.delivery-ticker::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    height: 1.5rem;
    pointer-events: none;
    z-index: 1;
}

.delivery-ticker::before {
    top: 0;
    background: linear-gradient(to bottom, var(--bs-card-bg, #fff), transparent);
}

.delivery-ticker::after {
    bottom: 0;
    background: linear-gradient(to top, var(--bs-card-bg, #fff), transparent);
}

/* 목록을 두 벌 넣고 절반만큼 밀어 올리면 이음매가 안 보인다(js-ticker 가 복제한다). */
.delivery-ticker.is-rolling .delivery-ticker-track {
    animation: hm-ticker-up var(--ticker-duration, 40s) linear infinite;
}

.delivery-ticker.is-rolling:hover .delivery-ticker-track,
.delivery-ticker.is-rolling:focus-within .delivery-ticker-track {
    animation-play-state: paused;
}

@keyframes hm-ticker-up {
    from { transform: translateY(0); }
    to   { transform: translateY(-50%); }
}

/* 글이 상자 밖으로 나가지 않게 — 긴 제목·주소가 칸을 밀어내던 것을 막는다. */
.delivery-ticker .d-flex > div {
    min-width: 0;
}

.delivery-ticker a,
.delivery-ticker .text-body-secondary {
    overflow-wrap: anywhere;
}

@media (prefers-reduced-motion: reduce) {
    .delivery-ticker.is-rolling .delivery-ticker-track { animation: none; }
    .delivery-ticker { overflow-y: auto; }
}

/* 슬라이더 카드에서 사진 대신 넣는 본문 발췌 — 사진과 같은 높이로 맞춘다. */
.top-card-excerpt {
    height: 120px;
    overflow: hidden;
    font-size: .8125rem;
    line-height: 1.5;
    color: var(--bs-secondary-color);
}

/* "실제로 나간 메일" 카드를 사이드바에 붙인다 — 왼쪽 요구 목록이 "더 보기"로 길어져도
   이 기록이 화면에 남아 있어야 한다. 내려갈수록 안 보이면 있으나 마나다.

   top 은 상단 메뉴 높이만큼 띄운다(custom.js 가 재서 --hm-header-h 에 넣는다).
   PC 에서만 — 모바일에서는 사이드바가 본문 아래로 쌓이는데 거기서 붙으면 따라다녀 거슬린다. */
@media (min-width: 992px) {
	.delivery-card {
		position: sticky;
		top: calc(var(--hm-header-h, 56px) + .75rem);
	}
}

/* 인물 페이지 오른쪽 "받은 주민 요구 메일" 블록. 목록이 길어질 수 있어 붙여 두되,
   화면보다 길면 카드 안에서만 스크롤한다 — 페이지 전체가 끌려다니지 않게. */
@media (min-width: 992px) {
	.mail-log-card {
		position: sticky;
		top: calc(var(--hm-header-h, 56px) + .75rem);
		max-height: calc(100vh - var(--hm-header-h, 56px) - 1.5rem);
		overflow-y: auto;
	}
}

/* 민원 상세 — 본문을 붙여 둔다. 오른쪽 사이드(비슷한 민원·공약·전달 기록)가 본문보다
   훨씬 길어서, 그대로 두면 사이드를 읽는 동안 민원 내용이 화면 밖으로 나간다.

   ⚠ 처음엔 "본문이 화면에 들어갈 때만" JS 로 붙였는데, 본문이 화면보다 조금만 커도
     아예 안 붙어서 사실상 동작하지 않았다(2026-09-07 사용자 지적). 조건을 없애고
     max-height + overflow 로 해결한다 — 짧으면 그대로 붙고, 길면 이 칸 안에서 스크롤되어
     댓글·입력칸에도 닿을 수 있다. 한 규칙으로 두 경우가 다 된다.

   align-self 를 주지 않으면 부트스트랩 row(flex)에서 컬럼이 세로로 꽉 차 붙지 않는다. */
@media (min-width: 992px) {
	.js-sticky-main {
		position: sticky;
		top: calc(var(--hm-header-h, 56px) + .75rem);
		align-self: flex-start;
		max-height: calc(100vh - var(--hm-header-h, 56px) - 1.5rem);
		overflow-y: auto;
		/* 붙은 칸 안에서 스크롤할 때 뒤 페이지가 같이 밀리지 않게. */
		overscroll-behavior: contain;
		/* 스크롤바가 본문에 딱 붙어 글자를 가리지 않도록 살짝 띄운다. */
		padding-right: .25rem;
	}
}

/* 후원 페이지 오른쪽 칸은 붙이지 않는다.
   한 번 붙여 봤다가 걷어냈다(2026-09-08 사용자 지적) — 후원 폼은 금액·영수증·개인정보·
   동의까지 길어서 어떤 화면보다도 크다. 붙이면 max-height 안에서 스크롤되는데, 폼 안에서
   또 스크롤이 생기면 어디까지 입력했는지 알기 어렵고 입력 중 화면이 갇힌 느낌을 준다.
   짧은 카드(지역 사이드·민원 본문)와 달리 폼은 그냥 페이지와 함께 흐르는 게 맞다. */

/* 비밀번호 보기 단추 — custom.js 가 비밀번호 칸마다 감싸서 넣는다.
   칸 안 오른쪽에 겹쳐 두되, 글자가 단추 밑으로 들어가지 않게 오른쪽 여백을 준다. */
.pw-toggle-wrap { position: relative; display: block; }
.pw-toggle-wrap > input { padding-right: 2.5rem; }
.pw-toggle {
    position: absolute;
    top: 50%;
    right: .25rem;
    transform: translateY(-50%);
    border: 0;
    background: transparent;
    color: var(--bs-secondary-color, #6c757d);
    padding: .25rem .5rem;
    line-height: 1;
    cursor: pointer;
}
.pw-toggle:hover { color: var(--bs-body-color, #212529); }
.pw-toggle:focus-visible { outline: 2px solid var(--bs-primary, #2563eb); outline-offset: 1px; border-radius: .25rem; }
/* 작은 입력칸(form-control-sm)에서는 단추도 같이 작게. */
.pw-toggle-wrap > .form-control-sm + .pw-toggle { font-size: .875rem; padding: .2rem .4rem; }

/* .text-muted 색 강제(secondary-color)를 풀어 본문색을 따르게 한다 — 너무 흐려 잘 안 보이던
   뮤트 텍스트의 가독성을 높인다. style.css의 !important를 이기려면 여기도 !important. */
.text-muted {
    --bs-text-opacity: 1;
    color: inherit !important;
}
