/*
 * PBL 프로젝트 목록(/pbl) 화면 전용.
 *
 * mili-home-v3 시안(참조: mili-ai-4-screens-share.vercel.app, 사이드바 "프로젝트" 메뉴)을 옮겼다.
 * 좌측 사이드바·다크 셸은 홈·VOD 목록과 같은 공용 조각을 쓰고, 이 파일에는 이 화면 전용
 * 레이아웃·히어로·카드만 둔다.
 *
 * ⚠️ 카드·히어로·필터의 치수는 VOD 목록(css/vod/course-list.css)과 의도적으로 같은 값이다 —
 * 프로젝트를 강의보다 크게 다룰 이유가 없어서 예전의 행(row)형 큰 카드와 큰 그라디언트 히어로를
 * 걷어내고 강의 카드와 같은 무게로 맞췄다. 클래스명을 catalog-* 로 공유하지 않고 pbl-* 로 두는
 * 이유는 화면 전용 CSS 는 뷰 경로를 미러링한다는 규약 때문이다(course-list.css 를 이 화면에서
 * 불러올 수 없다). 한쪽 치수를 손보면 다른 쪽도 같이 보는 게 맞다 — 단, 카드 배너 높이(264px, §6
 * 카드 배너 주석 참고)는 예외다. Figma node 1476:1479 실측이 PBL 카드만 이렇게 크고 VOD
 * (catalog-card__banner, 80px)는 그대로라 여기만 의도적으로 갈라져 있다. 그리드 열 수(3열)는
 * 이제 VOD 와 같다 — 예전엔 VOD 가 4열이었는데 그 사이 VOD 쪽이 3열로 바뀌어(course-list.css
 * .catalog-grid, 1280px+) 둘 다 3열이다. 전환 뷰포트(min-width)만 VOD 와 맞춰 1280px 을 쓴다.
 *
 * 분야 칩(표준 알약 탭 .tab-pill)은 theme/figma-classes.css 한 곳이 정본이다(2026-08-27 탭
 * 표준화). 페이지네이션(.pagination)의 다크 배색은 theme/components.css 의
 * ".mili-theme-dark ..." 오버라이드가 VOD 목록과 함께 처리한다.
 */

/* ===== 1) 본문 열 =====
   얼개(.app-frame/.app-frame__body/.app-topbar)는 theme/components.css §8 공용이다.
   폭은 화면 CSS 가 아니라 셸이 정한다(design-system.md §7) — VOD 목록과 마찬가지로 이 화면도
   shellWidth 를 넘기지 않으므로 기본값인 Standard(--mili-content-standard, 1200px)를 쓴다.
   카드 그리드가 3열까지 벌어지는 것도 VOD 목록과 같다. 세로 여백만 이 파일 소관이다. */

/* 상단 여백은 .page-hero 가 갖는다(course-list.css 의 .catalog-page 주석 참고). */
.pbl-page {
    padding-block-end: 4rem;
}

/* 2026-08-12 PBL 전용 노드(1653:6003 다크 · 1653:6561 라이트)로 재확인 완료 — "PBL" 다크는
   #b4ff39(--mili-brand 다크와 정확히 일치, 공용 규칙 그대로), 라이트는 #9fe970 로 VOD 와
   똑같이 일치한다. 이전엔 VOD 값을 그대로 가져다 썼는데(추정), 이번에 PBL 자체 노드로
   직접 대조해 같은 값임을 확인했다. */
/* 2026-08-13: 리터럴 #9FE970 가 --mili-brand 라이트 토큰과 정확히 같은 값이 됐다
   (2단계에서 tokens.css 라이트 브랜드색을 Figma 실측대로 오버라이드) — 토큰 참조로 되돌린다. */
.mili-light .pbl-page .page-hero__title-prefix {
    color: var(--mili-brand);
}

/* 2026-09-22 재실측(VOD 목록 course-list.css 와 같은 라운드·같은 근거, node 4038:312771) —
   이전 2026-08-28 라운드(node 2723:88109)는 구 노드였다. 실제 화면 노드는 숫자만
   Primary/500(#1a987f, 라이트)을 쓴다 — --mili-primary-500 토큰으로 옮긴다. 공용 클래스지만
   화면마다 별도 CSS 를 불러오므로 여기도 따로 필요하다. */
.mili-light .catalog-count-label__num {
    color: var(--mili-primary-500);
}

/* ===== 2) 히어로 (제목 + 검색) — theme/components.css 의 .page-hero 로 이관 =====
   VOD 목록과 같은 공통 프래그먼트(common/_page-hero.jsp)를 쓴다. 상세는 course-list.css 참고. */

/* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .catalog-page 모바일 오버라이드)에만 있고
   여기 없어서 상단 타이틀 여백이 화면마다 달랐다. 사용자 제공 모바일 실측 이미지 반영 —
   상단바~제목(48→20)·부제~검색창(32→16)은 공용 .page-hero(theme/components.css)가 갖는 값이라,
   그 파일을 고치지 않고 이 화면 스코프(.pbl-page)로만 좁혀 오버라이드한다(다른 목록형 화면에
   영향 없음, VOD 목록과 같은 값). */
@media (max-width: 767px) {
    .pbl-page .page-hero {
        margin-top: 12px;
        margin-bottom: 12px;
    }

    .pbl-page .page-hero__search {
        margin-top: 16px;
    }
}

/* ===== 2b) 프로모션 배너 =====
   2026-08-31 — 강의·PBL·로드맵 세 목록이 함께 쓰는 공용 캐러셀이 되어 theme/components.css
   §프로모션 배너 캐러셀(.mili-promo-*)로 옮겼다(마크업도 common/_promo-carousel.jsp 로 통합,
   promoActive="pbl" 로 이 화면 슬라이드를 기본 활성화한다). 이 화면 전용 .pbl-promo-banner* 는
   더 이상 쓰지 않는다. */

/*
 * ===== 3) 난이도 pill + 정렬 드롭다운 =====
 * 탭 자체(밑줄 스타일·pill·gap)는 theme/components.css 의 .level-filter 공용 컴포넌트다
 * (VOD 목록과 완전히 같은 값이라 2026-08-15 QA37 이후 그쪽으로 옮겼다). 이 화면은 히어로
 * 아래 상단 여백(margin)만 소관이다.
 * 우측 정렬은 VOD 목록(course-list.css .catalog-sort-dropdown)과 같은 최신순/가나다순
 * Bootstrap dropdown 이다(2026-08-21 추가). 값·클래스 구조는 화면 전용 CSS 미러링 규칙 때문에
 * 그대로 복제한다 — 한쪽 배색을 고치면 다른 쪽도 같이 봐야 한다.
 */

/* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .catalog-level-filter)과 값이 어긋나 있었다
   (36px vs 15px). 같은 히어로 아래 여백이라 맞춘다. */
.pbl-level-filter {
    margin: 15px 0 0;
}

/* 2026-08-27 추가(Figma node 2224:99512 실측) — VOD 목록(course-list.css
   .catalog-level-filter__actions)과 완전히 같은 값. "추천 콘텐츠 보기"·정렬 드롭다운을 8px
   간격으로 묶는다. .level-filter 가 justify-content:space-between 인 2단 구조라, 우측에 둘
   이상을 두려면 이 래퍼로 한 덩어리를 만들어야 pills 반대편에 제대로 붙는다. */
.pbl-level-filter__actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

/* 정렬 드롭다운(최신순/가나다순)은 이제 화면 전용 CSS 가 아니라 공용 컴포넌트다 —
   .mili-sort-dropdown__*(theme/components.css §21-1) 를 그대로 쓴다. VOD 목록과 완전히
   같은 값이라 화면마다 복제해 두던 것을 2026-08-28 에 통합했다. */

/* 2026-08-28 VOD 목록(course-list.css)과 같은 사고·같은 조치 — 모바일에서 "추천 콘텐츠 보기"·
   정렬 드롭다운 자리가 데스크톱과 다르다(추천 버튼은 "전체 N개" 줄 오른쪽, 정렬은 분야 칩 줄
   다음의 독립된 줄 우측 정렬). DOM 은 그대로 두고 각자 자리에 트리거를 하나씩 더 둔(JSP 참고)
   뒤 폭에 따라 어느 쪽을 보일지만 CSS 로 바꾼다. */
.recommend-trigger-btn--mobile-count,
.mili-sort-dropdown-row--mobile {
    display: none;
}

@media (max-width: 767px) {
    /* 2026-09-02 사용자 지적 — 검색창~배너~"전체 N개" 등과 같은 12px 리듬으로 맞춘다
       (course-list.css .catalog-level-filter 모바일 오버라이드와 같은 값·같은 이유). */
    .pbl-level-filter {
        margin-top: 12px;
    }

    /* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .catalog-level-filter .tab-line__link)과
       레벨 필터 탭 크기가 어긋나 있었다. 데스크톱 밑줄 탭(theme/figma-classes.css .tab-line__link,
       min-height 49px·패딩 12/20/13px·B2 16px)을 그대로 물려받아 시안(39px·8/20/9px·14px)보다 컸다. */
    .pbl-level-filter .tab-line__link {
        min-height: 39px;
        padding: 8px 20px 9px;
        font-size: var(--mili-body-b3-size);
    }

    .pbl-level-filter__actions {
        display: none;
    }

    /* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .catalog-count-label 모바일 오버라이드)과
       크기가 어긋나 있었다. 데스크톱 폰트(components.css .catalog-count-label, 24px)를 그대로
       물려받아 시안(18px)보다 컸다. */
    .catalog-count-label {
        font-size: 18px;
    }

    /* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .recommend-trigger-btn--mobile-count)과
       크기가 어긋나 있었다. 데스크톱 크기(components.css .recommend-trigger-btn, 패딩 8/12px·
       폰트 12px·아이콘 18px)를 그대로 물려받아 시안보다 컸다. */
    .recommend-trigger-btn--mobile-count {
        display: inline-flex;
        padding: 6.5px 9.75px;
        font-size: 11.35px;
    }

    .recommend-trigger-btn--mobile-count svg {
        width: 14.6px;
        height: 14.6px;
    }

    /* 2026-09-02 사용자 지적(devtools 실측, 첫 조치는 원인을 잘못 짚었다) — 진짜 원인은
       .pbl-filters 자신의 margin 이 아니라, 그 안에 중첩된 공용 컴포넌트 .tab-pill
       (theme/figma-classes.css) 이 갖는 margin-bottom: var(--mili-space-4)=16px 였다.
       .pbl-filters__chips 가 flex 아이템(BFC 경계)이라 이 마진이 형제 마진 collapse 없이 그대로
       갇혀 컨테이너 높이에 그대로 더해진다(course-list.css 의 같은 문제·같은 조치 참고). 이 화면
       스코프로만 0 으로 죽인다(다른 .tab-pill 사용처엔 영향 없음). */
    .pbl-filters .tab-pill {
        margin-bottom: 0;
    }

    /* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .catalog-filters .tab-pill__link)과
       분야 칩 크기가 어긋나 있었다. 데스크톱 알약 탭(theme/figma-classes.css .tab-pill__link,
       패딩 12/15px·B3 14px)을 그대로 물려받아 시안(세로 34px·패딩 8/12px·12px)보다 컸다. */
    .pbl-filters .tab-pill__link {
        min-height: 34px;
        padding: 8px 12px;
        font-size: var(--mili-caption-size);
    }

    /* 2026-09-02 사용자 지적 — margin 을 문자 그대로 위/아래 12px 로 둔다.
       2026-09-08 재대조(VOD 목록과 같은 근거, node 2804:25196) — "초기화"를 이 줄로 옮긴
       2026-09-07 조치가 시안과 어긋났다(재지적으로 되돌림). 시안엔 이 줄에 정렬 버튼
       하나뿐이라 space-between 이 아니라 flex-end 로 오른쪽 끝에 고정한다. "초기화"는
       다시 위 분야 칩 줄(.pbl-filters)에서만 그린다 — 그쪽 모바일 크기 보정은 §4 에 있다. */
    .mili-sort-dropdown-row--mobile {
        display: flex;
        align-items: center;
        justify-content: flex-end;
        gap: 8px;
        margin-top: 12px;
        margin-bottom: 12px;
    }

    /* 2026-09-02 사용자 지적 — VOD 목록(course-list.css 의 같은 선택자)과 드롭다운 버튼 모양이
       어긋나 있었다. 데스크톱 정렬 드롭다운(테두리 있는 버튼형)을 그대로 물려받아 모바일에서도
       테두리·배경이 남아 있었다 — 시안은 테두리·배경이 없는 텍스트+화살표뿐이다.
       2026-09-07 — course-list.css 와 같은 이유로 글자색 리터럴(--mili-neutral-550)을 뺀다.
       components.css 기본값(rgb(var(--mili-fg-rgb)))을 그대로 물려받는다. */
    .mili-sort-dropdown-row--mobile .mili-sort-dropdown__toggle {
        height: 36px;
        padding: 0 4px;
        border: 0;
        background: transparent;
        font-size: var(--mili-caption-size);
    }

    /* 2026-09-22 재실측(VOD 목록과 같은 근거) — 화살표 아이콘 12×12. */
    .mili-sort-dropdown-row--mobile .mili-sort-dropdown__toggle i {
        font-size: 12px;
    }
}

/* ===== 4) 보조 필터 줄 (분야 칩 + 초기화) =====
   2026-09-08 재대조(node 2804:25172/25196, course-list.css 와 같은 근거) — "초기화"를
   모바일에서만 정렬 줄로 옮겼던 2026-09-07 조치를 되돌린다. 시안은 PC·모바일 구분 없이
   "초기화"가 이 분야 칩 줄에 있고, 정렬 버튼만 별도 줄(§3-1)에 산다 — 그래서 PC 전용
   --desktop 수식자도 함께 걷어내 모든 폭에서 이 줄 하나로만 그린다. */

/* 2026-09-02 사용자 지적 — VOD 목록(course-list.css .catalog-filters)과 여백값이 어긋나 있었다
   (margin: 1.5rem 0 vs margin-top:15px/margin-bottom:24px). 같은 값으로 맞춘다. */
/* 2026-09-07 사용자 지적 — VOD 목록(course-list.css .catalog-filters)과 같은 이유로 nowrap 으로
   바꾼다. "초기화"가 분야 칩 줄 밑으로 떨어지던 것은 원래부터 있던 버그였다.
   align-items 도 flex-start 로 — categoryNo 선택 시 칩이 2줄로 늘어나면 center 는 "초기화"를
   그 전체 높이의 중앙에 놓아 칩 첫 줄보다 아래로 처져 보인다. */
.pbl-filters {
    display: flex;
    flex-wrap: nowrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--mili-space-3);
    margin-top: 15px;
    margin-bottom: var(--mili-space-6);
}

.pbl-filters__chips {
    flex: 1 1 auto;
    min-width: 0;
}

/* 2026-09-07 — 분야 칩(.tab-pill__link)과 같은 크기(패딩 12/15px·B3 폰트)로 맞춘다.
   글자색도 --mili-fg-muted(흐림)를 걷어낸다 — 최신순과 나란히 있을 때 유독 흐려 보인다는
   사용자 지적, 최신순 기본 글자색(rgb(var(--mili-fg-rgb)))과 맞춘다. */
.pbl-filters__reset {
    display: inline-flex;
    flex-shrink: 0;
    align-items: center;
    gap: 0.375rem;
    padding: 0.75rem 0.9375rem;
    border: 1px solid var(--mili-line-strong);
    border-radius: var(--mili-radius-pill);
    color: rgb(var(--mili-fg-rgb));
    font-size: var(--mili-body-b3-size);
    line-height: var(--mili-body-b3-line);
    font-weight: var(--mili-font-weight-semibold);
    text-decoration: none;
    white-space: nowrap;
}

.pbl-filters__reset:hover,
.pbl-filters__reset:focus {
    color: var(--mili-brand);
    background: rgba(var(--mili-fg-rgb), 0.06);
}

/* 2026-09-02 — 위 §3-1 .mili-sort-dropdown-row--mobile 모바일 오버라이드와 짝을 이루는 반대편
   (분야 칩 줄 → 정렬 줄 12px). 같은 특정성이면 소스 순서가 늦은 쪽이 이기므로, 위 무조건부
   .pbl-filters(margin:1.5rem 0) 정의보다 파일 뒤쪽에 둬야 이긴다. */
@media (max-width: 767px) {
    .pbl-filters {
        margin-top: 12px;
        margin-bottom: 12px;
    }

    /* 2026-09-08 사용자 지적 — "초기화"가 VOD 목록(course-list.css)과 크기가 달랐다. 원인은
       이 오버라이드가 위 §3-1(라인 165쯤) 무조건부 .pbl-filters__reset 정의보다 "먼저" 있어서
       소스 순서상 졌던 것 — 같은 규칙을 그 정의보다 뒤인 여기로 옮겨 이기게 한다(course-list.css
       와 같은 배치). 모바일 전용 크기(34px·8/12px·caption)는 그대로다. */
    .pbl-filters__reset {
        min-height: 34px;
        padding: 8px 12px;
        font-size: var(--mili-caption-size);
    }
}

/* ===== 5) 결과 없음 ===== */

/* 2026-09-04 Figma QA(node 3771:55253, VOD "공통" 결과없음 박스) 반영을 PBL 에도 맞춘다 —
   2026-09-02 주석대로 VOD 목록(course-list.css .catalog-empty)과 같은 컴포넌트다.
   2026-09-07 라이트 모드 실측(node 3230:69050) — course-list.css .catalog-empty 와 같은
   이유로 테두리 대신 라이트 전용 배경(--mili-surface-interactive)으로 맞춘다. */
.pbl-empty {
    padding: 3.5rem 1rem;
    text-align: center;
    color: rgba(var(--mili-fg-rgb), 0.7);
    background: var(--mili-surface);
    border-radius: var(--mili-radius-card);
}

.mili-light .pbl-empty {
    background: var(--mili-surface-interactive);
}

.pbl-empty strong {
    color: rgb(var(--mili-fg-rgb));
    font-weight: 600;
}

/*
 * ===== 6) 카드 그리드 =====
 * 640px 에서 2열, 1280px 에서 3열 — Figma node 1476:1443 실측(1행 3장)과도, VOD 목록
 * (course-list.css .catalog-grid)과도 일치한다. 전환 뷰포트도 VOD 와 같은 1280px 을 쓴다
 * (예전엔 VOD 가 4열인 줄 알고 그보다 일찍 3열로 좁히려고 1024px 을 썼는데, 지금은 VOD 도
 * 3열이라 그 근거가 없어져 VOD 값으로 되돌린다).
 */

.pbl-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--mili-space-5);
    margin-bottom: var(--mili-space-8);
}

@media (min-width: 640px) {
    .pbl-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (min-width: 1280px) {
    .pbl-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* 2026-08-27 Figma 모바일 시안(강의 목록과 같은 라운드의 같은 카드 컴포넌트, node 2769:98645
   실측) — 390px 폭에서 2열(카드 171px, gap 8px). VOD 목록(course-list.css .catalog-grid)과
   같은 이유·같은 값이다. */
@media (max-width: 767px) {
    .pbl-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }
}

/*
 * ⚠️ 2026-08-06 정정: --mili-panel 은 "고정 다크 톤"이 아니라 테마를 따르는 표면 토큰이다.
 * 표면만 뒤집히고 그 위의 글자·태그는 흰색 하드코딩이라 라이트에서 흰 판에 흰 글자가 됐었다.
 * 지금은 표면·글자·태그가 함께 뒤집힌다 — Figma 다크(#15181c)·라이트(#f8f9fa) 카드 배경
 * 실측이 각각 --mili-panel 의 다크·라이트 값과 정확히 일치한다(2026-08-27 재확인).
 *
 * 2026-08-27 재설계(node 2723:88929/89928) — 카드 상단은 더 이상 난이도별 그라디언트
 * 배너가 아니라 219px 고정 높이 이미지다(§6b 참고, images/pbl/project-{purple,blue,green}.png
 * 는 여전히 안 쓴다). 난이도 구분은 배너색이 아니라 §6c 의 강의레벨 배지 색으로 옮겨졌다.
 */
/* 2026-08-28 VOD 목록(course-list.css .catalog-card)과 같은 재실측·같은 조치 — 카드 자체엔
   drop-shadow 가 없다(평시 그림자 제거, hover 만 --mili-shadow-lg). 라이트 배경/테두리도
   neutral/100(#F8F9FA)·neutral/300(#F0F0F0)로 --mili-panel(순백)보다 한 단 낮은 톤이다. */
.pbl-card {
    position: relative;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--mili-line);
    border-radius: var(--mili-radius-card);
    background: var(--mili-panel);
    overflow: hidden;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.pbl-card:hover,
.pbl-card:focus-within {
    border-color: var(--mili-line-strong);
    box-shadow: var(--mili-shadow-lg);
}

.mili-light .pbl-card {
    background: var(--mili-neutral-100);
    border-color: var(--mili-neutral-300);
}

.pbl-card__link {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-width: 0;
    color: inherit;
    text-decoration: none;
}

.pbl-card__link:hover,
.pbl-card__link:focus {
    color: inherit;
}

/*
 * ===== 6b) 카드 상단 이미지 =====
 * Figma node 2723:88929(다크)/2723:89928(라이트) 실측(2026-08-27 재설계) — 219px 고정 높이.
 * 시안은 프로젝트별 실제 사진/일러스트를 쓰지만 그런 자산이 없어(사용자 확인) 목록 상세·
 * 마이페이지가 이미 쓰는 공용 배경 40장(theme/components.css .course-card__thumb--N,
 * --card-bg 커스텀 프로퍼티)을 그대로 얹는다 — pbl/project-detail.css 의 같은 패턴 재사용.
 */
.pbl-card__media {
    position: relative;
    /* z-index:0 으로 이 요소를 스택 컨텍스트 경계로 못박는다 — 아래 __media-photo 의
       z-index:-1 이 카드 다른 부위(본문 텍스트 등) 밑으로 새지 않고 이 매체 영역
       배경과 ::before 오버레이 사이에만 놓이게 한다. */
    z-index: 0;
    height: 219px;
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 0.625rem;
    padding: 1.25rem;
    background: var(--mili-neutral-900) var(--card-bg, none) no-repeat center / cover;
    overflow: hidden;
}

/* 실제 업로드 표지(card.coverImgAttachNo) — 있을 때만 마크업에 나타나는 <img>.
   공용 배경(위 background)과 아래 ::before 어둡게 하는 오버레이 사이에 끼워 넣는다
   (course-list.css .catalog-card__media-photo 와 같은 패턴, 2026-09-09). */
.pbl-card__media-photo {
    position: absolute;
    inset: 0;
    z-index: -1;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 배경이 그라디언트 타일에서 실사진(course-card__thumb--pbl-N)으로 바뀌면서(2026-08-28)
   태그·인원수 pill 가독성이 사진 내용에 따라 흔들릴 수 있어, 상세 히어로
   (project-detail.css)와 같은 톤의 어둡게 하는 오버레이를 더한다(VOD 목록과 같은 패턴). */
.pbl-card__media::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.05) 30%, rgba(0, 0, 0, 0.45) 100%);
}

.pbl-card__media-top {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

/* "프로젝트" 태그 — theme/figma-classes.css 의 .tag.pbl(콘텐츠 타입 공용 태그, sky 색, 다크/라이트
   값 모두 이미 정의됨)을 그대로 쓴다. Figma 는 아이콘을 작은 sky 원 안에 얹지만, 새 변형을
   만들기보다 이미 검증된 컴포넌트를 재사용한다(2026-08-27 AI 판단 — 재확인 필요).
   아이콘 글리프 다크색(Neutral/900)은 2026-09-22 재실측으로 공용 컴포넌트 자체
   (figma-classes.css node 2042:215476 "Tag" 시트 확인)가 정정돼 이 화면에 별도 오버라이드가
   필요 없다. */
.pbl-card__kind {
    flex: 0 0 auto;
}

/* 배지·북마크는 이미지 위에 항상 겹쳐 그려지므로 테마와 무관하게 어두운 반투명 오버레이를
   쓴다(Figma 다크·라이트 프레임 모두 rgba(26,29,34,.8)로 동일 — 사진 위 오버레이는 사이트
   테마가 아니라 이미지 밝기 기준이다). 불투명도는 2026-08-27 재실측으로 .24 → .8 로 올렸다.
   2026-09-11 재실측(실제 화면 node 4038:312771 안의 카드 인스턴스) — 이 pill은 태그·북마크
   줄이 아니라 매체 영역 좌하단에 독립적으로 앉는다(course-list.css 와 같은 정정). 북마크와
   같은 줄이 아니므로 자리를 비워 둘 필요가 없다. */
.pbl-card__count-pill {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    gap: var(--mili-space-1);
    min-height: 32px;
    padding: 0.375rem 0.625rem;
    border-radius: var(--mili-radius-pill);
    background: rgba(26, 29, 34, 0.8);
    color: var(--mili-neutral-100);
    /* 폰트 크기·굵기(Caption/Semibold, 12px·600)는 화면 CSS 에 다시 적지 않는다 — 마크업의
       .caption_s(공용 타이포그래피 카탈로그)가 담당한다. */
    white-space: nowrap;
}

/* bi-people 아이콘은 .caption_s 의 line-height(0.975rem)를 그대로 물려받으면 12px 글리프가
   세로로 남는 여백 때문에 정사각형으로 안 보인다 — 14px 고정 정사각 박스로 분리한다
   (css/vod/course-list.css .catalog-card__count-pill .bi-people 와 동일 근거, 2026-09-22
   Figma QA — 이 화면만 빠져 있던 것을 반영). */
.pbl-card__count-pill .bi-people {
    display: inline-flex;
    width: 0.875rem;
    height: 0.875rem;
    font-size: 0.875rem;
    line-height: 1;
    flex-shrink: 0;
}

/* 2026-09-11 Figma 재실측(node 3498:32256/32412, get_design_context — course-list.css 와 동일
   근거) — 수강중/수료 상태 배지는 PC 목록 뷰에도 그려진다. 이전 주석("데스크톱은 이번
   라운드에 안 함")은 낡은 상태였다. 배경 흰색(수강중)/라임(수료), 글자 --mili-neutral-900,
   14px SemiBold, pill 모서리 — 사진 위 오버레이라 테마 무관 고정색. 아래 모바일 압축
   블록이 축소된 크기로 덮어쓴다. */
.pbl-card__status {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 32px;
    padding: 0 0.625rem;
    border-radius: var(--mili-radius-pill);
    font-size: var(--mili-body-b3-size);
    font-weight: var(--mili-font-weight-semibold);
    color: var(--mili-neutral-900);
    white-space: nowrap;
    margin-right: 2.75rem;
}

.pbl-card__status--flush {
    margin-right: 0;
}

.pbl-card__status--enrolled {
    background: var(--mili-neutral-50);
}

.pbl-card__status--done {
    background: var(--mili-primary-500);
}


/*
 * 찜(북마크) — 이미지 위에 겹쳐 그리는 별도 form(카드 링크 안에 넣을 수 없다, 카드 전체가
 * 하나의 <a> 라서 — 2026-08-27 재설계로 하단 CTA 가 없어졌지만 이 제약은 그대로다).
 */
.pbl-card__bookmark-form {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4.5rem;
    z-index: 2;
    pointer-events: none;
}

.pbl-card__bookmark {
    position: absolute;
    top: 1.25rem;
    right: 1.25rem;
    pointer-events: auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 50%;
    background: rgba(26, 29, 34, 0.8);
    color: var(--mili-neutral-100);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.pbl-card__bookmark:hover {
    color: rgba(248, 249, 250, 0.8);
}

/* 채워진 상태(bi-bookmark-fill)는 윤곽선 상태(bi-bookmark)와 같은 font-size 인데도 도형이 꽉 차
   있어 원 안에서 눈에 띄게 더 커 보인다(2026-09-03 관심목록 QA — 전 카드가 항상 채워진 상태라
   유독 도드라졌다). 채워진 쪽만 살짝 줄여 두 상태의 체감 크기를 맞춘다(css/vod/course-list.css
   .catalog-card__bookmark 와 같은 값). */
.pbl-card__bookmark .bi-bookmark-fill {
    font-size: 0.8125rem;
}

/*
 * ===== 6c) 카드 본문 (제목 + 정의 목록) =====
 * Figma node 2723:88951(다크)/2723:89951(라이트) 실측 — 이미지 밖 일반 패널이라 테마 토큰이
 * 그대로 뒤집힌다(제목 색은 var(--mili-fg), VOD 목록(catalog-card__title)과 같은 토큰).
 */
.pbl-card__body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

.pbl-card__media + .pbl-card__body {
    gap: 1rem;
    padding: 1.5rem 1.5rem 1.5625rem;
}

/* 크기·굵기·줄높이(Heading/H4/Bold, 20px·700·1.4)는 화면 CSS 에 다시 적지 않는다 — 마크업의
   .h4_b(공용 타이포그래피 카탈로그)가 담당한다. letter-spacing 만 여기서 다시 지정한다
   (.h4_b 는 0으로 초기화하는데, 실측(-0.4px=-0.02em)이 남아 있다). */
.pbl-card__title {
    margin: 0;
    min-height: 56px;
    letter-spacing: -0.02em;
    color: var(--mili-fg);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 강의레벨(배지) / 제공기관 / 카테고리 / 이수시간 정의 목록. 2026-08-27 재설계 — 예전엔
   수행형태(개인/N인 팀) 줄이 있고 이수시간은 카드 하단 액션 줄이었는데, 시안(node 2723:88951)은
   수행형태가 없고 이수시간이 이 목록 마지막 줄이다(사용자 확인). */
/* dt/dd 크기(Body/B3, 14px)는 화면 CSS 에 다시 적지 않는다 — 마크업의 .b3_r/.b3_m
   (공용 타이포그래피 카탈로그)이 담당한다. */
.pbl-card__facts {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--mili-space-2);
}

.pbl-card__facts-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 20px;
}

/* 2026-09-22 재실측(node 4038:312771 카드 인스턴스, get_design_context — VOD 목록
   course-list.css 와 같은 근거) — 라벨+아이콘은 다크 Neutral/550·라이트 Neutral/750, 값(dd)은
   다크 Neutral/50·라이트 Neutral/900 고정값이다. Neutral 프리미티브는 테마 무관 고정값이라
   (theme/primitives.css) 라이트는 별도로 다시 지정해야 한다. */
.pbl-card__facts-row dt {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--mili-neutral-550);
}

/* 2026-09-22 Bootstrap Icons(bi-*) → Figma 실측 Lucide 인라인 SVG 교체(get_design_context,
   node 4839:204532) — 아이콘은 stroke="currentColor" 라 위 dt 의 color 를 그대로 물려받는다.
   크기만 여기서 16px(시안 native 16×16 viewBox) 정사각 박스로 고정한다. */
.pbl-card__fact-icon {
    width: var(--mili-space-4);
    height: var(--mili-space-4);
    flex-shrink: 0;
}

.pbl-card__facts-row dd {
    margin: 0;
    color: var(--mili-neutral-50);
}

.mili-light .pbl-card__facts-row dt {
    color: var(--mili-neutral-750);
}

.mili-light .pbl-card__facts-row dd {
    color: var(--mili-neutral-900);
}

/* 강의레벨 배지 — VOD 목록(course-list.css .catalog-card__level-badge)과 완전히 같은 값·패턴
   (Figma get_variable_defs 실측: 초급 sky-900/E3F5FF, 중급 green-900/DDF8E1, 고급 orange-900/
   FFEBDD, 라이트는 각 /50 배경 + /700~800 글자). PBL 카드는 3단(basic/intermediate/advanced)만
   쓴다(수행형태 줄과 마찬가지로 "전문가" 4단은 이번 범위 밖 — 2026-08-27 사용자 확인). */
/* 크기·굵기(Caption/Semibold, 12px·600)는 화면 CSS 에 다시 적지 않는다 — 마크업의 .caption_s
   (공용 타이포그래피 카탈로그)가 담당한다. */
.pbl-card__level-badge {
    display: inline-flex;
    align-items: center;
    /* 2026-09-18 Figma 재실측(node 2042:215476, VOD 목록과 동일 값) — height 20px 명시. */
    height: 20px;
    padding: 0.25rem 0.625rem;
    border-radius: var(--mili-radius-pill);
    background: var(--level-badge-bg);
    color: var(--level-badge-fg);
}

.pbl-card--basic .pbl-card__level-badge { --level-badge-bg: var(--mili-sky-900); --level-badge-fg: var(--mili-sky-100); }
.pbl-card--intermediate .pbl-card__level-badge { --level-badge-bg: var(--mili-green-900); --level-badge-fg: var(--mili-green-100); }
.pbl-card--advanced .pbl-card__level-badge { --level-badge-bg: var(--mili-orange-900); --level-badge-fg: var(--mili-orange-100); }

/* 2026-08-28 재실측(VOD 목록 course-list.css 와 같은 라운드·같은 근거, node 2723:89961 등
   get_design_context/get_variable_defs) — 라이트는 배경 100~200단, 글자 700~800단이다.
   기존 50/500~700 조합은 다른 화면(추천 모달 카드)을 옮겨적은 값이라 어긋났다. */
.mili-light .pbl-card--basic .pbl-card__level-badge { --level-badge-bg: var(--mili-sky-200); --level-badge-fg: var(--mili-sky-800); }
.mili-light .pbl-card--intermediate .pbl-card__level-badge { --level-badge-bg: var(--mili-green-100); --level-badge-fg: var(--mili-green-800); }
.mili-light .pbl-card--advanced .pbl-card__level-badge { --level-badge-bg: var(--mili-orange-100); --level-badge-fg: var(--mili-orange-700); }

/* 2026-08-31 — .pbl-cta(프로모션 배너 버튼이 쓰던 사이트 전역 Primary CTA 뉴트럴 흑백 반전)는
   배너가 3화면 공용 컴포넌트가 되면서 지웠다. 같은 값의 .mili-promo-banner__cta
   (theme/components.css)로 흡수됐다. */

/*
 * ===== 7) 모바일 카드 압축(≤767px) =====
 * VOD 목록(course-list.css §8)과 같은 라운드의 같은 실측·같은 이유 — 카드 구조가 데스크톱과
 * 다르다(매체 219px→82px, 패딩 20/24px→12px, 제목 20px→16px, 제공기관 줄 없음, 강의레벨+
 * 이수시간 한 줄, 카테고리는 아이콘만). 2026-08-27 사용자 확인.
 */
@media (max-width: 767px) {
    /* 2026-09-02 재실측(node 2804:24908 다크/2804:26658 라이트, VOD 강의 목록과 같은 카드
       컴포넌트를 프로젝트 색으로 재사용) — course-list.css .catalog-card__media 와 같은 조치.
       고정 82px·padding 12px 는 이 시안(160/90 종횡비, 패딩 8px)과 달랐다. */
    .pbl-card__media {
        height: auto;
        aspect-ratio: 16 / 9;
        padding: 8px;
        gap: 0.5rem;
    }

    .pbl-card__media + .pbl-card__body {
        padding: 12px;
        gap: 0.625rem;
    }

    /* 2026-09-02 재실측 — course-list.css .catalog-card__title 과 같은 사고. 16px 는 다른
       카드를 옮겨 적은 값이었다. 실제 시안은 Body/B3/SemiBold 14px·line-height 1.3, 다크·
       라이트 모두 SemiBold 로 같다(둘로 갈라 뒀던 font-weight 규칙 통합). */
    .pbl-card__title {
        min-height: 39px;
        font-size: 14px;
        font-weight: var(--mili-font-weight-semibold);
        line-height: 1.3;
    }

    /* 2026-09-02 재실측(node 2804:24908 다크/2804:26658 라이트) — 글자 크기는 라이트(8.75px
       =14×0.625)가 정상, 다크(5.47px)는 이중 축소된 값이라 8.75px 유지(사용자 확인).
       패딩·테두리·그림자는 반대로 다크(3.75/6.25/2.5px)가 정상, 라이트가 이중 축소였다 —
       다크 값을 쓴다. 공용 .tag:is(.vod,...) 데스크톱 패딩(4/10/4/6px)의 정확히 0.625배다. */
    /* 2026-09-02 사용자 지적 — course-list.css .catalog-card__kind 와 같은 사고. "모바일" 구간
       (≤767px)은 카드 폭이 171px(390 뷰포트)~359px(767 뷰포트)까지 넓게 걸쳐 있는데 고정 px
       는 390px 한 지점에만 맞아 넓은 폭에서 태그가 작아 보였다. 컨테이너 쿼리 대신 뷰포트
       기준 clamp() — 이 카드를 재사용하는 유일한 다른 화면(mypage/wishlist.jsp)도 같은
       그리드·같은 뷰포트-카드폭 공식이라(모바일에서 사이드바 오프캔버스) 컨테이너 폭이
       뷰포트와 달라지는 경우가 없다. --tag-scale 은 390px 에서 0.625, 767px 에서 1(데스크톱
       .tag:is(...) 값)이 되도록 선형 보간 — course-list.css 와 완전히 같은 공식.
       ⚠️ 사용자 실측 지적(2026-09-02, "카드마다 제각각/PC보다 큼") — course-list.css 와 같은
       원인: 나눗셈에 단위를 안 붙이면(/377) 결과가 길이(px)로 남아 단위 없는 0.625 와 더할 때
       CSS calc 타입 불일치로 --tag-scale 전체가 guaranteed-invalid 가 되고, 이를 쓰는 속성들이
       저마다 다른 기본값으로 떨어져 크기가 들쭉날쭉했다. 377 → 377px(길이÷길이=단위 없는 숫자).
       2026-09-04 — 공용 .tag 그림자가 실측 근거 없이 들어갔던 것으로 밝혀져 걷어냈다
       (figma-classes.css 참고). 이 스케일 규칙의 box-shadow 도 같이 뺀다. */
    .pbl-card__kind {
        --tag-scale: clamp(0.625, calc(0.625 + (100vw - 390px) / 377px * 0.375), 1);
        font-size: calc(14px * var(--tag-scale));
    }

    .pbl-card__kind.tag {
        height: calc(32px * var(--tag-scale));
        border-width: calc(1px * var(--tag-scale));
        padding: calc(4px * var(--tag-scale)) calc(10px * var(--tag-scale)) calc(4px * var(--tag-scale)) calc(6px * var(--tag-scale));
        gap: calc(4px * var(--tag-scale));
    }

    .pbl-card__kind .tag__icon {
        width: calc(20px * var(--tag-scale));
        height: calc(20px * var(--tag-scale));
    }

    .pbl-card__kind .tag__icon > i,
    .pbl-card__kind .tag__icon > svg {
        font-size: calc(12px * var(--tag-scale));
    }

    /* 2026-09-02 재실측 — course-list.css .catalog-card__count-pill--mobile 과 같은 사고.
       기존 padding 2.5px/7.222px·font 7.778px 는 이 pill이 아니라 옆의 수강중/수료 상태
       배지 수치를 잘못 옮겨 온 값이었다. 실측: min-h 20px·padding 4px 8px·gap 2px·font 8px. */
    .pbl-card__count-pill--mobile {
        min-height: 20px;
        padding: 4px 8px;
        gap: 2px;
        font-size: 8px;
    }

    .pbl-card__bookmark {
        top: 8px;
        right: 8px;
        width: 20px;
        height: 20px;
        font-size: 0.5rem;
    }

    /* 2026-09-02 재실측(node 2804:24908 다크/2804:26658 라이트) — 태그 옆 줄 오른쪽의
       수강중/수료 상태 배지 축소판(course-list.css .catalog-card__status 와 같은 값). 색상·
       폰트는 위 데스크톱 기본값과 같고(2026-09-11 재확인) 크기·여백만 모바일용으로 줄인다. */
    .pbl-card__status {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-height: 20px;
        padding: 0 7.222px;
        border-radius: var(--mili-radius-pill);
        font-size: 8.75px;
        font-weight: var(--mili-font-weight-semibold);
        color: var(--mili-neutral-900);
        white-space: nowrap;
        margin-right: 1.5rem;
    }

    .pbl-card__status--flush {
        margin-right: 0;
    }

    .pbl-card__status--enrolled {
        background: var(--mili-neutral-50);
    }

    .pbl-card__status--done {
        background: var(--mili-primary-500);
    }

    /* data-role="wish-icon" 는 토글(browse) 모드 아이콘에만 붙는 JS 훅 속성이다 — 관심목록
       (mypage/wishlist.jsp, 토글이 아니라 항상 해제만 하는 모드)의 아이콘엔 없어서 이 축소가
       빠졌고, 그 결과 같은 카드인데 관심목록 쪽만 모바일에서 아이콘이 커 보였다(2026-09-03
       QA 재지적 — 실측 9.1px 대 13px, css/vod/course-list.css 와 같은 원인). 아이콘 자체(i)를
       잡아 모드와 무관하게 축소한다. */
    .pbl-card__bookmark i {
        transform: scale(0.7);
    }

    /* 2026-08-28 재실측(VOD 목록 course-list.css 와 같은 사고, get_metadata) — 시안 모바일 카드는
       4줄(강의레벨/제공기관/카테고리/이수시간)을 압축 없이 그대로 세로 나열하고, 라벨 텍스트
       없이 아이콘+값만 보인다. 이전엔 스크린샷만 보고 "2줄 압축, 제공기관 숨김"으로 잘못
       판단했었다. */
    .pbl-card__facts {
        gap: 0.25rem;
    }

    .pbl-card__facts-row {
        min-height: 0;
        gap: 0.375rem;
    }

    .pbl-card__facts-row dt {
        font-size: 0;
        gap: 0;
    }

    .pbl-card__fact-icon {
        width: var(--mili-space-3);
        height: var(--mili-space-3);
        margin-right: 0.375rem;
    }

    /* 2026-09-22 사용자 지적(VOD 목록과 같은 근거) — 제공기관/카테고리 값 한 줄 초과시 말줄임표. */
    .pbl-card__facts-row dd {
        font-size: 0.625rem;
        flex: 1 1 auto;
        min-width: 0;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
    }

    /* 2026-09-02 사용자 지적 — VOD 목록(course-list.css 모바일 .catalog-card__level-badge)과
       레벨 배지 크기가 어긋나 있었다(데스크톱 패딩 4/10px·caption_s 12px·600 을 그대로 물려받아
       시안 13px·패딩 1/6px·8px·700 보다 컸다). */
    .pbl-card__level-badge {
        padding: 1px 6px;
        font-size: 8px;
        /* 2026-09-22 재실측(VOD 목록과 같은 근거) — leading-[1.4](140%). */
        line-height: 1.4;
        font-weight: var(--mili-font-weight-bold);
    }
}
