- {leftContent ||
{title}
}
+
+ {/* Content container - full width when floating, content width when docked */}
+
+
+
+ {/* Left content */}
+ {leftContent && (
+
+ {leftContent}
+
+ )}
+
+ {/* Right actions */}
+ {children}
+
+
-
{children}
);
}
diff --git a/src/components/ui/calendar.tsx b/src/components/ui/calendar.tsx
index ca62e4c..09f4984 100644
--- a/src/components/ui/calendar.tsx
+++ b/src/components/ui/calendar.tsx
@@ -6,7 +6,11 @@ import {
ChevronLeftIcon,
ChevronRightIcon,
} from "lucide-react";
-import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker";
+import {
+ type DayButton,
+ DayPicker,
+ getDefaultClassNames,
+} from "react-day-picker";
import { cn } from "~/lib/utils";
import { Button, buttonVariants } from "~/components/ui/button";
@@ -24,7 +28,7 @@ function Calendar({
showOutsideDays = true,
captionLayout = "label",
buttonVariant = "ghost",
- formatters,
+ formatters: _formatters,
components,
month,
onMonthChange,
@@ -49,8 +53,8 @@ function Calendar({
"Dec",
];
- const currentYear = month?.getFullYear() || new Date().getFullYear();
- const currentMonth = month?.getMonth() || new Date().getMonth();
+ const currentYear = month?.getFullYear() ?? new Date().getFullYear();
+ const currentMonth = month?.getMonth() ?? new Date().getMonth();
const years = Array.from({ length: 11 }, (_, i) => currentYear - 5 + i);
@@ -173,9 +177,9 @@ function Calendar({
);
},
DayButton: CalendarDayButton,
- MonthCaption: ({ calendarMonth }) => {
+ MonthCaption: ({ calendarMonth: _calendarMonth }) => {
if (captionLayout !== "dropdown") {
- return null;
+ return <>>;
}
return (
@@ -248,7 +252,7 @@ function CalendarDayButton({
modifiers,
...props
}: React.ComponentProps
) {
- const defaultClassNames = getDefaultClassNames();
+ const _defaultClassNames = getDefaultClassNames();
const ref = React.useRef(null);
React.useEffect(() => {
diff --git a/src/lib/pdf-export.tsx b/src/lib/pdf-export.tsx
index a87a6c9..90ad12b 100644
--- a/src/lib/pdf-export.tsx
+++ b/src/lib/pdf-export.tsx
@@ -104,7 +104,7 @@ const styles = StyleSheet.create({
// Dense header (first page)
denseHeader: {
marginBottom: 30,
- borderBottom: "2px solid #16a34a",
+ borderBottom: "2px solid #10b981",
paddingBottom: 20,
},
@@ -123,7 +123,7 @@ const styles = StyleSheet.create({
businessName: {
fontSize: 24,
fontWeight: "bold",
- color: "#1f2937",
+ color: "#111827",
marginBottom: 4,
},
@@ -148,7 +148,7 @@ const styles = StyleSheet.create({
invoiceTitle: {
fontSize: 32,
fontWeight: "bold",
- color: "#16a34a",
+ color: "#10b981",
marginBottom: 8,
},
@@ -156,7 +156,7 @@ const styles = StyleSheet.create({
fontSize: 15,
fontWeight: "semibold",
fontFamily: "AzeretMono",
- color: "#1f2937",
+ color: "#111827",
marginBottom: 4,
},
@@ -170,8 +170,8 @@ const styles = StyleSheet.create({
},
statusPaid: {
- backgroundColor: "#dcfce7",
- color: "#166534",
+ backgroundColor: "#ecfdf5",
+ color: "#065f46",
},
statusUnpaid: {
@@ -194,14 +194,14 @@ const styles = StyleSheet.create({
sectionTitle: {
fontSize: 14,
fontWeight: "bold",
- color: "#1f2937",
+ color: "#111827",
marginBottom: 12,
},
clientName: {
fontSize: 13,
fontWeight: "bold",
- color: "#1f2937",
+ color: "#111827",
marginBottom: 4,
},
@@ -233,7 +233,7 @@ const styles = StyleSheet.create({
detailValue: {
fontSize: 10,
fontFamily: "AzeretMono",
- color: "#1f2937",
+ color: "#111827",
fontWeight: "semibold",
flex: 1,
textAlign: "right",
@@ -252,7 +252,7 @@ const styles = StyleSheet.create({
notesTitle: {
fontSize: 12,
fontWeight: "bold",
- color: "#1f2937",
+ color: "#111827",
marginBottom: 6,
},
@@ -282,7 +282,7 @@ const styles = StyleSheet.create({
abridgedBusinessName: {
fontSize: 18,
fontWeight: "bold",
- color: "#1f2937",
+ color: "#111827",
},
abridgedInvoiceInfo: {
@@ -294,14 +294,14 @@ const styles = StyleSheet.create({
abridgedInvoiceTitle: {
fontSize: 16,
fontWeight: "bold",
- color: "#16a34a",
+ color: "#10b981",
},
abridgedInvoiceNumber: {
fontSize: 13,
fontWeight: "semibold",
fontFamily: "AzeretMono",
- color: "#1f2937",
+ color: "#111827",
},
// Table styles
@@ -313,7 +313,7 @@ const styles = StyleSheet.create({
tableHeader: {
flexDirection: "row",
backgroundColor: "#f3f4f6",
- borderBottom: "2px solid #16a34a",
+ borderBottom: "2px solid #10b981",
paddingVertical: 8,
paddingHorizontal: 4,
},
@@ -321,7 +321,7 @@ const styles = StyleSheet.create({
tableHeaderCell: {
fontSize: 11,
fontWeight: "bold",
- color: "#1f2937",
+ color: "#111827",
paddingHorizontal: 4,
},
@@ -362,7 +362,7 @@ const styles = StyleSheet.create({
tableCell: {
fontSize: 10,
- color: "#1f2937",
+ color: "#111827",
paddingHorizontal: 4,
paddingVertical: 2,
},
@@ -433,7 +433,7 @@ const styles = StyleSheet.create({
totalAmount: {
fontSize: 10,
fontFamily: "AzeretMono",
- color: "#1f2937",
+ color: "#111827",
fontWeight: "semibold",
},
@@ -442,7 +442,7 @@ const styles = StyleSheet.create({
justifyContent: "space-between",
marginTop: 8,
paddingTop: 8,
- borderTop: "2px solid #16a34a",
+ borderTop: "2px solid #10b981",
},
finalTotalLabel: {
@@ -455,7 +455,7 @@ const styles = StyleSheet.create({
fontSize: 15,
fontFamily: "AzeretMono",
fontWeight: "bold",
- color: "#16a34a",
+ color: "#10b981",
},
itemCount: {
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 0a0f16e..ab839f1 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -67,8 +67,8 @@
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--destructive-foreground: oklch(0.985 0 0);
- --border: oklch(0.922 0 0);
- --input: oklch(0.922 0 0);
+ --border: oklch(0.82 0.02 150);
+ --input: oklch(0.82 0.02 150);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.646 0.222 41.116);
--chart-2: oklch(0.6 0.118 184.704);
@@ -81,7 +81,7 @@
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
- --sidebar-border: oklch(0.922 0 0);
+ --sidebar-border: oklch(0.82 0.02 150);
--sidebar-ring: oklch(0.708 0 0);
/* Brand colors */
@@ -1380,20 +1380,8 @@
}
/* Floating Action Bar Utility Classes */
- .floating-action-bar {
- @apply border-border/40 bg-background/60 animate-in slide-in-from-bottom-4 sticky bottom-4 z-20 flex items-center justify-between rounded-2xl border p-4 shadow-lg backdrop-blur-xl backdrop-saturate-150 duration-300;
- }
-
- .floating-action-bar-content {
- @apply flex-1;
- }
-
- .floating-action-bar-title {
- @apply text-muted-foreground text-sm;
- }
-
- .floating-action-bar-actions {
- @apply flex items-center gap-2 sm:gap-3;
+ .pb-safe-area-inset-bottom {
+ padding-bottom: env(safe-area-inset-bottom);
}
/* Form Action Footer Utility Classes */