fix the homepage pages
Build & Deploy / Build & Push Docker Image (push) Failing after 49s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Has been cancelled
Test / Admin Unit Tests (push) Has been cancelled
Test / Dashboard Unit Tests (push) Has been cancelled
Test / API Integration Tests (push) Has been cancelled
Build & Deploy / Build & Push Docker Image (push) Failing after 49s
Build & Deploy / Deploy to VPS (push) Has been skipped
Test / API Unit Tests (push) Failing after 5m4s
Test / Marketplace Unit Tests (push) Has been cancelled
Test / Admin Unit Tests (push) Has been cancelled
Test / Dashboard Unit Tests (push) Has been cancelled
Test / API Integration Tests (push) Has been cancelled
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 836 KiB |
@@ -60,12 +60,13 @@ export default async function LocaleLayout({ children, params }: LocaleLayoutPro
|
||||
dir={getDirection(locale)}
|
||||
data-theme-preference={preference}
|
||||
data-theme={resolvedTheme}
|
||||
data-scroll-behavior="smooth"
|
||||
suppressHydrationWarning
|
||||
>
|
||||
<head>
|
||||
<script
|
||||
id="theme-bootstrap"
|
||||
nonce={nonce}
|
||||
nonce={nonce || undefined}
|
||||
suppressHydrationWarning
|
||||
dangerouslySetInnerHTML={{ __html: themeBootstrapScript }}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
||||
<rect width="32" height="32" rx="8" fill="#0f172a" />
|
||||
<text
|
||||
x="16"
|
||||
y="21"
|
||||
text-anchor="middle"
|
||||
font-family="Inter, Arial, sans-serif"
|
||||
font-size="18"
|
||||
font-weight="700"
|
||||
fill="#ffffff"
|
||||
>
|
||||
R
|
||||
</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 302 B |
@@ -1,75 +1,18 @@
|
||||
'use client';
|
||||
|
||||
import { localizedPath, locales, type Locale } from '@/lib/localization/config';
|
||||
import { persistLocale } from '@/lib/localization/client';
|
||||
import { persistTheme, themePreferenceEvent } from '@/lib/theme/client';
|
||||
import { localizedPath, type Locale } from '@/lib/localization/config';
|
||||
import { type ThemePreference } from '@/lib/theme/config';
|
||||
import Image from 'next/image';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { LocalePill } from './LocalePill';
|
||||
import { ThemePill } from './ThemePill';
|
||||
import styles from './AuthHeader.module.css';
|
||||
|
||||
const langLabels: Record<Locale, string> = { en: 'EN', fr: 'FR', ar: 'AR' };
|
||||
const langFlags: Record<Locale, string> = { en: '🇺🇸', fr: '🇫🇷', ar: '🇲🇦' };
|
||||
|
||||
const themeDict: Record<Locale, Record<string, string>> = {
|
||||
en: { theme: 'Theme', light: 'Light', dark: 'Dark' },
|
||||
fr: { theme: 'Mode', light: 'Clair', dark: 'Sombre' },
|
||||
ar: { theme: 'الوضع', light: 'فاتح', dark: 'داكن' },
|
||||
};
|
||||
|
||||
interface Props {
|
||||
locale: Locale;
|
||||
themePreference: ThemePreference;
|
||||
}
|
||||
|
||||
export function AuthHeader({ locale, themePreference: initialPref }: Props) {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
const [pref, setPref] = useState<ThemePreference>(initialPref);
|
||||
|
||||
const t = themeDict[locale] ?? themeDict.en;
|
||||
const themeLabel = pref === 'dark' ? t.dark : t.light;
|
||||
|
||||
const localeMenuRef = useRef<HTMLDivElement | null>(null);
|
||||
const [localeOpen, setLocaleOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setPref(initialPref);
|
||||
}, [initialPref]);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = () => {
|
||||
const stored = localStorage.getItem('hpc.theme.preference');
|
||||
if (stored === 'light' || stored === 'dark' || stored === 'system') setPref(stored);
|
||||
};
|
||||
window.addEventListener(themePreferenceEvent, handler);
|
||||
return () => window.removeEventListener(themePreferenceEvent, handler);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function handleClick(e: MouseEvent) {
|
||||
if (!localeMenuRef.current?.contains(e.target as Node)) setLocaleOpen(false);
|
||||
}
|
||||
document.addEventListener('mousedown', handleClick);
|
||||
return () => document.removeEventListener('mousedown', handleClick);
|
||||
}, []);
|
||||
|
||||
const cycleTheme = () => {
|
||||
const next = pref === 'dark' ? 'light' : 'dark';
|
||||
persistTheme(next);
|
||||
setPref(next);
|
||||
};
|
||||
|
||||
const switchLocale = (next: Locale) => {
|
||||
setLocaleOpen(false);
|
||||
persistLocale(next);
|
||||
const segments = pathname.split('/').filter(Boolean);
|
||||
if (segments.length >= 2) segments[1] = next;
|
||||
router.push('/' + segments.join('/'));
|
||||
};
|
||||
|
||||
const otherLocales = locales.filter((l) => l !== locale);
|
||||
export function AuthHeader({ locale, themePreference }: Props) {
|
||||
const homePath = localizedPath('home', locale);
|
||||
|
||||
return (
|
||||
@@ -92,54 +35,11 @@ export function AuthHeader({ locale, themePreference: initialPref }: Props) {
|
||||
|
||||
<div className={styles.controls}>
|
||||
<div className={styles.pill}>
|
||||
<div ref={localeMenuRef} className={styles.localeMenuWrap}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setLocaleOpen((v) => !v)}
|
||||
className={styles.localeBtn}
|
||||
aria-expanded={localeOpen}
|
||||
aria-haspopup="menu"
|
||||
>
|
||||
<span aria-hidden="true">{langFlags[locale]}</span>
|
||||
<span>{langLabels[locale]}</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`${styles.chevron} ${localeOpen ? styles.chevronOpen : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
{localeOpen && (
|
||||
<div className={styles.localeMenu}>
|
||||
{otherLocales.map((l) => (
|
||||
<button
|
||||
key={l}
|
||||
type="button"
|
||||
onClick={() => switchLocale(l)}
|
||||
className={styles.localeOption}
|
||||
>
|
||||
<span aria-hidden="true">{langFlags[l]}</span>
|
||||
<span>{langLabels[l]}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<LocalePill locale={locale} />
|
||||
|
||||
<span className={styles.divider} aria-hidden="true" />
|
||||
|
||||
<button
|
||||
type="button"
|
||||
onClick={cycleTheme}
|
||||
className={styles.themeBtn}
|
||||
aria-label={themeLabel}
|
||||
>
|
||||
<span className={styles.themeLabel}>{themeLabel}</span>
|
||||
</button>
|
||||
<ThemePill initialPreference={themePreference} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
.wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
min-width: 4.75rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.375rem;
|
||||
border-radius: 999px;
|
||||
padding: 0.375rem 0.625rem;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #44403c;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #f5f5f4;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .button {
|
||||
color: #e7e5e4;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .button:hover {
|
||||
background: rgb(30 58 138 / 0.4);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.button {
|
||||
min-width: 5.25rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.chevron {
|
||||
width: 0.875rem;
|
||||
height: 0.875rem;
|
||||
transition: transform 0.15s;
|
||||
}
|
||||
|
||||
.chevronOpen {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
z-index: 30;
|
||||
margin-top: 0.5rem;
|
||||
width: 12rem;
|
||||
max-width: calc(100vw - 2rem);
|
||||
overflow: hidden;
|
||||
border-radius: 1rem;
|
||||
border: 1px solid #e7e5e4;
|
||||
background: rgb(255 255 255 / 0.95);
|
||||
text-align: left;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12);
|
||||
backdrop-filter: blur(16px);
|
||||
left: 0;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.menu {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .menu {
|
||||
border-color: #1e3a8a;
|
||||
background: rgb(23 37 84 / 0.95);
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.option {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
color: #44403c;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: #f5f5f4;
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .option {
|
||||
color: #e7e5e4;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .option:hover {
|
||||
background: rgb(30 58 138 / 0.4);
|
||||
color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
'use client';
|
||||
|
||||
import { persistLocale } from '@/lib/localization/client';
|
||||
import {
|
||||
localeSwitchUrl,
|
||||
locales,
|
||||
routeIdFromPathname,
|
||||
type Locale,
|
||||
} from '@/lib/localization/config';
|
||||
import { usePathname, useRouter } from 'next/navigation';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import styles from './LocalePill.module.css';
|
||||
|
||||
const langLabels: Record<Locale, string> = { en: 'EN', fr: 'FR', ar: 'AR' };
|
||||
const langFlags: Record<Locale, string> = { en: '🇺🇸', fr: '🇫🇷', ar: '🇲🇦' };
|
||||
|
||||
interface Props {
|
||||
locale: Locale;
|
||||
}
|
||||
|
||||
export function LocalePill({ locale }: Props) {
|
||||
const pathname = usePathname();
|
||||
const router = useRouter();
|
||||
const menuRef = useRef<HTMLDivElement | null>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
function handleClick(e: MouseEvent) {
|
||||
if (!menuRef.current?.contains(e.target as Node)) setOpen(false);
|
||||
}
|
||||
document.addEventListener('mousedown', handleClick);
|
||||
return () => document.removeEventListener('mousedown', handleClick);
|
||||
}, []);
|
||||
|
||||
const switchLocale = (next: Locale) => {
|
||||
setOpen(false);
|
||||
persistLocale(next);
|
||||
const routeId = routeIdFromPathname(pathname) ?? 'home';
|
||||
router.push(
|
||||
localeSwitchUrl(new URL(window.location.href), next, routeId).pathname +
|
||||
new URL(window.location.href).search +
|
||||
new URL(window.location.href).hash,
|
||||
);
|
||||
};
|
||||
|
||||
const otherLocales = locales.filter((l) => l !== locale);
|
||||
|
||||
return (
|
||||
<div ref={menuRef} className={styles.wrap}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className={styles.button}
|
||||
aria-expanded={open}
|
||||
aria-haspopup="menu"
|
||||
>
|
||||
<span aria-hidden="true">{langFlags[locale]}</span>
|
||||
<span>{langLabels[locale]}</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`${styles.chevron} ${open ? styles.chevronOpen : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
{open && (
|
||||
<div className={styles.menu}>
|
||||
{otherLocales.map((l) => (
|
||||
<button
|
||||
key={l}
|
||||
type="button"
|
||||
onClick={() => switchLocale(l)}
|
||||
className={styles.option}
|
||||
>
|
||||
<span aria-hidden="true">{langFlags[l]}</span>
|
||||
<span>{langLabels[l]}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -5,10 +5,10 @@ import { ActionLink } from '@/components/actions/ActionLink';
|
||||
import { accountCreateUrl } from '@/lib/account-urls';
|
||||
import { BrandLink } from './BrandLink';
|
||||
import { HeaderNavigation } from './HeaderNavigation';
|
||||
import { LocaleSelector } from './LocaleSelector';
|
||||
import { LocalePill } from './LocalePill';
|
||||
import { MobileNavigation } from './MobileNavigation';
|
||||
import styles from './SiteHeader.module.css';
|
||||
import { ThemeSelector } from './ThemeSelector';
|
||||
import { ThemePill } from './ThemePill';
|
||||
|
||||
function signInUrl(locale: Locale): string {
|
||||
return localizedPath('sign-in', locale);
|
||||
@@ -39,19 +39,8 @@ export function SiteHeader({ locale, messages, themePreference }: SiteHeaderProp
|
||||
role="group"
|
||||
aria-label={messages.header.controlsLabel}
|
||||
>
|
||||
<LocaleSelector
|
||||
currentLocale={locale}
|
||||
label={messages.controls.language}
|
||||
localeNames={messages.controls.localeNames}
|
||||
compact
|
||||
/>
|
||||
<ThemeSelector
|
||||
initialPreference={themePreference}
|
||||
label={messages.controls.theme}
|
||||
statusTemplate={messages.controls.themeStatus}
|
||||
optionLabels={messages.controls.themes}
|
||||
compact
|
||||
/>
|
||||
<LocalePill locale={locale} />
|
||||
<ThemePill initialPreference={themePreference} />
|
||||
<ActionLink href={signInUrl(locale)} variant="button-primary">
|
||||
{messages.header.login}
|
||||
</ActionLink>
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
.wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 0.375rem;
|
||||
border-radius: 999px;
|
||||
padding: 0.25rem 0.5rem;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
background: #f5f5f4;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .button:hover {
|
||||
background: rgb(30 58 138 / 0.4);
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.button {
|
||||
padding: 0.375rem 0.625rem;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
border-radius: 999px;
|
||||
background: #1e3a8a;
|
||||
padding: 0.25rem 0.75rem;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .label {
|
||||
background: #fb923c;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
.label {
|
||||
padding: 0.375rem 0.875rem;
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.chevron {
|
||||
width: 0.875rem;
|
||||
height: 0.875rem;
|
||||
color: #78716c;
|
||||
transition: transform 0.15s;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .chevron {
|
||||
color: #a8a29e;
|
||||
}
|
||||
|
||||
.chevronOpen {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
z-index: 30;
|
||||
right: 0;
|
||||
margin-top: 0.5rem;
|
||||
width: 11rem;
|
||||
max-width: calc(100vw - 2rem);
|
||||
overflow: hidden;
|
||||
border-radius: 1rem;
|
||||
border: 1px solid #e7e5e4;
|
||||
background: rgb(255 255 255 / 0.95);
|
||||
text-align: left;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.12);
|
||||
backdrop-filter: blur(16px);
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .menu {
|
||||
border-color: #1e3a8a;
|
||||
background: rgb(23 37 84 / 0.95);
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.option {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 0.875rem;
|
||||
color: #44403c;
|
||||
background: transparent;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
}
|
||||
|
||||
.option:hover {
|
||||
background: #f5f5f4;
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .option {
|
||||
color: #e7e5e4;
|
||||
}
|
||||
|
||||
:global(html[data-theme='dark']) .option:hover {
|
||||
background: rgb(30 58 138 / 0.4);
|
||||
color: #fff;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
'use client';
|
||||
|
||||
import { persistTheme, themePreferenceEvent } from '@/lib/theme/client';
|
||||
import { type ThemePreference } from '@/lib/theme/config';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import styles from './ThemePill.module.css';
|
||||
|
||||
interface Props {
|
||||
initialPreference: ThemePreference;
|
||||
}
|
||||
|
||||
const labels: Record<ThemePreference, string> = {
|
||||
light: 'Light',
|
||||
dark: 'Dark',
|
||||
system: 'System',
|
||||
};
|
||||
|
||||
export function ThemePill({ initialPreference }: Props) {
|
||||
const [pref, setPref] = useState<ThemePreference>(initialPreference);
|
||||
const menuRef = useRef<HTMLDivElement | null>(null);
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setPref(initialPreference);
|
||||
}, [initialPreference]);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = () => {
|
||||
const stored = localStorage.getItem('hpc.theme.preference');
|
||||
if (stored === 'light' || stored === 'dark' || stored === 'system') setPref(stored);
|
||||
};
|
||||
window.addEventListener(themePreferenceEvent, handler);
|
||||
return () => window.removeEventListener(themePreferenceEvent, handler);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
function handleClick(e: MouseEvent) {
|
||||
if (!menuRef.current?.contains(e.target as Node)) setOpen(false);
|
||||
}
|
||||
document.addEventListener('mousedown', handleClick);
|
||||
return () => document.removeEventListener('mousedown', handleClick);
|
||||
}, []);
|
||||
|
||||
const selectTheme = (next: ThemePreference) => {
|
||||
setOpen(false);
|
||||
persistTheme(next);
|
||||
setPref(next);
|
||||
};
|
||||
|
||||
const options: ThemePreference[] = ['light', 'dark', 'system'];
|
||||
const otherOptions = options.filter((o) => o !== pref);
|
||||
|
||||
const displayLabel = pref === 'dark' ? 'Dark' : 'Light';
|
||||
|
||||
return (
|
||||
<div ref={menuRef} className={styles.wrap}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
className={styles.button}
|
||||
aria-expanded={open}
|
||||
aria-haspopup="menu"
|
||||
aria-label={displayLabel}
|
||||
>
|
||||
<span className={styles.label}>{displayLabel}</span>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={`${styles.chevron} ${open ? styles.chevronOpen : ''}`}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
strokeWidth={2}
|
||||
>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19 9l-7 7-7-7" />
|
||||
</svg>
|
||||
</button>
|
||||
{open && (
|
||||
<div className={styles.menu}>
|
||||
{otherOptions.map((o) => (
|
||||
<button
|
||||
key={o}
|
||||
type="button"
|
||||
onClick={() => selectTheme(o)}
|
||||
className={styles.option}
|
||||
>
|
||||
<span>{labels[o]}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
.brandImage {
|
||||
object-fit: contain;
|
||||
background: var(--surface-page);
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
.heroGrid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1.02fr) minmax(22rem, 0.98fr);
|
||||
grid-template-columns: minmax(0, 1fr) minmax(26rem, 1.15fr);
|
||||
align-items: center;
|
||||
gap: clamp(var(--space-10), 7vw, var(--space-20));
|
||||
}
|
||||
@@ -53,11 +53,10 @@
|
||||
.previewStage {
|
||||
position: relative;
|
||||
min-inline-size: 0;
|
||||
padding: clamp(var(--space-3), 2.5vw, var(--space-6));
|
||||
padding: clamp(var(--space-4), 3vw, var(--space-8));
|
||||
}
|
||||
|
||||
.previewStage::before,
|
||||
.previewStage::after {
|
||||
.previewStage::before {
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
border-radius: var(--radius-md);
|
||||
@@ -70,17 +69,9 @@
|
||||
transform: rotate(-2deg);
|
||||
}
|
||||
|
||||
.previewStage::after {
|
||||
inset-block-start: 8%;
|
||||
inset-inline: 8%;
|
||||
block-size: 88%;
|
||||
border: 1px solid var(--border-strong);
|
||||
transform: rotate(2deg);
|
||||
}
|
||||
|
||||
@media (max-width: 1023px) {
|
||||
.heroGrid {
|
||||
grid-template-columns: minmax(0, 1fr) minmax(18rem, 0.9fr);
|
||||
grid-template-columns: minmax(0, 1fr) minmax(21rem, 1.05fr);
|
||||
gap: var(--space-10);
|
||||
}
|
||||
}
|
||||
@@ -103,8 +94,7 @@
|
||||
padding-inline: 0;
|
||||
}
|
||||
|
||||
.previewStage::before,
|
||||
.previewStage::after {
|
||||
.previewStage::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -116,15 +106,13 @@
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.previewStage::before,
|
||||
.previewStage::after {
|
||||
.previewStage::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.previewStage::before,
|
||||
.previewStage::after {
|
||||
.previewStage::before {
|
||||
transform: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ export function buildHomepageContent(
|
||||
image: localizedImage(
|
||||
'rentaldrivego',
|
||||
locale,
|
||||
'jpeg',
|
||||
'png',
|
||||
{ width: 1220, height: 1167 },
|
||||
'RentalDriveGo',
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user