File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
08-14
08-14
08-18
08-18
08-18
08-14
08-14
08-14
08-18
08-18
08-14
08-18
// FoxAlert — 시안: 통합관리자페이지 디자인시스템 Figma alert
//
// 화면 안에 놓이는 띠 모양 알림이다. 아이콘 상자 · 제목 · 본문이 한 줄로 선다.
// **모달이 아니다** — 화면을 덮지 않고 내용 흐름 안에 그대로 놓인다.
//
// 마크업 계약 (React 밖 소비자용):
// <div class="fox-alert fox-alert--default" role="status">
// <span class="fox-alert__icon">…아이콘…</span>
// <div class="fox-alert__content">
// <strong class="fox-alert__title">제목</strong>
// <span class="fox-alert__message">본문</span>
// </div>
// </div>
//
// 제목·본문은 각각 없을 수 있다. 아이콘 상자는 아이콘이 없어도 그린다 — 시안이 흰 판을
// 배치의 일부로 주고, 있고 없고에 따라 글자 시작점이 흔들리면 안 된다.
//
// 제목이 `heading/xsm`(title 패밀리·bold)이고 본문이 `body/md`(body 패밀리·regular)다.
// 글자 크기는 둘 다 15px이라 굵기와 패밀리로만 갈린다 — 시안이 그렇게 준다.
//
// 토큰이 아닌 값:
// - ⚠️ `inline-size: 72rem`: **시안의 폭(720px)을 일단 그대로 적용해 둔 것이다.** Figma가
// 변수로 export하지 않았고 토큰 스케일에도 720이 없다(modal 계열의 가장 큰 값이 760px).
// 토큰이 생기면 `fox.*()`로 바꾸고, 폭을 고정하지 않는 쪽으로 정해지면 여기서 뺀다.
// 그때까지 폭을 바꿔야 하는 자리는 호출부가 `className`으로 덮는다
// (`fox-toggle-quantity`와 같은 처리).
// - `max-inline-size: 100%`: 시안에 없는 구조 규칙이다. 720px보다 좁은 자리에 놓였을 때
// 띠가 부모를 뚫고 나가지 않게 막는다 — 고정 폭만 두면 표 안이나 좁은 단에서 넘친다.
// - line-height / letter-spacing: 시안 텍스트 스타일 heading/xsm·body/md의 값이나 Figma가
// 변수로 export하지 않는다. 시안의 -0.375px은 15px 기준이라 `-0.025em`으로 적는다
// (다른 컴포넌트와 같은 근거).
// - box-sizing / display / flex / aspect-ratio: 구조 규칙.
//
// 아이콘은 컴포넌트의 `TYPE_ICON`이 계열마다 하나씩 쥐고 있다(Prohibit · Warning ·
// CheckCircle · Info · ChatDots, 전부 `weight="duotone"`). 색은 **제목 글자와 같은 계열색**을
// 쓴다(default는 `font-neutral-strong`) — 시안 확인 완료.
//
// duotone은 연한 면과 진한 선을 겹쳐 그리고 **둘 다 `currentColor`를 쓴다** — 연한 쪽은
// 글리프 자체가 `opacity: 0.2`를 물고 있어 색을 하나만 줘도 두 톤이 나온다.
//
// duotone은 연한 면과 진한 선을 겹쳐 그리고 **둘 다 `currentColor`를 쓴다** — 연한 쪽은
// 글리프 자체가 `opacity: 0.2`를 물고 있어 색을 하나만 줘도 두 톤이 나온다.
//
@use "@fox/styles/abstracts" as fox;
.fox-alert {
// 안쪽 여백이 바깥 폭을 늘리지 않게 한다 — 720px이 720px로 그려진다.
box-sizing: border-box;
display: flex;
align-items: center;
gap: fox.gap(4);
inline-size: 72rem;
max-inline-size: 100%;
padding: fox.padding(5) fox.padding(6);
border: fox.border(1) solid fox.color(border-neutral-subtler);
border-radius: fox.radius(4);
background: fox.color(surface-neutral-gray);
// 정사각 흰 판. 글자가 길어져 띠가 늘어나도 크기가 그대로여야 해서 줄어들지 않게 막는다.
&__icon {
display: flex;
flex-shrink: 0;
justify-content: center;
align-items: center;
inline-size: fox.number(13);
block-size: fox.number(13);
aspect-ratio: 1 / 1;
border-radius: fox.radius(4);
background: fox.color(element-neutral-inverse);
// 글리프가 `fill: currentColor`라 이 색을 그대로 입는다. 계열이 있으면 아래에서 덮는다.
color: fox.color(font-neutral-strong);
}
// 글리프는 흰 판(36px)보다 작은 24px이다 — 판이 글리프를 감싸는 여백을 갖는다.
// 상자와 마찬가지로 줄어들지 않게 막고 정사각을 못박는다(시안이 둘 다 명시한다).
&__icon > * {
flex-shrink: 0;
inline-size: fox.icon(5);
block-size: fox.icon(5);
aspect-ratio: 1 / 1;
}
// 남는 폭을 전부 가져간다. `min-inline-size: 0`이 없으면 긴 글이 줄바꿈되지 않고 띠를
// 밀어 넓힌다(flex 자식의 기본 최소 크기가 내용 크기라서다).
&__content {
display: flex;
flex: 1 0 0;
flex-direction: column;
align-items: flex-start;
gap: fox.gap(1);
min-inline-size: 0;
}
&__title {
align-self: stretch;
color: fox.color(font-neutral-strong);
font-family: fox.font-family(title);
font-size: fox.font-size(heading-xsm);
font-weight: fox.font-weight(bold);
line-height: 1.4;
letter-spacing: -0.025em;
}
&__message {
align-self: stretch;
color: fox.color(font-neutral-strong);
font-family: fox.font-family(body);
font-size: fox.font-size(body-md);
font-weight: fox.font-weight(regular);
line-height: 1.5;
letter-spacing: -0.025em;
}
// ── 계열 ────────────────────────────────────────────────────────────────────
// 계열이 바꾸는 것은 **배경 · 테두리 · 제목 글자색** 셋뿐이다. 본문 글자색과 아이콘 상자의
// 흰 배경은 계열과 무관하게 블록 규칙을 그대로 쓴다(시안 확인).
//
// 테두리만 `-inverse`다 — 같은 계열의 5(연한 배경)와 10(그보다 한 단계 진한 선)을 짝지어
// 쓰라고 토큰이 그렇게 갈라져 있다. 다크 모드에서는 세 값이 함께 뒤집힌다(95 / 90 / 20).
//
// `default`는 블록 규칙이 곧 그 계열의 모양이라 따로 덮을 것이 없다.
&--default {
// 시안 그대로 — 블록에 있는 값이 전부다.
}
&--information {
border-color: fox.color(border-system-information-inverse);
background: fox.color(surface-system-information);
}
&--information &__title,
&--information &__icon {
color: fox.color(font-system-information);
}
&--success {
border-color: fox.color(border-system-success-inverse);
background: fox.color(surface-system-success);
}
&--success &__title,
&--success &__icon {
color: fox.color(font-system-success);
}
&--warning {
border-color: fox.color(border-system-warning-inverse);
background: fox.color(surface-system-warning);
}
&--warning &__title,
&--warning &__icon {
color: fox.color(font-system-warning);
}
&--danger {
border-color: fox.color(border-system-danger-inverse);
background: fox.color(surface-system-danger);
}
&--danger &__title,
&--danger &__icon {
color: fox.color(font-system-danger);
}
}