Introduce end-to-end chapterized audiobook generation with persistent storage, resumable workflows, and MP3/M4B support. API: - add /api/audio/convert/chapter (GET/DELETE) for per-chapter ops - add /api/audio/convert/chapters (GET/DELETE) for listing/reset - enhance /api/audio/convert: - accept mp3|m4b, stream combined file, cache complete output - robust chapter indexing, docstore persistence, list concat - AbortSignal-aware ffmpeg/ffprobe, 499 on cancel UI/UX: - add AudiobookExportModal with progress, resume, regenerate, download - add ProgressCard, enhance ProgressPopup (click-to-focus, richer info) - add Header, ZoomControl; move TTSPlayer to sticky bottom bar - redesign EPUB/HTML/PDF pages for full-height layout and controls - add HomeContent; compact uploader variant; document list polish TTS/Contexts: - EPUB/PDF contexts now generate per-chapter to disk, return bookId - support chapter regeneration; progress/cancel propagation - pass provider/model/instructions; standardize MP3 TTS output - HTML context updates for model/instructions Styling: - globals: overlay-dim, scrollbar styles, prism gradient utilities - theme vars: secondary-accent, prism-gradient; tailwind color addition Misc: - fix PDF scale calc to use container height - EPUB theme reader area fills height - time estimation update cadence stab - audio util passes format to combine endpoint
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import type { Config } from "tailwindcss";
|
|
import typography from "@tailwindcss/typography";
|
|
|
|
export default {
|
|
content: [
|
|
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
|
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
|
],
|
|
darkMode: 'class',
|
|
theme: {
|
|
extend: {
|
|
colors: {
|
|
background: "var(--background)",
|
|
foreground: "var(--foreground)",
|
|
base: "var(--base)",
|
|
offbase: "var(--offbase)",
|
|
accent: "var(--accent)",
|
|
"secondary-accent": "var(--secondary-accent)",
|
|
muted: "var(--muted)",
|
|
},
|
|
animation: {
|
|
'spin-slow': 'spin 2s linear infinite',
|
|
'fade-in': 'fadeIn 200ms ease-in',
|
|
'fade-out': 'fadeOut 200ms ease-out',
|
|
'scale-in': 'scaleIn 200ms ease-in',
|
|
'scale-out': 'scaleOut 200ms ease-out',
|
|
},
|
|
keyframes: {
|
|
fadeIn: {
|
|
'0%': { opacity: '0' },
|
|
'100%': { opacity: '1' },
|
|
},
|
|
fadeOut: {
|
|
'0%': { opacity: '1' },
|
|
'100%': { opacity: '0' },
|
|
},
|
|
scaleIn: {
|
|
'0%': { transform: 'scale(0.95)', opacity: '0' },
|
|
'100%': { transform: 'scale(1)', opacity: '1' },
|
|
},
|
|
scaleOut: {
|
|
'0%': { transform: 'scale(1)', opacity: '1' },
|
|
'100%': { transform: 'scale(0.95)', opacity: '0' },
|
|
},
|
|
},
|
|
typography: {
|
|
DEFAULT: {
|
|
css: {
|
|
'--tw-prose-body': 'var(--foreground)',
|
|
'--tw-prose-headings': 'var(--foreground)',
|
|
'--tw-prose-lead': 'var(--muted)',
|
|
'--tw-prose-links': 'var(--accent)',
|
|
'--tw-prose-bold': 'var(--foreground)',
|
|
'--tw-prose-counters': 'var(--muted)',
|
|
'--tw-prose-bullets': 'var(--muted)',
|
|
'--tw-prose-hr': 'var(--offbase)',
|
|
'--tw-prose-quotes': 'var(--foreground)',
|
|
'--tw-prose-quote-borders': 'var(--offbase)',
|
|
'--tw-prose-captions': 'var(--muted)',
|
|
'--tw-prose-code': 'var(--foreground)',
|
|
'--tw-prose-pre-code': 'var(--foreground)',
|
|
'--tw-prose-pre-bg': 'var(--base)',
|
|
'--tw-prose-th-borders': 'var(--offbase)',
|
|
'--tw-prose-td-borders': 'var(--offbase)',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
plugins: [typography],
|
|
} satisfies Config;
|