BillTracker/client/index.css

491 lines
12 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ============================================================
Bill Tracker — Material Design theme via shadcn/studio
:root is the default Material Design light theme.
============================================================ */
/* ── Georgia for digits only ─────────────────────────────── */
@import 'tailwindcss';
@plugin 'tailwindcss-animate';
@custom-variant dark (&:is(.dark *));
@utility container {
margin-inline: auto;
padding-inline: 2rem;
@media (width >= --theme(--breakpoint-sm)) {
max-width: none;
}
@media (width >= 1400px) {
max-width: 1400px;
}
}
@theme {
--color-border: oklch(var(--border));
--color-input: oklch(var(--input));
--color-ring: oklch(var(--ring));
--color-background: oklch(var(--background));
--color-foreground: oklch(var(--foreground));
--color-primary: oklch(var(--primary));
--color-primary-foreground: oklch(var(--primary-foreground));
--color-secondary: oklch(var(--secondary));
--color-secondary-foreground: oklch(var(--secondary-foreground));
--color-destructive: oklch(var(--destructive));
--color-destructive-foreground: oklch(var(--destructive-foreground));
--color-muted: oklch(var(--muted));
--color-muted-foreground: oklch(var(--muted-foreground));
--color-accent: oklch(var(--accent));
--color-accent-foreground: oklch(var(--accent-foreground));
--color-popover: oklch(var(--popover));
--color-popover-foreground: oklch(var(--popover-foreground));
--color-card: oklch(var(--card));
--color-card-foreground: oklch(var(--card-foreground));
--color-sidebar: oklch(var(--sidebar));
--color-sidebar-foreground: oklch(var(--sidebar-foreground));
--color-sidebar-primary: oklch(var(--sidebar-primary));
--color-sidebar-accent: oklch(var(--sidebar-accent));
--color-sidebar-border: oklch(var(--sidebar-border));
--color-sidebar-ring: oklch(var(--sidebar-ring));
--font-sans:
Inter, Roboto, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
sans-serif;
--font-serif: var(--font-serif), ui-serif, serif;
--font-mono: var(--font-mono), ui-monospace, SFMono-Regular, monospace;
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;
--animate-collapsible-down: collapsible-down 0.2s ease-out;
--animate-collapsible-up: collapsible-up 0.2s ease-out;
@keyframes accordion-down {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
@keyframes collapsible-down {
from {
height: 0;
}
to {
height: var(--radix-collapsible-content-height);
}
}
@keyframes collapsible-up {
from {
height: var(--radix-collapsible-content-height);
}
to {
height: 0;
}
}
}
/*
The default border color has changed to `currentcolor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}
/* ── Utilities ───────────────────────────────────────────── */
@utility surface {
/* Generic surface */
@apply rounded-xl border border-border/75 bg-card/95 shadow-xs shadow-black/10;
}
@utility surface-elevated {
/* Elevated surface */
@apply surface backdrop-blur-xs;
box-shadow:
0 1px 2px rgb(0 0 0 / 0.05),
0 10px 30px rgb(15 23 42 / 0.07);
.dark & {
box-shadow:
0 0 0 1px oklch(var(--border) / 0.7),
0 14px 34px rgb(0 0 0 / 0.42);
}
}
@utility dark {
& .surface-elevated {
box-shadow:
0 0 0 1px oklch(var(--border) / 0.7),
0 14px 34px rgb(0 0 0 / 0.42);
}
& .surface-premium {
box-shadow:
0 0 0 1px oklch(var(--border) / 0.55),
0 12px 30px rgb(0 0 0 / 0.34);
}
/* Faded muted-text variants: keep them readable in dark mode — Tailwind's
raw /40/70 alphas dissolve into the background. */
& .text-muted-foreground\/40 {
color: oklch(var(--muted-foreground) / 0.8);
}
& .text-muted-foreground\/50 {
color: oklch(var(--muted-foreground) / 0.85);
}
& .text-muted-foreground\/60 {
color: oklch(var(--muted-foreground) / 0.9);
}
& .text-muted-foreground\/70 {
color: oklch(var(--muted-foreground) / 0.95);
}
}
@utility surface-premium {
@apply rounded-xl border border-border/75 bg-card/95 shadow-xs shadow-black/10 backdrop-blur-xs;
.dark & {
box-shadow:
0 0 0 1px oklch(var(--border) / 0.55),
0 12px 30px rgb(0 0 0 / 0.34);
}
}
@utility metric-card {
@apply relative min-h-31 overflow-hidden rounded-xl border border-border/75 bg-card/95 px-4 py-4 shadow-xs shadow-black/10 sm:px-5;
&::before {
content: '';
position: absolute;
inset: 0 0 auto;
height: 2px;
background: currentColor;
opacity: 0.24;
}
}
@utility stat-card {
/* Stat cards */
@apply surface-elevated p-6;
}
@utility table-surface {
/* Table */
@apply surface-premium overflow-hidden;
}
@utility tracker-number {
font-family: 'GeorgiaDigits', Inter, Roboto, ui-sans-serif, system-ui, sans-serif;
font-variant-numeric: tabular-nums lining-nums;
font-feature-settings:
'tnum' 1,
'lnum' 1;
-webkit-font-smoothing: auto;
text-rendering: optimizeLegibility;
}
@utility metric-value {
@apply tracker-number font-bold tracking-tight text-foreground;
overflow-wrap: anywhere;
}
@utility text-muted-foreground/40 {
/* Faded muted-text variants: keep them readable in dark mode — Tailwind's
raw /40/70 alphas dissolve into the background. */
.dark & {
color: oklch(var(--muted-foreground) / 0.8);
}
}
@utility text-muted-foreground/50 {
.dark & {
color: oklch(var(--muted-foreground) / 0.85);
}
}
@utility text-muted-foreground/60 {
.dark & {
color: oklch(var(--muted-foreground) / 0.9);
}
}
@utility text-muted-foreground/70 {
.dark & {
color: oklch(var(--muted-foreground) / 0.95);
}
}
@utility scrollbar-thin {
/* Custom Scrollbar */
scrollbar-width: thin;
}
@utility scrollbar-thumb-muted {
scrollbar-color: oklch(var(--muted) / 0.3) transparent;
&::-webkit-scrollbar-thumb {
background-color: oklch(var(--muted) / 0.3);
border-radius: 8px;
}
&::-webkit-scrollbar-thumb:hover {
background-color: oklch(var(--muted) / 0.5);
}
}
@utility scrollbar-track-transparent {
scrollbar-color: oklch(var(--muted) / 0.3) transparent;
&::-webkit-scrollbar-track {
background-color: transparent;
}
}
@layer base {
@font-face {
font-family: 'GeorgiaDigits';
src: local('Georgia');
unicode-range:
U+0030-0039,
/* 09 */ U+002C,
/* , thousands separator */ U+002E,
/* . decimal point */ U+002D,
/* - minus / hyphen */ U+002B,
/* + plus */ U+0025,
/* % percent */ U+0024,
/* $ dollar */ U+00A2,
/* ¢ cent */ U+00A3,
/* £ pound */ U+00A5,
/* ¥ yen */ U+20AC; /* € euro */
}
}
/* ── Tailwind base ───────────────────────────────────────── */
@layer base {
:root {
--background: 0.985 0.006 235;
--foreground: 0.185 0.018 238;
--card: 0.998 0.003 238;
--card-foreground: 0.185 0.018 238;
--popover: 1 0 0;
--popover-foreground: 0.185 0.018 238;
--primary: 0.64 0.17 154;
--primary-foreground: 0.985 0.006 154;
--secondary: 0.94 0.01 235;
--secondary-foreground: 0.245 0.018 238;
--muted: 0.945 0.009 235;
--muted-foreground: 0.44 0.016 238;
--accent: 0.925 0.02 184;
--accent-foreground: 0.205 0.02 190;
--destructive: 0.58 0.21 22;
--destructive-foreground: 0.99 0.003 250;
--border: 0.875 0.01 235;
--input: 0.875 0.01 235;
--ring: 0.64 0.15 154;
--chart-1: 0.62 0.17 154;
--chart-2: 0.58 0.13 195;
--chart-3: 0.64 0.16 65;
--chart-4: 0.62 0.17 335;
--chart-5: 0.55 0.11 250;
--sidebar: 0.965 0.008 235;
--sidebar-foreground: 0.22 0.018 238;
--sidebar-primary: 0.64 0.17 154;
--sidebar-primary-foreground: 0.985 0.006 154;
--sidebar-accent: 0.925 0.02 184;
--sidebar-accent-foreground: 0.205 0.02 190;
--sidebar-border: 0.875 0.01 235;
--sidebar-ring: 0.64 0.15 154;
--font-sans:
Inter, Roboto, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI',
sans-serif;
--font-serif: Merriweather, ui-serif, serif;
--font-mono: 'Roboto Mono', ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
--radius: 1rem;
}
.dark {
--background: 0.145 0.018 238;
--foreground: 0.962 0.008 235;
--card: 0.205 0.02 238;
--card-foreground: 0.962 0.008 235;
--popover: 0.235 0.022 238;
--popover-foreground: 0.962 0.008 235;
--primary: 0.72 0.15 154;
--primary-foreground: 0.145 0.02 154;
--secondary: 0.275 0.02 238;
--secondary-foreground: 0.94 0.008 235;
--muted: 0.275 0.018 238;
/* Secondary text. Raised 0.76 → 0.85 — at 0.76 labels and hints sat too
close to the card background (L 0.235) and strained the eyes. */
--muted-foreground: 0.85 0.012 245;
--accent: 0.33 0.05 184;
--accent-foreground: 0.965 0.008 235;
--destructive: 0.66 0.18 26;
--destructive-foreground: 0.98 0.004 245;
--border: 0.37 0.02 238;
--input: 0.37 0.02 238;
--ring: 0.72 0.14 154;
--chart-1: 0.72 0.15 154;
--chart-2: 0.7 0.12 195;
--chart-3: 0.75 0.15 68;
--chart-4: 0.7 0.16 340;
--chart-5: 0.68 0.1 250;
--sidebar: 0.165 0.018 238;
--sidebar-foreground: 0.95 0.008 235;
--sidebar-primary: 0.72 0.15 154;
--sidebar-primary-foreground: 0.145 0.02 154;
--sidebar-accent: 0.3 0.045 184;
--sidebar-accent-foreground: 0.95 0.008 235;
--sidebar-border: 0.34 0.02 238;
--sidebar-ring: 0.72 0.14 154;
}
* {
@apply border-border;
}
html {
@apply scroll-smooth;
}
body {
@apply bg-background font-sans text-foreground antialiased;
letter-spacing: 0;
}
::selection {
color: oklch(var(--primary-foreground));
background: oklch(var(--primary) / 0.75);
}
strong {
@apply font-semibold text-foreground;
}
}
@media print {
body {
background: white !important;
color: #111827 !important;
}
header,
.analytics-screen-header,
.analytics-controls,
.analytics-actions,
.summary-screen-header,
.summary-controls,
.summary-actions,
.summary-reorder-controls,
.summary-edit-actions,
.summary-income-form,
.tracker-print-hide {
display: none !important;
}
/* Tracker printout: don't split a bill row across a page boundary. */
[data-tracker-row] {
break-inside: avoid;
}
main,
main > div {
max-width: none !important;
padding: 0 !important;
}
.analytics-page,
.summary-page {
color: #111827 !important;
}
.analytics-report-meta,
.analytics-print-footer,
.summary-print-meta,
.summary-print-footer {
display: block !important;
margin-bottom: 1rem;
}
.analytics-report-meta h1,
.summary-print-meta h1 {
font-size: 22px;
font-weight: 700;
margin-bottom: 0.25rem;
}
.analytics-report-meta p,
.analytics-print-footer,
.summary-print-meta p,
.summary-print-footer {
color: #4b5563 !important;
font-size: 12px;
margin: 0.125rem 0;
}
.analytics-range {
margin-bottom: 1rem;
}
.summary-page input {
border: 0 !important;
background: white !important;
box-shadow: none !important;
color: #111827 !important;
padding-left: 0 !important;
}
.summary-expense-row {
grid-template-columns: minmax(0, 1fr) 7.5rem 5.5rem !important;
}
.analytics-chart-grid {
display: block !important;
}
.analytics-chart,
.summary-card,
.summary-chart-card {
break-inside: avoid;
page-break-inside: avoid;
margin-bottom: 1rem;
border: 1px solid #d1d5db !important;
box-shadow: none !important;
background: white !important;
}
}