v0.1.41 theme: 홈/사이드바/추천 모달 동작 정리
Made-with: Cursor
This commit is contained in:
@@ -100,6 +100,7 @@ menu {
|
||||
min-height: calc(100vh - var(--topbar-height));
|
||||
width: min(100%, var(--shell-width));
|
||||
margin: 0 auto;
|
||||
align-items: start;
|
||||
transition: grid-template-columns 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
@@ -109,31 +110,13 @@ menu {
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.site-shell-wrap {
|
||||
height: calc(100vh - var(--topbar-height));
|
||||
}
|
||||
|
||||
.site-shell {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.site-main {
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
.sidebar--left,
|
||||
.sidebar--right {
|
||||
height: 100%;
|
||||
.sidebar.sidebar--left,
|
||||
.sidebar.sidebar--right {
|
||||
position: sticky;
|
||||
top: var(--topbar-height);
|
||||
align-self: start;
|
||||
height: calc(100vh - var(--topbar-height)) !important;
|
||||
max-height: calc(100vh - var(--topbar-height));
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
@@ -310,12 +293,22 @@ body.left-sidebar-collapsed .sidebar--left .sidebar__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 0 6px 16px;
|
||||
padding: 6px 10px 6px 0;
|
||||
border-radius: 18px;
|
||||
transition: background-color 0.22s ease, color 0.22s ease, padding 0.22s ease;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.menu-group .nav a::before {
|
||||
content: "";
|
||||
width: 4px;
|
||||
height: 16px;
|
||||
border-radius: 3px;
|
||||
background: color-mix(in srgb, var(--border) 88%, #ffffff 12%);
|
||||
flex: 0 0 auto;
|
||||
transition: width 0.22s ease, height 0.22s ease, border-radius 0.22s ease, background-color 0.22s ease, transform 0.22s ease;
|
||||
}
|
||||
|
||||
.menu-group .nav a:hover,
|
||||
.menu-sub-link:hover {
|
||||
background: var(--surface-muted);
|
||||
@@ -324,6 +317,33 @@ body.left-sidebar-collapsed .sidebar--left .sidebar__inner {
|
||||
padding-right: 12px;
|
||||
}
|
||||
|
||||
.menu-group .nav li:not(.nav-current) > a:hover::before {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: #cfc7be;
|
||||
transform: translateX(1px);
|
||||
}
|
||||
|
||||
.menu-group .nav .nav-current > a,
|
||||
.menu-group .nav a.nav-current {
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.menu-group .nav .nav-current > a::before,
|
||||
.menu-group .nav a.nav-current::before {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.menu-group .nav .nav-current > a:hover::before,
|
||||
.menu-group .nav a.nav-current:hover::before {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--accent);
|
||||
transform: translateX(1px);
|
||||
}
|
||||
|
||||
.link-list {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -153,28 +153,6 @@
|
||||
|
||||
syncLeftSidebarState();
|
||||
|
||||
var siteMain = document.querySelector(".site-main");
|
||||
var sidebarNodes = document.querySelectorAll(".sidebar--left, .sidebar--right");
|
||||
|
||||
function shouldProxySidebarWheel() {
|
||||
return !tabletMedia.matches && !!siteMain;
|
||||
}
|
||||
|
||||
sidebarNodes.forEach(function (sidebar) {
|
||||
sidebar.addEventListener("wheel", function (event) {
|
||||
if (!shouldProxySidebarWheel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
siteMain.scrollBy({
|
||||
top: event.deltaY,
|
||||
left: 0,
|
||||
behavior: "auto"
|
||||
});
|
||||
}, { passive: false });
|
||||
});
|
||||
|
||||
var tabRoot = document.querySelector("[data-tabs]");
|
||||
if (tabRoot) {
|
||||
var triggers = tabRoot.querySelectorAll("[data-tab-trigger]");
|
||||
@@ -371,6 +349,64 @@
|
||||
|
||||
syncUserMenuToggles();
|
||||
|
||||
var recommendationsPortalTrigger = document.querySelector("[data-portal='recommendations']");
|
||||
var recommendationsPortalTitle = recommendationsPortalTrigger ? recommendationsPortalTrigger.getAttribute("data-portal-title") : "";
|
||||
var recommendationsPortalDescription = recommendationsPortalTrigger ? recommendationsPortalTrigger.getAttribute("data-portal-description") : "";
|
||||
|
||||
function getPortalDocuments() {
|
||||
var docs = [document];
|
||||
|
||||
document.querySelectorAll("iframe").forEach(function (frame) {
|
||||
try {
|
||||
if (frame.contentDocument) {
|
||||
docs.push(frame.contentDocument);
|
||||
}
|
||||
} catch (error) {}
|
||||
});
|
||||
|
||||
return docs;
|
||||
}
|
||||
|
||||
function applyRecommendationsPortalCopy() {
|
||||
if (!recommendationsPortalTitle && !recommendationsPortalDescription) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var hasPatched = false;
|
||||
|
||||
getPortalDocuments().forEach(function (docRoot) {
|
||||
var portalTitle = docRoot.querySelector(".gh-portal-main-title");
|
||||
var portalDescription = docRoot.querySelector(".gh-portal-recommendations-description");
|
||||
|
||||
if (portalTitle && recommendationsPortalTitle) {
|
||||
portalTitle.textContent = recommendationsPortalTitle;
|
||||
hasPatched = true;
|
||||
}
|
||||
|
||||
if (portalDescription && recommendationsPortalDescription) {
|
||||
portalDescription.textContent = recommendationsPortalDescription;
|
||||
hasPatched = true;
|
||||
}
|
||||
});
|
||||
|
||||
return hasPatched;
|
||||
}
|
||||
|
||||
if (recommendationsPortalTrigger && (recommendationsPortalTitle || recommendationsPortalDescription)) {
|
||||
recommendationsPortalTrigger.addEventListener("click", function () {
|
||||
applyRecommendationsPortalCopy();
|
||||
var attempts = 0;
|
||||
var maxAttempts = 20;
|
||||
var retryTimer = window.setInterval(function () {
|
||||
attempts += 1;
|
||||
var done = applyRecommendationsPortalCopy();
|
||||
if (done || attempts >= maxAttempts) {
|
||||
window.clearInterval(retryTimer);
|
||||
}
|
||||
}, 100);
|
||||
});
|
||||
}
|
||||
|
||||
function updateLoadMoreState(pagination, nextUrl, loading) {
|
||||
var trigger = pagination.querySelector("[data-load-more-trigger]");
|
||||
if (!trigger) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 배포 가이드
|
||||
|
||||
## 현재 버전
|
||||
- `v0.1.40`
|
||||
- `v0.1.41`
|
||||
|
||||
## Git 기본 설정
|
||||
- 저장소 작성자 정보는 아래 값으로 통일한다.
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# 의사결정 이력
|
||||
|
||||
## 2026-04-16 v0.1.41
|
||||
Ghost Portal Recommendations 모달의 제목/설명은 렌더링 시점이 일정하지 않고, 경우에 따라 iframe 문서 내부에서 생성되어 기존 문서 단일 선택자 접근으로는 치환이 실패했다. 또한 이전 구현은 전역 `MutationObserver`를 상시 감시로 두고 있어 페이지 체감 지연 가능성이 있었다. 그래서 클릭 시점에 한정해 메인 문서와 접근 가능한 iframe 문서를 함께 탐색하고, 짧은 재시도 구간에서만 텍스트를 치환하는 방식으로 변경했다. 이 방식은 치환 성공률을 높이면서도 상시 관찰 비용을 제거해 안정성을 높인다.
|
||||
|
||||
## 2026-04-16 v0.1.40
|
||||
홈 메인에서 4개 탭을 유지하면 원본 화면과 다르게 상단 컨트롤이 과해지고, 실제 요구사항인 Featured 강조 흐름이 약해진다. 그래서 탭형 전환 UI를 홈 진입 구조에서 제거하고, Featured가 있을 때만 수평 슬라이드로 노출한 뒤 Latest 리스트를 바로 이어 붙이는 구성으로 정리했다. 이 방식은 원본의 정보 우선순위(Featured -> Latest)를 그대로 따르면서 Ghost `featured:true` 데이터도 자연스럽게 재사용할 수 있다.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 파일-화면 매핑 가이드
|
||||
|
||||
## 현재 버전
|
||||
- `v0.1.40`
|
||||
- `v0.1.41`
|
||||
|
||||
## 공통 레이아웃
|
||||
- [default.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/default.hbs): 전체 3열 셸, 1296px 공통 폭 계산, 공통 자산 로드
|
||||
@@ -11,7 +11,7 @@
|
||||
- [tags-index.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/tags-index.hbs): `/tags/` 커스텀 라우트용 태그 디렉터리
|
||||
- [authors-index.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/authors-index.hbs): `/authors/` 커스텀 라우트용 작성자 디렉터리
|
||||
- [partials/site/topbar.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/site/topbar.hbs): 상단 3열 헤더, 중앙 검색, 좌측 사이드바 토글
|
||||
- [partials/site/sidebar-right.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/site/sidebar-right.hbs): 우측 287px 사이드바, Tailwind 기반 작성자/구독/추천/푸터 구성
|
||||
- [partials/site/sidebar-right.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/partials/site/sidebar-right.hbs): 우측 287px 사이드바, Ghost Recommendations 기반 추천 링크/구독/푸터 구성
|
||||
|
||||
## 홈 및 목록
|
||||
- [home.hbs](/Users/bicute/Desktop/UGREEN/GHOST%20THEME/home.hbs): 메인 홈
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 기술 명세
|
||||
|
||||
## 현재 버전
|
||||
- `v0.1.40`
|
||||
- `v0.1.41`
|
||||
|
||||
## 테마 개요
|
||||
- Ghost `v5` 대응 커스텀 테마
|
||||
@@ -27,6 +27,8 @@
|
||||
- `tags-index.hbs`, `authors-index.hbs`는 Ghost `routes.yaml` 커스텀 라우트로 `/tags/`, `/authors/`에 연결됨
|
||||
- 로컬 개발 환경의 실제 라우트 설정은 `.docker/ghost/content/settings/routes.yaml`을 기준으로 사용함
|
||||
- 홈 메인 피드는 히어로, Featured 수평 슬라이드, Latest 리스트 구성을 사용함
|
||||
- 우측 사이드바 `Recommended` 섹션은 Ghost `recommendations` 데이터를 우선 사용하며, 항목별 외부 링크와 favicon 표시를 지원함
|
||||
- Recommendations Portal 모달의 제목/설명은 트리거 버튼의 `data-portal-title`, `data-portal-description` 값으로 오픈 시점에 동기화함
|
||||
- 리스트형 `post-card`는 Tailwind 유틸리티 중심 마크업으로 구성되며, 썸네일은 `aspect-square sm:aspect-video` 비율을 사용
|
||||
- 각 카드 항목은 `border-b border-brd` 구분선을 유지하고, 콘텐츠 래퍼는 `min-w-0` 기준으로 줄바꿈 폭을 제어
|
||||
- 포스트 상세 헤더는 제목, 메타, 공유 버튼, 대표 이미지를 Tailwind 유틸리티 중심 마크업으로 구성하고 상단 단일 태그 라벨은 표시하지 않음
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# 업데이트 로그
|
||||
|
||||
## v0.1.41 - 2026-04-16
|
||||
- `package.json` 버전을 `0.1.41`로 증가.
|
||||
- `docs/spec.md`, `docs/map.md`, `docs/deploy.md` 현재 버전을 `v0.1.41`로 동기화.
|
||||
- `docs/history.md`에 `v0.1.41` 의사결정 이력(Portal 문구 치환 안정화) 추가.
|
||||
- `assets/built/theme.js` Portal 문구 치환 로직을 메인 문서+iframe 탐색 기반 재시도 방식으로 보정하고, 상시 `MutationObserver`를 제거해 지연 가능성을 완화.
|
||||
|
||||
## v0.1.40 - 2026-04-16
|
||||
- 문서 버전 표기를 `v0.1.40`으로 정합성 수정.
|
||||
- `docs/history.md` 의사결정 이력 최신 버전 항목 추가.
|
||||
@@ -24,6 +30,21 @@
|
||||
- `partials/lists/post-feed.hbs` Featured 카드에서 썸네일 미존재 시 텍스트를 검은색으로 보정하고, 썸네일 카드와 동일한 라디우스/테두리 형태로 통일.
|
||||
- `assets/built/screen.css` Featured 가로 슬라이드 스크롤바 비노출 처리 추가.
|
||||
- `partials/site/sidebar-right.hbs` 우측 사이드바를 세로 플렉스 구조로 보정해 하단 footer가 화면 하단에 고정되도록 수정.
|
||||
- `assets/built/screen.css` 좌측 Home pages 하위 링크의 배지/hover 동작을 원본처럼 사각 배지→원형 전환 및 현재 페이지 accent 표시로 보정.
|
||||
- `assets/built/screen.css`, `assets/built/theme.js` 데스크톱 스크롤을 본문 전용 내부 스크롤에서 문서 스크롤로 전환해 스크롤바가 브라우저 우측에 표시되도록 정리.
|
||||
- `assets/built/screen.css` 현재 활성화된 좌측 하위 메뉴 hover 시 배지가 회색으로 바뀌지 않고 accent 색상을 유지하도록 우선순위 보정.
|
||||
- `assets/built/screen.css` 그리드 컨테이너 `align-items`를 보정해 사이드바 sticky 고정을 안정화하고, 스크롤 시 사이드바 동반 이동/푸터 이탈 현상을 완화.
|
||||
- `assets/built/screen.css` `h-full` 클래스 우선순위로 깨지던 사이드바 뷰포트 고정을 `sidebar.sidebar--*` 선택자와 높이 보정으로 수정해 footer/nav가 화면 하단에 유지되도록 보정.
|
||||
- `assets/built/screen.css` 하위 메뉴 hover 비활성 선택자에서 `a:not(.nav-current)` 조건을 제거해 활성 항목 hover 시 accent 배지가 회색으로 덮이지 않도록 수정.
|
||||
- `partials/lists/post-items.hbs` 본문 요약 유무와 길이에 관계없이 카드 콘텐츠 높이가 균일하도록 콘텐츠 영역 높이/요약 최소 높이를 보정.
|
||||
- `partials/site/sidebar-right.hbs` Recommended 섹션을 featured 글 목록에서 Ghost `recommendations` 데이터 기반 외부 링크 목록으로 전환하고, 항목별 favicon/타이틀 렌더링을 추가.
|
||||
- `docs/spec.md`, `docs/map.md` 추천 섹션 데이터 소스 변경 기준으로 문서 정합성 갱신.
|
||||
- `partials/site/sidebar-right.hbs` Recommended 목록 렌더링을 `{{get}}` 호출 대신 `data-recommendations` 기반 Portal 자동 주입 방식으로 전환.
|
||||
- `partials/site/sidebar-right.hbs`, `partials/recommendations.hbs` Recommended를 공식 `{{recommendations}}` 헬퍼 기반 렌더링으로 전환하고 커스텀 recommendations partial을 추가.
|
||||
- `partials/lists/post-items.hbs` 메타 구분자(`/`)를 직접 자식 선택자 기반으로 보정해 마지막 항목 뒤에는 표시되지 않도록 수정.
|
||||
- `partials/recommendations.hbs` 추천 favicon 크기/라디우스를 원본 기준(`18px`, `8px`)으로 보정.
|
||||
- `partials/site/sidebar-right.hbs`, `assets/built/theme.js` Portal Recommendations 모달이 열릴 때 제목/설명을 버튼 데이터 속성(`발견하기`) 기준으로 치환하도록 보정.
|
||||
- `assets/built/theme.js` Portal 문구 치환 로직을 메인 문서+iframe 탐색 기반 재시도 방식으로 보정하고, 상시 `MutationObserver`를 제거해 지연 가능성을 완화.
|
||||
|
||||
## v0.1.39 - 2026-04-16
|
||||
- `tags-index.hbs` 태그 카드 목록 마크업을 원본(Thred) 구조 기준으로 변환 수정.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ghost-theme-thred-clone",
|
||||
"version": "0.1.40",
|
||||
"version": "0.1.41",
|
||||
"private": true,
|
||||
"description": "A Ghost theme inspired by the Thred reference layout.",
|
||||
"keywords": [
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
<h1 class="text-xl md:text-2xl font-semibold text-balance leading-[1.125]">
|
||||
Ideas <em>published</em> for meaningful conversation, <em>discussed</em> and shaped by the community
|
||||
</h1>
|
||||
{{#if @site.description}}
|
||||
<p class="text-base text-balance text-typ-tone max-w-md leading-snug">{{@site.description}}</p>
|
||||
{{/if}}
|
||||
<p class="text-base text-balance text-typ-tone max-w-md leading-snug">A modern Ghost theme for curated, community-driven publishing, where members join the conversation.</p>
|
||||
<form class="group relative flex w-full max-w-xs flex-col items-start mt-1" data-members-form="subscribe">
|
||||
<fieldset class="w-full flex gap-2 flex-wrap text-sm">
|
||||
<legend class="sr-only">Personal information</legend>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div class="overflow-hidden mt-4">
|
||||
<div class="featured-slider flex gap-4 sm:gap-5 overflow-x-auto snap-x snap-mandatory scroll-smooth" data-featured-track style="scrollbar-width: none; -ms-overflow-style: none;">
|
||||
{{#foreach posts}}
|
||||
<a href="{{url}}" class="featured-slider__item relative bg-bgr-tone block group shrink-0 snap-start basis-[78%] sm:basis-[58%] lg:basis-[38%]">
|
||||
<a href="{{url}}" class="featured-slider__item relative block group shrink-0 snap-start basis-[78%] sm:basis-[58%] lg:basis-[38%]">
|
||||
{{#if feature_image}}
|
||||
<figure class="relative block rounded-theme overflow-hidden contrast-125 brightness-75 group-hover:contrast-110 group-hover:brightness-90 transition-all" role="none">
|
||||
<img class="w-full aspect-video object-cover rounded-[inherit]" src="{{img_url feature_image size="m"}}" alt="{{title}}">
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<span class="block w-full aspect-square sm:aspect-video rounded-lg 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-0.5 justify-between h-full self-stretch" 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}}
|
||||
@@ -23,10 +23,13 @@
|
||||
<span>{{title}}</span>
|
||||
</a>
|
||||
</h2>
|
||||
{{#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 *:after:content-['/'] *:after:ml-2 sm:*:after:ml-1.5 *:after:text-brd *:last:after:hidden!" data-post-card-info>
|
||||
|
||||
<p class="text-[0.8rem] text-typ-tone leading-tight line-clamp-2 text-ellipsis flex-1 min-h-[2.2rem]" data-post-card-excerpt>
|
||||
{{#if excerpt}}
|
||||
{{excerpt words="24"}}
|
||||
{{/if}}
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-2 sm:gap-1.5 items-center text-xs text-typ-tone [&>*:not(:last-child)]:after:content-['/'] [&>*:not(:last-child)]:after:ml-2 sm:[&>*:not(:last-child)]:after:ml-1.5 [&>*:not(:last-child)]:after:text-brd" data-post-card-info>
|
||||
<time data-post-card-date datetime="{{date format="YYYY-MM-DD"}}">{{date format="MMM D"}}</time>
|
||||
{{#primary_author}}
|
||||
<a data-post-card-author href="{{url}}" class="hover:opacity-75">{{name}}</a>
|
||||
@@ -41,8 +44,10 @@
|
||||
{{#unless access}}
|
||||
<span class="font-medium">Members</span>
|
||||
{{/unless}}
|
||||
<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="">
|
||||
<a data-post-card-comments class="flex gap-1 items-center hover:opacity-75" href="{{url}}#ghost-comments">
|
||||
<i class="icon icon-comments size-3.5 stroke-2 -mt-px pointer-events-none" role="presentation">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-message-circle"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 20l1.3 -3.9c-2.324 -3.437 -1.426 -7.872 2.1 -10.374c3.526 -2.501 8.59 -2.296 11.845 .48c3.255 2.777 3.695 7.266 1.029 10.501c-2.666 3.235 -7.615 4.215 -11.574 2.293l-4.7 1"></path></svg>
|
||||
</i>
|
||||
<span class="pointer-events-none">{{#if comments}}{{comment_count empty="0" singular="" plural="" autowrap="false"}}{{else}}0{{/if}}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
14
partials/recommendations.hbs
Normal file
14
partials/recommendations.hbs
Normal file
@@ -0,0 +1,14 @@
|
||||
{{#if recommendations}}
|
||||
<ul class="flex flex-col gap-1 rounded-theme overflow-hidden" data-recommendations="">
|
||||
{{#each recommendations as |rec|}}
|
||||
<li>
|
||||
<a class="py-1 text-[0.8rem] leading-tight flex items-center gap-2 hover:opacity-75" href="{{rec.url}}" data-recommendation="{{rec.id}}" target="_blank" rel="noopener">
|
||||
{{#if rec.favicon}}
|
||||
<img class="w-[18px] h-[18px] rounded-[8px] aspect-square object-cover" src="{{rec.favicon}}" alt="" loading="lazy" onerror="this.style.display='none'">
|
||||
{{/if}}
|
||||
<h3 class="font-medium line-clamp-1 text-ellipsis overflow-hidden" title="{{rec.title}}">{{rec.title}}</h3>
|
||||
</a>
|
||||
</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
{{/if}}
|
||||
@@ -78,7 +78,8 @@
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="sidebar-card sidebar-card--authors border-b border-brd px-5 sm:px-6 py-4 sm:py-5 xl:pl-0 pr-3 sm:pr-3 flex flex-col gap-1.5" x-data="{ authorsOpen: window.innerWidth >= 1024 }" x-init="window.addEventListener('resize', () => { authorsOpen = window.innerWidth >= 1024 })" data-sidebar-authors>
|
||||
{{!-- 작가 목록 섹션 (주석으로 유지) --}}
|
||||
{{!-- <section class="sidebar-card sidebar-card--authors border-b border-brd px-5 sm:px-6 py-4 sm:py-5 xl:pl-0 pr-3 sm:pr-3 flex flex-col gap-1.5" x-data="{ authorsOpen: window.innerWidth >= 1024 }" x-init="window.addEventListener('resize', () => { authorsOpen = window.innerWidth >= 1024 })" data-sidebar-authors>
|
||||
<button class="sidebar-card__trigger flex items-center gap-1 justify-between cursor-pointer pr-2 hover:opacity-75" type="button" @click="authorsOpen = !authorsOpen" :aria-expanded="authorsOpen.toString()">
|
||||
<span class="sidebar-card__eyebrow uppercase font-medium text-xs">Authors</span>
|
||||
<span class="sidebar-card__chevron" aria-hidden="true">
|
||||
@@ -108,7 +109,7 @@
|
||||
{{/foreach}}
|
||||
{{/get}}
|
||||
</ul>
|
||||
</section>
|
||||
</section> --}}
|
||||
|
||||
<span class="flex-1"></span>
|
||||
|
||||
|
||||
@@ -47,43 +47,55 @@
|
||||
<h2 class="uppercase font-medium text-xs text-typ-tone">Follow</h2>
|
||||
<nav class="relative flex flex-wrap items-center gap-1 text-typ text-sm z-10">
|
||||
{{!-- {{#if @site.facebook}}<a href="{{social_url type="facebook"}}" class="hover:opacity-75 p-0.5" aria-label="Facebook">f</a>{{/if}} --}}
|
||||
{{#if @site.twitter}}<a href="{{social_url type="twitter"}}" class="w-5 h-5 hover:opacity-75 p-0.5" aria-label="X">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-x" width="20" height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M4 4l11.733 16h4.267l-11.733 -16z"></path>
|
||||
<path d="M4 20l6.768 -6.768m2.46 -2.46l6.772 -6.772"></path>
|
||||
</svg>
|
||||
</a>{{/if}}
|
||||
{{#if @site.twitter}}
|
||||
<a href="https://x.com/ghost" class="hover:opacity-75 p-0.5" aria-label="Twitter">
|
||||
<i class="icon icon-brand-x size-4 stroke-2" role="presentation">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-brand-x" width="16" height="16" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M4 4l11.733 16h4.267l-11.733 -16z"></path>
|
||||
<path d="M4 20l6.768 -6.768m2.46 -2.46l6.772 -6.772"></path>
|
||||
</svg>
|
||||
</i><span class="hidden">Twitter</span></a>
|
||||
{{/if}}
|
||||
|
||||
<a href="{{@site.url}}/rss/" class="hover:w-5 h-5 opacity-75 p-0.5" aria-label="RSS">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-rss" width="20" height="20" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<circle cx="5" cy="19" r="1"></circle>
|
||||
<path d="M4 4a16 16 0 0 1 16 16"></path>
|
||||
<path d="M4 11a9 9 0 0 1 9 9"></path>
|
||||
</svg>
|
||||
<i class="icon icon-rss size-4 stroke-2" role="presentation">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-rss" width="16" height="16" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<circle cx="5" cy="19" r="1"></circle>
|
||||
<path d="M4 4a16 16 0 0 1 16 16"></path>
|
||||
<path d="M4 11a9 9 0 0 1 9 9"></path>
|
||||
</svg>
|
||||
</i>
|
||||
</a>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<section class="px-4 sm:px-5 py-4 sm:py-5 xl:pr-1 flex flex-col gap-1.5 border-b border-brd">
|
||||
<div class="flex items-center justify-between gap-2 mb-2">
|
||||
<h2 class="uppercase font-medium text-xs text-typ-tone">Recommended</h2>
|
||||
<button class="text-sm font-medium flex items-center gap-1 rounded-btn group bg-bgr text-typ hover:text-typ-tone cursor-pointer gh-portal-close">↗</button>
|
||||
<h2 class="uppercase font-bold text-xs text-typ-tone">발견하기</h2>
|
||||
<button data-portal="recommendations" data-portal-title="발견하기" data-portal-description="회원님이 좋아하실 만한 다른 사이트들이에요." class="text-sm font-medium flex items-center gap-1 rounded-btn group bg-bgr text-typ hover:text-typ-tone cursor-pointer gh-portal-close">
|
||||
<span class="sr-only">모두 보기</span>
|
||||
<i class="icon icon-arrow-up-right size-4 stroke-2" role="presentation">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M17 7l-10 10"></path>
|
||||
<path d="M8 7l9 0l0 9"></path>
|
||||
</svg>
|
||||
</i>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="flex flex-col gap-1 rounded-theme overflow-hidden">
|
||||
{{#get "posts" filter="featured:true" limit="3" include="tags"}}
|
||||
{{#foreach posts}}
|
||||
<li><a href="{{url}}" class="py-1 text-[0.8rem] leading-tight flex items-center gap-2 hover:opacity-75">{{title}}</a></li>
|
||||
{{/foreach}}
|
||||
{{else}}
|
||||
<li><a href="{{@site.url}}" class="py-1 text-[0.8rem] leading-tight flex items-center gap-2 hover:opacity-75">{{@site.title}}</a></li>
|
||||
{{/get}}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section class="px-4 sm:px-5 py-4 sm:py-5 xl:pr-1 flex flex-col gap-2.5 border-b border-brd">
|
||||
<p class="text-sm white-space: pre-wrap;">{{@site.title}} is a thoughtfully designed Ghost theme inspired by editorial communities, with flexible settings that let you shape it to your publication.</p>
|
||||
<a class="button button--accent" href="{{@site.url}}">About {{@site.title}}</a>
|
||||
{{#match @site.recommendations_enabled}}
|
||||
{{recommendations limit="4"}}
|
||||
{{else}}
|
||||
<ul class="flex flex-col gap-1 rounded-theme overflow-hidden">
|
||||
<li>
|
||||
<a href="{{@site.url}}" class="py-1 text-[0.8rem] leading-tight flex items-center gap-2 hover:opacity-75">
|
||||
<h3 class="font-medium line-clamp-1 text-ellipsis overflow-hidden">{{@site.title}}</h3>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
{{/match}}
|
||||
</section>
|
||||
|
||||
{{#is "post"}}
|
||||
|
||||
8
post.hbs
8
post.hbs
@@ -19,12 +19,14 @@
|
||||
</li>
|
||||
</ul>
|
||||
{{/if}}
|
||||
{{#if comments}}
|
||||
{{!-- {{#if comments}} --}}
|
||||
<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="">
|
||||
<i class="icon icon-comments size-3.5 stroke-2 -mt-px pointer-events-none" role="presentation">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon icon-tabler icons-tabler-outline icon-tabler-message-circle"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M3 20l1.3 -3.9c-2.324 -3.437 -1.426 -7.872 2.1 -10.374c3.526 -2.501 8.59 -2.296 11.845 .48c3.255 2.777 3.695 7.266 1.029 10.501c-2.666 3.235 -7.615 4.215 -11.574 2.293l-4.7 1"></path></svg>
|
||||
</i>
|
||||
<span class="pointer-events-none">{{comment_count empty="0" singular="" plural="" autowrap="false"}}</span>
|
||||
</a>
|
||||
{{/if}}
|
||||
{{!-- {{/if}} --}}
|
||||
</div>
|
||||
|
||||
<button data-post-share-toggle class="absolute bottom-4 right-0 flex gap-1 items-center hover:opacity-75 cursor-pointer" type="button" aria-label="Share this post">
|
||||
|
||||
Reference in New Issue
Block a user