This commit is contained in:
Anaïs Saraiva
2026-09-22 00:42:57 +02:00
parent 7defbfcc2e
commit aad8e2600f
6 changed files with 56 additions and 42 deletions
+1 -1
View File
@@ -138,7 +138,7 @@ export function AdminCenter() {
key={t.id}
onClick={() => setTab(t.id)}
className={cn(
"flex flex-1 items-center justify-center gap-2 whitespace-nowrap rounded-full px-4 py-2 text-sm font-medium transition",
"relative flex flex-1 items-center justify-center gap-2 whitespace-nowrap rounded-full px-4 py-2 text-sm font-medium transition",
tab === t.id
? "bg-white text-stone-900 shadow dark:bg-zinc-800 dark:text-zinc-100"
: "opacity-60 hover:opacity-100",
+34 -32
View File
@@ -155,40 +155,42 @@ function ModelRow({ model, onChanged, onError }: {
<span className="block truncate text-sm font-medium">{model.label || model.id}</span>
<span className="block truncate font-mono text-xs opacity-50">{model.id}</span>
</span>
<label className="flex items-center gap-1.5 text-xs opacity-80">
<Input
type="number"
min={0}
max={1000000}
value={hourly}
disabled={busy}
placeholder={t("models.unlimited")}
aria-label={t("models.hourly")}
onChange={(e) => setHourly(e.target.value)}
onBlur={(e) => commitNumber("hourly", e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") (e.target as HTMLInputElement).blur();
}}
className="w-24"
/>
<label className="flex shrink-0 items-center gap-1.5 whitespace-nowrap text-xs opacity-80">
<span className="w-24 shrink-0">
<Input
type="number"
min={0}
max={1000000}
value={hourly}
disabled={busy}
placeholder={t("models.unlimited")}
aria-label={t("models.hourly")}
onChange={(e) => setHourly(e.target.value)}
onBlur={(e) => commitNumber("hourly", e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") (e.target as HTMLInputElement).blur();
}}
/>
</span>
{t("models.hourly")}
</label>
<label className="flex items-center gap-1.5 text-xs opacity-80">
<Input
type="number"
min={0}
max={1000000}
value={daily}
disabled={busy}
placeholder={t("models.unlimited")}
aria-label={t("models.daily")}
onChange={(e) => setDaily(e.target.value)}
onBlur={(e) => commitNumber("daily", e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") (e.target as HTMLInputElement).blur();
}}
className="w-24"
/>
<label className="flex shrink-0 items-center gap-1.5 whitespace-nowrap text-xs opacity-80">
<span className="w-24 shrink-0">
<Input
type="number"
min={0}
max={1000000}
value={daily}
disabled={busy}
placeholder={t("models.unlimited")}
aria-label={t("models.daily")}
onChange={(e) => setDaily(e.target.value)}
onBlur={(e) => commitNumber("daily", e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") (e.target as HTMLInputElement).blur();
}}
/>
</span>
{t("models.daily")}
</label>
<Switch
+1
View File
@@ -15,6 +15,7 @@
--ka-accent-700: 4 120 87;
--ka-accent-800: 6 95 70;
--ka-accent-900: 6 78 59;
--ka-accent-950: 2 44 34;
}
html, body, #root {
+6 -6
View File
@@ -1,11 +1,11 @@
/**
* Runtime accent color (settings → accent color). Predefined palettes plus a
* custom picker; shades 50–900 are derived from a single base hex via HSL and
* custom picker; shades 50–950 are derived from a single base hex via HSL and
* written to the --ka-accent-* CSS variables that back Tailwind's `accent`
* palette. Persisted per-browser (localStorage), like the feature flags.
*/
export type AccentShades = Record<"50" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900", string>;
export type AccentShades = Record<"50" | "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | "950", string>;
export interface AccentPreset {
id: string;
@@ -25,11 +25,11 @@ export const ACCENT_PRESETS: AccentPreset[] = [
];
const STORAGE_KEY = "ka:accent";
const SHADE_KEYS = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900"] as const;
// Lightness ramps for 50→900 around a mid 500 (HSL L values in %).
const SHADE_KEYS = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950"] as const;
// Lightness ramps for 50→950 around a mid 500 (HSL L values in %).
const RAMP: Record<(typeof SHADE_KEYS)[number], number> = {
"50": 97, "100": 93, "200": 86, "300": 76, "400": 64,
"500": 52, "600": 45, "700": 38, "800": 30, "900": 24,
"500": 52, "600": 45, "700": 38, "800": 30, "900": 24, "950": 15,
};
function hexToHsl(hex: string): { h: number; s: number; l: number } {
@@ -66,7 +66,7 @@ function hslToRgbTriplet(h: number, s: number, l: number): string {
return `${to(r)} ${to(g)} ${to(b)}`;
}
/** Build the 50–900 ramp from a base hex (HSL ramp, emerald-style). */
/** Build the 50–950 ramp from a base hex (HSL ramp, emerald-style). */
export function shadesFor(baseHex: string): AccentShades {
const { h, s } = hexToHsl(baseHex);
const out = {} as AccentShades;
+1
View File
@@ -21,6 +21,7 @@ export default {
700: "rgb(var(--ka-accent-700) / <alpha-value>)",
800: "rgb(var(--ka-accent-800) / <alpha-value>)",
900: "rgb(var(--ka-accent-900) / <alpha-value>)",
950: "rgb(var(--ka-accent-950) / <alpha-value>)",
},
},
},