/* 오류 표시 한 벌 — 디자인 가이드 §4.6「오류 표시 목표 모습」·§4.9「오류 알림」(v2.51.0).
 *
 * 폼 오류를 그리는 방식이 열 가지였다(cl-error · field-error · fbar-field-error ·
 * error-text · errorlist · 칸마다 alert-error 상자 · 인라인 style …).  그중 입력
 * 테두리가 실제로 빨개지는 곳은 고객 상세의 두 조상 선택자 안뿐이었다.  이 파일이
 * 그 모두를 대신하는 한 벌이다.  색은 --pundit-* 토큰만 쓴다(§2.1).
 *
 *   (a) 칸 오류     : 입력 경계(aria-invalid) + 칸 아래 한 줄 + 있으면 해결 행동
 *                     템플릿 shared/_field_errors.html
 *   (b) 폼·구역 오류: 폼/구역 맨 위 알림 상자 하나   shared/_form_errors.html
 *   (c) 페이지 오류 : 페이지 맨 위 같은 상자         shared/_messages.html
 *   (d) 스크립트    : 같은 클래스를 shared/form_errors.js(PunditFormErrors)로 만든다
 */

/* ------------------------------------------------------------------ */
/* (a) 칸 오류 — 경계                                                   */
/* ------------------------------------------------------------------ */

/* 경계의 신호는 aria-invalid 하나다.  Django 5.2 는 오류가 있는 바운드 필드의
   위젯에 aria-invalid="true" 와 aria-describedby="<id>_error" 를 스스로 붙이므로,
   {{ field }} 로 그리는 칸은 템플릿을 고치지 않아도 테두리가 빨개진다.  스크립트가
   만드는 오류도 같은 속성을 쓴다 — 화면낭독기와 눈이 같은 사실을 읽는다(§6).
   .pundit-invalid 는 라디오 묶음·파일 드롭 영역처럼 테두리가 바깥 틀에 있는 조작용. */
input[aria-invalid="true"],
select[aria-invalid="true"],
textarea[aria-invalid="true"],
.pundit-invalid {
    border-color: var(--pundit-danger);
}

/* 포커스가 들어가도 빨간 경계는 남는다.  포커스 링(§6)은 화면의 규칙이 그대로 그린다. */
input[aria-invalid="true"]:focus,
select[aria-invalid="true"]:focus,
textarea[aria-invalid="true"]:focus,
.pundit-invalid:focus-within {
    border-color: var(--pundit-danger);
}

/* ------------------------------------------------------------------ */
/* (a) 칸 오류 — 메시지와 해결 행동                                      */
/* ------------------------------------------------------------------ */

/* 입력 바로 아래, 도움말과 같은 12–13px 자리(§4.6).  아이콘을 앞에 붙이지 않는다 —
   이모지·CSS 아이콘은 보조기술에 전달되지 않고(§7) 빨간 글자와 경계가 이미 상태를
   말한다.  화면낭독기에는 「오류:」 접두어가 읽힌다(.pundit-error-prefix). */
.pundit-field-error {
    display: grid;
    justify-items: start;
    gap: 4px;
    margin: 6px 0 0;
    color: var(--pundit-danger);
    font-size: 13px;
    font-weight: 400;
    line-height: 1.5;
    text-align: left;
    overflow-wrap: anywhere;
}

.pundit-field-error[hidden] {
    display: none;
}

.pundit-field-error__message {
    margin: 0;
}

/* 해결 행동(§4.13): 「AI 검색으로 찾기」「원본값으로 되돌리기」처럼 이 오류를
   푸는 다음 한 걸음.  문장 속 링크 모양이라 40×40 표적 기준의 인라인 예외다. */
.pundit-field-error__action {
    padding: 0;
    border: 0;
    background: none;
    color: var(--pundit-primary);
    font: inherit;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.pundit-field-error__action:hover {
    color: var(--pundit-primary-strong);
}

.pundit-field-error__action:focus-visible {
    outline: 3px solid var(--pundit-primary);
    outline-offset: 2px;
    border-radius: 2px;
}

/* 화면에는 보이지 않고 화면낭독기만 읽는 접두어. */
.pundit-error-prefix {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ------------------------------------------------------------------ */
/* (b)(c) 알림 상자 — §4.9 v2.10.1 완료 배너와 같은 뼈대                 */
/* ------------------------------------------------------------------ */

/* 옅은 배경 + 옅은 1px 테두리 + 10px 모서리 + 최소 56px.  상자 전체를 빨갛게
   칠하지 않고 결과 라벨(「저장하지 못했습니다」)만 -strong 색 700 으로 세운다.
   본문은 기본 글자색 — 긴 설명이 전부 빨간 글이면 읽기 전에 겁부터 준다. */
.pundit-alert {
    box-sizing: border-box;
    display: flex;
    align-items: stretch;
    min-height: 56px;
    margin: 0 0 16px;
    border: 1px solid var(--pundit-border);
    border-radius: 10px;
    background: var(--pundit-surface);
    color: var(--pundit-text);
    font-size: 14px;
    line-height: 1.55;
    overflow-wrap: anywhere;
}

.pundit-alert[hidden] {
    display: none;
}

/* 프로그램 방식 포커스(오류 뒤 상자로 옮기는 focus())에 이중 외곽선을 만들지 않는다
   (§4.9 v2.10.1).  키보드 대상은 안의 링크와 닫기 단추다. */
.pundit-alert:focus {
    outline: none;
}

.pundit-alert__body {
    flex: 1 1 auto;
    min-width: 0;
    display: grid;
    align-content: center;
    gap: 4px;
    padding: 12px 16px;
}

.pundit-alert__label {
    font-weight: 700;
}

.pundit-alert__message {
    margin: 0;
}

.pundit-alert__list {
    margin: 0;
    padding-left: 20px;
}

.pundit-alert__list a {
    color: var(--pundit-primary-strong);
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.pundit-alert__list a:focus-visible {
    outline: 3px solid var(--pundit-primary);
    outline-offset: 2px;
}

/* 접힌 「자세히」(§4.13): 해결 문장 아래에 원문(검증 오류 문장 등)을 접어 둔다 — 원문은 조사에
   필요할 때만 펼쳐 본다.  여는 줄은 펼침 표시(▸)를 남긴 채 링크 색 700 이고, 클릭 영역은 40px(§6). */
.pundit-alert__details > summary {
    display: list-item;
    box-sizing: border-box;
    min-height: 40px;
    padding: 8px 0;
    color: var(--pundit-primary-strong);
    font-weight: 700;
    cursor: pointer;
}

.pundit-alert__details > summary:focus-visible {
    outline: 3px solid var(--pundit-primary);
    outline-offset: 2px;
}

.pundit-alert__details > .pundit-alert__message {
    color: var(--pundit-muted-strong);
    font-size: 13px;
}

/* 닫기(×): 오른쪽 42×42 영역 한가운데, 본문과는 옅은 세로선으로 가른다(v2.10.1). */
.pundit-alert__close {
    flex: 0 0 42px;
    align-self: stretch;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 42px;
    min-height: 42px;
    margin: 0;
    padding: 0;
    border: 0;
    /* 본문과 가르는 옅은 세로선.  단추의 윤곽이 아니라 구분선이라(§2.1 장식 경계)
       테두리 대신 안쪽 그림자 1px 로 그린다 — 테두리로 그리면 조작 경계로 읽힌다. */
    box-shadow: inset 1px 0 0 var(--pundit-border);
    border-radius: 0 9px 9px 0;
    background: transparent;
    color: var(--pundit-muted-strong);
    font: inherit;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.pundit-alert__close:hover {
    color: var(--pundit-text);
}

.pundit-alert__close:focus-visible {
    outline: 3px solid var(--pundit-primary);
    outline-offset: 2px;
}

/* 수준별 색.  라벨은 옅은 배경 위 작은 상태 글자 자리라 -strong 을 쓴다(§2.1). */
.pundit-alert--danger {
    border-color: var(--pundit-danger-border);
    background: var(--pundit-danger-bg);
    color: var(--pundit-text);
}

.pundit-alert--danger .pundit-alert__label {
    color: var(--pundit-danger-strong);
}

.pundit-alert--danger .pundit-alert__close {
    box-shadow: inset 1px 0 0 var(--pundit-danger-border);
}

.pundit-alert--warning {
    border-color: var(--pundit-warning-border);
    background: var(--pundit-warning-bg);
    color: var(--pundit-text);
}

.pundit-alert--warning .pundit-alert__label {
    color: var(--pundit-warning-strong);
}

.pundit-alert--warning .pundit-alert__close {
    box-shadow: inset 1px 0 0 var(--pundit-warning-border);
}

.pundit-alert--success {
    border-color: var(--pundit-success-border);
    background: var(--pundit-success-bg);
    color: var(--pundit-text);
}

.pundit-alert--success .pundit-alert__label {
    color: var(--pundit-success-strong);
}

.pundit-alert--success .pundit-alert__close {
    box-shadow: inset 1px 0 0 var(--pundit-success-border);
}

.pundit-alert--info {
    border-color: var(--pundit-info-border);
    background: var(--pundit-info-bg);
    color: var(--pundit-text);
}

.pundit-alert--info .pundit-alert__label {
    color: var(--pundit-primary-strong);
}

.pundit-alert--info .pundit-alert__close {
    box-shadow: inset 1px 0 0 var(--pundit-info-border);
}

@media (max-width: 650px) {
    .pundit-alert__body {
        padding: 12px;
    }
}
