release: v0.15.0 (#585)

Eighteen changes since v0.14.0. See CHANGELOG.md for the full list and the upgrade notes (bump IMAGE_CACHE_VERSION).
This commit is contained in:
Ralksta
2026-09-19 22:24:10 +02:00
committed by GitHub
parent e99d3f2f1b
commit c3f92ca4ec
74 changed files with 4791 additions and 2146 deletions

View File

@@ -7,6 +7,7 @@ import { ProofingProvider, useProofing } from '@/components/ProofingContext';
import { ProofingModal } from '@/components/ProofingModal';
import { FadeIn } from '@/components/FadeIn';
import type { ParsedEssay, EssayBlock } from '@/lib/essay';
import { renderInlineMarkdown } from '@/lib/essay';
import type { PhotoItem } from './PhotoGrid';
import './essay.css';
import { useDictionary } from '@/components/I18nProvider';
@@ -78,7 +79,15 @@ function EssayViewContent({
return (
<blockquote key={idx} className="essay-quote">
<div dangerouslySetInnerHTML={{ __html: block.text }} />
{block.author && <span className="essay-quote__author">— {block.author}</span>}
{block.author && (
<span
className="essay-quote__author"
// The attribution keeps its Markdown and is rendered here, like
// the quote body, so `[link](…)` becomes an anchor (#559).
// renderInlineMarkdown escapes everything it does not emit.
dangerouslySetInnerHTML={{ __html: `— ${renderInlineMarkdown(block.author)}` }}
/>
)}
</blockquote>
);
@@ -312,9 +321,9 @@ function EssayViewContent({
gap: '12px',
padding: '8px 16px',
borderRadius: '30px',
background: 'var(--bg-surface, #1e1e1e)',
background: 'var(--bg-card, #1e1e1e)',
color: 'var(--text-primary, #ffffff)',
border: '1px solid var(--border-color, rgba(255,255,255,0.15))',
border: '1px solid var(--border-subtle, rgba(255,255,255,0.15))',
boxShadow: '0 8px 24px rgba(0,0,0,0.4)',
backdropFilter: 'blur(8px)',
}}
@@ -325,8 +334,8 @@ function EssayViewContent({
style={{
background: proofing.isFilterActive
? 'var(--accent, #e60012)'
: 'rgba(255,255,255,0.15)',
color: '#fff',
: 'var(--bg-card-hover)',
color: proofing.isFilterActive ? '#fff' : 'var(--text-primary)',
border: 'none',
padding: '6px 14px',
borderRadius: '20px',

View File

@@ -266,9 +266,9 @@ function PhotoGridInner({
gap: '12px',
padding: '8px 16px',
borderRadius: '30px',
background: 'var(--bg-surface, #1e1e1e)',
background: 'var(--bg-card, #1e1e1e)',
color: 'var(--text-primary, #ffffff)',
border: '1px solid var(--border-color, rgba(255,255,255,0.15))',
border: '1px solid var(--border-subtle, rgba(255,255,255,0.15))',
boxShadow: '0 8px 24px rgba(0,0,0,0.4)',
backdropFilter: 'blur(8px)',
}}
@@ -279,8 +279,8 @@ function PhotoGridInner({
style={{
background: proofing.isFilterActive
? 'var(--accent, #e60012)'
: 'rgba(255,255,255,0.15)',
color: '#fff',
: 'var(--bg-card-hover)',
color: proofing.isFilterActive ? '#fff' : 'var(--text-primary)',
border: 'none',
padding: '6px 14px',
borderRadius: '20px',

View File

@@ -55,13 +55,19 @@ function AlbumGrid({
key={album.id}
href={`/${slug}/${album.slug}`}
className="subpage-grid__item"
style={ph?.dominantColor ? { backgroundColor: ph.dominantColor } : undefined}
aria-label={getServerDictionary().subpage.coverAria(
album.albumName,
photoCount(album.assetCount),
)}
>
<span className="subpage-grid__item-media">
{/* The loading colour belongs to the image, not the card: presets
with a caption bar below the cover (studio-modern) would
otherwise paint the bar in the photo's dominant colour, and
their --text-primary caption becomes dark-on-dark in light mode. */}
<span
className="subpage-grid__item-media"
style={ph?.dominantColor ? { backgroundColor: ph.dominantColor } : undefined}
>
{album.albumThumbnailAssetId ? (
<Image
src={imageUrl(album.albumThumbnailAssetId, 'preview')}

View File

@@ -32,7 +32,7 @@
}
.essay-header__title {
font-family: var(--font-heading, serif);
font-family: var(--font-serif, serif);
font-size: clamp(2.2rem, 5vw, 3.8rem);
font-weight: 700;
line-height: 1.15;
@@ -41,7 +41,7 @@
}
.essay-header__subtitle {
font-family: var(--font-body, sans-serif);
font-family: var(--font-sans, sans-serif);
font-size: clamp(1.1rem, 2.5vw, 1.4rem);
opacity: 0.8;
line-height: 1.5;
@@ -60,7 +60,7 @@
.essay-prose {
max-width: var(--essay-measure);
margin: 0 auto 2.5rem auto;
font-family: var(--font-body, sans-serif);
font-family: var(--font-sans, sans-serif);
font-size: clamp(1.05rem, 2vw, 1.2rem);
line-height: 1.75;
color: var(--text-primary, rgba(255, 255, 255, 0.92));
@@ -71,7 +71,7 @@
}
.essay-heading {
font-family: var(--font-heading, serif);
font-family: var(--font-serif, serif);
max-width: var(--essay-measure);
margin: 3.5rem auto 1.5rem auto;
font-weight: 600;
@@ -94,9 +94,9 @@
margin: 3.5rem auto;
padding: 1.5rem 2rem;
border-left: 3px solid var(--accent, #e60012);
background: var(--bg-surface, rgba(255, 255, 255, 0.03));
background: var(--bg-card, rgba(255, 255, 255, 0.03));
border-radius: 0 8px 8px 0;
font-family: var(--font-heading, serif);
font-family: var(--font-serif, serif);
font-style: italic;
font-size: clamp(1.15rem, 2.2vw, 1.35rem);
line-height: 1.6;
@@ -142,7 +142,7 @@
position: relative;
width: 100%;
overflow: hidden;
border-radius: var(--radius, 0px);
border-radius: var(--radius-md, 0px);
max-height: 80vh;
}