/* ============================================================
   OFFNOISE 합본 — 인트로 오버레이 + 노이즈 스위치

   switch(5173) 인트로를 iframe 으로 얹고, 스위치를 끄면
   baseline-green(5174) 본문으로 넘긴다.

   ⚠️ 두 사이트는 --bg · --line · --font-body 등 CSS 변수 7개와
   .container · .hero · .footer 같은 클래스명을 공유한다.
   그래서 인트로를 같은 문서에 합치지 않고 iframe 으로 격리했다.
   이 파일의 모든 클래스는 .intro- / .noise- 접두사를 써서
   초록 사이트 스타일과 절대 겹치지 않게 한다.
   ============================================================ */

/* ── 1. 인트로가 떠 있는 동안 ───────────────────────────── */

html.intro-pending,
html.intro-pending body {
  overflow: hidden;
  height: 100%;
}

/* 인트로가 사라지는 700ms 동안에도 문서를 잠근 채로 둔다.
   dismiss() 는 본문을 먼저 드러내려고 intro-pending 을 벗기는데 덮개는 아직
   700ms 더 살아 있다. 그 사이 문서가 다시 스크롤 가능해지면 absolute 가 된
   덮개가 스크롤을 따라 올라가 페이드가 어긋난다. 덮개를 지울 때 함께 벗긴다. */
html.intro-leaving,
html.intro-leaving body {
  overflow: hidden;
  height: 100%;
}

/* 본문은 레이아웃까지 다 잡힌 채로 숨어 있다가 그대로 드러난다(리플로우 없음) */
html.intro-pending body > *:not(.intro-shell) {
  visibility: hidden;
}

/* ⚠️ fixed 가 아니라 absolute 다.
   실기기(iOS 크롬, 왓츠앱 링크로 진입) 스크린샷을 픽셀 단위로 잰 결과:
     · 상자 높이 765.8css  = 뷰포트 766 과 동일  → 짧지 않다
     · 상자 상단 y=55.4px  = 기기 화면 맨 위      → 원점이 틀렸다
     · 밀린 양 112.2css    = 크롬 상단 UI 112.4css (상태바+"◀ WhatsApp" 칩+주소창)
     · 아래 검은 띠의 실제 색 #0A0B0A = 부모 --bg  → 덮개가 그 자리를 안 덮는다
   즉 fixed 컨테이닝 블록의 '높이'는 맞고 '원점'만 화면 최상단에 잡힌다.
   그래서 innerHeight·clientHeight·visualViewport 가 전부 766 으로 맞게 나오면서도
   화면은 틀렸다 — 그 값들은 높이만 보고 원점을 보지 않는다.

   intro-pending 이 html·body 에 height:100%+overflow:hidden 을 걸어 문서가
   정확히 뷰포트 한 장이고 스크롤이 0 에 잠겨 있으므로, absolute 는 fixed 와
   픽셀 단위로 같은 상자를 그리되 문서 원점에 걸린다 — 어긋난 fixed 원점
   계산을 아예 타지 않는다. 카카오톡을 고친 수정을 한 층 위에 적용한 것이다. */
.intro-shell {
  position: absolute;
  inset: 0;
  z-index: 2147483000;
  background: #0a0a0a;          /* 인트로 배경과 같은 검정 — 로드 전 흰 깜빡임 방지 */
  opacity: 1;
  transition: opacity 700ms cubic-bezier(0.22, 1, 0.36, 1);
}
.intro-shell.is-leaving { opacity: 0; }

.intro-shell__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: #0a0a0a;
}

/* ── 2. 인트로 → 본문 인계 연출 ─────────────────────────────
   인트로는 CRT 가 꺼지며 완전한 검정으로 끝난다.
   그 검정에서 히어로가 천천히 떠오르게 해 이음매를 없앤다. */

@media (prefers-reduced-motion: no-preference) {
  html.js.intro-handoff .hero__canvas { animation: introCanvasIn 1500ms cubic-bezier(0.22, 1, 0.36, 1) both; }
  html.js.intro-handoff .hero__content > * { animation: introRise 900ms cubic-bezier(0.22, 1, 0.36, 1) both; }
  html.js.intro-handoff .hero__kicker { animation-delay: 240ms; }
  html.js.intro-handoff .hero__title { animation-delay: 380ms; }
  html.js.intro-handoff .noise-switch { animation: introRise 900ms cubic-bezier(0.22, 1, 0.36, 1) 720ms both; }
  html.js.intro-handoff .hero__scroll { animation: introRise 900ms cubic-bezier(0.22, 1, 0.36, 1) 860ms both; }
  html.js.intro-handoff .nav { animation: introRise 900ms cubic-bezier(0.22, 1, 0.36, 1) 560ms both; }
}
@keyframes introCanvasIn { from { opacity: 0; } to { opacity: 1; } }
@keyframes introRise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}

/* ── 3. 본문 → 인트로 복귀: CRT 켜지는 섬광 ─────────────── */

.crt-on-flash {
  position: fixed;
  inset: 0;
  z-index: 2147482000;
  pointer-events: none;
  background: #d7fbe8;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .crt-on-flash.is-firing { animation: crtOnFlash 460ms cubic-bezier(0.4, 0, 0.2, 1) both; }
}
@keyframes crtOnFlash {
  0%   { opacity: 0; transform: scaleY(0.004); }
  24%  { opacity: 0.9; transform: scaleY(0.004); }
  44%  { opacity: 0.75; transform: scaleY(1); }
  100% { opacity: 0; transform: scaleY(1); }
}

/* ── 4. 노이즈 스위치 (히어로 좌하단) ─────────────────────
   인트로 한가운데 있던 물리 스위치를 그대로 축소한 것이다.
   같은 재질·같은 조명·같은 ON/OFF 문법을 쓴다. */

.noise-switch {
  --nsw-w: 26px;                 /* 트랙 너비 */
  --nsw-h: 44px;                 /* 트랙 높이 */
  --nsw-pad: 3px;

  position: absolute;
  left: var(--gutter, 24px);
  bottom: clamp(28px, 5vh, 56px);
  z-index: 4;

  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.noise-switch__track {
  position: relative;
  flex: none;
  width: var(--nsw-w);
  height: var(--nsw-h);
  border-radius: 999px;
  background: linear-gradient(180deg, #1c1c1f 0%, #121214 100%);
  box-shadow:
    inset 0 3px 8px rgba(0, 0, 0, 0.9),
    inset 0 -1px 0 rgba(255, 255, 255, 0.07),
    0 0 0 1px rgba(255, 255, 255, 0.16),
    0 10px 22px rgba(0, 0, 0, 0.55);
  transition: box-shadow 300ms ease, background 300ms ease;
}

.noise-switch__knob {
  position: absolute;
  left: var(--nsw-pad);
  width: calc(var(--nsw-w) - var(--nsw-pad) * 2);
  height: calc(var(--nsw-w) - var(--nsw-pad) * 2);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 30%, #6e6e67 0%, #45454a 60%, #303034 100%);
  box-shadow:
    0 5px 12px rgba(0, 0, 0, 0.7),
    0 1px 0 rgba(255, 255, 255, 0.26) inset,
    0 -2px 5px rgba(0, 0, 0, 0.5) inset;
  /* OFF = 아래. 인트로의 스위치도 끄면 아래로 내려간다 */
  top: calc(var(--nsw-h) - var(--nsw-w) + var(--nsw-pad));
  transition: top 420ms cubic-bezier(0.34, 1.4, 0.5, 1), background 300ms ease;
}
.noise-switch__grip {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 44%;
  height: 1.5px;
  border-radius: 2px;
  transform: translate(-50%, -50%);
  background: rgba(0, 0, 0, 0.55);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.14);
}

/* 눌리는 순간 위로 — 노이즈가 다시 켜진다 */
.noise-switch.is-on .noise-switch__knob { top: var(--nsw-pad); }
.noise-switch.is-on .noise-switch__track {
  background: linear-gradient(180deg, #16241c 0%, #0f1a14 100%);
  box-shadow:
    inset 0 3px 8px rgba(0, 0, 0, 0.9),
    0 0 0 1px rgba(167, 243, 208, 0.45),
    0 10px 22px rgba(0, 0, 0, 0.55);
}

.noise-switch__text {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  font: 500 11px/1 "IBM Plex Mono", ui-monospace, SFMono-Regular, monospace;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.42);
  transition: color 300ms ease;
}
.noise-switch__state {
  color: rgba(255, 255, 255, 0.72);
  letter-spacing: 0.14em;
}
.noise-switch:hover .noise-switch__text,
.noise-switch:focus-visible .noise-switch__text { color: rgba(255, 255, 255, 0.72); }
.noise-switch:hover .noise-switch__state,
.noise-switch:focus-visible .noise-switch__state { color: #fff; }
.noise-switch:hover .noise-switch__knob {
  background: radial-gradient(circle at 50% 30%, #7e7e76 0%, #4e4e53 60%, #35353a 100%);
}

.noise-switch:focus-visible { outline: none; }
.noise-switch:focus-visible .noise-switch__track {
  box-shadow:
    inset 0 3px 8px rgba(0, 0, 0, 0.9),
    0 0 0 1px rgba(255, 255, 255, 0.16),
    0 0 0 3px #0a0b0a,
    0 0 0 5px var(--accent, #22c55e);
}

/* 히어로를 눌러 노이즈를 걷어낸 상태(hero.is-off)에서는 스위치 LED 도 같이 반응한다 */
.hero.is-off .noise-switch__state { color: var(--accent, #22c55e); }

@media (max-width: 640px) {
  .noise-switch { --nsw-w: 23px; --nsw-h: 39px; gap: 10px; }
  .noise-switch__text { font-size: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .intro-shell { transition: none; }
  .noise-switch__knob { transition: none; }
}

/* ⚠️ 국기 스프라이트는 화면에 자리를 차지하면 안 된다.
   크기를 안 주면 인라인 SVG 기본값 300×150 이 잡혀 본문 전체가 150px 밀린다
   (히어로 위에 검은 띠가 생기고 글자가 아래로 내려갔던 원인). */
.flag-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
  pointer-events: none;
}

/* ── 5. 언어 전환 — 국기 (헤더 우측, 기존 Contact 버튼 자리) ───
   글자(한국어/EN/日本語)로 두니 헤더가 어수선했다. 원형 국기 두 개로 줄였다.
   ⚠️ 이모지 국기(🇰🇷)를 쓰지 않았다 — 윈도우 크롬은 그것을 국기가 아니라
   'KR' 글자로 그린다. SVG 로 직접 그리고 CSS 로 동그랗게 자른다. */
.lang {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.lang__btn {
  appearance: none;
  border: 0;
  background: none;
  padding: 8px 6px;             /* 눌리는 영역 44px 확보 (국기 자체는 27×18) */
  min-height: 34px;
  align-items: center;
  border-radius: 999px;
  cursor: pointer;
  line-height: 0;
  display: inline-flex;
}
.flag {
  display: block;
  /* 원형. 태극기는 사각 국기를 자른 게 아니라 흰 원 안에 태극·4괘를 넣은 전용 심볼이다
     (그냥 자르면 네 귀퉁이 괘가 날아간다). 성조기·일장기는 가운데를 정사각으로 잘랐다. */
  width: 24px;
  height: 24px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22), 0 2px 6px rgba(0, 0, 0, 0.5);
  opacity: 0.42;
  filter: saturate(0.55);
  transition: opacity 240ms ease, filter 240ms ease, box-shadow 240ms ease, transform 240ms ease;
}
.flag svg { display: block; width: 100%; height: 100%; }
.lang__btn:hover .flag { opacity: 0.8; filter: saturate(0.9); }
.lang__btn.is-on .flag {
  opacity: 1;
  filter: none;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.5), 0 0 0 3px var(--accent-soft, rgba(34,197,94,.3)), 0 2px 8px rgba(0, 0, 0, 0.55);
}
.lang__btn:active .flag { transform: scale(0.94); }
.lang__btn:focus-visible { outline: none; }
.lang__btn:focus-visible .flag {
  box-shadow: 0 0 0 2px #0a0b0a, 0 0 0 4px var(--accent, #22c55e);
}

.lang--menu { margin-top: 22px; align-self: flex-start; gap: 14px; }
.lang--menu .flag { width: 30px; height: 30px; }

@media (max-width: 899px) {
  .nav__actions .lang { display: none; }
}

/* ── 히어로 문구의 광학적 중앙 (폰만) ───────────────────────────
   제보: 폰에서 "노이즈를 끕니다 / 진짜만 만듭니다" 가 세로 중앙보다
   살짝 아래에 있는 느낌. 실측해 보니 맞다 —
     글자 잉크 중심이 화면 중심보다 +11px 아래 (393x852 기준)
     위 여백 317 : 아래 여백 309
   원인은 셋이다:
     ① .hero__content 의 padding-top(136) 과 padding-bottom(128) 이 안 맞는다
     ② 폰에는 화면 아래에 스위치·화살표가 있어 시각적 바닥이 위로 올라온다
     ③ 브라우저 주소창·툴바가 실제 보이는 높이를 줄여, 계산상 중앙이
        눈으로는 아래로 내려간다
   그리고 사람 눈은 정중앙을 '아래'로 인식하므로, 화면 중앙 정렬은
   관례적으로 정중앙보다 조금 위에 둔다(광학적 중앙). 지금은 반대였다.

   ⚠️ 640px 미만에서만 적용한다. 데스크톱 레이아웃은 그대로 둔다
      (측정으로 좌표 불변 확인). */
@media (max-width: 639px) {
  .hero__content {
    padding-bottom: calc(8rem + 34px);   /* 아래를 늘려 글자를 위로 밀어올린다 */
  }
}

/* 데스크톱·태블릿도 같은 불일치가 있었다 — 중앙보다 +12px 아래.
   다만 폰만큼 올리면 안 된다. 여기는 아래쪽 스위치·화살표가 멀어서
   시각적 바닥이 낮고, 글자도 화면 왼쪽에만 있어 시선이 분산된다.
   그래서 광학적 중앙까지 가지 않고 거의 정중앙(+2px)에 맞춘다.
   위 여백 328 : 아래 여백 323 으로 균등해진다. */
@media (min-width: 640px) {
  .hero__content {
    padding-bottom: calc(8rem + 20px);
  }
}

/* ── 6. 터치 영역 ─────────────────────────────────────────
   아이패드 가로(1024)는 데스크톱 레이아웃이지만 손가락으로 만진다.
   메뉴 글자 높이가 22px 라 탭이 빗나간다 — 글자는 그대로 두고
   눌리는 영역만 44px 로 넓힌다(세로 중앙 정렬이라 위치는 안 밀린다). */
@media (min-width: 900px) {
  .nav__inner > .nav__links a {
    padding-block: 11px;
    display: inline-block;
  }
}

/* ── 7. 개정판(v2) 추가 — 문구 구조가 바뀌면서 필요해진 것들 ─────
   피드백 반영: 선언만 크고 정작 사업 설명이 작고 어두웠다.
   본문 대비를 올리고, 슬로건 아래 '무엇을 하는 회사인가' 한 줄을 넣었다. */

/* 슬로건 바로 아래 정체 한 줄 — 사업 분야까지 안 내려가도 알 수 있게 */

/* 본문 가독성 — 설명이 분위기에 묻히지 않게 */
.field__line { color: var(--fg); opacity: 0.86; }
.block p { color: var(--fg); opacity: 0.82; font-size: 1.1875rem; }
.lead { color: var(--fg); opacity: 0.9; }

/* 문의 안내 */
.contact__what {
  margin: 0.5rem 0 1.5rem;
  font-size: 0.9375rem;
  line-height: 1.7;
  color: var(--fg-dim);
}

/* ── OUR AMBITION ──────────────────────────────────────────
   하는 일(교육 → 전환 → 서비스) 다음, 연락처 앞.
   통짜 좌측 정렬을 유지한다 — 2단으로 나눴더니 제목이 세 줄로 꺾이고
   오른쪽 본문이 좁아져 더 나빴다. 여백만 매니페스토와 같은 값으로 맞춘다. */
.ambition {
  position: relative;
  padding-block: clamp(6rem, 12vw, 10rem);   /* = 매니페스토와 동일 */
  overflow: hidden;
}
.ambition__glow {
  position: absolute;
  left: 58%; top: 50%;
  width: min(64rem, 110%);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, var(--accent-glow) 0%, transparent 64%);
  opacity: 0.4;
  pointer-events: none;
}
.ambition__inner { position: relative; }
.ambition__inner .label { display: block; margin-bottom: 1.25rem; }
.ambition__title { margin: 0 0 2.75rem; text-wrap: balance; }
.ambition__body { display: grid; gap: 1.5rem; max-width: 46rem; }
.ambition__body p {
  margin: 0;
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  line-height: 1.8;
  color: var(--fg);
  opacity: 0.84;
}
.ambition__punch {
  margin: 3.5rem 0 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.6vw, 2.375rem);
  line-height: 1.25;
  letter-spacing: -0.03em;
  text-wrap: balance;
  color: var(--accent-3);
}

/* 가운데 메뉴를 화면 정중앙에 고정 (space-between 이라 좌우 폭에 따라 밀린다).
   ⚠️ 이 규칙은 한 번 지워졌다가 메뉴가 9px 밀려서 되살렸다. 지우지 말 것. */
@media (min-width: 900px) {
  .nav__inner { position: relative; }
  .nav__inner > .nav__links {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
  }
}

/* ── 8. 푸터: 운영 주체 ────────────────────────────────────
   데스크톱은 한 줄(회사 정보 · 대표 · 아이콘), 폭이 좁아지면 두 줄로 나뉜다.
   짧은 대표 정보가 아래에 따로 떨어져 있으면 붙다 만 것처럼 보인다. */
.footer__meta {
  display: flex;
  flex-direction: column;            /* 좁을 때: 회사 정보 / 대표·아이콘 두 줄 */
  align-items: flex-start;
  gap: 0.35rem;
}
.footer__sep { display: none; }      /* 두 줄일 때는 구분점이 줄 끝에 매달린다 */

/* 좁은 화면: 워드마크와 회사정보를 위아래로 쌓는다.
   기본값(styles.css)이 가로 배치 + align-items:center 라, 회사정보가 두 줄이 되는
   순간 워드마크가 두 줄 '사이'에 떠서 어느 줄과도 안 맞았다.
   640px 이상은 이 규칙이 아예 적용되지 않으므로 데스크톱은 그대로다. */
@media (max-width: 639px) {
  .footer__inner {
    flex-direction: column;
    align-items: flex-start;
    gap: 1.15rem;
  }
}

@media (min-width: 640px) {
  .footer__meta {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 0 0.5rem;
    text-align: right;
  }
  .footer__sep { display: inline; }
}

.footer__copy, .footer__who, .footer__sep {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--fg-dim);
}
.footer__sep { opacity: 0.5; }
.footer__who {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;                      /* 이름과 아이콘 사이는 구분점 없이 간격만 */
}
.footer__li {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;                       /* 탭 영역 확보 — 아이콘 자체는 14px */
  height: 30px;
  margin-block: -8px;
  border-radius: 6px;
  color: var(--fg-dim);
  transition: color 220ms ease, background 220ms ease;
}
.footer__li svg { width: 13px; height: 13px; display: block; opacity: 0.85; }
.footer__li:hover,
.footer__li:focus-visible { color: var(--accent-3); background: rgba(255, 255, 255, 0.06); }

/* ── 9. 영문 레이아웃 ──────────────────────────────────────
   영어는 같은 뜻을 쓰는 데 글자가 훨씬 길다. 한국어 기준으로 짠 배치를
   그대로 두면 긴 제목이 옆 칸을 밀어낸다. */

/* ① 분야 행: 설명 열이 제목 길이에 밀리던 것을 고정한다.
   원래 제목 열이 minmax(max-content, 1fr) 이라 'AI Transformation' 이
   열을 넓히고 설명 열을 22rem → 14rem 으로 짓눌렀다(설명이 243px 밀리고 128px 좁아짐).
   min 을 0 으로 두면 제목이 넘칠 때 자기 열 안에서 줄바꿈한다. */
@media (min-width: 1024px) {
  .field__inner {
    grid-template-columns: 9.5rem minmax(0, 1fr) minmax(18rem, 22rem);
  }
}

/* ② 라틴 제목은 한 줄을 강제하지 않는다. 좁은 화면에서 넘치는 것보다
   'AI / Transformation' 두 줄이 낫다. 크기도 조금 낮춰 대개 한 줄에 들어간다. */
html[lang="en"] .field__word {
  white-space: normal;
  font-size: clamp(2.75rem, 5.6vw, 6rem);
  text-wrap: balance;
}

/* ③ 히어로: 영어가 'We turn off the / noise.' 처럼 끊겼다.
   balance 로 두 줄 길이를 맞추면 'We turn off / the noise.' 로 갈린다. */
html[lang="en"] .hero__line,
html[lang="ja"] .hero__line { text-wrap: balance; }
/* 한국어 기준 max-width:14ch 가 영어를 강제로 꺾고 있었다. 문장당 한 줄이 되게 넓힌다. */
html[lang="en"] .hero__title {
  font-size: clamp(2.5rem, 6.4vw, 6.5rem);
  max-width: 26ch;
}

/* ── 10. 일본어 줄바꿈 ─────────────────────────────────────
   ⚠️ 전역에 word-break:keep-all + overflow-wrap:anywhere 가 걸려 있다.
   한국어는 어절이 끊기지 않아 좋지만, 일본어는 keep-all 때문에 정상 분할이
   막히고 anywhere 로 떨어지면서 **금칙 처리가 무너진다** —
   'つくりま / す。' 처럼 어미가 잘리고 '、' 가 줄 맨 앞에 온다.
   일본어에서만 표준 분할 + 엄격 금칙으로 되돌린다. */
html[lang="ja"],
html[lang="ja"] body,
html[lang="ja"] p,
html[lang="ja"] span,
html[lang="ja"] h1,
html[lang="ja"] h2,
html[lang="ja"] h3 {
  word-break: normal;
  overflow-wrap: break-word;   /* anywhere 가 아니다 — 넘칠 때만 끊는다 */
  line-break: strict;          /* 、。ー 작은 가나가 줄 앞에 오지 않게 */
}
/* 일본어 큰 제목은 balance 를 쓰지 않는다 — 짧은 꼬리 줄이 더 잘 생긴다 */
html[lang="ja"] .hero__line { text-wrap: initial; }
/* ⚠️ 폭 제한에 ch 를 쓰면 안 된다 — ch 는 라틴 '0' 글자 폭(≈0.5em)이라
   전각 문자에는 절반으로 잡힌다. 일본어는 em 으로 센다(1글자 ≈ 1em). */
html[lang="ja"] .hero__title {
  max-width: 14em;
  font-size: clamp(2.2rem, 6.4vw, 6.5rem);
}
