Replace all hardcoded brand color hex values with CSS custom properties
so BrandingContext drives both the customer portal and staff site.
- index.css: add derived accent/primary vars using color-mix()
(--color-accent-hover, --color-accent-dark, --color-accent-light,
--color-accent-lighter, --color-primary-dark); fix focus ring styles
to use var(--color-primary) instead of hardcoded hex
- BrandingContext.tsx: also update <meta name="theme-color"> in sync
with primaryColor so PWA theme-color tracks branding at runtime
- portal/sections: replace bg-[#8b7355], text-[#6b5a42], bg-[#f0ebe4],
bg-[#faf5ef], hover:bg-[#7a6549] etc. with Tailwind v4 CSS var
utilities (bg-(--color-accent), text-(--color-accent-dark), etc.)
- pages: replace inline style "#4f8a6f"/"#3d7a5f" with
var(--color-primary) / var(--color-primary-dark) across Appointments,
Book, Clients, GroupBooking, Invoices, Reports, Services, Staff, and
DevSessionIndicator
Closes#91
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* feat: add customizable business branding (name, logo, colors)
Add admin settings for business branding with name, logo upload, and
color scheme via CSS custom properties. Includes database migration,
API endpoints, admin settings page, and dynamic branding in both
admin nav and customer portal.
Closes#61
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address review feedback on branding PR
- Replace dynamic import with static import for @groombook/db in public branding endpoint
- Restore active nav item background highlight (bg-stone-100) in CustomerPortal
- Remove non-null assertion in settings route, add proper error handling
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: trigger CI
* fix: resolve lint error and test failure for branding feature
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update E2E tests for branding changes
- Update navigation test to expect "GroomBook" (default branding) instead
of hardcoded "Paws & Reflect" since CustomerPortal now uses dynamic branding
- Add /api/branding mock to shared E2E fixtures so BrandingProvider resolves
immediately in all tests, preventing unhandled fetch interference
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: GroomBook CTO <cto@groombook.dev>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: GroomBook CTO <cto@groombook.app>
* Improve admin UI visual design — polish look and feel
- Sticky nav bar with subtle shadow, branded GroomBook wordmark, green gradient Book button
- Consistent brand green (#4f8a6f) for primary buttons across all admin pages
- Tables wrapped in white cards with rounded corners and soft shadows
- Uppercase table headers with better spacing and hierarchy
- Input/button border-radius increased to 6px for softer feel
- Global CSS: button transitions, input focus states with brand green ring, subtle card shadows
- Background changed from plain white to light gray (#f0f2f5) for depth
- Reports: polished stat cards with shadows, refined section headers, card-wrapped tables
- Custom scrollbar styling for a cleaner look
Closesgroombook/groombook#58
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* Fix test selectors for branded nav text
- Use regex /Groom\s*Book/ to match split-element brand text
- Use getByRole("link") for Book CTA to avoid matching brand <strong>
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* Fix brand text test to handle split-element rendering
The nav brand was changed to <span>Groom</span>Book for color styling,
but getByText with a regex can't match text split across child elements.
Use a custom text matcher that checks the STRONG element's textContent.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
* Fix E2E tests for split-element brand name
The brand is now <span>Groom</span>Book (no space), so Playwright's
getByText needs "GroomBook" instead of "Groom Book".
Co-Authored-By: Paperclip <noreply@paperclip.ing>
---------
Co-authored-by: Groom Book CTO <cto@groombook.dev>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Groom Book CTO <cto@groombook.app>
Sets up the initial project structure for groombook/groombook:
- pnpm monorepo with apps/api (Hono + TypeScript), apps/web (React + Vite + PWA), packages/db (Drizzle ORM), packages/types (shared types)
- Core DB schema: clients, pets, services, appointments, staff with CNPG-compatible Postgres
- REST API routes for clients, pets, services, appointments with Zod validation
- OIDC auth middleware for Authentik integration
- React PWA with vite-plugin-pwa, service worker, offline caching, installable manifest
- GitHub Actions CI: lint, typecheck, test, build, Docker image build (groombook-runners)
- Dockerfiles for API (Node.js) and Web (nginx)
- docker-compose.yml for local development
Co-Authored-By: Paperclip <noreply@paperclip.ing>