diff --git a/app/globals.css.hbr b/app/globals.css.hbr new file mode 100644 index 0000000..9857d3f --- /dev/null +++ b/app/globals.css.hbr @@ -0,0 +1,237 @@ +@import 'tailwindcss'; + +@custom-variant dark (&:is(.dark *)); + +@theme { + /* Palette generated from the store's brand colours */ + --color-background: {{bgColor}}; + --color-foreground: {{fgColor}}; + + /* Card */ + --color-card: {{surfaceColor}}; + --color-card-foreground: {{fgColor}}; + + /* Popover */ + --color-popover: {{surfaceColor}}; + --color-popover-foreground: {{fgColor}}; + + /* Primary - the store's main brand colour */ + --color-primary: {{primaryColor}}; + --color-primary-foreground: {{primaryFgColor}}; + + /* Secondary */ + --color-secondary: {{mutedColor}}; + --color-secondary-foreground: {{fgColor}}; + + /* Muted */ + --color-muted: {{mutedColor}}; + --color-muted-foreground: {{mutedFgColor}}; + + /* Accent - the store's secondary brand colour */ + --color-accent: {{accentColor}}; + --color-accent-foreground: {{accentFgColor}}; + + /* Destructive */ + --color-destructive: hsl(0 84.2% 60.2%); + --color-destructive-foreground: hsl(0 0% 98%); + + /* Shop (accelerated checkout) purple */ + --color-shop: #5a31f4; + + /* Border */ + --color-border: {{borderColor}}; + --color-input: {{borderColor}}; + --color-ring: {{primaryColor}}; + + /* Radius - Modern larger corners */ + --radius-sm: 0.5rem; + --radius-md: 0.75rem; + --radius-lg: 1rem; + --radius-xl: 1.25rem; + + /* Typography — {{fontHeaderName}} headings / {{fontBodyName}} body. + The family variables are declared by next/font in app/layout.tsx. */ + --font-sans: var(--font-body-family), system-ui, sans-serif; + --font-mono: var(--font-mono-family), ui-monospace, SFMono-Regular, monospace; + --font-heading: var(--font-heading-family), system-ui, sans-serif; + --font-body: var(--font-body-family), system-ui, sans-serif; + --font-poppins: var(--font-heading-family), system-ui, sans-serif; +} + +/* Base styles for light, modern Shopify storefront */ +/* Tailwind v4 defaults an unqualified `border` to currentColor. shadcn + components (e.g. Button's outline variant) rely on this base layer to pick up + the theme's border colour instead of the text colour. */ +@layer base { + * { + border-color: var(--color-border); + } +} + +body { + font-feature-settings: + 'kern' 1, + 'tnum' 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +/* Modern card design for products and collections */ +.card-modern { + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + border: 1px solid var(--color-border); +} + +.card-modern:hover { + transform: translateY(-8px); + box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.1); + border-color: color-mix(in oklab, var(--color-border), {{fgColor}} 4.5%); +} + +/* Heading styles — regular weight, slightly tightened like the Geist reference */ +h1, +h2, +.font-heading { + font-family: var(--font-heading); + font-weight: 400; + letter-spacing: -0.02em; +} + +/* Swipeable rows (mobile galleries) without a visible scrollbar */ +.no-scrollbar { + scrollbar-width: none; + -ms-overflow-style: none; +} + +.no-scrollbar::-webkit-scrollbar { + display: none; +} + +/* Diagonal strike marking an unavailable product option (size pill, swatch) */ +.option-unavailable { + background-image: linear-gradient( + to top right, + transparent calc(50% - 0.5px), + currentColor calc(50% - 0.5px), + currentColor calc(50% + 0.5px), + transparent calc(50% + 0.5px) + ); +} + +/* Product description (HTML returned by the Storefront API) */ +.product-description p { + margin-bottom: 1rem; +} + +.product-description > :last-child { + margin-bottom: 0; +} + +/* Shop policy body (HTML returned by the Storefront API) */ +.policy-body p, +.policy-body ul, +.policy-body ol { + margin-bottom: 1.5rem; +} + +.policy-body ul, +.policy-body ol { + padding-left: 1.25rem; + list-style: revert; +} + +.policy-body li { + margin-bottom: 0.5rem; +} + +.policy-body h2, +.policy-body h3, +.policy-body h4 { + margin-top: 2.5rem; + margin-bottom: 1rem; + font-size: 1.25rem; + font-weight: 500; +} + +.policy-body a { + text-decoration: underline; + text-underline-offset: 2px; +} + +.policy-body strong { + font-weight: 500; +} + +.policy-body > :last-child { + margin-bottom: 0; +} + +/* Enhanced button styles */ +button, +.btn-modern { + transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); +} + +.btn-modern:hover { + transform: translateY(-1px); + box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.1), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +} + +/* Hero section styles */ +.hero-bg { + background: linear-gradient( + 135deg, + color-mix(in oklab, var(--color-muted), {{bgColor}} 50%) 0%, + var(--color-muted) 100% + ); +} + +/* Product gallery improvements */ +.product-gallery-main { + transition: box-shadow 0.3s ease; +} + +.product-gallery-main:hover { + box-shadow: 0 0 0 1px + color-mix(in oklab, var(--color-border), {{fgColor}} 10%) inset; +} + +/* Clean price display */ +.price-display { + font-feature-settings: 'tnum'; +} + +@theme inline { + --animate-rainbow: rainbow var(--speed, 2s) infinite linear; + --color-color-5: var(--color-5); + --color-color-4: var(--color-4); + --color-color-3: var(--color-3); + --color-color-2: var(--color-2); + --color-color-1: var(--color-1); + @keyframes rainbow { + 0% { + background-position: 0%; + } + 100% { + background-position: 200%; + } + } +} + +:root { + --color-1: oklch(66.2% 0.225 25.9); + --color-2: oklch(60.4% 0.26 302); + --color-3: oklch(69.6% 0.165 251); + --color-4: oklch(80.2% 0.134 225); + --color-5: oklch(90.7% 0.231 133); +} + +.dark { + --color-1: oklch(66.2% 0.225 25.9); + --color-2: oklch(60.4% 0.26 302); + --color-3: oklch(69.6% 0.165 251); + --color-4: oklch(80.2% 0.134 225); + --color-5: oklch(90.7% 0.231 133); +} diff --git a/app/layout.tsx.hbr b/app/layout.tsx.hbr new file mode 100644 index 0000000..ed535ac --- /dev/null +++ b/app/layout.tsx.hbr @@ -0,0 +1,48 @@ +import React from 'react'; +import './globals.css'; +import type { Metadata } from 'next'; +import { + {{fontHeader}}, +{{#unless sameFont}} + {{fontBody}}, +{{/unless}} + Geist_Mono, +} from 'next/font/google'; +import StoreAssistant from '@/components/shopify/store-assistant'; + +const headingFont = {{fontHeader}}({ + subsets: ['latin'], + variable: '--font-heading-family', +}); + +const bodyFont = {{fontBody}}({ + subsets: ['latin'], + variable: '--font-body-family', +}); + +const monoFont = Geist_Mono({ + subsets: ['latin'], + variable: '--font-mono-family', +}); + +export const metadata: Metadata = { + title: {{json shopName}}, +}; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + +
+ {children} +