/* DW Builder Core — Block CSS (Tier 1)
 *
 * Comprehensive layout/responsive rules for WP core blocks. Loaded for every
 * dwwp child theme via parent functions.php. WP core's wp-block-library.css
 * already covers basic block painting; this file adds the layout/grid/
 * responsive behaviors that block themes typically generate from theme.json
 * but which we want consistent across all DW Builder sites.
 *
 * Conventions:
 *   - Mobile-first where possible.
 *   - Breakpoints follow WP defaults: 600px (small), 782px (medium).
 *   - Use CSS variables emitted by theme.json (var(--wp--preset--color--*),
 *     var(--wp--preset--font-size--*)) — NOT hard-coded values — so child
 *     themes override naturally.
 */

/* ── Reset / base ─────────────────────────────────────────────────────── */

body {
  margin: 0;
  font-family: var(--wp--preset--font-family--body, system-ui, -apple-system, sans-serif);
}

/* ── Korean typography 보정 (parent v1.3.12+) ───────────────────────────
 *
 * 한글은 같은 px 사이즈에서 라틴 글자보다 시각적으로 더 크고 빽빽해 보임.
 * line-height +0.1 / letter-spacing 약간 음의 값 / word-break keep-all 로
 * 보정. :lang(ko) 가 html lang="ko" / lang="ko-KR" 둘 다 매칭 — WP 의
 * 사이트 언어 설정이 한국어면 자동 적용. 다국어 사이트의 한글 영역에만 영향.
 *
 * 참고: docs/web-block-patterns-reference.md §2 (한글 타이포 가이드).
 */
/* :where() 0 특이성 — 이 보정은 "기본값"이라 커스텀 값(customCss 클래스,
 * 인라인)이 항상 이겨야 함. (0,1,1) 이던 시절 클래스 자간(.14em 등)을
 * -0.01em 이 덮음 (2026-09-06 실측). 캔버스 globals.css 와 동률. */
:where(:lang(ko)) :where(p, li, blockquote) {
  line-height: 1.7;
  letter-spacing: -0.01em;
  word-break: keep-all;
  overflow-wrap: break-word;
}

:where(:lang(ko)) :where(h1, h2, h3, h4, h5, h6) {
  letter-spacing: -0.04em;
  word-break: keep-all;
  overflow-wrap: break-word;
}

/* 숫자가 많이 등장하는 영역 — 가격/통계 — 너비 일정. 한글 본문에서도 의미 있음. */
.has-numeric,
[class*="price"],
[class*="stat"],
.wp-block-pullquote cite,
table th, table td {
  font-variant-numeric: tabular-nums;
}

img, video, svg {
  max-width: 100%;
  height: auto;
}

/* ── Layout — wp-block-group + is-layout-* ─────────────────────────────── */

.wp-block-group {
  box-sizing: border-box;
}

/* (v1.3.3+) 글로벌 section padding rule 제거.
 * 이전엔 .alignfull / .alignwide 의 group 에 75px top/bottom 을 강제로
 * 박았지만 — 1) header/footer 의 inline style 보다 약하게 적용되거나
 * 2) static HTML 에 inline style 이 빠진 경우 75px 가 의도치 않게 이김.
 * 사용자 보고: header/footer 위아래 75px, hero 위 100px 등이 글로벌로
 * 적용돼 의도와 다름.
 *
 * 이제는 각 block (header/footer/content section) 이 자기 padding 을
 * 명시적으로 inline style 로 emit. 글로벌 fallback 없음. 안 박혀있으면
 * 0 — 안 보이는 것보다 의도된 명시 padding 이 항상 우선.
 */

/* Vertical rhythm between sections — adjacent section groups touch with no
 * extra margin (each carries its own padding). */
.wp-block-group + .wp-block-group,
.wp-block-cover + .wp-block-group,
.wp-block-group + .wp-block-cover,
.wp-block-cover + .wp-block-cover {
  margin-top: 0;
}

/* Inner column padding so card content doesn't crowd column edges. */
.wp-block-columns > .wp-block-column {
  padding: 0.5rem;
}

.wp-block-group.is-layout-constrained > *,
.is-layout-constrained > * {
  max-width: var(--wp--style--global--content-size, 100%);
  margin-left: auto;
  margin-right: auto;
}
.wp-block-group.is-layout-constrained > .alignwide,
.is-layout-constrained > .alignwide {
  max-width: var(--wp--style--global--wide-size, 1400px);
}
/* WP 표준 alignfull escape — 부모 constrained 안에서 viewport 풀폭으로
 * negative margin 으로 빠져나감. 모든 섹션 블록 (cover/group/media-text/
 * columns) 동일 적용. */
.wp-block-group.is-layout-constrained > .alignfull,
.is-layout-constrained > .alignfull {
  max-width: none;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
  width: auto;
}

/* 풀폭 escape 한 section 안의 콘텐츠가 viewport 끝까지 펼쳐지지 않도록
 * 좌우 padding. cover/media-text/columns 는 자체 layout 으로 처리하므로
 * 제외 — 일반 group section (cta/features/about-text 등) 의 텍스트가
 * viewport 끝까지 가는 부작용 방지. */
.is-layout-constrained > .alignfull:not(.wp-block-cover):not(.wp-block-media-text):not(.wp-block-columns) {
  padding-left: var(--wp--style--root--padding-left, clamp(1rem, 5vw, 2.5rem));
  padding-right: var(--wp--style--root--padding-right, clamp(1rem, 5vw, 2.5rem));
}

.wp-block-group.is-layout-flow > *,
.is-layout-flow > * {
  margin-block-start: 0;
  margin-block-end: 0;
}

.wp-block-group.is-layout-flex,
.is-layout-flex {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5em;
}
.is-layout-flex > * {
  margin: 0;
}
.is-vertical.is-layout-flex,
.is-layout-flex.is-vertical {
  flex-direction: column;
  align-items: flex-start;
}

.is-content-justification-left           { justify-content: flex-start; }
.is-content-justification-center         { justify-content: center; }
.is-content-justification-right          { justify-content: flex-end; }
.is-content-justification-space-between  { justify-content: space-between; }

/* ── Alignment ────────────────────────────────────────────────────────── */

.alignleft   { float: left;  margin-right: 1.5em; }
.alignright  { float: right; margin-left: 1.5em; }
.aligncenter { display: block; margin-left: auto; margin-right: auto; }

.alignwide,
.alignfull   { clear: both; }
.alignfull   {
  width: 100%;
  max-width: none !important;
  margin-left: 0;
  margin-right: 0;
}

.has-text-align-left   { text-align: left; }
.has-text-align-center { text-align: center; }
.has-text-align-right  { text-align: right; }

/* ── Columns ──────────────────────────────────────────────────────────── */

.wp-block-columns {
  display: flex;
  flex-wrap: wrap;
  gap: 2em;
  box-sizing: border-box;
}
/* ↑ 위 선언 중 일부는 전역 토큰 규칙과 **특이성 동점**(둘 다 0,1,0)이라 문서
 * 순서로만 이기고 있었다. 프런트는 blocks.css 가 global styles 뒤에 실려
 * 이겼지만, 구텐베르크 편집기는 순서가 반대라 이 선언들만 죽었다
 * (2026-09-19 실측: 6개 페이지 전수 비교로 확인).
 *   :root :where(.wp-block-group){padding-block:80px}
 *   :root :where(.is-layout-flow) > *{margin-block:0}
 * 요소 선택자 한 칸(0,1,1)만 올리면 순서와 무관하게 패턴 기본이 토큰을 이기고,
 * 기존 (0,2,0) 오버라이드들과의 관계는 그대로다. 값은 여기 한 번만 쓴다. */
div.wp-block-columns { margin-bottom: 1.75em; }
.wp-block-columns.is-not-stacked-on-mobile { flex-wrap: nowrap; }

@media (min-width: 782px) {
  .wp-block-columns { flex-wrap: nowrap; }
}

.wp-block-column {
  flex-grow: 1;
  min-width: 0;
  word-break: break-word;
  overflow-wrap: break-word;
  flex-basis: 0;
}

/* ── Buttons ──────────────────────────────────────────────────────────── */

.wp-block-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75em;
  margin-top: 1.5em;
  box-sizing: border-box;
}
/* Buttons immediately following a heading get a bit more breathing room. */
.wp-block-heading + .wp-block-buttons,
.wp-block-paragraph + .wp-block-buttons,
p + .wp-block-buttons {
  margin-top: 1.75em;
}
.wp-block-button {
  display: inline-block;
}
.wp-block-button__link,
.wp-element-button {
  display: inline-block;
  /* Default = dasomweb.com/en 실측 확정 (2026-07-16): 18px/35px 패딩,
   * pill(999px), 16px w600. 프로젝트가 --dw-btn-radius 를 지정하면 그 값. */
  padding: 1.1em 2.2em;
  border-radius: var(--dw-btn-radius, 999px);
  background-color: var(--wp--preset--color--primary, currentColor);
  color: #fff;
  font-family: inherit;
  font-size: inherit;
  font-weight: 600;
  line-height: 1.1;
  text-decoration: none;
  border: 0;
  cursor: pointer;
  transition: opacity 0.15s ease, transform 0.05s ease;
}
.wp-block-button__link:hover,
.wp-element-button:hover { opacity: 0.9; }
.wp-block-button__link:active,
.wp-element-button:active { transform: translateY(1px); }

.wp-block-button.is-style-outline .wp-block-button__link {
  background-color: transparent;
  color: var(--wp--preset--color--primary, currentColor);
  border: 2px solid var(--wp--preset--color--primary, currentColor);
}
/* Ghost — 배경/테두리 없이 텍스트만 (ButtonEditor variant) */
.wp-block-button.is-style-ghost .wp-block-button__link {
  background-color: transparent;
  color: var(--wp--preset--color--primary, currentColor);
  border: 0;
  padding-left: 0.5em;
  padding-right: 0.5em;
}
/* 버튼 크기 프리셋 (ButtonEditor Size S/M/L). 기본(md)은 위 기본 padding. */
.wp-block-button.dwwp-btn-sm .wp-block-button__link {
  padding: 0.5em 1.2em;
  font-size: 0.875em;
}
.wp-block-button.dwwp-btn-lg .wp-block-button__link {
  padding: 1em 2.4em;
  font-size: 1.125em;
}

/* 헤더 CTA / 인증 버튼 — 섹션용 큰 버튼(1.1em 2.2em, pill 999px)을 그대로
 * 물려받아 헤더에서 과도하게 커지던 문제(2026-07-28 사용자). 헤더에 어울리는
 * 콤팩트 크기로 교정 — 이 wrapper 스코프에서만. */
.dw-header-cta-wrap .wp-block-button__link,
.dw-header-auth .wp-block-button__link {
  padding: 0.5em 1.15em;
  border-radius: 8px;
  font-size: 0.9em;
  font-weight: 600;
  line-height: 1.4;
}
.dw-header-cta-wrap .wp-block-button.is-style-outline .wp-block-button__link,
.dw-header-auth .wp-block-button.is-style-outline .wp-block-button__link {
  border-width: 1.5px;
}
/* 인증 버튼 그룹 — 헤더 우측(메뉴 뒤) 로그인/회원가입 슬롯. 버튼 렌더는 auth
 * 플러그인(DW Easy Auth) 몫, 여기는 위치/컨테이너만.
 * 디자인 1c (2026-08-06 사용자 선택): 메뉴와 계정 영역 사이 세로 구분선
 * (1px×28px, 앞뒤 ~20px) + 버튼 간격 10px. 모바일은 드로어 하단(3b)으로 내림. */
.dw-header-auth {
  display: flex;
  align-items: center;
  align-self: center;
  gap: 10px;
  white-space: nowrap;
}
/* 우측 클러스터(메뉴+검색+auth) — WP flex 기본 gap(≈7.5px)이 좁아 메뉴가 숏코드와
 * 붙음 (2026-08-07 실측 8px). 간격 확장 + 수직 중앙 명시. */
/* 특이도 (0,2,1) — 위 .wp-block-group.is-layout-flex{gap:.5em}(0,2,0) 을 이겨야 함
 * (2026-08-07 실측: 8px 로 붙던 원인). */
header .wp-block-group.dw-header-right {
  align-items: center;
  gap: 28px;
}
/* 구분선은 그리지 않는다 — DW Easy Auth 플러그인 출력이 자체 구분선을 가져
 * 테마 ::before 와 겹치면 이중선(2026-08-06 사용자 스크린샷). 시각 요소는
 * 전부 플러그인 소관, 테마는 위치/간격만. */
/* 슬롯 안 숏코드가 <p>/<a> 를 emit 하는 경우의 기본 정리(플러그인 자체 스타일 우선). */
.dw-header-auth p { margin: 0; }
.dw-header-auth a { text-decoration: none; }

/* ── 헤더 상단 유틸리티 바 + 인증 메뉴 (로그인/회원가입 · 이름|Profile|Logout) ── */
/* 시안(OneFlow): 헤더 위쪽 얇은 바 우측에 텍스트 링크형 인증 메뉴. */
/* ── Top Bar (헤더 상단 좌/중/우 숏코드 바) ──────────────────────────────── */
.dw-topbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 2px 0 6px;
  margin-bottom: 6px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.06);
  font-size: 0.8125rem;
  line-height: 1.4;
}
.dw-topbar-slot { flex: 1 1 0; min-width: 0; display: flex; align-items: center; }
.dw-topbar-left { justify-content: flex-start; }
.dw-topbar-center { justify-content: center; text-align: center; }
.dw-topbar-right { justify-content: flex-end; }
/* wpautop 이 숏코드를 <p> 로 감싸며 넣는 기본 margin 제거 — 헤더 height 벌어짐 방지. */
.dw-topbar p { margin: 0; }
/* ── 헤더/푸터 전역 섹션-패딩 예외 ────────────────────────────────────────
   theme.json `:root :where(.wp-block-group){padding:50px 0}` 은 본문 섹션용인데
   :where() specificity 0 이라 헤더/푸터 안쪽 그룹(로고+메뉴 행, 푸터 인라인 행
   등)까지 상속돼 상하 50px+50px 로 헤더가 170px 로 부풀던 근본 원인(2026-07-28
   사용자 DevTools 실측, 요청: "Header 쪽에는 예외 적용이 되야지 / Footer 도
   마찬가지"). 헤더/푸터 자체(외곽)는 자기 inline 패딩을 가지므로 그대로 두고,
   그 '안쪽' 중첩 그룹의 세로 패딩만 통째로 0 처리 — 이후 그룹을 더 넣어도 안전. */
header.wp-block-group .wp-block-group,
footer.wp-block-group .wp-block-group {
  padding-top: 0;
  padding-bottom: 0;
}
.dw-header-main { margin-top: 0; margin-bottom: 0; }
/* Top Bar 와 그 슬롯은 자체 소량 패딩 복원(위 예외와 동일 specificity, 뒤 순서로
   이김). 슬롯은 세로 패딩 0 유지(전역 50px 상속 차단). */
header.wp-block-group .dw-topbar { padding: 2px 0 6px; }
header.wp-block-group .dw-topbar-slot { padding-top: 0; padding-bottom: 0; }

/* ── Container(자유 블록 컨테이너) 자식 세로 간격 ──────────────────────────
   제목이 위 문단에 딱 붙던 문제 해결: WP blockGap 은 :where() 로 emit 돼
   specificity 가 낮아 테마의 .wp-block-heading{margin-top:0} 에 밀림. 여기서
   확정해 제목/문단 모두 일관 간격(캔버스 ContainerPreview space-y-3 와 parity). */
.dw-container > * { margin-top: 0.75rem; }
/* 제목은 base `.wp-block-heading{margin-top:0}`(0,1,0)을 이겨야 하므로 태그
   기반 :is() 로 specificity(0,1,1) 확보. `.wp-block-heading` 리터럴을 피해
   base 색-inherit 가드(test_block_principles)와도 충돌 안 함. */
.dw-container > :is(h1, h2, h3, h4, h5, h6) { margin-top: 0.75rem; }
.dw-container > :first-child { margin-top: 0; }
/* 슬롯 안의 링크 — 숏코드가 <a> 를 emit 하는 경우의 기본 톤(플러그인 자체 스타일이
   있으면 그쪽이 우선). */
.dw-topbar a { color: #4b5563; text-decoration: none; transition: color 0.15s ease; }
.dw-topbar a:hover { color: var(--wp--preset--color--primary, currentColor); }

/* ── Top Bar 기기별 표시 선택 ─────────────────────────────────────────────
   빌더 Header 설정의 PC/태블릿/모바일 토글이 hide-클래스로 emit(끌 때만 부여).
   브레이크포인트는 프로젝트 columns 반응형과 동일: PC ≥1025, 태블릿 641–1024,
   모바일 ≤640. 클래스 있을 때만 그 구간에서 숨김(.dw-topbar 0,1,0 을 0,2,0 이 이김).
   기본값: 서버가 showMobile!==true 이면 hide-mobile 을 붙여 모바일 기본 숨김 유지. */
@media (min-width: 1025px) {
  .dw-topbar.dw-topbar-hide-desktop { display: none; }
}
@media (min-width: 641px) and (max-width: 1024px) {
  .dw-topbar.dw-topbar-hide-tablet { display: none; }
}
@media (max-width: 640px) {
  .dw-topbar.dw-topbar-hide-mobile { display: none; }
}

/* ── 모바일 햄버거 드로어 숏코드 슬롯 ─────────────────────────────────────
   서버는 슬롯을 헤더 안에 숨김(.dw-drawer-slot display:none)으로 실어 보내고,
   nav.js 가 모바일에서 드로어(nav) 상단/하단으로 옮겨 .dw-nav-drawer-item 으로
   감싼다. 데스크톱에선 Top Bar(.dw-topbar)만 보이고 드로어 슬롯은 안 보임. */
.dw-drawer-slot { display: none; }
.dw-nav-drawer-item { display: none; list-style: none; }
.dw-nav-drawer-item p { margin: 0; }
@media (max-width: 782px) {
  /* 햄버거 활성 구간 — 드로어 슬롯 노출. Top Bar 표시 여부는 위 기기별 hide
     클래스가 독립적으로 결정(무조건 숨김 아님, 2026-07-29 사용자 선택 기능). */
  .dw-nav-drawer-item { display: block; }
  .dw-nav-drawer-item .dw-drawer-slot { display: block; }
  /* 헤더 우측 로그인/회원가입 슬롯은 모바일에서 숨김(디자인 1b: 헤더=로고+햄버거만).
     같은 숏코드를 드로어 '하단 고정' 블록(dw-drawer-auth)이 대신 노출(디자인 3b):
     드로어(flex column) 맨 아래에 surface 배경 + 상단 구분선 컨테이너. 버튼
     내용물은 auth 플러그인(DW Easy Auth) 렌더. */
  .dw-header-auth { display: none; }
  /* 드로어(flex column, 100dvh)에서 하단 슬롯 li 를 맨 아래로 밀착. */
  .dw-nav-drawer-item.dw-nav-drawer-bottom { margin-top: auto; }
  /* 로그인/회원가입 슬롯 컨테이너 (dw-easyauth 협의 2026-08-20):
   * 소유권 분리 — **테마는 컨테이너만**(배치 여백), **버튼 모양(색·크기·모서리·정렬·
   * 방향)은 플러그인이 소유**(dw-easyauth). 그래서 여기선 버튼/링크 내부 스타일을
   * 일절 주지 않는다(예전 width:100%/justify-content 제거 — 플러그인의 가로 2분할
   * .dw-ea-nav--block flex row 와 경합했음). 구분선은 dw-nav-drawer-top li border-bottom.
   * 방향은 플러그인이 결정: style="block"=가로 한 쌍, style="menu"=세로 전폭 —
   * 컨테이너는 단일 <p> 를 감싸는 flex 라 둘 다 그대로 통과. */
  .dw-nav-drawer-item .dw-drawer-auth {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 2px 0 4px;
  }
  .dw-nav-drawer-item .dw-drawer-auth p { margin: 0; }
  .dw-nav-drawer-top {
    margin: 0 0 0.75rem;
    padding: 0 0 0.9rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  }
  .dw-nav-drawer-bottom {
    margin: 0.75rem 0 0;
    padding: 0.9rem 0 0;
    border-top: 1px solid rgba(0, 0, 0, 0.08);
  }
}

/* ── Cover ────────────────────────────────────────────────────────────── */

.wp-block-cover {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 430px;
  overflow: hidden;
  box-sizing: border-box;
  padding: 2em;
  background-size: cover;
  background-position: center center;
}
.wp-block-cover__background,
.wp-block-cover__gradient-background {
  position: absolute;
  inset: 0;
  z-index: 1;
}
.wp-block-cover__image-background {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  border: 0;
  margin: 0;
  padding: 0;
}
.wp-block-cover__inner-container {
  position: relative;
  z-index: 2;
  width: 100%;
  color: #fff;
}
/* Cover 안의 heading + paragraph default color 흰색.
 * theme.json 의 styles.elements.heading.color.text (= designSystem.text)
 * 가 specificity 0,1,0 으로 모든 heading 에 적용. cover dim overlay 가
 * 깔린 위에서도 어두운 text 색이면 거의 안 보임 — 강제로 흰색.
 *
 * specificity (0,1,1) — element selector + class. theme.json 이 emit 하는
 * `:root :where(h1)` (0,1,0) / `:root :where(.wp-element-..)` 보다 우위.
 * (이전엔 `:where()` 로 0,1,0 이라 cascade 순서에 의존했고 일부 환경에서
 * theme.json 이 후행 emit 되어 어두운 색으로 깨지는 사고가 났음.)
 *
 * 사용자가 Properties Panel 에서 typography.color 명시하면 #blockId
 * inline rule (1,0,0) 이라 이 룰을 이김 — single-source 원칙 유지. */
.wp-block-cover__inner-container h1,
.wp-block-cover__inner-container h2,
.wp-block-cover__inner-container h3,
.wp-block-cover__inner-container h4,
.wp-block-cover__inner-container h5,
.wp-block-cover__inner-container h6,
.wp-block-cover__inner-container p {
  color: #fff;
}
.wp-block-cover .has-background-dim          { background-color: #000; opacity: 0.5; }
.wp-block-cover .has-background-dim-10       { opacity: 0.1; }
.wp-block-cover .has-background-dim-20       { opacity: 0.2; }
.wp-block-cover .has-background-dim-30       { opacity: 0.3; }
.wp-block-cover .has-background-dim-40       { opacity: 0.4; }
.wp-block-cover .has-background-dim-50       { opacity: 0.5; }
.wp-block-cover .has-background-dim-60       { opacity: 0.6; }
.wp-block-cover .has-background-dim-70       { opacity: 0.7; }
.wp-block-cover .has-background-dim-80       { opacity: 0.8; }
.wp-block-cover .has-background-dim-90       { opacity: 0.9; }
.wp-block-cover .has-background-dim-100      { opacity: 1; }

/* ── Media & Text ─────────────────────────────────────────────────────── */

.wp-block-media-text {
  display: grid;
  grid-template-columns: 1fr 1fr;
  /* 세로 정렬 기본 = **WP 코어 기본(center)**. 2026-09-18 엔 start 로 바꿨지만
   * 그건 데이터가 없던 시절의 임시값이었고, 캔버스는 계속 가운데를 그려
   * "디자인 패널은 middle 인데 WP 프리뷰만 상단" 이 됐다 (2026-09-24 p29-b85).
   * 이제 세로 정렬은 패널 속성(native verticalAlignment)이므로 상단이 필요한
   * 섹션은 데이터로 지정한다 — 기본은 코어와 같게 둔다. */
  align-items: center;
  gap: 2em;
  box-sizing: border-box;
}
/* 자식에 align-self 가 명시돼 있으면 부모의 align-items 는 무시된다 —
 * 그래서 기본값도 **자식 쪽에** 준다 (2026-09-18 실측: 부모만 start 로
 * 바꿔도 media/content 의 align-self 가 center 로 남아 그대로였다). */
.wp-block-media-text > .wp-block-media-text__media,
.wp-block-media-text > .wp-block-media-text__content { align-self: center; }
/* grid 아이템 기본 min-width:auto 는 "콘텐츠보다 작아지지 않는다" 라서, 사진이
 * 최소높이×종횡비로 계산한 폭(예: 440px × 4/3 = 586.66px)이 자기 컬럼(45% =
 * 513px)보다 크면 **트랙을 밀어내 레이아웃 폭 밖으로 튀어나간다**
 * (2026-09-24 p29-b85 실측: 밴드 우변 1290px 인데 사진 우변 1366px).
 * min-width:0 으로 트랙 폭이 정본이 되게 한다 — 사진은 object-fit 으로 크롭. */
.wp-block-media-text > .wp-block-media-text__media,
.wp-block-media-text > .wp-block-media-text__content { min-width: 0; }
/* 블록에 지정된 세로 정렬이 있으면 그것이 정본 (WP 코어 클래스, 특이도 0,3,0). */
.wp-block-media-text.is-vertically-aligned-top > .wp-block-media-text__media,
.wp-block-media-text.is-vertically-aligned-top > .wp-block-media-text__content { align-self: start; }
.wp-block-media-text.is-vertically-aligned-center > .wp-block-media-text__media,
.wp-block-media-text.is-vertically-aligned-center > .wp-block-media-text__content { align-self: center; }
.wp-block-media-text.is-vertically-aligned-bottom > .wp-block-media-text__media,
.wp-block-media-text.is-vertically-aligned-bottom > .wp-block-media-text__content { align-self: end; }
.wp-block-media-text:not(.has-media-on-the-right) { grid-template-areas: "media content"; }
.wp-block-media-text.has-media-on-the-right       { grid-template-areas: "content media"; }
.wp-block-media-text__media {
  grid-area: media;
  margin: 0;
  /* Match the canvas ImageSlot's aspect="4-3" so what the operator
   * sees in the builder is what the live page renders. AI inner-variant
   * images are 1024x1024 (1:1); object-fit: cover crops them into the
   * 4:3 frame instead of letting the figure expand to the intrinsic
   * ratio (which produced the canvas-vs-site mismatch on Korus). */
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.wp-block-media-text__content { grid-area: content; word-break: break-word; }
.wp-block-media-text__media img,
.wp-block-media-text__media video {
  width: 100%;
  /* 높이 정본은 --dwwp-img-h 한 곳 — assets/editor.css 가 편집기의 인라인
   * height:auto 를 무력화할 때 값을 새로 쓰지 않고 이 변수를 다시 읽는다. */
  --dwwp-img-h: 100%;
  height: var(--dwwp-img-h);
  object-fit: cover;
  vertical-align: middle;
}
.wp-block-media-text__media .wp-block-image {
  margin: 0;
  height: 100%;
  /* WP 코어는 .wp-block-image 를 display:table + width:fit-content 로 만들어
   * intrinsic 이미지 폭으로 줄어듦 → media-text 이미지마다 크기가 제각각으로
   * 보이는 원인. 4:3 컨테이너를 항상 꽉 채우도록 block/100% 강제 (2026-07-06
   * 사용자: "이미지 사이즈가 다 달라, 기본 4:3"). */
  width: 100%;
  display: block;
}

@media (max-width: 600px) {
  .wp-block-media-text.is-stacked-on-mobile {
    grid-template-columns: 1fr;
    grid-template-areas: "media" "content";
  }
  .wp-block-media-text.is-stacked-on-mobile.has-media-on-the-right {
    grid-template-areas: "media" "content";
  }
  /* 세로로 쌓이면 코어의 좌우 8% 패딩(`.wp-block-media-text > .__content`)이
   * 글만 안쪽으로 밀어 사진과 좌우선이 어긋나고 글줄이 눌린다
   * (2026-09-19 라이브 실측 390px: 사진 L=48 · 글 L=72, 글줄 폭 207px).
   * 쌓였을 땐 사진과 같은 좌우선에 맞춘다 — 가로 배치일 땐 그 8% 가 두 칸
   * 사이 간격이므로 건드리지 않는다. 특이성 (0,3,0) 으로 코어 (0,2,0) 를
   * 이기므로 !important 불필요. */
  .wp-block-media-text.is-stacked-on-mobile > .wp-block-media-text__content {
    padding-left: 0;
    padding-right: 0;
  }
}

/* ── Text+Image dark card (pattern: text-image-dark-card) ─────────────── */
/* 라운드 다크 카드 그룹 안의 media-text. 카드의 배경/글자색·radius·padding 은
 * native attrs (backgroundColor/textColor slug + style.border/spacing) 가 정본 —
 * 여기는 카드 내부 요소의 패턴 시각 정체성(이미지 라운드, 아이브로우 색,
 * 본문 muted)만 담당한다. */
.wp-block-group.dw-darkcard-media { overflow: hidden; }
/* 원본(Team Logix Proven) 실측 비율 — imgph--dark min-height 250px · 폭 ~525px
 * ≈ 21/10. 기본 media-text 4:3 이면 이미지가 원본보다 세로로 길어진다. */
.dw-darkcard-media .wp-block-media-text__media { border-radius: 18px; aspect-ratio: 21 / 10; }
.dw-darkcard-media .is-style-overline { color: var(--wp--preset--color--accent, currentColor); }
.dw-darkcard-media .wp-block-media-text__content > p:not(.is-style-overline) { opacity: 0.85; }
/* ⇄N 미디어 박스 실측 이관 — blockOptions(mediaBorderWidth/Color/Radius/MinHeight)
 * → 런타임 var. 패턴 기본(위 18px/21:10)보다 뒤에 둬 이관값이 이긴다
 * (2026-09-06 사용자: 이미지 Border Color/Size·Height 미이관). */
.dwwp-media-box .wp-block-media-text__media {
  border: var(--dwwp-media-border-width, 0px) solid var(--dwwp-media-border-color, transparent);
  border-radius: var(--dwwp-media-radius, 18px);
  min-height: var(--dwwp-media-minh, auto);
}
.dwwp-media-box .wp-block-media-text__media img {
  border-radius: inherit;
  --dwwp-img-h: 100%;
  height: var(--dwwp-img-h);
  object-fit: cover;
}

/* ── text-chips-card (⇄N 승격 3호, Team Logix 인트로 실측 2026-09-06) ──
 * 좌 텍스트(eyebrow/제목/본문) + 우 칩 카드. 카드 = line 보더 + accent 상단
 * 3px + radius 16 + padding 28 (.dwwp-v4-chipcard 실측). 칩 = pill
 * (13.5px/600/ink, surface 배경, line 보더, radius 100, 7px 14px).
 * 전부 토큰 참조 — 팔레트 변경 즉시 반영. 커스텀 값 게이트(:not) 유지. */
.dw-chipcard {
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-top: 3px solid var(--wp--preset--color--accent, var(--wp--preset--color--primary, currentColor));
  border-radius: 16px;
}
/* ↑ 위 선언 중 일부는 전역 토큰 규칙과 **특이성 동점**(둘 다 0,1,0)이라 문서
 * 순서로만 이기고 있었다. 프런트는 blocks.css 가 global styles 뒤에 실려
 * 이겼지만, 구텐베르크 편집기는 순서가 반대라 이 선언들만 죽었다
 * (2026-09-19 실측: 6개 페이지 전수 비교로 확인).
 *   :root :where(.wp-block-group){padding-block:80px}
 *   :root :where(.is-layout-flow) > *{margin-block:0}
 * 요소 선택자 한 칸(0,1,1)만 올리면 순서와 무관하게 패턴 기본이 토큰을 이기고,
 * 기존 (0,2,0) 오버라이드들과의 관계는 그대로다. 값은 여기 한 번만 쓴다. */
:is(div, section).dw-chipcard { padding: 28px; }
/* 선택자에 .wp-block-list 를 함께 둔다 — 범용 `ul.wp-block-list` 규칙과
 * **특이성이 같아** 문서 뒤에 오는 그쪽의 들여쓰기(24px)가 이기던 문제
 * (2026-09-16 실측: 칩이 카드 안에서 24px 밀림. 캔버스엔 해당 규칙이 없어
 * WP 에서만 보였다). 값을 새로 만드는 게 아니라 원래 선언을 먹게 하는 것. */

/* 칩 = 가로로 늘어선 알약 라벨. **리스트가 아니다** — 원본 디자인도
 * `div.dwwp-v4-chips > p.dwwp-v4-chip` 이었다. core/list 로 만들면 문자열
 * 배열(values)이라 리치 텍스트 경로를 안 타 HTML 엔티티가 새고, 범용
 * `.wp-block-list` 규칙(들여쓰기/마커)이 따라붙으며, 칩을 개별 블록으로
 * 선택·편집할 수도 없다 (2026-09-16 사용자 지적). 구조를 원본과 맞춘다.
 * 구 블록(ul.is-style-chips)용 규칙은 아래에 그대로 둔다. */
.dwwp-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 14px 0 0;
  padding: 0;
}
.dwwp-chips > p,
.dwwp-chip {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--wp--preset--color--foreground, currentColor);
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 100px;
  padding: 7px 14px;
  margin: 0;
}

ul.is-style-chips,
ul.wp-block-list.is-style-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  list-style: none;
  padding-left: 0;
  padding-inline-start: 0;
  margin: 14px 0 0;
}
ul.is-style-chips > li {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.4;
  color: var(--wp--preset--color--foreground, currentColor);
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 100px;
  padding: 7px 14px;
}
ul.is-style-chips > li::marker { content: ""; }

/* ── hero-split-badge (⇄N 승격 4호, Team Logix 히어로 실측 2026-09-06) ──
 * 좌 텍스트(2색 h1 은 has-inline-color mark = WP 네이티브) + 우 이미지 위
 * 플로팅 배지 카드. 미디어 박스 값은 --dwwp-media-* var(이관) 우선, 기본은
 * 실측값(min-h 440 · radius 18 · 얇은 흰 보더). */
/* 편집기-안전 구현 (2026-09-06 실측): 구텐베르크 편집기는 블록 사이에 래퍼
 * DOM 을 끼워 넣어 `>` 직계 선택자와 absolute-fill 이 깨진다 (배지가 엉뚱한
 * 위치로). → 이미지는 고정 높이+cover(flow), 배지는 negative margin 으로
 * 끌어올림(flow 기반이라 DOM 중첩 무관). !important = WP is-layout-flow 가
 * 자식 margin 을 0/gap 으로 덮는 것 방지 (feedback_wp_layout_zeroes_margins). */
.dw-hero-media {
  position: relative;
  overflow: visible;
  border-radius: var(--dwwp-media-radius, 18px);
}
/* 전역 토큰 :root :where(.wp-block-group){padding-block:80px} 무력화 — 이건
 * 최상위 섹션 그룹용인데 패턴 스킨 안쪽 그룹까지 먹어 사진이 80px 내려갔다
 * (2026-09-19 라이브 실측: p29-b10 pt/pb 80, 그래서 라이브만 세로 정렬 어긋남).
 * 캔버스·api-preview 엔 이 전역 레이어가 없어 정상이던 4벌 격차 —
 * 중첩 그룹 스킨은 이 opt-out 필수 (.dw-service-split/.dw-cfc 와 같은 관례).
 * 토큰과 동점(0,1,0)이면 순서로만 이겨 편집기에서 또 지므로 요소 한 칸 올린다. */
:is(div, section).dw-hero-media { padding-block: 0; }
.dw-hero-media .wp-block-image { margin: 0; border: none; }
/* 특이성 (0,2,1) — 뒤에 오는 범용 .wp-block-image img{height:auto} 가 동일
 * 특이성으로 크롭을 무효화하던 실측 (2026-09-06: 프리뷰 원본비율 691px). */
.dw-hero-media .wp-block-image img,
.dw-hero-media img {
  width: 100%;
  --dwwp-img-h: var(--dwwp-media-minh, 440px);
  height: var(--dwwp-img-h);
  object-fit: cover;
  display: block;
  max-width: none;
  border-radius: var(--dwwp-media-radius, 18px);
  border: var(--dwwp-media-border-width, 1px) solid var(--dwwp-media-border-color, rgba(255,255,255,0.12));
}
.dw-hero-badge {
  position: relative;
  z-index: 1;
  /* block-level flex — inline-flex 는 인라인 라인박스에 얹혀 마진 기준점이
   * 92px 밀리던 실측 (2026-09-06 프리뷰: 배지가 이미지 아래로). */
  display: flex;
  width: fit-content;
  flex-direction: column;
  gap: 2px;
  background: var(--wp--preset--color--background, transparent);
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 14px;
  box-shadow: 0 14px 34px rgba(20, 30, 60, .18);
}
/* ↑ 위 선언 중 일부는 전역 토큰 규칙과 **특이성 동점**(둘 다 0,1,0)이라 문서
 * 순서로만 이기고 있었다. 프런트는 blocks.css 가 global styles 뒤에 실려
 * 이겼지만, 구텐베르크 편집기는 순서가 반대라 이 선언들만 죽었다
 * (2026-09-19 실측: 6개 페이지 전수 비교로 확인).
 *   :root :where(.wp-block-group){padding-block:80px}
 *   :root :where(.is-layout-flow) > *{margin-block:0}
 * 요소 선택자 한 칸(0,1,1)만 올리면 순서와 무관하게 패턴 기본이 토큰을 이기고,
 * 기존 (0,2,0) 오버라이드들과의 관계는 그대로다. 값은 여기 한 번만 쓴다. */
:is(div, section).dw-hero-badge { padding: 14px 18px; }
/* 배지 위치 = 섹션 속성 badgeOffsetX/Y (패턴 기본 -24/-104, 패널에서 변경).
 * 예전엔 `margin:-104px 0 0 -24px !important` 로 강제해 속성이 먹지 않았다
 * (2026-09-22). 그 !important 가 실제로 덮고 있던 건 이 파일의
 * `.wp-block-group.is-layout-flow > * { margin-block: 0 }` (0,2,0) 이었다 —
 * 배지는 .dw-hero-media 의 직계라 (0,2,1) 로 구조를 써서 이긴다. 배지 요소에
 * 직접 준 margin(인라인 속성)은 이 규칙도 이긴다. */
/* 폴백 값은 **패턴 기본값과 같은 수**여야 한다 (test_hero_badge_offsets 가 강제).
 * var 에 폴백이 없으면 값이 안 실렸을 때 선언 전체가 무효가 돼 배지가 이미지
 * 아래로 떨어진다 — 실제로 p29-b01 이 그랬다 (2026-09-24). 패널/데이터가 값을
 * 주면 그 값이 이긴다. */
.dw-hero-media > :is(div, section).dw-hero-badge {
  margin: var(--dwwp-badge-y, -104px) 0 0 var(--dwwp-badge-x, -24px);
}
.dw-hero-badge p { margin: 0; }
/* 배지 부제 간격 — 예전 `!important` 가 덮던 대상은 flow 0,2,0 규칙. 구조
 * 선택자(0,2,2)로 이기고, 문단에 직접 준 margin(인라인 속성)은 이 규칙을 이긴다. */
.dw-hero-media .dw-hero-badge > p + p { margin-top: .15em; }
.dw-hero-badge p:first-child {
  font-size: 13.5px;
  font-weight: 800;
  color: var(--wp--preset--color--foreground, currentColor);
}
.dw-hero-badge p + p {
  font-size: 11.5px;
  font-weight: 600;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
}
@media (max-width: 781px) {
  .dw-hero-media > :is(div, section).dw-hero-badge { margin: var(--dwwp-badge-y-m) 0 0 0; }
  /* 모바일 사진 높이 = 섹션 속성 mediaMinHeightMobile (기본 230 = MEDIA_BOX_DEFAULTS).
   * 예전 230px 고정은 속성을 무시했고 캔버스와도 달랐다 (2026-09-22). */
  .dw-hero-media .wp-block-image img,
  .dw-hero-media img { --dwwp-img-h: var(--dwwp-media-minh-m, 230px); height: var(--dwwp-img-h); }
}

/* ── 본문(lead) 폭 이관 — ⇄N 이 실측한 max-width(--dwwp-lead-max var).
 * 문단 인라인 width 는 validator 미정합이라 클래스+var 경로 (2026-09-06). */
/* 폭 = 섹션 속성(leadMaxWidth). 비우면 콘텐츠 폭 — 예전 560px 폴백은 속성을
 * 지워도 560 이 남아 캔버스(제한 없음)와 갈라졌다 (2026-09-22). 클래스는 발행기가
 * 속성이 있을 때 본문 문단에 붙인다(gutenberg._normalize_section_options).
 * 둘째 선택자(0,2,1): 문단이 constrained 그룹의 직계(hero-text)면 레이아웃 규칙
 * `.wp-block-group.is-layout-constrained > *`(0,2,0)가 p.dw-lead(0,1,1)를 이겨
 * 속성이 무반응이었다 (2026-09-22 실측 p30-b169: 300px 줘도 1244px). */
p.dw-lead,
.is-layout-constrained > p.dw-lead { max-width: var(--dwwp-lead-max, var(--wp--style--global--content-size, 100%)); }
/* 폭이 제한된 텍스트(패널 Width % → .dwwp-sized / ⇄N lead 폭 → .dw-lead)의 가로 위치 =
 * 자기 정렬을 따른다 — 캔버스와 같은 규칙. WP constrained 는 폭 제한 자식을 무조건
 * 가운데(auto !important)에 두어 왼쪽 정렬 제목(60%)이 가운데 박스로 뜨고, 옛 dw-lead
 * 규칙은 이미 사라진 --dwwp-band-content 에 기대 밴드 가장자리에 붙었다 (2026-09-24
 * p40-b54 실측: 제목 x=318 / lead x=48, 캔버스는 둘 다 콘텐츠 왼쪽). 코어가
 * !important 인 자리라 같은 무기 — 허용 예외. 폭 제한이 없는 요소엔 무해. */
/* 왼쪽/오른쪽 = **콘텐츠 상자** 가장자리 (부모 폭 − 사이트 콘텐츠 폭)/2 — 다른 constrained
 * 자식(전폭 제목 등)의 auto 마진과 같은 값. margin 0 은 밴드 패딩 가장자리라 넓은 화면에서
 * lead 만 제목보다 왼쪽으로 튀어나온다 (2026-09-24 Industries hero 스크린샷: 제목 x=163,
 * lead x=48). --wp--style--global--content-size 는 WP 코어(theme.json layout)·프리뷰가 정의. */
:is(h1, h2, h3, h4, h5, h6, p):is(.dwwp-sized, .dw-lead).has-text-align-left {
  margin-left: max(0px, calc((100% - var(--wp--style--global--content-size, 100%)) / 2)) !important;
  margin-right: auto !important;
}
:is(h1, h2, h3, h4, h5, h6, p):is(.dwwp-sized, .dw-lead).has-text-align-center {
  margin-left: auto !important;
  margin-right: auto !important;
}
:is(h1, h2, h3, h4, h5, h6, p):is(.dwwp-sized, .dw-lead).has-text-align-right {
  margin-left: auto !important;
  margin-right: max(0px, calc((100% - var(--wp--style--global--content-size, 100%)) / 2)) !important;
}

/* ── features-service-split (⇄N 승격 5호, p30 서비스 섹션 실측 2026-09-06) ──
 * 좌(넘버 eyebrow·제목·본문·사진) + 우(보더 카드 세로 리스트).
 * 실측: grid .85fr/1.15fr gap 56 · 카드 gap 12 · bordcard(흰 배경, line 보더,
 * radius 14, padding 22 24) · 미디어 min-h 210 — 전부 토큰/var 참조. */
.dw-service-split {
  display: grid;
  grid-template-columns: .85fr 1.15fr;
  gap: 56px;
  align-items: start;
}
/* constrained 자식 auto 마진/폭 제약 해제 — grid 셀을 그대로 채움 */
.dw-service-split > * {
  max-width: none;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* 라이브/편집기 전역 :where(.wp-block-group){padding:80px 0} 무력화 —
 * 좌 lead 그룹·미디어 그룹이 80px 씩 밀려 top 정렬 파괴 + 본문↔이미지
 * 벌어짐 (2026-09-06 라이브 실측: lead pt 80, dw-svc-media pt/pb 80).
 * 캔버스·api-preview 엔 이 전역 레이어가 없어 정상이던 4벌 격차 —
 * 중첩 그룹 스킨은 이 opt-out 필수 (§dwwp global group padding). */
.dw-service-split .wp-block-group {
  padding-block: 0;
}
/* 전체 너비(align full) 밴드 — 배경은 전폭, grid 콘텐츠는 콘텐츠 폭으로
 * 중앙 (2026-09-06 b198 실측: 스킨이 grid 라 constrained 자식 중앙화가
 * 적용되지 않아 제목이 화면 왼쪽 끝(x=0)까지 퍼짐). fr 대신 콘텐츠폭
 * 기반 고정 트랙(.85:1.15 = 42.5:57.5, gap 56 제외) + justify center —
 * 인라인 좌우 패딩(변환 캐리 0px)과 충돌 없음. */
.dw-service-split.alignfull:not(.dwwp-full-content) {
  --dwwp-svc-content: var(--dwwp-band-content, var(--wp--style--global--content-size, 100%));
  grid-template-columns:
    minmax(0, calc((var(--dwwp-svc-content) - 56px) * 0.425))
    minmax(0, calc((var(--dwwp-svc-content) - 56px) * 0.575));
  justify-content: center;
}
/* 전체 너비(내용까지) — bo fullContent: group 밴드의 constrained 자식
 * 중앙화를 해제해 내용도 전폭 (섹션 너비 3종의 ③). */
.wp-block-group.alignfull.dwwp-full-content > :where(:not(.alignfull)) {
  max-width: none !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
.dw-service-split .wp-block-columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}
/* 카드 값 = 섹션 속성(카드 배경/테두리 두께·색/모서리/패딩). 예전엔 숫자를 박아
 * 패널에서 바꿔도 적용되지 않았다 (2026-09-22 섹션별 실측: p30 서비스 카드 5속성
 * 미적용). 괄호 안 값은 속성이 비었을 때의 패턴 기본 — 캔버스 cardBox() 와 동일. */
.wp-block-column.dw-svc-card {
  background: var(--dwwp-card-bg, var(--wp--preset--color--background, transparent));
  border: var(--dwwp-card-border-width, 1px) solid var(--dwwp-card-border-color, var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)));
  border-radius: var(--dwwp-card-radius, 14px);
  padding: var(--dwwp-card-padding, 22px 24px);
}
.dw-svc-media {
  position: relative;
  overflow: hidden;
  border-radius: var(--dwwp-media-radius, 18px);
}
/* 사진 위 여백 = 섹션 속성 mediaGap (--dwwp-media-gap, 기본 22 = MEDIA_BOX_DEFAULTS.gap).
 * 구조 선택자(0,3,0) — WP 가 문서에 인라인으로 찍는 `:root :where(.is-layout-flow) > *
 * {margin-block:0}` 와 테마의 `.wp-block-group.is-layout-flow > *`(0,2,0) 리셋이 같은
 * 특이성의 `.dw-svc-media{margin-top}` 를 순서로 이겨 라이브만 0 이었다
 * (2026-09-24 p30-b07 실측: 캔버스 23 / WP 프리뷰 22 / 라이브 0). !important 금지. */
.dw-service-split .dw-service-split__lead > .dw-svc-media {
  margin-top: var(--dwwp-media-gap, 22px);
}
.dw-svc-media .wp-block-image { margin: 0; border: none; }
/* 이미지 자체 비율(패널 "비율" → img 인라인 aspect-ratio)이 있으면 패턴 높이
 * (--dwwp-img-h)를 양보한다 — 명시 height 가 있으면 aspect-ratio 는 무시되므로.
 * 커스텀 > 패턴 기본 (2026-09-25 p32-b02). 특이성 (0,3,1) > 아래 (0,2,1). */
.dw-hero-media .wp-block-image img[style*="aspect-ratio"],
.dw-hero-media img[style*="aspect-ratio"],
.dw-svc-media .wp-block-image img[style*="aspect-ratio"],
.dw-svc-media img[style*="aspect-ratio"] {
  height: auto;
}
.dw-svc-media .wp-block-image img,
.dw-svc-media img {
  width: 100%;
  --dwwp-img-h: var(--dwwp-media-minh, 210px);
  height: var(--dwwp-img-h);
  object-fit: cover;
  display: block;
  max-width: none;
  border-radius: var(--dwwp-media-radius, 18px);
  border: var(--dwwp-media-border-width, 1px) solid var(--dwwp-media-border-color, rgba(255,255,255,0.12));
}
@media (max-width: 781px) {
  /* 전체 너비 밴드 규칙(.alignfull:not(...), 특이성 0,3,0)과 같은 선택자를 둬야
   * 이긴다 — 예전엔 0,2,0 이라 전폭 섹션만 모바일에서 2칸(179px)으로 남았다
   * (2026-09-22 p30-b198 실측). */
  .dw-service-split,
  .dw-service-split.alignfull:not(.dwwp-full-content) { grid-template-columns: minmax(0, 1fr); gap: 32px; }
  /* 모바일 좌우 여백은 섹션 속성 '좌우 여백 — 모바일'(padInlineMobile, 기본 =
   * 루트 여백 토큰)이 정한다 (.dwwp-rpad, 1.5.142). 예전 24px !important 강제는
   * 속성을 무력화해서 삭제 (2026-09-22). */
  /* 모바일 사진 높이 = 섹션 속성 mediaMinHeightMobile (기본 200 = MEDIA_BOX_DEFAULTS).
   * 예전 200px 고정은 속성을 무시했고 캔버스와도 달랐다 (2026-09-22). */
  .dw-svc-media .wp-block-image img,
  .dw-svc-media img { --dwwp-img-h: var(--dwwp-media-minh-m, 200px); height: var(--dwwp-img-h); }
}

/* ── Image / figure ───────────────────────────────────────────────────── */

.wp-block-image {
  margin: 0 0 1em;
  box-sizing: border-box;
}
.wp-block-image img {
  max-width: 100%;
  height: auto;
  vertical-align: middle;
}
.wp-block-image figcaption {
  margin-top: 0.5em;
  font-size: 0.9em;
  text-align: center;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
}


/* 팔레트 slug 'text'/'border' ↔ WP 마커 클래스(has-text-color/has-border-color)
 * 이름 충돌은 **발행 이름을 바꿔 근본 해소**했다 (2026-09-22, app/services/wp_names:
 * text→foreground, border→outline). 예전 이 자리의 `.has-text-color.has-*-color
 * {…!important}` 복원 규칙 17줄은 삭제 — WP 가 만드는 팔레트 클래스가 그대로 맞고,
 * 특히 `.has-text-color.has-border-color` 는 개명 후엔 "글자색+테두리색 둘 다 준
 * 블록" 의 글자를 테두리색으로 칠하는 오작동이 된다. */

/* ── Headings ─────────────────────────────────────────────────────────── */

.wp-block-heading {
  font-family: var(--wp--preset--font-family--heading, inherit);
  line-height: 1.2;
  /* 색을 여기서 직접 지정하지 않는다 (2026-07-15 근본 수정) — 직접 지정은
   * 다크 섹션(.has-*-background-color)의 흰 글자 "상속"을 항상 이겨서, 어두운
   * 배경 위 제목이 어두운 색으로 렌더되던 사고의 원인. 기본 어두운 글자색은
   * WP global styles(body color)에서 상속받고, 명시 색은 has-*-color 클래스가
   * 담당한다 (WP native 색 체계 존중). */
  color: inherit;
}
/* 제목 상/하 여백은 전역 토큰 규칙과 **특이성 동점**(둘 다 0,1,0)이라 문서
 * 순서로만 이기고 있었다. 프런트는 blocks.css 가 global styles 뒤에 실려
 * 이겼지만, 구텐베르크 편집기는 순서가 반대라 이 선언들만 죽었다
 * (2026-09-19 실측: 6개 페이지 전수 비교로 확인).
 *   :root :where(.wp-block-group){padding-block:80px}
 *   :root :where(.is-layout-flow) > *{margin-block:0}
 * 요소 선택자 한 칸(0,1,1)만 올리면 순서와 무관하게 패턴 기본이 토큰을 이기고,
 * 기존 (0,2,0) 오버라이드들과의 관계는 그대로다. 값은 여기 한 번만 쓴다. */
:is(h1, h2, h3, h4, h5, h6).wp-block-heading {
  margin-top: 0;
  margin-bottom: 0.6em;
}

/* Context-aware heading sizes — when a heading lives inside a column or a
 * card-like wrapper, reduce its size so it reads as a card title rather than
 * a page hero. AI-generated content commonly emits h2/h3 in column slots
 * which would otherwise dominate the layout.
 */
.wp-block-column .wp-block-heading,
.wp-block-column h1.wp-block-heading,
.wp-block-column h2.wp-block-heading {
  font-size: clamp(1.25rem, 1.8vw + 0.5rem, 1.75rem);
  line-height: 1.25;
}
.wp-block-column h3.wp-block-heading,
.wp-block-column h4.wp-block-heading {
  font-size: clamp(1.1rem, 1.5vw + 0.4rem, 1.5rem);
}
.wp-block-column h5.wp-block-heading,
.wp-block-column h6.wp-block-heading {
  font-size: 1rem;
}

/* Heading + paragraph rhythm — paragraph following a heading should sit
 * comfortably below it. */
.wp-block-heading + p,
.wp-block-heading + .wp-block-paragraph {
  margin-top: 0;
}

/* ── Paragraph & body ─────────────────────────────────────────────────── */

p {
  margin-top: 0;
  margin-bottom: 1em;
  font-family: var(--wp--preset--font-family--body, inherit);
  line-height: 1.65;
  /* heading 과 동일 — 직접 색 지정 금지, 상속 (2026-07-15 근본 수정). */
  color: inherit;
}

/* ── Lists ────────────────────────────────────────────────────────────── */

.wp-block-list,
ul.wp-block-list,
ol.wp-block-list {
  margin: 0 0 1em;
  padding-left: 1.5em;
}
.wp-block-list li { margin-bottom: 0.35em; }

/* ── Checklist (text-list 섹션) ──────────────────────────────────────────
   플레인 불릿 대신 브랜드색 체크마크 원 + 데스크탑 2열. pattern text-list 의
   group.className = "dwwp-checklist". (2026-07-06 사용자 요청 — 레퍼런스 체크리스트) */
.dwwp-checklist > .wp-block-list,
.dwwp-checklist ul.wp-block-list {
  list-style: none;
  margin: 1.75rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.85rem 2.5rem;
}
@media (min-width: 720px) {
  .dwwp-checklist > .wp-block-list,
  .dwwp-checklist ul.wp-block-list { grid-template-columns: 1fr 1fr; }
}
/* media-text(about-section) 안의 체크리스트는 콘텐츠 반쪽 폭이라 1열 유지. */
.wp-block-media-text.dwwp-checklist .wp-block-list {
  grid-template-columns: 1fr !important;
  margin-top: 1rem;
}

/* ── Stats split (이미지 + 2×2 통계) — pattern stats-split ──────────────── */
.dwwp-stats-split .dwwp-stats-split__grid {
  display: grid !important;
  grid-template-columns: 1fr 1fr;
  gap: 1.75rem 2rem;
  margin-top: 1.5rem;
}
.dwwp-stats-split .dwwp-stats-split__grid > .wp-block-column {
  flex-basis: auto !important;
  margin: 0 !important;
}
.dwwp-stats-split .dwwp-stats-split__grid h1,
.dwwp-stats-split .dwwp-stats-split__grid h2,
.dwwp-stats-split .dwwp-stats-split__grid h3 {
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 1;
  margin: 0 0 0.3rem;
  color: var(--wp--preset--color--primary, currentColor);
  font-weight: 800;
}
.dwwp-stats-split .dwwp-stats-split__grid p {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.4;
  opacity: 0.75;
}

/* ── 첫 카드 강조 (features-highlight, 레퍼런스 ①) ───────────────────────
   blockOptions.highlightFirst → 첫 카드만 primary 배경 + 흰 글씨. */
.dwwp-highlight-first .wp-block-columns > .wp-block-column:first-child {
  background: var(--wp--preset--color--primary, currentColor);
  border-radius: 16px;
  padding: 1.9rem 1.6rem;
}
.dwwp-highlight-first .wp-block-columns > .wp-block-column:first-child,
.dwwp-highlight-first .wp-block-columns > .wp-block-column:first-child :where(h1, h2, h3, h4, h5, h6, p, a, li) {
  color: #fff !important;
}
.dwwp-highlight-first .wp-block-columns > .wp-block-column:first-child .dwwp-icon,
.dwwp-highlight-first .wp-block-columns > .wp-block-column:first-child svg {
  color: #fff;
}
.dwwp-checklist > .wp-block-list > li,
.dwwp-checklist ul.wp-block-list > li {
  position: relative;
  list-style: none;
  margin: 0;
  padding-left: 2.1rem;
  line-height: 1.5;
}
.dwwp-checklist > .wp-block-list > li::before,
.dwwp-checklist ul.wp-block-list > li::before {
  content: "\2713"; /* ✓ */
  position: absolute;
  left: 0;
  top: 0.05em;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 50%;
  background: var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor));
  color: #fff;
  font-size: 0.82rem;
  line-height: 1.4rem;
  text-align: center;
  font-weight: 700;
  flex: 0 0 auto;
}
/* 아이콘 색 (Properties 패널 SectionListStyle) — dwwp-check-{slug} → CSS 변수. */
.dwwp-check-primary { --dwwp-check-color: var(--wp--preset--color--primary, currentColor); }
.dwwp-check-secondary { --dwwp-check-color: var(--wp--preset--color--secondary, currentColor); }
.dwwp-check-accent { --dwwp-check-color: var(--wp--preset--color--accent, currentColor); }
.dwwp-check-text { --dwwp-check-color: var(--wp--preset--color--foreground, currentColor); }
.dwwp-check-muted { --dwwp-check-color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent)); }
.dwwp-check-background { --dwwp-check-color: var(--wp--preset--color--background, transparent); }
.dwwp-check-border { --dwwp-check-color: var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)); }
/* 아이콘 모양 변형 (Properties 패널 SectionListStyle) — 기본 체크 위에 override. */
.dwwp-checklist.dwwp-list-dot > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-dot ul.wp-block-list > li::before {
  content: ""; width: 0.55rem; height: 0.55rem; top: 0.5em; left: 0.45rem;
}
.dwwp-checklist.dwwp-list-dash > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-dash ul.wp-block-list > li::before {
  content: "\2013"; background: transparent; border-radius: 0;
  color: var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor)); font-size: 1.2rem;
}
.dwwp-checklist.dwwp-list-none > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-none ul.wp-block-list > li::before { display: none; }
.dwwp-checklist.dwwp-list-none > .wp-block-list > li,
.dwwp-checklist.dwwp-list-none ul.wp-block-list > li { padding-left: 0; }
/* 아이콘 모양 추가 (2026-07-14 사용자: 아이콘 셋에서 선택) — glyph 계열은
 * dash 와 동일하게 배경 없는 색 글리프. */
.dwwp-checklist.dwwp-list-arrow > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-arrow ul.wp-block-list > li::before {
  content: "\2192"; background: transparent; border-radius: 0;
  color: var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor)); font-size: 1.05rem;
}
.dwwp-checklist.dwwp-list-chevron > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-chevron ul.wp-block-list > li::before {
  content: "\203A"; background: transparent; border-radius: 0;
  color: var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor)); font-size: 1.3rem; top: -0.08em;
}
.dwwp-checklist.dwwp-list-star > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-star ul.wp-block-list > li::before {
  content: "\2605"; background: transparent; border-radius: 0;
  color: var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor)); font-size: 0.95rem;
}
/* 리스트 lucide 마커 (2026-07-15) — dwwp-list-lucide-{name} 클래스 + PHP 렌더
 * 필터가 주입한 --dwwp-list-mask(data URI). 타일 배경 = 기존 체크 원형과 동일
 * (--dwwp-check-color 시스템), 아이콘 = 마스크로 색칠. */
.dwwp-checklist[class*="dwwp-list-lucide-"] > .wp-block-list > li::before,
.dwwp-checklist[class*="dwwp-list-lucide-"] ul.wp-block-list > li::before {
  content: "";
  background: color-mix(in srgb, var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor)) 12%, transparent);
  color: transparent;
}
.dwwp-checklist[class*="dwwp-list-lucide-"] > .wp-block-list > li,
.dwwp-checklist[class*="dwwp-list-lucide-"] ul.wp-block-list > li { position: relative; }
.dwwp-checklist[class*="dwwp-list-lucide-"] > .wp-block-list > li::after,
.dwwp-checklist[class*="dwwp-list-lucide-"] ul.wp-block-list > li::after {
  content: "";
  position: absolute;
  left: 0.3rem;
  top: calc(0.05em + 0.3rem);
  width: 0.8rem;
  height: 0.8rem;
  background: var(--dwwp-check-color, var(--wp--preset--color--primary, currentColor));
  -webkit-mask: var(--dwwp-list-mask) center / contain no-repeat;
  mask: var(--dwwp-list-mask) center / contain no-repeat;
}

/* 들여쓰기 (2026-07-14) — 리스트 전체를 좌측에서 밀어넣기. */
.dwwp-checklist.dwwp-list-indent-1 > .wp-block-list,
.dwwp-checklist.dwwp-list-indent-1 ul.wp-block-list { padding-left: 1.5rem; }
.dwwp-checklist.dwwp-list-indent-2 > .wp-block-list,
.dwwp-checklist.dwwp-list-indent-2 ul.wp-block-list { padding-left: 3rem; }
/* 가운데 정렬 — 2열 grid 를 1열 + 아이콘 inline 중앙. */
.dwwp-checklist.dwwp-list-center ul.wp-block-list { grid-template-columns: 1fr !important; }
.dwwp-checklist.dwwp-list-center > .wp-block-list > li,
.dwwp-checklist.dwwp-list-center ul.wp-block-list > li { text-align: center; padding-left: 0; }
.dwwp-checklist.dwwp-list-center > .wp-block-list > li::before,
.dwwp-checklist.dwwp-list-center ul.wp-block-list > li::before {
  position: static; display: inline-flex; align-items: center; justify-content: center;
  vertical-align: middle; margin-right: 0.4rem;
}

/* ── Quote ────────────────────────────────────────────────────────────── */

.wp-block-quote {
  margin: 0 0 1.5em;
  padding-left: 1em;
  border-left: 4px solid var(--wp--preset--color--accent, currentColor);
  font-style: italic;
}
.wp-block-quote cite {
  display: block;
  margin-top: 0.5em;
  font-size: 0.9em;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
  font-style: normal;
}

/* ── Separator ────────────────────────────────────────────────────────── */

.wp-block-separator {
  border: 0;
  border-bottom: 1px solid currentColor;
  margin: 2em auto;
  opacity: 0.4;
  max-width: 4em;
}
.wp-block-separator.is-style-wide,
.wp-block-separator.alignwide { max-width: var(--wp--style--global--content-size, 100%); }
.wp-block-separator.alignfull { max-width: none; }
.wp-block-separator.has-alpha-channel-opacity { opacity: 1; }
/* 푸터 저작권 위 구분선 (footerContent.copyrightDivider) — 현재 글자색의 은은한 1px 선.
 * 캔버스는 같은 데이터로 border-top(currentColor 25%)을 그린다. */
.wp-block-separator.dw-footer-sep {
  opacity: 0.25;
  margin: 20px auto 14px;
}
/* 전체 폭 (footerContent.copyrightDividerWidth = "full") — 푸터 콘텐츠 상자를 벗어나 뷰포트
 * 끝까지. 섹션 alignfull escape 와 같은 계산(50% − 50vw). 캔버스는 프레임 좌우 패딩만큼 음수 마진. */
.wp-block-separator.dw-footer-sep--full {
  max-width: none;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-right: calc(50% - 50vw);
}

/* ── Spacer ───────────────────────────────────────────────────────────── */

.wp-block-spacer { clear: both; }

/* ── DW Builder nav list (replaces wp:navigation, v1.2.0) ────────────────
 *
 * AI-generated header/footer template-parts use `wp:list` with anchor
 * children instead of `wp:navigation` because the latter requires a
 * wp_navigation CPT post to render reliably; without one, WP marks the
 * inline-children variant as "invalid content" in the block editor and
 * strips hrefs in the rendered output.
 *
 * The list-based markup parses cleanly across all WP versions and themes,
 * survives wp_kses_post(), and renders with proper hrefs. CSS makes it
 * look like a traditional horizontal nav.
 */

.wp-block-list.dw-nav-list,
ul.wp-block-list.dw-nav-list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--dw-nav-gap, 1.5rem); /* 메뉴 사이 간격 — menu typography itemGap (v1.5.48) */
  list-style: none;
  margin: 0;
  padding: 0;
}
.dw-nav-list li {
  margin: 0;
  list-style: none;
}
/* Nav link typography — designSystem.headerMenuTypography → CSS variables
 * emitted on the <header> element. Each var has a sensible fallback so
 * unset values fall back to the surrounding text (color: inherit) or to
 * baseline values defined here. */
.dw-nav-list a {
  color: var(--dw-nav-color, inherit);
  text-decoration: none;
  font-size: var(--dw-nav-font-size, 0.95rem);
  font-weight: var(--dw-nav-font-weight, inherit);
  text-transform: var(--dw-nav-text-transform, none);
  letter-spacing: var(--dw-nav-letter-spacing, normal);
  transition: color 0.15s ease, opacity 0.15s ease;
  white-space: nowrap;
}
.dw-nav-list a:hover {
  /* hoverColor 가 설정돼있으면 그 색으로, 아니면 기존 opacity 효과로 */
  color: var(--dw-nav-hover-color, var(--dw-nav-color, inherit));
  opacity: var(--dw-nav-hover-opacity, 0.7);
}
/* hoverColor 가 명시된 경우엔 opacity 변화는 끄고 색만 바꿈 — 아니면
 * 사용자 의도와 다른 페이드 발생. */
.dw-nav-list a[style*="--dw-nav-hover-color"]:hover,
header[style*="--dw-nav-hover-color"] .dw-nav-list a:hover {
  opacity: 1;
}

/* Centered header — push nav into the row's center axis. */
.dw-nav-centered {
  justify-content: center;
}

/* Minimal header — push nav to the right (header itself is space-between). */
.dw-nav-minimal {
  justify-content: flex-end;
}

/* Transparent header — light text on dark/image backgrounds. */
.dw-nav-transparent a {
  color: #fff;
}

/* Transparent header overlay — 헤더가 아래 첫 섹션(hero) 위로 겹치게.
 * WP block attr 로 position:absolute 표현 불가(sticky/fixed 만) → 클래스가 담당.
 * dw-constrained 헤더도 left/right 0 + max-width + auto 마진으로 그대로 중앙 정렬. */
header.wp-block-group.dw-header-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

/* 푸터 링크 (v1.5.49) — 전역 링크색(primary)이 어두운 푸터 배경과 동색이 되어
 * 링크 글자가 안 보이던 사고 (2026-07-17 라이브 실측: link=bg=#2D3748).
 * 푸터 안 링크는 주변 글자색을 상속하고, 밑줄은 기본 제거(사용자 지시) —
 * hover 에만 표시해 링크임을 알림. 버튼은 제외. */
footer.wp-block-group a:not(.wp-block-button__link) {
  color: inherit;
  text-decoration: none;
}
footer.wp-block-group a:not(.wp-block-button__link):hover {
  text-decoration: underline;
}

/* Vertical orientation — used in footer columns. */
.dw-nav-list.dw-nav-vertical,
ul.wp-block-list.dw-nav-list.dw-nav-vertical {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
}

/* Submenu — proper nested <ul> inside parent <li> (v2.6.6+).
 * Hover dropdown: hide by default, show absolutely-positioned panel under
 * the parent on hover/focus-within. Touch devices fall back to tap-toggle
 * via :focus-within (mobile WP themes typically expand on tap). */
.dw-nav-list li.dw-nav-has-children {
  position: relative;
}
.dw-nav-list li.dw-nav-has-children > a::after {
  content: " ▾";
  font-size: 0.75em;
  opacity: 0.6;
  margin-left: 0.15em;
}
.dw-nav-list .dw-nav-submenu,
.dw-nav-list ul.dw-nav-submenu {
  position: absolute;
  top: 100%;
  left: 0;
  display: none;
  flex-direction: column;
  align-items: flex-start;
  min-width: 200px;
  margin: 0;
  padding: 0.5rem 0;
  list-style: none;
  background: var(--wp--preset--color--background, transparent);
  color: var(--wp--preset--color--foreground, currentColor);
  border: 1px solid var(--wp--preset--color--outline, rgba(0, 0, 0, 0.08));
  border-radius: var(--wp--preset--spacing--radius, 6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
  z-index: 50;
  gap: 0;
}
.dw-nav-list .dw-nav-submenu li {
  width: 100%;
  white-space: nowrap;
}
.dw-nav-list .dw-nav-submenu li a {
  display: block;
  padding: 0.4rem 1rem;
  font-size: 0.92rem;
}
.dw-nav-list .dw-nav-submenu li a:hover {
  background: var(--wp--preset--color--surface, rgba(0, 0, 0, 0.04));
  opacity: 1;
}
.dw-nav-list li.dw-nav-has-children:hover > .dw-nav-submenu,
.dw-nav-list li.dw-nav-has-children:focus-within > .dw-nav-submenu {
  display: flex;
}

/* Vertical orientation (footer) — submenu inline-stacks rather than dropping. */
.dw-nav-list.dw-nav-vertical .dw-nav-submenu,
.dw-nav-list.dw-nav-vertical ul.dw-nav-submenu {
  position: static;
  display: flex;
  border: 0;
  box-shadow: none;
  background: transparent;
  padding-left: 1rem;
  min-width: 0;
}

/* Legacy class kept as no-op for any pages not yet re-synced after upgrade. */
.dw-nav-list li.dw-nav-subitem {
  padding-left: 1rem;
}
.dw-nav-list li.dw-nav-subitem a {
  font-size: 0.88rem;
  opacity: 0.85;
}

/* ── Mobile hamburger (header nav) ──────────────────────────────────────────
 * nav.js 가 헤더 nav 앞에 .dw-nav-burger 버튼을 주입. 데스크탑에선 숨김,
 * 782px 이하에서 버튼 노출 + nav 를 드롭다운 패널로. 색은 currentColor /
 * theme 토큰(var(--wp--preset--color--*)) 참조 — 하드코딩 없음. */
.dw-nav-burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  margin-left: 0.5rem;
  border: 0;
  background: transparent;
  color: var(--dw-nav-color, currentColor);
  cursor: pointer;
}
.dw-nav-burger-light { color: #fff; }
.dw-nav-burger-bars {
  position: relative;
  display: block;
  width: 24px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: background 0.2s ease;
}
.dw-nav-burger-bars::before,
.dw-nav-burger-bars::after {
  content: "";
  position: absolute;
  left: 0;
  width: 24px;
  height: 2px;
  background: currentColor;
  border-radius: 2px;
  transition: transform 0.2s ease;
}
.dw-nav-burger-bars::before { top: -7px; }
.dw-nav-burger-bars::after { top: 7px; }
/* open 상태 → X 아이콘 */
.dw-nav-open .dw-nav-burger-bars { background: transparent; }
.dw-nav-open .dw-nav-burger-bars::before { transform: translateY(7px) rotate(45deg); }
.dw-nav-open .dw-nav-burger-bars::after { transform: translateY(-7px) rotate(-45deg); }

/* Mobile — wrap to multiple rows so nothing overflows. */
@media (max-width: 600px) {
  .dw-nav-list {
    gap: var(--dw-nav-gap, 0.75rem 1rem);
  }
}

@media (max-width: 782px) {
  /* 드롭다운이 헤더 기준으로 위치하도록 */
  header.wp-block-group { position: relative; }

  .dw-nav-burger { display: inline-flex; }

  /* 헤더 nav → 기본 접힘. 햄버거 클릭(.dw-nav-open) 시에만 드롭다운 표시.
   * ⚠️ 특이도 주의 — 기본 규칙 `ul.wp-block-list.dw-nav-list{display:flex}`
   * (0,2,1) 을 이겨야 하므로 여기 선택자도 최소 (0,2,2) 로 올림. 이전엔
   * `header .dw-nav-list`(0,1,1) 라 display:none 이 안 먹어 모바일에서 메뉴가
   * 항상 펼쳐지던 버그 (2026-07-02 사용자 보고). */
  /* 모바일 메뉴 = 우측 슬라이드-인 드로어 (2026-07-15 사용자: 슬라이드 인 +
   * 컴팩트). display 토글 대신 transform 애니메이션 — 항상 flex, 화면 밖 대기. */
  header.wp-block-group .wp-block-list.dw-nav-list {
    display: flex;
    position: fixed;
    top: 0;
    right: 0;
    left: auto;
    height: 100dvh;
    width: min(78vw, 320px);
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    margin: 0;
    padding: 4.5rem 1.5rem 2rem;
    background: var(--wp--preset--color--background, transparent);
    box-shadow: -12px 0 40px rgba(0, 0, 0, 0.18);
    transform: translateX(105%);
    transition: transform 0.28s ease;
    z-index: 100;
    overflow-y: auto;
  }
  header.wp-block-group.dw-nav-open .wp-block-list.dw-nav-list { transform: translateX(0); }
  @media (prefers-reduced-motion: reduce) {
    header.wp-block-group .wp-block-list.dw-nav-list { transition: none; }
  }
  /* 어두운 오버레이 — 드로어 뒤 본문 클릭 시 닫힘 (nav.js 바깥클릭 핸들러). */
  header.wp-block-group.dw-nav-open::after {
    content: "";
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.38);
    z-index: 99;
  }
  /* 드로어 열림 동안 본문 스크롤 잠금 (nav.js 가 토글). */
  html.dw-nav-locked, html.dw-nav-locked body { overflow: hidden; }
  /* 버거 버튼은 오버레이/드로어 위 */
  .dw-nav-burger { position: relative; z-index: 101; }
  /* 컴팩트 모바일 헤더 — 인라인 패딩보다 우선 (모바일 한정 의도적 override). */
  header.wp-block-group.alignfull,
  header.wp-block-group {
    padding-top: 12px !important;
    padding-bottom: 12px !important;
    /* 좌우는 모바일 공통 여백 토큰 — centered 변형(데스크톱 좌우 0)이 모바일에서
     * 로고·버거가 화면 끝에 붙던 것 (2026-09-25 실측 x=0/390). 본문 섹션과 같은 20px. */
    padding-left: var(--dwwp-pad-mobile) !important;
    padding-right: var(--dwwp-pad-mobile) !important;
  }

  /* 드롭다운 링크 — 본문 텍스트 색으로 통일 (transparent 헤더 흰 글자가 밝은
   * 배경서 안 보이던 문제 방지). */
  header.wp-block-group.dw-nav-open .wp-block-list.dw-nav-list a,
  header.wp-block-group .wp-block-list.dw-nav-list.dw-nav-transparent a {
    color: var(--wp--preset--color--foreground, currentColor);
  }
  /* 드로어 링크 풀폭 — **테마 자신의 메뉴 항목에만** 한정(> li:not(.dw-nav-drawer-item)).
   * 이전엔 슬롯 안 플러그인 버튼(dw-easyauth)에도 display:block/width:100% 가 걸려
   * 버튼 정렬·2분할이 깨졌다(dw-easyauth 협의 2026-08-20). 슬롯은 플러그인이 소유. */
  header.wp-block-group .wp-block-list.dw-nav-list > li:not(.dw-nav-drawer-item) a {
    display: block;
    width: 100%;
  }

  /* 드로어 메뉴 항목 표시 디자인 — 3b default (2026-08-13 사용자 확정):
   * 항목마다 하단 구분선 + 넉넉한 터치 패딩 + 중간 굵기. auth 슬롯
   * (.dw-nav-drawer-item)은 자체 스타일이라 제외(구분선/패딩 미적용). */
  header.wp-block-group .wp-block-list.dw-nav-list > li:not(.dw-nav-drawer-item) {
    width: 100%;
    border-bottom: 1px solid var(--wp--preset--color--outline, rgba(0, 0, 0, 0.09));
  }
  /* auth 슬롯(.dw-nav-drawer-item)은 위 :not() 폭 규칙에서 제외돼(구분선/패딩만
   * 제외할 의도였으나 width:100% 도 함께 딸려나감) 세로 flex(align-items:flex-start)
   * 에서 내용 크기로 줄어 버튼 한 쌍이 왼쪽에 몰렸다. 교차축 stretch 로 **슬롯만**
   * 전폭 복구 — 그제서야 플러그인 flex(.dw-ea-nav--block 가로 2분할)가 패널 폭을
   * 받는다. 구분선/패딩 제외는 그대로. (dw-easyauth 협의 2026-08-21, 옵션 a) */
  header.wp-block-group .wp-block-list.dw-nav-list > .dw-nav-drawer-item {
    align-self: stretch;
  }
  header.wp-block-group .wp-block-list.dw-nav-list > li:not(.dw-nav-drawer-item) > a {
    padding: 15px 2px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.3;
    opacity: 1;
  }

  /* 서브메뉴 — 드롭다운 안에서 static 하게 인라인 펼침. */
  header.wp-block-group .wp-block-list.dw-nav-list .dw-nav-submenu {
    position: static;
    display: flex;
    min-width: 0;
    padding: 0 0 0 1rem;
    border: 0;
    box-shadow: none;
    background: transparent;
  }
  header.wp-block-group .wp-block-list.dw-nav-list li.dw-nav-has-children > a::after {
    content: "";
  }
}

/* ── Navigation (legacy wp:navigation, kept for sites already using it) ── */

/* ── 모바일 헤더 행: [로고] … [CTA 버튼] [햄버거] (2026-09-25 사용자 지시: 로고·버튼·햄버거) ──
 * 데스크톱 구조(브랜드 | 우측 클러스터 .dw-header-right{메뉴·검색·CTA·auth})를
 * 모바일에서 한 행으로 편다. nav.js 가 버거를 메뉴(ul) 앞에 주입하므로 버거는
 * 클러스터 안에 있다 → 클러스터를 display:contents 로 풀어 CTA·버거가 행의 직접
 * 항목이 되게 하고 order 로 배치: 로고(1, 왼쪽) · CTA(2, 오른쪽 밀착) · 버거(3, 맨 오른쪽).
 * 메뉴(ul)는 fixed 드로어라 무관. */
@media (max-width: 782px) {
  header.wp-block-group,
  header.wp-block-group > .dw-header-main {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: space-between;
    min-height: 56px;
  }
  header.wp-block-group .wp-block-group.dw-header-right { display: contents; }
  header.wp-block-group .dw-header-brand,
  header.wp-block-group > .dw-header-logo,
  header.wp-block-group > .wp-block-site-title,
  header.wp-block-group > .dw-header-main > .dw-header-logo,
  header.wp-block-group > .dw-header-main > .wp-block-site-title {
    order: 1;
    margin: 0 auto 0 0;
    max-width: 55%;
    min-width: 0;
  }
  /* 범용 .wp-block-buttons{margin-top:1.5em} 가 행 안에서 27px 로 내려앉힘 → 0 */
  header.wp-block-group .dw-header-cta-wrap { order: 2; margin: 0 0 0 auto; }
  header.wp-block-group .dw-header-cta-wrap .wp-block-button__link { white-space: nowrap; }
  /* 검색·auth 클러스터는 CTA 앞(오른쪽 묶음) */
  header.wp-block-group .wp-block-search,
  header.wp-block-group .dw-header-auth { order: 2; }
  header.wp-block-group .dw-nav-burger { order: 3; margin-left: 0.5rem; }
}

.wp-block-navigation {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.wp-block-navigation a,
.wp-block-navigation__container a {
  color: inherit;
  text-decoration: none;
  font-size: 0.95rem;
  transition: opacity 0.15s ease;
}
.wp-block-navigation a:hover { opacity: 0.7; }

/* Submenu */
.wp-block-navigation .wp-block-navigation-submenu {
  position: relative;
}
.wp-block-navigation .wp-block-navigation__submenu-container {
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 200px;
  background: var(--wp--preset--color--background, transparent);
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: var(--wp--preset--spacing--radius, 6px);
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.08);
  padding: 0.5rem 0;
  display: none;
  flex-direction: column;
  z-index: 50;
}
.wp-block-navigation .wp-block-navigation-submenu:hover .wp-block-navigation__submenu-container,
.wp-block-navigation .wp-block-navigation-submenu:focus-within .wp-block-navigation__submenu-container {
  display: flex;
}
.wp-block-navigation .wp-block-navigation__submenu-container a {
  display: block;
  padding: 0.5rem 1rem;
  white-space: nowrap;
}
.wp-block-navigation .wp-block-navigation__submenu-container a:hover {
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  opacity: 1;
}

/* ── Site title ───────────────────────────────────────────────────────── */

.wp-block-site-title {
  font-family: var(--wp--preset--font-family--heading, inherit);
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0;
}
.wp-block-site-title a {
  color: inherit;
  text-decoration: none;
}

/* ── Query (post grid/list) ───────────────────────────────────────────── */

.wp-block-query .wp-block-post-template.is-layout-grid {
  display: grid;
  gap: 2rem;
  list-style: none;
  padding: 0;
  margin: 0 0 2rem;
}
.wp-block-query .wp-block-post-template.is-layout-grid.columns-1 { grid-template-columns: 1fr; }
.wp-block-query .wp-block-post-template.is-layout-grid.columns-2 { grid-template-columns: repeat(2, 1fr); }
.wp-block-query .wp-block-post-template.is-layout-grid.columns-3 { grid-template-columns: repeat(3, 1fr); }
.wp-block-query .wp-block-post-template.is-layout-grid.columns-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 782px) {
  .wp-block-query .wp-block-post-template.is-layout-grid.columns-3,
  .wp-block-query .wp-block-post-template.is-layout-grid.columns-4 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .wp-block-query .wp-block-post-template.is-layout-grid {
    grid-template-columns: 1fr;
  }
}

.wp-block-query-pagination {
  display: flex;
  gap: 0.5rem;
  margin-top: 2rem;
}

/* ── Search ───────────────────────────────────────────────────────────── */

.wp-block-search__inside-wrapper {
  display: flex;
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: var(--wp--preset--spacing--radius, 6px);
  overflow: hidden;
}
.wp-block-search__input {
  flex: 1;
  padding: 0.6em 0.9em;
  border: 0;
  outline: 0;
  background: transparent;
  font-family: inherit;
  font-size: 1rem;
}
.wp-block-search__button {
  padding: 0.6em 1.2em;
  background: var(--wp--preset--color--primary, currentColor);
  color: #fff;
  border: 0;
  cursor: pointer;
  font-family: inherit;
}

/* ── DW Builder variant cards (v1.1.0) ────────────────────────────────────
 *
 * Pattern variants emit specific wrapper classNames that the canvas styles
 * inline. These rules reproduce that intent on the WP side so live pages
 * match the builder preview. Each rule targets a wrapper that the pattern
 * service places via `content.className`, never a free-floating utility.
 */

/* Eyebrow — small-caps overline label used by hero/about/cta/news/etc.
 *
 * Hero patterns emit Gutenberg's block-style class `is-style-overline`
 * (set via the paragraph block's className attr). The legacy `.overline`
 * selectors are kept for older patterns that still ship the bare class.
 *
 * Color routes through theme.json's `secondary` palette slot so it
 * follows the project's design tokens — same source of truth the canvas
 * `buildOverlineStyle` reads from. Falls back to currentColor when no
 * secondary preset is registered, so the rule is never destructive.
 */
p.is-style-overline,
.wp-block-paragraph.is-style-overline,
p.overline,
.wp-block-paragraph.overline {
  /* mono 프리셋(selectedMonoFont)이 있으면 eyebrow 를 모노로 — 목업의 IBM Plex
     Mono eyebrow 룩. 없으면 상속(다른 사이트 무영향). 2026-07-31. */
  /* 정본은 디자인시스템: 크기 = fontSizes.overline 프리셋, 굵기/자간/행간/색 =
     fontScales.overline → --wp--custom--dw--overline-* (theme_service). 폴백은 옛
     하드코딩 값 — 변수가 없는 사이트만 해당 (2026-09-24 p33-b09 캔버스 parity). */
  font-family: var(--wp--preset--font-family--mono, inherit);
  font-size: var(--wp--preset--font-size--overline, 0.7rem);
  font-weight: var(--wp--custom--dw--overline-weight, 600);
  letter-spacing: var(--wp--custom--dw--overline-letter-spacing, 0.18em);
  line-height: var(--wp--custom--dw--overline-line-height, inherit);
  text-transform: uppercase;
  /* eyebrow = 디자인 요소 → 강조색(accent, 없으면 primary). 캔버스 parity
   * (2026-07-04): 이전엔 muted 라 밋밋했음. */
  color: var(--wp--custom--dw--overline-color, var(--wp--preset--color--accent, var(--wp--preset--color--primary, currentColor)));
  opacity: 0.95;
  margin-bottom: 0.5em;
}
/* 어두운 배경(Hero cover) 위 eyebrow — 강조색을 흰색과 혼합해 가독성 확보
 * (캔버스 buildTextColors.onDark.eyebrow 와 동일). */
.wp-block-cover .is-style-overline,
.wp-block-cover .overline {
  color: color-mix(in srgb, var(--wp--preset--color--accent, var(--wp--preset--color--primary, currentColor)) 55%, white);
  opacity: 1;
}

/* Footer 인라인 메뉴 (dw-nav-inline, 2026-07-15) — 가로 한 줄, 구분점. */
ul.wp-block-list.dw-nav-inline {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35em 1.4em;
  list-style: none;
  padding-left: 0;
  margin: 0;
  justify-content: center;
}
ul.wp-block-list.dw-nav-inline > li { margin: 0; }
ul.wp-block-list.dw-nav-inline a {
  color: var(--dw-nav-color, inherit);
  font-size: var(--dw-nav-font-size, 0.9rem);
  font-weight: var(--dw-nav-font-weight, 500);
  text-transform: var(--dw-nav-text-transform, none);
  letter-spacing: var(--dw-nav-letter-spacing, normal);
  text-decoration: none;
}
ul.wp-block-list.dw-nav-inline a:hover { color: var(--dw-nav-hover-color, var(--wp--preset--color--primary, inherit)); }

/* 빈 eyebrow/overline 은 숨김 (2026-07-14) — 발행에서 빈 pill 이 버튼처럼
 * 보이던 문제. 텍스트 없으면 자리 차지 안 함. */
p.is-style-overline:empty,
p.is-style-eyebrow-badge:empty,
.wp-block-cover .is-style-overline:empty { display: none; }

/* Eyebrow/overline 기본 폭 = 글자에 딱 (v1.5.50, 2026-07-17 사용자) —
 * 모든 섹션 공통. 블록-레벨 100% 로 펼쳐지지 않게 fit-content.
 * 정렬은 데이터(has-text-align-*)가 정본: center → margin auto 로 pill/라벨
 * 자체를 중앙에, right → 오른쪽에. 좌측 디자인 패턴(align 미지정)은 그대로 좌측. */
/* eyebrow 가로 위치 = 자기 정렬. 기본(정렬 없음)은 블록 폭 그대로(왼쪽 텍스트) — 예전엔
 * 기본이 width:fit-content 라 WP constrained 의 auto 마진이 상자를 가운데로 밀어, 긴
 * eyebrow 가 라이브에서만 오른쪽으로 밀렸다 (2026-09-24 p33-b09: x=202 vs 캔버스 80).
 * fit-content 는 가운데/오른쪽을 명시했을 때만 (그때 auto 마진이 위치를 만든다). */
p.is-style-overline.has-text-align-center {
  width: fit-content;
  margin-inline: auto;
}
p.is-style-overline.has-text-align-right {
  width: fit-content;
  margin-left: auto;
}

/* Hero eyebrow → pill 배지 (is-style-eyebrow-badge, 2026-07-14 Portway 레퍼런스).
 * 레퍼런스 스펙: inline-flex + gap 8px + padding 6px 14px + radius 999 +
 * 0.8rem/600 + 문장체(uppercase 아님) + 6px 상태점.
 * 클래스 opt-in — 히어로 패턴(hero-section/hero-tilted-photo)의 eyebrow 슬롯이
 * 이 클래스를 ship. cover 여부와 무관하게 동작 (hero 변형들이 cover 가 아닌
 * media-text/columns 루트라 cover 스코프는 커버리지 구멍이었음). */
.is-style-eyebrow-badge {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border: 1px solid color-mix(in srgb, currentColor 30%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 8%, transparent);
  backdrop-filter: blur(2px);
  /* 베이스 overline 규칙(uppercase/wide tracking) 해제 — 레퍼런스는 문장체 */
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.8rem;
  font-weight: 600;
}
/* 중앙 정렬 히어로(has-text-align-center)에선 pill 자체를 중앙으로 */
.is-style-eyebrow-badge.has-text-align-center {
  margin-inline: auto;
}
.is-style-eyebrow-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--wp--preset--color--accent, var(--wp--preset--color--primary, currentColor));
  flex: none;
}

/* Hero 베네핏 리스트 → 수평 칩 (is-style-hero-benefits).
 * 세로 bullet 리스트는 히어로에서 올드해 보임 → 중앙 정렬 캡슐 칩 행. */
ul.is-style-hero-benefits {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.6em;
  list-style: none;
  padding-left: 0;
  margin: 1.2em 0;
}
ul.is-style-hero-benefits > li {
  padding: 0.4em 1em;
  border: 1px solid color-mix(in srgb, currentColor 22%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, currentColor 6%, transparent);
  font-size: 0.85em;
  line-height: 1.4;
}
ul.is-style-hero-benefits > li::marker { content: ""; }

/* 스탯 스트립 (is-style-stats-strip, 2026-07-14 모던 디자인).
 * 레퍼런스 스펙: 숫자 26px/800/ls-.02em + 라벨 13px muted, 컬럼 사이 1px
 * 디바이더, 상단 헤어라인. stats-numbers 패턴의 기본 모습. */
/* 헤어라인+28px 은 **맨몸 스트립** 전용 장식이다. 배경/테두리가 있는 카드형
 * 밴드에 그대로 붙으면 카드 안쪽이 위 53px / 아래 25px 로 비대칭이 되어 내용이
 * 아래로 쏠린다 (2026-09-16 p29-b15 실측, 사용자 "이 여백이 안 보여?").
 * 패턴 CSS 기본은 has-background 게이트 필수 — 이 규칙만 빠져 있었다.
 * 데이터 변경 없이 기존 블록까지 즉시 교정된다. */
.is-style-stats-strip:not(.has-background):not(.has-border-color):not(.dwwp-stat-nohairline) .wp-block-columns,
.is-style-stats-strip.dwwp-stat-hairline .wp-block-columns {
  border-top: 1px solid color-mix(in srgb, currentColor 10%, transparent);
  padding-top: 28px;
}
/* ↑ 섹션 속성 '상단 헤어라인': 끔(.dwwp-stat-nohairline)이 기본 규칙에서 빠지도록
 * :not() 으로 제외 — 예전엔 기본 규칙(0,4,0)이 끔 규칙(0,2,0)을 이겨 맨몸 스트립에서
 * 꺼지지 않았다. 둘째 선택자 = 명시 켜짐 — 배경 있는 스트립은 기본이 꺼짐이라
 * 켜도 안 보이던 죽은 토글이었다 (2026-09-22). */

/* 히어로 높이 = 섹션 속성 heroHeight 프리셋 (정본 HERO_HEIGHT_PRESETS).
 * 예전엔 패턴 생성 때만 쓰이고 패널에서 바꾸면 아무 데도 반영되지 않았다.
 * 요소 한정(0,1,1) — 전역 토큰 규칙과 순서 무관하게 이긴다(편집기 포함). */
:is(div, section, header).dwwp-hero-h { min-height: var(--dwwp-hero-minh); }
.is-style-stats-strip .wp-block-columns {
  gap: 0;
  /* 값이 글자보다 키 큰 경우(로고 이미지)에도 칸끼리 중심이 맞게 —
   * 위 정렬이면 키 큰 칸의 라벨만 아래로 밀린다 (2026-09-16 실측 10px). */
  align-items: center;
}
.is-style-stats-strip .wp-block-column {
  text-align: left;
  padding-inline: 28px;
}
/* 첫 칸 flush 도 **맨몸 스트립 전용** — 카드형은 자체 좌우 패딩이 있어 필요
 * 없고, 첫 칸만 좌우가 0/28 로 비대칭이 되어 값·라벨이 14px 왼쪽으로 밀린다
 * (2026-09-16 실측, 사용자 "전부 중앙 정렬이 아니야"). 헤어라인과 같은 게이트. */
/* 첫 칸 flush(좌패딩 0)는 **좌정렬 스트립** 전용이다. 칸 내용이 가운데
 * 정렬이면 첫 칸만 좌우가 0/28 로 비대칭이 되어 값·라벨이 14px 왼쪽으로
 * 밀린다. 판정 기준은 배경 유무가 아니라 **정렬**이다 — 배경 기준으로 하면
 * 배경 없는 밴드(p32-b188)가 그대로 밀린다 (2026-09-16 실측 -14px). */
.is-style-stats-strip .wp-block-column:first-child:not(:has(.has-text-align-center)):not(:has(.has-text-align-right)) {
  padding-left: 0;
}
.is-style-stats-strip .wp-block-column :is(h1, h2, h3, h4, h5, h6) {
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.1;
  margin: 0 0 4px;
}
/* 숫자 크기 = 데이터(heading level)의 폰트 토큰 — 캔버스 headingScaleOverride 와 동률.
 * 예전 clamp(24px,2.2vw,30px) 리터럴은 캔버스(h2 토큰 40px)와 갈라졌다
 * (2026-09-25 p33-b102 등 6곳 사용자: "폰트 사이즈가 디자인 패널대로 안 나온다"). */
.is-style-stats-strip .wp-block-column h1 { font-size: var(--wp--preset--font-size--h-1); }
.is-style-stats-strip .wp-block-column h2 { font-size: var(--wp--preset--font-size--h-2); }
.is-style-stats-strip .wp-block-column h3 { font-size: var(--wp--preset--font-size--h-3); }
.is-style-stats-strip .wp-block-column h4 { font-size: var(--wp--preset--font-size--h-4); }
.is-style-stats-strip .wp-block-column h5 { font-size: var(--wp--preset--font-size--h-5); }
.is-style-stats-strip .wp-block-column h6 { font-size: var(--wp--preset--font-size--h-6); }
/* 라벨 = 본문 토큰 (캔버스 16px 동률; 예전 0.82rem 리터럴 = 13px) */
.is-style-stats-strip .wp-block-column p {
  font-size: var(--wp--preset--font-size--body);
  opacity: 0.65;
  margin: 0;
}
@media (min-width: 782px) {
  .is-style-stats-strip .wp-block-column + .wp-block-column {
    /* 구분선 색은 bo dividerColor(--dwwp-stat-divider) 우선 (2026-09-11 —
     * ⇄N 이 원본 구분선 색을 실측 이관, 사용자 "구분선 프로퍼티"). */
    border-left: 1px solid var(--dwwp-stat-divider, color-mix(in srgb, currentColor 10%, transparent));
  }
}
/* bo itemDividers=false — 구분선 제거 (원본에 구분선 없는 스탯 밴드). */
.dwwp-stat-nodivider .wp-block-column + .wp-block-column {
  border-left: 0 !important;
}

/* ── stats-cards (⇄N 승격 6호 — 지표 카드 그리드, 2026-09-12) ──────────────
 * 좌정렬 카드(큰 지표 + 설명 '문장') + 상단 eyebrow + 하단 출처 각주.
 * stats-numbers(중앙 스트립)와의 차이가 승격 사유 — 스트립엔 eyebrow/각주
 * 슬롯이 아예 없어 오버라인·출처가 통째로 소실되고, 문장 설명이 13px 라벨
 * 자리에서 뭉개진다 (2026-09-12 p33-b15 'Why Atlanta' 4카드 실측).
 * 카드 chrome(배경/보더/패딩/radius)은 공용 .dwwp-card-* + blockOptions 가
 * 담당 — 여기선 타이포/리듬만. 실측 이관값은 인라인이라 항상 이 기본을 이김. */
.dwwp-stat-cards .wp-block-columns { margin-top: 16px; }
.dwwp-stat-cards .wp-block-column h1,
.dwwp-stat-cards .wp-block-column h2,
.dwwp-stat-cards .wp-block-column h3,
.dwwp-stat-cards .wp-block-column h4 {
  font-size: clamp(20px, 2.2vw, 24px);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1.25;
  margin: 0;
}
.dwwp-stat-cards .wp-block-column p {
  font-size: 14px;
  line-height: 1.6;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
  margin: 0.7em 0 0;
}
/* 출처 각주 (slot description) — 그리드 밖이라 카드 규칙과 섞이지 않음. */
.dwwp-stat-cards .dwwp-stat-note {
  font-size: 12.5px;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
  margin: 14px 0 0;
}

/* ── text-callout (⇄N 승격 7호 — 콜아웃/경고 밴드, 2026-09-12) ─────────────
 * 좌측 강조바 + 색면 박스 + 라벨 + 본문. text-block 으로 가면 강조바·색면이
 * 통째로 사라지고 라벨이 평범한 부제가 되며, 빈 title 슬롯에 시드가 남아
 * 'Section Title' 유령까지 생긴다 (2026-09-12 p34-b15 실측).
 * 배경·패딩은 루트 native 이관이 담당하고, 박스 보더/radius 는 기존 카드
 * 변수(--dwwp-card-*)를 재사용 — 강조바만 콜아웃 전용 변수. */
.dwwp-callout {
  border: var(--dwwp-card-border-width, 1px) solid
    var(--dwwp-card-border-color, color-mix(in srgb, currentColor 12%, transparent));
  border-left: var(--dwwp-callout-accent-width, 4px) solid
    var(--dwwp-callout-accent, var(--wp--preset--color--primary, currentColor));
  border-radius: var(--dwwp-card-radius, 12px);
}
/* 라벨 색 기본 = 강조바 색 (원본 실측: 바와 라벨이 같은 빨강). 이관된
 * native typography/색은 인라인이라 이 기본을 항상 이긴다. */
.dwwp-callout .dwwp-callout__label {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dwwp-callout-accent, var(--wp--preset--color--primary, currentColor));
  margin: 0 0 0.8em;
}
.dwwp-callout .dwwp-callout__text {
  font-size: 16px;
  line-height: 1.6;
  margin: 0;
}
/* ── 섹션 너비 3종 (2026-09-11 사용자: "세 종류가 필요하다") ──
 * ①레이아웃(align 없음) ②배경만 전체(align full — 배경 전폭, 내용은
 * 콘텐츠 폭이 기본) ③전체 너비(align full + bo fullContent → 내용까지).
 * group 은 WP constrained 가 ②를 처리하지만 columns(text-split 등)는
 * constrained 미지원이라 전폭 시 내용까지 퍼짐 — 여기서 동률 에뮬레이션.
 * 기본값일 뿐이다 — 섹션에 좌우 패딩 데이터가 있으면(인라인) 그 값이 이긴다.
 * 예전엔 max(48px, …) !important 로 사용자가 0 을 줘도 48px 이상을 강제했다
 * (2026-09-21 사용자: "0 으로 바꿨는데 여전히 여백"). 숨은 최소값·강제 없음. */
/* 밴드 여백은 **변수로** 노출한다. 최상위 섹션은 좌우 패딩이 인라인
 * (`var(--dwwp-pi, …)`)으로 박혀 나오므로 여기서 padding 을 선언해봐야 항상
 * 진다 — 발행 렌더러가 인라인 값을 `calc(패딩 + var(--dwwp-band, 0px))` 로
 * 만들고, 이 변수만 값을 공급한다 (2026-09-24 p29-b92: "배경만 전체" 인데
 * 내용이 viewport 끝까지). 아래 padding 선언은 인라인이 없는 블록용 기본값.
 * viewport 가 콘텐츠 폭보다 좁으면 음수 → max 로 0 (모바일 안전). */
.wp-block-columns.alignfull:not(.dwwp-full-content),
.wp-block-media-text.alignfull:not(.dwwp-full-content) {
  /* = 루트 여백 토큰 + 콘텐츠 폭 가운데 정렬. WP 의 root-padding-aware alignfull 과
   * 같은 기하: alignfull 은 루트 여백 밖으로 나가고(음수 마진) 100% 는 post-content
   * 콘텐츠 폭이라, 루트 여백을 더해야 레이아웃 섹션 좌변(x = 루트 여백 + 센터링)과
   * 정확히 같은 x 가 된다. 블록에 좌우 패딩 데이터가 없어도 성립 — 예전 max(0px, …)
   * 만으로는 콘텐츠 폭 이하 화면(≤1440px)에서 0 이 되어 내용이 화면 끝까지 갔다
   * (2026-09-25 p32-b63 사용자: "좌우 패딩 데이터가 없을 때 이런 문제가 생기면 안 되지"). */
  --dwwp-band: calc(var(--wp--style--root--padding-left, 0px) + max(0px, (100% - var(--wp--style--global--content-size, 100%)) / 2));
}
.wp-block-columns.alignfull:not(.dwwp-full-content) {
  padding-left: var(--dwwp-band);
  padding-right: var(--dwwp-band);
}
/* media-text 도 동일 — 위 §"alignfull escape" 주석의 "cover/media-text/columns
 * 는 자체 layout 으로 처리" 가정이 media-text 엔 성립하지 않는다(자체 grid 는
 * 폭을 제한하지 않음). columns 만 밴드 제약을 받고 media-text 는 빠져 있어,
 * 캔버스는 콘텐츠 폭인데 **발행·WP 프리뷰만 내용이 viewport 끝까지** 퍼졌다
 * (2026-09-13 사용자 실측: hero-split(media-text) 배경만 전체). */
.wp-block-media-text.alignfull:not(.dwwp-full-content) {
  padding-left: var(--dwwp-band);
  padding-right: var(--dwwp-band);
}

/* bo stripHairline=false — 상단 헤어라인+28px 이 스킨 장식이라 원본(헤어라인
 * 없는 밴드)과 갈라짐 (2026-09-11 p32-b14 실측: 밴드 126px ↔ 200px 의 잔여). */
.dwwp-stat-nohairline .wp-block-columns {
  border-top: 0;
  padding-top: 0;
}
/* 스트립 안에서는 밴드 패딩이 세로 리듬 담당 — columns 전역 margin-bottom
 * 28px + column 상하 8px 패딩이 새면 밴드가 원본보다 44px 두꺼움
 * (2026-09-11 p32-b14 실측 171↔126. 공용 규칙 오타격 계열 §8). */
.is-style-stats-strip .wp-block-columns {
  margin-bottom: 0;
}
.is-style-stats-strip .wp-block-column {
  padding-top: 0;
  padding-bottom: 0;
}

/* CTA 섹션 — 배경 없음(흰)일 때 1px 팔레트 보더 + 라운드 (dwwp-cta-outlined,
 * 2026-07-14 사용자). 배경을 넣으면 normalize 가 클래스를 안 붙임. */
/* CTA 패턴 디자인 = 가운데 정렬. :where() 로 0-특이도라 요소에 지정된 정렬
 * (WP has-text-align-*)이 항상 이긴다 — 패턴 기본 < 커스텀 값 순서 유지.
 * 캔버스는 이 디자인을 text-center 로 그리는데 발행엔 없어서 라이브만 왼쪽
 * 정렬이었다 (2026-09-24 p29-b97 실측). */
:where(.dwwp-cta) :where(h1, h2, h3, h4, p, .wp-block-buttons) { text-align: center; }
:where(.dwwp-cta) :where(.wp-block-buttons) { justify-content: center; }
/* ── 섹션 정렬 (패널 '정렬' — 가로/세로) ──────────────────────────────────
 * 정본은 블록 데이터(style.alignment). 발행기가 dwwp-align-h/v-* 클래스로 굽고
 * 여기서만 소비한다 — 플러그인을 지워도 살아남고(핸드오프), 편집기·캔버스와 같은
 * 규칙을 쓴다.
 * 가로 = text-align 만. 제목/문단/버튼의 정렬은 요소 자체 속성(has-text-align-*,
 * is-content-justification-*)으로 데이터에 저장되고(section_alignment.py), 이 규칙은
 * 칩·인라인 이미지 같은 나머지 인라인 콘텐츠용 폴백이다. **display:flex 로 바꾸지
 * 않는다** — flex 컨테이너는 자식 margin 을 겹치지(collapse) 않아 요소 사이가 벌어졌다
 * (2026-09-24 실측: 설명→버튼 32px → 50px, 사용자 "위아래로 조금씩 벌어진다").
 * 0-특이성(:where) — 요소의 명시 정렬(has-text-align-* 등)이 항상 이긴다. CTA 의
 * :where(.dwwp-cta) 기본 규칙보다 뒤에 있어야 섹션 선택이 패턴 기본을 이긴다. */
/* 직계 자식에게만 — 섹션 루트에 text-align 을 주면 상속으로 카드(columns)·폼 숏코드
 * (라벨)·중첩 그룹까지 가운데가 된다 (2026-09-24 p39-b01: 연락처 폼 라벨이 갑자기
 * 가운데). 제목/문단/버튼은 요소 자체 속성(has-text-align-*)이 정본이고 이 규칙은
 * 직계 인라인 콘텐츠(리스트·이미지·칩)용 폴백이다. */
:where(.dwwp-align-h-start) > :where(p, h1, h2, h3, h4, h5, h6, ul, ol, figure) { text-align: left; }
:where(.dwwp-align-h-center) > :where(p, h1, h2, h3, h4, h5, h6, ul, ol, figure) { text-align: center; }
:where(.dwwp-align-h-end) > :where(p, h1, h2, h3, h4, h5, h6, ul, ol, figure) { text-align: right; }
:where(.dwwp-align-h-start) > :where(.wp-block-buttons) { justify-content: flex-start; }
:where(.dwwp-align-h-center) > :where(.wp-block-buttons) { justify-content: center; }
:where(.dwwp-align-h-end) > :where(.wp-block-buttons) { justify-content: flex-end; }
/* 세로 = 높이가 있는 섹션 안에서 위/가운데/아래. 주축 배치라 flex 가 필요하다
 * (세로 정렬을 고른 섹션만 해당). 높이가 없으면 기본 최소 높이. */
:is(div, section)[class*="dwwp-align-v-"] { display: flex; }
:is(div, section):is(.wp-block-group, .wp-block-cover)[class*="dwwp-align-v-"] { flex-direction: column; }
:is(div, section).dwwp-align-v-start { justify-content: flex-start; }
:is(div, section).dwwp-align-v-center { justify-content: center; }
:is(div, section).dwwp-align-v-end { justify-content: flex-end; }
:is(div, section)[class*="dwwp-align-v-"] { min-height: var(--dwwp-align-minh, 60vh); }

.dwwp-cta-outlined {
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 14px;
}

/* CTA 카드 (cta-card 패턴) — 라운드 카드: 좌 제목/설명, 우 버튼 (2026-08-06
 * 사용자, BiZiLiA 디자인). 색은 블록 attr(backgroundColor/textColor)이 정본 —
 * 여기는 레이아웃과 버튼 반전(배경 토큰)만. */
.dwwp-cta-card {
  /* 바깥 여백 — 루트가 곧 박스라 패딩으로는 박스가 안 좁아진다. 거터 이관값
   * (--dwwp-outer-inset)을 max-width 로 반영해 다른 섹션 본문과 좌우를 맞춘다.
   * ⚠ 기준은 반드시 **콘텐츠 폭**이다. calc(100% - …) 로 쓰면 이 규칙이 WP
   * 레이아웃의 `.is-layout-constrained > *{max-width:content-size}` 를 같은
   * 특이도·뒤 순서로 이겨, 값이 없어도(inset 0) 카드가 콘텐츠 폭을 벗어나
   * 전폭이 된다 (2026-09-17 라이브 전수 실측: 콘텐츠 폭 → 전폭, 패널은
   * Layout 표시. 사용자 "모든 페이지에서 CTA가 full width").
   * 기준 폭은 theme.json 토큰(--wp--style--global--content-size)만 쓴다 —
   * px 폴백을 박으면 프로젝트가 콘텐츠 폭을 바꿔도 카드만 옛 값에 남는다.
   * 토큰이 없으면 이 선언이 무효가 되어 WP 레이아웃 제약이 그대로 적용된다.
   * min() 으로 더 좁은 부모도 존중. */
  max-width: min(
    100%,
    calc(var(--wp--style--global--content-size) - 2 * var(--dwwp-outer-inset, 0px))
  );
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas: "title btn" "desc btn";
  align-items: center;
  column-gap: 40px;
  border-radius: 16px;
}
/* 상하 마진 — WP constrained 컨테이너가 .wp-container-X.wp-container-X (0,2,0)
 * 로 자식 margin 을 리셋하므로 (0,3,0) 으로 승격 (2026-08-06 실측). */
/* 카드 바깥 상하 리듬은 **패턴 데이터**(patterns.json cta-card 루트
 * style.spacing.margin)가 담당한다 — 여기서 CSS 로 박아두면 블록에 인라인
 * 마진이 없을 때 사용자가 패널에서 0 을 넣어도 되살아난다 (2026-09-13 CTA
 * 전수조사: 캔버스 ?? 56/64 와 이 규칙이 같은 값을 이중으로 하드코딩). */
/* 자식 auto-center 방어 — constrained 로 저장된 기존 마크업도 좌정렬 유지. */
.wp-block-post-content > .dwwp-cta-card.dwwp-cta-card > *,
.entry-content > .dwwp-cta-card.dwwp-cta-card > * {
  max-width: none;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* cta-color-strip 에서 전환된 블록의 잔존 center 정렬 attr 방어 — 카드는 좌측. */
.dwwp-cta-card > .has-text-align-center { text-align: left; }
.dwwp-cta-card > :is(h1, h2, h3) {
  grid-area: title;
  text-align: left;
  margin: 0 0 8px;
}
.dwwp-cta-card > p {
  grid-area: desc;
  text-align: left;
  margin: 0;
  opacity: 0.85;
}
.dwwp-cta-card > .wp-block-buttons {
  grid-area: btn;
  margin: 0;
}
/* 패턴 기본(반전 버튼)은 커스텀 색이 없을 때만 — 커스텀 > 패턴 기본 > 토큰
 * (사용자 2026-09-05: 전역 토큰이 커스텀 값보다 우선이 되어서는 절대 안 됨). */
.dwwp-cta-card .wp-block-button__link:not(.has-background) {
  background: var(--wp--preset--color--background, transparent);
}
.dwwp-cta-card .wp-block-button__link:not(.has-text-color) {
  color: var(--wp--preset--color--primary, currentColor);
}
.dwwp-cta-card .wp-block-button__link {
  font-weight: 800;
  border-radius: 10px;
  padding: 15px 30px;
}
@media (max-width: 640px) {
  .dwwp-cta-card {
    grid-template-columns: 1fr;
    grid-template-areas: "title" "desc" "btn";
    row-gap: 14px;
  }
  .dwwp-cta-card > .wp-block-buttons { justify-content: flex-start; }
}

/* 이미지 히어로(cover) 버튼 — 칩과 동일 계열 (v1.5.45, 2026-07-16 사용자:
 * "히어로 버튼은 내가 표시한 [칩] 스타일처럼"): pill + 반투명 배경 + 은은한
 * 밝은 보더 + 흰 글자. 첫 버튼은 약간 진하게(주 CTA 위계), outline 은 투명. */
.wp-block-cover .wp-block-button:not(.is-style-ghost) .wp-block-button__link {
  background-color: rgba(255, 255, 255, 0.14);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.38);
  backdrop-filter: blur(2px);
}
.wp-block-cover .wp-block-button.is-style-outline .wp-block-button__link {
  background-color: transparent;
}
.wp-block-cover .wp-block-button .wp-block-button__link:hover {
  background-color: rgba(255, 255, 255, 0.24);
  opacity: 1;
}

/* FAQ (core/details) — 카드형 아코디언 (2026-07-14).
 * 이전엔 발행측 details 스타일이 아예 없어 라이브가 브라우저 기본 disclosure
 * 로 렌더 — 캔버스(카드) 와 불일치. 캔버스 faq 카드와 동일 스펙 (r14 / 14·20). */
.wp-block-details {
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 14px;
  padding: 14px 20px;
  background: var(--wp--preset--color--surface, transparent);
  margin-bottom: 10px;
}
.wp-block-details > summary {
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.wp-block-details > summary::-webkit-details-marker { display: none; }
.wp-block-details > summary::after {
  content: "+";
  float: right;
  opacity: 0.5;
  font-weight: 400;
}
.wp-block-details[open] > summary::after { content: "\2212"; }
.wp-block-details[open] > summary { margin-bottom: 8px; }
.wp-block-details > p { margin: 0; opacity: 0.8; font-size: 0.95em; }

/* 로고 스트립 (dw-logo-strip) — trusted-by 톤: 로고 무채색 + 저채도,
 * 제목은 소형 대문자 라벨. */
.dw-logo-strip .wp-block-heading {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.55;
}

/* 브랜드 로고 행 (.dwwp-logos = core/group flex, 자식 core/image 슬롯 logo).
 * 2026-09-25 p30-b29 재설계 — 예전 core/gallery 는 코어 갤러리 CSS(열 폭·
 * !important max-width·크롭)가 로고 크기를 정해 데이터가 없었고, 캔버스는
 * 32px 하드코딩이었다. 이제 표시값은 섹션 속성(PATTERN_DEFAULT_OPTIONS
 * logo-grid)이 정본: 로고 높이 --dwwp-logo-h / -h-m, 간격 --dwwp-logo-gap,
 * 한 줄 개수 dwwp-cols-N / dwwp-cols-mobile-N, 배치 dwwp-logos-carousel +
 * --dwwp-logo-speed. CSS 폴백 없음(기본은 데이터 1벌).
 * 전역 :where(.wp-block-group){padding:75px 0} 을 행에서 무력화. */
.dw-logo-strip .dwwp-logos {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--dwwp-logo-gap);
  padding: 0;
}
.dw-logo-strip .dwwp-logos > .wp-block-image {
  margin: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 0;
}
.dw-logo-strip .dwwp-logos > .wp-block-image > a {
  display: inline-flex;
  line-height: 0;
}
.dw-logo-strip .dwwp-logos img {
  display: block;
  /* 높이 정본은 --dwwp-img-h 한 곳(편집기 인라인 height:auto 무력화 규약, editor.css) */
  --dwwp-img-h: var(--dwwp-logo-h);
  height: var(--dwwp-img-h);
  width: auto;
  max-width: 100%;
  object-fit: contain;
}
/* 로고 톤 = 섹션 속성 logoTone (기본 color = 원본 그대로). "gray" 일 때만 무채색·저채도
 * + hover 복원. 예전엔 이 값이 조건 없이 박혀 있어 조종할 곳이 없었다
 * (2026-09-25 사용자: "선명하게 안 나온다, 시킨 적 없다, 어디서 조종하나"). */
.dw-logo-strip.dwwp-logos-gray .dwwp-logos img {
  filter: grayscale(1);
  opacity: 0.55;
  transition: opacity 0.15s ease;
}
.dw-logo-strip.dwwp-logos-gray .dwwp-logos img:hover { opacity: 0.85; }
/* 그리드: 한 줄 개수 = 섹션 columnsDesktop (dwwp-cols-N). 캐러셀은 제외. */
.dw-logo-strip.dwwp-cols-1:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 100%; }
.dw-logo-strip.dwwp-cols-2:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 1) / 2); }
.dw-logo-strip.dwwp-cols-3:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 2) / 3); }
.dw-logo-strip.dwwp-cols-4:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 3) / 4); }
.dw-logo-strip.dwwp-cols-5:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 4) / 5); }
.dw-logo-strip.dwwp-cols-6:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 5) / 6); }
/* 모바일(로고 높이 -h-m · 한 줄 개수 dwwp-cols-mobile-N)은 아래 Columns 모바일
 * @media (max-width: 640px) 블록에 함께 있다. */
/* 캐러셀: JS(logos.js) 가 행 안에 트랙(.dwwp-logos__track)을 만들고 로고를 1회
 * 복제해 끊김 없이 흐른다(hover 시 정지, 감속 선호 시 정지). JS 전/없음 = 가로
 * 스크롤 스트립. 좌우 클립은 섹션 상자 기준(전폭 마퀴). */
.dw-logo-strip.dwwp-logos-carousel { overflow: hidden; }
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos {
  flex-wrap: nowrap;
  justify-content: flex-start;
  overflow-x: auto;
  scrollbar-width: none;
}
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos::-webkit-scrollbar { display: none; }
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos > .wp-block-image { flex: 0 0 auto; }
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos.is-marquee {
  display: block;
  overflow: hidden;
}
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos.is-marquee > .dwwp-logos__track {
  display: flex;
  align-items: center;
  gap: var(--dwwp-logo-gap);
  width: max-content;
  animation: dwwp-logo-marquee var(--dwwp-logo-speed) linear infinite;
}
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos.is-marquee > .dwwp-logos__track > .wp-block-image { flex: 0 0 auto; margin: 0; }
.dw-logo-strip.dwwp-logos-carousel > .dwwp-logos.is-marquee:hover > .dwwp-logos__track { animation-play-state: paused; }
/* 한 바퀴 = 세트 1개 폭(트랙/K + gap/K). K(--dwwp-logo-sets)는 logos.js 가
 * 행 폭의 2배를 채울 만큼 세트를 복제한 뒤 적는다 (최소 2). */
@keyframes dwwp-logo-marquee {
  to { transform: translateX(calc(-100% / var(--dwwp-logo-sets, 2) - var(--dwwp-logo-gap) / var(--dwwp-logo-sets, 2))); }
}
@media (prefers-reduced-motion: reduce) {
  .dw-logo-strip.dwwp-logos-carousel > .dwwp-logos.is-marquee > .dwwp-logos__track { animation: none; }
}

/* 모서리 radius 가 있는 섹션 — 내용을 모서리 모양대로 자른다. 렌더러가 radius 가 있는
 * 최상위 섹션에 dwwp-clip 을 붙인다(_normalize_rounded_clip). WP 는 그룹 radius 를
 * 인라인으로만 그리고 자식을 안 잘라, 섹션을 꽉 채운 지도 iframe 이 각진 채로 둥근
 * 테두리 위를 덮었다 (2026-09-26 p39-b21). 캔버스도 같은 조건에서 overflow hidden. */
.dwwp-clip { overflow: hidden; }

/* 구글 지도 (google-map) — core/html 안 임베드 iframe. 높이는 섹션 속성
 * mapHeight / mapHeightMobile → --dwwp-map-h / --dwwp-map-h-m (기본은
 * PATTERN_DEFAULT_OPTIONS 데이터, CSS 폴백 없음). 모바일: 전폭 + 모바일 높이. */
.dwwp-map {
  width: 100%;
}
.dwwp-map .dwwp-map__frame {
  display: block;
  width: 100%;
  max-width: 100%;
  height: var(--dwwp-map-h);
  border: 0;
}
@media (max-width: 781px) {
  .dwwp-map .dwwp-map__frame {
    height: var(--dwwp-map-h-m);
  }
}

/* Hero — Tilted Photo: right column rotates ~-4deg with subtle drop shadow.
 * The column is the 45% photo column; the inner image inherits the rotation
 * so the heading/text column stays upright. */
.wp-block-column.dw-tilted-photo-card {
  transform: rotate(-4deg);
  transform-origin: center center;
  perspective: 800px;
}
.wp-block-column.dw-tilted-photo-card .wp-block-image,
.wp-block-column.dw-tilted-photo-card img {
  border-radius: var(--wp--preset--spacing--radius, 6px);
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.18);
  overflow: hidden;
}
@media (max-width: 782px) {
  /* Mobile — keep rotation but reduce so card doesn't bleed off-screen. */
  .wp-block-column.dw-tilted-photo-card { transform: rotate(-2deg); }
}

/* Features — Dark Photo Cards: card-style column on dark parent bg. The
 * parent group provides the dark background; this rule paints each column
 * as a translucent card with image at top + content stack below. */
.wp-block-column.dw-feature-photo-card {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: var(--wp--preset--spacing--radius, 8px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 0;
}
.wp-block-column.dw-feature-photo-card > .wp-block-image {
  margin: 0;
}
.wp-block-column.dw-feature-photo-card > .wp-block-image img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.wp-block-column.dw-feature-photo-card > .wp-block-heading,
.wp-block-column.dw-feature-photo-card > .wp-block-paragraph,
.wp-block-column.dw-feature-photo-card > p,
.wp-block-column.dw-feature-photo-card > .wp-block-buttons {
  margin-left: 1rem;
  margin-right: 1rem;
}
.wp-block-column.dw-feature-photo-card > .wp-block-heading {
  margin-top: 1rem;
  text-align: center; /* 기본값 — cardAlignment 미설정 시 */
}
/* cardAlignment(left/right) 이 photo-card 제목의 하드코딩 center 를 이기도록
 * 더 높은 specificity 로 override (2026-07-03 하드코딩 감사). */
.dwwp-align-left > .wp-block-columns > .wp-block-column.dw-feature-photo-card > .wp-block-heading {
  text-align: left;
}
.dwwp-align-right > .wp-block-columns > .wp-block-column.dw-feature-photo-card > .wp-block-heading {
  text-align: right;
}
.wp-block-column.dw-feature-photo-card > .wp-block-buttons {
  margin-top: auto;
  margin-bottom: 1rem;
}

/* Locations Carousel card — min-width card inside horizontal scroll group.
 * Inline style already handles scroll-snap-align + min-width; we add the
 * visual frame (border, rounded, image sizing, padded text). */
.wp-block-group.dw-location-card {
  border: 1px solid var(--wp--preset--color--outline, rgba(0, 0, 0, 0.1));
  border-radius: var(--wp--preset--spacing--radius, 8px);
  overflow: hidden;
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  padding: 0;
  text-align: center;
  flex-shrink: 0;
}
.wp-block-group.dw-location-card > .wp-block-image {
  margin: 0;
}
.wp-block-group.dw-location-card > .wp-block-image img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
.wp-block-group.dw-location-card > .wp-block-heading,
.wp-block-group.dw-location-card > .wp-block-paragraph,
.wp-block-group.dw-location-card > p {
  padding-left: 0.75rem;
  padding-right: 0.75rem;
}
.wp-block-group.dw-location-card > .wp-block-heading {
  padding-top: 0.75rem;
  margin-bottom: 0.25em;
  font-size: 1rem;
}
.wp-block-group.dw-location-card > p:last-child {
  padding-bottom: 0.75rem;
  font-size: 0.85rem;
  opacity: 0.85;
}

/* News 4-col grid card — column-based card with image + title + excerpt +
 * read more. Same skeleton as the feature card but light theme by default. */
.wp-block-column.dw-news-card {
  border: 1px solid var(--wp--preset--color--outline, rgba(0, 0, 0, 0.08));
  border-radius: var(--wp--preset--spacing--radius, 8px);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  padding: 0;
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
}
.wp-block-column.dw-news-card > .wp-block-image {
  margin: 0;
}
.wp-block-column.dw-news-card > .wp-block-image img {
  width: 100%;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  display: block;
}
.wp-block-column.dw-news-card > .wp-block-heading,
.wp-block-column.dw-news-card > .wp-block-paragraph,
.wp-block-column.dw-news-card > p,
.wp-block-column.dw-news-card > .wp-block-buttons {
  margin-left: 0.85rem;
  margin-right: 0.85rem;
}
.wp-block-column.dw-news-card > .wp-block-heading {
  margin-top: 0.85rem;
  font-size: 1.05rem;
  line-height: 1.3;
}
.wp-block-column.dw-news-card > p {
  font-size: 0.85rem;
  opacity: 0.85;
}
.wp-block-column.dw-news-card > .wp-block-buttons {
  margin-top: auto;
  margin-bottom: 0.85rem;
}

@media (max-width: 782px) {
  /* News grid — 4 columns becomes 2 on tablet to keep card readable. */
  .wp-block-columns:has(.dw-news-card) { flex-wrap: wrap; }
  .wp-block-column.dw-news-card { flex-basis: calc(50% - 1em); }
}
@media (max-width: 600px) {
  .wp-block-column.dw-news-card { flex-basis: 100%; }
}

/* ── Mobile responsive — section-level padding scale ──────────────────── */

@media (max-width: 782px) {
  .wp-block-cover {
    min-height: 320px;
    padding: 1.5em;
  }
  .wp-block-group.has-padding {
    padding-left: 1em;
    padding-right: 1em;
  }
  /* (v1.5.39) heading 반응형 리터럴 제거 — theme.json fluid 타이포(clamp)가
   * 뷰포트 축소를 담당한다. 여기 있던 h1~h4 고정 px 는 특이도(0,1,1)로
   * theme.json elements 규칙(0,0,1)을 이겨 사용자 h2~h4 설정이 태블릿/모바일
   * 에서 무시되던 원인 (2026-07-16 사용자: "h2 부터 반영이 안 돼").
   * 원칙 ②: 부모 CSS 가 데이터(theme.json)를 이기면 안 된다. */
}

@media (max-width: 600px) {
  .wp-block-cover { min-height: 280px; padding: 1em; }
}

/* ── Pricing 3-tier 카드 강조 (parent v1.3.12+) ─────────────────────────
 *
 * pricing-3tier 패턴의 가운데 column 에 className="is-pricing-featured" 박혀있음.
 * 살짝 scale + accent border + shadow 로 시각적 강조. 5% 이내가 자연스러움
 * (그 이상이면 과함).
 */
.is-pricing-featured {
  border: 2px solid var(--wp--preset--color--primary, currentColor);
  border-radius: var(--wp--custom--border-radius, 12px);
  padding: 1.5rem;
  position: relative;
  transform: scale(1.02);
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  box-shadow: 0 12px 32px rgba(0,0,0,0.10), 0 4px 8px rgba(0,0,0,0.06);
}

.is-pricing-featured .pricing-badge {
  position: absolute;
  top: -12px;
  left: 50%;
  transform: translateX(-50%);
  background: var(--wp--preset--color--primary, currentColor);
  color: var(--wp--preset--color--background, transparent);
  padding: 4px 12px;
  border-radius: 9999px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* 가격 숫자는 tabular-nums + 큰 사이즈 */
.price-value {
  font-variant-numeric: tabular-nums;
  font-size: clamp(2rem, 4vw, 3rem) !important;
  line-height: 1 !important;
  margin-block: 0.5rem !important;
}

/* ── Auto-contrast foreground (parent v1.3.13+) ─────────────────────────
 *
 * 컬러 슬롯 background 가 사용된 영역의 본문 텍스트 색을 자동으로 contrast
 * 보장된 fg 토큰으로 swap. theme.json 에 {slot}-fg 가 함께 emit 되어 CSS
 * 변수 var(--wp--preset--color--{slot}-fg) 가 사용 가능.
 *
 * specificity: .has-X-background-color (0,1,0) + :where() 가 0 추가 = 0,1,0.
 * 사용자가 inline 또는 #blockId 로 색 명시한 경우 그게 이김 — 자동 fg 는
 * 사용자 미명시 시 default 만 적용.
 *
 * 참고: docs/web-block-patterns-reference.md §1.4 + §5.2 (가독성 4.5:1 AA).
 */
.has-primary-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--primary-fg, currentColor);
}
.has-secondary-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--secondary-fg, currentColor);
}
.has-accent-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--accent-fg, currentColor);
}
.has-background-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--background-fg, currentColor);
}
.has-surface-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--surface-fg, currentColor);
}
.has-foreground-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--text-fg, currentColor);
}
.has-muted-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--muted-fg, currentColor);
}
.has-outline-background-color :where(h1, h2, h3, h4, h5, h6, p, li, blockquote, cite, figcaption) {
  color: var(--wp--preset--color--border-fg, currentColor);
}

/* ── Hero Split (Photo + Column) — button visibility on solid bg ──────────
 *
 * hero-split 패턴은 섹션 자체 bg 가 primary 컬러 케이스가 흔함. theme.json
 * default elements.button (bg=primary, text=primary-fg) 를 그대로 쓰면
 * primary on primary 로 invisible. 사용자 보고 (Korus 2026-05-04): "Photo +
 * Column 으로 바꾸면 버튼 안 보임".
 *
 * 캔버스는 ghost-on-primary + outline-on-primary 변형으로 fix 했고, publish
 * 도 같은 시각 결과를 내도록 — hero-split 안의 버튼 색상을 inverse 로 override.
 *   첫 번째 button (default) — bg=background, text=primary
 *   is-style-outline 이 붙은 button — transparent + background 색 border/text
 */
.is-style-hero-split .wp-block-button:not(.is-style-outline) .wp-block-button__link,
.is-style-hero-split .wp-block-button:not(.is-style-outline) .wp-element-button {
  background-color: var(--wp--preset--color--background, transparent) !important;
  color: var(--wp--preset--color--primary, currentColor) !important;
}
.is-style-hero-split .wp-block-button.is-style-outline .wp-block-button__link,
.is-style-hero-split .wp-block-button.is-style-outline .wp-element-button {
  background-color: transparent !important;
  color: var(--wp--preset--color--background, transparent) !important;
  border: 1.5px solid var(--wp--preset--color--background, transparent) !important;
}

/**
 * Card icon size — features-grid / about-section 카드 안 image (icon).
 * 이전엔 patterns.json 에 width/height '64px' 하드코딩.
 * 2026-07-01 리팩토링 — className 로 이동, theme CSS variable 관리.
 * 사용자가 theme.json 이나 custom CSS 로 override 가능.
 */
:root {
  --dwwp-card-icon-size: 64px;
}
.wp-block-image.is-style-card-icon,
.wp-block-image.is-style-card-icon img {
  width: var(--dwwp-card-icon-size);
  --dwwp-img-h: var(--dwwp-card-icon-size);
  height: var(--dwwp-img-h);
}

/**
 * Card subtitle — features-grid 카드의 H4 서브제목.
 * H3 title 다음, description 이전. 시각적으로 약간 톤 다운.
 * 빈 문자열이면 hide (Phase 12 placeholder cleanup 이 empty text 유지).
 */
.wp-block-heading.is-style-card-subtitle {
  font-size: 0.9em;
  font-weight: 500;
  opacity: 0.8;
  margin-top: -0.25em;
  margin-bottom: 0.25em;
}
.wp-block-heading.is-style-card-subtitle:empty {
  display: none;
}

/**
 * Phase 18 — BlockOptions CSS 규칙.
 * dwwp_apply_block_options() PHP filter 가 root section 에 이 class 들을
 * 부여. Phase 17 자동 결정 + Properties 수동 편집 결과가 시각으로 반영.
 */

/* Columns (grid) — desktop */
.dwwp-cols-1 > .wp-block-columns { grid-template-columns: 1fr; }
.dwwp-cols-2 > .wp-block-columns { grid-template-columns: repeat(2, 1fr); }
.dwwp-cols-3 > .wp-block-columns { grid-template-columns: repeat(3, 1fr); }
.dwwp-cols-4 > .wp-block-columns { grid-template-columns: repeat(4, 1fr); }
.dwwp-cols-5 > .wp-block-columns { grid-template-columns: repeat(5, 1fr); }
.dwwp-cols-6 > .wp-block-columns { grid-template-columns: repeat(6, 1fr); }
.dwwp-cols-1 > .wp-block-columns,
.dwwp-cols-2 > .wp-block-columns,
.dwwp-cols-3 > .wp-block-columns,
.dwwp-cols-4 > .wp-block-columns,
.dwwp-cols-5 > .wp-block-columns,
.dwwp-cols-6 > .wp-block-columns {
  display: grid;
  /* gap = row col (blockOptions.gridRowGap / gridColumnGap). 기본 20px —
   * dasomweb.com/en 실측 확정 (2026-07-16, gap 히스토그램 지배값). */
  gap: var(--dwwp-grid-row-gap, 20px) var(--dwwp-grid-col-gap, 20px);
}

/* 반응형 좌우 여백 (blockOptions.padInlineMobile / padInlineTablet).
 *
 * 문제: 섹션 여백은 native attrs 에서 **인라인**으로 emit 되고, CSS 는 인라인을
 * 특이도로 이길 수 없다 (WP 코어도 margin auto 에 !important 를 쓴다).
 * 해결: 인라인 값을 `padding-left: var(--dwwp-pi, 48px)` 로 바꿔두고
 * (발행 시 _normalize_responsive_padding), 여기서는 **변수만** 바꾼다.
 * 변수 대입은 평범한 선언이라 !important 가 필요 없다.
 *
 * 값이 없는 브레이크포인트는 var() 참조가 무효가 되어 폴백(데스크톱 값)이
 * 그대로 쓰인다 — 모바일만 지정해도 태블릿은 데스크톱 값 유지 (실측 확인).
 * 테마 CSS 가 없는 환경에서도 폴백이 살아 있어 레이아웃이 안 깨진다. */
/* 모바일 좌우 여백 통일 (2026-09-19 사용자: "모든 섹션 모바일 20px 동일").
 * 실측 결과 섹션마다 화면 끝에서 0/20/48/50/69px 로 제각각이었다 —
 * 데스크톱 값(48px 등)이 모바일에 그대로 남고, alignfull 섹션은 루트 여백을
 * 벗어나 0 이 되기 때문.
 *
 * 값을 여기 박지 않는다. 기준은 테마의 루트 여백 토큰
 * (--wp--style--root--padding-left, 이 프로젝트는 clamp(20px,5vw,40px) → 모바일 20px).
 *   · alignfull  — 루트 여백 밖이므로 자기 패딩으로 같은 값을 만든다.
 *   · 그 외      — 루트 여백이 이미 적용돼 있으므로 자기 패딩은 0.
 * 두 경우 모두 콘텐츠가 화면 끝에서 정확히 '루트 여백' 만큼 떨어진다.
 * 블록에 padInlineMobile 이 있으면 그 값이 이긴다 (커스텀 > 패턴 기본 > 토큰). */
/* 2026-09-24 사용자 지시: "모바일은 왼쪽·오른쪽 각각 20px 로 모두 통일.
 * 글자, 이미지 모두." 실측(라이브 390px)은 섹션마다 8 / 20 / 30 / 49 / 58px 로
 * 제각각이었다 — 루트 여백(clamp)·섹션 자기 패딩·밴드 여백이 겹쳐서.
 * 그래서 모바일에서는 **한 곳**만 여백을 만든다: 최상위 섹션의 인라인 좌우
 * 패딩(--dwwp-pi). 루트 여백과 밴드 여백은 0 으로 눕힌다.
 * 섹션에 padInlineMobile 이 있으면 그 값이 이긴다 (커스텀 > 기본). */
/* 모바일 좌우 여백 — 테마 전체의 **단일 값**. 프로젝트가 바꾸려면 이 변수만
 * 재정의하면 된다 (섹션별 예외는 padInlineMobile 속성). 2026-09-24 사용자:
 * "왼쪽, 오른쪽 각각 20px 로 해서 모두 통일". */
:root { --dwwp-pad-mobile: 20px; }

@media (max-width: 640px) {
  .wp-block-post-content,
  .wp-site-blocks > .wp-block-post-content { padding-left: 0; padding-right: 0; }
  .dwwp-rpad,
  .dwwp-rpad.alignfull {
    --dwwp-pi: var(--dwwp-pi-m, var(--dwwp-pad-mobile));
    --dwwp-band: 0px;
  }
  /* 밴드 변수 정의 선택자(0,3,0)와 같은 특이성으로 되돌린다 — 루트 여백 토큰을
   * 더하는 데스크톱 식이 모바일에 새면 여백이 20+20 으로 겹친다 (2026-09-25 실측 40px). */
  .wp-block-columns.alignfull:not(.dwwp-full-content),
  .wp-block-media-text.alignfull:not(.dwwp-full-content) {
    --dwwp-band: 0px;
  }
  /* 인라인 패딩이 없는(레거시) 최상위 섹션도 같은 여백을 갖게 — 구조 선택자라
   * !important 없이 이긴다. 인라인이 있는 섹션은 인라인이 우선. */
  .wp-block-post-content > .wp-block-group,
  .wp-block-post-content > .wp-block-columns,
  .wp-block-post-content > .wp-block-media-text,
  .wp-block-post-content > .wp-block-cover {
    padding-left: var(--dwwp-pad-mobile);
    padding-right: var(--dwwp-pad-mobile);
  }
  /* cover 는 내부 컨테이너가 또 좌우 패딩을 갖는다 — 겹치면 40px 가 된다. */
  .wp-block-post-content > .wp-block-cover > .wp-block-cover__inner-container {
    padding-left: 0;
    padding-right: 0;
  }
}
@media (min-width: 641px) and (max-width: 1024px) {
  .dwwp-rpad { --dwwp-pi: var(--dwwp-pi-t); }
}

/* 스탯 스트립 모바일 — 숫자/라벨을 **가로 한 줄**로.
 *
 * 1열로 쌓으면 숫자와 라벨이 가운데 정렬로 위아래 배치돼 5개가 407px 를
 * 차지하고 휑하다 (2026-09-17 사용자: "한개씩 나오니까 너무 좀 그런데").
 * 2열도 답이 아니다 — 칸이 114px 로 좁아져 "180,000+" 가 "180,00 / 0+" 로
 * 쪼개진다 (실측 스크린샷 확인).
 * 숫자 왼쪽 · 라벨 오른쪽 + 행 사이 헤어라인이 가장 읽기 쉽다: 384px.
 *
 * 구분선은 데스크톱의 세로 구분선과 **같은 데이터**(--dwwp-stat-divider)를
 * 방향만 바꿔 쓴다 — 새 변수를 만들지 않는다. */
@media (max-width: 640px) {
  .is-style-stats-strip > .wp-block-columns {
    gap: 0;
  }
  .is-style-stats-strip > .wp-block-columns > .wp-block-column {
    display: flex;
    align-items: baseline;
    /* 가운데 — 캔버스 모바일 행과 동률. 예전 flex-start/left 는 라이브만 왼쪽 붙음
     * (2026-09-25 사용자: "중앙 정렬도 안 돼 있다"). */
    justify-content: center;
    gap: 10px;
    text-align: center;
    padding-block: 12px;
  }
  /* 첫 칸은 위 여백 없이 카드 상단에 붙고, 둘째 칸부터 헤어라인으로 구분 */
  .is-style-stats-strip > .wp-block-columns > .wp-block-column + .wp-block-column {
    border-top: 1px solid
      var(--dwwp-stat-divider, color-mix(in srgb, currentColor 10%, transparent));
  }
  .is-style-stats-strip.dwwp-stat-nodivider > .wp-block-columns > .wp-block-column
    + .wp-block-column {
    border-top: 0;
  }
  /* 행 안에서는 왼쪽 정렬이 레이아웃의 일부다 — 데스크톱 스택 배치용
   * 가운데 정렬(has-text-align-center)이 남아 있으면 줄바꿈된 라벨이
   * 어정쩡하게 가운데로 몰린다. 데스크톱 값은 그대로 둔다. */
  .is-style-stats-strip > .wp-block-columns > .wp-block-column > * {
    margin: 0;
    text-align: center;
  }
  /* 숫자(또는 로고)는 줄바꿈 없이 자기 폭 유지, 라벨이 남은 폭을 쓴다 */
  .is-style-stats-strip > .wp-block-columns > .wp-block-column > *:first-child {
    flex: 0 0 auto;
  }
  .is-style-stats-strip > .wp-block-columns > .wp-block-column > *:last-child {
    flex: 0 1 auto;
    min-width: 0;
  }
}

/* 모바일 탭 타깃 — 버튼만 최소 높이(44px).
 *
 * 조건은 **폭이 아니라 터치 여부**(pointer: coarse)다 — 폭으로 걸면 768px
 * 태블릿이 빠지고, 마우스로 쓰는 좁은 데스크톱 창에는 불필요하게 적용된다.
 * 푸터 메뉴 링크는 제외 — 링크마다 12px 상하 패딩을 주자 서브메뉴 줄이 50px 로
 * 벌어졌다 (2026-09-25 사용자: "모바일에서 Services/Company 아래 서브메뉴 사이가
 * 완전히 벌어져"). 문장 안 인라인 링크도 건드리지 않는다. */
/* 푸터 메뉴 리스트 — 불릿·들여쓰기 없음 (2026-09-25 사용자: 메뉴 앞 bullet 제거).
 * WP 코어 .wp-block-list 기본(disc + padding-left)을 덮는다. */
ul.wp-block-list.dw-footer-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
}
@media (pointer: coarse) {
  .wp-block-button__link,
  .dw-header-cta-wrap .wp-block-button__link {
    min-height: 44px;
    /* border-box — content-box 면 44 + 상하 패딩(16) = 60px 로 부풀어 모바일 헤더가
     * 111px 까지 커졌다 (2026-09-25 실측). 44px 는 패딩 포함 총 높이. */
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
}

/* media-text 이미지는 자기 칸을 넘지 않는다.
 *
 * WP 코어가 `.wp-block-media-text__media img { max-width: unset }` 을 걸어
 * 두는데, 모바일에서 미디어가 1열로 쌓이면 트랙이 고정폭이 되어 이미지가
 * 원본 크기(525~589px)로 튀어나온다 — 390px 화면에서 가로 스크롤의 주범
 * (2026-09-17 실측: /about/ figure 589px vs 셀 294px, 768px 에서도 +205px).
 *
 * ⚠ 데스크톱에는 걸지 않는다. 전 폭에 적용했더니 1440px 에서 figure 가
 * 527 → 513px 로 줄었다 — 디자인이 정본이므로 모바일/태블릿에서만 제한한다
 * (실측으로 확인, 2026-09-17). */
@media (max-width: 1024px) {
  .wp-block-media-text__media {
    max-width: 100%;
    overflow: hidden;
  }
  .wp-block-media-text__media img,
  .wp-block-media-text__media video {
    max-width: 100%;
  }
}

/* Columns — mobile responsive. blockOptions.columnsMobile 이 명시되면 그 값
 * (dwwp-cols-mobile-N), 미설정이면 **1열**이 기본이다.
 *
 * 이 기본 폴백이 없어서 columnsMobile 을 안 넣은 섹션은 모바일에서도
 * 데스크톱 열 수를 그대로 유지했다 — 390px 에서 5열이 남아 칸마다 56px 로
 * 찌그러지고 페이지가 가로로 247px 넘쳤다 (2026-09-17 실측: /about/ p32-b188.
 * 같은 패턴인 홈 p29-b15 는 dwwp-cols-mobile-1 이 있어 멀쩡했다).
 * 캔버스는 이미 `columnsMobile || 1` 규칙이었으므로 라이브만 어긋나 있었다. */
@media (max-width: 640px) {
  .dwwp-cols-mobile-1 > .wp-block-columns { grid-template-columns: 1fr; }
  .dwwp-cols-mobile-2 > .wp-block-columns { grid-template-columns: repeat(2, 1fr); }
  .dwwp-cols-mobile-3 > .wp-block-columns { grid-template-columns: repeat(3, 1fr); }
  .dwwp-cols-mobile-4 > .wp-block-columns { grid-template-columns: repeat(4, 1fr); }
  /* default fallback — columnsMobile 미설정 섹션만 (mobile 클래스 없을 때) */
  .dwwp-cols-2:not([class*="dwwp-cols-mobile-"]) > .wp-block-columns,
  .dwwp-cols-3:not([class*="dwwp-cols-mobile-"]) > .wp-block-columns,
  .dwwp-cols-4:not([class*="dwwp-cols-mobile-"]) > .wp-block-columns,
  .dwwp-cols-5:not([class*="dwwp-cols-mobile-"]) > .wp-block-columns,
  .dwwp-cols-6:not([class*="dwwp-cols-mobile-"]) > .wp-block-columns { grid-template-columns: 1fr; }
  /* 브랜드 로고 행 — 모바일 로고 높이(--dwwp-logo-h-m) + 한 줄 개수(columnsMobile).
   * 데스크톱 규칙은 .dw-logo-strip .dwwp-logos 절 참조 (2026-09-25). */
  .dw-logo-strip .dwwp-logos img { --dwwp-img-h: var(--dwwp-logo-h-m); height: var(--dwwp-img-h); }
  .dw-logo-strip.dwwp-cols-mobile-1:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 100%; }
  .dw-logo-strip.dwwp-cols-mobile-2:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 1) / 2); }
  .dw-logo-strip.dwwp-cols-mobile-3:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 2) / 3); }
  .dw-logo-strip.dwwp-cols-mobile-4:not(.dwwp-logos-carousel) > .dwwp-logos > .wp-block-image { flex: 0 0 calc((100% - var(--dwwp-logo-gap) * 3) / 4); }
}

/* Columns — tablet responsive. blockOptions.columnsTablet 이 명시되면 그 값을
 * 우선 사용 (dwwp-cols-tablet-N). 미설정 섹션은 아래 default fallback
 * (desktop 3/4/5/6 → 태블릿 2). 캔버스 previewBp=tablet 로직과 동일. */
@media (min-width: 641px) and (max-width: 1024px) {
  .dwwp-cols-tablet-1 > .wp-block-columns { grid-template-columns: 1fr; }
  .dwwp-cols-tablet-2 > .wp-block-columns { grid-template-columns: repeat(2, 1fr); }
  .dwwp-cols-tablet-3 > .wp-block-columns { grid-template-columns: repeat(3, 1fr); }
  .dwwp-cols-tablet-4 > .wp-block-columns { grid-template-columns: repeat(4, 1fr); }
  /* default fallback — columnsTablet 미설정 섹션만 (tablet 클래스 없을 때) */
  .dwwp-cols-3:not([class*="dwwp-cols-tablet-"]) > .wp-block-columns,
  .dwwp-cols-4:not([class*="dwwp-cols-tablet-"]) > .wp-block-columns,
  .dwwp-cols-5:not([class*="dwwp-cols-tablet-"]) > .wp-block-columns,
  .dwwp-cols-6:not([class*="dwwp-cols-tablet-"]) > .wp-block-columns { grid-template-columns: repeat(2, 1fr); }
}

/* 카드 그리드 제목 높이 통일 — 1줄/2줄 제목이 섞여도 카드(제목↔본문)가 정렬
 * 되도록 2줄 min-height (2026-07-04 사용자). dwwp-cols-* 카드 그리드에만 적용
 * (text-split 등 일반 2단은 제외). */
[class*="dwwp-cols-"] > .wp-block-columns > .wp-block-column > .wp-block-heading {
  /* 2줄 min-height(2.5em) 는 캔버스에 없는 라이브 전용 간격이라 제목↔설명이 벌어졌다
   * (2026-09-25 p31-b46 사용자: "간격도 디자인 패널 형태로"). 캔버스와 동률 = 0. */
  min-height: 0;
}
/* 카드 안쪽 간격 = 섹션 속성 cardGap(--dwwp-card-gap, 기본 4 = PATTERN_DEFAULT_OPTIONS).
 * 아이콘 래퍼(.wp-block-image 1em)·제목(0.6em)·부제 문단(1em)의 범용 margin 을
 * 카드 그리드 안에서만 같은 값으로 통일 — 캔버스 space-y 와 동률. 마지막 요소는 0. */
[class*="dwwp-cols-"] > .wp-block-columns > .wp-block-column > .wp-block-image,
[class*="dwwp-cols-"] > .wp-block-columns > .wp-block-column > .dwwp-lucide-icon-wrap,
[class*="dwwp-cols-"] > .wp-block-columns > .wp-block-column > .wp-block-heading,
[class*="dwwp-cols-"] > .wp-block-columns > .wp-block-column > p {
  margin-bottom: var(--dwwp-card-gap, 4px);
}
[class*="dwwp-cols-"] > .wp-block-columns > .wp-block-column > :last-child {
  margin-bottom: 0;
}
/* 카드 제목 링크(items[].titleUrl) — 제목 색·장식을 그대로 (링크색/밑줄이 덮어쓰면
 * 디자인 패널(검정)과 라이브(주황 밑줄)가 갈라진다, 2026-09-25 p31-b46). */
:is(h1, h2, h3, h4, h5, h6).wp-block-heading a {
  color: inherit;
  text-decoration: none;
}
:is(h1, h2, h3, h4, h5, h6).wp-block-heading a:hover {
  text-decoration: underline;
}
/* 스탯 스트립은 카드가 아님 — 위 2줄 min-height 가 숫자 박스를 75px 로
 * 부풀려 숫자↔라벨 간격이 벌어짐 (2026-09-06 실측: 사용자 "gap 너무 커"). */
.is-style-stats-strip > .wp-block-columns > .wp-block-column > .wp-block-heading {
  min-height: 0;
}
/* 서비스 분할 카드는 1열 스택 — 제목 높이 통일이 무의미하고, 2.5em(45px)
 * min-height 가 제목↔설명 간격을 원본(8px)의 4배로 벌림 (2026-09-06 실측 b146).
 * 원 규칙이 (0,4,0) 이라 opt-out 도 4단 직계로 동률 특이성 + 후순위 승리. */
.dw-service-split > .wp-block-columns > .wp-block-column > .wp-block-heading {
  min-height: 0;
}

/* 카드 이미지 비율 통일 (imageAspect) — 카드 안 이미지를 지정 비율로 crop해
 * 카드 높이를 균일하게 (2026-07-04 사용자: 이미지 크기 제각각 방지). 배경
 * 이미지(cover)엔 미적용 — 카드(column) 안 wp-block-image 만. */
.dwwp-card-img-aspect .wp-block-column .wp-block-image:not(.dw-icon-img) {
  aspect-ratio: var(--dwwp-card-img-aspect, 4 / 3);
  overflow: hidden;
}
.dwwp-card-img-aspect .wp-block-column .wp-block-image:not(.dw-icon-img) img {
  width: 100%;
  --dwwp-img-h: 100%;
  height: var(--dwwp-img-h);
  object-fit: cover;
}

/* 아이콘 대체 이미지 (v1.5.53) — 사용자가 아이콘 자리에 넣은 이미지는 카드
 * 전폭이 아니라 아이콘 크기로. 크기 = 기존 Icon Size 옵션(--dwwp-icon-size)
 * 공유 (섹션 STYLE > 상세 옵션 > 아이콘에서 조절). 정렬은 카드 정렬을 따름. */
.wp-block-column figure.wp-block-image.dw-icon-img {
  width: auto;
  height: auto;
  margin: 0 0 4px;
}
/* is-style-card-icon 의 고정(--dwwp-card-icon-size, 정사각) 규칙(0,2,1)을
 * 이기도록 동급 특이도 + 후순위 (v1.5.55 — 72px 설정이 64px 로 눌리던 실측). */
figure.wp-block-image.dw-icon-img img,
.wp-block-image.dw-icon-img img {
  width: var(--dwwp-icon-size, 48px);
  height: auto;
}
.dwwp-align-center .wp-block-column .dw-icon-img { display: flex; justify-content: center; }
.dwwp-align-right .wp-block-column .dw-icon-img { display: flex; justify-content: flex-end; }

/* Card style — 각 column 을 카드로 취급. border 굵기·색, padding, shadow 는
 * blockOptions CSS 변수(--dwwp-card-*)로 조정 가능. 미설정 시 스타일별 기본값. */
.dwwp-card-outlined > .wp-block-columns > .wp-block-column {
  border: var(--dwwp-card-border-width, 1px) solid
    var(--dwwp-card-border-color, var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)));
  border-radius: var(--dwwp-card-radius, 14px); /* 2026-07-14 모던 기본 */
  padding: var(--dwwp-card-padding, 26px);
  background: var(--dwwp-card-bg, transparent);
  box-shadow: var(--dwwp-card-shadow, none);
}
.dwwp-card-filled > .wp-block-columns > .wp-block-column {
  background: var(--dwwp-card-bg, var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent)));
  border: var(--dwwp-card-border-width, 0px) solid var(--dwwp-card-border-color, transparent);
  border-radius: var(--dwwp-card-radius, 14px); /* 2026-07-14 모던 기본 */
  padding: var(--dwwp-card-padding, 26px);
  box-shadow: var(--dwwp-card-shadow, none);
}
.dwwp-card-elevated > .wp-block-columns > .wp-block-column {
  background: var(--dwwp-card-bg, var(--wp--preset--color--background, transparent));
  border: var(--dwwp-card-border-width, 0px) solid var(--dwwp-card-border-color, transparent);
  border-radius: var(--dwwp-card-radius, 14px); /* 2026-07-14 모던 기본 */
  padding: var(--dwwp-card-padding, 26px);
  box-shadow: var(--dwwp-card-shadow, 0 4px 12px rgba(0, 0, 0, 0.08));
}
.dwwp-card-flat > .wp-block-columns > .wp-block-column {
  background: var(--dwwp-card-bg, transparent);
  border: var(--dwwp-card-border-width, 0px) solid var(--dwwp-card-border-color, transparent);
  border-radius: var(--dwwp-card-radius, 0px);
  padding: var(--dwwp-card-padding, 16px 8px);
  box-shadow: var(--dwwp-card-shadow, none);
}

/* 카드 안 quote (testimonials) — 기본 좌측 보더/이탤릭 톤 다운 (2026-07-14). */
[class*="dwwp-card-"] > .wp-block-columns > .wp-block-column .wp-block-quote {
  border: 0;
  margin: 0;
  padding: 0;
  font-style: normal;
}
[class*="dwwp-card-"] > .wp-block-columns > .wp-block-column .wp-block-quote cite {
  display: block;
  margin-top: 14px;
  font-size: 0.8rem;
  font-style: normal;
  font-weight: 600;
  opacity: 0.65;
}

/* 카드 가로 레이아웃 (dwwp-card-layout-h, 2026-07-14) — 아이콘/이미지 좌측
 * 고정 컬럼 + 텍스트(제목/부제/설명) 우측. Top-Down 스택의 가로형 변형. */
.dwwp-card-layout-h > .wp-block-columns > .wp-block-column {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 16px;
  align-items: start;
  text-align: left;
}
.dwwp-card-layout-h > .wp-block-columns > .wp-block-column > .wp-block-image,
.dwwp-card-layout-h > .wp-block-columns > .wp-block-column > .dwwp-lucide-icon-wrap {
  grid-column: 1;
  grid-row: 1 / span 6;
  margin: 0;
}
.dwwp-card-layout-h > .wp-block-columns > .wp-block-column > .wp-block-heading,
.dwwp-card-layout-h > .wp-block-columns > .wp-block-column > p,
.dwwp-card-layout-h > .wp-block-columns > .wp-block-column > .wp-block-buttons {
  grid-column: 2;
}

/* Card alignment — text alignment 안 카드 안 element */
.dwwp-align-left > .wp-block-columns > .wp-block-column {
  text-align: left;
}
.dwwp-align-center > .wp-block-columns > .wp-block-column {
  text-align: center;
}
.dwwp-align-right > .wp-block-columns > .wp-block-column {
  text-align: right;
}
.dwwp-align-center > .wp-block-columns > .wp-block-column > .wp-block-image {
  margin-left: auto;
  margin-right: auto;
}
/* 아이콘(lucide) 정렬 — .dwwp-lucide-icon-wrap 은 flex(justify-center 기본)라
 * 컬럼 text-align 이 안 먹는다. cardAlignment 에 맞춰 justify 조정해야 라이브가
 * 캔버스(_iconJustify)와 일치 (2026-07-03 사용자 보고: 아이콘 정렬 반영 안됨). */
.dwwp-align-left > .wp-block-columns > .wp-block-column .dwwp-lucide-icon-wrap {
  justify-content: flex-start;
}
.dwwp-align-right > .wp-block-columns > .wp-block-column .dwwp-lucide-icon-wrap {
  justify-content: flex-end;
}
/* 도형 래퍼는 고정폭 + margin:0 auto (위 도형 공통 규칙)라 justify 로는 타일
 * 자체가 안 움직인다 — margin 도 정렬을 따라야 라이브가 캔버스와 일치
 * (2026-07-15 사용자: "재발행해도 아이콘 정렬 안 됨" 근본). 셀렉터 특이성이
 * 도형 규칙(0,2,0)보다 높아(0,4,0) 순서 무관하게 이긴다. */
.dwwp-align-left > .wp-block-columns > .wp-block-column .dwwp-lucide-icon-wrap {
  margin-left: 0;
  margin-right: auto;
}
.dwwp-align-right > .wp-block-columns > .wp-block-column .dwwp-lucide-icon-wrap {
  margin-left: auto;
  margin-right: 0;
}

/* 요소 단위 정렬 (2026-07-16) — 아이콘/이미지의 align{X} 클래스가 섹션
 * cardAlignment(dwwp-align-*) 기본을 이긴다 (요소 명시 = 최우선, !important 는
 * (0,4,0) 섹션 규칙을 확실히 이기기 위한 의도적 사용). */
.wp-block-column .wp-block-image.alignleft,
.dwwp-lucide-icon-wrap.alignleft {
  margin-left: 0 !important;
  margin-right: auto !important;
}
.wp-block-column .wp-block-image.aligncenter,
.dwwp-lucide-icon-wrap.aligncenter {
  margin-left: auto !important;
  margin-right: auto !important;
}
.wp-block-column .wp-block-image.alignright,
.dwwp-lucide-icon-wrap.alignright {
  margin-left: auto !important;
  margin-right: 0 !important;
}

/* Image style — 카드 안 image 형태 */
.dwwp-image-square > .wp-block-columns > .wp-block-column > .wp-block-image:not(.dw-icon-img) img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 8px;
  width: 100%;
  height: auto;
}
.dwwp-image-circle > .wp-block-columns > .wp-block-column > .wp-block-image:not(.dw-icon-img) img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 50%;
  width: 100%;
  height: auto;
}
.dwwp-image-wide > .wp-block-columns > .wp-block-column > .wp-block-image:not(.dw-icon-img) img {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: 8px;
  width: 100%;
  height: auto;
}
.dwwp-image-card-width > .wp-block-columns > .wp-block-column > .wp-block-image:not(.dw-icon-img) img {
  width: 100%;
  height: auto;
  border-radius: 8px 8px 0 0;
  display: block;
}
/* 풀블리드는 "사진" 전용 — 아이콘(lucide 래퍼/카드 아이콘/커스텀 SVG)은 제외.
 * 아이콘 래퍼도 wp-block-image 클래스를 가져서 이 음수 마진에 걸리면 타일이
 * 카드 패딩(26px)을 뚫고 모서리에 박힘 (2026-07-15 사용자 "아이콘이 왼쪽에
 * 딱 붙는다" — 라이브 computed margin -24px 실측으로 확정). */
.dwwp-image-card-width > .wp-block-columns > .wp-block-column > .wp-block-image:not(.dwwp-lucide-icon-wrap):not(.is-style-card-icon):not(.dw-card-icon-svg) {
  margin: -24px -24px 16px -24px;
}

/* ── Lucide 아이콘 배경 도형 (features-grid icon 카드) ──────────────────────
 * dwwp_render_lucide_svg 가 .dwwp-lucide-icon-wrap 으로 감싸고, 섹션 루트가
 * blockOptions 로 .dwwp-icon-{shape} + --dwwp-icon-* CSS 변수를 받는다.
 * 색은 theme 토큰(var(--wp--preset--color--*)) 참조 — 하드코딩 없음. */
.dwwp-lucide-icon-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0; /* 기본(도형 없음) — 아이콘만 */
}
.dwwp-lucide-icon-wrap .dwwp-lucide-icon {
  color: var(--dwwp-icon-color, currentColor);
  /* 크기·굵기 조정 — blockOptions.iconSize / iconStroke. SVG 의 width/height/
   * stroke-width 속성보다 CSS 가 우선. 미설정 시 48px / 1.5. */
  width: var(--dwwp-icon-size, 48px);
  height: var(--dwwp-icon-size, 48px);
  stroke-width: var(--dwwp-icon-stroke, 1.5);
}

/* 도형 공통 — 컨테이너화 (fill/border/size/padding). 색·굵기는 변수로 override. */
.dwwp-icon-circle .dwwp-lucide-icon-wrap,
.dwwp-icon-rounded .dwwp-lucide-icon-wrap,
.dwwp-icon-squircle .dwwp-lucide-icon-wrap,
.dwwp-icon-square .dwwp-lucide-icon-wrap,
.dwwp-icon-blob .dwwp-lucide-icon-wrap,
.dwwp-icon-hexagon .dwwp-lucide-icon-wrap,
.dwwp-icon-triangle .dwwp-lucide-icon-wrap {
  /* 배경 도형 크기 — iconBgSize 명시 시 그 값, 없으면 아이콘 크기×1.5 (기존
   * 비례). 아이콘과 독립 조정 가능 (2026-07-04 사용자). */
  width: var(--dwwp-icon-bg-size, calc(var(--dwwp-icon-size, 48px) * 1.5));
  height: var(--dwwp-icon-bg-size, calc(var(--dwwp-icon-size, 48px) * 1.5));
  margin: 0 auto 4px;
  padding: 0;
  background: var(--dwwp-icon-bg, color-mix(in srgb, var(--wp--preset--color--primary, currentColor) 12%, transparent));
  color: var(--dwwp-icon-color, var(--wp--preset--color--primary, currentColor));
}
/* border 는 radius 계열 도형에만 적용 (clip-path 는 테두리 클리핑됨) */
.dwwp-icon-circle .dwwp-lucide-icon-wrap,
.dwwp-icon-rounded .dwwp-lucide-icon-wrap,
.dwwp-icon-squircle .dwwp-lucide-icon-wrap,
.dwwp-icon-square .dwwp-lucide-icon-wrap,
.dwwp-icon-blob .dwwp-lucide-icon-wrap {
  border: var(--dwwp-icon-border-width, 0) solid var(--dwwp-icon-border-color, transparent);
}
.dwwp-icon-circle .dwwp-lucide-icon-wrap { border-radius: 50%; }
.dwwp-icon-rounded .dwwp-lucide-icon-wrap { border-radius: 16px; }
.dwwp-icon-squircle .dwwp-lucide-icon-wrap { border-radius: 32%; }
.dwwp-icon-square .dwwp-lucide-icon-wrap { border-radius: 0; }
/* blob — 붓칠/유기적 형태 (비대칭 radius) */
.dwwp-icon-blob .dwwp-lucide-icon-wrap {
  border-radius: 42% 58% 63% 37% / 41% 44% 56% 59%;
}
/* clip-path 도형 (fill only) */
.dwwp-icon-hexagon .dwwp-lucide-icon-wrap {
  clip-path: polygon(50% 0%, 93% 25%, 93% 75%, 50% 100%, 7% 75%, 7% 25%);
}
.dwwp-icon-triangle .dwwp-lucide-icon-wrap {
  clip-path: polygon(50% 6%, 96% 94%, 4% 94%);
}
.dwwp-icon-triangle .dwwp-lucide-icon { transform: translateY(4px); }

/* Section 자체에 background image */
.dwwp-has-bg-image {
  padding: 60px 20px;
  color: #fff;
  position: relative;
}
.dwwp-has-bg-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 0;
  pointer-events: none;
}
.dwwp-has-bg-image > * {
  position: relative;
  z-index: 1;
}

/* Numbered steps — blockOptions.numbered → dwwp-numbered. 카드에 01·02·03
   워터마크 숫자 (CSS counter). 캔버스는 index 기반 숫자 div 로 동일 표현.
   v1.5.51: dwwp-steps-intro(넘버드 스텝 패턴)는 숫자가 레이아웃 정체성이라
   플래그 없이도 항상 숫자 표시 — 레이아웃 스왑이 blockOptions 를 비우면
   "보였다 안 보였다" 하던 사고 방지. 숫자 크기/색/투명도는 --dwwp-step-num-*
   변수 (blockOptions numberSize/numberColor/numberOpacity → functions.php). */
.dwwp-numbered .wp-block-columns,
.dwwp-steps-intro .wp-block-columns { counter-reset: dwwp-step; }
.dwwp-numbered .wp-block-column,
.dwwp-steps-intro .wp-block-column {
  position: relative;
  counter-increment: dwwp-step;
}
.dwwp-numbered .wp-block-column::before,
.dwwp-steps-intro .wp-block-column::before {
  content: counter(dwwp-step, decimal-leading-zero);
  display: block;
  font-size: var(--dwwp-step-num-size, 2.75rem);
  font-weight: 800;
  line-height: 1;
  color: var(--dwwp-step-num-color, var(--wp--preset--color--primary, currentColor));
  opacity: var(--dwwp-step-num-opacity, 0.22);
  margin-bottom: 0.25rem;
}

/* Steps (Intro + Numbered) — 좌측 인트로 + 우측 넘버드 스텝 카드.
   pattern features-steps-intro. 넘버드 워터마크는 dwwp-numbered 재사용. */
@media (min-width: 782px) {
  .wp-block-group.dwwp-steps-intro {
    display: grid;
    /* 인트로:카드 컬럼 비율 — blockOptions.introRatio ("1:2" 등) →
       --dwwp-steps-intro-cols (v1.5.52, 2026-07-18 사용자). 기본 1:2. */
    grid-template-columns: var(--dwwp-steps-intro-cols, minmax(0, 1fr) minmax(0, 2fr));
    gap: 2.5rem;
    align-items: start;
  }
}
.dwwp-steps-intro .dwwp-steps-intro__cards { margin-top: 0; }

/* == 히어로 보존 리스트 -> 칩 (v1.5.40) ================================
 * handoff [Hero Bullets] 가 cover 안에서 기본 ul 로 밋밋하게 나오던 것.
 * 캔버스 hero 칩 렌더와 parity. */
.wp-block-cover ul.dwwp-hero-list {
  list-style: none; padding: 0; margin: 18px auto 6px;
  display: flex; flex-wrap: wrap; gap: 8px 10px; justify-content: center;
}
.wp-block-cover ul.dwwp-hero-list > li {
  margin: 0; padding: 6px 14px; border-radius: 999px;
  font-size: 14px; line-height: 1.4;
  background: rgba(255,255,255,0.12);
  border: 1px solid rgba(255,255,255,.28);
}
.wp-block-cover ul.dwwp-hero-list > li::before { content: none; }

/* == Constrained header/footer (v1.5.42) ================================
 * headerWidth/footerWidth=constrained — 이전의 inline max-width var 는 attrs
 * 와 불일치해 WP validator INVALID (2026-07-16 GT 실측). 클래스로 이동.
 * !important: .alignfull{max-width:none!important} fallback 대비. */
.wp-block-group.dw-constrained {
  max-width: var(--wp--style--global--content-size, 100%) !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* 커스텀 헤더 폭 (v1.5.48) — 레이아웃(contentSize)보다 넓게도 지정 가능.
 * 값은 theme.json settings.custom.dw.headerMaxWidth (WP 가 변수로 auto-emit).
 * dw-constrained 와 같은 특이도 — 뒤에 와서 이김. */
.wp-block-group.dw-header-custom {
  max-width: var(--wp--custom--dw--header-max-width, var(--wp--style--global--content-size, 100%)) !important;
}

/* 배경 full-width + 콘텐츠는 레이아웃 폭 (v1.5.56) — 헤더/푸터가 배경색은
 * viewport 전체로 펼치되 안쪽 콘텐츠는 contentSize 로 정렬. alignfull(배경
 * 전체폭) + 이 클래스(좌우 padding 을 gutter 로 계산)로 래퍼 없이 full-bleed
 * 배경 구현. inline padding 을 이기려 !important. dw-header-custom 과 함께면
 * 커스텀 폭 기준. */
.wp-block-group.dw-fullbg-constrained {
  padding-left: max(24px, calc((100% - var(--wp--style--global--content-size, 100%)) / 2)) !important;
  padding-right: max(24px, calc((100% - var(--wp--style--global--content-size, 100%)) / 2)) !important;
}
.wp-block-group.dw-fullbg-constrained.dw-header-custom {
  padding-left: max(24px, calc((100% - var(--wp--custom--dw--header-max-width, var(--wp--style--global--content-size, 100%))) / 2)) !important;
  padding-right: max(24px, calc((100% - var(--wp--custom--dw--header-max-width, var(--wp--style--global--content-size, 100%))) / 2)) !important;
}

/* == Contact split (v1.5.43) — 좌 정보 / 우 폼 카드 ======================
 * 디자인 패턴 패밀리 (2026-07-16 사용자 레퍼런스). */
.dw-contact-split .dw-contact-split-cols > .wp-block-columns {
  display: grid; grid-template-columns: 1fr 1.1fr; gap: 48px; align-items: start;
}
@media (max-width: 781px) {
  .dw-contact-split .dw-contact-split-cols > .wp-block-columns { grid-template-columns: 1fr; gap: 28px; }
}
.dw-contact-split .dw-contact-split-info { text-align: left; }
/* 연락처 정보(이메일/전화/주소)는 세로 1줄씩 — 실제 구조는 columns 자체에
 * .dw-contact-info-list 가 붙음 (v1.5.47: 이전 셀렉터가 존재하지 않는 wrapper
 * 구조를 겨냥해 미매칭 → WP 기본 가로 3열로 렌더되던 버그, 2026-07-16 사용자). */
.dw-contact-split .wp-block-columns.dw-contact-info-list {
  display: flex; flex-direction: column; flex-wrap: nowrap; gap: 18px; margin-top: 10px;
}
.dw-contact-split .wp-block-columns.dw-contact-info-list > .wp-block-column {
  flex: 0 0 auto; width: 100%;
}
/* 아이콘 칸은 **아이콘이 있을 때만** 잡는다. 무조건 40px 을 두면 원본에
 * 아이콘이 없는 연락처(유령 아이콘 제거분)에서 왼쪽에 62px 빈 칸이 남고
 * 글자가 밀린다 (2026-09-17 실측, 사용자 "왠 공백? 글자가 middle 정렬
 * 되야지"). 캔버스는 이미 hasIcon 조건부라 발행만 어긋나 있었다. */
.dw-contact-split .dw-contact-info-row {
  display: grid; grid-template-columns: 1fr; column-gap: 14px; align-items: center;
}
.dw-contact-split .dw-contact-info-row:has(.dwwp-lucide-icon-wrap),
.dw-contact-split .dw-contact-info-row:has(> .wp-block-image),
.dw-contact-split .dw-contact-info-row:has(> figure) {
  grid-template-columns: var(--dwwp-icon-bg-size, 40px) 1fr;
}
/* 행 구분선 — 원본 연락처 목록은 행마다 상단 헤어라인으로 구분된다
 * (.dwwp-v4-cd{border-top:1px solid …}, 2026-09-14 사용자 "그리고 밑줄은?").
 * bo itemDividers/dividerColor 를 스탯과 **같은 어휘**로 재사용 — 소비 3벌이
 * 이미 --dwwp-stat-divider 를 emit 하므로 새 변수/배선이 필요 없다.
 * 켜고 끄기 = 섹션 속성 itemDividers (패턴 기본 꺼짐 → .dwwp-stat-nodivider).
 * 예전엔 색이 없으면 transparent 라 '켜짐'으로 바꿔도 선이 안 보였고, 캔버스는
 * 켜짐이면 테두리 색으로 그려 갈라졌다 (2026-09-22). 색 기본 = 테두리 토큰. */
.dw-contact-split .dw-contact-info-row {
  border-top: 1px solid var(--dwwp-stat-divider, var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)));
}
.dw-contact-split.dwwp-stat-nodivider .dw-contact-info-row {
  border-top: 0;
}
.dw-contact-split .dw-contact-info-row .dwwp-lucide-icon-wrap {
  width: var(--dwwp-icon-bg-size, 40px); height: var(--dwwp-icon-bg-size, 40px); border-radius: 10px; margin: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--dwwp-icon-bg, color-mix(in srgb, var(--wp--preset--color--primary, currentColor) 10%, transparent));
  color: var(--dwwp-icon-color, var(--wp--preset--color--primary, currentColor));
}
.dw-contact-split .dw-contact-info-row .dwwp-lucide-icon-wrap svg {
  width: var(--dwwp-icon-size, 18px); height: var(--dwwp-icon-size, 18px);
}
.dw-contact-split .dw-contact-info-row h4 {
  margin: 0; font-size: var(--wp--preset--font-size--caption, 12px); font-weight: 500; opacity: .72;
}
.dw-contact-split .dw-contact-info-row p {
  margin: 2px 0 0; font-size: 15px; font-weight: 600;
}
/* 글자를 2열에 놓는 것도 아이콘 칸이 **있을 때만**. 1열 그리드에 grid-column:2 를
 * 남겨두면 브라우저가 오른쪽에 암시적 열을 만들어 글자가 우측으로 밀린다
 * (2026-09-17 실측: 아이콘 없는 행 488px+197px, 글자 x=510 — 사용자 "누가 우측 정렬?"). */
.dw-contact-split .dw-contact-info-row:has(.dwwp-lucide-icon-wrap) :is(h4, p),
.dw-contact-split .dw-contact-info-row:has(> .wp-block-image) :is(h4, p),
.dw-contact-split .dw-contact-info-row:has(> figure) :is(h4, p) {
  grid-column: 2;
}
.dw-contact-split .dw-contact-info-row .wp-block-image { grid-row: 1 / span 2; grid-column: 1; margin: 0; }
.dw-contact-split .dw-contact-form-card {
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 20px; padding: 28px; min-height: 240px;
}

/* contact-split 폼 위치 좌/우 (v1.5.44) — 루트 dw-form-left 토큰이 정본.
 * DOM 순서 불변(콘텐츠/발행 안정), 시각 순서만 스왑. */
.dw-contact-split.dw-form-left .dw-contact-split-cols > .wp-block-columns > .wp-block-column:first-child { order: 2; }
.dw-contact-split.dw-form-left .dw-contact-split-cols > .wp-block-columns > .wp-block-column:last-child { order: 1; }


/* ── contact-form-card (승격 2026-09-18) — 좌 폼 카드 / 우 정보 카드 ──
 * 원본: Team Logix 견적 요청 p40-b25 실측.
 * 좌 = 라운드 보더 카드(폼 숏코드), 우 = 연회색 카드(overline / 주소 /
 * 영업시간 / 이미지 / 헤어라인 / 전화·이메일 강조 링크).
 * 색·굵기는 전부 토큰 참조 — 브랜드 hex 금지 (PALETTE_FALLBACK 정책). */
/* 전역 :where(.wp-block-group){padding:75px 0} 무력화 — 중첩 group 마다
 * 쌓이면 카드가 위아래로 벌어진다 (feedback_dwwp_global_group_padding). */
.dw-cfc .dw-cfc-cols { padding: 0; }
.dw-cfc .dw-cfc-cols {
  display: grid;
  /* 비율은 패널의 Split Ratio 가 정한다 (기본 50:50). */
  grid-template-columns: var(--dwwp-split-cols, minmax(0, 1fr) minmax(0, 1fr));
  gap: 40px;
  align-items: start;
}
@media (max-width: 781px) {
  .dw-cfc .dw-cfc-cols { grid-template-columns: 1fr; gap: 24px; }
}
/* 카드 모서리·패딩 = 섹션 속성(두 카드 공통), 폼 카드 배경·테두리 = 카드 배경/테두리
 * 속성. 예전엔 16px/28px 를 박아 패널 값이 적용되지 않았다 (2026-09-22). 패턴
 * 기본(16/28/background)은 PATTERN_DEFAULT_OPTIONS 데이터 — 괄호 값과 동일. */
.dw-cfc .dw-cfc-form {
  border: var(--dwwp-card-border-width, 1px) solid var(--dwwp-card-border-color, var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)));
  border-radius: var(--dwwp-card-radius, 16px);
  padding: var(--dwwp-card-padding, 28px);
  background: var(--dwwp-card-bg, var(--wp--preset--color--background, transparent));
}
.dw-cfc .dw-cfc-info {
  background: var(--wp--preset--color--surface, color-mix(in srgb, currentColor 4%, transparent));
  border-radius: var(--dwwp-card-radius, 16px);
  padding: var(--dwwp-card-padding, 28px);
  /* 정보 카드 글자색 — 미지정이면 상속. 개별 요소에 색을 지정하면 그 인라인
   * 값이 이긴다 (커스텀 > 섹션 > 토큰). */
  color: var(--dwwp-info-text, inherit);
}
.dw-cfc .dw-cfc-info > * { margin-block: 0; }
.dw-cfc .dw-cfc-addr {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.45;
  margin-top: 10px;
}
.dw-cfc .dw-cfc-hours {
  font-size: 15px;
  margin-top: 6px;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
}
.dw-cfc .dw-cfc-img { margin-top: 18px; }
/* 원본 실측 비율 ≈2:1 (가로로 넓은 크롭). 비율은 패널의 Image Aspect 가
 * emit 하는 기존 변수를 그대로 소비 — 새 변수를 만들지 않는다. */
.dw-cfc .dw-cfc-img img {
  width: 100%;
  aspect-ratio: var(--dwwp-card-img-aspect, 2 / 1);
  object-fit: cover;
  border-radius: 10px;
  display: block;
}
/* 전화·이메일 — 헤어라인으로 구분된 강조색 링크 스택 */
.dw-cfc .dw-cfc-links {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
}
.dw-cfc .dw-cfc-links > .wp-block-column {
  flex: 0 0 auto;
  width: 100%;
  /* 칸 기본 패딩(8px)이 행마다 위아래로 붙어 캔버스(10px)보다 26px 벌어졌다
   * (2026-09-18 라이브 실측: 행 높이 41px). 간격은 gap 만으로 정한다. */
  padding: 0;
}
.dw-cfc .dw-cfc-link p,
.dw-cfc .dw-cfc-link a {
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--wp--preset--color--accent, currentColor);
  text-decoration: none;
}
.dw-cfc .dw-cfc-link a:hover { text-decoration: underline; }

/* ── Contact Form (dwwp_contact_form 숏코드) — 카드형 폼 (2026-08-07 디자인) ── */
.dwwp-contact-form {
  background: var(--wp--preset--color--background, transparent);
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 16px;
  padding: 32px;
}
.dwwp-cf-hp { position: absolute !important; left: -9999px !important; height: 0; overflow: hidden; }
.dwwp-cf-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px 24px; margin: 0; }
.dwwp-cf-field { margin: 0; }
.dwwp-cf-field.dwwp-cf-full { grid-column: 1 / -1; }
.dwwp-cf-field label { display: block; font-weight: 700; font-size: 15px; }
.dwwp-cf-field label i { color: var(--wp--preset--color--primary, currentColor); font-style: normal; }
.dwwp-cf-field input,
.dwwp-cf-field select,
.dwwp-cf-field textarea {
  display: block; width: 100%; margin-top: 8px;
  padding: 13px 14px; font: inherit; font-size: 15px;
  color: var(--wp--preset--color--foreground, currentColor);
  background: var(--wp--preset--color--background, transparent);
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 10px; outline: none;
}
.dwwp-cf-field input:focus,
.dwwp-cf-field select:focus,
.dwwp-cf-field textarea:focus { border-color: var(--wp--preset--color--primary, currentColor); }
.dwwp-cf-field textarea { resize: vertical; min-height: 160px; }
.dwwp-cf-copy { margin: 18px 0 0; padding-top: 18px; border-top: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)); font-size: 14.5px; }
.dwwp-cf-copy input { margin-right: 8px; }
.dwwp-cf-actions { display: flex; align-items: center; gap: 16px; margin: 18px 0 0; flex-wrap: wrap; }
.dwwp-cf-submit {
  font: inherit; font-size: 15.5px; font-weight: 700; color: #fff;
  background: var(--wp--preset--color--primary, currentColor);
  border: 0; border-radius: 10px; padding: 14px 26px; cursor: pointer;
}
.dwwp-cf-submit:hover { filter: brightness(0.92); }
.dwwp-cf-note { font-size: 13.5px; color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent)); }
.dwwp-cf-notice { border-radius: 10px; padding: 12px 14px; margin-bottom: 18px; font-size: 14.5px; font-weight: 600; }
.dwwp-cf-ok { background: #ecfdf3; color: #067647; border: 1px solid #abefc6; }
.dwwp-cf-err { background: #fef3f2; color: #b42318; border: 1px solid #fecdca; }

/* 우측 정보 카드 (contact-form-mail 패턴의 rail) */
.dwwp-info-card {
  background: var(--wp--preset--color--background, transparent);
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  border-radius: 16px;
  padding: 24px !important;
}
.dwwp-info-card + .dwwp-info-card { margin-top: 16px; }
.dwwp-info-card > :is(h3, h4) { margin: 0 0 12px; font-size: 1.06em; }
.dwwp-info-card p { margin: 0 0 10px; font-size: 14.5px; }
.dwwp-info-card p strong { display: block; font-size: 13px; color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent)); }
.dwwp-contact-mail-cols { align-items: flex-start; }
@media (max-width: 781px) {
  .dwwp-cf-grid { grid-template-columns: 1fr; }
  .dwwp-contact-form { padding: 22px; }
}

/* Contact form 확장 — Services 칩(체크박스 필), OPTIONAL 구분 (2026-08-10 TL v4) */
.dwwp-cf-chips { grid-column: 1 / -1; }
.dwwp-cf-chips-label { display: block; font-weight: 700; font-size: 15px; margin-bottom: 10px; }
.dwwp-cf-chips-label i { color: var(--wp--preset--color--primary, currentColor); font-style: normal; }
.dwwp-cf-chip { display: inline-block; margin: 0 8px 8px 0; cursor: pointer; }
.dwwp-cf-chip input { position: absolute; opacity: 0; pointer-events: none; }
.dwwp-cf-chip span {
  display: inline-block; padding: 9px 18px; border-radius: 999px; font-size: 14px; font-weight: 600;
  border: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent));
  background: var(--wp--preset--color--background, transparent); color: var(--wp--preset--color--foreground, currentColor);
}
.dwwp-cf-chip input:checked + span {
  background: var(--wp--preset--color--primary, currentColor);
  border-color: var(--wp--preset--color--primary, currentColor); color: #fff;
}
.dwwp-cf-optlabel {
  grid-column: 1 / -1; margin: 6px 0 -6px; font-size: 12px; font-weight: 700; letter-spacing: .1em;
  color: var(--wp--preset--color--muted, color-mix(in srgb, currentColor 65%, transparent));
  border-top: 1px solid var(--wp--preset--color--outline, color-mix(in srgb, currentColor 12%, transparent)); padding-top: 16px;
}
