style: add highlight hover animation to navigation and footer

- add dynamic accessible labels to heading anchors
- update theme toggle button svg
This commit is contained in:
radishzzz 2025-05-13 23:33:09 +01:00
parent 2d80d7effd
commit 610c86db0d
21 changed files with 131 additions and 108 deletions

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M12 1C5.9 1 1 5.9 1 12s4.9 11 11 11 11-4.9 11-11S18.1 1 12 1m0 20c-5.8 0-10.5-4-10.5-9S6.2 3 12 3s10.5 4 10.5 9-4.7 9-10.5 9"/>
<path d="M12,.5C5.6.5.4,5.6.4,12s5.1,11.5,11.6,11.5,11.5-5.1,11.5-11.5S18.4.5,12,.5M12,21.5C5.9,21.5,1,17.3,1,12S5.9,2.6,12,2.6s11,4.2,11,9.5-4.9,9.4-11,9.4"/>
</svg>

Before

Width:  |  Height:  |  Size: 206 B

After

Width:  |  Height:  |  Size: 229 B

Before After
Before After

View file

@ -50,7 +50,7 @@ const nextUrl = useSupportedLangs
<!-- Theme Toggle -->
<button
aria-label="Switch light/dark theme"
class="button-theme-toggle aspect-square w-4.2 c-secondary active:scale-90 hover:c-primary"
class="button-theme-toggle aspect-square w-4 c-secondary active:scale-90 hover:c-primary"
>
<ThemeToggleIcon
aria-hidden="true"

View file

@ -30,7 +30,7 @@ const links = socialLinks.map((link) => {
<p>
{links.map((link, index) => (
<>
<a class="transition-colors hover:c-primary" href={link.url} target="_blank" rel="noopener noreferrer">
<a class="highlight-hover transition-colors hover:c-primary after:bottom-0!" href={link.url} target="_blank" rel="noopener noreferrer">
{link.name}
</a>
{index < links.length - 1 && ' / '}
@ -39,7 +39,7 @@ const links = socialLinks.map((link) => {
</p>
<p>
Powered by <a class="transition-colors hover:c-primary" href="https://astro.build/" target="_blank" rel="noopener noreferrer">Astro</a> and <a class="transition-colors hover:c-primary" href="https://github.com/radishzzz/astro-theme-retypeset" target="_blank" rel="noopener noreferrer">Retypeset</a>
Powered by <a class="highlight-hover transition-colors hover:c-primary after:bottom-0!" href="https://astro.build/" target="_blank" rel="noopener noreferrer">Astro</a> and <a class="highlight-hover transition-colors hover:c-primary after:bottom-0!" href="https://github.com/radishzzz/astro-theme-retypeset" target="_blank" rel="noopener noreferrer">Retypeset</a>
</p>
<p>

View file

@ -10,7 +10,7 @@ const isTagActive = isTag
const isAboutActive = isAbout
function getNavItemClass(isActive: boolean) {
return isActive ? 'font-bold c-primary' : 'hover:(c-primary font-bold) transition-all'
return isActive ? 'font-bold c-primary highlight-static' : 'hover:(c-primary font-bold) transition-all highlight-hover'
}
const navItems = [

View file

@ -61,5 +61,5 @@ function initBackToTop() {
}
// Handle page transitions
document.addEventListener('astro:page-load', initBackToTop)
document.addEventListener('astro:after-swap', initBackToTop)
</script>

View file

@ -217,6 +217,6 @@ function setupTOCHighlight() {
}
setupTOCHighlight()
document.addEventListener('astro:page-load', setupTOCHighlight)
document.addEventListener('astro:after-swap', setupTOCHighlight)
</script>

View file

@ -1,9 +1,9 @@
---
import { ClientRouter } from 'astro:transitions'
import katexCSS from 'katex/dist/katex.min.css?url'
import { allLocales, defaultLocale, themeConfig } from '@/config'
import { ui } from '@/i18n/ui'
import { getPageInfo } from '@/utils/page'
import { ClientRouter } from 'astro:transitions'
import katexCSS from 'katex/dist/katex.min.css?url'
interface Props {
postTitle?: string

View file

@ -22,7 +22,7 @@ interface Props {
}
const { postTitle, postDescription, postSlug, supportedLangs = [] } = Astro.props
const { isPost, isAbout } = getPageInfo(Astro.url.pathname)
const { isPost } = getPageInfo(Astro.url.pathname)
const fontStyle = themeConfig.global.fontStyle === 'serif' ? 'font-serif' : 'font-sans'
const MarginBottom = isPost && themeConfig.comment?.enabled
? 'mb-10' // Post page with comment system
@ -51,7 +51,7 @@ const MarginBottom = isPost && themeConfig.comment?.enabled
</div>
<Button supportedLangs={supportedLangs} />
<Scrollbar />
{(isPost || isAbout) && <GithubCard />}
{(isPost || isAbout) && <PhotoSwipe />}
<GithubCard />
<PhotoSwipe />
</body>
</html>

View file

@ -9,5 +9,5 @@ import Layout from '@/layouts/Layout.astro'
<h3 class="mt--1.3 text-8 text-primary font-bold leading-1.2em font-navbar lg:text-9">PAGE<br>NOT<br>FOUND</h3>
<p class="mt-3.6 text-3.6 leading-1.4em font-navbar lg:(mt-4 text-4)">It looks like the page you're looking for<br>does not exist or has been moved.</p>
<!-- Unused Div -->
<!-- <div class=""></div> -->
<div class=""></div>
</Layout>

View file

@ -1,7 +1,7 @@
---
import { getCollection, render } from 'astro:content'
import { defaultLocale, moreLocales } from '@/config'
import Layout from '@/layouts/Layout.astro'
import { getCollection, render } from 'astro:content'
export async function getStaticPaths() {
type PathItem = {

View file

@ -1,5 +1,6 @@
---
import type { CollectionEntry } from 'astro:content'
import { getCollection, render } from 'astro:content'
import Comments from '@/components/Comments/index.astro'
import PostDate from '@/components/PostDate.astro'
import GoBack from '@/components/Widgets/GoBack.astro'
@ -9,7 +10,6 @@ import { getTagPath } from '@/i18n/path'
import Layout from '@/layouts/Layout.astro'
import { checkPostSlugDuplication } from '@/utils/content'
import { generateDescription } from '@/utils/description'
import { getCollection, render } from 'astro:content'
export async function getStaticPaths() {
const posts = await getCollection('posts')

View file

@ -1,7 +1,7 @@
import type { CollectionEntry } from 'astro:content'
import { generateDescription } from '@/utils/description'
import { OGImageRoute } from 'astro-og-canvas'
import { getCollection } from 'astro:content'
import { generateDescription } from '@/utils/description'
// eslint-disable-next-line antfu/no-top-level-await
const blogEntries = await getCollection('posts')

View file

@ -6,16 +6,31 @@
html {
--at-apply: 'bg-background c-secondary antialiased';
}
/* Fix flash issue on iOS */
::selection {
--at-apply: 'bg-mark';
}
/* Fix Flash Issue On iOS */
body {
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
::selection {
--at-apply: 'bg-mark';
/* Highlight Hover Animation */
.highlight-static,
.highlight-hover {
--at-apply: 'relative inline-block';
}
html.dark ::selection {
--at-apply: 'c-background';
.highlight-static::after,
.highlight-hover::after {
--at-apply: 'content-[""] absolute bottom-0.5em left-0 z--1 h-0.5em w-full bg-mark';
}
.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 duration-300 ease-out';
}
/* View Transition with Theme Toggle >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */

View file

@ -22,7 +22,7 @@
.heti :where(h4),
.heti :where(h5),
.heti :where(h6) {
--at-apply: 'mt-6 mb-3 font-semibold';
--at-apply: 'mb-3 mt-6 font-semibold';
}
.heti :where(h1) {
--at-apply: 'text-7 leading-12';
@ -62,7 +62,7 @@
/* Links */
.heti :where(a:not(.gc-container)) {
--at-apply: 'break-all font-medium tracking-0 underline decoration-secondary/40 underline-0.075em underline-offset-0.2em';
--at-apply: 'break-all font-medium tracking-0 underline underline-0.075em decoration-secondary/40 underline-offset-0.2em';
--at-apply: 'transition-colors hover:(c-primary decoration-secondary/80) lg:underline-0.1em';
}
@ -81,10 +81,10 @@
/* Code Blocks */
.heti :where(pre) {
--at-apply: 'mb-4 px-4 py-3 overflow-auto uno-round-border bg-secondary/5!';
--at-apply: 'mb-4 overflow-auto uno-round-border px-4 py-3 bg-secondary/5!';
}
.heti pre :where(code) {
--at-apply: 'p-0 border-none bg-transparent';
--at-apply: 'border-none bg-transparent p-0';
}
html.dark .heti pre :where(span) {
--at-apply: 'text-[var(--shiki-dark)]!';
@ -92,14 +92,14 @@ html.dark .heti pre :where(span) {
/* Inline Code */
.heti :where(code) {
--at-apply: 'px-0.4em py-0.2em text-0.85em tracking-0 uno-round-border bg-secondary/5 cjk:break-all';
--at-apply: 'uno-round-border bg-secondary/5 px-0.4em py-0.2em text-0.85em tracking-0 cjk:break-all';
counter-reset: line;
}
.heti :where(code) span.line {
--at-apply: 'relative pl-8';
}
.heti :where(code) span.line::before {
--at-apply: 'absolute left-0 w-4 leading-1.9em text-secondary/40';
--at-apply: 'absolute left-0 w-4 text-secondary/40 leading-1.9em';
content: counter(line);
counter-increment: line;
direction: rtl;
@ -107,7 +107,7 @@ html.dark .heti pre :where(span) {
/* Blockquotes */
.heti :where(blockquote) {
--at-apply: 'mb-4 px-4 py-0.5 c-secondary/80 border-l-4 border-solid border-secondary/25';
--at-apply: 'mb-4 border-l-4 border-secondary/25 border-solid px-4 py-0.5 c-secondary/80';
}
.heti blockquote[class*="admonition-"] {
--at-apply: 'py-1.5 c-secondary';
@ -124,14 +124,14 @@ html.dark .heti pre :where(span) {
/* Tables */
.heti :where(table) {
--at-apply: 'mb-4 block box-border table-fixed max-w-full overflow-x-auto scrollbar-hidden';
--at-apply: 'mb-4 box-border block max-w-full table-fixed overflow-x-auto scrollbar-hidden';
}
.heti :where(table)::-webkit-scrollbar {
--at-apply: 'hidden';
}
.heti :where(th),
.heti :where(td) {
--at-apply: 'px-3 pb-1.5 border-b border-b-secondary/25';
--at-apply: 'border-b border-b-secondary/25 px-3 pb-1.5';
}
.heti :where(tr td:first-child),
.heti :where(tr th:first-child) {
@ -157,7 +157,7 @@ html.dark .heti pre :where(span) {
.heti ul :where(ol),
.heti ol :where(ul),
.heti ol :where(ol) {
--at-apply: 'mt-0 mb-0.25em';
--at-apply: 'mb-0.25em mt-0';
}
.heti :where(ul) {
--at-apply: 'list-disc';
@ -182,7 +182,7 @@ html.dark .heti pre :where(span) {
/* Superscript and Subscript >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> */
.heti :where(sub),
.heti :where(sup) {
--at-apply: 'relative mx-0.1em text-0.75em leading-1 align-baseline';
--at-apply: 'relative mx-0.1em align-baseline text-0.75em leading-1';
}
.heti :where(sub) {
--at-apply: 'bottom--0.25em';
@ -193,15 +193,15 @@ html.dark .heti pre :where(span) {
/* Abbreviations */
.heti :where(abbr[title]) {
--at-apply: 'pb-0.25 no-underline border-b-1 border-dotted border-secondary cursor-help';
--at-apply: 'cursor-help border-b-1 border-secondary border-dotted pb-0.25 no-underline';
}
/* Wavy Underline */
.heti :where(u) {
--at-apply: 'underline underline-offset-0.25em decoration-wavy decoration-red-400';
--at-apply: 'underline decoration-red-400 underline-offset-0.25em decoration-wavy';
}
html.dark .heti :where(u) {
--at-apply: 'decoration-red-400/80';
--at-apply: 'decoration-red-400/60';
}
/* Keyboard Input */
@ -212,10 +212,7 @@ html.dark .heti :where(u) {
/* Highlighted Text */
.heti :where(mark) {
--at-apply: 'py-0.25 text-inherit bg-mark';
}
html.dark .heti :where(mark) {
--at-apply: 'text-background';
--at-apply: 'bg-mark py-0.65 text-inherit';
}
/* Footnotes */
@ -227,12 +224,8 @@ html.dark .heti :where(mark) {
.heti sup a:target {
--at-apply: 'bg-mark';
}
html.dark .heti sup:target,
html.dark .heti sup a:target {
--at-apply: 'text-background';
}
.heti .data-footnote-backref {
--at-apply: 'no-underline font-serif';
--at-apply: 'font-serif no-underline';
}
/* Horizontal Rules */

View file

@ -1,7 +1,7 @@
import type { CollectionEntry } from 'astro:content'
import { getCollection, render } from 'astro:content'
import { defaultLocale } from '@/config'
import { memoize } from '@/utils/cache'
import { getCollection, render } from 'astro:content'
/**
* Core Functions

View file

@ -1,6 +1,6 @@
import type { CollectionEntry } from 'astro:content'
import { defaultLocale } from '@/config'
import MarkdownIt from 'markdown-it'
import { defaultLocale } from '@/config'
type ExcerptScene = 'list' | 'meta' | 'og' | 'feed'

View file

@ -1,16 +1,16 @@
import type { APIContext, ImageMetadata } from 'astro'
import type { CollectionEntry } from 'astro:content'
import type { Author } from 'feed'
import { defaultLocale, themeConfig } from '@/config'
import { ui } from '@/i18n/ui'
import { memoize } from '@/utils/cache'
import { generateDescription } from '@/utils/description'
import { getImage } from 'astro:assets'
import { getCollection } from 'astro:content'
import { Feed } from 'feed'
import MarkdownIt from 'markdown-it'
import { parse as htmlParser } from 'node-html-parser'
import sanitizeHtml from 'sanitize-html'
import { defaultLocale, themeConfig } from '@/config'
import { ui } from '@/i18n/ui'
import { memoize } from '@/utils/cache'
import { generateDescription } from '@/utils/description'
interface GenerateFeedOptions {
lang?: string