fix: resolve merge conflicts

This commit is contained in:
radishzzz 2025-05-28 20:56:38 +01:00
commit 0cbb8402b9
25 changed files with 311 additions and 242 deletions

View file

@ -1,3 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M7.2 1h14.4v17.7l-1.3.5V2.5H6.7zM2.3 4.9h15.4V23H2.3zm14.1 1.5H3.6v15.1h12.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 159 B

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M6.9.8v18h14.5V.8zm12.8 16h-11v-14h11z"/>
<path d="M4.3 21.2V5.6l-1.7.5v17.1h14.3l.6-2z"/>
</svg>

After

Width:  |  Height:  |  Size: 171 B

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M9 20 .9 11.9l1.2-.6L9 17.6 22.5 5l.6 1z"/>
<path d="m23.1 6.4-1.3-1.3L9.4 16.6l-6.3-5.4-1.2 1.2L9.4 20z"/>
</svg>

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 133 B

Before After
Before After

View file

@ -10,8 +10,7 @@ const { waline: { serverURL = '', emoji = [], search = false, imageUploader = fa
class="mt-16"
></div>
<!-- >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
<!-- Waline Script >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
<script
is:inline
define:vars={{
@ -37,8 +36,7 @@ function initWaline() {
init({
el: '#waline',
serverURL,
// Share comments on posts in different languages
path: window.location.pathname.replace(/^\/([a-z]{2}(-[a-z]{2})?)\//, '/'),
path: window.location.pathname.replace(/^\/([a-z]{2}(-[a-z]{2})?)\//, '/'), // Share comments on posts in different languages
lang: currentWalineLang,
emoji,
dark: 'html.dark',

View file

@ -14,14 +14,16 @@ import GoBackIcon from '@/assets/icons/go-back.svg';
/>
</button>
<!-- Go Back Script >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
<!-- Go Back Script >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -->
<script>
function setupBackButton() {
document.getElementById('back-button')?.addEventListener('click', () => {
// Navigate back if history exists
if (window.history.length > 1) {
window.history.back()
}
else {
// Fallback to homepage
const siteTitleLink = document.getElementById('site-title-link')
if (siteTitleLink) {
siteTitleLink.click()

View file

@ -1,14 +1,23 @@
<script>
const copyIcons = {
copy: `<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"/>
</svg>`,
success: `<svg viewBox="0 0 24 24" fill="currentColor">
<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
</svg>`,
copy:
`<svg
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M6.9.8v18h14.5V.8zm12.8 16h-11v-14h11z"/>
<path d="M4.3 21.2V5.6l-1.7.5v17.1h14.3l.6-2z"/>
</svg>`,
success:
`<svg
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="m23.1 6.4-1.3-1.3L9.4 16.6l-6.3-5.4-1.2 1.2L9.4 20z"/>
</svg>`,
}
// Store active timeouts to prevent memory leaks
// Track timeout references for each button to manage icon state transitions
const activeTimeouts = new WeakMap<HTMLButtonElement, ReturnType<typeof setTimeout>>()
async function handleCopy(button: HTMLButtonElement) {
@ -18,32 +27,37 @@ async function handleCopy(button: HTMLButtonElement) {
try {
await navigator.clipboard.writeText(code)
// Clear existing timeout to prevent visual glitches on multiple clicks
// Clear existing timeout to prevent icon state conflicts on multiple clicks
const existingTimeout = activeTimeouts.get(button)
if (existingTimeout) {
clearTimeout(existingTimeout)
}
button.innerHTML = copyIcons.success
button.classList.add('copy-success')
// Set timeout to revert to copy icon after 2 seconds
// Set timeout to revert to copy icon after 1.5s
const timeoutId = setTimeout(() => {
button.innerHTML = copyIcons.copy
button.classList.remove('copy-success')
activeTimeouts.delete(button)
}, 1000)
}, 1500)
activeTimeouts.set(button, timeoutId)
}
catch {
}
}
// Initialize copy buttons with icons and mark them to prevent duplicate initialization
function setupCodeCopyButtons() {
// Only initialize buttons that haven't been initialized yet
document.querySelectorAll<HTMLButtonElement>('.code-copy-button:not([data-initialized])').forEach((button) => {
button.innerHTML = copyIcons.copy
button.setAttribute('data-initialized', 'true')
})
document
.querySelectorAll<HTMLButtonElement>('.code-copy-button:not([data-initialized])')
.forEach((button) => {
button.innerHTML = copyIcons.copy
button.setAttribute('data-initialized', 'true')
})
}
// Use event delegation for better performance

View file

@ -12,7 +12,7 @@ function setupGithubCards() {
observer.unobserve(entry.target)
}
})
}, { rootMargin: '400px' })
}, { rootMargin: '500px' })
Array.from(githubCards).forEach(card => observer.observe(card))
}

View file

@ -2,7 +2,7 @@
import { gsap } from 'gsap'
function setupPostPageAnimation() {
// Elements
// Animated Elements
const postContent = document.getElementById('gsap-post-page-content')
const postContentChildren = postContent ? Array.from(postContent.children) : []
const tocContainer = document.getElementById('toc-container')
@ -10,7 +10,7 @@ function setupPostPageAnimation() {
const tocList = document.getElementById('toc-list')
const tocListChildren = tocList ? Array.from(tocList.children) : []
const backButton = document.getElementById('back-button')
const dateElement = document.getElementById('gsap-post-page-date')
const postDate = document.getElementById('gsap-post-page-date')
// Screen Size Check
const isLargeScreen = window.matchMedia('(min-width: 1024px)').matches
@ -38,8 +38,8 @@ function setupPostPageAnimation() {
}
// Post Date
if (dateElement) {
gsap.to(dateElement, {
if (postDate) {
gsap.to(postDate, {
opacity: 1,
y: 0,
duration: 0.5,

View file

@ -65,9 +65,3 @@ function lazySetupPhotoSwipe() {
lazySetupPhotoSwipe()
document.addEventListener('astro:page-load', lazySetupPhotoSwipe)
</script>
<style is:global>
.pswp .pswp__bg {
--at-apply: 'bg-background!'
}
</style>

View file

@ -96,20 +96,18 @@ const filteredHeadings = headings.filter(heading =>
--at-apply: 'ml-4 font-semibold 2xl:hidden';
}
.toc-list {
--at-apply: 'mb-3 mt-1 list-none pl-0 space-y-1.1 2xl:(mb-2 space-y-1)';
--at-apply: 'mb-2.5 mt-1 list-none pl-0 space-y-1.1 2xl:(mb-1 space-y-1)';
}
.toc-link-h2, .toc-link-h3, .toc-link-h4 {
--at-apply: 'text-balance text-sm font-normal no-underline 2xl:(text-3.2 c-secondary/60 transition-colors transition-font-weight duration-300 ease-out hover:c-secondary hover:font-medium)';
}
.toc-list > :first-child {
--at-apply: 'mt-0';
--at-apply: 'text-balance text-sm font-normal no-underline 2xl:(text-3.2 c-secondary/60 transition-colors transition-font-weight ease-out hover:c-secondary hover:font-medium)';
}
/* Initial collapsed state with zero height grid row */
.accordion-wrapper {
--at-apply: 'grid rows-[0fr] transition-all duration-350 ease-in-out';
}
.accordion-content {
--at-apply: 'max-h-59 overflow-hidden pl-4 pr-6 2xl:(max-h-[calc(100vh-26.5rem)] pl-1)';
--at-apply: 'max-h-59.3 overflow-hidden pl-4 pr-6 2xl:(max-h-[calc(100vh-26.75rem)] pl-1)';
}
/* When toggle is checked, expand the wrapper to show content */

View file

@ -187,8 +187,8 @@ preload: {
// link prefetch strategies
linkPrefetch: 'viewport' // hover, tap, viewport, load
// image hosting url
imageHostURL: 'https://image.radishzz.cc'
// optimize remote images in Markdown files to avoid cumulative layout shift
imageHostURL: 'https://image.radishzz.cc'
// custom google analytics js
// for users who route analytics javascript to a customized domain
customGoogleAnalyticsJS: ''
@ -271,7 +271,7 @@ getImageOptions: (_path, page) => ({
[RSS feed page](https://retypeset.radishzz.cc/en/rss.xml) styles.
```html
<!-- public/rss/rss-style.xsl -->
<!-- public/feeds/xxx-style.xsl -->
<style type="text/css">
body{color:oklch(25% 0.005 298)} /* Font color */

View file

@ -187,8 +187,8 @@ preload: {
// estrategias de precarga de enlaces
linkPrefetch: 'viewport' // hover, tap, viewport, load
// URL de alojamiento de imágenes
imageHostURL: 'https://image.radishzz.cc'
// optimizar imágenes remotas en archivos Markdown para evitar cambios de diseño acumulativos
imageHostURL: 'https://image.radishzz.cc'
// js personalizado de google analytics
// para usuarios que redirigen javascript de analytics a un dominio personalizado
customGoogleAnalyticsJS: ''
@ -271,7 +271,7 @@ getImageOptions: (_path, page) => ({
Estilos de [página del feed RSS](https://retypeset.radishzz.cc/es/rss.xml).
```html
<!-- public/rss/rss-style.xsl -->
<!-- public/feeds/xxx-style.xsl -->
<style type="text/css">
body{color:oklch(25% 0.005 298)} /* Color de fuente */

View file

@ -26,7 +26,7 @@ site: {
subtitle: 'Revive the beauty of typography'
// サイト説明
description: 'Retypeset is a static blog theme...'
// 上記の静的設定ではなく src/i18n/ui.ts の多言語タイトル/サブタイトル/説明を使用
// 上記の静的設定の代わりに src/i18n/ui.ts の多言語タイトル/サブタイトル/説明を使用
i18nTitle: true // true, false
// 著者名
author: 'radishzz'
@ -187,8 +187,8 @@ preload: {
// リンクプリフェッチ戦略
linkPrefetch: 'viewport' // hover, tap, viewport, load
// 画像ホスティング URL
imageHostURL: 'https://image.radishzz.cc'
// Markdownファイル内のリモート画像を最適化してレイアウトシフトを防止
imageHostURL: 'https://image.radishzz.cc'
// カスタム Google Analytics JS
// アナリティクス JavaScript をカスタムドメインにルーティングするユーザー向け
customGoogleAnalyticsJS: ''
@ -271,7 +271,7 @@ getImageOptions: (_path, page) => ({
[RSSフィードページ](https://retypeset.radishzz.cc/ja/rss.xml)スタイル。
```html
<!-- public/rss/rss-style.xsl -->
<!-- public/feeds/xxx-style.xsl -->
<style type="text/css">
body{color:oklch(25% 0.005 298)} /* フォントカラー */

View file

@ -26,7 +26,7 @@ site: {
subtitle: 'Revive the beauty of typography'
// описание сайта
description: 'Retypeset is a static blog theme...'
// использовать многоязычные заголовок/подзаголовок/описание из src/i18n/ui.ts, а не статические выше
// использовать многоязычные заголовок/подзаголовок/описание из src/i18n/ui.ts вместо статических выше
i18nTitle: true // true, false
// имя автора
author: 'radishzz'
@ -187,8 +187,8 @@ preload: {
// стратегии предзагрузки ссылок
linkPrefetch: 'viewport' // hover, tap, viewport, load
// URL хостинга изображений
imageHostURL: 'https://image.radishzz.cc'
// оптимизировать удаленные изображения в файлах Markdown для избежания накопления сдвига макета
imageHostURL: 'https://image.radishzz.cc'
// пользовательский скрипт Google Analytics
// для пользователей, которые направляют JavaScript аналитики на собственный домен
customGoogleAnalyticsJS: ''
@ -271,7 +271,7 @@ getImageOptions: (_path, page) => ({
Стили [страницы RSS-ленты](https://retypeset.radishzz.cc/ru/rss.xml).
```html
<!-- public/rss/rss-style.xsl -->
<!-- public/feeds/xxx-style.xsl -->
<style type="text/css">
body{color:oklch(25% 0.005 298)} /* Цвет шрифта */

View file

@ -26,7 +26,7 @@ site: {
subtitle: 'Revive the beauty of typography'
// 站點描述
description: 'Retypeset is a static blog theme...'
// 使用 src/i18n/ui.ts 中的多語言標題/副標題/站點描述,而不是上方靜態配置
// 使用 src/i18n/ui.ts 中的多語言標題/副標題/站點描述,代替上方靜態配置
i18nTitle: true // true, false
// 作者名稱
author: 'radishzz'
@ -187,8 +187,8 @@ preload: {
// 鏈接預加載策略
linkPrefetch: 'viewport' // hover, tap, viewport, load
// 圖床地址
imageHostURL: 'https://image.radishzz.cc'
// 優化 Markdown 文件中的遠程圖片以避免佈局抖動
imageHostURL: 'https://image.radishzz.cc'
// 定制 google analytics js
// 適用於路由 google analytics js 到自定義域名的用戶
customGoogleAnalyticsJS: ''
@ -271,7 +271,7 @@ getImageOptions: (_path, page) => ({
[RSS 訂閱頁](https://retypeset.radishzz.cc/zh-tw/rss.xml) 配色。
```html
<!-- public/rss/rss-style.xsl -->
<!-- public/feeds/xxx-style.xsl -->
<style type="text/css">
body{color:oklch(25% 0.005 298)} /* 字體顏色 */

View file

@ -26,7 +26,7 @@ site: {
subtitle: 'Revive the beauty of typography'
// 站点描述
description: 'Retypeset is a static blog theme...'
// 使用 src/i18n/ui.ts 中的多语言标题/副标题/站点描述,而不是上方静态配置
// 使用 src/i18n/ui.ts 中的多语言标题/副标题/站点描述,代替上方静态配置
i18nTitle: true // true, false
// 作者名称
author: 'radishzz'
@ -187,8 +187,8 @@ preload: {
// 链接预加载策略
linkPrefetch: 'viewport' // hover, tap, viewport, load
// 图床地址
imageHostURL: 'https://image.radishzz.cc'
// 优化 Markdown 文件中的远程图片以避免布局抖动
imageHostURL: 'https://image.radishzz.cc'
// 定制 google analytics js
// 适用于路由 google analytics js 到自定义域名的用户
customGoogleAnalyticsJS: ''
@ -271,7 +271,7 @@ getImageOptions: (_path, page) => ({
[RSS 订阅页](https://retypeset.radishzz.cc/rss.xml) 配色。
```html
<!-- public/rss/rss-style.xsl -->
<!-- public/feeds/xxx-style.xsl -->
<style type="text/css">
body{color:oklch(25% 0.005 298)} /* 字体颜色 */

View file

@ -143,6 +143,8 @@ window
</script>
<!-- Google Analytics -->
<!-- Define gtag on window object for proper Partytown forwarding -->
<!-- See https://github.com/QwikDev/partytown/issues/382 -->
{googleAnalyticsID && (
<>
<script
@ -156,18 +158,18 @@ window
define:vars={{ googleAnalyticsID, customGoogleAnalyticsJS }}
>
window.dataLayer = window.dataLayer || []
function gtag(...args) {
dataLayer.push(args)
window.gtag = function () {
// eslint-disable-next-line prefer-rest-params
dataLayer.push(arguments)
}
gtag('js', new Date())
window.gtag('js', new Date())
if (customGoogleAnalyticsJS) {
gtag('config', googleAnalyticsID, {
window.gtag('config', googleAnalyticsID, {
transport_url: new URL(customGoogleAnalyticsJS).origin,
})
}
else {
gtag('config', googleAnalyticsID)
window.gtag('config', googleAnalyticsID)
}
</script>
</>

View file

@ -120,44 +120,7 @@
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.47.22A.749.749 0 0 1 5 0h6c.199 0 .389.079.53.22l4.25 4.25c.141.14.22.331.22.53v6a.749.749 0 0 1-.22.53l-4.25 4.25A.749.749 0 0 1 11 16H5a.749.749 0 0 1-.53-.22L.22 11.53A.749.749 0 0 1 0 11V5c0-.199.079-.389.22-.53Zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5ZM8 4a.75.75 0 0 1 .75.75v3.5a.75.75 0 0 1-1.5 0v-3.5A.75.75 0 0 1 8 4Zm0 8a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'%3E%3C/path%3E%3C/svg%3E");
}
/* Fix KaTeX Overflow with Hidden Scrollbar >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
.katex-display {
--at-apply: 'my-6 overflow-x-auto overflow-y-hidden scrollbar-hidden';
}
.katex-display::-webkit-scrollbar {
display: none;
}
/* Video */
.heti iframe {
--at-apply: 'my-6 aspect-video w-full';
}
.heti :is(h1, h2, h3, h4, h5, h6, iframe) + iframe {
--at-apply: 'mt-4';
}
.heti iframe:has(+ iframe) {
--at-apply: 'mb-4';
}
/* Code Copy Button */
.code-copy-button {
--at-apply: 'z-99 absolute top-2.3 right-2.3 w-8 aspect-square uno-round-border border-secondary/15 c-secondary/80 cursor-pointer';
--at-apply: 'transition-opacity duration-300 ease-out op-100 bg-background lg:(op-0 bg-background)';
}
.code-block-wrapper:hover .code-copy-button {
--at-apply: 'op-100';
}
.code-copy-button:hover {
--at-apply: 'c-primary/80';
}
.code-copy-button svg {
--at-apply: 'w-4 h-4 block mx-auto';
}
.code-copy-button svg,
.code-copy-button svg path {
pointer-events: none;
}
/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
/* :where(details) {
--at-apply: 'my-4 px-4 py-3 border border-solid border-secondary/25 rounded cursor-pointer';
}

View file

@ -14,6 +14,37 @@ body::selection {
--at-apply: 'bg-highlight';
}
/* PhotoSwipe Background Color */
.pswp .pswp__bg {
--at-apply: 'bg-background!';
}
/* Fix KaTeX Overflow with Hidden Scrollbar */
.katex-display {
--at-apply: 'my-6 overflow-x-auto overflow-y-hidden scrollbar-hidden';
}
.katex-display::-webkit-scrollbar {
display: none;
}
/* Highlight Hover Animation */
.highlight-static,
.highlight-hover {
--at-apply: 'relative inline-block';
}
.highlight-static::after,
.highlight-hover::after {
content: '';
--at-apply: 'absolute left-0 z--1 h-0.5em w-full bg-highlight';
}
.highlight-static::after,
.highlight-hover:hover::after {
--at-apply: 'origin-bottom-left scale-x-100';
}
.highlight-hover::after {
--at-apply: 'origin-bottom-right scale-x-0 transition-transform ease-out lg:duration-300';
}
/* Heading Anchor Link */
.heading-anchor-link {
--at-apply: 'inline-block translate-y-0.1em';
@ -34,20 +65,25 @@ h4:hover .heading-anchor-link svg:hover {
--at-apply: 'op-80';
}
/* Highlight Hover Animation */
.highlight-static,
.highlight-hover {
--at-apply: 'relative inline-block';
/* Code Copy Button */
.code-copy-button {
--at-apply: 'absolute right-2.2 top-2.2 z-99 aspect-square w-8 cursor-pointer uno-round-border border-secondary/15';
--at-apply: 'bg-background c-secondary/80 op-100 hover:(border-primary/15 c-primary/80) lg:op-0';
transition: opacity 300ms ease-out, background-color 150ms ease-out;
}
.highlight-static::after,
.highlight-hover::after {
content: '';
--at-apply: 'absolute left-0 z--1 h-0.5em w-full bg-highlight';
.code-block-wrapper:hover .code-copy-button {
--at-apply: 'op-100';
}
.highlight-static::after,
.highlight-hover:hover::after {
--at-apply: 'origin-bottom-left scale-x-100';
.code-copy-button.copy-success {
--at-apply: 'border-none bg-emerald-600 c-background';
}
.highlight-hover::after {
--at-apply: 'origin-bottom-right scale-x-0 transition-transform ease-out lg:duration-300';
html.dark .code-copy-button.copy-success {
--at-apply: 'bg-emerald-500';
}
.code-copy-button svg {
--at-apply: 'mx-auto aspect-square w-50%';
}
.code-copy-button svg,
.code-copy-button svg path {
--at-apply: 'pointer-events-none';
}

View file

@ -75,6 +75,17 @@
--at-apply: 'mb-4';
}
/* Video */
.heti iframe {
--at-apply: 'my-6 aspect-video w-full';
}
.heti :is(h1, h2, h3, h4, h5, h6, iframe) + iframe {
--at-apply: 'mt-4';
}
.heti iframe:has(+ iframe) {
--at-apply: 'mb-4';
}
/* Code Blocks */
.heti :where(pre) {
--at-apply: 'overflow-auto uno-round-border px-4 py-3 bg-secondary/5!';

View file

@ -36,7 +36,7 @@ html.reduce-motion {
--at-apply: 'transition-colors duration-300 ease-out';
}
/* GSAP Animation Elements Initial States */
/* GSAP Animation Elements Initial States >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
@media (min-width: 1024px) {
html:not(.reduce-motion) #gsap-post-page-content > * {
opacity: 0;
@ -59,12 +59,14 @@ html.reduce-motion {
transform: translateY(1.5rem);
}
}
@media (max-width: 1023px) {
html:not(.reduce-motion) #gsap-post-page-content > :nth-child(-n+7) {
opacity: 0;
transform: translateY(3rem);
}
}
@media (max-width: 1535px) {
html:not(.reduce-motion) #toc-container {
opacity: 0;