tw93--kami
663 行
17 KiB
HTML
663 行
17 KiB
HTML
<!DOCTYPE html>
|
|
<!-- ==================================================================
|
|
PORTFOLIO TEMPLATE (KO) · parchment design system
|
|
다중 A4 포트폴리오 / 작품집 / 프로젝트 모음
|
|
구조: 표지 -> About -> 프로젝트 페이지(들) -> 연락처
|
|
각 프로젝트 1-2페이지, 비주얼 중심
|
|
변경 후 실행: python3 -c "from weasyprint import HTML; HTML('portfolio-ko.html').write_pdf('out.pdf')"
|
|
목표: 최대 8페이지
|
|
================================================================== -->
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>{{이름}} · 포트폴리오</title>
|
|
<meta name="author" content="{{이름}}">
|
|
<meta name="description" content="{{요약}}">
|
|
<meta name="keywords" content="{{키워드}}">
|
|
<meta name="generator" content="Kami">
|
|
<style>
|
|
/* Regular weight */
|
|
@font-face {
|
|
font-family: "Source Han Serif K";
|
|
src: url("../fonts/SourceHanSerifKR-Regular.otf") format("opentype"),
|
|
url("https://cdn.jsdelivr.net/gh/tw93/Kami@main/assets/fonts/SourceHanSerifKR-Regular.otf") format("opentype");
|
|
font-weight: 400;
|
|
font-style: normal;
|
|
}
|
|
|
|
/* Medium weight */
|
|
@font-face {
|
|
font-family: "Source Han Serif K";
|
|
src: url("../fonts/SourceHanSerifKR-Medium.otf") format("opentype"),
|
|
url("https://cdn.jsdelivr.net/gh/tw93/Kami@main/assets/fonts/SourceHanSerifKR-Medium.otf") format("opentype");
|
|
font-weight: 500;
|
|
font-style: normal;
|
|
}
|
|
|
|
@page {
|
|
size: A4;
|
|
margin: 12mm 15mm 12mm 15mm;
|
|
background: #f5f4ed;
|
|
}
|
|
|
|
@page:first {
|
|
margin: 0;
|
|
}
|
|
|
|
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
|
|
:root {
|
|
--parchment: #f5f4ed;
|
|
--ivory: #faf9f5;
|
|
--near-black:#141413;
|
|
--dark-warm: #3d3d3a;
|
|
--olive: #504e49;
|
|
--stone: #6b6a64;
|
|
--brand: #1B365D;
|
|
--border: #e8e6dc;
|
|
--border-soft:#e5e3d8;
|
|
--tag-bg: #E4ECF5;
|
|
--serif: "Source Han Serif K", "Source Han Serif KR", "Noto Serif KR", "Apple SD Gothic Neo", "AppleMyungjo", Charter, Georgia, serif;
|
|
--sans: var(--serif);
|
|
|
|
--rhythm-module: 14pt;
|
|
--rhythm-section: 18pt;
|
|
}
|
|
|
|
html, body { background: var(--parchment); }
|
|
|
|
@media screen {
|
|
body { max-width: 210mm; margin: 0 auto; padding: 12mm 15mm; }
|
|
}
|
|
|
|
body {
|
|
color: var(--near-black);
|
|
font-family: var(--serif);
|
|
font-size: 10pt;
|
|
line-height: 1.45;
|
|
letter-spacing: 0.3pt;
|
|
widows: 3;
|
|
orphans: 3;
|
|
font-synthesis: none;
|
|
}
|
|
|
|
.serif {
|
|
font-family: var(--serif);
|
|
}
|
|
|
|
/* ========== COVER ========== */
|
|
.cover {
|
|
width: 100%;
|
|
height: 297mm;
|
|
padding: 25mm 20mm;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: space-between;
|
|
break-after: page;
|
|
}
|
|
.cover-top {
|
|
font-family: var(--serif);
|
|
font-size: 10pt;
|
|
color: var(--brand);
|
|
letter-spacing: 2pt;
|
|
text-transform: uppercase;
|
|
}
|
|
.cover-center {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 14pt;
|
|
}
|
|
.cover-name {
|
|
font-family: var(--serif);
|
|
font-size: 58pt;
|
|
font-weight: 500;
|
|
line-height: 1.05;
|
|
color: var(--near-black);
|
|
letter-spacing: 1pt;
|
|
}
|
|
.cover-tagline {
|
|
font-family: var(--serif);
|
|
font-size: 18pt;
|
|
color: var(--olive);
|
|
line-height: 1.4;
|
|
max-width: 80%;
|
|
}
|
|
.cover-line {
|
|
width: 80pt;
|
|
height: 2pt;
|
|
background: var(--brand);
|
|
margin: 18pt 0 4pt 0;
|
|
}
|
|
.cover-meta {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: flex-end;
|
|
font-size: 10pt;
|
|
color: var(--stone);
|
|
}
|
|
.cover-meta strong {
|
|
color: var(--dark-warm);
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* ========== ABOUT ========== */
|
|
section.about {
|
|
break-after: page;
|
|
padding: 10mm 0;
|
|
}
|
|
.about-eyebrow {
|
|
font-size: 9pt;
|
|
color: var(--brand);
|
|
letter-spacing: 1pt;
|
|
text-transform: uppercase;
|
|
margin-bottom: 8pt;
|
|
}
|
|
.about-title {
|
|
font-family: var(--serif);
|
|
font-size: 32pt;
|
|
font-weight: 500;
|
|
line-height: 1.2;
|
|
margin-bottom: 20pt;
|
|
border-left: 2.5pt solid var(--brand);
|
|
border-radius: 1.5pt;
|
|
padding-left: 8pt;
|
|
}
|
|
.about-lead {
|
|
font-family: var(--serif);
|
|
font-size: 15pt;
|
|
line-height: 1.5;
|
|
color: var(--dark-warm);
|
|
margin-bottom: 24pt;
|
|
max-width: 90%;
|
|
}
|
|
.about-body {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 24pt;
|
|
}
|
|
.about-body p {
|
|
line-height: 1.45;
|
|
margin-bottom: 10pt;
|
|
}
|
|
.about-body h3 {
|
|
font-family: var(--serif);
|
|
font-size: 13pt;
|
|
font-weight: 500;
|
|
color: var(--near-black);
|
|
margin-bottom: 6pt;
|
|
}
|
|
|
|
/* ========== PROJECT PAGE ========== */
|
|
.project {
|
|
break-before: page;
|
|
break-after: page;
|
|
padding: 8mm 0;
|
|
}
|
|
.project-header {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
margin-bottom: var(--rhythm-module);
|
|
border-left: 2.5pt solid var(--brand);
|
|
border-radius: 1.5pt;
|
|
padding-left: 8pt;
|
|
}
|
|
.project-num {
|
|
font-family: var(--serif);
|
|
font-size: 42pt;
|
|
font-weight: 500;
|
|
color: var(--brand);
|
|
line-height: 1;
|
|
margin-right: 18pt;
|
|
}
|
|
.project-title-block {
|
|
flex: 1;
|
|
padding-top: 6pt;
|
|
}
|
|
.project-type {
|
|
font-size: 9pt;
|
|
color: var(--brand);
|
|
letter-spacing: 1pt;
|
|
text-transform: uppercase;
|
|
margin-bottom: 3pt;
|
|
}
|
|
.project-title {
|
|
font-family: var(--serif);
|
|
font-size: 22pt;
|
|
font-weight: 500;
|
|
color: var(--near-black);
|
|
line-height: 1.2;
|
|
margin-bottom: 4pt;
|
|
}
|
|
.project-subtitle {
|
|
font-size: 11pt;
|
|
color: var(--olive);
|
|
line-height: 1.4;
|
|
}
|
|
.project-date {
|
|
text-align: right;
|
|
font-size: 9pt;
|
|
color: var(--stone);
|
|
font-variant-numeric: tabular-nums;
|
|
white-space: nowrap;
|
|
min-width: 80pt;
|
|
padding-top: 10pt;
|
|
}
|
|
|
|
/* Tags row */
|
|
.project-tags {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 4pt;
|
|
margin-bottom: var(--rhythm-module);
|
|
}
|
|
.tag {
|
|
background: var(--tag-bg);
|
|
color: var(--brand);
|
|
font-size: 9pt;
|
|
font-weight: 500;
|
|
padding: 2pt 7pt;
|
|
border-radius: 3pt;
|
|
}
|
|
|
|
/* Image / Visual */
|
|
.project-hero {
|
|
width: 100%;
|
|
height: 110mm;
|
|
background: var(--ivory);
|
|
border-radius: 6pt;
|
|
margin-bottom: var(--rhythm-module);
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
color: var(--stone);
|
|
font-size: 10pt;
|
|
}
|
|
.project-hero img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
/* 3-column body */
|
|
.project-body {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr 1fr;
|
|
gap: 16pt;
|
|
}
|
|
.project-block h3 {
|
|
font-family: var(--serif);
|
|
font-size: 11pt;
|
|
font-weight: 500;
|
|
color: var(--brand);
|
|
margin-bottom: 4pt;
|
|
letter-spacing: 0.3pt;
|
|
}
|
|
.project-block p {
|
|
font-size: 9.5pt;
|
|
line-height: 1.45;
|
|
color: var(--dark-warm);
|
|
}
|
|
.project-block .hl {
|
|
color: var(--brand);
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* Results metrics row */
|
|
.project-results {
|
|
display: flex;
|
|
gap: 14pt;
|
|
margin-top: var(--rhythm-module);
|
|
padding-top: 10pt;
|
|
border-top: 0.5pt dotted var(--border);
|
|
}
|
|
.result-item {
|
|
flex: 1;
|
|
}
|
|
.result-value {
|
|
font-family: var(--serif);
|
|
font-size: 18pt;
|
|
font-weight: 500;
|
|
color: var(--brand);
|
|
line-height: 1.1;
|
|
font-variant-numeric: tabular-nums;
|
|
}
|
|
.result-label {
|
|
font-size: 9pt;
|
|
color: var(--olive);
|
|
margin-top: 2pt;
|
|
line-height: 1.3;
|
|
}
|
|
|
|
/* ========== 2-IMAGE VARIANT ========== */
|
|
.project-visuals-2col {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 10pt;
|
|
margin-bottom: var(--rhythm-module);
|
|
}
|
|
.project-visuals-2col .project-hero {
|
|
height: 80mm;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
/* ========== SELECTED WORKS LIST ========== */
|
|
section.more-works {
|
|
break-before: page;
|
|
padding-top: 10mm;
|
|
}
|
|
.more-works-title {
|
|
font-family: var(--serif);
|
|
font-size: 24pt;
|
|
font-weight: 500;
|
|
margin-bottom: 16pt;
|
|
border-left: 2.5pt solid var(--brand);
|
|
border-radius: 1.5pt;
|
|
padding-left: 8pt;
|
|
}
|
|
.work-item {
|
|
display: grid;
|
|
grid-template-columns: 40pt 1fr 80pt;
|
|
gap: 12pt;
|
|
padding: 8pt 0;
|
|
border-bottom: 0.3pt dotted var(--border);
|
|
align-items: baseline;
|
|
}
|
|
.work-item:last-of-type { border-bottom: none; }
|
|
.work-year {
|
|
font-family: var(--serif);
|
|
color: var(--brand);
|
|
font-size: 11pt;
|
|
white-space: nowrap;
|
|
}
|
|
.work-title-block .title {
|
|
font-family: var(--serif);
|
|
font-size: 11pt;
|
|
font-weight: 500;
|
|
color: var(--near-black);
|
|
}
|
|
.work-title-block .desc {
|
|
font-size: 9pt;
|
|
color: var(--olive);
|
|
margin-top: 1pt;
|
|
}
|
|
.work-link {
|
|
text-align: right;
|
|
font-size: 9pt;
|
|
color: var(--stone);
|
|
}
|
|
|
|
/* ========== CONTACT ========== */
|
|
section.contact {
|
|
break-before: page;
|
|
padding: 20mm 0;
|
|
min-height: 230mm;
|
|
display: flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
}
|
|
.contact-eyebrow {
|
|
font-size: 10pt;
|
|
color: var(--brand);
|
|
letter-spacing: 2pt;
|
|
text-transform: uppercase;
|
|
margin-bottom: 12pt;
|
|
}
|
|
.contact-title {
|
|
font-family: var(--serif);
|
|
font-size: 48pt;
|
|
font-weight: 500;
|
|
line-height: 1.1;
|
|
margin-bottom: 20pt;
|
|
color: var(--near-black);
|
|
}
|
|
.contact-line {
|
|
width: 80pt;
|
|
height: 2pt;
|
|
background: var(--brand);
|
|
margin-bottom: 24pt;
|
|
}
|
|
.contact-list {
|
|
font-size: 12pt;
|
|
line-height: 1.55;
|
|
color: var(--dark-warm);
|
|
}
|
|
.contact-list strong {
|
|
color: var(--stone);
|
|
font-weight: 500;
|
|
font-size: 10pt;
|
|
letter-spacing: 0.5pt;
|
|
margin-right: 12pt;
|
|
display: inline-block;
|
|
min-width: 70pt;
|
|
text-transform: uppercase;
|
|
}
|
|
.contact-list a {
|
|
color: var(--brand);
|
|
text-decoration: none;
|
|
}
|
|
|
|
/* ========== TABLE (kami-table) ========== */
|
|
table, .kami-table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
font-size: 9.5pt;
|
|
margin: 10pt 0;
|
|
break-inside: avoid;
|
|
}
|
|
table th, .kami-table th {
|
|
text-align: left;
|
|
font-weight: 500;
|
|
color: var(--dark-warm);
|
|
padding: 5pt 8pt;
|
|
border-bottom: 1pt solid var(--border);
|
|
background: transparent;
|
|
}
|
|
table td, .kami-table td {
|
|
padding: 4pt 8pt;
|
|
border-bottom: 0.3pt solid var(--border-soft);
|
|
vertical-align: top;
|
|
}
|
|
table.compact th, .kami-table.compact th { padding: 3pt 6pt; font-size: 8pt; }
|
|
table.compact td, .kami-table.compact td { padding: 2pt 6pt; font-size: 8pt; line-height: 1.4; }
|
|
table.financial td:not(:first-child), .kami-table.financial td:not(:first-child) {
|
|
text-align: right; font-variant-numeric: tabular-nums;
|
|
}
|
|
table.financial th:not(:first-child), .kami-table.financial th:not(:first-child) { text-align: right; }
|
|
table.striped tbody tr:nth-child(even) td, .kami-table.striped tbody tr:nth-child(even) td {
|
|
background: var(--ivory);
|
|
}
|
|
table .total td, .kami-table .total td {
|
|
font-weight: 500; border-top: 1pt solid var(--brand); border-bottom: none; color: var(--near-black);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- ========== 표지 ========== -->
|
|
<div class="cover">
|
|
<div class="cover-top">{{연도 또는 분야 태그 · 예: "Selected Works 2023–2026"}}</div>
|
|
|
|
<div class="cover-center">
|
|
<div class="cover-name">{{이름<br>포트폴리오}}</div>
|
|
<div class="cover-tagline">{{한 줄 자기 설명 / 포트폴리오 주제}}</div>
|
|
<div class="cover-line"></div>
|
|
</div>
|
|
|
|
<div class="cover-meta">
|
|
<div>
|
|
<strong>{{전문 분야 / 역할}}</strong><br>
|
|
{{소재지}}
|
|
</div>
|
|
<div style="text-align: right;">
|
|
{{EMAIL}}<br>
|
|
{{웹사이트 / 소셜 링크}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- ========== ABOUT ========== -->
|
|
<section class="about">
|
|
<div class="about-eyebrow">About</div>
|
|
<div class="about-title">{{자기 정의를 담은 한 문장 headline}}</div>
|
|
<div class="about-lead">
|
|
{{2-3줄의 자기소개 인트로. serif 서체, 너무 홍보성이 되지 않게.
|
|
자신이 무엇에 관심을 갖고 무엇을 잘하는지 자신의 언어로 기술한다.}}
|
|
</div>
|
|
<div class="about-body">
|
|
<div>
|
|
<h3>경력</h3>
|
|
<p>{{과거 경력에 대한 개요.}}</p>
|
|
</div>
|
|
<div>
|
|
<h3>관심사</h3>
|
|
<p>{{현재의 관심사 / 방법론 / 접근 방식.}}</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ========== 프로젝트 01 ========== -->
|
|
<section class="project">
|
|
<div class="project-header">
|
|
<div class="project-num">01</div>
|
|
<div class="project-title-block">
|
|
<div class="project-type">{{프로젝트 유형 · 예: "Product Design" / "Open Source"}}</div>
|
|
<div class="project-title">{{프로젝트 이름}}</div>
|
|
<div class="project-subtitle">{{이 프로젝트가 무엇을 했는지 한 문장으로}}</div>
|
|
</div>
|
|
<div class="project-date">{{기간 · 예: "2025.04 - 2026.02"}}</div>
|
|
</div>
|
|
|
|
<div class="project-tags">
|
|
<span class="tag">{{태그 1}}</span>
|
|
<span class="tag">{{태그 2}}</span>
|
|
<span class="tag">{{태그 3}}</span>
|
|
</div>
|
|
|
|
<!-- 메인 이미지 -->
|
|
<div class="project-hero">
|
|
<!-- 교체: <img src="project-01-hero.png" alt=""> -->
|
|
[프로젝트 메인 이미지 자리 · <img src="xxx.png">로 교체]
|
|
</div>
|
|
|
|
<!-- 3단 본문 -->
|
|
<div class="project-body">
|
|
<div class="project-block">
|
|
<h3>Context</h3>
|
|
<p>{{왜 이 프로젝트를 했는가? 어떤 문제를 해결하려 했는가? 누가 사용자인가?}}</p>
|
|
</div>
|
|
<div class="project-block">
|
|
<h3>Approach</h3>
|
|
<p>{{어떻게 접근했는가? 핵심 의사결정, 설계 고려사항, 기술 방안.}}</p>
|
|
</div>
|
|
<div class="project-block">
|
|
<h3>Outcome</h3>
|
|
<p>{{결과는 무엇인가? <span class="hl">수치</span>, 피드백, 영향.}}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 핵심 수치 (선택) -->
|
|
<div class="project-results">
|
|
<div class="result-item">
|
|
<div class="result-value">{{수치}}</div>
|
|
<div class="result-label">{{라벨}}</div>
|
|
</div>
|
|
<div class="result-item">
|
|
<div class="result-value">{{수치}}</div>
|
|
<div class="result-label">{{라벨}}</div>
|
|
</div>
|
|
<div class="result-item">
|
|
<div class="result-value">{{수치}}</div>
|
|
<div class="result-label">{{라벨}}</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ========== 프로젝트 02 (2-이미지 레이아웃) ========== -->
|
|
<section class="project">
|
|
<div class="project-header">
|
|
<div class="project-num">02</div>
|
|
<div class="project-title-block">
|
|
<div class="project-type">{{프로젝트 유형 · 예: "Product Design" / "Open Source"}}</div>
|
|
<div class="project-title">{{프로젝트 이름}}</div>
|
|
<div class="project-subtitle">{{한 문장 설명}}</div>
|
|
</div>
|
|
<div class="project-date">{{기간 · 예: "2025.04 - 2026.02"}}</div>
|
|
</div>
|
|
|
|
<div class="project-tags">
|
|
<span class="tag">{{태그}}</span>
|
|
<span class="tag">{{태그}}</span>
|
|
</div>
|
|
|
|
<!-- 좌우 2이미지 -->
|
|
<div class="project-visuals-2col">
|
|
<div class="project-hero">[좌측 이미지]</div>
|
|
<div class="project-hero">[우측 이미지]</div>
|
|
</div>
|
|
|
|
<div class="project-body">
|
|
<div class="project-block">
|
|
<h3>Context</h3>
|
|
<p>{{왜 이 프로젝트를 했는가? 어떤 문제를 해결하려 했는가? 누가 사용자인가?}}</p>
|
|
</div>
|
|
<div class="project-block">
|
|
<h3>Approach</h3>
|
|
<p>{{어떻게 접근했는가? 핵심 의사결정, 설계 고려사항, 기술 방안.}}</p>
|
|
</div>
|
|
<div class="project-block">
|
|
<h3>Outcome</h3>
|
|
<p>{{결과는 무엇인가? <span class="hl">수치</span>, 피드백, 영향.}}</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ========== 추가 작품 목록 (선택) ========== -->
|
|
<section class="more-works">
|
|
<div class="more-works-title">추가 작품</div>
|
|
|
|
<div class="work-item">
|
|
<span class="work-year">2025</span>
|
|
<div class="work-title-block">
|
|
<div class="title">{{작품 제목}}</div>
|
|
<div class="desc">{{한 줄 설명}}</div>
|
|
</div>
|
|
<div class="work-link">{{링크 / 상태}}</div>
|
|
</div>
|
|
|
|
<div class="work-item">
|
|
<span class="work-year">2024</span>
|
|
<div class="work-title-block">
|
|
<div class="title">{{작품 제목}}</div>
|
|
<div class="desc">{{한 줄 설명}}</div>
|
|
</div>
|
|
<div class="work-link">{{링크 / 상태}}</div>
|
|
</div>
|
|
|
|
<div class="work-item">
|
|
<span class="work-year">2023</span>
|
|
<div class="work-title-block">
|
|
<div class="title">{{작품 제목}}</div>
|
|
<div class="desc">{{한 줄 설명}}</div>
|
|
</div>
|
|
<div class="work-link">{{링크 / 상태}}</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- ========== 연락처 ========== -->
|
|
<section class="contact">
|
|
<div class="contact-eyebrow">Let's Talk</div>
|
|
<div class="contact-title">{{연락을 환영하는 한 문장 · 예: "새로운 협업을 기대합니다"}}</div>
|
|
<div class="contact-line"></div>
|
|
<div class="contact-list">
|
|
<div><strong>Email</strong><a href="mailto:{{EMAIL}}">{{EMAIL}}</a></div>
|
|
<div><strong>Phone</strong>{{전화번호}}</div>
|
|
<div><strong>Website</strong><a href="{{URL}}">{{URL}}</a></div>
|
|
<div><strong>{{기타 플랫폼}}</strong><a href="{{URL}}">@{{ID}}</a></div>
|
|
</div>
|
|
</section>
|
|
|
|
</body>
|
|
</html>
|