@charset "utf-8";

/**
 * 게시판 CSS
 *
 * **스킨이 그리는 것은 여기, 테마가 그리는 것은 front.css.** 선이 그렇게
 * 그어진 이유는 실리는 곳이 다르기 때문이다.
 *
 * | | globals | board | front | jh_admin |
 * |---|---|---|---|---|
 * | 홈페이지 | O | O | O | |
 * | 관리자 껍데기 | O | O | | O |
 *
 * 게시판 목록과 쓰기는 관리자 안에서도 연다(adm/jh_board.php). **마크업 한
 * 벌이 껍데기 둘에서 도는 것이라 CSS 도 둘 다 닿아야 한다.** 스킨이
 * `add_stylesheet()` 로 부르면 코어가 껍데기와 상관없이 끼워 넣어 준다.
 *
 * > **`:root` 를 쓰지 않는다.** front.css 는 `--fs-body` · `--bg` 같은 토큰을
 * > `:root` 에서 덮는데, 그것이 관리자에 실리면 관리자 전체 글자와 바닥색이
 * > 바뀐다. 이 파일이 관리자까지 가는 이유가 그 하나다. 토큰이 필요하면
 * > globals.css 에 넣고 둘이 같이 읽는다.
 *
 * 글자는 `em` 으로 잰다. 껍데기마다 바탕 크기가 달라서(관리자 14px ·
 * 홈페이지 16px) `rem` 으로 박으면 관리자 안에서 게시판만 커 보인다.
 *
 * 이름은 `board-` 그대로다. 게시판은 홈페이지 화면이고 관리자 껍데기는 그것을
 * 들여다보는 두 번째 창이다. 접두사는 **어느 껍데기에 실리느냐가 아니라 무엇의
 * 화면이냐**를 가리킨다.
 *
 * **스킨마다 CSS 를 두지 않는다.** 그누보드는 스킨 폴더마다 style.css 를
 * 넣어 배포하는데, basic 과 gallery 를 견줘 보면 선택자 274개 중 245개(83%)가
 * 같은 코드였다. 상세 · 쓰기 · 댓글 · 검색이 통째로 두 벌인 것이다. 우리는
 * 배포하지 않고 테마를 통째로 복제해 쓰므로 한 장으로 둔다. 스킨마다 다른
 * 것은 파일이 아니라 **이름으로 가른다** (목록 표는 `board-list`, 격자는
 * `board-gallery`).
 */

/* ============================================================
   메인 히어로 슬라이드

   마크업은 skin/latest/hero, 넘기는 일은 Swiper 다. 첫 화면에만 있다.

   **Swiper 의 화살표 · 페이지네이션을 안 쓴다.** 그쪽은 제 클래스로 그려서
   우리 규칙 밖에 있고, 생김새를 고치려면 라이브러리 클래스를 덮어쓰는 규칙이
   늘어난다. 우리가 그리고 값만 받는다(front.js).
   ============================================================ */
.board-hero {
    position: relative;

    /*
     * **안을 자른다.** 사진이 스크롤을 따라 아래로 처지는데(front.js 의
     * 「사진이 스크롤을 따라 처진다」) 안 자르면 그만큼이 다음 구획 위로
     * 넘어온다. 조작기는 이 상자의 자식이지 사진 쪽이 아니라 안 딸려 간다.
     */
    overflow: hidden;
    background: var(--color-gray-900);
}

/*
 * 커튼이 지나가는 결.
 *
 * **Swiper 클래스를 덮는 자리는 여기 하나뿐이다.** 넘어가는 시간은 Swiper 가
 * 인라인으로 적어 주지만 **가속 곡선은 CSS 몫**이라, 안 적으면 브라우저 기본값
 * `ease` 가 걸린다. 그것은 앞이 빠르고 뒤가 긴 곡선이라 커튼이 **처음에
 * 확 지나가고 끝에서 질질 끌린다.**
 *
 * 앞뒤가 같은 곡선으로 바꾼다. 경계선이 일정한 속도로 화면을 가로지르는 것이
 * 커튼이 커튼으로 읽히는 조건이다.
 *
 * 슬라이드와 그 안에서 반대로 밀리는 겹이 **같은 곡선이어야 한다.** 하나만
 * 바꾸면 사진이 가만히 서 있지 않고 미세하게 흔들린다.
 */
.board-hero__viewport .swiper-wrapper,
.board-hero [data-swiper-parallax] {
    transition-timing-function: cubic-bezier(.62, .03, .2, 1);
}

/*
 * .swiper 는 라이브러리 클래스다. **여기 하나만 겹쳐 쓴다.** Swiper 가 폭·넘침·
 * 배치를 그 이름으로 잡으므로 뗄 수 없고, 우리는 높이만 얹는다.
 */
.board-hero__viewport {
    /*
     * **화면 하나를 꽉 채운다.**
     *
     * **`vh` 도 `dvh` 도 아니고 `svh` 다.** 셋 다 화면 높이지만 폰의 주소창을
     * 다르게 센다. `vh` 는 주소창이 접힌 큰 높이라 처음에 화면보다 크게
     * 그려지고, `dvh` 는 스크롤할 때마다 값이 바뀌어 **히어로가 늘었다 줄었다
     * 한다.** `svh` 는 늘 작은 쪽으로 고정이라 한 번 그린 크기가 그대로다.
     *
     * 하한 420px 은 가로로 눕힌 폰을 위한 것이다. 거기서는 100svh 가 350px
     * 언저리라, 그 안에서 대문구와 버튼이 설 자리가 안 나온다.
     */
    height: max(420px, 100svh);
}

.board-hero__list {
    /* globals 가 ul 의 목록표만 걷는다. 자리 잡는 것은 Swiper 몫이다 */
    height: 100%;
}

.board-hero__slide {
    position: relative;
    overflow: hidden;
}

/*
 * 그림을 미는 겹. 커튼은 이것을 슬라이드와 **반대로 밀어서** 만든다.
 * 슬라이드가 왼쪽으로 가는 만큼 이 겹이 오른쪽으로 가므로 화면에서는 사진이
 * 가만히 서 있고, 움직이는 것은 슬라이드의 경계선뿐이다.
 */
.board-hero__shift {
    display: block;
    width: 100%;
    height: 100%;
}

/*
 * 그림. 정한 비율과 실제 그림 비율이 다를 때 남는 자리를 만들지 않고 잘라 낸다.
 * globals 의 `:where(img) { height: auto }` 를 여기서 되돌린다.
 */
.board-hero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/*
 * 움직이기 전의 자리를 CSS 가 갖는다.
 *
 * 사진이 제 크기로 내려앉는 것과 글이 떠오르는 것은 front.js 가 만드는데,
 * 그 파일은 문서를 다 읽은 뒤에 돈다(`defer`). 시작값을 스크립트에만 두면
 * **첫 페인트와 그 사이에 끝난 화면이 한 번 보인다.** CPU 를 여섯 배 느리게
 * 하고 재보니 사진이 0.38초에 제 크기로 서 있다가 **1.32초에 1.03배로 튀었고**,
 * 대문구도 그 자리에서 보였다가 사라졌다 다시 올라왔다.
 *
 * **여는 화면이 서면 커튼이 그것을 다 가린다.** 그래서 오래 안 보였다. 같은
 * 방문에 두 번째로 들어오는 사람은 덮개가 없어 그대로 본다.
 *
 * **`kit-motion` 에 건다.** 스크립트가 꺼져 있거나 어지럼을 타는 설정이면 표가
 * 안 붙어 규칙이 통째로 죽고 화면이 그냥 선다. 라이브러리가 안 실리는 때를
 * 위해 head.sub.php 가 문서를 다 읽고 표를 뗀다. **초기값이 정상 동작이다**
 * (web/CLAUDE.md 의 「첫 페인트 전에 정리한다」).
 *
 * > **뗄 때 튀지 않는다.** `defer` 스크립트는 `load` 보다 반드시 먼저 도므로,
 * > 표를 떼는 시점에는 GSAP 이 이미 인라인 값을 걸어 둔 뒤다. 인라인이 이겨서
 * > 표가 빠져도 화면이 안 바뀐다.
 */
.kit-motion .board-hero__img { transform: scale(1.03); }

/*
 * 글은 슬라이드마다 따로 연다. front.js 의 intro() 가 그 장을 맡을 때
 * `data-hero-live` 를 붙이고, 그 순간 GSAP 이 이미 시작값을 써 둔 뒤다.
 *
 * **장마다 가르는 것은 넘어갈 때도 같은 일이 일어나기 때문이다.** 아직 안 온
 * 장의 글은 화면 밖에 있어도 열어 둘 이유가 없다.
 */
.kit-motion .board-hero__slide:not([data-hero-live]) .board-hero__title,
.kit-motion .board-hero__slide:not([data-hero-live]) .board-hero__desc,
.kit-motion .board-hero__slide:not([data-hero-live]) .board-hero__btn { opacity: 0; }

/*
 * 그림 위에 까는 어두운 겹.
 *
 * **글이 있는 슬라이드에만 깐다.** 그림마다 밝기가 달라 이것이 없으면 밝은
 * 사진에서 흰 글자가 안 읽힌다. 글이 앉는 왼쪽만 진하고 오른쪽으로 갈수록
 * 옅어져, 사진을 통째로 어둡게 만들지 않는다.
 */
.board-hero__veil {
    position: absolute;
    inset: 0;

    /*
     * **파는 것이 사진이라 사진을 죽이면 안 된다.**
     *
     * 한때 위아래와 왼쪽을 함께 눌러 화면 전체가 한 겹 어두웠다. 글자는 잘
     * 읽혔지만 **사진이 인쇄물처럼 가라앉았다.** 대비는 글이 실제로 앉는
     * 자리에서만 벌면 된다.
     *
     * 그래서 두 겹 다 **절반쯤에서 완전히 사라진다.** 오른쪽 절반과 아래쪽은
     * 사진 원본 그대로다. 남는 자리는 글자 제 그림자(아래 __title)가 받는다.
     *
     *   가로 겹  글이 앉는 왼쪽. 55% 에서 0
     *   세로 겹  겹쳐 있는 머리줄의 흰 글자 몫. 위 22% 까지만
     */
    background:
        linear-gradient(180deg,
            rgb(0 0 0 / .3) 0%,
            rgb(0 0 0 / 0) 22%),
        linear-gradient(96deg,
            rgb(0 0 0 / .6) 0%,
            rgb(0 0 0 / .3) 28%,
            rgb(0 0 0 / 0) 55%);
}

/*
 * 글이 앉는 자리. **기본은 왼쪽 위다.**
 *
 * 시안마다 자리가 달라지는 곳이라, 바꿀 때는 이 규칙의 정렬 두 줄만 고친다.
 */
.board-hero__body {
    position: absolute;
    inset: 0;

    /*
     * 본문과 같은 세로선에서 시작한다.
     *
     * 예전에는 마크업에 .board-inner 를 함께 얹었는데, 그 이름은 front.css 것이라
     * **관리자 껍데기에서는 규칙이 없다.** 그 화면(글 하나 보기의 미리보기)에서만
     * 글이 그림 끝에 붙었다. 이 파일은 제 힘으로 서야 한다.
     *
     * `--content-max` 와 `--gutter` 는 **껍데기가 덮는 값**이다. globals.css 에
     * 기본값이 있고 관리자와 홈페이지가 제 값으로 바꾼다. 그래서 이름 하나로
     * 「지금 이 화면의 값」을 가리킬 수 있다. web/CLAUDE.md 의 「토큰이 사는 곳」.
     */
    width: 100%;
    max-width: var(--content-max);
    margin-inline: auto;
    padding-inline: var(--gutter);

    display: flex;
    flex-direction: column;
    /*
     * **왼쪽 아래에 앉는다.**
     *
     * 한때 세로 가운데였는데, 음식 사진은 담긴 것이 대개 한가운데라 **글이
     * 피사체 위에 그대로 얹혔다.** 아래로 내리면 사진의 위 두 겹이 통째로
     * 열리고, 글은 아래 여백에 앉는다. 건축 · 사진 쪽 사이트가 대개 이 자리다.
     *
     * 아래 여백은 조작 줄이 설 자리를 남긴 값이다. 둘이 같은 아래줄을 나눠
     * 쓴다. 왼쪽에 글, 오른쪽에 선 셋.
     */
    align-items: flex-start;   /* 가로: 왼쪽 */
    justify-content: flex-end; /* 세로: 아래 */
    gap: clamp(12px, 1.6vw, 22px);
    padding-block: clamp(72px, 12vh, 140px) clamp(84px, 11vh, 130px);
    color: var(--color-white);
    /* 글자 위를 눌러도 슬라이드를 끌 수 있어야 한다. 버튼만 받는다 */
    pointer-events: none;
}

.board-hero__title {
    /*
     * **`em` 이라 글자가 커질수록 함께 넓어진다.** 대문구는 폭을 따라 40px 에서
     * 112px 까지 자라므로, px 로 가두면 넓은 화면에서만 줄이 갈린다. 10em 은
     * 한글 열 자 언저리이고, 그보다 길면 두 줄로 넘어가는 것이 맞다.
     */
    max-width: 10em;
    font-size: var(--fs-display);
    font-weight: 700;
    /*
     * **크게 갈수록 조이되 1 까지 내리지는 않는다.** 112px 짜리 두 줄에 1.25 를
     * 주면 줄 사이가 28px 이라 두 줄이 따로 논다. 그렇다고 1 로 두면 **한글은
     * 두 줄이 서로 붙는다.** 라틴 글자와 달리 받침이 글자칸 아래까지 내려와서,
     * 글자칸을 글자 크기에 딱 맞추면 윗줄 받침과 아랫줄 머리가 맞닿는다.
     * 1.18 이면 붙지 않으면서 한 덩어리로 읽힌다. 자간도 같이 좁힌다. 큰
     * 글자는 원래 자간이 넓어 보인다.
     */
    line-height: 1.18;
    letter-spacing: var(--ls-display);
    /*
     * 스크림을 걷어 사진을 살린 만큼(위 __veil) **글자가 제 그림자로 선다.**
     * 넓고 옅게 깔아 글자 뒤만 눌러 준다. 진하고 좁게 주면 글자에 테두리가
     * 생긴 것처럼 보인다.
     */
    text-shadow: 0 2px 24px rgb(0 0 0 / .45);
}

.board-hero__desc {
    max-width: 32em;
    font-size: var(--fs-heading);
    line-height: 1.6;
    letter-spacing: var(--ls-label);
    text-shadow: 0 1px 14px rgb(0 0 0 / .45);
}

/*
 * 버튼.
 *
 * **알약이 아니다.** 둥근 알약은 부드럽고 친근한 쪽인데 이 사이트가 잡은
 * 결(Refined · Tailored)은 각이 선 쪽이다. 모서리를 거의 없애고 자간을 벌려
 * 글자를 또박또박 세운다.
 */
.board-hero__btn {
    display: inline-flex;
    align-items: center;
    min-height: 3em;
    margin-top: 10px;
    padding: 0 1.7em;
    border-radius: 2px;
    background: var(--color-primary);
    color: var(--color-white);
    font-size: var(--fs-caption);
    font-weight: 700;
    letter-spacing: var(--ls-label);
    pointer-events: auto;   /* 위에서 꺼 둔 것을 이 버튼만 되살린다 */
}

.board-hero__btn:hover { background: var(--color-primary-hover); }

/* ------------------------------------------------------------
   조작 줄

   그림 위 오른쪽 아래에 얹는다. 덩어리는 둘뿐이다. 가는 선 셋과 멈춤 하나.
   슬라이드가 하나면 마크업 자체가 안 나온다.
   ------------------------------------------------------------ */
.board-hero__bar {
    position: absolute;
    right: 0;
    bottom: clamp(20px, 4vh, 44px);
    left: 0;

    /*
     * 본문과 같은 세로선에서 끝난다.
     *
     * `--content-max` 와 `--gutter` 는 **껍데기가 덮는 값**이다. globals.css 에
     * 기본값이 있고 관리자와 홈페이지가 제 값으로 바꾼다. 그래서 이름 하나로
     * 「지금 이 화면의 값」을 가리킬 수 있다. web/CLAUDE.md 의 「토큰이 사는 곳」.
     */
    width: 100%;
    max-width: var(--content-max);
    margin-inline: auto;
    padding-inline: var(--gutter);

    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 20px;
    pointer-events: none;
}

/*
 * 선 셋.
 *
 * **어두운 판을 안 깐다.** 그것을 깔면 사진 위에 상자가 하나 더 생긴다.
 * 대신 선 자체에 그림자를 줘서 밝은 사진 위에서도 가장자리가 보이게 한다.
 */
.board-hero__dots {
    display: flex;
    align-items: center;
    gap: 10px;
    list-style: none;
    pointer-events: auto;
    filter: drop-shadow(0 1px 3px rgb(0 0 0 / .5));
}

.board-hero__dot { display: flex; }

/*
 * 누르는 자리는 선보다 크다. 선은 2px 인데 손가락은 그것을 못 짚는다.
 * 위아래 여백으로 키우고 눈에 보이는 것은 선만 남긴다.
 */
.board-hero__dotbtn {
    display: block;
    width: clamp(28px, 4vw, 52px);
    padding: 11px 0;
    border: 0;
    background: none;
}

/*
 * 선의 바닥.
 *
 * **셋이 같은 밝기다.** 한때 안 고른 선을 45%, 고른 선의 바닥을 30% 로 두었는데
 * 그러면 **안 고른 선이 더 밝아서 「이미 가득 찬 게이지」로 보인다.** 게이지는
 * 바닥이 어둡고 채워지는 것이 밝아야 읽힌다. 지금 어느 것인지는 그 위에
 * 차오르는 흰 선이 말한다.
 */
.board-hero__dotbtn::before {
    content: "";
    display: block;
    height: 2px;
    border-radius: var(--radius-full);
    background: rgb(255 255 255 / .3);
}

/*
 * 다음 장까지 남은 시간.
 *
 * 폭이 아니라 **scaleX 로 늘린다.** 폭을 애니메이션하면 프레임마다 배치를
 * 다시 재느라 끊긴다. transform 은 그리기 단계에서만 움직인다.
 */
.board-hero__dotfill {
    display: block;
    height: 2px;
    margin-top: -2px;
    border-radius: var(--radius-full);
    background: var(--color-white);
    transform: scaleX(0);
    transform-origin: left center;
}

/*
 * 재생 · 멈춤.
 *
 * 네모 둘이 멈춤, 세모 하나가 재생이다. 상태는 aria-pressed 가 말하고
 * 생김새는 그것을 그대로 잡는다.
 */
.board-hero__play {
    display: flex;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: 0;
    background: none;
    color: var(--color-white);
    pointer-events: auto;
    filter: drop-shadow(0 1px 3px rgb(0 0 0 / .5));
}

.board-hero__play:hover { opacity: .7; }

.board-hero__playicon {
    width: 9px;
    height: 11px;
    border-left: 3px solid currentColor;
    border-right: 3px solid currentColor;
}

/* 멈춰 있으면 세모(재생)로 바뀐다 */
.board-hero__play[aria-pressed="false"] .board-hero__playicon {
    width: 0;
    height: 0;
    border-top: 6px solid transparent;
    border-bottom: 6px solid transparent;
    border-right: 0;
    border-left: 10px solid currentColor;
}

/*
 * **좁은 화면용 규칙이 없다.** 선 셋과 버튼 하나뿐이라 폰에서도 자리가 남고,
 * 선 하나의 폭이 `clamp()` 라 화면을 따라 함께 줄어든다. 한때 여기서 진행
 * 막대를 감췄는데, 그것은 조작기가 다섯이던 때의 이야기다.
 */

/* ============================================================
   게시판 공용 부품

   프론트에서 관리자가 손대는 화면(지금은 메인 슬라이드)과 앞으로 짤 게시판
   스킨이 함께 쓴다. **부품은 화면마다 새로 만들지 않는다.** 관리자에서
   admin-btn · admin-input 하나로 모은 것과 같은 규칙이다.
   ============================================================ */

/* ── 안내 상자 ────────────────────────────── */
.board-alert {
    margin-bottom: 24px;
    padding: 14px 18px;
    border-left: 3px solid var(--color-primary);
    border-radius: var(--radius-md);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
    font-size: var(--fs-caption);
}

.board-alert__strong { font-weight: 700; }

/*
 * **버튼과 입력칸은 여기 없다.** globals.css 의 `kit-btn` · `kit-input` 이다.
 * 한때 `board-` 와 `front-` 두 벌이 접두사만 다른 같은 글자였다.
 */

.board-check { width: 18px; height: 18px; accent-color: var(--color-primary); }

/* ── 글줄에 곁들이는 표시 ─────────────────── */
/*
 * 분류 · 댓글 수 · 새 글. **글 한 줄에 붙는 작은 표시 셋**이라 목록이 표든
 * 격자든 모양이 같다. 표(board-list)에서 먼저 나왔지만 갤러리가 그대로 쓰므로
 * 공용으로 올렸다. 「글자 모양은 공용 이름을 쓴다」(web/CLAUDE.md).
 */
.board-tag {
    display: inline-block;
    margin-right: 6px;
    padding: 0.2em 0.6em;
    border-radius: var(--radius-full);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
    font-size: var(--fs-caption);
}

/* <a> 로도 <span> 으로도 쓴다. 밑줄만 막으면 둘 다 같게 보인다 */
.board-tag:hover { text-decoration: none; }

/* 공지는 분류 자리에 같은 모양으로 앉는다 */
.board-tag--notice { background: var(--color-primary); color: var(--color-white); font-weight: 700; }

/*
 * 지금 고른 것. **`aria-current` 를 그대로 짚는다.** 클래스를 따로 붙이면
 * 화면과 읽는 기계가 어긋날 자리가 하나 는다 (web/CLAUDE.md 의
 * 「상태를 나타내는 훅」). 전체검색 결과의 게시판 줄이 쓴다.
 */
.board-tag[aria-current="page"] {
    background: var(--color-primary);
    color: var(--color-white);
    font-weight: 700;
}

.board-tag[aria-current="page"] .board-result__count { color: var(--color-white); }

.board-cmt,
.board-flag {
    display: inline-block;
    margin-left: 4px;
    padding: 0 0.4em;
    border-radius: var(--radius-sm);
    font-size: var(--fs-caption);
    font-weight: 700;
    vertical-align: middle;
}

.board-cmt  { background: var(--color-primary-light); color: var(--color-primary-ink); }
.board-flag { color: var(--text-weak); }

/* ── 입력 폼 ──────────────────────────────── */
.board-form {
    display: grid;
    gap: 28px;
    padding: 32px 0;
    border-top: 1px solid var(--border);
}

/*
 * 이름과 칸을 나란히 둔다. 좁아지면 이름이 칸 위로 올라간다.
 * 최소 폭을 주는 이유는 이름이 길어도 칸이 먼저 좁아지지 않게 하려는 것이다.
 */
.board-form__row {
    display: grid;
    grid-template-columns: minmax(120px, 160px) minmax(0, 1fr);
    gap: 12px 24px;
    align-items: start;
}

.board-form__label {
    padding-top: 0.7em;
    color: var(--text-weak);
    font-weight: 500;
}

/* 필수 칸은 이름 뒤에 별표. 색만으로 알리지 않는다 */
.board-form__label--required::after {
    content: " *";
    color: var(--color-danger);
}

.board-form__field {
    display: grid;
    gap: 8px;
}

.board-form__help {
    color: var(--text-weak);
    font-size: var(--fs-caption);
    line-height: 1.6;
}

.board-form__preview { display: block; }

.board-form__previewimg {
    display: block;
    width: 100%;
    max-width: 320px;
    height: auto;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
}

/*
 * 폼 아래 버튼 줄.
 *
 * **가운데로 모은다.** 오른쪽 끝에 두면 화면 우하단의 「맨 위로」와 겹친다.
 * 목록의 버튼 줄(board-bar--foot)과 같은 이유고 관리자 툴바도 그렇다.
 */
/*
 * 폼의 저장 줄.
 *
 * **바닥에 붙어 따라다닌다.** 목록의 버튼 줄(`board-bar--foot`)과 관리자
 * 툴바(`admin-toolbar`)가 이미 그렇다. 이 줄만 안 그러고 있었다.
 *
 * 여기가 그 셋 중 가장 긴 화면이다. 글 쓰는 폼에는 에디터가 들어가서,
 * 저장하려면 그 상자를 통째로 지나 내려가야 했다.
 *
 * **좁은 화면의 문의 판은 제 것을 쓴다.** `front.css` 의
 * `.front-layer--sheet .front-inquiry__foot` 이 특이도가 높아 이 규칙을 이긴다.
 * 그쪽은 디자인한 화면이라 여백을 따로 쟀다.
 */
.board-form__foot {
    position: sticky;
    bottom: 0;
    z-index: 16;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: center;
    padding-top: 24px;
    /* 떠 있을 때 뒤의 폼이 비쳐 보이지 않게 바탕을 깐다. 목록 줄과 같다 */
    padding-bottom: 16px;
    border-top: 1px solid var(--border);
    background: var(--bg);
}

@media (max-width: 640px) {
    .board-form__row { grid-template-columns: 1fr; }
    .board-form__label { padding-top: 0; }
}

/* ============================================================
   글쓴이 이름 · board-name

   게시판 목록 · 상세 · 댓글 · 갤러리가 글쓴이를 내는 자리다. 이름 하나뿐이라
   제 규칙이 없다. 감싸는 칸(board-list__name · board-view__by ·
   board-comment__by · board-gallery__name)이 글자 모양을 이미 정한다.

   **이름만 있는 것이 원래 모습이 아니다.** 코어 get_sideview() 는 이름을
   `<a>` 로 감싸고 그 밑에 링크 다섯을 펼치는 작은 메뉴를 단다(사이드뷰).
   그 다섯을 extend/jh_sideview.extend.php 가 걷었다. 왜 걷었는지는 그 파일에
   있다.

   ── 코어가 남기는 빈 상자 셋 ───────────────────────────────

   `sv_wrap` · `sv` · `sv_nojs` 는 훅이 못 닿는 자리라 그대로 나온다. 메뉴가
   비었으니 `<span class="sv"></span>` 처럼 안이 빈 채로 남고, 빈 인라인
   상자는 자리를 안 차지하므로 규칙을 줄 것이 없다.

   > **그래도 `.sv` 를 감춰 둔다.** 저 상자에 무엇이든 들어가는 순간 이름 옆에
   > 글자로 쏟아진다. 실제로 겪었다. 사이드뷰를 처음 켰을 때 감추는 규칙이
   > 없어 「관리자쪽지보…」처럼 링크 다섯이 열 너비에 잘린 채 박혀 있었다.
   > 그누보드는 그 규칙을 스킨의 style.css 에 두는데 우리는 그 파일을 지웠다.
   > 한 줄로 그 자리를 막아 둔다.
   ============================================================ */
.sv_wrap .sv { display: none; }

/* ============================================================
   전체게시물 · board-new__*

   게시판을 가리지 않고 최근 글과 댓글을 한 줄로 세우는 화면이다(bbs/new.php).
   목록 표는 board-list 를 그대로 물려받고, 이 화면에만 있는 것은 거르는 줄과
   그룹·게시판 두 칸이다.

   **`board-search` 를 안 쓴다.** 그 이름은 버튼으로 여닫는 검색 판이라 평소에는
   `[hidden]` 으로 접혀 있다. 여기 것은 늘 보이는 줄이다.
   ============================================================ */
.board-new__filter { margin-bottom: 16px; }

.board-new__form {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* 코어가 만들어 주는 상자라 안쪽에 이름을 못 붙인다. 담는 자리만 잡는다 */
.board-new__group,
.board-new__select { flex: 0 0 auto; }

.board-new__group select,
.board-new__select {
    min-height: 2.6em;
    padding: 0 2em 0 0.7em;
    border: 1px solid var(--border-strong);
    border-radius: var(--radius-md);
    /* 화살표는 globals.css 가 background-image 로 넣는다. shorthand 로 쓰면 지워진다 */
    background-color: var(--surface);
    color: var(--text);
    font-size: 0.95em;
}

.board-new__id { flex: 1 1 12em; min-width: 0; }

.board-new__help {
    margin-top: 6px;
    color: var(--text-faint);
    font-size: 0.85em;
}

/* 그룹 · 게시판 두 칸. 좁은 화면에서 줄이 밀리지 않게 가운데로 세운다 */
.board-new__cell { text-align: center; white-space: nowrap; }

.board-new__celllink { color: var(--text-weak); }
.board-new__celllink:hover { color: var(--color-primary); }

/* ============================================================
   목록 화면의 위아래 줄 · board-cate / board-bar / board-paging / board-search

   **목록을 그리는 방식만 스킨마다 다르고 위아래로 붙는 것은 같다.** 표로
   세우는 게시판(board-list)과 격자로 세우는 갤러리가 이 넷을 함께 쓴다.
   ============================================================ */

/* ── 분류 줄 ─────────────────────────────── */

.board-cate {
    margin-bottom: 20px;
}

.board-cate__list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/*
 * 분류 알약. **여기만 요소 선택자를 쓴다.**
 *
 * 상자 안의 `<li><a>` 를 코어가 통째로 만든다(`bbs/list.php:11`). 클래스를
 * 하나도 안 붙이므로 붙일 자리가 없고, 스킨은 그 글자를 그대로 echo 할
 * 뿐이다. **아직 갈아타지 않은 그누보드 마크업**이라는 예외에 해당한다
 * (web/CLAUDE.md 의 「선택자는 클래스 하나로 끝낸다」).
 *
 * > 한동안 `.board-cate__link` 로 적어 두었는데 **그 이름이 어느 마크업에도
 * > 없어 규칙이 하나도 안 걸렸다.** 분류를 켠 게시판이 없어서 아무도 못
 * > 알아챘다. 이름을 우리가 못 정하는 자리는 「못 정한다」고 적고 실제로
 * > 있는 것을 짚어야 한다.
 */
.board-cate__list a {
    display: inline-block;
    padding: 0.4em 1em;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

.board-cate__list a:hover { border-color: var(--color-primary); color: var(--color-primary); }

/* 지금 고른 분류에 코어가 id="bo_cate_on" 을 붙인다. 그것도 코어가 정하는
   이름이라 속성으로 짚는다 */
.board-cate__list a[id="bo_cate_on"] {
    border-color: var(--color-primary);
    background: var(--color-primary);
    color: var(--color-white);
}

/* ── 총건수와 버튼 줄 ─────────────────────── */

/*
 * 버튼이 서는 줄. 목록 위와 아래에 하나씩이고 **맡는 일이 다르다.**
 *
 * | | 위 (`--head`) | 아래 (`--foot`) |
 * |---|---|---|
 * | 무엇 | 읽는 것 | 하는 것 |
 * | 담기는 것 | 총건수 · 검색 · 게시판 설정 · RSS | 글쓰기 · 선택삭제 · 선택복사 · 선택이동 |
 * | 자리 | 표 위. 흐름대로 | 표 아래. **바닥에 붙어 따라다닌다** |
 *
 * 가르는 기준은 「고르는 일과 상관이 있나」다. 긴 목록을 훑으며 고르는 동안
 * 손이 닿아야 하는 것만 아래로 간다. 검색과 설정은 한 번 누르면 이 화면을
 * 떠나므로 표 위가 제자리다. 관리자 목록도 같은 가름이다
 * (admin-searchbar 는 위, admin-toolbar 는 바닥).
 */
.board-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.board-bar__total {
    margin: 0;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

/* 총건수는 왼쪽, 도구는 오른쪽 끝 */
.board-bar--head { margin-bottom: 12px; }
.board-bar--head .board-bar__total { margin-right: auto; }

/*
 * **가운데로 모은다.** 오른쪽에 두면 화면 우하단의 「맨 위로」와 겹친다.
 * 관리자 툴바가 같은 이유로 같은 자리를 쓴다.
 */
.board-bar--foot {
    position: sticky;
    bottom: 0;
    z-index: 16;
    justify-content: center;
    padding: 12px 0;
    /* 떠 있을 때 뒤의 목록이 비쳐 보이지 않게 바탕을 깐다. 줄 하나를 얹어
       쪽 번호와 버튼 줄이 붙어 보이지 않게 한다 */
    border-top: 1px solid var(--border-subtle);
    background: var(--bg);
}

.board-bar__count { color: var(--text); font-weight: 600; }

/*
 * 몇 개 골랐나.
 *
 * **줄의 눈금을 그대로 따른다.** 옆에 선 것이 다 테두리를 두른 버튼이라, 작은
 * 글자를 그대로 끼우면 그것만 낮게 떠서 줄이 어긋나 보인다. 키와 글자 크기를
 * 버튼에 맞추고 양옆에 숨 쉴 자리를 준다. **테두리는 안 두른다.** 누르는
 * 것이 아니므로 그것까지 같으면 눌러도 되는 줄 알게 된다.
 *
 * 관리자 툴바는 버튼이 테두리 없이 그림자로 뜨는 꼴이라 이 손질이 필요 없다.
 */
.board-bar__note {
    display: inline-flex;
    align-items: center;
    min-height: var(--control-h);
    /*
     * **고르는 것끼리 붙인다.** 왼쪽은 전체선택 버튼이라 한 덩어리로 읽혀야 하고,
     * 오른쪽은 글쓰기 같은 딴 일이라 떼어 놓는다. 넷이 고르게 벌어져 있으면
     * 무엇과 무엇이 한 짝인지가 안 보인다.
     */
    margin-inline: -2px 10px;
    padding-inline: 0.4em;
    color: var(--text-weak);
    font-size: var(--fs-body);
    white-space: nowrap;
}

.board-bar__picked {
    color: var(--text);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}


.board-bar__tools {
    display: flex;
    /*
     * **좁아지면 접힌다.** 안 접으면 줄이 화면 밖으로 나가 잘린다. 슬라이드
     * 목록이 390px 에서 418px 를 그어 「⋮」가 통째로 잘려 있었다. 전체선택과
     * 셈이 늘면서 줄이 그만큼 길어진 자리다. 관리자 툴바도 같은 이유로 접는다.
     */
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/*
 * 더 보기 차림표.
 *
 * 여는 버튼이 `aria-expanded`, 차림표가 `hidden` 이다. 클래스를 함께 붙이지
 * 않는다 (web/CLAUDE.md 의 「상태를 나타내는 훅」).
 */
.board-bar__opt { position: relative; }

/*
 * 도구 줄의 전체선택. **버튼 꼴이다.**
 *
 * 옆에 선 것이 다 버튼인데 혼자 체크박스면 눌러도 되는 것인지가 안 읽힌다.
 * 켜지면 색이 차서 지금 켜져 있다는 것이 멀리서도 보인다. 상태는 여전히
 * 체크박스가 지고 값도 그것이 실어 나른다.
 *
 * **칸은 눈에서만 감춘다**(`sr-only`). `display:none` 이면 Tab 이 지나쳐
 * 키보드로는 켤 수 없다. 그래서 초점 고리도 라벨이 대신 낸다.
 */
.board-bar__all {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: var(--control-h);
    padding-inline: 1em;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    color: var(--text-weak);
    font-size: var(--fs-body);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color var(--duration-fast) ease,
                background   var(--duration-fast) ease,
                color        var(--duration-fast) ease;
}

.board-bar__all:hover { color: var(--text); }

/* 켜진 것. 상태는 체크박스가 지고 색은 라벨이 낸다 */
.board-bar__all:has(input:checked) {
    border-color: var(--color-primary);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
}

/* 일부만 고른 것. 칸이 안 보이므로 셋째 상태도 라벨이 보여준다 */
.board-bar__all:has(input:indeterminate) {
    border-color: var(--color-primary);
    border-style: dashed;
    color: var(--color-primary-ink);
}

/* 칸이 안 보이므로 초점 표시를 라벨이 낸다 */
.board-bar__all:has(input:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}


/* 툴바가 바닥에 붙어 있으므로 차림표는 **위로** 열린다 */
.board-bar__menu {
    position: absolute;
    bottom: calc(100% + 6px);
    right: 0;
    z-index: 5;
    min-width: 10em;
    margin: 0;
    padding: 4px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--shadow-md);
    list-style: none;
}

.board-bar__menu[hidden] { display: none; }

.board-bar__menubtn {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 0.6em 0.8em;
    border: 0;
    border-radius: var(--radius-sm);
    background: none;
    color: var(--text);
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.board-bar__menubtn:hover { background: var(--surface-hover); }

/*
 * **아이콘 폭을 고정한다.** 글자가 서는 세로선을 맞추려는 것이다.
 *
 * 아이콘마다 제 폭이 달라서(휴지통 · 문서 · 화살표) 그대로 두면 줄마다 글자
 * 시작점이 어긋난다. 셋을 세로로 훑을 때 그 어긋남이 먼저 눈에 걸린다.
 *
 * font-awesome 에도 같은 일을 하는 `fa-fw` 가 있지만, 그것은 저쪽 라이브러리
 * 이름이라 아이콘을 다른 것으로 갈면 함께 사라진다. 자리를 잡는 것은 우리 몫이다.
 */
.board-bar__menuicon {
    flex: none;
    width: 1.2em;
    text-align: center;
}

/* ── 쪽 번호 ─────────────────────────────── */

/*
 * **이 이름들은 코어가 만든다.** lib/common.lib.php 의 get_paging() 이
 * `<nav class="pg_wrap"><span class="pg">` 안에 pg_page · pg_current 를 찍는다.
 * 스킨이 만드는 마크업이 아니라 이름을 우리 것으로 바꿀 수가 없다.
 *
 * 그래서 **우리 상자 안에서만** 칠한다. 관리자 껍데기에는 jh_admin.css 에도
 * 같은 이름의 규칙이 있는데, 조상을 하나 더 두면 특이도가 높아 이쪽이 이긴다.
 */
.board-paging {
    margin: 24px 0 0;
    text-align: center;
}

.board-paging .pg { display: inline-flex; flex-wrap: wrap; gap: 4px; }

.board-paging .pg_page,
.board-paging .pg_current {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.4em;
    min-height: 2.4em;
    padding: 0 0.6em;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

.board-paging .pg_page:hover { border-color: var(--color-primary); color: var(--color-primary); }

.board-paging .pg_current {
    border-color: var(--color-primary);
    background: var(--color-primary);
    color: var(--color-white);
    font-weight: 600;
}

/* ── 화면 한가운데에 뜨는 판 · board-modal ─── */

/*
 * 검색과 「다른 게시판으로」가 함께 쓴다. **부품은 화면마다 새로 만들지
 * 않는다.** 검색에서 먼저 나왔지만 둘째가 생겨 공용으로 올렸다.
 *
 * 닫힌 상태는 `hidden` 하나로 나타낸다. 원본은 jQuery 의 `.toggle()` 로
 * style 을 직접 만졌는데, 그러면 화면에서 사라져도 **읽는 기계에는 그대로
 * 있고** 감춰진 채로 Tab 을 받는다. 여닫는 것은 board.js 다.
 *
 * > **테마의 레이어팝업(`front-layer`)이 아니다.** 그쪽은 `<dialog>` 를
 * > `tail.php` 가 내는데, 게시판 목록은 **관리자 껍데기
 * > (`adm/jh_board.php`)에서도 돈다.** 껍데기는 그 파일을 안 지나므로 거기서는
 * > 꺼낼 상자가 없다. 이 판은 스킨이 제 손으로 내므로 두 껍데기에서 다 뜬다.
 */
.board-modal[hidden] { display: none; }

.board-modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--gutter);
}

.board-modal__veil {
    position: absolute;
    inset: 0;
    background: rgb(0 0 0 / .4);
}

/*
 * 판. **화면보다 길어지면 안쪽이 흐른다.** 게시판이 열댓이면 목록만으로
 * 화면을 넘겨, 밑에 있는 버튼을 누를 수가 없어진다.
 */
.board-modal__panel {
    position: relative;
    display: flex;
    flex-direction: column;
    width: min(100%, 26em);
    max-height: 100%;
    margin: 0;
    padding: 24px;
    border: 0;
    border-radius: var(--radius-lg);
    background: var(--surface);
    box-shadow: var(--shadow-lg);
}

.board-modal__title {
    margin: 0 0 16px;
    padding-right: 2em;   /* 닫기 버튼 자리 */
    font-size: var(--fs-heading);
    font-weight: 600;
}

.board-modal__lead {
    margin-bottom: 12px;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

.board-modal__close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 2.2em;
    height: 2.2em;
    border: 0;
    border-radius: var(--radius-md);
    background: none;
    color: var(--text-weak);
    cursor: pointer;
}

.board-modal__close:hover { background: var(--surface-hover); color: var(--text); }

/* 판 밑의 버튼 줄. 그만두는 것이 왼쪽, 하는 것이 오른쪽이다 */
.board-modal__foot {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
    margin-top: 20px;
}

/* ── 검색 ────────────────────────────────── */

.board-search__row { display: grid; gap: 8px; }

/* 검색어 칸과 버튼을 한 줄에 붙인다 */
.board-search__bar { display: flex; gap: 6px; }
.board-search__bar .kit-input { flex: 1 1 auto; }

/* ── 다른 게시판으로 · board-move ─────────── */

/*
 * 고른 글을 다른 게시판으로 복사하거나 옮기는 판이다. 마크업은 목록 스킨,
 * 채우고 여는 것은 board.js, 받는 곳은 코어 `bbs/move_update.php` 다.
 *
 * **원본은 620×550 짜리 새 창이었다.** `window.open` 으로 열고 끝나면
 * `opener.document.location` 을 고쳐 부모 창을 되돌렸다. 창 크기가 화면마다
 * 뜻을 잃는 값이고, 팝업 차단에 걸리면 아무 일도 안 일어난다.
 */
.board-move__list {
    flex: 1 1 auto;
    overflow-y: auto;
    margin: 0;
    padding: 4px 0;
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
    list-style: none;
}

.board-move__item {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 8px 4px;
    border-radius: var(--radius-sm);
}

.board-move__item:hover { background: var(--surface-hover); }

/* 라벨이 줄 전체를 받는다. 글자만 눌러야 하면 고르기가 까다롭다 */
.board-move__label {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--fs-caption);
    cursor: pointer;
}

.board-move__group { color: var(--text-faint); }

/* 지금 보고 있는 게시판. 복사는 되지만 옮기는 것은 뜻이 없어 알려 준다 */
.board-move__now {
    margin-left: 4px;
    padding: 0 0.5em;
    border-radius: var(--radius-full);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
    font-weight: 700;
}

/* ============================================================
   목록 · board-list__*

   **표로 세운다.** 열이 다섯이라 관리자 표(admin-table)의 카드 기계를 가져올
   일이 아니다. 좁아지면 글쓴이와 조회를 접고 제목과 날짜만 남긴다.

   재는 것은 화면 폭이 아니라 **표가 놓인 칸의 폭**이다(@container). 관리자
   껍데기에서는 사이드바 옆이라 화면이 넓어도 칸은 좁다. 화면 폭으로 재면
   그 화면에서만 열이 넘친다.
   ============================================================ */

.board-list {
    container-type: inline-size;
    margin-bottom: 8px;
}

.board-list__table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}

/*
 * 열 너비를 여기서 못박는다. 비워 두면 쪽마다 칸에 든 글자 길이로 자리가
 * 정해져, 제목이 긴 글 하나에 표 전체가 밀린다.
 */
.board-list__col--chk     { width: 3em; }
.board-list__col--num     { width: 4.5em; }
.board-list__col--subject { width: auto; }
.board-list__col--name    { width: 8em; }
.board-list__col--hit     { width: 5em; }
.board-list__col--date    { width: 7em; }

/*
 * 헤더는 가운데가 기본이다. **칸의 정렬과 그 열 헤더의 정렬을 맞춘다.**
 * 어긋나면 어느 열의 이름인지 눈으로 잇기 어렵다. 제목만 왼쪽이다.
 */
.board-list__th {
    padding: 0.9em 0.6em;
    border-bottom: 1px solid var(--text-weak);
    color: var(--text-weak);
    font-size: var(--fs-caption);
    font-weight: 600;
    text-align: center;
    white-space: nowrap;
}

.board-list__th--subject { text-align: left; }

.board-list__td {
    padding: 0.9em 0.6em;
    border-bottom: 1px solid var(--border-subtle);
    font-size: var(--fs-caption);
    vertical-align: middle;
}

.board-list__row:hover .board-list__td { background: var(--surface-hover); }

/* 공지는 바탕이 옅게 깔리고 제목이 굵다 */
.board-list__row--notice .board-list__td { background: var(--color-primary-light); }
.board-list__row--notice .board-list__title { font-weight: 700; }

.board-list__chk,
.board-list__num,
.board-list__name,
.board-list__hit,
.board-list__date { text-align: center; white-space: nowrap; }

/* 글쓴이는 길면 자른다. 옆으로 밀어내지 않는다 */
.board-list__name { overflow: hidden; text-overflow: ellipsis; }

/* 지금 열어 둔 글 · 공지 표시 */
.board-list__now    { color: var(--color-primary); font-weight: 600; }
.board-list__notice { color: var(--color-primary); font-weight: 700; }

/*
 * 제목 칸. 답변글은 왼쪽이 밀려 들어가는데 그 값은 코어가 글자 수로 준다.
 * 마크업에서 style 로 넣는 자리라 여기서는 넘침 처리만 한다.
 */
.board-list__subject { overflow: hidden; }

/*
 * 한 줄로 세우는 상자. **제목만 줄고 곁들이는 표시는 자리를 지킨다.**
 *
 * 칸(`<td>`)에 바로 못 건다. display 를 바꾸면 표 칸이 아니게 되어 열 폭이
 * 흔들린다. 그래서 스킨이 안에 상자를 하나 두고 그것이 진다.
 */
.board-list__line {
    display: flex;
    gap: 6px;
    align-items: center;
    min-width: 0;
}

/* 곁들이는 표시는 안 줄어든다. 줄어들 것은 제목 하나다 */
.board-list__line > :not(.board-list__title) { flex: 0 0 auto; }

/*
 * 제목은 **한 줄**이다. 목록은 한 줄이 한 글이라, 어떤 줄만 두 줄이 되면
 * 아래위 간격이 그 줄에서만 달라진다.
 *
 * **`min-width: 0` 이 있어야 줄어든다.** flex 칸의 기본 최소 너비는
 * 「안에 든 것이 넘치지 않는 크기」라, 안 주면 긴 제목이 상자를 밀어낸다.
 * 말줄임을 걸어 두고도 안 잘리는 자리가 거의 다 이것이다.
 */
.board-list__title {
    overflow: hidden;
    min-width: 0;
    color: var(--text);
    font-size: var(--fs-body);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-list__title:hover { color: var(--color-primary); text-decoration: underline; }

/* 분류 · 댓글 수 · 새 글은 공용이다. 위 「글줄에 곁들이는 표시」 */

/*
 * 찾은 낱말.
 *
 * **이 이름은 코어가 만든다.** lib/common.lib.php 의 search_font() 가 검색어와
 * 맞는 자리를 `<b class="sch_word">` 로 감싼다. 스킨이 만드는 마크업이 아니라
 * 이름을 우리 것으로 바꿀 수가 없다. 쪽 번호(pg_*)와 같은 갈래다.
 *
 * 그래서 **우리 상자 안에서만** 칠한다. 그누보드 기본 테마는 형광 분홍
 * 바탕(#ff005a)을 깔았는데, 목록에서 여러 줄이 걸리면 그 색이 화면을 덮는다.
 * 업체 색을 옅게 깔아 「여기가 걸렸다」만 알린다.
 */
.board-list .sch_word,
.board-gallery .sch_word,
.board-result__link .sch_word,
.board-result__text .sch_word {
    padding: 0 0.15em;
    border-radius: var(--radius-sm);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
}

.board-list__empty {
    padding: 4em 0;
    border-bottom: 1px solid var(--border-subtle);
    color: var(--text-faint);
    text-align: center;
}

/*
 * 좁아지면 글쓴이와 조회를 접는다.
 *
 * **읽는 기계에서도 함께 접힌다.** 화면에서만 감추면 줄의 칸 수와 헤더 수가
 * 어긋나 「세 열짜리 표에 헤더가 다섯」으로 읽힌다. display:none 은 접근성
 * 트리에서도 빠지므로 둘이 같이 움직인다.
 */
@container (max-width: 560px) {
    .board-list__col--name,
    .board-list__col--hit { width: 0; }

    .board-list__name,
    .board-list__hit,
    .board-list__th--name,
    .board-list__th--hit { display: none; }

    .board-list__col--num  { width: 3.5em; }
    .board-list__col--date { width: 5.5em; }
}

@container (max-width: 420px) {
    .board-list__col--chk { width: 2.4em; }

    .board-list__col--num,
    .board-list__num,
    .board-list__th--num { display: none; }
}

/* ============================================================
   갤러리 목록 · board-gallery__*

   **표 대신 격자로 세운다.** 위아래 줄(board-bar) · 분류(board-cate) ·
   쪽 번호(board-paging) · 검색(board-search)은 표 목록과 같은 것을 쓴다.
   이 구획에 있는 것은 격자와 카드뿐이다.

   ── 열이 몇이 되는가 ───────────────────────────────────────

   게시판 설정의 「열 수」(bo_gallery_cols)를 스킨이 `--board-gallery-cols` 로
   넘긴다. 그 값을 그대로 못박으면 폰에서 카드가 네 쪽으로 쪼개지므로,
   **열 수는 넓을 때의 상한이고 좁아지면 저절로 준다.**

       minmax(max(220px, 100%/열수 - 여백), 1fr)

   넓을 때는 `100%/열수` 쪽이 커서 설정한 열 수가 그대로 나오고, 좁아지면
   220px 쪽이 커져 들어가는 만큼만 선다. auto-fill 이 그 폭으로 나눠 센다.
   끊는 지점을 손으로 잡지 않아 값이 튀지 않는다.

   **여백을 뺀 것은 auto-fill 이 칸 사이 간격을 따로 세기 때문이다.** 안 빼면
   마지막 열이 한 칸 넘쳐 한 줄이 접힌다.

   ── 사진 크기 ──────────────────────────────────────────────

   카드의 가로세로비는 게시판 설정의 「사진 폭 · 높이」를 스킨이 넘긴 것이다
   (`--board-gallery-ratio`). 그 둘은 **썸네일 파일이 만들어지는 크기**이기도
   해서, 카드가 그보다 넓게 서면 늘려 그린 것이라 흐릿하다. 흐리면 게시판
   설정에서 그 값을 올린다. 격자의 최소 폭 220px 은 화면 몫이라 여기 있다.
   ============================================================ */

.board-gallery {
    --board-gallery-cols: 4;
    --board-gallery-ratio: 4 / 3;
    --board-gallery-gap: 20px;

    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(max(220px, 100% / var(--board-gallery-cols) - var(--board-gallery-gap)), 1fr));
    gap: var(--board-gallery-gap);
    margin-bottom: 8px;
    padding: 0;
    list-style: none;
}

/*
 * 카드. **세로 flex 다.** 제목이 한 줄인 카드와 두 줄인 카드가 섞여도 밑줄
 * (글쓴이 · 날짜 · 조회)이 같은 높이에 서게 하려고 그것에 margin-top:auto 를
 * 준다. 격자가 이미 칸 높이를 맞춰 두므로 남는 자리가 밑줄 위로 몰린다.
 */
.board-gallery__item {
    position: relative;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    background: var(--surface);
    transition: border-color var(--duration-fast) var(--ease), box-shadow var(--duration-fast) var(--ease);
}

.board-gallery__item:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-md);
}

/* 방금 보고 돌아온 글. 테두리만으로 나타내고 글자는 sr-only 로 함께 낸다 */
.board-gallery__item--now {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 1px var(--color-primary);
}

/*
 * 고르기. **사진 위에 얹는다.** 카드 위에 줄을 따로 두면 체크박스 하나 때문에
 * 모든 카드가 그만큼 길어진다. 사진이 어두울 수 있어 바탕을 깐다.
 */
.board-gallery__chk {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 1;
    display: flex;
    padding: 4px;
    border-radius: var(--radius-sm);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
}

.board-gallery__thumb {
    display: block;
    aspect-ratio: var(--board-gallery-ratio);
    background: var(--surface-hover);
}

/*
 * **잘라서 채운다.** 비가 다른 사진이 섞여도 카드 크기는 같아야 격자가 격자로
 * 보인다. 남는 쪽을 비워 두면 카드마다 흰 띠의 위치가 달라진다.
 */
.board-gallery__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.board-gallery__noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

.board-gallery__body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 6px;
    padding: 12px 14px 14px;
}

/*
 * 공지 · 분류 알약이 사진 위에 앉는 자리.
 *
 * **모양은 board-tag 가 지고 자리만 여기서 잡는다**(BEM 의 mix). 그 알약이
 * 글줄 안에서 쓰라고 갖고 있는 오른쪽 여백은 여기서 걷는다. 뒤에 오는 규칙이
 * 이기므로 이 파일에서 board-tag 보다 아래에 있으면 된다.
 */
.board-gallery__badge {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 1;
    margin-right: 0;
}

/* 제목은 두 줄까지. 긴 제목 하나에 카드 하나만 길어지는 것을 막는다 */
.board-gallery__title {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    color: var(--text);
    font-size: var(--fs-body);
    font-weight: 600;
    line-height: 1.45;
}

.board-gallery__title:hover { color: var(--color-primary); }

/*
 * 본문 앞머리. 코어가 비밀글의 wr_content 를 비워 주므로 새어 나가지 않는다.
 *
 * **곁들이는 글은 세 줄까지다.** 제목보다 길어도 되는 자리지만, 넉 줄이 되면
 * 카드 하나가 옆 카드보다 눈에 띄게 길어져 격자가 흐트러진다.
 */
.board-gallery__excerpt {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    color: var(--text-weak);
    font-size: var(--fs-caption);
    line-height: 1.6;
}

.board-gallery__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 12px;
    margin-top: auto;
    padding-top: 6px;
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

/* 글쓴이는 사이드뷰가 드는 자리라 안 자른다 */
.board-gallery__name { color: var(--text-weak); }

/* 댓글 수 · 새 글은 한 덩어리로 밑줄 끝에 선다. 안쪽 여백은 board-cmt 가 진다 */
.board-gallery__marks { margin-left: auto; }

.board-gallery__empty {
    grid-column: 1 / -1;
    padding: 4em 0;
    color: var(--text-faint);
    text-align: center;
}

/* ============================================================
   메인 슬라이드 목록 · board-slidelist__*

   `hero` 게시판의 목록이다. 글 목록이 아니라 **첫 화면에 뜨는 띠의 목록**이라
   제목 · 글쓴이 · 조회수를 늘어놓는 표 대신 그림과 대문구를 나란히 세운다.
   ============================================================ */
.board-slidelist {
    display: grid;
    gap: 12px;
    padding: 24px 0;
    list-style: none;
}

.board-slidelist__item {
    display: grid;
    grid-template-columns: auto 240px minmax(0, 1fr);
    gap: 20px;
    align-items: center;
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    background: var(--surface);
}

.board-slidelist__img {
    display: block;
    width: 240px;
    height: auto;
    border-radius: var(--radius-md);
}

/* 그림이 없으면 저장이 안 되지만, 서버에서 파일만 지워지면 이 자리가 나온다 */
.board-slidelist__noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 240px;
    aspect-ratio: 16 / 9;
    border-radius: var(--radius-md);
    background: var(--surface-hover);
    color: var(--color-danger);
    font-size: var(--fs-caption);
}

.board-slidelist__body {
    display: grid;
    gap: 6px;
}

.board-slidelist__name {
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

/*
 * 대문구. **여기서는 한 줄이다.** 실제 화면에서는 엔터가 그대로 나가는 여러
 * 줄이지만, 이 목록은 어느 슬라이드인지 알아보는 자리라 첫 줄이면 된다.
 */
.board-slidelist__title {
    overflow: hidden;
    color: var(--text);
    font-size: var(--fs-heading);
    font-weight: 700;
    line-height: 1.4;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-slidelist__meta {
    display: flex;
    gap: 12px;
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

/* 링크를 걸어 둔 슬라이드에만 나온다. 버튼 글자를 그대로 보여준다 */
.board-slidelist__link-on {
    padding: 0 8px;
    border-radius: var(--radius-full);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
}

.board-slidelist__empty {
    padding: 48px 0;
    color: var(--text-weak);
    text-align: center;
}

@media (max-width: 768px) {
    .board-slidelist__item { grid-template-columns: auto minmax(0, 1fr); }
    .board-slidelist__img,
    .board-slidelist__noimg { width: 120px; }
}

/* ============================================================
   전체검색 결과 · board-result__*

   게시판을 가리지 않고 글과 댓글을 뒤진 결과다(bbs/search.php). 마크업은
   skin/search/basic/, 들어오는 곳은 머리줄의 돋보기다.

   **게시판 화면이 아닌데 이름이 `board-` 다.** 쪽 번호(board-paging) · 버튼 ·
   입력칸을 게시판 것과 그대로 쓰고, 찾은 낱말을 칠하는 `.sch_word` 규칙도
   여기 있다. 전체게시물(board-new)이 목록 표를 물려받은 것과 같은 자리다.
   ============================================================ */
.board-result__form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 24px;
}

/*
 * 「어디서 찾나」는 담기는 글자가 정해져 있어 제 폭이면 되고, 검색어 칸이
 * 남는 자리를 다 갖는다.
 *
 * **둘 다 kit-input 이라 이름을 갈라 잡는다.** 상자 쪽만 잡으려고
 * `.board-result__form .kit-input` 처럼 타고 들어가면 특이도가 높아져
 * 검색어 칸 규칙까지 이겨 버린다 (web/CLAUDE.md 의 「선택자는 클래스 하나로」).
 */
.board-result__where { flex: 0 0 auto; width: auto; }
.board-result__key   { flex: 1 1 12em; min-width: 0; }

.board-result__sum {
    margin-bottom: 12px;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

.board-result__word { color: var(--color-primary); font-weight: 700; }

/* 몇 건인지. 게시판 줄에서는 알약 안에 들어간다 */
.board-result__count { color: var(--text); font-weight: 600; }

.board-result__boards {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 28px;
    padding: 0;
    list-style: none;
}


.board-result__group { margin-bottom: 32px; }

.board-result__title {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: baseline;
    margin-bottom: 10px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--border-subtle);
}

.board-result__board {
    margin-right: auto;
    color: var(--text);
    font-size: var(--fs-heading);
    font-weight: 700;
}

.board-result__board:hover { color: var(--color-primary); }

.board-result__list {
    display: grid;
    gap: 4px;
    padding: 0;
    list-style: none;
}

.board-result__item {
    padding: 12px 10px;
    border-radius: var(--radius-md);
}

.board-result__item:hover { background: var(--surface-hover); }

/* 목록이라 제목은 한 줄이다. 아래 본문 앞머리가 여러 줄을 맡는다 */
.board-result__link {
    display: block;
    overflow: hidden;
    color: var(--text);
    font-size: var(--fs-body);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-result__link:hover { color: var(--color-primary); }

/*
 * 본문 앞머리. 코어가 300자로 자르고 비밀글은 「[비밀글 입니다.]」로 바꿔 준다
 * (bbs/search.php:189). 두 줄까지만 보인다.
 */
.board-result__text {
    display: -webkit-box;
    overflow: hidden;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    margin-top: 4px;
    color: var(--text-weak);
    font-size: var(--fs-caption);
    line-height: 1.6;
}

.board-result__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 12px;
    margin-top: 6px;
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

.board-result__empty {
    padding: 4em 0;
    color: var(--text-faint);
    text-align: center;
}

/* ============================================================
   글 하나 보기 · board-view__*

   그누보드 basic 스킨의 자리 순서를 그대로 따른다.
   제목 → 정보줄 → 버튼 → 본문 → 첨부 → 링크.
   ============================================================ */
.board-view__head {
    padding-bottom: 20px;
    border-bottom: 1px solid var(--border);
}

.board-view__title {
    font-size: var(--fs-section);
    font-weight: 700;
    letter-spacing: var(--ls-section);
}

.board-view__info {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    margin-top: 10px;
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

.board-view__tools {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-end;
    padding: 16px 0;
}

.board-view__body { padding: 12px 0 32px; }

/*
 * 여분필드. 게시판 설정의 「여분필드 이름」이 붙어 있고 값이 든 칸만 줄이 선다.
 * 지금 이 목록이 나오는 곳은 문의(`qa`)의 연락처 하나다.
 *
 * **본문과 갈라 놓는다.** 글쓴이가 적은 본문과 폼이 받은 값은 갈래가 달라서,
 * 이어 붙여 두면 어디까지가 받은 값인지 안 보인다. 상자로 묶고 본문 위에 둔다.
 *
 * `1fr` 이 아니라 `minmax(0, 1fr)` 이다. 그냥 두면 칸의 최소 너비가 「안에 든
 * 것이 넘치지 않는 크기」라 긴 값이 격자를 밀어낸다. Works 상세와 같은 자리다.
 */
.board-view__meta {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: 8px 20px;
    align-items: baseline;
    margin-bottom: 20px;
    padding: 16px 20px;
    border-radius: var(--radius-md);
    background: var(--surface-hover);
}

.board-view__key {
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

.board-view__val {
    color: var(--text);
    font-size: var(--fs-body);
}

/* 좁은 화면에서는 이름을 값 위로 올린다. 두 칸으로 두면 값이 한 줄에 서너 자다 */
@media (max-width: 480px) {
    .board-view__meta {
        grid-template-columns: minmax(0, 1fr);
        gap: 2px;
    }

    .board-view__val { margin-bottom: 8px; }
}

.board-view__note {
    margin-bottom: 12px;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

.board-view__note--warn { color: var(--color-danger); }

/* 미리보기라 넘기지 않는다. 높이만 낮춰 화면을 덜 먹게 한다 */
/*
 * 관리자에서 한 장만 미리 보는 꼴.
 *
 * 첫 화면 히어로는 화면을 꽉 채우지만 여기는 글 보기 안의 상자다. 높이와
 * 여백을 따로 잡아 준다. **위 값을 그대로 쓰면 여백이 상자를 다 먹어** 대문구가
 * 두 줄 설 자리도 안 남는다.
 */
.board-hero--preview { overflow: hidden; border-radius: var(--radius-lg); }
.board-hero--preview .board-hero__viewport { height: clamp(220px, 34vw, 380px); }
.board-hero--preview .board-hero__body { padding-block: clamp(20px, 4vw, 40px); }

.board-view__subtitle {
    margin-bottom: 10px;
    color: var(--text-weak);
    font-size: var(--fs-caption);
    font-weight: 700;
}

.board-view__files,
.board-view__links {
    padding: 20px 0;
    border-top: 1px solid var(--border-subtle);
}

/* 첨부와 링크가 같은 모양이다. 둘 다 「이름 + 곁들이는 값」 목록이다 */
.board-filelist {
    display: grid;
    gap: 12px;
    list-style: none;
}

.board-filelist__link { display: inline-flex; gap: 6px; align-items: baseline; }
.board-filelist__link:hover .board-filelist__name { color: var(--color-primary); }

.board-filelist__name { font-weight: 500; }
.board-filelist__size,
.board-filelist__meta,
.board-filelist__desc { color: var(--text-faint); font-size: var(--fs-caption); }

/* ── 글 하나 보기: 스킨마다 더 붙는 것 ────────── */

/*
 * **뼈대는 한 벌이고 담기는 칸만 스킨마다 다르다.** 히어로는 대문구 · 소문구 ·
 * 링크, basic 은 제목 · 내용 · 첨부다. 서는 자리(제목 → 정보줄 → 버튼 → 본문
 * → 첨부 → 링크)는 같으므로 아래 이름을 함께 쓴다.
 */

/* 글머리 분류. 목록의 것과 같은 모양이다 */
.board-view__cate {
    display: inline-block;
    margin-bottom: 8px;
    padding: 0.2em 0.7em;
    border-radius: var(--radius-full);
    background: var(--color-primary-light);
    color: var(--color-primary-ink);
    font-size: var(--fs-caption);
}

/* 정보줄 안의 낱값. 이름만 살짝 진하게 */
.board-view__by { color: var(--text-weak); font-weight: 500; }

/*
 * 본문. **여기 들어오는 것은 글쓴이가 만든 HTML 이다.**
 *
 * 그 글의 생김새는 globals.css 의 `kit-prose` 가 낸다. 내용관리 · 쪽지와 같은
 * 규칙이라 한 벌로 뒀다. 여기서는 이 화면 몫의 자리만 잡는다.
 */
.board-view__content { padding: 8px 0 24px; }

/* 본문에 딸려 나오는 그림 묶음 (get_file_thumbnail) */
.board-view__pics { display: grid; gap: 12px; padding-bottom: 20px; }

/* 스크랩 · SNS 처럼 글을 내보내는 것들 */
.board-view__share {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    justify-content: flex-end;
    padding-bottom: 12px;
}

/* 서명 */
.board-view__sign {
    padding-top: 16px;
    border-top: 1px dashed var(--border-subtle);
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

/*
 * 추천 · 비추천.
 *
 * `#good_button` · `#bo_v_act_good` 은 **이름을 바꿀 수 없다.** 눌렀을 때
 * 도는 스크립트가 그 id 로 찾는다. 자리와 생김새만 우리가 정한다.
 */
.board-view__act {
    display: flex;
    gap: 10px;
    justify-content: center;
    padding: 8px 0 24px;
}

.board-view__gng { position: relative; }

/* 눌렀을 때 잠깐 뜨는 말. 스크립트가 fadeIn 으로 켠다 */
.board-view__gng b {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    z-index: 5;
    padding: 0.5em 0.9em;
    border-radius: var(--radius-md);
    background: var(--color-gray-900);
    color: var(--color-white);
    font-size: var(--fs-caption);
    white-space: nowrap;
    transform: translateX(-50%);
}

/* ── 이전글 · 다음글 ─────────────────────────── */

.board-view__nb {
    display: grid;
    border-top: 1px solid var(--border-subtle);
    list-style: none;
}

/*
 * **`min-width: 0` 이 있어야 아래 말줄임이 걸린다.** 격자 칸의 기본 최소폭은
 * `auto` 이고 그것은 「알맹이가 요구하는 폭」이다. 두 줄이 같은 열을 쓰므로
 * 열의 최소폭이 긴 제목 줄에서 정해지고, 그 열이 통보다 넓어지면 줄이 통 밖으로
 * 나간다. 줄 안에서는 자리가 남으니 링크는 줄어들 일이 없어 말줄임도 안 걸린다.
 * 짧은 제목 줄까지 같은 폭으로 벌어지는 것이 그 증상이었다.
 */
.board-view__nbitem {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: baseline;
    min-width: 0;
    padding: 14px 4px;
    border-bottom: 1px solid var(--border-subtle);
}

.board-view__nblabel {
    flex: none;
    width: 5em;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

/* 제목이 길면 한 줄로 자른다. 이웃 글은 훑는 값이지 읽는 값이 아니다 */
.board-view__nblink {
    flex: 1 1 12em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.board-view__nblink:hover { color: var(--color-primary); }

.board-view__nbdate { color: var(--text-faint); font-size: var(--fs-caption); }

/* ── 글쓰기 · 수정: 스킨마다 더 붙는 것 ───────── */

/*
 * 한 줄에 칸이 여럿일 때. 이름 · 비밀번호 · 이메일처럼 한 덩어리로 읽히는
 * 것들을 세로로 쌓는다. 가로로 늘어놓으면 좁은 화면에서 칸이 글자보다 좁아진다.
 */
.board-form__grid { display: grid; gap: 8px; }

/*
 * 체크박스 줄 (공지 · 비밀글 · 답변메일받기 …).
 *
 * 게시판 설정에 따라 하나도 안 나올 수 있어서, 이 줄 자체를 그릴지 말지는
 * 스킨이 판단한다.
 */
.board-form__opts {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 20px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.board-form__opt {
    display: inline-flex;
    gap: 6px;
    align-items: center;
}

/*
 * 에디터가 앉는 자리.
 *
 * **안쪽 마크업은 우리 것이 아니다.** SmartEditor2 가 iframe 과 제 도구줄을
 * 통째로 그린다. 자리와 최소 높이만 준다.
 */
.board-form__editor { display: block; }
.board-form__editor textarea { display: block; width: 100%; min-height: 18em; }

/* 글자 수 제한을 쓰는 게시판에만 나온다 */
.board-form__count {
    margin-top: 6px;
    color: var(--text-faint);
    font-size: var(--fs-caption);
    text-align: right;
}

/* 파일 한 줄. 고르는 칸 · 설명 · 지우기 */
.board-form__file { display: grid; gap: 6px; }

.board-form__filedel {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

/*
 * 임시 저장된 글.
 *
 * **id 를 바꿀 수 없다.** js/autosave.js 가 `#btn_autosave` · `#autosave_pop` ·
 * `#autosave_count` 를 찾고, 목록도 저쪽이 `#autosave_pop ul` 안에 그린다.
 * 안쪽에 붙는 `.autosave_load` · `.autosave_del` 도 저쪽 이름이다.
 */
.board-form__autosave { position: relative; }

/* 칸이 격자라 그냥 두면 버튼이 줄 폭을 다 먹는다 */
.board-form__autosavebtn { justify-self: start; }

#autosave_pop {
    display: none;      /* autosave.js 가 show()/hide() 로 켠다 */
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 10;
    width: min(24em, 90vw);
    padding: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
    box-shadow: var(--shadow-md);
}

#autosave_pop ul { margin: 10px 0; list-style: none; }

#autosave_pop li {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 6px 0;
    border-bottom: 1px solid var(--border-subtle);
    font-size: var(--fs-caption);
}

#autosave_pop .autosave_load { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#autosave_pop .autosave_del { flex: none; color: var(--color-danger); }

/* 자동등록방지 */
.board-form__captcha { display: block; }

/* ── 댓글 · board-comment__* ─────────────────── */

/*
 * 접히는 상자다. `<details>` 라 여닫는 상태를 브라우저가 갖는다. 원본은 jQuery
 * 로 style 만 만져서 읽는 기계에는 「접혔다」는 말이 가지 않았고, 접힌 채로도
 * 안의 링크가 Tab 을 받았다.
 */
.board-comment {
    margin-top: 32px;
    border-top: 1px solid var(--border);
}

.board-comment__head {
    padding: 16px 4px;
    color: var(--text-weak);
    font-size: var(--fs-caption);
    font-weight: 600;
    cursor: pointer;
    list-style: none;   /* 파이어폭스의 기본 세모를 걷는다 */
}

/* 사파리·크롬의 기본 세모 */
.board-comment__head::-webkit-details-marker { display: none; }

/*
 * **열리고 닫히는 것이 보인다.** 똑딱 켜지고 꺼지지 않는다
 * (web/CLAUDE.md 의 「움직임」).
 *
 * **격자로는 안 된다.** `grid-template-rows: 0fr → 1fr` 은 `<details>` 에 안
 * 걸린다. 닫혀 있는 동안 안쪽이 아예 안 그려져서 재고 말고 할 것이 없다.
 * 브라우저가 그 안쪽을 담아 두는 자리(`::details-content`)에서만 그릴 수 있다.
 *
 * `interpolate-size` 를 **이 상자에 직접 적는다.** 물려받는 성질이라 홈페이지
 * 쪽은 테마 `:root` 가 이미 켜 두었지만, 이 파일은 관리자 껍데기에서도 도는데
 * 그쪽에는 그 줄이 없다. 없으면 `0` 에서 `auto` 로 가는 사이를 못 재서 첫
 * 프레임에 다 열린다.
 *
 * `content-visibility` 는 중간값이 없는 성질이라 `allow-discrete` 로 닫히는
 * 동안 버티게 한다. 이 의사요소를 모르는 브라우저에서는 그냥 즉시 열린다.
 */
.board-comment { interpolate-size: allow-keywords; }

.board-comment::details-content {
    block-size: 0;
    overflow: hidden;
    transition:
        block-size         var(--duration-base) ease,
        content-visibility var(--duration-base) allow-discrete;
}

.board-comment[open]::details-content { block-size: auto; }

/* 우리 세모를 오른쪽에 그린다 */
.board-comment__head::after {
    content: "";
    float: right;
    width: 7px;
    height: 7px;
    margin-top: 0.35em;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);
}

.board-comment[open] .board-comment__head::after {
    margin-top: 0.6em;
    transform: rotate(-135deg);
}

.board-comment__count { color: var(--color-primary); }

.board-comment__list { list-style: none; }

.board-comment__item {
    padding: 16px 4px;
    border-top: 1px solid var(--border-subtle);
}

.board-comment__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: center;
    margin-bottom: 8px;
    color: var(--text-faint);
    font-size: var(--fs-caption);
}

.board-comment__by { color: var(--text-weak); font-weight: 500; }

/* 차림표를 오른쪽 끝으로 민다 */
.board-comment__opt { margin-left: auto; }

/* 댓글 줄 안에 서는 버튼이라 한 치수 작다 */

.board-comment__body {
    color: var(--text);
    font-size: var(--fs-caption);
    line-height: 1.7;
    white-space: pre-line;   /* 줄바꿈을 그대로 낸다 */
}

/*
 * 남의 비밀 댓글. 코어가 내용 자리에 「댓글내용 확인」 링크를 대신 넣는다
 * (bbs/view_comment.php:54, `<a class="s_cmt">`). 이름을 못 바꾸는 자리라
 * 우리 상자 안에서 칠한다. 누르면 비밀번호를 묻는 화면으로 간다.
 */
.board-comment__body .s_cmt {
    display: inline-block;
    padding: 0.3em 0.8em;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    color: var(--text-weak);
}

.board-comment__body .s_cmt:hover { border-color: var(--color-primary); color: var(--color-primary); }

.board-comment__lock {
    display: inline-block;
    margin-right: 6px;
    color: var(--text-faint);
}

.board-comment__empty {
    padding: 3em 0;
    color: var(--text-faint);
    font-size: var(--fs-caption);
    text-align: center;
}

/*
 * 쓰기 폼이 앉는 자리.
 *
 * **비어 있을 때는 자리를 안 먹어야 한다.** 폼이 들어오면 스크립트가
 * `style.display = ''` 로 되돌리므로, 여기에 display 를 적으면 안 된다.
 * 빈 div 는 높이가 0 이라 그대로 두면 된다.
 */
.board-comment__slot { margin-top: 12px; }

.board-comment__form {
    display: grid;
    gap: 10px;
    padding: 16px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    background: var(--surface);
}

.board-comment__text { min-height: 6em; resize: vertical; }

/* 비회원이 적는 이름 · 비밀번호 */
.board-comment__guest { display: grid; gap: 8px; }

.board-comment__foot {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    justify-content: flex-end;
}

.board-comment__secret {
    display: inline-flex;
    gap: 6px;
    align-items: center;
    margin-right: auto;
    color: var(--text-weak);
    font-size: var(--fs-caption);
}

@media (min-width: 480px) {
    .board-comment__guest { grid-template-columns: 1fr 1fr; }
}

/* ============================================================
   벽돌 격자 · board-masonry__*

   **사진마다 가로세로가 다른 목록을 세우는 한 벌이다.** 칸 높이를 맞출 수
   없으니 격자가 빈자리를 채워 쌓는다. 자리를 잡는 것은 Masonry, 분류 탭을
   눌렀을 때 카드가 제자리로 옮겨 가는 것은 GSAP Flip 이다
   (board.js 의 「벽돌 격자」).

   **두 곳이 같이 쓴다.** 게시판 목록 스킨(`skin/board/masonry`)과 첫 화면의
   최신글 스킨(`skin/latest/masonry`)이다. 화면 몫으로 다른 것은 그 위에 이름을
   하나 더 얹는다(BEM 의 mix). Works 목록의 한 줄과 분류 탭이 그 꼴이다.

   **위아래 여백을 안 준다.** 담기는 자리가 정한다. 게시판 화면은 `front-page`
   가, 첫 화면은 `front-section` 이 이미 벌려 놓았다.
   ============================================================ */
/*
 * **격자 자체가 블록이다.** 감싸는 상자를 따로 두지 않는다. 최신글 스킨은
 * 격자만 내고 그것이 어디에 담기는지는 부르는 쪽이 정하는데, 값을 바깥 상자에
 * 두면 **부르는 쪽이 이름 하나를 잊는 순간 칸 폭이 통째로 무너진다.**
 * 실제로 그렇게 해 봤다가 카드가 80px 로 찌그러졌다.
 *
 * Masonry 가 칸마다 `position: absolute` 와 좌표를 박고 이 상자의 높이를
 * 잡는다. **칸의 폭만 CSS 가 정한다.**
 */
.board-masonry {
    list-style: none;

    /*
     * 열 수와 칸 사이. **여기 둘만 바꾸면 격자가 통째로 따라온다.**
     *
     * 칸 사이는 아래 `margin-bottom` 으로도 나가는데, Masonry 가 가로 사이를
     * 그 값에서 읽어 간다. clamp() 는 사용자 정의 속성으로 읽으면 글자 그대로
     * 나오지만 진짜 속성은 픽셀로 계산된 뒤에 나오기 때문이다.
     */
    --board-masonry-cols: 4;
    --board-masonry-gap: clamp(12px, 1.6vw, 24px);
}

.board-masonry__item {
    /* 고르는 칸(관리자)이 사진 위에 얹히므로 기준을 칸 자신으로 둔다 */
    position: relative;
    width: calc(
        (100% - (var(--board-masonry-cols) - 1) * var(--board-masonry-gap))
        / var(--board-masonry-cols)
    );
    margin-bottom: var(--board-masonry-gap);
}

/* 걸러져 빠진 칸. board.js 가 이 이름으로 격자에서 아예 뺀다 */
.board-masonry__item--off { display: none; }

/*
 * **첫 쪽 뒤의 카드는 처음부터 접혀 있다.** 스킨이 표를 달고 여기서 접는다.
 *
 * 까닭은 사진이다. Masonry 가 자리를 잡기 전에는 카드가 전부 `position:
 * absolute` 로 0,0 에 겹쳐 있어 **그 순간에는 다 화면 안**이라, `loading="lazy"`
 * 가 하나도 안 걸리고 브라우저가 전부 받아 버린다. 재보니 첫 화면에서 사진
 * 마흔아홉 장 2.2MB 를 받았고 그중 스물여섯 장이 안 보이는 것이었다.
 * **`visibility: hidden` 으로는 안 막힌다.** 그 값은 자리를 지우지 않아
 * 브라우저가 여전히 화면 안으로 본다. `display: none` 이라야 안 받는다.
 *
 * **`.kit-js` 아래에서만 접는다.** 스크립트가 안 돌면 더 보기 버튼도 안 나오므로
 * 여기서 접으면 그 카드들을 영영 못 본다. JS 가 자리를 잡으면 이 표를 걷고,
 * 그때부터는 위 `--off` 가 같은 일을 한다.
 */
.kit-js .board-masonry__item--rest { display: none; }

/*
 * 자리를 잡기 전. **한 자리에 포개 두고 안 보이게 한다.**
 *
 * Masonry 가 돌기 전에는 칸들이 제 폭(3분의 1)으로 세로로 죽 흐른다. 카드가
 * 마흔넷이라 그것만으로 문서가 17,930px 이 되고, 그 화면이 2초 넘게 서 있다가
 * 스크립트가 열여덟 장만 남기고 자리를 잡으면 4분의 1로 접힌다. 표를 붙이는
 * 자리와 이유는 head.sub.php 에 적었다.
 *
 * **높이를 미리 잡아 둔다.** 포개 두면 격자가 높이 0 이 되어 이번에는 짧았던
 * 쪽에서 늘어난다. 화면 하나를 잡아 두면 늘어나는 폭이 그만큼 줄고, 스크립트가
 * 자리를 잡는 순간 제 높이로 간다.
 *
 * **스스로 걷힌다.** board.js 가 첫 배치를 마치면서 `data-masonry-live` 를
 * 붙인다. 그것이 안 붙으면(라이브러리가 안 실렸거나 스크립트가 죽었으면)
 * <head> 의 안전장치가 문서가 다 뜬 뒤에 표째 뗀다.
 */
.kit-js .board-masonry:not([data-masonry-live]) { visibility: hidden; min-height: 100vh; }

.kit-js .board-masonry:not([data-masonry-live]) .board-masonry__item {
    position: absolute;
    top: 0;
    left: 0;
}

.board-masonry__card {
    display: block;
    color: inherit;
}

/*
 * 사진 칸. **비는 사진이 정한다.**
 *
 * `--board-masonry-ratio` 는 스킨이 첨부의 원본 크기에서 뽑아 얹는다. 미리
 * 적어 두어야 사진이 오기 전에도 칸의 높이가 서고, 격자가 두 번 안 흔들린다.
 */
.board-masonry__frame {
    /* 스킨이 사진의 실제 크기로 덮는다. 못 덮을 때(첨부가 없는 글)의 값이다 */
    --board-masonry-ratio: 4 / 3;

    position: relative;
    display: block;
    overflow: hidden;
    aspect-ratio: var(--board-masonry-ratio);
    background: var(--surface-hover);
}

.board-masonry__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /*
     * **`--duration-slower` 를 안 쓴다.** 그 이름은 프론트에만 있어서
     * (web/CLAUDE.md 의 「토큰이 사는 곳」의 ③) 관리자 껍데기에서는 규칙이
     * 통째로 조용히 죽는다. 큰 사진이 천천히 자라는 자리라 값은 그대로 쓴다.
     */
    transition: transform .6s cubic-bezier(.2, .6, .2, 1);
}

.board-masonry__card:hover .board-masonry__img,
.board-masonry__card:focus-visible .board-masonry__img { transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
    .board-masonry__img { transition: none; }
    .board-masonry__card:hover .board-masonry__img { transform: none; }
    .board-masonry__caption { transition: none; }
}

.board-masonry__noimg {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--text-weak);
    font-size: 0.875em;
}

/*
 * 사진 **위에 얹는** 한 줄. 왼쪽이 이름이고 오른쪽이 곁들이는 값이다.
 *
 * **밑에 두지 않는다.** 격자에서 알맹이는 사진이고, 글이 밑에 한 줄씩 붙으면
 * 카드마다 사진 크기가 달라 그 줄들이 들쭉날쭉 선다. 위에 얹으면 사진만
 * 늘어서고 글은 볼 사람만 본다.
 *
 * **사진 한 장을 통째로 덮는다.** 밑에 오는 사진이 무엇일지 모른다. 흰
 * 접시나 밝은 벽이 오면 흰 글자가 사라지고, 아래만 어둡게 하면 그 경계선이
 * 사진을 가로지르는 띠로 보인다. 위까지 덮으면 **올린 카드가 한 장으로
 * 가라앉고** 옆 카드와도 갈린다. 히어로의 겹(위 `board-hero__scrim`)과 같은
 * 짜임이다.
 *
 * **아래로 갈수록 짙다.** 글이 앉는 자리라 거기서 가장 벌어야 한다. 위쪽은
 * 덮는 티만 나는 정도다. **한 번 더 짙게 해 봤다가 되돌렸다**(위 .45).
 * 사진이 알맹이인 격자에서 그만큼 덮으면 무엇을 찍은 것인지가 안 보인다.
 */
.board-masonry__caption {
    position: absolute;
    inset: 0;
    z-index: 1;

    display: flex;
    gap: 0.5em 1em;
    /* 두 글이 밑변을 맞춘다. 이름이 두 줄이면 그 둘째 줄과 나란히 선다 */
    align-items: flex-end;
    justify-content: space-between;

    padding: 1.1em;
    background: linear-gradient(
        to top,
        rgb(0 0 0 / .72) 0%,
        rgb(0 0 0 / .40) 42%,
        rgb(0 0 0 / .20) 100%);
    color: #fff;
}

/*
 * **올릴 수 있는 화면에서만 감춘다.**
 *
 * 손가락으로 쓰는 화면에는 「올린다」가 없다. 거기서 감추면 한 번 눌러야
 * 보이거나 영영 안 보인다. 그래서 감추는 쪽을 미디어 쿼리 안에 두고,
 * 밖에서는 늘 보이는 것이 기본이다.
 *
 * **`opacity` 로 감춘다.** `display: none` 이면 읽어주는 프로그램에서도
 * 사라지는데, 이 글자는 링크의 이름이라 사라지면 「무엇으로 가는 링크인지」가
 * 없어진다. 초점이 와도 나타나게 해서 키보드로도 읽힌다.
 */
@media (hover: hover) {
    .board-masonry__caption {
        opacity: 0;
        transition: opacity .32s cubic-bezier(.2, .6, .2, 1);
    }

    .board-masonry__card:hover .board-masonry__caption,
    .board-masonry__card:focus-visible .board-masonry__caption { opacity: 1; }
}

/*
 * 카드 이름은 **두 줄**까지. 격자에서는 카드마다 높이가 달라도 되지만, 한
 * 카드만 제목으로 넉 줄을 먹으면 사진이 아니라 글자가 보인다.
 *
 * **`min-width: 0` 이 있어야 줄어든다.** 옆의 곁들이는 값과 한 줄에 서는
 * flex 칸이라, 안 주면 긴 이름이 그것을 밀어낸다.
 */
.board-masonry__name {
    display: -webkit-box;
    overflow: hidden;
    min-width: 0;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    font-weight: 600;
    letter-spacing: var(--ls-heading);
    word-break: keep-all;
}

.board-masonry__meta {
    display: flex;
    flex: 0 0 auto;
    gap: 0.6em;

    /* 사진 위다. `--text-weak` 는 밝은 사진에서 사라진다 */
    color: rgb(255 255 255 / .88);
    font-size: 0.8125em;
}

.board-masonry__empty {
    width: 100%;
    padding: 3em 0;
    color: var(--text-weak);
    text-align: center;
}

/* 고르는 칸은 사진 위 왼쪽에 얹는다. **관리자에게만 나온다.** */
.board-masonry__chk {
    position: absolute;
    z-index: 2;
    top: 10px;
    left: 10px;
}

/* ── 분류 탭 ──────────────────────────────────────────────
   **눌러도 화면이 안 넘어간다.** 그래도 마크업은 링크다. 스크립트가 안 돌면
   그 주소로 넘어가 서버가 걸러 준 목록이 나온다.
   ────────────────────────────────────────────────────────── */
.board-masonry__tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25em 1.6em;
    margin-bottom: clamp(20px, 3vw, 40px);
}

/*
 * 고른 것에만 밑줄이 선다. **자리는 늘 잡아 둔다.** `::after` 를 늘 그려
 * 놓고 색만 바꾼다. 붙였다 뗐다 하면 누를 때마다 줄 전체가 1px 씩 움직인다.
 */
.board-masonry__tab {
    position: relative;
    padding-bottom: 0.4em;
    color: var(--text-weak);
    font-weight: 500;
    letter-spacing: var(--ls-heading);
    transition: color var(--duration-base) ease;
}

.board-masonry__tab::after {
    content: "";
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 1px;
    background: transparent;
    transition: background var(--duration-base) ease;
}

.board-masonry__tab:hover { color: var(--text); }

.board-masonry__tab[aria-current="page"] {
    color: var(--text);
    font-weight: 600;
}

.board-masonry__tab[aria-current="page"]::after { background: currentColor; }

/* 건수는 어깨에 얹는다. 이름과 같은 크기로 두면 무엇이 이름인지 흐려진다 */
.board-masonry__tabnum {
    color: var(--text-weak);
    font-size: 0.7em;
    font-weight: 400;
    vertical-align: super;
}

@media (max-width: 1280px) { .board-masonry { --board-masonry-cols: 3; } }
@media (max-width: 820px)  { .board-masonry { --board-masonry-cols: 2; } }
/*
 * **한 칸짜리 줄은 없다.** 좁아진다고 한 칸으로 내리면 카드가 화면 폭을 다
 * 먹어 한 장에 한 화면이 된다. 사진이 마흔 장이면 내려가는 것이 일이 되고,
 * 색이 강한 사진은 그 크기로 내리 보면 금세 지친다. 둘에서 멈춘다.
 */

/* ============================================================
   Works 목록 · board-works__*

   위 벽돌 격자에 이 업체 몫을 얹은 것이다. 격자 · 카드 · 분류 탭은
   `board-masonry` 가 지고, **여기 있는 것은 한 줄 안내뿐이다.**

   **제목은 여기서 안 그린다.** 테마 골격의 `front-page__title` 이 이미 낸다.
   ============================================================ */
.board-works__lead {
    max-width: 34em;
    margin-bottom: clamp(20px, 3vw, 40px);
    color: var(--text-weak);
    line-height: 1.7;
    text-wrap: pretty;
    word-break: keep-all;
}

/* ============================================================
   Works 상세 · board-workview__*

   한 촬영 건이다. **레이어로도 열리고 한 장으로도 열린다.** 왼쪽이 사진이고
   오른쪽이 그 촬영에 대한 값 몇이다. 지금 사이트처럼 사진을 세로로 늘어놓지
   않는다.

   레이어 쪽의 크기는 front.css 의 `front-layer--photo` 가 정한다.
   ============================================================ */
/*
 * **자리를 손으로 짚는다.** 칸에 드는 것이 셋(사진 · 넘기는 줄 · 값)인데
 * 저절로 채우면 넘기는 줄이 오른쪽 칸으로 올라간다. 왼쪽에 사진과 그 줄을
 * 위아래로 세우고 오른쪽 칸은 값이 두 줄을 통째로 쓴다.
 *
 * **줄 사이는 좁고 칸 사이는 넓다.** 사진과 넘기는 줄은 한 덩어리고, 왼쪽과
 * 오른쪽은 다른 이야기다.
 */
.board-workview__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 15em);
    gap: 0.75em clamp(16px, 2.5vw, 40px);
    align-items: start;
}

.board-workview__photos { grid-area: 1 / 1; }
.board-workview__nav    { grid-area: 2 / 1; }
.board-workview__info   { grid-area: 1 / 2 / span 2; }

/*
 * 사진 칸의 높이를 못박는다. **넘길 때마다 상자가 늘었다 줄면 안 된다.**
 * 가로 사진과 세로 사진이 섞여 있어서, 비에 맡기면 한 장 넘길 때마다 아래
 * 글까지 따라 움직인다. 남는 자리는 옅은 바닥으로 둔다.
 */
.board-workview__swiper { height: min(66vh, 620px); }

/*
 * **칸의 폭은 사진이 정한다**(스킨이 Swiper 에 `slidesPerView: 'auto'` 를
 * 준다). 높이만 맞추고 폭을 저마다 두면 세로 사진 양옆이 빈 바닥으로 남지
 * 않고, 그 자리에 앞뒤 사진이 걸쳐 보인다.
 */
/*
 * **감싼 것까지 적어 특이도를 올린다.** Swiper 의 `.swiper-slide` 가 폭을
 * 100% 로 못박는데 그 CSS 가 우리 것보다 뒤에 실린다(스킨이 board.css 를
 * 먼저 부르고 라이브러리를 그다음에 부른다). 이름 하나로는 못 이긴다.
 */
.board-workview__swiper .board-workview__slide {
    display: flex;
    width: auto;
    max-width: 100%;
    align-items: center;
    justify-content: center;
    opacity: 0.28;
    transition: opacity .4s ease;   /* 위와 같다. 프론트에만 있는 이름을 안 쓴다 */
}

.board-workview__swiper .swiper-slide-active { opacity: 1; }

.board-workview__img {
    width: auto;
    max-width: 100%;
    height: 100%;
    object-fit: contain;
}

@media (prefers-reduced-motion: reduce) {
    .board-workview__slide { transition: none; }
}

.board-workview__nav {
    display: flex;
    gap: 0.75em;
    align-items: center;
}

.board-workview__arrow {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.25em;
    height: 2.25em;
    border-radius: 50%;
    color: var(--text-weak);
    transition: background var(--duration-base) ease, color var(--duration-base) ease;
}

.board-workview__arrow:hover {
    background: var(--surface-hover);
    color: var(--text);
}

.board-workview__count {
    color: var(--text-weak);
    font-size: 0.875em;
    font-variant-numeric: tabular-nums;
}

/*
 * 오른쪽 값들. **선을 긋지 않고 여백으로만 가른다.**
 * 이름은 옅게, 값은 진하게. 첫 화면의 `front-why__meta` 와 같은 꼴이다.
 */
.board-workview__meta {
    display: grid;
    /* `1fr` 이 아니라 `minmax(0, 1fr)` 이다. 그냥 두면 칸의 최소 너비가
       「안에 든 것이 넘치지 않는 크기」라 긴 값이 격자를 밀어낸다 */
    grid-template-columns: auto minmax(0, 1fr);
    gap: 0.5em 1.25em;

    /*
     * **세로로 가운데 맞춘다.** 이름은 작고 줄 간격이 넓고(0.8125em · 1.9)
     * 값은 크고 좁아서, 그냥 두면 둘의 줄 상자 높이가 달라 **글자가 어긋난
     * 자리에 선다.** 칸마다 가운데로 모으면 어느 쪽이 길어져도 짝이 맞는다.
     */
    align-items: center;
}

.board-workview__key {
    color: var(--text-weak);
    font-size: 0.8125em;
    line-height: 1.9;
}

.board-workview__val {
    font-weight: 600;
    letter-spacing: var(--ls-heading);
    word-break: keep-all;
}

.board-workview__text {
    margin-top: 1.5em;
    color: var(--text-weak);
    line-height: 1.7;
    word-break: keep-all;
}

/*
 * 좁아지면 위아래로 선다. 사진 칸도 함께 낮춘다. 폰에서 66vh 는 사진 하나가
 * 화면을 다 먹고 그 아래 값이 있는지도 모르게 된다.
 */
@media (max-width: 820px) {
    .board-workview__grid { grid-template-columns: 1fr; }

    /* 한 줄로 서면 짚어 둔 자리가 오히려 걸린다. 마크업 차례대로 쌓는다 */
    .board-workview__photos,
    .board-workview__nav,
    .board-workview__info { grid-area: auto; }
    /*
     * **좁은 화면에서는 상자를 비로 잡는다.**
     *
     * 넓은 화면에서는 키만 못박고 폭을 사진이 정하게 두어(`width: auto`) 띠가
     * 안 생긴다. 여기서는 줄이 하나뿐이라 **폭이 `max-width: 100%` 에 걸리고**,
     * 그러면 가로 사진이 그 폭에 맞춰 줄어들어 **위아래가 빈 바닥으로 남는다.**
     * 키를 폭에서 뽑으면 그 자리가 없어진다.
     *
     * **4:3 이다.** 마흔넷 중 스물셋이 그 비라, 가장 많은 것이 딱 맞게 서고
     * 나머지는 폭이 줄어 앞뒤 사진이 옆에 걸쳐 보인다. 그것은 넓은 화면에서도
     * 하던 것이다. 키를 못박는 뜻(넘길 때 상자가 안 흔들린다)도 그대로다.
     */
    .board-workview__swiper {
        height: auto;
        aspect-ratio: 4 / 3;
    }
}

/* ============================================================
   FAQ 한 장 · board-faq (bbs/faq.php)

   **디자인하는 화면이 아니다.** 한 장짜리 홈페이지라 주메뉴의 FAQ 는 첫
   화면의 구획으로 내려간다. 손님이 이 주소로 올 일이 없고 지나는 것은
   관리자와 검색엔진이다. 그래서 **첫 화면 구획(`front-faq`)의 시안을 빌려오지
   않는다.** 가르는 규칙은 web/CLAUDE.md 의 「디자인한 화면과 안 한 화면을
   가른다」.

   그렇다고 깨뜨리지도 않는다. 우리 골격 안에 서는 화면이므로 게시판 계열의
   **수수한 기본 꼴**은 갖춘다. 전체검색 결과(`board-result`)와 같은 자리다.
   ============================================================ */
.board-faq { margin-bottom: 32px; }

/*
 * 묶음 고르기. **링크다.** 코어가 fm_id 로 한 묶음만 읽어 오므로 누르면
 * 화면이 갈린다. 지금 보고 있는 것은 `aria-current` 가 짚는다.
 */
.board-faq__cate {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 8px;
    margin-bottom: 20px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border-subtle);
}

.board-faq__catelink {
    padding: 6px 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    color: var(--text-weak);
    font-size: var(--fs-body);
}

.board-faq__catelink:hover { border-color: var(--color-gray-400); color: var(--text); }

.board-faq__catelink[aria-current="page"] {
    border-color: var(--color-primary);
    background: var(--color-primary);
    color: var(--color-white);
}

/* 검색 한 줄. 칸이 남는 자리를 다 쓰고 버튼은 제 글자만큼이다 */
.board-faq__search {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 24px;
}

.board-faq__searchbox { flex: 1 1 14em; min-width: 0; }

.board-faq__list {
    margin: 0;
    padding: 0;
    list-style: none;
    border-top: 1px solid var(--border-subtle);
}

.board-faq__item { border-bottom: 1px solid var(--border-subtle); }

/*
 * 질문 줄. **누르는 자리는 줄 전체다.** 표식만 누를 수 있게 하면 손가락으로
 * 맞히기 어렵다. `<details>` 가 여닫으므로 스크립트가 없다.
 */
.board-faq__q {
    display: grid;
    grid-template-columns: 1.6em minmax(0, 1fr);
    gap: 10px;
    padding: 16px 4px;
    cursor: pointer;
    list-style: none;
    font-weight: 600;
}

.board-faq__q::-webkit-details-marker { display: none; }
.board-faq__q:hover { color: var(--color-primary); }

.board-faq__qmark,
.board-faq__amark {
    color: var(--color-primary);
    font-weight: 700;
}

.board-faq__amark { color: var(--text-faint); }

.board-faq__qtext { word-break: keep-all; }

/* 답. 질문과 같은 칸에 선다 */
.board-faq__a {
    display: grid;
    grid-template-columns: 1.6em minmax(0, 1fr);
    gap: 10px;
    padding: 0 4px 20px;
}

.board-faq__atext {
    color: var(--text-weak);
    line-height: 1.8;
    word-break: keep-all;
}

/* 여닫히는 것도 움직인다. 이 의사요소를 모르는 브라우저에서는 즉시 열린다 */
.board-faq__box::details-content {
    block-size: 0;
    overflow: hidden;
    transition:
        block-size         var(--duration-base) ease,
        content-visibility var(--duration-base) allow-discrete;
}

.board-faq__box[open]::details-content { block-size: auto; }

/* 찾은 것이 없을 때. 목록 자리에 그대로 선다 */
.board-faq__none {
    padding: 48px 0;
    border-top: 1px solid var(--border-subtle);
    color: var(--text-weak);
    text-align: center;
}

