/* ============================================================================
   ieGenie 홈페이지 — 연출 층 (모양)

   · 여기 규칙은 html[data-fx="on"] 일 때만 먹는다.
     그 속성이 없거나(스크립트가 안 돌았다) "off"(클래식)면 지금 홈페이지 그대로다.
   · 분위기에 따라 바뀌는 화면 색은 아래 변수 세 개뿐이다. 입자·빛·소리 쪽 값은 fx.js 의 MOODS 표.
   · 처음 열릴 분위기는 index.html 맨 위 DEFAULT_MOOD 한 줄.
   ============================================================================ */

:root {
  --fx-accent: #44bbbb;      /* CI ieGenie Teal */
  --fx-grad-a: #82d5d5;
  --fx-grad-b: #2fa4b4;
  --fx-brass: #d8a94b;       /* 램프의 황동 — 연출에서 새로 들어오는 색은 이것 하나 */
  --fx-navy: #020617;
}
html[data-mood="dawn"]  { --fx-accent: #b6a1ff; --fx-grad-a: #d6c9ff; --fx-grad-b: #ff9fc8; }   /* 새벽 하늘빛 — 보라에서 분홍으로(옅은 청록이던 것을 2026-10-03 에 옮겼다: 심해 청록과 구분이 안 됐다) */
html[data-mood="ember"] { --fx-accent: #f2c66b; --fx-grad-a: #82d5d5; --fx-grad-b: #f2c66b; }

/* ── 무대(3D 캔버스) — 지금 홈페이지의 배경 층(격자·빛 덩이)과 같은 자리에 깔린다 ── */
#fxStage { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; display: none; pointer-events: none; }
html[data-fx="on"] #fxStage { display: block; }
html[data-fx="on"] [data-fx-bg="glow"] { display: none; }                 /* 흐린 빛 덩이는 입자가 대신한다 */
html[data-fx="on"] [data-fx-bg="grid"]::after {                            /* 가장자리를 눌러 가운데로 눈이 가게 */
  content: ''; position: absolute; inset: 0;
  background: radial-gradient(ellipse 85% 80% at 50% 46%, transparent 45%, rgba(2, 6, 23, 0.6) 100%);
}

/* 입자가 설 자리 — 클래식에서는 아예 없다 */
.fx-stage { display: none; }
html[data-fx="on"] .fx-stage { display: block; min-height: 46vh; pointer-events: none; }

/* ── 글이 입자 위에서도 읽히게 ── (바탕 농도를 낮추면 뒤의 3D 가 비쳐 글이 묻힌다 — 고치면 docs/tools/contrast-verify.mjs 로 잰다) */
html[data-fx="on"] .glass-card {
  background: rgba(7, 15, 34, 0.6);
  -webkit-backdrop-filter: blur(12px) saturate(1.15); backdrop-filter: blur(12px) saturate(1.15);
}
html[data-fx="on"] .text-gradient {
  background: linear-gradient(to right, var(--fx-grad-a), var(--fx-grad-b));
  -webkit-background-clip: text; background-clip: text;
  text-shadow: none;
}
/* 제목 안에서 강조색으로 물들이는 낱말 — 분위기를 바꾸면 같이 바뀐다 (2026-10-03 사장님 「아이지니시스템 색상을 좀 바꿔줘」). 클래식에서는 예전 그대로 흰 글자다 */
html[data-fx="on"] [data-fx="tint"] {
  background: linear-gradient(to right, var(--fx-grad-a), var(--fx-grad-b));
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  text-shadow: none;
}
html[data-fx="on"] [data-fx="copy"],
html[data-fx="on"] [data-fx="head"],
html[data-fx="on"] #services h4,
html[data-fx="on"] #demo > div > p { text-shadow: 0 1px 14px rgba(2, 6, 23, 0.9), 0 0 2px rgba(2, 6, 23, 0.6); }
html[data-fx="on"] [data-fx="panel"] {                                    /* 카드 밖에 있던 글 덩이를 유리판에 올린다 */
  padding: 2rem; border-radius: 1.5rem;
  background: rgba(7, 15, 34, 0.6); border: 1px solid rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(12px) saturate(1.15); backdrop-filter: blur(12px) saturate(1.15);
}

/* 손이 닿았거나, 연출이 지금 가리키고 있는 카드 */
html[data-fx="on"] .fx-lit {
  border-color: var(--fx-accent) !important;
  box-shadow: 0 0 0 1px var(--fx-accent), 0 22px 54px -22px var(--fx-accent);
}
html[data-fx="on"] [data-fx-shape].fx-lit { transform: translateY(-6px); }

/* 기울어지는 카드 — 마우스 쪽으로 기울고 그 자리에 빛이 맺힌다 */
html[data-fx="on"] .fx-tilt { position: relative; transform-style: preserve-3d; will-change: transform; }
html[data-fx="on"] .fx-tilt::after {
  content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0; transition: opacity 0.3s; border-radius: inherit; z-index: 5;
  background: radial-gradient(280px circle at var(--gx, 50%) var(--gy, 50%), rgba(130, 213, 213, 0.3), transparent 62%);
}
html[data-fx="on"] .fx-tilt.fx-live { box-shadow: 0 30px 60px -22px rgba(68, 187, 187, 0.55); }
html[data-fx="on"] .fx-tilt.fx-live::after { opacity: 1; }
html[data-fx="on"] .fx-wish { animation: fx-wish 1.1s ease-in-out 3; }
@keyframes fx-wish { 50% { box-shadow: 0 0 0 10px rgba(130, 213, 213, 0), 0 0 44px 6px rgba(130, 213, 213, 0.75); } }

/* ── 제목 줄바꿈 ── (2026-10-03 사장님 「글자가 한줄로 나와야지」 — 넓은 화면에서 「…핵심 사업 영 / 역」 으로 꺾여 있었다)
   한글은 그냥 두면 글자 사이 어디서나 줄이 바뀐다. 제목은 띄어쓰기에서만 끊고, 두 줄이 되면 고르게 나눈다(낱말 하나만 떨어지지 않게).
   ★화면낭독기용 숨은 제목(.sr-only)은 뺀다★ — text-wrap 이 그 글의 white-space: nowrap 을 풀어, 1px 상자 안에서 글자마다 줄이 바뀐다(23줄).
   눈에는 안 보여도 낭독기가 끊어 읽을 수 있다. 글 대비 검사가 「머리말 제목이 안 읽힌다」 로 잡아서 알았다(2026-10-03). */
html[data-fx="on"] :is(h1, h2, h3, h4, h5):not(.sr-only),
html[data-fx="on"] [data-fx="head"] p { word-break: keep-all; overflow-wrap: break-word; text-wrap: balance; }   /* 머리말의 부제도 — 「…설계합니다.」 한 낱말만 떨어지지 않게 */
/* 구역 머리말 제목(사업영역 · AX · 데모)은 한 줄로 — 칸 폭에 맞춰 글자 크기를 정한다(아래 넓은 화면 · 휴대폰 규칙이 쓴다).
   --fx-fit = 그 제목을 한 줄로 썼을 때 「글 폭 ÷ 글자 크기」(Pretendard · 자간 -0.02em 으로 잰 값)에 여유 5% 를 더한 수.
   ★제목 글을 바꾸면 이 수도 다시 잰다★ — docs/tools/title-wrap.mjs 가 꺾임을 잡는다. */
html[data-fx="on"] [data-fx="head"] { container-type: inline-size; }
html[data-fx="on"] [data-scene="services"] [data-fx="head"] { --fx-fit: 12.2; }    /* 「아이지니시스템 핵심 사업 영역」 11.61 */
html[data-fx="on"] [data-scene="ax"] [data-fx="head"] { --fx-fit: 18.05; }         /* 「AI 시대의 병목은 모델이 아니라 시스템입니다」 17.19 */
html[data-fx="on"] [data-scene="demo"] [data-fx="head"] { --fx-fit: 6.26; }        /* 「데모 · 개발 포털」 5.96 */

/* ── 구간 배치 (넓은 화면) — 제목 옆에 입자가 설 자리를 낸다 ── */
@media (min-width: 1024px) {
  /* 첫 화면 — 글 왼쪽, 오른쪽에 램프와 로고. 사무실 사진은 그 아래 줄로 */
  html[data-fx="on"] [data-fx="hero-grid"] { grid-template-columns: minmax(0, 640px) minmax(0, 1fr); row-gap: 10vh; }
  html[data-fx="on"] [data-fx="hero-grid"] > [data-fx="copy"] { order: 1; grid-column: 1; grid-row: 1; }
  html[data-fx="on"] [data-fx="hero-grid"] > .fx-stage { order: 2; grid-column: 2; grid-row: 1; min-height: min(74vh, 760px); }
  html[data-fx="on"] [data-fx="hero-grid"] > [data-fx="hero-photo"] { order: 3; grid-column: 1 / -1; grid-row: 2; width: min(100%, 880px); justify-self: center; }

  /* 회사소개 — 왼쪽에 지니, 오른쪽에 글. 네 카드는 그 아래 한 줄 */
  html[data-fx="on"] [data-fx="about-grid"] { row-gap: 3rem; }
  html[data-fx="on"] [data-fx="about-grid"] > .fx-stage { grid-column: 1; grid-row: 1; min-height: 72vh; }
  html[data-fx="on"] [data-fx="about-grid"] > [data-fx="copy"] { grid-column: 2; grid-row: 1; }
  html[data-fx="on"] [data-fx="about-grid"] > [data-fx="about-cards"] { grid-column: 1 / -1; grid-row: 2; grid-template-columns: repeat(4, minmax(0, 1fr)); }

  /* 제목과 무대를 나란히 — 사업영역 · AX · 데모 */
  html[data-fx="on"] [data-fx="split"] { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 4rem; align-items: center; }
  html[data-fx="on"] [data-fx="split"] > * { grid-column: 1 / -1; }
  html[data-fx="on"] [data-fx="split"] > [data-fx="head"] { grid-column: 1; grid-row: 1; text-align: left; max-width: none; margin: 0 0 2rem; }
  html[data-fx="on"] [data-fx="split"] > .fx-stage { grid-column: 2; grid-row: 1; min-height: 70vh; margin-bottom: 2rem; }
  html[data-fx="on"] [data-fx="split"][data-fx-side="left"] > [data-fx="head"] { grid-column: 2; }
  html[data-fx="on"] [data-fx="split"][data-fx-side="left"] > .fx-stage { grid-column: 1; }
  html[data-fx="on"] [data-fx="split"] > [data-fx="head"] :is(h2, h3) { font-size: clamp(2.1rem, 3.3vw, 3.25rem); line-height: 1.18; letter-spacing: -0.02em; }   /* 구역 제목 — index.html 은 h3, ax-ready.html 은 h2 */
  @supports (width: 1cqw) {   /* 제목은 한 줄 — 칸에 한 줄로 들어가는 크기를 넘지 않는다(칸은 584px 에서 더 안 넓어지는데 글자는 화면을 따라 커져서, 1460px 부터 꺾였다) */
    html[data-fx="on"] [data-fx="split"] > [data-fx="head"] :is(h2, h3) { font-size: min(clamp(2.1rem, 3.3vw, 3.25rem), calc(100cqw / var(--fx-fit, 12.2))); white-space: nowrap; }
  }
  html[data-fx="on"] [data-fx="split"] > [data-fx="head"] p { font-size: 1.2rem; line-height: 1.7; }

  /* AX — 세 층은 왼쪽에 머물고(따라 내려온다), 오른쪽에 제목과 「통로 · 교과서 · 규칙」 석 줄이 온다.
     석 줄에 손을 올리면 바로 옆의 그 층에 전기가 들어온다. 인용문은 석 줄 아래에 온다.
     (격자 칸 안의 sticky 는 칸이 아니라 격자 전체를 따라 내려온다 — 그래서 왼쪽 줄은 끝까지 무대 몫으로 비워 둔다) */
  html[data-fx="on"] [data-fx="split"] > [data-fx="ax-body"] { display: contents; }
  html[data-fx="on"] [data-fx="split"][data-fx-side="left"] > .fx-stage {
    grid-row: 1 / span 3; position: sticky; top: 12vh; align-self: start; min-height: 0; height: 80vh; margin: 0;
  }
  html[data-fx="on"] [data-fx="ax-body"] > [data-fx="panel"] { grid-column: 2; grid-row: 2; }
  html[data-fx="on"] [data-fx="ax-body"] > [data-fx="ax-quote"] { grid-column: 2; grid-row: 3; margin-top: 2.5rem; }
}

/* ══ AX Ready 쪽 (ax-ready.html) ══ 구간 이름이 ar- 로 시작한다. 구간마다 무엇이 뜨는지는 fx.js 의 SCENES 표 아래쪽
   (2026-10-03 사장님 「이 페이지도 비슷한 효과로」). 글은 그대로다 — 넓은 화면에서 그림이 설 자리를 내는 배치만 바꾼다.
   제목과 무대를 나란히 놓는 구간(준비할 것 · 여덟 패턴)은 위의 split 규칙을 그대로 쓴다. */
html[data-fx="on"] [data-fx="ar-hero"] { text-shadow: 0 1px 14px rgba(2, 6, 23, 0.9), 0 0 2px rgba(2, 6, 23, 0.6); }
html[data-fx="on"] [data-scene="ar-hero"] { padding-top: 6.5rem; }                   /* 머리띠 바로 아래에서 시작 — 그림이 첫 화면에 다 들어온다 */
html[data-fx="on"] [data-scene^="ar-"] [data-fx="split"] > [data-fx="head"] > p:first-child { font-size: 1rem; line-height: 1.5; }   /* 제목 위의 작은 이름(「AX Ready」 · 「방법론」) — 부제처럼 키우지 않는다 */
html[data-fx="on"] [data-scene="ar-ready"] [data-fx="head"] { --fx-fit: 11.28; }     /* 「준비할 것은 세 가지뿐입니다」 10.74 */
html[data-fx="on"] [data-scene="ar-pattern"] [data-fx="head"] { --fx-fit: 14.96; }   /* 「현장의 AI 요구는 8가지로 수렴합니다」 14.25 */
/* 유리판(glass-card)이 아닌 글 상자 — 「달라지는 것」의 전 · 후 상자와 그 아래 두 줄, 「단계」 아래 안내. 바탕이 2~6% 라 뒤의 입자가 글에 그대로 비친다.
   유리판과 같은 받침을 깐다(「AX 후」 상자는 분위기 색을 조금 섞어 구별을 남긴다). 본문은 안 건드리려고 그 상자들의 바탕 클래스로 고른다 */
html[data-fx="on"] [data-scene^="ar-"] :is([class*="bg-white/["], [class*="bg-brand-500/["]) {
  background-color: rgba(7, 15, 34, 0.6);
  -webkit-backdrop-filter: blur(12px) saturate(1.15); backdrop-filter: blur(12px) saturate(1.15);
}
@supports (background-color: color-mix(in srgb, red 50%, blue)) {
  html[data-fx="on"] [data-scene^="ar-"] [class*="bg-brand-500/["] { background-color: color-mix(in srgb, var(--fx-accent) 9%, rgba(7, 15, 34, 0.62)); }
}
html[data-fx="on"] .fx-stage[data-fx-stage="ar-genie"] { min-height: 48vh; margin-bottom: 1.5rem; }   /* 「지니 AX」 제목 위에 지니가 떠오른다 */
html[data-fx="on"] .fx-stage[data-fx-stage="ar-cta"] { min-height: 62vh; margin-bottom: 3rem; }   /* 마지막 — 로고와 램프. 아래 여백 = 램프 밑에 뜨는 「문질러 보세요」 안내가 제목 글자 위로 내려오지 않게 */
@media (min-width: 1024px) {
  /* 첫 화면 — 글 왼쪽, 오른쪽에 병목 그림. 글 네 덩이(이름표 · 제목 · 설명 · 단추)는 위아래 가운데에 모아 둔다
     (무대가 더 높아도 글 사이가 벌어지지 않게 위아래에 빈 줄을 하나씩 둔다) */
  html[data-fx="on"] [data-fx="ar-hero"] {
    max-width: 80rem; display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr); grid-template-rows: 1fr auto auto auto auto 1fr;
    column-gap: 3.5rem; justify-items: start; text-align: left; container-type: inline-size; --fx-fit: 12.96;   /* 「시스템이 먼저 준비되어야 합니다」 12.35 */
  }
  html[data-fx="on"] [data-fx="ar-hero"] > * { grid-column: 1; }
  html[data-fx="on"] [data-fx="ar-hero"] > :first-child { grid-row: 2; }
  html[data-fx="on"] [data-fx="ar-hero"] > h1 { grid-row: 3; }
  html[data-fx="on"] [data-fx="ar-hero"] > p { grid-row: 4; margin-left: 0; margin-right: 0; }
  html[data-fx="on"] [data-fx="ar-hero"] > .flex { grid-row: 5; justify-content: flex-start; }
  html[data-fx="on"] [data-fx="ar-hero"] > .fx-stage { grid-column: 2; grid-row: 1 / -1; justify-self: stretch; min-height: min(72vh, 740px); }
  @supports (width: 1cqw) {   /* 제목 둘째 줄은 한 줄 — 왼쪽 칸 폭 = (전체 − 틈) × 1.2 / 2.2 */
    html[data-fx="on"] [data-fx="ar-hero"] > h1 { font-size: min(3.75rem, calc((100cqw - 3.5rem) * 0.5454 / var(--fx-fit))); }
    html[data-fx="on"] [data-fx="ar-hero"] > h1 > span { white-space: nowrap; }
  }
  /* 인용문 — 왼쪽에 배선 그림, 오른쪽에 인용문 */
  html[data-fx="on"] [data-fx="ar-quote"] { max-width: 80rem; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); column-gap: 4rem; align-items: center; }
  html[data-fx="on"] [data-fx="ar-quote"] > .fx-stage { min-height: 62vh; }
  /* 준비할 것 세 가지 — 층 그림은 왼쪽에 머물고(따라 내려온다), 오른쪽에 제목과 세 카드가 세로로 온다. 카드에 손을 올리면 바로 옆의 그 층에 전기가 들어온다 */
  html[data-fx="on"] [data-scene="ar-ready"] [data-fx="split"] { grid-template-rows: auto auto 1fr; }   /* 화면이 아주 높아 무대(80vh)가 글보다 길어도 제목과 카드 사이는 그대로다 */
  html[data-fx="on"] [data-fx="split"] > [data-fx="ar-cards"] { grid-column: 2; grid-row: 2; grid-template-columns: minmax(0, 1fr); align-self: start; }
  /* 여덟 패턴 — 엔진 그림은 오른쪽에 머물고(따라 내려온다), 왼쪽에 제목과 여덟 카드가 두 줄씩 온다. 카드에 손을 올리면 바로 옆의 그 가지에 불이 들어온다
     (카드를 그림 아래에 네 줄로 두면, 손을 올릴 때는 그림이 화면 밖으로 올라가 있어 가지가 답하는 것이 안 보인다) */
  html[data-fx="on"] [data-scene="ar-pattern"] [data-fx="split"] { grid-template-rows: auto 1fr; }
  html[data-fx="on"] [data-scene="ar-pattern"] [data-fx="split"] > .fx-stage { grid-row: 1 / span 2; position: sticky; top: 12vh; align-self: start; min-height: 0; height: 80vh; margin: 0; }
  html[data-fx="on"] [data-fx="split"] > [data-fx="ar-nodes"] { grid-column: 1; grid-row: 2; grid-template-columns: repeat(2, minmax(0, 1fr)); align-self: start; }
}
@media (max-width: 1023.98px) {
  html[data-fx="on"] [data-scene="ar-hero"] { padding-top: 5.5rem; }
  html[data-fx="on"] [data-fx="ar-hero"] { display: flex; flex-direction: column; }   /* 그림이 맨 위, 글이 그 아래 */
  html[data-fx="on"] [data-fx="ar-hero"] > :first-child { align-self: center; }
  html[data-fx="on"] [data-fx="ar-hero"] > .fx-stage { order: -1; min-height: 50vh; }
  html[data-fx="on"] .fx-stage[data-fx-stage="ar-ready"] { min-height: 58vh; }        /* 위아래로 긴 구조다 */
}

/* 브랜드 스토리 — 제목과 카드 석 장 사이에 지니·시스템·로고가 떠오른다 */
html[data-fx="on"] .fx-stage[data-fx-stage="story"] { min-height: 46vh; }
html[data-fx="on"] .fx-stage[data-fx-stage="contact"] { min-height: 62vh; }
html[data-fx="on"] .fx-stage[data-fx-stage="brand"] { min-height: 46vh; }
/* 데모 — 노트북과 휴대폰은 잡아서 돌릴 수 있다 */
html[data-fx="on"] .fx-stage[data-fx-stage="demo"] { pointer-events: auto; cursor: grab; touch-action: pan-y; -webkit-user-select: none; user-select: none; }
html[data-fx="on"] .fx-stage[data-fx-stage="demo"].fx-grabbing { cursor: grabbing; }

/* 좁은 화면 — 무대가 제목 아래에 온다 */
@media (max-width: 1023.98px) {
  html[data-fx="on"] [data-fx="hero-grid"] > .fx-stage { order: 0; min-height: 50vh; }
  html[data-fx="on"] [data-fx="hero-grid"] > [data-fx="copy"] { order: 1; }
  html[data-fx="on"] [data-fx="hero-grid"] > [data-fx="hero-photo"] { order: 2; }
  html[data-fx="on"] [data-fx="about-grid"] > .fx-stage { order: -1; }
  html[data-fx="on"] [data-fx="split"] > [data-fx="head"] { margin-bottom: 1rem; }
  html[data-fx="on"] [data-fx="split"] > .fx-stage { margin-bottom: 2rem; }
  html[data-fx="on"] [data-fx="panel"] { padding: 1.25rem; }
  html[data-fx="on"] .fx-stage[data-fx-stage="ax"] { min-height: 58vh; }       /* 위아래로 긴 구조다 */
  /* 석 줄 상자가 무대 바로 아래에 오게 — 넓은 화면과 같은 차례(제목 → 석 줄 → 인용문). 석 줄을 누를 때 세 층이 같이 보인다 */
  html[data-fx="on"] [data-fx="ax-body"] { display: flex; flex-direction: column; gap: 3rem; }
  html[data-fx="on"] [data-fx="ax-body"] > [data-fx="panel"] { order: -1; }
}
/* 휴대폰 — 조금만 줄이면 한 줄에 들어가는 제목은 칸에 맞춰 줄인다. 원래 크기는 index.html 의 text-3xl(30px) · text-2xl(24px) */
@media (max-width: 767.98px) {
  @supports (width: 1cqw) {
    /* 사업영역 제목 — 390 에서 28px · 접는 휴대폰의 바깥 화면(280)에서 19px. 18px 아래로는 안 줄인다(그때는 두 줄). AX 제목은 길어서 원래 크기로 두 줄이다 */
    html[data-fx="on"] [data-scene="services"] [data-fx="head"] h3 { letter-spacing: -0.02em; font-size: max(1.125rem, min(1.875rem, calc(100cqw / var(--fx-fit)))); }
    /* AX 유리판의 큰 글 — 둘째 줄 「시스템이 먼저 준비되어야 합니다」(12.77)가 유리판 안쪽에 들어가게. 유리판 여백 때문에 원래(두 줄)보다 한 줄 늘어 있었다 */
    html[data-fx="on"] [data-fx="panel"] { container-type: inline-size; }
    html[data-fx="on"] [data-fx="panel"] h2 { font-size: max(1.25rem, min(1.5rem, calc(100cqw / 13.4))); }
  }
}

/* ── 램프 옆 안내 ── */
.fx-rub {
  position: fixed; z-index: 30; left: 0; top: 0; pointer-events: none; text-align: center;
  font-size: 13px; font-weight: 600; color: var(--fx-grad-a); letter-spacing: 0.02em; white-space: nowrap;
  transform: translate(-50%, 0); opacity: 0; transition: opacity 0.5s; text-shadow: 0 2px 12px rgba(2, 6, 23, 0.9);
}
html[data-fx="on"] .fx-rub.fx-show { opacity: 1; }
.fx-rub u { display: block; width: 132px; height: 3px; margin: 9px auto 0; border-radius: 3px; background: rgba(255, 255, 255, 0.12); overflow: hidden; text-decoration: none; }
.fx-rub u b { display: block; height: 100%; width: 0; border-radius: 3px; background: linear-gradient(90deg, var(--fx-accent), var(--fx-brass)); }

/* ── AX 이름표 — 3D 구조의 자리마다 붙는 글자 (자리는 fx.js 가 매 장면 옮긴다) ── */
.fx-tags { position: fixed; inset: 0; z-index: 4; pointer-events: none; overflow: hidden; display: none; }
html[data-fx="on"] .fx-tags { display: block; }
.fx-tag { position: absolute; left: 0; top: 0; will-change: transform; --fx-tail: 29px; }   /* --fx-tail 이음선 20px + 글자와의 사이 9px (fx.js 가 겹침을 셈할 때 읽는다) */
.fx-tag i {
  display: block; white-space: nowrap; font: 700 15px/1.2 Pretendard, -apple-system, 'Malgun Gothic', sans-serif; letter-spacing: 0.01em;
  color: #cfeeee; opacity: 0; transform: translate(-50%, -50%); transition: opacity 0.35s, color 0.3s, transform 0.35s;
  text-shadow: 0 1px 10px rgba(2, 6, 23, 0.95), 0 0 3px rgba(2, 6, 23, 0.9);
}
.fx-tag[data-side="right"] i { transform: translate(-100%, -50%); }
.fx-tag[data-side="left"] i { transform: translate(0, -50%); }
.fx-tag b { color: var(--fx-accent); font-weight: 700; margin-right: 7px; font-variant-numeric: tabular-nums; }
.fx-tag[data-side="right"] i::after, .fx-tag[data-side="left"] i::before {
  content: ''; display: inline-block; width: 20px; height: 1px; vertical-align: middle; background: var(--fx-accent); opacity: 0.7;
}
.fx-tag[data-side="right"] i::after { margin-left: 9px; }
.fx-tag[data-side="left"] i::before { margin-right: 9px; }
.fx-tags.fx-show .fx-tag.fx-main i { opacity: 0.8; }
.fx-tags.fx-show .fx-tag.fx-main.fx-on i { opacity: 1; color: #fff; }
/* 큰 이름표의 글자는 어두운 받침 위에 선다 — 받침 없이 3D 위에 뜨면 빛알이 글자 뒤를 지나가는 순간 번호가 3:1 아래로 떨어진다(심해 청록 2.98 · 새벽 2.42).
   2026-10-03 — 자리마다 24번 찍어 잰 것(한두 번 찍어서는 안 걸린다). 받침은 글자 쪽에만 깐다: 이음선(--fx-tail)은 받침 밖으로 뻗어 자리를 가리킨다.
   작은 이름표가 이 받침에 걸리면 fx.js 가 작은 것을 위나 아래로 비켜 세운다(겹치면 한쪽 글이 묻힌다) */
.fx-tag.fx-main i { padding: 4px 10px; border-radius: 9px; background: rgba(4, 12, 26, 0.85); }
.fx-tag.fx-main[data-side="right"] i { padding-right: 0; background: linear-gradient(to left, transparent calc(var(--fx-tail) - 8px), rgba(4, 12, 26, 0.85) calc(var(--fx-tail) - 8px)); }
.fx-tag.fx-main[data-side="left"] i { padding-left: 0; background: linear-gradient(to right, transparent calc(var(--fx-tail) - 8px), rgba(4, 12, 26, 0.85) calc(var(--fx-tail) - 8px)); }
/* 작은 이름표 — 그 층에 전기가 들어왔을 때만 뜬다 */
.fx-tag:not(.fx-main) i {
  font-size: 12px; font-weight: 700; padding: 3px 9px; border-radius: 999px; color: #04121a; background: var(--fx-grad-a); text-shadow: none;
  box-shadow: 0 4px 14px -4px rgba(2, 6, 23, 0.9); transform: translate(-50%, -50%) scale(0.8);
}
.fx-tags.fx-show .fx-tag:not(.fx-main).fx-on i { opacity: 0.96; transform: translate(-50%, -50%) scale(1); }
@media (max-width: 1023.98px) {
  .fx-tag { --fx-tail: 16px; }
  .fx-tag i { font-size: 12px; }
  .fx-tag.fx-main i { padding: 3px 8px; border-radius: 8px; }
  .fx-tag:not(.fx-main) i { font-size: 10.5px; padding: 2px 7px; }
  .fx-tag[data-side="right"] i::after, .fx-tag[data-side="left"] i::before { width: 10px; }
  .fx-tag[data-side="right"] i::after { margin-left: 6px; }
  .fx-tag[data-side="left"] i::before { margin-right: 6px; }
}

/* ── AX 그림 고르기 — 무대 칸 왼쪽 위의 단추 셋(층 · 병목 · 배선). 모양은 오른쪽 아래 분위기 스위치와 같다 ──
   (2026-10-03 사장님 「3가지 선택하게 … 넣어줘」. 단추는 fx.js 가 무대 칸 안에 넣는다 — 클래식에서는 칸째로 안 보인다) */
html[data-fx="on"] .fx-stage[data-fx-stage="ax"] { position: relative; }   /* 단추가 붙을 기준. 넓은 화면에서는 위의 sticky 규칙이 이긴다(sticky 도 기준이 된다) */
.fx-pick {
  position: absolute; left: 0; top: 0; z-index: 5; display: flex; align-items: center; gap: 4px; padding: 5px 5px 5px 15px; border-radius: 999px;
  background: rgba(2, 6, 23, 0.84); border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  font: 600 13px/1.2 Pretendard, -apple-system, 'Malgun Gothic', sans-serif; color: var(--fx-grad-a); white-space: nowrap; pointer-events: auto;
}
.fx-pick span { margin-right: 5px; }
.fx-pick button {
  border: 0; cursor: pointer; font: inherit; color: #cbd5e1; padding: 8px 13px; border-radius: 999px; background: transparent;
  transition: background 0.25s, color 0.25s;
}
.fx-pick button:hover { color: #fff; }
.fx-pick button[aria-pressed="true"] { background: var(--fx-accent); color: #04121a; }
@media (max-width: 1023.98px) {
  .fx-pick { padding-left: 12px; }
  .fx-pick button { padding: 9px 12px; }
}

/* ── 오른쪽 아래 — 분위기 스위치와 소리 단추 (클래식에서도 보인다: 돌아갈 길이 있어야 한다) ── */
.fx-dock {
  position: fixed; right: 16px; bottom: 16px; z-index: 45; display: flex; flex-direction: column; align-items: flex-end; gap: 8px;
  font-family: Pretendard, -apple-system, 'Malgun Gothic', sans-serif; transition: transform 0.3s, opacity 0.3s;
}
.fx-dock .fx-sw {
  display: flex; align-items: center; gap: 4px; padding: 5px; border-radius: 999px;
  background: rgba(2, 6, 23, 0.84); border: 1px solid rgba(255, 255, 255, 0.12);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
}
.fx-dock button {
  border: 0; cursor: pointer; font: inherit; font-size: 13px; font-weight: 600; color: #cbd5e1; line-height: 1.2;
  padding: 8px 13px; border-radius: 999px; background: transparent; transition: background 0.25s, color 0.25s, opacity 0.25s; white-space: nowrap;
}
.fx-dock button:hover { color: #fff; }
.fx-dock button[aria-pressed="true"] { background: var(--fx-accent); color: #04121a; }
.fx-dock button:disabled { opacity: 0.38; cursor: not-allowed; }
.fx-dock .fx-bar { width: 1px; align-self: stretch; margin: 5px 3px; background: rgba(255, 255, 255, 0.14); }
.fx-dock .fx-snd { display: inline-flex; align-items: center; gap: 6px; }
.fx-dock .fx-snd svg, .fx-dock .fx-fab svg { width: 16px; height: 16px; flex: none; }
.fx-dock .fx-snd .fx-wave { display: none; }
.fx-dock .fx-snd[aria-pressed="true"] .fx-wave { display: inline; }
.fx-dock .fx-snd[aria-pressed="true"] .fx-mute { display: none; }
/* 켜 두기로 했는데 브라우저가 아직 소리를 안 풀어 준 동안(방문자가 화면을 처음 누르기 전) — 켜진 것처럼 칠하지 않는다. 「곧 켜진다」 만 보인다 */
.fx-dock .fx-snd[data-wait="1"] { color: var(--fx-grad-a); box-shadow: inset 0 0 0 1px var(--fx-accent); }
.fx-dock .fx-snd[data-wait="1"] .fx-wave { display: inline; opacity: 0.5; }
.fx-dock .fx-snd[data-wait="1"] .fx-mute { display: none; }
.fx-dock .fx-snd.fx-nudge { animation: fx-nudge 1.6s ease-in-out 3; }
@keyframes fx-nudge { 50% { box-shadow: 0 0 0 4px rgba(130, 213, 213, 0.35); color: #fff; } }
html[data-fx="off"] .fx-dock .fx-snd, html[data-fx="off"] .fx-dock .fx-bar { display: none; }     /* 클래식에는 소리도 없다 */
.fx-dock .fx-fab { display: none; }
.fx-dock .fx-meter, .fx-dock .fx-why {
  font-size: 12px; padding: 6px 12px; border-radius: 12px; background: rgba(2, 6, 23, 0.86); max-width: min(86vw, 420px);
}
.fx-dock .fx-meter { color: #94a3b8; border: 1px solid rgba(255, 255, 255, 0.08); font-variant-numeric: tabular-nums; }
.fx-dock .fx-why { color: #fde68a; border: 1px solid rgba(253, 230, 138, 0.3); }
.fx-dock [hidden] { display: none !important; }

/* 좁은 화면 — 동그란 단추 하나로 접어 두고, 누르면 펼친다 */
@media (max-width: 1023.98px) {
  .fx-dock { right: 12px; bottom: 12px; }
  .fx-dock .fx-fab {
    display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; padding: 0;
    background: rgba(2, 6, 23, 0.86); border: 1px solid rgba(255, 255, 255, 0.16); color: var(--fx-grad-a);
    -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  }
  .fx-dock .fx-fab svg { width: 20px; height: 20px; }
  .fx-dock .fx-sw { display: none; flex-wrap: wrap; justify-content: flex-end; border-radius: 22px; max-width: calc(100vw - 24px); }
  .fx-dock[data-open="1"] .fx-sw { display: flex; }
  .fx-dock button { padding: 9px 12px; }
}

@media (prefers-reduced-motion: reduce) {
  html[data-fx="on"] .fx-wish, .fx-dock .fx-snd.fx-nudge { animation: none; }
}
@media print {
  #fxStage, .fx-dock, .fx-rub, .fx-stage, .fx-tags { display: none !important; }
}
