Auto-mode commit 7aa33cd accidentally deleted 78 files (14,814 lines) during M005
execution. Subsequent commits rebuilt some frontend files but backend/, alembic/,
tests/, whisper/, docker configs, and prompts were never restored in this repo.
This commit restores the full project tree by syncing from ub01's working directory,
which has all M001-M007 features running in production containers.
Restored: backend/ (config, models, routers, database, redis, search_service, worker),
alembic/ (6 migrations), docker/ (Dockerfiles, nginx, compose), prompts/ (4 stages),
tests/, whisper/, README.md, .env.example, chrysopedia-spec.md
124 lines
4.1 KiB
XML
124 lines
4.1 KiB
XML
/**
|
|
* Purpose-built SVG icons for topic categories and navigation.
|
|
* Monoline stroke style — no fills, currentColor inheritance,
|
|
* designed to feel like audio tool UI, not clip art.
|
|
*/
|
|
|
|
const S = { width: "1.2em", height: "1.2em", verticalAlign: "-0.15em" } as const;
|
|
const P = { fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round" as const, strokeLinejoin: "round" as const };
|
|
|
|
/** Routing nodes — signal flow / DAW session */
|
|
export function IconWorkflow() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<circle {...P} cx="4" cy="12" r="2" />
|
|
<circle {...P} cx="20" cy="6" r="2" />
|
|
<circle {...P} cx="20" cy="18" r="2" />
|
|
<path {...P} d="M6 12 h4 q4 0 4-4 l0-2" />
|
|
<path {...P} d="M6 12 h4 q4 0 4 4 l0 2" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Interval / two notes on a staff fragment */
|
|
export function IconMusicTheory() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<line {...P} x1="3" y1="8" x2="21" y2="8" strokeOpacity={0.3} />
|
|
<line {...P} x1="3" y1="12" x2="21" y2="12" strokeOpacity={0.3} />
|
|
<line {...P} x1="3" y1="16" x2="21" y2="16" strokeOpacity={0.3} />
|
|
<ellipse {...P} cx="8" cy="14" rx="2.5" ry="2" transform="rotate(-15 8 14)" strokeWidth={1.8} />
|
|
<line {...P} x1="10.3" y1="13" x2="10.3" y2="4" strokeWidth={1.8} />
|
|
<ellipse {...P} cx="16" cy="10" rx="2.5" ry="2" transform="rotate(-15 16 10)" strokeWidth={1.8} />
|
|
<line {...P} x1="18.3" y1="9" x2="18.3" y2="4" strokeWidth={1.8} />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Speaker cone with two radiation arcs */
|
|
export function IconSoundDesign() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<polygon {...P} points="3,9 3,15 6,15 11,19 11,5 6,9" />
|
|
<path {...P} d="M14 9.5 a4 4 0 0 1 0 5" />
|
|
<path {...P} d="M16.5 7 a7.5 7.5 0 0 1 0 10" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Oscillator waveshapes — sine morphing to saw */
|
|
export function IconSynthesis() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<path {...P} d="M2 12 Q5 4, 8 12 Q11 20, 14 12 L17 5 V19 L20 12 H22" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Timeline blocks — arrangement regions at staggered positions */
|
|
export function IconArrangement() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<rect {...P} x="2" y="5" width="8" height="3" rx="1" />
|
|
<rect {...P} x="6" y="10.5" width="12" height="3" rx="1" />
|
|
<rect {...P} x="10" y="16" width="6" height="3" rx="1" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Dual faders at different levels */
|
|
export function IconMixing() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<line {...P} x1="7" y1="4" x2="7" y2="20" />
|
|
<rect {...P} x="4.5" y="8" width="5" height="4" rx="1" />
|
|
<line {...P} x1="17" y1="4" x2="17" y2="20" />
|
|
<rect {...P} x="14.5" y="13" width="5" height="4" rx="1" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Peak meter hitting ceiling — limiter bar at top */
|
|
export function IconMastering() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<line {...P} x1="2" y1="4" x2="22" y2="4" strokeOpacity={0.5} strokeDasharray="2 2" />
|
|
<rect {...P} x="4" y="10" width="3" height="10" rx="0.5" />
|
|
<rect {...P} x="10" y="6" width="3" height="14" rx="0.5" />
|
|
<rect {...P} x="16" y="4" width="3" height="16" rx="0.5" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Grid of categorized items */
|
|
export function IconTopics() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<rect {...P} x="3" y="3" width="7" height="7" rx="1.5" />
|
|
<rect {...P} x="14" y="3" width="7" height="7" rx="1.5" />
|
|
<rect {...P} x="3" y="14" width="7" height="7" rx="1.5" />
|
|
<rect {...P} x="14" y="14" width="7" height="7" rx="1.5" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Person silhouette — minimal */
|
|
export function IconCreators() {
|
|
return (
|
|
<svg viewBox="0 0 24 24" style={S}>
|
|
<circle {...P} cx="12" cy="8" r="4" />
|
|
<path {...P} d="M4 21 v-1 a7 7 0 0 1 16 0 v1" />
|
|
</svg>
|
|
);
|
|
}
|
|
|
|
/** Map from category name → component */
|
|
export const CATEGORY_ICON: Record<string, () => JSX.Element> = {
|
|
"Workflow": IconWorkflow,
|
|
"Music Theory": IconMusicTheory,
|
|
"Sound Design": IconSoundDesign,
|
|
"Synthesis": IconSynthesis,
|
|
"Arrangement": IconArrangement,
|
|
"Mixing": IconMixing,
|
|
"Mastering": IconMastering,
|
|
};
|