/* ============================================================
   ux-common.css — 박수칠때퇴근 리뉴얼 공통 그리드 + 인터랙션
   2026-07-30 신설. 근거 = website_uiux_revision_request.md §1 · §7

   ⛔ 이 파일은 5개 페이지가 공유한다. 페이지 전용 스타일을 여기 넣지 말 것.
   ⛔ site.css / tokens.css / navbar.css 를 덮어쓰지 않는다(전부 ux- 접두사).

   ── 그리드 기준선 (실측 2026-07-30) ────────────────────────
   .gnb-in : max-width 1520px / padding 0 32px
   로고 좌측    = 컨테이너 좌 + 32px
   버거 박스    = 52px 정사각, 컨테이너 우 - 32px 에서 끝남
   버거 3선(.ln)= 26px, 박스 안에서 좌우 13px 여백
   → 눈에 보이는 햄버거 우측 끝 = 컨테이너 우 - 32 - 13 = -45px

   좌 32 / 우 45 의 비대칭이 정상이다. 사장님 지시가
   "좌측은 로고 시작점, 우측은 햄버거 우측 끝점"이기 때문.
   ============================================================ */

:root{
  --ux-max: 1520px;      /* .gnb-in 과 동일 */
  --ux-padL: 32px;       /* 로고 좌측 시작점 */
  --ux-padR: 45px;       /* 햄버거 3선 우측 끝점 */
  --ux-gut: 20px;        /* 모바일 최소 좌우 여백 */

  /* 열린 오버레이의 X(회전 상태) 보정 —
     26px 선이 45° 회전하면 획 끝이 박스 중심에서 9.9px.
     (26·cos45 + 2·sin45)/2 = 9.9 → 획 끝 = 박스우측 - 16.1px
     X 획 끝을 --ux-padR 에 맞추려면 박스를 28.9px 에 둔다. */
  --ux-xbox: 28.9px;

  /* §7 모션 공통 — 동일 기능엔 동일 규칙 */
  --ux-ease: cubic-bezier(.22,1,.36,1);
  --ux-ul-dur: .38s;     /* 밑줄 그어지는 시간 */
  --ux-arrow-dur: .62s;  /* 화살표 1회 왕복 */
  --ux-shine-dur: 1.9s;  /* 유리 빛 통과 — 느리게 (사장님 지시) */
  --ux-draw-dur: .52s;   /* 윤곽선 그려짐 */

  /* ════════════════════════════════════════════════════════
     2차 요청서 §6 — 전체 페이지 공통 레이아웃 토큰 (2026-08-04 신설)

     실측 결과 페이지마다 값이 제각각이었다:
       섹션 상하  sv-final 96·104·112·116·118·120·126px
       히어로 상단 포트폴리오 150px / 미디어 178px
     아래 값 하나만 참조하도록 바꾼다. 페이지에서 임의의
     max-width / padding / margin 을 새로 쓰지 않는다.
     ⛔예외가 필요하면 그 자리에 이유를 주석으로 남길 것.
     ════════════════════════════════════════════════════════ */

  /* 콘텐츠 폭·좌우 패딩 — 위 --ux-max/padL/padR 의 별칭.
     요청서가 요구한 이름을 쓰되 값은 하나만 유지한다(이중 관리 방지) */
  --page-max-width:      var(--ux-max);
  --page-padding-desktop: var(--ux-padL);   /* 좌 = 로고 시작점 */
  --page-padding-tablet:  var(--ux-padL);   /* ★태블릿도 낮추지 않는다 — GNB가 32 고정 */
  --page-padding-mobile:  var(--ux-padL);   /* ★모바일도 동일(≤380px만 우측 완화) */

  /* 세로 리듬 — 히어로 */
  --hero-space-top:    176px;  /* 헤더와 첫 섹션 사이 간격을 겸한다(고정 GNB 76px 포함) */
  --hero-space-bottom: 120px;  /* 히어로 ↔ 첫 콘텐츠 섹션 */

  /* 세로 리듬 — 일반 섹션 */
  --section-space-lg: 112px;   /* 기본 섹션 상하 — 서비스 페이지 20섹션 실측 최빈값 */
  --section-space-md:  84px;   /* 앞 섹션과 이어지는 보조 섹션 */
  --section-head-gap:  44px;   /* 섹션 제목 묶음 ↔ 본문 */
  --card-gap:          24px;   /* 카드 사이 간격 */
  --page-tail:        132px;   /* 페이지 마지막 섹션 하단 여백 */

  /* 좌 안내 패널 ↔ 우 콘텐츠 (§2)
     ★기준 = 견적계산기 estimate-v1 의 .spec (사장님 확정).
       상담문의·셀프진단·진단탭이 이 값을 그대로 참조한다. */
  --panel-w:       460px;   /* 좌 패널 전체 너비 (2026-08-07 사장님 확정: 468 → 460) */
  --panel-pad-t:    72px;   /* 상단 내부 여백 = 페이지 상단 시작 위치 */
  --panel-pad-b:    34px;   /* 하단 내부 여백 */
  --panel-pad-l:    16px;   /* 좌 패딩(컨테이너 기준) — 텍스트 시작선 */
  --panel-pad-r:    44px;   /* 우 패딩 — 패널 글자가 배경 오른쪽 끝에 붙지 않게 */
  /* ★★2026-08-04 — 44 → 76px.
     44 는 '패널 안쪽 우 패딩'과 같은 값이라 우 콘텐츠가 패널 배경에 너무 붙었다.
     기준인 견적계산기(estimate-v1)의 대화 영역이 실제로 쓰던 값이 76px 이고
     (배경 우측 484 + 76 = 첫 글자 560), 사장님 지시가 "견적계산기에 맞춰서" 이므로
     이 값을 네 화면 공통 기준선으로 승격한다.
     ⛔페이지에서 px 를 다시 쓰지 말 것 — 네 화면이 같이 어긋난다. */
  --panel-gap:      80px;   /* 좌 패널 배경 우측 끝 ↔ 우 콘텐츠 첫 글자 (2026-08-07: 76 → 80) */
  --panel-min-h:   100vh;   /* 패널 최소 높이 */
  /* ★고정 헤더 높이. 기본 0 = 헤더를 걷어낸 페이지(body.ux-hd0).
     헤더가 살아 있는 페이지(셀프진단 등)가 :root 에서 76px 로 덮는다.
     이 값 덕분에 네 화면의 "페이지 상단 시작 위치"가
     '헤더 아래 72px' 로 같아진다 — 헤더 유무와 무관하게. */
  --panel-hh:        0px;
  --panel-bg: radial-gradient(700px 440px at 112% -8%, rgba(46,111,242,.26), transparent 62%), var(--navy);
}

/* 태블릿/모바일 세로 리듬 — 좌우 기준선은 그대로 두고 상하만 줄인다 */
@media (max-width: 1080px){
  :root{
    --hero-space-top:    138px;
    --hero-space-bottom:  84px;
    --section-space-lg:   88px;
    --section-space-md:   64px;
    --section-head-gap:   34px;
    --page-tail:          96px;
  }
}
@media (max-width: 640px){
  :root{
    --hero-space-top:    118px;
    --hero-space-bottom:  64px;
    --section-space-lg:   72px;
    --section-space-md:   52px;
    --section-head-gap:   28px;
    --card-gap:           16px;
    --page-tail:          78px;
  }
}

/* ── 1. 공통 그리드 ──────────────────────────────────────── */

.ux-wrap{
  width: 100%;
  max-width: calc(var(--ux-max) - var(--ux-padL) - var(--ux-padR));
  margin-inline: auto;
  padding-left: 0;
  padding-right: 0;
}

/* 컨테이너째 쓰는 경우 — 좌우 패딩이 기준선을 만든다.
   ★ padding 단축 지정 금지. 좌우가 지워져 본문이 화면 끝에 붙는다. */
.ux-bleed{
  width: 100%;
  max-width: var(--ux-max);
  margin-inline: auto;
  padding-left: var(--ux-padL);
  padding-right: var(--ux-padR);
}

/* 좌/우 한쪽만 필요할 때 */
.ux-edgeL{ padding-left: var(--ux-padL); }
.ux-edgeR{ padding-right: var(--ux-padR); }

/* 화면 끝에 고정되는 요소를 기준선에 맞출 때 */
.ux-pinR{ right: max(var(--ux-padR), calc((100vw - var(--ux-max)) / 2 + var(--ux-padR))); }
.ux-pinL{ left:  max(var(--ux-padL), calc((100vw - var(--ux-max)) / 2 + var(--ux-padL))); }

/* ★★모바일에서도 기준선을 낮추지 않는다 (2026-07-30 정정)
   실측: navbar.css / site.css 에 `.gnb-in` 의 모바일 패딩 재정의가 **0건**이다.
   즉 GNB 는 375px 에서도 padding 32px 고정이고, 로고는 늘 좌 32px,
   햄버거 3선 끝은 늘 우 45px 에 있다.
   여기서 --ux-padL/R 을 20px 로 낮추면 §1("좌측은 로고 시작점,
   우측은 햄버거 우측 끝점")이 모바일에서만 12~25px 어긋난다.
   좁은 화면에서 콘텐츠가 다소 줄더라도 정렬 일관성을 우선한다.

   ⛔ 페이지별로 이 값을 다시 덮지 말 것. 5개 페이지가 같이 어긋난다.
   진짜로 여백이 부족한 개별 요소만 자기 페이지에서 예외 처리할 것. */
@media (max-width: 380px){
  /* 아주 좁은 화면에서만 우측을 3선 끝이 아닌 버거 박스 끝으로 완화 */
  :root{ --ux-padR: 32px; }
}

/* ══ 1-b. 화면 끝 기준 3화면 — .ux-wide (2026-08-07 사장님 확정) ══════
   대상 = 상담문의(cf-final) · 견적계산기(estimate-v1, 진단탭 포함) · 셀프진단(sv-diag).
   ⛔이 규칙은 .ux-wide 가 붙은 화면에만 적용된다.
     미디어·포트폴리오·서비스처럼 좌 패널이 없는 페이지는 종전대로 1520 컨테이너 기준이다.

   ★왜 필요했나 —
     이 세 화면은 좌 패널이 화면 왼쪽 끝까지 흐르는데(풀블리드),
     정작 패널 안 글자는 '가운데 정렬된 1520px 컨테이너'에 묶여 있었다.
     1961px 화면에서는 컨테이너 좌측 여백만 220px 이라
     --panel-pad-l 을 0 으로 줘도 글자가 237px 아래로 못 내려왔다.
     → 컨테이너 상한을 풀어 좌 패널·햄버거가 '화면 끝'을 기준으로 서게 한다.
     ★1520px 이하 화면에서는 두 기준이 기하학적으로 같다(컨테이너 여백이 0이므로).
       즉 이 규칙이 눈에 보이는 차이를 만드는 것은 1520px 보다 넓은 화면뿐이다. */
.ux-wide{
  /* --ux-side = 컨테이너가 가운데 정렬되며 좌우로 버리던 여백 = (화면폭 - 1520)/2.
     '컨테이너에 묶여 있던' 공간이 정확히 이만큼이다. 이걸 되찾아 기준선에 더한다. */
  --ux-side: max(0px, calc((100vw - var(--ux-max)) / 2));

  /* 사장님 확정값 = 120px(2026-08-07, 1961px 화면에서 직접 지정).
     ★좁은 화면까지 120 을 그대로 물리면 안 된다 — 1265px 실측에서 우 콘텐츠가
       485px 로 줄어 셀프진단 체크리스트가 판정 패널에 가려졌다.
     → 되찾은 여백만큼만 더하고 120 에서 멈춘다.
       1520 이하 = 16/45(종전 검증값) · 1760 이상 = 120/120 · 그 사이는 연속적으로 이어진다. */
  --panel-pad-l: min(120px, calc(var(--ux-side) + 16px));   /* 화면 왼쪽 끝 ↔ 패널 텍스트 */
  --ux-padR:     min(120px, calc(var(--ux-side) + 45px));   /* 화면 오른쪽 끝 ↔ 햄버거 3선 */
  /* ⚠️100vw 는 스크롤바를 포함한다(맥 오버레이 스크롤바는 0). 좌·우가 같은 식을 쓰므로
     대칭은 어느 환경에서도 유지되고, 절대값만 스크롤바 폭의 절반만큼 안쪽으로 들어간다. */

  /* ★★2026-08-07 2차 — 패널 안 좌우 여백을 같게 (사장님 재지시).
     지시 = "텍스트 시작점과 너비 자체는 괜찮은데 우측 여백이 부족하다".
     → 글자는 그대로 두고 오른쪽 여백만 왼쪽과 같은 값으로 키운다.
       그만큼 패널이 넓어져야 텍스트 폭이 유지된다. */
  --panel-pad-r: var(--panel-pad-l);
  --panel-w: calc(var(--ux-panel-text-w) + var(--panel-pad-r));
  --ux-panel-text-w: 416px;   /* 패널 안 글자가 쓰는 폭. 종전 460 - 44 = 416 을 승계 */
  /* 실측: 1946px → 좌 120 / 글자 416 / 우 120 (패널 폭 536, 배경 끝 656)
           1265px → 좌  16 / 글자 416 / 우  16 (패널 폭 432, 배경 끝 448) */
}
@media (max-width: 380px){
  .ux-wide{ --ux-padR: 32px; }
}

/* 컨테이너 상한 해제 — 화면마다 셸 클래스가 다르다.
   .estw = 견적계산기 / .ux-split = 셀프진단·진단탭 / .r1-in = 햄버거 오버레이(hb-pn2)
   / .gnb-in = 햄버거 3선이 든 네비.
   ⛔하나라도 빠뜨리면 그 화면만 왼쪽에 흰 띠가 남는다(.ux-split 에서 실제로 겪음). */
.ux-wide .estw,
.ux-wide .ux-split,
.ux-wide .r1-in,
.ux-wide .gnb-in{ max-width: none; }
/* ★navbar.css 가 햄버거 오버레이의 우 컬럼을 1520 기준으로 묶어 둔다
   (`.r1-in > .p2-main{max-width:calc(--ux-max - --pn2-side)}`).
   공용 파일이라 손대지 않고 여기서만 푼다 — 안 풀면 우 콘텐츠가 1520 에서 끊겨
   햄버거 3선(우 120)까지 닿지 못한다. */
.ux-wide .r1-in > .p2-main{ max-width: none; }

/* ★햄버거 3선을 --ux-padR 에 연결한다.
   원래 .gnb-in 의 padding 은 32px 하드코딩이라 --ux-padR 을 바꿔도 따라오지 않았다.
   3선(26px)은 52px 박스 안에서 좌우 13px 안쪽이므로 padding = --ux-padR - 13.
   기본값 45 에서는 45-13=32 로 navbar.css 의 값과 완전히 같다(무해한 연결). */
.ux-wide .gnb-in{
  padding-left:  var(--ux-padL);
  padding-right: calc(var(--ux-padR) - 13px);
}

/* 패널 왼쪽 네이비 배경판도 같이 따라온다 — 안 맞추면 왼쪽에 흰 띠가 남는다.
   .ev-bleed 는 estimate-v1 이, .ux-panel-bleed 는 이 파일이 정의한다. */
.ux-wide .ux-panel-bleed,
.ux-wide .ev-bleed{ width: var(--panel-pad-l); }

/* ⑤ 말풍선·입력 묶음 폭 상한 — 넓은 화면에서 우측이 비어 보이던 것 해소.
   1961px 실측: 상한 880 이면 말풍선 우측 끝이 햄버거 3선보다 35px 안쪽에서 끝났다. */
.ux-wide{ --bub-max: 1400px; }

/* ★2026-08-07 — 좌 패널 우상단 그라데이션 원형.
   상담문의(cf-final)에만 `.glow` 요소로 있던 것을 나머지 패널에도 같은 값으로 맞춘다.
   ⛔자식 요소로 넣으면 안 된다 — .spec/.ux-panel 은 overflow-y:auto 라
     right:-90px 짜리 원이 가로 스크롤을 만든다. 배경 레이어로 얹는다.
   좌표 환산: .glow(300px, right:-90, top:-70) 의 중심 = 오른쪽에서 60px 안쪽 · 위에서 80px 아래.
   ★★2026-08-12 정정 — 반지름을 150px 로 잡았던 것이 실제보다 작았다.
     원본 `.glow` 는 300×300 박스에 `radial-gradient(circle, …)` = 기본 farthest-corner 라
     중심에서 모서리까지 **212px** 가 진짜 반지름이다. 150 이면 원이 작고 가장자리가
     급하게 끊겨 "각져 보인다"(사장님 지적: 상담문의처럼 퍼진 느낌으로).
     ⛔다시 150 으로 줄이지 말 것 — 상담문의(.cf3-lead .glow)와 어긋난다. */
.ux-wide .spec,
.ux-wide .ux-panel{
  background:
    radial-gradient(circle 212px at calc(100% - 60px) 80px,
      rgba(77,162,255,.20) 0%, rgba(77,162,255,0) 68%),
    var(--panel-bg);
}

/* ★2026-08-12 — 헤드라인 위 라벨을 상담문의(.cf3-sla)와 같은 둥근 알약으로.
   종전엔 자간만 벌린 맨 텍스트라 두 화면의 인상이 달랐다. */
.ux-wide .spec .kick,
.ux-wide .ux-panel-kick{
  display:inline-flex; align-items:center; gap:8px; align-self:flex-start;
  padding:7px 15px; border-radius:999px;
  background:rgba(77,162,255,.12); border:1px solid rgba(77,162,255,.3);
  font-size:12.5px; font-weight:700; letter-spacing:.14em; color:#DCE9FF;
  word-break:keep-all;
}
.ux-wide .spec .kick::before,
.ux-wide .ux-panel-kick::before{
  content:''; width:7px; height:7px; border-radius:50%; background:var(--blue-l); flex:none;
}

/* ── 선택 '팡' 모션 (§7 동일 기능엔 동일 규칙) ──────────────
   가견적 계산의 선택지 pill 이 쓰던 눌림+퍼지는 링을 공통으로 올린다.
   체크박스·라디오를 고르면 ux-common.js 가 감싼 라벨에 .ux-pop 을 붙인다. */
/* ★2026-08-07 2차 — "너무 과하다" 지시로 강도를 낮췄다.
   구값 = 눌림 .94 / 튐 1.045 / 링 scale 1.3·opacity .8 (.3s·.52s)
   신값 = 눌림 .982 / 튐 1.012 / 링 scale 1.13·opacity .42, 시간은 늘려 더 부드럽게.
   ⛔다시 키우지 말 것 — 선택 피드백이지 연출이 아니다. */
@keyframes ux-pop{
  0%{ transform:scale(1); } 34%{ transform:scale(.982); }
  70%{ transform:scale(1.012); } 100%{ transform:scale(1); }
}
@keyframes ux-pop-ring{
  0%{ transform:scale(1); opacity:.42; } 100%{ transform:scale(1.13); opacity:0; }
}
.ux-pop{ animation:ux-pop .36s cubic-bezier(.33,.9,.4,1); }
.ux-pop-ring{
  position:absolute; inset:-1px; border-radius:inherit;
  border:1.5px solid var(--blue); opacity:0; pointer-events:none;
}
.ux-pop > .ux-pop-ring{ animation:ux-pop-ring .58s cubic-bezier(.25,.9,.35,1); }
@media (prefers-reduced-motion: reduce){
  .ux-pop, .ux-pop > .ux-pop-ring{ animation:none; }
}

/* ── 2. 밑줄 — 좌에서 우로 그어진다 (§7) ─────────────────── */
/* 텍스트 전체에 한 번에 나타나지 않는다. transform-origin 이 핵심. */

.ux-ul{
  position: relative;
  display: inline-block;
  text-decoration: none;
}
.ux-ul::after{
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 1.5px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--ux-ul-dur) var(--ux-ease);
  pointer-events: none;
}
.ux-ul:hover::after,
.ux-ul:focus-visible::after,
.ux-ul.ux-on::after,
[data-ux-hover]:hover .ux-ul::after,
[data-ux-hover].ux-hv .ux-ul::after{
  transform: scaleX(1);
}
/* 빠져나갈 때는 오른쪽으로 걷힌다 — 되감기보다 자연스럽다 */
/* ★★2026-07-30 버그 수정 — origin 을 조건부로 바꾸지 않는다.
   원래는 "빠져나갈 때 오른쪽으로 걷힌다"는 의도로
   `.ux-ul:not(:hover):not(.ux-on)::after{ transform-origin:right center }`
   를 뒀는데, 이 해제 조건은 **커서가 밑줄 텍스트 자체에 있을 때만** 성립한다.
   카드처럼 부모(`[data-ux-hover]`)에 호버해서 밑줄을 긋는 경우
   텍스트 자신은 :hover 가 아니라 origin 이 right 로 남아
   **밑줄이 우→좌로 그어졌다**(mx-2 에서 실측 62.375px).
   §7 은 "좌측에서 우측으로"만 요구하므로 걷힘 방향 전환은 버린다. */
.ux-ul::after{ transition-property: transform; transform-origin: left center; }

/* ── 3. 화살표 — 짧게 1~2회만 (§7) ──────────────────────── */
/* ⛔ infinite 금지. 사장님 지시 "과도하게 반복하거나 빠르게 흔들리지 않도록" */

@keyframes uxArrowX{
  0%,100%{ transform: translateX(0); }
  50%    { transform: translateX(5px); }
}
@keyframes uxArrowY{
  0%,100%{ transform: translateY(0); }
  50%    { transform: translateY(4px); }
}

.ux-ar{
  display: inline-flex;
  will-change: transform;
}
[data-ux-hover]:hover .ux-ar,
[data-ux-hover].ux-hv .ux-ar,
.ux-arwrap:hover .ux-ar,
.ux-arwrap.ux-hv .ux-ar{
  animation: uxArrowX var(--ux-arrow-dur) var(--ux-ease) 2;
}
/* 아래 방향(더보기 류) */
[data-ux-hover]:hover .ux-ar.ux-ar-y,
[data-ux-hover].ux-hv .ux-ar.ux-ar-y,
.ux-arwrap:hover .ux-ar.ux-ar-y,
.ux-arwrap.ux-hv .ux-ar.ux-ar-y{
  animation: uxArrowY var(--ux-arrow-dur) var(--ux-ease) 2;
}
/* 굵고 큰 화살표가 필요한 곳 (§3.3) */
.ux-ar.ux-ar-bold svg{ stroke-width: 2.4; }
.ux-ar.ux-ar-lg svg{ width: 20px; height: 20px; }

/* ── 4. 유리 샤인 — 반투명 사선 빛의 면이 천천히 통과 (§7) ── */
/* ⛔ 그라데이션 배경 이동(background-position) 아님. 실제 면이 지나간다. */

@keyframes uxShine{
  from{ transform: translateX(-140%) skewX(-18deg); }
  to  { transform: translateX(320%)  skewX(-18deg); }
}

.ux-shine{
  position: relative;
  overflow: hidden;
  isolation: isolate;
}
.ux-shine::before{
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: 0;
  width: 42%;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0)    0%,
    rgba(255,255,255,.30) 42%,
    rgba(255,255,255,.44) 50%,
    rgba(255,255,255,.30) 58%,
    rgba(255,255,255,0)  100%
  );
  transform: translateX(-140%) skewX(-18deg);
}
[data-ux-hover]:hover .ux-shine::before,
.ux-shine:hover::before,
.ux-shine.ux-hv::before{
  opacity: 1;
  animation: uxShine var(--ux-shine-dur) var(--ux-ease) 1;
}
/* 밝은(노란·흰) 버튼 위에서는 흰 빛이 안 보인다 → 농도를 올린다 */
.ux-shine.ux-shine-lt::before{
  background: linear-gradient(
    90deg,
    rgba(255,255,255,0)    0%,
    rgba(255,255,255,.62) 42%,
    rgba(255,255,255,.86) 50%,
    rgba(255,255,255,.62) 58%,
    rgba(255,255,255,0)  100%
  );
}

/* ── 5. 윤곽선이 둘러싸이는 호버 — 위닝피피티 히어로 CTA 원본 이식 ──
   ★★2026-08-01 전면 교체.
   이전 구현은 ::before/::after 를 clip-path 로 잘라 순차로 그리는
   **내가 임의 해석한 모션**이었다. 사장님 지적("새롭게 임의 해석한 모션을
   만들지 말고 원본을 그대로 재현하라")에 따라 실제 원본을 받아 이식했다.

   출처 = https://www.winningppt.com/ 홈 인라인 <style> 의 `.hero-cta-m3`
   (히어로 CTA `무료 견적/상담 받기` · `견적 계산하기` 에 실제 적용된 것)
   원리 = @property 로 각도를 애니메이션 가능한 커스텀 속성으로 등록하고,
          conic-gradient 를 mask-composite:exclude 로 테두리만 남긴 뒤
          각도를 360deg 돌린다. 빛줄기가 외곽선을 따라 한 바퀴 도는 느낌.
   ⛔수치를 임의로 바꾸지 말 것 — 각도 정지점·색·1.6s 는 전부 원본 값이다. */

@property --ux-draw-angle{
  syntax: '<angle>';
  inherits: false;
  initial-value: 0deg;
}

.ux-draw{
  position: relative;
  z-index: 0;
  transition: letter-spacing .4s ease;
}
.ux-draw::before{
  content: '';
  position: absolute;
  inset: -2.5px;
  z-index: 1;
  border-radius: inherit;
  padding: 2.5px;
  background: conic-gradient(
    from var(--ux-draw-angle),
    transparent 0deg,
    transparent 250deg,
    rgba(96,165,250,.3) 290deg,
    #93c5fd 330deg,
    #e0efff 352deg,
    transparent 360deg
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
  opacity: 0;
  pointer-events: none;
  /* 떼었을 때의 역방향 = 회전을 되감지 않고 부드럽게 사라진다(원본 동작) */
  transition: opacity .3s ease;
}
[data-ux-hover]:hover .ux-draw,
[data-ux-hover].ux-hv .ux-draw,
.ux-draw:hover,
.ux-draw.ux-hv{
  letter-spacing: .05em;
}
[data-ux-hover]:hover .ux-draw::before,
[data-ux-hover].ux-hv .ux-draw::before,
.ux-draw:hover::before,
.ux-draw.ux-hv::before{
  opacity: 1;
  animation: uxDrawRunner 1.6s linear infinite;
}
@keyframes uxDrawRunner{
  to{ --ux-draw-angle: 360deg; }
}

/* ★letter-spacing 이 늘면 버튼 폭이 밀린다("기존 버튼 크기와 레이아웃을
   해치지 않을 것"). 폭이 고정돼야 하는 버튼에는 이 클래스를 같이 줄 것. */
.ux-draw.ux-draw-fixw{
  letter-spacing: normal !important;
}

/* ── 5-b. 어두운 섹션 CTA — 홈 히어로와 같은 러너로 통일 (2026-08-07) ──
   ★사장님 지시: "모든 페이지에서 어두운 배경 섹션에 CTA 버튼이 있으면
   홈 히어로 CTA의 윤곽선 둘러싸는 모션을 똑같이 적용."

   §5 의 기본 러너 색은 밝은 바탕을 전제로 한 코발트라, 어두운 바탕 위에서는
   거의 보이지 않는다. 그래서 홈 히어로의 파란 버튼(.hx .b1)이 쓰는
   **흰 빛 러너**를 그대로 옮겨 다크 전용 변형으로 둔다.
   ⛔각도 정지점(250/290/330/352deg)·1.6s 는 원본 값이므로 바꾸지 말 것.

   부착은 손으로 하지 않는다 — ux-common.js 가 배경 밝기를 재서
   어두운 섹션 안의 CTA 를 찾아 자동으로 붙인다(아래 markDarkCtas). */
.ux-draw-dark::before{
  background: conic-gradient(
    from var(--ux-draw-angle),
    transparent 0deg,
    transparent 250deg,
    rgba(224,239,255,.35) 290deg,
    #cfe4ff 330deg,
    #ffffff 352deg,
    transparent 360deg
  );
}

/* ── 6. 접근성 (§7) ─────────────────────────────────────── */

@media (prefers-reduced-motion: reduce){
  .ux-ul::after{ transition: none; }
  .ux-ul:hover::after,
  .ux-ul.ux-on::after{ transform: scaleX(1); }

  .ux-ar,
  [data-ux-hover]:hover .ux-ar,
  [data-ux-hover].ux-hv .ux-ar,
  .ux-arwrap:hover .ux-ar{ animation: none !important; }

  .ux-shine::before,
  [data-ux-hover]:hover .ux-shine::before,
  .ux-shine:hover::before{ animation: none !important; opacity: 0 !important; }

  .ux-draw::before,
  .ux-draw::after{ transition: none !important; }
  [data-ux-hover]:hover .ux-draw::before,
  [data-ux-hover]:hover .ux-draw::after,
  .ux-draw:hover::before,
  .ux-draw:hover::after{ opacity: 1; transform: scaleX(1); }
}

/* ── 6.5 서비스 페이지 헤더 3안 (§1 · 사장님 "3가지 다 시안으로") ──
   견적계산기 · 상담문의 는 "일반 홈페이지의 연장선이 아니라
   별도로 분리된 서비스 페이지처럼" 보여야 한다.
   body 에 .ux-hd1 / .ux-hd2 / .ux-hd3 중 하나를 붙여 전환한다.
   ⛔ navbar.css 는 건드리지 않는다. 전부 여기서 오버라이드. */

/* ── ★★HD0. 헤더 없음 — 햄버거 버튼만 (2026-08-01 사장님 확정) ──
   요청서 §7 = 상담문의 · 견적계산기 · 햄버거 화면은 **별도 헤더 영역을
   쓰지 않고 상단에 햄버거 버튼만** 노출한다. (미디어 상세·목록은 제외)
   로고까지 없앨지 물었고 **"햄버거만 남김"** 으로 확정받았다.

   → 아래 HD1/HD2/HD3 3안은 이 지시로 무의미해졌다. 남겨는 두되
     기본값은 HD0 이며, 전환 칩에서 골라도 헤더가 살아나지 않는다.

   ⛔`navbar.css` 는 건드리지 않는다. 전부 body 스코프 오버라이드. */
body.ux-hd0 .gnb{
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-bottom: 0 !important;
  box-shadow: none !important;
  pointer-events: none;          /* 빈 바가 클릭을 먹지 않게 */
}
/* 햄버거만 남기고 전부 감춘다 */
body.ux-hd0 .gnb .gnb-logo,
body.ux-hd0 .gnb .logo,
body.ux-hd0 .gnb-menu,
body.ux-hd0 .gnb-nav,
body.ux-hd0 .gnb-cta,
body.ux-hd0 .gnb-ghost,
body.ux-hd0 .ux-hd-back{
  display: none !important;
}
/* ★★2026-08-01 수정 — 레이아웃 값을 건드리지 않는다.
   처음엔 `height:auto; min-height:0; padding-top:18px` 을 줬는데,
   `navbar.css` 가 이미 잡아둔 햄버거 위치를 **9.5px 아래로 밀어버렸다**
   (hb-pn2 에서 top 11.5 → 21px 로 실측 확인).
   ux-hd0 의 역할은 "무엇을 보이게 할지"까지다 — 위치는 원래 값을 쓴다.
   그래야 3개 페이지에서 햄버거가 같은 자리에 선다. */
body.ux-hd0 .gnb-in{
  justify-content: flex-end;     /* 로고가 사라져도 햄버거는 우측에 */
}
body.ux-hd0 .burger,
body.ux-hd0 .gnb-right{
  pointer-events: auto;          /* 바는 투과, 버튼만 살린다 */
}

/* ★★헤더 바가 사라지면 햄버거가 본문 위를 그대로 지나간다.
   상담문의에서 스크롤 시 3선이 폼 셀렉트 위에 겹쳐 읽히지 않는 것이
   실제로 관측됐다. 헤더 바를 되살리면 §7 지시("헤더 영역 없이")에
   역행하므로, **버튼 하나에만** 반투명 원형 배경을 깔아 대비를 만든다.
   바가 아니라 버튼이므로 헤더로 보이지 않는다. */
body.ux-hd0 .burger{
  border-radius: 999px;
  background: rgba(255,255,255,.82);
  backdrop-filter: saturate(180%) blur(8px);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
  box-shadow: 0 2px 14px rgba(15,26,46,.10);
  transition: background-color .25s var(--ux-ease), box-shadow .25s var(--ux-ease);
}
body.ux-hd0 .burger:hover{
  background: rgba(255,255,255,.95);
  box-shadow: 0 3px 18px rgba(15,26,46,.16);
}
/* 오버레이가 열리면 배경은 이미 다크다 — 흰 알약이 뜨면 어색하므로 해제 */
body.ux-hd0.ovl-on .burger{
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
}
/* 다크 배경 페이지는 페이지 쪽에서 이 클래스로 뒤집을 것 */
body.ux-hd0.ux-hd0-dark .burger{
  background: rgba(12,24,48,.72);
  box-shadow: 0 2px 14px rgba(0,0,0,.28);
}
/* 헤더가 비었으므로 본문이 그 자리를 쓴다 — 페이지에서 상단 여백 재조정할 것.
   각 페이지가 `--ux-hd0-top` 으로 자기 값을 잡는다(기본 76px 네비 높이 해제). */
body.ux-hd0{
  --ux-hd0-top: 0px;
}

/* 공통 — 전환을 부드럽게 */
body[class*="ux-hd"] .gnb{
  transition: background-color .32s var(--ux-ease),
              backdrop-filter .32s var(--ux-ease),
              box-shadow .32s var(--ux-ease),
              border-color .32s var(--ux-ease);
}

/* ── HD1. 투명 → 스크롤하면 응고 (기본 추천) ─────────────── */
body.ux-hd1 .gnb{
  background: transparent;
  box-shadow: none;
  border-bottom: 1px solid transparent;
  backdrop-filter: none;
}
body.ux-hd1.ux-scrolled .gnb{
  background: rgba(255,255,255,.72);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: rgba(15,26,46,.08);
  box-shadow: 0 1px 24px rgba(15,26,46,.06);
}

/* ── HD2. 얇은 전용 헤더 — GNB 메뉴를 접고 로고만 남긴다 ── */
body.ux-hd2 .gnb{
  background: rgba(255,255,255,.92);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid rgba(15,26,46,.07);
  box-shadow: none;
}
body.ux-hd2 .gnb-in{ height: 62px; min-height: 62px; }
/* 메뉴·CTA 를 감춰 폼에 집중시킨다. 햄버거는 남겨 이동 경로를 유지 */
body.ux-hd2 .gnb-menu,
body.ux-hd2 .gnb-nav,
body.ux-hd2 .gnb-cta{ display: none !important; }
body.ux-hd2 .ux-hd-back{ display: inline-flex !important; }

/* ── HD3. 불투명 흰 바 + 하단 구분선 ────────────────────── */
body.ux-hd3 .gnb{
  background: #fff;
  backdrop-filter: none;
  border-bottom: 1px solid rgba(15,26,46,.10);
  box-shadow: none;
}

/* HD2 전용 '돌아가기' 링크 — 기본은 숨김 */
.ux-hd-back{
  display: none;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  font-weight: 600;
  color: #4A5568;
  text-decoration: none;
}
.ux-hd-back:hover{ color: #2E6FF2; }

/* ── 7. 한글 조판 (사장님 상시 지시) ────────────────────── */
/* 조사·어미가 홀로 남지 않게. 명사구는 쪼개지 않는다. */

.ux-kr{ word-break: keep-all; overflow-wrap: break-word; }
.ux-nb{ white-space: nowrap; }

/* ★ <br class="ux-br"> 를 숨길 때 앞뒤 어절이 붙는 사고가 있었다.
   반드시 <br> 앞에 공백을 한 칸 넣을 것 — 데스크톱은 줄 끝 공백이라 무영향. */
@media (max-width: 640px){
  br.ux-br{ display: none; }
}

/* ── 8. 공통 세로 리듬 유틸 (2차 요청서 §6) ──────────────
   §6 "공통 컨테이너 또는 디자인 토큰을 만들어 반복 적용한다".
   페이지가 자기 값을 새로 쓰는 대신 아래 클래스를 붙인다. */

/* 히어로 — 페이지 첫 섹션. 상단 여백이 헤더와의 간격을 겸한다 */
.ux-hero{ padding-top: var(--hero-space-top); padding-bottom: var(--hero-space-bottom); }

/* 일반 섹션 */
.ux-sec{ padding-top: var(--section-space-lg); padding-bottom: var(--section-space-lg); }
.ux-sec-md{ padding-top: var(--section-space-md); padding-bottom: var(--section-space-md); }
/* 앞 섹션에 이어 붙는 경우 — 위쪽만 좁힌다 */
.ux-sec-tight-t{ padding-top: var(--section-space-md); }
.ux-sec-tight-b{ padding-bottom: var(--section-space-md); }
/* 페이지 마지막 섹션 */
.ux-sec-last{ padding-bottom: var(--page-tail); }

/* 섹션 제목 묶음 ↔ 본문 */
.ux-head-gap{ margin-bottom: var(--section-head-gap); }
/* 카드 그리드 */
.ux-cards{ gap: var(--card-gap); }

/* ── 9. 좌 안내 패널 / 우 콘텐츠 (2차 요청서 §2) ──────────
   대상 = 상담문의 · 견적계산기 · 업무 셀프진단 · 견적계산기 내 진단 탭.
   ★기준은 견적계산기(estimate-v1)의 다크 네이비 패널이다(사장님 확정).

   페이지마다 콘텐츠 분량이 다르므로 "완전한 복사본"을 만들지 않는다.
   아래가 강제하는 것은 위계뿐 —
     너비 / 상단 시작 위치 / 내부 상하·좌우 여백 / 제목·설명 기준선 /
     배경 범위 / 우측 콘텐츠와의 간격 / 최소 높이와 세로 정렬.
   패널 안에 무엇을 넣을지는 페이지가 정한다. */

/* 좌우 2단 셸 — 좌 패널 폭이 토큰 하나로 결정된다 */
.ux-split{
  display: grid;
  grid-template-columns: var(--panel-w) 1fr;
  align-items: start;
  width: 100%;
  max-width: var(--page-max-width);
  margin-inline: auto;
  /* ★좌는 패널 전용 시작선(16px), 우는 햄버거 기준선(45px).
     좌우가 대칭이 아닌 것이 정상이다 — 서로 다른 요소를 기준 삼는다. */
  padding-left: var(--panel-pad-l);
  padding-right: var(--ux-padR);
  /* 고정 헤더가 있는 페이지에서 패널이 헤더 밑으로 파고들지 않게 */
  padding-top: var(--panel-hh);
}

/* 좌 패널 본체 */
.ux-panel{
  position: sticky;
  top: var(--panel-hh);
  height: calc(var(--panel-min-h) - var(--panel-hh));
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  /* 좌 패딩 0 = 셸의 --panel-pad-l 이 곧 텍스트 시작선.
     우 패딩이 그대로 우측 콘텐츠와의 간격(--panel-gap)이 된다. */
  padding: var(--panel-pad-t) var(--panel-pad-r) var(--panel-pad-b) 0;
  background: var(--panel-bg);
  color: #fff;
  word-break: keep-all;
  overflow-wrap: break-word;
  scrollbar-width: none;
}
.ux-panel::-webkit-scrollbar{ width: 0; }

/* 패널 배경이 화면 왼쪽 끝까지 흐르게 하는 고정 배경판.
   ★없으면 넓은 화면에서 네이비가 '잘린 카드'처럼 보인다. */
.ux-panel-bleed{
  position: fixed; top: var(--panel-hh); bottom: 0; left: 0; z-index: 0;
  pointer-events: none;
  background: var(--navy);
  width: max(var(--ux-padL), calc((100vw - var(--page-max-width)) / 2 + var(--ux-padL) + 24px));
}

/* 패널 안 위계 — 네 화면이 같은 기준선에서 시작한다.
   ★콘텐츠 분량이 달라도 제목·본문이 시작되는 위치는 같아야 한다(§2 주의사항). */
.ux-panel-kick{ font-size: 12.5px; font-weight: 700; letter-spacing: .2em; color: var(--blue-l); }
.ux-panel-title{
  margin-top: 18px;
  font-size: clamp(30px, 3.1vw, 46px);
  font-weight: 700; letter-spacing: -.042em; line-height: 1.2;
  color: #fff;
}
.ux-panel-sub{ margin-top: 20px; font-size: 14.5px; line-height: 1.82; color: #9DB3D2; }
.ux-panel-sub b{ color: #D3E0F2; font-weight: 600; }
/* 단계 표시·부가 정보는 제목 묶음과 같은 좌측 기준선에 정렬 */
.ux-panel-steps{ margin-top: 26px; display: flex; flex-direction: column; gap: 0; }
/* 하단 그룹(버튼·링크·사업자정보)은 패널 바닥에 앵커 */
.ux-panel-foot{ margin-top: auto; padding-top: 26px; }
/* 위아래 사이의 탄력 여백 — 내용이 짧아도 하단 그룹이 뜨지 않게 */
.ux-panel-gap{ flex: 1 1 auto; min-height: 30px; max-height: 118px; }

/* 우 콘텐츠 패널 */
.ux-content{
  /* 좌 패널의 우 패딩이 이미 간격을 만든다. 여기서 또 밀면 기준선이 어긋난다. */
  padding: var(--panel-pad-t) 0 var(--page-tail) var(--panel-gap);
  min-height: var(--panel-min-h);
}

/* ── 좁은 화면: 좌 패널이 위로 눕는다 (§2 "반응형에서도 동일한 규칙") ──
   ★네 화면 모두 같은 분기점(1240px)·같은 방식으로 눕는다.
     패널은 화면 폭을 꽉 채우되 글자는 계속 로고 기준선에서 시작한다. */
@media (max-width: 1240px){
  .ux-split{ grid-template-columns: 1fr; padding-left: 0; padding-right: 0; }
  .ux-panel-bleed{ display: none; }
  .ux-panel{
    position: static; height: auto; overflow: visible;
    padding: var(--panel-pad-t) var(--ux-padR) var(--section-space-md) var(--panel-pad-l);
  }
  .ux-panel-gap{ display: none; }
  .ux-content{
    padding: var(--section-space-md) var(--ux-padR) var(--page-tail) var(--panel-pad-l);
    min-height: 0;
  }
}
