feat(t5): neue Farbwerte, Dunkel für alle, Farb-Codemod (T5a A4)
- globals.css: Hell, Dunkel und Druck mit den Spec-Werten aus 4.2, Fokusring = --primary-ink, Verlaufs-Token entfernt. - Codemod scripts/codemod-t5-colors.mjs: text-primary/-warning auf -ink, Vordergrund nur auf voller Fläche, Auswahlrahmen dunkel; --check-Modus und Spec halten src sauber. - Kontrast-Wächter misst die echte globals.css (VALUES_SWITCHED), alle 21 Zeilen aus 4.4 in allen vier Sätzen; keine dark:-Klassen mehr in src. - Dunkel ist ohne Entwickler-Schalter wählbar, Standard bleibt Hell. - Review-Nacharbeit: Auswahl-Umrisse und aktueller Schritt in Vordergrund, deaktivierte Felder bg-muted, Avatar ohne Blend, Honig-Check-Rahmen über --input. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
6edae3efec
commit
d8238855fc
91 files changed
+673
-391
No files matched your search
@@ -126,8 +126,8 @@ export function WeatherCard({
|
||||
<div
|
||||
className={`flex items-center gap-2 rounded-lg border p-2.5 text-sm ${
|
||||
todaySuitability
|
||||
? "border-primary/30 bg-primary/5 text-primary"
|
||||
: "border-warning/40 bg-warning/10 text-warning-foreground"
|
||||
? "border-primary/30 bg-primary/5 text-primary-ink"
|
||||
: "border-warning/40 bg-warning/10 text-warning-ink"
|
||||
}`}
|
||||
>
|
||||
{todaySuitability ? (
|
||||
@@ -155,7 +155,7 @@ export function WeatherCard({
|
||||
{day.tempMinC !== null ? `${Math.round(day.tempMinC)}°` : "–"}
|
||||
</span>
|
||||
{day.precipitationMm !== null && day.precipitationMm > 0 ? (
|
||||
<span className="text-xs text-primary">
|
||||
<span className="text-xs text-primary-ink">
|
||||
{day.precipitationMm.toFixed(0)} mm
|
||||
</span>
|
||||
) : null}
|
||||
|
||||
@@ -26,7 +26,7 @@ const PRINT_DONE = "Etiketten-PDF heruntergeladen.";
|
||||
const PROOF_DONE = "Probedruck (MUSTER) heruntergeladen. Er ist nicht zum Verkauf gedacht.";
|
||||
const CHECK_FALLBACK = "Die Pflichtangaben konnten nicht geprüft werden.";
|
||||
const LINK_CLASS =
|
||||
"inline-flex min-h-11 items-center rounded-md text-sm font-medium text-primary underline underline-offset-4 focus-visible:outline-2 focus-visible:outline-ring";
|
||||
"inline-flex min-h-11 items-center rounded-md text-sm font-medium text-primary-ink underline underline-offset-4 focus-visible:outline-2 focus-visible:outline-ring";
|
||||
|
||||
type FixTarget = "master" | "product" | "designer";
|
||||
|
||||
@@ -301,7 +301,7 @@ export function PrintLabelsCard({
|
||||
<ul className="flex flex-col gap-1">
|
||||
{warnings.map((warning, index) => (
|
||||
<li key={`${warning.code}-${index}`} className="flex items-start gap-2 text-sm">
|
||||
<TriangleAlert aria-hidden className="mt-0.5 size-4 shrink-0 text-warning" />
|
||||
<TriangleAlert aria-hidden className="mt-0.5 size-4 shrink-0 text-warning-ink" />
|
||||
<span>
|
||||
<span className="font-medium">Hinweis:</span> {warning.title}
|
||||
</span>
|
||||
|
||||
@@ -452,14 +452,14 @@ export default function NewBottlingBatchPage() {
|
||||
/>
|
||||
{withdrawalCheckFailed ? (
|
||||
<p role="alert" className="flex items-start gap-2 rounded-lg bg-warning/15 p-3 text-sm">
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning" aria-hidden />
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning-ink" aria-hidden />
|
||||
Wartezeit konnte nicht geprüft werden
|
||||
</p>
|
||||
) : null}
|
||||
{withdrawalHints.length > 0 ? (
|
||||
<div className="flex flex-col gap-1.5 rounded-lg bg-warning/15 p-3 text-sm">
|
||||
<p className="flex items-center gap-2 font-medium">
|
||||
<AlertTriangle className="size-4 shrink-0 text-warning" aria-hidden />
|
||||
<AlertTriangle className="size-4 shrink-0 text-warning-ink" aria-hidden />
|
||||
Honig aus einer Wartezeit
|
||||
</p>
|
||||
<ul className="flex flex-col gap-1">
|
||||
|
||||
@@ -28,7 +28,7 @@ export function BottomNav({ user }: { user: Pick<AuthUser, "permissions"> }) {
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
className={cn(
|
||||
"flex flex-1 flex-col items-center justify-center gap-1 text-xs",
|
||||
isActive ? "text-primary" : "text-muted-foreground",
|
||||
isActive ? "text-primary-ink" : "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
<Icon className="size-5" aria-hidden="true" />
|
||||
|
||||
@@ -355,7 +355,7 @@ export default function CalendarPage() {
|
||||
className={cn(
|
||||
"flex min-h-24 flex-col gap-1 border-r border-b p-1.5 text-left last:border-r-0",
|
||||
isCurrentMonth ? "bg-card" : "bg-muted/40",
|
||||
isSelected && "outline-2 -outline-offset-2 outline-primary",
|
||||
isSelected && "outline-2 -outline-offset-2 outline-foreground",
|
||||
)}
|
||||
>
|
||||
<span
|
||||
|
||||
@@ -209,7 +209,7 @@ function VarroaTrendChart({
|
||||
<div className="flex flex-col gap-2">
|
||||
<svg
|
||||
viewBox={`0 0 ${CHART_WIDTH} ${CHART_HEIGHT}`}
|
||||
className="w-full text-primary"
|
||||
className="w-full text-primary-ink"
|
||||
role="img"
|
||||
aria-labelledby={titleId}
|
||||
aria-describedby={descId}
|
||||
@@ -293,7 +293,7 @@ function ChartLegend({ hasRed, hasYellow }: { hasRed: boolean; hasYellow: boolea
|
||||
return (
|
||||
<ul aria-label="Legende" className="flex flex-wrap gap-x-4 gap-y-1 text-xs text-muted-foreground">
|
||||
<li className="flex items-center gap-1.5">
|
||||
<span className="text-primary">
|
||||
<span className="text-primary-ink">
|
||||
<LegendSwatch width={2} />
|
||||
</span>
|
||||
<span>Milbenfall pro Tag</span>
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { createColony } from "@/lib/colonies/api";
|
||||
import { COLONY_TYPES, COLONY_TYPE_LABELS, MAX_OCCUPIED_FRAMES } from "@/lib/colonies/labels";
|
||||
import { fetchApiaries } from "@/lib/apiaries/api";
|
||||
|
||||
@@ -33,7 +33,7 @@ function Step({ number, title, titleId, state, children }: StepProps) {
|
||||
return (
|
||||
<li
|
||||
aria-current={state === "current" ? "step" : undefined}
|
||||
className="flex flex-col gap-1 rounded-lg border border-border/60 p-3 aria-[current=step]:border-primary aria-[current=step]:bg-primary/10"
|
||||
className="flex flex-col gap-1 rounded-lg border border-border/60 p-3 aria-[current=step]:border-foreground aria-[current=step]:bg-primary/10"
|
||||
>
|
||||
<span className="flex flex-wrap items-center justify-between gap-2">
|
||||
<span
|
||||
|
||||
@@ -136,7 +136,7 @@ function CreateNoticeForm({ onDone }: { onDone: () => void }) {
|
||||
{NOTICE_KINDS.map((entry) => (
|
||||
<label
|
||||
key={entry}
|
||||
className="flex min-h-11 cursor-pointer items-start gap-3 rounded-lg border border-border px-3 py-2 has-[:checked]:border-primary has-[:checked]:bg-primary/10"
|
||||
className="flex min-h-11 cursor-pointer items-start gap-3 rounded-lg border border-border px-3 py-2 has-[:checked]:border-foreground has-[:checked]:bg-primary/10"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
|
||||
@@ -17,7 +17,7 @@ const STATE_ICON: Record<ReadinessItemState, LucideIcon> = {
|
||||
};
|
||||
|
||||
const FIX_LINK_CLASS =
|
||||
"inline-flex min-h-11 shrink-0 items-center gap-1 rounded-lg px-2 font-medium text-primary underline-offset-4 outline-none hover:underline focus-visible:ring-3 focus-visible:ring-ring/50";
|
||||
"inline-flex min-h-11 shrink-0 items-center gap-1 rounded-lg px-2 font-medium text-primary-ink underline-offset-4 outline-none hover:underline focus-visible:ring-3 focus-visible:ring-ring/50";
|
||||
|
||||
function FixLink({ itemKey, subject, context }: { itemKey: string; subject: ReadinessSubject | null; context: string }) {
|
||||
const { href, label, available } = fixLinkFor(itemKey, subject);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { NoComplianceAccess } from "@/components/compliance/no-compliance-access";
|
||||
import { DetailHeader } from "@/components/detail-header";
|
||||
import { StandNote } from "@/components/offline/stand-note";
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { FormEvent, useEffect, useState } from "react";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { NoComplianceAccess } from "@/components/compliance/no-compliance-access";
|
||||
import { DetailHeader, DetailQueryFallback } from "@/components/detail-header";
|
||||
|
||||
@@ -219,7 +219,7 @@ export default function DashboardPage() {
|
||||
</span>
|
||||
{href ? (
|
||||
<Link
|
||||
className="inline-flex min-h-11 shrink-0 items-center rounded-lg px-2 font-medium text-primary underline-offset-4 hover:underline"
|
||||
className="inline-flex min-h-11 shrink-0 items-center rounded-lg px-2 font-medium text-primary-ink underline-offset-4 hover:underline"
|
||||
href={href}
|
||||
>
|
||||
Ansehen
|
||||
@@ -247,7 +247,7 @@ export default function DashboardPage() {
|
||||
className="flex min-h-11 items-center gap-3 rounded-xl px-3 py-2 transition-colors hover:bg-muted focus-visible:outline-2 focus-visible:outline-ring"
|
||||
>
|
||||
<Icon
|
||||
className={`size-5 shrink-0 ${tile.attention ? "text-warning" : "text-primary"}`}
|
||||
className={`size-5 shrink-0 ${tile.attention ? "text-warning-ink" : "text-primary-ink"}`}
|
||||
aria-hidden
|
||||
/>
|
||||
<span className="font-heading text-lg font-semibold tabular-nums">
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { fetchEquipment, updateEquipment } from "@/lib/equipment/api";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { createEquipment } from "@/lib/equipment/api";
|
||||
import { useFormDraft } from "@/lib/forms/use-form-draft";
|
||||
import { errorMessage } from "@/lib/forms/error-message";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { fetchExtraction } from "@/lib/extractions/api";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { fetchHarvests } from "@/lib/harvests/api";
|
||||
import {
|
||||
createExtraction,
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { createFeeding } from "@/lib/feedings/api";
|
||||
import { createFeedingsBulk } from "@/lib/bulk/api";
|
||||
import {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { fetchHarvest } from "@/lib/harvests/api";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
@@ -284,7 +284,7 @@ export default function NewHarvestPage() {
|
||||
</Field>
|
||||
{withdrawalQuery.isError ? (
|
||||
<p role="alert" className="flex items-start gap-2 rounded-lg bg-warning/15 p-3 text-sm">
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning" aria-hidden />
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning-ink" aria-hidden />
|
||||
Wartezeiten konnten nicht geprüft werden. Vor der Ernte die Behandlungen der
|
||||
Völker selbst ansehen.
|
||||
</p>
|
||||
|
||||
@@ -114,7 +114,7 @@ function MovementList({ movements }: { movements: HoneyBatchMovement[] }) {
|
||||
className={
|
||||
movement.quantityGrams < 0
|
||||
? "font-semibold tabular-nums text-destructive"
|
||||
: "font-semibold tabular-nums text-primary"
|
||||
: "font-semibold tabular-nums text-primary-ink"
|
||||
}
|
||||
>
|
||||
{formatSignedKg(gramsToKg(movement.quantityGrams))}
|
||||
|
||||
@@ -98,7 +98,7 @@ function HiveOpsList({ ops, base, catalog, onChange, onUndone, onEmptied }: Hive
|
||||
</div>
|
||||
{blocked?.index === index ? (
|
||||
<p role="alert" className="flex items-start gap-2 text-sm">
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning" aria-hidden />
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning-ink" aria-hidden />
|
||||
{blocked.reason} Mach zuerst die späteren Änderungen rückgängig.
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -734,7 +734,7 @@ function InspectionCaptureForm({
|
||||
{noQueenSigns ? (
|
||||
<p className="flex items-start gap-2 rounded-lg bg-warning/15 p-3 text-sm">
|
||||
<AlertTriangle
|
||||
className="mt-0.5 size-4 shrink-0 text-warning"
|
||||
className="mt-0.5 size-4 shrink-0 text-warning-ink"
|
||||
aria-hidden
|
||||
/>
|
||||
Weder Königin noch Stifte gesehen. Nach dem Speichern wird
|
||||
@@ -894,7 +894,7 @@ function InspectionCaptureForm({
|
||||
/>
|
||||
{values.feedLegacyText !== null ? (
|
||||
<p role="status" className="flex items-start gap-2 text-sm">
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning" aria-hidden />
|
||||
<AlertTriangle className="mt-0.5 size-4 shrink-0 text-warning-ink" aria-hidden />
|
||||
{feedLegacyHint(values.feedLegacyText)}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
import type { ReactNode } from "react";
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useAuth } from "@/lib/auth/auth-context";
|
||||
import { buildBook } from "@/lib/medicines/book";
|
||||
|
||||
@@ -37,7 +37,7 @@ export function MoreSheet({ user }: { user: Pick<AuthUser, "permissions"> }) {
|
||||
<SheetTrigger
|
||||
className={cn(
|
||||
"flex flex-1 flex-col items-center justify-center gap-1 text-xs",
|
||||
isMoreActive ? "text-primary" : "text-muted-foreground",
|
||||
isMoreActive ? "text-primary-ink" : "text-muted-foreground",
|
||||
)}
|
||||
>
|
||||
<Menu className="size-5" aria-hidden="true" />
|
||||
|
||||
@@ -4,7 +4,6 @@ import { Suspense } from "react";
|
||||
import Link from "next/link";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { useAuth, useCurrentUserId } from "@/lib/auth/auth-context";
|
||||
import {
|
||||
OFFLINE_PACKS_QUERY_KEY,
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { FormEvent, useRef, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { createProductionBatch } from "@/lib/production-batches/api";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useParams } from "next/navigation";
|
||||
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { fetchProduct } from "@/lib/products/api";
|
||||
import { fetchProductionBatches } from "@/lib/production-batches/api";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { createProduct } from "@/lib/products/api";
|
||||
import { useFormDraft } from "@/lib/forms/use-form-draft";
|
||||
import { errorMessage } from "@/lib/forms/error-message";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import userEvent from "@testing-library/user-event";
|
||||
import { mockMedia, resetDocument } from "@/lib/appearance/test-helpers";
|
||||
@@ -30,21 +30,20 @@ describe("AppearanceSection", () => {
|
||||
expect(screen.getByText("Gilt nur für dieses Gerät.")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("hides Dunkel and Wie Gerät without the dev flag", () => {
|
||||
it("starts on Hell and offers Dunkel and Wie Gerät without a flag", () => {
|
||||
render(<AppearanceSection />);
|
||||
expect(screen.getByRole("radio", { name: /^Hell/ })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("radio", { name: /^Dunkel/ })).not.toBeInTheDocument();
|
||||
expect(screen.queryByRole("radio", { name: /^Wie Gerät/ })).not.toBeInTheDocument();
|
||||
expect(screen.getByRole("radio", { name: /^Hell/ })).toBeChecked();
|
||||
expect(screen.getByRole("radio", { name: /^Dunkel/ })).not.toBeChecked();
|
||||
expect(screen.getByRole("radio", { name: /^Wie Gerät/ })).not.toBeChecked();
|
||||
});
|
||||
|
||||
it("offers Dunkel and Wie Gerät with the dev flag", async () => {
|
||||
vi.stubEnv("NEXT_PUBLIC_APPEARANCE_DARK", "1");
|
||||
it("dark is selectable without a flag", async () => {
|
||||
render(<AppearanceSection />);
|
||||
|
||||
await userEvent.click(screen.getByRole("radio", { name: /^Dunkel/ }));
|
||||
|
||||
expect(document.documentElement).toHaveClass("dark");
|
||||
expect(screen.getByRole("radio", { name: /^Wie Gerät/ })).toBeInTheDocument();
|
||||
expect(window.localStorage.getItem("apicore.theme")).toBe("dark");
|
||||
});
|
||||
|
||||
it("changes the motion level to Dezent and applies it", async () => {
|
||||
|
||||
@@ -3,12 +3,7 @@
|
||||
import { useId } from "react";
|
||||
import { ChoiceGroup, type ChoiceOption } from "@/components/form/choice-group";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import {
|
||||
isDarkEnabled,
|
||||
useAppearance,
|
||||
type ContrastChoice,
|
||||
type ThemeChoice,
|
||||
} from "@/lib/appearance/appearance";
|
||||
import { useAppearance, type ContrastChoice, type ThemeChoice } from "@/lib/appearance/appearance";
|
||||
import { MOTION_LEVELS, type MotionLevel } from "@/lib/motion/motion-preference";
|
||||
|
||||
const OPTION_CLASS = "h-auto justify-start px-3 py-2 text-left";
|
||||
@@ -38,8 +33,6 @@ const MOTION_OPTIONS: readonly ChoiceOption<MotionLevel>[] = MOTION_LEVELS.map((
|
||||
export function AppearanceSection() {
|
||||
const { theme, contrast, motion, setTheme, setContrast, setMotion } = useAppearance();
|
||||
const ids = { theme: useId(), contrast: useId(), motion: useId(), motionHint: useId() };
|
||||
// Dark has unreadable old values until task A4; the dev flag shows it for work on A4.
|
||||
const themeOptions = isDarkEnabled() ? THEME_OPTIONS : THEME_OPTIONS.slice(0, 1);
|
||||
|
||||
return (
|
||||
<Card>
|
||||
@@ -56,7 +49,7 @@ export function AppearanceSection() {
|
||||
Farbschema
|
||||
</p>
|
||||
<ChoiceGroup
|
||||
options={themeOptions}
|
||||
options={THEME_OPTIONS}
|
||||
value={theme}
|
||||
onChange={setTheme}
|
||||
labelledBy={ids.theme}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { ChangeEvent, FormEvent, useRef, useState } from "react";
|
||||
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { useAuth } from "@/lib/auth/auth-context";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { useParams } from "next/navigation";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { fetchQueen } from "@/lib/queens/api";
|
||||
import { QUEEN_STATUS_LABELS } from "@/lib/queens/labels";
|
||||
import { QrCodeDialog } from "@/components/qr-code-dialog";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { createQueen, fetchQueens } from "@/lib/queens/api";
|
||||
import { useFormDraft } from "@/lib/forms/use-form-draft";
|
||||
import { errorMessage } from "@/lib/forms/error-message";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { FormEvent, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
import { createRawMaterialLot } from "@/lib/raw-materials/api";
|
||||
|
||||
@@ -53,8 +53,8 @@ export function ApiKeyAllowlist({ apiKey }: { apiKey: ApiKey }) {
|
||||
Nur von: <span className="font-mono">{apiKey.allowedIps.join(", ")}</span>
|
||||
</span>
|
||||
) : (
|
||||
<span className="flex items-center gap-1 text-warning-foreground">
|
||||
<ShieldAlert className="size-3.5 text-warning" aria-hidden />
|
||||
<span className="flex items-center gap-1 text-warning-ink">
|
||||
<ShieldAlert className="size-3.5 text-warning-ink" aria-hidden />
|
||||
Von jeder Adresse nutzbar – besser auf den Server von Wabenhain beschränken.
|
||||
</span>
|
||||
)}
|
||||
|
||||
@@ -155,7 +155,7 @@ export function ApiKeysTab() {
|
||||
className="flex flex-col gap-3 rounded-2xl border border-primary/40 bg-primary/5 p-4"
|
||||
>
|
||||
<div className="flex items-center gap-2 font-medium">
|
||||
<ShieldCheck className="size-5 text-primary" aria-hidden />
|
||||
<ShieldCheck className="size-5 text-primary-ink" aria-hidden />
|
||||
Schlüssel „{created.name}“ angelegt
|
||||
</div>
|
||||
<p className="text-sm">
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
|
||||
import { PageHeader } from "@/components/page-header";
|
||||
import { TabSwitcher } from "@/components/tab-switcher";
|
||||
import { WebhooksTab } from "./webhooks-tab";
|
||||
|
||||
@@ -133,7 +133,7 @@ function ElementBox({
|
||||
<div
|
||||
className={cn(
|
||||
"absolute cursor-move touch-none select-none",
|
||||
selected && "outline outline-2 outline-primary",
|
||||
selected && "outline outline-2 outline-foreground",
|
||||
)}
|
||||
style={{
|
||||
left: box.left,
|
||||
@@ -146,7 +146,7 @@ function ElementBox({
|
||||
{renderContent(element, scale)}
|
||||
{selected ? (
|
||||
<div
|
||||
className="absolute right-0 bottom-0 size-3 translate-x-1/2 translate-y-1/2 cursor-nwse-resize rounded-full border-2 border-primary bg-background"
|
||||
className="absolute right-0 bottom-0 size-3 translate-x-1/2 translate-y-1/2 cursor-nwse-resize rounded-full border-2 border-foreground bg-background"
|
||||
onPointerDown={(event) => {
|
||||
event.stopPropagation();
|
||||
onStartResize(event);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
|
||||
import { createLabelTemplate } from "@/lib/label-templates/api";
|
||||
import { FormBackLink } from "@/components/form/form-back-link";
|
||||
import { PageHeader } from "@/components/page-header";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { Suspense } from "react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
|
||||
import { PageHeader } from "@/components/page-header";
|
||||
import { TabSwitcher } from "@/components/tab-switcher";
|
||||
import { UsersTab } from "./users-tab";
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import { useSyncExternalStore } from "react";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { toast } from "sonner";
|
||||
import { ConfirmDialog } from "@/components/confirm-dialog";
|
||||
import { useAuth } from "@/lib/auth/auth-context";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { createTask } from "@/lib/tasks/api";
|
||||
import { TASK_PRIORITIES, TASK_PRIORITY_LABELS } from "@/lib/tasks/labels";
|
||||
import { fetchUsers } from "@/lib/users/api";
|
||||
|
||||
@@ -4,7 +4,6 @@ import { FormEvent, useState } from "react";
|
||||
import { useRouter, useSearchParams } from "next/navigation";
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { toast } from "sonner";
|
||||
|
||||
import { saveErrorText } from "@/lib/honey-batches/errors";
|
||||
import { useAuth } from "@/lib/auth/auth-context";
|
||||
import { fetchColonies } from "@/lib/colonies/api";
|
||||
|
||||
@@ -102,55 +102,52 @@
|
||||
}
|
||||
|
||||
:root {
|
||||
--background: oklch(0.955 0.017 80);
|
||||
--foreground: oklch(0.22 0.028 55);
|
||||
--background: oklch(0.968 0.014 85);
|
||||
--foreground: oklch(0.21 0.03 55);
|
||||
--card: oklch(0.995 0.004 90);
|
||||
--card-foreground: oklch(0.22 0.028 55);
|
||||
--card-foreground: oklch(0.21 0.03 55);
|
||||
--popover: oklch(0.995 0.004 90);
|
||||
--popover-foreground: oklch(0.22 0.028 55);
|
||||
--primary: oklch(0.6 0.15 48);
|
||||
--primary-foreground: oklch(0.99 0.02 85);
|
||||
--popover-foreground: oklch(0.21 0.03 55);
|
||||
--primary: oklch(0.8 0.145 78);
|
||||
--primary-foreground: oklch(0.21 0.035 55);
|
||||
--secondary: oklch(0.44 0.07 145);
|
||||
--secondary-foreground: oklch(0.98 0.015 100);
|
||||
--muted: oklch(0.9 0.02 82);
|
||||
--muted-foreground: oklch(0.48 0.032 65);
|
||||
--accent: oklch(0.93 0.032 74);
|
||||
--accent-foreground: oklch(0.26 0.045 50);
|
||||
--destructive: oklch(0.5 0.16 30);
|
||||
--border: oklch(0.85 0.024 78);
|
||||
--input: oklch(0.85 0.024 78);
|
||||
--ring: oklch(0.6 0.15 48);
|
||||
--warning: oklch(0.68 0.14 75);
|
||||
--warning-foreground: oklch(0.24 0.04 60);
|
||||
--success: oklch(0.46 0.06 145);
|
||||
--muted: oklch(0.925 0.018 82);
|
||||
--muted-foreground: oklch(0.44 0.03 60);
|
||||
--accent: oklch(0.935 0.03 78);
|
||||
--accent-foreground: oklch(0.25 0.045 50);
|
||||
--destructive: oklch(0.5 0.17 28);
|
||||
--border: oklch(0.86 0.022 78);
|
||||
--input: oklch(0.6 0.035 65);
|
||||
--ring: oklch(0.47 0.115 55);
|
||||
--warning: oklch(0.79 0.15 80);
|
||||
--warning-foreground: oklch(0.23 0.04 60);
|
||||
--success: oklch(0.46 0.08 145);
|
||||
--success-foreground: oklch(0.98 0.015 100);
|
||||
--condition-excellent: oklch(0.58 0.13 145);
|
||||
--condition-excellent-foreground: oklch(0.16 0.04 145);
|
||||
--condition-good: oklch(0.64 0.13 118);
|
||||
--condition-good-foreground: oklch(0.26 0.05 118);
|
||||
--condition-average: oklch(0.7 0.14 90);
|
||||
--condition-average-foreground: oklch(0.28 0.05 90);
|
||||
--condition-weak: oklch(0.68 0.15 55);
|
||||
--condition-weak-foreground: oklch(0.26 0.05 55);
|
||||
--condition-critical: oklch(0.64 0.16 30);
|
||||
--condition-excellent: oklch(0.62 0.13 150);
|
||||
--condition-excellent-foreground: oklch(0.15 0.04 150);
|
||||
--condition-good: oklch(0.645 0.13 125);
|
||||
--condition-good-foreground: oklch(0.17 0.04 125);
|
||||
--condition-average: oklch(0.665 0.125 88);
|
||||
--condition-average-foreground: oklch(0.19 0.04 90);
|
||||
--condition-weak: oklch(0.665 0.14 58);
|
||||
--condition-weak-foreground: oklch(0.18 0.04 55);
|
||||
--condition-critical: oklch(0.62 0.17 30);
|
||||
--condition-critical-foreground: oklch(0.15 0.04 30);
|
||||
--chart-1: oklch(0.6 0.135 50);
|
||||
--chart-2: oklch(0.46 0.06 145);
|
||||
--chart-3: oklch(0.68 0.14 75);
|
||||
--chart-4: oklch(0.5 0.16 30);
|
||||
--chart-5: oklch(0.55 0.05 250);
|
||||
--chart-1: oklch(0.56 0.13 55);
|
||||
--chart-2: oklch(0.46 0.08 145);
|
||||
--chart-3: oklch(0.6 0.12 85);
|
||||
--chart-4: oklch(0.5 0.17 28);
|
||||
--chart-5: oklch(0.52 0.08 250);
|
||||
--radius: 0.75rem;
|
||||
--sidebar: oklch(0.995 0.004 90);
|
||||
--sidebar-foreground: oklch(0.22 0.028 55);
|
||||
--sidebar-primary: oklch(0.6 0.15 48);
|
||||
--sidebar-primary-foreground: oklch(0.99 0.02 85);
|
||||
--sidebar-accent: oklch(0.93 0.032 74);
|
||||
--sidebar-accent-foreground: oklch(0.26 0.045 50);
|
||||
--sidebar-border: oklch(0.85 0.024 78);
|
||||
--sidebar-ring: oklch(0.6 0.15 48);
|
||||
--gradient-honey: linear-gradient(135deg, oklch(0.74 0.15 62) 0%, oklch(0.56 0.16 38) 100%);
|
||||
--gradient-sage: linear-gradient(135deg, oklch(0.64 0.09 150) 0%, oklch(0.4 0.075 145) 100%);
|
||||
--gradient-sky: linear-gradient(135deg, oklch(0.68 0.1 235) 0%, oklch(0.5 0.1 255) 100%);
|
||||
--sidebar-foreground: oklch(0.21 0.03 55);
|
||||
--sidebar-primary: oklch(0.8 0.145 78);
|
||||
--sidebar-primary-foreground: oklch(0.21 0.035 55);
|
||||
--sidebar-accent: oklch(0.935 0.03 78);
|
||||
--sidebar-accent-foreground: oklch(0.25 0.045 50);
|
||||
--sidebar-border: oklch(0.86 0.022 78);
|
||||
--sidebar-ring: oklch(0.47 0.115 55);
|
||||
--shadow-elevated: 0 1px 2px -1px oklch(0.3 0.05 50 / 8%), 0 8px 24px -8px oklch(0.3 0.05 50 / 16%);
|
||||
--shadow-soft: 0 1px 2px -1px oklch(0.3 0.05 50 / 6%), 0 4px 12px -4px oklch(0.3 0.05 50 / 10%);
|
||||
/* Hive "screen": always dark, in light and dark mode (spec 9.3). */
|
||||
@@ -160,7 +157,7 @@
|
||||
--holo-fill: oklch(0.78 0.14 220 / 10%);
|
||||
--holo-label-bg: oklch(0.26 0.04 250);
|
||||
--holo-label-fg: oklch(0.95 0.02 230);
|
||||
/* T5 tokens, end values (spec 4.2); the old values above switch in task A4. */
|
||||
/* T5 tokens (spec 4.2). */
|
||||
--primary-ink: oklch(0.47 0.115 55);
|
||||
--warning-ink: oklch(0.5 0.11 65);
|
||||
--destructive-foreground: oklch(0.985 0.005 30);
|
||||
@@ -188,54 +185,51 @@
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: oklch(0.2 0.018 55);
|
||||
--foreground: oklch(0.94 0.02 80);
|
||||
--card: oklch(0.25 0.02 55);
|
||||
--card-foreground: oklch(0.94 0.02 80);
|
||||
--popover: oklch(0.25 0.02 55);
|
||||
--popover-foreground: oklch(0.94 0.02 80);
|
||||
--primary: oklch(0.72 0.13 55);
|
||||
--primary-foreground: oklch(0.2 0.02 55);
|
||||
--secondary: oklch(0.62 0.075 145);
|
||||
--secondary-foreground: oklch(0.15 0.02 145);
|
||||
--muted: oklch(0.29 0.018 55);
|
||||
--muted-foreground: oklch(0.7 0.025 75);
|
||||
--accent: oklch(0.32 0.03 60);
|
||||
--accent-foreground: oklch(0.94 0.02 80);
|
||||
--destructive: oklch(0.62 0.16 30);
|
||||
--border: oklch(1 0 0 / 12%);
|
||||
--input: oklch(1 0 0 / 16%);
|
||||
--ring: oklch(0.72 0.13 55);
|
||||
--warning: oklch(0.74 0.13 75);
|
||||
--background: oklch(0.19 0.016 55);
|
||||
--foreground: oklch(0.95 0.018 80);
|
||||
--card: oklch(0.235 0.018 55);
|
||||
--card-foreground: oklch(0.95 0.018 80);
|
||||
--popover: oklch(0.235 0.018 55);
|
||||
--popover-foreground: oklch(0.95 0.018 80);
|
||||
--primary: oklch(0.8 0.14 78);
|
||||
--primary-foreground: oklch(0.19 0.03 55);
|
||||
--secondary: oklch(0.66 0.08 145);
|
||||
--secondary-foreground: oklch(0.16 0.02 145);
|
||||
--muted: oklch(0.28 0.018 55);
|
||||
--muted-foreground: oklch(0.76 0.025 75);
|
||||
--accent: oklch(0.31 0.03 60);
|
||||
--accent-foreground: oklch(0.95 0.018 80);
|
||||
--destructive: oklch(0.7 0.15 28);
|
||||
--border: oklch(0.34 0.02 60);
|
||||
--input: oklch(0.56 0.025 70);
|
||||
--ring: oklch(0.82 0.13 80);
|
||||
--warning: oklch(0.8 0.14 80);
|
||||
--warning-foreground: oklch(0.2 0.03 60);
|
||||
--success: oklch(0.62 0.075 145);
|
||||
--success-foreground: oklch(0.15 0.02 145);
|
||||
--condition-excellent: oklch(0.66 0.11 145);
|
||||
--condition-excellent-foreground: oklch(0.2 0.04 145);
|
||||
--condition-good: oklch(0.72 0.12 118);
|
||||
--condition-good-foreground: oklch(0.22 0.04 118);
|
||||
--condition-average: oklch(0.76 0.13 90);
|
||||
--condition-average-foreground: oklch(0.24 0.04 90);
|
||||
--condition-weak: oklch(0.74 0.13 55);
|
||||
--condition-weak-foreground: oklch(0.22 0.04 55);
|
||||
--condition-critical: oklch(0.62 0.16 30);
|
||||
--condition-critical-foreground: oklch(0.2 0.04 30);
|
||||
--chart-1: oklch(0.72 0.13 55);
|
||||
--chart-2: oklch(0.62 0.075 145);
|
||||
--chart-3: oklch(0.74 0.13 75);
|
||||
--chart-4: oklch(0.62 0.16 30);
|
||||
--chart-5: oklch(0.65 0.06 250);
|
||||
--sidebar: oklch(0.22 0.02 55);
|
||||
--sidebar-foreground: oklch(0.94 0.02 80);
|
||||
--sidebar-primary: oklch(0.72 0.13 55);
|
||||
--sidebar-primary-foreground: oklch(0.2 0.02 55);
|
||||
--sidebar-accent: oklch(0.32 0.03 60);
|
||||
--sidebar-accent-foreground: oklch(0.94 0.02 80);
|
||||
--sidebar-border: oklch(1 0 0 / 12%);
|
||||
--sidebar-ring: oklch(0.72 0.13 55);
|
||||
--gradient-honey: linear-gradient(135deg, oklch(0.62 0.14 55) 0%, oklch(0.38 0.13 40) 100%);
|
||||
--gradient-sage: linear-gradient(135deg, oklch(0.5 0.08 148) 0%, oklch(0.3 0.06 145) 100%);
|
||||
--gradient-sky: linear-gradient(135deg, oklch(0.55 0.09 235) 0%, oklch(0.34 0.09 255) 100%);
|
||||
--success: oklch(0.7 0.09 145);
|
||||
--success-foreground: oklch(0.16 0.02 145);
|
||||
--condition-excellent: oklch(0.68 0.12 150);
|
||||
--condition-excellent-foreground: oklch(0.17 0.04 150);
|
||||
--condition-good: oklch(0.72 0.12 125);
|
||||
--condition-good-foreground: oklch(0.18 0.04 125);
|
||||
--condition-average: oklch(0.77 0.13 90);
|
||||
--condition-average-foreground: oklch(0.2 0.04 90);
|
||||
--condition-weak: oklch(0.74 0.13 60);
|
||||
--condition-weak-foreground: oklch(0.19 0.04 55);
|
||||
--condition-critical: oklch(0.68 0.16 28);
|
||||
--condition-critical-foreground: oklch(0.16 0.04 30);
|
||||
--chart-1: oklch(0.78 0.13 70);
|
||||
--chart-2: oklch(0.7 0.09 145);
|
||||
--chart-3: oklch(0.82 0.12 90);
|
||||
--chart-4: oklch(0.7 0.15 28);
|
||||
--chart-5: oklch(0.72 0.08 250);
|
||||
--sidebar: oklch(0.235 0.018 55);
|
||||
--sidebar-foreground: oklch(0.95 0.018 80);
|
||||
--sidebar-primary: oklch(0.8 0.14 78);
|
||||
--sidebar-primary-foreground: oklch(0.19 0.03 55);
|
||||
--sidebar-accent: oklch(0.31 0.03 60);
|
||||
--sidebar-accent-foreground: oklch(0.95 0.018 80);
|
||||
--sidebar-border: oklch(0.34 0.02 60);
|
||||
--sidebar-ring: oklch(0.82 0.13 80);
|
||||
--shadow-elevated: 0 1px 2px -1px oklch(0 0 0 / 30%), 0 8px 24px -8px oklch(0 0 0 / 45%);
|
||||
--shadow-soft: 0 1px 2px -1px oklch(0 0 0 / 25%), 0 4px 12px -4px oklch(0 0 0 / 30%);
|
||||
/* Hive "screen": always dark, in light and dark mode (spec 9.3). */
|
||||
@@ -245,7 +239,7 @@
|
||||
--holo-fill: oklch(0.78 0.14 220 / 10%);
|
||||
--holo-label-bg: oklch(0.26 0.04 250);
|
||||
--holo-label-fg: oklch(0.95 0.02 230);
|
||||
/* T5 tokens, end values (spec 4.2); the old values above switch in task A4. */
|
||||
/* T5 tokens (spec 4.2). */
|
||||
--primary-ink: oklch(0.82 0.13 80);
|
||||
--warning-ink: oklch(0.82 0.13 82);
|
||||
--destructive-foreground: oklch(0.17 0.03 30);
|
||||
@@ -364,51 +358,51 @@
|
||||
.dark,
|
||||
:root[data-contrast="sun"],
|
||||
.dark[data-contrast="sun"] {
|
||||
--background: oklch(0.955 0.017 80);
|
||||
--foreground: oklch(0.22 0.028 55);
|
||||
--background: oklch(0.968 0.014 85);
|
||||
--foreground: oklch(0.21 0.03 55);
|
||||
--card: oklch(0.995 0.004 90);
|
||||
--card-foreground: oklch(0.22 0.028 55);
|
||||
--card-foreground: oklch(0.21 0.03 55);
|
||||
--popover: oklch(0.995 0.004 90);
|
||||
--popover-foreground: oklch(0.22 0.028 55);
|
||||
--primary: oklch(0.6 0.15 48);
|
||||
--primary-foreground: oklch(0.99 0.02 85);
|
||||
--popover-foreground: oklch(0.21 0.03 55);
|
||||
--primary: oklch(0.8 0.145 78);
|
||||
--primary-foreground: oklch(0.21 0.035 55);
|
||||
--secondary: oklch(0.44 0.07 145);
|
||||
--secondary-foreground: oklch(0.98 0.015 100);
|
||||
--muted: oklch(0.9 0.02 82);
|
||||
--muted-foreground: oklch(0.48 0.032 65);
|
||||
--accent: oklch(0.93 0.032 74);
|
||||
--accent-foreground: oklch(0.26 0.045 50);
|
||||
--destructive: oklch(0.5 0.16 30);
|
||||
--border: oklch(0.85 0.024 78);
|
||||
--input: oklch(0.85 0.024 78);
|
||||
--ring: oklch(0.6 0.15 48);
|
||||
--warning: oklch(0.68 0.14 75);
|
||||
--warning-foreground: oklch(0.24 0.04 60);
|
||||
--success: oklch(0.46 0.06 145);
|
||||
--muted: oklch(0.925 0.018 82);
|
||||
--muted-foreground: oklch(0.44 0.03 60);
|
||||
--accent: oklch(0.935 0.03 78);
|
||||
--accent-foreground: oklch(0.25 0.045 50);
|
||||
--destructive: oklch(0.5 0.17 28);
|
||||
--border: oklch(0.86 0.022 78);
|
||||
--input: oklch(0.6 0.035 65);
|
||||
--ring: oklch(0.47 0.115 55);
|
||||
--warning: oklch(0.79 0.15 80);
|
||||
--warning-foreground: oklch(0.23 0.04 60);
|
||||
--success: oklch(0.46 0.08 145);
|
||||
--success-foreground: oklch(0.98 0.015 100);
|
||||
--condition-excellent: oklch(0.58 0.13 145);
|
||||
--condition-excellent-foreground: oklch(0.16 0.04 145);
|
||||
--condition-good: oklch(0.64 0.13 118);
|
||||
--condition-good-foreground: oklch(0.26 0.05 118);
|
||||
--condition-average: oklch(0.7 0.14 90);
|
||||
--condition-average-foreground: oklch(0.28 0.05 90);
|
||||
--condition-weak: oklch(0.68 0.15 55);
|
||||
--condition-weak-foreground: oklch(0.26 0.05 55);
|
||||
--condition-critical: oklch(0.64 0.16 30);
|
||||
--condition-excellent: oklch(0.62 0.13 150);
|
||||
--condition-excellent-foreground: oklch(0.15 0.04 150);
|
||||
--condition-good: oklch(0.645 0.13 125);
|
||||
--condition-good-foreground: oklch(0.17 0.04 125);
|
||||
--condition-average: oklch(0.665 0.125 88);
|
||||
--condition-average-foreground: oklch(0.19 0.04 90);
|
||||
--condition-weak: oklch(0.665 0.14 58);
|
||||
--condition-weak-foreground: oklch(0.18 0.04 55);
|
||||
--condition-critical: oklch(0.62 0.17 30);
|
||||
--condition-critical-foreground: oklch(0.15 0.04 30);
|
||||
--chart-1: oklch(0.6 0.135 50);
|
||||
--chart-2: oklch(0.46 0.06 145);
|
||||
--chart-3: oklch(0.68 0.14 75);
|
||||
--chart-4: oklch(0.5 0.16 30);
|
||||
--chart-5: oklch(0.55 0.05 250);
|
||||
--chart-1: oklch(0.56 0.13 55);
|
||||
--chart-2: oklch(0.46 0.08 145);
|
||||
--chart-3: oklch(0.6 0.12 85);
|
||||
--chart-4: oklch(0.5 0.17 28);
|
||||
--chart-5: oklch(0.52 0.08 250);
|
||||
--sidebar: oklch(0.995 0.004 90);
|
||||
--sidebar-foreground: oklch(0.22 0.028 55);
|
||||
--sidebar-primary: oklch(0.6 0.15 48);
|
||||
--sidebar-primary-foreground: oklch(0.99 0.02 85);
|
||||
--sidebar-accent: oklch(0.93 0.032 74);
|
||||
--sidebar-accent-foreground: oklch(0.26 0.045 50);
|
||||
--sidebar-border: oklch(0.85 0.024 78);
|
||||
--sidebar-ring: oklch(0.6 0.15 48);
|
||||
--sidebar-foreground: oklch(0.21 0.03 55);
|
||||
--sidebar-primary: oklch(0.8 0.145 78);
|
||||
--sidebar-primary-foreground: oklch(0.21 0.035 55);
|
||||
--sidebar-accent: oklch(0.935 0.03 78);
|
||||
--sidebar-accent-foreground: oklch(0.25 0.045 50);
|
||||
--sidebar-border: oklch(0.86 0.022 78);
|
||||
--sidebar-ring: oklch(0.47 0.115 55);
|
||||
--shadow-elevated: 0 1px 2px -1px oklch(0.3 0.05 50 / 8%), 0 8px 24px -8px oklch(0.3 0.05 50 / 16%);
|
||||
--shadow-soft: 0 1px 2px -1px oklch(0.3 0.05 50 / 6%), 0 4px 12px -4px oklch(0.3 0.05 50 / 10%);
|
||||
--holo-bg: oklch(0.18 0.03 250);
|
||||
@@ -515,7 +509,7 @@
|
||||
}
|
||||
input,
|
||||
textarea {
|
||||
caret-color: var(--primary);
|
||||
caret-color: var(--primary-ink);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,7 +581,7 @@
|
||||
position: absolute;
|
||||
inset: 0.375rem;
|
||||
border-radius: 0.6rem;
|
||||
border: 2px solid color-mix(in oklch, var(--primary) 65%, var(--border));
|
||||
border: 2px solid var(--input);
|
||||
background: var(--card);
|
||||
transition:
|
||||
border-color 150ms ease-out,
|
||||
|
||||
@@ -62,7 +62,7 @@ interface InfoRowProps {
|
||||
function InfoRow({ icon: Icon, label, value }: InfoRowProps) {
|
||||
return (
|
||||
<div className="flex items-start gap-2.5">
|
||||
<Icon className="mt-0.5 size-4 shrink-0 text-primary" />
|
||||
<Icon className="mt-0.5 size-4 shrink-0 text-primary-ink" />
|
||||
<div>
|
||||
<dt className="text-muted-foreground">{label}</dt>
|
||||
<dd className="font-medium">{value}</dd>
|
||||
@@ -80,7 +80,7 @@ interface StatProps {
|
||||
function Stat({ icon: Icon, label, value }: StatProps) {
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-1 rounded-xl bg-accent/40 px-3 py-3 text-center">
|
||||
<Icon className="size-4 text-primary" />
|
||||
<Icon className="size-4 text-primary-ink" />
|
||||
<span className="text-sm font-semibold">{value}</span>
|
||||
<span className="text-[0.7rem] text-muted-foreground">{label}</span>
|
||||
</div>
|
||||
@@ -137,7 +137,7 @@ export default function PublicBatchPage() {
|
||||
{batch.productName ?? "Honig"}
|
||||
</h1>
|
||||
{batch.honeyType ? (
|
||||
<span className="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2.5 py-0.5 text-xs font-medium text-primary">
|
||||
<span className="inline-flex items-center gap-1 rounded-full bg-primary/10 px-2.5 py-0.5 text-xs font-medium text-primary-ink">
|
||||
<Sparkles className="size-3" />
|
||||
{batch.honeyType}
|
||||
</span>
|
||||
@@ -197,7 +197,7 @@ export default function PublicBatchPage() {
|
||||
href={link.url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-1.5 rounded-full bg-primary/10 px-3 py-1.5 text-sm font-medium text-primary transition-colors hover:bg-primary/20"
|
||||
className="flex items-center gap-1.5 rounded-full bg-primary/10 px-3 py-1.5 text-sm font-medium text-primary-ink transition-colors hover:bg-primary/20"
|
||||
>
|
||||
<Icon className="size-4" />
|
||||
{link.label}
|
||||
|
||||
Reference in new issue
Block a user