@@ -25,6 +25,12 @@ copyFileSync(
2525 join ( docsDir , 'logo-footer.png' )
2626) ;
2727
28+ // Copy the brand intro video used as the looping hero on the fractional-cfo page
29+ copyFileSync (
30+ join ( assetsDir , 'animation' , 'Make Bold Intro.mp4' ) ,
31+ join ( docsDir , content . fractionalCfo . video . src )
32+ ) ;
33+
2834// Copy favicon
2935const staticDir = join ( __dirname , 'static' ) ;
3036copyFileSync ( join ( staticDir , 'favicon.png' ) , join ( docsDir , 'favicon.png' ) ) ;
@@ -992,36 +998,20 @@ h1, h2, h3, h4, h5, h6 {
992998.card-spark-link:hover { color: var(--primary); }
993999.card-footer { text-align: center; font-size: 0.75rem; color: var(--muted-fg); opacity: 0.7; padding: 1.5rem 0; }
9941000
995- /* Presentation Carousel */
996- .deck-hero { text-align: center; padding: 4rem 0 2rem ; }
1001+ /* Fractional CFO — video hero + restated content */
1002+ .deck-hero { text-align: center; padding: 2.5rem 0 1.5rem ; }
9971003.deck-hero .kicker { color: var(--primary); font-weight: 800; letter-spacing: 0.18em; text-transform: uppercase; font-size: 0.8rem; }
9981004.deck-hero h1 { font-size: 2.5rem; margin: 0.75rem 0; }
9991005.deck-hero p { color: var(--muted-fg); max-width: 40rem; margin: 0 auto; }
1006+ .deck-intro { color: var(--muted-fg); max-width: 40rem; margin: 2.5rem auto 0; text-align: center; font-size: 1.0625rem; line-height: 1.7; }
10001007.deck { max-width: 64rem; margin: 0 auto 4rem; padding: 0 1rem; }
1001- .deck-viewport { position: relative; overflow: hidden; border-radius: 1.25rem; box-shadow: 0 24px 60px rgba(30,30,30,0.18); }
1002- .deck-track { display: flex; transition: transform 0.5s cubic-bezier(0.4,0,0.2,1); }
1003- .slide {
1004- flex: 0 0 100%; min-height: 30rem; display: flex; flex-direction: column;
1005- justify-content: center; padding: 4rem; gap: 1.25rem;
1006- background: linear-gradient(135deg, #1E1E1E 0%, #2b1208 60%, var(--primary) 140%);
1007- color: #fff; position: relative;
1008- }
1009- .slide-num { position: absolute; top: 1.5rem; right: 2rem; font-size: 0.8rem; letter-spacing: 0.1em; color: rgba(255,255,255,0.45); font-weight: 700; }
1010- .slide-icon { width: 3.5rem; height: 3.5rem; border-radius: 0.875rem; background: rgba(255,255,255,0.1); display: flex; align-items: center; justify-content: center; color: var(--secondary); }
1011- .slide-kicker { color: var(--secondary); font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase; font-size: 0.8rem; }
1012- .slide h2 { font-size: 2.25rem; line-height: 1.15; max-width: 32rem; }
1013- .slide-lead { font-size: 1.25rem; font-weight: 600; color: #fff; }
1014- .slide p { font-size: 1.0625rem; color: rgba(255,255,255,0.82); max-width: 38rem; }
1015- .slide-bullets { display: flex; flex-direction: column; gap: 0.75rem; margin-top: 0.5rem; }
1016- .slide-bullets li { display: flex; align-items: flex-start; gap: 0.625rem; color: rgba(255,255,255,0.9); font-size: 1rem; }
1017- .slide-bullets svg { color: var(--secondary); flex-shrink: 0; margin-top: 0.15rem; }
1018- .deck-controls { display: flex; align-items: center; justify-content: center; gap: 1.5rem; margin-top: 1.5rem; }
1019- .deck-btn { width: 3rem; height: 3rem; border-radius: 50%; border: 1px solid var(--border); background: #fff; color: var(--fg); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: background 0.2s; }
1020- .deck-btn:hover { background: var(--primary); color: #fff; border-color: var(--primary); }
1021- .deck-dots { display: flex; gap: 0.5rem; }
1022- .deck-dot { width: 0.6rem; height: 0.6rem; border-radius: 50%; border: none; background: var(--border); cursor: pointer; padding: 0; }
1023- .deck-dot.active { background: var(--primary); width: 1.75rem; border-radius: 1rem; }
1024- @media (max-width: 640px) { .slide { padding: 2.5rem 1.5rem; min-height: 26rem; } .slide h2 { font-size: 1.6rem; } .deck-hero h1 { font-size: 1.9rem; } }
1008+ .intro-video-frame { position: relative; overflow: hidden; border-radius: 1.25rem; box-shadow: 0 24px 60px rgba(30,30,30,0.18); background: #1E1E1E; aspect-ratio: 16 / 9; }
1009+ .intro-video-frame video { display: block; width: 100%; height: 100%; object-fit: cover; }
1010+ .intro-video-caption { text-align: center; margin-top: 0.875rem; font-size: 0.8125rem; color: var(--muted-fg); font-style: italic; }
1011+ .intro-cta { text-align: center; margin-top: 2rem; }
1012+ .cfo-card-icon { width: 3.5rem; height: 3.5rem; margin-bottom: 1.5rem; }
1013+ .cfo-card-kicker { color: var(--primary); font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; font-size: 0.75rem; display: block; margin-bottom: 0.625rem; }
1014+ @media (max-width: 640px) { .deck-hero h1 { font-size: 1.9rem; } }
10251015` ;
10261016
10271017
@@ -1747,23 +1737,23 @@ function buildContact() {
17471737 </section>` + footer ( ) + closePage ( ) ;
17481738}
17491739
1750- function buildPresentation ( ) {
1751- const p = content . presentation ;
1752- const slides = p . slides . map ( ( s , i ) => {
1753- const lead = s . lead ? `<p class="slide-lead">${ escapeHtml ( s . lead ) } </p>` : '' ;
1754- const bullets = s . bullets ? `<ul class="slide-bullets">${ s . bullets . map ( b => `<li>${ icon ( 'check-circle' , 18 ) } <span>${ escapeHtml ( b ) } </span></li>` ) . join ( '' ) } </ul>` : '' ;
1740+ function buildFractionalCfo ( ) {
1741+ const p = content . fractionalCfo ;
1742+ const intro = p . slides [ 0 ] ;
1743+ const closing = p . slides [ p . slides . length - 1 ] ;
1744+ const middleSlides = p . slides . slice ( 1 , - 1 ) ;
1745+
1746+ const cards = middleSlides . map ( s => {
1747+ const bullets = s . bullets ? `<div class="features">${ s . bullets . map ( b => `<div class="feature">${ escapeHtml ( b ) } </div>` ) . join ( '' ) } </div>` : '' ;
17551748 return `
1756- <article class="slide" role="group" aria-roledescription="slide" aria-label="${ i + 1 } of ${ p . slides . length } ">
1757- <span class="slide-num">${ String ( i + 1 ) . padStart ( 2 , '0' ) } / ${ String ( p . slides . length ) . padStart ( 2 , '0' ) } </span>
1758- <div class="slide-icon">${ icon ( s . icon , 26 ) } </div>
1759- <span class="slide-kicker">${ escapeHtml ( s . kicker ) } </span>
1760- <h2>${ escapeHtml ( s . title ) } </h2>
1761- ${ lead }
1762- <p>${ escapeHtml ( s . body ) } </p>
1763- ${ bullets }
1764- </article>` ;
1749+ <div class="service-card">
1750+ <div class="icon-box cfo-card-icon">${ icon ( s . icon , 40 ) } </div>
1751+ <span class="cfo-card-kicker">${ escapeHtml ( s . kicker ) } </span>
1752+ <h3>${ escapeHtml ( s . title ) } </h3>
1753+ <p>${ escapeHtml ( s . body ) } </p>
1754+ ${ bullets }
1755+ </div>` ;
17651756 } ) . join ( '' ) ;
1766- const dots = p . slides . map ( ( _ , i ) => `<button class="deck-dot${ i === 0 ? ' active' : '' } " data-go="${ i } " aria-label="Go to slide ${ i + 1 } "></button>` ) . join ( '' ) ;
17671757
17681758 return htmlHead (
17691759 'Fractional CFO & Executive Leadership' ,
@@ -1778,32 +1768,39 @@ function buildPresentation() {
17781768 </div>
17791769
17801770 <div class="deck">
1781- <div class="deck-viewport">
1782- <div class="deck-track" id="deck-track">${ slides }
1783- </div>
1784- </div>
1785- <div class="deck-controls">
1786- <button class="deck-btn" id="deck-prev" aria-label="Previous slide">${ icon ( 'arrow-left' , 22 ) } </button>
1787- <div class="deck-dots">${ dots } </div>
1788- <button class="deck-btn" id="deck-next" aria-label="Next slide">${ icon ( 'arrow-right' , 22 ) } </button>
1771+ <div class="intro-video-frame">
1772+ <video autoplay muted loop playsinline aria-label="${ escapeAttr ( p . video . label ) } ">
1773+ <source src="${ escapeAttr ( p . video . src ) } " type="video/mp4">
1774+ </video>
17891775 </div>
1790- <div style="text-align:center;margin-top:2.5rem">
1776+ <p class="intro-video-caption">${ escapeHtml ( p . video . label ) } </p>
1777+ <div class="intro-cta">
17911778 <a href="contact.html" class="btn-primary">Start Your Climb to Value</a>
17921779 </div>
1780+ <p class="deck-intro">${ escapeHtml ( intro . body ) } </p>
17931781 </div>
17941782
1795- <script>
1796- (function () {
1797- var track = document.getElementById('deck-track');
1798- var dots = Array.prototype.slice.call(document.querySelectorAll('.deck-dot'));
1799- var total = dots.length, i = 0;
1800- function go(n) { i = (n + total) % total; track.style.transform = 'translateX(-' + (i * 100) + '%)'; dots.forEach(function (d, x) { d.classList.toggle('active', x === i); }); }
1801- document.getElementById('deck-prev').onclick = function () { go(i - 1); };
1802- document.getElementById('deck-next').onclick = function () { go(i + 1); };
1803- dots.forEach(function (d) { d.onclick = function () { go(parseInt(d.dataset.go, 10)); }; });
1804- document.addEventListener('keydown', function (e) { if (e.key === 'ArrowLeft') go(i - 1); if (e.key === 'ArrowRight') go(i + 1); });
1805- })();
1806- </script>` + footer ( ) + closePage ( ) ;
1783+ <section class="section-muted section">
1784+ <div class="container">
1785+ <div class="text-center max-w-2xl mx-auto mb-12">
1786+ <h2 class="text-3xl font-heading font-bold mb-4">${ escapeHtml ( p . sectionHeading ) } </h2>
1787+ <p class="text-muted">${ escapeHtml ( p . sectionIntro ) } </p>
1788+ </div>
1789+ <div class="grid grid-2-lg" style="gap:1.5rem">${ cards }
1790+ </div>
1791+ </div>
1792+ </section>
1793+
1794+ <section class="section-primary section">
1795+ <div class="container text-center">
1796+ <h2 class="text-3xl font-heading font-bold mb-6">${ escapeHtml ( closing . title ) } </h2>
1797+ <p class="text-white-80 max-w-2xl mx-auto mb-10 text-lg">${ escapeHtml ( closing . body ) } </p>
1798+ <div class="flex flex-col sm-flex-row gap-4 justify-center">
1799+ <a href="contact.html" class="btn-white btn-large">Start Your Climb to Value</a>
1800+ <a href="services-cfo.html" class="btn-outline-white btn-large">Explore Our Services</a>
1801+ </div>
1802+ </div>
1803+ </section>` + footer ( ) + closePage ( ) ;
18071804}
18081805
18091806function buildNotFound ( ) {
@@ -2004,7 +2001,7 @@ const pages = [
20042001 { file : 'about.html' , builder : buildAbout } ,
20052002 { file : 'cfo-of-the-year.html' , builder : buildCfoOfTheYear } ,
20062003 { file : 'contact.html' , builder : buildContact } ,
2007- { file : 'fractional-cfo.html' , builder : buildPresentation } ,
2004+ { file : 'fractional-cfo.html' , builder : buildFractionalCfo } ,
20082005 { file : '404.html' , builder : buildNotFound } ,
20092006 ...cards . map ( person => ( { file : `${ person . slug } /card/index.html` , builder : ( ) => buildCard ( person ) } ) ) ,
20102007] ;
0 commit comments