v0.1.1 테마 구성 및 레이아웃 수정

This commit is contained in:
2026-04-13 10:35:20 +09:00
commit 890b3c1902
31 changed files with 1813 additions and 0 deletions

974
assets/built/screen.css Normal file
View File

@@ -0,0 +1,974 @@
@import url("../fonts/pretendard.css");
:root {
--bg: #fcfbf9;
--surface: #ffffff;
--surface-muted: #f4f1ed;
--surface-strong: #131313;
--text: #1b1918;
--text-soft: #6e6661;
--border: #e6dfd7;
--accent: #f0632f;
--accent-strong: #d84d1d;
--shadow: 0 10px 30px rgba(20, 16, 12, 0.05);
--radius: 16px;
--radius-sm: 12px;
--sidebar-left: 240px;
--sidebar-right: 320px;
--content-column: 720px;
--content-measure: 680px;
--topbar-height: 72px;
--shell-width: calc(var(--sidebar-left) + var(--content-column) + var(--sidebar-right));
--font-sans: "Pretendard", "Apple SD Gothic Neo", "Noto Sans KR", "Segoe UI", sans-serif;
}
body.theme-dark {
--bg: #111111;
--surface: #131313;
--surface-muted: #1a1a1a;
--surface-strong: #f4f1ed;
--text: #f3efe9;
--text-soft: #ada59c;
--border: #272727;
--shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
margin: 0;
background: var(--bg);
color: var(--text);
font-family: var(--font-sans);
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
a {
color: inherit;
text-decoration: none;
}
img {
display: block;
max-width: 100%;
}
button,
input {
font: inherit;
}
.site-shell {
display: grid;
grid-template-columns: var(--sidebar-left) minmax(0, var(--content-column)) var(--sidebar-right);
min-height: 100vh;
width: min(100%, var(--shell-width));
margin: 0 auto;
}
.sidebar,
.site-main {
min-width: 0;
}
.sidebar {
border-right: 1px solid var(--border);
}
.sidebar--right {
border-right: 0;
border-left: 1px solid var(--border);
}
.sidebar__inner {
position: sticky;
top: 0;
height: 100vh;
padding: 18px 14px;
overflow-y: auto;
}
.sidebar__inner--right {
display: flex;
flex-direction: column;
gap: 18px;
}
.brand {
display: inline-flex;
align-items: center;
gap: 10px;
margin-bottom: 16px;
font-weight: 800;
}
.brand__mark {
width: 14px;
height: 14px;
border: 2px solid currentColor;
border-radius: 3px;
}
.brand__logo {
max-height: 32px;
}
.menu-groups {
display: grid;
gap: 6px;
}
.menu-group {
border-bottom: 1px solid var(--border);
}
.menu-group__trigger {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 13px 0;
border: 0;
background: none;
color: inherit;
cursor: pointer;
}
.menu-group__content {
padding: 0 0 10px;
display: none;
}
.menu-group.is-open .menu-group__content {
display: block;
}
.menu-group .nav {
margin: 0;
padding: 0;
list-style: none;
}
.menu-group .nav li + li,
.link-list li + li {
margin-top: 8px;
}
.menu-group .nav a,
.link-list a {
color: var(--text-soft);
}
.link-list {
margin: 0;
padding: 0;
list-style: none;
}
.sidebar-card {
padding: 16px 0 0;
border-top: 1px solid var(--border);
}
.sidebar-card--tight {
padding-top: 14px;
}
.sidebar-card__header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
}
.sidebar-card__header h2 {
margin: 0;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-soft);
}
.category-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 10px 12px;
}
.category-chip {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border-radius: 10px;
transition: background 0.2s ease;
}
.category-chip:hover,
.author-list__item:hover,
.recommended-list a:hover {
background: var(--surface-muted);
}
.category-chip__dot {
width: 8px;
height: 8px;
border-radius: 999px;
background: linear-gradient(135deg, #5d66ff, #29b6f6);
}
.category-chip__count {
margin-left: auto;
color: var(--text-soft);
font-size: 12px;
}
.author-list {
display: grid;
gap: 10px;
}
.author-list__item {
display: flex;
align-items: center;
gap: 10px;
padding: 7px 8px;
border-radius: 12px;
}
.author-list__item strong,
.author-list__item small {
display: block;
}
.author-list__item small {
color: var(--text-soft);
}
.sidebar-footer {
display: flex;
flex-wrap: wrap;
gap: 10px 14px;
align-items: center;
margin-top: auto;
padding-top: 16px;
color: var(--text-soft);
font-size: 13px;
}
.topbar {
position: sticky;
top: 0;
z-index: 20;
display: flex;
justify-content: space-between;
gap: 16px;
align-items: center;
height: var(--topbar-height);
padding: 16px 20px;
border-bottom: 1px solid var(--border);
background: color-mix(in srgb, var(--bg) 88%, transparent);
backdrop-filter: blur(14px);
}
.topbar__search {
flex: 1;
max-width: 320px;
}
.search-trigger,
.search-modal__input {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
padding: 12px 16px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: var(--shadow);
color: var(--text-soft);
}
.search-trigger {
cursor: pointer;
}
.search-shortcut {
margin-left: auto;
padding: 1px 7px;
border: 1px solid var(--border);
border-radius: 8px;
font-size: 12px;
}
.topbar__actions {
display: flex;
align-items: center;
gap: 10px;
}
.button,
.gh-subscribe-form button {
display: inline-flex;
justify-content: center;
align-items: center;
padding: 11px 16px;
border: 0;
border-radius: 10px;
background: var(--surface-strong);
color: var(--bg);
font-weight: 700;
cursor: pointer;
}
.button--accent {
background: var(--accent);
color: #fff;
}
.button--accent:hover {
background: var(--accent-strong);
}
.button--light {
background: var(--surface);
color: var(--text);
border: 1px solid var(--border);
}
.button--subscribe {
padding-inline: 14px;
}
.icon-button {
display: inline-flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
border: 1px solid var(--border);
border-radius: 999px;
background: var(--surface);
color: inherit;
cursor: pointer;
}
.icon-button--plain {
border: 0;
background: transparent;
}
.content-area {
padding: 0 20px 44px;
}
.hero {
display: grid;
justify-items: center;
gap: 16px;
padding: 38px 20px 28px;
text-align: center;
border-bottom: 1px solid var(--border);
}
.hero__title {
max-width: 680px;
margin: 0;
font-size: clamp(2rem, 3vw, 3.1rem);
line-height: 1.08;
letter-spacing: -0.04em;
font-weight: 800;
}
.hero__description,
.section-description {
max-width: 620px;
margin: 0;
color: var(--text-soft);
font-size: 1rem;
line-height: 1.7;
}
.subscribe-form,
.gh-subscribe-form {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.gh-subscribe-form {
width: 100%;
}
.gh-subscribe-form .gh-subscribe-input,
.subscribe-form input {
min-width: 0;
flex: 1 1 180px;
padding: 12px 14px;
border: 1px solid var(--border);
border-radius: 10px;
background: var(--surface);
color: inherit;
}
.subscribe-form--hero {
justify-content: center;
}
.stack-section {
padding: 18px 0;
}
.section-header {
padding-bottom: 18px;
border-bottom: 1px solid var(--border);
}
.section-header--author {
padding-top: 8px;
}
.section-title {
margin: 0 0 8px;
font-size: clamp(1.7rem, 2vw, 2.15rem);
line-height: 1.12;
letter-spacing: -0.03em;
}
.author-header {
display: flex;
align-items: center;
gap: 18px;
}
.tab-row {
display: flex;
flex-wrap: wrap;
gap: 8px;
padding-bottom: 14px;
border-bottom: 1px solid var(--border);
}
.tab-row__button {
padding: 10px 2px;
border: 0;
border-bottom: 2px solid transparent;
background: none;
color: var(--text-soft);
font-weight: 700;
cursor: pointer;
}
.tab-row__button.is-active {
color: var(--text);
border-color: var(--accent);
}
.tab-panel {
display: none;
}
.tab-panel.is-active {
display: block;
}
.post-list {
display: grid;
}
.post-card {
display: grid;
grid-template-columns: 96px minmax(0, 1fr);
gap: 16px;
padding: 16px 0;
border-bottom: 1px solid var(--border);
}
.post-card__media img,
.post-card__media-fallback {
width: 96px;
height: 72px;
object-fit: cover;
border-radius: 10px;
background: var(--surface-muted);
}
.post-card__media-fallback {
display: grid;
place-items: center;
padding: 8px;
color: var(--text-soft);
font-size: 12px;
text-align: center;
}
.post-card__content h2 {
margin: 0 0 6px;
font-size: 1.04rem;
line-height: 1.34;
letter-spacing: -0.01em;
}
.post-card__content p {
margin: 0 0 8px;
color: var(--text-soft);
font-size: 0.94rem;
line-height: 1.55;
}
.post-card__meta {
display: flex;
flex-wrap: wrap;
gap: 8px;
color: var(--text-soft);
font-size: 13px;
}
.meta-pill {
display: inline-flex;
align-items: center;
padding: 4px 8px;
border-radius: 999px;
background: var(--surface-muted);
color: var(--text);
font-size: 12px;
font-weight: 700;
}
.category-overview {
display: grid;
}
.category-overview__row {
display: grid;
grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
gap: 24px;
padding: 20px 0;
border-bottom: 1px solid var(--border);
}
.category-overview__row h2 {
margin: 0 0 10px;
}
.category-overview__row p {
margin: 0 0 14px;
color: var(--text-soft);
line-height: 1.6;
}
.category-overview__row ol {
margin: 0;
padding-left: 18px;
display: grid;
gap: 10px;
}
.site-icon,
.site-icon--fallback {
width: 54px;
height: 54px;
border-radius: 16px;
object-fit: cover;
background: var(--surface-strong);
color: var(--bg);
display: grid;
place-items: center;
font-weight: 800;
}
.about-block h2,
.author-feature h3 {
margin: 0 0 4px;
}
.about-block p,
.author-feature p,
.copyright {
margin: 0;
color: var(--text-soft);
line-height: 1.55;
}
.social-row {
display: flex;
gap: 12px;
}
.social-row a {
color: var(--text-soft);
text-transform: uppercase;
font-size: 12px;
font-weight: 700;
}
.recommended-list {
margin: 0;
padding: 0;
list-style: none;
display: grid;
gap: 8px;
}
.recommended-list a {
display: block;
padding: 6px 8px;
border-radius: 10px;
line-height: 1.5;
font-size: 0.94rem;
}
.author-feature {
display: flex;
gap: 14px;
align-items: center;
padding-bottom: 8px;
border-bottom: 1px solid var(--border);
}
.avatar,
.avatar--fallback {
width: 34px;
height: 34px;
border-radius: 999px;
object-fit: cover;
background: linear-gradient(135deg, #ff8a65, #ffb74d);
color: #fff;
display: inline-grid;
place-items: center;
font-weight: 800;
}
.avatar--large {
width: 56px;
height: 56px;
}
.post-template {
max-width: var(--content-measure);
margin: 0 auto;
padding: 24px 0 10px;
}
.post-header {
display: grid;
gap: 16px;
padding-bottom: 24px;
border-bottom: 1px solid var(--border);
}
.post-tag {
color: var(--accent);
font-weight: 700;
}
.post-title {
margin: 0;
font-size: clamp(2rem, 3vw, 2.8rem);
line-height: 1.08;
letter-spacing: -0.04em;
}
.post-meta {
display: flex;
flex-wrap: wrap;
gap: 10px;
color: var(--text-soft);
}
.post-feature-image img {
width: 100%;
border-radius: 18px;
}
.kg-content {
font-size: 1.02rem;
line-height: 1.88;
}
.kg-content > * + * {
margin-top: 1.2em;
}
.kg-content .kg-width-wide {
position: relative;
width: min(100vw - 48px, 820px);
max-width: none;
margin-left: 50%;
transform: translateX(-50%);
}
.kg-content .kg-width-full {
position: relative;
width: 100vw;
max-width: none;
margin-left: 50%;
transform: translateX(-50%);
}
.kg-content .kg-width-full img,
.kg-content .kg-width-wide img {
width: 100%;
}
.page-template .kg-content > .kg-width-full:first-child,
.page-template .kg-content > .kg-width-wide:first-child {
margin-top: 0;
}
.page-template .kg-content > .kg-width-full:last-child,
.page-template .kg-content > .kg-width-wide:last-child {
margin-bottom: 0;
}
.kg-content .kg-width-full + .kg-width-full:not(.kg-card-hascaption),
.kg-content .kg-width-wide + .kg-width-wide:not(.kg-card-hascaption),
.kg-content .kg-width-full + .kg-width-wide:not(.kg-card-hascaption),
.kg-content .kg-width-wide + .kg-width-full:not(.kg-card-hascaption) {
margin-top: 0;
}
.kg-content blockquote {
margin: 1.4em 0;
padding: 1em 1.1em;
border-left: 4px solid var(--accent);
background: color-mix(in srgb, var(--accent) 10%, var(--surface));
border-radius: 12px;
}
.membership-cta,
.comments-empty {
display: grid;
justify-items: center;
gap: 12px;
padding: 36px 24px;
margin-top: 28px;
background: var(--surface-strong);
color: var(--bg);
border-radius: 20px;
text-align: center;
}
.comments-empty {
background: var(--surface-muted);
color: var(--text);
border: 1px solid var(--border);
}
.author-inline-card,
.discussion-panel,
.post-navigation {
max-width: var(--content-measure);
margin-inline: auto;
}
.author-inline-card {
display: flex;
gap: 14px;
align-items: center;
padding-top: 18px;
border-top: 1px solid var(--border);
}
.discussion-panel {
margin-top: 24px;
padding-top: 18px;
border-top: 1px solid var(--border);
}
.discussion-header {
display: flex;
justify-content: space-between;
margin-bottom: 18px;
}
.discussion-header h2 {
margin: 0;
}
.post-navigation {
display: flex;
justify-content: space-between;
gap: 14px;
padding: 24px 0;
border-top: 1px solid var(--border);
}
.post-navigation__link {
display: block;
flex: 1 1 0;
padding: 12px 0;
}
.post-navigation__link small {
display: block;
margin-bottom: 4px;
color: var(--text-soft);
text-transform: uppercase;
}
.post-navigation__link--next {
text-align: right;
}
.pagination {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
padding-top: 20px;
}
.pagination__link {
padding: 10px 14px;
border: 1px solid var(--border);
border-radius: 10px;
}
.pagination__status {
color: var(--text-soft);
}
.search-modal[hidden] {
display: none;
}
.search-modal {
position: fixed;
inset: 0;
z-index: 80;
}
.search-modal__backdrop {
position: absolute;
inset: 0;
background: rgba(10, 10, 10, 0.42);
backdrop-filter: blur(4px);
}
.search-modal__panel {
position: relative;
width: min(100%, 720px);
margin: 56px auto;
padding: 0 18px;
}
.search-modal__input input {
flex: 1;
border: 0;
background: transparent;
color: inherit;
outline: none;
}
.search-modal__body {
margin-top: 14px;
padding: 18px;
background: var(--surface);
border: 1px solid var(--border);
border-radius: 18px;
box-shadow: var(--shadow);
max-height: 70vh;
overflow: auto;
}
.search-modal__hint,
.search-empty {
color: var(--text-soft);
}
.search-result {
display: block;
padding: 10px 4px;
border-bottom: 1px solid var(--border);
}
.search-result:last-child {
border-bottom: 0;
}
@media (max-width: 1240px) {
.site-shell {
width: 100%;
grid-template-columns: 240px minmax(0, 1fr);
}
.sidebar--right {
display: none;
}
}
@media (max-width: 960px) {
.site-shell {
grid-template-columns: 1fr;
}
.sidebar--left {
display: none;
}
.topbar {
padding-inline: 14px;
}
.content-area {
padding-inline: 14px;
}
.hero {
padding-inline: 0;
}
.category-overview__row {
grid-template-columns: 1fr;
gap: 10px;
}
}
@media (max-width: 640px) {
.topbar {
gap: 10px;
}
.topbar__search {
max-width: none;
}
.search-trigger span:nth-child(2) {
display: none;
}
.button--accent {
padding-inline: 12px;
font-size: 14px;
}
.post-card {
grid-template-columns: 1fr;
}
.post-card__media img,
.post-card__media-fallback {
width: 100%;
height: 180px;
}
.post-navigation {
flex-direction: column;
}
.post-navigation__link--next {
text-align: left;
}
}

134
assets/built/theme.js Normal file
View File

@@ -0,0 +1,134 @@
(function () {
var root = document.documentElement;
var body = document.body;
var storageKey = "ghost-thred-theme";
function setTheme(theme) {
body.classList.toggle("theme-dark", theme === "dark");
localStorage.setItem(storageKey, theme);
}
var savedTheme = localStorage.getItem(storageKey);
if (savedTheme) {
setTheme(savedTheme);
}
document.querySelectorAll("[data-theme-toggle]").forEach(function (button) {
button.addEventListener("click", function () {
setTheme(body.classList.contains("theme-dark") ? "light" : "dark");
});
});
document.querySelectorAll("[data-accordion]").forEach(function (button) {
button.addEventListener("click", function () {
var section = button.parentElement;
section.classList.toggle("is-open");
});
});
var tabRoot = document.querySelector("[data-tabs]");
if (tabRoot) {
var triggers = tabRoot.querySelectorAll("[data-tab-trigger]");
var panels = tabRoot.querySelectorAll("[data-tab-panel]");
triggers.forEach(function (trigger) {
trigger.addEventListener("click", function () {
var target = trigger.getAttribute("data-tab-trigger");
triggers.forEach(function (item) {
item.classList.toggle("is-active", item === trigger);
});
panels.forEach(function (panel) {
panel.classList.toggle("is-active", panel.getAttribute("data-tab-panel") === target);
});
});
});
}
var searchModal = document.querySelector("[data-search-modal]");
var searchInput = document.querySelector("[data-search-input]");
var searchResults = document.querySelector("[data-search-results]");
function getSearchItems() {
var items = [];
document.querySelectorAll(".post-card h2 a, .recommended-list a, .category-chip, .author-list__item").forEach(function (link) {
items.push({
title: (link.textContent || "").trim(),
url: link.getAttribute("href") || "#"
});
});
return items.filter(function (item, index, array) {
return item.title && array.findIndex(function (candidate) {
return candidate.title === item.title && candidate.url === item.url;
}) === index;
});
}
function renderSearchResults(keyword) {
var normalized = keyword.trim().toLowerCase();
if (!normalized) {
searchResults.innerHTML = '<p class="search-modal__hint">Start typing to filter visible posts, tags, and authors in the current page.</p>';
return;
}
var items = getSearchItems().filter(function (item) {
return item.title.toLowerCase().indexOf(normalized) !== -1;
});
if (!items.length) {
searchResults.innerHTML = '<p class="search-empty">No matching items in the current view.</p>';
return;
}
searchResults.innerHTML = items.map(function (item) {
return '<a class="search-result" href="' + item.url + '">' + item.title + "</a>";
}).join("");
}
function toggleSearch(open) {
if (!searchModal) {
return;
}
searchModal.hidden = !open;
body.style.overflow = open ? "hidden" : "";
if (open && searchInput) {
window.setTimeout(function () {
searchInput.focus();
}, 10);
}
}
document.querySelectorAll("[data-search-open]").forEach(function (button) {
button.addEventListener("click", function () {
toggleSearch(true);
});
});
document.querySelectorAll("[data-search-close]").forEach(function (button) {
button.addEventListener("click", function () {
toggleSearch(false);
});
});
if (searchInput) {
searchInput.addEventListener("input", function (event) {
renderSearchResults(event.target.value);
});
}
document.addEventListener("keydown", function (event) {
if (event.key === "/" && !/input|textarea/i.test(document.activeElement.tagName)) {
event.preventDefault();
toggleSearch(true);
}
if (event.key === "Escape") {
toggleSearch(false);
}
});
})();

View File

@@ -0,0 +1,71 @@
/*
Copyright (c) 2021 Kil Hyung-jin, with Reserved Font Name Pretendard.
https://github.com/orioncactus/pretendard
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
*/
@font-face {
font-family: 'Pretendard';
font-weight: 900;
font-display: swap;
src: local('Pretendard Black'), url(./woff2/Pretendard-Black.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 800;
font-display: swap;
src: local('Pretendard ExtraBold'), url(./woff2/Pretendard-ExtraBold.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 700;
font-display: swap;
src: local('Pretendard Bold'), url(./woff2/Pretendard-Bold.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 600;
font-display: swap;
src: local('Pretendard SemiBold'), url(./woff2/Pretendard-SemiBold.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 500;
font-display: swap;
src: local('Pretendard Medium'), url(./woff2/Pretendard-Medium.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 400;
font-display: swap;
src: local('Pretendard Regular'), url(./woff2/Pretendard-Regular.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 300;
font-display: swap;
src: local('Pretendard Light'), url(./woff2/Pretendard-Light.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 200;
font-display: swap;
src: local('Pretendard ExtraLight'), url(./woff2/Pretendard-ExtraLight.woff2) format('woff2');
}
@font-face {
font-family: 'Pretendard';
font-weight: 100;
font-display: swap;
src: local('Pretendard Thin'), url(./woff2/Pretendard-Thin.woff2) format('woff2');
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.