/* =========================================================
 * common.css
 * 디자인 토큰 · 리셋 · 공통 컴포넌트
 * 팔레트는 wireframes.svg 에서 쓰인 값을 그대로 가져왔다.
 * ========================================================= */

/* ── 본문 서체 ───────────────────────────────────────────
 * Pretendard (SIL Open Font License 1.1, 상업적 사용·재배포 자유).
 * [2026-09-18] 토큰에는 'Pretendard' 가 적혀 있었는데 정작 폰트를 받아오는 줄이
 *   없어서, 윈도우에서는 늘 맑은 고딕으로 떨어지고 있었다. 글자가 얇고 획이
 *   흐려 보인 원인이 이거다.
 *
 * dynamic-subset 을 쓰는 이유: 한글 폰트는 통짜로 받으면 1MB 를 넘는다.
 *   화면에 실제로 쓰인 글자가 든 조각만 골라 받으므로 수십 KB 로 끝난다.
 *
 * ⚠ 외부 CDN(jsDelivr)이라 폰트를 받을 때 접속 IP 가 그쪽에 남는다.
 *   개인정보를 보내는 건 아니지만, 심사 환경에서 외부망이 막히면 서체만
 *   맑은 고딕으로 돌아간다(레이아웃은 그대로). 제출 직전에 폰트 파일을
 *   static/fonts/ 로 내려받아 self-host 로 바꾸는 편이 안전하다 — 기획안 13번.
 */
@import url('https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css');

/* ── 로고 서체 ───────────────────────────────────────────
 * Jua (주아체) — Google Fonts, SIL Open Font License 1.1.
 * 획 끝이 둥글어 말을 거는 느낌이 난다. "갈래 말래" 라는 이름의 말투와 맞는다.
 *
 * ⚠ 앱 이름 딱 한 곳에만 쓴다. 본문까지 덮으면 글자 구분이 뭉개져 읽기가 나빠진다.
 *
 * Google Fonts 의 한글은 unicode-range 로 잘게 쪼개 내려주므로,
 * 실제로 화면에 쓴 네 글자가 든 조각만 받아온다(수 KB).
 */
@import url('https://fonts.googleapis.com/css2?family=Jua&display=swap');

/* ── 디자인 토큰 ─────────────────────────────────────── */
:root {
    /* 색상 */
    --color-bg:             #F1EFE8;
    --color-surface:        #FFFFFF;
    --color-surface-sunken: #FAF9F5;

    --color-border:         #DAD7CE;
    --color-border-strong:  #B7B4AA;

    --color-text:           #2C2C2A;
    --color-text-muted:     #5F5E5A;
    --color-text-subtle:    #8B8980;

    --color-primary:        #185FA5;
    --color-primary-hover:  #124B83;
    --color-primary-soft:   #E6F1FB;

    --color-accent:         #854F0B;
    --color-accent-soft:    #FAEEDA;

    --color-danger:         #B42318;
    --color-danger-hover:   #912016;
    --color-danger-soft:    #FDECEA;

    /* 간격 */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;

    /* 모서리 */
    --radius-sm:   8px;
    --radius-md:   12px;
    --radius-lg:   20px;
    --radius-full: 999px;

    /* 그림자 */
    --shadow-sm: 0 1px 2px rgba(44, 44, 42, .06);
    --shadow-md: 0 4px 16px rgba(44, 44, 42, .08);

    /* 타이포
       Variable 폰트라 이름이 'Pretendard Variable' 이다. 못 받아왔을 때를 대비해
       정적 버전('Pretendard')·시스템 폰트를 뒤에 계속 남겨 둔다. */
    --font-sans: 'Pretendard Variable', 'Pretendard', -apple-system, BlinkMacSystemFont,
                 'Apple SD Gothic Neo', 'Malgun Gothic', 'Segoe UI', sans-serif;

    /* 앱 이름 전용. 본문에는 쓰지 않는다 */
    --font-display: 'Jua', var(--font-sans);

    /* 레이아웃 */
    --header-height: 56px;
    --content-width: 480px;

    /* 모션 */
    --ease: cubic-bezier(.22, .61, .36, 1);
}

/* ── 리셋 ────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

html, body { height: 100%; }

body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: 15px;
    /* Pretendard 는 가변 폭이라 400 과 500 사이를 직접 고를 수 있다.
       400 은 모바일에서 얇아 보이고 500 은 본문치고 무거워서 그 사이로 둔다.
       가변 폰트를 못 받아온 경우에는 브라우저가 가장 가까운 400 으로 떨어뜨린다. */
    font-weight: 450;
    line-height: 1.55;
    letter-spacing: -.003em;
    color: var(--color-text);
    background: var(--color-bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    -webkit-tap-highlight-color: transparent;
}

h1, h2, h3, p, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }
img, svg { display: block; max-width: 100%; }

/* 접근성: 화면에는 안 보이지만 스크린리더에는 읽히는 텍스트 */
.sr-only {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ── 앱 셸 ───────────────────────────────────────────── */
.app {
    display: flex;
    flex-direction: column;
    min-height: 100%;
}

.app__main {
    flex: 1;
    width: 100%;
    max-width: var(--content-width);
    margin: 0 auto;
    padding: var(--space-6) var(--space-4) var(--space-10);
}

/* 헤더 */
.app-header {
    position: sticky;
    top: 0;
    z-index: 10;
    height: var(--header-height);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 0 var(--space-4);
    background: rgba(241, 239, 232, .88);
    backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--color-border);
}

.app-header__brand {
    font-family: var(--font-display);
    /* 주아체는 글자가 작아 보이는 편이라 본문 대비 한 단계 키운다 */
    font-size: 1.22rem;
    /* 주아체는 굵기가 하나뿐이라 이 값이 먹지 않는다.
       폰트를 못 받아왔을 때 본문 서체가 대신 서므로 그때를 위해 남겨 둔다 */
    font-weight: 800;
    letter-spacing: 0;
    color: var(--color-text);
}

.app-header__brand span { color: var(--color-primary); }

.app-header__nav {
    display: flex;
    align-items: center;
    gap: var(--space-4);
    font-size: .85rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

.app-header__nav button {
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
    font-weight: 600;
    color: var(--color-text-muted);
}

.app-header__nav button:hover,
.app-header__nav a:hover { color: var(--color-primary); }

/* 로그인 상태에 따라 JS 가 토글한다 */
[data-nav-auth], [data-nav-guest] { display: none; }
body[data-auth="in"]  [data-nav-auth]  { display: inline-flex; }
body[data-auth="out"] [data-nav-guest] { display: inline-flex; }

/* 푸터 */
.app-footer {
    padding: var(--space-6) var(--space-4) var(--space-8);
    text-align: center;
    font-size: .72rem;
    line-height: 1.7;
    color: var(--color-text-subtle);
}

/* ── 페이지 타이틀 ───────────────────────────────────── */
.page-head { margin-bottom: var(--space-6); }

.page-head__title {
    font-size: 1.4rem;
    font-weight: 800;
    letter-spacing: -.03em;
}

.page-head__desc {
    margin-top: var(--space-2);
    font-size: .87rem;
    color: var(--color-text-muted);
}

/* ── 카드 ────────────────────────────────────────────── */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-sm);
}

.card + .card { margin-top: var(--space-4); }

.card__title {
    font-size: .95rem;
    font-weight: 700;
    margin-bottom: var(--space-4);
}

/* ── 폼 ──────────────────────────────────────────────── */
.form { display: flex; flex-direction: column; gap: var(--space-4); }

.field { display: flex; flex-direction: column; gap: var(--space-2); }

.field__label {
    font-size: .8rem;
    font-weight: 600;
    color: var(--color-text-muted);
}

.field__label .req { color: var(--color-danger); margin-left: 2px; }

.field__input {
    width: 100%;
    padding: 11px 14px;
    font: inherit;
    font-size: .92rem;
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    outline: none;
    transition: border-color .15s var(--ease), box-shadow .15s var(--ease);
}

.field__input::placeholder { color: var(--color-text-subtle); }

.field__input:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-soft);
}

.field__input:disabled {
    background: var(--color-surface-sunken);
    color: var(--color-text-subtle);
    cursor: not-allowed;
}

.field__hint {
    font-size: .75rem;
    color: var(--color-text-subtle);
}

.field__error {
    display: none;
    font-size: .75rem;
    font-weight: 500;
    color: var(--color-danger);
}

.field.is-invalid .field__input {
    border-color: var(--color-danger);
}

.field.is-invalid .field__input:focus {
    box-shadow: 0 0 0 3px var(--color-danger-soft);
}

.field.is-invalid .field__error { display: block; }

/* ── 버튼 ────────────────────────────────────────────── */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 12px 18px;
    font-size: .92rem;
    font-weight: 700;
    letter-spacing: -.01em;
    border: 1px solid transparent;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background .15s var(--ease), border-color .15s var(--ease), color .15s var(--ease);
}

.btn:disabled { opacity: .55; cursor: not-allowed; }

.btn--block { width: 100%; }

.btn--primary {
    background: var(--color-primary);
    color: #fff;
}
.btn--primary:not(:disabled):hover { background: var(--color-primary-hover); }

.btn--ghost {
    background: var(--color-surface);
    border-color: var(--color-border-strong);
    color: var(--color-text);
}
.btn--ghost:not(:disabled):hover { border-color: var(--color-text-muted); }

.btn--danger {
    background: var(--color-danger-soft);
    border-color: transparent;
    color: var(--color-danger);
}
.btn--danger:not(:disabled):hover { background: #F9D9D5; }

.btn--text {
    padding: 0;
    background: none;
    border: 0;
    font-weight: 600;
    color: var(--color-primary);
}
.btn--text:not(:disabled):hover { text-decoration: underline; }

/* 제출 중 스피너 */
.btn.is-loading { position: relative; color: transparent !important; }

.btn.is-loading::after {
    content: '';
    position: absolute;
    width: 16px; height: 16px;
    border: 2px solid currentColor;
    border-radius: 50%;
    border-top-color: transparent;
    color: #fff;
    animation: spin .6s linear infinite;
}

.btn--ghost.is-loading::after,
.btn--danger.is-loading::after { color: var(--color-text-muted); }

@keyframes spin { to { transform: rotate(360deg); } }

/* ── 링크 문단 ───────────────────────────────────────── */
.link-row {
    margin-top: var(--space-5);
    text-align: center;
    font-size: .84rem;
    color: var(--color-text-muted);
}

.link-row a {
    font-weight: 700;
    color: var(--color-primary);
    margin-left: var(--space-1);
}

.link-row a:hover { text-decoration: underline; }

/* ── 토스트 ──────────────────────────────────────────── */
.toast-area {
    position: fixed;
    left: 50%;
    bottom: var(--space-6);
    z-index: 100;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    width: calc(100% - var(--space-8));
    max-width: 400px;
    transform: translateX(-50%);
    pointer-events: none;
}

.toast {
    padding: 12px 16px;
    font-size: .85rem;
    font-weight: 600;
    color: #fff;
    background: var(--color-text);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    animation: toast-in .22s var(--ease);
}

.toast--success { background: #1B6B3A; }
.toast--error   { background: var(--color-danger); }

.toast.is-leaving { animation: toast-out .18s var(--ease) forwards; }

@keyframes toast-in  { from { opacity: 0; transform: translateY(8px); } }
@keyframes toast-out { to   { opacity: 0; transform: translateY(8px); } }

/* ── 로딩/빈 상태 ────────────────────────────────────── */
.state {
    padding: var(--space-10) var(--space-4);
    text-align: center;
    font-size: .87rem;
    color: var(--color-text-subtle);
}

/* ── 로그인 여부에 따른 노출 ─────────────────────────── */
/* 판정 전에는 자리는 유지한 채 감춰 화면이 번쩍이지 않게 한다 */
body[data-auth="pending"] [data-auth-only],
body[data-auth="pending"] [data-guest-only] { visibility: hidden; }

/* 판정 후에는 auth.js 가 hidden 속성을 붙여 실제로 제거한다 */
[hidden] { display: none !important; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
