add SmallCaps component and use for title

This commit is contained in:
2026-03-03 20:31:46 -05:00
parent 6b0a985ee1
commit b0e6576b33
4 changed files with 63 additions and 13 deletions

View File

@@ -1,6 +1,6 @@
export default new Map([ export default new Map([
["posts/after.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fafter.mdx&astroContentModuleFlag=true")], ["posts/after.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fafter.mdx&astroContentModuleFlag=true")],
["posts/test.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Ftest.mdx&astroContentModuleFlag=true")], ["posts/before.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fbefore.mdx&astroContentModuleFlag=true")],
["posts/before.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Fbefore.mdx&astroContentModuleFlag=true")]]); ["posts/test.mdx", () => import("astro:content-layer-deferred-module?astro%3Acontent-layer-deferred-module=&fileName=posts%2Ftest.mdx&astroContentModuleFlag=true")]]);

View File

@@ -2,6 +2,7 @@
import type { CollectionEntry } from 'astro:content'; import type { CollectionEntry } from 'astro:content';
import { render } from 'astro:content'; import { render } from 'astro:content';
import SmallCaps from '@components/SmallCaps.astro';
import Toc from '@components/Toc.vue'; import Toc from '@components/Toc.vue';
import { formatDate } from '@lib/datefmt'; import { formatDate } from '@lib/datefmt';
@@ -39,9 +40,9 @@ article {
} }
.subtitle { .subtitle {
font-size: 0.9em; font-size: 0.85em;
font-style: italic; font-style: italic;
margin-top: -0.75rem; margin-top: -1rem;
} }
.post { .post {
@@ -73,7 +74,9 @@ footer {
<article class="prose"> <article class="prose">
<header class="title"> <header class="title">
<h1>{ entry.data.title }</h1> <h1>
<SmallCaps text={entry.data.title} upperWeight={500} lowerWeight={800} />
</h1>
<p class="subtitle">{ formatDate(entry.data.date) }</p> <p class="subtitle">{ formatDate(entry.data.date) }</p>
</header> </header>

View File

@@ -0,0 +1,50 @@
---
// few web fonts have "true" smallcaps, so instead they just take the full-size caps and scale them
// down to match the height of lowercase letters. But this leads to an awkward effect where the
// scaled-down caps are "lighter" looking than the regular-sized caps, so here we reduce the weight
// of just the full-sized caps to compensate.
export interface Props {
text: string,
upperWeight?: number | string,
lowerWeight?: number | string,
};
const { text, upperWeight = 'inherit', lowerWeight = 'bolder' } = Astro.props;
const upperOrDigit = /[A-Z0-9]+/g;
let prevIdx = 0;
let segments = [];
for (const match of text.matchAll(upperOrDigit)) {
const lower = text.slice(prevIdx, match.index);
// if the first letter of the text is upper, this first segment will be '', so skip it
if (lower) {
segments.push({type: 'lower', chars: lower})
};
segments.push({type: 'upper', chars: match[0]})
prevIdx = match.index + match[0].length;
}
const final = text.slice(prevIdx);
// if there is a final segment, it wasn't a match, so it must be lowercase
if (final) {
segments.push({type: 'lower', chars: final})
};
---
<span class="small-caps">
{ segments.map(s => <span class={s.type}>{ s.chars }</span>) }
</span>
<style define:vars={{ upperWeight, lowerWeight }}>
.small-caps {
font-variant: small-caps;
}
.upper {
font-weight: var(--upperWeight);
}
.lower {
font-weight: var(--lowerWeight);
}
</style>

View File

@@ -69,7 +69,7 @@ onBeforeUnmount(() => {
<template> <template>
<div id="toc"> <div id="toc">
<h5><span class="initial">C</span>ontents</h5> <h5>C<span class="lower">ontents</span></h5>
<ul id="toc-list"> <ul id="toc-list">
<li <li
v-for="heading in headings" v-for="heading in headings"
@@ -108,7 +108,7 @@ onBeforeUnmount(() => {
h5 { h5 {
font-variant: petite-caps; font-variant: petite-caps;
font-weight: 500; font-weight: 350;
font-size: var(--content-size); font-size: var(--content-size);
font-family: 'Figtree Variable'; font-family: 'Figtree Variable';
color: var(--content-color-faded); color: var(--content-color-faded);
@@ -122,12 +122,9 @@ h5 {
/* make the border stretch beyond the text just a bit, because I like the effect */ /* make the border stretch beyond the text just a bit, because I like the effect */
padding-right: 1.5rem; padding-right: 1.5rem;
& .initial { /* SmallCaps is an Astro component so we can't use it here, but we can fake it */
/* & .lower {
Our font doesn't have "proper" smallcaps, but we can fake it by font-weight: 500;
setting the weight separately for the initial (non-small) capital
*/
font-weight: 350
} }
} }