/* ==========================================================================
   G5Pro 코어 — 베이스 + 레이아웃 + 컴포넌트
   shadcn/ui 의 시각 스펙을 손으로 옮긴 순수 CSS. 빌드 스텝 없음.

   스코프 격리 규칙
   - 엘리먼트 셀렉터는 반드시 .pro-body 하위에서만 쓴다.
     순정 css/default.css 가 table/input/a 같은 전역 셀렉터를 쓰기 때문에,
     한쪽이 다른 쪽을 덮어쓰는 사고를 구조적으로 막는다.
   - 컴포넌트 클래스는 전부 .pro- 접두사. 어디에 놓여도 안전하다.
   ========================================================================== */

/* ---------- 베이스 ---------- */

/* 머리말이 sticky 라, #앵커 로 이동하면 목표가 그 아래에 깔려 안 보인다.
   :target 은 주소의 조각(#tokens)이 가리키는 그 요소에만 맞으므로, 앵커로 온
   경우에만 머리말 높이만큼 위를 비워 둔다. 평소 여백에는 영향이 없다. */
.pro-body :target {
    scroll-margin-top: calc(var(--pro-header-h) + var(--pro-sp-4));
}

.pro-body {
    margin: 0;
    background: hsl(var(--pro-background));
    color: hsl(var(--pro-foreground));
    font-family: var(--pro-font-sans);
    font-size: var(--pro-text-sm);
    line-height: var(--pro-leading-normal);
    -webkit-text-size-adjust: 100%;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

.pro-body *,
.pro-body *::before,
.pro-body *::after { box-sizing: border-box; }

.pro-body h1, .pro-body h2, .pro-body h3,
.pro-body h4, .pro-body h5, .pro-body h6 {
    margin: 0;
    font-weight: 600;
    line-height: var(--pro-leading-tight);
    letter-spacing: -0.01em;
}
.pro-body h1 { font-size: var(--pro-text-2xl); }
.pro-body h2 { font-size: var(--pro-text-xl); }
.pro-body h3 { font-size: var(--pro-text-lg); }

.pro-body p, .pro-body ul, .pro-body ol, .pro-body dl, .pro-body figure { margin: 0; }
.pro-body ul, .pro-body ol { padding-left: 1.25rem; }

/* :where() 로 감싸 특정도를 0 으로 만든다. 그러지 않으면 이 규칙(0,1,1)이
   .pro-btn 같은 단일 클래스 규칙(0,1,0)을 이겨 <a class="pro-btn"> 의 글자색을
   덮어쓴다 — 어두운 버튼에 어두운 글자가 나오는 원인이었다. */
.pro-body :where(a) {
    color: inherit;
    text-decoration: none;
    transition: color var(--pro-transition);
}
.pro-body :where(a):hover { color: hsl(var(--pro-foreground)); }

.pro-body img, .pro-body svg, .pro-body video { max-width: 100%; height: auto; vertical-align: middle; }

.pro-body hr {
    border: 0;
    border-top: 1px solid hsl(var(--pro-border));
    margin: var(--pro-sp-6) 0;
}

.pro-body code, .pro-body kbd, .pro-body pre, .pro-body samp { font-family: var(--pro-font-mono); }
.pro-body code {
    font-size: 0.85em;
    background: hsl(var(--pro-muted));
    padding: 0.125em 0.375em;
    border-radius: var(--pro-radius-sm);
}
.pro-body pre {
    background: hsl(var(--pro-muted));
    color: hsl(var(--pro-foreground));
    padding: var(--pro-sp-4);
    border-radius: var(--pro-radius-md);
    overflow-x: auto;
    margin: 0;
}
.pro-body pre code { background: none; padding: 0; }

/* 키보드 포커스만 링을 그린다. 마우스 클릭에는 안 그린다. */
.pro-body :focus-visible {
    outline: 2px solid hsl(var(--pro-ring));
    outline-offset: 2px;
}

/* 스크린리더 전용
   .sound_only 는 순정 규약이다. get_paging()·get_sideview()·captcha_html() 같은
   lib 함수가 스킨을 거치지 않고 이 클래스를 직접 뱉으므로, 순정 CSS 를 안 싣는
   pro 테마에서는 여기서 같은 뜻을 정의해 줘야 그 텍스트가 화면에 노출되지 않는다. */
.pro-sr,
.sound_only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ---------- 자동등록방지 (순정 규약) ----------
   plugin/kcaptcha/kcaptcha.lib.php:242 captcha_html() 이 스킨을 거치지 않고 아래 구조를
   그대로 뱉는다. 마크업을 못 바꾸므로 CSS 로만 고친다.

       <fieldset id="captcha" class="captcha">
         <legend><label for="captcha_key">자동등록방지</label></legend>
         <img id="captcha_img">                     ← kcaptcha.js 가 src 를 채운다
         <input id="captcha_key" class="captcha_box required">
         <button id="captcha_mp3"><span></span>숫자음성듣기</button>
         <button id="captcha_reload"><span></span>새로고침</button>
         <span id="captcha_info">…</span>
       </fieldset>

   순정 CSS 를 안 싣는 pro 테마에서는 이 정의가 없으면 브라우저 기본 <fieldset> 이
   그대로 나와, 화면에서 유일하게 각진 회색 상자가 된다. */

.pro-body #captcha {
    display: flex; align-items: center; flex-wrap: wrap;
    gap: var(--pro-sp-2);
    margin: 0;
    padding: var(--pro-sp-3);
    border: 0;
    border-radius: var(--pro-radius-md);
    background: hsl(var(--pro-card));
    box-shadow: var(--pro-shadow-sm);
    min-width: 0;
}
/* fieldset 이 flex 여도 legend 는 브라우저가 위에 따로 얹는다(플렉스 아이템이 아니다).
   그 성질을 그대로 두고 라벨처럼만 꾸민다. */
.pro-body #captcha legend {
    padding: 0 0 var(--pro-sp-2);
    font-size: var(--pro-text-xs); font-weight: 600;
    color: hsl(var(--pro-muted-foreground));
}
.pro-body #captcha legend label { cursor: pointer; }

.pro-body #captcha_img {
    flex: none;
    height: 2.75rem; width: auto;
    border-radius: var(--pro-radius-sm);
    background: #fff;
    outline: 1px solid hsl(var(--pro-border)); outline-offset: -1px;
}

/* 숫자를 한 자씩 또박또박 넣는 칸이다. 모노 + 자간을 벌려 자릿수가 세어지게 한다. */
.pro-body #captcha_key {
    flex: none;
    width: 7.5rem; min-height: 2.75rem;
    padding: var(--pro-sp-2);
    border: 1px solid hsl(var(--pro-input));
    border-radius: var(--pro-radius-md);
    background: hsl(var(--pro-card));
    color: hsl(var(--pro-foreground));
    font-family: var(--pro-font-mono);
    font-size: var(--pro-text-lg);
    letter-spacing: .2em; text-indent: .2em; text-align: center;
}
.pro-body #captcha_key:focus {
    outline: none;
    border-color: hsl(var(--pro-ring));
    box-shadow: 0 0 0 3px hsl(var(--pro-ring) / .15);
}

.pro-body #captcha_mp3,
.pro-body #captcha_reload {
    flex: none;
    height: 2.25rem; padding-inline: var(--pro-sp-4);
    border: 1px solid hsl(var(--pro-border));
    border-radius: var(--pro-radius-btn);
    background: hsl(var(--pro-card));
    color: hsl(var(--pro-muted-foreground));
    font-family: inherit; font-size: var(--pro-text-xs); font-weight: 600;
    white-space: nowrap; cursor: pointer;
    transition: background var(--pro-transition), color var(--pro-transition);
}
.pro-body #captcha_mp3:hover,
.pro-body #captcha_reload:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-foreground)); }
/* 버튼 안의 빈 <span> 은 순정이 아이콘 스프라이트를 깔던 자리다.
   아이콘 폰트도 스프라이트도 안 싣는 테마이므로 없앤다. */
.pro-body #captcha_mp3 > span,
.pro-body #captcha_reload > span { display: none; }

.pro-body #captcha_info {
    flex: 1 1 12rem; min-width: 0;
    font-size: var(--pro-text-xs);
    color: hsl(var(--pro-muted-foreground));
}

@media (max-width: 560px) {
    .pro-body #captcha_key { width: 100%; }
    .pro-body #captcha_info { flex-basis: 100%; }
}

/* 캡챠 PNG 는 검은 글자 / 흰 바탕이라 어두운 화면에서 흰 덩어리로 튄다.
   반전하면 흰 글자 / 검은 바탕이 되어 카드에 자연스럽게 앉는다.
   테두리는 반전 대상이라 같이 지운다. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme]) .pro-body #captcha_img { filter: invert(1); outline: 0; }
}
:root[data-theme="dark"] .pro-body #captcha_img { filter: invert(1); outline: 0; }

/* ---------- 사이드뷰 (순정 규약) ----------
   get_sideview()(common.lib.php:1620~)가 스킨을 거치지 않고 아래 구조를 직접 뱉는다.

       <span class="sv_wrap">
         <a class="sv_member">이름</a>
         <span class="sv">쪽지보내기 메일보내기 자기소개 …</span>
         <noscript class="sv_nojs"><span class="sv">…</span></noscript>
       </span>

   js/common.js 가 이름을 클릭하면 .sv 에 .sv_on 을 붙여 여는 방식이다.
   순정 CSS 를 싣지 않는 pro 테마에서 이 정의가 없으면 메뉴가 접히지 않고
   한 줄로 펼쳐져 표 폭을 밀어내고, 좁은 화면에서는 페이지에 가로 스크롤이 생긴다. */

.sv_wrap { position: relative; display: inline-block; }
.sv_wrap .sv {
    display: none;
    position: absolute; z-index: 40; top: calc(100% + var(--pro-sp-2)); inset-inline-start: 0;
    min-width: 9rem;
    padding: var(--pro-sp-1);
    background: hsl(var(--pro-popover));
    color: hsl(var(--pro-popover-foreground));
    border: 1px solid hsl(var(--pro-border));
    border-radius: var(--pro-radius-md);
    box-shadow: var(--pro-shadow-md);
    font-size: var(--pro-text-sm);
    font-weight: 400;
    white-space: nowrap;
    text-align: start;
}
.sv_wrap .sv a {
    display: block;
    padding: var(--pro-sp-2) var(--pro-sp-3);
    border-radius: var(--pro-radius-sm);
    color: hsl(var(--pro-popover-foreground));
}
.sv_wrap .sv a:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }
/* js/common.js 가 붙이는 클래스. 순정도 !important 로 연다. */
.sv_wrap .sv.sv_on { display: block; }
.sv_member, .sv_guest { cursor: pointer; }
/* JS 가 꺼진 브라우저에서는 <noscript> 안의 사본이 그대로 나온다.
   이때는 팝오버가 아니라 그냥 목록으로 두어야 위치가 어긋나지 않는다. */
.sv_nojs .sv { display: block; position: static; box-shadow: none; }

/* ---------- 순정이 스킨을 거치지 않고 직접 뱉는 마크업 대응 ----------

   pro 테마는 아이콘 폰트를 싣지 않는다(인라인 SVG 를 쓴다). 그래서 순정 lib·페이지가
   스킨을 안 거치고 뿌리는 <i class="fa …"> 는 글리프 없이 빈 자리만 차지한다.
   숨기는 것이 정직하다 — 없는 그림을 위해 공간을 비워 둘 이유가 없다. */
.pro-body i[class*="fa-"] { display: none; }

/* 다만 관리자 버튼은 라벨이 .sound_only 안에 들어 있어, 아이콘을 숨기면 빈 상자가 된다.
   (예: bbs/content.php:84 이 run_replace 로 뿌리는 "내용 수정" 버튼)
   여기서만 그 라벨을 드러내고 버튼 모양을 준다. */
.pro-body .btn_admin {
    display: inline-flex; align-items: center; gap: var(--pro-sp-2);
    height: 2rem; padding-inline: var(--pro-sp-3);
    border: 1px solid hsl(var(--pro-border)); border-radius: var(--pro-radius-md);
    color: hsl(var(--pro-muted-foreground));
    font-size: var(--pro-text-xs);
}
.pro-body .btn_admin:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }
.pro-body .btn_admin .sound_only {
    position: static; width: auto; height: auto;
    clip: auto; margin: 0; overflow: visible; white-space: nowrap;
}
.ctt_admin { display: flex; justify-content: flex-end; margin-bottom: var(--pro-sp-3); }

/* ---------- 방문자 집계 (푸터) ----------
   순정 skin/visit/basic 을 쓰지 않고 우리가 직접 그린다.
   그 스킨은 dd strong{color:#fff} 를 전제해 밝은 배경에서 숫자가 사라지고,
   자기 style.css 를 order 0 으로 실어 우리 core.css(order -11) 를 이겨 버린다. */
.pro-visit { display: flex; gap: var(--pro-sp-3); flex-wrap: wrap; align-items: baseline; margin: 0; }
.pro-visit dt { color: hsl(var(--pro-muted-foreground)); font-size: var(--pro-text-xs); margin: 0; }
.pro-visit dd { margin: 0 var(--pro-sp-2) 0 0; font-size: var(--pro-text-xs); font-weight: 600; }

/* ---------- 레이아웃 ---------- */

.pro-container {
    width: 100%;
    max-width: var(--pro-container);
    margin-inline: auto;
    padding-inline: var(--pro-sp-4);
}
@media (min-width: 768px) {
    .pro-container { padding-inline: var(--pro-sp-6); }
}

.pro-main { padding-block: var(--pro-sp-6) var(--pro-sp-12); min-height: 60vh; }

.pro-stack   { display: flex; flex-direction: column; gap: var(--pro-sp-4); }
.pro-row     { display: flex; align-items: center; gap: var(--pro-sp-2); flex-wrap: wrap; }
.pro-between { display: flex; align-items: center; justify-content: space-between; gap: var(--pro-sp-3); flex-wrap: wrap; }
.pro-spacer  { flex: 1 1 auto; }

/* ---------- 헤더 / 네비 ---------- */

.pro-header {
    position: sticky; top: 0; z-index: 40;
    height: var(--pro-header-h);
    display: flex; align-items: center;
    background: hsl(var(--pro-background) / .85);
    backdrop-filter: saturate(180%) blur(8px);
    border-bottom: 1px solid hsl(var(--pro-border));
}
.pro-header .pro-container { display: flex; align-items: center; gap: var(--pro-sp-4); }

.pro-logo {
    font-size: var(--pro-text-lg); font-weight: 700;
    letter-spacing: -0.02em; white-space: nowrap;
}

.pro-nav { display: none; align-items: center; gap: var(--pro-sp-1); }
@media (min-width: 768px) { .pro-nav { display: flex; } }

/* 햄버거: 모바일에서만 표시(헤더 우측 끝), 네비가 보이는 데스크탑에서는 숨김 */
@media (min-width: 768px) {
    .pro-header [data-pro-drawer-open] { display: none; }
}

.pro-header-auth { display: flex; align-items: center; gap: var(--pro-sp-2); }

/* 모바일 헤더: 간격을 줄이고, 로그인·회원가입은 드로어로 보낸다 */
@media (max-width: 767px) {
    .pro-header .pro-container { gap: var(--pro-sp-2); }
    .pro-header-auth { display: none; }
}

.pro-nav a {
    padding: var(--pro-sp-2) var(--pro-sp-3);
    border-radius: var(--pro-radius-md);
    font-weight: 500;
    color: hsl(var(--pro-muted-foreground));
    transition: background var(--pro-transition), color var(--pro-transition);
}
.pro-nav a:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }
.pro-nav a.is-active { color: hsl(var(--pro-foreground)); background: hsl(var(--pro-accent)); }

.pro-footer {
    border-top: 1px solid hsl(var(--pro-border));
    padding-block: var(--pro-sp-8);
    color: hsl(var(--pro-muted-foreground));
    font-size: var(--pro-text-xs);
}

/* ---------- 드로어 (모바일 네비) ---------- */

.pro-drawer-backdrop {
    position: fixed; inset: 0; z-index: 50;
    background: hsl(240 10% 3.9% / .5);
    opacity: 0; pointer-events: none;
    transition: opacity var(--pro-transition);
}
.pro-drawer-backdrop.is-open { opacity: 1; pointer-events: auto; }

.pro-drawer {
    position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 51;
    width: min(19rem, 82vw);
    background: hsl(var(--pro-background));
    border-inline-end: 1px solid hsl(var(--pro-border));
    box-shadow: var(--pro-shadow-lg);
    transform: translateX(-100%);
    transition: transform var(--pro-transition);
    display: flex; flex-direction: column;
    padding: var(--pro-sp-4);
    gap: var(--pro-sp-1);
    overflow-y: auto;
}
.pro-drawer.is-open { transform: translateX(0); }
.pro-drawer a {
    padding: var(--pro-sp-3);
    border-radius: var(--pro-radius-md);
    font-weight: 500;
}
.pro-drawer a:hover { background: hsl(var(--pro-accent)); }

/* 드로어 안 검색: 560px 이하에서 board.css 가 .pro-search 에 주는 flex:1 1 100% 는
   가로 플렉스(게시판 하단)용인데, 세로 플렉스인 드로어에서는 남는 높이를 다 먹고
   세로로 부풀어 오른다. 드로어 안에서는 늘지 않게 고정한다. */
.pro-drawer .pro-search { flex: none; }
/* 검색어 칸은 드로어 폭에서 남는 자리를 다 쓴다 — 9rem 에서 멈추면 버튼 오른쪽에
   죽은 여백이 남는다(560px 초과 태블릿 폭에서만 생기는 문제) */
.pro-drawer .pro-search .pro-input { flex: 1 1 auto; }

/* ---------- 버튼 ---------- */

/* 마루의 버튼은 pill 이다. 액센트 버튼만 탠저린 글로우를 달고 hover 에 1px 뜬다 —
   화면에서 「지금 누를 것」이 하나뿐임을 그림자로 말한다. */
.pro-btn {
    display: inline-flex; align-items: center; justify-content: center;
    gap: var(--pro-sp-2);
    height: 2.25rem;
    padding-inline: var(--pro-sp-4);
    border: 1px solid transparent;
    border-radius: var(--pro-radius-btn);
    background: hsl(var(--pro-primary));
    color: hsl(var(--pro-primary-foreground));
    box-shadow: var(--pro-shadow-primary);
    font-family: inherit;
    font-size: var(--pro-text-sm);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1;
    white-space: nowrap;
    cursor: pointer;
    text-decoration: none;
    transition: background var(--pro-transition), color var(--pro-transition),
                border-color var(--pro-transition), opacity var(--pro-transition),
                transform var(--pro-transition), box-shadow var(--pro-transition);
}
.pro-btn:hover      { background: hsl(var(--pro-primary) / .92); color: hsl(var(--pro-primary-foreground)); transform: translateY(-1px); }
.pro-btn:active     { transform: translateY(0); }
.pro-btn:disabled,
.pro-btn.is-disabled { opacity: .5; pointer-events: none; box-shadow: none; transform: none; }

/* 액센트가 아닌 변형은 글로우도 뜸도 없다. 액센트 버튼과 섞이면 위계가 무너진다. */
.pro-btn-secondary,
.pro-btn-outline,
.pro-btn-ghost,
.pro-btn-link { box-shadow: none; font-weight: 600; }
.pro-btn-secondary:hover,
.pro-btn-outline:hover,
.pro-btn-ghost:hover,
.pro-btn-link:hover { transform: none; }

.pro-btn-secondary   { background: hsl(var(--pro-secondary)); color: hsl(var(--pro-secondary-foreground)); }
.pro-btn-secondary:hover { background: hsl(var(--pro-secondary) / .7); color: hsl(var(--pro-foreground)); }

.pro-btn-outline     { background: hsl(var(--pro-card)); border-color: hsl(var(--pro-border)); color: hsl(var(--pro-foreground)); box-shadow: var(--pro-shadow-sm); }
.pro-btn-outline:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }

.pro-btn-ghost       { background: transparent; color: hsl(var(--pro-foreground)); }
.pro-btn-ghost:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }

.pro-btn-destructive { background: hsl(var(--pro-destructive)); color: hsl(var(--pro-destructive-foreground)); }
.pro-btn-destructive:hover { background: hsl(var(--pro-destructive) / .9); color: hsl(var(--pro-destructive-foreground)); }

/* link 변형은 버튼이 아니라 링크로 읽혀야 한다. 그래서 hover 에 바탕을 칠하지 않고
   밑줄만 진해진다 — .pro-btn:hover 가 primary 바탕을 칠하므로 여기서 되돌려 준다.
   밑줄 색을 따로 두는 이유: 쉬는 상태에서 글자보다 연해야 글이 먼저 읽힌다. */
.pro-btn-link {
    background: transparent;
    color: hsl(var(--pro-primary));
    padding-inline: 0;
    height: auto;
    border-radius: var(--pro-radius-sm);
    text-decoration: underline;
    text-decoration-color: hsl(var(--pro-primary) / .4);
    text-decoration-thickness: 1px;
    text-underline-offset: 4px;
    transition: color var(--pro-transition), text-decoration-color var(--pro-transition);
}
.pro-btn-link:hover {
    background: transparent;
    color: hsl(var(--pro-primary));
    text-decoration-color: currentColor;
    text-decoration-thickness: 2px;
}
.pro-btn-link:active { color: hsl(var(--pro-primary) / .8); }
.pro-btn-link:disabled,
.pro-btn-link.is-disabled { text-decoration-color: transparent; }

.pro-btn-sm   { height: 2rem; padding-inline: var(--pro-sp-3); font-size: var(--pro-text-xs); }
.pro-btn-lg   { height: 2.75rem; padding-inline: var(--pro-sp-6); font-size: var(--pro-text-base); }
.pro-btn-icon { width: 2.25rem; padding-inline: 0; }
.pro-btn-block{ display: flex; width: 100%; }

.pro-btn svg { width: 1rem; height: 1rem; flex: none; }

/* ---------- 폼 ---------- */

.pro-field { display: flex; flex-direction: column; gap: var(--pro-sp-2); }

.pro-label {
    font-size: var(--pro-text-sm); font-weight: 500;
    line-height: 1; color: hsl(var(--pro-foreground));
}
.pro-label .pro-required { color: hsl(var(--pro-destructive)); margin-inline-start: 2px; }

.pro-input, .pro-textarea, .pro-select {
    width: 100%;
    min-height: 2.25rem;
    padding: var(--pro-sp-2) var(--pro-sp-3);
    border: 1px solid hsl(var(--pro-input));
    border-radius: var(--pro-radius-md);
    /* 바닥색(--pro-background)이 아니라 카드색을 쓴다. 마루의 바닥은 라일락이라
       바닥색으로 채우면 muted 패널(댓글폼) 위에 놓였을 때 입력칸이 사라진다.
       흰 채움 + 실선이면 흰 카드·muted 패널·라일락 바닥 어디에 놓여도 읽힌다. */
    background: hsl(var(--pro-card));
    color: hsl(var(--pro-foreground));
    font-family: inherit;
    font-size: var(--pro-text-sm);
    line-height: 1.4;
    transition: border-color var(--pro-transition), box-shadow var(--pro-transition);
}
.pro-textarea { min-height: 8rem; resize: vertical; }

.pro-select {
    appearance: none;
    padding-inline-end: var(--pro-sp-8);
    background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right var(--pro-sp-3) center;
}

/* 비밀번호 표시 토글 — 입력창 오른쪽 안에 눈 아이콘을 얹는다.
   버튼이 자리를 먹지 않게 절대배치하고, 입력창은 그만큼 오른쪽 패딩을 비워 둔다. */
.pro-input-eye-wrap { position: relative; }
.pro-input-eye-wrap .pro-input { padding-inline-end: var(--pro-sp-8); }
.pro-input-eye {
    position: absolute; inset-inline-end: var(--pro-sp-1);
    top: 50%; transform: translateY(-50%);
    display: inline-flex; align-items: center; justify-content: center;
    width: 1.75rem; height: 1.75rem;
    border: 0; background: none; border-radius: var(--pro-radius-md);
    color: hsl(var(--pro-muted-foreground)); cursor: pointer;
}
.pro-input-eye:hover { color: hsl(var(--pro-foreground)); }
/* 기본은 eye 만, 표시 중(is-on)에는 eyeoff 만 보인다 */
.pro-input-eye svg:last-child { display: none; }
.pro-input-eye.is-on svg:first-child { display: none; }
.pro-input-eye.is-on svg:last-child { display: block; }

.pro-input::placeholder, .pro-textarea::placeholder { color: hsl(var(--pro-muted-foreground)); }

.pro-input:focus, .pro-textarea:focus, .pro-select:focus {
    outline: none;
    border-color: hsl(var(--pro-ring));
    box-shadow: 0 0 0 3px hsl(var(--pro-ring) / .15);
}

.pro-input:disabled, .pro-textarea:disabled, .pro-select:disabled {
    background: hsl(var(--pro-muted)); cursor: not-allowed; opacity: .7;
}

.pro-help  { font-size: var(--pro-text-xs); color: hsl(var(--pro-muted-foreground)); }
.pro-error { font-size: var(--pro-text-xs); color: hsl(var(--pro-destructive)); }

.pro-field.is-invalid .pro-input,
.pro-field.is-invalid .pro-textarea,
.pro-field.is-invalid .pro-select { border-color: hsl(var(--pro-destructive)); }

/* 체크박스 / 라디오
   ★ 이 테마의 마크업은 어디서나 <label class="pro-check-label"><input class="pro-check">…</label> 다.
      즉 .pro-check 는 감싸는 라벨이 아니라 input 자신에 붙는다. 예전 규칙은 .pro-check 를
      래퍼로 보고 「.pro-check input[type=checkbox]」에 크기를 줬는데 그런 마크업이 한 군데도
      없어(=규칙이 아무데도 안 걸려) 테마의 모든 체크박스·라디오가 브라우저 기본 13px 상자로
      남아 있었다. 기본 상자는 margin: 3px 3px 3px 4px 를 달고 나오므로 왼쪽으로 4px 밀리고,
      accent-color 도 안 먹어 같은 줄·아래 줄의 버튼과 세로선이 어긋났다.
      _pro/admin/design.php 목업만 <label class="pro-check"> 래퍼 형태라 그쪽도 함께 받는다. */
label.pro-check { display: inline-flex; align-items: center; gap: var(--pro-sp-2); cursor: pointer; font-size: var(--pro-text-sm); }
input.pro-check,
label.pro-check input[type="checkbox"],
label.pro-check input[type="radio"] {
    width: 1rem; height: 1rem; flex: none; margin: 0;
    accent-color: hsl(var(--pro-primary));
    cursor: pointer;
}

/* 스위치 */
.pro-switch { display: inline-flex; align-items: center; gap: var(--pro-sp-2); cursor: pointer; }
.pro-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.pro-switch-track {
    width: 2.25rem; height: 1.25rem; flex: none;
    border-radius: var(--pro-radius-full);
    background: hsl(var(--pro-input));
    transition: background var(--pro-transition);
    display: inline-flex; align-items: center; padding: 2px;
}
.pro-switch-thumb {
    width: 1rem; height: 1rem;
    border-radius: var(--pro-radius-full);
    background: hsl(var(--pro-background));
    box-shadow: var(--pro-shadow-sm);
    transition: transform var(--pro-transition);
}
.pro-switch input:checked + .pro-switch-track { background: hsl(var(--pro-primary)); }
.pro-switch input:checked + .pro-switch-track .pro-switch-thumb { transform: translateX(1rem); }

/* ---------- 카드 ---------- */

/* 마루의 카드는 테두리가 없다. 라일락 바닥 위에 흰 면을 얹고 두 겹 그림자로만
   띄운다. 테두리를 다시 넣으면 화면이 즉시 예전 shadcn 으로 돌아간다. */
.pro-card {
    background: hsl(var(--pro-card));
    color: hsl(var(--pro-card-foreground));
    border: 0;
    border-radius: var(--pro-radius-lg);
    box-shadow: var(--pro-shadow);
}
.pro-card-header { padding: var(--pro-sp-5) var(--pro-sp-6); border-bottom: 1px solid hsl(var(--pro-border)); }
.pro-card-title   { font-size: var(--pro-text-lg); font-weight: 600; }
.pro-card-desc    { font-size: var(--pro-text-sm); color: hsl(var(--pro-muted-foreground)); margin-top: var(--pro-sp-1); }
.pro-card-body    { padding: var(--pro-sp-6); }
.pro-card-footer  { padding: var(--pro-sp-4) var(--pro-sp-6); border-top: 1px solid hsl(var(--pro-border)); display: flex; gap: var(--pro-sp-2); flex-wrap: wrap; }

/* ---------- 배지 ---------- */

.pro-badge {
    display: inline-flex; align-items: center; gap: var(--pro-sp-1);
    padding: 0.125rem var(--pro-sp-2);
    border: 1px solid transparent;
    border-radius: var(--pro-radius-sm);
    background: hsl(var(--pro-primary));
    color: hsl(var(--pro-primary-foreground));
    font-size: var(--pro-text-xs); font-weight: 600; line-height: 1.4;
    white-space: nowrap;
}
.pro-badge-secondary   { background: hsl(var(--pro-secondary)); color: hsl(var(--pro-secondary-foreground)); }
.pro-badge-outline     { background: transparent; border-color: hsl(var(--pro-border)); color: hsl(var(--pro-foreground)); }
.pro-badge-destructive { background: hsl(var(--pro-destructive)); color: hsl(var(--pro-destructive-foreground)); }
.pro-badge-success     { background: hsl(var(--pro-success)); color: hsl(var(--pro-success-foreground)); }
.pro-badge-warning     { background: hsl(var(--pro-warning)); color: hsl(var(--pro-warning-foreground)); }
.pro-badge-info        { background: hsl(var(--pro-info)); color: hsl(var(--pro-info-foreground)); }

/* ---------- 알림띠 ---------- */

.pro-alert {
    display: flex; gap: var(--pro-sp-3);
    padding: var(--pro-sp-4);
    border: 1px solid hsl(var(--pro-border));
    border-radius: var(--pro-radius-lg);
    background: hsl(var(--pro-card));
    font-size: var(--pro-text-sm);
}
.pro-alert svg { width: 1.125rem; height: 1.125rem; flex: none; margin-top: 1px; }
.pro-alert-title { font-weight: 600; margin-bottom: var(--pro-sp-1); }
.pro-alert-info        { border-color: hsl(var(--pro-info) / .4);        background: hsl(var(--pro-info) / .08); }
.pro-alert-success     { border-color: hsl(var(--pro-success) / .4);     background: hsl(var(--pro-success) / .08); }
.pro-alert-warning     { border-color: hsl(var(--pro-warning) / .4);     background: hsl(var(--pro-warning) / .08); }
.pro-alert-destructive { border-color: hsl(var(--pro-destructive) / .4); background: hsl(var(--pro-destructive) / .08); }

/* ---------- 표 ---------- */

/* 열이 많아 카드로 접기 어려운 표(관리자 목록 등)는 이 래퍼로 가로 스크롤시킨다.
   페이지 body 가 가로로 밀리는 것은 어떤 경우에도 허용하지 않는다. */
.pro-table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

.pro-table { width: 100%; border-collapse: collapse; font-size: var(--pro-text-sm); }
.pro-table th, .pro-table td {
    padding: var(--pro-sp-3);
    text-align: left;
    border-bottom: 1px solid hsl(var(--pro-border));
    vertical-align: middle;
}
.pro-table thead th {
    font-weight: 500;
    color: hsl(var(--pro-muted-foreground));
    background: hsl(var(--pro-muted) / .5);
    white-space: nowrap;
}
.pro-table tbody tr { transition: background var(--pro-transition); }
.pro-table tbody tr:hover { background: hsl(var(--pro-muted) / .5); }

/* ---------- 페이지네이션 ---------- */

.pro-pagination { display: flex; align-items: center; justify-content: center; gap: var(--pro-sp-1); flex-wrap: wrap; margin-top: var(--pro-sp-6); }
/* 마루의 페이지네이션은 테두리가 없다. 현재 쪽만 먹색으로 채운다 —
   여기까지 탠저린을 쓰면 액센트가 화면에 두 번 나와 글쓰기 버튼이 안 보인다. */
.pro-pagination a, .pro-pagination span {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 2.25rem; height: 2.25rem;
    padding-inline: var(--pro-sp-2);
    border: 0;
    border-radius: var(--pro-radius-btn);
    font-size: var(--pro-text-sm);
    font-variant-numeric: tabular-nums;
    color: hsl(var(--pro-muted-foreground));
    transition: background var(--pro-transition), color var(--pro-transition);
}
.pro-pagination a:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }
.pro-pagination .is-current {
    background: hsl(var(--pro-foreground));
    color: hsl(var(--pro-background));
    font-weight: 700;
}
/* 좁은 화면에서는 현재 페이지 주변만 남긴다 (서버에서 기기 분기하지 않기 위한 CSS 축약) */
@media (max-width: 639px) {
    .pro-pagination .pro-page-far { display: none; }
}

/* 순정 get_paging() 이 뱉는 <nav.pg_wrap><span.pg><a.pg_page>…<strong.pg_current>
   구조를 그대로 받아 위 스타일에 태운다. 래퍼 두 겹은 display:contents 로 걷어내
   자식(a·strong)이 .pro-pagination 의 flex 아이템이 되게 한다. */
.pro-pagination .pg_wrap,
.pro-pagination .pg { display: contents; }
.pro-pagination .pg_current {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 2.25rem; height: 2.25rem; padding-inline: var(--pro-sp-2);
    border: 0; border-radius: var(--pro-radius-btn);
    background: hsl(var(--pro-foreground)); color: hsl(var(--pro-background));
    font-size: var(--pro-text-sm); font-weight: 700;
    font-variant-numeric: tabular-nums;
}
/* 검색 이전/다음 구간 버튼은 글자가 길어 최소폭만 갖는다 */
.pro-pagination .pg_search { min-width: auto; }

/* ---------- 탭 ---------- */

.pro-tabs { display: inline-flex; gap: var(--pro-sp-1); padding: var(--pro-sp-1); background: hsl(var(--pro-muted)); border-radius: var(--pro-radius-md); }
.pro-tab {
    padding: var(--pro-sp-2) var(--pro-sp-4);
    border-radius: var(--pro-radius-sm);
    font-size: var(--pro-text-sm); font-weight: 500;
    color: hsl(var(--pro-muted-foreground));
    cursor: pointer;
    transition: background var(--pro-transition), color var(--pro-transition);
}
.pro-tab.is-active { background: hsl(var(--pro-background)); color: hsl(var(--pro-foreground)); box-shadow: var(--pro-shadow-sm); }

/* ---------- 아바타 ---------- */

.pro-avatar {
    display: inline-flex; align-items: center; justify-content: center;
    width: 2rem; height: 2rem; flex: none;
    border-radius: var(--pro-radius-full);
    /* 원이 보여야 사람 자리로 읽힌다. --pro-muted 는 바닥과 겹쳐 사라진다. */
    background: hsl(var(--pro-secondary));
    color: hsl(var(--pro-secondary-foreground));
    font-size: var(--pro-text-xs); font-weight: 600;
    overflow: hidden;
}
.pro-avatar img { width: 100%; height: 100%; object-fit: cover; }
.pro-avatar-sm { width: 1.5rem; height: 1.5rem; font-size: 0.625rem; }
.pro-avatar-lg { width: 3rem; height: 3rem; font-size: var(--pro-text-sm); }

/* ---------- 드롭다운 ---------- */

.pro-dropdown { position: relative; display: inline-block; }
.pro-dropdown-menu {
    position: absolute; inset-inline-end: 0; top: calc(100% + var(--pro-sp-2)); z-index: 30;
    min-width: 11rem;
    padding: var(--pro-sp-1);
    background: hsl(var(--pro-popover));
    color: hsl(var(--pro-popover-foreground));
    border: 1px solid hsl(var(--pro-border));
    border-radius: var(--pro-radius-md);
    box-shadow: var(--pro-shadow-md);
    display: none;
}
.pro-dropdown-menu.is-open { display: block; }
.pro-dropdown-item {
    display: flex; align-items: center; gap: var(--pro-sp-2);
    padding: var(--pro-sp-2) var(--pro-sp-3);
    border-radius: var(--pro-radius-sm);
    font-size: var(--pro-text-sm);
    cursor: pointer;
}
.pro-dropdown-item:hover { background: hsl(var(--pro-accent)); color: hsl(var(--pro-accent-foreground)); }
.pro-dropdown-sep { height: 1px; background: hsl(var(--pro-border)); margin: var(--pro-sp-1) 0; }

/* ---------- 모달 ---------- */

.pro-modal-backdrop {
    position: fixed; inset: 0; z-index: 60;
    background: hsl(240 10% 3.9% / .6);
    display: none; align-items: center; justify-content: center;
    padding: var(--pro-sp-4);
}
.pro-modal-backdrop.is-open { display: flex; }
.pro-modal {
    width: 100%; max-width: 30rem;
    max-height: 85vh; overflow-y: auto;
    background: hsl(var(--pro-background));
    border: 1px solid hsl(var(--pro-border));
    border-radius: var(--pro-radius-lg);
    box-shadow: var(--pro-shadow-lg);
}
.pro-modal-header { padding: var(--pro-sp-5) var(--pro-sp-6); }
.pro-modal-title  { font-size: var(--pro-text-lg); font-weight: 600; }
.pro-modal-body   { padding: 0 var(--pro-sp-6) var(--pro-sp-5); }
.pro-modal-footer { padding: var(--pro-sp-4) var(--pro-sp-6); border-top: 1px solid hsl(var(--pro-border)); display: flex; justify-content: flex-end; gap: var(--pro-sp-2); }

/* ---------- 토스트 ---------- */

.pro-toast-stack {
    position: fixed; inset-block-end: var(--pro-sp-4); inset-inline-end: var(--pro-sp-4);
    z-index: 70; display: flex; flex-direction: column; gap: var(--pro-sp-2);
    max-width: min(24rem, calc(100vw - 2rem));
}
.pro-toast {
    padding: var(--pro-sp-3) var(--pro-sp-4);
    background: hsl(var(--pro-popover));
    color: hsl(var(--pro-popover-foreground));
    border: 1px solid hsl(var(--pro-border));
    border-radius: var(--pro-radius-md);
    box-shadow: var(--pro-shadow-lg);
    font-size: var(--pro-text-sm);
    animation: pro-toast-in 200ms cubic-bezier(0.4, 0, 0.2, 1);
}
.pro-toast-destructive { border-color: hsl(var(--pro-destructive) / .5); }
@keyframes pro-toast-in {
    from { opacity: 0; transform: translateY(0.5rem); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ---------- 로딩 ---------- */

.pro-skeleton {
    /* --pro-muted 는 바닥(#F1F1F6)과 1.01:1 이라 자리표시가 안 보였다.
       스켈레톤은 '여기에 무언가 올 것이다' 를 보여주는 게 전부다. 안 보이면 없느니만 못하다. */
    background: hsl(var(--pro-border));
    border-radius: var(--pro-radius-sm);
    animation: pro-pulse 1.6s ease-in-out infinite;
}
@keyframes pro-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } }

.pro-spinner {
    width: 1rem; height: 1rem;
    border: 2px solid hsl(var(--pro-muted-foreground) / .3);
    border-top-color: hsl(var(--pro-foreground));
    border-radius: var(--pro-radius-full);
    animation: pro-spin 700ms linear infinite;
    display: inline-block;
}
@keyframes pro-spin { to { transform: rotate(360deg); } }

/* ---------- 브레드크럼 ---------- */

.pro-breadcrumb { display: flex; align-items: center; gap: var(--pro-sp-2); font-size: var(--pro-text-xs); color: hsl(var(--pro-muted-foreground)); flex-wrap: wrap; }
.pro-breadcrumb a:hover { color: hsl(var(--pro-foreground)); }
.pro-breadcrumb-sep { opacity: .5; }

/* ---------- 빈 상태 ---------- */

.pro-empty { padding: var(--pro-sp-12) var(--pro-sp-4); text-align: center; color: hsl(var(--pro-muted-foreground)); }
.pro-empty svg { width: 2.5rem; height: 2.5rem; opacity: .4; margin-bottom: var(--pro-sp-3); }

/* ---------- 접근성: 모션 축소 ---------- */

@media (prefers-reduced-motion: reduce) {
    .pro-body *, .pro-body *::before, .pro-body *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }
}
