Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4a8b351772 | |||
| 875fdd4c97 | |||
| 10e94075af | |||
| 270f4205a8 | |||
| 127fec21f3 | |||
| f36df32471 |
@@ -5,34 +5,25 @@ import { Open_Sans } from "next/font/google";
|
||||
import "./globals.css";
|
||||
import { ServiceWrapper } from "@/components/ServiceWrapper";
|
||||
import Tag from "@/tag/Tag";
|
||||
import { Montserrat } from "next/font/google";
|
||||
|
||||
const halant = Halant({
|
||||
variable: "--font-halant", subsets: ["latin"],
|
||||
weight: ["300", "400", "500", "600", "700"],
|
||||
});
|
||||
|
||||
const inter = Inter({
|
||||
variable: "--font-inter", subsets: ["latin"],
|
||||
});
|
||||
|
||||
const openSans = Open_Sans({
|
||||
variable: "--font-open-sans", subsets: ["latin"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Proof Digital - Award-Winning Digital Agency", description: "Transform your digital vision into reality with Proof Digital. We deliver strategic design, development, and marketing solutions for ambitious brands.", keywords: "digital agency, web design, development, digital marketing, UX design, brand strategy", metadataBase: new URL("https://proofdigital.com"),
|
||||
title: "Draco Digital - Award-Winning Digital Agency", description: "Transform your digital vision into reality with Draco Digital. We deliver strategic design, development, and marketing solutions for ambitious brands.", keywords: "digital agency, web design, development, digital marketing, UX design, brand strategy", metadataBase: new URL("https://dracodigital.com"),
|
||||
alternates: {
|
||||
canonical: "https://proofdigital.com"
|
||||
canonical: "https://dracodigital.com"
|
||||
},
|
||||
openGraph: {
|
||||
title: "Proof Digital - Award-Winning Digital Agency", description: "Strategic design & development for digital transformation", url: "https://proofdigital.com", siteName: "Proof Digital", type: "website", images: [
|
||||
title: "Draco Digital - Award-Winning Digital Agency", description: "Strategic design & development for digital transformation", url: "https://dracodigital.com", siteName: "Draco Digital", type: "website", images: [
|
||||
{
|
||||
url: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AQFKBKtzUE9UtHpu5cFGLuPTXL/a-modern-sleek-digital-agency-dashboard--1772516969990-f3574ef1.png", alt: "Proof Digital Hero Dashboard"
|
||||
url: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AQFKBKtzUE9UtHpu5cFGLuPTXL/a-modern-sleek-digital-agency-dashboard--1772516969990-f3574ef1.png", alt: "Draco Digital Hero Dashboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image", title: "Proof Digital - Award-Winning Digital Agency", description: "Strategic design & development for digital transformation", images: ["https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AQFKBKtzUE9UtHpu5cFGLuPTXL/a-modern-sleek-digital-agency-dashboard--1772516969990-f3574ef1.png"]
|
||||
card: "summary_large_image", title: "Draco Digital - Award-Winning Digital Agency", description: "Strategic design & development for digital transformation", images: ["https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AQFKBKtzUE9UtHpu5cFGLuPTXL/a-modern-sleek-digital-agency-dashboard--1772516969990-f3574ef1.png"]
|
||||
},
|
||||
robots: {
|
||||
index: true,
|
||||
@@ -40,6 +31,15 @@ export const metadata: Metadata = {
|
||||
}
|
||||
};
|
||||
|
||||
const montserrat = Montserrat({
|
||||
variable: "--font-montserrat",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
const inter = Inter({
|
||||
variable: "--font-inter",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
@@ -48,9 +48,7 @@ export default function RootLayout({
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<ServiceWrapper>
|
||||
<body
|
||||
className={`${halant.variable} ${inter.variable} ${openSans.variable} antialiased`}
|
||||
>
|
||||
<body className={`${montserrat.variable} ${inter.variable} antialiased`}>
|
||||
<Tag />
|
||||
{children}
|
||||
|
||||
@@ -295,9 +293,7 @@ export default function RootLayout({
|
||||
const getElementInfo = (element, assignId = false) => {
|
||||
const rect = element.getBoundingClientRect();
|
||||
const tagName = element.tagName.toLowerCase();
|
||||
const selector = getUniqueSelector(element, assignId);
|
||||
const sectionId = getSectionId(element);
|
||||
|
||||
|
||||
let className = undefined;
|
||||
try {
|
||||
if (element.className) {
|
||||
@@ -325,8 +321,7 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
if (tagName === 'img') {
|
||||
const originalSrc = extractOriginalUrl(element.src);
|
||||
info.imageData = {
|
||||
info.imageData = {
|
||||
src: originalSrc,
|
||||
alt: element.alt || undefined,
|
||||
naturalWidth: element.naturalWidth,
|
||||
@@ -337,8 +332,7 @@ export default function RootLayout({
|
||||
|
||||
if (tagName === 'video') {
|
||||
const rawSrc = element.src || element.currentSrc || (element.querySelector('source') && element.querySelector('source').src) || '';
|
||||
const resolvedSrc = extractOriginalUrl(rawSrc);
|
||||
info.imageData = {
|
||||
info.imageData = {
|
||||
src: resolvedSrc,
|
||||
alt: element.getAttribute('aria-label') || undefined,
|
||||
isBackground: false,
|
||||
@@ -351,8 +345,7 @@ export default function RootLayout({
|
||||
if (backgroundImage && backgroundImage !== 'none') {
|
||||
const urlMatch = backgroundImage.match(/url(['"]?([^'")]+)['"]?)/);
|
||||
if (urlMatch) {
|
||||
const originalBgSrc = extractOriginalUrl(urlMatch[1]);
|
||||
if (tagName !== 'img') {
|
||||
if (tagName !== 'img') {
|
||||
info.imageData = {
|
||||
src: originalBgSrc,
|
||||
isBackground: true
|
||||
@@ -364,8 +357,7 @@ export default function RootLayout({
|
||||
}
|
||||
}
|
||||
|
||||
const elementType = getElementType(element);
|
||||
info.elementType = elementType;
|
||||
info.elementType = elementType;
|
||||
|
||||
if (elementType === 'Button') {
|
||||
const buttonText = element.textContent?.trim() || element.value || element.getAttribute('aria-label') || '';
|
||||
@@ -458,13 +450,11 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
const isTextElement = (element) => {
|
||||
const elementType = getElementType(element);
|
||||
return elementType === 'Text';
|
||||
return elementType === 'Text';
|
||||
};
|
||||
|
||||
const isButtonElement = (element) => {
|
||||
const elementType = getElementType(element);
|
||||
return elementType === 'Button';
|
||||
return elementType === 'Button';
|
||||
};
|
||||
|
||||
const updateButtonText = (element, newText) => {
|
||||
@@ -539,8 +529,7 @@ export default function RootLayout({
|
||||
};
|
||||
|
||||
const handleInput = () => {
|
||||
const elementInfo = getElementInfo(element);
|
||||
let currentText = element.textContent;
|
||||
let currentText = element.textContent;
|
||||
|
||||
// Ensure there's always at least a space to keep the element editable
|
||||
if (currentText === '' || currentText === null || currentText.length === 0) {
|
||||
@@ -653,8 +642,7 @@ export default function RootLayout({
|
||||
}, '*');
|
||||
|
||||
if (save && originalContent !== element.textContent) {
|
||||
const elementInfo = getElementInfo(element);
|
||||
let finalText = element.textContent;
|
||||
let finalText = element.textContent;
|
||||
|
||||
// Trim the final text and convert space-only to empty string for saving
|
||||
if (finalText === ' ' || finalText.trim() === '') {
|
||||
@@ -783,7 +771,7 @@ export default function RootLayout({
|
||||
lastMouseX = e.clientX;
|
||||
lastMouseY = e.clientY;
|
||||
|
||||
const target = getMostSpecificElement(e.clientX, e.clientY) || e.target;
|
||||
|| e.target;
|
||||
|
||||
if (!isValidElement(target) || target === hoveredElement || target === selectedElement) {
|
||||
return;
|
||||
@@ -815,8 +803,7 @@ export default function RootLayout({
|
||||
hoverOverlay = createHoverOverlay(target);
|
||||
}
|
||||
|
||||
const elementType = getElementType(target);
|
||||
showElementTypeLabel(target, elementType);
|
||||
showElementTypeLabel(target, elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'webild-element-hover',
|
||||
@@ -858,7 +845,7 @@ export default function RootLayout({
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const target = getMostSpecificElement(e.clientX, e.clientY) || e.target;
|
||||
|| e.target;
|
||||
if (!isValidElement(target)) return;
|
||||
|
||||
if (selectedElement && selectedElement !== target) {
|
||||
@@ -903,8 +890,7 @@ export default function RootLayout({
|
||||
hoveredElement = null;
|
||||
}
|
||||
|
||||
const elementInfo = getElementInfo(target, true);
|
||||
selectedElement.dataset.webildSelector = elementInfo.selector;
|
||||
selectedElement.dataset.webildSelector = elementInfo.selector;
|
||||
showElementTypeLabel(target, elementInfo.elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
@@ -987,8 +973,7 @@ export default function RootLayout({
|
||||
isScrolling = false;
|
||||
|
||||
if (lastMouseX > 0 && lastMouseY > 0) {
|
||||
const target = getMostSpecificElement(lastMouseX, lastMouseY);
|
||||
if (target && isValidElement(target) && target !== selectedElement) {
|
||||
if (target && isValidElement(target) && target !== selectedElement) {
|
||||
hoveredElement = target;
|
||||
|
||||
const computedStyle = window.getComputedStyle(target);
|
||||
@@ -1002,8 +987,7 @@ export default function RootLayout({
|
||||
hoveredElement.classList.add(hoverClass);
|
||||
hoverOverlay = createHoverOverlay(target);
|
||||
|
||||
const elementType = getElementType(target);
|
||||
showElementTypeLabel(target, elementType);
|
||||
showElementTypeLabel(target, elementType);
|
||||
|
||||
window.parent.postMessage({
|
||||
type: 'webild-element-hover',
|
||||
@@ -1026,8 +1010,7 @@ export default function RootLayout({
|
||||
|
||||
const saveChangeToStorage = (change) => {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]');
|
||||
const existingChanges = JSON.parse(localStorage.getItem(storageKey) || '[]');
|
||||
|
||||
const filteredChanges = existingChanges.filter(c => {
|
||||
return !(c.oldValue === change.oldValue && c.sectionId === change.sectionId);
|
||||
@@ -1047,8 +1030,7 @@ export default function RootLayout({
|
||||
|
||||
const clearLocalChanges = () => {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
localStorage.removeItem(storageKey);
|
||||
localStorage.removeItem(storageKey);
|
||||
window.parent.postMessage({
|
||||
type: 'webild-local-changes-cleared',
|
||||
data: {}
|
||||
@@ -1097,8 +1079,7 @@ export default function RootLayout({
|
||||
|
||||
if (e.data.type === 'webild-cancel-changes') {
|
||||
try {
|
||||
const storageKey = getStorageKey();
|
||||
const savedChanges = localStorage.getItem(storageKey);
|
||||
const savedChanges = localStorage.getItem(storageKey);
|
||||
if (savedChanges) {
|
||||
const changes = JSON.parse(savedChanges);
|
||||
changes.forEach(change => {
|
||||
@@ -1120,8 +1101,7 @@ export default function RootLayout({
|
||||
if (isBackground) {
|
||||
element.style.backgroundImage = change.oldValue ? 'url(' + change.oldValue + ')' : '';
|
||||
} else {
|
||||
const oldMediaType = getMediaTypeFromUrl(change.oldValue);
|
||||
if (revertTag === 'video' && oldMediaType === 'image') {
|
||||
if (revertTag === 'video' && oldMediaType === 'image') {
|
||||
swapMediaElement(element, 'img', change.oldValue);
|
||||
} else if (revertTag === 'img' && oldMediaType === 'video') {
|
||||
swapMediaElement(element, 'video', change.oldValue);
|
||||
@@ -1169,8 +1149,7 @@ export default function RootLayout({
|
||||
const el = textElements[i];
|
||||
if (isTextElement(el) && el.textContent.trim() === (oldValue || '').trim()) {
|
||||
element = el;
|
||||
const newSelector = getUniqueSelector(element, true);
|
||||
if (newSelector) {
|
||||
if (newSelector) {
|
||||
element.dataset.webildSelector = newSelector;
|
||||
}
|
||||
break;
|
||||
@@ -1261,10 +1240,8 @@ export default function RootLayout({
|
||||
replaced = true;
|
||||
} else if (element.tagName.toLowerCase() === 'img') {
|
||||
oldValue = element.src;
|
||||
const newMediaType = getMediaTypeFromUrl(newSrc);
|
||||
if (newMediaType === 'video' && allowMediaTypeSwap) {
|
||||
const swapped = swapMediaElement(element, 'video', newSrc);
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
if (newMediaType === 'video' && allowMediaTypeSwap) {
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
element = swapped;
|
||||
} else {
|
||||
element.src = newSrc;
|
||||
@@ -1272,11 +1249,9 @@ export default function RootLayout({
|
||||
replaced = true;
|
||||
} else if (element.tagName.toLowerCase() === 'video') {
|
||||
oldValue = element.src || element.currentSrc || '';
|
||||
const newMediaType = getMediaTypeFromUrl(newSrc);
|
||||
const sources = element.querySelectorAll('source');
|
||||
const sources = element.querySelectorAll('source');
|
||||
if (newMediaType === 'image' && allowMediaTypeSwap) {
|
||||
const swapped = swapMediaElement(element, 'img', newSrc);
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
if (selectedElement === element) selectedElement = swapped;
|
||||
element = swapped;
|
||||
} else {
|
||||
if (sources.length > 0) {
|
||||
@@ -1298,8 +1273,7 @@ export default function RootLayout({
|
||||
}
|
||||
|
||||
if (replaced) {
|
||||
const elementInfo = getElementInfo(element);
|
||||
|
||||
|
||||
let cleanOldValue = oldValue;
|
||||
if (oldValue.includes('url(')) {
|
||||
const urlMatch = oldValue.match(/url(['"]?([^'")]+)['"]?)/);
|
||||
@@ -1370,13 +1344,7 @@ export default function RootLayout({
|
||||
}
|
||||
}, true);
|
||||
|
||||
const urlCheckInterval = setInterval(() => {
|
||||
if (lastPathname !== window.location.pathname) {
|
||||
lastPathname = window.location.pathname;
|
||||
notifyPageChange();
|
||||
}
|
||||
}, 500);
|
||||
|
||||
|
||||
notifyPageChange();
|
||||
|
||||
window.webildCleanup = () => {
|
||||
|
||||
@@ -28,7 +28,7 @@ export default function LandingPage() {
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="Proof Digital"
|
||||
brandName="Draco Digital"
|
||||
navItems={[
|
||||
{ name: "Services", id: "services" },
|
||||
{ name: "Our Work", id: "work" },
|
||||
@@ -52,7 +52,7 @@ export default function LandingPage() {
|
||||
buttonAnimation="slide-up"
|
||||
background={{ variant: "glowing-orb" }}
|
||||
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AQFKBKtzUE9UtHpu5cFGLuPTXL/a-modern-sleek-digital-agency-dashboard--1772516969990-f3574ef1.png"
|
||||
imageAlt="Proof Digital dashboard interface"
|
||||
imageAlt="Draco Digital dashboard interface"
|
||||
imagePosition="right"
|
||||
mediaAnimation="slide-up"
|
||||
fixedMediaHeight={true}
|
||||
@@ -61,9 +61,9 @@ export default function LandingPage() {
|
||||
|
||||
<div id="about" data-section="about">
|
||||
<TextSplitAbout
|
||||
title="About Proof Digital"
|
||||
title="About Draco Digital"
|
||||
description={[
|
||||
"At Proof Digital, we believe exceptional design and strategic thinking are the foundation of digital success. Our multidisciplinary team combines creativity, technology, and business acumen to deliver transformative solutions.", "With over a decade of experience, we've helped hundreds of brands across industries achieve their goals through intelligent digital strategy, beautiful design, and robust development. We're committed to understanding your unique challenges and crafting solutions that truly work.", "Our approach is collaborative, transparent, and results-driven. We don't just build websites—we build partnerships that drive measurable business impact."
|
||||
"At Draco Digital, we believe exceptional design and strategic thinking are the foundation of digital success. Our multidisciplinary team combines creativity, technology, and business acumen to deliver transformative solutions.", "With over a decade of experience, we've helped hundreds of brands across industries achieve their goals through intelligent digital strategy, beautiful design, and robust development. We're committed to understanding your unique challenges and crafting solutions that truly work.", "Our approach is collaborative, transparent, and results-driven. We don't just build websites—we build partnerships that drive measurable business impact."
|
||||
]}
|
||||
buttons={[{ text: "Learn More", href: "services" }]}
|
||||
showBorder={false}
|
||||
@@ -185,7 +185,7 @@ export default function LandingPage() {
|
||||
}
|
||||
]}
|
||||
imageSrc="https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3AQFKBKtzUE9UtHpu5cFGLuPTXL/professional-customer-support-team-worki-1772516970613-7862134b.png"
|
||||
imageAlt="Proof Digital support team"
|
||||
imageAlt="Draco Digital support team"
|
||||
mediaAnimation="slide-up"
|
||||
mediaPosition="left"
|
||||
faqsAnimation="slide-up"
|
||||
@@ -198,8 +198,8 @@ export default function LandingPage() {
|
||||
<div id="contact" data-section="contact">
|
||||
<ContactFaq
|
||||
ctaTitle="Ready to Transform Your Digital Presence?"
|
||||
ctaDescription="Let's discuss how Proof Digital can help you achieve your business goals through strategic digital solutions."
|
||||
ctaButton={{ text: "Schedule a Consultation", href: "https://calendly.com" }}
|
||||
ctaDescription="Let's discuss how Draco Digital can help you achieve your business goals through strategic digital solutions."
|
||||
ctaButton={{ text: "Book Your Free Consultation Call", href: "https://calendly.com" }}
|
||||
ctaIcon={Phone}
|
||||
faqs={[
|
||||
{
|
||||
@@ -219,8 +219,8 @@ export default function LandingPage() {
|
||||
|
||||
<div id="footer" data-section="footer">
|
||||
<FooterBase
|
||||
logoText="Proof Digital"
|
||||
copyrightText="© 2025 Proof Digital. All rights reserved."
|
||||
logoText="Draco Digital"
|
||||
copyrightText="© 2025 Draco Digital. All rights reserved."
|
||||
columns={[
|
||||
{
|
||||
title: "Services", items: [
|
||||
@@ -235,15 +235,15 @@ export default function LandingPage() {
|
||||
{ label: "About Us", href: "#about" },
|
||||
{ label: "Our Work", href: "#work" },
|
||||
{ label: "Testimonials", href: "#testimonials" },
|
||||
{ label: "Blog", href: "https://blog.proofdigital.com" }
|
||||
{ label: "Blog", href: "https://blog.dracodigital.com" }
|
||||
]
|
||||
},
|
||||
{
|
||||
title: "Connect", items: [
|
||||
{ label: "Contact Us", href: "#contact" },
|
||||
{ label: "LinkedIn", href: "https://linkedin.com/company/proof-digital" },
|
||||
{ label: "Twitter", href: "https://twitter.com/proofdigital" },
|
||||
{ label: "Instagram", href: "https://instagram.com/proofdigital" }
|
||||
{ label: "LinkedIn", href: "https://linkedin.com/company/draco-digital" },
|
||||
{ label: "Twitter", href: "https://twitter.com/dracodigital" },
|
||||
{ label: "Instagram", href: "https://instagram.com/dracodigital" }
|
||||
]
|
||||
}
|
||||
]}
|
||||
|
||||
@@ -11,7 +11,7 @@ html {
|
||||
body {
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: var(--font-open-sans), sans-serif;
|
||||
font-family: var(--font-inter), sans-serif;
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
overscroll-behavior: none;
|
||||
@@ -24,5 +24,5 @@ h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-open-sans), sans-serif;
|
||||
font-family: var(--font-montserrat), sans-serif;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user