File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
// 로그인 화면 — 시안: 관리자페이지(QsFVFFUKGH68xAPVkF3SJ9) login 5435:14598
//
// 입력·라벨·버튼은 시안이 디자인시스템 컴포넌트를 그대로 쓰고 있어 FoxInput/FoxButton으로
// 덮인다. 여기 남는 건 화면 셸(배경·중앙 정렬)과 카드, 그리고 비밀번호 보기 토글의 자리뿐이라
// @fox에 넣지 않고 화면 전용으로 둔다(사용자 확정). 값은 전부 @fox 토큰을 거친다.
@use "@fox/styles/abstracts" as fox;
.page {
display: flex;
flex: 1;
align-items: center;
justify-content: center;
padding: fox.padding(8);
background: fox.color(background-neutral);
}
.card {
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
gap: fox.gap(5);
// 시안 440px. Figma가 변수로 export하지 않는다.
inline-size: 44rem;
max-inline-size: 100%;
padding: fox.padding(10);
border-radius: fox.radius(6);
background: fox.color(surface-neutral-default);
// 시안의 neutral/lv2 — 가까운 그림자와 먼 그림자 두 겹이다.
box-shadow:
fox.shadow(location1) fox.shadow(location1) fox.shadow(blur2) 0
fox.primitive(alpha-black10),
fox.shadow(location3) fox.shadow(location3) fox.shadow(blur3) 0
fox.primitive(alpha-black10);
}
.title {
inline-size: 100%;
margin: 0;
color: fox.color(font-neutral-strong);
font-family: fox.font-family(title);
font-size: fox.font-size(display-md);
font-weight: fox.font-weight(bold);
line-height: 1.5;
letter-spacing: -0.025em;
}
.fields {
display: flex;
inline-size: 100%;
flex-direction: column;
gap: fox.gap(5);
}
// 비밀번호 칸 — 보기 토글을 입력 위에 얹기 위한 위치 기준이다.
.passwordField {
position: relative;
}
// FoxInput의 `icon` 슬롯은 `aria-hidden="true"`라 그 안에 버튼을 넣으면 보조기술에서
// 사라진다. 그래서 슬롯을 쓰지 않고 같은 자리에 버튼을 겹쳐 놓는다 — 시안의 아이콘 위치
// (오른쪽 여백 form/padding/lg 안쪽)와 크기(24)를 그대로 맞춘다.
//
// 아래에서 띄우는 방식이라 **입력칸이 이 래퍼의 마지막 요소여야** 가운데에 온다. 오류 문구를
// FoxInput의 `message`가 아니라 카드의 helper 자리에 모아 두는 이유가 이것이다.
.passwordToggle {
position: absolute;
inset-block-end: calc(
(#{fox.form(height-lg)} - #{fox.form(icon-lg)}) / 2
);
inset-inline-end: fox.form(padding-lg);
display: inline-flex;
align-items: center;
justify-content: center;
inline-size: fox.form(icon-lg);
block-size: fox.form(icon-lg);
padding: 0;
border: none;
background: none;
color: fox.color(icon-neutral-default);
cursor: pointer;
}
.passwordToggle > svg {
inline-size: 100%;
block-size: 100%;
}
// 브라우저 자동완성이 채운 칸은 Chrome이 자기 배경(연한 파랑)을 칠한다 — 일반 CSS로는 못
// 덮어서 `inset` 그림자로 가리는 것이 표준 우회다. 글자색은 `-webkit-text-fill-color`로만
// 바꿀 수 있다. 전환을 길게 잡는 편법 대신 그림자를 쓰므로 애니메이션이 필요 없다.
//
// @fox에도 앱 어디에도 이 처리가 없어 모든 FoxInput이 같은 상태다 — 여기서는 로그인 카드
// 안으로 범위를 좁혀 두었다. 디자인시스템에 올릴지는 별도 판단이 필요하다.
.card :global(.fox-input__field):autofill,
.card :global(.fox-input__field):-webkit-autofill {
box-shadow: inset 0 0 0 100rem fox.color(input-surface);
-webkit-text-fill-color: fox.color(font-neutral-default);
caret-color: fox.color(font-neutral-default);
}
.helper {
inline-size: 100%;
margin: 0;
color: fox.color(font-neutral-subtle);
font-family: fox.font-family(body);
font-size: fox.font-size(body-sm);
line-height: 1.5;
letter-spacing: -0.025em;
}
.error {
color: fox.color(font-system-danger);
}
.submit {
inline-size: 100%;
}