/* =========================================================
   Self-hosted fonts — base.html이 PretendardVariable.woff2를
   preload한다. CSP font-src가 gstatic 등 외부 폰트 CDN을 막으므로
   반드시 self-host 한다.
   ========================================================= */
@font-face {
    font-family: 'Pretendard Variable';
    src: url("../fonts/PretendardVariable.302ec55f5b43.woff2") format('woff2-variations');
    font-weight: 45 920;
    font-display: swap;
}
@font-face {
    font-family: 'IBM Plex Mono';
    src: url("../fonts/IBMPlexMono-Regular.79936b18df9f.woff2") format('woff2');
    font-weight: 400;
    font-display: swap;
}
@font-face {
    font-family: 'IBM Plex Mono';
    src: url("../fonts/IBMPlexMono-Medium.b1c8a895f5fd.woff2") format('woff2');
    font-weight: 500;
    font-display: swap;
}
@font-face {
    font-family: 'IBM Plex Mono';
    src: url("../fonts/IBMPlexMono-SemiBold.5a2ce7798732.woff2") format('woff2');
    font-weight: 600;
    font-display: swap;
}

/* =========================================================
   Design Tokens — 단일 팔레트 출처
   ========================================================= */
:root {
    /* Brand palette (녹색 테마) */
    --color-primary: #2C6E4A;
    --color-primary-hover: #235B3C;
    --color-primary-press: #1C462F;
    --color-primary-soft: #EDF3EE;
    --color-primary-border: #98c7aa;
    --ink-on-primary: #ffffff;

    /* Text — 시안은 네 단계를 쓴다. 두 단계로 줄이면 위계가 뭉갠다. */
    --color-text: #14211A;
    --color-text-body: #4C5B52;
    --color-text-muted: #6C7A70;
    --color-text-meta: #8B968D;
    --color-text-disabled: #C4CCC6;
    --color-danger-text: #B4471F;
    --color-danger-soft: #FDF6F3;

    /* Surface */
    --color-surface: #ffffff;
    --color-surface-soft: #F5F6F4;
    --color-track: #F1F3F0;
    --color-border: #E3E6E1;
    --color-border-soft: #EDEFEB;
    --color-border-muted: #F2F4F1;

    /* 소비시간 5분류. 회색은 미분류 전용이라 어느 카테고리에도 쓰지 않는다. */
    --color-accent-work: #7CD9A0;   /* 투자시간 */
    --color-accent-move: #7DCFE8;   /* 주도적 사용시간 */
    --color-accent-care: #FFA98C;   /* 수동적 소비시간 */
    --color-accent-rest: #FFD166;   /* 기초 생활시간 */
    --color-accent-sleep: #B8A6F0;  /* 수면시간 */
    --color-accent-muted: #D5DBD7;  /* 미분류 */

    /* 시안의 #14211A 는 투자·주도적 색에서 4.5:1에 못 미쳐 한 단계 낮췄다 */
    --ink-on-accent: #0F1A14;
    /* 라이트의 danger 는 어두워 흰 글자가 5.40:1 */
    --ink-on-danger: #FFFFFF;

    /* Note (노란 강조 박스) */
    --color-note-bg: #fff7df;
    --color-note-border: #efd98c;
    --color-note-text: #5d4a15;

    /* Bootstrap 호환 alias */
    --primary-color: var(--color-primary);
    --success-color: #198754;
    --warning-color: #ffc107;
    --danger-color: #dc3545;
    /* 부트스트랩 기본 #0dcaf0 은 흰 배경에서 1.96:1 이라 본문에 못 쓴다 */
    --info-color: #0a7c92;
    --light-color: var(--color-surface-soft);
    --dark-color: var(--color-text);

    /* Bootstrap 5 CSS 변수 오버라이드 — btn-outline-primary, text-primary 등 자동 적용 */
    --bs-primary: #2C6E4A;
    --bs-primary-rgb: 44, 110, 74;
    --bs-info: #0a7c92;
    --bs-info-rgb: 10, 124, 146;

    /* Radius */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-lg: 16px;

    /* Responsive heights — clamp(min, viewport, max).
       모든 차트·스크롤 패널 공용. 한 곳에서만 조정. */
    --panel-h-sm: clamp(160px, 25vh, 220px);
    --panel-h-md: clamp(180px, 35vh, 320px);
    --panel-h-lg: clamp(220px, 45vh, 420px);
    --chart-cap-sm: clamp(180px, 30vh, 280px);
    --chart-cap-md: clamp(220px, 35vh, 320px);
    --chart-cap-lg: clamp(260px, 45vh, 420px);

    /* Typography — self-host (위 @font-face), CDN 미사용 */
    --font-body: 'Pretendard Variable', Pretendard, 'Noto Sans KR',
        system-ui, -apple-system, 'Segoe UI', sans-serif;
    --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo,
        Consolas, monospace;
}

/* =========================================================
   Dark Theme Tokens
   ========================================================= */
[data-theme="dark"] {
    --color-primary: #4aa66d;
    --color-primary-hover: #5cb87e;
    --color-primary-press: #75C392;
    --color-primary-soft: #1a2e22;
    --color-primary-border: #3a6b4a;
    /* 다크 초록은 라이트보다 훨씬 밝다. 흰 글자로는 2.44:1 밖에 안 나온다. */
    --ink-on-primary: var(--ink-on-accent);

    --color-text: #E4EBE6;
    --color-text-body: #B9C6BD;
    --color-text-muted: #9AAB9F;
    --color-text-meta: #7F8F85;
    --color-text-disabled: #5A6860;
    --color-danger-text: #E8927A;
    --color-danger-soft: #2E1D18;

    --color-surface: #1a1f1c;
    --color-surface-soft: #232a26;
    --color-track: #2A322D;
    --color-border: #3a4a3e;
    --color-border-soft: #2e3a32;
    --color-border-muted: #2a3630;

    --color-accent-work: #7CD9A0;
    --color-accent-move: #7DCFE8;
    --color-accent-care: #FFA98C;
    --color-accent-rest: #FFD166;
    --color-accent-sleep: #B8A6F0;
    --color-accent-muted: #4A554E;

    --ink-on-accent: #0F1A14;
    /* 다크의 danger 는 밝아 흰 글자로는 대비가 안 나온다 — 어두운 잉크로 7.33:1 */
    --ink-on-danger: var(--ink-on-accent);

    --color-note-bg: #2a2615;
    --color-note-border: #5d4a15;
    --color-note-text: #efd98c;

    --primary-color: var(--color-primary);
    --success-color: #22a45c;
    --warning-color: #e6ac00;
    --danger-color: #e05555;
    /* 다크 표면에서는 밝은 쪽이 대비를 얻는다 */
    --info-color: #4FC3D9;
    --light-color: var(--color-surface-soft);
    --dark-color: var(--color-text);

    --bs-primary: #4aa66d;
    --bs-primary-rgb: 74, 166, 109;
    --bs-info: #4FC3D9;
    --bs-info-rgb: 79, 195, 217;

    color-scheme: dark;
}

/* =========================================================
   Base
   ========================================================= */
body {
    background-color: var(--light-color);
    font-family: var(--font-body);
    color: var(--color-text);
    font-variant-numeric: tabular-nums;
}

.num {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}

/* App nav — 최상위는 기록·분석·설정 셋뿐이다. 언어와 테마는 로그인 없이도
   써야 하므로 브랜드 옆에 고정한다 */
.app-nav {
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 1.5rem;
}

.app-nav__inner {
    display: flex;
    align-items: center;
    gap: 26px;
    height: 56px;
}

.app-nav__brand {
    font-weight: 700;
    font-size: 15px;
    color: var(--color-primary);
    text-decoration: none;
    flex: none;
}

.app-nav__prefs {
    display: flex;
    align-items: center;
    gap: 2px;
    flex: none;
    margin-left: -14px;
}

.app-nav__pref {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 8px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--color-text-body);
    font-size: 13px;
    transition: background-color .15s ease, color .15s ease;
}

.app-nav__pref:hover {
    background: var(--color-surface-soft);
    color: var(--color-text);
}

.app-nav__pref:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.app-nav__pref-code {
    font-weight: 600;
    font-size: 11.5px;
}

.app-nav__pref-menu {
    min-width: 9.5rem;
    padding: 4px;
}

.app-nav__pref-menu form {
    margin: 0;
}

.app-nav__pref-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: 40px;
    border-radius: 6px;
    font-size: 12.5px;
}

.app-nav__pref-item.is-active {
    font-weight: 600;
    color: var(--color-text);
    background: var(--color-primary-soft);
}

.app-nav__pref-icon {
    flex: none;
    width: 1.25rem;
    text-align: center;
    font-size: 11.5px;
    color: var(--color-text-meta);
}

.app-nav__tabs {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-right: auto;
}

.app-nav__tabs--guest {
    margin-left: auto;
    margin-right: 0;
    gap: 10px;
}

.app-nav__tab {
    font-size: 13.5px;
    color: var(--color-text-body);
    text-decoration: none;
    padding: 7px 12px;
    border-radius: 7px;
    white-space: nowrap;
    transition: background-color .15s ease, color .15s ease;
}

.app-nav__tab:hover {
    color: var(--color-text);
    background-color: var(--color-surface-soft);
}

.app-nav__tab:active {
    color: var(--color-text);
    background-color: var(--color-primary-soft);
}

.app-nav__tab.is-active {
    font-weight: 500;
    color: var(--color-text);
    background: var(--color-primary-soft);
}

/* 탭이 접히는 폭에서도 아바타는 오른쪽 끝에 남는다 */
.app-nav__account {
    flex: none;
    margin-left: auto;
}

.app-nav__avatar {
    width: 32px;
    height: 32px;
    border: 0;
    border-radius: 50%;
    background: var(--color-primary-soft);
    color: var(--color-primary);
    font-weight: 600;
    font-size: 11px;
}

.app-nav__account-name {
    font-size: 12px;
    color: var(--color-text-meta);
}

@media (max-width: 575.98px) {
    .app-nav__inner {
        gap: 8px;
    }
    .app-nav__tab {
        padding: 7px 9px;
    }
    /* 브랜드·테마·언어·로그인·가입을 320px 한 줄에 들여보낸다. 줄바꿈을 허용하면
       버튼이 56px 헤더 밖으로 자란다. */
    .app-nav__prefs {
        gap: 0;
        margin-left: -10px;
    }
    .app-nav__pref {
        min-width: 32px;
        padding: 0 6px;
    }
    .app-nav__tabs--guest {
        gap: 4px;
    }
    .app-nav__tabs--guest .app-nav__tab {
        padding: 7px 6px;
        font-size: 12px;
    }
    .app-nav__tabs--guest .btn-sian {
        padding: 7px 10px;
        font-size: 12px;
        white-space: nowrap;
    }
}

/* 시안 공통 컴포넌트 */
.section-title {
    font-weight: 600;
    font-size: 12.5px;
    color: var(--color-text);
    margin-bottom: 8px;
}

.section-title__note {
    font-weight: 400;
    font-size: 11px;
    color: var(--color-text-meta);
    margin-left: 4px;
}

.page-title {
    font-weight: 700;
    font-size: 19px;
    color: var(--color-text);
    margin: 0;
}

.page-subtitle {
    font-size: 12px;
    color: var(--color-text-muted);
    margin: 3px 0 0;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 32px;
    padding: 0 11px;
    border: 1px solid var(--color-border);
    border-radius: 16px;
    background: var(--color-surface);
    font-size: 12px;
    color: var(--color-text);
    text-decoration: none;
}

.chip__swatch {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    flex: none;
}

.chip.is-selected {
    background: var(--color-primary-soft);
    border-color: transparent;
    box-shadow: 0 0 0 1.5px var(--color-primary) inset;
    font-weight: 500;
}

.segmented {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border-radius: 8px;
    background: var(--color-track);
}

.segmented__item {
    border: 0;
    background: transparent;
    border-radius: 6px;
    padding: 6px 11px;
    font-size: 12px;
    color: var(--color-text-body);
    text-decoration: none;
}

.segmented__item.is-active {
    background: var(--color-surface);
    font-weight: 500;
    color: var(--color-text);
}

/* 세그먼트를 라디오 그룹으로도 쓴다(설정의 테마 3값). 네이티브 라디오라
   방향키 순회·그룹 이름·상태 안내가 공짜로 따라온다 — 직접 구현하지 않는다.
   display:none 이 아니라 clip-path 로 숨겨야 포커스를 받는다. */
.segmented__radio {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.segmented__radio:checked + .segmented__item {
    background: var(--color-surface);
    font-weight: 500;
    color: var(--color-text);
}

.segmented__radio:focus-visible + .segmented__item {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

label.segmented__item {
    cursor: pointer;
}

@media (max-width: 767.98px) {
    .segmented--tabs {
        display: flex;
        width: 100%;
    }

    .segmented--tabs .segmented__item {
        flex: 1;
        text-align: center;
    }
}

.btn-sian {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 44px;
    padding: 9px 14px;
    border: 1px solid var(--color-border);
    border-radius: 9px;
    background: var(--color-surface);
    font-weight: 500;
    font-size: 13.5px;
    color: var(--color-text-body);
    text-decoration: none;
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.btn-sian:where(:not(:disabled)):hover {
    background-color: var(--color-surface-soft);
    border-color: var(--color-primary-border);
    color: var(--color-text);
}

.btn-sian:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.btn-sian:where(:not(:disabled)):active {
    background-color: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-primary);
}

/* 좁은 카드 안에 두 개가 나란히 들어가는 버튼.
   기본 좌우 여백 14px 은 카드 폭에서 글자 자리를 다 먹어 라벨이 두 줄로
   접힌다. 여백과 글자만 줄이고 44px 높이는 그대로 지킨다. */
.btn-sian--compact {
    padding-inline: 6px;
    gap: 4px;
    min-width: 0;
    font-size: 12px;
    white-space: nowrap;
}

@media (min-width: 576px) {
    .btn-sian--compact {
        padding-inline: 10px;
        font-size: 13px;
    }
}

@media (min-width: 768px) {
    .btn-sian--compact {
        padding-inline: 14px;
        gap: 6px;
        font-size: 13.5px;
    }
}

.btn-sian--primary {
    border-color: transparent;
    background: var(--color-primary);
    color: var(--ink-on-primary);
    font-weight: 600;
}

.btn-sian--primary:where(:not(:disabled)):hover {
    background: var(--color-primary-hover);
    border-color: transparent;
    color: var(--ink-on-primary);
}

.btn-sian--primary:where(:not(:disabled)):active {
    background: var(--color-primary-press);
    border-color: transparent;
    color: var(--ink-on-primary);
}

.settings-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 48px;
    padding: 6px 0;
}

.settings-panel {
    max-width: 560px;
    margin: 0 auto;
}

.settings-panel__account {
    font-size: 12px;
    color: var(--color-text-muted);
    margin: 4px 0 0;
}

.settings-group__label {
    font-weight: 600;
    font-size: 11px;
    color: var(--color-text-meta);
    margin: 14px 0 2px;
}

/* 행 전체가 링크다 — 48px 띠 어디를 눌러도 이동한다. */
.settings-row--link {
    text-decoration: none;
    color: inherit;
    transition: background-color .15s ease;
}

.settings-row--link:hover {
    background: var(--color-surface-soft);
}

.settings-row--link:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.settings-row__meta {
    margin-left: auto;
    font-size: 12px;
    color: var(--color-text-meta);
}

.settings-row__chevron {
    flex: none;
    margin-left: 8px;
    font-size: 13px;
    color: var(--color-text-meta);
}

/* 태그 관리의 행 리스트 — 카테고리로 묶고 행마다 이름·누적 기록·버튼 넷. */
.tag-group__heading {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 20px 0 2px;
    font-size: 13px;
    font-weight: 600;
    color: var(--color-text-muted);
}

.tag-group:first-child .tag-group__heading {
    margin-top: 4px;
}

.tag-group__count {
    font-weight: 400;
}

/* 360px 에서는 버튼 넷이 이름 옆에 들어가지 않는다. 버튼을 숨기거나 줄이는
   대신 아랫줄로 내린다 — 관리 화면이라 넷 다 손에 닿아야 한다. */
.tag-row {
    flex-wrap: wrap;
}

.tag-row__info {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px 8px;
    min-width: 0;
}

.tag-row__name {
    font-weight: 500;
    overflow-wrap: anywhere;
}

/* 이름 앞의 카테고리 색.
   `.chip__swatch` 는 flex 안에서 쓰이던 것이라 글자 옆에 놓으려면
   `.data-table td` 쪽과 같은 방식으로 흐름과 기준선을 잡아 줘야 한다.

   테두리를 border 가 아니라 inset 그림자로 넣는 이유는 10x10 크기를
   그대로 두기 위해서다 — border 는 상자를 키우거나 채움을 8x8 로 깎는다.
   파스텔 다섯 색은 흰 표면 대비가 1.44~2.15 라 홀로 두면 흐릿하다.
   경계선이 3:1 을 대신 진다(#6C7A70 대 흰 배경 4.51). */
.tag-row__name .chip__swatch {
    display: inline-block;
    margin-right: 6px;
    vertical-align: -1px;
    box-shadow: inset 0 0 0 1px var(--color-text-muted);
}

/* 어두운 표면에서는 채움색 자체가 7.76~11.59 로 충분히 드러난다.
   경계선을 남기면 밝은 사각형에 흐린 테를 두른 꼴이 된다. */
[data-theme="dark"] .tag-row__name .chip__swatch {
    box-shadow: none;
}

.tag-row__meta {
    font-size: 12.5px;
    color: var(--color-text-muted);
}

/* 분석 화면의 엑셀 내보내기 — 설명과 컨트롤이 한 줄에 선다.
   설명이 라벨 자리를 대신하므로 한 줄짜리 짧은 라벨보다 길다. 남는 폭을
   가져가되 컨트롤을 밀어내지 않게 줄바꿈을 허용한다. */
/* 공용 .settings-row 는 줄바꿈하지 않는다. 짧은 라벨 하나를 전제로 만들어진
   규칙이라, 설명이 들어온 이 행에서만 풀어 준다. */
.stats-export .settings-row {
    flex-wrap: wrap;
}

.stats-export__note {
    flex: 1 1 260px;
    font-size: 12px;
    color: var(--color-text-muted);
    line-height: 1.45;
}

/* 좁은 화면에서는 설명과 컨트롤이 각자 줄을 쓴다. 그때 오른쪽으로 밀면
   한 줄짜리가 들여쓴 것처럼 보인다. */
@media (min-width: 576px) {
    .stats-export .section-title {
        text-align: right;
    }

    .stats-export__note {
        flex-grow: 0;
        margin-left: auto;
    }
}

/* 360px 에서는 줄바꿈되게 두되, Bootstrap 기본 select 높이(약 31px)를
   버튼과 같은 44px 로 올린다. 손가락이 닿아야 한다. */
.stats-export__control {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.stats-export__control .form-select {
    min-height: 44px;
    width: auto;
}

/* "내보내는 중…" 이 103.4px. 라벨이 바뀔 때 옆의 select 가 밀리면 안 된다. */
#statsExportBtn {
    min-width: 110px;
}

.tag-row__actions {
    display: flex;
    gap: 6px;
    margin-left: auto;
}

/* 좁은 화면에서 글자만 남아도 손가락이 닿을 44px 폭을 지킨다.
   .btn-sian--compact 는 min-width 를 0 으로 풀어 둔다. */
.tag-row__actions .btn-sian {
    min-width: 44px;
}

.settings-row + /* 홈 미리보기 — 장식이 아니라 실제 기록 화면의 축소판이다 */
.home-daygrid {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.home-daygrid__row {
    display: grid;
    grid-template-columns: 38px 1fr;
    gap: 8px;
    align-items: center;
}

.home-daygrid__label {
    font: 500 9.5px/1 var(--font-mono);
    color: var(--color-text-muted);
    text-align: right;
}

.home-daygrid__cells {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 2px;
}

.home-daygrid__block {
    height: 13px;
    border-radius: 2px;
    background: var(--color-track);
}

.home-daygrid__block.is-work { background: var(--color-accent-work); }
.home-daygrid__block.is-move { background: var(--color-accent-move); }
.home-daygrid__block.is-care { background: var(--color-accent-care); }
.home-daygrid__block.is-rest { background: var(--color-accent-rest); }
.home-daygrid__block.is-sleep { background: var(--color-accent-sleep); }

/* 모바일 하단 탭바 — 시안 6b·4a. 데스크톱에는 상단 내비게이션이 있다 */
.tabbar {
    display: none;
}

@media (max-width: 767.98px) {
    .tabbar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1030;
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        height: 58px;
        background: var(--color-surface);
        border-top: 1px solid var(--color-border);
    }

    .tabbar__item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        font-size: 10px;
        color: var(--color-text-meta);
        text-decoration: none;
    }

    .tabbar__item.is-active {
        font-weight: 600;
        color: var(--color-primary);
    }

    .tabbar__icon {
        font-size: 15px;
    }

    /* 탭바가 본문 끝을 가리지 않게 자리를 비운다 */
    body {
        padding-bottom: 58px;
    }

    .app-nav__tabs {
        display: none;
    }

    /* 로그인 탭은 하단 탭바가 대신하지만, 비로그인 진입점은 대신할 것이 없다 */
    .app-nav__tabs--guest {
        display: flex;
        gap: 6px;
    }
}

/* 빈 상태 — "데이터가 없습니다" 대신 다음 동작 하나만 제시한다 */
.empty-nudge {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
    padding: 14px 16px;
    border: 1px solid var(--color-primary-border);
    border-radius: var(--radius-md);
    background: var(--color-primary-soft);
}

.empty-nudge__title {
    font-weight: 700;
    font-size: 14px;
    color: var(--color-text);
    margin-bottom: 3px;
}

.empty-nudge__text {
    font-size: 12.5px;
    color: var(--color-text-body);
    margin: 0;
}

/* 온보딩 3스텝 — 읽는 화면이 아니라 고르는 화면이다 */
/* 파괴적 동작 — 단순 confirm 대신 옮길 경로를 기본값으로 둔다 */
.danger-panel__title {
    font-weight: 700;
    font-size: 14px;
    color: #8A3A18;
    margin: 0 0 6px;
}

.danger-panel__text {
    font-size: 12px;
    line-height: 1.6;
    color: #6B4030;
    margin: 0 0 14px;
}

.danger-panel__link {
    border: 0;
    background: transparent;
    font-size: 12px;
    color: #6B4030;
    text-decoration: underline;
    padding: 6px;
}

#tagDeleteModal .modal-content {
    border: 1px solid #E8CFC6;
    background: #FDF6F3;
    border-radius: var(--radius-md);
}

#tagDeleteModal .modal-body {
    padding: 18px 20px 20px;
}

[data-theme="dark"] #tagDeleteModal .modal-content {
    border-color: #5A3A2C;
    background: #2A1D18;
}

[data-theme="dark"] .danger-panel__title { color: #E8927A; }
[data-theme="dark"] .danger-panel__text,
[data-theme="dark"] .danger-panel__link { color: #D3B2A5; }

.onboarding {
    max-width: 420px;
    margin: 0 auto;
    padding: 8px 4px 32px;
}

.onboarding__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
}

.onboarding__progress {
    display: flex;
    gap: 5px;
}

.onboarding__tick {
    width: 22px;
    height: 3px;
    border-radius: 2px;
    background: var(--color-border);
}

.onboarding__tick.is-done {
    background: var(--color-primary);
}

.onboarding__skip {
    font-size: 12.5px;
    color: var(--color-text-muted);
    text-decoration: none;
}

.onboarding__step {
    font-family: var(--font-mono);
    font-weight: 600;
    font-size: 11px;
    color: var(--color-primary);
    margin: 0 0 8px;
}

.onboarding__title {
    font-weight: 700;
    font-size: 22px;
    line-height: 1.35;
    color: var(--color-text);
    margin: 0 0 8px;
}

.onboarding__lead {
    font-size: 13px;
    line-height: 1.65;
    color: var(--color-text-body);
    margin: 0 0 16px;
}

.onboarding__chips {
    display: flex;
    flex-wrap: wrap;
    gap: 7px;
    margin-bottom: 20px;
}

/* STEP1 의 태그 고르기. 네이티브 체크박스를 칩 모양으로 입힌다 —
   카테고리 라디오와 같은 이유로, 체크 상태를 브라우저가 들게 한다. */
.onboarding__group {
    border: 0;
    padding: 0;
    margin: 0 0 14px;
}

.onboarding__group-title {
    float: none;
    width: auto;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-muted);
}

.chip--pick {
    cursor: pointer;
    min-height: 44px;
    padding: 0 14px;
    user-select: none;
    transition: background-color .15s ease, border-color .15s ease;
}

/* `:has(.chip__check)` 로 한정하는 이유: .chip--pick 은 두 상태 모델을 쓴다 —
   온보딩은 숨은 체크박스, 기록 화면 시트는 .active 클래스다. 이 한정이 없으면
   체크박스가 없는 시트 칩에서 `:not(:has(:checked))` 가 항상 참이 되어
   선택된 칩까지 흐려진다. */
.chip--pick:has(.chip__check):not(:has(.chip__check:checked)):hover {
    border-color: var(--color-primary-border);
    background-color: var(--color-surface-soft);
}

.chip__check {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.chip--pick:has(.chip__check:checked) {
    background: var(--color-primary-soft);
    border-color: transparent;
    font-weight: 600;
}

.chip--pick:has(.chip__check:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.chip--pick:has(.chip__check):not(:has(.chip__check:checked)) .chip__swatch {
    opacity: 0.35;
}

.onboarding__picks-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin: 4px 0 16px;
}

.onboarding__count {
    font-size: 12px;
    color: var(--color-text-muted);
}

.onboarding__guide {
    margin: -8px 0 16px;
    font-size: 11.5px;
    color: var(--color-text-meta);
}

.onboarding__guide a {
    color: var(--color-text-muted);
    text-decoration: underline;
}

/* STEP2 는 기록 화면의 그리드를 그대로 얹는다. 온보딩 열은 420px 이라
   시각 라벨 폭을 줄여야 여섯 칸이 눌릴 만큼 남는다. */
.onboarding__grid {
    margin-bottom: 12px;
}

.onboarding__grid .day-row {
    grid-template-columns: 38px 1fr;
    gap: 6px;
}

.onboarding__selection {
    min-height: 20px;
    margin-bottom: 8px;
    font-size: 12.5px;
    color: var(--color-text-muted);
}

.onboarding__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 14px;
}

.onboarding__foot-link {
    display: block;
    margin-top: 10px;
    text-align: center;
    font-size: 12.5px;
    color: var(--color-text-muted);
}

/* 목표 시간 스테퍼. 숫자 입력을 그대로 두고 버튼을 양옆에 붙인다 —
   방향키 증감과 값 낭독을 브라우저가 이미 해 준다. */
.stepper {
    display: flex;
    align-items: center;
    gap: 8px;
}

.stepper__btn {
    width: 44px;
    height: 44px;
    flex: none;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
    font-size: 18px;
    line-height: 1;
    color: var(--color-text);
    transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.stepper__btn:where(:not(:disabled)):hover {
    background-color: var(--color-surface-soft);
    border-color: var(--color-primary-border);
    color: var(--color-primary);
}

.stepper__btn:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.stepper__btn:where(:not(:disabled)):active {
    background-color: var(--color-primary-soft);
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.stepper__value {
    flex: 1;
    min-width: 0;
    height: 44px;
    padding: 0 10px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
    color: var(--color-text);
    text-align: center;
    font-size: 15px;
}

.onboarding__stepper {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 14px;
}

.onboarding__period {
    border: 0;
    padding: 0;
    margin: 0 0 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.onboarding__period-option {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-height: 44px;
    cursor: pointer;
}

.onboarding__preview {
    margin-bottom: 16px;
}

.onboarding__preview-label {
    display: block;
    margin-bottom: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--color-text-muted);
}

.onboarding__preview-caption {
    margin: 6px 0 0;
    font-size: 11.5px;
    color: var(--color-text-muted);
}

.onboarding__undo {
    margin-bottom: 12px;
}

.onboarding__undo-note {
    margin: 0 0 6px;
    font-size: 12.5px;
    color: var(--color-text-muted);
}

.onboarding__undo-btn {
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--color-border);
    border-radius: 9px;
    background: var(--color-surface);
    font-size: 12.5px;
    color: var(--color-text-body);
}

.onboarding__next {
    width: 100%;
    min-height: 50px;
    font-size: 15px;
}

.onboarding__goal {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.onboarding__field {
    display: block;
}

.onboarding__field-label {
    display: block;
    font-weight: 500;
    font-size: 11.5px;
    color: var(--color-text-body);
    margin-bottom: 5px;
}

.onboarding__foot {
    font-size: 11.5px;
    color: var(--color-text-muted);
    text-align: center;
    margin: 10px 0 0;
}

.trend-wait {
    padding: 22px 18px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-surface-soft);
    text-align: center;
}

.trend-wait__title {
    font-weight: 500;
    font-size: 13px;
    color: var(--color-text);
    margin-bottom: 6px;
}

.trend-wait__text {
    font-size: 12px;
    line-height: 1.6;
    color: var(--color-text-body);
    max-width: 34em;
    margin: 0 auto 12px;
}

.category-guide {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.category-guide__row {
    display: grid;
    grid-template-columns: minmax(160px, 172px) 1fr minmax(180px, 210px);
    gap: 16px;
    align-items: start;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 13px 15px;
}

.category-guide__head {
    display: flex;
    align-items: center;
    gap: 9px;
}

.category-guide__swatch {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    flex: none;
}

.category-guide__name {
    font-weight: 700;
    font-size: 14px;
    color: var(--color-text);
}

.category-guide__hex {
    font-size: 10.5px;
    color: var(--color-text-meta);
}

.category-guide__desc {
    font-size: 12px;
    line-height: 1.6;
    color: var(--color-text-body);
    margin: 0;
}

.category-guide__foot {
    font-size: 11.5px;
    line-height: 1.6;
    color: var(--color-text-muted);
    margin: 12px 0 0;
    padding-top: 11px;
    border-top: 1px solid var(--color-border-muted);
}

@media (max-width: 575.98px) {
    .category-guide__row {
        grid-template-columns: 1fr;
        gap: 8px;
    }
}

.tag-color-preview {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 12px;
    border-radius: 9px;
    background: var(--color-surface-soft);
}

.tag-color-preview__text {
    font-size: 11px;
    line-height: 1.5;
    color: var(--color-text-muted);
}

.auth-panel {
    max-width: 400px;
    margin: 0 auto;
}

.auth-panel__brand {
    font-weight: 700;
    font-size: 15px;
    color: var(--color-primary);
    margin-bottom: 22px;
}

.auth-panel__title {
    font-weight: 700;
    font-size: 24px;
    color: var(--color-text);
    margin: 0 0 6px;
}

.auth-panel__lead {
    font-size: 13px;
    color: var(--color-text-muted);
    margin: 0 0 22px;
}

.auth-card .form-label {
    display: block;
    font-weight: 500;
    font-size: 11.5px;
    color: var(--color-text-body);
    margin-bottom: 5px;
}

.auth-panel__forgot {
    display: flex;
    justify-content: flex-end;
    margin: -2px 0 12px;
    font-size: 12px;
}

.auth-panel__forgot a {
    color: var(--color-text-muted);
    text-decoration: none;
}

.auth-panel__forgot a:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* 주 CTA 는 44px 기준선보다 한 단 크다(시안 4d). */
.auth-panel__submit {
    width: 100%;
    min-height: 50px;
    font-size: 15px;
}

.auth-card .auth-google-login {
    width: 100%;
    margin-top: 8px;
    font-size: 13px;
    color: var(--color-text-body);
}

.auth-google__mark {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 13px;
    line-height: 1;
}

.auth-panel--centered .card-body {
    text-align: center;
}

.auth-panel--centered .auth-panel__lead {
    margin-bottom: 20px;
}

.auth-panel__actions {
    display: flex;
    flex-direction: column;
    gap: 9px;
}

.auth-panel__actions .auth-panel__submit {
    margin-top: 0;
}

.auth-panel__actions .auth-google-login {
    margin-top: 0;
}

/* 입력이 아니라 이미 확인된 신원이다. 고칠 수 있는 칸처럼 보이면 안 된다. */
.auth-identity {
    display: flex;
    align-items: center;
    gap: 9px;
    min-height: 44px;
    padding: 0 13px;
    border: 1px solid var(--color-border-soft);
    border-radius: var(--radius-sm);
    background: var(--color-surface-soft);
    font-size: 13px;
    color: var(--color-text-muted);
}

.auth-identity__value {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.auth-identity__source {
    margin-left: auto;
    font-family: var(--font-mono);
    font-size: 10px;
    color: var(--color-text-meta);
}

.form-label__hint {
    float: right;
    font-weight: 400;
    font-size: 11px;
    color: var(--color-text-meta);
}

/* 화면에서는 지우고 보조기술에는 남긴다. 코드 화면의 Enter 가드 버튼과
   만료 알림이 쓴다. */
.u-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    min-width: 0;
    min-height: 0;
    padding: 0;
    margin: -1px;
    border: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
}

.auth-code-input {
    font-family: var(--font-mono);
    font-size: 22px;
    font-weight: 600;
    letter-spacing: .4em;
    text-align: center;
    /* letter-spacing 이 마지막 글자 뒤에도 붙어 가운데가 왼쪽으로 밀린다. */
    text-indent: .4em;
}

.auth-code__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: -2px 0 12px;
    font-size: 12px;
    color: var(--color-text-muted);
}

.auth-code__resend {
    flex: none;
    min-height: 44px;
    padding: 8px 4px;
    border: 0;
    background: none;
    font-size: 12px;
    font-weight: 500;
    color: var(--color-primary);
    text-decoration: underline;
    cursor: pointer;
}

.auth-code__resend:disabled {
    color: var(--color-text-disabled);
    text-decoration: none;
    cursor: default;
}

.auth-code__resend:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* Errors sit under their own field, not in a page-top banner. */
.field-error {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: baseline;
    margin-top: 6px;
    font-size: 12px;
    color: var(--color-danger-text);
}

.field-error__count {
    font-family: var(--font-mono);
    font-size: 11px;
}

.form-control.is-invalid,
.form-select.is-invalid {
    border-color: var(--color-danger-text);
    background-color: var(--color-danger-soft);
}

.consent-check .form-check-label {
    font-size: 12.5px;
    color: var(--color-text-body);
}

/* 부트스트랩 기본 링크색(#0d6efd)이 팔레트 밖이라 여기서 덮는다. */
.consent-check .form-check-label a {
    color: var(--color-primary);
    text-decoration: underline;
}

.consent-check .field-error {
    margin-left: -1.5em;
}

.auth-panel__foot {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border-muted);
    text-align: center;
}

.auth-panel__foot-alt {
    margin: 0 0 6px;
    font-size: 12.5px;
    color: var(--color-text-muted);
}

.auth-panel__foot-alt a,
.auth-panel__foot-link {
    color: var(--color-primary);
    font-weight: 500;
    text-decoration: underline;
}

.auth-panel__foot-minor {
    margin: 0;
    font-size: 11.5px;
}

.auth-panel__foot-minor a {
    color: var(--color-text-meta);
    text-decoration: none;
}

.auth-card .card-body {
    padding: 30px 32px 26px;
}

.breadcrumb-trail {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    color: var(--color-text-muted);
    margin-bottom: 10px;
}

.breadcrumb-trail a {
    color: var(--color-text-muted);
    text-decoration: none;
    transition: color .15s ease;
}

.breadcrumb-trail a:hover {
    color: var(--color-text);
    text-decoration: underline;
}

.breadcrumb-trail .is-current {
    color: var(--color-text);
    font-weight: 500;
}

.settings-danger {
    color: var(--color-danger-text);
}

.page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}


.inline-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 26px;
}

.inline-stat__value {
    font-weight: 600;
    font-size: 20px;
    color: var(--color-text);
    line-height: 1.1;
}

.inline-stat__value.is-up {
    color: var(--color-primary);
}

.inline-stat__value--empty {
    color: var(--color-text-disabled);
}

.inline-stat__unit {
    font-size: 12px;
    color: var(--color-text-muted);
}

.inline-stat__label {
    font-size: 10.5px;
    color: var(--color-text-meta);
    margin-top: 2px;
}

.composition-bar {
    display: flex;
    height: 22px;
    border-radius: 5px;
    overflow: hidden;
    background: var(--color-track);
}

.composition-bar > span {
    display: block;
    min-width: 0;
}

/* Tables grow columns over time; keep the overflow inside the table, never on
   the page body.

   Consumers MUST render this as
   `<div class="table-scroll" tabindex="0" role="region" aria-label="...">`.
   CSS alone cannot grant focus, so without tabindex a keyboard user cannot
   reach the clipped columns. */
.table-scroll {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
}

.table-scroll:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.data-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11.5px;
}

.data-table th {
    text-align: left;
    padding: 5px 6px;
    border-bottom: 1px solid var(--color-border);
    font-weight: 600;
    font-size: 10.5px;
    color: var(--color-text-meta);
}

.data-table td {
    padding: 7px 6px;
    border-bottom: 1px solid var(--color-border-muted);
    color: var(--color-text);
}

.data-table .is-num {
    text-align: right;
}

.data-table td .chip__swatch {
    display: inline-block;
    margin-right: 7px;
    vertical-align: -1px;
}

.data-table tr.is-rest td {
    color: var(--color-text-muted);
}

/* 시안 3b·3c·3d 의 차트는 116~150px 대다. aspect-ratio 로 두면 전체 폭에서
   1000px 넘게 늘어난다. */
.chart-panel {
    position: relative;
    height: 150px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.chart-panel--tall {
    height: 220px;
}

.chart-panel--tall.has-legend {
    height: 248px;
}

.chart-panel__canvas-wrap {
    position: relative;
    flex: 1;
    min-height: 0;
}

.chart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
    flex: none;
}

.chart-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 24px;
    padding: 2px 0;
    border: none;
    background: none;
    font: 500 11px/1 var(--font-body);
    color: var(--color-text-body);
    cursor: pointer;
}

.chart-legend__item.is-off {
    color: var(--color-text-disabled);
    text-decoration: line-through;
}

.chart-legend__swatch {
    display: inline-block;
    width: 14px;
    height: 3px;
    border-radius: 2px;
}

.chart-empty {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    padding: 12px;
    text-align: center;
    background: var(--color-surface-soft);
    border-radius: 8px;
}

.chart-empty__title {
    margin: 0;
    font: 500 12.5px/1.4 var(--font-body);
    color: var(--color-text-body);
}

.chart-empty__hint {
    margin: 0;
    font: 400 11px/1.4 var(--font-body);
    color: var(--color-text-meta);
}

.chart-empty__action {
    display: inline-flex;
    align-items: center;
    min-height: 36px;
    margin-top: 4px;
    padding: 0 12px;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
    color: var(--color-primary);
    font: 500 12px/1 var(--font-body);
    text-decoration: none;
}

.goal-progress__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 8px;
}

.goal-progress__manage {
    font-size: 11.5px;
    font-weight: 500;
    color: var(--color-primary);
    text-decoration: underline;
}

.goal-progress__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    min-height: 44px;
    text-decoration: none;
    color: inherit;
}

.goal-progress__label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    font-weight: 500;
    color: var(--color-text);
}

.goal-progress__value {
    font-size: 12px;
    font-weight: 500;
    color: var(--color-text);
    white-space: nowrap;
}

.goal-progress__value.is-under {
    color: var(--color-danger-text);
}

.goal-progress__sep {
    font-weight: 400;
    color: var(--color-text-meta);
}

.goal-progress__track {
    position: relative;
    display: block;
    height: 10px;
    margin-bottom: 14px;
    border-radius: 5px;
    background: var(--color-track);
}

.goal-progress__fill {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    border-radius: 5px;
}

.goal-progress__pace {
    position: absolute;
    top: -2px;
    bottom: -2px;
    width: 2px;
    background: var(--color-text-meta);
}

.goal-progress__empty {
    margin: 0;
    font-size: 12.5px;
    color: var(--color-text-muted);
}

.goal-progress__empty a {
    color: var(--color-primary);
    text-decoration: underline;
}

.settings-row {
    border-top: 1px solid var(--color-border-muted);
}

.settings-row__label {
    font-size: 12.5px;
    color: var(--color-text-body);
}

.settings-row__control {
    margin: 0;
    flex: none;
}

.btn-sian--danger {
    border-color: transparent;
    background: #8A3A18;
    color: #fff;
    font-weight: 600;
}

.btn-sian--danger:where(:not(:disabled)):hover {
    background: #6d2f13;
    border-color: transparent;
    color: #fff;
}

.btn-sian--danger:where(:not(:disabled)):active {
    background: #50220E;
    border-color: transparent;
    color: #fff;
}

footer {
    background-color: var(--color-surface);
}

.navbar-brand {
    font-weight: bold;
    color: var(--color-primary) !important;
    margin-right: 0.75rem;
}

.navbar-utility-controls {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    flex-wrap: nowrap;
    gap: 0.375rem;
    margin-right: 0.5rem;
}

.navbar-language-form {
    display: inline-flex;
    align-items: center;
    margin: 0;
}

.navbar-language-select {
    width: auto;
    min-width: 5.75rem;
    min-height: 2.75rem;
    font-size: 0.8rem;
}

/* Day Grid — 24행 × 6열. 열 수는 화면 폭과 무관하게 고정 */
.day-grid {
    display: flex;
    flex-direction: column;
    gap: 3px;
    -webkit-user-select: none;
    user-select: none;
    touch-action: pan-y;
}

.day-row {
    display: grid;
    grid-template-columns: 46px 1fr;
    gap: 10px;
    /* 08:00 은 08 시 띠의 한가운데가 아니라 그 띠가 시작하는 선이다.
       가운데 정렬하면 라벨이 가리키는 시각이 30 분씩 밀려 읽힌다. */
    align-items: start;
}

.day-row__label {
    font: 500 10.5px/1 var(--font-mono);
    color: var(--color-text-muted);
    text-align: right;
}

.day-row__cells {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 3px;
    position: relative;
}

.slot-block {
    height: 19px;
    border-radius: 3px;
    display: flex;
    align-items: center;
    overflow: hidden;
    padding: 0 7px;
    cursor: pointer;
    color: var(--ink-on-accent);
    font: 600 10.5px/1 var(--font-body);
    -webkit-touch-callout: none;
}

.slot-block.is-empty {
    /* 축약 background 를 쓰면 아래의 10분 눈금 background-image 가 함께
       지워진다. 특정도가 높아 순서로도 되살릴 수 없다. */
    background-color: var(--color-track);
    padding: 0;
}

/* 칸 경계가 보여야 한 칸이 10분이라는 게 읽힌다. 병합된 블록 안에서도
   10분 눈금을 세로선으로 남긴다. 어두운 잉크를 고정해 두면 다크 테마에서
   어두운 바탕에 어두운 선이라 사라지므로 테마 변수로 둔다. */
.slot-block {
    --slot-tick: rgba(20, 33, 26, 0.14);
    box-shadow: 0 0 0 1px var(--color-border) inset;
    background-image: repeating-linear-gradient(
        90deg,
        transparent 0,
        transparent calc(100% / var(--slot-span, 1) - 1px),
        var(--slot-tick) calc(100% / var(--slot-span, 1) - 1px),
        var(--slot-tick) calc(100% / var(--slot-span, 1))
    );
    transition: box-shadow .15s ease;
}

.slot-block:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

[data-theme="dark"] .slot-block {
    --slot-tick: rgba(233, 240, 235, 0.16);
}

.slot-block.is-empty {
    box-shadow: 0 0 0 1px var(--color-border-soft) inset;
}

@media (hover: hover) and (pointer: fine) {
    .slot-block:hover {
        box-shadow: 0 0 0 1.5px var(--color-primary) inset;
    }
}

.slot-block__label {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.btn-tag-legend {
    transition: box-shadow .15s ease;
}

@media (hover: hover) and (pointer: fine) {
    .btn-tag-legend:hover {
        box-shadow: 0 0 0 2px var(--color-primary);
    }
}

/* 아직 오지 않은 시간. 안 채운 것이 아니라 아직 올 수 없는 것이라
   지난 빈 칸과 같은 회색으로 두면 0%가 실패로 읽힌다. 시안대로 "더 연하게" —
   바탕색을 덮어 뒤로 물러나게 한다. 라이트에서는 밝아지고 다크에서는
   어두워지므로 두 테마 모두 같은 뜻이 된다. */
.day-row__future {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 3px;
    pointer-events: none;
}

.day-row__future > span {
    background: var(--color-surface);
    opacity: 0.72;
    border-radius: 3px;
}

/* 지금 이 순간이 놓인 자리. 음영만으로는 경계가 안 읽혀 선을 하나 긋는다. */
.day-row__now {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 3px;
    pointer-events: none;
}

.day-row__now > span {
    border-left: 2px solid var(--color-primary);
    margin-left: -1px;
}

.day-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 10px;
    font: 500 11.5px/1 var(--font-body);
    color: var(--color-text-muted);
}

.day-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.day-legend__swatch {
    width: 14px;
    height: 12px;
    border-radius: 3px;
    background: var(--color-track);
    box-shadow: 0 0 0 1px var(--color-border-soft) inset;
}

/* 격자에서와 같은 겹침을 그대로 보여 준다. */
.day-legend__swatch.is-future {
    position: relative;
    overflow: hidden;
}

.day-legend__swatch.is-future::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--color-surface);
    opacity: 0.62;
}

/* 빈 화면에서 바로 집을 태그 몇 개. 넛지 다음의 조용한 지름길이다. */
.frequent-tags__head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 8px;
}

.frequent-tags__title {
    font-weight: 700;
    font-size: 13px;
}

.frequent-tags__note {
    color: var(--color-text-muted);
    font-size: 12px;
}

.frequent-tags__row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.frequent-tags__chip {
    min-height: 44px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

.frequent-tags__chip:hover {
    background-color: var(--color-surface-soft);
    border-color: var(--color-primary-border);
}

.day-row__selection {
    position: absolute;
    inset: 0;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 3px;
    pointer-events: none;
}

.day-row__selection .is-selected {
    border-radius: 3px;
    background: var(--color-primary-soft);
    box-shadow: 0 0 0 1.5px var(--color-primary) inset;
}

/* 분 눈금은 칸 가운데가 아니라 칸이 시작하는 선 위에 앉는다. 가운데 두면
   :00 이 첫 칸 한복판을 가리켜 5분씩 밀려 읽힌다. */
.day-header__cell {
    font: 500 10px/1 var(--font-mono);
    color: var(--color-text-muted);
    justify-self: start;
    width: max-content;
    transform: translateX(-50%);
}

/* 마지막 :60 은 여섯째 칸의 오른쪽 끝선이다. 칸이 여섯이라 격자에는
   그 자리가 없으므로 따로 얹는다. */
.day-header__cell--end {
    position: absolute;
    right: 0;
    transform: translateX(50%);
}

[data-theme="dark"] .slot-block.is-empty {
    background-color: var(--color-surface-soft);
}

.dashboard-date-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

@media (max-width: 767.98px) {
    .day-row {
        grid-template-columns: 40px 1fr;
        gap: 8px;
    }
    .slot-block {
        height: 22px;
    }
}

/* 시안은 19/22px 이지만 WCAG 2.5.8 최소 타깃은 24px 이다. 손가락으로
   고르는 기기에서는 화면 폭과 무관하게 기준을 따른다. */
@media (pointer: coarse) {
    .slot-block {
        height: 24px;
    }
}

@media (max-width: 768px) {
    .dashboard-date-header {
        flex-direction: column;
        gap: 0.5rem;
    }
    .dashboard-date-title {
        font-size: 1rem;
    }
    .dashboard-stats .fw-bold {
        font-size: 0.9rem;
    }
    .dashboard-stats small {
        font-size: 0.7rem;
    }
}

/* Summary tab — 수치 타일 · 관찰 · 기록 밀도 */
.summary-tiles {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    background: var(--color-border);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.summary-tile {
    background: var(--color-surface);
    padding: 12px 14px;
}

.summary-tile__label {
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--color-text-muted);
    margin-bottom: 4px;
}

.summary-tile__value {
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.1;
}

.summary-tile__value--empty {
    color: var(--color-text-muted);
}

.summary-tile__unit {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--color-text-muted);
    margin-left: 2px;
}

.summary-tile__note {
    font-size: 0.7rem;
    color: var(--color-text-muted);
    margin-top: 3px;
}

.observation-list {
    list-style: none;
    padding: 0;
    margin: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}

.observation {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    padding: 10px 14px;
}

.observation + .observation {
    border-top: 1px solid var(--color-border-muted);
}

.observation__mark {
    flex: none;
    width: 3px;
    align-self: stretch;
    border-radius: 2px;
}

.observation__headline {
    font-size: 0.85rem;
    font-weight: 500;
}

.observation__detail {
    display: block;
    font-size: 0.75rem;
    color: var(--color-text-muted);
    margin-top: 2px;
}

/* 축 라벨과 격자를 같은 행 높이·같은 간격으로 맞춘다. 셀 14px + gap 1px 을
   ylabels 쪽에서 그대로 되풀이해야 날짜가 제 행에 선다. */
.density__chart {
    display: flex;
    align-items: flex-start;
    gap: 6px;
}

.density__ylabels {
    display: grid;
    grid-auto-rows: 14px;
    gap: 1px;
    flex: none;
}

.density__ylabel {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    font-size: 9.5px;
    line-height: 1;
    color: var(--color-text-meta);
}

.density__plot {
    flex: 1;
    min-width: 0;
}

.density__xlabels {
    display: flex;
    justify-content: space-between;
    margin-top: 3px;
}

.density__xlabel {
    font-size: 9.5px;
    line-height: 1;
    color: var(--color-text-meta);
}

.density__grid {
    display: grid;
    grid-template-columns: repeat(24, 1fr);
    gap: 1px;
}

.density__cell {
    display: block;
    height: 14px;
    background: var(--color-border-muted);
}

/* 다섯 단계 단일 색조. 카테고리 색과 섞이면 의미가 겹친다. */
.density__cell:not([data-minutes="0"]) { background: #C3D8CB; }
.density__cell[data-minutes="0"] { background: #E7EAE6; }
.density__cell[data-minutes="30"],
.density__cell[data-minutes="40"] { background: #8FBBA0; }
.density__cell[data-minutes="50"] { background: #4E8F63; }
.density__cell[data-minutes="60"] { background: #2C6E4A; }

/* 다크에서 밝은 회색을 그대로 쓰면 빈 칸이 제일 도드라져 의미가 뒤집힌다. */
[data-theme="dark"] .density__cell:not([data-minutes="0"]) { background: #2E5E44; }
[data-theme="dark"] .density__cell[data-minutes="0"] { background: #272E29; }
[data-theme="dark"] .density__cell[data-minutes="30"],
[data-theme="dark"] .density__cell[data-minutes="40"] { background: #3C7A55; }
[data-theme="dark"] .density__cell[data-minutes="50"] { background: #4E8F63; }
[data-theme="dark"] .density__cell[data-minutes="60"] { background: #6BB183; }

.density__legend {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 8px;
    font-size: 0.7rem;
    color: var(--color-text-muted);
}

.density__legend .density__cell {
    width: 14px;
}

@media (max-width: 767.98px) {
    .summary-tiles {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Undo Snackbar */
.undo-snackbar {
    position: fixed;
    left: 50%;
    bottom: 24px;
    transform: translate(-50%, 12px);
    z-index: 1080;
    display: flex;
    align-items: center;
    gap: 14px;
    max-width: calc(100vw - 32px);
    padding: 12px 14px 12px 18px;
    border-radius: var(--radius-md);
    background: var(--color-text);
    color: var(--color-surface);
    font-size: 0.875rem;
    box-shadow: 0 8px 24px rgba(20, 33, 26, 0.24);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}

.undo-snackbar.is-open {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

.undo-snackbar__action {
    flex: none;
    min-height: 44px;
    padding: 0 12px;
    border: none;
    border-radius: var(--radius-sm);
    background: transparent;
    color: var(--color-accent-work);
    font-weight: 600;
    font-size: 0.875rem;
    cursor: pointer;
    transition: background-color .15s ease;
}

.undo-snackbar__action:hover,
.undo-snackbar__action:focus-visible {
    background: rgba(255, 255, 255, 0.12);
}

@media (max-width: 767.98px) {
    .undo-snackbar {
        left: 16px;
        right: 16px;
        bottom: 84px;
        transform: translateY(12px);
    }
    .undo-snackbar.is-open {
        transform: translateY(0);
    }
}

@media (prefers-reduced-motion: reduce) {
    .undo-snackbar {
        transition: opacity 0.18s ease, visibility 0.18s;
    }
}

.quick-input-sheet-backdrop {
    display: none;
}

.quick-input-tag-list {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 0.25rem 0.375rem;
}

.quick-input-tag-list .tag-btn {
    width: fit-content;
    max-width: 100%;
    white-space: normal;
}

.quick-input-sheet__empty-tags {
    margin: 4px 0;
    font-size: 12.5px;
    color: var(--color-text-muted);
}

/* 데스크톱: 사이드바 안의 평범한 패널. 시안에는 카드 헤더가 없다 —
   .quick-input-sheet 자체가 표면을 갖는다. */
.quick-input-sheet {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 1px 3px rgba(20, 33, 26, 0.06);
    overflow: hidden;
}

.quick-input-sheet__handle {
    display: none;
}

.quick-input-sheet__header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.quick-input-sheet__range {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.quick-input-sheet__prompt {
    font-size: 12.5px;
    color: var(--color-text-muted);
}

.quick-input-sheet__time {
    font: 600 14px/1.3 var(--font-mono);
    color: var(--color-text);
}

.quick-input-sheet__meta {
    font-size: 11.5px;
    color: var(--color-text-muted);
}

.quick-input-sheet__memo-preview {
    display: block;
    font-size: 11.5px;
    color: var(--color-text-muted);
}

.quick-input-sheet__delete {
    align-self: flex-start;
    margin-top: 2px;
    padding: 4px 0;
    border: none;
    background: none;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--color-danger-text);
    text-decoration: underline;
    cursor: pointer;
}

.quick-input-sheet__header-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: none;
    padding-top: 1px;
}

/* 글자는 11.5px 로 작지만 터치 영역은 44px 를 지킨다(시안 4a). */
.quick-input-sheet__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 0 0 12px;
    border: none;
    background: none;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--color-text-muted);
    text-decoration: underline;
    cursor: pointer;
}

.quick-input-sheet__close {
    display: none;
}

.quick-input-sheet__body {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 14px 16px;
}

.quick-input-sheet__help {
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--color-surface-soft);
    font-size: 12px;
    color: var(--color-text-muted);
}

.quick-input-sheet__help ul {
    margin: 6px 0 0;
    padding-left: 18px;
}

.quick-input-sheet__help li {
    margin-bottom: 2px;
}

/* .quick-input-sheet__body 가 flex column 이라 align-self 없이는 폭이 늘어난다.
   칩은 내용만큼만 차지해야 한다. */
.chip--add {
    display: inline-flex;
    align-self: flex-start;
    align-items: center;
    gap: 6px;
    min-height: 44px;
    padding: 0 14px;
    margin-top: 8px;
    border: 1px dashed var(--color-text-disabled);
    border-radius: 16px;
    background: transparent;
    font-size: 12px;
    color: var(--color-text-muted);
    cursor: pointer;
}

.chip__swatch--add {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 10px;
    height: 10px;
    font-size: 11px;
    line-height: 1;
    color: var(--color-text-muted);
}

/* 시트의 칩은 .active 클래스로 선택을 나타낸다. 온보딩은 같은 .chip--pick 에
   숨은 체크박스를 쓰므로(위쪽 :has(.chip__check) 규칙들), 두 상태 모델이 서로
   새지 않도록 이쪽은 .quick-input-sheet 안으로 한정한다. */
.quick-input-sheet .chip--pick {
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-text);
}

.quick-input-sheet .chip--pick.active {
    background: var(--color-primary-soft);
    border-color: transparent;
    font-weight: 600;
}

.quick-input-sheet .chip--pick:not(.active):hover {
    border-color: var(--color-primary-border);
    background-color: var(--color-surface-soft);
}

.quick-input-sheet .chip--pick:not(.active) .chip__swatch {
    opacity: 0.35;
}

.quick-input-sheet__memo {
    min-height: 64px;
    padding: 10px 12px;
    border: 1px solid var(--color-border);
    border-radius: 9px;
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 13px;
    resize: vertical;
}

.quick-input-sheet__footer {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--color-border-muted);
}

.quick-input-sheet__save {
    min-height: 50px;
}

.quick-input-sheet__footmeta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 11px;
    color: var(--color-text-muted);
}

.quick-input-sheet__footmeta a {
    color: var(--color-primary);
    text-decoration: underline;
}

#saveBtn:disabled {
    background-color: var(--color-text-muted);
    border-color: var(--color-text-muted);
    color: white;
    opacity: 1;
}


@media (max-width: 767.98px) {
    body.dashboard-sheet-open {
        overflow: hidden;
    }

    .quick-input-sheet-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 1035;
        background: rgba(15, 23, 42, 0.45);
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease;
    }

    .quick-input-sheet-backdrop.is-open {
        opacity: 1;
        pointer-events: auto;
    }

    .quick-input-sheet {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1040;
        box-sizing: border-box;
        height: 80dvh;
        max-height: calc(100dvh - env(safe-area-inset-bottom, 0px));
        border: none;
        border-radius: 16px 16px 8px 8px;
        box-shadow: 0 -12px 32px rgba(15, 23, 42, 0.24);
        transform: translateY(100%);
        transition: transform 0.24s ease;
        will-change: transform;
    }

    .quick-input-sheet.is-open {
        transform: translateY(0);
    }

    .quick-input-sheet__handle {
        display: block;
        flex: none;
        width: 36px;
        height: 4px;
        margin: 10px auto 0;
        border-radius: 2px;
        background: var(--color-border);
    }

    .quick-input-sheet__header {
        flex: none;
        position: sticky;
        top: 0;
        z-index: 1;
        background: var(--color-surface);
    }

    .quick-input-sheet__close {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 32px;
        height: 32px;
        border: none;
        background: none;
        font-size: 20px;
        line-height: 1;
        color: var(--color-text-muted);
        cursor: pointer;
    }

    .quick-input-sheet__body {
        flex: 1;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }

    .quick-input-sheet__footer {
        flex: none;
        padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    }

    /* #saveBtn 을 여기서 빼는 이유: id 선택자가 .quick-input-sheet__save 의
       50px 를 특정도로 눌러 저장 버튼만 44px 로 주저앉는다. 저장은 시트의
       주 CTA 라 50px 를 지킨다(시안 4a). */
    .quick-input-sheet .btn,
    .quick-input-sheet .tag-btn {
        min-height: 44px;
    }
}

/* =========================================================
   Card & Button (전역 공통)
   ========================================================= */
/* 시안에는 카드 헤더가 없다. 제목은 본문 안의 소제목이고 경계선만 남긴다. */
.card {
    border-color: var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 1px 3px rgba(20, 33, 26, 0.06);
}

.card-header {
    background: var(--color-surface);
    color: var(--color-text);
    border-bottom: 1px solid var(--color-border);
    padding: 14px 20px;
    font-size: 13px;
}

.card-header h5,
.card-header h6 {
    font-weight: 600;
    font-size: 13px;
    color: var(--color-text);
}

.card-header .fas,
.card-header .far {
    display: none;
}

.card-body {
    padding: 18px 20px 20px;
}

.card-header .nav-link {
    color: var(--color-text) !important;
}

.card-header .nav-link.active {
    color: var(--color-text) !important;
    background-color: var(--color-surface);
}

.btn-primary {
    background: var(--color-primary);
    border: none;
    color: var(--ink-on-primary);
}

.btn-primary:hover {
    background: var(--color-primary-hover);
    transform: translateY(-1px);
    color: var(--ink-on-primary);
}

/* 부트스트랩의 .btn:first-child:active 가 (0,3,0) 이라 .btn 을 함께 적어야 이긴다. */
.btn.btn-primary:focus-visible {
    background: var(--color-primary-hover);
    color: var(--ink-on-primary);
}

/* 같은 특정도라 순서가 갈린다. 키보드로 누르면 focus 와 active 가 동시에 참이다. */
.btn.btn-primary:active {
    background: var(--color-primary-press);
    color: var(--ink-on-primary);
}

/* =========================================================
   Welcome Screen — 회원가입 직후 환영 화면
   ========================================================= */
.welcome-screen {
    max-width: 720px;
    margin: 3rem auto;
    padding: 0 1rem;
}

.welcome-screen__inner {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    padding: 3rem 2.5rem;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.06);
}

.welcome-screen__hero {
    text-align: center;
    margin-bottom: 2.5rem;
}

.welcome-screen__logo {
    font-size: 2.75rem;
    color: var(--color-primary);
    margin-bottom: 1rem;
}

.welcome-screen__title {
    font-size: 1.75rem;
    font-weight: 700;
    margin-bottom: 0.75rem;
}

.welcome-screen__lead {
    font-size: 1rem;
    line-height: 1.6;
    color: var(--color-text-muted);
    margin-bottom: 0;
}

.welcome-screen__features {
    list-style: none;
    padding: 0;
    margin: 0 0 2.5rem;
    display: grid;
    gap: 1.25rem;
}

.welcome-screen__feature {
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    padding: 1rem;
    border-radius: var(--radius-md);
    background: rgba(47, 125, 79, 0.05);
}

.welcome-screen__feature-icon {
    flex: 0 0 auto;
    font-size: 1.5rem;
    color: var(--color-primary);
    width: 2.5rem;
    height: 2.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-surface);
    border-radius: 50%;
}

.welcome-screen__feature-title {
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 0.25rem;
}

.welcome-screen__feature-desc {
    font-size: 0.875rem;
    color: var(--color-text-muted);
    margin-bottom: 0;
    line-height: 1.5;
}

.welcome-screen__cta {
    text-align: center;
}

.welcome-screen__cta-btn {
    padding: 0.75rem 2.5rem;
    font-weight: 600;
    border-radius: var(--radius-md);
}

.welcome-screen__skip {
    display: block;
    margin-top: 1rem;
    color: var(--color-text-muted);
    text-decoration: none;
    font-size: 0.875rem;
}

.welcome-screen__skip:hover,
.welcome-screen__skip:focus {
    color: var(--color-text);
    text-decoration: underline;
}

@media (max-width: 576px) {
    .welcome-screen__inner {
        padding: 2rem 1.25rem;
    }
    .welcome-screen__title {
        font-size: 1.4rem;
    }
    .welcome-screen__feature {
        padding: 0.75rem;
    }
}

[data-theme="dark"] .welcome-screen__inner {
    box-shadow: none;
    border: 1px solid var(--color-border);
}

[data-theme="dark"] .welcome-screen__feature {
    background: var(--color-surface-soft);
}

/* =========================================================
   Auth Split — 좌측 브랜드 / 우측 폼 (login/signup)
   ========================================================= */
.auth-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    max-width: 880px;
    margin: 3rem auto;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-surface);
}

.auth-split__brand {
    background: linear-gradient(135deg, #2C6E4A 0%, #1B4A31 100%);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 3rem 2rem;
}

.auth-split__brand-inner {
    text-align: center;
    max-width: 280px;
}

.auth-split__logo {
    font-size: 3rem;
    margin-bottom: 1rem;
    opacity: 0.95;
}

.auth-split__title {
    font-size: 1.75rem;
    font-weight: 700;
    margin-bottom: 0.75rem;
}

.auth-split__tagline {
    font-size: 0.95rem;
    line-height: 1.6;
    opacity: 0.9;
    margin-bottom: 0;
}

.auth-split .auth-card.auth-split__panel {
    margin-top: 0;
    border-radius: 0;
    box-shadow: none;
}

.auth-split .auth-card.auth-split__panel .card-header {
    border-radius: 0 !important;
}

@media (max-width: 768px) {
    .auth-split {
        grid-template-columns: 1fr;
        max-width: 420px;
    }
    .auth-split__brand {
        padding: 1.25rem 1.5rem;
        flex-direction: row;
        gap: 0.75rem;
    }
    .auth-split__brand-inner {
        text-align: left;
        max-width: none;
    }
    .auth-split__logo {
        font-size: 1.75rem;
        margin-bottom: 0;
    }
    .auth-split__title {
        font-size: 1.25rem;
        margin-bottom: 0;
    }
    .auth-split__tagline {
        display: none;
    }
}

/* =========================================================
   Auth Card — login/signup 공통
   ========================================================= */
.auth-card {
    margin-top: 3rem;
    border: none;
    border-radius: var(--radius-lg);
}

.auth-card .card-header {
    border-radius: var(--radius-lg) var(--radius-lg) 0 0 !important;
}

.auth-card .form-control {
    border-radius: var(--radius-md);
    border: 1px solid var(--color-border);
    padding: 0 14px;
    min-height: 44px;
    font-size: 13px;
}

.auth-card .form-control:focus {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 0.2rem rgba(47, 125, 79, 0.2);
}

.auth-card .btn-primary {
    border-radius: var(--radius-md);
    padding: 12px;
    font-weight: bold;
}

.auth-card .form-text {
    font-size: 0.875rem;
    color: var(--color-text-muted);
}

/* =========================================================
   Goal cards — 일/주/월 목표 진행 (3카드 가로 + 카드별 토글)
   ========================================================= */
.goal-card__header {
    display: flex;
    align-items: center;
    background: transparent;
    border: 0;
    cursor: pointer;
    padding: 0.6rem 0.85rem;
    color: inherit;
    transition: background-color .15s ease;
}

.goal-card__header:hover {
    background-color: var(--color-surface-soft);
}

.goal-card__header:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

.goal-card__header .badge {
    font-size: 0.75rem;
}

.goal-card__chevron {
    transition: transform 0.2s ease;
    font-size: 0.8rem;
    color: var(--color-text-muted);
}

.goal-card__header.collapsed .goal-card__chevron {
    transform: rotate(-90deg);
}

.goal-card .card-body {
    padding: 0.5rem 0.85rem 0.75rem;
}

.goal-empty {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
    padding: 0.25rem 0;
}

/* =========================================================
   Stats — 4개 탭 버튼: 반응형 한 줄 + 명확한 클릭 영역
   ========================================================= */
/* 공통: 4개 균등 분배 + 명확한 hover/active 경계 */
#statsTabs.nav-tabs {
    flex-wrap: nowrap;
}
#statsTabs .nav-item {
    flex: 1 1 0;
    min-width: 0;
}
#statsTabs .nav-link {
    width: 100%;
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    border: none;
    border-bottom: 1px solid var(--color-border);
    border-radius: 0;
    color: var(--color-text-muted);
    background-color: transparent;
    transition: color 0.15s, border-color 0.15s;
}
#statsTabs .nav-link:hover:not(.active) {
    color: var(--color-text);
}
#statsTabs .nav-link.active {
    color: var(--color-primary);
    background-color: transparent;
    border-bottom: 2px solid var(--color-primary);
    font-weight: 600;
}
#statsTabs .nav-link:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: -2px;
}

/* 태블릿(768~991px): 텍스트 크기 약간 축소 */
@media (min-width: 768px) and (max-width: 991.98px) {
    #statsTabs .nav-link {
        padding: 0.5rem 0.5rem;
        font-size: 0.875rem;
    }
}

/* 모바일(<768px): 아이콘 위·라벨 아래 2단 배치 */
@media (max-width: 767.98px) {
    #statsTabs .nav-link {
        padding: 0.5rem 0.25rem;
        font-size: 0.7rem;
        line-height: 1.1;
        min-height: 44px;
    }
    #statsTabs .nav-link i {
        display: block;
        margin: 0 0 0.2rem 0 !important;
        font-size: 1rem;
    }
}

/* Password field with show/hide toggle */
.auth-card .password-field {
    position: relative;
}

.auth-card .password-field input {
    padding-right: 58px;
}

.auth-card .password-toggle {
    position: absolute;
    top: 50%;
    right: 4px;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 50px;
    min-height: 44px;
    padding-inline: 6px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 500;
    background: transparent;
    border: 0;
    padding: 0;
    color: var(--color-text-muted);
    cursor: pointer;
    border-radius: var(--radius-sm, 6px);
    line-height: 1;
    transition: color .15s ease, background-color .15s ease;
}

.auth-card .password-toggle:hover,
.auth-card .password-toggle:focus-visible {
    color: var(--color-primary);
    background: rgba(47, 125, 79, 0.08);
    outline: none;
}

.auth-card .caps-lock-warning {
    margin-top: 6px;
    font-size: 0.8125rem;
    color: var(--color-danger-text);
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Password strength meter */
.auth-card .password-strength {
    margin-top: 8px;
    display: flex;
    align-items: center;
    gap: 10px;
}

.auth-card .password-strength__bar {
    flex: 1;
    height: 6px;
    background: rgba(0, 0, 0, 0.08);
    border-radius: 999px;
    overflow: hidden;
}

.auth-card .password-strength__fill {
    height: 100%;
    width: 0;
    transition: width 0.2s ease, background-color 0.2s ease;
    background: #9ca3af;
}

.auth-card .password-strength__label {
    font-size: 0.8125rem;
    font-weight: 600;
    min-width: 56px;
    text-align: right;
    color: var(--color-text-muted);
}

/* 팔레트 안의 토큰만 쓴다. 카테고리 강조색(--color-accent-*)은 분류를 뜻하므로
   강도 표시에 빌려 쓰지 않는다. 토큰이 테마를 따라가 다크 오버라이드도 필요 없다. */
.auth-card .password-strength.is-veryweak .password-strength__fill,
.auth-card .password-strength.is-weak .password-strength__fill { background: var(--color-danger-text); }
.auth-card .password-strength.is-veryweak .password-strength__label,
.auth-card .password-strength.is-weak .password-strength__label { color: var(--color-danger-text); }

.auth-card .password-strength.is-fair .password-strength__fill { background: var(--color-text-muted); }
.auth-card .password-strength.is-fair .password-strength__label { color: var(--color-text-muted); }

.auth-card .password-strength.is-good .password-strength__fill { background: var(--color-primary-border); }
.auth-card .password-strength.is-good .password-strength__label { color: var(--color-primary-border); }

.auth-card .password-strength.is-strong .password-strength__fill { background: var(--color-primary); }
.auth-card .password-strength.is-strong .password-strength__label { color: var(--color-primary); }

/* =========================================================
   Loading Overlay (plain div — body 스크롤 락 없음)
   ========================================================= */
.loading-overlay {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(5px);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 2000;
}

.loading-overlay.is-visible {
    display: flex;
}

.loading-overlay-content {
    background: var(--color-surface);
    border-radius: var(--radius-lg);
    padding: 2.5rem 3rem;
    text-align: center;
    box-shadow: 0 16px 34px rgba(43, 73, 53, 0.2);
}

.loading-spinner {
    width: 3rem;
    height: 3rem;
    border: 4px solid var(--color-surface-soft);
    border-top: 4px solid var(--color-primary);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.loading-text {
    color: var(--color-text-muted);
    font-size: 1.1rem;
    margin-top: 1rem;
}

/* =========================================================
   Dark Mode — Bootstrap & Component Overrides
   ========================================================= */
[data-theme="dark"] .navbar {
    border-bottom: 1px solid var(--color-border);
    box-shadow: none !important;
}

[data-theme="dark"] .navbar .nav-link {
    color: var(--color-text-muted) !important;
    transition: color .15s ease;
}

[data-theme="dark"] .navbar .nav-link:hover {
    color: var(--color-text) !important;
}

[data-theme="dark"] .navbar-toggler {
    border-color: var(--color-border);
    color: var(--color-text);
}

[data-theme="dark"] .navbar-toggler:focus {
    box-shadow: 0 0 0 0.2rem rgba(74, 166, 109, 0.25);
}

[data-theme="dark"] .navbar-toggler-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='%239aab9f' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

[data-theme="dark"] .card {
    background-color: var(--color-surface);
    border-color: var(--color-border);
    color: var(--color-text);
}

[data-theme="dark"] .card-body {
    color: var(--color-text);
}

[data-theme="dark"] .table {
    --bs-table-bg: var(--color-surface);
    --bs-table-color: var(--color-text);
    --bs-table-border-color: var(--color-border);
    color: var(--color-text);
}

[data-theme="dark"] .table-bordered > :not(caption) > * > * {
    border-color: var(--color-border);
}

[data-theme="dark"] footer {
    border-color: var(--color-border) !important;
}

[data-theme="dark"] .form-control,
[data-theme="dark"] .form-select {
    background-color: var(--color-surface-soft);
    border-color: var(--color-border);
    color: var(--color-text);
}

[data-theme="dark"] .form-control:focus,
[data-theme="dark"] .form-select:focus {
    background-color: var(--color-surface);
    border-color: var(--color-primary);
    color: var(--color-text);
    box-shadow: 0 0 0 0.2rem rgba(74, 166, 109, 0.25);
}

/* signup 실시간 검증: password 인풋은 토글 버튼과 시각 충돌 방지를 위해
   Bootstrap is-valid/is-invalid background 아이콘 숨김. 색 테두리는 유지. */
.auth-card .password-field input.is-valid,
.auth-card .password-field input.is-invalid {
    background-image: none;
    padding-right: 44px;
}

/* 실시간 피드백이 표시되면 같은 행의 정적 form-text 도움말 숨김 (시각 정리) */
.mb-3:has(.realtime-feedback.d-block) > .form-text {
    display: none;
}

/* Auth split: dark theme */
[data-theme="dark"] .auth-split__brand {
    background: linear-gradient(135deg, #1f5d3a 0%, #143d27 100%);
}

/* Auth-card extras: dark theme overrides for password toggle, caps lock, strength meter */
[data-theme="dark"] .auth-card .password-toggle {
    color: var(--color-text-muted);
}
[data-theme="dark"] .auth-card .password-toggle:hover,
[data-theme="dark"] .auth-card .password-toggle:focus-visible {
    color: var(--color-primary);
    background: rgba(74, 166, 109, 0.15);
}
[data-theme="dark"] .auth-card .password-strength__bar {
    background: rgba(255, 255, 255, 0.1);
}
[data-theme="dark"] .auth-card .password-strength__label {
    color: var(--color-text-muted);
}


[data-theme="dark"] .list-group-item {
    background-color: var(--color-surface);
    border-color: var(--color-border);
    color: var(--color-text);
}

[data-theme="dark"] .modal-content {
    background-color: var(--color-surface);
    border-color: var(--color-border);
    color: var(--color-text);
}

[data-theme="dark"] .dropdown-menu {
    background-color: var(--color-surface);
    border-color: var(--color-border);
}

[data-theme="dark"] .dropdown-item {
    color: var(--color-text);
    transition: background-color .15s ease;
}

[data-theme="dark"] .dropdown-item:hover {
    background-color: var(--color-surface-soft);
    color: var(--color-text);
}

[data-theme="dark"] .alert-info {
    background-color: rgba(23, 162, 184, 0.15);
    border-color: rgba(23, 162, 184, 0.3);
    color: #5bc0de;
}

[data-theme="dark"] .text-muted {
    color: var(--color-text-muted) !important;
}

[data-theme="dark"] .text-dark {
    color: var(--color-text) !important;
}

[data-theme="dark"] .text-secondary {
    color: var(--color-text-muted) !important;
}

[data-theme="dark"] .border-primary {
    border-color: var(--color-primary) !important;
}

/* Theme Toggle Button */
.theme-toggle {
    background: none;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    color: var(--color-text-muted);
    cursor: pointer;
    min-height: 2.75rem;
    min-width: 3.25rem;
    padding: 0.375rem 0.625rem;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1;
    transition: color 0.2s, border-color 0.2s, background-color 0.2s;
    white-space: nowrap;
}

.theme-toggle:hover,
.theme-toggle:focus-visible {
    color: var(--color-primary);
    border-color: var(--color-primary);
    background-color: var(--color-primary-soft);
    outline: none;
}

@media (max-width: 480px) {
    .navbar-brand {
        margin-right: 0.5rem;
    }

    .navbar-utility-controls {
        gap: 0.25rem;
        margin-right: 0.375rem;
    }

    .navbar-language-select {
        min-width: 5rem;
        font-size: 0.75rem;
    }

    .theme-toggle {
        min-width: 3rem;
        padding-inline: 0.5rem;
        font-size: 0.8rem;
    }
}

/* =========================================================
   Shared UI Utilities
   ========================================================= */

/* Date input (stats + dashboard 공용) */
.date-input-sm {
    width: 150px;
    /* 옆의 .btn-sian 이 44px 이다. 부트스트랩 form-control-sm 은 약 31px 이라
       한 줄에서 높이가 어긋나고 손가락도 닿지 않는다. */
    min-height: 44px;
}

/* =========================================================
   Stats — 차트 / 스크롤 패널 공통 (반응형)
   토큰: --chart-cap-{sm,md,lg}, --panel-h-{sm,md,lg}
   ========================================================= */

/* 공유 reset — :where()는 0 specificity라 override 친화적 */
:where(.chart-container, .chart-container-lg) {
    width: 100%;
    height: auto;
}
/* 내부 스크롤 패널을 두지 않는다. 키보드로는 캡 너머를 볼 방법이 없고,
   터치에서는 페이지 스크롤과 겹친다. 목록은 서버에서 잘라 내려준다. */

/* 차트 변형 */
.chart-container {
    aspect-ratio: 4 / 3;
    max-height: var(--chart-cap-md);
}
.chart-container-lg {
    aspect-ratio: 16 / 9;
    max-height: var(--chart-cap-lg);
}

/* 스크롤 패널 변형 */

/* 상세 분석 테이블 — 컴팩트 셀 + sticky 헤더 */

.tag-color-recommendations {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.tag-color-recommendations__label {
    color: var(--color-text-muted);
    font-size: 0.875rem;
    font-weight: 600;
    margin-right: 0.15rem;
}

.tag-color-swatch {
    width: 1.35rem;
    height: 1.35rem;
    flex: 0 0 1.35rem;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 0;
    transition: border-color .15s ease;
}

.tag-color-swatch:hover,
.tag-color-swatch:focus {
    border-color: var(--color-text);
    outline: 2px solid var(--color-primary-border);
    outline-offset: 2px;
}

/* 목표 안내 패널 (mypage) */
.goal-guide-panel {
    background-color: var(--color-primary-soft);
    border-radius: var(--radius-sm);
    padding: 0;
}

.goal-guide-toggle {
    color: var(--color-text-muted);
    font-weight: bold;
}


/* Google's reCAPTCHA iframe is a fixed ~304px and overflows the auth card at
   360px. Scale it down rather than letting the page scroll sideways. */
@media (max-width: 400px) {
    .auth-card .g-recaptcha {
        transform: scale(0.9);
        transform-origin: 0 0;
        height: 70px;
    }
}

/* 증감은 색만으로 말하지 않는다 — 부호를 항상 함께 둔다 */
.data-table .is-delta-up { color: var(--color-primary); }
.data-table .is-delta-down { color: var(--color-danger-text); }
.data-table .is-primary { font-weight: 600; }
.data-table .text-meta { color: var(--color-text-meta); }

/* 시안 4b 의 하루 구성은 3열을 유지한다. 슬롯·7일 평균 대비는 좁은 화면에서 뺀다 */
@media (max-width: 575.98px) {
    .data-table .is-wide-only {
        display: none;
    }
}

/* 읽기 전용 예시다 — 클릭 핸들러도 tabindex 도 붙이지 않는다 */
.category-guide__examples {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.category-guide__examples .chip {
    min-height: 26px;
    font-size: 11.5px;
}

/* 월 탭 태그 합계 — 시안 3d 는 데스크톱에서 이 패널을 유지한다 */
.tag-totals {
    margin-top: 22px;
}

.tag-totals__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.tag-totals__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 0;
    border-bottom: 1px solid var(--color-border-soft);
    font-size: 11.5px;
    color: var(--color-text-body);
}

.tag-totals__name {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.tag-totals__row--sum {
    border-bottom: 0;
    font-weight: 600;
    color: var(--color-text);
}

.is-narrow-only {
    display: none;
}

@media (max-width: 575.98px) {
    .is-wide-only-block {
        display: none;
    }

    .is-narrow-only {
        display: inline;
        color: var(--color-text-meta);
    }

    /* 시안 4d 의 주차별 요약은 표가 아니라 두 줄짜리 스택 행이다 */
    .weekly-summary,
    .weekly-summary tbody,
    .weekly-summary tr,
    .weekly-summary td {
        display: block;
        width: 100%;
    }

    .weekly-summary thead {
        display: none;
    }

    .weekly-summary tr {
        padding: 9px 0;
        border-bottom: 1px solid var(--color-border-soft);
    }

    .weekly-summary td {
        padding: 0;
        text-align: left;
    }

    .weekly-summary td:first-child {
        font-size: 11.5px;
        color: var(--color-text-muted);
        margin-bottom: 3px;
    }

    .weekly-summary td.is-primary {
        display: inline-block;
        width: auto;
        font-size: 13px;
        margin-right: 10px;
    }

    .weekly-summary td.is-focus-cell {
        display: inline-block;
        width: auto;
        font-size: 12px;
        color: var(--color-text-body);
    }
}

/* 새 태그 모달 (시안 7b · 440px) */
.tag-modal {
    max-width: 440px;
}

.tag-modal__title {
    font-weight: 700;
    font-size: 17px;
    color: var(--color-text);
    margin: 0 0 3px;
}

.tag-modal__lead {
    font-size: 12px;
    color: var(--color-text-muted);
    margin: 0 0 18px;
}

.category-picker {
    border: 0;
    padding: 0;
    margin: 0 0 1rem;
}

.category-picker__required {
    margin-left: 5px;
    font-size: 10.5px;
    font-weight: 600;
    color: var(--color-danger-text);
}

.category-picker__list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.category-picker__option {
    display: flex;
    align-items: center;
    gap: 9px;
    min-height: 44px;
    padding: 0 12px;
    border: 1px solid var(--color-border);
    border-radius: 9px;
    background: var(--color-surface);
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

.category-picker__option:not(:has(.category-picker__radio:checked)):hover {
    border-color: var(--color-primary-border);
    background-color: var(--color-surface-soft);
}

/* 라디오는 화면에서 감추되 접근성 트리에는 남긴다. display:none 이면
   키보드로도 못 고른다. */
.category-picker__radio {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.category-picker__swatch {
    width: 14px;
    height: 14px;
    border-radius: 4px;
    flex: none;
}

.category-picker__name {
    font-size: 13px;
    color: var(--color-text);
}

.category-picker__hint {
    margin-left: auto;
    font-size: 11px;
    color: var(--color-text-meta);
}

/* 고른 것 */
.category-picker__option:has(.category-picker__radio:checked) {
    background: var(--color-primary-soft);
    border-color: transparent;
    box-shadow: 0 0 0 1.5px var(--color-primary) inset;
}

.category-picker__option:has(.category-picker__radio:checked) .category-picker__name {
    font-weight: 600;
}

/* 지금 포커스가 닿은 것 — 고른 것과 구별되어야 키보드로 움직이는 게 보인다 */
.category-picker__option:has(.category-picker__radio:focus-visible) {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

.tag-color-preview {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.tag-color-preview__text {
    font-size: 11.5px;
    color: var(--color-text-muted);
    flex: 1 1 180px;
}

/* 설정 화면 (시안 5c) */
.settings-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}

.settings-head__action {
    flex: none;
    min-height: 44px;
    padding: 0 6px;
    border: 0;
    background: transparent;
    color: var(--color-primary);
    font-size: 12.5px;
    font-weight: 500;
    cursor: pointer;
    transition: color .15s ease;
}

.settings-head__action:hover {
    color: var(--color-primary-hover);
}

.goal-add {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--color-border-soft);
}

.goal-add__fields {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 12px;
    margin-bottom: 12px;
}

.goal-add__field {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.category-legend,
.settings-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 14px;
    padding: 0;
    list-style: none;
}

.category-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    color: var(--color-text-muted);
}

.settings-danger {
    color: var(--color-danger-text);
}

/* 로그아웃은 데스크톱 상단바에 이미 있다. 좁은 화면에서만 설정에 노출한다. */
.is-narrow-only-row {
    display: none;
}

@media (max-width: 767.98px) {
    .is-narrow-only-row {
        display: flex;
    }
}

/* =========================================================
   목표 관리 — 시안 5·6 + 진행률 카드
   ========================================================= */

.settings-panel--wide {
    max-width: 720px;
}

/* page-head 가 접히면 개수만 남은 줄이 생긴다 — 접혀도 오른쪽에 붙여둔다. */
.goal-count {
    flex: none;
    margin-left: auto;
    font-size: 11.5px;
    color: var(--color-text-meta);
}

.goal-progress__meta,
.goal-progress__period {
    font-weight: 400;
    font-size: 11px;
    color: var(--color-text-meta);
}

.goal-progress__note {
    margin: 2px 0 0;
    font-size: 11px;
    line-height: 1.5;
    color: var(--color-text-meta);
}

/* 파스텔 스와치가 흰 표면에서 1.44:1 까지 떨어진다. 링을 둘러 경계를 만든다.
   전역 .chip__swatch 규칙으로 올리는 것은 별도 접근성 트랙 몫이라 여기서만. */
.goal-progress-card .chip__swatch,
.goal-row__tag .chip__swatch {
    box-shadow: inset 0 0 0 1px var(--color-text-meta);
}

.chip__swatch--empty {
    background: transparent;
}

.goal-manager {
    --goal-grid: minmax(0, 1fr) 104px 116px minmax(96px, auto);
    border: 1px solid var(--color-border);
    border-radius: 10px;
    background: var(--color-surface);
    overflow: hidden;
}

.goal-manager__head {
    display: grid;
    grid-template-columns: var(--goal-grid);
    align-items: center;
    gap: 12px;
    padding: 0 16px;
    height: 36px;
    background: var(--color-surface-soft);
    border-bottom: 1px solid var(--color-border-muted);
    font: 500 10px/1 var(--font-mono);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--color-text-meta);
}

.goal-manager__head .is-num {
    text-align: right;
}

.goal-row {
    display: grid;
    grid-template-columns: var(--goal-grid);
    align-items: center;
    gap: 12px;
    margin: 0;
    padding: 9px 16px;
    border-bottom: 1px solid var(--color-border-muted);
}

.goal-row.is-dirty {
    background: var(--color-surface-soft);
}

.goal-row__cell {
    display: flex;
    align-items: center;
    min-width: 0;
}

.goal-row__tag {
    gap: 8px;
}

.goal-row__select {
    flex: 1;
    min-width: 0;
    height: 38px;
    padding: 0 8px;
    border: 1px solid var(--color-border);
    border-radius: 7px;
    background: var(--color-surface);
    color: var(--color-text);
    font: 400 13px/1 var(--font-body);
}

.goal-row__hours {
    justify-content: flex-end;
    gap: 6px;
}

.goal-row__input {
    width: 64px;
    height: 38px;
    padding: 0 9px;
    border: 1px solid var(--color-border);
    border-radius: 7px;
    background: var(--color-surface);
    color: var(--color-text);
    font: 500 13px/1 var(--font-mono);
    text-align: right;
}

.goal-row.is-dirty .goal-row__input,
.goal-row.is-dirty .goal-row__select {
    border-color: var(--color-primary);
}

.goal-row.has-error .goal-row__input,
.goal-add.has-error .goal-row__input {
    border-color: var(--color-danger-text);
    background: var(--color-danger-soft);
}

/* UA 기본 파란 포커스 링은 팔레트 밖이다. 다른 폼 컨트롤과 같은 초록 링으로. */
.goal-row__select:focus-visible,
.goal-row__input:focus-visible,
.goal-row__delete:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}

.goal-row__unit {
    font-size: 12px;
    color: var(--color-text-meta);
}

.goal-row__action {
    justify-content: flex-end;
    gap: 10px;
}

.goal-row__save {
    min-height: 34px;
    padding: 0 12px;
    font-size: 12px;
}

.goal-row__delete {
    display: inline-flex;
    align-items: center;
    min-height: 34px;
    font-size: 12px;
    color: var(--color-text-meta);
    text-decoration: underline;
}

.goal-row__delete:hover {
    color: var(--color-danger-text);
}

.goal-row__error {
    grid-column: 1 / -1;
    margin: 4px 0 0;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--color-danger-text);
}

/* 삭제 확인 — 행이 통째로 확인 줄로 바뀐다. 별도 화면으로 나가지 않는다. */
.goal-row.is-confirming {
    grid-template-columns: minmax(0, 1fr) auto;
    background: var(--color-danger-soft);
    box-shadow: inset 2px 0 0 var(--color-danger-text);
}

.goal-row.is-confirming .goal-row__cell {
    display: none;
}

.goal-confirm__text {
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--color-text);
}

.goal-confirm__actions {
    display: flex;
    justify-content: flex-end;
    gap: 7px;
}

.goal-confirm__yes,
.goal-confirm__no {
    min-height: 34px;
    padding: 0 12px;
    font-size: 12px;
}

.goal-confirm__yes {
    border-color: transparent;
    background: var(--color-danger-text);
    color: var(--ink-on-danger);
    font-weight: 600;
}

.goal-empty {
    padding: 22px 18px;
    text-align: center;
    border-bottom: 1px solid var(--color-border-muted);
}

.goal-empty__text {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.7;
    color: var(--color-text-muted);
}

.goal-add {
    margin: 0;
    padding: 14px 16px 16px;
    background: var(--color-surface-soft);
}

.goal-add__label {
    margin-bottom: 9px;
    font: 500 9.5px/1 var(--font-mono);
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--color-text-meta);
}

.goal-add__grid {
    display: grid;
    grid-template-columns: var(--goal-grid);
    align-items: center;
    gap: 12px;
}

.goal-add .goal-row__select,
.goal-add .goal-row__input {
    height: 40px;
}

.goal-add__submit {
    min-height: 40px;
    padding: 0 12px;
    font-size: 12.5px;
}

.goal-add__plus {
    font-size: 15px;
    line-height: 1;
}

.goal-add__hint {
    margin: 8px 0 0;
    font-size: 11.5px;
    color: var(--color-text-meta);
}

.goal-tag-nudge {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px;
    padding: 12px 16px;
    border-top: 1px solid var(--color-border-muted);
}

.goal-tag-nudge__text {
    margin: 0;
    font-size: 11.5px;
    color: var(--color-text-muted);
}

.goal-tag-nudge__link {
    min-height: 40px;
    padding: 0 12px;
    font-size: 12.5px;
}

.goal-tag-nudge__plus {
    font-size: 15px;
    line-height: 1;
}

.goal-status {
    min-height: 22px;
    margin-top: 12px;
}

.goal-status__pill {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 5px 11px;
    border-radius: 6px;
    background: var(--color-primary-soft);
    font-size: 12px;
    color: var(--color-text);
}

.goal-status__pill.is-error {
    background: var(--color-danger-soft);
    color: var(--color-danger-text);
}

/* 서버 왕복 중에는 버튼이 스스로 말한다 — 라벨 폭을 유지한 채 스피너만 얹어
   레이아웃이 흔들리지 않게 한다. */
.is-busy {
    position: relative;
    color: transparent !important;
    pointer-events: none;
}

.is-busy::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 14px;
    height: 14px;
    margin: -7px 0 0 -7px;
    border: 2px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: 50%;
    animation: spin .7s linear infinite;
}

.goal-confirm__yes.is-busy::after {
    border-color: var(--color-danger-soft);
    border-top-color: var(--color-danger-text);
}

@media (prefers-reduced-motion: reduce) {
    .is-busy::after {
        animation: none;
        border-top-color: var(--color-border);
        border-right-color: var(--color-primary);
    }
}

.goal-snackbar {
    position: fixed;
    left: 50%;
    bottom: 28px;
    z-index: 1050;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 16px;
    border-radius: 9px;
    background: var(--color-text);
    box-shadow: 0 8px 24px rgba(15, 23, 42, .22);
}

.goal-snackbar[hidden] {
    display: none;
}

.goal-snackbar__text {
    font-size: 13px;
    color: var(--color-surface);
}

.goal-snackbar__undo {
    border: 0;
    background: transparent;
    padding: 4px 0;
    font-weight: 600;
    font-size: 12.5px;
    color: var(--color-accent-work);
    text-decoration: underline;
    cursor: pointer;
}

/* 360px 에서는 4열이 들어가지 않는다 — 표를 풀어 행 목록으로 바꾼다(시안 5c). */
@media (max-width: 767.98px) {
    .goal-manager__head {
        display: none;
    }

    .goal-row,
    .goal-add__grid {
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 8px 10px;
        padding: 12px 14px;
    }

    .goal-add__grid {
        padding: 0;
    }

    .goal-row__tag {
        grid-column: 1;
    }

    /* 기간은 값이 두 글자뿐이라, 태그 이름 칸만큼 늘리면 행이 어긋나 보인다. */
    .goal-row__period {
        grid-column: 1;
        grid-row: 2;
        justify-self: start;
    }

    .goal-row__period .goal-row__select {
        flex: none;
        width: 128px;
    }

    .goal-row__hours {
        grid-column: 2;
        grid-row: 1;
    }

    .goal-row__action {
        grid-column: 2;
        grid-row: 2;
    }

    .goal-row__input,
    .goal-row__select,
    .goal-add .goal-row__input,
    .goal-add .goal-row__select {
        height: 44px;
    }

    .goal-row__save,
    .goal-row__delete,
    .goal-confirm__yes,
    .goal-confirm__no,
    .goal-tag-nudge__link {
        min-height: 44px;
    }

    .goal-add__grid > .goal-row__action {
        grid-column: 1 / -1;
        grid-row: auto;
    }

    .goal-add__submit {
        flex: 1;
        min-height: 48px;
    }

    .goal-row.is-confirming {
        grid-template-columns: minmax(0, 1fr);
    }
}
