편집 요약 없음 |
편집 요약 없음 |
||
| 1번째 줄: | 1번째 줄: | ||
/* ========================================= | /* ========================================= | ||
COASTLINE: BLACK ICE - | COASTLINE: BLACK ICE - MainPage | ||
대문 | 대문 전용 스타일 | ||
========================================= */ | ========================================= */ | ||
| 7번째 줄: | 7번째 줄: | ||
설계 목적 | 설계 목적 | ||
----------------------------------------- | ----------------------------------------- | ||
이 파일은 대문 | 이 파일은 대문 전용 화면 구성만 담당한다. | ||
이전 테스트 단계에서는 MediaWiki:Test.css 안에 | |||
대문 레이아웃, 이미지 피드, 방명록 더미, 스타일 매뉴얼, | |||
카테고리 네비 실험 코드가 모두 섞여 있었다. | |||
그 상태로 실사용에 넣으면 다음 문제가 생긴다. | |||
1. 어느 코드가 대문 전용인지, 어느 코드가 공통 컴포넌트인지 구분하기 어렵다. | |||
2. 일반 문서 네비바나 사이드바를 고칠 때 대문 코드가 같이 영향을 받을 수 있다. | |||
3. 테스트용 더미와 실제 운영 UI가 같은 파일에 남아 유지보수가 어려워진다. | |||
따라서 이 파일은 대문 본문 안에서 쓰는 | |||
.main-portal 스코프 내부만 담당한다. | |||
따라서 | |||
주의: | |||
- body, .liberty-content, .content-wrapper 같은 전역 레이아웃은 건드리지 않는다. | |||
- 상단 공통 네비바, 좌우 사이드바, 관리자 패널은 이 파일의 책임이 아니다. | |||
- 카테고리 네비는 JS가 SVG DOM을 생성하고, 이 파일은 그 결과물의 시각 스타일만 담당한다. | |||
- 버튼 폭, 사선 좌표, 프로젝트 폭은 CSS가 아니라 CategoryNav.js가 계산한다. | |||
*/ | */ | ||
/* ----------------------------------------- | |||
0. Main portal scope | |||
----------------------------------------- */ | |||
.main-portal { | |||
--surface-page:#070707; | |||
--surface-frame:#101010; | |||
--surface-frame-soft:#141414; | |||
--surface-title:#1d1d1d; | |||
--surface-title-hover:#252525; | |||
--surface-well:#080808; | |||
--edge-top:#555555; | |||
--edge-side:#2b2b2b; | |||
--edge-bottom:#050505; | |||
--edge-soft:#202020; | |||
--text-main:#e2e2e2; | |||
--text-soft:#c8c8c8; | |||
--text-dim:#8a8a8a; | |||
--text-faint:#626262; | |||
--space-block:8px; | |||
--space-inner:6px; | |||
--pad-panel:8px; | |||
--nav-h:30px; | |||
width:100%; | |||
margin:0 auto; | |||
padding:var(--space-block); | |||
box-sizing:border-box; | |||
background:var(--surface-page); | |||
color:var(--text-main); | |||
font-size:11px; | |||
line-height:1.5; | |||
} | |||
.main-portal *, | |||
.main-portal *::before, | |||
.main-portal *::after { | |||
box-sizing:border-box; | |||
} | |||
.main-portal a { | |||
color:var(--text-main) !important; | |||
text-decoration:none !important; | |||
} | |||
.main-portal a:hover { | |||
color:#ffffff !important; | |||
text-decoration:none !important; | |||
} | |||
/* ----------------------------------------- | |||
1. Category nav mount | |||
----------------------------------------- */ | |||
/* | |||
[data-component="category-nav"]는 본문에 남겨두는 자리 표시자다. | |||
본문에 위키문법으로 링크를 직접 조립하면, | |||
MediaWiki가 생성한 <a>와 바깥 span이 분리된다. | |||
그 상태에서는 실제 클릭 영역, 호버 영역, 사선 모양이 서로 어긋난다. | |||
따라서 본문에는 비어 있는 mount만 두고, | |||
CategoryNav.js가 실제 SVG 네비를 생성한다. | |||
*/ | |||
.main-portal [data-component="category-nav"] { | |||
display:block; | |||
width:100%; | |||
margin:0 0 var(--space-block); | |||
} | |||
/* ----------------------------------------- | |||
2. Category navigation - SVG version | |||
----------------------------------------- */ | |||
/* | |||
왜 SVG로 바꿨는가 | |||
----------------------------------------- | |||
CSS 박스 기반 구현에서는 계속 같은 문제가 생겼다. | |||
1. clip-path를 span에 걸면 MediaWiki가 생성한 <a>와 | |||
시각적 버튼이 분리된다. | |||
2. ::after로 검은 획을 만들면 clip-path가 획까지 잘라먹는다. | |||
3. 획과 호버를 별도 overlay로 만들면 좌표가 다시 어긋난다. | |||
4. 음수 margin으로 버튼을 겹치면 호버가 옆 칸으로 넘어간다. | |||
SVG 방식에서는 각 항목이 실제 polygon이다. | |||
즉, | |||
- 보이는 면 | |||
- 호버되는 면 | |||
- 클릭되는 면 | |||
- 검은 구분 획 | |||
이 모두가 같은 SVG 좌표계 안에서 처리된다. | |||
CSS의 책임 | |||
----------------------------------------- | |||
이 파일은 색상, 호버, 텍스트 스타일, 외곽 표면만 담당한다. | |||
버튼 폭과 사선 좌표는 CategoryNav.js가 계산한다. | |||
따라서 이 파일에는 --cat-cell-w, --cat-cell-2, --cat-cell-3 같은 | |||
좌표성 변수를 두지 않는다. | |||
*/ | |||
.portal-category-nav { | |||
position:relative; | |||
width:100%; | |||
height:var(--nav-h); | |||
margin:0; | |||
padding:0; | |||
overflow:hidden; | |||
background:var(--surface-frame-soft); | |||
border:1px solid; | |||
border-color: | |||
var(--edge-top) | |||
var(--edge-side) | |||
var(--edge-bottom) | |||
var(--edge-side); | |||
box-shadow: | |||
inset 0 1px 0 rgba(255,255,255,0.055), | |||
inset 0 -1px 0 rgba(0,0,0,0.72); | |||
} | |||
/* | |||
SVG는 JS가 현재 nav 폭을 읽어서 viewBox를 계산한다. | |||
CSS는 svg의 표시 크기만 지정한다. | |||
*/ | |||
.portal-category-svg { | |||
display:block; | |||
width:100%; | |||
height:100%; | |||
} | |||
/* | |||
각 항목의 polygon은 기본적으로 투명하다. | |||
표면은 부모 .portal-category-nav가 담당한다. | |||
호버 시에만 아주 약한 밝기 레이어를 polygon에 입힌다. | |||
이렇게 해야 독립 버튼 외장처럼 보이지 않는다. | |||
*/ | |||
.portal-cat-shape { | |||
fill:transparent; | |||
stroke:none; | |||
pointer-events:all; | |||
} | |||
.portal-cat-anchor:hover .portal-cat-shape { | |||
fill:rgba(255,255,255,0.035); | |||
} | |||
.portal-cat-anchor:active .portal-cat-shape { | |||
fill:rgba(0,0,0,0.20); | |||
} | |||
/* | |||
텍스트는 SVG 내부 text로 렌더링된다. | |||
SVG text에는 일반 CSS text-shadow가 브라우저에 따라 안정적으로 먹지 않을 수 있다. | |||
그래서 CategoryNav.js에서 fill, stroke, stroke-width, paint-order를 직접 넣는다. | |||
여기서는 hover 색상과 기본 클래스 스타일을 보조한다. | |||
*/ | |||
.portal-cat-label { | |||
fill:var(--text-main); | |||
font-size:10px; | |||
font-weight:700; | |||
font-family:inherit; | |||
text-anchor:middle; | |||
dominant-baseline:middle; | |||
pointer-events:none; | |||
paint-order:stroke; | |||
stroke:#000000; | |||
stroke-width:2px; | |||
stroke-linejoin:round; | |||
} | |||
.portal-cat-anchor:hover .portal-cat-label { | |||
fill:#ffffff; | |||
} | |||
.portal-cat-project-label { | |||
font-size:11px; | |||
letter-spacing:0.2px; | |||
} | |||
/* | |||
검은 획은 SVG line이다. | |||
polygon 안에 넣지 않고, 같은 svg 좌표계 안의 별도 line으로 그린다. | |||
이전 CSS 방식의 실패: | |||
- 버튼 내부 ::after는 clip-path에 잘렸다. | |||
- absolute overlay는 CSS grid 좌표와 프로젝트 가변폭 때문에 어긋났다. | |||
SVG line은 polygon 좌표와 같은 값으로 생성되므로, | |||
사선 면과 획이 같은 기준을 사용한다. | |||
*/ | |||
.portal-cat-divider { | |||
stroke:#050505; | |||
stroke-width:1; | |||
shape-rendering:crispEdges; | |||
vector-effect:non-scaling-stroke; | |||
pointer-events:none; | |||
} | |||
/* | |||
좁은 화면에서는 SVG 사선 네비가 과밀해질 수 있다. | |||
현재는 JS가 폭에 맞춰 각 칸을 줄인다. | |||
모바일 전용 대문이 필요해지면 여기서 별도 compact nav로 분기한다. | |||
*/ | |||
2026년 5월 19일 (화) 08:14 판
/* =========================================
COASTLINE: BLACK ICE - MainPage
대문 전용 스타일
========================================= */
/*
설계 목적
-----------------------------------------
이 파일은 대문 전용 화면 구성만 담당한다.
이전 테스트 단계에서는 MediaWiki:Test.css 안에
대문 레이아웃, 이미지 피드, 방명록 더미, 스타일 매뉴얼,
카테고리 네비 실험 코드가 모두 섞여 있었다.
그 상태로 실사용에 넣으면 다음 문제가 생긴다.
1. 어느 코드가 대문 전용인지, 어느 코드가 공통 컴포넌트인지 구분하기 어렵다.
2. 일반 문서 네비바나 사이드바를 고칠 때 대문 코드가 같이 영향을 받을 수 있다.
3. 테스트용 더미와 실제 운영 UI가 같은 파일에 남아 유지보수가 어려워진다.
따라서 이 파일은 대문 본문 안에서 쓰는
.main-portal 스코프 내부만 담당한다.
주의:
- body, .liberty-content, .content-wrapper 같은 전역 레이아웃은 건드리지 않는다.
- 상단 공통 네비바, 좌우 사이드바, 관리자 패널은 이 파일의 책임이 아니다.
- 카테고리 네비는 JS가 SVG DOM을 생성하고, 이 파일은 그 결과물의 시각 스타일만 담당한다.
- 버튼 폭, 사선 좌표, 프로젝트 폭은 CSS가 아니라 CategoryNav.js가 계산한다.
*/
/* -----------------------------------------
0. Main portal scope
----------------------------------------- */
.main-portal {
--surface-page:#070707;
--surface-frame:#101010;
--surface-frame-soft:#141414;
--surface-title:#1d1d1d;
--surface-title-hover:#252525;
--surface-well:#080808;
--edge-top:#555555;
--edge-side:#2b2b2b;
--edge-bottom:#050505;
--edge-soft:#202020;
--text-main:#e2e2e2;
--text-soft:#c8c8c8;
--text-dim:#8a8a8a;
--text-faint:#626262;
--space-block:8px;
--space-inner:6px;
--pad-panel:8px;
--nav-h:30px;
width:100%;
margin:0 auto;
padding:var(--space-block);
box-sizing:border-box;
background:var(--surface-page);
color:var(--text-main);
font-size:11px;
line-height:1.5;
}
.main-portal *,
.main-portal *::before,
.main-portal *::after {
box-sizing:border-box;
}
.main-portal a {
color:var(--text-main) !important;
text-decoration:none !important;
}
.main-portal a:hover {
color:#ffffff !important;
text-decoration:none !important;
}
/* -----------------------------------------
1. Category nav mount
----------------------------------------- */
/*
[data-component="category-nav"]는 본문에 남겨두는 자리 표시자다.
본문에 위키문법으로 링크를 직접 조립하면,
MediaWiki가 생성한 <a>와 바깥 span이 분리된다.
그 상태에서는 실제 클릭 영역, 호버 영역, 사선 모양이 서로 어긋난다.
따라서 본문에는 비어 있는 mount만 두고,
CategoryNav.js가 실제 SVG 네비를 생성한다.
*/
.main-portal [data-component="category-nav"] {
display:block;
width:100%;
margin:0 0 var(--space-block);
}
/* -----------------------------------------
2. Category navigation - SVG version
----------------------------------------- */
/*
왜 SVG로 바꿨는가
-----------------------------------------
CSS 박스 기반 구현에서는 계속 같은 문제가 생겼다.
1. clip-path를 span에 걸면 MediaWiki가 생성한 <a>와
시각적 버튼이 분리된다.
2. ::after로 검은 획을 만들면 clip-path가 획까지 잘라먹는다.
3. 획과 호버를 별도 overlay로 만들면 좌표가 다시 어긋난다.
4. 음수 margin으로 버튼을 겹치면 호버가 옆 칸으로 넘어간다.
SVG 방식에서는 각 항목이 실제 polygon이다.
즉,
- 보이는 면
- 호버되는 면
- 클릭되는 면
- 검은 구분 획
이 모두가 같은 SVG 좌표계 안에서 처리된다.
CSS의 책임
-----------------------------------------
이 파일은 색상, 호버, 텍스트 스타일, 외곽 표면만 담당한다.
버튼 폭과 사선 좌표는 CategoryNav.js가 계산한다.
따라서 이 파일에는 --cat-cell-w, --cat-cell-2, --cat-cell-3 같은
좌표성 변수를 두지 않는다.
*/
.portal-category-nav {
position:relative;
width:100%;
height:var(--nav-h);
margin:0;
padding:0;
overflow:hidden;
background:var(--surface-frame-soft);
border:1px solid;
border-color:
var(--edge-top)
var(--edge-side)
var(--edge-bottom)
var(--edge-side);
box-shadow:
inset 0 1px 0 rgba(255,255,255,0.055),
inset 0 -1px 0 rgba(0,0,0,0.72);
}
/*
SVG는 JS가 현재 nav 폭을 읽어서 viewBox를 계산한다.
CSS는 svg의 표시 크기만 지정한다.
*/
.portal-category-svg {
display:block;
width:100%;
height:100%;
}
/*
각 항목의 polygon은 기본적으로 투명하다.
표면은 부모 .portal-category-nav가 담당한다.
호버 시에만 아주 약한 밝기 레이어를 polygon에 입힌다.
이렇게 해야 독립 버튼 외장처럼 보이지 않는다.
*/
.portal-cat-shape {
fill:transparent;
stroke:none;
pointer-events:all;
}
.portal-cat-anchor:hover .portal-cat-shape {
fill:rgba(255,255,255,0.035);
}
.portal-cat-anchor:active .portal-cat-shape {
fill:rgba(0,0,0,0.20);
}
/*
텍스트는 SVG 내부 text로 렌더링된다.
SVG text에는 일반 CSS text-shadow가 브라우저에 따라 안정적으로 먹지 않을 수 있다.
그래서 CategoryNav.js에서 fill, stroke, stroke-width, paint-order를 직접 넣는다.
여기서는 hover 색상과 기본 클래스 스타일을 보조한다.
*/
.portal-cat-label {
fill:var(--text-main);
font-size:10px;
font-weight:700;
font-family:inherit;
text-anchor:middle;
dominant-baseline:middle;
pointer-events:none;
paint-order:stroke;
stroke:#000000;
stroke-width:2px;
stroke-linejoin:round;
}
.portal-cat-anchor:hover .portal-cat-label {
fill:#ffffff;
}
.portal-cat-project-label {
font-size:11px;
letter-spacing:0.2px;
}
/*
검은 획은 SVG line이다.
polygon 안에 넣지 않고, 같은 svg 좌표계 안의 별도 line으로 그린다.
이전 CSS 방식의 실패:
- 버튼 내부 ::after는 clip-path에 잘렸다.
- absolute overlay는 CSS grid 좌표와 프로젝트 가변폭 때문에 어긋났다.
SVG line은 polygon 좌표와 같은 값으로 생성되므로,
사선 면과 획이 같은 기준을 사용한다.
*/
.portal-cat-divider {
stroke:#050505;
stroke-width:1;
shape-rendering:crispEdges;
vector-effect:non-scaling-stroke;
pointer-events:none;
}
/*
좁은 화면에서는 SVG 사선 네비가 과밀해질 수 있다.
현재는 JS가 폭에 맞춰 각 칸을 줄인다.
모바일 전용 대문이 필요해지면 여기서 별도 compact nav로 분기한다.
*/