/* ============================================================
   main.css — 메인(index.html) 계열 요소 스타일
   출처: index.html <head> 내 :root 토큰 + #block-01 히어로 <style>(385~599행)

   변환 규칙 (docs/BD-PLAN.md §2)
   · #block-01  →  .b01h-hero
     (원본 섹션이 id="block-01" class="b01h-hero" 를 동시에 가지므로 동치)
   · body.tone-d 웜톤은 상시 확정(DECISIONS.md) → :root 에 그 값을 굳힌다
   · body[data-tx] 시안 분기는 A안 확정이므로 반입하지 않는다
     (미디어 표시 여부는 요소가 렌더 단계에서 결정)

   토큰 이름은 haneul.css(서브 계열)와 하나도 겹치지 않는다 — 실측 확인됨.
   ============================================================ */

:root {
  --gutter: clamp(39px, calc(65 / 1440 * 100vw), 97.5px);

  /* 타이포 스케일 */
  --fs-hero: clamp(64px, calc(120 / 1440 * 100vw), 156px);
  --fs-d2: clamp(52px, calc(96 / 1440 * 100vw), 125px);
  --fs-body: clamp(14.5px, calc(17 / 1440 * 100vw), 22px);
  --fs-label: clamp(12px, calc(14 / 1440 * 100vw), 19px);
  --fs-meta: clamp(12px, calc(12 / 1440 * 100vw), 16px);
  --lh-display: 1.05;
  --lh-body: 1.65;
  --ls-label: 0.18em;
  --ls-meta: 0.08em;

  /* 수직 리듬 */
  --pad-b06: clamp(57.6px, calc(96 / 1440 * 100vw), 144px);

  /* 모션 */
  --dur-micro: 0.6s;
  --dur-std: 0.9s;
  --dur-reveal: 1.4s;
  --stagger: 0.12s;
  --ease-soft: cubic-bezier(0.22, 0.61, 0.36, 1);

  --radius-3: 12px;

  /* 컬러 — body.tone-d 확정값을 굳힘 (원본 :root 의 #111827 계열 아님) */
  --neutral-1: #1A1A1A;
  --neutral-2: #474747;
  --neutral-3: #767676;
  --neutral-4: #9CA3AF;
  --neutral-5: #E3E3E3;

  /* 폰트 */
  --font-heading: 'NT Fabulous', 'Instrument Serif', Georgia, serif;
  --font-body: 'NT Fabulous', 'Manrope', 'Helvetica Neue', Arial, sans-serif;
}

/* ────────────────────────────────────────────────
   정본 차이 보정 — 메인(index.html) vs 서브(sub-open.html)
   ──────────────────────────────────────────────── */

/* haneul.css 는 sub-open.html 에서 통째로 떠온 파일이라 `html{scroll-behavior:smooth}` 를
   메인까지 끌고 온다. 정본 index.html 의 메인은 smooth 가 없다(실측: auto).
   <html class="butler-main"> 은 functions.php 의 language_attributes 필터가 붙인다. */
html.butler-main { scroll-behavior: auto; }

/* Breakdance 래퍼가 자체 배경(#F9FAFB)을 깐다. 정본 배경은 웜 아이보리 #FBFAF8 이고,
   원래 이 역할은 header.php 의 #pgwrap 이 했으나 Breakdance 헤더가 header.php 를
   대체하면서 #pgwrap 자체가 사라졌다 — 래퍼에 직접 지정한다. */
/* `body .breakdance`(0,1,1) — Breakdance global-settings.css 의
   `.breakdance{background-color:var(--bde-background-color)}`(0,1,0)가 더 늦게 로드되므로
   같은 특이도로는 진다. 한 단계 올려서 이긴다. */
body .breakdance { background-color: #FBFAF8; }

/* ────────────────────────────────────────────────
   메인 히어로 (원본 #block-01 .b01h-*)
   ──────────────────────────────────────────────── */

.b01h-hero {
  width: 100%;
  padding: 0; /* 프레임 */
  /* 원본은 `#block-01{background:#fff}` 이지만 `body.tone-d #block-01{background:#FBFAF8}`
     (0,1,1,1)가 (0,1,0,0)을 이기므로 실제 렌더값은 #FBFAF8 이다. 실측 확인. */
  background: #FBFAF8;
}

.b01h-hero .b01h-stage {
  position: relative;
  height: 95vh;
  border-radius: 0;
  overflow: hidden;
  background: #145A2E; /* 이미지 로드 전 지색 */
}

/* 배경 미디어.
   기본 상태 = 완전히 보임(opacity:1, scale:1). 이것이 핵심이다.
   ※ Breakdance 편집기 캔버스는 문서 타임라인을 정지시켜 CSS 애니메이션이 currentTime:0 에
      멈춘다(연출을 멈추고 디자인을 보게 하는 편집기 특성). 그래서 "숨김에서 시작하는"
      애니메이션은 편집기에서 영영 시작 프레임(숨김)에 갇힌다.
      → 기본을 보임으로 두고, 페이드인 연출은 .is-on 진입 클래스로만 얹는다.
        JS 가 안 돌거나 타임라인이 멈춰도 최종 모습(보임)이 그대로 유지된다. */
.b01h-hero .b01h-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1);
  opacity: 1;
}

/* 프론트에서 JS 가 이미지 로드 완료를 감지해 .is-on 을 붙이면 페이드인+슬로우줌을 재생.
   .no-anim(초기 1프레임 숨김용)과 함께 쓰여 깜빡임을 없앤다. 편집기에는 .is-on 이 안 붙어
   기본 보임 상태가 유지된다. */
.b01h-hero .b01h-media.b01h-anim {
  opacity: 0;
  transform: scale(1.08);
  transition: opacity 1.2s var(--ease-soft);
}
.b01h-hero .b01h-media.b01h-anim.is-on {
  opacity: 1;
  animation: b01h-zoom 5s var(--ease-soft) forwards;
}
@keyframes b01h-zoom {
  to { transform: scale(1); }
}

/* 영상은 슬로우 줌 제외 */
.b01h-hero .b01h-media--vid { transform: none; }
.b01h-hero .b01h-media--vid.b01h-anim.is-on { animation: none; }

.b01h-hero .b01h-veil {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    transparent 45%,
    color-mix(in srgb, var(--neutral-1) 45%, transparent) 100%);
}

/* 영상 히어로 — 타이틀 중앙부에만 라디얼 그라데이션으로 글씨를 받침 */
.b01h-hero.is-video .b01h-veil {
  background: radial-gradient(ellipse 58% 42% at 50% 50%,
    rgba(0, 0, 0, 0.2) 0%,
    rgba(0, 0, 0, 0.13) 55%,
    transparent 100%),
    linear-gradient(180deg,
    transparent 45%,
    color-mix(in srgb, var(--neutral-1) 45%, transparent) 100%);
}
.b01h-hero.is-video .b01h-stage { background: var(--neutral-1); }

.b01h-hero .b01h-title {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  color: #fff;
}

/* 킥커 — 본문급 영문은 한국어 서체와 동일.
   ※ 원본에 `body.tone-d .b01h-kicker{Cormorant Garamond/500/0.42em}` 이 있으나
      (0,0,2,1)로 `#block-01 .b01h-kicker`(0,1,0,1)에 져서 실제로는 적용되지 않는 죽은 규칙이다.
      실측 결과 원본은 Noto Serif KR / 400 / 0.18em 으로 렌더된다. */
.b01h-hero .b01h-kicker {
  margin-bottom: clamp(12px, calc(22 / 1440 * 100vw), 33px);
  font-family: 'Noto Serif KR', serif;
  font-size: var(--fs-label);
  font-weight: 400;
  line-height: 1;
  letter-spacing: var(--ls-label);
  color: rgba(255, 255, 255, 0.75);
  /* 기본 = 보임. 진입 연출은 .b01h-anim 이 붙을 때만 (편집기는 타임라인 정지 → 기본 유지) */
}
.b01h-hero.b01h-anim .b01h-kicker {
  opacity: 0;
  transform: translateY(16px);
  animation: b01h-rise 1.4s var(--ease-soft) 1.1s forwards;
}

/* 타이틀 — 블러 포커스 인 */
.b01h-hero .b01h-title h1 {
  font-family: var(--font-heading);
  font-size: clamp(44.8px, calc(84 / 1440 * 100vw), 109.2px); /* 축소 스케일 확정값 */
  font-weight: 400;
  line-height: var(--lh-display);
  /* 원본 h1 은 color 선언 없이 .b01h-title 의 #fff 를 상속한다.
     그러나 Breakdance global-settings.css 의
     `.breakdance h1,...{color:var(--bde-headings-color)}` 가 명시 선언이라
     상속을 이긴다(상속은 어떤 매칭 선언에도 진다). 선택자 특이도는
     .b01h-hero .b01h-title h1 (0,0,2,1) > .breakdance h1 (0,0,1,1) 이므로
     inherit 을 명시하는 것만으로 충분하다. !important 불필요. */
  color: inherit;
  /* 기본 = 보임 (편집기 타임라인 정지 대응) */
}
.b01h-hero.b01h-anim .b01h-title h1 {
  opacity: 0;
  filter: blur(16px);
  transform: scale(1.05);
  animation: b01h-focus 2s var(--ease-soft) 0.2s forwards;
}

@keyframes b01h-focus {
  from { opacity: 0; filter: blur(16px); transform: scale(1.05); }
  60% { opacity: 1; }
  to { opacity: 1; filter: blur(0); transform: scale(1); }
}

/* 한국어 서브카피 — 명조 Light */
.b01h-hero .b01h-sub {
  margin-top: clamp(16px, calc(28 / 1440 * 100vw), 42px);
  word-break: keep-all;
  font-family: 'Noto Serif KR', serif;
  font-size: clamp(9.6px, calc(16 / 1440 * 100vw), 24px); /* 축소 스케일 확정값 */
  font-weight: 300;
  line-height: var(--lh-body);
  color: rgba(255, 255, 255, 0.92);
  /* 기본 = 보임 */
}
.b01h-hero.b01h-anim .b01h-sub {
  opacity: 0;
  transform: translateY(16px);
  animation: b01h-rise 1.4s var(--ease-soft) 1.35s forwards;
}

@keyframes b01h-rise {
  to { opacity: 1; transform: translateY(0); }
}

@media (max-width: 767px) {
  .b01h-hero { padding: 0; }
  .b01h-hero .b01h-stage { height: 95vh; min-height: 600px; }
  .b01h-hero .b01h-kicker { font-size: 11px; letter-spacing: 0.26em; }
  .b01h-hero .b01h-title h1 { font-size: 6.09vw; }
  .b01h-hero .b01h-sub { font-size: 12px; margin-top: 16px; }
}

/* ── 스크롤 인디케이터 — 심볼 스핀 ──
   주의: 컨테이너에 transform·opacity를 걸면 스태킹 컨텍스트가 생겨
   심볼의 mix-blend-mode 가 격리된다(검은 배경 노출). 페이드는 자식 개별 처리. */
.b01h-hero .b01h-scroll {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(22px, calc(36 / 1440 * 100vw), 54px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  margin-bottom: -10px;
  color: rgba(255, 255, 255, 0.65);
  transition: margin-bottom 1.2s var(--ease-soft);
  pointer-events: none;
}
.b01h-hero .b01h-scroll .b01h-symbol-spin,
.b01h-hero .b01h-scroll .b01h-scroll-label {
  opacity: 0;
  transition: opacity 1.2s var(--ease-soft);
}
.b01h-hero .b01h-scroll.is-on { margin-bottom: 0; }
.b01h-hero .b01h-scroll.is-on .b01h-symbol-spin { opacity: 0.85; }
.b01h-hero .b01h-scroll.is-on .b01h-scroll-label { opacity: 1; }
.b01h-hero .b01h-scroll-label {
  font-family: 'Noto Serif KR', serif;
  font-size: 11px;
  /* 원본은 line-height 선언이 없어 body 의 normal 을 상속한다(계산값 15.5px).
     워드프레스 쪽은 body line-height 가 1.6 이라 17.6px 이 되어 스크롤 블록이 2.1px 높아졌다.
     원본이 실제로 계산하는 값(normal)을 명시해 상속 차이를 차단한다. */
  line-height: normal;
  letter-spacing: 0.32em;
  text-indent: 0.32em;
  text-transform: uppercase;
}
.b01h-hero .b01h-symbol-spin {
  display: block;
  width: 27.6px;
  /* JPG 심볼(흰 배경) 대응 — 반전 후 스크린 블렌드로 배경 소거 */
  filter: invert(1) grayscale(1) brightness(1.8);
  mix-blend-mode: screen;
  animation: b01h-spin 12s linear infinite;
}
@keyframes b01h-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .b01h-hero .b01h-scroll { margin-bottom: 0; transition: none; }
  .b01h-hero .b01h-scroll .b01h-symbol-spin { opacity: 0.85; transition: none; }
  .b01h-hero .b01h-scroll .b01h-scroll-label { opacity: 1; transition: none; }
  .b01h-hero .b01h-scroll * { animation: none !important; }
}

/* 폰트 준비 전 히어로 텍스트 애니메이션 대기 — FOUT 방지.
   ※ .b01h-anim(연출 재생 중)일 때만 적용. 기본 상태에는 애니메이션이 없으므로 무관. */
.b01h-hero.b01h-anim .b01h-kicker,
.b01h-hero.b01h-anim .b01h-title h1,
.b01h-hero.b01h-anim .b01h-sub {
  animation-play-state: paused;
}
html.fonts-ready .b01h-hero.b01h-anim .b01h-kicker,
html.fonts-ready .b01h-hero.b01h-anim .b01h-title h1,
html.fonts-ready .b01h-hero.b01h-anim .b01h-sub {
  animation-play-state: running;
}

@media (prefers-reduced-motion: reduce) {
  .b01h-hero .b01h-title h1 { animation: none; opacity: 1; filter: none; transform: none; }
  .b01h-hero .b01h-sub, .b01h-hero .b01h-kicker { animation: none; opacity: 1; transform: none; }
  .b01h-hero .b01h-media { animation: none; transform: none; opacity: 1; transition: none; }
}

/* ===== 브랜드 선언 (b02x-v1) ===== */
/* 원본 index.html #b02x1 (.b02x b02x-v1) — 스크롤 스크럽 리빌 섹션.
   변환 규칙(BD-PLAN §2):
   · #b02x1 → .b02x-v1  (원본 섹션이 id 와 class 를 동시에 가지므로 동치)
   · display:none / body[data-tx] 시안 게이트 제거 → 상시 표시(A안 확정, DECISIONS.md)
   · #fff → #FBFAF8  (body.tone-d 웜톤 상시 확정 → main.css :root 기조와 일치, 히어로와 동일)
   · 기본 상태 = 리빌 완료(보임): 편집기 타임라인 정지 대비(BD-ELEMENT-SPEC §2-B).
     어절(--b2v1-p) 폴백 1(진한색), 브랜드(--b2v1-bp) 폴백 1, 심볼 기본 보임.
     프론트 JS 가 인라인 변수/클래스로 리빌 시작점(숨김)에서 스크럽한다. */

.b02x-v1 {
  position: relative;
  height: 240vh;
  background: #FBFAF8;
}

.b02x-v1 .b2v1-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: #FBFAF8;
}

.b02x-v1 .b2v1-center {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 var(--gutter);
}

.b02x-v1 .b2v1-copy {
  margin: -12vh 0 0;
  max-width: 22em;
  font-family: 'Noto Serif KR', serif;
  font-weight: 300;
  font-size: clamp(16.8px, calc(26.4 / 1440 * 100vw), 38.4px);
  line-height: 1.58;
  letter-spacing: -0.01em;
  text-align: center;
  word-break: keep-all;
  will-change: transform;
}

.b02x-v1 .b2v1-line { display: block; }

/* 어절 진해짐 — --b2v1-p(어절별 리빌 진행도)는 JS 스크럽 구동.
   기본값 1 = 최종(진한색) → 편집기·무JS 에서도 읽힌다. 프론트 JS 가 인라인으로 0→1 스크럽. */
.b02x-v1 .b2v1-chunk {
  --b2v1-p: 1;
  color: var(--neutral-5);
  color: color-mix(in oklab, var(--neutral-1) calc(var(--b2v1-p) * 100%), var(--neutral-5));
}

/* 브랜드 — 하단 중앙. 기본 표시(bp 폴백 1). 프론트 JS 가 인라인 --b2v1-bp 로 0→1 페이드 */
.b02x-v1 .b2v1-brand {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(32px, 7vh, 72px);
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  text-align: center;
  opacity: var(--b2v1-bp, 1);
  transform: translate3d(0, calc((1 - var(--b2v1-bp, 1)) * 18px), 0);
  pointer-events: none;
}
.b02x-v1 .b2v1-brand-rule {
  width: 1px;
  height: 34px;
  background: var(--neutral-4);
}
.b02x-v1 .b2v1-brand-name {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(50.4px, calc(105 / 1440 * 100vw), 147px);
  letter-spacing: -1px;
  line-height: 1.2;
  color: var(--neutral-1);
}
.b02x-v1 .b2v1-brand-label {
  font-family: var(--font-heading);
  font-weight: 400;
  font-size: clamp(10.4px, calc(14.4 / 1440 * 100vw), 20.8px);
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--neutral-3);
}

/* 심볼 — 원샷 45° 회전 + 페이드 등장.
   기본 = 보임(§2-B). 프론트 JS 가 .b2v1-anim 을 붙여 숨김에서 시작 → .b2v1-on 으로 등장. */
.b02x-v1 .b2v1-symbol {
  display: block;
  margin: 0 auto clamp(20px, calc(32 / 1440 * 100vw), 48px);
  width: clamp(40px, calc(56 / 1440 * 100vw), 80px);
  height: auto;
  mix-blend-mode: multiply; /* JPG 심볼(흰 배경) 대응 — 흰 배경을 지색에 녹여 소거 */
  opacity: 1;
  transform: rotate(0deg);
}
.b02x-v1 .b2v1-symbol.b2v1-anim {
  opacity: 0;
  transform: rotate(-45deg);
  transition: opacity 1.6s var(--ease-soft), transform 1.6s var(--ease-soft);
}
.b02x-v1 .b2v1-symbol.b2v1-anim.b2v1-on {
  opacity: 1;
  transform: rotate(0deg);
}

@media (max-width: 767px) {
  .b02x-v1 .b2v1-copy {
    font-size: clamp(22px, 6.4vw, 30px);
    line-height: 1.66;
  }
  .b02x-v1 .b2v1-center { padding: 0 20px; }
  .b02x-v1 .b2v1-brand { bottom: 40px; gap: 11px; }
  .b02x-v1 .b2v1-brand-rule { height: 26px; }
}

/* 정적 완성 상태 — 감속 모션 미러 (JS 가 .b2v1-static 토글) */
.b02x-v1.b2v1-static {
  height: auto;
  background: #FBFAF8;
}
.b02x-v1.b2v1-static .b2v1-stage { position: relative; }
.b02x-v1.b2v1-static .b2v1-chunk { --b2v1-p: 1; }
.b02x-v1.b2v1-static .b2v1-copy { transform: none; }
.b02x-v1.b2v1-static .b2v1-brand { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .b02x-v1 { height: auto; }
  .b02x-v1 .b2v1-stage { position: relative; }
  .b02x-v1 .b2v1-chunk { --b2v1-p: 1; }
  .b02x-v1 .b2v1-copy { transform: none; }
  .b02x-v1 .b2v1-brand { opacity: 1; transform: none; }
  .b02x-v1 .b2v1-symbol { opacity: 1 !important; transform: none !important; transition: none; }
}
/* ===== end 브랜드 선언 ===== */

/* ===== 아이덴티티 스택 (b03s) ===== */
/* 출처: index.html #block-03 <style>(1162~1252행). 변환: #block-03 → .b03s-identity
   (원본 섹션이 id="block-03" class="b03s-identity" 를 동시에 가지므로 동치)
   · body.tone-d 상시 확정값을 굳힘: 배경 #FBFAF8, .b03s-text 굵기 300 + 데스크톱 축소 스케일
   · body[data-tx] 시안 분기(진입 블러)는 반입하지 않는다 — A안 확정
   · 편집기 타임라인 정지 대비: 기본 상태 = card0(Surgery) 완전 노출, card1 opacity:0.
     JS 가 없어도 첫 카드가 온전히 보인다(휴지 상태). */

/* 원본 `#block-03{background:#fff}` 이지만 `body.tone-d #block-03{background:#FBFAF8}`
   가 이기므로 실제 렌더값은 #FBFAF8. 그 값을 굳힌다. */
.b03s-identity { background: #FBFAF8; }

.b03s-identity .b03s-stack { position: relative; }
.b03s-identity.b03s-anim .b03s-stack { height: 380vh; } /* 양쪽 홀드 확보용 러닝웨이 */
.b03s-identity.b03s-anim .b03s-viewport {
  position: sticky;
  top: 0;
  height: 100svh;
  overflow: hidden;
  clip-path: inset(0); /* 스티키+오버플로 조합에서 하위 페인트 누출 방지 */
}
/* 기본(편집기·JS 없음) = 두 카드가 위아래로 나란히 모두 보인다.
   ⚠ 체크리스트 §4-1: 편집기는 애니메이션 타임라인을 정지시키므로 "숨김에서 시작하는" 연출은
     시작 프레임에 갇힌다. 예전엔 card1(Skin care)이 opacity:0 이라 편집기에서 영영 안 보였다.
     → 겹침·크로스페이드는 JS 가 .b03s-anim 을 붙인 프론트에서만 건다. */
.b03s-identity .b03s-card {
  position: relative;
  overflow: hidden;
  height: 100svh;
}
.b03s-identity.b03s-anim .b03s-card {
  position: absolute;
  inset: 0;
  height: auto;
  will-change: transform;
}
.b03s-identity.b03s-anim .b03s-card[data-card="1"] { opacity: 0; } /* 크로스페이드 줌 시작 상태 = 첫 카드만 보임 */
.b03s-identity .b03s-media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  will-change: transform;
}
.b03s-identity .b03s-shade {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0) 42%, rgba(0, 0, 0, 0.62) 100%);
}
.b03s-identity .b03s-smoke {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  opacity: 0;
  pointer-events: none;
}
/* Surgery 카드(card 0) — 스크럽이 블러/확대를 매 프레임 구동할 자리(프론트 한정) */
.b03s-identity .b03s-card[data-card="0"] { will-change: transform, filter; }
.b03s-identity .b03s-detail {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: clamp(40px, calc(64 / 1440 * 100vw), 96px);
  display: flex;
  flex-direction: column;
  align-items: center; /* 중앙 하단 배치 */
  text-align: center;
  color: #fff;
}
.b03s-identity .b03s-name {
  margin-bottom: 18px;
  font-family: 'NT Fabulous', 'Noto Serif KR', serif;
  font-weight: 400;
  font-size: var(--fs-d2);
  line-height: var(--lh-display);
  color: #fff;
}
.b03s-identity .b03s-text {
  max-width: none;
  font-family: 'Pretendard', sans-serif;
  font-size: var(--fs-body);
  font-weight: 300; /* body.tone-d 상시적용값을 굳힘 (원본 base 는 미선언) */
  line-height: var(--lh-body);
  color: rgba(255, 255, 255, 0.82);
  word-break: keep-all;
}
/* body.tone-d 데스크톱 축소 스케일을 굳힘 (원본: body.tone-d #block-03 .b03s-text) */
@media (min-width: 769px) {
  .b03s-identity .b03s-text { font-size: clamp(12.5px, calc(15 / 1440 * 100vw), 19px); }
}

@media (max-width: 767px) {
  /* 모바일: 풀스크린 와이프 → 90svh 단일 밴드 크로스페이드, 텍스트 수직 중앙
     ⚠ 연출 규칙과 겨루는 항목은 반드시 `.b03s-anim` 을 붙여 특이도를 맞춘다.
       `.b03s-identity .b03s-stack`(0,2,0) 는 `.b03s-identity.b03s-anim .b03s-stack`(0,3,0)
       에 져서 죽는다. 실제로 그래서 모바일 러닝웨이가 280vh 가 아니라 380vh 로 렌더됐다
       (실측: 원본 2274px vs 이관본 3086px). */
  .b03s-identity.b03s-anim .b03s-stack { height: 280vh; }
  .b03s-identity.b03s-anim .b03s-viewport {
    top: 5svh; /* 핀 상태에서 밴드가 화면 세로 중앙에 위치 */
    height: 90svh;
  }
  /* 크로스페이드 시작 상태 — 연출이 켜졌을 때만. 편집기에선 두 카드가 모두 보여야 한다(§4-1). */
  .b03s-identity.b03s-anim .b03s-card[data-card="1"] { transform: none; opacity: 0; }
  .b03s-identity .b03s-smoke { display: none; }
  .b03s-identity .b03s-text br { display: none; } /* 데스크톱 2줄 지정 해제 */
}

@media (prefers-reduced-motion: reduce) {
  .b03s-identity .b03s-stack { height: auto; }
  .b03s-identity .b03s-viewport { position: static; height: auto; overflow: visible; }
  .b03s-identity .b03s-card { position: relative; inset: auto; height: 100svh; transform: none !important; opacity: 1 !important; }
  .b03s-identity .b03s-media { transform: none !important; }
  .b03s-identity .b03s-smoke { display: none; }
  .b03s-identity .b03s-card { filter: none !important; will-change: auto; }
}
/* ===== end 아이덴티티 스택 (b03s) ===== */
