diff --git a/package-lock.json b/package-lock.json
index c084eecd..f48d1ab3 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -77,7 +77,6 @@
"@radix-ui/react-tooltip": "^1.1.4",
"@sentry/react": "^10.42.0",
"@tanstack/react-query": "^5.56.2",
- "@types/dompurify": "^3.0.5",
"@unhead/addons": "^2.0.10",
"@unhead/react": "^2.0.10",
"blurhash": "^2.0.5",
@@ -125,6 +124,7 @@
"@tailwindcss/typography": "^0.5.15",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
+ "@types/dompurify": "^3.0.5",
"@types/node": "^22.5.5",
"@types/qrcode": "^1.5.5",
"@types/react": "^18.3.1",
@@ -4005,6 +4005,7 @@
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/@types/dompurify/-/dompurify-3.0.5.tgz",
"integrity": "sha512-1Wg0g3BtQF7sSb27fJQAKck1HECM6zV1EB66j8JH9i3LCjYabJa0FSdiSgsD5K/RbrsR0SiraKacLB+T8ZVYAg==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/trusted-types": "*"
@@ -4123,6 +4124,7 @@
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
"integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "devOptional": true,
"license": "MIT"
},
"node_modules/@types/unist": {
diff --git a/package.json b/package.json
index 42d16ca0..c48a06a9 100644
--- a/package.json
+++ b/package.json
@@ -85,7 +85,6 @@
"@radix-ui/react-tooltip": "^1.1.4",
"@sentry/react": "^10.42.0",
"@tanstack/react-query": "^5.56.2",
- "@types/dompurify": "^3.0.5",
"@unhead/addons": "^2.0.10",
"@unhead/react": "^2.0.10",
"blurhash": "^2.0.5",
@@ -133,6 +132,7 @@
"@tailwindcss/typography": "^0.5.15",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
+ "@types/dompurify": "^3.0.5",
"@types/node": "^22.5.5",
"@types/qrcode": "^1.5.5",
"@types/react": "^18.3.1",
diff --git a/src/components/ColorMomentContent.tsx b/src/components/ColorMomentContent.tsx
index c84f945d..c2222ab0 100644
--- a/src/components/ColorMomentContent.tsx
+++ b/src/components/ColorMomentContent.tsx
@@ -2,7 +2,7 @@ import { useMemo, useState, useEffect, useId } from 'react';
import { cn } from '@/lib/utils';
import { useTheme } from '@/hooks/useTheme';
-import { hexToHslString, hexToRgb, rgbToHsl, hslToRgb, getLuminance, getContrastRatio, parseHsl, formatHsl } from '@/lib/colorUtils';
+import { hexToHslString, hexToRgb, rgbToHsl, hslToRgb, getLuminance, getContrastRatio, parseHsl, formatHsl, hexLuminance } from '@/lib/colorUtils';
import type { CoreThemeColors } from '@/themes';
import type { NostrEvent } from '@nostrify/nostrify';
@@ -195,10 +195,6 @@ function DiagonalStripesLayout({ colors }: { colors: string[] }) {
// ─── Palette → theme mapping ─────────────────────────────
-function hexLuminance(hex: string): number {
- return getLuminance(...hexToRgb(hex));
-}
-
function hexContrast(hex1: string, hex2: string): number {
return getContrastRatio(hexToRgb(hex1), hexToRgb(hex2));
}
diff --git a/src/components/letter/ColorPaletteDisplay.tsx b/src/components/letter/ColorPaletteDisplay.tsx
index 21abadbf..ad23de8e 100644
--- a/src/components/letter/ColorPaletteDisplay.tsx
+++ b/src/components/letter/ColorPaletteDisplay.tsx
@@ -5,6 +5,8 @@
* matching the approach used in mew and espy for kind 3367 color moments.
*/
+import { hexLuminance } from '@/lib/colorUtils';
+
export type PaletteLayout =
| 'horizontal'
| 'vertical'
@@ -169,14 +171,6 @@ function DiagonalStripesLayout({ colors }: { colors: string[] }) {
);
}
-function hexLum(hex: string): number {
- const h = hex.replace('#', '');
- const r = parseInt(h.slice(0, 2), 16) / 255;
- const g = parseInt(h.slice(2, 4), 16) / 255;
- const b = parseInt(h.slice(4, 6), 16) / 255;
- return 0.2126 * r + 0.7152 * g + 0.0722 * b;
-}
-
export function ColorPaletteDisplay({
colors,
layout = 'horizontal',
@@ -185,7 +179,7 @@ export function ColorPaletteDisplay({
}: ColorPaletteDisplayProps) {
if (colors.length === 0) return null;
- const avgLum = colors.reduce((s, c) => s + hexLum(c), 0) / colors.length;
+ const avgLum = colors.reduce((s, c) => s + hexLuminance(c), 0) / colors.length;
const emojiColorClass = avgLum > 0.5 ? 'text-black/80' : 'text-white/90';
return (
diff --git a/src/components/letter/ComposeLetterSheet.tsx b/src/components/letter/ComposeLetterSheet.tsx
index 72ce382b..0b4f9fb0 100644
--- a/src/components/letter/ComposeLetterSheet.tsx
+++ b/src/components/letter/ComposeLetterSheet.tsx
@@ -16,6 +16,8 @@ import { backgroundTextColor } from '@/lib/colorUtils';
import {
LETTER_KIND,
FONT_OPTIONS,
+ LINE_HEIGHT_RATIO,
+ DEFAULT_STATIONERY_COLOR,
resolveStationery,
type Stationery,
type FrameStyle,
@@ -36,9 +38,9 @@ import { SendAnimation, useEnvelopeDimensions } from './SendAnimation';
/** Lightweight letter preview used inside the send animation */
function AnimationLetter({ content, width }: { content: LetterContent; width: number }) {
const { text: textColor, line: lineColor } = useStationeryColors(content.stationery);
- const resolved = resolveStationery(content.stationery ?? { color: '#F5E6D3' });
+ const resolved = resolveStationery(content.stationery ?? { color: DEFAULT_STATIONERY_COLOR });
const fontFamily = resolved.fontFamily ?? FONT_OPTIONS[0].family;
- const lh = Math.round(width * 0.084);
+ const lh = Math.round(width * LINE_HEIGHT_RATIO);
return (
@@ -268,8 +270,8 @@ export function ComposeLetterSheet({ onClose, toPubkey }: ComposeLetterSheetProp
|| recipientAuthor.data?.metadata?.name
|| (resolvedRecipient ? genUserName(resolvedRecipient) : 'friend');
- const resolvedSt = useMemo(() => resolveStationery(stationery ?? { color: '#F5E6D3' }), [stationery]);
- const bgColor = resolvedSt.color ?? '#F5E6D3';
+ const resolvedSt = useMemo(() => resolveStationery(stationery ?? { color: DEFAULT_STATIONERY_COLOR }), [stationery]);
+ const bgColor = resolvedSt.color ?? DEFAULT_STATIONERY_COLOR;
const primaryColor = resolvedSt.primaryColor ?? '#7c52e0';
const textColor = resolvedSt.textColor ?? backgroundTextColor(bgColor);
diff --git a/src/components/letter/EnvelopeCard.tsx b/src/components/letter/EnvelopeCard.tsx
index 0d3b13fc..929a5bbb 100644
--- a/src/components/letter/EnvelopeCard.tsx
+++ b/src/components/letter/EnvelopeCard.tsx
@@ -25,8 +25,8 @@ import { Clock } from 'lucide-react';
import { useAuthor } from '@/hooks/useAuthor';
import { useDecryptLetter } from '@/hooks/useLetters';
import { genUserName } from '@/lib/genUserName';
-import { resolveStationery, type Letter } from '@/lib/letterTypes';
-import { hexToRgb, rgbToHex, hexLuminance } from '@/lib/colorUtils';
+import { resolveStationery, DEFAULT_STATIONERY_COLOR, type Letter } from '@/lib/letterTypes';
+import { hexLuminance, darkenHex, lightenHex, blendHex } from '@/lib/colorUtils';
import { StationeryBackground } from './StationeryBackground';
interface EnvelopeCardProps {
@@ -37,31 +37,9 @@ interface EnvelopeCardProps {
}
// ---------------------------------------------------------------------------
-// Color helpers — matches SendAnimation
+// Color helpers
// ---------------------------------------------------------------------------
-function blendHex(hex1: string, hex2: string, amount: number): string {
- const [r1, g1, b1] = hexToRgb(hex1);
- const [r2, g2, b2] = hexToRgb(hex2);
- return rgbToHex(
- Math.round(r1 + (r2 - r1) * amount),
- Math.round(g1 + (g2 - g1) * amount),
- Math.round(b1 + (b2 - b1) * amount),
- );
-}
-
-function darkenHex(hex: string, amount: number): string {
- const [r, g, b] = hexToRgb(hex);
- const dark = (c: number) => Math.max(0, Math.round(c * (1 - amount)));
- return rgbToHex(dark(r), dark(g), dark(b));
-}
-
-function lightenHex(hex: string, amount: number): string {
- const [r, g, b] = hexToRgb(hex);
- const light = (c: number) => Math.min(255, Math.round(c + (255 - c) * amount));
- return rgbToHex(light(r), light(g), light(b));
-}
-
function deriveColors(bgHex: string, primaryHex: string) {
const body = blendHex(bgHex, primaryHex, 0.08);
const isDark = hexLuminance(body) < 0.45;
@@ -114,7 +92,7 @@ export function EnvelopeCard({ letter, mode, index, onClick }: EnvelopeCardProps
const timeStr = shortTimeAgo(letter.timestamp);
const stationery = decrypted?.stationery;
- const resolved = useMemo(() => resolveStationery(stationery ?? { color: '#F5E6D3' }), [stationery]);
+ const resolved = useMemo(() => resolveStationery(stationery ?? { color: DEFAULT_STATIONERY_COLOR }), [stationery]);
const bgColor = resolved.color;
const primaryColor = resolved.primaryColor ?? resolved.colors?.[0] ?? bgColor;
const C = useMemo(() => deriveColors(bgColor, primaryColor), [bgColor, primaryColor]);
diff --git a/src/components/letter/LetterCard.tsx b/src/components/letter/LetterCard.tsx
index f58495e0..8861a50e 100644
--- a/src/components/letter/LetterCard.tsx
+++ b/src/components/letter/LetterCard.tsx
@@ -9,7 +9,7 @@ import { useNostrPublish } from '@/hooks/useNostrPublish';
import { useQueryClient } from '@tanstack/react-query';
import { toast } from '@/hooks/useToast';
import { genUserName } from '@/lib/genUserName';
-import { FONT_OPTIONS, LETTER_KIND, type Letter } from '@/lib/letterTypes';
+import { FONT_OPTIONS, LETTER_KIND, LINE_HEIGHT_RATIO, type Letter } from '@/lib/letterTypes';
import { StationeryBackground } from './StationeryBackground';
import { useStationeryColors } from '@/hooks/useStationeryColors';
import { LetterStickers } from './LetterStickers';
@@ -110,7 +110,7 @@ export function LetterCard({ letter, mode }: LetterCardProps) {
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
const w = entry.contentBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
- setLineHeightPx(Math.round(w * 0.084));
+ setLineHeightPx(Math.round(w * LINE_HEIGHT_RATIO));
});
});
ro.observe(el);
diff --git a/src/components/letter/LetterDetailSheet.tsx b/src/components/letter/LetterDetailSheet.tsx
index 46187fe3..62af3e06 100644
--- a/src/components/letter/LetterDetailSheet.tsx
+++ b/src/components/letter/LetterDetailSheet.tsx
@@ -6,7 +6,7 @@
import { useState, useRef, useEffect } from 'react';
import { Loader2, Lock } from 'lucide-react';
import { useDecryptLetter } from '@/hooks/useLetters';
-import { FONT_OPTIONS, type Letter } from '@/lib/letterTypes';
+import { FONT_OPTIONS, LINE_HEIGHT_RATIO, type Letter } from '@/lib/letterTypes';
import { StationeryBackground } from './StationeryBackground';
import { useStationeryColors } from '@/hooks/useStationeryColors';
import { LetterStickers } from './LetterStickers';
@@ -18,11 +18,10 @@ import {
interface LetterDetailSheetProps {
letter: Letter | null;
- mode: 'inbox' | 'sent';
onClose: () => void;
}
-export function LetterDetailSheet({ letter, mode, onClose }: LetterDetailSheetProps) {
+export function LetterDetailSheet({ letter, onClose }: LetterDetailSheetProps) {
const letterRef = useRef(null);
const [lineHeightPx, setLineHeightPx] = useState(0);
@@ -47,7 +46,7 @@ export function LetterDetailSheet({ letter, mode, onClose }: LetterDetailSheetPr
const el = letterRef.current;
if (!el) return;
const w = el.getBoundingClientRect().width;
- if (w > 0) setLineHeightPx(Math.round(w * 0.084));
+ if (w > 0) setLineHeightPx(Math.round(w * LINE_HEIGHT_RATIO));
}, 50);
const el = letterRef.current;
@@ -58,7 +57,7 @@ export function LetterDetailSheet({ letter, mode, onClose }: LetterDetailSheetPr
cancelAnimationFrame(raf);
raf = requestAnimationFrame(() => {
const w = entry.contentBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
- if (w > 0) setLineHeightPx(Math.round(w * 0.084));
+ if (w > 0) setLineHeightPx(Math.round(w * LINE_HEIGHT_RATIO));
});
});
ro.observe(el);
diff --git a/src/components/letter/LetterEditor.tsx b/src/components/letter/LetterEditor.tsx
index 759b3e93..236fce1d 100644
--- a/src/components/letter/LetterEditor.tsx
+++ b/src/components/letter/LetterEditor.tsx
@@ -13,6 +13,7 @@ import { TabButton } from '@/components/TabButton';
import {
FONT_OPTIONS,
CLOSING_PRESETS,
+ LINE_HEIGHT_RATIO,
type Stationery,
type FrameStyle,
} from '@/lib/letterTypes';
@@ -133,7 +134,7 @@ export function LetterEditor({
if (!el) return;
const ro = new ResizeObserver(([entry]) => {
const w = entry.contentBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
- setLineHeightPx(Math.round(w * 0.084));
+ setLineHeightPx(Math.round(w * LINE_HEIGHT_RATIO));
});
ro.observe(el);
return () => ro.disconnect();
diff --git a/src/components/letter/LetterRecipientInput.tsx b/src/components/letter/LetterRecipientInput.tsx
index 57fc7ab0..45de3b5b 100644
--- a/src/components/letter/LetterRecipientInput.tsx
+++ b/src/components/letter/LetterRecipientInput.tsx
@@ -1,4 +1,4 @@
-import { useState, useRef, useEffect } from 'react';
+import { useState, useRef, useEffect, useMemo } from 'react';
import { nip19 } from 'nostr-tools';
import { Loader2, X } from 'lucide-react';
import { useSearchProfiles, type SearchProfile } from '@/hooks/useSearchProfiles';
@@ -27,7 +27,8 @@ export function LetterRecipientInput({ onSelect, initialNpub, friendsOnly = fals
const { data: searchResults, isLoading } = useSearchProfiles(selected ? '' : query);
const followListData = useFollowList();
- const followedPubkeys = new Set(followListData.data?.pubkeys ?? []);
+ const followPubkeyArray = followListData.data?.pubkeys;
+ const followedPubkeys = useMemo(() => new Set(followPubkeyArray ?? []), [followPubkeyArray]);
const profiles = (() => {
const all = searchResults ?? [];
diff --git a/src/components/letter/SendAnimation.tsx b/src/components/letter/SendAnimation.tsx
index 71fc4db4..b17d979f 100644
--- a/src/components/letter/SendAnimation.tsx
+++ b/src/components/letter/SendAnimation.tsx
@@ -9,7 +9,7 @@
*/
import { useId, useRef, useEffect, useLayoutEffect, useCallback, useState, useMemo } from 'react';
-import { hexToRgb, rgbToHex } from '@/lib/colorUtils';
+import { hexToRgb, rgbToHex, darkenHex, blendHex } from '@/lib/colorUtils';
// ---------------------------------------------------------------------------
// Easing + animation driver
@@ -79,22 +79,6 @@ function mixHex(hex: string, lightAmount: number): string {
return rgbToHex(mix(r), mix(g), mix(b));
}
-function darkenHex(hex: string, amount: number): string {
- const [r, g, b] = hexToRgb(hex);
- const dark = (c: number) => Math.max(0, Math.round(c * (1 - amount)));
- return rgbToHex(dark(r), dark(g), dark(b));
-}
-
-function blendHex(hex: string, targetHex: string, amount: number): string {
- const [r1, g1, b1] = hexToRgb(hex);
- const [r2, g2, b2] = hexToRgb(targetHex);
- return rgbToHex(
- Math.round(r1 + (r2 - r1) * amount),
- Math.round(g1 + (g2 - g1) * amount),
- Math.round(b1 + (b2 - b1) * amount),
- );
-}
-
function envelopeColors(bgHex: string, primaryHex: string) {
// Tint the envelope body slightly toward the primary color so it
// contrasts with the raw background even on matching themes.
diff --git a/src/components/letter/StationeryBackground.tsx b/src/components/letter/StationeryBackground.tsx
index bc76a13d..0df8eb00 100644
--- a/src/components/letter/StationeryBackground.tsx
+++ b/src/components/letter/StationeryBackground.tsx
@@ -13,17 +13,18 @@
import { useMemo } from 'react';
import {
FRAME_PRESETS,
+ DEFAULT_STATIONERY_COLOR,
type Stationery,
type ResolvedStationery,
type FrameStyle,
resolveStationery,
} from '@/lib/letterTypes';
import { ColorPaletteDisplay, type PaletteLayout } from './ColorPaletteDisplay';
-import { hexLuminance } from '@/lib/colorUtils';
+import { hexLuminance, darkenHex } from '@/lib/colorUtils';
export type { PaletteLayout } from './ColorPaletteDisplay';
-const DEFAULT_STATIONERY: Stationery = { color: '#F5E6D3' };
+const DEFAULT_STATIONERY: Stationery = { color: DEFAULT_STATIONERY_COLOR };
function frameTintColor(resolved: ResolvedStationery): string {
if (resolved.primaryColor) return resolved.primaryColor;
@@ -31,18 +32,6 @@ function frameTintColor(resolved: ResolvedStationery): string {
return resolved.color ?? '#3a7a3a';
}
-function darkenHex(hex: string, amount: number): string {
- if (!hex) return '#000000';
- const r = parseInt(hex.slice(1, 3), 16);
- const g = parseInt(hex.slice(3, 5), 16);
- const b = parseInt(hex.slice(5, 7), 16);
- const f = 1 - amount;
- const dr = Math.round(r * f);
- const dg = Math.round(g * f);
- const db = Math.round(b * f);
- return `#${dr.toString(16).padStart(2, '0')}${dg.toString(16).padStart(2, '0')}${db.toString(16).padStart(2, '0')}`;
-}
-
interface EmojiFrameProps {
tint: string | null;
thickness: number;
diff --git a/src/components/letter/StationeryPicker.tsx b/src/components/letter/StationeryPicker.tsx
index ffec9272..407fab69 100644
--- a/src/components/letter/StationeryPicker.tsx
+++ b/src/components/letter/StationeryPicker.tsx
@@ -244,7 +244,8 @@ export function StationeryPicker({ selected, onSelect }: StationeryPickerProps)
const { user } = useCurrentUser();
const followListData = useFollowList();
- const followList = new Set(followListData.data?.pubkeys ?? []);
+ const followPubkeyArray = followListData.data?.pubkeys;
+ const followList = useMemo(() => new Set(followPubkeyArray ?? []), [followPubkeyArray]);
const scopedAuthors = useMemo(() => {
if (scope === 'mine') return user ? [user.pubkey] : undefined;
diff --git a/src/hooks/useStationeryColors.ts b/src/hooks/useStationeryColors.ts
index db70225f..36ba0427 100644
--- a/src/hooks/useStationeryColors.ts
+++ b/src/hooks/useStationeryColors.ts
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
-import { type Stationery, resolveStationery } from '@/lib/letterTypes';
+import { type Stationery, resolveStationery, DEFAULT_STATIONERY_COLOR } from '@/lib/letterTypes';
import {
paletteTextColor,
paletteTextColorFaint,
@@ -10,7 +10,7 @@ import {
} from '@/lib/colorUtils';
/** Default stationery when none is provided */
-const DEFAULT_STATIONERY: Stationery = { color: '#F5E6D3' };
+const DEFAULT_STATIONERY: Stationery = { color: DEFAULT_STATIONERY_COLOR };
/**
* useStationeryColors
diff --git a/src/lib/colorUtils.ts b/src/lib/colorUtils.ts
index cdd2abf4..3b83145d 100644
--- a/src/lib/colorUtils.ts
+++ b/src/lib/colorUtils.ts
@@ -207,6 +207,33 @@ export function tokensToCoreColors(tokens: ThemeTokens): CoreThemeColors {
};
}
+// ─── Hex color manipulation ───────────────────────────────────────────
+
+/** Darken a hex color by a factor (0 = no change, 1 = black). */
+export function darkenHex(hex: string, amount: number): string {
+ const [r, g, b] = hexToRgb(hex);
+ const dark = (c: number) => Math.max(0, Math.round(c * (1 - amount)));
+ return rgbToHex(dark(r), dark(g), dark(b));
+}
+
+/** Lighten a hex color by a factor (0 = no change, 1 = white). */
+export function lightenHex(hex: string, amount: number): string {
+ const [r, g, b] = hexToRgb(hex);
+ const light = (c: number) => Math.min(255, Math.round(c + (255 - c) * amount));
+ return rgbToHex(light(r), light(g), light(b));
+}
+
+/** Blend two hex colors by a factor (0 = hex1, 1 = hex2). */
+export function blendHex(hex1: string, hex2: string, amount: number): string {
+ const [r1, g1, b1] = hexToRgb(hex1);
+ const [r2, g2, b2] = hexToRgb(hex2);
+ return rgbToHex(
+ Math.round(r1 + (r2 - r1) * amount),
+ Math.round(g1 + (g2 - g1) * amount),
+ Math.round(b1 + (b2 - b1) * amount),
+ );
+}
+
// ─── Letter stationery color utilities ────────────────────────────────
/** WCAG 2.1 relative luminance of a hex color (0 = black, 1 = white). */
diff --git a/src/lib/letterTypes.ts b/src/lib/letterTypes.ts
index e99f80dc..a2c28930 100644
--- a/src/lib/letterTypes.ts
+++ b/src/lib/letterTypes.ts
@@ -4,6 +4,12 @@ export const LETTER_KIND = 8211;
export const COLOR_MOMENT_KIND = 3367;
export const THEME_KIND = 36767;
+/** Default stationery background color (parchment). */
+export const DEFAULT_STATIONERY_COLOR = '#F5E6D3';
+
+/** Ratio of ruled-line height to card width. Used across letter rendering components. */
+export const LINE_HEIGHT_RATIO = 0.084;
+
/** A sticker placed on top of the letter card */
export interface LetterSticker {
/** Image URL of the sticker (empty string for drawn stickers) */
@@ -203,7 +209,7 @@ export interface Letter {
* No gradients.
*/
export const STATIONERY_PRESETS: Record = {
- parchment: { name: 'Parchment', color: '#F5E6D3', emoji: undefined },
+ parchment: { name: 'Parchment', color: DEFAULT_STATIONERY_COLOR, emoji: undefined },
meadow: { name: 'Meadow', color: '#C8E6C9', emoji: '🌿' },
twilight: { name: 'Twilight', color: '#E1BEE7', emoji: '🌙' },
ocean: { name: 'Ocean', color: '#B3E5FC', emoji: '🌊' },
@@ -276,12 +282,12 @@ export function presetToStationery(key: string): Stationery | undefined {
/** Build a Stationery from a kind 3367 color moment event. */
export function colorMomentToStationery(event: NostrEvent): Stationery {
- const color = event.tags.find(([n]) => n === 'c')?.[1] ?? '#F5E6D3';
+ const color = event.tags.find(([n]) => n === 'c')?.[1] ?? DEFAULT_STATIONERY_COLOR;
return { color, event };
}
/** Build a Stationery from a kind 36767 theme event. */
export function themeToStationery(event: NostrEvent): Stationery {
const bg = event.tags.filter(([n]) => n === 'c').find(([, , marker]) => marker === 'background');
- return { color: bg?.[1] ?? '#F5E6D3', event };
+ return { color: bg?.[1] ?? DEFAULT_STATIONERY_COLOR, event };
}
diff --git a/src/pages/LettersPage.tsx b/src/pages/LettersPage.tsx
index 4b818775..cd86e508 100644
--- a/src/pages/LettersPage.tsx
+++ b/src/pages/LettersPage.tsx
@@ -159,7 +159,6 @@ export function LettersPage() {
{/* Letter detail drawer */}
setSelectedLetter(null)}
/>