// 말풍선 공용 조각. // // 꼬리가 달린 판(`FoxPopover` · `FoxTooltipRich`)이 같은 그림을 쓴다. 그 되풀이를 여기로 모은다. // 믹스인만 있고 규칙이 없어 @use 해도 CSS가 늘지 않는다 — 부르는 자리에서만 나온다. // // ── 꼬리를 CSS로 그리는 이유 ─────────────────────────────────────────────────── // // 시안은 꼬리를 22×12 SVG로 준다. 그 그림에는 평평한 끝을 덮는 1px 흰 띠가 들어 있는데, // 꼬리를 판 위로 1px 겹쳐 올려 그 띠로 판의 1px 테두리를 지우는 구조다. Figma에서는 맞지만 // 브라우저에서는 **1px 두 개를 정확히 겹쳐야 하는 방식**이라, 소수 배율 화면(윈도우 125% 등)에서 // 둘이 서로 다른 물리 픽셀에 떨어지면 이음새에 실선이 비친다. 실제로 그렇게 보였다. // // 그래서 CSS로 그린다. **회전한 정사각형의 절반을 판 위에 걸치는** 방식이다: // // 1. 한 변이 22 ÷ √2(≈15.56px)인 정사각형을 45° 돌린다 → 밑변 22px, 높이 11px의 마름모 // 2. 그 마름모의 **가운데를 판과 맞닿는 변 위에** 둔다 // 3. 바깥을 향하는 두 변에만 1px 테두리를 준다 (안쪽 두 변은 테두리 없음) // // 그러면 안쪽 절반(11px)이 판의 테두리 선을 자기 배경으로 덮는다 — 1px끼리 맞추는 것이 아니라 // 11px짜리 면이 1px 선을 덮으므로 어떤 배율에서도 이음새가 남지 않는다. 바깥 두 변의 테두리는 // 마름모의 좌우 꼭짓점, 즉 판의 테두리와 같은 높이에서 끝나므로 선이 자연스럽게 이어진다. // // 45°로 돌리면 밑변과 높이의 비가 2:1이라 22×11이 된다. 시안은 22×12이므로 돌린 뒤 세로로 // 12/11만큼 늘인다(CSS 변환은 오른쪽부터 적용되므로 `scaleY(...) rotate(45deg)` 순서다). // 빗변 테두리가 그만큼 두꺼워지지만 1.09배라 눈에 띄지 않는다. // // SVG를 쓰지 않으니 마스크 id가 문서에서 겹칠 일도 없다(시안 SVG를 그대로 넣으면 말풍선이 // 둘 이상 뜰 때 같은 id를 서로 참조한다). // // 토큰이 아닌 값: // - ⚠️ 꼬리가 차지하는 자리 22×12px: 시안이 준 그림의 크기이고 토큰 스케일에 없다. // - ⚠️ 정사각형의 한 변 `1.5556rem`: 밑변이 22px이 되는 값(22 ÷ √2)이다. 밑변을 바꾸려면 // 이 값을 √2로 나눠 다시 구한다. // - ⚠️ `scaleY(12 / 11)`: 45° 마름모의 높이(11px)를 시안의 12px로 맞추는 보정이다. // - 시안의 `gap: -1px`은 옮기지 않았다 — 정사각형의 안쪽 절반이 이미 판 위에 걸쳐 테두리를 // 덮으므로 따로 당길 필요가 없다. @use "@fox/styles/abstracts" as fox; /// 말풍선 바깥 틀. 꼬리와 판이 세로로 서고, 꼬리의 가로 위치를 이 정렬이 정한다. @mixin root($inline-size: 36rem) { box-sizing: border-box; display: flex; flex-direction: column; inline-size: $inline-size; } /// 꼬리와 방향·위치 규칙 한 벌. /// /// `$block`은 BEM 블록 이름(`"fox-popover"` 등)이고, `$border`·`$fill`은 판과 **같은 값**을 /// 넘긴다 — 꼬리는 판이 뾰족하게 튀어나온 부분이라 색이 갈리면 안 된다. /// /// 부르는 쪽은 다음 마크업을 갖는다: ///