v0.1.30 본문 타이포그래피와 태그 배지 보정

This commit is contained in:
2026-04-14 12:43:35 +09:00
parent 4c460e62fc
commit 8c591b3b93
12 changed files with 285 additions and 34 deletions

View File

@@ -767,11 +767,6 @@ body:not(.left-sidebar-collapsed) .topbar__sidebar-toggle-icon--close {
background: transparent;
}
.content-area {
padding: 0 20px 44px;
min-width: 0;
}
.hero {
padding: 28px 0 18px;
text-align: center;

File diff suppressed because one or more lines are too long

View File

@@ -13,6 +13,238 @@
}
}
@layer components {
.prose {
color: var(--tw-prose-body);
max-width: 65ch;
font-size: 1rem;
line-height: 1.75;
}
.prose-theme {
--tw-prose-body: var(--text);
--tw-prose-headings: var(--text);
--tw-prose-lead: var(--text-soft);
--tw-prose-links: var(--text);
--tw-prose-bold: var(--text);
--tw-prose-counters: var(--text-soft);
--tw-prose-bullets: var(--border-strong);
--tw-prose-hr: var(--border);
--tw-prose-quotes: var(--text);
--tw-prose-quote-borders: var(--border);
--tw-prose-captions: var(--text-soft);
--tw-prose-kbd: var(--text);
--tw-prose-kbd-shadows: color-mix(in srgb, var(--text) 10%, transparent);
--tw-prose-code: var(--text);
--tw-prose-pre-code: #f8f5f0;
--tw-prose-pre-bg: #26221f;
--tw-prose-th-borders: var(--border-strong);
--tw-prose-td-borders: var(--border);
}
.prose :where(p):not(:where(.not-prose, .not-prose *)) {
margin-top: 1.25em;
margin-bottom: 1.25em;
}
.prose :where(a):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-links);
font-weight: 500;
text-decoration: underline;
text-underline-offset: 0.12em;
}
.prose :where(strong):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-bold);
font-weight: 600;
}
.prose :where(ol):not(:where(.not-prose, .not-prose *)) {
margin-top: 1.25em;
margin-bottom: 1.25em;
padding-inline-start: 1.625em;
list-style-type: decimal;
}
.prose :where(ul):not(:where(.not-prose, .not-prose *)) {
margin-top: 1.25em;
margin-bottom: 1.25em;
padding-inline-start: 1.625em;
list-style-type: disc;
}
.prose :where(ol > li):not(:where(.not-prose, .not-prose *))::marker {
color: var(--tw-prose-counters);
font-weight: 400;
}
.prose :where(ul > li):not(:where(.not-prose, .not-prose *))::marker {
color: var(--tw-prose-bullets);
}
.prose :where(li):not(:where(.not-prose, .not-prose *)) {
margin-top: 0.5em;
margin-bottom: 0.5em;
}
.prose :where(ol > li, ul > li):not(:where(.not-prose, .not-prose *)) {
padding-inline-start: 0.375em;
}
.prose :where(hr):not(:where(.not-prose, .not-prose *)) {
border-color: var(--tw-prose-hr);
border-top-width: 1px;
margin-top: 3em;
margin-bottom: 3em;
}
.prose :where(blockquote):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-quotes);
border-inline-start-width: 0.25rem;
border-inline-start-color: var(--tw-prose-quote-borders);
margin-top: 1.6em;
margin-bottom: 1.6em;
padding-inline-start: 1em;
font-style: italic;
font-weight: 500;
}
.prose :where(h1):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-headings);
margin-top: 0;
margin-bottom: 0.888889em;
font-size: 2.25em;
font-weight: 800;
line-height: 1.11111;
}
.prose :where(h2):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-headings);
margin-top: 2em;
margin-bottom: 1em;
font-size: 1.5em;
font-weight: 700;
line-height: 1.33333;
}
.prose :where(h3):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-headings);
margin-top: 1.6em;
margin-bottom: 0.6em;
font-size: 1.25em;
font-weight: 600;
line-height: 1.6;
}
.prose :where(h4):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-headings);
margin-top: 1.5em;
margin-bottom: 0.5em;
font-weight: 600;
line-height: 1.5;
}
.prose :where(img, picture, video):not(:where(.not-prose, .not-prose *)) {
margin-top: 2em;
margin-bottom: 2em;
}
.prose :where(picture):not(:where(.not-prose, .not-prose *)) {
display: block;
}
.prose :where(picture > img):not(:where(.not-prose, .not-prose *)) {
margin-top: 0;
margin-bottom: 0;
}
.prose :where(figure):not(:where(.not-prose, .not-prose *)) {
margin-top: 2em;
margin-bottom: 2em;
}
.prose :where(figure > *):not(:where(.not-prose, .not-prose *)) {
margin-top: 0;
margin-bottom: 0;
}
.prose :where(figcaption):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-captions);
margin-top: 0.857143em;
font-size: 0.875em;
line-height: 1.42857;
}
.prose :where(code):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-code);
font-size: 0.875em;
font-weight: 600;
}
.prose :where(code):not(:where(.not-prose, .not-prose *))::before,
.prose :where(code):not(:where(.not-prose, .not-prose *))::after {
content: "`";
}
.prose :where(pre):not(:where(.not-prose, .not-prose *)) {
color: var(--tw-prose-pre-code);
background-color: var(--tw-prose-pre-bg);
padding: 0.857143em 1.14286em;
border-radius: 0.375rem;
margin-top: 1.71429em;
margin-bottom: 1.71429em;
font-size: 0.875em;
font-weight: 400;
line-height: 1.71429;
overflow-x: auto;
}
.prose :where(pre code):not(:where(.not-prose, .not-prose *)) {
font-weight: inherit;
color: inherit;
font-size: inherit;
background-color: transparent;
padding: 0;
}
.prose :where(pre code):not(:where(.not-prose, .not-prose *))::before,
.prose :where(pre code):not(:where(.not-prose, .not-prose *))::after {
content: none;
}
.prose :where(table):not(:where(.not-prose, .not-prose *)) {
table-layout: auto;
width: 100%;
margin-top: 2em;
margin-bottom: 2em;
font-size: 0.875em;
line-height: 1.71429;
}
.prose :where(thead):not(:where(.not-prose, .not-prose *)) {
border-bottom-width: 1px;
border-bottom-color: var(--tw-prose-th-borders);
}
.prose :where(tbody tr):not(:where(.not-prose, .not-prose *)) {
border-bottom-width: 1px;
border-bottom-color: var(--tw-prose-td-borders);
}
.prose :where(th, td):not(:where(.not-prose, .not-prose *)) {
text-align: start;
padding: 0.571429em;
}
.prose :where(.prose > :first-child):not(:where(.not-prose, .not-prose *)) {
margin-top: 0;
}
.prose :where(.prose > :last-child):not(:where(.not-prose, .not-prose *)) {
margin-bottom: 0;
}
}
@layer utilities {
[x-cloak] {
display: none !important;
@@ -42,6 +274,18 @@
background: var(--color-accent);
}
.bg-accent\/10 {
background-color: color-mix(in srgb, var(--color-accent) 10%, transparent);
}
.hover\:bg-accent\/5:hover {
background-color: color-mix(in srgb, var(--color-accent) 5%, transparent);
}
.text-accent {
color: var(--color-accent);
}
.gap-0\.75 {
gap: 0.1875rem;
}
@@ -76,6 +320,10 @@
max-width: var(--content-header);
}
.divide-brd > :not([hidden]) ~ :not([hidden]) {
border-color: var(--border);
}
.line-clamp-1 {
overflow: hidden;
text-overflow: ellipsis;

View File

@@ -1,7 +1,7 @@
# 배포 가이드
## 현재 버전
- `v0.1.29`
- `v0.1.30`
## Git 기본 설정
- 저장소 작성자 정보는 아래 값으로 통일한다.

View File

@@ -1,5 +1,8 @@
# 의사결정 이력
## 2026-04-14 v0.1.30
`prose`는 Tailwind 기본 유틸리티가 아니라 `@tailwindcss/typography` 플러그인 영역인데, 현재 저장소에는 해당 플러그인이 들어있지 않았다. 이번 단계에서는 사용자가 이미 수정한 Tailwind 마크업을 최대한 유지하는 것이 우선이었기 때문에, 의존성을 새로 늘리기보다 `assets/styles/tailwind.css``@layer components`에 원본 소스 기준 타이포그래피 규칙을 직접 옮겨 적용했다. 동시에 `bg-accent/10`처럼 현재 빌드에서 누락되던 유틸리티도 같은 방식으로 보강해 카드 태그 배경과 리스트 구분선이 다시 보이도록 정리했다.
## 2026-04-14 v0.1.29
브라우저 기본 `h1`, `button` 스타일이 계속 남는 문제는 개별 요소 보정보다 Tailwind 전역 초기화 자체를 다시 켜는 편이 더 맞다고 판단했다. 초기 단계에서 `preflight`를 꺼두었지만, 현재처럼 Tailwind 마크업 비중이 커진 상태에서는 기본 리셋이 없는 쪽이 오히려 예측 불가능한 차이를 만들기 때문에 `preflight`를 복원했다.

View File

@@ -1,7 +1,7 @@
# 파일-화면 매핑 가이드
## 현재 버전
- `v0.1.29`
- `v0.1.30`
## 공통 레이아웃
- [default.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/default.hbs): 전체 3열 셸과 공통 자산 로드
@@ -18,7 +18,7 @@
- [index.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/index.hbs): 기본 목록 진입
- [partials/home/hero.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/home/hero.hbs): 홈 히어로 영역
- [partials/home/tabbed-feed.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/home/tabbed-feed.hbs): Latest/Featured/Updated/Categories 탭과 카테고리 개요 행
- [partials/lists/post-items.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/lists/post-items.hbs): Tailwind 기반 리스트형 포스트 카드, 댓글 아이콘, 우측 공유 액션, 메타 정보
- [partials/lists/post-items.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/lists/post-items.hbs): Tailwind 기반 리스트형 포스트 카드, 댓글 아이콘, 우측 공유 액션, 메타 정보, 태그 accent 배지
## 상세 및 아카이브
- [post.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/post.hbs): 포스트 상세
@@ -32,7 +32,7 @@
- [assets/built/tailwind.css](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/assets/built/tailwind.css): Tailwind 빌드 결과물
- [assets/built/alpine.js](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/assets/built/alpine.js): Alpine.js 로컬 배포 파일
- [assets/built/theme.js](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/assets/built/theme.js): 인터랙션 스크립트
- [assets/styles/tailwind.css](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/assets/styles/tailwind.css): Tailwind 입력 파일
- [assets/styles/tailwind.css](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/assets/styles/tailwind.css): Tailwind 입력 파일, `prose` 타이포그래피 규칙, accent/구분선 보조 유틸리티
- [tailwind.config.js](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/tailwind.config.js): Tailwind 스캔 경로, 테마 설정, preflight 초기화 설정
- [routes.yaml.example](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/routes.yaml.example): Ghost 커스텀 라우트 예시
- [package.json](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/package.json): Ghost 테마 메타데이터

View File

@@ -1,7 +1,7 @@
# 기술 명세
## 현재 버전
- `v0.1.29`
- `v0.1.30`
## 테마 개요
- Ghost `v5` 대응 커스텀 테마
@@ -27,6 +27,9 @@
- 리스트형 `post-card`는 Tailwind 유틸리티 중심 마크업으로 구성되며, 썸네일은 `aspect-square sm:aspect-video` 비율을 사용
- 각 카드 항목은 `border-b border-brd` 구분선을 유지하고, 콘텐츠 래퍼는 `min-w-0` 기준으로 줄바꿈 폭을 제어
- 포스트 상세 헤더는 제목, 메타, 공유 버튼, 대표 이미지를 Tailwind 유틸리티 중심 마크업으로 구성하고 상단 단일 태그 라벨은 표시하지 않음
- 포스트 본문은 `prose prose-theme` 클래스를 사용하며, Typography 플러그인 대신 Tailwind 입력 파일에서 원본 기준 타이포그래피 규칙을 직접 제공함
- 본문 `ul`, `ol`은 전역 리스트 리셋과 별개로 `prose` 범위 안에서 실제 마커와 들여쓰기를 다시 적용함
- 태그 배지는 `--color-accent` 기반 배경 혼합색(`bg-accent/10`, `hover:bg-accent/5`)을 사용함
## 주요 스타일 방향
- 밝은 크림톤 배경 + 오렌지 포인트

View File

@@ -1,5 +1,12 @@
# 업데이트 로그
## v0.1.30 - 2026-04-14
- `prose` 본문 타이포그래피 스타일 추가.
- `ul`, `ol`, `blockquote`, `code`, `table` 본문 표현 복구.
- `bg-accent/10`, `hover:bg-accent/5`, `divide-brd` 유틸리티 추가.
- 리스트형 `post-card` 하드코딩 클래스 정리.
- 리스트 메타 구분 슬래시 중복 출력 수정.
## v0.1.29 - 2026-04-14
- Tailwind `preflight` 초기화 다시 활성화.
- `assets/styles/tailwind.css`에 base 레이어 추가.

View File

@@ -1,6 +1,6 @@
{
"name": "ghost-theme-thred-clone",
"version": "0.1.29",
"version": "0.1.30",
"private": true,
"description": "A Ghost theme inspired by the Thred reference layout.",
"keywords": [

View File

@@ -1,5 +1,6 @@
<section class="stack-section home-feed" data-tabs data-home-content>
<div class="tab-row-wrap home-feed__toolbar">
<section class="px-5 sm:px-6 py-4" data-tabs data-home-content>
<div class="max-w-content mx-auto">
<div class="flex gap-2 items-center justify-between border-b border-brd pb-2">
<div class="tab-row home-feed__tabs" role="tablist" aria-label="Homepage sections">
<button class="tab-row__button is-active" type="button" data-tab-trigger="latest">Latest</button>
<button class="tab-row__button" type="button" data-tab-trigger="featured">Featured</button>
@@ -12,7 +13,7 @@
</button>
</div>
<div class="tab-panel is-active" data-tab-panel="latest">
<div class="flex flex-col gap-8 mb-8 is-active" data-tab-panel="latest">
{{> "lists/post-feed"}}
</div>
@@ -54,4 +55,5 @@
{{/get}}
</div>
</div>
</div>
</section>

View File

@@ -1,7 +1,7 @@
<div class="post-list home-post-list">
<div class="post-list home-post-list flex flex-col divide-y divide-brd">
{{#foreach posts}}
<article class="post {{post_class}} relative flex flex-row items-start gap-3 text-typ py-4 group overflow-hidden border-b border-brd" data-post-card{{#if featured}} data-featured{{/if}}>
<a href="{{url}}" data-post-card-media class="flex-1 relative group aspect-square sm:aspect-video min-w-16">
<article class="post {{post_class}} relative flex flex-row items-start gap-3 text-typ py-4 group overflow-hidden" data-post-card{{#if featured}} data-featured{{/if}}>
<a href="{{url}}" data-post-card-media class="flex-1 relative group aspect-square sm:aspect-video min-w-16 ">
{{#if feature_image}}
<figure class="block rounded-theme overflow-hidden" role="none">
<img class="w-full aspect-square sm:aspect-video object-cover rounded-[inherit] hover:opacity-90 transition-all blur-0" src="{{img_url feature_image size="s"}}" alt="{{title}}">
@@ -10,7 +10,7 @@
<span class="block w-full aspect-square sm:aspect-video rounded-theme bg-bgr-tone text-typ-tone text-xs text-center p-4">{{title}}</span>
{{/if}}
</a>
<div class="relative min-w-0 flex-[3] md:flex-[4] flex flex-col gap-1.5 justify-between" data-post-card-content>
<div class="relative min-w-0 flex-3 md:flex-4 flex flex-col gap-1.5 justify-between " data-post-card-content>
<h2 class="text-sm font-medium leading-tight flex flex-wrap gap-y-0.5 gap-x-1.5 items-end max-w-[90%]" data-post-card-title>
<a href="{{url}}" class="hover:opacity-75 flex items-start gap-1.5">
{{#if featured}}
@@ -24,14 +24,12 @@
{{#if excerpt}}
<p class="text-[0.8rem] text-typ-tone leading-tight line-clamp-2 text-ellipsis flex-1" data-post-card-excerpt>{{excerpt words="24"}}</p>
{{/if}}
<div class="flex flex-wrap gap-2 sm:gap-1.5 items-center text-xs text-typ-tone" data-post-card-info>
<div class="flex flex-wrap gap-2 sm:gap-1.5 items-center text-xs text-typ-tone *:after:content-['/'] *:after:ml-2 sm:*:after:ml-1.5 *:after:text-brd *:last:after:hidden!" data-post-card-info>
<time data-post-card-date datetime="{{date format="YYYY-MM-DD"}}">{{date format="MMM D"}}</time>
{{#primary_author}}
<span class="opacity-70">/</span>
<a data-post-card-author href="{{url}}" class="hover:opacity-75">{{name}}</a>
{{/primary_author}}
{{#primary_tag}}
<span class="opacity-70">/</span>
<ul class="flex flex-wrap items-center font-medium" data-post-card-tags>
<li{{#if accent_color}} style="--color-accent: {{accent_color}};"{{/if}}>
<a href="{{url}}" class="bg-accent/10 px-1.5 py-px rounded-sm text-typ hover:bg-accent/5 hover:text-accent">{{name}}</a>
@@ -39,13 +37,11 @@
</ul>
{{/primary_tag}}
{{#unless access}}
<span class="opacity-70">/</span>
<span class="font-medium">Members</span>
{{/unless}}
<span class="opacity-70">/</span>
<a data-post-card-comments class="flex gap-0.5 items-center hover:opacity-75" href="{{url}}#ghost-comments">
<img class="size-3.5 -mt-px pointer-events-none" src="{{asset "icons/chat_bubble.svg"}}" alt="">
{{#if comments}}{{comment_count empty="0" singular="" plural="" autowrap="false"}}{{else}}0{{/if}}
<span class="pointer-events-none">{{#if comments}}{{comment_count empty="0" singular="" plural="" autowrap="false"}}{{else}}0{{/if}}</span>
</a>
</div>
<button data-post-share-toggle class="absolute top-0 md:top-auto md:bottom-0 right-0 flex gap-1 items-center hover:opacity-75 cursor-pointer md:opacity-0 md:invisible group-hover:opacity-100 group-hover:visible transition-[opacity,visibility]" type="button" aria-label="Share this post">

View File

@@ -1,21 +1,18 @@
{{!< default}}
{{#post}}
<main class="content-area content-area--post">
<article class="post-article {{post_class}}">
<section class="px-4 sm:px-5 mt-6 mb-8">
<main class="flex-2 max-w-content">
<section class="px-4 sm:px-[max(2vmin,20px)] mt-6 mb-8">
<div class="max-w-content mx-auto flex flex-col gap-2.5">
<h1 class="font-semibold text-xl sm:text-2xl leading-[1.125]">{{title}}</h1>
<div class="relative border-b border-brd pb-4">
<div class="flex flex-wrap gap-2 sm:gap-1.5 items-center text-xs text-typ-tone" data-post-card-info>
<div class="flex flex-wrap gap-2 sm:gap-1.5 items-center text-xs text-typ-tone *:after:content-['/'] *:after:ml-2 sm:*:after:ml-1.5 *:after:text-brd *:last:after:hidden!" data-post-card-info>
<time data-post-card-date datetime="{{date format="YYYY-MM-DD"}}">{{date format="MMM D, YYYY"}}</time>
{{#primary_author}}
<span class="opacity-70">/</span>
<a data-post-card-author href="{{url}}" class="hover:opacity-75">{{name}}</a>
{{/primary_author}}
{{#if primary_tag}}
<span class="opacity-70">/</span>
<ul class="flex flex-wrap items-center font-medium" data-post-card-tags>
<li{{#if primary_tag.accent_color}} style="--color-accent: {{primary_tag.accent_color}};"{{/if}}>
<a href="{{primary_tag.url}}" class="bg-accent/10 px-1.5 py-px rounded-sm text-typ hover:bg-accent/5 hover:text-accent">{{primary_tag.name}}</a>
@@ -23,7 +20,6 @@
</ul>
{{/if}}
{{#if comments}}
<span class="opacity-70">/</span>
<a data-post-card-comments class="flex gap-0.5 items-center hover:opacity-75" href="#comments">
<img class="size-3.5 -mt-px pointer-events-none" src="{{asset "icons/chat_bubble.svg"}}" alt="">
<span class="pointer-events-none">{{comment_count empty="0" singular="" plural="" autowrap="false"}}</span>
@@ -48,9 +44,10 @@
</figure>
{{/if}}
</div>
</section>
</section>
<article class="post-article {{post_class}}">
<div class="post-body">
<div class="post-body px-4 sm:px-[max(2vmin,20px)]">
<section class="post-content kg-content ghost-content prose prose-theme">
{{content}}
</section>