Baseline - Eddys Nova Estrutura
@@ -0,0 +1,173 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- TRACKING:START -->
|
||||||
|
<!-- Google Tag Manager -->
|
||||||
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||||
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||||
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||||
|
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||||
|
})(window,document,'script','dataLayer','GTM-P9T4GN');</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script>
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//analytics.dbtsites.com.br/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '3']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->
|
||||||
|
<!-- TRACKING:END -->
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="description" content="Masonry Services - Eddy's Construction & Masonry - Page ERROR 404.">
|
||||||
|
<meta name="author" content="Deyson Thomé">
|
||||||
|
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Playfair+Display:400,700,400italic' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Raleway:100,300,400,500,600,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link type="text/css" href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>Error Page | 404 | Page not found</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Google Tag Manager (noscript) -->
|
||||||
|
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-P9T4GN"
|
||||||
|
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||||
|
<!-- End Google Tag Manager (noscript) -->
|
||||||
|
|
||||||
|
<!-- PRELOAD -->
|
||||||
|
<div id="preload" class="preload">
|
||||||
|
<div class="square"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- HEADER -->
|
||||||
|
<header class="header head3">
|
||||||
|
<!-- HEADER:START -->
|
||||||
|
<div class="main-header">
|
||||||
|
<div class="container header-container">
|
||||||
|
<div class="logo"><a href="/index.html"><img alt="Eddy's Construction & Masonry" src="/img/logo.png"/></a></div>
|
||||||
|
<div class="info-contact">
|
||||||
|
<ul class="info-contact-list">
|
||||||
|
<li><i class="fa fa-phone"></i><p>(508) 782-2159</p><p class="vice">Call Us Free</p></li>
|
||||||
|
<li><i class="fa fa-clock-o"></i><p>Mon - Sat: 7:00 AM - 7:00 PM</p><p class="vice">Sunday CLOSED</p></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- HEADER:END -->
|
||||||
|
<!-- NAV:START -->
|
||||||
|
<div class="navBar6">
|
||||||
|
<div class="container nav-container">
|
||||||
|
<nav class="navigation" id="main-nav" aria-label="Main Navigation">
|
||||||
|
<ul class="nav text-uppercase">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li><a href="/about.html">About Us</a></li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/services/index.html" aria-haspopup="true">Our Services <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/services/masonry-stone/index.html">Masonry & Stone</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/locations/index.html" aria-haspopup="true">Locations <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/locations/wellesley/index.html">Wellesley</a></li>
|
||||||
|
<li><a href="/locations/index.html">Others</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/resources/index.html" aria-haspopup="true">Resources <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/resources/masonry-stone/index.html">Masonry & Stonework</a></li>
|
||||||
|
<li><a href="/resources/outdoor-living/index.html">Outdoor Living</a></li>
|
||||||
|
<li><a href="/resources/concrete/index.html">Concrete</a></li>
|
||||||
|
<li><a href="/resources/roofing-exterior/index.html">Roofing & Exterior</a></li>
|
||||||
|
<li><a href="/resources/excavation-drainage/index.html">Excavation & Drainage</a></li>
|
||||||
|
<li><a href="/resources/decks-porches/index.html">Decks & Porches</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="/portfolio/index.html">Our Portfolio</a></li>
|
||||||
|
<li><a href="/contact.html">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<button aria-label="Toggle Navigation" class="mobile-nav-toggle" id="mobile-toggle"><span class="hamburger"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- NAV:END -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="page-wrap">
|
||||||
|
<!-- CONTENT -->
|
||||||
|
<section class="section page-not-found bg-white">
|
||||||
|
<div class="container">
|
||||||
|
<div class="site-content">
|
||||||
|
<img src="/img/not-found.png" alt="404 Not Found" />
|
||||||
|
<h1 class="sbig mt-30 mb-30">404 Oops!</h1>
|
||||||
|
<h2 class="play-font mb-40">The page you’re looking for was not found</h2>
|
||||||
|
<a href="index.html" class="btn btn-primary radius">Back to homepage</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- FOOTER:START -->
|
||||||
|
<footer class="footer bg-dark" id="footer">
|
||||||
|
<div class="foot-widget">
|
||||||
|
<div class="container">
|
||||||
|
<div class="footer-grid">
|
||||||
|
<div class="widget widget_about">
|
||||||
|
<div class="logo"><a href="/index.html"><img alt="Eddy's Construction & Masonry" src="/img/logo-w.png"/></a></div>
|
||||||
|
<p>Eddy's Construction & Masonry treats every construction project, large or small, residential or commercial, as if we are working on our own homes.</p>
|
||||||
|
<ul class="social-list">
|
||||||
|
<li><a href="https://www.facebook.com/Eddys-Construction-Masonry-950975358293175/" target="_blank" rel="noopener"><i class="fa fa-facebook"></i></a></li>
|
||||||
|
<li><a href="https://br.pinterest.com/eddysconstructi/" target="_blank" rel="noopener"><i class="fa fa-pinterest"></i></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_contact">
|
||||||
|
<h3 class="widget-title">Get in touch</h3>
|
||||||
|
<ul>
|
||||||
|
<li><i class="fa fa-mobile"></i>(508) 782-2159</li>
|
||||||
|
<li><i class="fa fa-map-marker"></i>299 Church St #1, Marlborough, MA 01752</li>
|
||||||
|
<li><i class="fa fa-paper-plane"></i>contact@eddysconstruction.com</li>
|
||||||
|
<li><i class="fa fa-clock-o"></i>Mon - Sat: 7:00 AM - 7:00 PM</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_subscribe">
|
||||||
|
<h3 class="widget-title">Mobile Contact</h3>
|
||||||
|
<p>Quick options to call or email directly from your phone:</p>
|
||||||
|
<div class="mobile-actions">
|
||||||
|
<a class="btn btn-transparent radius" href="tel:+15087822159">Click to Call</a>
|
||||||
|
<a class="btn btn-transparent radius" href="mailto:contact@eddysconstruction.com">Click to Email</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot-credit">
|
||||||
|
<div class="container foot-credit-flex">
|
||||||
|
<p>EDDY'S Construction & Masonry © 2026 By DBT Sites. All rights Reserved</p>
|
||||||
|
<ul class="foot-menu">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li><a href="/about.html">Who we are</a></li>
|
||||||
|
<li><a href="/services/index.html">Our Services</a></li>
|
||||||
|
<li><a href="/portfolio/index.html">Our Portfolio</a></li>
|
||||||
|
<li><a href="/contact.html">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- FOOTER:END -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- TRACKING:START -->
|
||||||
|
<!-- Google Tag Manager -->
|
||||||
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||||
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||||
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||||
|
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||||
|
})(window,document,'script','dataLayer','GTM-P9T4GN');</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script>
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//analytics.dbtsites.com.br/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '3']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->
|
||||||
|
<!-- TRACKING:END -->
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="description" content="In this page you can know more about Eddy's Construction & Masonry. How do we think about our job, about quality and about commitment...">
|
||||||
|
<meta name="author" content="Deyson Thomé">
|
||||||
|
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Playfair+Display:400,700,400italic' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Raleway:100,300,400,500,600,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link type="text/css" href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>About Us | Masonry Contractor</title>
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "AboutPage",
|
||||||
|
"url": "https://eddysconstruction.com/about/",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "MasonryContractor",
|
||||||
|
"name": "Eddy's Construction & Masonry LLC",
|
||||||
|
"url": "https://eddysconstruction.com/",
|
||||||
|
"description": "Licensed and insured residential and commercial masonry contractor with years of experience serving Eastern Massachusetts."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Google Tag Manager (noscript) -->
|
||||||
|
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-P9T4GN"
|
||||||
|
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||||
|
<!-- End Google Tag Manager (noscript) -->
|
||||||
|
|
||||||
|
<!-- PRELOAD -->
|
||||||
|
<div id="preload" class="preload">
|
||||||
|
<div class="square"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- HEADER -->
|
||||||
|
<header class="header head3">
|
||||||
|
<!-- HEADER:START -->
|
||||||
|
<div class="main-header">
|
||||||
|
<div class="container header-container">
|
||||||
|
<div class="logo"><a href="/index.html"><img alt="Eddy's Construction & Masonry" src="/img/logo.png"/></a></div>
|
||||||
|
<div class="info-contact">
|
||||||
|
<ul class="info-contact-list">
|
||||||
|
<li><i class="fa fa-phone"></i><p>(508) 782-2159</p><p class="vice">Call Us Free</p></li>
|
||||||
|
<li><i class="fa fa-clock-o"></i><p>Mon - Sat: 7:00 AM - 7:00 PM</p><p class="vice">Sunday CLOSED</p></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- HEADER:END -->
|
||||||
|
<!-- NAV:START -->
|
||||||
|
<div class="navBar6">
|
||||||
|
<div class="container nav-container">
|
||||||
|
<nav class="navigation" id="main-nav" aria-label="Main Navigation">
|
||||||
|
<ul class="nav text-uppercase">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li class="active"><a href="/about.html">About Us</a></li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/services/index.html" aria-haspopup="true">Our Services <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/services/masonry-stone/index.html">Masonry & Stone</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/locations/index.html" aria-haspopup="true">Locations <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/locations/wellesley/index.html">Wellesley</a></li>
|
||||||
|
<li><a href="/locations/index.html">Others</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/resources/index.html" aria-haspopup="true">Resources <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/resources/masonry-stone/index.html">Masonry & Stonework</a></li>
|
||||||
|
<li><a href="/resources/outdoor-living/index.html">Outdoor Living</a></li>
|
||||||
|
<li><a href="/resources/concrete/index.html">Concrete</a></li>
|
||||||
|
<li><a href="/resources/roofing-exterior/index.html">Roofing & Exterior</a></li>
|
||||||
|
<li><a href="/resources/excavation-drainage/index.html">Excavation & Drainage</a></li>
|
||||||
|
<li><a href="/resources/decks-porches/index.html">Decks & Porches</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="/portfolio/index.html">Our Portfolio</a></li>
|
||||||
|
<li><a href="/contact.html">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<button aria-label="Toggle Navigation" class="mobile-nav-toggle" id="mobile-toggle"><span class="hamburger"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- NAV:END -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="page-wrap">
|
||||||
|
<!-- SUB HEADER -->
|
||||||
|
<section id="sub-header" class="section bg-parallax" style="background-image: url('/img/bg/about.jpg');">
|
||||||
|
<div class="bg-overlay-black"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="sub-wrapper">
|
||||||
|
<h1>About Us</h1>
|
||||||
|
<h2 class="h4">If you’d like to talk to us about a project, or anything else, we’d love to hear from you.</h2>
|
||||||
|
<!-- BREADCRUMB:START -->
|
||||||
|
<div class="breadcrumb-container">
|
||||||
|
<span>You are here:</span>
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li>About Us</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- BREADCRUMB:END -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- CONTENT -->
|
||||||
|
<section class="section bg-white">
|
||||||
|
<div class="container">
|
||||||
|
<div class="layout-with-sidebar reverse">
|
||||||
|
<!-- SIDEBAR -->
|
||||||
|
<div class="sidebar">
|
||||||
|
<aside class="widget widget_linklist">
|
||||||
|
<ul>
|
||||||
|
<li class="active"><a href="about.html">About Us</a></li>
|
||||||
|
<li><a href="patios.html">Patios</a></li>
|
||||||
|
<li><a href="walkway.html">Walkways</a></li>
|
||||||
|
<li><a href="stonewall.html">Stone Wall</a></li>
|
||||||
|
<li><a href="steps.html">Steps</a></li>
|
||||||
|
<li><a href="pits.html">Fire Pit</a></li>
|
||||||
|
<li><a href="fires.html">Fire Place</a></li>
|
||||||
|
<li><a href="asphalt.html">Asphalt</a></li>
|
||||||
|
<li><a href="concrete.html">Concrete</a></li>
|
||||||
|
<li><a href="paint.html">Painting</a></li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
<!-- CONTACT:START -->
|
||||||
|
<aside class="widget widget_contact">
|
||||||
|
<h3 class="widget-title">Contact Us</h3>
|
||||||
|
<ul>
|
||||||
|
<li><i class="fa fa-mobile"></i>(508) 782-2159</li>
|
||||||
|
<li><i class="fa fa-map-marker"></i>299 Church St #1, Marlborough, MA 01752</li>
|
||||||
|
<li><i class="fa fa-paper-plane"></i>contact@eddysconstruction.com</li>
|
||||||
|
<li><i class="fa fa-clock-o"></i>Mon - Sat: 7:00 AM - 7:00 PM</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
<!-- CONTACT:END -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- MAIN CONTENT -->
|
||||||
|
<div class="main-content">
|
||||||
|
<h2 class="section-header">Who we are?</h2>
|
||||||
|
<p>Eddy's Construction & Masonry LLC treats every construction project, large or small, residential or commercial, as if we are working on our own homes. With thousands of successful projects under our belt, we can proudly say that we are one of the most trusted construction companies in Marlborough Area performing best quality works.</p>
|
||||||
|
<p>Within the broad spectrum of our construction capabilities, our diversely talented masonry team specializes in all diferent kind of stone work; bluestone, cobblestone, fieldstone, flatstone, granite and others. We always work with diferent ideas to have the best results in all of our projects.</p>
|
||||||
|
<p>Eddy's Construction & Masonry LLC has offered a wide range of construction services in many cities around Marlborough, MA. We strive to maintain the highest standards while exceeding client’s expectations at all levels. We not only honor commitments, but are known for meeting tough deadlines while delivering nothing but the best. We aim to create a responsive client relationship that allows us to meet and even exceed the goals of each of our projects.</p>
|
||||||
|
|
||||||
|
<div class="grid-2col mb-30" style="margin-top: 30px;">
|
||||||
|
<img src="/img/about/eddys-logo.jpg" alt="Eddys Contruction Masonry Services" />
|
||||||
|
<img src="/img/about/selos.png" alt="Eddys Contruction selos" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FOOTER -->
|
||||||
|
<!-- FOOTER:START -->
|
||||||
|
<footer class="footer bg-dark" id="footer">
|
||||||
|
<div class="foot-widget">
|
||||||
|
<div class="container">
|
||||||
|
<div class="footer-grid">
|
||||||
|
<div class="widget widget_about">
|
||||||
|
<div class="logo"><a href="/index.html"><img alt="Eddy's Construction & Masonry" src="/img/logo-w.png"/></a></div>
|
||||||
|
<p>Eddy's Construction & Masonry treats every construction project, large or small, residential or commercial, as if we are working on our own homes.</p>
|
||||||
|
<ul class="social-list">
|
||||||
|
<li><a href="https://www.facebook.com/Eddys-Construction-Masonry-950975358293175/" target="_blank" rel="noopener"><i class="fa fa-facebook"></i></a></li>
|
||||||
|
<li><a href="https://br.pinterest.com/eddysconstructi/" target="_blank" rel="noopener"><i class="fa fa-pinterest"></i></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_contact">
|
||||||
|
<h3 class="widget-title">Get in touch</h3>
|
||||||
|
<ul>
|
||||||
|
<li><i class="fa fa-mobile"></i>(508) 782-2159</li>
|
||||||
|
<li><i class="fa fa-map-marker"></i>299 Church St #1, Marlborough, MA 01752</li>
|
||||||
|
<li><i class="fa fa-paper-plane"></i>contact@eddysconstruction.com</li>
|
||||||
|
<li><i class="fa fa-clock-o"></i>Mon - Sat: 7:00 AM - 7:00 PM</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_subscribe">
|
||||||
|
<h3 class="widget-title">Mobile Contact</h3>
|
||||||
|
<p>Quick options to call or email directly from your phone:</p>
|
||||||
|
<div class="mobile-actions">
|
||||||
|
<a class="btn btn-transparent radius" href="tel:+15087822159">Click to Call</a>
|
||||||
|
<a class="btn btn-transparent radius" href="mailto:contact@eddysconstruction.com">Click to Email</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot-credit">
|
||||||
|
<div class="container foot-credit-flex">
|
||||||
|
<p>EDDY'S Construction & Masonry © 2026 By DBT Sites. All rights Reserved</p>
|
||||||
|
<ul class="foot-menu">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li><a href="/about.html">Who we are</a></li>
|
||||||
|
<li><a href="/services/index.html">Our Services</a></li>
|
||||||
|
<li><a href="/portfolio/index.html">Our Portfolio</a></li>
|
||||||
|
<li><a href="/contact.html">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- FOOTER:END -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,458 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
build_site.py - lê site-manifest.json e escreve os blocos repetidos das páginas.
|
||||||
|
|
||||||
|
Comandos (rode na pasta do site, ao lado do site-manifest.json):
|
||||||
|
scan compara pastas x manifesto: acrescenta páginas novas e preenche status que faltam
|
||||||
|
init coloca as marcas <!-- NOME:START --> / <!-- NOME:END --> nas páginas que ainda não têm
|
||||||
|
apply reescreve o conteúdo entre as marcas (use --dry-run para só ver o que mudaria)
|
||||||
|
check confere manifesto x disco, marcas, blocos desatualizados, links e endereços antigos
|
||||||
|
|
||||||
|
O script só escreve DENTRO das marcas. Nada fora delas é tocado.
|
||||||
|
"""
|
||||||
|
import argparse, fnmatch, json, os, re, sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
BLOCKS = ["TRACKING", "HEADER", "NAV", "BREADCRUMB", "FOOTER", "CONTACT"]
|
||||||
|
OPTIONAL = {"CONTACT"} # só existe em páginas com o cartão "Contact Us" na sidebar
|
||||||
|
IGNORE_DIRS = {".git", "img", "images", "css", "js", "node_modules", "modelo"}
|
||||||
|
IGNORE_FILES = re.compile(r"^(google[0-9a-f]+|pinterest-[0-9a-z]+)\.html$")
|
||||||
|
HOME = "index.html"
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------- manifesto
|
||||||
|
def load(root):
|
||||||
|
path = root / "site-manifest.json"
|
||||||
|
if not path.exists():
|
||||||
|
sys.exit(f"Não achei {path}")
|
||||||
|
m = json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
m["_by"] = {p["file"]: p for p in m["pages"]}
|
||||||
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
def save(root, m):
|
||||||
|
data = {k: v for k, v in m.items() if not k.startswith("_")}
|
||||||
|
head = json.dumps({k: v for k, v in data.items() if k != "pages"}, ensure_ascii=False, indent=2)
|
||||||
|
head = head.rstrip("}").rstrip().rstrip(",")
|
||||||
|
lines = ",\n".join(" " + json.dumps(p, ensure_ascii=False) for p in data["pages"])
|
||||||
|
(root / "site-manifest.json").write_text(head + ',\n "pages": [\n' + lines + "\n ]\n}\n", encoding="utf-8")
|
||||||
|
|
||||||
|
|
||||||
|
def url(m, f):
|
||||||
|
if m["options"].get("strip_index"):
|
||||||
|
if f == HOME:
|
||||||
|
return "/"
|
||||||
|
if f.endswith("/index.html"):
|
||||||
|
return "/" + f[: -len("index.html")]
|
||||||
|
return "/" + f
|
||||||
|
|
||||||
|
|
||||||
|
def pub(p):
|
||||||
|
return p.get("status") == "publicada"
|
||||||
|
|
||||||
|
|
||||||
|
def chain(m, f):
|
||||||
|
"""arquivo -> pai -> ... -> home (protegido contra ciclo)"""
|
||||||
|
out, seen = [], set()
|
||||||
|
while f and f not in seen and f in m["_by"]:
|
||||||
|
out.append(f)
|
||||||
|
seen.add(f)
|
||||||
|
f = m["_by"][f].get("parent")
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def esc(t):
|
||||||
|
return t.replace("&", "&").replace("<", "<").replace(">", ">")
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------- geradores
|
||||||
|
def gen_tracking(m, cur):
|
||||||
|
t = m["site"]["tracking"]
|
||||||
|
return f"""<!-- Google Tag Manager -->
|
||||||
|
<script>(function(w,d,s,l,i){{w[l]=w[l]||[];w[l].push({{'gtm.start':
|
||||||
|
new Date().getTime(),event:'gtm.js'}});var f=d.getElementsByTagName(s)[0],
|
||||||
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||||
|
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||||
|
}})(window,document,'script','dataLayer','{t['gtm']}');</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script>
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {{
|
||||||
|
var u="{t['matomo_url']}";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '{t['matomo_site_id']}']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
}})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->"""
|
||||||
|
|
||||||
|
|
||||||
|
def gen_header(m, cur):
|
||||||
|
s = m["site"]
|
||||||
|
return f"""<div class="main-header">
|
||||||
|
<div class="container header-container">
|
||||||
|
<div class="logo"><a href="{url(m, HOME)}"><img alt="{esc(s['name'])}" src="/img/logo.png"/></a></div>
|
||||||
|
<div class="info-contact">
|
||||||
|
<ul class="info-contact-list">
|
||||||
|
<li><i class="fa fa-phone"></i><p>{esc(s['phone'])}</p><p class="vice">Call Us Free</p></li>
|
||||||
|
<li><i class="fa fa-clock-o"></i><p>{esc(s['hours'])}</p><p class="vice">{esc(s['closed_note'])}</p></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>"""
|
||||||
|
|
||||||
|
|
||||||
|
def gen_nav(m, cur):
|
||||||
|
pages = m["pages"]
|
||||||
|
ch = set(chain(m, cur))
|
||||||
|
li = []
|
||||||
|
for top in (p for p in pages if p.get("menu") == "top" and pub(p)):
|
||||||
|
active = top["file"] in ch and (top["file"] != HOME or cur == HOME)
|
||||||
|
subs = [c for c in pages if c.get("menu") == "sub" and c.get("parent") == top["file"] and pub(c)]
|
||||||
|
if not subs:
|
||||||
|
cls = ' class="active"' if active else ""
|
||||||
|
li.append(f'<li{cls}><a href="{url(m, top["file"])}">{esc(top["label"])}</a></li>')
|
||||||
|
continue
|
||||||
|
items = []
|
||||||
|
for c in subs:
|
||||||
|
cls = ' class="active"' if c["file"] in ch else ""
|
||||||
|
items.append(f' <li{cls}><a href="{url(m, c["file"])}">{esc(c["label"])}</a></li>')
|
||||||
|
if top.get("others"):
|
||||||
|
items.append(f' <li><a href="{url(m, top["file"])}">Others</a></li>')
|
||||||
|
cls = "menu-item-has-children" + (" active" if active else "")
|
||||||
|
li.append(
|
||||||
|
f'<li class="{cls}">\n'
|
||||||
|
f' <a href="{url(m, top["file"])}" aria-haspopup="true">{esc(top["label"])} <span class="fa fa-angle-down"></span></a>\n'
|
||||||
|
f' <ul class="sub-menu">\n' + "\n".join(items) + "\n </ul>\n</li>"
|
||||||
|
)
|
||||||
|
body = "\n".join(" " + l.replace("\n", "\n ") for l in li)
|
||||||
|
return f"""<div class="navBar6">
|
||||||
|
<div class="container nav-container">
|
||||||
|
<nav class="navigation" id="main-nav" aria-label="Main Navigation">
|
||||||
|
<ul class="nav text-uppercase">
|
||||||
|
{body}
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<button aria-label="Toggle Navigation" class="mobile-nav-toggle" id="mobile-toggle"><span class="hamburger"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>"""
|
||||||
|
|
||||||
|
|
||||||
|
def gen_breadcrumb(m, cur):
|
||||||
|
trail = list(reversed(chain(m, cur)))
|
||||||
|
items = []
|
||||||
|
for i, f in enumerate(trail):
|
||||||
|
p = m["_by"][f]
|
||||||
|
label = esc(p.get("crumb") or p["label"])
|
||||||
|
if i == len(trail) - 1 or not pub(p):
|
||||||
|
items.append(f" <li>{label}</li>")
|
||||||
|
else:
|
||||||
|
items.append(f' <li><a href="{url(m, f)}">{label}</a></li>')
|
||||||
|
return ('<div class="breadcrumb-container">\n <span>You are here:</span>\n <ul class="breadcrumb">\n'
|
||||||
|
+ "\n".join(items) + "\n </ul>\n</div>")
|
||||||
|
|
||||||
|
|
||||||
|
def gen_footer(m, cur):
|
||||||
|
s = m["site"]
|
||||||
|
social = "\n".join(
|
||||||
|
f' <li><a href="{x["url"]}" target="_blank" rel="noopener"><i class="fa {x["icon"]}"></i></a></li>'
|
||||||
|
for x in s.get("social", []))
|
||||||
|
fm = "\n".join(
|
||||||
|
f' <li><a href="{url(m, p["file"])}">{esc(p.get("footer_label") or p["label"])}</a></li>'
|
||||||
|
for p in m["pages"] if p.get("footer") and pub(p))
|
||||||
|
return f"""<footer class="footer bg-dark" id="footer">
|
||||||
|
<div class="foot-widget">
|
||||||
|
<div class="container">
|
||||||
|
<div class="footer-grid">
|
||||||
|
<div class="widget widget_about">
|
||||||
|
<div class="logo"><a href="{url(m, HOME)}"><img alt="{esc(s['name'])}" src="/img/logo-w.png"/></a></div>
|
||||||
|
<p>{esc(s['about_short'])}</p>
|
||||||
|
<ul class="social-list">
|
||||||
|
{social}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_contact">
|
||||||
|
<h3 class="widget-title">Get in touch</h3>
|
||||||
|
<ul>
|
||||||
|
<li><i class="fa fa-mobile"></i>{esc(s['phone'])}</li>
|
||||||
|
<li><i class="fa fa-map-marker"></i>{esc(s['address'])}</li>
|
||||||
|
<li><i class="fa fa-paper-plane"></i>{esc(s['email'])}</li>
|
||||||
|
<li><i class="fa fa-clock-o"></i>{esc(s['hours'])}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_subscribe">
|
||||||
|
<h3 class="widget-title">Mobile Contact</h3>
|
||||||
|
<p>Quick options to call or email directly from your phone:</p>
|
||||||
|
<div class="mobile-actions">
|
||||||
|
<a class="btn btn-transparent radius" href="tel:{s['phone_tel']}">Click to Call</a>
|
||||||
|
<a class="btn btn-transparent radius" href="mailto:{s['email']}">Click to Email</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot-credit">
|
||||||
|
<div class="container foot-credit-flex">
|
||||||
|
<p>{s['copyright']}</p>
|
||||||
|
<ul class="foot-menu">
|
||||||
|
{fm}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>"""
|
||||||
|
|
||||||
|
|
||||||
|
def gen_contact(m, cur):
|
||||||
|
s = m["site"]
|
||||||
|
return f"""<aside class="widget widget_contact">
|
||||||
|
<h3 class="widget-title">Contact Us</h3>
|
||||||
|
<ul>
|
||||||
|
<li><i class="fa fa-mobile"></i>{esc(s['phone'])}</li>
|
||||||
|
<li><i class="fa fa-map-marker"></i>{esc(s['address'])}</li>
|
||||||
|
<li><i class="fa fa-paper-plane"></i>{esc(s['email'])}</li>
|
||||||
|
<li><i class="fa fa-clock-o"></i>{esc(s['hours'])}</li>
|
||||||
|
</ul>
|
||||||
|
</aside>"""
|
||||||
|
|
||||||
|
|
||||||
|
GEN = {"TRACKING": gen_tracking, "HEADER": gen_header, "NAV": gen_nav,
|
||||||
|
"BREADCRUMB": gen_breadcrumb, "FOOTER": gen_footer, "CONTACT": gen_contact}
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------- marcas
|
||||||
|
def marker_re(name):
|
||||||
|
return re.compile(r"([ \t]*)<!-- %s:START -->.*?<!-- %s:END -->" % (name, name), re.S)
|
||||||
|
|
||||||
|
|
||||||
|
def render(text, m, cur):
|
||||||
|
"""devolve (novo_texto, faltando) com os blocos regenerados"""
|
||||||
|
missing = []
|
||||||
|
for name in BLOCKS:
|
||||||
|
if name == "BREADCRUMB" and (cur == HOME or m["_by"][cur].get("no_breadcrumb")):
|
||||||
|
continue
|
||||||
|
rx = marker_re(name)
|
||||||
|
mt = rx.search(text)
|
||||||
|
if not mt:
|
||||||
|
if name not in OPTIONAL:
|
||||||
|
missing.append(name)
|
||||||
|
continue
|
||||||
|
ind = mt.group(1)
|
||||||
|
body = GEN[name](m, cur)
|
||||||
|
block = ind + f"<!-- {name}:START -->\n" + "\n".join(ind + l if l else l for l in body.split("\n")) \
|
||||||
|
+ f"\n{ind}<!-- {name}:END -->"
|
||||||
|
text = text[: mt.start()] + block + text[mt.end():]
|
||||||
|
return text, missing
|
||||||
|
|
||||||
|
|
||||||
|
def balanced_div(text, start):
|
||||||
|
depth = 0
|
||||||
|
for mt in re.finditer(r"<div\b|</div>", text[start:]):
|
||||||
|
depth += 1 if mt.group(0).startswith("<div") else -1
|
||||||
|
if depth == 0:
|
||||||
|
return start + mt.end()
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def find_span(text, name):
|
||||||
|
if name == "TRACKING":
|
||||||
|
a = text.find("<!-- Google Tag Manager -->")
|
||||||
|
b = text.find("<!-- End Matomo Code -->")
|
||||||
|
return (a, b + len("<!-- End Matomo Code -->")) if a >= 0 and b > a else None
|
||||||
|
if name == "CONTACT":
|
||||||
|
a = text.find('<aside class="widget widget_contact">')
|
||||||
|
b = text.find("</aside>", a)
|
||||||
|
return (a, b + len("</aside>")) if a >= 0 and b > a else None
|
||||||
|
if name == "FOOTER":
|
||||||
|
a = text.find("<footer")
|
||||||
|
b = text.find("</footer>", a)
|
||||||
|
return (a, b + len("</footer>")) if a >= 0 and b > a else None
|
||||||
|
cls = {"HEADER": "main-header", "NAV": "navBar6", "BREADCRUMB": "breadcrumb-container"}[name]
|
||||||
|
mt = re.search(r'<div class="%s"' % cls, text)
|
||||||
|
if not mt:
|
||||||
|
return None
|
||||||
|
end = balanced_div(text, mt.start())
|
||||||
|
return (mt.start(), end) if end else None
|
||||||
|
|
||||||
|
|
||||||
|
def add_markers(text):
|
||||||
|
added = []
|
||||||
|
for name in BLOCKS:
|
||||||
|
if f"<!-- {name}:START -->" in text:
|
||||||
|
continue
|
||||||
|
span = find_span(text, name)
|
||||||
|
if not span:
|
||||||
|
continue
|
||||||
|
a, b = span
|
||||||
|
line_start = text.rfind("\n", 0, a) + 1
|
||||||
|
ind = text[line_start:a] if not text[line_start:a].strip() else ""
|
||||||
|
text = (text[:line_start] + f"{ind}<!-- {name}:START -->\n" + text[line_start:b]
|
||||||
|
+ f"\n{ind}<!-- {name}:END -->" + text[b:])
|
||||||
|
added.append(name)
|
||||||
|
return text, added
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------- comandos
|
||||||
|
def is_ignored(m, f):
|
||||||
|
"""padrões do manifesto (options.ignore), estilo curinga: 'files/*', 'resources/old-index.html'"""
|
||||||
|
return any(fnmatch.fnmatch(f, pat) for pat in m["options"].get("ignore", []))
|
||||||
|
|
||||||
|
|
||||||
|
def disk_pages(root, m=None):
|
||||||
|
for dp, dn, fn in os.walk(root):
|
||||||
|
dn[:] = [d for d in dn if d not in IGNORE_DIRS]
|
||||||
|
for f in fn:
|
||||||
|
if f.endswith(".html") and not IGNORE_FILES.match(f):
|
||||||
|
rel = str(Path(dp, f).relative_to(root)).replace(os.sep, "/")
|
||||||
|
yield rel
|
||||||
|
|
||||||
|
|
||||||
|
def label_from_h1(root, f):
|
||||||
|
try:
|
||||||
|
t = (root / f).read_text(encoding="utf-8", errors="ignore")
|
||||||
|
except OSError:
|
||||||
|
return None
|
||||||
|
mt = re.search(r"<h1[^>]*>(.*?)</h1>", t, re.S | re.I)
|
||||||
|
if not mt:
|
||||||
|
return None
|
||||||
|
txt = re.sub(r"<[^>]+>", "", mt.group(1))
|
||||||
|
txt = re.sub(r"\s+", " ", txt).strip()
|
||||||
|
return txt.replace("&", "&") or None
|
||||||
|
|
||||||
|
|
||||||
|
def has_content(root, f):
|
||||||
|
p = root / f
|
||||||
|
return p.is_file() and p.stat().st_size > 0
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_scan(root, m):
|
||||||
|
changed = False
|
||||||
|
for p in m["pages"]:
|
||||||
|
if "status" not in p:
|
||||||
|
p["status"] = "publicada" if has_content(root, p["file"]) else "planejada"
|
||||||
|
print(f"status definido pelo disco: {p['file']} -> {p['status']}")
|
||||||
|
changed = True
|
||||||
|
known = set(m["_by"])
|
||||||
|
ignored = []
|
||||||
|
for f in sorted(disk_pages(root)):
|
||||||
|
if f in known:
|
||||||
|
continue
|
||||||
|
if is_ignored(m, f):
|
||||||
|
ignored.append(f)
|
||||||
|
continue
|
||||||
|
folder = Path(f).parent.as_posix()
|
||||||
|
parent = (folder + "/index.html") if folder != "." and f.endswith("/index.html") is False else None
|
||||||
|
if f.endswith("/index.html"):
|
||||||
|
up = Path(folder).parent.as_posix()
|
||||||
|
parent = (up + "/index.html") if up != "." else HOME
|
||||||
|
if parent and parent not in known and parent != HOME:
|
||||||
|
parent = HOME
|
||||||
|
label = label_from_h1(root, f) or Path(f).stem.replace("-", " ").title()
|
||||||
|
page = {"file": f, "label": label, "parent": parent or HOME,
|
||||||
|
"status": "publicada" if has_content(root, f) else "planejada"}
|
||||||
|
m["pages"].append(page)
|
||||||
|
print(f"NOVA página no disco, acrescentada ao manifesto: {f} ({page['status']}). Ajuste label/parent/menu.")
|
||||||
|
changed = True
|
||||||
|
for f in ignored:
|
||||||
|
print(f"ignorada (options.ignore): {f}")
|
||||||
|
for p in m["pages"]:
|
||||||
|
if not (root / p["file"]).exists():
|
||||||
|
print(f"AVISO: no manifesto mas não existe no disco: {p['file']} ({p.get('status')})")
|
||||||
|
if changed:
|
||||||
|
save(root, m)
|
||||||
|
else:
|
||||||
|
print("Nada a acrescentar.")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_init(root, m):
|
||||||
|
for p in m["pages"]:
|
||||||
|
if not has_content(root, p["file"]):
|
||||||
|
continue
|
||||||
|
path = root / p["file"]
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
new, added = add_markers(text)
|
||||||
|
if added:
|
||||||
|
path.write_text(new, encoding="utf-8")
|
||||||
|
print(f"{p['file']}: marcas em {', '.join(added)}")
|
||||||
|
print("Pronto. Agora rode: apply --dry-run")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_apply(root, m, dry):
|
||||||
|
n = 0
|
||||||
|
for p in m["pages"]:
|
||||||
|
if not pub(p):
|
||||||
|
continue
|
||||||
|
if not has_content(root, p["file"]):
|
||||||
|
print(f"ERRO: {p['file']} está 'publicada' no manifesto mas o arquivo falta ou está vazio")
|
||||||
|
continue
|
||||||
|
path = root / p["file"]
|
||||||
|
text = path.read_text(encoding="utf-8")
|
||||||
|
new, missing = render(text, m, p["file"])
|
||||||
|
if missing:
|
||||||
|
print(f"{p['file']}: sem marcas em {', '.join(missing)} (rode init)")
|
||||||
|
if new != text:
|
||||||
|
n += 1
|
||||||
|
print(("mudaria: " if dry else "atualizada: ") + p["file"])
|
||||||
|
if not dry:
|
||||||
|
path.write_text(new, encoding="utf-8")
|
||||||
|
print(f"{n} página(s) {'mudariam' if dry else 'atualizadas'}.")
|
||||||
|
|
||||||
|
|
||||||
|
def cmd_check(root, m):
|
||||||
|
errors = warns = 0
|
||||||
|
legacy = m["site"].get("old_strings", [])
|
||||||
|
for p in m["pages"]:
|
||||||
|
f = p["file"]
|
||||||
|
if not pub(p):
|
||||||
|
continue
|
||||||
|
if not has_content(root, f):
|
||||||
|
print(f"ERRO {f}: 'publicada' mas o arquivo falta ou está vazio"); errors += 1
|
||||||
|
continue
|
||||||
|
text = (root / f).read_text(encoding="utf-8")
|
||||||
|
new, missing = render(text, m, f)
|
||||||
|
if missing:
|
||||||
|
print(f"AVISO {f}: sem marcas em {', '.join(missing)}"); warns += 1
|
||||||
|
elif new != text:
|
||||||
|
print(f"AVISO {f}: blocos desatualizados (rode apply)"); warns += 1
|
||||||
|
for s in legacy:
|
||||||
|
if s in text:
|
||||||
|
print(f"ERRO {f}: contém '{s}'"); errors += 1
|
||||||
|
visible = re.sub(r"<!--.*?-->", "", text, flags=re.S) # ignora trechos comentados
|
||||||
|
for mt in re.finditer(r'(?:href|src)="([^"#?]+)', visible):
|
||||||
|
u = mt.group(1)
|
||||||
|
if re.match(r"(https?:|mailto:|tel:|//|data:|javascript:)", u):
|
||||||
|
continue
|
||||||
|
rel = u.lstrip("/") if u.startswith("/") else os.path.normpath(os.path.join(os.path.dirname(f), u))
|
||||||
|
cand = [rel, rel.rstrip("/") + "/index.html"] if not rel.endswith(".html") else [rel]
|
||||||
|
if not any((root / c).is_file() and (root / c).stat().st_size > 0 for c in cand):
|
||||||
|
if rel.startswith(("img/", "css/", "js/", "images/")) or "." in os.path.basename(rel) and not rel.endswith(".html"):
|
||||||
|
if (root / rel).is_file():
|
||||||
|
continue
|
||||||
|
print(f"ERRO {f}: link quebrado ou para página vazia -> {u}"); errors += 1
|
||||||
|
print(f"\n{errors} erro(s), {warns} aviso(s).")
|
||||||
|
return 1 if errors else 0
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||||
|
ap.add_argument("cmd", choices=["scan", "init", "apply", "check"])
|
||||||
|
ap.add_argument("--root", default=".", help="pasta do site (padrão: pasta atual)")
|
||||||
|
ap.add_argument("--dry-run", action="store_true")
|
||||||
|
a = ap.parse_args()
|
||||||
|
root = Path(a.root).resolve()
|
||||||
|
m = load(root)
|
||||||
|
if a.cmd == "scan":
|
||||||
|
cmd_scan(root, m)
|
||||||
|
elif a.cmd == "init":
|
||||||
|
cmd_init(root, m)
|
||||||
|
elif a.cmd == "apply":
|
||||||
|
cmd_apply(root, m, a.dry_run)
|
||||||
|
else:
|
||||||
|
sys.exit(cmd_check(root, m))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,267 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<!-- TRACKING:START -->
|
||||||
|
<!-- Google Tag Manager -->
|
||||||
|
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
||||||
|
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
||||||
|
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
||||||
|
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
||||||
|
})(window,document,'script','dataLayer','GTM-P9T4GN');</script>
|
||||||
|
<!-- End Google Tag Manager -->
|
||||||
|
<!-- Matomo -->
|
||||||
|
<script>
|
||||||
|
var _paq = window._paq = window._paq || [];
|
||||||
|
_paq.push(['trackPageView']);
|
||||||
|
_paq.push(['enableLinkTracking']);
|
||||||
|
(function() {
|
||||||
|
var u="//analytics.dbtsites.com.br/";
|
||||||
|
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
||||||
|
_paq.push(['setSiteId', '3']);
|
||||||
|
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
||||||
|
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<!-- End Matomo Code -->
|
||||||
|
<!-- TRACKING:END -->
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="description" content="Contact Eddy's Construction & Masonry LLC for a free estimate on your project.">
|
||||||
|
<meta name="author" content="Deyson Thomé">
|
||||||
|
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Montserrat:400,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Playfair+Display:400,700,400italic' rel='stylesheet' type='text/css'>
|
||||||
|
<link href='https://fonts.googleapis.com/css?family=Raleway:100,300,400,500,600,700' rel='stylesheet' type='text/css'>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link type="text/css" href="/css/style.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<title>Eddy's Construction | Contact Page</title>
|
||||||
|
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{
|
||||||
|
"@context": "https://schema.org",
|
||||||
|
"@type": "ContactPage",
|
||||||
|
"url": "https://eddysconstruction.com/contact/",
|
||||||
|
"mainEntity": {
|
||||||
|
"@type": "MasonryContractor",
|
||||||
|
"name": "Eddy's Construction & Masonry LLC",
|
||||||
|
"telephone": "+1-508-782-2159",
|
||||||
|
"email": "contact@eddysconstruction.com",
|
||||||
|
"address": {
|
||||||
|
"@type": "PostalAddress",
|
||||||
|
"streetAddress": "299 Church St #1",
|
||||||
|
"addressLocality": "Marlborough",
|
||||||
|
"addressRegion": "MA",
|
||||||
|
"postalCode": "01752",
|
||||||
|
"addressCountry": "US"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- Google Tag Manager (noscript) -->
|
||||||
|
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-P9T4GN"
|
||||||
|
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
||||||
|
<!-- End Google Tag Manager (noscript) -->
|
||||||
|
|
||||||
|
<div id="preload" class="preload">
|
||||||
|
<div class="square"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<header class="header head3">
|
||||||
|
<!-- HEADER:START -->
|
||||||
|
<div class="main-header">
|
||||||
|
<div class="container header-container">
|
||||||
|
<div class="logo"><a href="/index.html"><img alt="Eddy's Construction & Masonry" src="/img/logo.png"/></a></div>
|
||||||
|
<div class="info-contact">
|
||||||
|
<ul class="info-contact-list">
|
||||||
|
<li><i class="fa fa-phone"></i><p>(508) 782-2159</p><p class="vice">Call Us Free</p></li>
|
||||||
|
<li><i class="fa fa-clock-o"></i><p>Mon - Sat: 7:00 AM - 7:00 PM</p><p class="vice">Sunday CLOSED</p></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- HEADER:END -->
|
||||||
|
<!-- NAV:START -->
|
||||||
|
<div class="navBar6">
|
||||||
|
<div class="container nav-container">
|
||||||
|
<nav class="navigation" id="main-nav" aria-label="Main Navigation">
|
||||||
|
<ul class="nav text-uppercase">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li><a href="/about.html">About Us</a></li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/services/index.html" aria-haspopup="true">Our Services <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/services/masonry-stone/index.html">Masonry & Stone</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/locations/index.html" aria-haspopup="true">Locations <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/locations/wellesley/index.html">Wellesley</a></li>
|
||||||
|
<li><a href="/locations/index.html">Others</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li class="menu-item-has-children">
|
||||||
|
<a href="/resources/index.html" aria-haspopup="true">Resources <span class="fa fa-angle-down"></span></a>
|
||||||
|
<ul class="sub-menu">
|
||||||
|
<li><a href="/resources/masonry-stone/index.html">Masonry & Stonework</a></li>
|
||||||
|
<li><a href="/resources/outdoor-living/index.html">Outdoor Living</a></li>
|
||||||
|
<li><a href="/resources/concrete/index.html">Concrete</a></li>
|
||||||
|
<li><a href="/resources/roofing-exterior/index.html">Roofing & Exterior</a></li>
|
||||||
|
<li><a href="/resources/excavation-drainage/index.html">Excavation & Drainage</a></li>
|
||||||
|
<li><a href="/resources/decks-porches/index.html">Decks & Porches</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="/portfolio/index.html">Our Portfolio</a></li>
|
||||||
|
<li class="active"><a href="/contact.html">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<button aria-label="Toggle Navigation" class="mobile-nav-toggle" id="mobile-toggle"><span class="hamburger"></span></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- NAV:END -->
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div id="page-wrap">
|
||||||
|
<section id="sub-header" class="section bg-parallax" style="background-image: url('/img/bg/contact.jpg');">
|
||||||
|
<div class="bg-overlay-black"></div>
|
||||||
|
<div class="container">
|
||||||
|
<div class="sub-wrapper">
|
||||||
|
<h1>Contact Us</h1>
|
||||||
|
<h2 class="h4">If you’d like to talk to us about a project, or anything else, we’d love to hear from you.</h2>
|
||||||
|
<!-- BREADCRUMB:START -->
|
||||||
|
<div class="breadcrumb-container">
|
||||||
|
<span>You are here:</span>
|
||||||
|
<ul class="breadcrumb">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li>Contact us</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!-- BREADCRUMB:END -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="section bg-white">
|
||||||
|
<div class="container">
|
||||||
|
<div class="layout-with-sidebar">
|
||||||
|
<div class="main-content">
|
||||||
|
<p class="mb-30">Send us a message to request information and estimates. Thank you.</p>
|
||||||
|
|
||||||
|
<form id="contact-form" action="processContact.php" method="post" class="contact-form-container">
|
||||||
|
<div class="form-group-2col">
|
||||||
|
<input type="text" name="name" placeholder="Name *" class="form-control" required />
|
||||||
|
<input type="email" name="email" placeholder="Email *" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group-2col">
|
||||||
|
<input type="text" name="phone" placeholder="Phone Number" class="form-control" />
|
||||||
|
<input type="text" name="address_zip" placeholder="Address or ZIP Code *" class="form-control" required />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group-2col">
|
||||||
|
<div class="select-field">
|
||||||
|
<label for="phone_allowed" class="label-sm">May we contact you by phone?</label>
|
||||||
|
<select name="phone_allowed" id="phone_allowed" class="form-control">
|
||||||
|
<option value="Yes">Yes, phone calls or text are OK</option>
|
||||||
|
<option value="No">No, email correspondence only</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="select-field">
|
||||||
|
<label for="best_time" class="label-sm">Best time to contact you:</label>
|
||||||
|
<select name="best_time" id="best_time" class="form-control">
|
||||||
|
<option value="Morning">Morning (8:00 AM - 12:00 PM)</option>
|
||||||
|
<option value="Afternoon">Afternoon (12:00 PM - 5:00 PM)</option>
|
||||||
|
<option value="Evening">Evening (5:00 PM - 7:00 PM)</option>
|
||||||
|
<option value="Anytime">Anytime during business hours</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="text" name="subject" placeholder="Subject *" class="form-control" required />
|
||||||
|
<textarea name="message" placeholder="Message (min. 10 characters) *" class="form-control" rows="5" required></textarea>
|
||||||
|
|
||||||
|
<div class="notice-box">
|
||||||
|
<i class="fa fa-info-circle"></i>
|
||||||
|
<p><strong>Important Email Notice:</strong> After sending this form, an automated response will be sent to your email. Please check your <strong>Spam/Junk folder</strong> if it does not appear in your primary inbox, and reply to it so we can establish a verified line of communication.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="optin-consent">
|
||||||
|
<label class="checkbox-container">
|
||||||
|
<input type="checkbox" name="marketing_optin" value="Yes" checked>
|
||||||
|
<span class="checkmark"></span>
|
||||||
|
I agree to receive occasional updates, seasonal offers, and holiday greetings from Eddy's Construction & Masonry. You can unsubscribe at any time using the link provided in our emails or by viewing our <a href="privacy.html" target="_blank">Privacy Policy</a>.
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<button type="submit" class="btn btn-primary radius">Send message</button>
|
||||||
|
</div>
|
||||||
|
<div id="contact-content"></div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="sidebar">
|
||||||
|
<aside class="widget widget_text">
|
||||||
|
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d2949.0764737527425!2d-71.5383062!3d42.34089290000001!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x89e38b4fae57bd4b%3A0x4b3bc05dcf2223b8!2sEddy's%20Construction%20%26%20Masonry!5e0!3m2!1spt-BR!2sbr!4v1790691199587!5m2!1spt-BR!2sbr" width="400" height="300" style="border:0;" allowfullscreen="" loading="lazy" referrerpolicy="strict-origin-when-cross-origin"></iframe>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- FOOTER:START -->
|
||||||
|
<footer class="footer bg-dark" id="footer">
|
||||||
|
<div class="foot-widget">
|
||||||
|
<div class="container">
|
||||||
|
<div class="footer-grid">
|
||||||
|
<div class="widget widget_about">
|
||||||
|
<div class="logo"><a href="/index.html"><img alt="Eddy's Construction & Masonry" src="/img/logo-w.png"/></a></div>
|
||||||
|
<p>Eddy's Construction & Masonry treats every construction project, large or small, residential or commercial, as if we are working on our own homes.</p>
|
||||||
|
<ul class="social-list">
|
||||||
|
<li><a href="https://www.facebook.com/Eddys-Construction-Masonry-950975358293175/" target="_blank" rel="noopener"><i class="fa fa-facebook"></i></a></li>
|
||||||
|
<li><a href="https://br.pinterest.com/eddysconstructi/" target="_blank" rel="noopener"><i class="fa fa-pinterest"></i></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_contact">
|
||||||
|
<h3 class="widget-title">Get in touch</h3>
|
||||||
|
<ul>
|
||||||
|
<li><i class="fa fa-mobile"></i>(508) 782-2159</li>
|
||||||
|
<li><i class="fa fa-map-marker"></i>299 Church St #1, Marlborough, MA 01752</li>
|
||||||
|
<li><i class="fa fa-paper-plane"></i>contact@eddysconstruction.com</li>
|
||||||
|
<li><i class="fa fa-clock-o"></i>Mon - Sat: 7:00 AM - 7:00 PM</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="widget widget_subscribe">
|
||||||
|
<h3 class="widget-title">Mobile Contact</h3>
|
||||||
|
<p>Quick options to call or email directly from your phone:</p>
|
||||||
|
<div class="mobile-actions">
|
||||||
|
<a class="btn btn-transparent radius" href="tel:+15087822159">Click to Call</a>
|
||||||
|
<a class="btn btn-transparent radius" href="mailto:contact@eddysconstruction.com">Click to Email</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="foot-credit">
|
||||||
|
<div class="container foot-credit-flex">
|
||||||
|
<p>EDDY'S Construction & Masonry © 2026 By DBT Sites. All rights Reserved</p>
|
||||||
|
<ul class="foot-menu">
|
||||||
|
<li><a href="/index.html">Home</a></li>
|
||||||
|
<li><a href="/about.html">Who we are</a></li>
|
||||||
|
<li><a href="/services/index.html">Our Services</a></li>
|
||||||
|
<li><a href="/portfolio/index.html">Our Portfolio</a></li>
|
||||||
|
<li><a href="/contact.html">Contact us</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<!-- FOOTER:END -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/* =========================================================
|
||||||
|
ARTICLE.CSS
|
||||||
|
Only new article components.
|
||||||
|
Existing /css/style.css remains the site's baseline.
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.article-page {
|
||||||
|
padding-top: 60px;
|
||||||
|
padding-bottom: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-article {
|
||||||
|
max-width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-header {
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-category,
|
||||||
|
.section-label,
|
||||||
|
.author-label {
|
||||||
|
font-size: .78rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: .08em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-category {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-header h1 {
|
||||||
|
margin: 0 0 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 18px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
font-size: .9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-featured-image {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-content {
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-content h2 {
|
||||||
|
margin-top: 38px;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-note {
|
||||||
|
margin: 32px 0;
|
||||||
|
padding: 22px 24px;
|
||||||
|
border-left: 4px solid currentColor;
|
||||||
|
background: rgba(0, 0, 0, .04);
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-author-box {
|
||||||
|
display: flex;
|
||||||
|
gap: 22px;
|
||||||
|
align-items: flex-start;
|
||||||
|
margin-top: 48px;
|
||||||
|
padding: 28px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-avatar {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
flex: 0 0 64px;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
background: rgba(0, 0, 0, .08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-info h2 {
|
||||||
|
margin: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.author-role {
|
||||||
|
margin-top: 0;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-categories {
|
||||||
|
margin-top: 60px;
|
||||||
|
padding-top: 40px;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-categories h2,
|
||||||
|
.latest-articles h2 {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 10px;
|
||||||
|
margin-top: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-list a {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 9px 14px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, .16);
|
||||||
|
border-radius: 999px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest-articles {
|
||||||
|
margin-top: 56px;
|
||||||
|
padding-top: 40px;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest-articles-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 22px;
|
||||||
|
margin-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest-article-card {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest-article-card h3 {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest-article-card p {
|
||||||
|
line-height: 1.55;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-image {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
aspect-ratio: 16 / 10;
|
||||||
|
background: rgba(0, 0, 0, .06);
|
||||||
|
border: 1px solid rgba(0, 0, 0, .12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder-image span {
|
||||||
|
font-size: .75rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: .08em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 900px) {
|
||||||
|
.latest-articles-grid {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 700px) {
|
||||||
|
.article-author-box {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.latest-articles-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.article-meta {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Template completo: componentes adicionais ---- */
|
||||||
|
.article-meta span+span::before{content:"\2022";margin-right:18px;opacity:.5}
|
||||||
|
.article-featured-image{border-radius:2px}
|
||||||
|
.article-figure{margin:0}
|
||||||
|
.article-figure figcaption{margin-top:8px;font-size:.85rem;opacity:.7}
|
||||||
|
.article-takeaways{margin:0 0 32px;padding:22px 26px;background:#f9f9f9;border-left:4px solid #ffbf00}
|
||||||
|
.article-takeaways h2{margin:0 0 10px!important;font-size:1.1rem}
|
||||||
|
.article-takeaways ul{margin:0;padding-left:20px;line-height:1.7}
|
||||||
|
.article-content ol,.article-content ul{margin:0 0 20px;padding-left:22px}
|
||||||
|
.article-content li{margin-bottom:8px}
|
||||||
|
.article-content h2[id]{scroll-margin-top:90px}
|
||||||
|
.article-toc ol{margin:0;padding-left:18px;line-height:1.9;font-size:.92rem}
|
||||||
|
.article-toc a{text-decoration:none}
|
||||||
|
.article-inline-cta{margin:34px 0;padding:24px 28px;background:#ffbf00;border-radius:3px;display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between}
|
||||||
|
.article-inline-cta p{margin:0;font-weight:700;color:#111}
|
||||||
|
.article-inline-cta .btn{background:#111;color:#fff;border-color:#111}
|
||||||
|
.article-faq{margin-top:44px}
|
||||||
|
.article-faq details{border-top:1px solid rgba(0,0,0,.12);padding:14px 0}
|
||||||
|
.article-faq details:last-child{border-bottom:1px solid rgba(0,0,0,.12)}
|
||||||
|
.article-faq summary{cursor:pointer;font-weight:700}
|
||||||
|
.article-faq summary:focus-visible{outline:3px solid #ffbf00;outline-offset:3px}
|
||||||
|
.article-faq details p{margin:10px 0 0;line-height:1.7}
|
||||||
|
.article-related{margin-top:44px}
|
||||||
|
.article-related ul{margin:12px 0 0;padding-left:20px;line-height:1.9}
|
||||||
|
.article-review-note{margin-top:28px;font-size:.85rem;opacity:.7}
|
||||||
|
.article-categories,.latest-articles{clear:both}
|
||||||
|
|
||||||
|
/* ---- Intro em duas colunas (TOC + Key takeaways) e sidebar de recursos ---- */
|
||||||
|
.article-intro{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.4fr);gap:22px;margin:0 0 32px}
|
||||||
|
.article-intro .article-takeaways{margin:0}
|
||||||
|
.article-toc{padding:22px 26px;background:#fff;border:1px solid rgba(0,0,0,.12)}
|
||||||
|
.article-toc h2{margin:0 0 10px;font-size:1.1rem}
|
||||||
|
.article-sidebar-cta{padding:26px 24px;background:#111;color:#fff;border-radius:3px}
|
||||||
|
.article-sidebar-cta h3{margin:0 0 10px;color:#fff;font-size:1.15rem}
|
||||||
|
.article-sidebar-cta p{margin:0 0 18px;line-height:1.6;color:rgba(255,255,255,.85)}
|
||||||
|
.article-sidebar-cta .btn{display:block;text-align:center;background:#ffbf00;border-color:#ffbf00;color:#111}
|
||||||
|
@media (max-width:991px){
|
||||||
|
.article-page .main-content{order:1}
|
||||||
|
.article-page .sidebar{order:2;margin-top:40px}
|
||||||
|
}
|
||||||
|
@media (max-width:700px){
|
||||||
|
.article-intro{grid-template-columns:1fr}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/* Eddys Construction & Masonry
|
||||||
|
Category Index Template — v1
|
||||||
|
Scope: category index pages only.
|
||||||
|
Global site styles remain in /css/style.css.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.category-index-page .eddys-category-index {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.category-index-page .eddys-section-intro {
|
||||||
|
max-width: 900px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Future category-card styles belong here so the same component
|
||||||
|
can be reused by Resources, Services and Portfolio indexes. */
|
||||||
|
.category-index-page .eddys-category-card {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep category grids adaptable as the number of categories grows. */
|
||||||
|
.category-index-page .eddys-category-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.category-index-page .eddys-category-grid {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.category-index-page .eddys-category-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* Eddys Construction & Masonry
|
||||||
|
* Category / Section Index Pages
|
||||||
|
*
|
||||||
|
* Purpose:
|
||||||
|
* Reusable CSS hooks for index pages that organize categories and content.
|
||||||
|
*
|
||||||
|
* Scope:
|
||||||
|
* Resources, Services and Portfolio category/index pages.
|
||||||
|
*
|
||||||
|
* Important:
|
||||||
|
* This file does NOT redefine the site's global design system.
|
||||||
|
* Existing /css/style.css and existing component CSS remain authoritative.
|
||||||
|
* These rules are intentionally conservative and avoid overlays, new
|
||||||
|
* visual effects, or forced redesigns.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.eddys-category-index-page {
|
||||||
|
/* Page-level hook only. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
Shared index-page regions
|
||||||
|
--------------------------------------------------------- */
|
||||||
|
|
||||||
|
.eddys-category-index-page .eddys-index-hero {
|
||||||
|
/* Uses the existing hero/parallax system. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-category-index-page .eddys-index-trust {
|
||||||
|
/* Uses the existing trust-strip component. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-category-index-page .eddys-index-intro {
|
||||||
|
/* Uses the existing section spacing and typography. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-category-index-page .eddys-index-content {
|
||||||
|
/* Uses the existing content/card system. */
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-category-index-page .eddys-index-cta {
|
||||||
|
/* Uses the existing final CTA component. */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
Universal category components
|
||||||
|
---------------------------------------------------------
|
||||||
|
These classes are available for future category indexes.
|
||||||
|
They intentionally inherit the site's existing typography,
|
||||||
|
spacing and colors unless a component needs a specific rule.
|
||||||
|
--------------------------------------------------------- */
|
||||||
|
|
||||||
|
.eddys-index-category-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-card {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-card__label {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-card__title {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-card__text {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-card__link {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-list__item {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-category-list__link {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
Optional grouping helpers
|
||||||
|
--------------------------------------------------------- */
|
||||||
|
|
||||||
|
.eddys-index-section {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-section__inner {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-index-section__intro {
|
||||||
|
max-width: 900px;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------
|
||||||
|
Responsive behavior
|
||||||
|
--------------------------------------------------------- */
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.eddys-index-category-grid {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.eddys-index-category-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,473 @@
|
|||||||
|
/*
|
||||||
|
* EDDY'S CONSTRUCTION & MASONRY LLC
|
||||||
|
* HOME PAGE SPECIFIC STYLES (home.css)
|
||||||
|
* =========================================================
|
||||||
|
* Classes exclusivas da página inicial (Index).
|
||||||
|
* =========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
00. HOME — HEADER CONTACT BAR (independent of style.css)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.header-container {
|
||||||
|
column-gap: 56px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
margin-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list {
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list li {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list p {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1199px) {
|
||||||
|
.header-container {
|
||||||
|
column-gap: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list {
|
||||||
|
gap: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list p {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.header-container {
|
||||||
|
gap: 18px;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
margin-bottom: 0;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact {
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list li {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list p {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.header-container {
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 12px;
|
||||||
|
border-top: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list li {
|
||||||
|
width: 100%;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-contact-list i {
|
||||||
|
flex: 0 0 22px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
00b. HOME — HERO SLIDER DOT RESET (dots are <button>s)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.hero-slider .dot {
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
01. HOME — TRUST STRIP
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.eddys-trust-strip {
|
||||||
|
background: #fff;
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item {
|
||||||
|
padding: 24px 18px;
|
||||||
|
text-align: center;
|
||||||
|
border-right: 1px solid #e8e8e8;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item:last-child {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item strong {
|
||||||
|
display: block;
|
||||||
|
margin: 0 0 7px;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.35;
|
||||||
|
letter-spacing: .8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item span {
|
||||||
|
display: block;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
02. HOME — PROMISE (THE EDDY'S PROMISE)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.eddys-eyebrow {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.4;
|
||||||
|
letter-spacing: 1.5px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-promise p {
|
||||||
|
line-height: 1.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-promise .btn {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-promise .btn:focus-visible {
|
||||||
|
outline: 3px solid currentColor;
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
03. HOME — WHY EDDY'S
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.eddys-why {
|
||||||
|
background: #f7f7f7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-section-intro {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 820px;
|
||||||
|
margin: 0 auto 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-section-intro .section-header {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
gap: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 10px 15px;
|
||||||
|
text-align: center;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature > i {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature h3 {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature p {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
04. HOME — RESOURCES
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.eddys-resources {
|
||||||
|
border-top: 1px solid #ededed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-cards {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 30px;
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
background: #fff;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card h3 {
|
||||||
|
margin: 10px 0 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card p {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card a {
|
||||||
|
display: inline-block;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card a i {
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card a:focus-visible {
|
||||||
|
outline: 3px solid currentColor;
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-label {
|
||||||
|
display: block;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.4;
|
||||||
|
letter-spacing: 1.2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
05. HOME — FINAL CTA
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
.eddys-final-cta {
|
||||||
|
position: relative;
|
||||||
|
padding-top: 70px;
|
||||||
|
padding-bottom: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1.65fr) minmax(250px, .75fr);
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: rgba(255, 255, 255, 0.85); /* Fundo claro para contrastar com a imagem Parallax */
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 38px 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy h2 {
|
||||||
|
margin: 0 0 15px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy p {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 32px;
|
||||||
|
background: #ffbf00;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn {
|
||||||
|
min-width: 210px;
|
||||||
|
color: #fff;
|
||||||
|
background: #111;
|
||||||
|
border-color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn:hover {
|
||||||
|
color: #111;
|
||||||
|
background: #fff;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn:focus-visible {
|
||||||
|
outline: 3px solid currentColor;
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
06. ACCESSIBILITY & PRINT (HOME SPECIFIC)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.eddys-resource-card *,
|
||||||
|
.eddys-feature *,
|
||||||
|
.eddys-final-cta-action * {
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
transition: none !important;
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.eddys-trust-strip,
|
||||||
|
.eddys-why,
|
||||||
|
.eddys-resources,
|
||||||
|
.eddys-final-cta {
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================
|
||||||
|
07. RESPONSIVE QUERIES (HOME SPECIFIC)
|
||||||
|
========================================================= */
|
||||||
|
|
||||||
|
/* Tabletes em modo paisagem e Laptops menores (991px) */
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.eddys-trust-grid,
|
||||||
|
.eddys-feature-grid {
|
||||||
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item:nth-child(2n) {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item:nth-child(-n+2) {
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-cards {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablets em modo retrato e Celulares grandes (768px) */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.eddys-trust-grid,
|
||||||
|
.eddys-feature-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item {
|
||||||
|
padding: 20px 16px;
|
||||||
|
border-right: 0;
|
||||||
|
border-bottom: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-trust-item:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature {
|
||||||
|
padding: 10px 5px 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-feature:last-child {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-resource-card {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-card {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy {
|
||||||
|
padding: 28px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy p {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action {
|
||||||
|
padding: 24px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 320px;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/* ==========================================================================
|
||||||
|
PROJECT NAVIGATION BAR (PREVIOUS / ALL / NEXT)
|
||||||
|
========================================================================== */
|
||||||
|
|
||||||
|
.project-navigation-bar {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding: 18px 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-nav-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-nav-item {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-family: "Montserrat", sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #444;
|
||||||
|
transition: color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-nav-item:hover {
|
||||||
|
color: #ffbf00;
|
||||||
|
}
|
||||||
|
|
||||||
|
.project-nav-center .btn-portfolio-all {
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.project-nav-container {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
/*
|
||||||
|
* EDDY'S CONSTRUCTION & MASONRY LLC
|
||||||
|
* SHARED "FINAL CTA" / QUOTE COMPONENT (quote-cta.css)
|
||||||
|
* =========================================================
|
||||||
|
* Substitui o antigo bloco ".quote-banner".
|
||||||
|
* Usado em qualquer página que tenha a seção "eddys-final-cta".
|
||||||
|
* Depende de classes genéricas já existentes no style.css oficial:
|
||||||
|
* .bg-parallax, .bg-overlay-black, .container, .pos-r, .btn, .btn-black, .radius
|
||||||
|
* =========================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
.eddys-eyebrow {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.4;
|
||||||
|
letter-spacing: 1.5px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta {
|
||||||
|
position: relative; /* mantém o bg-overlay-black contido, sem depender do style.css */
|
||||||
|
padding-top: 70px;
|
||||||
|
padding-bottom: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-card {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1.65fr) minmax(250px, .75fr);
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
background: rgba(255, 255, 255, 0.85);
|
||||||
|
border: 1px solid #e5e5e5;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 38px 42px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy h2 {
|
||||||
|
margin: 0 0 15px;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1.35;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy p {
|
||||||
|
max-width: 680px;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 32px;
|
||||||
|
background: #ffbf00;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn {
|
||||||
|
min-width: 210px;
|
||||||
|
color: #fff;
|
||||||
|
background: #111;
|
||||||
|
border-color: #111;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn:hover {
|
||||||
|
color: #111;
|
||||||
|
background: #fff;
|
||||||
|
border-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn:focus-visible {
|
||||||
|
outline: 3px solid currentColor;
|
||||||
|
outline-offset: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.eddys-final-cta-action * {
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
transition: none !important;
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
.eddys-final-cta {
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.eddys-final-cta-card {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy {
|
||||||
|
padding: 28px 24px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-copy p {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action {
|
||||||
|
padding: 24px;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eddys-final-cta-action .btn {
|
||||||
|
width: 100%;
|
||||||
|
max-width: 320px;
|
||||||
|
min-width: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
google-site-verification: googlec7ec1b6082f7b3b7.html
|
||||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 44 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 553 B |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 77 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 103 KiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 64 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 99 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 80 KiB |
|
After Width: | Height: | Size: 107 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 17 KiB |