Files
ahp-decision-analysis/src/styles/main.scss
T
2026-08-13 21:35:38 +09:00

913 lines
22 KiB
SCSS

// ──────────────────────────────────────────
// Variables — monochrome only
// ──────────────────────────────────────────
$ink: #111111; // 본문 / 강조 (검정)
$ink-soft: #333333;
$muted: #6E6E6E; // 보조 텍스트 (회색)
$line: #111111; // 구조 구분선 (검정 border)
$line-soft: #CCCCCC; // 입력/바/내부 구분선 (회색)
$track: #E5E5E5; // 바 트랙 (회색)
$wash: #F5F5F5; // 유일하게 허용하는 옅은 회색 면
$white: #FFFFFF;
$radius: 0;
// ──────────────────────────────────────────
// Reset & Base
// ──────────────────────────────────────────
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: 16px; scroll-behavior: smooth; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Noto Sans KR', sans-serif;
background: $white;
color: $ink;
line-height: 1.6;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
}
// 클릭 요소 focus 시 별도 디자인 없음
:focus,
:focus-visible { outline: none; }
// ──────────────────────────────────────────
// Layout
// ──────────────────────────────────────────
#app { display: flex; flex-direction: column; min-height: 100vh; }
#app-header {
background: $white;
border-bottom: 1px solid $line;
padding: 0 1.5rem;
position: sticky;
top: 0;
z-index: 100;
}
.header-inner {
max-width: 760px;
margin: 0 auto;
display: flex;
align-items: center;
gap: 1rem;
height: 56px;
}
.header-title {
font-size: .85rem;
font-weight: 700;
color: $ink;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: -.01em;
}
.header-name {
direction: rtl;
font-size: .85rem;
font-weight: 700;
color: $ink;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: -.01em;
}
#app-main {
flex: 1;
padding: 2rem 1rem 4rem;
display: flex;
justify-content: center;
align-items: center;
}
.step-wrap {
// #app-main이 flex 컨테이너라 폭을 명시하지 않으면 콘텐츠 크기로 줄어듦
width: 100%;
max-width: 720px;
margin: 0 auto;
}
// ──────────────────────────────────────────
// Step Progress Indicator
// ──────────────────────────────────────────
.step-progress {
display: flex;
align-items: center;
gap: 0;
margin-bottom: 2rem;
.step-dot {
display: flex;
flex-direction: column;
align-items: center;
gap: .25rem;
flex: 1;
position: relative;
&:not(:last-child)::after {
content: '';
position: absolute;
top: 14px;
left: calc(50% + 14px);
right: calc(-50% + 14px);
height: 1px;
background: $line-soft;
}
&.done::after { background: $ink; }
.dot-circle {
width: 28px;
height: 28px;
border-radius: 50%;
border: 1px solid $line-soft;
background: $white;
display: flex;
align-items: center;
justify-content: center;
font-size: .72rem;
font-weight: 700;
color: $muted;
position: relative;
z-index: 1;
}
.dot-label {
font-size: .68rem;
color: $muted;
text-align: center;
line-height: 1.2;
}
&.done .dot-circle { background: $ink; border-color: $ink; color: $white; }
&.active .dot-circle { background: $ink; border-color: $ink; color: $white; }
&.active .dot-label { color: $ink; font-weight: 700; }
}
}
// ──────────────────────────────────────────
// Cards
// ──────────────────────────────────────────
.card {
background: $white;
border: 1px solid $line;
border-radius: $radius;
padding: 2rem;
margin-bottom: 1.5rem;
&.card-sm { padding: 1.5rem; }
}
.section-title {
font-size: 1.3rem;
font-weight: 800;
color: $ink;
letter-spacing: -.02em;
margin-bottom: .4rem;
}
.section-subtitle {
color: $muted;
font-size: .9rem;
margin-bottom: 1.5rem;
line-height: 1.5;
}
// ──────────────────────────────────────────
// Forms (Step 1)
// ──────────────────────────────────────────
.form-group {
margin-bottom: 1.2rem;
label {
display: block;
font-size: .875rem;
font-weight: 700;
margin-bottom: .5rem;
color: $ink;
}
input[type="text"] {
width: 100%;
padding: .6rem .9rem;
border: 1px solid $line-soft;
border-radius: $radius;
font-size: .9rem;
color: $ink;
background: $white;
&::placeholder { color: #A3A3A3; }
}
}
.radio-group {
display: flex;
flex-wrap: wrap;
gap: .5rem;
label {
display: flex;
align-items: center;
gap: .4rem;
padding: .5rem 1rem;
border: 1px solid $line-soft;
border-radius: $radius;
cursor: pointer;
font-size: .875rem;
font-weight: 400;
color: $muted;
margin: 0;
white-space: nowrap;
input[type="radio"] { display: none; }
&:hover { border-color: $line; color: $ink; }
&.selected { border-color: $ink; background: $ink; color: $white; font-weight: 700; }
}
}
// 카드 바깥에 놓이는 단계 안내문 — 본문보다 크게
.step-instruction {
font-size: 1.05rem;
line-height: 1.65;
font-weight: 500;
color: $ink;
margin-bottom: 1.5rem;
}
// ──────────────────────────────────────────
// Buttons
// ──────────────────────────────────────────
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: .4rem;
padding: .65rem 1.6rem;
border-radius: $radius;
border: 1px solid transparent;
font-size: .9rem;
font-weight: 700;
cursor: pointer;
text-decoration: none;
background: $white;
color: $ink;
&:disabled { opacity: .35; cursor: not-allowed; }
&.btn-primary {
background: $ink;
color: $white;
border-color: $ink;
&:not(:disabled):hover { background: $white; color: $ink; }
}
&.btn-outline {
background: $white;
color: $ink;
border-color: $ink;
&:not(:disabled):hover { background: $ink; color: $white; }
}
&.btn-gray {
background: $white;
color: $muted;
border-color: $line-soft;
&:not(:disabled):hover { border-color: $line; color: $ink; }
}
&.btn-lg { padding: .85rem 2.2rem; font-size: 1rem; }
&.btn-full { width: 100%; }
// 선정 / 미선정 — 미선택 상태는 회색 테두리, 선택 시 검정 반전
&.btn-select,
&.btn-reject {
flex: 1;
font-size: 1rem;
padding: .9rem 1rem;
background: $white;
color: $ink;
border-color: $line-soft;
&:not(:disabled):hover { border-color: $line; }
}
&.btn-selected-select,
&.btn-selected-reject {
flex: 1;
padding: .9rem 1rem;
font-size: 1rem;
background: $ink;
color: $white;
border-color: $ink;
}
}
.btn-row {
display: flex;
gap: .75rem;
margin-top: 1.2rem;
&.center { justify-content: center; }
&.end { justify-content: flex-end; }
}
// ──────────────────────────────────────────
// Case Card (Step 2)
// ──────────────────────────────────────────
.progress-bar-wrap {
margin-bottom: 1.5rem;
.progress-label {
display: flex;
justify-content: space-between;
font-size: .82rem;
color: $muted;
margin-bottom: .4rem;
font-weight: 700;
}
.progress-track {
height: 4px;
background: $track;
border-radius: $radius;
overflow: hidden;
.progress-fill {
height: 100%;
background: $ink;
transition: width .3s ease;
}
}
}
.case-card {
.case-header {
display: flex;
align-items: center;
gap: .75rem;
margin-bottom: 1.4rem;
padding-bottom: 1rem;
border-bottom: 1px solid $line-soft;
.team-badge {
font-size: 1.4rem;
font-weight: 800;
color: $ink;
background: $white;
border: 1px solid $line;
border-radius: $radius;
padding: .2rem .7rem;
line-height: 1.4;
}
.industry-tag {
font-size: .82rem;
background: $white;
border: 1px solid $line-soft;
border-radius: $radius;
padding: .25rem .7rem;
color: $muted;
font-weight: 400;
}
}
}
.var-row {
display: flex;
align-items: center;
gap: .75rem;
margin-bottom: .85rem;
.var-name {
font-size: .82rem;
font-weight: 400;
color: $ink-soft;
min-width: 110px;
flex-shrink: 0;
}
.var-bar-track {
flex: 1;
height: 8px;
background: $track;
border-radius: $radius;
overflow: hidden;
.var-bar-fill {
height: 100%;
transition: width .4s ease;
}
}
.var-score {
font-size: .85rem;
font-weight: 700;
min-width: 32px;
text-align: right;
color: $ink;
font-variant-numeric: tabular-nums;
}
}
// 점수 수준은 색이 아니라 회색 농도로 구분
.var-bar-fill[data-level="low"] { background: #C7C7C7; }
.var-bar-fill[data-level="mid"] { background: #8A8A8A; }
.var-bar-fill[data-level="high"] { background: $ink; }
.judgment-section {
margin-top: 1.5rem;
padding-top: 1.2rem;
border-top: 1px solid $line-soft;
.judgment-label {
font-size: .875rem;
font-weight: 700;
margin-bottom: .75rem;
color: $ink;
}
}
.confidence-section {
margin-top: 1.2rem;
padding: 1rem 1.2rem;
background: $white;
border: 1px solid $line-soft;
border-radius: $radius;
.confidence-label {
font-size: .82rem;
font-weight: 700;
color: $ink;
margin-bottom: .6rem;
display: flex;
justify-content: space-between;
}
.confidence-slider {
width: 100%;
appearance: none;
height: 4px;
border-radius: $radius;
background: $track;
cursor: pointer;
&::-webkit-slider-thumb {
appearance: none;
width: 18px;
height: 18px;
border-radius: 50%;
background: $ink;
cursor: pointer;
border: none;
}
&::-moz-range-thumb {
width: 18px;
height: 18px;
border-radius: 50%;
background: $ink;
border: none;
cursor: pointer;
}
}
.confidence-labels {
display: flex;
justify-content: space-between;
margin-top: .4rem;
.cl { font-size: .7rem; color: $muted; }
}
}
// ──────────────────────────────────────────
// Judgment Likert (Step 2)
// ──────────────────────────────────────────
.judgment-likert-row {
display: flex;
margin-top: .5rem;
}
.judgment-likert-btn {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: .3rem;
padding: .7rem .3rem;
border: 1px solid $line-soft;
border-radius: $radius;
background: $white;
cursor: pointer;
+ .judgment-likert-btn { margin-left: -1px; }
.jl-num {
font-size: 1.1rem;
font-weight: 800;
color: $muted;
}
.jl-label {
font-size: .65rem;
color: $muted;
text-align: center;
line-height: 1.3;
}
&:hover { border-color: $line; position: relative; z-index: 1; }
// 값별 색상 구분 없이 선택만 검정 반전
&.active,
&[data-val].active {
border-color: $ink;
background: $ink;
position: relative;
z-index: 2;
.jl-num, .jl-label { color: $white; }
}
}
// ──────────────────────────────────────────
// AHP (Step 3)
// ──────────────────────────────────────────
.ahp-pair-card {
.pair-title {
font-size: .85rem;
color: $muted;
margin-bottom: 1.2rem;
font-weight: 400;
}
.pair-criteria {
display: flex;
align-items: center;
justify-content: space-between;
gap: 1rem;
margin-bottom: 1.2rem;
.crit {
flex: 1;
text-align: center;
font-size: 1rem;
font-weight: 400;
color: $muted;
padding: .6rem;
border-radius: $radius;
&.crit-left { text-align: right; }
&.crit-right { text-align: left; }
// 우세한 쪽은 색이 아니라 굵기/명도로 강조
&.crit-active-left,
&.crit-active-right { color: $ink; font-weight: 800; }
}
.vs-badge {
font-size: .75rem;
font-weight: 700;
color: $muted;
background: $white;
border: 1px solid $line-soft;
border-radius: $radius;
padding: .2rem .5rem;
flex-shrink: 0;
}
}
}
.ahp-slider-wrap {
padding: .5rem 0;
}
.ahp-scale-labels {
display: flex;
justify-content: space-between;
margin-bottom: .5rem;
// Pad by half the thumb width (11px) so labels align with thumb at min/max
padding: 0 11px;
span {
font-size: .7rem;
color: $muted;
font-weight: 400;
text-align: center;
min-width: 0;
}
.sc-mid { font-weight: 800; color: $ink; font-size: .72rem; }
}
.ahp-slider {
width: 100%;
appearance: none;
height: 4px;
border-radius: $radius;
background: $track;
cursor: pointer;
&::-webkit-slider-thumb {
appearance: none;
width: 22px;
height: 22px;
border-radius: 50%;
background: $ink;
border: none;
cursor: pointer;
}
&::-moz-range-thumb {
width: 22px;
height: 22px;
border-radius: 50%;
background: $ink;
border: none;
cursor: pointer;
}
}
.ahp-description {
text-align: center;
margin-top: 1rem;
padding: .7rem 1rem;
background: $white;
border: 1px solid $line-soft;
border-radius: $radius;
font-size: .875rem;
font-weight: 700;
color: $ink;
min-height: 42px;
}
// ──────────────────────────────────────────
// Results (Step 4)
// ──────────────────────────────────────────
.weight-chart {
margin-top: .5rem;
.wc-row {
display: flex;
align-items: center;
gap: .75rem;
margin-bottom: .7rem;
.wc-label {
font-size: .82rem;
font-weight: 400;
color: $ink-soft;
min-width: 110px;
flex-shrink: 0;
}
.wc-track {
flex: 1;
height: 14px;
background: $track;
border-radius: $radius;
overflow: hidden;
.wc-fill {
height: 100%;
background: $ink;
transition: width .5s ease;
}
}
.wc-pct {
font-size: .82rem;
font-weight: 700;
color: $ink;
min-width: 38px;
text-align: right;
font-variant-numeric: tabular-nums;
}
}
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: .75rem;
margin-top: 1rem;
.stat-box {
background: $white;
border: 1px solid $line-soft;
border-radius: $radius;
padding: 1rem;
text-align: center;
.stat-val { font-size: 1.6rem; font-weight: 800; color: $ink; font-variant-numeric: tabular-nums; }
.stat-label { font-size: .75rem; color: $muted; margin-top: .25rem; line-height: 1.3; }
// 경고/정상 모두 색 대신 테두리 굵기로만 구분
&.stat-warn { border-color: $line; }
&.stat-ok { border-color: $line-soft; }
}
}
.comparison-table-wrap {
overflow-x: auto;
margin-top: 1rem;
border: 1px solid $line;
border-radius: $radius;
table {
width: 100%;
border-collapse: collapse;
font-size: .82rem;
th {
background: $white;
padding: .6rem .8rem;
text-align: center;
font-weight: 700;
border-bottom: 1px solid $line;
white-space: nowrap;
color: $ink;
}
td {
padding: .55rem .8rem;
text-align: center;
border-bottom: 1px solid $line-soft;
color: $ink-soft;
&:first-child { font-weight: 700; color: $ink; }
}
tr:last-child td { border-bottom: none; }
// 불일치 행은 옅은 회색 면으로만 표시
tr.mismatch td { background: $wash; color: $ink; }
tr.mismatch td:first-child { color: $ink; }
}
}
.badge {
display: inline-block;
padding: .2rem .55rem;
border-radius: $radius;
font-size: .72rem;
font-weight: 700;
line-height: 1.4;
border: 1px solid transparent;
&.badge-select { background: $ink; color: $white; border-color: $ink; }
&.badge-reject { background: $white; color: $muted; border-color: $line-soft; }
&.badge-match { background: $white; color: $ink; border-color: $line; }
&.badge-mismatch { background: $ink; color: $white; border-color: $ink; }
&.badge-neutral { background: $white; color: $muted; border-color: $line-soft; }
}
.neutral-row td { background: $wash; color: $ink-soft; }
// ──────────────────────────────────────────
// Post Survey (Step 5)
// ──────────────────────────────────────────
.likert-group {
margin-bottom: 1.5rem;
.likert-q {
font-size: .9rem;
font-weight: 700;
color: $ink;
margin-bottom: .75rem;
line-height: 1.5;
}
.likert-options {
display: flex;
label {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: .3rem;
cursor: pointer;
+ label .likert-btn { margin-left: -1px; }
input[type="radio"] { display: none; }
.likert-btn {
width: 100%;
padding: .55rem .2rem;
border: 1px solid $line-soft;
border-radius: $radius;
text-align: center;
font-size: .9rem;
font-weight: 700;
color: $muted;
background: $white;
}
.likert-desc { font-size: .65rem; color: $muted; text-align: center; line-height: 1.2; }
input:checked + .likert-btn { border-color: $ink; background: $ink; color: $white; position: relative; z-index: 1; }
&:hover .likert-btn { border-color: $line; }
}
}
}
.open-textarea {
width: 100%;
padding: .8rem 1rem;
border: 1px solid $line-soft;
border-radius: $radius;
font-size: .875rem;
font-family: inherit;
color: $ink;
background: $white;
resize: vertical;
min-height: 100px;
}
// ──────────────────────────────────────────
// Complete Screen
// ──────────────────────────────────────────
.complete-screen {
text-align: center;
padding: 2rem 1rem;
.complete-icon { font-size: 2.5rem; margin-bottom: 1rem; filter: grayscale(1); }
.complete-title { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; margin-bottom: .5rem; }
.complete-desc { color: $muted; font-size: .9rem; margin-bottom: 2rem; line-height: 1.7; }
}
.json-output {
background: $white;
color: $ink-soft;
border: 1px solid $line-soft;
border-radius: $radius;
padding: 1.2rem;
font-family: 'Menlo', 'Monaco', 'Consolas', monospace;
font-size: .75rem;
line-height: 1.6;
text-align: left;
overflow-x: auto;
max-height: 400px;
overflow-y: auto;
white-space: pre;
margin-top: 1rem;
}
// ──────────────────────────────────────────
// Utilities
// ──────────────────────────────────────────
.divider {
height: 1px;
background: $line-soft;
margin: 1.5rem 0;
}
.text-muted { color: $muted; font-size: .85rem; }
.text-center { text-align: center; }
.mt-1 { margin-top: .5rem; }
.mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; }
.mb-1 { margin-bottom: .5rem; }
// 파란색 강조 대신 굵기로만 강조
.highlight-text {
color: $ink;
font-weight: 800;
}
// ──────────────────────────────────────────
// Responsive
// ──────────────────────────────────────────
@media (max-width: 600px) {
#app-header { padding: 0 1rem; }
.header-title { font-size: .78rem; }
.card { padding: 1.2rem; }
.step-instruction { font-size: .95rem; margin-bottom: 1.2rem; }
.step-progress .step-dot .dot-label { display: none; }
.var-row .var-name { min-width: 80px; font-size: .76rem; }
.ahp-pair-card .pair-criteria { flex-direction: column; text-align: center; gap: .5rem; }
.ahp-pair-card .pair-criteria .crit { text-align: center !important; }
.stats-grid { grid-template-columns: repeat(2, 1fr); }
.comparison-table-wrap table { font-size: .75rem; }
.comparison-table-wrap table td,
.comparison-table-wrap table th { padding: .4rem .5rem; }
.likert-group .likert-options label .likert-desc { display: none; }
.btn.btn-lg { padding: .75rem 1.5rem; font-size: .9rem; }
}
@media (max-width: 380px) {
.step-progress .step-dot .dot-circle { width: 22px; height: 22px; font-size: .65rem; }
}