Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/css/base/variables.css
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,16 @@
--transition-base: 200ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-slow: 300ms cubic-bezier(0.4, 0, 0.2, 1);
--transition-spring: 400ms cubic-bezier(0.34, 1.56, 0.64, 1);
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);

/* Stagger delays for orchestrated animations */
--stagger-1: 0.1s;
--stagger-2: 0.15s;
--stagger-3: 0.2s;
--stagger-4: 0.25s;
--stagger-5: 0.3s;
--stagger-6: 0.35s;

Comment on lines +86 to +93

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The stagger delay variables defined in this file are not being used. In animations.css, the animation delays are hardcoded (0.1s, 0.15s, 0.2s, etc.) instead of using these CSS variables. Consider either removing these unused variables or updating the animation delays in animations.css to use them (e.g., animation-delay: var(--stagger-1);). This would improve maintainability by centralizing the delay values.

Suggested change
/* Stagger delays for orchestrated animations */
--stagger-1: 0.1s;
--stagger-2: 0.15s;
--stagger-3: 0.2s;
--stagger-4: 0.25s;
--stagger-5: 0.3s;
--stagger-6: 0.35s;

Copilot uses AI. Check for mistakes.
/* Primary color as RGB for alpha usage */
--primary-rgb: 99, 102, 241;
}
5 changes: 3 additions & 2 deletions src/css/components/buttons.css
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ button:focus-visible {
}

.primary:active {
transform: translateY(0);
transform: translateY(0) scale(0.98);
box-shadow: var(--shadow-sm);
}

Expand All @@ -109,7 +109,7 @@ button:focus-visible {
}

.secondary:active {
transform: translateY(0);
transform: translateY(0) scale(0.98);
}

/* Ghost Button */
Expand All @@ -129,4 +129,5 @@ button:focus-visible {

.ghost:active {
background: var(--gray-100);
transform: scale(0.98);
}
14 changes: 11 additions & 3 deletions src/css/components/forms.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
}

/* ===== Form Blocks ===== */
/* Animation is handled in utilities/animations.css for orchestrated staggered entry */
.form-block {
padding-bottom: var(--space-5);
margin-bottom: var(--space-5);
border-bottom: 1px solid var(--gray-100);
animation: fadeInUp var(--transition-slow) ease-out;
}

.form-block:last-of-type {
Expand Down Expand Up @@ -193,9 +193,17 @@
grid-template-columns: 2fr 0.7fr 1fr 1fr 40px;
gap: var(--space-3);
align-items: center;
padding: var(--space-2) 0;
padding: var(--space-2) var(--space-1);
margin-bottom: var(--space-2);
animation: fadeInUp var(--transition-fast) ease-out;
border-radius: var(--radius-sm);
transition:
transform var(--transition-fast),
background-color var(--transition-fast);
}

.item-row:hover {
transform: translateX(4px);
background: var(--gray-50);
}

.item-row input {
Expand Down
2 changes: 2 additions & 0 deletions src/css/components/history.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ button.small {
margin-bottom: var(--space-2);
cursor: pointer;
transition:
transform var(--transition-fast),
border-color var(--transition-fast),
background-color var(--transition-fast);
}
Expand All @@ -63,6 +64,7 @@ button.small {
}

.history-item:hover {
transform: translateX(4px);
border-color: var(--primary-300);
background: var(--primary-50);
}
Expand Down
3 changes: 2 additions & 1 deletion src/css/layout/grid.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/* ===== Layout ===== */
.container {
display: grid;
grid-template-columns: 1fr 1fr;
/* Asymmetrical grid for visual interest */
grid-template-columns: 0.9fr 1fr;
Comment on lines +4 to +5

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a discrepancy in the asymmetrical grid ratio. This PR implements 0.9fr 1fr, but the referenced PR #6 (mentioned in the description) states it uses 0.85fr : 1fr. Please verify which ratio is intended and ensure consistency between the implementations.

Copilot uses AI. Check for mistakes.
min-height: 100vh;
gap: 0;
}
Expand Down
25 changes: 24 additions & 1 deletion src/css/layout/responsive.css
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@
* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
animation: none !important;
transition: none !important;
}

html,
Expand All @@ -249,6 +251,11 @@
font-size: 12px !important;
}

/* Hide noise texture in print */
body::before {
display: none !important;
}

.container {
display: block !important;
max-width: none !important;
Expand All @@ -258,11 +265,14 @@
gap: 0 !important;
}

.form-section {
.form-section,
.invoice-placeholder,
.skip-link {
display: none !important;
}

.invoice-section {
display: block !important;
box-shadow: none !important;
padding: 20px !important;
margin: 0 !important;
Expand Down Expand Up @@ -322,6 +332,19 @@
font-size: 11px !important;
}

/* Preserve dark total row in print */
.total-row {
background: #1f2937 !important;
color: white !important;
padding: 8px 12px !important;
border-radius: 4px !important;
}

.total-row .total-label,
.total-row .total-amount {
color: white !important;
}

.balance-due h2 {
font-size: 14px !important;
}
Expand Down
98 changes: 95 additions & 3 deletions src/css/utilities/animations.css
Original file line number Diff line number Diff line change
@@ -1,16 +1,104 @@
/* ===== Animations ===== */
@keyframes fadeInUp {
/* ===== Keyframe Animations ===== */

/* Slide in from left (form section) */
@keyframes slideInFromLeft {
from {
opacity: 0;
transform: translateY(8px);
transform: translateX(-24px);
}
to {
opacity: 1;
transform: translateX(0);
}
}

/* Slide in from right (invoice preview) */
@keyframes slideInFromRight {
from {
opacity: 0;
transform: translateX(24px);
}
to {
opacity: 1;
transform: translateX(0);
}
}

/* Fade up for content blocks */
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

/* Scale in for panels/modals */
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}

/* Focus ring pulse */
@keyframes focusRingPulse {
0% {
box-shadow: 0 0 0 0 rgba(var(--primary-rgb), 0.4);
}
100% {
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.15);
}
}

/* ===== Page Entry Orchestration ===== */
.form-section {
animation: slideInFromLeft 0.5s var(--ease-out-expo) forwards;
}

.invoice-section,
.invoice-placeholder {
animation: slideInFromRight 0.5s var(--ease-out-expo) 0.08s backwards;
}

/* ===== Staggered Form Block Entry ===== */
.form-block {
animation: fadeInUp 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cubic-bezier timing function is hardcoded here but a CSS variable --ease-out-expo is defined in variables.css with the same value. Consider using var(--ease-out-expo) instead for consistency and maintainability, as is done in other animation rules (lines 63, 68, 87, 92).

Suggested change
animation: fadeInUp 0.4s cubic-bezier(0.16, 1, 0.3, 1) both;
animation: fadeInUp 0.4s var(--ease-out-expo) both;

Copilot uses AI. Check for mistakes.
}
Comment on lines +72 to +74

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep form blocks visible after entry animation

Because main.css imports utilities before components, the later .form-block rule in components/forms.css overrides the animation here and drops the forwards fill mode. With opacity: 0 still coming from this rule, once the entry animation finishes (normal motion, non-reduced), the blocks revert to opacity 0 and effectively disappear. Consider removing the base opacity or ensuring the final animation rule keeps forwards/sets opacity: 1.

Useful? React with 👍 / 👎.


.form-block:nth-child(1) { animation-delay: 0.1s; }
.form-block:nth-child(2) { animation-delay: 0.15s; }
.form-block:nth-child(3) { animation-delay: 0.2s; }
.form-block:nth-child(4) { animation-delay: 0.25s; }
.form-block:nth-child(5) { animation-delay: 0.3s; }
.form-block:nth-child(6) { animation-delay: 0.35s; }
Comment on lines +76 to +81

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The animation delays are hardcoded here, but CSS variables for stagger delays (--stagger-1 through --stagger-6) are defined in variables.css. Consider using these variables instead to improve maintainability. For example: animation-delay: var(--stagger-1); for the first child, animation-delay: var(--stagger-2); for the second, etc.

Suggested change
.form-block:nth-child(1) { animation-delay: 0.1s; }
.form-block:nth-child(2) { animation-delay: 0.15s; }
.form-block:nth-child(3) { animation-delay: 0.2s; }
.form-block:nth-child(4) { animation-delay: 0.25s; }
.form-block:nth-child(5) { animation-delay: 0.3s; }
.form-block:nth-child(6) { animation-delay: 0.35s; }
.form-block:nth-child(1) { animation-delay: var(--stagger-1); }
.form-block:nth-child(2) { animation-delay: var(--stagger-2); }
.form-block:nth-child(3) { animation-delay: var(--stagger-3); }
.form-block:nth-child(4) { animation-delay: var(--stagger-4); }
.form-block:nth-child(5) { animation-delay: var(--stagger-5); }
.form-block:nth-child(6) { animation-delay: var(--stagger-6); }

Copilot uses AI. Check for mistakes.
.form-block:nth-child(7) { animation-delay: 0.4s; }
.form-block:nth-child(8) { animation-delay: 0.45s; }

/* ===== Line Item Entry Animation ===== */
.item-row {
animation: fadeInUp 0.25s var(--ease-out-expo) forwards;
}

/* ===== History Panel Animation ===== */
.history-panel {
animation: scaleIn 0.25s var(--ease-out-expo) forwards;
}

/* ===== Focus Ring Animation ===== */
.form-group input:focus,
.form-group textarea:focus,
.form-group select:focus {
animation: focusRingPulse 0.2s ease-out forwards;
}
Comment on lines +95 to +100

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The focusRingPulse animation sets box-shadow values that will override the static box-shadow defined in forms.css line 146 (.form-group input:focus has box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.12);). The animation starts with box-shadow: 0 0 0 0 rgba(var(--primary-rgb), 0.4) and ends with box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.15). This means after the animation completes, the box-shadow will be 0 0 0 3px rgba(99, 102, 241, 0.15) instead of the expected 0 0 0 3px rgba(99, 102, 241, 0.12) from the :focus rule. Consider adjusting the animation's final state to match the static focus style, or adjust the static style to use the animation's end state.

Copilot uses AI. Check for mistakes.

/* Respect reduced motion preferences */
@media (prefers-reduced-motion: reduce) {
*,
Expand All @@ -21,4 +109,8 @@
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}

.form-block {

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reduced motion media query only explicitly sets opacity for .form-block elements, but other animated elements (.form-section, .invoice-section, .invoice-placeholder, .item-row, .history-panel) also start with opacity: 0 in their animations. When animations are disabled with animation-duration: 0.01ms, these elements might flash briefly at opacity 0 or may have visibility issues. Consider adding explicit opacity rules for all animated elements within the reduced motion media query to ensure they're fully visible, similar to what's done for .form-block.

Suggested change
.form-block {
.form-block,
.form-section,
.invoice-section,
.invoice-placeholder,
.item-row,
.history-panel {

Copilot uses AI. Check for mistakes.
opacity: 1;
}
}