/* 커스텀 스타일 — design-ref.md (Toss 스타일) 기반. Pico 뒤에 로드해 변수 오버라이드. 폰트는 폐쇄망 대비 로컬 동봉(static/fonts), CDN 의존 없음. */ @font-face { font-family: "Pretendard Variable"; font-weight: 45 920; font-style: normal; font-display: swap; src: url("/static/fonts/PretendardVariable.woff2") format("woff2-variations"); } @font-face { font-family: "JetBrains Mono"; font-weight: 100 800; font-style: normal; font-display: swap; src: url("/static/fonts/JetBrainsMono.woff2") format("woff2-variations"); } :root { /* palette (design-ref §2) */ --bg: #ffffff; --bg-alt: #f9fafb; --surface: #f2f4f6; --surface-2: #e8f3ff; --text: #191f28; --text-secondary: #333d4b; --text-muted: #6b7684; --text-dim: #8b95a1; --border: #e5e8eb; --border-strong: #d1d6db; --accent: #3182f6; --accent-hover: #1b64da; --accent-deep: #1e40af; --accent-soft: #e8f3ff; --success-text: #00a37a; --warning-text: #c5700a; --danger: #f04452; --radius-card: 12px; /* 영문/숫자(저장소명·버전·패키지수·시각)는 모노 — 도구다운 가독성 (design-ref §3) */ --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace; /* Pico 매핑 */ --pico-font-family-sans-serif: "Pretendard Variable", -apple-system, BlinkMacSystemFont, "Apple SD Gothic Neo", "Segoe UI", "Noto Sans KR", system-ui, sans-serif; --pico-font-family: var(--pico-font-family-sans-serif); --pico-line-height: 1.55; --pico-border-radius: 7px; --pico-background-color: var(--bg-alt); --pico-color: var(--text-secondary); --pico-h1-color: var(--text); --pico-h2-color: var(--text); --pico-h3-color: var(--text); --pico-muted-color: var(--text-muted); --pico-primary: #ffffff; --pico-primary-background: var(--accent); --pico-primary-hover-background: var(--accent-hover); --pico-primary-border: var(--accent); --pico-primary-hover-border: var(--accent-hover); --pico-card-background-color: var(--bg); --pico-card-border-color: var(--border); --pico-card-box-shadow: 0 1px 3px rgba(25, 31, 40, 0.04); } body { background: var(--bg-alt); color: var(--text-secondary); -webkit-font-smoothing: antialiased; } main.container { max-width: 1040px; padding-block: 40px; } h1, h2, h3 { color: var(--text); font-weight: 700; letter-spacing: -0.02em; } h2 { font-size: 22px; margin: 0; } section { margin-bottom: 44px; } .mono { font-family: var(--font-mono); font-feature-settings: "tnum" 1; } /* 상단 내비 */ .app-nav { background: var(--bg); border-bottom: 1px solid var(--border); } .app-nav .container { max-width: 1040px; padding-block: 18px; } .app-nav .brand { margin: 0; font-size: 18px; font-weight: 700; color: var(--text); letter-spacing: -0.02em; } .app-nav .brand .accent { color: var(--accent); } .section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; } /* 버튼 — Toss: radius 7, weight 600, 누름 피드백 scale(0.98) (design-ref §4·§6) */ button, [role="button"] { font-weight: 600; transition: background-color 0.12s ease, border-color 0.12s ease, transform 0.096s ease; } button:active, [role="button"]:active { transform: scale(0.98); } button.secondary, [role="button"].secondary, a.secondary { --pico-background-color: var(--surface-2); --pico-border-color: var(--surface-2); --pico-color: var(--accent-hover); font-weight: 600; } button.danger, [role="button"].danger { --pico-background-color: var(--danger); --pico-border-color: var(--danger); --pico-color: #ffffff; } button:disabled, [role="button"]:disabled { opacity: 0.45; } /* 표 안 액션 버튼: 컴팩트 */ .btn-sm { padding: 7px 14px; font-size: 13px; margin: 0; width: auto; } /* 요약 카드 */ .summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 24px; } .summary .card { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-card); padding: 20px 22px; box-shadow: 0 1px 3px rgba(25, 31, 40, 0.04); transition: border-color 0.12s ease; } .summary .card:hover { border-color: var(--border-strong); } .summary .value { font-family: var(--font-mono); font-size: 34px; font-weight: 600; color: var(--text); line-height: 1.1; letter-spacing: -0.02em; font-feature-settings: "tnum" 1; } .summary .value.is-accent { color: var(--accent); } .summary .value.is-success { color: var(--success-text); } .summary .label { margin-top: 8px; font-size: 13px; font-weight: 500; color: var(--text-muted); } /* 표 (카드로 감싸기, hairline 행, hover) */ .table-card { background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-card); overflow: hidden; box-shadow: 0 1px 3px rgba(25, 31, 40, 0.04); } .table-card table { margin: 0; } .table-card thead th { font-size: 12px; font-weight: 600; color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; background: var(--bg-alt); border-bottom: 1px solid var(--border); padding-block: 14px; } .table-card tbody td { height: 56px; border-bottom: 1px solid var(--border); padding-block: 12px; vertical-align: middle; } .table-card tbody tr:last-child td { border-bottom: none; } .table-card tbody tr:hover { background: var(--bg-alt); } .repo-name a { font-family: var(--font-mono); font-weight: 600; color: var(--text); text-decoration: none; } .repo-name a:hover { color: var(--accent); } /* 숫자/버전/시각: 모노 + tabular */ .num, .mono { font-family: var(--font-mono); font-feature-settings: "tnum" 1; } td.num, th.num { text-align: right; } /* 액션 셀: swap(버튼→진행률) 시 행 높이 안 흔들리게 고정 */ .row-action { display: flex; align-items: center; min-height: 34px; } /* 검증 배지 칩 (dot + 라벨, 이모지 없음) */ .badge { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 999px; font-size: 13px; font-weight: 500; white-space: nowrap; } .badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; } .badge-pass { color: var(--success-text); background: rgba(0, 200, 150, 0.12); } .badge-warn { color: var(--warning-text); background: rgba(255, 149, 0, 0.13); } .badge-unset { color: var(--text-muted); background: var(--surface); } .badge-deployed { color: var(--accent-hover); background: var(--accent-soft); } /* 버전 검증 상세 */ .verify-detail { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; } .verify-detail small { color: var(--text-muted); font-family: var(--font-mono); } /* 패키지 증감 */ .delta-add { color: var(--success-text); } .delta-del { color: var(--danger); } /* 동기화 진행률 바 */ .sync-progress { display: flex; flex-direction: column; gap: 5px; min-width: 150px; } .sync-progress progress { margin: 0; height: 6px; } .sync-progress small { color: var(--text-muted); font-family: var(--font-mono); font-size: 12px; } /* 연결 상태 칩 (dot + 텍스트) */ .status-line { display: inline-flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px; font-weight: 500; background: var(--surface); } .status-line::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; } .status-ok { color: var(--success-text); background: rgba(0, 200, 150, 0.1); } .status-bad { color: var(--danger); background: rgba(240, 68, 82, 0.1); } .status-loading { color: var(--text-muted); } @media (max-width: 640px) { .summary { grid-template-columns: repeat(2, 1fr); } }