diff --git a/src/App.tsx b/src/App.tsx
index 7f91fc7..54cf8a3 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,6 +10,7 @@ import { LightenDarken } from './pages/LightenDarken';
import { MainLayout } from './pages/MainLayout';
import { Mixer } from './pages/Mixer';
import { NewScheme } from './pages/NewScheme';
+import { AutomaticPalette } from './pages/Palette';
import { SchemeDetail } from './pages/SchemeDetail';
import { SchemeNotFound } from './pages/SchemeNotFound';
import { Schemes } from './pages/Schemes';
@@ -39,6 +40,7 @@ const routes = createBrowserRouter([
{ path: 'tints-shades', element: },
{ path: 'lighten-darken', element: },
{ path: 'mixer', element: },
+ { path: 'palette', element: },
{ path: 'wacg', element: },
{ path: 'compare', element: },
{
diff --git a/src/pages/Palette.module.css b/src/pages/Palette.module.css
new file mode 100644
index 0000000..54a8322
--- /dev/null
+++ b/src/pages/Palette.module.css
@@ -0,0 +1,47 @@
+@layer pages {
+ .palette_workspace {
+ flex-direction: column;
+ }
+ .palette_section {
+ width: 100%;
+ flex: 1;
+ display: flex;
+ flex-direction: row;
+ align-items: stretch;
+ gap: var(--spacing-m);
+ }
+ .function_side {
+ display: flex;
+ flex-direction: column;
+ gap: var(--spacing-m);
+ font-size: var(--font-size-s);
+ .mode_navigation {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: var(--spacing-s);
+ }
+ h5 {
+ padding-block: var(--spacing-m);
+ font-size: var(--font-size-m);
+ }
+ }
+ .palette_content {
+ flex: 1;
+ padding: 0 var(--spacing-m);
+ display: flex;
+ flex-direction: column;
+ gap: var(--spacing-s);
+ h5 {
+ padding-block: var(--spacing-m);
+ font-size: var(--font-size-m);
+ }
+ .color_value_mode {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ gap: var(--spacing-s);
+ font-size: var(--font-size-s);
+ }
+ }
+}
diff --git a/src/pages/Palette.tsx b/src/pages/Palette.tsx
new file mode 100644
index 0000000..dac505b
--- /dev/null
+++ b/src/pages/Palette.tsx
@@ -0,0 +1,111 @@
+import cx from 'clsx';
+import { useAtom } from 'jotai';
+import { useEffect, useMemo, useState } from 'react';
+import { ColorPicker } from '../components/ColorPicker';
+import { HSegmentedControl } from '../components/HSegmentedControl';
+import { Labeled } from '../components/Labeled';
+import { LabeledPicker } from '../components/LabeledPicker';
+import { ScrollArea } from '../components/ScrollArea';
+import { Switch } from '../components/Switch';
+import { currentPickedColor } from '../stores/colors';
+import styles from './Palette.module.css';
+
+export function AutomaticPalette() {
+ const [selectedColor, setSelectedColor] = useAtom(currentPickedColor);
+ const [useReferenceColor, setUseReferenceColor] = useState(false);
+ const [swatchAmount, setSwatchAmount] = useState(5);
+ const maxBias = useMemo(
+ () => (swatchAmount > 3 ? Math.floor(swatchAmount / 2) - 1 : 0),
+ [swatchAmount],
+ );
+ const [referenceBias, setReferenceBias] = useState(0);
+ const [minLightness, setMinLightness] = useState(10);
+ const [maxLightness, setMaxLightness] = useState(90);
+ const [mode, setMode] = useState<'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch'>('hex');
+
+ useEffect(() => {
+ if (useReferenceColor) {
+ setReferenceBias(0);
+ }
+ }, [swatchAmount, useReferenceColor]);
+
+ return (
+
+
+
+
+
+
+
Generated Palette
+
+
+
+
+
+
+
+
+ );
+}