// 전역 피드백(토스트·스피너)이 화면에서 차지하는 자리. // // FoxToast·FoxSpinner는 모양만 갖고 어디에 뜰지는 호출부가 정한다(@fox 규칙) — 그 배치를 // 여기서 준다. // // 이슈: FoxModal은 `.showModal()`이라 브라우저 top layer에 올라간다. 보통 요소는 // z-index를 아무리 올려도 그 위에 그릴 수 없어, 모달을 띄운 채 저장에 실패하면 토스트가 // 모달 뒤에 가려진다. 그래서 토스트도 popover로 같은 top layer에 얹는다 — popover의 기본 // 스타일(가운데 정렬·테두리·배경)을 아래에서 전부 지우는 이유다. @use "@fox/styles/abstracts" as fox; .toastLayer { position: fixed; inset-block-start: fox.padding(7); inset-block-end: auto; inset-inline: 0; inline-size: auto; max-inline-size: none; block-size: auto; max-block-size: none; margin: 0; padding-inline: fox.padding(6); border: 0; background: none; color: inherit; overflow: visible; // 읽고 지나가는 자리라 아래 화면 조작을 막지 않는다. pointer-events: none; } .toastLayer:popover-open { display: flex; flex-direction: column; align-items: center; gap: fox.gap(3); } // popover가 없는 브라우저 — top layer는 못 쓰지만 자리는 잡는다. @supports not selector(:popover-open) { .toastLayer { display: flex; flex-direction: column; align-items: center; gap: fox.gap(3); z-index: 50; } } // 스피너 막도 같은 이유로 top layer에 얹는다 — 모달 안에서 시작한 저장·삭제도 덮어야 한다. // 토스트와 달리 필요할 때만 DOM에 붙인다(막이 늘 떠 있으면 안 되므로). .spinnerLayer { position: fixed; inset: 0; inline-size: auto; max-inline-size: none; block-size: auto; max-block-size: none; margin: 0; padding: 0; border: 0; overflow: hidden; background: fox.color(background-dim); } .spinnerLayer:popover-open { display: flex; align-items: center; justify-content: center; } @supports not selector(:popover-open) { .spinnerLayer { display: flex; align-items: center; justify-content: center; z-index: 50; } }