Some checks are pending
ci / build (push) Waiting to run
Measured convergence before: split hero 13/19, top-bar nav 19/19, one-line notice footer 14/19, body Pretendard 17/21, 10 similarity pairs above 0.78. Each showcase got a pre-assigned hero family, nav form, footer form, type pair, background, accent hue, radius, motion grammar and material from outputs/rework-2026-10-06/plan.md; direction cards and the chosen reason are recorded in every design.md. After: 0 similarity warnings, 19 distinct display faces, 7 hero families, 5 nav forms, 5 footer forms, no scroll reveals, 5 showcases with SVG filter materials. Example contact values replace bracket placeholders under the existing fictional-brand notices. Thumbnails, OG images, card copy and three e2e assertions updated; dead CSS in dure-enrollment and hannam-jari removed; similarity.mjs learns the new font families.
1177 lines
25 KiB
CSS
1177 lines
25 KiB
CSS
/* ==========================================================================
|
||
RFS — 메인 스타일시트 (2026-10-06 재작업)
|
||
|
||
구조 원칙: 페이지는 밝은 쿨 바탕 한 체제다. 어두운 면은 캔버스 화면(.hero-stage) 하나뿐이고
|
||
그것은 띠가 아니라 계기판의 부품이다. 이전 판의 .band-dark/.band-light 토큰 재정의 규칙은
|
||
띠 교대 자체를 없앴으므로 같이 없앴다. 토큰은 tokens.css 한 곳에서만 정의한다.
|
||
========================================================================== */
|
||
|
||
/* Spoqa Han Sans Neo — OFL. jsdelivr 고정 버전 3.3.0, 한글 서브셋(Subset/) woff2.
|
||
쓰는 굵기는 400·700 두 종만 선언한다 — 패밀리 CSS 를 그대로 싣으면 5종이 선언되고
|
||
브라우저가 500·300 을 합성 대신 요청할 수 있다 */
|
||
@font-face {
|
||
font-family: "Spoqa Han Sans Neo";
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
src:
|
||
local("Spoqa Han Sans Neo Regular"),
|
||
url("https://cdn.jsdelivr.net/gh/spoqa/spoqa-han-sans@3.3.0/Subset/SpoqaHanSansNeo/SpoqaHanSansNeo-Regular.woff2") format("woff2");
|
||
}
|
||
|
||
@font-face {
|
||
font-family: "Spoqa Han Sans Neo";
|
||
font-weight: 700;
|
||
font-display: swap;
|
||
src:
|
||
local("Spoqa Han Sans Neo Bold"),
|
||
url("https://cdn.jsdelivr.net/gh/spoqa/spoqa-han-sans@3.3.0/Subset/SpoqaHanSansNeo/SpoqaHanSansNeo-Bold.woff2") format("woff2");
|
||
}
|
||
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
box-sizing: border-box;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
html {
|
||
font-size: 16px;
|
||
scroll-behavior: smooth;
|
||
overflow-x: hidden;
|
||
background: var(--surface);
|
||
font-synthesis-style: none;
|
||
-webkit-font-smoothing: antialiased;
|
||
-moz-osx-font-smoothing: grayscale;
|
||
}
|
||
|
||
body {
|
||
min-height: 100dvh;
|
||
font-family: var(--font-body);
|
||
font-size: var(--step-0);
|
||
line-height: var(--leading-normal);
|
||
background: var(--surface);
|
||
color: var(--ink);
|
||
word-break: keep-all;
|
||
overflow-wrap: anywhere;
|
||
line-break: strict;
|
||
overflow-x: hidden;
|
||
}
|
||
|
||
img,
|
||
picture,
|
||
canvas,
|
||
svg {
|
||
display: block;
|
||
max-width: 100%;
|
||
}
|
||
|
||
a {
|
||
color: inherit;
|
||
text-decoration: none;
|
||
text-underline-position: under;
|
||
}
|
||
|
||
button,
|
||
input,
|
||
select,
|
||
textarea {
|
||
font: inherit;
|
||
color: inherit;
|
||
}
|
||
|
||
em,
|
||
i,
|
||
cite {
|
||
font-style: normal;
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
h1,
|
||
h2,
|
||
h3 {
|
||
font-weight: var(--weight-strong);
|
||
line-height: var(--leading-tight);
|
||
letter-spacing: -0.01em;
|
||
text-wrap: balance;
|
||
}
|
||
|
||
strong {
|
||
font-weight: var(--weight-strong);
|
||
color: var(--ink);
|
||
}
|
||
|
||
.num {
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
.sr-only {
|
||
position: absolute;
|
||
width: 1px;
|
||
height: 1px;
|
||
padding: 0;
|
||
margin: -1px;
|
||
overflow: hidden;
|
||
clip-path: inset(50%);
|
||
white-space: nowrap;
|
||
border: 0;
|
||
}
|
||
|
||
.wrap {
|
||
width: min(100% - 2 * var(--pad-inline), var(--container));
|
||
margin-inline: auto;
|
||
}
|
||
|
||
/* ── 접근성 ─────────────────────────────────────────────────────── */
|
||
.skip-link {
|
||
position: fixed;
|
||
top: var(--space-3);
|
||
left: var(--space-3);
|
||
z-index: 200;
|
||
padding: var(--space-2) var(--space-3);
|
||
background: var(--ink);
|
||
color: var(--surface);
|
||
transform: translateY(-250%);
|
||
transition: transform var(--dur-quick) var(--ease);
|
||
}
|
||
|
||
.skip-link:focus-visible {
|
||
transform: translateY(0);
|
||
}
|
||
|
||
:where(a, button, input, [tabindex]):focus-visible {
|
||
outline: 2px solid var(--accent);
|
||
outline-offset: 3px;
|
||
}
|
||
|
||
/* ── 상단 바 — 고정하지 않는다. 페이지가 다섯 화면 남짓이라 늘 보일 이유가 없다 ── */
|
||
.site-head {
|
||
background: var(--surface);
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
|
||
.head-inner {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-3);
|
||
min-height: 56px;
|
||
min-width: 0;
|
||
}
|
||
|
||
.wordmark {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
flex-shrink: 0;
|
||
color: var(--ink);
|
||
}
|
||
|
||
.wordmark-mark {
|
||
display: block;
|
||
width: 28px;
|
||
color: var(--accent);
|
||
}
|
||
|
||
.wordmark-text {
|
||
font-weight: var(--weight-strong);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
|
||
.nav {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: clamp(var(--space-3), 2vw, var(--space-5));
|
||
min-width: 0;
|
||
}
|
||
|
||
.nav a {
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
white-space: nowrap;
|
||
padding: var(--space-2) var(--space-1);
|
||
transition: color var(--dur-quick) var(--ease);
|
||
}
|
||
|
||
.nav a:hover {
|
||
color: var(--ink);
|
||
}
|
||
|
||
.nav .nav-cta {
|
||
color: var(--accent);
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
/* ── 계기판 (히어로) ───────────────────────────────────────────── */
|
||
.hero-grid {
|
||
display: grid;
|
||
grid-template-columns: minmax(0, 1fr);
|
||
gap: var(--space-4);
|
||
padding-block: var(--space-4) var(--space-6);
|
||
}
|
||
|
||
.hero h1 {
|
||
font-size: var(--step-2);
|
||
max-width: 30em;
|
||
}
|
||
|
||
.hero-lead {
|
||
margin-top: var(--space-2);
|
||
max-width: var(--measure);
|
||
color: var(--ink-muted);
|
||
}
|
||
|
||
.hero-screen {
|
||
min-width: 0;
|
||
}
|
||
|
||
/* 캔버스 화면 — 페이지에서 유일한 어두운 면 */
|
||
.hero-stage {
|
||
position: relative;
|
||
width: 100%;
|
||
height: clamp(220px, 40dvh, 340px);
|
||
overflow: clip;
|
||
background: var(--screen);
|
||
border: 1px solid var(--screen-line);
|
||
}
|
||
|
||
#thermalField {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
opacity: 0;
|
||
transition: opacity var(--dur-slow) var(--ease);
|
||
}
|
||
|
||
[data-field-state="live"] #thermalField {
|
||
opacity: 1;
|
||
}
|
||
|
||
.hero-fallback {
|
||
position: absolute;
|
||
inset: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
object-position: 50% 46%;
|
||
opacity: 0.72;
|
||
mix-blend-mode: screen;
|
||
transition: opacity var(--dur-slow) var(--ease);
|
||
}
|
||
|
||
/* 캔버스가 실제로 돌기 시작하면 실물 렌더는 물러난다 — 둘이 겹치면 무엇이 실시간인지 알 수 없다 */
|
||
[data-field-state="live"] .hero-fallback {
|
||
opacity: 0;
|
||
}
|
||
|
||
.stage-grid {
|
||
position: absolute;
|
||
inset: 0;
|
||
background-image:
|
||
linear-gradient(to right, var(--screen-line) 1px, transparent 1px),
|
||
linear-gradient(to bottom, var(--screen-line) 1px, transparent 1px);
|
||
background-size: 64px 64px;
|
||
opacity: 0.4;
|
||
pointer-events: none;
|
||
}
|
||
|
||
/* 장비 형상 — 셰이더 상수와 같은 좌표. 랙 x 44%–56% · FWU x 3% 부터 */
|
||
.stage-solid {
|
||
position: absolute;
|
||
pointer-events: none;
|
||
border: 1px solid var(--screen-line);
|
||
}
|
||
|
||
.stage-rack {
|
||
left: 44%;
|
||
right: 44%;
|
||
bottom: 12%;
|
||
top: 38%;
|
||
background: repeating-linear-gradient(
|
||
to bottom,
|
||
color-mix(in srgb, var(--screen) 92%, transparent) 0 6px,
|
||
color-mix(in srgb, var(--screen-2) 92%, transparent) 6px 8px
|
||
);
|
||
}
|
||
|
||
.stage-fwu {
|
||
left: 3%;
|
||
width: 2.5%;
|
||
bottom: 10%;
|
||
height: 24%;
|
||
background: color-mix(in srgb, var(--screen-2) 88%, transparent);
|
||
border-right: 2px solid var(--screen-accent);
|
||
}
|
||
|
||
.stage-tag {
|
||
position: absolute;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
font-size: var(--step--1);
|
||
color: var(--screen-ink-muted);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.stage-tag span {
|
||
background: color-mix(in srgb, var(--screen) 82%, transparent);
|
||
padding: 2px var(--space-2);
|
||
border-left: 2px solid var(--screen-accent);
|
||
}
|
||
|
||
/* 캔버스가 돌기 전(loading·JS 없음)과 정지 상태(감소 모션·WebGL 없음)에서는 실물 렌더가 남는다.
|
||
2D 데모의 장비 좌표는 실물 렌더와 맞지 않으므로 형상·표식·격자를 live 상태에서만 보인다 —
|
||
그림과 라벨이 어긋나면 라벨이 거짓말이 된다 */
|
||
[data-field-shell]:not([data-field-state="live"]) .stage-solid,
|
||
[data-field-shell]:not([data-field-state="live"]) .stage-tag,
|
||
[data-field-shell]:not([data-field-state="live"]) .stage-grid {
|
||
display: none;
|
||
}
|
||
|
||
.stage-tag-fwu {
|
||
left: 5.5%;
|
||
bottom: 34%;
|
||
}
|
||
|
||
.stage-tag-rack {
|
||
left: 44%;
|
||
bottom: 62%;
|
||
}
|
||
|
||
.stage-foot {
|
||
display: grid;
|
||
gap: var(--space-2);
|
||
padding-top: var(--space-3);
|
||
}
|
||
|
||
.temp-key {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-3);
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
}
|
||
|
||
.temp-key span {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
.temp-key i {
|
||
width: 1.5rem;
|
||
height: 3px;
|
||
background: var(--temp-cold);
|
||
}
|
||
|
||
.temp-key .temp-mid {
|
||
background: var(--temp-mid);
|
||
}
|
||
|
||
.temp-key .temp-hot {
|
||
background: var(--temp-hot);
|
||
}
|
||
|
||
.hero-note {
|
||
max-width: var(--measure);
|
||
font-size: var(--step--1);
|
||
color: var(--ink-muted);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
/* 제어 패널 — 흰 면 하나에 장면·슬라이더·판독이 위아래로 쌓인다 */
|
||
.hero-panel {
|
||
display: grid;
|
||
grid-template-rows: auto auto 1fr;
|
||
background: var(--panel);
|
||
border: 1px solid var(--line);
|
||
min-width: 0;
|
||
}
|
||
|
||
.panel-block {
|
||
padding: var(--space-3) var(--space-4);
|
||
}
|
||
|
||
.panel-block + .panel-block {
|
||
border-top: 1px solid var(--line);
|
||
}
|
||
|
||
.panel-title {
|
||
font-size: var(--step--1);
|
||
color: var(--ink-faint);
|
||
margin-bottom: var(--space-2);
|
||
}
|
||
|
||
.scenario-btns {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||
}
|
||
|
||
.scenario-btn,
|
||
.vis-tab {
|
||
min-height: 44px;
|
||
padding-inline: var(--space-2);
|
||
border: 1px solid var(--line-strong);
|
||
background: transparent;
|
||
color: var(--ink-muted);
|
||
cursor: pointer;
|
||
font-size: var(--step--1);
|
||
transition:
|
||
color var(--dur-quick) var(--ease),
|
||
background-color var(--dur-quick) var(--ease),
|
||
border-color var(--dur-quick) var(--ease);
|
||
}
|
||
|
||
.scenario-btn + .scenario-btn,
|
||
.vis-tab + .vis-tab {
|
||
border-left: 0;
|
||
}
|
||
|
||
.scenario-btn:hover,
|
||
.vis-tab:hover {
|
||
color: var(--ink);
|
||
border-color: var(--accent);
|
||
}
|
||
|
||
.scenario-btn[aria-pressed="true"],
|
||
.vis-tab[aria-pressed="true"] {
|
||
color: var(--accent-ink);
|
||
background: var(--accent);
|
||
border-color: var(--accent);
|
||
}
|
||
|
||
.hero-controls {
|
||
display: grid;
|
||
gap: var(--space-3);
|
||
}
|
||
|
||
.ctl-head {
|
||
display: flex;
|
||
align-items: baseline;
|
||
justify-content: space-between;
|
||
gap: var(--space-3);
|
||
font-size: var(--step--1);
|
||
color: var(--ink-muted);
|
||
margin-bottom: var(--space-1);
|
||
}
|
||
|
||
.ctl-head output {
|
||
color: var(--ink);
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
input[type="range"] {
|
||
width: 100%;
|
||
min-height: 44px; /* 터치 타깃 — 트랙은 가늘지만 누르는 영역은 44px */
|
||
accent-color: var(--accent);
|
||
background: transparent;
|
||
}
|
||
|
||
.field-readout-state {
|
||
color: var(--ink);
|
||
}
|
||
|
||
.field-readout-grid {
|
||
display: grid;
|
||
gap: var(--space-2);
|
||
margin-top: var(--space-3);
|
||
padding-top: var(--space-3);
|
||
border-top: 1px solid var(--line);
|
||
}
|
||
|
||
.field-readout-grid > div {
|
||
display: grid;
|
||
grid-template-columns: 5.5rem minmax(0, 1fr);
|
||
gap: var(--space-2);
|
||
font-size: var(--step--1);
|
||
}
|
||
|
||
.field-readout-grid dt {
|
||
color: var(--ink-faint);
|
||
}
|
||
|
||
.field-readout-grid dd {
|
||
color: var(--ink-muted);
|
||
}
|
||
|
||
/* 900px 부터 계기판: 왼쪽 표제 + 캔버스, 오른쪽 제어 패널 */
|
||
@media (min-width: 900px) {
|
||
.hero-grid {
|
||
grid-template-columns: minmax(0, 1fr) var(--panel-width);
|
||
grid-template-rows: auto auto;
|
||
column-gap: var(--space-5);
|
||
row-gap: var(--space-3);
|
||
align-items: start;
|
||
padding-block: var(--space-5) var(--space-6);
|
||
}
|
||
|
||
.hero-copy {
|
||
grid-column: 1;
|
||
grid-row: 1;
|
||
}
|
||
|
||
.hero-screen {
|
||
grid-column: 1;
|
||
grid-row: 2;
|
||
}
|
||
|
||
.hero-panel {
|
||
grid-column: 2;
|
||
grid-row: 1 / span 2;
|
||
align-self: stretch; /* 패널 바닥이 캔버스 바닥과 같은 선에 닿는다 */
|
||
}
|
||
|
||
.hero-note {
|
||
grid-column: 1;
|
||
grid-row: 3;
|
||
}
|
||
|
||
.hero-stage {
|
||
height: clamp(26rem, 54vh, 34rem);
|
||
}
|
||
}
|
||
|
||
/* ── 섹션 공통 — 한 체제. 섹션 사이는 선 하나와 간격으로만 나눈다 ── */
|
||
.section {
|
||
border-top: 1px solid var(--line);
|
||
}
|
||
|
||
.section > .wrap {
|
||
padding-block: var(--space-8);
|
||
}
|
||
|
||
.section h2 {
|
||
font-size: var(--step-2);
|
||
max-width: 24em;
|
||
}
|
||
|
||
.sub-heading {
|
||
font-size: var(--step-1);
|
||
max-width: 24em;
|
||
}
|
||
|
||
.section-lead,
|
||
.split-note {
|
||
margin-top: var(--space-3);
|
||
max-width: var(--measure);
|
||
color: var(--ink-muted);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
.section-lead {
|
||
font-size: var(--step-1);
|
||
}
|
||
|
||
/* 초광폭에서는 정보 표면만 넓힌다. 읽는 글의 폭은 각 블록의 max-width 가 계속 제어한다 */
|
||
@media (min-width: 120rem) {
|
||
.wrap {
|
||
width: min(100% - 2 * var(--pad-inline), var(--container-wide));
|
||
}
|
||
}
|
||
|
||
/* ── 레이아웃 패밀리 A · 비대칭 2열 ─────────────────────────────── */
|
||
.split {
|
||
display: grid;
|
||
gap: var(--space-5);
|
||
}
|
||
|
||
@media (min-width: 900px) {
|
||
.split {
|
||
grid-template-columns: 5fr 7fr;
|
||
gap: var(--space-7);
|
||
align-items: start;
|
||
}
|
||
}
|
||
|
||
.split-body > * + * {
|
||
margin-top: var(--space-4);
|
||
}
|
||
|
||
.split-body p {
|
||
max-width: var(--measure);
|
||
color: var(--ink-muted);
|
||
}
|
||
|
||
/* ── 레이아웃 패밀리 B · 대조 목록 ──────────────────────────────── */
|
||
.contrast {
|
||
margin-top: var(--space-5);
|
||
border-top: 1px solid var(--line-strong);
|
||
}
|
||
|
||
.contrast > div {
|
||
display: grid;
|
||
gap: var(--space-1) var(--space-4);
|
||
padding-block: var(--space-3);
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
|
||
@media (min-width: 640px) {
|
||
.contrast > div {
|
||
grid-template-columns: 11rem 1fr;
|
||
}
|
||
}
|
||
|
||
.contrast dt {
|
||
font-weight: var(--weight-strong);
|
||
color: var(--ink);
|
||
}
|
||
|
||
.contrast dd {
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
.contrast > div:last-child dt {
|
||
color: var(--accent);
|
||
}
|
||
|
||
/* ── 레이아웃 패밀리 C · 사양 원장 (행 문법) ────────────────────── */
|
||
.spec-ledger {
|
||
margin-top: var(--space-5);
|
||
list-style: none;
|
||
border-top: 1px solid var(--line-strong);
|
||
}
|
||
|
||
.spec-ledger li {
|
||
display: grid;
|
||
gap: var(--space-1) var(--space-4);
|
||
padding-block: var(--space-3);
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
|
||
@media (min-width: 720px) {
|
||
.spec-ledger li {
|
||
grid-template-columns: 9rem 14rem 1fr;
|
||
align-items: baseline;
|
||
}
|
||
}
|
||
|
||
.spec-name {
|
||
color: var(--ink-faint);
|
||
font-size: var(--step--1);
|
||
}
|
||
|
||
.spec-value {
|
||
color: var(--ink);
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
.spec-note {
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
/* ── 레이아웃 패밀리 D · 계층 ──────────────────────────────────── */
|
||
.spec-ledger + .sub-heading {
|
||
margin-top: var(--space-6);
|
||
}
|
||
|
||
.layers {
|
||
margin-top: var(--space-4);
|
||
list-style: none;
|
||
border: 1px solid var(--line-strong);
|
||
background: var(--panel);
|
||
}
|
||
|
||
.layers li {
|
||
display: grid;
|
||
gap: var(--space-1) var(--space-4);
|
||
padding: var(--space-3) var(--space-4);
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
|
||
.layers li:last-child {
|
||
border-bottom: 0;
|
||
}
|
||
|
||
@media (min-width: 760px) {
|
||
.layers li {
|
||
grid-template-columns: 3rem 13rem 1fr;
|
||
align-items: baseline;
|
||
}
|
||
}
|
||
|
||
/* 아래로 갈수록 물리 계층에 가까워진다는 것을 면의 농도로 말한다 */
|
||
.layers li:nth-child(2) { background: color-mix(in srgb, var(--surface-2) 25%, transparent); }
|
||
.layers li:nth-child(3) { background: color-mix(in srgb, var(--surface-2) 50%, transparent); }
|
||
.layers li:nth-child(4) { background: color-mix(in srgb, var(--surface-2) 75%, transparent); }
|
||
.layers li:nth-child(5) { background: var(--surface-2); }
|
||
|
||
.layer-id {
|
||
color: var(--accent);
|
||
font-size: var(--step--1);
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
.layer-name {
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
.layer-body {
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
/* ── 레이아웃 패밀리 E · 장비 목록 ─────────────────────────────── */
|
||
.equip-list {
|
||
margin-top: var(--space-5);
|
||
display: grid;
|
||
gap: var(--space-4);
|
||
border-top: 1px solid var(--line-strong);
|
||
padding-top: var(--space-4);
|
||
}
|
||
|
||
@media (min-width: 760px) {
|
||
.equip-list {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
column-gap: var(--space-7);
|
||
}
|
||
|
||
/* 다섯 개다. 마지막 하나가 홀로 남으므로 두 칸을 쓰게 한다 */
|
||
.equip-list article:last-child {
|
||
grid-column: 1 / -1;
|
||
border-top: 1px solid var(--line);
|
||
padding-top: var(--space-4);
|
||
}
|
||
}
|
||
|
||
.equip-list h3 {
|
||
font-size: var(--step-1);
|
||
display: flex;
|
||
align-items: baseline;
|
||
gap: var(--space-2);
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.equip-list p {
|
||
margin-top: var(--space-2);
|
||
color: var(--ink-muted);
|
||
max-width: 30em;
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
.tag {
|
||
font-size: var(--step--1);
|
||
font-weight: 400;
|
||
color: var(--accent);
|
||
border: 1px solid var(--line-strong);
|
||
padding: 1px var(--space-2);
|
||
}
|
||
|
||
.editor {
|
||
margin-top: var(--space-6);
|
||
padding-top: var(--space-5);
|
||
border-top: 1px solid var(--line-strong);
|
||
}
|
||
|
||
/* ── 기능 행 ────────────────────────────────────────────────────── */
|
||
.feature-rows {
|
||
border-top: 1px solid var(--line);
|
||
}
|
||
|
||
.feature-rows > div {
|
||
display: grid;
|
||
gap: var(--space-1) var(--space-4);
|
||
padding-block: var(--space-3);
|
||
border-bottom: 1px solid var(--line);
|
||
}
|
||
|
||
@media (min-width: 640px) {
|
||
.feature-rows > div {
|
||
grid-template-columns: 9rem 1fr;
|
||
}
|
||
}
|
||
|
||
.feature-rows dt {
|
||
font-weight: var(--weight-strong);
|
||
}
|
||
|
||
.feature-rows dd {
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
.keys {
|
||
margin-top: var(--space-4);
|
||
padding: var(--space-3) var(--space-4);
|
||
background: var(--panel);
|
||
border: 1px solid var(--line);
|
||
}
|
||
|
||
.keys-title {
|
||
font-size: var(--step--1);
|
||
color: var(--ink-faint);
|
||
margin-bottom: var(--space-2);
|
||
}
|
||
|
||
.keys ul {
|
||
list-style: none;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: var(--space-2) var(--space-4);
|
||
font-size: var(--step--1);
|
||
color: var(--ink-muted);
|
||
}
|
||
|
||
.keys li {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
kbd {
|
||
font-family: inherit;
|
||
font-variant-numeric: tabular-nums;
|
||
font-size: var(--step--1);
|
||
padding: 1px 6px;
|
||
background: var(--surface);
|
||
border: 1px solid var(--line-strong);
|
||
border-bottom-width: 2px;
|
||
color: var(--ink);
|
||
}
|
||
|
||
kbd + kbd {
|
||
margin-left: 2px;
|
||
}
|
||
|
||
/* ── 레이아웃 패밀리 F · 시각화 (목록 + 실물) ──────────────────── */
|
||
.vis-layout {
|
||
margin-top: var(--space-5);
|
||
display: grid;
|
||
gap: var(--space-5);
|
||
}
|
||
|
||
@media (min-width: 960px) {
|
||
.vis-layout {
|
||
grid-template-columns: 6fr 5fr;
|
||
gap: var(--space-7);
|
||
align-items: start;
|
||
}
|
||
}
|
||
|
||
.vis-list {
|
||
list-style: none;
|
||
counter-reset: vis;
|
||
border-top: 1px solid var(--line-strong);
|
||
}
|
||
|
||
.vis-list li {
|
||
counter-increment: vis;
|
||
padding-block: var(--space-4);
|
||
border-bottom: 1px solid var(--line);
|
||
display: grid;
|
||
grid-template-columns: 2.5rem 1fr;
|
||
gap: var(--space-2) var(--space-3);
|
||
}
|
||
|
||
.vis-list li::before {
|
||
content: counter(vis, decimal-leading-zero);
|
||
font-variant-numeric: tabular-nums;
|
||
font-size: var(--step--1);
|
||
color: var(--accent);
|
||
font-weight: var(--weight-strong);
|
||
grid-row: 1 / span 2;
|
||
padding-top: 0.35em;
|
||
}
|
||
|
||
.vis-list h3 {
|
||
font-size: var(--step-1);
|
||
}
|
||
|
||
.vis-list p {
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
line-height: var(--leading-loose);
|
||
grid-column: 2;
|
||
}
|
||
|
||
.vis-shots {
|
||
display: grid;
|
||
gap: var(--space-3);
|
||
min-width: 0;
|
||
}
|
||
|
||
.vis-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
gap: var(--space-3);
|
||
}
|
||
|
||
.vis-tabs {
|
||
display: flex;
|
||
}
|
||
|
||
.vis-tab {
|
||
min-width: 4.5rem;
|
||
}
|
||
|
||
.vis-source {
|
||
color: var(--ink-faint);
|
||
font-size: var(--step--1);
|
||
text-align: right;
|
||
}
|
||
|
||
.vis-frame {
|
||
min-width: 0;
|
||
}
|
||
|
||
/* 실물 렌더는 어두운 바탕의 그림이다 — 캔버스 화면과 같은 면 위에 싣는다 */
|
||
.vis-shots figure {
|
||
display: grid;
|
||
grid-template-rows: minmax(0, 1fr) auto;
|
||
border: 1px solid var(--screen-line);
|
||
background: var(--screen);
|
||
min-height: clamp(320px, 42vw, 520px);
|
||
}
|
||
|
||
.vis-shots figure[hidden] {
|
||
display: none;
|
||
}
|
||
|
||
.vis-shots img {
|
||
width: 100%;
|
||
height: 100%;
|
||
min-height: 0;
|
||
object-fit: contain;
|
||
}
|
||
|
||
.vis-shots figcaption {
|
||
padding: var(--space-2) var(--space-3);
|
||
border-top: 1px solid var(--screen-line);
|
||
font-size: var(--step--1);
|
||
color: var(--screen-ink-muted);
|
||
}
|
||
|
||
.shots-note {
|
||
font-size: var(--step--1);
|
||
color: var(--ink-faint);
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
/* ── 요구사양 표 ────────────────────────────────────────────────── */
|
||
.req {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
font-size: var(--step--1);
|
||
background: var(--panel);
|
||
border: 1px solid var(--line);
|
||
}
|
||
|
||
.req caption {
|
||
text-align: left;
|
||
}
|
||
|
||
.req th,
|
||
.req td {
|
||
text-align: left;
|
||
padding: var(--space-3);
|
||
border-bottom: 1px solid var(--line);
|
||
vertical-align: top;
|
||
}
|
||
|
||
.req thead th {
|
||
color: var(--ink-faint);
|
||
font-weight: 400;
|
||
border-bottom: 1px solid var(--line-strong);
|
||
}
|
||
|
||
.req tbody th {
|
||
font-weight: var(--weight-strong);
|
||
width: 7rem;
|
||
}
|
||
|
||
.req td {
|
||
color: var(--ink-muted);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* ── CTA ────────────────────────────────────────────────────────── */
|
||
.adopt-cta {
|
||
margin-top: var(--space-5);
|
||
padding-top: var(--space-4);
|
||
border-top: 1px solid var(--line-strong);
|
||
}
|
||
|
||
.btn {
|
||
display: inline-block;
|
||
margin-top: var(--space-4);
|
||
padding: var(--space-3) var(--space-5);
|
||
background: var(--accent);
|
||
color: var(--accent-ink);
|
||
font-weight: var(--weight-strong);
|
||
white-space: nowrap;
|
||
border: 1px solid var(--accent);
|
||
transition: background-color var(--dur-quick) var(--ease);
|
||
}
|
||
|
||
.btn:hover {
|
||
background: var(--accent-hover);
|
||
border-color: var(--accent-hover);
|
||
color: var(--accent-ink);
|
||
}
|
||
|
||
/* ── 다열 색인 푸터 ─────────────────────────────────────────────── */
|
||
.site-foot {
|
||
border-top: 1px solid var(--line-strong);
|
||
background: var(--surface-2);
|
||
}
|
||
|
||
.foot-grid {
|
||
display: grid;
|
||
gap: var(--space-5) var(--space-6);
|
||
padding-block: var(--space-6) var(--space-5);
|
||
}
|
||
|
||
@media (min-width: 640px) {
|
||
.foot-grid {
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
}
|
||
}
|
||
|
||
@media (min-width: 960px) {
|
||
.foot-grid {
|
||
grid-template-columns: 1.4fr 1fr 1fr 1fr;
|
||
}
|
||
}
|
||
|
||
.foot-col ul {
|
||
list-style: none;
|
||
display: grid;
|
||
gap: var(--space-1);
|
||
font-size: var(--step--1);
|
||
color: var(--ink-muted);
|
||
}
|
||
|
||
.foot-col a {
|
||
color: var(--ink-muted);
|
||
padding-block: 4px;
|
||
display: inline-block;
|
||
}
|
||
|
||
.foot-col a:hover {
|
||
color: var(--accent);
|
||
text-decoration: underline;
|
||
}
|
||
|
||
.foot-head {
|
||
font-size: var(--step--1);
|
||
color: var(--ink);
|
||
font-weight: var(--weight-strong);
|
||
margin-bottom: var(--space-2);
|
||
}
|
||
|
||
.foot-name {
|
||
font-weight: var(--weight-strong);
|
||
letter-spacing: 0.04em;
|
||
}
|
||
|
||
.foot-line {
|
||
margin-top: var(--space-2);
|
||
color: var(--ink-muted);
|
||
font-size: var(--step--1);
|
||
max-width: 24em;
|
||
line-height: var(--leading-loose);
|
||
}
|
||
|
||
.foot-facts {
|
||
display: grid;
|
||
gap: var(--space-1);
|
||
font-size: var(--step--1);
|
||
}
|
||
|
||
.foot-facts > div {
|
||
display: grid;
|
||
grid-template-columns: 4.5rem 1fr;
|
||
gap: var(--space-2);
|
||
}
|
||
|
||
.foot-facts dt {
|
||
color: var(--ink-faint);
|
||
}
|
||
|
||
.foot-facts dd {
|
||
color: var(--ink-muted);
|
||
}
|
||
|
||
.foot-fine {
|
||
padding-bottom: var(--space-5);
|
||
}
|
||
|
||
.foot-fine p {
|
||
padding-top: var(--space-3);
|
||
border-top: 1px solid var(--line);
|
||
font-size: var(--step--1);
|
||
color: var(--ink-faint);
|
||
line-height: var(--leading-loose);
|
||
max-width: 44em;
|
||
}
|
||
|
||
/* ── 좁은 화면 ──────────────────────────────────────────────────── */
|
||
@media (max-width: 640px) {
|
||
.head-inner {
|
||
flex-wrap: wrap;
|
||
padding-block: var(--space-2);
|
||
row-gap: var(--space-2);
|
||
}
|
||
|
||
.nav {
|
||
order: 3;
|
||
width: 100%;
|
||
justify-content: space-between;
|
||
gap: var(--space-2);
|
||
border-top: 1px solid var(--line);
|
||
padding-top: var(--space-2);
|
||
}
|
||
|
||
.stage-tag {
|
||
font-size: 0.6875rem;
|
||
}
|
||
|
||
.panel-block {
|
||
padding-inline: var(--space-3);
|
||
}
|
||
|
||
.req th,
|
||
.req td {
|
||
padding-inline: var(--space-2);
|
||
}
|
||
|
||
.vis-shots figure {
|
||
min-height: 300px;
|
||
}
|
||
}
|
||
|
||
/* ── 모션을 줄이는 설정 — 캔버스는 스크립트가 정지시키고 실물 렌더가 남는다 ── */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
html {
|
||
scroll-behavior: auto;
|
||
}
|
||
|
||
*,
|
||
*::before,
|
||
*::after {
|
||
animation-duration: 0.01ms !important;
|
||
animation-iteration-count: 1 !important;
|
||
transition-duration: 0.01ms !important;
|
||
}
|
||
}
|
||
|
||
/* ── 인쇄 ───────────────────────────────────────────────────────── */
|
||
@media print {
|
||
.site-head,
|
||
.hero-stage,
|
||
.hero-panel,
|
||
.skip-link {
|
||
display: none;
|
||
}
|
||
|
||
.section > .wrap {
|
||
padding-block: var(--space-4);
|
||
}
|
||
}
|