first commit

This commit is contained in:
2026-07-03 20:26:58 +09:00
commit 689d367b84
828 changed files with 269007 additions and 0 deletions
+909
View File
@@ -0,0 +1,909 @@
// ──────────────────────────────────────────
// Variables
// ──────────────────────────────────────────
$primary: #2563EB;
$primary-dk: #1D4ED8;
$success: #16A34A;
$danger: #DC2626;
$warning: #D97706;
$muted: #6B7280;
$border: #E5E7EB;
$bg: #F3F4F6;
$card-bg: #FFFFFF;
$text: #111827;
$text-sm: #374151;
$radius: 12px;
$radius-sm: 8px;
$shadow: 0 1px 4px rgba(0,0,0,.10), 0 4px 16px rgba(0,0,0,.06);
// ──────────────────────────────────────────
// 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: $bg;
color: $text;
line-height: 1.6;
min-height: 100vh;
}
// ──────────────────────────────────────────
// Layout
// ──────────────────────────────────────────
#app { display: flex; flex-direction: column; min-height: 100vh; }
#app-header {
background: $card-bg;
border-bottom: 1px solid $border;
padding: 0 1.5rem;
position: sticky;
top: 0;
z-index: 100;
box-shadow: 0 1px 8px rgba(0,0,0,.06);
}
.header-inner {
max-width: 760px;
margin: 0 auto;
display: flex;
align-items: center;
gap: 1rem;
height: 56px;
}
.header-title {
font-size: .85rem;
font-weight: 600;
color: $primary;
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.lang-btn {
font-size: .78rem;
padding: .3rem .8rem;
border: 1px solid $border;
border-radius: 20px;
background: transparent;
cursor: pointer;
color: $muted;
transition: all .15s;
white-space: nowrap;
&:hover { border-color: $primary; color: $primary; }
}
#app-main {
flex: 1;
padding: 2rem 1rem 4rem;
}
.step-wrap {
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: 2px;
background: $border;
transition: background .3s;
}
&.done::after { background: $primary; }
.dot-circle {
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid $border;
background: $card-bg;
display: flex;
align-items: center;
justify-content: center;
font-size: .72rem;
font-weight: 700;
color: $muted;
transition: all .3s;
position: relative;
z-index: 1;
}
.dot-label {
font-size: .68rem;
color: $muted;
text-align: center;
line-height: 1.2;
}
&.done .dot-circle { background: $primary; border-color: $primary; color: #fff; }
&.active .dot-circle { background: $primary; border-color: $primary; color: #fff; box-shadow: 0 0 0 4px rgba($primary, .2); }
&.active .dot-label { color: $primary; font-weight: 600; }
}
}
// ──────────────────────────────────────────
// Cards
// ──────────────────────────────────────────
.card {
background: $card-bg;
border-radius: $radius;
box-shadow: $shadow;
padding: 2rem;
margin-bottom: 1.5rem;
&.card-sm { padding: 1.5rem; }
}
.section-title {
font-size: 1.3rem;
font-weight: 700;
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: 600;
margin-bottom: .5rem;
color: $text-sm;
}
input[type="text"] {
width: 100%;
padding: .6rem .9rem;
border: 1.5px solid $border;
border-radius: $radius-sm;
font-size: .9rem;
outline: none;
transition: border-color .2s;
&:focus { border-color: $primary; }
&::placeholder { color: #9CA3AF; }
}
}
.radio-group {
display: flex;
flex-wrap: wrap;
gap: .6rem;
label {
display: flex;
align-items: center;
gap: .4rem;
padding: .5rem 1rem;
border: 1.5px solid $border;
border-radius: 24px;
cursor: pointer;
font-size: .875rem;
font-weight: normal;
color: $text-sm;
transition: all .15s;
margin: 0;
white-space: nowrap;
input[type="radio"] { display: none; }
&:hover { border-color: $primary; color: $primary; }
&.selected { border-color: $primary; background: rgba($primary,.07); color: $primary; font-weight: 600; }
}
}
.notice-box {
background: #EFF6FF;
border: 1px solid #BFDBFE;
border-radius: $radius-sm;
padding: 1rem 1.2rem;
margin-bottom: 1.5rem;
p {
font-size: .85rem;
color: #1E40AF;
line-height: 1.6;
&::before { content: ''; }
+ p { margin-top: .3rem; }
}
}
// ──────────────────────────────────────────
// Buttons
// ──────────────────────────────────────────
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: .4rem;
padding: .65rem 1.6rem;
border-radius: $radius-sm;
border: none;
font-size: .9rem;
font-weight: 600;
cursor: pointer;
transition: all .15s;
text-decoration: none;
&:disabled { opacity: .45; cursor: not-allowed; }
&.btn-primary {
background: $primary;
color: #fff;
&:not(:disabled):hover { background: $primary-dk; transform: translateY(-1px); box-shadow: 0 4px 12px rgba($primary,.35); }
}
&.btn-outline {
background: transparent;
color: $primary;
border: 1.5px solid $primary;
&:hover { background: rgba($primary,.06); }
}
&.btn-gray {
background: #F3F4F6;
color: $text-sm;
border: 1.5px solid $border;
&:not(:disabled):hover { background: $border; }
}
&.btn-lg { padding: .85rem 2.2rem; font-size: 1rem; border-radius: 10px; }
&.btn-full { width: 100%; }
&.btn-select {
background: $primary;
color: #fff;
flex: 1;
font-size: 1rem;
padding: .9rem 1rem;
&:not(:disabled):hover { background: $primary-dk; }
}
&.btn-reject {
background: #F9FAFB;
color: #6B7280;
border: 1.5px solid $border;
flex: 1;
font-size: 1rem;
padding: .9rem 1rem;
&:not(:disabled):hover { background: #F3F4F6; color: #374151; }
}
&.btn-selected-select { background: $success; color: #fff; flex: 1; padding: .9rem 1rem; font-size: 1rem; }
&.btn-selected-reject { background: $danger; color: #fff; flex: 1; padding: .9rem 1rem; font-size: 1rem; }
}
.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: 600;
}
.progress-track {
height: 6px;
background: $border;
border-radius: 3px;
overflow: hidden;
.progress-fill {
height: 100%;
background: $primary;
border-radius: 3px;
transition: width .4s ease;
}
}
}
.case-card {
.case-header {
display: flex;
align-items: center;
gap: .75rem;
margin-bottom: 1.4rem;
padding-bottom: 1rem;
border-bottom: 1px solid $border;
.team-badge {
font-size: 1.4rem;
font-weight: 800;
color: $primary;
background: rgba($primary,.08);
border-radius: $radius-sm;
padding: .3rem .8rem;
}
.industry-tag {
font-size: .82rem;
background: #F3F4F6;
border: 1px solid $border;
border-radius: 20px;
padding: .25rem .75rem;
color: $muted;
font-weight: 500;
}
}
}
.var-row {
display: flex;
align-items: center;
gap: .75rem;
margin-bottom: .85rem;
.var-name {
font-size: .82rem;
font-weight: 600;
color: $text-sm;
min-width: 110px;
flex-shrink: 0;
}
.var-bar-track {
flex: 1;
height: 10px;
background: #F3F4F6;
border-radius: 5px;
overflow: hidden;
.var-bar-fill {
height: 100%;
border-radius: 5px;
transition: width .5s ease;
}
}
.var-score {
font-size: .85rem;
font-weight: 700;
min-width: 32px;
text-align: right;
color: $text;
}
}
// Score color via data-score attribute (set inline via JS)
.var-bar-fill[data-level="low"] { background: linear-gradient(90deg, #EF4444, #F87171); }
.var-bar-fill[data-level="mid"] { background: linear-gradient(90deg, #FBBF24, #FCD34D); }
.var-bar-fill[data-level="high"] { background: linear-gradient(90deg, #22C55E, #4ADE80); }
.judgment-section {
margin-top: 1.5rem;
padding-top: 1.2rem;
border-top: 1px solid $border;
.judgment-label {
font-size: .875rem;
font-weight: 600;
margin-bottom: .75rem;
color: $text-sm;
}
}
.confidence-section {
margin-top: 1.2rem;
padding: 1rem 1.2rem;
background: #F9FAFB;
border-radius: $radius-sm;
border: 1px solid $border;
.confidence-label {
font-size: .82rem;
font-weight: 600;
color: $text-sm;
margin-bottom: .6rem;
display: flex;
justify-content: space-between;
}
.confidence-slider {
width: 100%;
appearance: none;
height: 6px;
border-radius: 3px;
background: $border;
outline: none;
cursor: pointer;
&::-webkit-slider-thumb {
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: $primary;
cursor: pointer;
border: 2px solid #fff;
box-shadow: 0 1px 4px rgba(0,0,0,.2);
}
}
.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;
gap: .5rem;
margin-top: .5rem;
}
.judgment-likert-btn {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: .3rem;
padding: .7rem .3rem;
border: 2px solid $border;
border-radius: $radius-sm;
background: $card-bg;
cursor: pointer;
transition: all .15s;
.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: $primary; }
&.active {
border-color: $primary;
background: rgba($primary, .07);
.jl-num { color: $primary; }
.jl-label { color: $primary; }
}
// Color coding by value
&[data-val="1"].active { border-color: $danger; background: rgba($danger,.07);
.jl-num, .jl-label { color: $danger; } }
&[data-val="2"].active { border-color: #F97316; background: rgba(#F97316,.07);
.jl-num, .jl-label { color: #F97316; } }
&[data-val="3"].active { border-color: $warning; background: rgba($warning,.07);
.jl-num, .jl-label { color: $warning; } }
&[data-val="4"].active { border-color: #22C55E; background: rgba(#22C55E,.07);
.jl-num, .jl-label { color: #22C55E; } }
&[data-val="5"].active { border-color: $success; background: rgba($success,.07);
.jl-num, .jl-label { color: $success; } }
}
// ──────────────────────────────────────────
// AHP (Step 3)
// ──────────────────────────────────────────
.ahp-pair-card {
.pair-title {
font-size: .85rem;
color: $muted;
margin-bottom: 1.2rem;
font-weight: 500;
}
.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: 700;
color: $text;
padding: .6rem;
border-radius: $radius-sm;
transition: background .2s;
&.crit-left { text-align: right; }
&.crit-right { text-align: left; }
&.crit-active-left { color: $primary; background: rgba($primary,.07); }
&.crit-active-right { color: $success; background: rgba($success,.07); }
}
.vs-badge {
font-size: .8rem;
font-weight: 700;
color: $muted;
background: $bg;
border: 1px solid $border;
border-radius: 20px;
padding: .25rem .6rem;
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 (12px) so labels align with thumb at min/max
padding: 0 12px;
span {
font-size: .7rem;
color: $muted;
font-weight: 600;
text-align: center;
min-width: 0;
}
.sc-mid { font-weight: 800; color: $text-sm; font-size: .75rem; }
}
.ahp-slider {
width: 100%;
appearance: none;
height: 8px;
border-radius: 4px;
background: linear-gradient(to right, rgba($primary,.15) 0%, $primary 50%, rgba($success,.15) 100%);
outline: none;
cursor: pointer;
&::-webkit-slider-thumb {
appearance: none;
width: 24px;
height: 24px;
border-radius: 50%;
background: #fff;
border: 3px solid $primary;
box-shadow: 0 2px 6px rgba(0,0,0,.2);
cursor: pointer;
transition: border-color .2s;
}
}
.ahp-description {
text-align: center;
margin-top: 1rem;
padding: .7rem 1rem;
background: #F0F9FF;
border: 1px solid #BAE6FD;
border-radius: $radius-sm;
font-size: .875rem;
font-weight: 600;
color: #0369A1;
min-height: 42px;
}
.cr-warning {
background: #FEF9C3;
border: 1px solid #FDE047;
border-radius: $radius-sm;
padding: 1rem 1.2rem;
margin-top: 1rem;
p { font-size: .875rem; color: #713F12; margin-bottom: .75rem; font-weight: 600; }
}
// ──────────────────────────────────────────
// 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: 600;
color: $text-sm;
min-width: 110px;
flex-shrink: 0;
}
.wc-track {
flex: 1;
height: 18px;
background: #F3F4F6;
border-radius: 9px;
overflow: hidden;
.wc-fill {
height: 100%;
background: linear-gradient(90deg, $primary, #60A5FA);
border-radius: 9px;
transition: width .6s ease;
}
}
.wc-pct { font-size: .82rem; font-weight: 700; color: $primary; min-width: 38px; text-align: right; }
}
}
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
gap: 1rem;
margin-top: 1rem;
.stat-box {
background: $bg;
border: 1px solid $border;
border-radius: $radius-sm;
padding: 1rem;
text-align: center;
.stat-val { font-size: 1.6rem; font-weight: 800; color: $primary; }
.stat-label { font-size: .75rem; color: $muted; margin-top: .25rem; line-height: 1.3; }
&.stat-warn .stat-val { color: $warning; }
&.stat-ok .stat-val { color: $success; }
}
}
.comparison-table-wrap {
overflow-x: auto;
margin-top: 1rem;
border-radius: $radius-sm;
border: 1px solid $border;
table {
width: 100%;
border-collapse: collapse;
font-size: .82rem;
th {
background: #F9FAFB;
padding: .6rem .8rem;
text-align: center;
font-weight: 700;
border-bottom: 1px solid $border;
white-space: nowrap;
color: $text-sm;
}
td {
padding: .55rem .8rem;
text-align: center;
border-bottom: 1px solid $border;
&:first-child { font-weight: 700; }
}
tr:last-child td { border-bottom: none; }
tr.mismatch td { background: #FEF2F2; color: $danger; }
tr.mismatch td:first-child { color: $danger; }
}
}
.badge {
display: inline-block;
padding: .2rem .55rem;
border-radius: 12px;
font-size: .75rem;
font-weight: 700;
line-height: 1;
&.badge-select { background: #DBEAFE; color: $primary; }
&.badge-reject { background: #F3F4F6; color: $muted; }
&.badge-match { background: #DCFCE7; color: $success; }
&.badge-mismatch { background: #FEE2E2; color: $danger; }
&.badge-neutral { background: #FEF9C3; color: $warning; }
}
.neutral-row td { background: #FAFAF0; color: $warning; }
// ──────────────────────────────────────────
// Post Survey (Step 5)
// ──────────────────────────────────────────
.likert-group {
margin-bottom: 1.5rem;
.likert-q {
font-size: .9rem;
font-weight: 600;
color: $text;
margin-bottom: .75rem;
line-height: 1.5;
}
.likert-options {
display: flex;
gap: .5rem;
label {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
gap: .3rem;
cursor: pointer;
input[type="radio"] { display: none; }
.likert-btn {
width: 100%;
padding: .55rem .2rem;
border: 2px solid $border;
border-radius: $radius-sm;
text-align: center;
font-size: .9rem;
font-weight: 700;
color: $muted;
transition: all .15s;
background: $card-bg;
}
.likert-desc { font-size: .65rem; color: $muted; text-align: center; line-height: 1.2; }
input:checked + .likert-btn { border-color: $primary; background: rgba($primary,.08); color: $primary; }
&:hover .likert-btn { border-color: $primary; }
}
}
}
.open-textarea {
width: 100%;
padding: .8rem 1rem;
border: 1.5px solid $border;
border-radius: $radius-sm;
font-size: .875rem;
font-family: inherit;
resize: vertical;
min-height: 100px;
outline: none;
transition: border-color .2s;
&:focus { border-color: $primary; }
}
// ──────────────────────────────────────────
// Complete Screen
// ──────────────────────────────────────────
.complete-screen {
text-align: center;
padding: 2rem 1rem;
.complete-icon { font-size: 3.5rem; margin-bottom: 1rem; }
.complete-title { font-size: 1.5rem; font-weight: 800; margin-bottom: .5rem; }
.complete-desc { color: $muted; font-size: .9rem; margin-bottom: 2rem; line-height: 1.7; }
}
.json-output {
background: #1E293B;
color: #94A3B8;
border-radius: $radius-sm;
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: $border;
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: $primary;
font-weight: 700;
}
// ──────────────────────────────────────────
// Responsive
// ──────────────────────────────────────────
@media (max-width: 600px) {
#app-header { padding: 0 1rem; }
.header-title { font-size: .78rem; }
.card { padding: 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; }
.btn-row.judgment-btns { gap: .5rem; }
}
@media (max-width: 380px) {
.step-progress .step-dot .dot-circle { width: 22px; height: 22px; font-size: .65rem; }
}