diff --git a/apps/web/src/components/project-controls.tsx b/apps/web/src/components/project-controls.tsx
index 1d6dd1b..61cdbdf 100644
--- a/apps/web/src/components/project-controls.tsx
+++ b/apps/web/src/components/project-controls.tsx
@@ -2,6 +2,11 @@ import { useRef, useState } from 'react'
import { Download, Upload } from 'lucide-react'
import { Button } from '@/components/ui/button'
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipTrigger,
+} from '@/components/ui/tooltip'
import { downloadProject, importProject } from '@/lib/project'
import { usePhotoStore } from '@/stores/photo-store'
import { settingsSnapshot, useSettingsStore } from '@/stores/settings-store'
@@ -53,24 +58,36 @@ export function ProjectControls() {
event.target.value = ''
}}
/>
-
-
+
+
+
+
+ Open project
+
+
+
+
+
+ Save project
+
{error && {error}}
diff --git a/apps/web/src/lib/pdf-fonts.ts b/apps/web/src/lib/pdf-fonts.ts
index 6305302..91d0db2 100644
--- a/apps/web/src/lib/pdf-fonts.ts
+++ b/apps/web/src/lib/pdf-fonts.ts
@@ -7,9 +7,10 @@ import patrickHandUrl from '@/fonts/PatrickHand-Regular.ttf?url'
import shadowsUrl from '@/fonts/ShadowsIntoLight-Regular.ttf?url'
// Static TTFs for the handwriting caption fonts, so the exported PDF matches the
-// on-screen preview. Only fonts that render faithfully in pdf-lib (which has no
-// GPOS kerning) are offered — Caveat, a connected script, was dropped for this
-// reason (see #23).
+// on-screen preview. We embed the FULL font (no subsetting): pdf-lib's subsetter
+// drops glyphs for some of these — Kalam came out as scattered half-words — and
+// the size cost is trivial next to the 300-DPI photos. Connected scripts that
+// rely on GPOS kerning pdf-lib lacks (e.g. Caveat) are still excluded (see #23).
const PDF_FONT_URLS: Record = {
'indie-flower': indieFlowerUrl,
'patrick-hand': patrickHandUrl,
@@ -40,7 +41,7 @@ export async function embedCaptionFont(
if (!url) return null
try {
doc.registerFontkit(fontkit)
- return await doc.embedFont(await fontBytes(url), { subset: true })
+ return await doc.embedFont(await fontBytes(url), { subset: false })
} catch {
return null
}
diff --git a/apps/web/src/styles.css b/apps/web/src/styles.css
index 9a66256..70d3aeb 100644
--- a/apps/web/src/styles.css
+++ b/apps/web/src/styles.css
@@ -10,6 +10,8 @@
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
+ --popover: oklch(1 0 0);
+ --popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
@@ -30,6 +32,8 @@
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
+ --popover: oklch(0.205 0 0);
+ --popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.985 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
@@ -53,6 +57,8 @@
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
+ --color-popover: var(--popover);
+ --color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);