sync: Auto-sync from ACG-M-L5090 at 2026-03-10 19:11:00

Synced files:
- Quote wizard frontend (all components, hooks, types, config)
- API updates (config, models, routers, schemas, services)
- Client work (bg-builders, gurushow)
- Scripts (BGB Lesley termination, CIPP, Datto, migration)
- Temp files (Bardach contacts, VWP investigation, misc)
- Credentials and session logs
- Email service, PHP API, session logs

Machine: ACG-M-L5090
Timestamp: 2026-03-10 19:11:00

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-10 19:59:08 -07:00
parent 84fce5a621
commit af72a12e3e
168 changed files with 879909 additions and 1243 deletions

View File

@@ -22,32 +22,33 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
ref
) => {
const baseStyles =
'inline-flex items-center justify-center font-medium rounded-lg transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
'inline-flex items-center justify-center font-semibold rounded-xl transition-all duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:opacity-40 disabled:cursor-not-allowed';
const variants = {
primary:
'bg-[#fe7400] text-white hover:bg-[#e56800] focus-visible:ring-[#fe7400] shadow-sm hover:shadow-md',
'bg-gradient-accent text-white hover:brightness-110 focus-visible:ring-[#fe7400] shadow-sm hover:shadow-md active:brightness-95',
secondary:
'bg-[#333d49] text-white hover:bg-[#252d36] focus-visible:ring-[#333d49] shadow-sm hover:shadow-md',
outline:
'border-2 border-[#333d49] text-[#333d49] hover:bg-[#333d49] hover:text-white focus-visible:ring-[#333d49]',
'border-2 border-gray-200 text-[#333d49] hover:border-[#333d49] hover:bg-gray-50 focus-visible:ring-[#333d49]',
ghost:
'text-[#333d49] hover:bg-gray-100 focus-visible:ring-[#333d49]',
'text-[#333d49] hover:bg-gray-100/80 focus-visible:ring-[#333d49]',
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-5 py-2.5 text-base',
lg: 'px-7 py-3.5 text-lg',
sm: 'px-4 py-2 text-sm',
md: 'px-6 py-2.5 text-sm',
lg: 'px-8 py-3.5 text-base',
};
return (
<motion.button
ref={ref}
whileHover={{ scale: disabled || isLoading ? 1 : 1.02 }}
whileTap={{ scale: disabled || isLoading ? 1 : 0.98 }}
whileHover={{ scale: disabled || isLoading ? 1 : 1.015 }}
whileTap={{ scale: disabled || isLoading ? 1 : 0.985 }}
className={cn(baseStyles, variants[variant], sizes[size], className)}
disabled={disabled || isLoading}
style={{ fontFamily: "'Plus Jakarta Sans', sans-serif" }}
{...props}
>
{isLoading ? (
@@ -72,7 +73,7 @@ const Button = forwardRef<HTMLButtonElement, ButtonProps>(
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
/>
</svg>
Loading...
Processing...
</>
) : (
children

View File

@@ -23,13 +23,20 @@ const Card = forwardRef<HTMLDivElement, CardProps>(
},
ref
) => {
const baseStyles = 'rounded-xl transition-all duration-200';
const baseStyles = 'rounded-2xl transition-all duration-300';
const variants = {
default: 'bg-white border border-gray-200',
elevated: 'bg-white shadow-lg',
outlined: 'bg-transparent border-2 border-[#333d49]',
highlighted: 'bg-white border-2 border-[#fe7400] shadow-lg',
default: 'bg-white border border-gray-200/80',
elevated: 'bg-white border border-gray-200/60',
outlined: 'bg-transparent border-2 border-[#333d49]/20',
highlighted: 'bg-white border-2 border-[#fe7400] ring-1 ring-[#fe7400]/10',
};
const shadowStyles: Record<string, React.CSSProperties> = {
default: { boxShadow: '0 1px 2px rgba(17,53,89,0.04), 0 4px 12px rgba(17,53,89,0.06)' },
elevated: { boxShadow: '0 4px 6px rgba(17,53,89,0.04), 0 12px 32px rgba(17,53,89,0.08)' },
outlined: {},
highlighted: { boxShadow: '0 4px 6px rgba(17,53,89,0.04), 0 12px 32px rgba(17,53,89,0.08)' },
};
const paddings = {
@@ -40,15 +47,15 @@ const Card = forwardRef<HTMLDivElement, CardProps>(
};
const hoverStyles = hoverable
? 'cursor-pointer hover:shadow-xl hover:-translate-y-1'
? 'cursor-pointer hover:-translate-y-0.5'
: '';
if (hoverable) {
return (
<motion.div
ref={ref}
whileHover={{ scale: 1.01 }}
whileTap={{ scale: 0.99 }}
whileHover={{ scale: 1.01, boxShadow: '0 2px 4px rgba(17,53,89,0.06), 0 8px 24px rgba(17,53,89,0.1)' }}
whileTap={{ scale: 0.995 }}
className={cn(
baseStyles,
variants[variant],
@@ -56,6 +63,7 @@ const Card = forwardRef<HTMLDivElement, CardProps>(
hoverStyles,
className
)}
style={shadowStyles[variant]}
onClick={onClick}
>
{children}
@@ -72,6 +80,7 @@ const Card = forwardRef<HTMLDivElement, CardProps>(
paddings[padding],
className
)}
style={shadowStyles[variant]}
onClick={onClick}
>
{children}
@@ -82,7 +91,6 @@ const Card = forwardRef<HTMLDivElement, CardProps>(
Card.displayName = 'Card';
// Card subcomponents
const CardHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
({ className, ...props }, ref) => (
<div
@@ -99,6 +107,7 @@ const CardTitle = forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingEleme
<h3
ref={ref}
className={cn('text-xl font-semibold text-[#333d49]', className)}
style={{ fontFamily: "'Plus Jakarta Sans', sans-serif" }}
{...props}
/>
)
@@ -109,7 +118,7 @@ const CardDescription = forwardRef<HTMLParagraphElement, HTMLAttributes<HTMLPara
({ className, ...props }, ref) => (
<p
ref={ref}
className={cn('text-sm text-gray-500 mt-1', className)}
className={cn('text-sm text-gray-400 mt-1', className)}
{...props}
/>
)

View File

@@ -16,7 +16,8 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
{label && (
<label
htmlFor={inputId}
className="block text-sm font-medium text-[#333d49] mb-1.5"
className="block text-sm font-medium text-[#333d49] mb-2"
style={{ fontFamily: "'Plus Jakarta Sans', sans-serif" }}
>
{label}
</label>
@@ -26,13 +27,13 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
type={type}
ref={ref}
className={cn(
'w-full px-4 py-2.5 rounded-lg border transition-all duration-200',
'text-[#333d49] placeholder-gray-400',
'w-full px-4 py-3 rounded-xl border transition-all duration-200',
'text-[#333d49] placeholder-gray-400 bg-white',
'focus:outline-none focus:ring-2 focus:ring-offset-0',
error
? 'border-red-500 focus:border-red-500 focus:ring-red-200'
: 'border-gray-300 focus:border-[#fe7400] focus:ring-[#fe7400]/20',
'disabled:bg-gray-50 disabled:text-gray-500 disabled:cursor-not-allowed',
? 'border-red-400 focus:border-red-400 focus:ring-red-100'
: 'border-gray-200 hover:border-gray-300 focus:border-[#fe7400] focus:ring-[#fe7400]/15',
'disabled:bg-gray-50 disabled:text-gray-400 disabled:cursor-not-allowed',
className
)}
aria-invalid={error ? 'true' : 'false'}
@@ -42,12 +43,15 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
{...props}
/>
{error && (
<p id={`${inputId}-error`} className="mt-1.5 text-sm text-red-500">
<p id={`${inputId}-error`} className="mt-2 text-sm text-red-500 flex items-center gap-1.5">
<svg className="w-3.5 h-3.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
</svg>
{error}
</p>
)}
{helperText && !error && (
<p id={`${inputId}-helper`} className="mt-1.5 text-sm text-gray-500">
<p id={`${inputId}-helper`} className="mt-2 text-sm text-gray-400">
{helperText}
</p>
)}

View File

@@ -19,26 +19,26 @@ export function ProgressBar({
const clampedProgress = Math.min(100, Math.max(0, progress));
const sizes = {
sm: 'h-1.5',
md: 'h-2.5',
lg: 'h-4',
sm: 'h-1',
md: 'h-1.5',
lg: 'h-2.5',
};
const variants = {
default: 'bg-[#333d49]',
accent: 'bg-[#fe7400]',
accent: 'bg-gradient-accent',
};
return (
<div className={cn('w-full', className)}>
{showLabel && (
<div className="flex justify-between items-center mb-1.5">
<div className="flex justify-between items-center mb-2">
<span className="text-sm font-medium text-[#333d49]">Progress</span>
<span className="text-sm font-medium text-[#333d49]">{clampedProgress}%</span>
<span className="text-sm font-semibold text-[#fe7400]">{clampedProgress}%</span>
</div>
)}
<div
className={cn('w-full bg-gray-200 rounded-full overflow-hidden', sizes[size])}
className={cn('w-full bg-gray-100 rounded-full overflow-hidden', sizes[size])}
role="progressbar"
aria-valuenow={clampedProgress}
aria-valuemin={0}
@@ -48,7 +48,7 @@ export function ProgressBar({
className={cn('h-full rounded-full', variants[variant])}
initial={{ width: 0 }}
animate={{ width: `${clampedProgress}%` }}
transition={{ duration: 0.5, ease: 'easeOut' }}
transition={{ duration: 0.6, ease: [0.25, 0.46, 0.45, 0.94] }}
/>
</div>
</div>