@odyn-app/api 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -2
- package/dist/index.d.ts +492 -0
- package/dist/index.js +487 -0
- package/dist/ui/button.d.ts +10 -0
- package/dist/ui/button.js +31 -0
- package/dist/ui/cn.d.ts +3 -0
- package/dist/ui/cn.js +6 -0
- package/dist/ui/index.d.ts +10 -0
- package/dist/ui/index.js +10 -0
- package/dist/ui/orb/orb-base.module.css +21 -0
- package/dist/ui/orb/orb-geometry-cache.d.ts +1 -0
- package/dist/ui/orb/orb-geometry-cache.js +11 -0
- package/dist/ui/orb/orb-helix-geometry.d.ts +7 -0
- package/dist/ui/orb/orb-helix-geometry.js +130 -0
- package/dist/ui/orb/orb-helix.module.css +155 -0
- package/dist/ui/orb/orb-lattice-geometry.d.ts +35 -0
- package/dist/ui/orb/orb-lattice-geometry.js +148 -0
- package/dist/ui/orb/orb-lattice.module.css +165 -0
- package/dist/ui/orb/orb-lens-primary.module.css +195 -0
- package/dist/ui/orb/orb-lens-secondary.module.css +143 -0
- package/dist/ui/orb/orb-lens.module.css +44 -0
- package/dist/ui/orb/orb-morph-geometry.d.ts +7 -0
- package/dist/ui/orb/orb-morph-geometry.js +88 -0
- package/dist/ui/orb/orb-morph.module.css +62 -0
- package/dist/ui/orb/orb-ring-geometry.d.ts +8 -0
- package/dist/ui/orb/orb-ring-geometry.js +42 -0
- package/dist/ui/orb/orb-ring.module.css +113 -0
- package/dist/ui/orb/orb-types.d.ts +23 -0
- package/dist/ui/orb/orb-types.js +48 -0
- package/dist/ui/orb/orb.d.ts +17 -0
- package/dist/ui/orb/orb.js +40 -0
- package/dist/ui/setting-row.d.ts +9 -0
- package/dist/ui/setting-row.js +9 -0
- package/dist/ui/skeleton.d.ts +3 -0
- package/dist/ui/skeleton.js +6 -0
- package/dist/ui/theme.css +232 -0
- package/package.json +56 -4
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S1–S5 are the family's five general looks. S6–S9 are the stacked-PR waits,
|
|
3
|
+
* drawn frame by frame on the same grid: S6 moving work (rising chevrons),
|
|
4
|
+
* S7 sending to GitHub (chevrons right), S8 fetching from it (chevrons left),
|
|
5
|
+
* S9 waiting on someone else (climb).
|
|
6
|
+
*/
|
|
7
|
+
export type LatticeFrameVariant = 'S6' | 'S7' | 'S8' | 'S9';
|
|
8
|
+
export type LatticeVariant = 'S1' | 'S2' | 'S3' | 'S4' | 'S5' | LatticeFrameVariant;
|
|
9
|
+
export type LensVariant = 'B1' | 'B2' | 'B3' | 'B4' | 'B5';
|
|
10
|
+
export type RingVariant = 'C1' | 'C2' | 'C3' | 'C4' | 'C5';
|
|
11
|
+
export type HelixVariant = 'G1' | 'G2' | 'G3' | 'G4' | 'G5';
|
|
12
|
+
export type MorphVariant = 'M1' | 'M2' | 'M3' | 'M4' | 'M5';
|
|
13
|
+
export type OrbVariant = LatticeVariant | LensVariant | RingVariant | HelixVariant | MorphVariant;
|
|
14
|
+
export declare const LATTICE_VARIANTS: readonly LatticeVariant[];
|
|
15
|
+
export declare const RING_VARIANTS: readonly RingVariant[];
|
|
16
|
+
export declare const HELIX_VARIANTS: readonly HelixVariant[];
|
|
17
|
+
export declare const MORPH_VARIANTS: readonly MorphVariant[];
|
|
18
|
+
/** The activity each variant was drawn to read as — used for the orb's label. */
|
|
19
|
+
export declare const ORB_TASKS: Record<OrbVariant, string>;
|
|
20
|
+
export declare function isLattice(variant: OrbVariant): variant is LatticeVariant;
|
|
21
|
+
export declare function isRing(variant: OrbVariant): variant is RingVariant;
|
|
22
|
+
export declare function isHelix(variant: OrbVariant): variant is HelixVariant;
|
|
23
|
+
export declare function isMorph(variant: OrbVariant): variant is MorphVariant;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const LATTICE_VARIANTS = ['S1', 'S2', 'S3', 'S4', 'S5', 'S6', 'S7', 'S8', 'S9'];
|
|
2
|
+
export const RING_VARIANTS = ['C1', 'C2', 'C3', 'C4', 'C5'];
|
|
3
|
+
export const HELIX_VARIANTS = ['G1', 'G2', 'G3', 'G4', 'G5'];
|
|
4
|
+
export const MORPH_VARIANTS = ['M1', 'M2', 'M3', 'M4', 'M5'];
|
|
5
|
+
/** The activity each variant was drawn to read as — used for the orb's label. */
|
|
6
|
+
export const ORB_TASKS = {
|
|
7
|
+
S1: 'Thinking',
|
|
8
|
+
S2: 'Processing',
|
|
9
|
+
S3: 'Working',
|
|
10
|
+
S4: 'Searching',
|
|
11
|
+
S5: 'Finalizing',
|
|
12
|
+
S6: 'Restacking',
|
|
13
|
+
S7: 'Sending',
|
|
14
|
+
S8: 'Fetching',
|
|
15
|
+
S9: 'Waiting',
|
|
16
|
+
B1: 'Thinking',
|
|
17
|
+
B2: 'Searching',
|
|
18
|
+
B3: 'Generating',
|
|
19
|
+
B4: 'Solving',
|
|
20
|
+
B5: 'Routing',
|
|
21
|
+
C1: 'Loading',
|
|
22
|
+
C2: 'Listening',
|
|
23
|
+
C3: 'Streaming',
|
|
24
|
+
C4: 'Analyzing',
|
|
25
|
+
C5: 'Compiling',
|
|
26
|
+
G1: 'Processing',
|
|
27
|
+
G2: 'Sequencing',
|
|
28
|
+
G3: 'Uploading',
|
|
29
|
+
G4: 'Syncing',
|
|
30
|
+
G5: 'Idling',
|
|
31
|
+
M1: 'Shaping',
|
|
32
|
+
M2: 'Expanding',
|
|
33
|
+
M3: 'Unfolding',
|
|
34
|
+
M4: 'Transforming',
|
|
35
|
+
M5: 'Dispersing',
|
|
36
|
+
};
|
|
37
|
+
export function isLattice(variant) {
|
|
38
|
+
return LATTICE_VARIANTS.includes(variant);
|
|
39
|
+
}
|
|
40
|
+
export function isRing(variant) {
|
|
41
|
+
return RING_VARIANTS.includes(variant);
|
|
42
|
+
}
|
|
43
|
+
export function isHelix(variant) {
|
|
44
|
+
return HELIX_VARIANTS.includes(variant);
|
|
45
|
+
}
|
|
46
|
+
export function isMorph(variant) {
|
|
47
|
+
return MORPH_VARIANTS.includes(variant);
|
|
48
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
2
|
+
import { type OrbVariant } from './orb-types';
|
|
3
|
+
export interface OrbProps {
|
|
4
|
+
readonly variant?: OrbVariant;
|
|
5
|
+
/** Rendered edge length in px. The 28px geometry scales to fit. */
|
|
6
|
+
readonly size?: number;
|
|
7
|
+
/** Accessible label. Omit and the variant's own activity word is used. */
|
|
8
|
+
readonly label?: string;
|
|
9
|
+
/** Hide from assistive technology when a visible label already says this. */
|
|
10
|
+
readonly decorative?: boolean;
|
|
11
|
+
/** Hold the orb on its opening frame — the row keeps its shape while idle. */
|
|
12
|
+
readonly paused?: boolean;
|
|
13
|
+
readonly className?: string;
|
|
14
|
+
readonly style?: CSSProperties;
|
|
15
|
+
}
|
|
16
|
+
export declare function Orb({ variant, size, label, decorative, paused, className, style, }: OrbProps): ReactElement;
|
|
17
|
+
export type { OrbVariant } from './orb-types';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import baseStyles from './orb-base.module.css';
|
|
4
|
+
import helixStyles from './orb-helix.module.css';
|
|
5
|
+
import latticeStyles from './orb-lattice.module.css';
|
|
6
|
+
import lensStyles from './orb-lens.module.css';
|
|
7
|
+
import lensPrimaryStyles from './orb-lens-primary.module.css';
|
|
8
|
+
import lensSecondaryStyles from './orb-lens-secondary.module.css';
|
|
9
|
+
import morphStyles from './orb-morph.module.css';
|
|
10
|
+
import ringStyles from './orb-ring.module.css';
|
|
11
|
+
import { globeDots } from './orb-helix-geometry';
|
|
12
|
+
import { latticeCells } from './orb-lattice-geometry';
|
|
13
|
+
import { morphDots } from './orb-morph-geometry';
|
|
14
|
+
import { ringDots } from './orb-ring-geometry';
|
|
15
|
+
import { isHelix, isLattice, isMorph, isRing, ORB_TASKS, } from './orb-types';
|
|
16
|
+
const STAGE = 28;
|
|
17
|
+
const DEFAULT_SIZE = 14;
|
|
18
|
+
const PRIMARY_LENS_VARIANTS = ['B1', 'B2', 'B3'];
|
|
19
|
+
function lensVariantClass(variant) {
|
|
20
|
+
return PRIMARY_LENS_VARIANTS.includes(variant)
|
|
21
|
+
? lensPrimaryStyles.variants
|
|
22
|
+
: lensSecondaryStyles.variants;
|
|
23
|
+
}
|
|
24
|
+
export function Orb({ variant = 'S1', size = DEFAULT_SIZE, label, decorative = false, paused = false, className, style, }) {
|
|
25
|
+
const text = label ?? `${ORB_TASKS[variant]}…`;
|
|
26
|
+
return (_jsx("span", { className: className ? `${baseStyles.root} ${className}` : baseStyles.root, "data-orb-paused": paused ? '' : undefined, style: style, children: _jsx("span", { className: baseStyles.glyph, role: decorative ? undefined : 'img', "aria-label": decorative ? undefined : text, "aria-hidden": decorative ? true : undefined, style: { width: size, height: size, '--orb-k': size / STAGE }, children: isLattice(variant) ? (_jsx("span", { className: latticeStyles.lattice, "data-variant": variant, children: latticeCells(variant).map((cell) => (_jsx("span", { className: latticeStyles.cell, "data-still": cell.still ? '' : undefined, "data-mid": cell.mid ? '' : undefined, style: {
|
|
27
|
+
left: cell.left,
|
|
28
|
+
top: cell.top,
|
|
29
|
+
animationDelay: `${cell.delay}ms`,
|
|
30
|
+
'--orb-ax': `${cell.ax}px`,
|
|
31
|
+
'--orb-ay': `${cell.ay}px`,
|
|
32
|
+
'--orb-bx': `${cell.bx}px`,
|
|
33
|
+
'--orb-by': `${cell.by}px`,
|
|
34
|
+
...cell.frames,
|
|
35
|
+
} }, cell.key))) })) : isRing(variant) ? (_jsx("span", { className: ringStyles.ring, "data-variant": variant, children: ringDots(variant).map((dot) => (_jsx("span", { className: ringStyles.ringDot, style: {
|
|
36
|
+
'--orb-rx': `${dot.rx}px`,
|
|
37
|
+
'--orb-ry': `${dot.ry}px`,
|
|
38
|
+
animationDelay: `${dot.delay}ms`,
|
|
39
|
+
} }, dot.key))) })) : isHelix(variant) ? (_jsx("span", { className: helixStyles.helix, "data-variant": variant, children: globeDots(variant).map((dot) => (_jsx("span", { className: helixStyles.helixDot, style: dot.style }, dot.key))) })) : isMorph(variant) ? (_jsx("span", { className: morphStyles.morph, "data-variant": variant, children: morphDots(variant).map((dot) => (_jsx("span", { className: morphStyles.morphDot, style: dot.style }, dot.key))) })) : (_jsxs("span", { className: `${lensStyles.lens} ${lensVariantClass(variant)}`, "data-variant": variant, children: [_jsx("span", { className: lensStyles.shape, "data-orb-shape": "a" }), _jsx("span", { className: lensStyles.shape, "data-orb-shape": "b" }), _jsx("span", { className: lensStyles.shape, "data-orb-shape": "c" }), variant === 'B1' && (_jsx("span", { className: lensStyles.shape, "data-orb-shape": "d" }))] })) }) }));
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactElement, ReactNode } from 'react';
|
|
2
|
+
export interface SettingRowProps {
|
|
3
|
+
readonly title: string;
|
|
4
|
+
readonly description: ReactNode;
|
|
5
|
+
readonly disabled?: boolean;
|
|
6
|
+
readonly children: ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/** One line of a settings page: a title and description on the left, a control on the right. */
|
|
9
|
+
export declare function SettingRow({ title, description, disabled, children }: SettingRowProps): ReactElement;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from './cn';
|
|
3
|
+
/** One line of a settings page: a title and description on the left, a control on the right. */
|
|
4
|
+
export function SettingRow({ title, description, disabled = false, children }) {
|
|
5
|
+
return (_jsxs("div", { "data-slot": "setting-row", className: cn(
|
|
6
|
+
// A faint line above any row that directly follows another row, so rows
|
|
7
|
+
// are split up without a line at the top or bottom of a group.
|
|
8
|
+
'flex items-start justify-between gap-8 border-border/50 py-3 [[data-slot=setting-row]+&]:border-t', disabled && 'pointer-events-none opacity-40'), children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: title }), _jsx("p", { className: "mt-0.5 max-w-[75%] text-pretty text-xs text-muted-foreground", children: description })] }), _jsx("div", { className: "shrink-0", children: children })] }));
|
|
9
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { cn } from './cn';
|
|
3
|
+
/** A shimmering grey block that holds a space while something loads. */
|
|
4
|
+
export function Skeleton({ className, ...props }) {
|
|
5
|
+
return (_jsx("div", { className: cn('animate-skeleton rounded-sm [--skeleton-highlight:--alpha(var(--color-white)/64%)] [background:linear-gradient(120deg,transparent_40%,var(--skeleton-highlight),transparent_60%)_var(--color-muted)_0_0/200%_100%_fixed] dark:[--skeleton-highlight:--alpha(var(--color-white)/4%)]', className), "data-slot": "skeleton", ...props }));
|
|
6
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The Odyn look for extension pages: colours, fonts and basic page styles, in
|
|
3
|
+
* light and dark. Import it once at the top of your page's stylesheet:
|
|
4
|
+
*
|
|
5
|
+
* @import "@odyn-app/api/theme.css";
|
|
6
|
+
*
|
|
7
|
+
* Dark mode follows a `dark` class on <html>, which your page sets from the
|
|
8
|
+
* theme Odyn hands over (see `connectSurface`).
|
|
9
|
+
*/
|
|
10
|
+
@import "tailwindcss";
|
|
11
|
+
/* The kit's own components live next to this file; tell Tailwind to read them. */
|
|
12
|
+
@source "./";
|
|
13
|
+
@custom-variant dark (&:is(.dark *));
|
|
14
|
+
|
|
15
|
+
:root {
|
|
16
|
+
--font-sans: 'Inter Variable', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
17
|
+
--font-heading: 'Inter Variable', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
@theme inline {
|
|
21
|
+
--animate-skeleton: skeleton 2s -1s infinite linear;
|
|
22
|
+
--animate-caret-blink: 1s ease-out infinite caret-blink;
|
|
23
|
+
--font-heading: var(--font-heading);
|
|
24
|
+
--font-mono: var(--font-mono);
|
|
25
|
+
--font-sans: var(--font-sans);
|
|
26
|
+
--color-sidebar-ring: var(--sidebar-ring);
|
|
27
|
+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
28
|
+
--color-sidebar-primary: var(--sidebar-primary);
|
|
29
|
+
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
30
|
+
--color-sidebar-border: var(--sidebar-border);
|
|
31
|
+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
32
|
+
--color-sidebar-accent: var(--sidebar-accent);
|
|
33
|
+
--color-sidebar: var(--sidebar);
|
|
34
|
+
--color-code-highlight: var(--code-highlight);
|
|
35
|
+
--code-foreground: var(--code-foreground);
|
|
36
|
+
--color-code: var(--code);
|
|
37
|
+
--color-chart-5: var(--chart-5);
|
|
38
|
+
--color-chart-4: var(--chart-4);
|
|
39
|
+
--color-chart-3: var(--chart-3);
|
|
40
|
+
--color-chart-2: var(--chart-2);
|
|
41
|
+
--color-chart-1: var(--chart-1);
|
|
42
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
43
|
+
--color-secondary: var(--secondary);
|
|
44
|
+
--color-ring: var(--ring);
|
|
45
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
46
|
+
--color-primary: var(--primary);
|
|
47
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
48
|
+
--color-popover: var(--popover);
|
|
49
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
50
|
+
--color-muted: var(--muted);
|
|
51
|
+
--color-input: var(--input);
|
|
52
|
+
--color-foreground: var(--foreground);
|
|
53
|
+
--color-destructive: var(--destructive);
|
|
54
|
+
--color-card-foreground: var(--card-foreground);
|
|
55
|
+
--color-card: var(--card);
|
|
56
|
+
--color-border: var(--border);
|
|
57
|
+
--color-background: var(--background);
|
|
58
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
59
|
+
--color-accent: var(--accent);
|
|
60
|
+
--color-warning-foreground: var(--warning-foreground);
|
|
61
|
+
--color-warning: var(--warning);
|
|
62
|
+
--color-success-foreground: var(--success-foreground);
|
|
63
|
+
--color-success: var(--success);
|
|
64
|
+
--color-info-foreground: var(--info-foreground);
|
|
65
|
+
--color-info: var(--info);
|
|
66
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
67
|
+
--text-sm: 0.8125rem;
|
|
68
|
+
--text-sm--line-height: calc(1.125 / 0.8125);
|
|
69
|
+
--radius-sm: calc(var(--radius) * 0.6);
|
|
70
|
+
--radius-md: calc(var(--radius) * 0.8);
|
|
71
|
+
--radius-lg: var(--radius);
|
|
72
|
+
--radius-xl: calc(var(--radius) * 1.4);
|
|
73
|
+
--radius-2xl: calc(var(--radius) * 1.8);
|
|
74
|
+
--radius-3xl: calc(var(--radius) * 2.2);
|
|
75
|
+
--radius-4xl: calc(var(--radius) * 2.6);
|
|
76
|
+
@keyframes skeleton {
|
|
77
|
+
to {
|
|
78
|
+
background-position: -200% 0;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
@keyframes caret-blink {
|
|
82
|
+
0%, 70%, to {
|
|
83
|
+
opacity: 1;
|
|
84
|
+
}
|
|
85
|
+
20%, 50% {
|
|
86
|
+
opacity: 0;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:root {
|
|
92
|
+
--destructive-foreground: var(--color-red-700);
|
|
93
|
+
--info: var(--color-blue-500);
|
|
94
|
+
--info-foreground: var(--color-blue-700);
|
|
95
|
+
--success: var(--color-emerald-500);
|
|
96
|
+
--success-foreground: var(--color-emerald-700);
|
|
97
|
+
--warning: var(--color-amber-500);
|
|
98
|
+
--warning-foreground: var(--color-amber-700);
|
|
99
|
+
--accent: --alpha(var(--color-black) / 4%);
|
|
100
|
+
--accent-foreground: var(--color-neutral-800);
|
|
101
|
+
--background: var(--color-white);
|
|
102
|
+
--border: --alpha(var(--color-black) / 8%);
|
|
103
|
+
--card: var(--color-white);
|
|
104
|
+
--card-foreground: var(--color-neutral-800);
|
|
105
|
+
--destructive: var(--color-red-500);
|
|
106
|
+
--foreground: var(--color-neutral-800);
|
|
107
|
+
--input: --alpha(var(--color-black) / 10%);
|
|
108
|
+
--muted: --alpha(var(--color-black) / 4%);
|
|
109
|
+
--muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-black));
|
|
110
|
+
--popover: var(--color-white);
|
|
111
|
+
--popover-foreground: var(--color-neutral-800);
|
|
112
|
+
--primary: var(--color-neutral-800);
|
|
113
|
+
--primary-foreground: var(--color-neutral-50);
|
|
114
|
+
--ring: var(--color-neutral-400);
|
|
115
|
+
--secondary: --alpha(var(--color-black) / 4%);
|
|
116
|
+
--secondary-foreground: var(--color-neutral-800);
|
|
117
|
+
--chart-1: var(--color-orange-600);
|
|
118
|
+
--chart-2: var(--color-teal-600);
|
|
119
|
+
--chart-3: var(--color-cyan-900);
|
|
120
|
+
--chart-4: var(--color-amber-400);
|
|
121
|
+
--chart-5: var(--color-amber-500);
|
|
122
|
+
--code: var(--color-neutral-50);
|
|
123
|
+
--code-foreground: var(--foreground);
|
|
124
|
+
--code-highlight: --alpha(var(--color-black) / 4%);
|
|
125
|
+
--radius: 0.625rem;
|
|
126
|
+
/* Same surface as the page: the default themes read as one window with a
|
|
127
|
+
divider in it rather than two panels of slightly different greys. The
|
|
128
|
+
named themes below keep their own tinted sidebar. */
|
|
129
|
+
--sidebar: var(--background);
|
|
130
|
+
--sidebar-accent: --alpha(var(--color-black) / 4%);
|
|
131
|
+
--sidebar-accent-foreground: var(--color-neutral-800);
|
|
132
|
+
--sidebar-border: --alpha(var(--color-black) / 6%);
|
|
133
|
+
--sidebar-foreground: color-mix(in srgb, var(--color-neutral-800) 64%, var(--sidebar));
|
|
134
|
+
--sidebar-primary: var(--color-neutral-800);
|
|
135
|
+
--sidebar-primary-foreground: var(--color-neutral-50);
|
|
136
|
+
--sidebar-ring: var(--color-neutral-400);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.dark {
|
|
140
|
+
--destructive-foreground: var(--color-red-400);
|
|
141
|
+
--info: var(--color-blue-500);
|
|
142
|
+
--info-foreground: var(--color-blue-400);
|
|
143
|
+
--success: var(--color-emerald-500);
|
|
144
|
+
--success-foreground: var(--color-emerald-400);
|
|
145
|
+
--warning: var(--color-amber-500);
|
|
146
|
+
--warning-foreground: var(--color-amber-400);
|
|
147
|
+
--accent: --alpha(var(--color-white) / 4%);
|
|
148
|
+
--accent-foreground: var(--color-neutral-100);
|
|
149
|
+
--background: color-mix(in srgb, var(--color-neutral-950) 82%, var(--color-white));
|
|
150
|
+
--border: --alpha(var(--color-white) / 6%);
|
|
151
|
+
--card: color-mix(in srgb, var(--background) 98%, var(--color-white));
|
|
152
|
+
--card-foreground: var(--color-neutral-100);
|
|
153
|
+
--destructive: color-mix(in srgb, var(--color-red-500) 90%, var(--color-white));
|
|
154
|
+
--foreground: var(--color-neutral-100);
|
|
155
|
+
--input: --alpha(var(--color-white) / 8%);
|
|
156
|
+
--muted: --alpha(var(--color-white) / 4%);
|
|
157
|
+
--muted-foreground: color-mix(in srgb, var(--color-neutral-500) 90%, var(--color-white));
|
|
158
|
+
--popover: color-mix(in srgb, var(--background) 98%, var(--color-white));
|
|
159
|
+
--popover-foreground: var(--color-neutral-100);
|
|
160
|
+
--primary: var(--color-neutral-100);
|
|
161
|
+
--primary-foreground: var(--color-neutral-800);
|
|
162
|
+
--ring: var(--color-neutral-500);
|
|
163
|
+
--secondary: --alpha(var(--color-white) / 4%);
|
|
164
|
+
--secondary-foreground: var(--color-neutral-100);
|
|
165
|
+
--chart-1: var(--color-blue-700);
|
|
166
|
+
--chart-2: var(--color-emerald-500);
|
|
167
|
+
--chart-3: var(--color-amber-500);
|
|
168
|
+
--chart-4: var(--color-purple-500);
|
|
169
|
+
--chart-5: var(--color-rose-500);
|
|
170
|
+
--code: color-mix(in srgb, var(--background) 98%, var(--color-white));
|
|
171
|
+
--code-foreground: var(--foreground);
|
|
172
|
+
--code-highlight: --alpha(var(--color-white) / 4%);
|
|
173
|
+
/* See the light default above — one surface, not two. */
|
|
174
|
+
--sidebar: var(--background);
|
|
175
|
+
--sidebar-accent: --alpha(var(--color-white) / 4%);
|
|
176
|
+
--sidebar-accent-foreground: var(--color-neutral-100);
|
|
177
|
+
--sidebar-border: --alpha(var(--color-white) / 5%);
|
|
178
|
+
--sidebar-foreground: color-mix(in srgb, var(--color-neutral-100) 64%, var(--sidebar));
|
|
179
|
+
--sidebar-primary: var(--color-neutral-100);
|
|
180
|
+
--sidebar-primary-foreground: var(--color-neutral-800);
|
|
181
|
+
--sidebar-ring: var(--color-neutral-400);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
@layer base {
|
|
185
|
+
* {
|
|
186
|
+
@apply border-border outline-foreground/50;
|
|
187
|
+
}
|
|
188
|
+
/* Neutralise Tailwind ring utilities (--tw-ring-shadow / --tw-ring-offset-shadow)
|
|
189
|
+
so focusable elements don't render the default ring. We still draw a
|
|
190
|
+
visible outline for keyboard users via :focus-visible below. */
|
|
191
|
+
*,
|
|
192
|
+
*::before,
|
|
193
|
+
*::after {
|
|
194
|
+
--tw-ring-shadow: 0 0 #0000 !important;
|
|
195
|
+
--tw-ring-offset-shadow: 0 0 #0000 !important;
|
|
196
|
+
--tw-ring-color: transparent !important;
|
|
197
|
+
--tw-ring-offset-width: 0px !important;
|
|
198
|
+
--tw-ring-offset-color: transparent !important;
|
|
199
|
+
}
|
|
200
|
+
/* Suppress focus outlines for mouse/touch focus only.
|
|
201
|
+
Preserve a visible ring for keyboard navigation (WCAG 2.4.7). */
|
|
202
|
+
*:focus:not(:focus-visible),
|
|
203
|
+
*:focus-within:not(:focus-visible) {
|
|
204
|
+
outline: none !important;
|
|
205
|
+
}
|
|
206
|
+
*:focus-visible {
|
|
207
|
+
outline: 2px solid var(--ring);
|
|
208
|
+
outline-offset: 2px;
|
|
209
|
+
}
|
|
210
|
+
button, [role="button"] {
|
|
211
|
+
@apply cursor-pointer select-none;
|
|
212
|
+
}
|
|
213
|
+
[role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], [role="option"] {
|
|
214
|
+
@apply cursor-pointer;
|
|
215
|
+
}
|
|
216
|
+
body {
|
|
217
|
+
@apply bg-background text-foreground overflow-hidden;
|
|
218
|
+
}
|
|
219
|
+
*::-webkit-scrollbar {
|
|
220
|
+
display: none;
|
|
221
|
+
}
|
|
222
|
+
* {
|
|
223
|
+
scrollbar-width: none;
|
|
224
|
+
-ms-overflow-style: none;
|
|
225
|
+
}
|
|
226
|
+
code, kbd, samp, pre {
|
|
227
|
+
font-family: var(--font-mono);
|
|
228
|
+
}
|
|
229
|
+
html {
|
|
230
|
+
@apply font-sans font-mono bg-background;
|
|
231
|
+
}
|
|
232
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,58 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odyn-app/api",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The public building kit for Odyn extensions.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://github.com/New-Genre/odyn-extensions",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/New-Genre/odyn-extensions.git"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"odyn",
|
|
13
|
+
"extension"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"main": "./dist/index.js",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./ui": {
|
|
24
|
+
"types": "./dist/ui/index.d.ts",
|
|
25
|
+
"default": "./dist/ui/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./theme.css": "./dist/ui/theme.css"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"README.md"
|
|
32
|
+
],
|
|
33
|
+
"sideEffects": [
|
|
34
|
+
"*.css"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "node scripts/build.mjs",
|
|
38
|
+
"prepublishOnly": "node scripts/build.mjs"
|
|
39
|
+
},
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"class-variance-authority": "^0.7.1",
|
|
45
|
+
"clsx": "^2.1.1",
|
|
46
|
+
"tailwind-merge": "^3.6.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"react": ">=19",
|
|
50
|
+
"tailwindcss": ">=4.3"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/react": "^19.2.17",
|
|
54
|
+
"react": "^19.2.8",
|
|
55
|
+
"tailwindcss": "^4.3.3",
|
|
56
|
+
"typescript": "^5.9.3"
|
|
57
|
+
}
|
|
58
|
+
}
|