diff --git a/.eslintrc.json b/.eslintrc.json index bb7ae4f7..575485d3 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -55,6 +55,7 @@ "no-loss-of-precision": "off", "no-magic-numbers": "off", "no-mixed-operators": "off", + "no-nested-ternary": "off", "no-plusplus": "off", "no-shadow": "off", "no-ternary": "off", diff --git a/src/app/api/(routes)/project/presets/DefaultPreset.ts b/src/app/api/(routes)/project/presets/DefaultPreset.ts index e9d07e56..d6b1bf93 100644 --- a/src/app/api/(routes)/project/presets/DefaultPreset.ts +++ b/src/app/api/(routes)/project/presets/DefaultPreset.ts @@ -6,8 +6,8 @@ import { DEFAULT_NAME, DEFAULT_POSITION, DEFAULT_QUANTIZATION, + DEFAULT_TRACK_INSTRUMENT_BASS, // DEFAULT_TRACK_AUDIO, - // DEFAULT_TRACK_INSTRUMENT_BASS, // DEFAULT_TRACK_SAMPLER, // DEFAULT_TRACK_PLAYERS, DEFAULT_CHANNEL_DRUMS, @@ -20,6 +20,8 @@ import { DEFAULT_SCALE, DEFAULT_ACTIVE_TRACK_ID, DEFAULT_TRACK_OH, + DEFAULT_SWING, + DEFAULT_SWING_SUBDIVISION, } from '@/constants'; import type { IProjectContext } from '@/types/project.types'; @@ -35,8 +37,8 @@ const DefaultPreset: IProjectContext = { position: DEFAULT_POSITION, quantization: DEFAULT_QUANTIZATION, states: DEFAULT_STATES, - swing: 0.25, - swingSubdivision: '8n', + swing: DEFAULT_SWING, + swingSubdivision: DEFAULT_SWING_SUBDIVISION, tracks: [ DEFAULT_TRACK_BD, DEFAULT_TRACK_SD, diff --git a/src/app/common/constants.tsx b/src/app/common/constants.tsx index a53298fc..5f1e1e60 100644 --- a/src/app/common/constants.tsx +++ b/src/app/common/constants.tsx @@ -1,73 +1,51 @@ import _ from 'lodash/fp'; -import * as Tone from 'tone'; import t from '@/core/i18n'; import { ETrackType, type ITrack } from '@/common/types/track.types'; import type { IChannel } from './types/channel.types'; +import { EInstrument } from './types/instrument.types'; // ---------- General - +/*** @Progression */ export const PROGRESSION = [ - /** - * Diatonic - */ - + /*** @Diatonic */ // Major 'ii V I', - /** - * Pop - */ - + /*** @Pop */ // 50s Progression 'I vi IV V', - // Pachelbel's Canon 'I V vi iii IV I IV V', - /** - * Medieval - */ - + /*** @Medieval */ // Passamezzo antico 'i VII i V III VII i V i', - // Passamezzo moderno 'I IV I V I IV I V I', - /** - * Classical - */ - + /*** @Classical */ // Circle Progression 'vi ii V I', - /** - * Blues - */ - + /*** @Blues */ // "12-bar blues" (verify AI msg) 'I V vi IV', - // Eight-bar blues 'I V IV IV I V I V', - // Sixteen-bar blues 'I I I I I I I I IV IV I I V IV I I', - /** - * Jazz - */ - + /*** @Jazz */ // Montgomery Ward bridge 'I IV ii V', ]; + export const isRomanNum = (test: string) => ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii'].includes(test.toLowerCase()); // ---------- Project - const DEFAULT_ACTIVE_TRACK_ID = 'track-bd'; const DEFAULT_BPM = 98; const DEFAULT_CLEF = 'D'; @@ -85,85 +63,59 @@ const DEFAULT_STATES = { }; // -------- Tracks - -/* const DEFAULT_TRACK_INSTRUMENT_BASS: ITrack = { - id: "track-instrument-bass", - name: "Bass", +/*** @Track */ +const DEFAULT_TRACK_INSTRUMENT_BASS: ITrack = { + id: 'track-instrument-bass', + name: 'Bass', type: ETrackType.Instrument, routing: { - output: "master", + output: 'master', input: { id: EInstrument.MonoSynth, - label: "BA", + label: 'BA', options: { - oscillator: { type: "sawtooth" }, - envelope: { attack: 0.01, decay: 0.4, release: 0.3, sustainote: 0.2 }, + oscillator: { type: 'sawtooth' }, + envelope: { attack: 0.01, decay: 0.4, release: 0.3, sustain: 0.2 }, filterEnvelope: { attack: 0.001, baseFrequency: 180, decay: 0.2, octaves: 0, release: 0.2, - sustainote: 0.25, + sustain: 0.25, }, volume: -35, }, parts: [ { - label: "BA-Part1", - events: [ - { note: "D#2", v: 100 }, - { note: "D#2", v: 100 }, - { note: "D#2", v: 100 }, - { note: "D#2", v: 100 }, - - { note: "E2", v: 100 }, - { note: "E2", v: 100 }, - { note: "E2", v: 100 }, - { note: "E2", v: 100 }, - - { note: "F#2", v: 100 }, - { note: "F#2", v: 100 }, - { note: "F#2", v: 100 }, - { note: "F#2", v: 100 }, - - { note: "G2", v: 100 }, - { note: "G2", v: 100 }, - { note: "G2", v: 100 }, - { note: "G2", v: 100 }, - ], - }, - ], + label: 'BA-Part1', + events: [], }, ], }, }, }; -*/ -/* + +// -------- Audio +/*** @Track */ const DEFAULT_TRACK_AUDIO: ITrack = { - id: "track-audio-halloween", - name: "Halloween", + id: 'track-audio-halloween', + name: 'Halloween', routing: { input: { parts: [], - id: "track-audio-input", - label: "Audio", + id: 'track-audio-input', + label: 'Audio', options: { - url: "/halloween.mp3", + url: '/halloween.mp3', }, }, - output: "master", + output: 'master', }, type: ETrackType.Audio, }; -*/ - // -------- Drums - -/*** - * @Track - */ +/*** @Track */ const DEFAULT_TRACK_BD: ITrack = { id: 'track-bd', name: 'Kick', @@ -189,9 +141,7 @@ const DEFAULT_TRACK_BD: ITrack = { }, type: ETrackType.Player, }; -/*** - * @Track - */ +/*** @Track */ const DEFAULT_TRACK_SD: ITrack = { id: 'track-sd', name: 'Snare', @@ -204,11 +154,11 @@ const DEFAULT_TRACK_SD: ITrack = { }, parts: [ { - label: 'SD', + label: 'p1-SD', events: [{ note: 'D2', duration: '16n', x: 8 }], }, { - label: 'SD', + label: 'p2-SD', events: [{ note: 'D2', duration: '16n', x: 8 }], }, ], @@ -217,9 +167,10 @@ const DEFAULT_TRACK_SD: ITrack = { }, type: ETrackType.Player, }; +/*** @Track */ const DEFAULT_TRACK_OH: ITrack = { id: 'track-oh', - name: 'OH', + name: 'Open HiHat', routing: { input: { id: 'Player', @@ -258,9 +209,7 @@ const DEFAULT_TRACK_OH: ITrack = { }, type: ETrackType.Player, }; -/*** - * @Track - */ +/*** @Track */ const DEFAULT_TRACK_HI_TOM: ITrack = { id: 'track-hi-tom', name: 'HiTom', @@ -272,9 +221,9 @@ const DEFAULT_TRACK_HI_TOM: ITrack = { url: './samples/WaveAlchemy/wa_drm_drums/high_tom/wadrm_hitom_acc1_r2.wav', }, parts: [ - { label: 'HiTomPart', events: [] }, + { label: 'HiTomPart1', events: [] }, { - label: 'HiTomPart', + label: 'HiTomPart2', events: [ { note: 'C4', duration: '16n', x: 12 }, { note: 'C4', duration: '16n', x: 13 }, @@ -286,9 +235,7 @@ const DEFAULT_TRACK_HI_TOM: ITrack = { }, type: ETrackType.Player, }; -/*** - * @Track - */ +/*** @Track */ const DEFAULT_TRACK_MI_TOM: ITrack = { id: 'track-mi-tom', name: 'MiToms', @@ -314,9 +261,7 @@ const DEFAULT_TRACK_MI_TOM: ITrack = { }, type: ETrackType.Player, }; -/*** - * @Track - */ +/*** @Track */ const DEFAULT_TRACK_LO_TOM: ITrack = { id: 'track-lo-tom', name: 'LoTom', @@ -342,20 +287,21 @@ const DEFAULT_TRACK_LO_TOM: ITrack = { }, type: ETrackType.Player, }; -/* +// -------- Sampler +/*** @Track */ const DEFAULT_TRACK_SAMPLER: ITrack = { - id: "track-sampler", - name: "Sampler", + id: 'track-sampler', + name: 'Sampler', routing: { input: { id: EInstrument.Sampler, - label: "Drums", + label: 'Drums', options: { - baseUrl: "./samples/WaveAlchemy/wa_808_tape/", + baseUrl: './samples/WaveAlchemy/wa_808_tape/', urls: { - C3: "wa_808tape_kick_01_sat.wav", - D3: "wa_808tape_snare_10_clean.wav", - E3: "wa_808tape_closedhat_08_clean.wav", + C3: 'wa_808tape_kick_01_sat.wav', + D3: 'wa_808tape_snare_10_clean.wav', + E3: 'wa_808tape_closedhat_08_clean.wav', }, volume: -40, fadeIn: 0.2, @@ -363,68 +309,18 @@ const DEFAULT_TRACK_SAMPLER: ITrack = { }, parts: [ { - label: "Drums (Sampler)", - sequences: [ - { - label: "Kick", - events: [ - { note: "C3", v: 95 }, - { note: null }, - { note: null }, - { note: null }, - { note: "C3", v: 89 }, - { note: null }, - { note: null }, - { note: null }, - ], - }, - { - label: "Snare", - events: [ - { note: null }, - { note: null }, - { note: null }, - { note: "D3", v: 94 }, - { note: null }, - { note: null }, - { note: null }, - { note: "D3", v: 89 }, - ], - }, - { - label: "Closed HiHat", - events: [ - [ - { note: "E3", v: 104 }, - { note: "E3", v: 89 }, - ], - { note: "E3", v: 104 }, - { note: "E3", v: 99 }, - { note: "E3", v: 99 }, - [ - { note: "E3", v: 104 }, - { note: "E3", v: 79 }, - ], - { note: "E3", v: 89 }, - { note: "E3", v: 74 }, - { note: null }, - ], - }, - ], + label: 'Drums (Sampler)', + events: [], }, ], }, - output: "ch-drums", + output: 'ch-drums', }, type: ETrackType.Sampler, }; -*/ // --------- Channels - -/*** - @Channel -*/ +/*** @Channel */ const DEFAULT_CHANNEL_DRUMS: IChannel = { id: 'ch-drums', label: 'Drums', @@ -440,9 +336,7 @@ const DEFAULT_CHANNEL_DRUMS: IChannel = { volume: 0, }, }; -/*** - @Channel -*/ +/*** @Channel */ const DEFAULT_CHANNEL_MASTER: IChannel = { id: 'master', label: 'Master', @@ -472,7 +366,7 @@ export { DEFAULT_STATES, // // DEFAULT_TRACK_AUDIO, - // DEFAULT_TRACK_INSTRUMENT_BASS, + DEFAULT_TRACK_INSTRUMENT_BASS, // DEFAULT_TRACK_PLAYERS, // DEFAULT_TRACK_SAMPLER, DEFAULT_TRACK_BD, diff --git a/src/app/components/App.tsx b/src/app/components/App.tsx index 8ed8b139..8be7872e 100644 --- a/src/app/components/App.tsx +++ b/src/app/components/App.tsx @@ -29,7 +29,7 @@ import { Settings, Sheet, } from '@/components'; -import { A, Adsr, Grid, Menu, Nav, Tabs, TabsPanel } from '@/pfui'; +import { A, Adsr, GoldKnob, Grid, Menu, Nav, Tabs, TabsPanel } from '@/pfui'; import useProjectContext from '@/core/hooks/api/useProjectContext'; import useAudioInstrument from '@/core/hooks/audio/useAudioInstrument'; @@ -213,6 +213,10 @@ export function App() {

News & Showroom


+
+

Knobs

+ +

@@ -225,6 +229,7 @@ export function App() {

+
diff --git a/src/app/components/track/Track.tsx b/src/app/components/track/Track.tsx index 1f112453..d8bbb1a0 100644 --- a/src/app/components/track/Track.tsx +++ b/src/app/components/track/Track.tsx @@ -49,9 +49,6 @@ function Track({ const $li = classNames($.row, className); const $e = { onArrangementClick: (event: MouseEvent) => { - const trackId = ( - event.currentTarget.previousSibling as HTMLElement - ).getAttribute('data-track-id')!; const element = event.target as HTMLElement; const clientX = event.clientX - DEFAULT_OFFSET_LEFT; const qWidth = windowWidth / 16 / measureCount; @@ -60,7 +57,6 @@ function Track({ const qIndex = qTotalIndex - partIndex * 16; const isNote = element.getAttribute('data-type') === 'note'; - console.log('partIndex', partIndex, qIndex); isNote ? deleteNote({ partIndex, diff --git a/src/app/globals.css b/src/app/globals.css index ce583fef..e24221b2 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -35,7 +35,7 @@ body { /** * Form */ -input[type="range"][orient="vertical"] { +input[type='range'][orient='vertical'] { -webkit-appearance: slider-vertical; appearance: slider-vertical; width: 16px; @@ -415,7 +415,7 @@ input[type="range"][orient="vertical"] { width: 80px; color: #c1c5c5; font-size: 10px; - font-family: "Helvetica", sans-serif; + font-family: 'Helvetica', sans-serif; font-weight: 700; text-align: center; letter-spacing: 1px; @@ -483,3 +483,98 @@ body.knob-input__drag-active, body.knob-input__drag-active * { cursor: grabbing !important; } + +/*** Gold Knob */ +.goldknob { + position: relative; +} + +.goldknob .knob { + width: 80%; + height: 80%; + position: relative; + margin: 10%; + cursor: pointer; +} + +.goldknob .teeth { + display: flex; + align-items: center; + justify-content: center; + border-radius: 100%; + width: 100%; + height: 100%; + transform: rotateZ(var(--angle)); + filter: blur(3px) contrast(7); + background: white; +} + +.goldknob .teeth::after { + content: ''; + width: 90%; + height: 90%; + border-radius: 100%; + background: radial-gradient(black 65%, transparent 66%) no-repeat, + repeating-conic-gradient(black 0%, 2.5%, transparent 2.5%, transparent 5%); +} + +.goldknob .cap { + display: flex; + border-radius: 100%; + width: 76%; + height: 76%; + position: absolute; + top: 12%; + left: 12%; + box-shadow: 0 0 2px 1px #c7a472; + background: repeating-conic-gradient( + from 15deg, + #3e2206 0%, + #3e2206 4%, + #f4ebd0 5%, + #f4ebd0 15%, + #3e2206 16%, + #3e2206 34%, + #f4ebd0 35%, + #f4ebd0 45%, + #3e2206 46%, + #3e2206 50% + ); +} + +.goldknob .cap::after { + content: ''; + border-radius: 100%; + width: 90%; + height: 90%; + margin: 5%; + background: repeating-radial-gradient( + transparent 0%, + rgb(244 235 208 / 15%) 2%, + transparent 4% + ), + repeating-conic-gradient( + from 15deg, + #4d3718 0%, + #c7a472 5%, + #4d3718 16%, + #4d3718 34%, + #c7a472 45%, + #4d3718 50% + ); + box-shadow: inset 0 0 7px 0px #c7a472; +} + +.goldknob .indicator { + top: 60%; + left: 48%; + transform-origin: 50% -50%; + position: absolute; + transform: rotateZ(var(--angle)); + width: 4%; + height: 20%; + background: black; + box-shadow: 0 0 2px white; + border-radius: 30%/10%; + pointer-events: none; +} diff --git a/src/packages/pfui/audio/knob/GoldKnob.tsx b/src/packages/pfui/audio/knob/GoldKnob.tsx new file mode 100644 index 00000000..66cdcf61 --- /dev/null +++ b/src/packages/pfui/audio/knob/GoldKnob.tsx @@ -0,0 +1,77 @@ +import classNames from 'classnames'; +import { ChangeEvent, KeyboardEvent, MouseEvent, useState } from 'react'; + +/*** @design https://codepen.io/ykadosh/pen/LYOwdEZ */ +export function GoldKnob({ + initialValue = 0, + size = 80, +}: { + initialValue?: number; + size?: number; +}) { + const [value, setValue] = useState(initialValue); + const [previewValue, setPreviewValue] = useState(initialValue); + const [inputVisible, setInputVisible] = useState(false); + const [y, setY] = useState(0); + + return ( +
{ + setInputVisible(true); + }} + onMouseDown={(event: MouseEvent) => { + setY(event.clientY); + }} + onMouseUp={(event: MouseEvent) => { + const newValue = value + (y - event.clientY); + const finalValue = newValue < 0 ? 0 : newValue > 320 ? 320 : newValue; + console.log('[GoldKnob] value:', finalValue); + setValue(finalValue); + }} + > +
+
+
+
+
+
+ { + const currentStringValue = (event.target as HTMLInputElement).value; + if (!currentStringValue) return setPreviewValue(0); + const currentValue = parseInt(currentStringValue, 10); + setPreviewValue( + currentValue < 0 ? 0 : currentValue > 320 ? 320 : currentValue + ); + }} + onKeyDown={(event: KeyboardEvent) => { + if (event.key === 'Escape') return setInputVisible(false); + if (event.key !== 'Enter') return; + const currentStringValue = (event.target as HTMLInputElement).value; + if (!currentStringValue) return setValue(0); + const currentValue = parseInt(currentStringValue, 10); + setValue( + currentValue < 0 ? 0 : currentValue > 320 ? 320 : currentValue + ); + setInputVisible(false); + }} + /> +
+
+ ); +} diff --git a/src/packages/pfui/index.ts b/src/packages/pfui/index.ts index 0886e692..93a72217 100644 --- a/src/packages/pfui/index.ts +++ b/src/packages/pfui/index.ts @@ -19,6 +19,7 @@ export { Tabs, TabsPanel } from './tabs'; // TabsPanel obsolete? // Audio export { Adsr } from './audio/envelope/adsr/Adsr'; +export { GoldKnob } from './audio/knob/GoldKnob'; export { Knob } from './audio/knob/Knob'; // Layout diff --git a/tailwind.config.js b/tailwind.config.js index 5c08a85a..2a118dfd 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,323 +1,323 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./src/app/**/*.{ts,tsx}", "./public/genres/**/*.{ts,tsx}"], + content: ['./src/app/**/*.{ts,tsx}', './public/genres/**/*.{ts,tsx}'], safelist: [{ pattern: /bg-./u }], theme: { extend: { backgroundImage: { - "gradient-radial": "radial-gradient(var(--tw-gradient-stops))", - "gradient-conic": - "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))", + 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', + 'gradient-conic': + 'conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))', }, }, colors: { - transparent: "transparent", - current: "currentColor", - black: "#000", - white: "#fff", + transparent: 'transparent', + current: 'currentColor', + black: '#000', + white: '#fff', amber: { - 50: "hsl(48, 100%, 96%)", - 100: "hsl(48, 96%, 89%)", - 200: "hsl(48, 97%, 77%)", - 300: "hsl(46, 97%, 65%)", - 400: "hsl(43, 96%, 56%)", - 500: "hsl(38, 92%, 50%)", - 600: "hsl(32, 95%, 44%)", - 700: "hsl(26, 90%, 37%)", - 800: "hsl(23, 83%, 31%)", - 900: "hsl(22, 78%, 26%)", - 950: "hsl(21, 92%, 14%)", + 50: 'hsl(48, 100%, 96%)', + 100: 'hsl(48, 96%, 89%)', + 200: 'hsl(48, 97%, 77%)', + 300: 'hsl(46, 97%, 65%)', + 400: 'hsl(43, 96%, 56%)', + 500: 'hsl(38, 92%, 50%)', + 600: 'hsl(32, 95%, 44%)', + 700: 'hsl(26, 90%, 37%)', + 800: 'hsl(23, 83%, 31%)', + 900: 'hsl(22, 78%, 26%)', + 950: 'hsl(21, 92%, 14%)', }, blue: { - 50: "hsl(214, 100%, 97%)", - 100: "hsl(214, 95%, 93%)", - 200: "hsl(213, 97%, 87%)", - 300: "hsl(212, 96%, 78%)", - 400: "hsl(213, 94%, 68%)", - 500: "hsl(217, 91%, 60%)", - 600: "hsl(221, 83%, 53%)", - 700: "hsl(224, 76%, 48%)", - 800: "hsl(226, 71%, 40%)", - 900: "hsl(224, 64%, 33%)", - 950: "hsl(226, 57%, 21%)", + 50: 'hsl(214, 100%, 97%)', + 100: 'hsl(214, 95%, 93%)', + 200: 'hsl(213, 97%, 87%)', + 300: 'hsl(212, 96%, 78%)', + 400: 'hsl(213, 94%, 68%)', + 500: 'hsl(217, 91%, 60%)', + 600: 'hsl(221, 83%, 53%)', + 700: 'hsl(224, 76%, 48%)', + 800: 'hsl(226, 71%, 40%)', + 900: 'hsl(224, 64%, 33%)', + 950: 'hsl(226, 57%, 21%)', }, cyan: { - 50: "hsl(183, 100%, 96%)", - 100: "hsl(185, 96%, 90%)", - 200: "hsl(186, 94%, 82%)", - 300: "hsl(187, 92%, 69%)", - 400: "hsl(188, 86%, 53%)", - 500: "hsl(189, 94%, 43%)", - 600: "hsl(192, 91%, 36%)", - 700: "hsl(193, 82%, 31%)", - 800: "hsl(194, 70%, 27%)", - 900: "hsl(196, 64%, 24%)", - 950: "hsl(197, 79%, 15%)", + 50: 'hsl(183, 100%, 96%)', + 100: 'hsl(185, 96%, 90%)', + 200: 'hsl(186, 94%, 82%)', + 300: 'hsl(187, 92%, 69%)', + 400: 'hsl(188, 86%, 53%)', + 500: 'hsl(189, 94%, 43%)', + 600: 'hsl(192, 91%, 36%)', + 700: 'hsl(193, 82%, 31%)', + 800: 'hsl(194, 70%, 27%)', + 900: 'hsl(196, 64%, 24%)', + 950: 'hsl(197, 79%, 15%)', }, emerald: { - 50: "#ecfdf5", - 100: "#d1fae5", - 200: "#a7f3d0", - 300: "#6ee7b7", - 400: "#34d399", - 500: "#10b981", - 600: "#059669", - 700: "#047857", - 800: "#065f46", - 900: "#064e3b", - 950: "#022c22", + 50: '#ecfdf5', + 100: '#d1fae5', + 200: '#a7f3d0', + 300: '#6ee7b7', + 400: '#34d399', + 500: '#10b981', + 600: '#059669', + 700: '#047857', + 800: '#065f46', + 900: '#064e3b', + 950: '#022c22', }, everglade: { - 50: "hsl(140, 53%, 97%)", - 100: "hsl(140, 63%, 93%)", - 200: "hsl(141, 61%, 85%)", - 300: "hsl(141, 58%, 73%)", - 400: "hsl(142, 52%, 58%)", - 500: "hsl(142, 53%, 45%)", - 600: "hsl(142, 58%, 36%)", - 700: "hsl(142, 54%, 29%)", - 800: "hsl(143, 50%, 24%)", - 900: "hsl(144, 47%, 17%)", - 950: "hsl(145, 61%, 10%)", + 50: 'hsl(140, 53%, 97%)', + 100: 'hsl(140, 63%, 93%)', + 200: 'hsl(141, 61%, 85%)', + 300: 'hsl(141, 58%, 73%)', + 400: 'hsl(142, 52%, 58%)', + 500: 'hsl(142, 53%, 45%)', + 600: 'hsl(142, 58%, 36%)', + 700: 'hsl(142, 54%, 29%)', + 800: 'hsl(143, 50%, 24%)', + 900: 'hsl(144, 47%, 17%)', + 950: 'hsl(145, 61%, 10%)', }, fuchsia: { - 50: "hsl(289, 100%, 98%)", - 100: "hsl(287, 100%, 95%)", - 200: "hsl(288, 96%, 91%)", - 300: "hsl(291, 93%, 83%)", - 400: "hsl(292, 91%, 73%)", - 500: "hsl(292, 84%, 61%)", - 600: "hsl(293, 69%, 49%)", - 700: "hsl(295, 72%, 40%)", - 800: "hsl(295, 70%, 33%)", - 900: "hsl(297, 64%, 28%)", - 950: "hsl(297, 90%, 16%)", + 50: 'hsl(289, 100%, 98%)', + 100: 'hsl(287, 100%, 95%)', + 200: 'hsl(288, 96%, 91%)', + 300: 'hsl(291, 93%, 83%)', + 400: 'hsl(292, 91%, 73%)', + 500: 'hsl(292, 84%, 61%)', + 600: 'hsl(293, 69%, 49%)', + 700: 'hsl(295, 72%, 40%)', + 800: 'hsl(295, 70%, 33%)', + 900: 'hsl(297, 64%, 28%)', + 950: 'hsl(297, 90%, 16%)', }, gray: { - 50: "hsl(210, 20%, 98%)", - 100: "hsl(220, 14%, 96%)", - 200: "hsl(220, 13%, 91%)", - 300: "hsl(216, 12%, 84%)", - 400: "hsl(218, 11%, 65%)", - 500: "hsl(220, 9%, 46%)", - 600: "hsl(215, 14%, 34%)", - 700: "hsl(217, 19%, 27%)", - 800: "hsl(215, 28%, 17%)", - 900: "hsl(221, 39%, 11%)", - 950: "hsl(224, 71%, 4%)", + 50: 'hsl(210, 20%, 98%)', + 100: 'hsl(220, 14%, 96%)', + 200: 'hsl(220, 13%, 91%)', + 300: 'hsl(216, 12%, 84%)', + 400: 'hsl(218, 11%, 65%)', + 500: 'hsl(220, 9%, 46%)', + 600: 'hsl(215, 14%, 34%)', + 700: 'hsl(217, 19%, 27%)', + 800: 'hsl(215, 28%, 17%)', + 900: 'hsl(221, 39%, 11%)', + 950: 'hsl(224, 71%, 4%)', }, green: { - 50: "hsl(138, 76%, 97%)", - 100: "hsl(141, 84%, 93%)", - 200: "hsl(141, 79%, 85%)", - 300: "hsl(142, 77%, 73%)", - 400: "hsl(142, 69%, 58%)", - 500: "hsl(142, 71%, 45%)", - 600: "hsl(142, 76%, 36%)", - 700: "hsl(142, 72%, 29%)", - 800: "hsl(143, 64%, 24%)", - 900: "hsl(144, 61%, 20%)", - 950: "hsl(145, 80%, 10%)", + 50: 'hsl(138, 76%, 97%)', + 100: 'hsl(141, 84%, 93%)', + 200: 'hsl(141, 79%, 85%)', + 300: 'hsl(142, 77%, 73%)', + 400: 'hsl(142, 69%, 58%)', + 500: 'hsl(142, 71%, 45%)', + 600: 'hsl(142, 76%, 36%)', + 700: 'hsl(142, 72%, 29%)', + 800: 'hsl(143, 64%, 24%)', + 900: 'hsl(144, 61%, 20%)', + 950: 'hsl(145, 80%, 10%)', }, indigo: { - 50: "hsl(226, 100%, 97%)", - 100: "hsl(226, 100%, 94%)", - 200: "hsl(228, 96%, 89%)", - 300: "hsl(230, 94%, 82%)", - 400: "hsl(234, 89%, 74%)", - 500: "hsl(239, 84%, 67%)", - 600: "hsl(243, 75%, 59%)", - 700: "hsl(245, 58%, 51%)", - 800: "hsl(244, 55%, 41%)", - 900: "hsl(242, 47%, 34%)", - 950: "hsl(244, 47%, 20%)", + 50: 'hsl(226, 100%, 97%)', + 100: 'hsl(226, 100%, 94%)', + 200: 'hsl(228, 96%, 89%)', + 300: 'hsl(230, 94%, 82%)', + 400: 'hsl(234, 89%, 74%)', + 500: 'hsl(239, 84%, 67%)', + 600: 'hsl(243, 75%, 59%)', + 700: 'hsl(245, 58%, 51%)', + 800: 'hsl(244, 55%, 41%)', + 900: 'hsl(242, 47%, 34%)', + 950: 'hsl(244, 47%, 20%)', }, lime: { - 50: "hsl(78, 92%, 95%)", - 100: "hsl(80, 89%, 89%)", - 200: "hsl(81, 88%, 80%)", - 300: "hsl(82, 85%, 67%)", - 400: "hsl(83, 78%, 55%)", - 500: "hsl(84, 81%, 44%)", - 600: "hsl(85, 85%, 35%)", - 700: "hsl(86, 78%, 27%)", - 800: "hsl(86, 69%, 23%)", - 900: "hsl(88, 61%, 20%)", - 950: "hsl(89, 80%, 10%)", + 50: 'hsl(78, 92%, 95%)', + 100: 'hsl(80, 89%, 89%)', + 200: 'hsl(81, 88%, 80%)', + 300: 'hsl(82, 85%, 67%)', + 400: 'hsl(83, 78%, 55%)', + 500: 'hsl(84, 81%, 44%)', + 600: 'hsl(85, 85%, 35%)', + 700: 'hsl(86, 78%, 27%)', + 800: 'hsl(86, 69%, 23%)', + 900: 'hsl(88, 61%, 20%)', + 950: 'hsl(89, 80%, 10%)', }, neutral: { - 50: "hsl(NaN, 0%, 98%)", - 100: "hsl(NaN, 0%, 96%)", - 200: "hsl(NaN, 0%, 90%)", - 300: "hsl(NaN, 0%, 83%)", - 400: "hsl(NaN, 0%, 64%)", - 500: "hsl(NaN, 0%, 45%)", - 600: "hsl(NaN, 0%, 32%)", - 700: "hsl(NaN, 0%, 25%)", - 800: "hsl(NaN, 0%, 15%)", - 900: "hsl(NaN, 0%, 9%)", - 950: "hsl(NaN, 0%, 4%)", + 50: 'hsl(NaN, 0%, 98%)', + 100: 'hsl(NaN, 0%, 96%)', + 200: 'hsl(NaN, 0%, 90%)', + 300: 'hsl(NaN, 0%, 83%)', + 400: 'hsl(NaN, 0%, 64%)', + 500: 'hsl(NaN, 0%, 45%)', + 600: 'hsl(NaN, 0%, 32%)', + 700: 'hsl(NaN, 0%, 25%)', + 800: 'hsl(NaN, 0%, 15%)', + 900: 'hsl(NaN, 0%, 9%)', + 950: 'hsl(NaN, 0%, 4%)', }, orange: { - 50: "hsl(33, 100%, 96%)", - 100: "hsl(34, 100%, 92%)", - 200: "hsl(32, 98%, 83%)", - 300: "hsl(31, 97%, 72%)", - 400: "hsl(27, 96%, 61%)", - 500: "hsl(25, 95%, 53%)", - 600: "hsl(21, 90%, 48%)", - 700: "hsl(17, 88%, 40%)", - 800: "hsl(15, 79%, 34%)", - 900: "hsl(15, 75%, 28%)", - 950: "hsl(13, 81%, 15%)", + 50: 'hsl(33, 100%, 96%)', + 100: 'hsl(34, 100%, 92%)', + 200: 'hsl(32, 98%, 83%)', + 300: 'hsl(31, 97%, 72%)', + 400: 'hsl(27, 96%, 61%)', + 500: 'hsl(25, 95%, 53%)', + 600: 'hsl(21, 90%, 48%)', + 700: 'hsl(17, 88%, 40%)', + 800: 'hsl(15, 79%, 34%)', + 900: 'hsl(15, 75%, 28%)', + 950: 'hsl(13, 81%, 15%)', }, pink: { - 50: "hsl(327, 73%, 97%)", - 100: "hsl(326, 78%, 95%)", - 200: "hsl(326, 85%, 90%)", - 300: "hsl(327, 87%, 82%)", - 400: "hsl(329, 86%, 70%)", - 500: "hsl(330, 81%, 60%)", - 600: "hsl(333, 71%, 51%)", - 700: "hsl(335, 78%, 42%)", - 800: "hsl(336, 74%, 35%)", - 900: "hsl(336, 69%, 30%)", - 950: "hsl(336, 84%, 17%)", + 50: 'hsl(327, 73%, 97%)', + 100: 'hsl(326, 78%, 95%)', + 200: 'hsl(326, 85%, 90%)', + 300: 'hsl(327, 87%, 82%)', + 400: 'hsl(329, 86%, 70%)', + 500: 'hsl(330, 81%, 60%)', + 600: 'hsl(333, 71%, 51%)', + 700: 'hsl(335, 78%, 42%)', + 800: 'hsl(336, 74%, 35%)', + 900: 'hsl(336, 69%, 30%)', + 950: 'hsl(336, 84%, 17%)', }, purple: { - 50: "hsl(270, 100%, 98%)", - 100: "hsl(269, 100%, 95%)", - 200: "hsl(269, 100%, 92%)", - 300: "hsl(269, 97%, 85%)", - 400: "hsl(270, 95%, 75%)", - 500: "hsl(271, 91%, 65%)", - 600: "hsl(271, 81%, 56%)", - 700: "hsl(272, 72%, 47%)", - 800: "hsl(273, 67%, 39%)", - 900: "hsl(274, 66%, 32%)", - 950: "hsl(274, 87%, 21%)", + 50: 'hsl(270, 100%, 98%)', + 100: 'hsl(269, 100%, 95%)', + 200: 'hsl(269, 100%, 92%)', + 300: 'hsl(269, 97%, 85%)', + 400: 'hsl(270, 95%, 75%)', + 500: 'hsl(271, 91%, 65%)', + 600: 'hsl(271, 81%, 56%)', + 700: 'hsl(272, 72%, 47%)', + 800: 'hsl(273, 67%, 39%)', + 900: 'hsl(274, 66%, 32%)', + 950: 'hsl(274, 87%, 21%)', }, red: { - 50: "hsl(0, 86%, 97%)", - 100: "hsl(0, 93%, 94%)", - 200: "hsl(0, 96%, 89%)", - 300: "hsl(0, 94%, 82%)", - 400: "hsl(0, 91%, 71%)", - 500: "hsl(0, 84%, 60%)", - 600: "hsl(0, 72%, 51%)", - 700: "hsl(0, 74%, 42%)", - 800: "hsl(0, 70%, 35%)", - 900: "hsl(0, 63%, 31%)", - 950: "hsl(0, 75%, 15%)", + 50: 'hsl(0, 86%, 97%)', + 100: 'hsl(0, 93%, 94%)', + 200: 'hsl(0, 96%, 89%)', + 300: 'hsl(0, 94%, 82%)', + 400: 'hsl(0, 91%, 71%)', + 500: 'hsl(0, 84%, 60%)', + 600: 'hsl(0, 72%, 51%)', + 700: 'hsl(0, 74%, 42%)', + 800: 'hsl(0, 70%, 35%)', + 900: 'hsl(0, 63%, 31%)', + 950: 'hsl(0, 75%, 15%)', }, rose: { - 50: "hsl(356, 100%, 97%)", - 100: "hsl(356, 100%, 95%)", - 200: "hsl(353, 96%, 90%)", - 300: "hsl(353, 96%, 82%)", - 400: "hsl(351, 95%, 71%)", - 500: "hsl(350, 89%, 60%)", - 600: "hsl(347, 77%, 50%)", - 700: "hsl(345, 83%, 41%)", - 800: "hsl(343, 80%, 35%)", - 900: "hsl(342, 75%, 30%)", - 950: "hsl(343, 88%, 16%)", + 50: 'hsl(356, 100%, 97%)', + 100: 'hsl(356, 100%, 95%)', + 200: 'hsl(353, 96%, 90%)', + 300: 'hsl(353, 96%, 82%)', + 400: 'hsl(351, 95%, 71%)', + 500: 'hsl(350, 89%, 60%)', + 600: 'hsl(347, 77%, 50%)', + 700: 'hsl(345, 83%, 41%)', + 800: 'hsl(343, 80%, 35%)', + 900: 'hsl(342, 75%, 30%)', + 950: 'hsl(343, 88%, 16%)', }, sky: { - 50: "hsl(204, 100%, 97%)", - 100: "hsl(204, 94%, 94%)", - 200: "hsl(201, 94%, 86%)", - 300: "hsl(199, 95%, 74%)", - 400: "hsl(198, 93%, 60%)", - 500: "hsl(199, 89%, 48%)", - 600: "hsl(200, 98%, 39%)", - 700: "hsl(201, 96%, 32%)", - 800: "hsl(201, 90%, 27%)", - 900: "hsl(202, 80%, 24%)", - 950: "hsl(204, 80%, 16%)", + 50: 'hsl(204, 100%, 97%)', + 100: 'hsl(204, 94%, 94%)', + 200: 'hsl(201, 94%, 86%)', + 300: 'hsl(199, 95%, 74%)', + 400: 'hsl(198, 93%, 60%)', + 500: 'hsl(199, 89%, 48%)', + 600: 'hsl(200, 98%, 39%)', + 700: 'hsl(201, 96%, 32%)', + 800: 'hsl(201, 90%, 27%)', + 900: 'hsl(202, 80%, 24%)', + 950: 'hsl(204, 80%, 16%)', }, slate: { - 50: "hsl(210, 40%, 98%)", - 100: "hsl(210, 40%, 96%)", - 200: "hsl(214, 32%, 91%)", - 300: "hsl(213, 27%, 84%)", - 400: "hsl(215, 20%, 65%)", - 500: "hsl(215, 16%, 47%)", - 600: "hsl(215, 19%, 35%)", - 700: "hsl(215, 25%, 27%)", - 800: "hsl(217, 33%, 17%)", - 900: "hsl(222, 47%, 11%)", - 950: "hsl(229, 84%, 5%)", + 50: 'hsl(210, 40%, 98%)', + 100: 'hsl(210, 40%, 96%)', + 200: 'hsl(214, 32%, 91%)', + 300: 'hsl(213, 27%, 84%)', + 400: 'hsl(215, 20%, 65%)', + 500: 'hsl(215, 16%, 47%)', + 600: 'hsl(215, 19%, 35%)', + 700: 'hsl(215, 25%, 27%)', + 800: 'hsl(217, 33%, 17%)', + 900: 'hsl(222, 47%, 11%)', + 950: 'hsl(229, 84%, 5%)', }, stone: { - 50: "hsl(60, 9%, 98%)", - 100: "hsl(60, 5%, 96%)", - 200: "hsl(20, 6%, 90%)", - 300: "hsl(24, 6%, 83%)", - 400: "hsl(24, 5%, 64%)", - 500: "hsl(25, 5%, 45%)", - 600: "hsl(33, 5%, 32%)", - 700: "hsl(30, 6%, 25%)", - 800: "hsl(12, 6%, 15%)", - 900: "hsl(24, 10%, 10%)", - 950: "hsl(20, 14%, 4%)", + 50: 'hsl(60, 9%, 98%)', + 100: 'hsl(60, 5%, 96%)', + 200: 'hsl(20, 6%, 90%)', + 300: 'hsl(24, 6%, 83%)', + 400: 'hsl(24, 5%, 64%)', + 500: 'hsl(25, 5%, 45%)', + 600: 'hsl(33, 5%, 32%)', + 700: 'hsl(30, 6%, 25%)', + 800: 'hsl(12, 6%, 15%)', + 900: 'hsl(24, 10%, 10%)', + 950: 'hsl(20, 14%, 4%)', }, teal: { - 50: "hsl(166, 76%, 97%)", - 100: "hsl(167, 85%, 89%)", - 200: "hsl(168, 84%, 78%)", - 300: "hsl(171, 77%, 64%)", - 400: "hsl(172, 66%, 50%)", - 500: "hsl(173, 80%, 40%)", - 600: "hsl(175, 84%, 32%)", - 700: "hsl(175, 77%, 26%)", - 800: "hsl(176, 69%, 22%)", - 900: "hsl(176, 61%, 19%)", - 950: "hsl(179, 84%, 10%)", + 50: 'hsl(166, 76%, 97%)', + 100: 'hsl(167, 85%, 89%)', + 200: 'hsl(168, 84%, 78%)', + 300: 'hsl(171, 77%, 64%)', + 400: 'hsl(172, 66%, 50%)', + 500: 'hsl(173, 80%, 40%)', + 600: 'hsl(175, 84%, 32%)', + 700: 'hsl(175, 77%, 26%)', + 800: 'hsl(176, 69%, 22%)', + 900: 'hsl(176, 61%, 19%)', + 950: 'hsl(179, 84%, 10%)', }, violet: { - 50: "hsl(250, 100%, 98%)", - 100: "hsl(251, 91%, 95%)", - 200: "hsl(251, 95%, 92%)", - 300: "hsl(252, 95%, 85%)", - 400: "hsl(255, 92%, 76%)", - 500: "hsl(258, 90%, 66%)", - 600: "hsl(262, 83%, 58%)", - 700: "hsl(263, 70%, 50%)", - 800: "hsl(263, 69%, 42%)", - 900: "hsl(264, 67%, 35%)", - 950: "hsl(261, 73%, 23%)", + 50: 'hsl(250, 100%, 98%)', + 100: 'hsl(251, 91%, 95%)', + 200: 'hsl(251, 95%, 92%)', + 300: 'hsl(252, 95%, 85%)', + 400: 'hsl(255, 92%, 76%)', + 500: 'hsl(258, 90%, 66%)', + 600: 'hsl(262, 83%, 58%)', + 700: 'hsl(263, 70%, 50%)', + 800: 'hsl(263, 69%, 42%)', + 900: 'hsl(264, 67%, 35%)', + 950: 'hsl(261, 73%, 23%)', }, yellow: { - 50: "hsl(55, 92%, 95%)", - 100: "hsl(55, 97%, 88%)", - 200: "hsl(53, 98%, 77%)", - 300: "hsl(50, 98%, 64%)", - 400: "hsl(48, 96%, 53%)", - 500: "hsl(45, 93%, 47%)", - 600: "hsl(41, 96%, 40%)", - 700: "hsl(35, 92%, 33%)", - 800: "hsl(32, 81%, 29%)", - 900: "hsl(28, 73%, 26%)", - 950: "hsl(26, 83%, 14%)", + 50: 'hsl(55, 92%, 95%)', + 100: 'hsl(55, 97%, 88%)', + 200: 'hsl(53, 98%, 77%)', + 300: 'hsl(50, 98%, 64%)', + 400: 'hsl(48, 96%, 53%)', + 500: 'hsl(45, 93%, 47%)', + 600: 'hsl(41, 96%, 40%)', + 700: 'hsl(35, 92%, 33%)', + 800: 'hsl(32, 81%, 29%)', + 900: 'hsl(28, 73%, 26%)', + 950: 'hsl(26, 83%, 14%)', }, zinc: { - 50: "hsl(NaN, 0%, 98%)", - 100: "hsl(240, 5%, 96%)", - 200: "hsl(240, 6%, 90%)", - 300: "hsl(240, 5%, 84%)", - 400: "hsl(240, 5%, 65%)", - 500: "hsl(240, 4%, 46%)", - 600: "hsl(240, 5%, 34%)", - 700: "hsl(240, 5%, 26%)", - 800: "hsl(240, 4%, 16%)", - 900: "hsl(240, 6%, 10%)", - 950: "hsl(240, 10%, 4%)", + 50: 'hsl(NaN, 0%, 98%)', + 100: 'hsl(240, 5%, 96%)', + 200: 'hsl(240, 6%, 90%)', + 300: 'hsl(240, 5%, 84%)', + 400: 'hsl(240, 5%, 65%)', + 500: 'hsl(240, 4%, 46%)', + 600: 'hsl(240, 5%, 34%)', + 700: 'hsl(240, 5%, 26%)', + 800: 'hsl(240, 4%, 16%)', + 900: 'hsl(240, 6%, 10%)', + 950: 'hsl(240, 10%, 4%)', }, }, }, plugins: [], // type TDarkMode = "class"|"media"|"false" - darkmode: "false", + darkmode: 'false', };