/* 사이트 움직임 — 문서 38 구현 순서 8 · 9 · 10 · 11 (2026-10-28) · 문서 41 구현 순서 42 메뉴 아이콘 모프 (2026-10-29)

   사이트 전체에 한 번 고르는 움직임(site.motion → <html data-gl-…>)과 구역마다 고르는 «스크롤 바탕색»(style.secolor → gl-secolor-…)을
   여기 한 곳에 둔다. 페이지 넘김(7)은 @view-transition 이 «켠 사이트만» 실려야 해서 gl-vt.css 로 따로 있다.

   🔴 기능마다 접두어가 다르다 — 밑줄 uline · 굴림 roll · 메뉴 모프 morph · 바탕색 secolor · 바닥글 footreveal. 다른 효과와 이름이 겹치지 않는다.
   🔴 색은 역할 토큰만 쓴다(--accent · --surface-2 · --chip · --ondark-fg …). 새 색값을 적지 않는다.
   🔴 움직이는 것은 transform · opacity 다. 밑줄만 background-size 다(여러 줄 링크도 줄마다 그어지는 방식 — 레이아웃은 안 바뀐다).
   🔴 «움직임 줄이기» 에서는 맨 아래 절이 전부 멈춘다 — 밑줄은 바로 그어지고 · 굴림 복제는 숨고 · 바탕색은 바로 바뀌고 · 바닥글은 보통 자리. */

/* ── 8. 링크 밑줄 그어지기 (uline) ───────────────────────────────────────────
   올리거나 키보드 초점이 가면 밑줄이 왼쪽에서 그어진다. 글 속 링크(문단 · 목록 안의 꾸밈 없는 <a>)는 옅은 밑줄을 늘 두고 그 위에 진한 줄이 그어진다 —
   링크가 색만으로 구별되지 않게(WCAG 1.4.1). 바닥글 링크 · 카드의 «자세히 보기» 는 평소에 줄이 없다.
   상단 메뉴는 이미 자기 밑줄(.nav-links a::after)이 있어 건드리지 않는다. */
:root[data-gl-uline="draw"] :is(.footer-links a, .legal-info a, .why-more, :is(p, li, dd, td, figcaption) > a:not([class])) {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size 0.32s var(--ease, ease);
}
:root[data-gl-uline="draw"] :is(p, li, dd, td, figcaption) > a:not([class]) {
  background-image: linear-gradient(currentColor, currentColor), linear-gradient(color-mix(in srgb, currentColor 35%, transparent), color-mix(in srgb, currentColor 35%, transparent));
  background-size: 0% 1px, 100% 1px;
}
:root[data-gl-uline="draw"] :is(.footer-links a, .legal-info a):is(:hover, :focus-visible),
:root[data-gl-uline="draw"] .why-link:is(:hover, :focus-visible) .why-more { background-size: 100% 1px; }
:root[data-gl-uline="draw"] :is(p, li, dd, td, figcaption) > a:not([class]):is(:hover, :focus-visible) { background-size: 100% 1px, 100% 1px; }

/* ── 9. 롤링 글자 버튼 (roll) ───────────────────────────────────────────────
   gl-roll.js 가 버튼 글을 두 벌로 나눈다 — 원본(.gl-roll-a) + 복제(.gl-roll-b · aria-hidden). 올리면 원본이 위로 빠지고 복제가 밑에서 올라온다.
   스크립트가 안 돌면 나눌 것이 없어 버튼은 종전 그대로다. 같은 칸(grid 한 칸)에 겹쳐 두므로 버튼 크기는 한 벌일 때와 같다. */
.gl-roll-in { display: inline-grid; overflow: hidden; gap: inherit; vertical-align: top; padding-block: 0.12em; margin-block: -0.12em; }
.gl-roll-a, .gl-roll-b { grid-area: 1 / 1; display: inline-flex; align-items: center; gap: inherit; transition: transform 0.38s var(--ease, cubic-bezier(0.65, 0, 0.35, 1)); }
.gl-roll-b { transform: translateY(115%); }
:root[data-gl-roll="on"] :is(.btn, .nav-cta):is(:hover, :focus-visible) .gl-roll-a { transform: translateY(-115%); }
:root[data-gl-roll="on"] :is(.btn, .nav-cta):is(:hover, :focus-visible) .gl-roll-b { transform: translateY(0); }

/* ── 문서 41 · 42. 메뉴 아이콘 모프 (morph) ─────────────────────────────────────
   상단바 ☰ 버튼(gl-nav.js 가 .gl-nav-btn 을 단다 · 손으로 쓴 홈은 .nav-burger)의 세 줄이 펼침판이 열리면 ✕ 로 바뀐다.
   선은 지금 그대로 셋이다 — 가운데 줄(span)과 위 · 아래 줄(span::before · ::after · gl-nav.css). 버튼 안에 요소를 더 넣지 않는다.
     열림 — 가운데 줄이 45° 돈다 · 위 줄은 가운데로 내려오며 사라진다 · 아래 줄은 가운데로 올라와 90° 더 돌아(합쳐 135°) 반대 사선이 된다.
   🔴 무엇을 볼지는 버튼의 aria-expanded 하나다(gl-nav.js 가 열고 닫을 때 바꾼다) — 낭독기가 듣는 상태와 눈에 보이는 모양이 늘 같다.
   🔴 움직이는 것은 transform · opacity 뿐. 움직임 줄이기 — 전환 없이 바로 ✕ / ☰. */
/* 🔴 전체 화면 메뉴(35 navfull)를 함께 켜면 그쪽이 ☰ → X 를 맡는다(gl-navfull.css — 위아래 선을 ±45°). 둘이 같이 돌리면
   버튼 전체 45° + 아래 선 90° 가 겹쳐 X 가 아니라 가로줄 하나(«—»)가 됐다(2026-10-29 예제 화면에서 발견). 그래서 navfull 이 살아 있으면 이 절은 물러난다. */
:root[data-gl-morph="on"]:not(.gl-navfull-live) :is(.gl-nav-btn, .nav-burger) span,
:root[data-gl-morph="on"]:not(.gl-navfull-live) :is(.gl-nav-btn, .nav-burger) span::before,
:root[data-gl-morph="on"]:not(.gl-navfull-live) :is(.gl-nav-btn, .nav-burger) span::after { transition: transform .32s cubic-bezier(.65, 0, .35, 1), opacity .2s ease; }
:root[data-gl-morph="on"]:not(.gl-navfull-live) :is(.gl-nav-btn, .nav-burger)[aria-expanded="true"] span { transform: rotate(45deg); }
:root[data-gl-morph="on"]:not(.gl-navfull-live) :is(.gl-nav-btn, .nav-burger)[aria-expanded="true"] span::before { transform: translateY(6px); opacity: 0; }
:root[data-gl-morph="on"]:not(.gl-navfull-live) :is(.gl-nav-btn, .nav-burger)[aria-expanded="true"] span::after { transform: translateY(-6px) rotate(90deg); }

/* ── 10. 섹션 색 전환 (secolor) ─────────────────────────────────────────────
   기본(스크립트 없음 · 움직임 줄이기 전) — 고른 구역만 그 색으로 칠해 둔다. 글자 역할 토큰도 짝이 맞는 칸으로 바꾼다.
   gl-secolor.js 가 돌면(html.gl-secolor-live) 구역은 투명해지고, 화면 뒤에 깔린 층 하나(.gl-secolor-layer)가 그 구역이 화면 가운데에 올 때
   그 색으로 나타난다(opacity) — 이웃한 바탕 없는 구역까지 «화면 바탕이 바뀌는» 효과다. 글자 짝은 구역이 가운데에 있는 동안만(.is-secolor-in). */
.gl-secolor-soft { background-color: var(--accent-soft); }
.gl-secolor-surface2 { background-color: var(--surface-2); }
.gl-secolor-chip { background-color: var(--chip); }
.gl-secolor-accent { background-color: var(--accent); }
:is(html:not(.gl-secolor-live) .gl-secolor-chip, .gl-secolor-chip.is-secolor-in) {
  --fg: var(--ondark-fg); --fg-strong: var(--ondark-fg); --muted: var(--ondark-fg); --muted-2: var(--ondark-fg);
  color: var(--ondark-fg);
}
:is(html:not(.gl-secolor-live) .gl-secolor-accent, .gl-secolor-accent.is-secolor-in) {
  --fg: var(--on-accent, var(--black)); --fg-strong: var(--on-accent, var(--black)); --muted: var(--on-accent, var(--black)); --muted-2: var(--on-accent, var(--black));
  color: var(--on-accent, var(--black));
}
html.gl-secolor-live :is(.gl-secolor-soft, .gl-secolor-surface2, .gl-secolor-chip, .gl-secolor-accent) { background-color: transparent; transition: color 0.6s var(--ease, ease); }
.gl-secolor-layer { position: fixed; inset: 0; z-index: -1; pointer-events: none; opacity: 0; transition: opacity 0.6s var(--ease, ease); }
.gl-secolor-layer[data-c="soft"] { background-color: var(--accent-soft); }
.gl-secolor-layer[data-c="surface2"] { background-color: var(--surface-2); }
.gl-secolor-layer[data-c="chip"] { background-color: var(--chip); }
.gl-secolor-layer[data-c="accent"] { background-color: var(--accent); }
.gl-secolor-layer.is-on { opacity: 1; }

/* ── 11. 바닥글 드러남 (footreveal) ─────────────────────────────────────────
   gl-footreveal.js 가 바닥글이 화면보다 작을 때만 html.gl-footreveal-live 를 단다(스크립트 없음 · 움직임 줄이기 · 긴 바닥글은 보통 자리).
   바닥글은 화면 아래에 붙어(sticky) 본문 «뒤»(z-index -1)에 깔리고, 본문이 위로 걷히면 드러난다.
   🔴 본문 칸이 투명하면 뒤의 바닥글이 비친다 — 몸통의 맨 위 칸에 페이지 바탕을 깐다(:where 로 무게 0 — 구역이 칠한 바탕이 늘 이긴다).
   🔴 투명한 구역(스크롤 바탕색 등) 밑으로 바닥글이 비치지 않게, 본문 끝이 화면 아래에 닿기 전에는 바닥글을 투명하게 둔다(is-footreveal-near 전).
      투명할 뿐 초점은 간다 — 초점이 바닥글로 가면 스크립트가 맨 아래로 내려 보이게 한다. */
/* 🔴 몸통을 쌓임 맥락으로 만든다(z-index 0) — 안 그러면 z-index -1 바닥글이 몸통 «아래» 로 내려가 보여도 눌리지 않는다(누른 자리가 몸통으로 잡힌다 · 2026-10-28 헤드리스 확인) */
html.gl-footreveal-live body { position: relative; z-index: 0; }
html.gl-footreveal-live body > footer { position: sticky; bottom: 0; z-index: -1; opacity: 0; }
html.gl-footreveal-live.is-footreveal-near body > footer { opacity: 1; }
:where(html.gl-footreveal-live body > :not(footer, script, style, link, nav, [data-gl-float], .gl-secolor-layer, .gl-footreveal-sentinel)) { background-color: var(--bg); }

/* ── 움직임 줄이기 ─────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  :root[data-gl-uline="draw"] :is(.footer-links a, .legal-info a, .why-more, :is(p, li, dd, td, figcaption) > a:not([class])) { transition: none; }
  .gl-roll-a { transform: none !important; transition: none; }
  .gl-roll-b { display: none; }
  :root[data-gl-morph="on"] :is(.gl-nav-btn, .nav-burger) :is(span, span::before, span::after) { transition: none; }
  html.gl-secolor-live :is(.gl-secolor-soft, .gl-secolor-surface2, .gl-secolor-chip, .gl-secolor-accent), .gl-secolor-layer { transition: none; }
  html.gl-footreveal-live body { position: static; z-index: auto; }
  html.gl-footreveal-live body > footer { position: static; z-index: auto; opacity: 1; }
}
