/* Olive Beacon — self-hosted typefaces (V12).
   Self-hosted rather than hotlinked from Google so no visitor IP is handed to a
   third party on page load; the site carries a UK privacy notice. */
@font-face{font-family:'Inter';font-style:normal;font-weight:400 800;font-display:swap;src:url('../fonts/inter-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 800;font-display:swap;src:url('../fonts/inter-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Instrument Serif';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/instrumentserif-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Instrument Serif';font-style:normal;font-weight:400;font-display:swap;src:url('../fonts/instrumentserif-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Instrument Serif';font-style:italic;font-weight:400;font-display:swap;src:url('../fonts/instrumentserif-italic-latin.woff2') format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Instrument Serif';font-style:italic;font-weight:400;font-display:swap;src:url('../fonts/instrumentserif-italic-latin-ext.woff2') format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* Olive Beacon launch site — zero-build static release */
:root{--ivory:rgb(var(--c-text));--sage:rgb(var(--c-surface));--sage2:rgb(var(--c-surface));--forest:rgb(var(--c-surface));--olive:rgb(var(--c-accent));--beacon:rgb(var(--c-gold));--moss:rgb(var(--c-accent));--gold:rgb(var(--c-gold-hi));--ink:rgb(var(--c-bg2));--muted:rgb(var(--c-text-mut));--line:rgb(var(--c-surface) / .14);--white:rgb(var(--c-text));--radius:28px;--radius-sm:18px;--shadow:0 24px 80px rgb(var(--c-bg2) / .12);--serif:Georgia,'Times New Roman',serif;--sans:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif}
*{box-sizing:border-box}html{scroll-behavior:smooth;background:var(--ivory)}body{margin:0;color:var(--ink);background:var(--ivory);font-family:var(--sans);-webkit-font-smoothing:antialiased;overflow-x:hidden}img{max-width:100%;display:block;height:auto}a{color:inherit;text-decoration:none}button,input,textarea,select{font:inherit}.shell{width:min(1240px,calc(100% - 48px));margin:auto}.section{padding:116px 0;position:relative}.section-sage{background:var(--sage)}.section-dark{background:var(--forest);color:var(--ivory)}.eyebrow{margin:0 0 20px;text-transform:uppercase;letter-spacing:.18em;font-size:11px;font-weight:800;color:var(--moss)}.section-dark .eyebrow{color:var(--gold)}h1,h2,h3,p{margin-top:0}.display{font:500 clamp(54px,7.4vw,104px)/.92 var(--serif);letter-spacing:-.065em}.section-title{font:500 clamp(42px,5vw,68px)/1 var(--serif);letter-spacing:-.05em;margin:0}.lede{font-size:clamp(17px,1.7vw,21px);line-height:1.7;color:var(--muted);max-width:720px}.section-dark .lede{color:rgb(var(--c-text-mut))}.section-head{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(300px,.65fr);gap:60px;align-items:end;margin-bottom:58px}.section-head .lede{margin:0}.btn{display:inline-flex;align-items:center;justify-content:center;gap:10px;min-height:52px;padding:0 21px;border-radius:999px;font-size:13px;font-weight:800;letter-spacing:.01em;transition:transform .25s ease,background .25s ease,border-color .25s ease,box-shadow .25s ease}.btn:hover{transform:translateY(-2px)}.btn-primary{background:var(--beacon);color:var(--forest);box-shadow:0 12px 30px rgb(var(--c-gold) / .16)}.btn-primary:hover{background:rgb(var(--c-gold-hi))}.btn-light{border:1px solid rgb(var(--c-text) / .28);color:var(--ivory);background:rgb(var(--c-text) / .06);backdrop-filter:blur(8px)}.btn-light:hover{background:rgb(var(--c-text) / .12)}.btn-outline{border:1px solid var(--line);background:transparent;color:var(--forest)}.btn-outline:hover{border-color:rgb(var(--c-accent) / .45);background:rgb(var(--c-gold) / .08)}.text-link{display:inline-flex;gap:9px;align-items:center;font-weight:800;font-size:13px}.text-link::after{content:'↗';transition:transform .2s}.text-link:hover::after{transform:translate(2px,-2px)}
.skip{position:fixed;left:16px;top:-80px;z-index:2000;background:var(--ivory);color:var(--forest);padding:12px 18px;border-radius:12px}.skip:focus{top:16px}.site-header{position:fixed;inset:0 0 auto;z-index:1000;background:rgb(var(--c-surface) / .84);border-bottom:1px solid rgb(var(--c-text) / .09);backdrop-filter:blur(18px)}.header-inner{height:76px;display:grid;grid-template-columns:220px 1fr auto;align-items:center;gap:28px}.logo{width:188px;height:auto}.desktop-nav{display:flex;justify-content:center;gap:30px}.desktop-nav a{font-size:13px;font-weight:700;color:rgb(var(--c-text-mut));transition:color .2s}.desktop-nav a:hover,.desktop-nav a[aria-current=page]{color:var(--ivory)}.menu-btn{display:none;width:44px;height:44px;border:1px solid rgb(var(--c-text) / .18);background:transparent;color:var(--ivory);border-radius:50%;cursor:pointer}.mobile-nav{display:none;position:absolute;top:76px;left:0;right:0;background:rgb(var(--c-surface) / .98);border-top:1px solid rgb(var(--c-text) / .08);padding:18px 24px 28px}.mobile-nav.open{display:grid}.mobile-nav a{padding:14px 0;border-bottom:1px solid rgb(var(--c-text) / .08);color:var(--ivory);font-weight:700}.mobile-nav .btn{margin-top:18px;border:0}
.hero{min-height:860px;display:flex;align-items:center;position:relative;overflow:hidden;background:var(--forest)}.hero-bg{position:absolute;inset:0;background-image:linear-gradient(90deg,rgb(var(--c-surface) / .98) 2%,rgb(var(--c-surface) / .89) 43%,rgb(var(--c-surface) / .48) 100%),url('../images/hero-bg-desktop.webp');background-size:cover;background-position:center}.hero-bg::after{content:'';position:absolute;inset:0;background:radial-gradient(circle at 72% 46%,rgb(var(--c-gold-hi) / .15),transparent 25%),radial-gradient(circle at 78% 35%,rgb(var(--c-gold) / .12),transparent 34%)}.hero-grid{position:relative;z-index:2;display:grid;grid-template-columns:.92fr 1.08fr;align-items:center;gap:34px;padding:140px 0 80px}.hero-copy{max-width:690px}.hero .display{color:var(--ivory);margin:0 0 26px}.hero .display em{font-style:normal;color:var(--gold)}.hero .lede{color:rgb(var(--c-text-mut));font-size:19px;margin-bottom:32px}.hero-actions{display:flex;gap:12px;flex-wrap:wrap}.hero-note{font-size:12px;margin:22px 0 0;color:rgb(var(--c-text) / .43)}.hero-visual{min-height:600px;position:relative}.hero-laptop{position:absolute;width:106%;left:-5%;top:14%;filter:drop-shadow(0 32px 55px rgba(0,0,0,.34));transform:rotate(-1.2deg)}.hero-phone{position:absolute;width:28%;right:-1%;bottom:5%;filter:drop-shadow(0 30px 34px rgba(0,0,0,.33));transform:rotate(3deg)}.signal-orbit{position:absolute;width:520px;height:520px;border:1px solid rgb(var(--c-gold-hi) / .13);border-radius:50%;right:-60px;top:35px}.signal-orbit::before,.signal-orbit::after{content:'';position:absolute;border-radius:50%;border:1px solid rgb(var(--c-gold) / .08);inset:62px}.signal-orbit::after{inset:130px}
.approach-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}.approach-card{position:relative;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:rgb(var(--c-text));min-height:560px;box-shadow:0 18px 48px rgb(var(--c-bg2) / .05);transition:transform .3s ease,box-shadow .3s ease}.approach-card:hover{transform:translateY(-7px);box-shadow:var(--shadow)}.approach-media{height:310px;background:linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-text)));overflow:hidden}.approach-media img{width:100%;height:100%;object-fit:cover;object-position:top center;transition:transform .55s cubic-bezier(.2,.7,.2,1)}.approach-card:hover .approach-media img{transform:scale(1.035)}.approach-copy{padding:28px}.approach-num{font-size:11px;letter-spacing:.15em;color:var(--moss);font-weight:800}.approach-copy h3{font:500 34px/1.05 var(--serif);letter-spacing:-.04em;margin:52px 0 12px}.approach-copy p{color:var(--muted);line-height:1.65;margin:0}
.services-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}.service-card{position:relative;border-radius:var(--radius);overflow:hidden;min-height:650px;border:1px solid var(--line);background:var(--ivory);display:flex;flex-direction:column}.service-card:nth-child(2){background:#e7ebdc}.service-card:nth-child(3){background:var(--forest);color:var(--ivory)}.service-media{height:320px;overflow:hidden}.service-media img{width:100%;height:100%;object-fit:cover;transition:transform .5s ease}.service-card:hover .service-media img{transform:scale(1.035)}.service-copy{padding:30px;display:flex;flex-direction:column;flex:1}.service-kicker{font-size:10px;text-transform:uppercase;letter-spacing:.16em;font-weight:800;color:var(--moss)}.service-card:nth-child(3) .service-kicker{color:var(--gold)}.service-copy h3{font:500 34px/1.05 var(--serif);letter-spacing:-.04em;margin:14px 0}.service-copy p{color:var(--muted);line-height:1.65}.service-card:nth-child(3) .service-copy p{color:rgb(var(--c-text-mut))}.service-copy .text-link{margin-top:auto}
.journey-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}.journey-card{background:rgb(var(--c-text) / .045);border:1px solid rgb(var(--c-text) / .11);border-radius:var(--radius);overflow:hidden;transition:transform .3s ease,border-color .3s}.journey-card:hover{transform:translateY(-6px);border-color:rgb(var(--c-gold-hi) / .34)}.journey-media{height:330px;background:linear-gradient(180deg,rgb(var(--c-tint) / .03),transparent);overflow:hidden}.journey-media img{width:100%;height:100%;object-fit:cover}.journey-copy{padding:27px}.journey-copy span{font-size:10px;letter-spacing:.15em;color:var(--gold);font-weight:800}.journey-copy h3{font:500 36px/1 var(--serif);margin:48px 0 12px}.journey-copy p{color:rgb(var(--c-text-mut));line-height:1.7;margin-bottom:0}
.product-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}.product-card{border:1px solid var(--line);background:rgb(var(--c-text));border-radius:var(--radius);overflow:hidden;transition:transform .3s ease,box-shadow .3s ease}.product-card:hover{transform:translateY(-6px);box-shadow:var(--shadow)}.product-media{height:360px;background:radial-gradient(circle at 65% 30%,rgb(var(--c-gold-hi) / .28),transparent 34%),linear-gradient(145deg,rgb(var(--c-text)),rgb(var(--c-surface)));display:grid;place-items:center;padding:32px}.product-media img{width:100%;height:100%;object-fit:contain;transition:transform .4s ease}.product-card:hover .product-media img{transform:scale(1.04)}.product-copy{padding:28px}.product-copy h3{font:500 34px/1.06 var(--serif);letter-spacing:-.04em;margin-bottom:11px}.product-copy p{color:var(--muted);line-height:1.65;min-height:78px}.product-note{margin-top:26px;padding:18px 20px;border:1px solid var(--line);border-radius:16px;font-size:13px;color:var(--muted);background:rgb(var(--c-tint) / .55)}
.bundle-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}.bundle-card{background:rgb(var(--c-text) / .82);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;transition:transform .3s ease,box-shadow .3s ease}.bundle-card:hover{transform:translateY(-6px);box-shadow:var(--shadow)}.bundle-media{height:330px;position:relative;background:radial-gradient(circle at 74% 26%,rgb(var(--c-gold-hi) / .28),transparent 36%),linear-gradient(145deg,#f6f6ef,#e8ecde);overflow:hidden}.bundle-web{position:absolute;left:-4%;top:15%;width:82%;height:68%;object-fit:cover;border-radius:18px;box-shadow:0 22px 48px rgb(var(--c-bg2) / .18);transform:rotate(-1deg)}.bundle-product{position:absolute;right:2%;bottom:0;width:39%;height:65%;object-fit:contain;filter:drop-shadow(0 22px 25px rgb(var(--c-bg2) / .22))}.bundle-copy{padding:28px}.bundle-copy h3{font:500 32px/1.05 var(--serif);letter-spacing:-.04em;margin:12px 0}.bundle-copy p{color:var(--muted);line-height:1.65;min-height:95px}.bundle-footer{margin-top:30px;padding-top:28px;border-top:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:24px}.bundle-footer p{margin:0;color:var(--muted)}
.industry-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}.industry-card{min-height:260px;border:1px solid rgb(var(--c-text) / .11);border-radius:22px;padding:28px;background:rgb(var(--c-text) / .035);position:relative;overflow:hidden;transition:background .25s,transform .25s,border-color .25s}.industry-card::after{content:'';position:absolute;width:140px;height:140px;border-radius:50%;border:1px solid rgb(var(--c-gold-hi) / .1);right:-60px;bottom:-60px;transition:transform .35s}.industry-card:hover{background:rgb(var(--c-text) / .065);transform:translateY(-4px);border-color:rgb(var(--c-gold-hi) / .27)}.industry-card:hover::after{transform:scale(1.45)}.industry-card .index{font-size:10px;color:var(--gold);letter-spacing:.15em;font-weight:800}.industry-card h3{font:500 28px/1.08 var(--serif);letter-spacing:-.03em;margin:70px 0 10px}.industry-card p{color:rgb(var(--c-text-mut));line-height:1.6;margin:0}
.process-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}.process-step{background:var(--ivory);padding:28px;min-height:300px;position:relative}.process-step .num{display:inline-grid;place-items:center;width:42px;height:42px;border-radius:50%;background:var(--forest);color:var(--ivory);font-size:11px;font-weight:800}.process-step h3{font:500 29px/1 var(--serif);margin:80px 0 12px}.process-step p{color:var(--muted);line-height:1.6;font-size:14px}.process-step::after{content:'';position:absolute;top:49px;left:70px;right:-1px;height:1px;background:rgb(var(--c-accent) / .28)}
.work-card{display:grid;grid-template-columns:1.15fr .85fr;border-radius:var(--radius);overflow:hidden;background:rgb(var(--c-text));border:1px solid var(--line);min-height:520px}.work-media{background:linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-text)));display:grid;place-items:center;padding:36px;overflow:hidden}.work-media img{width:100%;height:100%;object-fit:contain}.work-copy{padding:52px;display:flex;flex-direction:column;justify-content:center}.work-label{display:inline-flex;align-self:flex-start;padding:8px 11px;border-radius:999px;background:var(--sage2);color:var(--moss);font-size:10px;font-weight:800;letter-spacing:.14em;text-transform:uppercase}.work-copy h3{font:500 46px/.98 var(--serif);letter-spacing:-.05em;margin:24px 0 16px}.work-copy p{color:var(--muted);line-height:1.7}.why-grid{display:grid;grid-template-columns:.85fr 1.15fr;gap:80px;align-items:start}.why-grid h2{font:500 clamp(44px,5vw,70px)/.98 var(--serif);letter-spacing:-.055em}.why-copy{font-size:17px;line-height:1.8;color:var(--muted)}.principles{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:26px}.principle{padding:15px 16px;border:1px solid var(--line);border-radius:14px;font-weight:750;font-size:13px;background:rgb(var(--c-tint) / .48)}
.faq-grid{display:grid;grid-template-columns:.7fr 1.3fr;gap:80px}.faq-list{border-top:1px solid var(--line)}.faq-item{border-bottom:1px solid var(--line)}.faq-q{width:100%;border:0;background:transparent;padding:22px 0;display:flex;justify-content:space-between;gap:20px;align-items:center;text-align:left;color:var(--forest);font-weight:800;cursor:pointer}.faq-q span:last-child{font-size:24px;font-weight:400;transition:transform .2s}.faq-item.open .faq-q span:last-child{transform:rotate(45deg)}.faq-a{max-height:0;overflow:hidden;transition:max-height .32s ease}.faq-a p{color:var(--muted);line-height:1.7;padding:0 42px 22px 0;margin:0}.faq-item.open .faq-a{max-height:260px}.final-cta{padding:120px 0;overflow:hidden;position:relative;isolation:isolate}.final-inner{position:relative;z-index:2;max-width:900px}.final-inner h2{font:500 clamp(52px,7vw,88px)/.96 var(--serif);letter-spacing:-.06em;margin-bottom:22px}.final-inner p{color:rgb(var(--c-text-mut));font-size:18px;line-height:1.7;max-width:660px}.signal-grid{position:absolute;inset:0;opacity:.2;background-image:linear-gradient(rgb(var(--c-gold-hi) / .08) 1px,transparent 1px),linear-gradient(90deg,rgb(var(--c-gold-hi) / .08) 1px,transparent 1px);background-size:48px 48px;mask-image:linear-gradient(90deg,transparent,black)}
.site-footer{background:rgb(var(--c-bg2));color:var(--ivory);padding:72px 0 28px}.footer-grid{display:grid;grid-template-columns:1.7fr 1fr 1fr 1fr;gap:56px}.footer-brand p{color:rgb(var(--c-text-mut));line-height:1.7;max-width:390px;font-size:14px;margin-top:25px}.footer-col h3{font-size:11px;text-transform:uppercase;letter-spacing:.15em;color:var(--gold);margin-bottom:18px}.footer-col a{display:block;color:rgb(var(--c-text-mut));font-size:13px;padding:7px 0}.footer-col a:hover{color:var(--ivory)}.footer-bottom{margin-top:58px;padding-top:22px;border-top:1px solid rgb(var(--c-text) / .09);display:flex;justify-content:space-between;gap:20px;color:rgb(var(--c-text) / .35);font-size:11px}
.page-hero{min-height:590px;display:flex;align-items:flex-end;background:var(--forest);color:var(--ivory);position:relative;overflow:hidden}.page-hero::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 76% 32%,rgb(var(--c-gold-hi) / .14),transparent 24%),linear-gradient(135deg,transparent 45%,rgb(var(--c-gold) / .07))}.page-hero-inner{position:relative;z-index:2;padding:150px 0 76px;max-width:980px}.page-hero h1{font:500 clamp(54px,7vw,88px)/.96 var(--serif);letter-spacing:-.06em;margin-bottom:22px}.page-hero p:last-child{color:rgb(var(--c-text-mut));font-size:19px;line-height:1.7;max-width:760px}.content-grid{display:grid;grid-template-columns:.78fr 1.22fr;gap:72px;align-items:start}.content-grid h2{font:500 clamp(42px,4.8vw,64px)/1 var(--serif);letter-spacing:-.05em}.rich{font-size:17px;line-height:1.8;color:var(--muted)}.feature-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:26px}.feature{padding:15px 16px;border:1px solid var(--line);border-radius:14px;background:rgb(var(--c-tint) / .5);font-size:13px;font-weight:750}.service-detail{display:grid;grid-template-columns:.8fr 1.2fr;gap:70px;padding:58px 0;border-top:1px solid var(--line)}.service-detail:first-child{border-top:0}.service-detail h2{font:500 46px/1 var(--serif);letter-spacing:-.04em}.tags{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:24px 0}.tag{padding:13px 15px;border-radius:13px;background:rgb(var(--c-tint) / .6);border:1px solid var(--line);font-size:13px}.product-detail{display:grid;grid-template-columns:1.1fr .9fr;gap:70px;align-items:center}.product-detail-media{min-height:570px;display:grid;place-items:center;background:linear-gradient(145deg,rgb(var(--c-text)),rgb(var(--c-surface)));border-radius:var(--radius);padding:48px;border:1px solid var(--line)}.product-detail-media img{max-height:470px;object-fit:contain}.facts{margin:30px 0;border-top:1px solid var(--line)}.fact{display:flex;justify-content:space-between;gap:22px;padding:14px 0;border-bottom:1px solid var(--line);font-size:14px}.fact span:first-child{color:var(--muted)}.fact span:last-child{font-weight:800;text-align:right}.form{display:grid;gap:16px}.form-row{display:grid;grid-template-columns:1fr 1fr;gap:16px}.field{display:grid;gap:7px}.field label{font-size:12px;font-weight:800}.field input,.field textarea,.field select{width:100%;border:1px solid rgb(var(--c-surface) / .18);border-radius:13px;background:rgb(var(--c-tint) / .76);padding:15px 16px;outline:none}.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--moss);box-shadow:0 0 0 4px rgb(var(--c-gold) / .13)}.field textarea{min-height:130px;resize:vertical}.form-note{font-size:12px;color:var(--muted);line-height:1.6}.legal{max-width:860px}.legal h2{font:500 34px/1.1 var(--serif);margin:46px 0 14px}.legal p,.legal li{color:var(--muted);line-height:1.75}.legal strong{color:var(--forest)}.legal ul{padding-left:20px}.not-found{min-height:80vh;display:grid;place-items:center;text-align:center;padding:120px 20px;background:var(--forest);color:var(--ivory)}.not-found h1{font:500 clamp(80px,14vw,170px)/.8 var(--serif);color:var(--gold);margin-bottom:20px}
.reveal{opacity:0;transform:translateY(24px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.2,1)}.reveal.visible{opacity:1;transform:none}
@media(max-width:1050px){.desktop-nav,.desktop-cta{display:none}.header-inner{grid-template-columns:1fr auto}.menu-btn{display:grid;place-items:center}.hero-grid{grid-template-columns:1fr;gap:0}.hero{min-height:980px;align-items:flex-start}.hero-copy{padding-top:70px}.hero-visual{min-height:480px;margin-top:-20px}.hero-laptop{width:88%;left:0}.hero-phone{width:19%;right:7%;bottom:0}.section-head{grid-template-columns:1fr;gap:22px}.approach-grid,.services-grid,.journey-grid,.product-grid,.bundle-grid{grid-template-columns:1fr 1fr}.approach-card:last-child,.service-card:last-child,.journey-card:last-child,.product-card:last-child,.bundle-card:last-child{grid-column:1/-1}.industry-grid{grid-template-columns:1fr 1fr}.process-grid{grid-template-columns:1fr 1fr}.work-card,.why-grid,.faq-grid,.content-grid,.service-detail,.product-detail{grid-template-columns:1fr}.footer-grid{grid-template-columns:1.4fr 1fr 1fr}.footer-brand{grid-column:1/-1}.product-detail-media{min-height:460px}}
@media(max-width:720px){.shell{width:min(100% - 28px,1240px)}.section{padding:82px 0}.header-inner{height:68px}.logo{width:168px}.mobile-nav{top:68px}.hero{min-height:900px}.hero-bg{background-image:linear-gradient(180deg,rgb(var(--c-surface) / .96) 0%,rgb(var(--c-surface) / .82) 52%,rgb(var(--c-surface) / .62) 100%),url('../images/hero-bg-mobile.webp');background-position:center top}.hero-grid{padding:100px 0 36px}.hero-copy{padding-top:0}.hero .display{font-size:clamp(48px,13.5vw,72px)}.hero .lede{font-size:16px}.hero-actions{align-items:stretch}.hero-actions .btn{width:100%}.hero-visual{min-height:315px;margin:26px -14px 0}.hero-laptop{width:100%;left:-5%;top:12%}.hero-phone{width:24%;right:1%;bottom:1%}.signal-orbit{width:300px;height:300px;right:-120px}.section-title{font-size:42px}.approach-grid,.services-grid,.journey-grid,.product-grid,.bundle-grid,.industry-grid,.process-grid,.feature-grid,.tags,.form-row{grid-template-columns:1fr}.approach-card:last-child,.service-card:last-child,.journey-card:last-child,.product-card:last-child,.bundle-card:last-child{grid-column:auto}.approach-card{min-height:auto}.approach-media{height:260px}.service-card{min-height:auto}.service-media{height:260px}.journey-media{height:280px}.product-media{height:300px}.bundle-media{height:300px}.bundle-footer{align-items:stretch;flex-direction:column}.bundle-footer .btn{width:100%}.industry-card{min-height:220px}.process-step{min-height:240px}.process-step h3{margin-top:54px}.work-copy{padding:32px}.work-copy h3{font-size:38px}.principles{grid-template-columns:1fr}.footer-grid{grid-template-columns:1fr 1fr;gap:36px}.footer-brand{grid-column:1/-1}.footer-bottom{flex-direction:column}.page-hero{min-height:500px}.page-hero-inner{padding:125px 0 56px}.page-hero h1{font-size:50px}.content-grid,.service-detail,.product-detail{gap:28px}.product-detail-media{min-height:360px;padding:25px}.faq-grid{gap:28px}.final-cta{padding:90px 0}.final-inner h2{font-size:52px}}
@media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}.reveal{opacity:1;transform:none;transition:none}*{animation:none!important;transition-duration:.01ms!important}}

/* =============================
   Premium polish pass — V2
   ============================= */
:root{--ease-premium:cubic-bezier(.2,.72,.22,1);--header-h:76px}

/* Premium translucent navigation / watermark lockup */
.site-header{transition:background .35s var(--ease-premium),box-shadow .35s var(--ease-premium),border-color .35s var(--ease-premium)}
.site-header::after{content:'';position:absolute;left:0;right:0;bottom:-1px;height:1px;background:linear-gradient(90deg,transparent,rgb(var(--c-gold-hi) / .26),transparent);opacity:.36;pointer-events:none}
.site-header.scrolled{background:rgb(var(--c-surface) / .94);box-shadow:0 16px 50px rgb(var(--c-bg) / .2);border-color:rgb(var(--c-gold-hi) / .08)}
.header-inner{transition:height .35s var(--ease-premium)}
.site-header.scrolled .header-inner{height:68px}
.brand-link{display:inline-flex;align-items:center;width:max-content;position:relative;padding:4px 0;isolation:isolate}
.brand-link::before{content:'';position:absolute;inset:-14px -20px;border-radius:999px;background:radial-gradient(circle at 28% 50%,rgb(var(--c-gold-hi) / .11),transparent 58%);opacity:0;transform:scale(.92);transition:opacity .35s var(--ease-premium),transform .35s var(--ease-premium);z-index:-1}
.brand-link:hover::before,.brand-link:focus-visible::before{opacity:1;transform:scale(1)}
.header-watermark{width:202px;height:auto;object-fit:contain;filter:drop-shadow(0 1px 10px rgb(var(--c-gold-hi) / .06));transition:filter .35s var(--ease-premium),transform .35s var(--ease-premium),opacity .35s var(--ease-premium)}
.brand-link:hover .header-watermark{filter:drop-shadow(0 1px 15px rgb(var(--c-gold-hi) / .18));transform:translateY(-1px)}
.footer-logo{width:188px;height:auto}
.desktop-nav a{position:relative;padding:29px 0;transition:color .25s var(--ease-premium),opacity .25s var(--ease-premium)}
.desktop-nav a::after{content:'';position:absolute;left:50%;right:50%;bottom:20px;height:1px;background:linear-gradient(90deg,var(--gold),var(--beacon));transition:left .3s var(--ease-premium),right .3s var(--ease-premium);opacity:.85}
.desktop-nav a:hover::after,.desktop-nav a[aria-current=page]::after{left:0;right:0}
.site-header.scrolled .desktop-nav a{padding-top:25px;padding-bottom:25px}

/* Page progress adds life without getting in the way */
.scroll-progress{position:fixed;left:0;top:0;height:2px;width:var(--scroll,0%);z-index:1500;background:linear-gradient(90deg,var(--beacon),var(--gold));box-shadow:0 0 16px rgb(var(--c-gold-hi) / .35);pointer-events:none}

/* Buttons: subtle glass/highlight motion */
.btn{position:relative;overflow:hidden;isolation:isolate;will-change:transform}
.btn::before{content:'';position:absolute;top:-80%;left:-55%;width:36%;height:260%;background:linear-gradient(90deg,transparent,rgb(var(--c-tint) / .35),transparent);transform:rotate(18deg) translateX(-220%);transition:transform .7s var(--ease-premium);z-index:-1}
.btn:hover::before{transform:rotate(18deg) translateX(520%)}
.btn:active{transform:translateY(0) scale(.985)}
.text-link{position:relative;padding-bottom:3px}
.text-link::before{content:'';position:absolute;left:0;right:100%;bottom:0;height:1px;background:currentColor;opacity:.45;transition:right .28s var(--ease-premium)}
.text-link:hover::before{right:0}

/* Hero: corrected full-device presentation + refined interactive depth */
.hero-copy>*{will-change:transform,opacity}
.hero-visual{isolation:isolate;perspective:1200px}
.hero-visual::before{content:'';position:absolute;inset:9% 1% 5% 4%;border:1px solid rgb(var(--c-gold-hi) / .09);border-radius:42px;background:linear-gradient(145deg,rgb(var(--c-text) / .025),rgb(var(--c-text) / .006));backdrop-filter:blur(1px);transform:rotate(-2deg);pointer-events:none}
.hero-laptop,.hero-phone{transition:transform .7s var(--ease-premium),filter .7s var(--ease-premium);will-change:transform}
.hero-laptop{object-fit:contain}
.hero-phone{object-fit:contain}
.hero-visual:hover .hero-laptop{filter:drop-shadow(0 38px 65px rgba(0,0,0,.4))}
.hero-visual:hover .hero-phone{filter:drop-shadow(0 34px 40px rgba(0,0,0,.42))}
.signal-orbit{animation:orbit-breathe 7s ease-in-out infinite}
.signal-orbit::before{animation:orbit-breathe 7s ease-in-out 1s infinite reverse}
@keyframes orbit-breathe{0%,100%{transform:scale(1);opacity:.7}50%{transform:scale(1.045);opacity:1}}

/* Images that contain designed text must never be cropped */
.approach-media{height:360px;display:grid;place-items:center;padding:16px;background:radial-gradient(circle at 70% 25%,rgb(var(--c-gold-hi) / .16),transparent 32%),linear-gradient(145deg,rgb(var(--c-text)),#e7eadf)}
.approach-media img{object-fit:contain!important;object-position:center!important;width:100%;height:100%;filter:drop-shadow(0 18px 25px rgb(var(--c-bg2) / .08))}
.service-media{height:330px;display:grid;place-items:center;padding:12px;background:linear-gradient(145deg,rgb(var(--c-tint) / .72),rgb(var(--c-surface) / .7))}
.service-card:nth-child(2) .service-media{background:linear-gradient(145deg,#eef1e5,#dce3d0)}
.service-card:nth-child(3) .service-media{background:linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-surface)))}
.service-media img{object-fit:contain!important;object-position:center!important;width:100%;height:100%;border-radius:14px;filter:drop-shadow(0 14px 24px rgb(var(--c-bg2) / .09))}
.journey-media{height:360px;display:grid;place-items:center;padding:16px;background:linear-gradient(145deg,rgb(var(--c-text) / .055),rgb(var(--c-text) / .015))}
.journey-media img{object-fit:contain!important;object-position:center!important;width:100%;height:100%;border-radius:14px}

/* Shared premium interaction system */
.approach-card,.service-card,.journey-card,.product-card,.bundle-card,.industry-card,.process-step,.work-card,.feature,.principle,.product-detail-media{--mx:50%;--my:50%;position:relative;isolation:isolate;transition:transform .42s var(--ease-premium),box-shadow .42s var(--ease-premium),border-color .42s var(--ease-premium),background .42s var(--ease-premium)}
.approach-card::before,.service-card::before,.journey-card::before,.product-card::before,.bundle-card::before,.industry-card::before,.process-step::before,.work-card::before,.feature::before,.principle::before,.product-detail-media::before{content:'';position:absolute;inset:0;border-radius:inherit;background:radial-gradient(420px circle at var(--mx) var(--my),rgb(var(--c-gold-hi) / .15),transparent 44%);opacity:0;transition:opacity .35s var(--ease-premium);pointer-events:none;z-index:2}
.approach-card:hover::before,.service-card:hover::before,.journey-card:hover::before,.product-card:hover::before,.bundle-card:hover::before,.industry-card:hover::before,.process-step:hover::before,.work-card:hover::before,.feature:hover::before,.principle:hover::before,.product-detail-media:hover::before{opacity:1}
.approach-card:hover,.service-card:hover,.product-card:hover,.bundle-card:hover{transform:translateY(-8px);box-shadow:0 28px 70px rgb(var(--c-bg2) / .13)}
.journey-card:hover,.industry-card:hover{transform:translateY(-7px)}
.feature:hover,.principle:hover{transform:translateY(-3px);border-color:rgb(var(--c-accent) / .34);background:rgb(var(--c-tint) / .75)}

/* More tactile imagery */
.product-media,.bundle-media,.work-media,.product-detail-media{overflow:hidden}
.product-media img,.bundle-web,.bundle-product,.work-media img,.product-detail-media img{transition:transform .6s var(--ease-premium),filter .6s var(--ease-premium)}
.product-card:hover .product-media img{transform:scale(1.065) rotate(-.8deg)}
.bundle-card:hover .bundle-web{transform:rotate(-2.1deg) translate(-3px,-4px) scale(1.025)}
.bundle-card:hover .bundle-product{transform:translate(2px,-8px) scale(1.055)}
.work-card:hover .work-media img{transform:scale(1.035) translateY(-3px)}
.product-detail-media:hover img{transform:scale(1.035) rotate(-.4deg)}

/* Industry cards: richer depth and active ring */
.industry-card::after{width:170px;height:170px;right:-72px;bottom:-72px;box-shadow:0 0 0 28px rgb(var(--c-gold) / .025),0 0 0 58px rgb(var(--c-gold-hi) / .018)}
.industry-card h3,.industry-card p,.industry-card .index{position:relative;z-index:3}
.industry-card:hover h3{color:var(--gold)}

/* Process becomes an interactive progress story */
.process-step{overflow:hidden}
.process-step .num,.process-step h3,.process-step p{position:relative;z-index:3}
.process-step .num{transition:background .35s var(--ease-premium),color .35s var(--ease-premium),transform .35s var(--ease-premium),box-shadow .35s var(--ease-premium)}
.process-step::after{transition:background .5s var(--ease-premium),box-shadow .5s var(--ease-premium)}
.process-step.is-active{background:linear-gradient(145deg,rgb(var(--c-text)),rgb(var(--c-surface)))}
.process-step.is-active .num{background:var(--beacon);color:var(--forest);transform:scale(1.06);box-shadow:0 0 0 7px rgb(var(--c-gold) / .12)}
.process-step.is-active::after{background:linear-gradient(90deg,var(--beacon),rgb(var(--c-gold-hi) / .28));box-shadow:0 0 10px rgb(var(--c-gold) / .24)}
.process-step:hover{background:rgb(var(--c-text));z-index:2;box-shadow:0 18px 50px rgb(var(--c-bg2) / .08)}

/* FAQ feels less static */
.faq-q{transition:color .25s var(--ease-premium),padding-left .25s var(--ease-premium)}
.faq-q:hover{color:var(--moss);padding-left:6px}
.faq-item.open .faq-q{color:var(--moss)}
.faq-a{transition:max-height .45s var(--ease-premium),opacity .35s var(--ease-premium);opacity:.35}
.faq-item.open .faq-a{opacity:1}

/* Section polish */
.section-head .eyebrow{display:inline-flex;align-items:center;gap:10px}
.section-head .eyebrow::before{content:'';width:24px;height:1px;background:currentColor;opacity:.6}
.section-dark .section-head .eyebrow::before{background:var(--gold)}
.page-hero::after{content:'';position:absolute;width:540px;height:540px;border:1px solid rgb(var(--c-gold-hi) / .07);border-radius:50%;right:-170px;top:-130px;box-shadow:0 0 0 90px rgb(var(--c-gold) / .018),0 0 0 180px rgb(var(--c-gold-hi) / .012);pointer-events:none}
.page-hero-inner{animation:page-hero-in .8s var(--ease-premium) both}
@keyframes page-hero-in{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}

/* Reveal stagger helpers */
.reveal{transition-duration:.78s;transition-timing-function:var(--ease-premium);transition-delay:var(--reveal-delay,0ms)}

/* Broken image fallback is deliberate, not a browser icon */
img.asset-error{visibility:hidden}
.asset-fallback{display:grid;place-items:center;min-height:180px;padding:28px;text-align:center;border:1px dashed rgb(var(--c-accent) / .28);border-radius:18px;color:var(--muted);background:linear-gradient(145deg,var(--sage),var(--ivory));font-size:12px;font-weight:750;letter-spacing:.08em;text-transform:uppercase}

@media(max-width:1050px){
 .header-watermark{width:196px}
 .site-header.scrolled .header-inner{height:68px}
 .approach-media{height:340px}
 .journey-media{height:340px}
}
@media(max-width:720px){
 :root{--header-h:68px}
 .header-watermark{width:174px}
 .site-header.scrolled .header-inner{height:64px}
 .mobile-nav{transition:opacity .25s var(--ease-premium),transform .25s var(--ease-premium)}
 .approach-media{height:330px;padding:12px}
 .service-media{height:245px;padding:8px}
 .journey-media{height:330px;padding:12px}
 .hero-visual::before{inset:4% 1% 1%;border-radius:28px}
 .hero-laptop{width:105%;left:-7%;top:8%}
 .hero-phone{width:28%;right:0;bottom:0}
 .process-step::after{left:49px;top:70px;bottom:-1px;width:1px;height:auto;right:auto;background:rgb(var(--c-accent) / .22)}
 .process-step.is-active::after{background:linear-gradient(180deg,var(--beacon),rgb(var(--c-gold-hi) / .24))}
}
@media(hover:none){
 .approach-card:hover,.service-card:hover,.journey-card:hover,.product-card:hover,.bundle-card:hover,.industry-card:hover,.feature:hover,.principle:hover,.process-step:hover{transform:none}
 .approach-card::before,.service-card::before,.journey-card::before,.product-card::before,.bundle-card::before,.industry-card::before,.process-step::before,.work-card::before,.feature::before,.principle::before,.product-detail-media::before{display:none}
}
@media(prefers-reduced-motion:reduce){
 .signal-orbit,.signal-orbit::before{animation:none!important}
 .page-hero-inner{animation:none!important}
}

/* 21st.dev-inspired Olive Beacon scroll hero — adapted for zero-build static launch */
.scroll-hero{--hero-progress:0;position:relative;height:550vh;background:var(--forest);color:var(--ivory);isolation:isolate}
.scroll-hero-stage::before{content:'';position:absolute;inset:0;z-index:-4;transition:opacity .45s ease;background-image:linear-gradient(90deg,rgb(var(--c-surface) / .95),rgb(var(--c-surface) / .58)),url('../images/hero-bg-desktop.webp');background-size:cover;background-position:center;transform:scale(1.035)}
.scroll-hero-stage::after{content:'';position:absolute;inset:0;z-index:-3;transition:background .45s ease;background:linear-gradient(180deg,rgb(var(--c-surface) / .04) 0%,rgb(var(--c-surface) / .12) 56%,rgb(var(--c-surface) / .78) 100%)}
.scroll-hero-bg{position:absolute;inset:0;z-index:-2;pointer-events:none}
.scroll-hero-gridlines{position:absolute;inset:0;opacity:.2;background-image:linear-gradient(rgb(var(--c-gold-hi) / .08) 1px,transparent 1px),linear-gradient(90deg,rgb(var(--c-gold-hi) / .08) 1px,transparent 1px);background-size:72px 72px;mask-image:linear-gradient(to bottom,transparent 0%,#000 24%,#000 70%,transparent 100%)}
.scroll-hero-glow{position:absolute;border-radius:999px;filter:blur(12px);opacity:.34;mix-blend-mode:screen}
.scroll-hero-glow-a{width:520px;height:520px;right:4%;top:10%;background:radial-gradient(circle,rgb(var(--c-gold-hi) / .26),rgb(var(--c-gold-hi) / 0) 68%)}
.scroll-hero-glow-b{width:440px;height:440px;left:4%;bottom:4%;background:radial-gradient(circle,rgb(var(--c-gold) / .2),rgb(var(--c-gold) / 0) 68%)}
.scroll-hero-intro{position:relative;z-index:5;text-align:center;display:flex;flex-direction:column;align-items:center;padding-top:70px;will-change:transform,opacity}
.scroll-hero-intro .eyebrow{color:var(--gold)}
.scroll-hero-intro .display{max-width:1020px;color:var(--ivory);margin:0 auto 26px;font-size:clamp(56px,7.25vw,106px)}
.scroll-hero-intro .display em{font-style:normal;color:var(--gold)}
.scroll-hero-intro .lede{max-width:760px;color:rgb(var(--c-text-mut));margin:0 auto 30px}
.scroll-hero-intro .hero-actions{justify-content:center}
.scroll-hero-cue{display:flex;align-items:center;gap:10px;margin:28px 0 0;font-size:11px;font-weight:800;letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--c-text) / .48)}
.scroll-hero-cue span{width:28px;height:1px;background:linear-gradient(90deg,var(--gold),transparent);position:relative;overflow:hidden}
.scroll-hero-cue span::after{content:'';position:absolute;inset:0;background:var(--ivory);transform:translateX(-120%);animation:scroll-cue 1.8s ease-in-out infinite}
@keyframes scroll-cue{50%{transform:translateX(120%)}100%{transform:translateX(120%)}}
.scroll-hero-tiles{position:absolute;z-index:8;left:50%;bottom:34px;width:min(1120px,88vw);display:grid;grid-template-columns:repeat(5,1fr);gap:8px;transform:translateX(-50%);will-change:transform,opacity}
.scroll-hero-tile{position:relative;aspect-ratio:1/1;overflow:hidden;border-radius:14px;border:1px solid rgb(var(--c-text) / .18);background:rgb(var(--c-text) / .08);box-shadow:0 18px 44px rgba(0,0,0,.28);will-change:transform;transform-origin:center center}
.scroll-hero-tile::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,transparent 58%,rgb(var(--c-bg2) / .8) 100%)}
.scroll-hero-tile img{width:100%;height:100%;object-fit:cover;object-position:center;filter:saturate(.92) contrast(1.02);transform:scale(1.005)}
.scroll-hero-tile:nth-child(4) img,.scroll-hero-tile:nth-child(5) img{object-fit:contain;padding:14px;background:linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-text)))}
.scroll-hero-tile span{position:absolute;z-index:2;left:12px;bottom:11px;font-size:9px;font-weight:850;letter-spacing:.14em;text-transform:uppercase;color:var(--ivory)}
.scroll-hero-tile:nth-child(4) span,.scroll-hero-tile:nth-child(5) span{color:var(--forest)}
.scroll-hero-statement{position:absolute;z-index:6;inset:auto 0;top:50%;transform:translateY(-50%);text-align:center;opacity:1;pointer-events:none}
.scroll-hero-statement>.eyebrow{color:var(--moss);opacity:0}
.scroll-hero-statement-text{max-width:1120px;margin:0 auto;color:var(--forest);font:500 clamp(38px,5.4vw,76px)/1.12 var(--serif);letter-spacing:-.055em}
.scroll-hero-statement-text span{opacity:0;display:inline}
.scroll-hero-statement-text i{display:inline-block;width:58px;height:58px;margin:0 .12em -.13em;border-radius:13px;visibility:hidden}
.scroll-hero-statement-note{max-width:650px;margin:28px auto 0;color:var(--muted);font-size:16px;line-height:1.7;opacity:0}
.hero-floating-icon{position:fixed;z-index:999;width:58px;height:58px;border-radius:13px;overflow:hidden;border:1px solid rgb(var(--c-surface) / .13);background:var(--ivory);box-shadow:0 16px 38px rgb(var(--c-bg2) / .16);pointer-events:none;will-change:left,top,transform,opacity}
.hero-floating-icon img{width:100%;height:100%;object-fit:cover}
.hero-floating-icon:nth-of-type(4) img,.hero-floating-icon:nth-of-type(5) img{object-fit:contain;padding:5px;background:rgb(var(--c-text))}
.scroll-hero-stage{position:sticky;top:0;height:100vh;min-height:760px;display:grid;place-items:center;overflow:hidden;background:var(--forest);color:var(--ivory);isolation:isolate}
.scroll-hero-stage.is-final{color:var(--forest)}
.scroll-hero-stage.is-final::before{opacity:0}
.scroll-hero-stage.is-final::after{background:rgb(var(--c-text) / .98)}

@media(max-width:1050px){
 .scroll-hero{height:520vh}
 .scroll-hero-stage{min-height:720px}
 .scroll-hero-intro{padding-top:82px}
 .scroll-hero-intro .display{font-size:clamp(50px,8vw,82px);max-width:860px}
 .scroll-hero-tiles{width:min(900px,92vw);gap:6px}
 .scroll-hero-statement-text{font-size:clamp(34px,6vw,62px);max-width:900px}
 .scroll-hero-statement-text i,.hero-floating-icon{width:48px;height:48px;border-radius:11px}
}
@media(max-width:720px){
 .scroll-hero{height:460vh}
 .scroll-hero-stage{min-height:690px}
 .scroll-hero-stage::before{background-image:linear-gradient(180deg,rgb(var(--c-surface) / .82),rgb(var(--c-surface) / .72)),url('../images/hero-bg-mobile.webp');background-position:center}
 .scroll-hero-gridlines{background-size:46px 46px}
 .scroll-hero-intro{padding-top:88px}
 .scroll-hero-intro .display{font-size:clamp(45px,12.6vw,68px);line-height:.95;max-width:94vw}
 .scroll-hero-intro .lede{font-size:16px;line-height:1.6;max-width:88vw}
 .scroll-hero-cue{font-size:9px;margin-top:22px}
 .scroll-hero-tiles{bottom:22px;width:94vw;gap:4px}
 .scroll-hero-tile{border-radius:9px}
 .scroll-hero-tile span{display:none}
 .scroll-hero-tile:nth-child(4) img,.scroll-hero-tile:nth-child(5) img{padding:6px}
 .scroll-hero-statement{width:100%;padding:0 18px}
 .scroll-hero-statement-text{font-size:clamp(30px,8.3vw,47px);line-height:1.2;max-width:94vw}
 .scroll-hero-statement-text i,.hero-floating-icon{width:34px;height:34px;border-radius:8px;margin-bottom:-.08em}
 .scroll-hero-statement-note{font-size:14px;max-width:86vw;margin-top:20px}
}
@media(prefers-reduced-motion:reduce){
 .scroll-hero{height:auto;min-height:850px;background:var(--forest)}
 .scroll-hero-stage{position:relative;min-height:850px;padding:130px 0 50px;overflow:hidden}
 .scroll-hero-intro{position:relative;padding-top:0}
 .scroll-hero-tiles{position:relative;left:auto;bottom:auto;transform:none;width:min(1120px,88vw);margin:48px auto 0}
 .scroll-hero-statement{display:none}
 .scroll-hero-cue{display:none}
 .hero-floating-icon{display:none!important}
}

.hero-floating-icon[data-index='3'] img,.hero-floating-icon[data-index='4'] img{object-fit:contain;padding:5px;background:rgb(var(--c-text))}

/* =============================
   21st.dev bounce-card service bento — adapted for Olive Beacon
   ============================= */
.bounce-services-section{overflow:hidden}
.bounce-services-head{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(300px,.65fr);gap:64px;align-items:end;margin-bottom:34px}
.bounce-services-intro{display:flex;flex-direction:column;align-items:flex-start;gap:20px}
.bounce-services-intro p{margin:0;color:var(--muted);line-height:1.68;max-width:560px}
.bounce-services-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:18px}
.bounce-service-card{--mx:50%;--my:50%;position:relative;min-height:430px;overflow:hidden;border-radius:30px;border:1px solid rgb(var(--c-surface) / .10);background:rgb(var(--c-text) / .96);padding:30px 30px 0;box-shadow:0 16px 48px rgb(var(--c-bg2) / .06);isolation:isolate;cursor:pointer;transition:transform .34s cubic-bezier(.2,.72,.22,1),box-shadow .34s cubic-bezier(.2,.72,.22,1),border-color .34s ease}
.bounce-service-card::before{content:'';position:absolute;inset:0;border-radius:inherit;background:radial-gradient(540px circle at var(--mx) var(--my),rgb(var(--c-gold-hi) / .17),transparent 44%);opacity:0;transition:opacity .3s ease;pointer-events:none;z-index:1}
.bounce-service-card:hover{transform:scale(.965) rotate(-.55deg);box-shadow:0 30px 80px rgb(var(--c-bg2) / .13);border-color:rgb(var(--c-gold) / .34)}
.bounce-service-card:hover::before{opacity:1}
.bounce-small{grid-column:span 4}
.bounce-wide{grid-column:span 8}
.bounce-card-top{position:relative;z-index:4;max-width:620px}
.bounce-card-top h3{font:500 clamp(31px,3vw,45px)/1 var(--serif);letter-spacing:-.045em;margin:14px 0 12px}
.bounce-card-top p{margin:0;max-width:570px;color:var(--muted);line-height:1.62}
.bounce-card-top .text-link{display:inline-block;margin-top:14px}
.bounce-demo-panel{position:absolute;left:18px;right:18px;top:205px;bottom:-46px;border-radius:25px 25px 0 0;padding:14px 14px 32px;overflow:hidden;display:flex;align-items:flex-end;justify-content:center;transform:translateY(20px);transform-origin:50% 100%;box-shadow:0 -8px 36px rgb(var(--c-bg2) / .08);transition:transform .32s cubic-bezier(.2,.72,.22,1),box-shadow .32s ease;z-index:2}
.bounce-service-card:hover .bounce-demo-panel{transform:translateY(7px) rotate(1.15deg);box-shadow:0 -16px 50px rgb(var(--c-bg2) / .14)}
.bounce-demo-panel::after{content:'';position:absolute;inset:0;background:linear-gradient(180deg,transparent 52%,rgb(var(--c-surface) / .10));pointer-events:none}
.bounce-demo-panel img{position:absolute;inset:12px 12px 44px;width:calc(100% - 24px);height:calc(100% - 56px);object-fit:contain;object-position:center;border-radius:18px;filter:drop-shadow(0 18px 30px rgb(var(--c-bg2) / .12));transition:transform .44s cubic-bezier(.2,.72,.22,1),filter .44s ease}
.bounce-service-card:hover .bounce-demo-panel>img{transform:scale(1.025) translateY(-3px);filter:drop-shadow(0 22px 35px rgb(var(--c-bg2) / .16))}
.bounce-demo-panel>span{position:relative;z-index:3;font-size:10px;font-weight:800;letter-spacing:.15em;text-transform:uppercase;color:rgb(var(--c-surface) / .72)}
.bounce-demo-ivory{background:linear-gradient(145deg,rgb(var(--c-text)),#e8ebdc)}
.bounce-demo-sage{background:linear-gradient(145deg,#e8edd8,#cfd9bc)}
.bounce-demo-forest{background:linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-bg2)))}
.bounce-demo-forest>span{color:rgb(var(--c-text-mut))}
.bounce-demo-gold{background:linear-gradient(145deg,#f0e4a8,#d8c56e)}
.bounce-dark{background:linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-surface)));color:var(--ivory);border-color:rgb(var(--c-gold-hi) / .12)}
.bounce-dark .service-kicker{color:var(--gold)}
.bounce-dark .bounce-card-top p{color:rgb(var(--c-text-mut))}
.bounce-dark .text-link{color:var(--ivory)}
.bounce-connected{background:linear-gradient(145deg,#f5f2df,#e3e8cd)}
.bounce-connected-stack{position:absolute;inset:12px 12px 44px;display:flex;align-items:center;justify-content:center;overflow:hidden}
.bounce-connected-stack img{position:absolute!important;inset:auto!important;width:auto!important;height:auto!important;object-fit:contain!important;filter:drop-shadow(0 16px 26px rgb(var(--c-bg2) / .13))!important}
.bounce-connected-stack img:first-child{width:72%!important;left:1%!important;bottom:5%!important;z-index:1;transform:rotate(-2deg)}
.bounce-connected-stack img:last-child{width:35%!important;right:0!important;bottom:4%!important;z-index:2;transform:rotate(2deg)}
.bounce-service-card:hover .bounce-connected-stack img:first-child{transform:translateY(-4px) rotate(-3deg) scale(1.015)!important}
.bounce-service-card:hover .bounce-connected-stack img:last-child{transform:translateY(-8px) rotate(4deg) scale(1.035)!important}

@media(max-width:1050px){
 .bounce-services-head{grid-template-columns:1fr;gap:22px}
 .bounce-small,.bounce-wide{grid-column:span 6}
 .bounce-service-card{min-height:430px}
}
@media(max-width:720px){
 .bounce-services-grid{grid-template-columns:1fr;gap:16px}
 .bounce-small,.bounce-wide{grid-column:auto}
 .bounce-service-card{min-height:405px;border-radius:24px;padding:25px 22px 0;cursor:default}
 .bounce-card-top h3{font-size:34px}
 .bounce-demo-panel{left:12px;right:12px;top:205px;bottom:-40px;border-radius:20px 20px 0 0;transform:translateY(10px)}
 .bounce-service-card:hover{transform:none}
 .bounce-service-card:hover .bounce-demo-panel{transform:translateY(10px) rotate(0)}
 .bounce-service-card:hover .bounce-demo-panel>img{transform:none}
}
@media(prefers-reduced-motion:reduce){
 .bounce-service-card,.bounce-demo-panel,.bounce-demo-panel img,.bounce-connected-stack img{transition:none!important;transform:none!important}
}

/* =============================
   Premium floating glass navbar V5
   ============================= */
.site-header{position:fixed;inset:0 0 auto;z-index:1000;background:transparent;border:0;backdrop-filter:none;padding:12px 0 0;transition:padding .3s var(--ease-premium)}
.site-header::after{display:none}
.header-inner{height:72px;padding:0 16px 0 18px;border-radius:24px;background:rgb(var(--c-surface) / .58);border:1px solid rgb(var(--c-text) / .12);backdrop-filter:blur(24px) saturate(140%);-webkit-backdrop-filter:blur(24px) saturate(140%);box-shadow:0 12px 36px rgb(var(--c-bg) / .14),inset 0 1px 0 rgb(var(--c-tint) / .05);transition:height .3s var(--ease-premium),background .3s var(--ease-premium),box-shadow .3s var(--ease-premium),border-color .3s ease}
.site-header.scrolled{background:transparent;border:0;box-shadow:none;padding-top:8px}
.site-header.scrolled .header-inner{height:66px;background:rgb(var(--c-bg2) / .74);border-color:rgb(var(--c-gold-hi) / .16);box-shadow:0 18px 48px rgb(var(--c-bg) / .22),inset 0 1px 0 rgb(var(--c-tint) / .055)}
.desktop-nav a{position:relative;isolation:isolate;padding:27px 4px 24px;overflow:visible;color:rgb(var(--c-text-mut))}
.desktop-nav a::before{content:'';position:absolute;left:50%;bottom:4px;width:76px;height:44px;transform:translateX(-50%) translateY(10px) scale(.72);background:radial-gradient(ellipse at 50% 100%,rgb(var(--c-gold-hi) / .50) 0%,rgb(var(--c-gold) / .23) 30%,rgb(var(--c-gold) / .08) 52%,transparent 74%);filter:blur(7px);opacity:0;z-index:-1;pointer-events:none;transition:opacity .28s ease,transform .34s var(--ease-premium)}
.desktop-nav a::after{content:'';position:absolute;left:50%;right:50%;bottom:15px;height:2px;border-radius:999px;background:linear-gradient(90deg,rgb(var(--c-gold-hi) / .35),var(--gold) 48%,var(--beacon));box-shadow:0 0 8px rgb(var(--c-gold-hi) / .75),0 -8px 18px rgb(var(--c-gold-hi) / .25),0 -16px 30px rgb(var(--c-gold) / .11);opacity:0;transition:left .28s var(--ease-premium),right .28s var(--ease-premium),opacity .18s ease}
.desktop-nav a:hover,.desktop-nav a:focus-visible,.desktop-nav a[aria-current=page]{color:rgb(var(--c-text));text-shadow:0 0 18px rgb(var(--c-gold-hi) / .22)}
.desktop-nav a:hover::before,.desktop-nav a:focus-visible::before,.desktop-nav a[aria-current=page]::before{opacity:.92;transform:translateX(-50%) translateY(0) scale(1)}
.desktop-nav a:hover::after,.desktop-nav a:focus-visible::after,.desktop-nav a[aria-current=page]::after{left:4px;right:4px;opacity:1}
.site-header.scrolled .desktop-nav a{padding-top:24px;padding-bottom:21px}
.brand-link{display:flex;align-items:center;min-width:0}
.header-watermark{width:196px;max-height:46px;object-fit:contain;object-position:left center}
.mobile-nav{left:14px;right:14px;top:88px;border:1px solid rgb(var(--c-text) / .10);border-radius:20px;background:rgb(var(--c-surface) / .94);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);box-shadow:0 20px 52px rgb(var(--c-bg) / .28);padding:14px 20px 24px}
.site-header.scrolled .mobile-nav{top:80px}
.menu-btn{background:rgb(var(--c-text) / .045);backdrop-filter:blur(10px)}
@media(max-width:720px){.site-header{padding-top:8px}.header-inner{height:64px;border-radius:20px;padding:0 12px 0 14px}.site-header.scrolled{padding-top:6px}.site-header.scrolled .header-inner{height:60px}.header-watermark{width:164px}.mobile-nav{top:78px}.site-header.scrolled .mobile-nav{top:72px}}

/* =============================
   Website concept gallery
   ============================= */
.concept-showcase{overflow:hidden}
.concept-head{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,.62fr);gap:56px;align-items:end;margin-bottom:34px}
.concept-head p:last-child{margin:0;color:var(--muted);line-height:1.7}
.concept-grid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:18px}
.concept-card{--mx:50%;--my:50%;position:relative;grid-column:span 4;appearance:none;border:1px solid rgb(var(--c-surface) / .10);background:rgb(var(--c-text));border-radius:26px;padding:0;overflow:hidden;cursor:zoom-in;text-align:left;box-shadow:0 14px 38px rgb(var(--c-bg2) / .06);transition:transform .36s var(--ease-premium),box-shadow .36s var(--ease-premium),border-color .3s ease}
.concept-card.wide{grid-column:span 8}
.concept-card::before{content:'';position:absolute;inset:0;z-index:2;pointer-events:none;background:radial-gradient(460px circle at var(--mx) var(--my),rgb(var(--c-gold-hi) / .20),transparent 40%);opacity:0;transition:opacity .28s ease}
.concept-card:hover{transform:translateY(-8px) rotate(-.35deg);box-shadow:0 28px 76px rgb(var(--c-bg2) / .14);border-color:rgb(var(--c-gold) / .28)}
.concept-card:hover::before{opacity:1}
.concept-image-wrap{position:relative;aspect-ratio:16/10;overflow:hidden;background:#e9ecdf}
.concept-card.wide .concept-image-wrap{aspect-ratio:16/8.6}
.concept-image-wrap img{width:100%;height:100%;object-fit:cover;object-position:top center;display:block;transition:transform .65s cubic-bezier(.2,.72,.22,1),filter .45s ease}
.concept-card:hover img{transform:scale(1.035);filter:saturate(1.03) contrast(1.02)}
.concept-overlay{position:absolute;inset:0;display:flex;align-items:flex-end;padding:18px;background:linear-gradient(180deg,transparent 55%,rgb(var(--c-bg2) / .72));opacity:0;transition:opacity .28s ease;z-index:3}
.concept-card:hover .concept-overlay,.concept-card:focus-visible .concept-overlay{opacity:1}
.concept-view{margin-left:auto;padding:8px 12px;border-radius:999px;background:rgb(var(--c-text) / .94);color:var(--forest);font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;box-shadow:0 8px 28px rgba(0,0,0,.15)}
.concept-meta{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:17px 19px 19px;background:linear-gradient(180deg,rgb(var(--c-text)),rgb(var(--c-text)))}
.concept-meta strong{font:500 22px/1.05 var(--serif);letter-spacing:-.035em;color:var(--forest)}
.concept-meta span{font-size:10px;font-weight:800;letter-spacing:.13em;text-transform:uppercase;color:rgb(var(--c-surface) / .53)}
.concept-note{margin-top:18px;font-size:12px;color:rgb(var(--c-surface) / .58)}
.concept-dialog{width:min(1180px,calc(100vw - 32px));max-height:92vh;border:1px solid rgb(var(--c-gold-hi) / .22);border-radius:26px;padding:0;background:rgb(var(--c-bg2) / .96);box-shadow:0 40px 120px rgba(0,0,0,.45);overflow:hidden;color:rgb(var(--c-text))}
.concept-dialog::backdrop{background:rgb(var(--c-bg) / .78);backdrop-filter:blur(8px)}
.concept-dialog-inner{display:grid;grid-template-rows:auto 1fr;max-height:92vh}
.concept-dialog-bar{display:flex;align-items:center;justify-content:space-between;gap:18px;padding:14px 16px 14px 20px;border-bottom:1px solid rgb(var(--c-text) / .09)}
.concept-dialog-title{font-weight:700;font-size:13px;letter-spacing:.04em}
.concept-dialog-close{width:38px;height:38px;border-radius:50%;border:1px solid rgb(var(--c-text) / .14);background:rgb(var(--c-text) / .05);color:rgb(var(--c-text));font-size:22px;cursor:pointer}
.concept-dialog-scroll{overflow:auto;background:rgb(var(--c-bg2));padding:12px}
.concept-dialog img{display:block;width:100%;height:auto;border-radius:16px;background:rgb(var(--c-text))}
@media(max-width:1050px){.concept-head{grid-template-columns:1fr;gap:18px}.concept-card,.concept-card.wide{grid-column:span 6}}
@media(max-width:720px){.concept-grid{grid-template-columns:1fr}.concept-card,.concept-card.wide{grid-column:auto;border-radius:21px}.concept-card:hover{transform:none}.concept-image-wrap,.concept-card.wide .concept-image-wrap{aspect-ratio:16/10}.concept-meta strong{font-size:20px}.concept-overlay{opacity:1;background:linear-gradient(180deg,transparent 67%,rgb(var(--c-bg2) / .55));padding:12px}.concept-view{font-size:9px;padding:7px 10px}.concept-dialog{width:calc(100vw - 18px);border-radius:20px}.concept-dialog-scroll{padding:8px}}
@media(prefers-reduced-motion:reduce){.concept-card,.concept-image-wrap img,.desktop-nav a::before,.desktop-nav a::after{transition:none!important}.concept-card:hover,.concept-card:hover img{transform:none!important}}

/* =============================
   V6 cinematic dark system — MotionSites-inspired, Olive Beacon palette
   ============================= */
.theme-dark{--dark-0:rgb(var(--c-bg));--dark-1:rgb(var(--c-bg2));--dark-2:rgb(var(--c-surface));--glass:rgb(var(--c-surface) / .54);--glass-strong:rgb(var(--c-bg2) / .72);--dark-line:rgb(var(--c-gold-hi) / .12);color:rgb(var(--c-text));background:var(--dark-0);position:relative;isolation:isolate}
.theme-dark::before,.theme-dark::after{display:none!important}

.theme-dark main{position:relative;z-index:1;background:transparent}
.theme-dark .section{background:rgb(var(--c-bg) / .18);color:rgb(var(--c-text));border-top:1px solid rgb(var(--c-tint) / .018)}
.theme-dark .section-sage{background:linear-gradient(180deg,rgb(var(--c-surface) / .84),rgb(var(--c-bg2) / .74));color:rgb(var(--c-text))}
.theme-dark .section-dark{background:linear-gradient(180deg,rgb(var(--c-bg2) / .76),rgb(var(--c-bg2) / .84));color:rgb(var(--c-text))}
.theme-dark .section-title,.theme-dark .why-grid h2,.theme-dark .content-grid h2,.theme-dark .service-detail h2,.theme-dark .legal h2{color:rgb(var(--c-text))}
.theme-dark .eyebrow{color:var(--gold)}
.theme-dark .lede,.theme-dark .why-copy,.theme-dark .rich,.theme-dark .legal p,.theme-dark .legal li,.theme-dark .form-note{color:rgb(var(--c-text-mut))}
.theme-dark .legal strong{color:rgb(var(--c-text))}
.theme-dark .btn-outline{border-color:rgb(var(--c-gold-hi) / .18);color:rgb(var(--c-text));background:rgb(var(--c-tint) / .025);backdrop-filter:blur(16px)}
.theme-dark .btn-outline:hover{border-color:rgb(var(--c-gold-hi) / .42);background:rgb(var(--c-gold-hi) / .08);box-shadow:0 0 36px rgb(var(--c-gold-hi) / .08)}
.theme-dark .approach-card,.theme-dark .product-card,.theme-dark .bundle-card,.theme-dark .work-card,.theme-dark .feature,.theme-dark .principle,.theme-dark .process-step,.theme-dark .concept-card,.theme-dark .product-detail-media,.theme-dark .tag{background:linear-gradient(145deg,rgb(var(--c-surface) / .78),rgb(var(--c-bg2) / .64));border-color:rgb(var(--c-gold-hi) / .10);box-shadow:0 22px 70px rgba(0,0,0,.18);color:rgb(var(--c-text));backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
.theme-dark .approach-copy p,.theme-dark .product-copy p,.theme-dark .work-copy p,.theme-dark .why-copy,.theme-dark .process-step p,.theme-dark .bounce-card-top p,.theme-dark .concept-note{color:rgb(var(--c-text-mut))}
.theme-dark .approach-media,.theme-dark .product-media,.theme-dark .work-media,.theme-dark .product-detail-media{background:radial-gradient(circle at 68% 24%,rgb(var(--c-gold-hi) / .12),transparent 34%),linear-gradient(145deg,rgb(var(--c-surface) / .62),rgb(var(--c-bg2) / .85))}
.theme-dark .product-note{background:rgb(var(--c-tint) / .025);border-color:rgb(var(--c-gold-hi) / .10);color:rgb(var(--c-text-mut))}
.theme-dark .bounce-services-section{background:linear-gradient(180deg,rgb(var(--c-bg2) / .86),rgb(var(--c-bg) / .74))}
.theme-dark .bounce-service-card,.theme-dark .bounce-connected,.theme-dark .bounce-dark{background:linear-gradient(145deg,rgb(var(--c-surface) / .83),rgb(var(--c-bg2) / .79));border-color:rgb(var(--c-gold-hi) / .11);color:rgb(var(--c-text));box-shadow:0 22px 70px rgba(0,0,0,.2)}
.theme-dark .bounce-demo-ivory,.theme-dark .bounce-demo-sage,.theme-dark .bounce-demo-gold{background:linear-gradient(145deg,rgb(var(--c-accent) / .88),rgb(var(--c-surface) / .92))}
.theme-dark .bounce-demo-panel>span{color:rgb(var(--c-text-mut))}
.theme-dark .journey-card,.theme-dark .industry-card{background:rgb(var(--c-tint) / .025);border-color:rgb(var(--c-gold-hi) / .11);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
.theme-dark .journey-copy p,.theme-dark .industry-card p{color:rgb(var(--c-text-mut))}
.theme-dark .process-grid{background:rgb(var(--c-gold-hi) / .08);border-color:rgb(var(--c-gold-hi) / .09)}
.theme-dark .process-step .num{background:rgb(var(--c-tint) / .06);border:1px solid rgb(var(--c-gold-hi) / .12);color:var(--gold)}
.theme-dark .process-step.is-active,.theme-dark .process-step:hover{background:linear-gradient(145deg,rgb(var(--c-surface) / .92),rgb(var(--c-bg2) / .88))}
.theme-dark .faq-list{border-top-color:rgb(var(--c-gold-hi) / .11)}
.theme-dark .faq-item{border-bottom-color:rgb(var(--c-gold-hi) / .11)}
.theme-dark .faq-q{color:rgb(var(--c-text))}
.theme-dark .faq-a p{color:rgb(var(--c-text-mut))}
.theme-dark .faq-item.open .faq-q{color:var(--gold)}
.theme-dark .concept-meta{background:linear-gradient(180deg,rgb(var(--c-bg2) / .82),rgb(var(--c-bg2) / .96));color:rgb(var(--c-text))}
.theme-dark .concept-meta span{color:rgb(var(--c-text) / .46)}
.theme-dark .concept-dialog-inner{background:rgb(var(--c-bg2));border-color:rgb(var(--c-gold-hi) / .16);color:rgb(var(--c-text))}
.theme-dark .concept-dialog-bar{background:rgb(var(--c-surface) / .95);border-color:rgb(var(--c-gold-hi) / .10)}
.theme-dark .page-hero{background:transparent;color:rgb(var(--c-text));border-bottom:1px solid rgb(var(--c-gold-hi) / .06)}
.theme-dark .page-hero::before{background:radial-gradient(circle at 75% 30%,rgb(var(--c-gold-hi) / .15),transparent 26%),radial-gradient(circle at 24% 68%,rgb(var(--c-gold) / .10),transparent 34%),linear-gradient(180deg,rgb(var(--c-bg) / .16),rgb(var(--c-bg) / .74))}
.theme-dark .field label{color:rgb(var(--c-text-mut))}
.theme-dark .field input,.theme-dark .field textarea,.theme-dark .field select{background:rgb(var(--c-tint) / .045);border-color:rgb(var(--c-gold-hi) / .13);color:rgb(var(--c-text));backdrop-filter:blur(14px)}
.theme-dark .field input::placeholder,.theme-dark .field textarea::placeholder{color:rgb(var(--c-text) / .30)}
.theme-dark .field select option{background:rgb(var(--c-bg2));color:rgb(var(--c-text))}
.theme-dark .facts{border-top-color:rgb(var(--c-gold-hi) / .10)}
.theme-dark .fact{border-bottom-color:rgb(var(--c-gold-hi) / .10)}
.theme-dark .fact span:first-child{color:rgb(var(--c-text) / .47)}
.theme-dark .site-footer{background:linear-gradient(180deg,rgb(var(--c-bg) / .94),rgb(var(--c-bg)));border-top:1px solid rgb(var(--c-gold-hi) / .08)}

/* Cinematic CTA + footer transition. HLS video is a temporary reference source until Olive Beacon-owned motion is supplied. */
.cinematic-cta{position:relative;min-height:760px;padding:148px 0 84px;display:flex;align-items:center;overflow:hidden;background:rgb(var(--c-bg));color:rgb(var(--c-text));isolation:isolate}
.cinematic-cta-media{position:absolute;inset:0;z-index:-4;overflow:hidden;background:radial-gradient(circle at 50% 45%,rgb(var(--c-gold) / .20),transparent 42%),rgb(var(--c-bg))}
.cinematic-cta-video{position:absolute;inset:-5%;width:110%;height:110%;object-fit:cover;filter:saturate(.7) contrast(1.08) brightness(.52) sepia(.10);opacity:.68;transform:scale(1.03)}
.cinematic-cta-tint{position:absolute;inset:0;background:
 linear-gradient(180deg,rgb(var(--c-bg) / .97) 0%,rgb(var(--c-bg) / .18) 24%,rgb(var(--c-bg2) / .16) 56%,rgb(var(--c-bg) / .96) 100%),
 radial-gradient(circle at 50% 48%,rgb(var(--c-gold) / .15),transparent 40%),
 linear-gradient(110deg,rgb(var(--c-surface) / .55),rgb(var(--c-gold-hi) / .04) 52%,rgb(var(--c-surface) / .48));mix-blend-mode:normal}
.cinematic-cta::before,.cinematic-cta::after{content:'';position:absolute;left:0;right:0;height:220px;z-index:-2;pointer-events:none}
.cinematic-cta::before{top:0;background:linear-gradient(to bottom,rgb(var(--c-bg)),transparent)}
.cinematic-cta::after{bottom:0;background:linear-gradient(to top,rgb(var(--c-bg)),transparent)}
.cinematic-cta-inner{position:relative;z-index:2;text-align:center;max-width:930px}
.cinematic-cta-inner .eyebrow{color:var(--gold)}
.cinematic-cta-inner h2{font:italic 500 clamp(58px,7.6vw,104px)/.84 var(--serif);letter-spacing:-.065em;margin:0 auto 24px;max-width:900px;text-shadow:0 18px 70px rgba(0,0,0,.38)}
.cinematic-cta-inner>p:not(.eyebrow){max-width:650px;margin:0 auto 34px;color:rgb(var(--c-text-mut));font-size:17px;line-height:1.7}
.cinematic-cta-actions{display:flex;align-items:center;justify-content:center;gap:14px;flex-wrap:wrap}
.liquid-glass-btn{position:relative;overflow:hidden;background:rgb(var(--c-tint) / .018);border:1px solid rgb(var(--c-tint) / .14);box-shadow:4px 4px 18px rgba(0,0,0,.13),inset 0 1px 1px rgb(var(--c-tint) / .16);backdrop-filter:blur(36px) saturate(125%);-webkit-backdrop-filter:blur(36px) saturate(125%);color:rgb(var(--c-text))}
.liquid-glass-btn::before{content:'';position:absolute;inset:0;border-radius:inherit;padding:1px;background:linear-gradient(180deg,rgb(var(--c-gold-hi) / .70),rgb(var(--c-tint) / .11) 32%,rgb(var(--c-tint) / 0) 55%,rgb(var(--c-gold) / .38));-webkit-mask:linear-gradient(rgb(var(--c-text)) 0 0) content-box,linear-gradient(rgb(var(--c-text)) 0 0);-webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.liquid-glass-btn:hover{background:rgb(var(--c-gold-hi) / .08);box-shadow:0 0 42px rgb(var(--c-gold-hi) / .10),inset 0 1px 1px rgb(var(--c-tint) / .18)}
.cinematic-cta .btn-primary{background:rgb(var(--c-text));color:rgb(var(--c-bg2));box-shadow:0 12px 38px rgba(0,0,0,.28)}
.cinematic-cta .btn-primary:hover{background:rgb(var(--c-text))}
.cinematic-status{margin-top:20px!important;font-size:11px!important;letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--c-text) / .34)!important}

@media(max-width:720px){
 .cinematic-cta{min-height:680px;padding:108px 0 68px}
 .cinematic-cta-inner h2{font-size:clamp(52px,15vw,76px);line-height:.88}
 .cinematic-cta-inner>p:not(.eyebrow){font-size:15px}
 .cinematic-cta-actions{align-items:stretch}
 .cinematic-cta-actions .btn{width:100%}
}
@media(prefers-reduced-motion:reduce){.cinematic-cta-video{transform:none}}

/* V6 dark-theme contrast corrections */
html{background:rgb(var(--c-bg))}
.theme-dark .scroll-hero-stage.is-final{color:rgb(var(--c-text));background:rgb(var(--c-bg2))}
.theme-dark .scroll-hero-stage.is-final::after{background:radial-gradient(circle at 50% 48%,rgb(var(--c-gold) / .12),transparent 36%),linear-gradient(180deg,rgb(var(--c-bg2) / .98),rgb(var(--c-bg) / .98))}
.theme-dark .scroll-hero-statement>.eyebrow{color:var(--gold)}
.theme-dark .scroll-hero-statement-text{color:rgb(var(--c-text));text-shadow:0 18px 70px rgba(0,0,0,.24)}
.theme-dark .scroll-hero-statement-note{color:rgb(var(--c-text-mut))}
.theme-dark .bounce-services-intro p,.theme-dark .bundle-copy p,.theme-dark .bundle-footer p,.theme-dark .concept-head p:last-child{color:rgb(var(--c-text-mut))}
.theme-dark .concept-meta strong{color:rgb(var(--c-text))}
.theme-dark .service-kicker,.theme-dark .approach-num{color:var(--beacon)}
.theme-dark .bundle-media{background:radial-gradient(circle at 74% 26%,rgb(var(--c-gold-hi) / .14),transparent 36%),linear-gradient(145deg,rgb(var(--c-surface) / .68),rgb(var(--c-bg2) / .86))}
.theme-dark .principle,.theme-dark .feature,.theme-dark .tag{color:rgb(var(--c-text) / .82)}
.theme-dark .feature:hover,.theme-dark .principle:hover{background:rgb(var(--c-gold-hi) / .07);border-color:rgb(var(--c-gold-hi) / .24)}
.video-fallback{opacity:0!important}


/* =============================
   V7 Start Project cinematic gateway
   Motion background intentionally lives ONLY on /start-project/.
   ============================= */
.start-project-page{background:rgb(var(--c-bg))}
.start-project-page main{background:rgb(var(--c-bg))}
.project-gateway{position:relative;min-height:100svh;padding:150px 0 90px;display:grid;place-items:center;overflow:hidden;isolation:isolate;background:rgb(var(--c-bg));color:rgb(var(--c-text))}
.project-gateway-media{position:absolute;inset:0;z-index:-4;overflow:hidden;background:radial-gradient(circle at 50% 48%,rgb(var(--c-gold) / .22),transparent 42%),rgb(var(--c-bg))}
.project-gateway-video{position:absolute;inset:-6%;width:112%;height:112%;object-fit:cover;opacity:.76;filter:saturate(.62) hue-rotate(28deg) contrast(1.12) brightness(.46);transform:scale(1.045)}
.project-gateway-tint{position:absolute;inset:0;background:linear-gradient(180deg,rgb(var(--c-bg) / .80),rgb(var(--c-bg2) / .24) 30%,rgb(var(--c-bg2) / .20) 58%,rgb(var(--c-bg) / .94)),radial-gradient(circle at 50% 48%,rgb(var(--c-gold) / .23),transparent 38%),linear-gradient(112deg,rgb(var(--c-surface) / .62),rgb(var(--c-gold-hi) / .035) 48%,rgb(var(--c-surface) / .64))}
.project-gateway::before,.project-gateway::after{content:'';position:absolute;left:0;right:0;height:220px;z-index:-2;pointer-events:none}
.project-gateway::before{top:0;background:linear-gradient(to bottom,rgb(var(--c-bg)),transparent)}
.project-gateway::after{bottom:0;background:linear-gradient(to top,rgb(var(--c-bg)),transparent)}
.project-gateway-inner{width:min(980px,calc(100% - 48px));margin:auto;text-align:center;position:relative;z-index:2}
.project-gateway .eyebrow{color:var(--gold);margin-bottom:24px}
.project-gateway h1{font:italic 500 clamp(62px,8.8vw,122px)/.83 var(--serif);letter-spacing:-.068em;max-width:950px;margin:0 auto 28px;text-wrap:balance;text-shadow:0 22px 80px rgba(0,0,0,.42)}
.project-gateway-copy{max-width:700px;margin:0 auto 38px;color:rgb(var(--c-text-mut));font-size:clamp(16px,1.55vw,20px);line-height:1.7;text-wrap:balance}
.project-gateway-actions{display:flex;justify-content:center;align-items:center;gap:14px;flex-wrap:wrap}
.project-gateway-actions .btn{min-width:190px}
.project-gateway-note{margin:25px 0 0;font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:rgb(var(--c-text) / .34)}
.project-brief-section{padding:0 0 120px;background:rgb(var(--c-bg));color:rgb(var(--c-text));overflow:hidden}
.project-brief-section[hidden]{display:none!important}
.project-brief-shell{width:min(1120px,calc(100% - 48px));margin:auto;padding:76px;border:1px solid rgb(var(--c-gold-hi) / .12);border-radius:34px;background:linear-gradient(145deg,rgb(var(--c-surface) / .90),rgb(var(--c-bg2) / .92));box-shadow:0 38px 120px rgba(0,0,0,.34);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);opacity:0;transform:translateY(28px) scale(.985);transition:opacity .65s var(--ease-premium),transform .65s var(--ease-premium)}
.project-brief-section.is-open .project-brief-shell{opacity:1;transform:none}
.project-brief-intro{text-align:center;max-width:730px;margin:0 auto 52px}
.project-brief-intro h2{font:500 clamp(44px,5.8vw,72px)/.94 var(--serif);letter-spacing:-.055em;margin:0 0 20px;color:rgb(var(--c-text))}
.project-brief-intro p:last-child{color:rgb(var(--c-text-mut));line-height:1.75;margin-bottom:0}
.project-form-wrap{max-width:900px;margin:auto}
.project-form-wrap .form{background:transparent;border:0;padding:0}
.project-form-wrap .btn[type=submit]{margin-top:6px;min-width:190px}
.project-form-wrap .form-note{margin-top:16px}
@media(max-width:720px){
 .project-gateway{padding:128px 0 70px;min-height:100svh}
 .project-gateway-inner{width:min(100% - 32px,980px)}
 .project-gateway h1{font-size:clamp(54px,16vw,78px);line-height:.86}
 .project-gateway-copy{font-size:15px}
 .project-gateway-actions{align-items:stretch}
 .project-gateway-actions .btn{width:100%}
 .project-brief-section{padding-bottom:80px}
 .project-brief-shell{width:min(100% - 24px,1120px);padding:42px 20px;border-radius:26px}
 .project-brief-intro{margin-bottom:36px}
}
@media(prefers-reduced-motion:reduce){.project-gateway-video{transform:none}.project-brief-shell{transition:none}}

/* =============================
   Start Project liquid-ribbon gateway — V8
   ============================= */
.start-project-page{background:rgb(var(--c-bg))}
.start-project-page .site-footer{background:rgb(var(--c-bg))}
.liquid-project-gateway{min-height:100svh;padding:132px 0 72px;background:rgb(var(--c-bg));isolation:isolate}
.project-liquid-stage{position:absolute;inset:0;overflow:hidden;z-index:-3;background:rgb(var(--c-bg))}
.project-liquid-stage::before{content:'';position:absolute;inset:0;background:radial-gradient(circle at 51% 50%,rgb(var(--c-gold) / .055),transparent 29%),linear-gradient(180deg,rgb(var(--c-bg)) 0%,rgb(var(--c-bg)) 100%);z-index:-4}
.project-liquid-ribbon{position:absolute;left:50%;top:50%;width:max(1550px,116vw);height:max(720px,93vh);transform:translate(-50%,-47%);overflow:visible;filter:saturate(1.06) contrast(1.04);animation:ob-ribbon-float 9s ease-in-out infinite alternate;will-change:transform}
.ribbon-main-layer{transform-origin:50% 50%;animation:ob-ribbon-breathe 7.5s ease-in-out infinite alternate;will-change:transform}
.ribbon-glow-layer{transform-origin:50% 50%;animation:ob-ribbon-glow 6.8s ease-in-out infinite alternate}
.ribbon-sheen{animation:ob-sheen-pulse 5.8s ease-in-out infinite alternate}
.project-liquid-aura{position:absolute;border-radius:50%;filter:blur(95px);opacity:.34;pointer-events:none;mix-blend-mode:screen}
.project-liquid-aura-one{width:420px;height:320px;left:33%;top:40%;background:rgb(var(--c-gold-hi) / .15);animation:ob-aura-one 9s ease-in-out infinite alternate}
.project-liquid-aura-two{width:520px;height:360px;right:18%;top:37%;background:rgb(var(--c-gold) / .13);animation:ob-aura-two 11s ease-in-out infinite alternate}
.project-liquid-vignette{position:absolute;inset:0;background:radial-gradient(ellipse at center,transparent 19%,rgb(var(--c-bg) / .10) 49%,rgb(var(--c-bg) / .78) 90%),linear-gradient(180deg,rgb(var(--c-bg) / .58) 0%,transparent 20%,transparent 73%,rgb(var(--c-bg) / .82) 100%);z-index:3;pointer-events:none}
.liquid-project-gateway::before,.liquid-project-gateway::after{display:none}
.liquid-project-content{width:min(820px,calc(100% - 42px));z-index:5;margin:auto;text-align:center;transform:translateY(2px)}
.liquid-project-content h1{font-family:'Instrument Serif',Georgia,'Times New Roman',serif;font-style:italic;font-weight:400;font-size:clamp(58px,7.6vw,108px);line-height:.86;letter-spacing:-.047em;max-width:900px;margin:0 auto 20px;color:rgb(var(--c-text));text-shadow:0 14px 50px rgba(0,0,0,.76),0 0 30px rgb(var(--c-gold-hi) / .08)}
.liquid-project-content .project-gateway-copy{max-width:600px;margin:0 auto 31px;color:rgb(var(--c-text-mut));font-size:clamp(13px,1.25vw,16px);line-height:1.65;text-shadow:0 4px 18px rgba(0,0,0,.85)}
.liquid-project-content .project-gateway-actions{gap:12px}
.liquid-project-content .project-gateway-actions .btn{min-width:164px;min-height:48px;padding:0 20px;font-size:12px}
.project-quote-btn{border:0;background:#f4f1e3;color:rgb(var(--c-bg2));box-shadow:0 10px 32px rgba(0,0,0,.26),0 0 0 1px rgb(var(--c-tint) / .55) inset}
.project-quote-btn:hover{background:rgb(var(--c-text));color:rgb(var(--c-bg2));box-shadow:0 12px 36px rgba(0,0,0,.34),0 0 28px rgb(var(--c-gold-hi) / .10)}
.liquid-project-content .liquid-glass-btn{background:rgb(var(--c-tint) / .09);border-color:rgb(var(--c-tint) / .28);box-shadow:0 8px 26px rgba(0,0,0,.28),inset 0 1px 1px rgb(var(--c-tint) / .24);color:rgb(var(--c-text))}
.liquid-project-content .liquid-glass-btn:hover{background:rgb(var(--c-tint) / .14);box-shadow:0 8px 28px rgba(0,0,0,.3),0 0 28px rgb(var(--c-gold) / .12),inset 0 1px 1px rgb(var(--c-tint) / .25)}

.quote-modal{width:min(900px,calc(100% - 30px));max-height:min(88svh,900px);padding:0;border:1px solid rgb(var(--c-gold-hi) / .18);border-radius:30px;background:rgb(var(--c-bg2) / .95);color:rgb(var(--c-text));box-shadow:0 45px 140px rgba(0,0,0,.66),0 0 0 1px rgb(var(--c-tint) / .025) inset;backdrop-filter:blur(32px) saturate(120%);-webkit-backdrop-filter:blur(32px) saturate(120%);overflow:auto}
.quote-modal::backdrop{background:rgb(var(--c-bg) / .72);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
.quote-modal[open]{animation:quote-modal-in .36s var(--ease-premium)}
.quote-modal-card{position:relative;padding:52px 54px 48px;background:radial-gradient(circle at 78% 0%,rgb(var(--c-gold) / .11),transparent 28%),linear-gradient(145deg,rgb(var(--c-surface) / .92),rgb(var(--c-bg) / .96))}
.quote-modal-close{position:sticky;top:18px;float:right;z-index:5;width:42px;height:42px;margin:-22px -20px 0 0;border-radius:50%;border:1px solid rgb(var(--c-tint) / .13);background:rgb(var(--c-tint) / .055);color:rgb(var(--c-text));font-size:26px;line-height:1;cursor:pointer;transition:background .2s,transform .2s}
.quote-modal-close:hover{background:rgb(var(--c-tint) / .11);transform:rotate(4deg)}
.quote-modal-head{text-align:center;max-width:650px;margin:0 auto 34px;padding-top:4px}
.quote-modal-head .eyebrow{color:var(--gold);margin-bottom:14px}
.quote-modal-head h2{font:italic 400 clamp(42px,6vw,70px)/.92 'Instrument Serif',Georgia,serif;letter-spacing:-.04em;margin:0 0 16px;color:rgb(var(--c-text))}
.quote-modal-head p{color:rgb(var(--c-text-mut));line-height:1.65;margin-bottom:0}
.quote-modal .form{background:transparent;border:0;padding:0}
.quote-modal .field label{color:rgb(var(--c-text) / .82)}
.quote-modal .field input,.quote-modal .field textarea,.quote-modal .field select{background:rgb(var(--c-tint) / .045);border-color:rgb(var(--c-tint) / .12);color:rgb(var(--c-text))}
.quote-modal .field input:focus,.quote-modal .field textarea:focus,.quote-modal .field select:focus{outline:none;border-color:rgb(var(--c-gold) / .55);box-shadow:0 0 0 3px rgb(var(--c-gold) / .08)}
.quote-modal .field select option{background:rgb(var(--c-bg2));color:rgb(var(--c-text))}
.quote-modal .field-optional{font-weight:400;color:rgb(var(--c-text) / .38)}
.quote-modal .quote-submit{width:100%;margin-top:4px}
.quote-modal .form-note{color:rgb(var(--c-text) / .40);text-align:center;margin:15px auto 0;max-width:620px}
body.quote-modal-open{overflow:hidden}

@keyframes ob-ribbon-float{0%{transform:translate(-50%,-47%) scale(1.015) rotate(-.35deg)}100%{transform:translate(-50%,-49%) scale(1.045) rotate(.35deg)}}
@keyframes ob-ribbon-breathe{0%{transform:scaleX(1) scaleY(.96) translateX(-9px)}100%{transform:scaleX(1.018) scaleY(1.035) translateX(13px)}}
@keyframes ob-ribbon-glow{0%{opacity:.62;transform:translateY(9px) scale(1)}100%{opacity:.92;transform:translateY(-8px) scale(1.025)}}
@keyframes ob-sheen-pulse{0%{opacity:.42;transform:translateX(-18px)}100%{opacity:.86;transform:translateX(18px)}}
@keyframes ob-aura-one{0%{transform:translate(-18px,12px) scale(.88);opacity:.20}100%{transform:translate(44px,-18px) scale(1.12);opacity:.44}}
@keyframes ob-aura-two{0%{transform:translate(28px,-10px) scale(1.05);opacity:.18}100%{transform:translate(-38px,22px) scale(.9);opacity:.37}}
@keyframes quote-modal-in{from{opacity:0;transform:translateY(18px) scale(.975)}to{opacity:1;transform:none}}

@media(max-width:760px){
 .liquid-project-gateway{padding:112px 0 50px;min-height:100svh}
 .project-liquid-ribbon{width:1500px;height:720px;transform:translate(-50%,-46%) scale(.82);animation-name:ob-ribbon-float-mobile}
 .liquid-project-content{width:min(100% - 28px,700px)}
 .liquid-project-content h1{font-size:clamp(56px,17vw,82px);line-height:.86;margin-bottom:18px}
 .liquid-project-content .project-gateway-copy{max-width:470px;font-size:14px;margin-bottom:27px}
 .liquid-project-content .project-gateway-actions{flex-direction:row;align-items:center;justify-content:center;gap:9px}
 .liquid-project-content .project-gateway-actions .btn{width:auto;min-width:145px;min-height:46px;padding:0 16px;font-size:11px}
 .quote-modal{width:calc(100% - 18px);max-height:92svh;border-radius:24px}
 .quote-modal-card{padding:38px 18px 32px}
 .quote-modal-close{top:12px;margin:-21px -6px 0 0}
 .quote-modal-head{padding:0 8px;margin-bottom:28px}
 .quote-modal-head h2{font-size:48px}
}
@keyframes ob-ribbon-float-mobile{0%{transform:translate(-50%,-46%) scale(.80) rotate(-.2deg)}100%{transform:translate(-50%,-48%) scale(.85) rotate(.2deg)}}
@media(max-width:390px){.liquid-project-content .project-gateway-actions{flex-direction:column}.liquid-project-content .project-gateway-actions .btn{width:190px}}
@media(prefers-reduced-motion:reduce){.project-liquid-ribbon,.ribbon-main-layer,.ribbon-glow-layer,.ribbon-sheen,.project-liquid-aura{animation:none!important}.quote-modal[open]{animation:none}}

/* ============================================================
   Start Project liquid-glass ribbon refinement — V9
   Larger one-crest MotionSites-style flow: lower-left -> crest -> right.
   ============================================================ */
.start-project-page .liquid-project-gateway{background:rgb(var(--c-bg));min-height:100svh}
.start-project-page .project-liquid-stage{background:linear-gradient(180deg,rgb(var(--c-bg)) 0%,rgb(var(--c-bg)) 100%)}
.start-project-page .project-liquid-stage::before{
  content:'';position:absolute;inset:0;z-index:-4;
  background:
    radial-gradient(circle at 48% 49%,rgb(var(--c-gold-hi) / .07),transparent 22%),
    radial-gradient(circle at 42% 55%,rgb(var(--c-gold) / .055),transparent 38%),
    linear-gradient(180deg,rgb(var(--c-bg)) 0%,rgb(var(--c-bg)) 100%);
}
.start-project-page .project-liquid-ribbon{
  left:50%;top:51%;width:max(1760px,128vw);height:max(820px,104vh);
  transform:translate(-52%,-45%) scale(1.04) rotate(-.75deg);
  filter:saturate(1.12) contrast(1.07) drop-shadow(0 46px 70px rgba(0,0,0,.38));
  animation:ob-glass-wave-sweep 8.8s cubic-bezier(.45,.05,.32,.98) infinite alternate;
  will-change:transform,filter;
}
.start-project-page .ribbon-main-layer{
  transform-origin:48% 53%;
  animation:ob-glass-wave-breathe 6.4s ease-in-out infinite alternate;
  will-change:transform;
}
.start-project-page .ribbon-glow-layer{
  transform-origin:48% 53%;
  animation:ob-glass-wave-glow 5.6s ease-in-out infinite alternate;
}
.start-project-page .ribbon-glass-body{
  opacity:.93;
  mix-blend-mode:screen;
  filter:drop-shadow(0 18px 22px rgb(var(--c-bg2) / .34));
}
.start-project-page .ribbon-glass-depth{mix-blend-mode:multiply;opacity:.64}
.start-project-page .ribbon-bloom{mix-blend-mode:screen;animation:ob-glass-bloom 4.8s ease-in-out infinite alternate}
.start-project-page .ribbon-sheen{mix-blend-mode:screen;transform-origin:48% 48%;will-change:transform,opacity}
.start-project-page .ribbon-sheen-one{animation:ob-glass-sheen-one 4.6s ease-in-out infinite alternate}
.start-project-page .ribbon-sheen-two{animation:ob-glass-sheen-two 5.8s ease-in-out infinite alternate-reverse}
.start-project-page .ribbon-edge{filter:drop-shadow(0 0 7px rgb(var(--c-gold-hi) / .18))}
.start-project-page .project-liquid-aura{mix-blend-mode:screen;filter:blur(115px);opacity:.38}
.start-project-page .project-liquid-aura-one{width:520px;height:390px;left:34%;top:37%;background:rgb(var(--c-gold-hi) / .16);animation:ob-glass-aura-one 7.5s ease-in-out infinite alternate}
.start-project-page .project-liquid-aura-two{width:610px;height:430px;right:10%;top:48%;background:rgb(var(--c-gold) / .13);animation:ob-glass-aura-two 9.5s ease-in-out infinite alternate}
.start-project-page .project-liquid-aura-three{width:430px;height:360px;left:2%;bottom:7%;background:rgb(var(--c-accent) / .16);animation:ob-glass-aura-three 8.5s ease-in-out infinite alternate}
.start-project-page .project-liquid-vignette{
  background:
    radial-gradient(ellipse at 49% 51%,transparent 22%,rgb(var(--c-bg) / .04) 49%,rgb(var(--c-bg) / .74) 92%),
    linear-gradient(180deg,rgb(var(--c-bg) / .68) 0%,transparent 17%,transparent 77%,rgb(var(--c-bg) / .86) 100%);
}
.start-project-page .liquid-project-content{transform:translateY(-4px)}
.start-project-page .liquid-project-content h1{
  text-shadow:0 18px 56px rgba(0,0,0,.86),0 0 34px rgb(var(--c-gold-hi) / .075);
}
.start-project-page .liquid-project-content .liquid-glass-btn{
  background:rgb(var(--c-tint) / .018);
  background-blend-mode:luminosity;
  border:0;
  box-shadow:4px 4px 4px rgba(0,0,0,.05),inset 0 1px 1px rgb(var(--c-tint) / .20),0 12px 34px rgba(0,0,0,.28);
  backdrop-filter:blur(50px) saturate(145%);
  -webkit-backdrop-filter:blur(50px) saturate(145%);
}
.start-project-page .liquid-project-content .liquid-glass-btn::before{
  padding:1.4px;
  background:linear-gradient(180deg,rgb(var(--c-tint) / .60) 0%,rgb(var(--c-gold-hi) / .28) 21%,rgb(var(--c-tint) / 0) 40%,rgb(var(--c-tint) / 0) 60%,rgb(var(--c-gold) / .24) 80%,rgb(var(--c-tint) / .52) 100%);
}
.start-project-page .liquid-project-content .liquid-glass-btn:hover{
  background:rgb(var(--c-tint) / .07);
  box-shadow:0 12px 38px rgba(0,0,0,.34),0 0 34px rgb(var(--c-gold) / .15),inset 0 1px 1px rgb(var(--c-tint) / .26);
  transform:translateY(-2px);
}
@keyframes ob-glass-wave-sweep{
  0%{transform:translate(-55%,-39%) scale(1.00) rotate(-1.45deg);filter:saturate(1.08) contrast(1.05) drop-shadow(0 44px 66px rgba(0,0,0,.34))}
  46%{transform:translate(-50.8%,-47.5%) scale(1.105) rotate(.35deg);filter:saturate(1.17) contrast(1.08) drop-shadow(0 50px 80px rgba(0,0,0,.40))}
  100%{transform:translate(-46.5%,-43%) scale(1.16) rotate(1.25deg);filter:saturate(1.12) contrast(1.07) drop-shadow(0 52px 84px rgba(0,0,0,.42))}
}
@keyframes ob-glass-wave-breathe{
  0%{transform:scaleX(.985) scaleY(.94) skewX(-.6deg) translate(-12px,16px)}
  100%{transform:scaleX(1.035) scaleY(1.07) skewX(.7deg) translate(18px,-18px)}
}
@keyframes ob-glass-wave-glow{0%{opacity:.47;transform:translate(-18px,18px) scale(.98)}100%{opacity:.92;transform:translate(20px,-18px) scale(1.06)}}
@keyframes ob-glass-bloom{0%{opacity:.36;transform:translate(-28px,22px) scale(.86)}100%{opacity:.78;transform:translate(30px,-18px) scale(1.10)}}
@keyframes ob-glass-sheen-one{0%{opacity:.42;transform:translate(-36px,24px) scale(.98)}100%{opacity:.92;transform:translate(48px,-22px) scale(1.035)}}
@keyframes ob-glass-sheen-two{0%{opacity:.05;transform:translate(-18px,14px) scale(.96)}100%{opacity:.24;transform:translate(38px,-20px) scale(1.06)}}
@keyframes ob-glass-aura-one{0%{transform:translate(-58px,54px) scale(.82);opacity:.20}100%{transform:translate(65px,-46px) scale(1.18);opacity:.47}}
@keyframes ob-glass-aura-two{0%{transform:translate(48px,-32px) scale(.92);opacity:.18}100%{transform:translate(-64px,34px) scale(1.12);opacity:.42}}
@keyframes ob-glass-aura-three{0%{transform:translate(-20px,42px) scale(.90);opacity:.13}100%{transform:translate(78px,-40px) scale(1.22);opacity:.34}}

@media(max-width:760px){
  .start-project-page .project-liquid-ribbon{
    width:1760px;height:860px;left:50%;top:54%;
    animation:ob-glass-wave-sweep-mobile 9s cubic-bezier(.45,.05,.32,.98) infinite alternate;
  }
  .start-project-page .project-liquid-aura-one{left:20%;top:40%;width:410px;height:310px}
  .start-project-page .project-liquid-aura-two{right:-28%;top:49%;width:500px;height:360px}
  .start-project-page .project-liquid-aura-three{left:-28%;bottom:7%;width:380px;height:300px}
  .start-project-page .liquid-project-content{transform:translateY(-10px)}
}
@keyframes ob-glass-wave-sweep-mobile{
  0%{transform:translate(-57%,-34%) scale(.73) rotate(-1.2deg)}
  50%{transform:translate(-51%,-43%) scale(.82) rotate(.35deg)}
  100%{transform:translate(-45%,-39%) scale(.88) rotate(1.1deg)}
}
@media(prefers-reduced-motion:reduce){
  .start-project-page .project-liquid-ribbon,.start-project-page .ribbon-main-layer,.start-project-page .ribbon-glow-layer,.start-project-page .ribbon-bloom,.start-project-page .ribbon-sheen,.start-project-page .project-liquid-aura{animation:none!important}
}


/* ============================================================
   V10 — Website-first / SEO & visibility positioning
   ============================================================ */
.seo-demo-panel{display:flex;align-items:flex-end;justify-content:stretch}.seo-mini-ui{position:absolute;inset:28px 24px 56px;border-radius:20px;background:linear-gradient(145deg,rgb(var(--c-surface) / .96),rgb(var(--c-bg2) / .96));border:1px solid rgb(var(--c-gold-hi) / .16);padding:24px;display:flex;flex-direction:column;justify-content:center;gap:7px;box-shadow:0 24px 60px rgba(0,0,0,.18)}.seo-mini-ui span{font-size:11px;letter-spacing:.18em;color:var(--gold)}.seo-mini-ui strong{font:500 28px/1 var(--serif);color:rgb(var(--c-text))}.seo-mini-ui small{color:rgb(var(--c-text-mut))}
.seo-foundations{overflow:hidden}.seo-bento{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}.seo-card{position:relative;overflow:hidden;min-height:260px;padding:32px;border-radius:26px;background:linear-gradient(145deg,rgb(var(--c-tint) / .055),rgb(var(--c-tint) / .018));border:1px solid rgb(var(--c-tint) / .08);box-shadow:inset 0 1px 0 rgb(var(--c-tint) / .045);transition:transform .35s var(--ease-premium),border-color .35s,background .35s}.seo-card::before{content:'';position:absolute;width:220px;height:220px;right:-100px;top:-120px;border-radius:50%;background:radial-gradient(circle,rgb(var(--c-gold) / .18),transparent 68%);opacity:0;transition:opacity .35s}.seo-card:hover{transform:translateY(-5px);border-color:rgb(var(--c-gold) / .23);background:linear-gradient(145deg,rgb(var(--c-tint) / .075),rgb(var(--c-tint) / .025))}.seo-card:hover::before{opacity:1}.seo-card-wide{grid-column:span 2}.seo-card h3{font:500 clamp(28px,3vw,40px)/1 var(--serif);margin:18px 0 14px;color:rgb(var(--c-text))}.seo-card p{color:rgb(var(--c-text-mut));line-height:1.72;max-width:760px}.seo-icon{display:inline-grid;place-items:center;width:40px;height:40px;border-radius:50%;border:1px solid rgb(var(--c-gold-hi) / .22);color:var(--gold);font-size:11px;letter-spacing:.08em}.seo-tags{display:flex;gap:8px;flex-wrap:wrap;margin-top:22px}.seo-tags span{border:1px solid rgb(var(--c-tint) / .1);border-radius:999px;padding:8px 11px;color:rgb(var(--c-text-mut));font-size:11px}.light-link{color:var(--gold)}
.process-v10{display:grid;grid-template-columns:repeat(6,1fr);gap:0;border:1px solid rgb(var(--c-surface) / .1);border-radius:26px;overflow:hidden;background:rgb(var(--c-tint) / .38)}.process-v10-item{padding:28px 20px;min-height:190px;border-right:1px solid rgb(var(--c-surface) / .1);display:flex;flex-direction:column;gap:10px;justify-content:flex-end;transition:background .25s,transform .25s}.process-v10-item:last-child{border-right:0}.process-v10-item:hover{background:rgb(var(--c-tint) / .68)}.process-v10-item span{font-size:10px;letter-spacing:.18em;color:var(--moss)}.process-v10-item strong{font:500 24px/1.05 var(--serif);color:var(--forest)}.process-v10-item small{color:rgb(var(--c-surface) / .58);line-height:1.45}
.nfc-secondary{padding-top:72px;padding-bottom:72px}.nfc-secondary-card{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(260px,.6fr);align-items:center;gap:40px;padding:48px;border-radius:30px;background:linear-gradient(135deg,rgb(var(--c-bg2)),rgb(var(--c-surface)));color:rgb(var(--c-text));overflow:hidden;position:relative}.nfc-secondary-card::after{content:'';position:absolute;width:420px;height:420px;border-radius:50%;right:-210px;bottom:-270px;background:radial-gradient(circle,rgb(var(--c-gold) / .23),transparent 65%)}.nfc-secondary-copy{position:relative;z-index:2}.nfc-secondary-copy h2{font:500 clamp(38px,5vw,68px)/.95 var(--serif);letter-spacing:-.045em;margin:12px 0 18px;max-width:850px}.nfc-secondary-copy p:not(.eyebrow){color:rgb(var(--c-text-mut));line-height:1.7;max-width:760px}.nfc-secondary-copy .text-link{color:var(--gold)}.nfc-secondary-media{position:relative;z-index:2;display:flex;justify-content:center}.nfc-secondary-media img{width:min(260px,100%);filter:drop-shadow(0 25px 40px rgba(0,0,0,.35));transition:transform .4s var(--ease-premium)}.nfc-secondary-card:hover .nfc-secondary-media img{transform:translateY(-8px) rotate(2deg)}
.footer-grid-v10{grid-template-columns:1.5fr 1fr 1fr 1fr}
.seo-page-visual{min-height:420px;border-radius:28px;background:radial-gradient(circle at 60% 34%,rgb(var(--c-gold) / .22),transparent 28%),linear-gradient(145deg,rgb(var(--c-surface)),rgb(var(--c-bg)));border:1px solid rgb(var(--c-gold-hi) / .12);padding:52px 36px;display:flex;flex-direction:column;justify-content:center;color:rgb(var(--c-text));box-shadow:0 35px 80px rgba(0,0,0,.25)}.seo-search-bar{display:block;width:100%;border:1px solid rgb(var(--c-tint) / .12);border-radius:999px;padding:14px 18px;color:rgb(var(--c-text) / .38);font-size:12px;margin-bottom:30px}.seo-page-visual strong{font:500 42px/1 var(--serif);margin-bottom:20px}.seo-result-line{height:8px;border-radius:999px;background:linear-gradient(90deg,var(--beacon),rgb(var(--c-gold) / .12));width:84%;margin:6px 0}.seo-result-line.short{width:57%}.seo-page-visual small{margin-top:34px;color:rgb(var(--c-text) / .45);letter-spacing:.08em}.light-seo-bento .seo-card{background:rgb(var(--c-surface));color:var(--forest);border-color:rgb(var(--c-surface) / .08)}.light-seo-bento .seo-card h3{color:var(--forest)}.light-seo-bento .seo-card p{color:rgb(var(--c-surface) / .66)}.light-seo-bento .seo-icon{border-color:rgb(var(--c-surface) / .14);color:var(--moss)}.seo-expectations{display:grid;grid-template-columns:1fr 1fr;gap:18px}.seo-expect{padding:38px;border-radius:26px;background:rgb(var(--c-tint) / .58);border:1px solid rgb(var(--c-surface) / .08)}.seo-expect strong{font:500 32px/1 var(--serif);color:var(--forest)}.seo-expect ul{margin:24px 0 0;padding:0;list-style:none}.seo-expect li{padding:12px 0;border-top:1px solid rgb(var(--c-surface) / .08);color:rgb(var(--c-surface) / .68)}
@media(max-width:980px){.process-v10{grid-template-columns:repeat(3,1fr)}.process-v10-item:nth-child(3){border-right:0}.process-v10-item:nth-child(-n+3){border-bottom:1px solid rgb(var(--c-surface) / .1)}.footer-grid-v10{grid-template-columns:1.5fr 1fr 1fr}.footer-grid-v10 .footer-col:last-child{grid-column:2/4}.nfc-secondary-card{grid-template-columns:1fr .45fr}}
@media(max-width:720px){.seo-bento{grid-template-columns:1fr}.seo-card-wide{grid-column:auto}.process-v10{grid-template-columns:1fr}.process-v10-item,.process-v10-item:nth-child(3){border-right:0;border-bottom:1px solid rgb(var(--c-surface) / .1)}.process-v10-item:last-child{border-bottom:0}.nfc-secondary-card{grid-template-columns:1fr;padding:34px 24px}.nfc-secondary-media{display:none}.footer-grid-v10{grid-template-columns:1fr}.footer-grid-v10 .footer-col:last-child{grid-column:auto}.seo-expectations{grid-template-columns:1fr}.seo-page-visual{min-height:300px;padding:34px 24px}.seo-page-visual strong{font-size:34px}}


/* ============================================================
   V11 — Interaction density restoration
   Cursor-reactive glow, premium hover depth, magnetic CTAs.
   ============================================================ */
:root{--ob-ease:cubic-bezier(.2,.72,.22,1)}

/* Global desktop pointer halo — subtle normally, brighter over interactive UI. */
.ob-cursor-halo{position:fixed;left:0;top:0;width:190px;height:190px;margin:-95px 0 0 -95px;border-radius:50%;pointer-events:none;z-index:1600;background:radial-gradient(circle,rgb(var(--c-gold-hi) / .14) 0%,rgb(var(--c-gold) / .09) 28%,rgb(var(--c-accent) / .035) 48%,transparent 70%);filter:blur(8px);opacity:.28;transform:translate3d(-300px,-300px,0) scale(.78);transition:opacity .22s ease,scale .22s ease;mix-blend-mode:screen}
body.ob-over-interactive .ob-cursor-halo{opacity:.72;scale:1.12}

/* Shared interactive surface behaviour. */
.ob-interactive-surface,.ob-soft-surface{--gx:50%;--gy:50%;--rx:0deg;--ry:0deg;--surface-lift:0px;--surface-scale:1;position:relative;isolation:isolate;transform-style:preserve-3d;will-change:transform,box-shadow,border-color;transition:transform .36s var(--ob-ease),box-shadow .36s var(--ob-ease),border-color .28s ease,background .28s ease,filter .28s ease}
.ob-pointer-glow{position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;z-index:25;opacity:0;background:radial-gradient(420px circle at var(--gx) var(--gy),rgb(var(--c-gold-hi) / .22) 0%,rgb(var(--c-gold) / .12) 18%,rgb(var(--c-gold) / .045) 36%,transparent 62%);box-shadow:inset 0 0 0 1px rgb(var(--c-gold-hi) / .0);transition:opacity .26s ease,box-shadow .26s ease;mix-blend-mode:screen}
.ob-interactive-surface:hover>.ob-pointer-glow,.ob-interactive-surface:focus-within>.ob-pointer-glow,.ob-soft-surface:hover>.ob-pointer-glow,.ob-soft-surface:focus-within>.ob-pointer-glow{opacity:1;box-shadow:inset 0 0 0 1px rgb(var(--c-gold-hi) / .12)}

@media(hover:hover) and (pointer:fine){
  .ob-interactive-surface{transform:perspective(1100px) translate3d(0,var(--surface-lift),0) rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--surface-scale))}
  .ob-interactive-surface:hover{--surface-lift:-7px;box-shadow:0 30px 86px rgba(0,0,0,.30),0 0 44px rgb(var(--c-gold) / .075);border-color:rgb(var(--c-gold-hi) / .28)!important;filter:saturate(1.035)}
  .ob-soft-surface:hover{transform:translateY(-4px);box-shadow:0 20px 52px rgba(0,0,0,.18),0 0 32px rgb(var(--c-gold) / .055);border-color:rgb(var(--c-gold-hi) / .23)!important}
  .bounce-service-card.ob-interactive-surface:hover{--surface-scale:.975;--surface-lift:-5px}
  .concept-card.ob-interactive-surface:hover{--surface-lift:-9px;--surface-scale:1.006}
  .seo-card.ob-interactive-surface:hover{--surface-lift:-7px}
  .process-v10-item.ob-interactive-surface:hover{--surface-lift:-5px;--surface-scale:1.015;z-index:2}
}

/* Homepage industries are now actual premium, clickable cards. */
.industry-grid .industry{display:flex;flex-direction:column;min-height:270px;padding:29px;border:1px solid rgb(var(--c-gold-hi) / .11);border-radius:24px;background:linear-gradient(145deg,rgb(var(--c-surface) / .76),rgb(var(--c-bg2) / .72));color:rgb(var(--c-text));overflow:hidden;cursor:pointer;box-shadow:0 18px 52px rgba(0,0,0,.16);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px)}
.industry-grid .industry>span:first-child{font-size:10px;letter-spacing:.17em;font-weight:800;color:var(--gold)}
.industry-grid .industry h3{font:500 30px/1.05 var(--serif);letter-spacing:-.035em;margin:70px 0 11px;color:rgb(var(--c-text))}
.industry-grid .industry p{margin:0;color:rgb(var(--c-text-mut));line-height:1.62}
.industry-grid .industry .industry-cta{margin-top:auto;padding-top:24px;font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--beacon);transition:transform .25s ease,color .25s ease}
.industry-grid .industry:hover .industry-cta{transform:translateX(5px);color:var(--gold)}
.industry-grid .industry-card{display:block;cursor:pointer}

/* Make V10 process stages feel like real cards rather than flat table cells. */
.theme-dark .process-v10{gap:12px;border:0;background:transparent;overflow:visible}
.theme-dark .process-v10-item{border:1px solid rgb(var(--c-gold-hi) / .09)!important;border-radius:20px;background:linear-gradient(145deg,rgb(var(--c-surface) / .70),rgb(var(--c-bg2) / .65));box-shadow:0 14px 38px rgba(0,0,0,.12);overflow:hidden}
.theme-dark .process-v10-item strong{color:#f8f5e8}
.theme-dark .process-v10-item small{color:rgb(var(--c-text-mut))}
.theme-dark .process-v10-item span{color:var(--gold)}

/* Stronger outcome-card and SEO-card glow, visible even without pointer tracking. */
.theme-dark .approach-card:hover,.theme-dark .seo-card:hover,.theme-dark .nfc-secondary-card:hover,.theme-dark .industry-card:hover{box-shadow:0 34px 90px rgba(0,0,0,.30),0 0 55px rgb(var(--c-gold) / .08)}
.theme-dark .approach-card:hover .approach-media img{transform:scale(1.055) translateY(-2px)}
.theme-dark .seo-card:hover .seo-icon{background:rgb(var(--c-gold-hi) / .09);box-shadow:0 0 26px rgb(var(--c-gold-hi) / .12);transform:translateY(-2px)}
.seo-icon{transition:transform .28s var(--ob-ease),background .28s,box-shadow .28s}

/* Concepts: clearer affordance and more pronounced hover. */
.concept-card{touch-action:manipulation}
.concept-card:hover .concept-view,.concept-card:focus-visible .concept-view{box-shadow:0 0 0 1px rgb(var(--c-gold-hi) / .25),0 10px 30px rgba(0,0,0,.24),0 0 26px rgb(var(--c-gold-hi) / .12);transform:translateY(-2px)}
.concept-view{transition:transform .25s var(--ob-ease),box-shadow .25s ease}
.concept-card:focus-visible{outline:2px solid var(--gold);outline-offset:4px}
.concept-dialog[open]{animation:obDialogIn .28s var(--ob-ease) both}
.concept-dialog[open]::backdrop{animation:obBackdropIn .25s ease both}
@keyframes obDialogIn{from{opacity:0;transform:translateY(18px) scale(.975)}to{opacity:1;transform:none}}
@keyframes obBackdropIn{from{opacity:0}to{opacity:1}}

/* Buttons: magnetic movement is driven by JS; CSS supplies lift, glow and moving sheen. */
.btn{--mag-x:0px;--mag-y:0px;--btn-lift:0px;--btn-scale:1;position:relative;overflow:hidden;transform:translate3d(var(--mag-x),calc(var(--mag-y) + var(--btn-lift)),0) scale(var(--btn-scale));transition:transform .24s var(--ob-ease),background .25s ease,border-color .25s ease,box-shadow .25s ease,color .25s ease}
.btn:not(.liquid-glass-btn)::before{content:'';position:absolute;top:-90%;left:-42%;width:26%;height:280%;pointer-events:none;background:linear-gradient(90deg,transparent,rgb(var(--c-tint) / .36),transparent);transform:rotate(17deg) translateX(-250%);transition:transform .68s var(--ob-ease);mix-blend-mode:screen}
.btn:not(.liquid-glass-btn):hover::before{transform:rotate(17deg) translateX(650%)}
.btn:hover{--btn-lift:-3px;--btn-scale:1.018;box-shadow:0 16px 38px rgba(0,0,0,.22),0 0 30px rgb(var(--c-gold) / .11)}
.btn:active{--btn-lift:0px;--btn-scale:.975}
.btn-primary:hover{box-shadow:0 16px 40px rgb(var(--c-gold) / .20),0 0 38px rgb(var(--c-gold) / .20)}
.text-link{--mag-x:0px;--mag-y:0px;transform:translate3d(var(--mag-x),var(--mag-y),0);transition:transform .22s var(--ob-ease),color .22s ease,text-shadow .22s ease}
.text-link:hover{color:var(--gold);text-shadow:0 0 22px rgb(var(--c-gold-hi) / .18)}

/* FAQ, footer, nav/mobile affordances. */
.faq-item{position:relative;transition:background .25s ease,padding .25s ease,border-color .25s ease;border-radius:16px;padding:0 14px;margin:0 -14px}
.faq-item:hover{background:rgb(var(--c-gold-hi) / .035);border-color:rgb(var(--c-gold-hi) / .20)}
.faq-q:hover{color:var(--gold)}
.footer-col a{transition:color .22s ease,transform .22s var(--ob-ease),text-shadow .22s ease}
.footer-col a:hover{transform:translateX(5px);text-shadow:0 0 18px rgb(var(--c-gold-hi) / .12)}
.brand-link{transition:filter .25s ease,transform .25s var(--ob-ease)}
.brand-link:hover{filter:drop-shadow(0 0 14px rgb(var(--c-gold-hi) / .18));transform:translateY(-1px)}
.menu-btn,.concept-dialog-close,.quote-modal-close{transition:transform .22s var(--ob-ease),border-color .22s,background .22s,box-shadow .22s}
.menu-btn:hover,.concept-dialog-close:hover,.quote-modal-close:hover{transform:rotate(4deg) scale(1.06);border-color:rgb(var(--c-gold-hi) / .34);background:rgb(var(--c-gold-hi) / .08);box-shadow:0 0 24px rgb(var(--c-gold-hi) / .10)}
.mobile-nav a:not(.btn){transition:padding-left .22s var(--ob-ease),color .22s,background .22s}
.mobile-nav a:not(.btn):hover{padding-left:7px;color:var(--gold);background:rgb(var(--c-gold-hi) / .035)}

/* Scroll entry for surfaces that weren't already part of the original reveal system. */
.ob-auto-reveal{opacity:0;clip-path:inset(8% 0 0 0 round 18px);transition:opacity .65s ease,clip-path .65s var(--ob-ease);transition-delay:var(--ob-reveal-delay,0ms)}
.ob-auto-reveal.ob-seen{opacity:1;clip-path:inset(0 0 0 0 round 18px)}

@media(max-width:720px){
  .industry-grid .industry{min-height:220px;padding:24px}.industry-grid .industry h3{margin-top:44px}
  .theme-dark .process-v10{gap:10px}.theme-dark .process-v10-item{border-radius:18px}
  .ob-pointer-glow,.ob-cursor-halo{display:none!important}
  .ob-interactive-surface,.ob-soft-surface,.btn,.text-link{transform:none!important}
}
@media(prefers-reduced-motion:reduce){
  .ob-cursor-halo{display:none!important}.ob-interactive-surface,.ob-soft-surface,.btn,.text-link,.ob-auto-reveal{transform:none!important;transition:none!important;animation:none!important}.ob-auto-reveal{opacity:1!important;clip-path:none!important}
}

/* V11.1 — supporting interactive details */
.page-hero,.final-cta{--section-x:72%;--section-y:36%}
.page-hero::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:1;background:radial-gradient(520px circle at var(--section-x) var(--section-y),rgb(var(--c-gold-hi) / .10),rgb(var(--c-gold) / .045) 27%,transparent 65%);opacity:.75;transition:opacity .3s ease}
.page-hero:hover::after{opacity:1}
.final-cta::after{content:'';position:absolute;inset:0;pointer-events:none;z-index:1;background:radial-gradient(560px circle at var(--section-x) var(--section-y),rgb(var(--c-gold) / .10),transparent 64%);opacity:.55}
.final-cta .final-inner{z-index:3}
.field input,.field textarea,.field select{transition:border-color .22s ease,background .22s ease,box-shadow .22s ease,transform .22s var(--ob-ease)}
.field input:hover,.field textarea:hover,.field select:hover{border-color:rgb(var(--c-gold-hi) / .24)!important;background:rgb(var(--c-tint) / .055)!important}
.field input:focus,.field textarea:focus,.field select:focus{outline:none;border-color:rgb(var(--c-gold-hi) / .48)!important;box-shadow:0 0 0 3px rgb(var(--c-gold) / .08),0 0 30px rgb(var(--c-gold) / .07);transform:translateY(-1px)}
.rich a:not(.btn),.legal a:not(.btn){color:var(--beacon);text-decoration-color:rgb(var(--c-gold) / .35);text-underline-offset:3px;transition:color .2s,text-shadow .2s,text-decoration-color .2s}
.rich a:not(.btn):hover,.legal a:not(.btn):hover{color:var(--gold);text-decoration-color:var(--gold);text-shadow:0 0 18px rgb(var(--c-gold-hi) / .12)}
@media(max-width:720px){.page-hero::after,.final-cta::after{display:none}}

/* ============================================================
   V12 — Typography system + brand-accurate palette
   Palette values are the ones sampled from the canonical logo
   artwork, not eyeballed approximations.
   ============================================================ */
:root{
  /* Brand ground + depth */
  --forest:rgb(var(--c-surface));
  --deep:rgb(var(--c-bg));
  --ink:rgb(var(--c-bg2));

  /* Gold ramp, as it appears in the mark */
  --gold-deep:rgb(var(--c-accent));
  --gold:rgb(var(--c-gold));
  --gold-light:rgb(var(--c-gold-hi));

  /* Type */
  --serif:'Instrument Serif',Georgia,'Times New Roman',serif;
  --sans:'Inter',ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
}

/* Instrument Serif ships a single weight and a true italic. Suppress synthetic
   weights so the 500s inherited from the Georgia-era CSS render as real 400
   rather than a smeared fake bold. */
:where(h1,h2,h3,h4,.display,.section-title,.concept-meta strong,
       .process-v10-item strong,.seo-mini-ui strong,.seo-expect strong,
       .seo-page-visual strong){
  font-synthesis-weight:none;
}

/* Georgia needed aggressive negative tracking to look tight. Instrument Serif
   is already narrow — the same values crush it, so relax across the scale. */
.display{letter-spacing:-.018em}
.section-title,.content-grid h2,.service-detail h2{letter-spacing:-.012em}
.page-hero h1,.final-inner h2,.why-grid h2{letter-spacing:-.018em}
.bounce-card-top h3,.work-copy h3{letter-spacing:-.012em}
.approach-copy h3,.service-copy h3,.product-copy h3,.bundle-copy h3,
.industry-card h3,.industry-grid .industry h3,.concept-meta strong{letter-spacing:-.008em}
.not-found h1{letter-spacing:-.02em}
.cinematic-cta-inner h2,.project-gateway h1{letter-spacing:-.022em}
.scroll-hero-statement-text{letter-spacing:-.01em}

/* The emphasis in the hero headline was forced upright because Georgia's italic
   is unremarkable. Instrument Serif's italic is the reason to use the face. */
.hero .display em,.scroll-hero-intro .display em,.display em{font-style:italic;color:var(--gold)}

/* Body copy: Inter is now actually present, so let it do the work. */
body{font-feature-settings:'cv05' 1,'ss01' 1;letter-spacing:-.006em}
.eyebrow{font-weight:700;letter-spacing:.16em}

/* 404 — give the dead end somewhere to go. */
.notfound-links{margin-top:38px;padding-top:26px;border-top:1px solid rgb(var(--c-text) / .12);display:flex;flex-wrap:wrap;gap:10px 26px;justify-content:center}
.notfound-links a{color:rgb(var(--c-text-mut));font-size:13px;font-weight:600;transition:color .2s var(--ease-premium)}
.notfound-links a:hover,.notfound-links a:focus-visible{color:var(--gold)}

/* ------------------------------------------------------------
   /seo/ hero — the markup ships a two-column grid whose wrapper
   classes were never given rules, so the copy had no clearance
   from the fixed header and the art card had no placement.
   ------------------------------------------------------------ */
.page-hero.seo-page-hero{align-items:center}
.page-hero-grid{position:relative;z-index:2;width:min(1240px,calc(100% - 48px));display:grid;grid-template-columns:1.05fr .95fr;gap:64px;align-items:center;padding:calc(var(--header-h) + 74px) 0 76px}
.page-hero-grid>div:first-child{max-width:640px}
.page-hero-grid h1{font:500 clamp(46px,5.2vw,74px)/1 var(--serif);letter-spacing:-.018em;margin-bottom:22px}
.page-hero-grid .lede{color:rgb(var(--c-text-mut));font-size:18px;line-height:1.7;margin-bottom:30px}
.page-art-card{position:relative;z-index:2}
@media(max-width:1050px){
  .page-hero-grid{grid-template-columns:1fr;gap:44px;padding:calc(var(--header-h) + 56px) 0 60px}
  .page-hero-grid>div:first-child{max-width:none}
}
@media(max-width:720px){
  .page-hero-grid{gap:34px;padding:calc(var(--header-h) + 42px) 0 48px}
  .page-hero-grid h1{font-size:clamp(40px,10vw,52px)}
}

/* The SEO hero panel was darker than the ground it sits on, so it read as an
   empty black rectangle. Lift it into a glass panel instead. */
.seo-page-hero .seo-page-visual{
  background:radial-gradient(circle at 62% 26%,rgb(var(--c-gold) / .20),transparent 46%),
    linear-gradient(155deg,rgb(var(--c-tint) / .075),rgb(var(--c-tint) / .02) 46%,rgba(0,0,0,.28));
  border:1px solid rgb(var(--c-gold) / .30);
  box-shadow:0 40px 90px rgba(0,0,0,.45),inset 0 1px 0 rgb(var(--c-tint) / .09);
  backdrop-filter:blur(6px);
}
.seo-page-hero .seo-page-visual strong{color:var(--gold-light)}
.seo-page-hero .seo-search-bar{border-color:rgb(var(--c-tint) / .20);background:rgba(0,0,0,.22);color:rgb(var(--c-text-mut))}
.seo-page-hero .seo-page-visual small{color:rgb(var(--c-text-mut))}

/* Enquiry fallback — shown after submit so a dead mailto never swallows a lead.
   The whole site runs on body.theme-dark, so this panel is dark by default. */
.form-fallback{display:none;margin-top:22px;padding:24px;border:1px solid rgb(var(--c-tint) / .16);border-radius:var(--radius-sm);background:rgb(var(--c-tint) / .06);backdrop-filter:blur(8px)}
.form-fallback.is-visible{display:block;animation:page-hero-in .5s var(--ease-premium) both}
.form-fallback:focus{outline:none}
.form-fallback:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.form-fallback-title{margin:0 0 8px;font-weight:800;font-size:15px;line-height:1.45;color:var(--ivory)}
.form-fallback-note{margin:0 0 16px;font-size:13px;line-height:1.65;color:rgb(var(--c-text-mut))}
.form-fallback-note a{color:var(--gold);font-weight:700;text-decoration:underline;text-underline-offset:2px}
.form-fallback-body{margin:0 0 18px;padding:16px;border-radius:12px;background:rgba(0,0,0,.34);border:1px solid rgb(var(--c-tint) / .12);font:13px/1.65 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;color:rgb(var(--c-text) / .88);white-space:pre-wrap;word-break:break-word;max-height:280px;overflow:auto}
.form-fallback-actions{display:flex;flex-wrap:wrap;gap:12px}
@media(max-width:720px){.form-fallback-actions .btn{width:100%}}

/* FAQ answers: JS measures and sets max-height per item, so the fixed 260px
   clamp is lifted. Without JS every answer stays open rather than becoming
   unreachable content. */
.faq-item.open .faq-a{max-height:none}
html:not(.has-js) .faq-a{max-height:none;opacity:1}

/* Hero: the intro is centred in the stage while the decorative tile strip is
   pinned to its bottom, so the two layers knew nothing about each other and the
   CTAs landed on top of the tiles at ordinary desktop heights. Reserve the
   strip's exact footprint at the foot of the stage so the centring happens in
   the space that is actually free. The reservation is dropped once the stage
   turns over to the statement, by which point the tiles have faded out. */
@media(min-width:1051px){
  .scroll-hero-stage{
    --strip-w:min(1120px,88vw);
    --strip-gap:8px;
    --strip-bottom:34px;
    --strip-h:calc((var(--strip-w) - 4 * var(--strip-gap)) / 5);
  }
  /* Reserve the header at the top and the strip at the foot, so place-items:center
     centres the intro inside the region that is genuinely free. */
  .scroll-hero-stage:not(.is-final){padding-top:calc(var(--header-h) + 26px);padding-bottom:calc(var(--strip-h) + var(--strip-bottom) + 30px)}
  .scroll-hero-intro{padding-top:0}
  .scroll-hero-tiles{width:var(--strip-w);gap:var(--strip-gap);bottom:var(--strip-bottom)}
}
/* Shorter viewports: also tighten the intro so the reserved strip still leaves
   the headline room to breathe. */
@media(min-width:1051px) and (max-height:900px){
  .scroll-hero-stage{--strip-w:min(940px,76vw);--strip-bottom:26px}
  .scroll-hero-intro .display{margin-bottom:18px}
  .scroll-hero-intro .lede{margin-bottom:22px}
  .scroll-hero-cue{margin-top:18px}
}
@media(min-width:1051px) and (max-height:800px){
  .scroll-hero-stage{--strip-w:min(760px,64vw);--strip-bottom:20px}
  .scroll-hero-intro .display{font-size:clamp(46px,5.4vw,70px);margin-bottom:14px}
  .scroll-hero-intro .lede{margin-bottom:18px;font-size:16px}
  .scroll-hero-cue{margin-top:14px}
}

/* Final hero clearances: the stage's 760px floor exceeded short viewports, so
   the bottom-pinned strip fell below the fold; and the scroll cue grazed the
   strip in the ~860px band. */
@media(min-width:1051px) and (max-height:820px){
  .scroll-hero-stage{min-height:0}
}
@media(min-width:1051px) and (min-height:821px) and (max-height:900px){
  .scroll-hero-cue{margin-top:10px}
}

/* ============================================================
   V13 — Branded page ground
   Painted on <html> rather than a body pseudo-element: .theme-dark
   sets an opaque background on <body>, which buries any z-index:-1
   layer beneath it. Putting the artwork on the root and making body
   transparent avoids the stacking problem entirely.

   The scroll hero and its stage are fully opaque, so the homepage
   hero is unaffected by construction — nothing there changes.

   Layer order: the dimming gradient is listed first so it paints
   on top of the artwork.
   ============================================================ */
html{
  background-image:
    linear-gradient(rgb(var(--c-bg) / .52),rgb(var(--c-bg) / .46)),
    url('../images/ob-bg-desktop.webp');
  background-repeat:no-repeat,no-repeat;
  background-position:center center,center bottom;
  background-size:cover,100% auto;
  background-attachment:fixed,fixed;
}
/* .theme-dark's opaque ground would hide the artwork; specificity 0-1-1
   is needed to beat it. */
body.theme-dark{background-color:transparent}

@media(max-width:720px){
  html{
    background-image:
      linear-gradient(rgb(var(--c-bg) / .54),rgb(var(--c-bg) / .46)),
      url('../images/ob-bg-mobile.webp');
  }
}
/* Decorative only — drop it when contrast is forced. */
@media(forced-colors:active){
  html{background-image:none}
}

/* ============================================================
   V14 — Nav bar, built to the supplied design
   Full-pill bar, gold hairline rim with an asymmetric light
   streak top-right and bottom-left, OB monogram + divider,
   and a champagne "Get A Quote" pill.
   ============================================================ */
.header-inner{
  height:74px;
  padding:0 12px 0 22px;
  border-radius:999px;
  grid-template-columns:auto 1fr auto;
  gap:24px;
  position:relative;
  background:linear-gradient(180deg,rgb(var(--c-surface) / .90),rgb(var(--c-bg) / .95));
  border:1px solid rgb(var(--c-gold) / .34);
  box-shadow:0 26px 64px rgba(0,0,0,.52),inset 0 1px 0 rgb(var(--c-gold-hi) / .05);
  backdrop-filter:blur(22px) saturate(118%);
}
/* Rim light. Two streaks rather than one symmetric glow: the design catches
   light on the top-right and the bottom-left, which is what stops it reading
   as a plain outlined box. */
.header-inner::before,
.header-inner::after{
  content:'';position:absolute;left:5%;right:5%;height:1px;
  border-radius:999px;pointer-events:none;
}
.header-inner::before{
  top:-1px;
  background:linear-gradient(90deg,transparent,rgb(var(--c-gold-hi) / 0) 30%,rgb(var(--c-gold-hi) / .92) 66%,rgb(var(--c-gold-hi) / .30) 86%,transparent);
  box-shadow:0 0 16px rgb(var(--c-gold-hi) / .42);
}
.header-inner::after{
  bottom:-1px;
  background:linear-gradient(90deg,transparent,rgb(var(--c-gold-hi) / .62) 20%,rgb(var(--c-gold) / .48) 46%,rgb(var(--c-gold) / 0) 74%,transparent);
  box-shadow:0 0 14px rgb(var(--c-gold) / .30);
}
.site-header.scrolled .header-inner{
  height:68px;
  background:linear-gradient(180deg,rgb(var(--c-surface) / .93),rgb(var(--c-bg) / .96));
  border-color:rgb(var(--c-gold) / .42);
  box-shadow:0 24px 58px rgba(0,0,0,.58),inset 0 1px 0 rgb(var(--c-gold-hi) / .06);
}

/* Brand: monogram, then a hairline rule separating it from the links. */
.brand-link{gap:20px;padding:0}
.brand-mark{
  width:auto;height:46px;
  filter:drop-shadow(0 3px 14px rgb(var(--c-gold) / .30));
  transition:filter .35s var(--ease-premium),transform .35s var(--ease-premium);
}
.brand-link:hover .brand-mark{filter:drop-shadow(0 3px 20px rgb(var(--c-gold) / .55));transform:translateY(-1px)}
.brand-rule{
  display:block;width:1px;height:34px;flex:none;
  background:linear-gradient(180deg,transparent,rgb(var(--c-gold-hi) / .34),transparent);
}
.site-header.scrolled .brand-mark{height:42px}

/* Links: the design sets them lighter and larger than the old bold 13px. */
.desktop-nav{gap:34px}
.desktop-nav a{
  font-size:15px;font-weight:500;letter-spacing:-.004em;
  color:rgb(var(--c-text) / .86);
}
.desktop-nav a:hover,
.desktop-nav a:focus-visible,
.desktop-nav a[aria-current=page]{color:rgb(var(--c-text))}

/* Get A Quote — champagne pill with a circled arrow. */
.desktop-cta .btn-quote,
.mobile-nav .btn-quote{
  margin-top:0;
  min-height:52px;
  padding:0 24px 0 13px;
  gap:11px;
  font-size:15px;
  font-weight:600;
  letter-spacing:0;
  color:rgb(var(--c-on-gold));
  background:linear-gradient(135deg,#F1E8B8 0%,#DDCB86 46%,#C9B463 100%);
  box-shadow:0 12px 32px rgb(var(--c-gold-hi) / .26),inset 0 1px 0 rgb(var(--c-tint) / .42);
}
.desktop-cta .btn-quote:hover,
.mobile-nav .btn-quote:hover{
  background:linear-gradient(135deg,#F7F0CB 0%,#E7D897 46%,#D4C070 100%);
  box-shadow:0 16px 40px rgb(var(--c-gold-hi) / .38),inset 0 1px 0 rgb(var(--c-tint) / .5);
}
.cta-arrow{width:27px;height:27px;flex:none;color:rgb(var(--c-on-gold));opacity:.9}
.mobile-nav .btn-quote{margin-top:14px;justify-content:center}

@media(max-width:1050px){
  /* Only the brand and the toggle remain here, so the brand takes the free
     space and the toggle is pushed to the right edge. Without this the V14
     three-column rule above (which sits outside any media query) wins and
     leaves the toggle stranded next to the logo. */
  .header-inner{height:66px;padding:0 10px 0 16px;gap:14px;grid-template-columns:1fr auto}
  .menu-btn{justify-self:end}
  .brand-mark{height:38px}
  .brand-rule{display:none}
  .site-header.scrolled .header-inner{height:62px}
  .site-header.scrolled .brand-mark{height:36px}
}

/* ============================================================
   V15 — Footer, built to the supplied design
   Rounded card with a gold rim, four columns divided by hairlines,
   stacked lockup with contact rows, and the brand wave in the
   lower right. Social row intentionally absent for now.
   ============================================================ */
.site-footer{
  background:transparent;
  border-top:0;
  padding:0 0 40px;
}
.footer-card{
  position:relative;
  overflow:hidden;
  border-radius:30px;
  padding:56px 52px 0;
  background:linear-gradient(165deg,rgb(var(--c-bg2) / .94),rgb(var(--c-bg) / .97));
  border:1px solid rgb(var(--c-gold) / .34);
  box-shadow:0 30px 80px rgba(0,0,0,.5),inset 0 1px 0 rgb(var(--c-gold-hi) / .05);
}
/* The brand wave, reusing the ground artwork rather than shipping a new asset. */
.footer-glow{
  position:absolute;
  right:-6%;
  bottom:64px;
  width:72%;
  height:62%;
  background:url('../images/ob-bg-desktop.webp') center bottom / cover no-repeat;
  opacity:.44;
  pointer-events:none;
  -webkit-mask-image:radial-gradient(ellipse at 70% 82%,#000 12%,transparent 72%);
  mask-image:radial-gradient(ellipse at 70% 82%,#000 12%,transparent 72%);
}

.footer-grid-v12{
  position:relative;
  z-index:1;
  display:grid;
  grid-template-columns:1.55fr 1.15fr .95fr .85fr;
  gap:0;
  padding-bottom:52px;
}
.footer-grid-v12>*+*{
  border-left:1px solid rgb(var(--c-gold) / .16);
  padding-left:46px;
}
.footer-grid-v12>*+*{margin-left:0}
.footer-brand{padding-right:46px}

/* Stacked lockup, per the design. */
.footer-lockup{display:block;width:max-content;max-width:100%}
.footer-mark{width:auto;height:96px;margin:0 0 18px;filter:drop-shadow(0 4px 18px rgb(var(--c-gold) / .28))}
.footer-wordmark{width:100%;max-width:302px;height:auto}
.footer-brand-rule{
  display:block;width:96px;height:1px;margin:26px 0;
  background:linear-gradient(90deg,rgb(var(--c-gold) / .75),rgb(var(--c-gold) / 0));
}
.footer-brand p{
  color:rgb(var(--c-text-mut));
  font-size:14.5px;line-height:1.72;max-width:31ch;margin:0 0 30px;
}

/* Contact rows with circled icons. */
.footer-contact{list-style:none;margin:0;padding:0;display:grid;gap:18px}
.footer-contact li{display:flex;align-items:center;gap:15px}
.fc-icon{
  width:36px;height:36px;flex:none;border-radius:50%;
  border:1px solid rgb(var(--c-gold) / .42);
  display:grid;place-items:center;color:var(--gold);
  transition:border-color .25s var(--ease-premium),background .25s var(--ease-premium);
}
.fc-icon svg{width:17px;height:17px}
.footer-contact li:hover .fc-icon{border-color:rgb(var(--c-gold) / .8);background:rgb(var(--c-gold) / .10)}
.footer-contact a,.footer-contact span:last-child{
  color:rgb(var(--c-text) / .82);font-size:14.5px;
}
.footer-contact a{transition:color .2s var(--ease-premium)}
.footer-contact a:hover{color:var(--gold-light)}

/* Column headings: gold caps with a short rule beneath, as drawn. */
.footer-col h3{
  font-size:12.5px;text-transform:uppercase;letter-spacing:.14em;
  color:var(--gold);margin:0 0 8px;font-weight:700;
}
.footer-col h3::after{
  content:'';display:block;width:34px;height:1px;margin-top:12px;
  background:linear-gradient(90deg,rgb(var(--c-gold) / .8),rgb(var(--c-gold) / 0));
}
.footer-col{padding-top:2px}
.footer-col a{
  display:block;color:rgb(var(--c-text-mut));font-size:14.5px;padding:9px 0;
  transition:color .2s var(--ease-premium),transform .2s var(--ease-premium);
}
.footer-col a:first-of-type{margin-top:14px}
.footer-col a:hover{color:var(--gold-light);transform:translateX(3px)}

/* Bottom bar: hairline with a bright point, then the two statements. */
.footer-bottom{
  position:relative;z-index:1;
  margin:0 -52px;padding:26px 52px 34px;
  border-top:1px solid rgb(var(--c-gold) / .20);
  display:flex;justify-content:space-between;align-items:center;gap:22px;
  color:rgb(var(--c-text) / .48);font-size:13.5px;
}
.footer-bottom::before{
  content:'';position:absolute;top:-1px;left:22%;width:26%;height:1px;
  background:linear-gradient(90deg,transparent,rgb(var(--c-gold-hi) / .85),transparent);
  box-shadow:0 0 12px rgb(var(--c-gold-hi) / .4);
}
.footer-tagline em{font-style:normal;color:var(--gold)}

@media(max-width:1050px){
  .footer-card{padding:44px 32px 0;border-radius:26px}
  .footer-grid-v12{grid-template-columns:1fr 1fr;gap:40px 0}
  .footer-grid-v12>*+*{padding-left:34px}
  .footer-brand{grid-column:1/-1;padding-right:0;border-left:0;padding-left:0}
  .footer-grid-v12>.footer-col:nth-of-type(2){border-left:0;padding-left:0}
  .footer-bottom{margin:0 -32px;padding:24px 32px 30px}
  .footer-glow{width:96%;height:46%;opacity:.34}
}
@media(max-width:720px){
  .site-footer{padding:0 0 22px}
  .footer-card{padding:36px 22px 0;border-radius:22px}
  .footer-grid-v12{grid-template-columns:1fr;gap:34px}
  .footer-grid-v12>*+*{border-left:0;padding-left:0}
  .footer-mark{height:78px}
  .footer-wordmark{max-width:248px}
  .footer-bottom{margin:0 -22px;padding:22px 22px 26px;flex-direction:column;align-items:flex-start;gap:12px;font-size:12.5px}
  .footer-bottom::before{left:8%;width:44%}
}

/* ============================================================
   V16 — Hero, built to the supplied design
   Copy left, device scene right, five feature blocks along the
   foot. The scroll choreography is untouched: same hooks, same
   phases, same floater flight — only the contents are restyled.
   ============================================================ */

/* Two-column intro. The JS still drives transform/opacity on this
   element, so only layout changes here. */
.scroll-hero-intro{
  display:grid;
  grid-template-columns:1.02fr .98fr;
  align-items:center;
  gap:40px;
  text-align:left;
  padding-top:0;
}
.hero-copy-col{max-width:640px}
.scroll-hero-intro .eyebrow{color:var(--gold);margin-bottom:22px}
.scroll-hero-intro .display{
  margin:0 0 24px;
  max-width:none;
  font-size:clamp(44px,4.6vw,72px);
  line-height:1.02;
}
.scroll-hero-intro .lede{
  margin:0 0 34px;
  max-width:34rem;
  color:rgb(var(--c-text-mut));
}
.scroll-hero-intro .hero-actions{justify-content:flex-start;margin:0}
.scroll-hero-cue{margin-top:34px}

.hero-visual-col{position:relative;display:grid;place-items:center}
.hero-devices{
  width:100%;
  max-width:760px;
  height:auto;
  filter:drop-shadow(0 40px 90px rgba(0,0,0,.55));
}

/* Hero buttons, as drawn: solid gold with an arrow, and an outlined pair. */
.btn-hero-gold{
  background:linear-gradient(135deg,#E8CE72 0%,#D2B24F 48%,#BC9C3C 100%);
  color:rgb(var(--c-on-gold));font-weight:800;font-size:13px;letter-spacing:.09em;text-transform:uppercase;
  padding:0 24px;gap:12px;margin-top:0;
  box-shadow:0 14px 34px rgb(var(--c-gold-hi) / .26),inset 0 1px 0 rgb(var(--c-tint) / .4);
}
.btn-hero-gold:hover{
  background:linear-gradient(135deg,#F2DC8A 0%,#DFC066 48%,#CBAB4C 100%);
  box-shadow:0 18px 44px rgb(var(--c-gold-hi) / .36),inset 0 1px 0 rgb(var(--c-tint) / .48);
}
.hero-cta-arrow{width:18px;height:18px;flex:none}
.btn-hero-ghost{
  background:rgb(var(--c-bg) / .55);
  color:var(--ivory);font-weight:800;font-size:13px;letter-spacing:.09em;text-transform:uppercase;
  border:1px solid rgb(var(--c-text) / .30);padding:0 24px;margin-top:0;
  backdrop-filter:blur(10px);
}
.btn-hero-ghost:hover{border-color:rgb(var(--c-gold) / .7);background:rgb(var(--c-gold) / .12);color:rgb(var(--c-text))}

/* Feature strip. Height changes, so the stage's reserved space changes with it. */
.scroll-hero-stage{--strip-h:178px}
.scroll-hero-tiles{align-items:stretch}
.scroll-hero-tile{
  aspect-ratio:auto;
  overflow:visible;
  border:0;
  border-radius:0;
  background:transparent;
  box-shadow:none;
  display:flex;
  flex-direction:column;
  align-items:center;
  text-align:center;
  gap:12px;
  padding:0 16px;
}
.scroll-hero-tile::after{display:none}
.scroll-hero-tile+.scroll-hero-tile{border-left:1px solid rgb(var(--c-gold) / .20)}
/* Colour must be set at .scroll-hero-tile scope: the legacy
   `.scroll-hero-tile span` and `:nth-child(5) span` rules are more specific
   than a bare class and were painting icons ivory and forest-green. */
.scroll-hero-tile .hero-tile-icon{color:var(--gold)}
.scroll-hero-tile .hero-tile-label{color:var(--gold)}
.scroll-hero-tile .hero-tile-copy{color:rgb(var(--c-text-mut))}
.hero-tile-icon{
  width:52px;height:52px;flex:none;
  border-radius:13px;
  border:1px solid rgb(var(--c-gold) / .45);
  background:rgb(var(--c-gold) / .09);
  display:grid;place-items:center;
  transition:border-color .3s var(--ease-premium),background .3s var(--ease-premium);
}
.hero-tile-icon svg{width:24px;height:24px}
.scroll-hero-tile:hover .hero-tile-icon{border-color:rgb(var(--c-gold) / .85);background:rgb(var(--c-gold) / .18)}
/* The legacy rule absolutely positions EVERY span inside a tile, which
   collapsed the tile to zero height once the image was replaced by three
   in-flow spans. Put them all back in flow. */
.scroll-hero-tile .hero-tile-icon,
.scroll-hero-tile .hero-tile-label,
.scroll-hero-tile .hero-tile-copy{position:static;left:auto;bottom:auto}
.scroll-hero-tile .hero-tile-icon{display:grid}
.scroll-hero-tile .hero-tile-label{display:block}
.scroll-hero-tile .hero-tile-copy{display:block}
.hero-tile-label{
  font-size:12px;font-weight:800;letter-spacing:.15em;text-transform:uppercase;
  color:var(--gold);
}
.hero-tile-copy{
  font-size:12.5px;line-height:1.5;
  color:rgb(var(--c-text-mut));
  max-width:20ch;
}

/* The floating icons that fly into the statement now carry the icon tile. */
.hero-floating-icon{background:rgb(var(--c-surface) / .92);border-color:rgb(var(--c-gold) / .4)}
.hero-floating-icon .hero-tile-icon{width:100%;height:100%;border:0;border-radius:0;background:transparent}
.hero-floating-icon .hero-tile-icon svg{width:56%;height:56%}

@media(max-width:1050px){
  .scroll-hero-intro{grid-template-columns:1fr;gap:26px;text-align:center}
  .hero-copy-col{max-width:none;margin-inline:auto}
  .scroll-hero-intro .lede{margin-inline:auto}
  .scroll-hero-intro .hero-actions{justify-content:center}
  .scroll-hero-cue{justify-content:center}
  .hero-visual-col{order:2}
  .hero-devices{max-width:560px}
  /* Stacked, the intro is much taller, so it needs to be pinned clear of the
     fixed header rather than vertically centred into it. */
  .scroll-hero-stage{--strip-h:132px;align-content:start}
  .scroll-hero-stage:not(.is-final){padding-top:calc(var(--header-h) + 34px)}
  .hero-devices{width:auto;max-width:min(560px,80vw);max-height:32vh;object-fit:contain}
  .hero-tile-icon{width:44px;height:44px;border-radius:11px}
  .hero-tile-icon svg{width:21px;height:21px}
  .scroll-hero-tile .hero-tile-copy{display:none}
  .scroll-hero-tile{padding:0 8px;gap:10px}
}
@media(max-width:720px){
  .scroll-hero-stage{--strip-h:96px}
  /* Keep the device scene on phones — it is the hero's main visual and most
     visitors arrive on mobile. Room is made by tightening the headline and
     letting the stage grow instead of pinning it to viewport height. */
  .hero-visual-col{display:grid;order:2}
  .hero-devices{width:auto;max-width:min(430px,72vw);max-height:24vh;object-fit:contain}
  .scroll-hero-intro{gap:18px}
  .scroll-hero-intro .display{font-size:clamp(34px,8.6vw,46px);margin-bottom:12px}
  .scroll-hero-intro .lede{font-size:14.5px;line-height:1.6;margin-bottom:20px}
  .scroll-hero-intro .eyebrow{margin-bottom:14px;font-size:10px}
  .scroll-hero-cue{display:none}
  .scroll-hero-stage{min-height:auto}
  .hero-tile-icon{width:36px;height:36px;border-radius:9px}
  .hero-tile-icon svg{width:17px;height:17px}
  .hero-tile-label{font-size:8.5px;letter-spacing:.1em}
  .scroll-hero-tile{padding:0 3px;gap:7px}
  .scroll-hero-tile+.scroll-hero-tile{border-left:0}
  .btn-hero-gold,.btn-hero-ghost{width:100%}
}

/* Tiles 4 and 5 carried dark label text because their images used to sit on a
   light plate. They hold icons now, so the dark override has to go — matched
   at nth-child specificity to actually beat the legacy rule. */
.scroll-hero-tile:nth-child(4) .hero-tile-icon,
.scroll-hero-tile:nth-child(5) .hero-tile-icon,
.scroll-hero-tile:nth-child(4) .hero-tile-label,
.scroll-hero-tile:nth-child(5) .hero-tile-label{color:var(--gold)}
.scroll-hero-tile:nth-child(4) .hero-tile-copy,
.scroll-hero-tile:nth-child(5) .hero-tile-copy{color:rgb(var(--c-text-mut))}
/* Same reason: the floating icon for tile 5 had a light plate behind the photo. */
.hero-floating-icon:nth-of-type(5) .hero-tile-icon,
.hero-floating-icon[data-index='4'] .hero-tile-icon{background:transparent;padding:0}

/* Short viewports (small windows, landscape phones). The stage is pinned to
   viewport height and the feature strip is anchored near its foot, so on a
   short screen the copy, buttons and device cannot all fit above it. Shed the
   device first, then the strip copy — rather than let them collide. */
@media(max-height:760px){
  .hero-devices{max-height:20vh}
  .scroll-hero-intro .display{font-size:clamp(32px,4.4vw,52px)}
  .scroll-hero-cue{display:none}
}
@media(max-height:640px){
  .hero-visual-col{display:none}
  .scroll-hero-stage{--strip-h:104px}
}

/* ============================================================
   V17 — Hero background is the particle artwork
   The device mock is gone; the artwork itself is the hero visual,
   full-bleed behind the stage. Copy sits left over the dark side
   of the composition, the gold sweep carries the right.
   Scroll choreography still untouched.
   ============================================================ */
.scroll-hero-stage::before{
  background-image:
    linear-gradient(90deg,rgb(var(--c-bg) / .95) 0%,rgb(var(--c-bg) / .82) 34%,rgb(var(--c-bg) / .42) 64%,rgb(var(--c-bg) / .22) 100%),
    url('../images/bg-dark.webp');
  background-size:cover;
  background-position:center center;
  background-repeat:no-repeat;
}

/* Single column now — the right side is the artwork, not an element. */
.scroll-hero-intro{grid-template-columns:1fr;gap:0}
.hero-copy-col{max-width:41rem}
.scroll-hero-intro .display{font-size:clamp(44px,4.8vw,74px)}
.scroll-hero-intro .lede{max-width:33rem}

@media(max-width:1050px){
  .scroll-hero-stage::before{
    background-image:
      linear-gradient(180deg,rgb(var(--c-bg) / .90) 0%,rgb(var(--c-bg) / .62) 46%,rgb(var(--c-bg) / .80) 100%),
      url('../images/bg-dark-mobile.webp');
    background-position:center;
  }
  .scroll-hero-intro{text-align:left}
  .hero-copy-col{max-width:none;margin-inline:0}
  .scroll-hero-intro .lede{margin-inline:0}
  .scroll-hero-intro .hero-actions{justify-content:flex-start}
  .scroll-hero-cue{justify-content:flex-start}
}
@media(max-width:720px){
  .scroll-hero-intro .display{font-size:clamp(34px,8.6vw,48px)}
}

/* ============================================================
   V18 — Olive Beacon colour palette, applied site-wide
   ============================================================ */
:root{
  --bg:rgb(var(--c-bg));          /* main background   */
  --bg-2:rgb(var(--c-bg2));        /* secondary surface */
  --surface:rgb(var(--c-surface));     /* olive surface     */
  --accent-olive:rgb(var(--c-accent));/* muted olive accent*/
  --gold:rgb(var(--c-gold));        /* primary gold      */
  --gold-light:rgb(var(--c-gold-hi));  /* highlight gold    */
  --gold-deep:rgb(var(--c-accent));
  --text:rgb(var(--c-text));        /* main text         */
  --text-muted:rgb(var(--c-text-mut));  /* muted text        */

  /* legacy names kept so existing rules resolve to the new palette */
  --ivory:rgb(var(--c-text));
  --forest:rgb(var(--c-surface));
  --deep:rgb(var(--c-bg));
  --ink:rgb(var(--c-bg2));
  --muted:rgb(var(--c-text-mut));
  --beacon:rgb(var(--c-gold));
  --moss:rgb(var(--c-accent));
  --olive:rgb(var(--c-accent));
  --sage:rgb(var(--c-bg2));
  --sage2:rgb(var(--c-surface));
  --dark-0:rgb(var(--c-bg));
  --dark-1:rgb(var(--c-bg2));
  --dark-2:rgb(var(--c-surface));
  --line:rgb(var(--c-gold) / .20);
  --dark-line:rgb(var(--c-gold) / .20);
}
.theme-dark{
  --dark-0:rgb(var(--c-bg));
  --dark-1:rgb(var(--c-bg2));
  --dark-2:rgb(var(--c-surface));
  --glass:rgb(var(--c-surface) / .54);
  --glass-strong:rgb(var(--c-bg2) / .72);
  --dark-line:rgb(var(--c-gold) / .20);
}

/* ============================================================
   V19 — Particle artwork as the whole-site ground, blended footer
   ============================================================ */
html{
  background-color:var(--bg);
  background-image:
    linear-gradient(rgb(var(--c-bg) / .72),rgb(var(--c-bg) / .66)),
    url('../images/bg-dark.webp');
  background-repeat:no-repeat,no-repeat;
  background-position:center center,center center;
  background-size:cover,cover;
  background-attachment:fixed,fixed;
}
body.theme-dark{background-color:transparent}
@media(max-width:720px){
  html{
    background-image:
      linear-gradient(rgb(var(--c-bg) / .74),rgb(var(--c-bg) / .66)),
      url('../images/bg-dark-mobile.webp');
  }
}
@media(forced-colors:active){ html{background-image:none} }

/* Sections sit on the ground rather than covering it, so the artwork reads
   through the whole page instead of only behind the hero. */
.theme-dark .section{background:rgb(var(--c-bg) / .30)}
.theme-dark .section-sage{background:linear-gradient(rgb(var(--c-bg2) / .72),rgb(var(--c-bg) / .62))}
.theme-dark .section-dark{background:linear-gradient(rgb(var(--c-bg) / .66),rgb(var(--c-bg2) / .74))}
.theme-dark .bounce-services-section{background:linear-gradient(rgb(var(--c-bg2) / .74),rgb(var(--c-bg) / .64))}

/* Footer: no card, no border — it dissolves into the page. */
.site-footer{padding:0;background:transparent}
.footer-card{
  border:0;
  border-radius:0;
  box-shadow:none;
  background:linear-gradient(180deg,rgb(var(--c-bg) / 0) 0%,rgb(var(--c-bg) / .55) 26%,rgb(var(--c-bg) / .82) 100%);
  padding:78px 0 0;
  width:min(1240px,calc(100% - 48px));
}
.footer-card::before{
  content:'';position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,rgb(var(--c-gold) / .42) 30%,rgb(var(--c-gold-hi) / .55) 52%,rgb(var(--c-gold) / .32) 74%,transparent);
}
.footer-glow{opacity:.30}
.footer-bottom{margin:0;padding:26px 0 40px}
.footer-bottom::before{left:16%;width:30%}
@media(max-width:1050px){
  .footer-card{padding:56px 0 0}
  .footer-bottom{margin:0;padding:24px 0 34px}
}
@media(max-width:720px){
  .footer-card{padding:44px 0 0}
  .footer-bottom{margin:0;padding:22px 0 28px}
}

/* ============================================================
   V20 — Text corrections after the palette change
   Several components were dark-text-on-light-surface. The palette
   has no light surface, so those surfaces are now dark and their
   text has to invert or it renders invisible.
   ============================================================ */
.light-seo-bento .seo-card,
.light-seo-bento .seo-card h3,
.light-seo-bento .seo-card p{color:var(--text)}
.light-seo-bento .seo-card p{color:var(--text-muted)}
.light-seo-bento .seo-icon{color:var(--gold)}

.theme-dark .legal strong,
.theme-dark .seo-expect strong,
.theme-dark .concept-meta strong,
.theme-dark .process-v10-item strong{color:var(--text)}
.theme-dark .legal p,
.theme-dark .legal li,
.theme-dark .rich p,
.theme-dark .rich li{color:var(--text-muted)}
.theme-dark .process-v10-item span,
.theme-dark .approach-num,
.theme-dark .service-kicker,
.theme-dark .work-label,
.theme-dark .eyebrow{color:var(--gold)}
.theme-dark .faq-q{color:var(--text)}
.theme-dark .faq-q:hover,
.theme-dark .faq-item.open .faq-q{color:var(--gold-light)}

/* The pinned statement turns over to a dark stage in this theme, so its
   type must be light — the original flipped to a light stage. */
.theme-dark .scroll-hero-statement-text{color:var(--text)}
.theme-dark .scroll-hero-statement>.eyebrow{color:var(--gold)}
.theme-dark .scroll-hero-statement-note{color:var(--text-muted)}

/* About-page value list and any remaining numbered markers. */
.theme-dark .principle,
.theme-dark .value-index,
.theme-dark .about-index{color:var(--text)}

/* ============================================================
   V21 — Final contrast corrections
   ============================================================ */
/* .seo-expect was a light panel (58% white). The palette has no light
   surface, so it becomes a dark glass panel and its type inverts.
   (My V20 pass inverted the text but left the light panel — worse than
   before. This fixes both together.) */
.theme-dark .seo-expect{
  background:linear-gradient(150deg,rgb(var(--c-surface) / .82),rgb(var(--c-bg2) / .88));
  border:1px solid rgb(var(--c-gold) / .22);
}
.theme-dark .seo-expect strong{color:var(--text)}
.theme-dark .seo-expect li,
.theme-dark .seo-expect p{color:var(--text-muted)}

/* Primary gold is deep; on raised surfaces small labels need the highlight
   tone to stay legible. */
.theme-dark .industry-card .index,
.theme-dark .industry .index,
.theme-dark .approach-num,
.theme-dark .service-kicker,
.theme-dark .work-label{color:var(--gold-light)}

/* 10px caps at 46% opacity fell just under AA. */
.theme-dark .concept-meta span{color:rgb(var(--c-text-mut))}

/* Last two: spec labels and step numerals landed at ~4.4 against their card
   surfaces, just under AA for small text. */
.theme-dark .fact span:first-child{color:rgb(var(--c-text) / .80)}
.theme-dark .process-step .num{color:var(--gold-light)}

/* ============================================================
   V22 — Light and dark themes
   Every palette colour above resolves through these channel
   tokens, so the whole site switches by swapping this block.
   Light is the base; dark applies via the system preference or
   an explicit data-theme on <html>.
   ============================================================ */
:root{
  --c-bg:252 251 246;        /* #FCFBF6 main background      */
  --c-bg2:243 244 233;       /* #F3F4E9 secondary background */
  --c-surface:238 241 228;   /* #EEF1E4 surface / cards      */
  --c-border:229 226 213;    /* #E5E2D5 borders / dividers   */
  --c-text:29 41 28;         /* #1D291C primary text         */
  --c-text-mut:60 76 53;     /* #3C4C35 secondary text       */
  --c-accent:120 101 37;     /* #786525 bronze accent        */
  --c-gold:175 138 52;       /* #AF8A34 primary gold         */
  --c-gold-hi:231 196 105;   /* #E7C469 highlight gold       */
  --c-on-gold:29 41 28;      /* text on a gold fill          */
  --c-tint:0 0 0;            /* overlay tint: dark on light  */
  --c-shadow:29 41 28;
  --shadow-strength:.10;
  color-scheme:light;
}
:root[data-theme="dark"],
:root:not([data-theme="light"]) [data-theme-fallback]{ }

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --c-bg:8 13 7;           /* #080D07 */
    --c-bg2:16 23 12;        /* #10170C */
    --c-surface:25 33 16;    /* #192110 */
    --c-border:175 138 52;   /* gold hairlines on dark */
    --c-text:245 242 232;    /* #F5F2E8 */
    --c-text-mut:183 184 174;/* #B7B8AE */
    --c-accent:79 74 28;     /* #4F4A1C */
    --c-gold:175 138 52;
    --c-gold-hi:231 196 105;
    --c-on-gold:30 36 16;
    --c-tint:255 255 255;    /* overlay tint: light on dark */
    --c-shadow:0 0 0;
    --shadow-strength:.45;
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --c-bg:8 13 7;
  --c-bg2:16 23 12;
  --c-surface:25 33 16;
  --c-border:175 138 52;
  --c-text:245 242 232;
  --c-text-mut:183 184 174;
  --c-accent:79 74 28;
  --c-gold:175 138 52;
  --c-gold-hi:231 196 105;
  --c-on-gold:30 36 16;
  --c-tint:255 255 255;
  --c-shadow:0 0 0;
  --shadow-strength:.45;
  color-scheme:dark;
}

/* Legacy named tokens now resolve through the themed channels. */
:root{
  --ivory:rgb(var(--c-text));
  --forest:rgb(var(--c-surface));
  --deep:rgb(var(--c-bg));
  --ink:rgb(var(--c-text));
  --muted:rgb(var(--c-text-mut));
  --beacon:rgb(var(--c-gold));
  --moss:rgb(var(--c-accent));
  --olive:rgb(var(--c-accent));
  --sage:rgb(var(--c-bg2));
  --sage2:rgb(var(--c-surface));
  --gold:rgb(var(--c-gold));
  --gold-light:rgb(var(--c-gold-hi));
  --gold-deep:rgb(var(--c-accent));
  --text:rgb(var(--c-text));
  --text-muted:rgb(var(--c-text-mut));
  --bg:rgb(var(--c-bg));
  --bg-2:rgb(var(--c-bg2));
  --surface:rgb(var(--c-surface));
  --accent-olive:rgb(var(--c-accent));
  --dark-0:rgb(var(--c-bg));
  --dark-1:rgb(var(--c-bg2));
  --dark-2:rgb(var(--c-surface));
  --line:rgb(var(--c-border) / .55);
  --dark-line:rgb(var(--c-border) / .30);
  --white:rgb(var(--c-bg));
  --shadow:0 24px 80px rgb(var(--c-shadow) / var(--shadow-strength));
}

/* ---- Theme-aware artwork -------------------------------------------- */
:root[data-theme="light"] html,
html{ }
html{ background-image:linear-gradient(rgb(var(--c-bg) / .72),rgb(var(--c-bg) / .66)),url('../images/bg-light.webp'); }
@media(max-width:720px){
  html{ background-image:linear-gradient(rgb(var(--c-bg) / .74),rgb(var(--c-bg) / .66)),url('../images/bg-light-mobile.webp'); }
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    background-image:linear-gradient(rgb(var(--c-bg) / .72),rgb(var(--c-bg) / .66)),url('../images/bg-dark.webp');
  }
  @media(max-width:720px){
    :root:not([data-theme="light"]){
      background-image:linear-gradient(rgb(var(--c-bg) / .74),rgb(var(--c-bg) / .66)),url('../images/bg-dark-mobile.webp');
    }
  }
}
:root[data-theme="dark"]{
  background-image:linear-gradient(rgb(var(--c-bg) / .72),rgb(var(--c-bg) / .66)),url('../images/bg-dark.webp');
}
@media(max-width:720px){
  :root[data-theme="dark"]{
    background-image:linear-gradient(rgb(var(--c-bg) / .74),rgb(var(--c-bg) / .66)),url('../images/bg-dark-mobile.webp');
  }
}

/* Hero stage artwork follows the theme too. */
.scroll-hero-stage::before{
  background-image:
    linear-gradient(90deg,rgb(var(--c-bg) / .95) 0%,rgb(var(--c-bg) / .82) 34%,rgb(var(--c-bg) / .42) 64%,rgb(var(--c-bg) / .22) 100%),
    url('../images/bg-light.webp');
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .scroll-hero-stage::before{
    background-image:
      linear-gradient(90deg,rgb(var(--c-bg) / .95) 0%,rgb(var(--c-bg) / .82) 34%,rgb(var(--c-bg) / .42) 64%,rgb(var(--c-bg) / .22) 100%),
      url('../images/bg-dark.webp');
  }
}
:root[data-theme="dark"] .scroll-hero-stage::before{
  background-image:
    linear-gradient(90deg,rgb(var(--c-bg) / .95) 0%,rgb(var(--c-bg) / .82) 34%,rgb(var(--c-bg) / .42) 64%,rgb(var(--c-bg) / .22) 100%),
    url('../images/bg-dark.webp');
}

/* ---- Theme toggle ---------------------------------------------------- */
.theme-toggle{
  width:42px;height:42px;flex:none;display:grid;place-items:center;
  border-radius:50%;cursor:pointer;
  border:1px solid rgb(var(--c-gold) / .40);
  background:rgb(var(--c-tint) / .06);
  color:rgb(var(--c-gold-text));
  transition:border-color .25s var(--ease-premium),background .25s var(--ease-premium),color .25s var(--ease-premium);
}
.theme-toggle:hover{border-color:rgb(var(--c-gold) / .85);background:rgb(var(--c-gold) / .14);color:rgb(var(--c-gold-text))}
.theme-toggle:focus-visible{outline:2px solid rgb(var(--c-gold));outline-offset:3px}
.theme-toggle svg{width:19px;height:19px}
.theme-toggle .icon-sun{display:none}
.theme-toggle .icon-moon{display:block}
:root[data-theme="dark"] .theme-toggle .icon-sun{display:block}
:root[data-theme="dark"] .theme-toggle .icon-moon{display:none}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .theme-toggle .icon-sun{display:block}
  :root:not([data-theme="light"]) .theme-toggle .icon-moon{display:none}
}
.header-actions{display:flex;align-items:center;gap:12px}
.mobile-nav .theme-toggle{width:100%;border-radius:999px;height:48px;margin-top:12px;gap:10px;grid-auto-flow:column}


/* Gold reads as a highlight on dark and as bronze on light — the palette's
   bronze accent exists precisely because gold on cream fails contrast. */
:root{ --c-gold-text:120 101 37; }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){ --c-gold-text:231 196 105; }
}
:root[data-theme="dark"]{ --c-gold-text:231 196 105; }

/* Gold used as TEXT resolves to bronze on light, highlight gold on dark.
   Decorative gold (borders, glows, button fills) is deliberately left alone. */
.eyebrow,
.theme-dark .eyebrow,
.scroll-hero-intro .eyebrow,
.theme-dark .scroll-hero-statement>.eyebrow,
.hero-tile-label,
.scroll-hero-tile .hero-tile-label,
.scroll-hero-tile:nth-child(4) .hero-tile-label,
.scroll-hero-tile:nth-child(5) .hero-tile-label,
.approach-num,.theme-dark .approach-num,
.service-kicker,.theme-dark .service-kicker,
.work-label,.theme-dark .work-label,
.seo-icon,.theme-dark .seo-icon,
.light-seo-bento .seo-icon,
.industry-card .index,.theme-dark .industry-card .index,
.theme-dark .industry .index,
.process-v10-item span,.theme-dark .process-v10-item span,
.footer-col h3,
.text-link.light-link,
.theme-dark .process-step .num,
.theme-dark .fact span:first-child,
.scroll-hero-tile .hero-tile-icon,
.hero-tile-icon,
.fc-icon,
.theme-dark .faq-item.open .faq-q,
.theme-dark .faq-q:hover{color:rgb(var(--c-gold-text))}

/* The muted-text token is the right tool for secondary copy in both themes. */
.theme-dark .concept-note,
.concept-note,
.theme-dark .hero-tile-copy,
.scroll-hero-tile .hero-tile-copy,
.theme-dark .fact span:first-child{color:rgb(var(--c-text-mut))}
.theme-dark .fact span:first-child{color:rgb(var(--c-text-mut))}

/* Text sitting on a gold fill must use the on-gold token in both themes;
   in light theme it was inheriting the pale surface colour and vanishing. */
.btn-primary,.theme-dark .btn-primary,
.btn-quote,.desktop-cta .btn-quote,.mobile-nav .btn-quote,
.btn-hero-gold,
.cinematic-cta .btn-primary,
.project-quote-btn{color:rgb(var(--c-on-gold))}
.seo-tags span,.theme-dark .seo-tags span{color:rgb(var(--c-text-mut))}

/* Card call-to-action links: gold on a light card is ~2.9:1. */
.industry-cta,.theme-dark .industry-cta,
.industry .industry-cta{color:rgb(var(--c-gold-text))}

/* The legacy --gold token feeds dozens of text rules. On cream it measures
   ~2.9:1, so light theme resolves it to the palette's bronze. Dark theme keeps
   the exact gold it already had — nothing about the dark look changes. */
:root{
  --gold:rgb(120 101 37);
  --gold-light:rgb(120 101 37);
  --moss:rgb(120 101 37);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --gold:rgb(var(--c-gold));
    --gold-light:rgb(var(--c-gold-hi));
    --moss:rgb(var(--c-accent));
  }
}
:root[data-theme="dark"]{
  --gold:rgb(var(--c-gold));
  --gold-light:rgb(var(--c-gold-hi));
  --moss:rgb(var(--c-accent));
}

/* --beacon feeds card CTAs and inherits the same problem as --gold. */
:root{ --beacon:rgb(120 101 37); }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){ --beacon:rgb(var(--c-gold)); }
}
:root[data-theme="dark"]{ --beacon:rgb(var(--c-gold)); }

/* The gold demo panel composites to a mid bronze on light, where dark type
   fails. Keep it pale there so the copy on it stays readable. */
.theme-dark .bounce-demo-gold{
  background:linear-gradient(145deg,rgb(var(--c-gold-hi) / .42),rgb(var(--c-gold) / .26));
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .theme-dark .bounce-demo-gold{
    background:linear-gradient(145deg,rgb(var(--c-accent) / .88),rgb(var(--c-surface) / .92));
  }
}
:root[data-theme="dark"] .theme-dark .bounce-demo-gold{
  background:linear-gradient(145deg,rgb(var(--c-accent) / .88),rgb(var(--c-surface) / .92));
}

/* Last marginals: step numerals and the mock search bar on light cards. */
.theme-dark .process-step .num,.process-step .num{color:rgb(var(--c-text))}
.seo-search-bar,.theme-dark .seo-search-bar,
.seo-page-hero .seo-search-bar{color:rgb(var(--c-text-mut));background:rgb(var(--c-tint) / .06)}

/* In light theme the primary button fills with bronze, which is a dark tone —
   so its label needs to be the light ground colour, not the dark on-gold one. */
.btn-primary,.theme-dark .btn-primary{color:rgb(var(--c-bg))}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .btn-primary,
  :root:not([data-theme="light"]) .theme-dark .btn-primary{color:rgb(var(--c-on-gold))}
}
:root[data-theme="dark"] .btn-primary,
:root[data-theme="dark"] .theme-dark .btn-primary{color:rgb(var(--c-on-gold))}

/* Copy sitting on the bronze demo panel. */
.bounce-demo-gold,.bounce-demo-gold span,.bounce-demo-gold small,
.theme-dark .bounce-demo-gold span,.theme-dark .bounce-demo-gold small,
.seo-demo-panel span,.theme-dark .seo-demo-panel span,
.seo-mini-ui span,.seo-mini-ui small,.seo-mini-ui strong{color:rgb(var(--c-bg))}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .bounce-demo-gold span,
  :root:not([data-theme="light"]) .seo-mini-ui span,
  :root:not([data-theme="light"]) .seo-mini-ui small,
  :root:not([data-theme="light"]) .seo-mini-ui strong{color:rgb(var(--c-text))}
}
:root[data-theme="dark"] .bounce-demo-gold span,
:root[data-theme="dark"] .seo-mini-ui span,
:root[data-theme="dark"] .seo-mini-ui small,
:root[data-theme="dark"] .seo-mini-ui strong{color:rgb(var(--c-text))}

/* Correction: the demo panel is pale on light and dark on dark, so its copy
   simply follows --c-text in both. (The previous rule set light-on-pale.) */
.bounce-demo-gold,.bounce-demo-gold span,.bounce-demo-gold small,
.theme-dark .bounce-demo-gold span,.theme-dark .bounce-demo-gold small,
.seo-demo-panel span,.theme-dark .seo-demo-panel span,
.seo-mini-ui span,.seo-mini-ui small,.seo-mini-ui strong,
:root[data-theme="dark"] .bounce-demo-gold span,
:root[data-theme="dark"] .seo-mini-ui span,
:root[data-theme="dark"] .seo-mini-ui small,
:root[data-theme="dark"] .seo-mini-ui strong{color:rgb(var(--c-text))}

/* .btn-quote also carries .btn-primary, so it picked up the light-theme
   cream label — but its fill is always pale gold, so it needs the dark one. */
.btn-quote,.btn-quote span,
.desktop-cta .btn-quote,.desktop-cta .btn-quote span,
.mobile-nav .btn-quote,.mobile-nav .btn-quote span,
.btn-hero-gold,.btn-hero-gold span{color:rgb(var(--c-on-gold))}

/* The ivory/sage demo panels composite to a mid bronze on light. Keep them
   pale there so their captions stay legible; dark theme is untouched. */
.theme-dark .bounce-demo-ivory,.theme-dark .bounce-demo-sage{
  background:linear-gradient(145deg,rgb(var(--c-gold-hi) / .34),rgb(var(--c-surface) / .18));
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .theme-dark .bounce-demo-ivory,
  :root:not([data-theme="light"]) .theme-dark .bounce-demo-sage{
    background:linear-gradient(145deg,rgb(var(--c-accent) / .88),rgb(var(--c-surface) / .92));
  }
}
:root[data-theme="dark"] .theme-dark .bounce-demo-ivory,
:root[data-theme="dark"] .theme-dark .bounce-demo-sage{
  background:linear-gradient(145deg,rgb(var(--c-accent) / .88),rgb(var(--c-surface) / .92));
}
.bounce-demo-panel span,.theme-dark .bounce-demo-panel span{color:rgb(var(--c-text))}

/* Footer small print at 48% is too faint on cream. */
.footer-bottom,.footer-bottom span{color:rgb(var(--c-text-mut))}

/* The header now has brand / actions / toggle-menu. The old two-column mobile
   grid pushed the menu button onto a second row. */
@media(max-width:1050px){
  .header-inner{grid-template-columns:1fr auto auto;gap:10px}
  .header-actions{gap:8px}
  .desktop-cta{display:none}
  .menu-btn{justify-self:end}
  .theme-toggle{width:38px;height:38px}
  .theme-toggle svg{width:17px;height:17px}
}
@media(max-width:720px){
  .theme-toggle{width:36px;height:36px}
}

/* ============================================================
   V24 — Hero intro: centred, and bounded so it cannot collide
   The stage is viewport-height with the feature strip anchored
   near its foot. The intro was a fixed-size block centred in
   that space, so on a short window it overflowed onto the strip.
   Type is now capped against viewport height as well as width,
   which keeps it inside the space the stage actually reserves.
   The strip stays absolute at left:50% — the scroll animation
   writes translate3d(-50%,…) to it, so that must not change.
   ============================================================ */
.scroll-hero-intro{
  grid-template-columns:1fr;
  justify-items:center;
  text-align:center;
  gap:0;
  /* never grow into the strip's reserved band */
  max-height:calc(100dvh - var(--header-h) - var(--strip-h) - var(--strip-bottom) - 44px);
}
.hero-copy-col{
  max-width:min(58rem,92%);
  margin-inline:auto;
  display:flex;
  flex-direction:column;
  align-items:center;
}
.scroll-hero-intro .eyebrow{margin-bottom:min(22px,2.2vh)}
.scroll-hero-intro .display{
  /* the vh cap is what stops a short window pushing copy onto the strip */
  font-size:min(clamp(38px,4.7vw,72px),8.4vh);
  margin:0 0 min(24px,2.4vh);
  max-width:19ch;
}
.scroll-hero-intro .lede{
  font-size:min(18px,2.5vh);
  line-height:1.62;
  margin:0 0 min(32px,3.2vh);
  max-width:56ch;
  margin-inline:auto;
}
.scroll-hero-intro .hero-actions{justify-content:center;margin:0}
.scroll-hero-cue{justify-content:center;margin-top:min(30px,3vh)}

@media(max-width:1050px){
  .scroll-hero-intro{text-align:center;justify-items:center}
  .hero-copy-col{max-width:min(46rem,94%);margin-inline:auto;align-items:center}
  .scroll-hero-intro .lede{margin-inline:auto}
  .scroll-hero-intro .hero-actions{justify-content:center}
  .scroll-hero-cue{justify-content:center}
}
@media(max-width:720px){
  .scroll-hero-intro .display{font-size:min(clamp(32px,8.4vw,46px),8vh);max-width:16ch}
  .scroll-hero-intro .lede{font-size:min(15px,2.3vh);max-width:44ch}
}
/* Very short windows: drop the scroll cue before anything can overlap. */
@media(max-height:700px){ .scroll-hero-cue{display:none} }

/* Short windows: the tile copy was still rendering at wide-but-short sizes,
   so the strip stood ~168px tall while --strip-h reserved only 104px and the
   intro was laid out into space that was already taken. Reserve what is
   actually drawn, and drop the tile copy when there is no room for it. */
@media(max-height:760px){
  .scroll-hero-tile .hero-tile-copy{display:none}
  .scroll-hero-stage{--strip-h:118px}
  .scroll-hero-intro .display{font-size:min(clamp(34px,4.2vw,60px),7.6vh);margin-bottom:min(18px,1.9vh)}
  .scroll-hero-intro .lede{font-size:min(16px,2.3vh);margin-bottom:min(22px,2.4vh)}
  .scroll-hero-intro .eyebrow{margin-bottom:min(14px,1.6vh);font-size:10px}
}
@media(max-height:640px){
  .scroll-hero-stage{--strip-h:104px}
  .hero-tile-icon{width:42px;height:42px;border-radius:11px}
  .hero-tile-icon svg{width:20px;height:20px}
  .scroll-hero-intro .display{font-size:min(clamp(30px,3.8vw,50px),7.2vh)}
  .scroll-hero-intro .hero-actions .btn{min-height:46px}
}
@media(max-height:560px){
  .scroll-hero-stage{--strip-h:92px}
  .hero-tile-icon{width:36px;height:36px}
  .hero-tile-icon svg{width:17px;height:17px}
  .hero-tile-label{font-size:9.5px}
  .scroll-hero-intro .lede{display:none}
}

/* ============================================================
   V25 — /start-project/: ribbon replaced by the brand artwork
   The ribbon's gradients are inline in the HTML with the old lime
   palette, so the stylesheet could never re-colour them. Rather
   than restyle the SVG, the artwork is painted onto the same
   <svg> element — so it inherits the existing ob-glass-wave-sweep
   animation untouched — and the ribbon's own paths are hidden.
   A second, slower layer keeps the two-plane depth the ribbon had.
   ============================================================ */
.start-project-page .project-liquid-ribbon > *{display:none}
.start-project-page .project-liquid-ribbon{
  background-image:url('../images/bg-light.webp');
  background-size:cover;
  background-position:center center;
  background-repeat:no-repeat;
  opacity:.92;
  -webkit-mask-image:radial-gradient(ellipse 74% 62% at 50% 52%,#000 34%,rgba(0,0,0,.55) 62%,transparent 88%);
  mask-image:radial-gradient(ellipse 74% 62% at 50% 52%,#000 34%,rgba(0,0,0,.55) 62%,transparent 88%);
}
/* Second plane: slower breathe, offset scale — replaces the depth the
   layered ribbon paths used to give. */
.start-project-page .project-liquid-stage::after{
  content:'';
  position:absolute;
  inset:-10%;
  z-index:-1;
  pointer-events:none;
  background:url('../images/bg-light.webp') center center / cover no-repeat;
  opacity:.42;
  transform-origin:48% 53%;
  animation:ob-glass-wave-breathe 6.4s ease-in-out infinite alternate;
  -webkit-mask-image:radial-gradient(ellipse 82% 70% at 52% 48%,#000 22%,transparent 80%);
  mask-image:radial-gradient(ellipse 82% 70% at 52% 48%,#000 22%,transparent 80%);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .start-project-page .project-liquid-ribbon{
    background-image:url('../images/bg-dark.webp');
  }
  :root:not([data-theme="light"]) .start-project-page .project-liquid-stage::after{
    background-image:url('../images/bg-dark.webp');
  }
}
:root[data-theme="dark"] .start-project-page .project-liquid-ribbon{
  background-image:url('../images/bg-dark.webp');
}
:root[data-theme="dark"] .start-project-page .project-liquid-stage::after{
  background-image:url('../images/bg-dark.webp');
}
@media(prefers-reduced-motion:reduce){
  .start-project-page .project-liquid-stage::after{animation:none!important}
}

/* ============================================================
   V26 — Navbar: one unit, everything optically centred
   The links carried asymmetric padding (27px top / 24px bottom),
   so their text sat below the pill's centre line, and at narrow
   desktop widths they wrapped to two lines and pushed the whole
   row down. Links are now full-height flex boxes that centre
   their own text, and the labels never wrap.
   ============================================================ */
.header-inner{align-items:center}

.desktop-nav{
  align-items:stretch;
  align-self:stretch;
  gap:clamp(14px,1.9vw,32px);
}
.desktop-nav a{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  padding:0 2px;
  height:100%;
  line-height:1;
  white-space:nowrap;          /* two-line wrap was breaking the bar */
}
/* Decoration is measured from the centre line now that padding is gone. */
.desktop-nav a::after{bottom:calc(50% - 15px)}
.desktop-nav a::before{bottom:calc(50% - 26px)}
.site-header.scrolled .desktop-nav a{padding:0 2px}

/* Brand, actions and toggle share one centre line and one rhythm. */
.brand-link{align-self:center;height:100%;align-items:center}
.header-actions{align-self:center;height:100%;align-items:center}
.desktop-cta{display:flex;align-items:center;height:100%}
.desktop-cta .btn-quote{min-height:48px;align-self:center}
.theme-toggle{align-self:center;width:44px;height:44px}
.menu-btn{align-self:center}
.brand-rule{align-self:center}

/* A matching hairline before the actions binds the right-hand group to the
   brand mark, so the bar reads as one object rather than three. */
.header-actions::before{
  content:'';
  width:1px;
  height:32px;
  flex:none;
  margin-right:4px;
  background:linear-gradient(180deg,transparent,rgb(var(--c-gold) / .34),transparent);
}

/* Narrow desktop: tighten before anything is forced to wrap. */
@media(max-width:1320px){
  .desktop-nav a{font-size:14px}
}
@media(max-width:1180px){
  .desktop-nav a{font-size:13.2px}
  .header-inner{gap:16px;padding:0 10px 0 18px}
  .desktop-cta .btn-quote{padding:0 18px 0 11px;font-size:13.5px}
  .cta-arrow{width:23px;height:23px}
}
@media(max-width:1090px){
  .desktop-nav{gap:12px}
  .desktop-nav a{font-size:12.6px}
  .header-actions::before{display:none}
}
@media(max-width:1050px){
  .header-actions::before{display:none}
  .theme-toggle{width:38px;height:38px}
}

/* ============================================================
   V27 — Concept library: filters, themed cards, 3-page dialog
   ============================================================ */
.concept-filters{
  display:flex;flex-wrap:wrap;gap:9px;margin:0 0 30px;
}
.concept-chip{
  font-size:12.5px;font-weight:700;letter-spacing:.01em;
  padding:9px 15px;border-radius:999px;cursor:pointer;
  background:rgb(var(--c-tint) / .05);
  border:1px solid rgb(var(--c-border) / .40);
  color:rgb(var(--c-text-mut));
  display:inline-flex;align-items:center;gap:8px;
  transition:border-color .22s var(--ease-premium),background .22s var(--ease-premium),color .22s var(--ease-premium);
}
.concept-chip span{
  font-size:10.5px;font-variant-numeric:tabular-nums;
  padding:2px 6px;border-radius:999px;
  background:rgb(var(--c-gold) / .16);color:rgb(var(--c-gold-text));
}
.concept-chip:hover{border-color:rgb(var(--c-gold) / .6);color:rgb(var(--c-text))}
.concept-chip.is-active{
  background:rgb(var(--c-gold) / .14);
  border-color:rgb(var(--c-gold) / .7);
  color:rgb(var(--c-text));
}
.concept-chip:focus-visible{outline:2px solid rgb(var(--c-gold));outline-offset:2px}

.concept-grid-lib{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:18px;
}
.concept-grid-lib .concept-card{width:100%}
.concept-grid-lib .concept-card[hidden]{display:none}
.concept-industry{
  font-size:10.5px;letter-spacing:.13em;text-transform:uppercase;
  color:rgb(var(--c-gold-text));
}
.concept-theme{
  display:block;padding:0 19px 18px;margin-top:-6px;
  font-size:13px;line-height:1.55;text-align:left;
  color:rgb(var(--c-text-mut));
}
.concept-empty{color:rgb(var(--c-text-mut));font-size:15px;padding:26px 0}

/* Dialog: three stacked pages with a jump bar. */
.concept-dialog-theme{
  margin:0;padding:16px 20px 0;font-size:13.5px;line-height:1.6;
  color:rgb(var(--c-text-mut));max-width:70ch;
}
.concept-dialog-tabs{
  display:flex;flex-wrap:wrap;gap:8px;padding:14px 20px 4px;
  position:sticky;top:0;z-index:3;
  background:linear-gradient(rgb(var(--c-bg2)) 72%,transparent);
}
.concept-tab{
  font-size:12px;font-weight:700;padding:7px 13px;border-radius:999px;cursor:pointer;
  background:rgb(var(--c-tint) / .06);
  border:1px solid rgb(var(--c-border) / .40);
  color:rgb(var(--c-text-mut));
  transition:border-color .2s,color .2s,background .2s;
}
.concept-tab:hover{color:rgb(var(--c-text));border-color:rgb(var(--c-gold) / .55)}
.concept-tab.is-active{background:rgb(var(--c-gold) / .16);border-color:rgb(var(--c-gold) / .7);color:rgb(var(--c-text))}
.concept-pages{display:grid;gap:26px;padding:16px 20px 24px}
.concept-page{margin:0;display:grid;gap:9px}
.concept-page figcaption{
  font-size:10.5px;font-weight:800;letter-spacing:.15em;text-transform:uppercase;
  color:rgb(var(--c-gold-text));
}
.concept-page img{
  width:100%;height:auto;border-radius:12px;
  border:1px solid rgb(var(--c-border) / .34);
  box-shadow:0 20px 50px rgb(var(--c-shadow) / var(--shadow-strength));
}
@media(max-width:720px){
  .concept-grid-lib{grid-template-columns:1fr;gap:14px}
  .concept-filters{gap:7px;margin-bottom:22px}
  .concept-chip{font-size:11.5px;padding:8px 12px}
  .concept-pages{padding:12px 12px 18px;gap:18px}
  .concept-dialog-tabs{padding:12px 12px 4px}
  .concept-dialog-theme{padding:14px 12px 0}
}

/* ============================================================
   V28 — Hero feature icons swapped for the rendered brand set
   These are detailed 3D objects rather than line glyphs, so the
   outlined tile that framed the old SVGs is dropped — a box round
   each one competes with the object inside it. The .hero-tile-icon
   wrapper stays because the scroll animation clones it in flight.
   ============================================================ */
.scroll-hero-tile .hero-tile-icon,
.hero-tile-icon{
  width:72px;height:72px;
  border:0;
  background:transparent;
  border-radius:0;
  display:grid;place-items:center;
  filter:drop-shadow(0 8px 18px rgb(var(--c-shadow) / calc(var(--shadow-strength) * .9)));
  transition:transform .32s var(--ease-premium),filter .32s var(--ease-premium);
}
.hero-tile-icon img{
  width:100%;height:100%;
  object-fit:contain;
  display:block;
}
.scroll-hero-tile:hover .hero-tile-icon{
  background:transparent;
  transform:translateY(-3px) scale(1.05);
  filter:drop-shadow(0 12px 26px rgb(var(--c-gold) / .34));
}

/* In flight the icon keeps its own artwork — no plate behind it. */
.hero-floating-icon{background:transparent;border:0;box-shadow:none}
.hero-floating-icon .hero-tile-icon{width:100%;height:100%;filter:none}
.hero-floating-icon .hero-tile-icon img{width:100%;height:100%;object-fit:contain}

@media(max-width:1050px){
  .scroll-hero-tile .hero-tile-icon,.hero-tile-icon{width:58px;height:58px}
}
@media(max-width:720px){
  .scroll-hero-tile .hero-tile-icon,.hero-tile-icon{width:46px;height:46px}
}
@media(max-height:640px){
  .scroll-hero-tile .hero-tile-icon,.hero-tile-icon{width:52px;height:52px}
}
@media(max-height:560px){
  .scroll-hero-tile .hero-tile-icon,.hero-tile-icon{width:44px;height:44px}
}

/* ============================================================
   V29 — Strip legacy photo styling off the hero icons
   Tiles 4 and 5 used to hold product shots on a light plate, so
   `.scroll-hero-tile:nth-child(4|5) img` set a background gradient
   and padding. The rendered icons inherited that plate — which is
   the "background" showing behind Mobile and Growth. All five also
   inherited saturate(.92)/contrast(1.02) from the photo rule, which
   dulls the gold. Matched at nth-child specificity to actually win.
   ============================================================ */
.scroll-hero-tile .hero-tile-icon img,
.scroll-hero-tile:nth-child(1) .hero-tile-icon img,
.scroll-hero-tile:nth-child(2) .hero-tile-icon img,
.scroll-hero-tile:nth-child(3) .hero-tile-icon img,
.scroll-hero-tile:nth-child(4) .hero-tile-icon img,
.scroll-hero-tile:nth-child(5) .hero-tile-icon img{
  background:none;
  padding:0;
  filter:none;
  transform:none;
  object-fit:contain;
  width:100%;
  height:100%;
}
/* Same for the icons in flight. */
.hero-floating-icon img,
.hero-floating-icon:nth-of-type(4) img,
.hero-floating-icon:nth-of-type(5) img,
.hero-floating-icon[data-index='3'] img,
.hero-floating-icon[data-index='4'] img{
  background:none;padding:0;filter:none;object-fit:contain;
}

/* ============================================================
   V30 — Colour system rebuilt around forest/olive
   Deep Forest #172219 · Olive #3E5035 · Soft Sage #E8EEE2
   Warm Ivory #F8F5EE · Muted Gold #C8A95B

   Two changes do most of the de-yellowing:
   1. --c-border was gold (67 border rules); it is now Olive, so
      hairlines read green rather than brass.
   2. Gold splits by role. --c-gold is the brand accent and is the
      SAME value in both themes, used for fills, borders and glows.
      Gold used as TEXT resolves through --c-gold-text, because
      #C8A95B on Warm Ivory is only 2.08:1 and unreadable — on light
      it deepens to #7D6524 (5.13:1). The accent still matches; only
      the type tone shifts where it has to.
   ============================================================ */
:root{
  --c-bg:248 245 238;        /* #F8F5EE Warm Ivory   */
  --c-bg2:232 238 226;       /* #E8EEE2 Soft Sage    */
  --c-surface:241 245 236;   /* #F1F5EC              */
  --c-border:208 219 200;    /* #D0DBC8 sage line    */
  --c-text:23 34 25;         /* #172219 Deep Forest  */
  --c-text-mut:62 80 53;     /* #3E5035 Olive        */
  --c-accent:62 80 53;       /* #3E5035 Olive        */
  --c-gold:200 169 91;       /* #C8A95B accent — same in both themes */
  --c-gold-hi:180 149 74;    /* #B4954A              */
  --c-gold-text:125 101 36;  /* #7D6524 legible gold type on light   */
  --c-gold-hi-text:109 88 31;/* #6D581F              */
  --c-on-gold:23 34 25;      /* forest on a gold fill — 7.26:1       */
  --c-tint:0 0 0;
  --c-shadow:23 34 25;
  --shadow-strength:.10;
  color-scheme:light;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --c-bg:23 34 25;          /* #172219 Deep Forest — the dominant dark */
    --c-bg2:30 43 32;         /* #1E2B20 */
    --c-surface:38 52 40;     /* #263428 */
    --c-border:62 80 53;      /* #3E5035 Olive, not gold */
    --c-text:248 245 238;     /* #F8F5EE Warm Ivory */
    --c-text-mut:175 186 172; /* #AFBAAC sage grey  */
    --c-accent:62 80 53;
    --c-gold:200 169 91;
    --c-gold-hi:210 185 111;  /* #D2B96F */
    --c-gold-text:200 169 91; /* on forest the accent is already 7.26:1 */
    --c-gold-hi-text:210 185 111;
    --c-on-gold:23 34 25;
    --c-tint:255 255 255;
    --c-shadow:0 0 0;
    --shadow-strength:.45;
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --c-bg:23 34 25;
  --c-bg2:30 43 32;
  --c-surface:38 52 40;
  --c-border:62 80 53;
  --c-text:248 245 238;
  --c-text-mut:175 186 172;
  --c-accent:62 80 53;
  --c-gold:200 169 91;
  --c-gold-hi:210 185 111;
  --c-gold-text:200 169 91;
  --c-gold-hi-text:210 185 111;
  --c-on-gold:23 34 25;
  --c-tint:255 255 255;
  --c-shadow:0 0 0;
  --shadow-strength:.45;
  color-scheme:dark;
}

/* Legacy aliases. --gold/--gold-light are almost always used as TEXT
   (49 rules), so they resolve to the readable tone; --beacon stays the
   brand accent because it fills buttons. */
:root{
  --gold:rgb(var(--c-gold-text));
  --gold-light:rgb(var(--c-gold-hi-text));
  --gold-deep:rgb(var(--c-accent));
  --beacon:rgb(var(--c-gold));
  --moss:rgb(var(--c-accent));
  --olive:rgb(var(--c-accent));
  --forest:rgb(var(--c-surface));
  --ivory:rgb(var(--c-text));
  --deep:rgb(var(--c-bg));
  --ink:rgb(var(--c-text));
  --muted:rgb(var(--c-text-mut));
  --sage:rgb(var(--c-bg2));
  --sage2:rgb(var(--c-surface));
  --text:rgb(var(--c-text));
  --text-muted:rgb(var(--c-text-mut));
  --bg:rgb(var(--c-bg));
  --bg-2:rgb(var(--c-bg2));
  --surface:rgb(var(--c-surface));
  --accent-olive:rgb(var(--c-accent));
  --dark-0:rgb(var(--c-bg));
  --dark-1:rgb(var(--c-bg2));
  --dark-2:rgb(var(--c-surface));
  --line:rgb(var(--c-border) / .70);
  --dark-line:rgb(var(--c-border) / .45);
  --white:rgb(var(--c-bg));
  --shadow:0 24px 80px rgb(var(--c-shadow) / var(--shadow-strength));
}

/* Buttons were a bright brass gradient; retune to the muted accent. */
.btn-hero-gold,.desktop-cta .btn-quote,.mobile-nav .btn-quote{
  background:linear-gradient(135deg,rgb(var(--c-gold-hi)) 0%,rgb(var(--c-gold)) 52%,rgb(var(--c-gold) / .88) 100%);
  color:rgb(var(--c-on-gold));
  box-shadow:0 12px 30px rgb(var(--c-gold) / .22),inset 0 1px 0 rgb(255 255 255 / .28);
}
.btn-hero-gold:hover,.desktop-cta .btn-quote:hover,.mobile-nav .btn-quote:hover{
  background:linear-gradient(135deg,rgb(var(--c-gold-hi)) 0%,rgb(var(--c-gold-hi)) 48%,rgb(var(--c-gold)) 100%);
  box-shadow:0 16px 38px rgb(var(--c-gold) / .32),inset 0 1px 0 rgb(255 255 255 / .34);
}
.cta-arrow,.hero-cta-arrow{color:rgb(var(--c-on-gold))}
.theme-dark .btn-primary{background:rgb(var(--c-gold));color:rgb(var(--c-on-gold))}
.theme-dark .btn-primary:hover{background:rgb(var(--c-gold-hi))}

/* --beacon is the button-fill gold; used as TEXT it fails on light
   (2.06:1). Route these through the readable gold instead. */
.industry-grid .industry .industry-cta,
.industry-grid .industry:hover .industry-cta,
.industry .industry-cta{color:rgb(var(--c-gold-text))}

/* Chip counters sit on a raised chip, which costs ~0.3 of contrast. */
.concept-chip span,
.concept-chip.is-active span{
  color:rgb(var(--c-text));
  opacity:.72;
  font-weight:700;
}

/* Body-copy links were also on the fill gold. */
.rich a:not(.btn),.legal a:not(.btn),
.theme-dark .rich a:not(.btn),.theme-dark .legal a:not(.btn){color:rgb(var(--c-gold-text))}

/* The gold CTA is the most visible accent on the site, so it is pinned to
   fixed values rather than theme tokens — identical in light and dark. */
.btn-hero-gold,.desktop-cta .btn-quote,.mobile-nav .btn-quote,
.theme-dark .btn-primary{
  background:linear-gradient(135deg,#D6BB78 0%,#C8A95B 54%,#B99A4B 100%);
  color:#172219;
}
.btn-hero-gold:hover,.desktop-cta .btn-quote:hover,.mobile-nav .btn-quote:hover,
.theme-dark .btn-primary:hover{
  background:linear-gradient(135deg,#E0C88C 0%,#D2B96F 54%,#C8A95B 100%);
  color:#172219;
}

/* Outlined controls need 3:1 against their ground to be perceivable
   (WCAG 1.4.11). The ghost button sat at 1.89:1 on light, 2.58:1 on dark. */
.btn-hero-ghost{border-color:rgb(var(--c-text) / .52)}
.btn-hero-ghost:hover{border-color:rgb(var(--c-gold));background:rgb(var(--c-gold) / .12)}
.btn-outline{border-color:rgb(var(--c-text) / .46)}
.btn-outline:hover{border-color:rgb(var(--c-gold));background:rgb(var(--c-gold) / .12)}

/* Remaining outlined controls below the 3:1 perceivability floor.
   In light mode the rim uses the deeper gold so it reads without
   turning brassy; in dark the accent gold is already legible. */
.theme-dark .btn-outline,.btn-outline{
  border-color:rgb(var(--c-text) / .50);
  color:rgb(var(--c-text));
}
.theme-dark .btn-outline:hover,.btn-outline:hover{
  border-color:rgb(var(--c-gold));
  background:rgb(var(--c-gold) / .12);
  color:rgb(var(--c-text));
}
.theme-toggle{border-color:rgb(var(--c-gold-text) / .70)}
.theme-toggle:hover{border-color:rgb(var(--c-gold));background:rgb(var(--c-gold) / .16)}
.header-inner{border-color:rgb(var(--c-gold-text) / .55)}
.site-header.scrolled .header-inner{border-color:rgb(var(--c-gold-text) / .68)}

/* Light mode needs a touch more rim on these two to clear 3:1. */
:root[data-theme="light"] .theme-toggle,
:root:not([data-theme="dark"]) .theme-toggle{border-color:rgb(var(--c-gold-text) / .88)}
:root[data-theme="light"] .header-inner,
:root:not([data-theme="dark"]) .header-inner{border-color:rgb(var(--c-gold-text) / .80)}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .theme-toggle{border-color:rgb(var(--c-gold-text) / .70)}
  :root:not([data-theme="light"]) .header-inner{border-color:rgb(var(--c-gold-text) / .55)}
}
:root[data-theme="dark"] .theme-toggle{border-color:rgb(var(--c-gold-text) / .70)}
:root[data-theme="dark"] .header-inner{border-color:rgb(var(--c-gold-text) / .55)}

/* ============================================================
   V31 — /seo/ hero art card carries an image
   The card is a tall panel sitting opposite the hero copy, so the
   image has to fill that shape rather than dictate its own. Keeping
   height:auto turned a 16:9 image into a short wide strip and broke
   the two-column balance. It now fills the original card footprint,
   anchored right so the magnifier and panels stay in frame while the
   empty left of the source is what gets trimmed.
   ============================================================ */
.seo-page-visual-img,
.seo-page-hero .seo-page-visual-img{
  display:block;
  padding:0;
  min-height:420px;
  height:100%;
  overflow:hidden;
  border-radius:28px;
  border:1px solid rgb(var(--c-gold) / .30);
  background:rgb(var(--c-bg2));
  box-shadow:0 35px 80px rgb(var(--c-shadow) / calc(var(--shadow-strength) * 1.1));
  backdrop-filter:none;
}
/* height:100% cannot resolve here — .page-art-card has no definite height,
   so the percentage collapsed to auto and left ~113px of dead panel below
   the image. Absolute fill sidesteps the percentage-height chain entirely. */
.seo-page-visual-img{position:relative}
.seo-page-visual-img img{
  position:absolute;
  inset:0;
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
  object-position:72% center;   /* subject sits right of centre in the source */
}
/* let the card match the height of the copy beside it */
.seo-page-hero .page-hero-grid{align-items:stretch}
.seo-page-hero .page-art-card{display:flex;align-self:stretch}
.seo-page-hero .seo-page-visual-img{flex:1}
@media(max-width:1050px){
  .seo-page-hero .page-hero-grid{align-items:start}
  .seo-page-hero .page-art-card{display:block}
}
@media(max-width:1050px){
  .seo-page-visual-img,.seo-page-hero .seo-page-visual-img{min-height:340px}
}
@media(max-width:720px){
  .seo-page-visual-img,.seo-page-hero .seo-page-visual-img{min-height:260px;border-radius:22px}
  .seo-page-visual-img img{object-position:70% center}
}

/* ============================================================
   V31 — Service card panels sized to the new renders
   The panel spanned the full card width (2.9:1 on the wide cards)
   while the renders are 4:3, so object-fit:contain fitted them by
   height and left ~70% of the panel empty. On wide cards the panel
   is now right-aligned at roughly the artwork's own proportion, so
   the render fills it and the copy takes the freed space.
   ============================================================ */
.bounce-demo-panel img{
  object-fit:cover;
  object-position:center 42%;
}
@media(min-width:1051px){
  .bounce-service-card.bounce-wide .bounce-demo-panel{
    left:auto;
    right:18px;
    width:min(44%,420px);
  }
  .bounce-service-card.bounce-wide .bounce-card-top{
    max-width:min(52%,460px);
  }
  /* the small cards are already close to the artwork ratio */
  .bounce-service-card.bounce-small .bounce-demo-panel{left:14px;right:14px}
}

/* Small cards stack copy above the panel, so the "Explore service" link was
   running into the top of the image by up to 32px. Give the card a little
   more height and start the panel below the copy. Wide cards are unaffected
   — their copy and panel sit side by side. */
@media(min-width:1051px){
  .bounce-service-card{min-height:474px}
  .bounce-service-card.bounce-small .bounce-demo-panel{top:272px}
}
/* Stacked layout: the panel went back to ~2.2:1 and cropped half the render.
   Taller panel brings it near the artwork's own proportion. */
@media(max-width:1050px){
  .bounce-service-card{min-height:500px}
  .bounce-demo-panel{top:238px}
}
@media(max-width:720px){
  .bounce-service-card{min-height:520px}
  .bounce-demo-panel{top:236px;bottom:-38px}
}

/* =============================
   Service card fit V32
   -----------------------------
   The demo panel was pinned top AND bottom, so its height came from the card
   rather than from the artwork. Across 375px-1440px that swung the image box
   between 1.02:1 and 1.92:1 while the renders are 1.33:1 and 1.5:1, cropping
   up to 32% and colliding with the copy at some widths only.

   Now the image sizes itself (aspect-ratio) and the panel height follows it,
   so the crop is a constant ~5-7% everywhere. The panel still bleeds past the
   card bottom and is clipped by overflow:hidden, as designed.
   ============================= */
.bounce-demo-panel{
  display:flex;
  flex-direction:column;
  align-items:stretch;
  justify-content:flex-end;
  top:auto;
  height:auto;
}
.bounce-demo-panel img{
  position:static;
  inset:auto;
  width:100%;
  height:auto;
  aspect-ratio:7/5;
  object-fit:cover;
  object-position:center 42%;
}
.bounce-demo-panel>span{margin-top:10px;text-align:center}

/* Desktop: panel is anchored to the card bottom and grows upward, so the card
   only needs enough height to keep the stacked copy clear of it. */
@media(min-width:1051px){
  .bounce-service-card{min-height:505px}
  .bounce-service-card.bounce-small .bounce-demo-panel{top:auto}
}

/* Stacked layout: take the panel out of absolute positioning entirely so the
   card grows to fit copy + artwork instead of guessing a min-height. The
   negative bottom margin preserves the bleed off the card edge. */
@media(max-width:1050px){
  .bounce-service-card{min-height:0;display:flex;flex-direction:column}
  .bounce-card-top{flex:0 0 auto}
  .bounce-demo-panel{
    position:relative;
    left:auto;right:auto;bottom:auto;
    margin:26px -10px -40px;
    width:auto;
  }
}
@media(max-width:720px){
  .bounce-demo-panel{margin:24px -10px -38px}
}

/* Service card fit V33 — three leftovers from V32.
   1. At 1440px the longer headlines push the copy into the panel on the small
      cards, so the fixed desktop height needs a little more room.
   2. On the wide cards the copy column and the side panel were within 15px of
      touching; give them a real gutter.
   3. In the stacked grid a card stretched to match its row put the spare
      height *below* the panel, which cancelled the bleed. Pushing the panel
      down with an auto top margin keeps it welded to the card edge. */
@media(min-width:1051px){
  .bounce-service-card{min-height:525px}
  .bounce-service-card.bounce-wide .bounce-demo-panel{width:min(46%,420px)}
  .bounce-service-card.bounce-wide .bounce-card-top{max-width:min(46%,400px)}
}
@media(max-width:1050px){
  .bounce-demo-panel{margin-top:auto}
}

/* =============================
   Contrast pass V34 (post-palette audit)
   -----------------------------
   Swept 3,418 text nodes over 18 pages in both themes, compositing every
   transparent layer down to the real background artwork. 29 near-miss
   failures, in two causes:

   1. Light-theme gold type (#7D6524) landed at 4.18:1 on the pale sage
      surfaces (.seo-icon, .text-link.light-link) and 4.48:1 on .index —
      just under AA. Darkening the *text* token to #715A1E takes those to
      4.92:1. The gold ACCENT (--c-gold / --beacon, which fills buttons and
      rules) is untouched, so the palette still reads the same; only gold
      used as small type moves. Dark theme keeps its own token.
   2. The hero scroll cue was set at 48% of the text colour: 2.98:1 light,
      4.03:1 dark. 70% clears AA in both (5.9:1 / 6.5:1) while staying
      visibly secondary.
   ============================= */
:root{ --c-gold-text:113 90 30; }   /* #715A1E — light theme only; the
                                       dark-theme rules outrank this */
.scroll-hero-cue{color:rgb(var(--c-text) / .70)}

/* =============================
   Contrast pass V35 — hover states
   -----------------------------
   Forcing every :hover rule through the real cascade (302 hoverable
   elements per page) left exactly one failure, in both themes:
   .theme-dark .seo-card:hover .seo-icon adds a gold wash behind the icon,
   which moves the backdrop under the gold glyph — 4.45:1 light, 4.15:1
   dark. Darkening the light glyph and brightening the dark one puts both
   at 4.87:1 without touching the wash itself.
   ============================= */
.seo-card:hover .seo-icon,
.theme-dark .seo-card:hover .seo-icon{color:#6A5420}
:root[data-theme="dark"] .seo-card:hover .seo-icon,
:root[data-theme="dark"] .theme-dark .seo-card:hover .seo-icon{color:rgb(var(--c-gold-hi))}
@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .seo-card:hover .seo-icon,
  :root:not([data-theme="light"]) .theme-dark .seo-card:hover .seo-icon{color:rgb(var(--c-gold-hi))}
}

/* =============================
   Non-text contrast V36 — form fields
   -----------------------------
   WCAG 1.4.11 wants 3:1 on the visual boundary of a control that nothing
   else identifies. Most flagged borders here are decorative (concept cards
   and chips carry their own image or label), but an EMPTY input is defined
   by its border alone, and these were 0.67px of gold at 13% alpha — the
   same value in both themes — measuring 1.11:1 light / 1.30:1 dark.

   A muted-text border at 70% reads as a real hairline in both themes
   (3.94:1 light, 4.65:1 dark). Hover and focus were raised alongside it,
   because at their old alphas (.24/.48) they would have made the boundary
   *fainter* than the resting state.
   ============================= */
.field input,.field textarea,.field select,
.theme-dark .field input,.theme-dark .field textarea,.theme-dark .field select,
.quote-modal .field input,.quote-modal .field textarea,.quote-modal .field select{
  border-width:1px;
  border-color:rgb(var(--c-text-mut) / .70);
}
.field input:hover,.field textarea:hover,.field select:hover,
.theme-dark .field input:hover,.theme-dark .field textarea:hover,.theme-dark .field select:hover{
  border-color:rgb(var(--c-text-mut) / .90)!important;
}
.field input:focus,.field textarea:focus,.field select:focus,
.theme-dark .field input:focus,.theme-dark .field textarea:focus,.theme-dark .field select:focus{
  border-color:rgb(var(--c-gold-text))!important;
  box-shadow:0 0 0 3px rgb(var(--c-gold) / .30),0 0 30px rgb(var(--c-gold) / .10)!important;
}

/* =============================
   Service cards V37 — panel back to its original size
   -----------------------------
   V31-V33 fixed the image crop by growing the panel (and the card with it).
   That changed the layout, which isn't wanted: the panel returns to exactly
   the geometry it had before — absolute, pinned top:205px / bottom:-46px,
   full card width, card min-height 430px (405px on mobile) — and the ARTWORK
   is what adapts now, via object-fit:cover.

   Trade-off, stated plainly: a fixed-height panel is ~2.9:1 on the wide
   cards at 1440px while the renders are 1.33:1 and 1.5:1, so cover crops
   the top and bottom of the artwork there. That is the cost of keeping the
   original panel size, and it is preferred over the empty letterboxing that
   object-fit:contain produced in the same box.
   ============================= */
.bounce-service-card{min-height:430px;display:block}
.bounce-card-top{max-width:620px}
.bounce-demo-panel{
  position:absolute;
  display:flex;
  flex-direction:row;
  align-items:flex-end;
  justify-content:center;
  left:18px;right:18px;top:205px;bottom:-46px;
  width:auto;height:auto;margin:0;
}
.bounce-demo-panel img{
  position:absolute;
  inset:12px 12px 44px;
  width:calc(100% - 24px);
  height:calc(100% - 56px);
  aspect-ratio:auto;
  margin:0;
  object-fit:cover;
  object-position:center center;
}
.bounce-demo-panel>span{margin-top:0}

@media(min-width:1051px){
  .bounce-service-card{min-height:430px}
  .bounce-service-card.bounce-wide .bounce-demo-panel{left:18px;right:18px;width:auto}
  .bounce-service-card.bounce-wide .bounce-card-top{max-width:620px}
  .bounce-service-card.bounce-small .bounce-demo-panel{left:18px;right:18px;top:205px}
}
@media(max-width:1050px){
  .bounce-service-card{min-height:430px;display:block}
  .bounce-demo-panel{left:18px;right:18px;top:205px;bottom:-46px;margin:0;width:auto}
}
@media(max-width:720px){
  .bounce-service-card{min-height:405px}
  .bounce-demo-panel{left:12px;right:12px;top:205px;bottom:-40px;margin:0;width:auto}
}

/* Because the panel is a fixed-height letterbox, cover shows only a
   horizontal band of each render — so the band has to be aimed at the
   devices rather than the geometric centre. Values are the measured
   (brightness-weighted) subject mid-point of each frame.

   Interactive and Signature are now 1600x650 (2.46:1) wide renders, which
   sit far closer to the panel's own proportion than the 4:3 versions they
   replaced — their crop drops from ~58-62% to ~24-31%. Business and SEO
   are still 4:3 / 3:2 and crop more on the wide breakpoints. */
.bounce-demo-panel img[src*="service-business"]{object-position:center 52%}
.bounce-demo-panel img[src*="service-interactive"]{object-position:center 58%}
.bounce-demo-panel img[src*="service-signature"]{object-position:center 58%}
.bounce-demo-panel img[src*="service-seo"]{object-position:center 47%}

/* =============================
   Service cards V39 — art-directed wide renders
   -----------------------------
   The new 1600x650 (2.46:1) renders suit the wide desktop panels, where the
   box is 2.77-3.55:1, but the grid stacks below 1051px and the same panel
   becomes 1.32-1.63:1 — which cropped 34-46% off the SIDES of a deliberately
   wide composition. Both cards now carry a <picture>: the wide render above
   1051px, the original 4:3/3:2 render below it, so each breakpoint gets the
   crop it was framed for.

   <picture> puts the <img> one level deeper, so the two direct-child hover
   rules need the extra step, and the wrapper is display:contents so it
   generates no box of its own (the img stays absolutely positioned against
   the panel).
   ============================= */
.bounce-demo-panel picture{display:contents}
.bounce-service-card:hover .bounce-demo-panel>picture>img{
  transform:scale(1.025) translateY(-3px);
  filter:drop-shadow(0 22px 35px rgb(var(--c-bg2) / .16));
}
@media(max-width:720px){
  .bounce-service-card:hover .bounce-demo-panel>picture>img{transform:none}
}
@media(prefers-reduced-motion:reduce){
  .bounce-demo-panel picture>img{transition:none!important;transform:none!important}
}

/* Subject mid-points differ between the two crops of the same scene. */
.bounce-demo-panel img[src*="service-interactive"]{object-position:center 61%}
.bounce-demo-panel img[src*="service-signature"]{object-position:center 60%}
@media(min-width:1051px){
  .bounce-demo-panel img[src*="service-interactive"]{object-position:center 58%}
  .bounce-demo-panel img[src*="service-signature"]{object-position:center 58%}
}

/* =============================
   V41 — concept library grid placement
   -----------------------------
   .concept-card carries `grid-column:span 4` (and `span 6` under 1050px)
   from the original 12-column .concept-grid. The library grid added later
   uses repeat(auto-fill,minmax(310px,1fr)) instead, which resolves to 2-3
   columns — so a card asking for 4 columns overflowed the explicit grid and
   was pushed onto its own full-width row. All 47 concepts stacked in a single
   column: the /work/ grid measured 40,273px tall at 1440px, and the page got
   TALLER as the viewport widened. Under 720px it looked correct only because
   `grid-column:auto` already applied there.

   Span belongs to the 12-column grid, not the auto-fill one, so it is reset
   inside the library at every width. Higher specificity than the 1050px rule,
   so it holds there too.
   ============================= */
.concept-grid-lib .concept-card,
.concept-grid-lib .concept-card.wide{grid-column:auto}

/* =============================
   V42 — concept card image wrap
   -----------------------------
   .concept-image-wrap is a <span> and had no display rule, so it computed to
   `display:inline`. aspect-ratio does not apply to non-replaced inline
   elements, so `aspect-ratio:16/10` was silently ignored: the image sized
   itself against the card instead of its own ratio and filled the whole card
   (378 of 378px at 1440px), pushing .concept-meta and .concept-theme past the
   card's overflow:hidden edge. Every concept's brand, industry and theme line
   was cut off — 111px of each card hidden.

   Giving the wrap a block box restores the intended 16/10 media panel and
   lets the label block sit under it.
   ============================= */
.concept-image-wrap{display:block}
.concept-meta{box-sizing:border-box}

/* =============================
   V43 — approach card artwork fits its frame
   -----------------------------
   .approach-media is a centred grid with a fixed 360px height, and its img
   asks for width:100%;height:100%. On a grid item in an auto-sized row that
   height percentage is cyclic, so it resolves to auto: the image took its
   natural aspect from the width and ran 442px tall inside a 360px box with
   overflow:hidden, losing 98px (22%) off the top and bottom.

   max-width/max-height with auto sizing scales the artwork down to fit
   instead, so the whole render is visible and centred. object-fit is then
   moot, but left in place for the cover variants elsewhere.
   ============================= */
.approach-media img{
  width:auto!important;
  height:auto!important;
  max-width:100%;
  max-height:100%;
}

/* V43b — give the media grid a definite row.
   max-height:100% was still resolving against an auto-sized grid row, which
   is cyclic, so it was ignored everywhere except one breakpoint where the
   artwork happened to fit anyway. minmax(0,1fr) derives the row from the
   container's fixed height, so the percentage resolves and the image scales
   down to fit instead of overflowing into overflow:hidden. */
.approach-media{grid-template-rows:minmax(0,1fr);grid-template-columns:minmax(0,1fr)}

/* =============================
   V44 — retire the older ::before cursor glow
   -----------------------------
   Two pointer-following glows were stacked on the same elements: this
   ::before layer (420px radial, gold @15%, driven by --mx/--my) and the
   newer .ob-pointer-glow span (420px radial, gold 22/12/4.5%, driven by
   --gx/--gy, blend-mode screen). Both faded 0->1 on hover, so every card was
   painting two gradients and running two pointermove listeners to do it.

   The span is the brighter, blended one that actually reads, so the ::before
   goes. It was already display:none under @media(hover:none), so touch
   devices have been running on the span alone all along — this just makes
   desktop match.

   .bounce-service-card::before and .concept-card::before are NOT touched:
   those are separately tuned glows (540px/460px, different alpha) and remain
   the intended treatment for those two card types.
   ============================= */
.approach-card::before,.service-card::before,.journey-card::before,
.product-card::before,.bundle-card::before,.industry-card::before,
.process-step::before,.work-card::before,.feature::before,
.principle::before,.product-detail-media::before{content:none}

/* =============================
   V45 — beacon glow on pills and buttons
   -----------------------------
   Extends the existing glow to .tag, .concept-chip and .btn (plus
   .product-note, which joins the soft tier). Cards and blocks already had it.

   Three things are deliberate:
   1. The glow radius is a variable now. 420px across an 82x36 chip is a flat
      wash with no falloff, so pills and buttons get 190px and the gradient
      actually reads as a glow that tracks the cursor. Cards keep 420px via
      the fallback, so nothing existing changes.
   2. Buttons get the glow ONLY. They already lift 2px and shift background on
      hover; stacking a second transform on top reads as a judder. Their glow
      also sits at z-index:-1 inside an isolated stacking context, so it warms
      the fill from behind rather than washing over the label.
   3. Not applied to .faq-q, .concept-view, .seo-icon or .num - each of those
      sits inside something that already glows, and nesting two glows just
      doubles the wash.
   ============================= */
:root{
  --ob-glow-grad:radial-gradient(var(--ob-glow-r,420px) circle at var(--gx) var(--gy),
    rgb(var(--c-gold-hi) / .22) 0%,
    rgb(var(--c-gold) / .12) 18%,
    rgb(var(--c-gold) / .045) 36%,
    transparent 62%);
}
.ob-pointer-glow{background:var(--ob-glow-grad)}
.ob-pos-rel{position:relative}

.ob-pill-surface,.ob-btn-glow{--ob-glow-r:190px;--gx:50%;--gy:50%;isolation:isolate}
.ob-pill-surface{
  transition:transform .3s var(--ob-ease),box-shadow .3s var(--ob-ease),
             border-color .26s ease,background .26s ease,color .26s ease;
}
.ob-pill-surface:hover>.ob-pointer-glow,.ob-pill-surface:focus-within>.ob-pointer-glow,
.ob-btn-glow:hover>.ob-pointer-glow,.ob-btn-glow:focus-visible>.ob-pointer-glow{
  opacity:1;box-shadow:inset 0 0 0 1px rgb(var(--c-gold-hi) / .12);
}
/* behind the label, above the fill */
.ob-btn-glow>.ob-pointer-glow{z-index:-1}

@media(hover:hover) and (pointer:fine){
  .ob-pill-surface:hover{
    transform:translateY(-2px) scale(1.025);
    box-shadow:0 10px 26px rgba(0,0,0,.16),0 0 20px rgb(var(--c-gold) / .07);
    border-color:rgb(var(--c-gold-hi) / .38)!important;
  }
  /* don't let hover out-shout the chip that is currently selected */
  .concept-chip.is-active.ob-pill-surface:hover{transform:translateY(-1px) scale(1.012)}
}

/* .concept-chip span styles its count badge (opacity .72, gold pill, padding)
   and would repaint the injected glow, which is also a span. Scoped by
   specificity rather than !important so the global glow rules stay clean. */
.concept-chip>span.ob-pointer-glow{
  background:var(--ob-glow-grad);
  opacity:0;padding:0;border:0;border-radius:inherit;
}
.concept-chip:hover>span.ob-pointer-glow,
.concept-chip:focus-within>span.ob-pointer-glow{opacity:1}

@media(prefers-reduced-motion:reduce){
  .ob-pill-surface{transform:none!important;transition:none!important}
}

/* =============================
   V46 — homepage SEO bento: artwork above 1050px  (REMOVED)
   -----------------------------
   The five cards were briefly supplied renders above 1050px, with the real
   HTML cards kept underneath for narrow screens. Shaan asked for these cards
   to be transparent, to carry beacon glow, and to recolour with the light
   theme. A fixed raster can do none of the three: its background is baked, so
   it is an opaque dark block on the cream page whatever the theme says.

   The HTML cards it was hiding already do all three — the card is a tint over
   the page rather than a fill, its border and text come from theme tokens, and
   the glow layer sits inside it. So the artwork is gone and the markup shows
   at every width, which is also what happened to the industry cards (V48).

   Removed rather than left inert because it set .seo-card-art-img{display:none}
   globally and stripped the card's background, border, padding and shadow
   under .seo-bento-art — quiet landmines for anything reusing those names.
   ============================= */

/* =============================
   V47 — card fan carousel
   -----------------------------
   Vanilla port of the React/GSAP fan component. JS writes the per-card
   geometry into custom properties and CSS interpolates it, so no animation
   library is loaded — the site still fetches zero third-party scripts and
   the export stays a self-contained zip.

   `elastic.out(1,.75)` is approximated with an overshooting cubic-bezier.
   It is not identical to the spring, but it reads the same at these
   distances and costs nothing.

   Progressive enhancement: without JS, .fan-track is a plain wrapped flex
   row of the same concept buttons. The fan geometry only applies once JS
   adds .is-fanned, so the concept dialog and crawlers work either way.
   ============================= */
.fan{position:relative;width:100%}
.fan-track{
  display:flex;flex-wrap:wrap;gap:18px;justify-content:center;align-items:center;
}
.fan .fan-card{margin:0}

/* --- fanned state (JS active) --- */
.fan.is-fanned .fan-track{
  flex-wrap:nowrap;gap:0;
  position:relative;
  height:clamp(21rem,42vw,34rem);
  perspective:1400px;
}
.fan.is-fanned .fan-card{
  position:absolute;
  left:50%;top:50%;
  width:clamp(11rem,21vw,17rem);
  margin:0;
  /* centre origin, matching GSAP's default in the source component. A pivot
     below the card swings it ~80px further sideways when rotated, which
     both changed the fan geometry and defeated the fit calculation. */
  transform-origin:50% 50%;
  transform:translate(-50%,-50%)
            translate(var(--fx,0px),var(--fy,0px))
            rotate(var(--frot,0deg))
            scale(var(--fscale,1));
  z-index:var(--fz,1);
  opacity:1;
  transition:transform .55s cubic-bezier(.22,.9,.28,1.18) var(--fdelay,0s),
             opacity .35s ease;
  will-change:transform;
}
.fan.is-fanned .fan-card.is-out{
  opacity:0;
  pointer-events:none;
  transform:translate(-50%,-50%) scale(.5);
}
.fan.is-fanned .fan-card .concept-image-wrap{aspect-ratio:3/4}
.fan.is-fanned .fan-card .concept-meta{padding:13px 15px 15px}
.fan.is-fanned .fan-card .concept-meta strong{font-size:18px}

/* --- controls --- */
.fan-controls{
  display:flex;align-items:center;justify-content:center;gap:16px;
  margin-top:26px;position:relative;z-index:20;
}
.fan-controls[hidden]{display:none}
.fan-arrow{
  display:grid;place-items:center;
  width:44px;height:44px;border-radius:50%;
  border:1.5px solid rgb(var(--c-gold-hi) / .22);
  background:rgb(var(--c-tint) / .06);
  color:rgb(var(--c-text-mut));
  cursor:pointer;
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  transition:border-color .28s ease,color .28s ease,background .28s ease,transform .28s ease;
}
.fan-arrow svg{width:19px;height:19px}
.fan-arrow:hover{
  border-color:rgb(var(--c-gold-hi) / .55);
  color:rgb(var(--c-text));
  background:rgb(var(--c-gold) / .1);
  transform:translateY(-2px);
}
.fan-arrow:focus-visible{outline:2px solid rgb(var(--c-gold));outline-offset:3px}
.fan-dots{display:flex;align-items:center;gap:8px}
.fan-dot{
  width:7px;height:7px;border-radius:50%;
  background:rgb(var(--c-text) / .18);
  transition:background .3s ease,transform .3s ease;
}
.fan-dot.is-active{background:rgb(var(--c-gold));transform:scale(1.45)}

@media(max-width:720px){
  .fan.is-fanned .fan-track{height:clamp(17rem,64vw,22rem)}
  .fan.is-fanned .fan-card{width:clamp(8.5rem,38vw,11rem)}
  .fan-arrow{width:40px;height:40px}
}
@media(prefers-reduced-motion:reduce){
  .fan.is-fanned .fan-card{transition:none!important}
  .fan-arrow{transition:none!important}
}

/* V47b — keep the fan laid out where transforms are globally disabled.
   Two existing rules force `transform:none!important` on .ob-interactive-surface:
   one at <=720px (to stop hover-lift on touch) and one under reduced motion.
   The fan cards carry that class, so both were collapsing all seven cards into
   a single stack. The fan's transform is layout, not decoration, so it is
   re-asserted; the hover lift and transitions stay suppressed as intended. */
@media(max-width:720px){
  .fan.is-fanned .fan-card{
    transform:translate(-50%,-50%)
              translate(var(--fx,0px),var(--fy,0px))
              rotate(var(--frot,0deg))
              scale(var(--fscale,1))!important;
  }
  .fan.is-fanned .fan-card.is-out{
    transform:translate(-50%,-50%) scale(.5)!important;
  }
}
@media(prefers-reduced-motion:reduce){
  .fan.is-fanned .fan-card{
    transform:translate(-50%,-50%)
              translate(var(--fx,0px),var(--fy,0px))
              rotate(var(--frot,0deg))
              scale(var(--fscale,1))!important;
    transition:none!important;
  }
  .fan.is-fanned .fan-card.is-out{
    transform:translate(-50%,-50%) scale(.5)!important;
  }
}

/* V47c — counter instead of dots for large libraries.
   47 dots is an unreadable smear; past 12 cards the indicator becomes a
   plain "n / total" counter. */
.fan-dots.fan-counter{
  min-width:76px;
  justify-content:center;
  font-size:12px;
  font-weight:800;
  letter-spacing:.1em;
  font-variant-numeric:tabular-nums;
  color:rgb(var(--c-text-mut));
}

/* =============================
   V48 — industry cards: artwork only  (REMOVED)
   -----------------------------
   The ten trade cards were briefly supplied artwork rather than markup. Shaan
   preferred the original text cards, so the markup is back and this layer's
   selectors — .industry-grid-art, .industry-art-img, .industry-text — no
   longer match anything. It is gone rather than left inert: it stripped the
   card's padding, border, background and shadow, so anything that happened to
   pick up those class names later would silently lose its card styling.

   The original .industry-grid .industry rules were never touched while the
   artwork was in place, which is why removing this restores the old look with
   no replacement CSS. The layer number is kept so V49's notes still line up.
   ============================= */

/* =============================
   V49 — beacon glow: give back the halo three surfaces had lost
   -----------------------------
   These cards were already wired for beacon glow — the class is on them and
   the glow <span> is in the DOM — but the hover state was arriving stripped:
   the pointer halo lit up while the lift shadow and gold edge did not.

   The cause is cascade order, not a missing rule. The tier's
   `.ob-interactive-surface:hover` is (0,2,0), and three later rules match the
   same elements at the same specificity, so the later one simply wins:

     .theme-dark .process-v10-item   sets box-shadow, and border !important

   Two more, .industry-grid-art .industry and .seo-bento-art .seo-card, went
   with V48 and V46 when both sets of cards returned to markup. Of the text
   cards they became, only the industry ones needed the same repair (V51) —
   .seo-card sets its resting shadow earlier in this file than the tier's
   hover rule, so it loses the cascade and the halo lands on its own.

   The two artwork layers zero the chrome out on purpose — the render already
   draws the card — but zeroing the *resting* shadow also silently zeroed the
   hover one. Re-stating the halo at (0,3,1) puts it back without disturbing
   the resting look any of those layers was written to produce.

   Values are copied from the tier verbatim rather than re-tuned, so this is
   the same beacon glow the other cards use, not a lookalike.
   ============================= */
/* The lift itself was gone too, on every card that had scrolled in.
   The tier declares its transform on the base class:

     .ob-interactive-surface { transform:perspective(...) ... }   (0,1,0)

   while the reveal-on-scroll layer ends with

     .reveal.visible { transform:none }                            (0,2,0)

   Higher specificity wins wherever both apply, so the moment a card finished
   revealing it stopped being able to move at all — the halo and the saturate
   still fired on hover, which is why it read as "glow but no pop". Restating
   the transform at (0,3,0) for the revealed state fixes every strong-tier
   surface at once, not just the three above.

   The two guards the tier relies on are re-stated at the same weight, or this
   rule would hand the lift back to touch devices and to readers who have asked
   for less motion. The pre-reveal state is deliberately left as it is: those
   cards already fade in without sliding, and changing that here would alter
   the entry animation rather than the hover. */
@media(hover:hover) and (pointer:fine) and (min-width:721px){
  .reveal.visible.ob-interactive-surface{
    transform:perspective(1100px) translate3d(0,var(--surface-lift),0)
              rotateX(var(--rx)) rotateY(var(--ry)) scale(var(--surface-scale));
  }
}
@media(prefers-reduced-motion:reduce){
  .reveal.visible.ob-interactive-surface{transform:none}
}

@media(hover:hover) and (pointer:fine){

  /* Process stages: the themed card look overrode both properties. */
  .theme-dark .process-v10-item.ob-interactive-surface:hover{
    box-shadow:0 30px 86px rgba(0,0,0,.30),0 0 44px rgb(var(--c-gold) / .075);
    border-color:rgb(var(--c-gold-hi) / .28)!important;
  }

}

/* =============================
   V50 — SEO bento: close the hole beside card 04
   -----------------------------
   Five cards in a two-column grid, two of them full width, leaves one
   half-width slot empty: 01 spans the row, 02 and 03 pair up, 04 sits alone
   with a gap beside it, then 05 spans the row again.

   Card 04 spans the row too, so the grid closes up. This is only safe because
   the cards are markup: the copy simply reflows to the wider measure. While
   they were raster artwork it was not an option — the renders were authored at
   two widths, and stretching 04 across the row would have scaled its baked
   text to roughly double the size of the identical-looking text on 02 and 03.
   That version centred the card instead; the constraint left with the artwork.

   Only above 720px, where the grid actually has two columns. Below that
   everything is already a single column and there is no hole to close.
   ============================= */
@media(min-width:721px){
  .seo-bento .seo-card:nth-of-type(4){grid-column:1 / -1}
}

/* =============================
   V51 — beacon glow on the restored industry text cards
   -----------------------------
   Same cascade trap V49 documents, in a place V49 did not cover. The text
   cards carry their own resting shadow:

     .industry-grid .industry { box-shadow:0 18px 52px rgba(0,0,0,.16) }

   which is (0,2,0) and sits later in this file than the tier's
   .ob-interactive-surface:hover, also (0,2,0). Later wins, so the cards lifted
   and lit up on hover but never gained the halo.

   This was hidden while the cards were artwork: V48 zeroed their shadow and
   V49 restated the halo for .industry-grid-art. Removing V48 took that
   restatement with it and left the plain cards exposed. Values copied from the
   tier verbatim so it is the same beacon glow, not a lookalike.
   ============================= */
@media(hover:hover) and (pointer:fine){
  .industry-grid .industry.ob-interactive-surface:hover{
    box-shadow:0 30px 86px rgba(0,0,0,.30),0 0 44px rgb(var(--c-gold) / .075);
  }
}

/* =============================
   V52 — NFC product gallery: colour options and angle strip
   -----------------------------
   The plaque comes in two colours and each colour is photographed from three
   angles, so the media panel is a small gallery rather than a single image:
   chips choose the colour, thumbnails choose the angle.

   The panel keeps a fixed stage height. Sizing it to whichever shot is showing
   would make the whole page jump every time a colour or angle changed, because
   these products are photographed at different aspect ratios.

   A colour whose photography has not arrived yet is rendered as a disabled
   chip rather than being hidden — the range is what it is, and a missing photo
   should not quietly shrink the product line.
   ============================= */
.product-gallery{display:flex;flex-direction:column;gap:18px;padding:34px}
.product-stage{flex:1;display:grid;place-items:center;min-height:0}
.product-stage img{max-height:380px;width:auto;max-width:100%;object-fit:contain;
  transition:opacity .28s var(--ob-ease),transform .28s var(--ob-ease)}
.product-gallery.is-swapping .product-stage img{opacity:0;transform:scale(.985)}
.shot-pending{margin:0;font-size:13px;letter-spacing:.02em;color:rgb(var(--c-text-mut))}

.shot-thumbs{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;min-height:0}
.shot-thumbs:empty{display:none}
.shot-thumb{width:62px;height:62px;padding:6px;border-radius:14px;cursor:pointer;
  border:1px solid rgb(var(--c-text-mut) / .28);background:rgb(var(--c-surface) / .35);
  display:grid;place-items:center;transition:border-color .22s ease,background .22s ease}
.shot-thumb img{max-width:100%;max-height:100%;object-fit:contain}
.shot-thumb:hover{border-color:rgb(var(--c-gold-hi) / .55)}
.shot-thumb.is-active{border-color:rgb(var(--c-gold-hi) / .85);background:rgb(var(--c-gold) / .10)}

.colour-options{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:22px}
.colour-label{font-size:10px;font-weight:800;letter-spacing:.17em;text-transform:uppercase;
  color:rgb(var(--c-text-mut));margin-right:2px}
.colour-chip{display:inline-flex;align-items:center;gap:9px;padding:9px 16px 9px 10px;
  border-radius:999px;cursor:pointer;font:600 13px/1 var(--sans,inherit);
  color:rgb(var(--c-text));background:rgb(var(--c-surface) / .40);
  border:1px solid rgb(var(--c-text-mut) / .30);
  transition:border-color .22s ease,background .22s ease,color .22s ease}
.colour-chip:hover{border-color:rgb(var(--c-gold-hi) / .55)}
.colour-chip.is-active{border-color:rgb(var(--c-gold-hi) / .85);background:rgb(var(--c-gold) / .12)}
.colour-chip[data-pending]{opacity:.5;cursor:not-allowed}
.colour-chip[data-pending]::after{content:'soon';font-size:9px;font-weight:800;
  letter-spacing:.12em;text-transform:uppercase;color:rgb(var(--c-text-mut))}
.colour-dot{width:16px;height:16px;border-radius:50%;flex:none;
  box-shadow:inset 0 0 0 1px rgb(var(--c-text) / .22)}

.colour-swatches{display:flex;align-items:center;gap:7px;margin-top:12px;
  font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:rgb(var(--c-text-mut))}
.colour-swatches .colour-dot{width:13px;height:13px}

@media(max-width:720px){
  .product-gallery{padding:22px;gap:14px}
  .product-stage img{max-height:250px}
  .shot-thumb{width:52px;height:52px}
}

/* =============================
   V53 — colour switcher inside the stand cards
   -----------------------------
   The stands page shows two products side by side, so each card carries its
   own gallery rather than the page having one hero switcher. The panel is the
   card's existing .product-media, so it keeps the card's gradient and framing
   and only gains the stage/thumbnail layout.

   Two things the base card rules have to give up here. `.product-media img`
   stretches its image to fill the box, which is right for a single fixed shot
   and wrong for a stage that swaps between portrait stands and wide plaques —
   the stage sizes to the image instead. And `.product-card:hover img` scales
   the whole panel contents, which would drag the thumbnails and chips with it,
   so the zoom is narrowed to the stage image alone.
   ============================= */
.product-card-gallery{display:flex;flex-direction:column}
.product-card-gallery .product-media{
  height:auto;min-height:320px;display:flex;flex-direction:column;gap:14px;padding:26px}
.product-card-gallery .product-stage{flex:1;display:grid;place-items:center;min-height:0}
.product-card-gallery .product-stage img{
  width:auto;height:auto;max-width:100%;max-height:250px;object-fit:contain}
.product-card-gallery .product-copy{flex:1;display:flex;flex-direction:column}
.product-card-gallery .colour-options{margin-top:auto;padding-top:16px}

/* the card-wide hover zoom would carry the thumbnails and chips with it */
.product-card-gallery:hover .product-media img{transform:none}
.product-card-gallery:hover .product-stage img{transform:scale(1.03)}

/* two stands, two columns: the generic "last card spans the row" rule would
   stretch the second one across both */
.product-grid .product-card-gallery:last-child{grid-column:auto}

@media(max-width:720px){
  .product-card-gallery .product-media{min-height:260px;padding:20px}
  .product-card-gallery .product-stage img{max-height:190px}
}

/* =============================
   V54 — bigger hero headline, and the footer loses its panel
   -----------------------------
   HEADLINE. The winning rule was min(clamp(38px,4.7vw,72px), 8.4vh), landing
   at 60px on a 1280x900 screen. The vh half of that min() is not arbitrary:
   the hero is a fixed stage and the headline has to share it with an eyebrow,
   a lede, two buttons and a scroll cue, so a purely vw-driven size overflows
   on short laptop screens. Both halves move together here — a larger vw range
   with the vh ceiling lifted to match, so the type grows without the stage
   overflowing when the window is short.

   FOOTER. Two stacked washes were painting the footer as its own panel: a
   near-opaque one on .site-footer and a second fade on .footer-card. Both go,
   so the page's own background art runs straight through to the bottom of the
   page. They are cleared at .theme-dark specificity because that is where they
   are set -- and body always carries theme-dark, it is the "themed site" class
   rather than the dark-mode switch, so a bare .site-footer rule loses. The text colours were already theme tokens rather than fixed values,
   so they keep adapting — dark green on cream in light, pale sage on green in
   dark — and the separating rule above the footer is kept so the boundary is
   still legible without a filled box.
   ============================= */
.scroll-hero-intro .display{font-size:min(clamp(44px,6vw,92px),10.4vh)}
@media(max-width:720px){
  .scroll-hero-intro .display{font-size:min(clamp(36px,9.4vw,52px),8.6vh)}
}
@media(max-height:760px){
  .scroll-hero-intro .display{font-size:min(clamp(38px,4.8vw,66px),9.2vh)}
}
@media(max-height:640px){
  .scroll-hero-intro .display{font-size:min(clamp(32px,4vw,54px),8.4vh)}
}

.theme-dark .site-footer,
.theme-dark .footer-card{background:none}

/* With the wash gone, the decorative glow is the only thing between the footer
   text and the page. It used to sit behind an almost opaque panel, so its
   brightness never mattered; exposed at .30 it pulled the worst footer link
   down to 4.95:1 against AA's 4.5 — passing, but with nothing spare, and the
   glow moves relative to the text as the viewport changes. Dimming it keeps
   the effect and puts real margin back. */
.theme-dark .footer-glow{opacity:.2}

/* =============================
   V55 — wider hero copy column
   -----------------------------
   The column measured 671px while its own max-width allowed 928, so raising
   that alone would have done nothing. The real constraint was the headline's
   max-width:19ch — a ch-based measure, which is why the column tracked the
   headline exactly and why it grew when the type did in V54.

   Widening means moving all three together: the headline measure, the lede
   under it, and the column cap that would otherwise clip the result. The
   headline goes to 28.5ch (19 x 1.5) for roughly 1010px at the current size.

   The lede does not scale by the same factor. Line length drives readability,
   and 56ch is already inside the comfortable 45-75ch band; 1.5x would push it
   to 84ch, well past it. 68ch fills the wider column without becoming a
   trudge to read.

   Desktop only. Below 1051px the column is already near the full width of the
   screen, so there is nothing to widen — scaling there would just overflow.
   ============================= */
@media(min-width:1051px){
  .scroll-hero-intro .display{max-width:28.5ch}
  .scroll-hero-intro .lede{max-width:68ch}
  .hero-copy-col{max-width:min(72rem,94%)}
}

/* =============================
   V57 — strip the background artwork from the whole site
   ============================= */
html, body{background-image:none!important}

.scroll-hero-stage::before,
.hero-bg,
.footer-glow,
.signal-grid,
.scroll-hero-glow,
.project-liquid-aura,
.project-liquid-ribbon,
.start-project-page .project-liquid-stage::after{
  background-image:none!important;
  opacity:0!important;
}

/* =============================
   V58 — GhostFibers canvas behind the page
   ============================= */
.ob-fibers{position:fixed;inset:0;z-index:0;pointer-events:none;contain:strict}
.ob-fibers canvas{display:block;width:100%;height:100%}

/* Scrim between the canvas and the content. Without it the hero's gold italic
   measured 1.39:1 against the brightest fibre behind it.

   It is a radial rather than a flat fill so the protection is concentrated
   where centred page content sits and eases off toward the edges, where the
   weave can run at full strength. Because .ob-fibers is fixed to the viewport
   the falloff is never clipped by a container, so there is no edge to see --
   which is what went wrong with the per-block backing this replaces. */
.ob-fibers::after{
  content:'';position:absolute;inset:0;
  background:radial-gradient(ellipse farthest-corner at 50% 45%,
    rgb(var(--c-bg) / .90) 0%,
    rgb(var(--c-bg) / .89) 24%,
    rgb(var(--c-bg) / .88) 50%,
    rgb(var(--c-bg) / .62) 88%,
    rgb(var(--c-bg) / .38) 100%);
}

/* content sits above the canvas */
.site-header,main,.site-footer,.skip{position:relative;z-index:1}

/* The hero copy had its own radial backing here. In radial-gradient() the
   radius percentages are measured against the element's full width and height,
   not half of them, so a 78%/74% radius reached far outside the box: the
   browser clipped the gradient at about .72 alpha and the fade to transparent
   was never drawn. That left a hard-edged rectangle behind the headline. The
   scrim above does the job instead, with no element boundary to show. */

/* the scroll hero paints an opaque tone over its full height, which would
   hide the canvas for the first screen and more */
.theme-dark .scroll-hero,
.theme-dark .scroll-hero-stage,
.scroll-hero,
.scroll-hero-stage{background-color:transparent}

/* =============================
   V59 — the closing statement panel sits on the fibres too
   ============================= */
/* .is-final covered the canvas twice over: an opaque tone on the stage plus a
   .98 wash on its ::after. V58 cleared .scroll-hero-stage at (0,2,0), which
   loses to the (0,3,0) .is-final rules -- the same specificity trap the beacon
   glow hit. Restated here above both, in each theme.

   The gold glow is kept: it is the beacon accent, not a backdrop. Only the
   layers that hid the weave are dropped. */
.theme-dark .scroll-hero .scroll-hero-stage.is-final,
.scroll-hero .scroll-hero-stage.is-final{
  background:none;
}

/* One rule serves both themes. A .theme-dark-scoped selector would win in the
   light theme too -- body always carries theme-dark, it names the themed site
   rather than the dark mode -- so a bare light variant beneath it could never
   apply. The gold reads the same either way, so one rule is the honest form. */
.theme-dark .scroll-hero .scroll-hero-stage.is-final::after{
  background:radial-gradient(circle at 50% 48%,rgb(var(--c-gold) / .12),transparent 36%);
}

/* =============================
   V60 — the liquid-project artwork is gone
   ============================= */
/* The .project-liquid-stage block (three auras, the ribbon SVG and its
   vignette) was removed from start-project/index.html on 2026-09-12: purely
   decorative, aria-hidden, and already invisible since V57 hid it. Dropping
   the markup took that page from 18.1KB to 12.1KB.

   Its rules -- the .project-liquid- and .ribbon- selectors, plus the
   ob-ribbon and ob-glass-aura keyframes -- now match nothing. They are left in place rather than cut out of
   the earlier layers, which this file does not rewrite; several sit inside
   shared multi-selector rules and media queries. They cost bytes, not
   behaviour. .liquid-project-gateway and .liquid-project-content are still
   live: they lay out the heading, copy and buttons that remain. */

/* =============================
   V61 — the quote gateway sits on the fibres
   ============================= */
/* The start-project page painted an opaque --c-bg at four levels, so clearing
   the section alone changed nothing -- <main> underneath was still solid:

     .start-project-page                        (body, stays: it is the ground
                                                 behind the fixed canvas)
     .start-project-page main                   cleared
     .start-project-page .liquid-project-gateway  cleared
     .start-project-page .site-footer           cleared

   The footer goes with them deliberately. Leaving it opaque while main turned
   transparent would put a hard horizontal edge where the two meet -- the same
   kind of seam this whole pass has been removing.

   Body keeps its colour: it paints below .ob-fibers (z-index 0), so it backs
   the canvas rather than covering it.

   The section's ::before/::after fade strips are already display:none under
   .liquid-project-gateway, so nothing else is left over the canvas. */
.start-project-page main,
.start-project-page main .liquid-project-gateway,
.start-project-page main .project-gateway,
.start-project-page .site-footer{
  background:none;
}

/* =============================
   V62 — palette swap: forest becomes light, dark becomes black + olive
   ============================= */
/* The cream/ivory palette is retired. Today's deep-forest dark theme is
   promoted to the LIGHT theme unchanged -- so light mode ships values already
   measured at 0 contrast failures -- and a new pure-black theme sits under it
   with Olive carrying the accent work.

   Both themes are now visually dark, which drives two things that look wrong
   in isolation:

     color-scheme is dark in BOTH blocks. A forest page declaring itself light
     makes the browser paint native scrollbars, form controls and autofill in
     light style: pale widgets on a dark page.

     --c-tint is 255 255 255 in BOTH. It is a lightening tint applied at low
     alpha over surfaces; 0 0 0 was correct for cream and is wrong for forest.

   Olive splits by role on black, because one value cannot do both jobs:
     --c-border  #5A7350  4.0:1 on black, so hairlines are actually visible
     --c-accent  #6B8760  5.3:1 on black, so it still reads where it is type
   On forest both keep today's #3E5035, which is what already ships. */
:root{
  --c-bg:23 34 25;           /* #172219 Deep Forest */
  --c-bg2:30 43 32;          /* #1E2B20 */
  --c-surface:38 52 40;      /* #263428 */
  --c-border:62 80 53;       /* #3E5035 Olive */
  --c-text:248 245 238;      /* #F8F5EE Warm Ivory */
  --c-text-mut:175 186 172;  /* #AFBAAC sage grey */
  --c-accent:62 80 53;
  --c-gold:200 169 91;       /* #C8A95B */
  --c-gold-hi:210 185 111;   /* #D2B96F */
  --c-gold-text:200 169 91;  /* no cream left, so gold type is the accent */
  --c-gold-hi-text:210 185 111;
  --c-on-gold:23 34 25;
  --c-tint:255 255 255;
  --c-shadow:0 0 0;
  --shadow-strength:.45;
  color-scheme:dark;
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --c-bg:0 0 0;            /* #000000 pure black */
    --c-bg2:12 16 12;        /* #0C100C */
    --c-surface:20 26 20;    /* #141A14 panels lift just off black */
    --c-border:90 115 80;    /* #5A7350 Olive, visible on black */
    --c-text:248 245 238;
    --c-text-mut:175 186 172;
    --c-accent:107 135 96;   /* #6B8760 legible as type on black */
    --c-gold:200 169 91;
    --c-gold-hi:216 192 120; /* #D8C078 */
    --c-gold-text:200 169 91;
    --c-gold-hi-text:216 192 120;
    --c-on-gold:0 0 0;
    --c-tint:255 255 255;
    --c-shadow:0 0 0;
    --shadow-strength:.6;
    color-scheme:dark;
  }
}

:root[data-theme="dark"]{
  --c-bg:0 0 0;
  --c-bg2:12 16 12;
  --c-surface:20 26 20;
  --c-border:90 115 80;
  --c-text:248 245 238;
  --c-text-mut:175 186 172;
  --c-accent:107 135 96;
  --c-gold:200 169 91;
  --c-gold-hi:216 192 120;
  --c-gold-text:200 169 91;
  --c-gold-hi-text:216 192 120;
  --c-on-gold:0 0 0;
  --c-tint:255 255 255;
  --c-shadow:0 0 0;
  --shadow-strength:.6;
  color-scheme:dark;
}

/* =============================
   V63 — literals the palette swap left stranded
   ============================= */
/* 1. The SEO icon's hover colour was a dark bronze tuned for the cream light
      theme, set on a .theme-dark selector -- which, since .theme-dark means
      "themed site" and not "dark mode", is the value BOTH themes fall back to.
      The real dark-mode branches below it already used the token. With cream
      retired, every ground is dark, so the token is right everywhere. */
.seo-card:hover .seo-icon,
.theme-dark .seo-card:hover .seo-icon{color:rgb(var(--c-gold-hi))}

/* 2. Three panels are separated from their surroundings by a literal black
      fill. That reads on forest; on pure black it is invisible, and the panel
      loses its edge. On the black theme they lift instead of sink. */
:root[data-theme="dark"] .seo-page-hero .seo-search-bar{background:rgb(var(--c-tint) / .055)}
:root[data-theme="dark"] .form-fallback-body{background:rgb(var(--c-tint) / .07)}

@media(prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .seo-page-hero .seo-search-bar{background:rgb(var(--c-tint) / .055)}
  :root:not([data-theme="light"]) .form-fallback-body{background:rgb(var(--c-tint) / .07)}
}

/* =============================
   V64 — premium concept section on /websites/
   ============================= */
/* Ten brand studies, three screens each, reusing the .concept-card contract so
   the dialog in site.js drives them with no new JavaScript.

   Its own grid rather than the 12-column .concept-grid: that one pins cards to
   span 4, and auto-fill lets ten square tiles reflow sensibly instead of
   leaving a ragged final row. Declared after the 720px block that flattens
   .concept-grid to one column -- equal specificity, later wins, and the
   280px floor already collapses to a single column on a phone. */
.premium-grid{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(280px,1fr));
  gap:18px;
}
.premium-grid .concept-card{grid-column:auto;width:100%}

/* The sources are square whole-page compositions. The library's 16/10 would
   crop the headline off the top or the footer off the bottom, so these keep
   their aspect and sit flush -- object-fit:cover on a 1:1 image in a 1:1 box
   is an exact fit, nothing is lost. Specificity (0,2,0) so it also beats the
   aspect-ratio set inside the 720px block. */
.premium-card .concept-image-wrap{
  aspect-ratio:1/1;
  background:rgb(var(--c-bg2));
}

.premium-concepts .concept-note{margin-top:14px}

/* =============================
   V65 — the weave reads Olive Beacon green on black
   ============================= */
/* The threads are uLineColor in the shader and were wired to --c-text-mut,
   which is a pale sage GREY -- and is also the body-text colour everywhere on
   the site, so it could not simply be recoloured. --c-weave splits that role
   off. The gold glow bands are already uGlowColor / --c-gold and are left
   exactly as they were: green primary, gold secondary.

   Light theme keeps the value it has always had, so nothing changes there. */
:root{
  --c-weave:175 186 172;        /* #AFBAAC — unchanged on forest */
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --c-weave:104 158 72;       /* #689E48 — lifted brand olive; measured at 30%
                                   saturation once the shader's tone curve has
                                   compressed the peaks, vs 17% for a paler mix */
  }
}

:root[data-theme="dark"]{
  --c-weave:104 158 72;
}

/* Visibility. The scrim is the only thing holding the weave down -- it tints
   toward --c-bg, which on this theme IS black, so easing it lets more thread
   through without altering the ground colour, the motion or the effect. Only
   the dark theme is touched; the black palette was measured with far more
   contrast headroom than forest (7.38:1 against a 4.5 bar), and that headroom
   is what is being spent here. */
:root[data-theme="dark"] .ob-fibers::after{
  background:radial-gradient(ellipse farthest-corner at 50% 45%,
    rgb(var(--c-bg) / .78) 0%,
    rgb(var(--c-bg) / .76) 24%,
    rgb(var(--c-bg) / .70) 50%,
    rgb(var(--c-bg) / .48) 88%,
    rgb(var(--c-bg) / .24) 100%);
}

@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .ob-fibers::after{
    background:radial-gradient(ellipse farthest-corner at 50% 45%,
      rgb(var(--c-bg) / .78) 0%,
      rgb(var(--c-bg) / .76) 24%,
      rgb(var(--c-bg) / .70) 50%,
      rgb(var(--c-bg) / .48) 88%,
      rgb(var(--c-bg) / .24) 100%);
  }
}

/* =============================
   V66 — /concepts/<slug>/ pages
   ============================= */
/* Visible breadcrumb. The site had BreadcrumbList schema on every page but
   never showed the trail, so a visitor arriving on a concept from search had
   no way back up. */
.crumbs{margin:0 0 26px}
.crumbs ol{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0;
  font-size:12px;letter-spacing:.04em;color:rgb(var(--c-text-mut))}
.crumbs li+li::before{content:'/';margin-right:8px;opacity:.5}
.crumbs a{color:rgb(var(--c-text-mut));text-decoration:none;border-bottom:1px solid transparent}
.crumbs a:hover{color:rgb(var(--c-text));border-bottom-color:rgb(var(--c-gold-hi) / .5)}
.crumbs [aria-current]{color:rgb(var(--c-text))}

/* Palette sampled from each concept's own artwork -- objectively true and one
   of the few things that genuinely differs between sixty pages. */
.palette{list-style:none;display:flex;flex-wrap:wrap;gap:14px;margin:26px 0 0;padding:0}
.palette li{display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.06em;
  color:rgb(var(--c-text-mut))}
.palette .swatch{width:22px;height:22px;border-radius:6px;display:block;
  border:1px solid rgb(var(--c-tint) / .18)}

/* The three screens, full width. These are the reason the page exists, so they
   get the room -- one per row rather than a grid. */
.concept-shots{display:grid;gap:28px}
.concept-shot{margin:0;border-radius:var(--radius);overflow:hidden;
  border:1px solid rgb(var(--c-border) / .55);background:rgb(var(--c-bg2))}
.concept-shot img{width:100%;height:auto;display:block}
.concept-shot figcaption{padding:13px 18px;font-size:11px;font-weight:800;
  letter-spacing:.14em;text-transform:uppercase;color:rgb(var(--c-text-mut));
  border-top:1px solid rgb(var(--c-border) / .4)}

/* Sibling concepts, so each page has outbound links to its neighbours and is
   not a dead end for a crawler or a reader. */
.crumb-cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:16px}
.crumb-card{display:block;border-radius:20px;overflow:hidden;
  border:1px solid rgb(var(--c-border) / .5);background:rgb(var(--c-bg2));
  text-decoration:none;transition:transform .3s var(--ob-ease),border-color .3s}
.crumb-card:hover{transform:translateY(-4px);border-color:rgb(var(--c-gold-hi) / .4)}
.crumb-card img{width:100%;height:150px;object-fit:cover;object-position:top center;display:block}
.crumb-card span{display:block;padding:14px 16px 16px}
.crumb-card strong{display:block;font:500 19px/1.1 var(--serif);color:rgb(var(--c-text))}
.crumb-card em{display:block;margin-top:5px;font-style:normal;font-size:10px;font-weight:800;
  letter-spacing:.13em;text-transform:uppercase;color:rgb(var(--c-gold-text))}

@media(max-width:720px){
  .concept-shots{gap:18px}
  .crumb-card img{height:130px}
}


/* =============================
   V67 -- enquiry form delivery
   ============================= */
/* The forms now POST to a delivery endpoint instead of handing a mailto: URL
   to the visitor's mail client, so they need three things the old flow never
   had: a busy state on the button, a success state, and a failure state that
   still shows the enquiry so nothing is lost. .form-fallback above is the old
   handler's panel and is no longer emitted. */

/* The honeypot. Off-screen rather than display:none -- a bot that skips
   display:none fields still fills this one in, which is the whole point. Never
   focusable (tabindex="-1"), never announced (aria-hidden). */
.ob-hp{position:absolute!important;left:-9999px!important;top:auto!important;
  width:1px!important;height:1px!important;overflow:hidden!important;
  opacity:0!important;pointer-events:none!important}

/* Button while the request is in flight. */
.form button[aria-busy="true"],.form .btn[aria-busy="true"]{opacity:.72;cursor:progress}
.sending-dots{display:inline-block;width:1.1em;text-align:left}
.sending-dots::after{content:'';animation:ob-dots 1.2s steps(4,end) infinite}
@keyframes ob-dots{0%{content:''}25%{content:'.'}50%{content:'..'}75%{content:'...'}}
@media(prefers-reduced-motion:reduce){.sending-dots::after{animation:none;content:'...'}}

/* Result panel. Same shape for both outcomes; the left rule carries the
   meaning, so it reads correctly without relying on colour alone -- the
   heading says which it is. */
.form-status{display:none;margin-top:22px;padding:22px 24px;
  border:1px solid rgb(var(--c-tint) / .16);border-left-width:3px;
  border-radius:var(--radius-sm);background:rgb(var(--c-tint) / .06);
  backdrop-filter:blur(8px)}
.form-status.is-visible{display:block;animation:page-hero-in .5s var(--ease-premium) both}
.form-status:focus{outline:none}
.form-status:focus-visible{outline:2px solid var(--gold);outline-offset:3px}
.form-status.is-ok{border-left-color:rgb(var(--c-accent))}
.form-status.is-error{border-left-color:rgb(var(--c-gold-hi))}
.form-status-title{margin:0 0 8px;font-weight:800;font-size:15px;line-height:1.45;
  color:rgb(var(--c-text))}
.form-status.is-ok .form-status-title{font:500 24px/1.2 var(--serif);letter-spacing:-.02em}
.form-status-note{margin:0;font-size:13px;line-height:1.65;color:rgb(var(--c-text-mut))}
.form-status-note a{color:var(--gold);font-weight:700;text-decoration:underline;
  text-underline-offset:2px}
.form-status-reason{opacity:.7}
.form-status-body{margin:16px 0 18px;padding:16px;border-radius:12px;
  background:rgb(var(--c-tint) / .07);border:1px solid rgb(var(--c-tint) / .12);
  font:13px/1.65 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  color:rgb(var(--c-text) / .88);white-space:pre-wrap;word-break:break-word;
  max-height:280px;overflow:auto}
.form-status-body[hidden]{display:none}
.form-status-actions{display:flex;flex-wrap:wrap;gap:12px}
.form-status-actions[hidden]{display:none}
@media(max-width:720px){.form-status-actions .btn{width:100%}}

/* Inside the quote dialog the panel sits in a scrolling card, so it needs the
   same inner rhythm as the form it replaces the bottom of. */
.quote-modal .form-status{margin-bottom:6px}


/* =============================
   V68 -- Instagram DM routes
   ============================= */

/* ---- nav DM button ---------------------------------------------------- */
/* Lives inside .desktop-cta, which already hides itself under 1050px, so this
   needs no breakpoint rules of its own. Outline rather than filled: the gold
   "Get a quote" beside it is the primary action and has to stay the loudest
   thing in the header. */
.btn-dm{display:inline-flex;align-items:center;gap:7px;
  border:1px solid rgb(var(--c-text) / .22);background:transparent;
  color:rgb(var(--c-text));font-weight:750}
.btn-dm:hover{border-color:rgb(var(--c-gold-hi) / .55);color:rgb(var(--c-gold-text))}
.dm-glyph{width:17px;height:17px;flex:0 0 auto}
.desktop-cta .btn-dm{min-height:48px;align-self:center;padding:0 15px;font-size:13.5px}

/* In the mobile sheet it is a full-width row like the quote button under it,
   and earns the full label -- there is room, and "DM" alone is jargon to
   plenty of people. */
.btn-dm-mobile{width:100%;justify-content:center;margin-top:14px;min-height:48px}

/* ---- corner card ------------------------------------------------------ */
/* Fixed to the corner and never over the text column. On phones it spans the
   width but still sits below the content rather than on top of it, which is
   what keeps it outside Google's intrusive-interstitial rule. */
.ig-card{position:fixed;right:22px;bottom:22px;z-index:1200;width:min(330px,calc(100vw - 44px));
  padding:20px 22px 22px;border-radius:var(--radius);
  border:1px solid rgb(var(--c-border) / .6);background:rgb(var(--c-surface) / .97);
  box-shadow:0 22px 60px -18px rgba(0,0,0,.55);backdrop-filter:blur(14px);
  opacity:0;transform:translate3d(0,14px,0);
  transition:opacity .3s var(--ease-premium),transform .3s var(--ease-premium)}
.ig-card.is-in{opacity:1;transform:translate3d(0,0,0)}
.ig-card[hidden]{display:none}

.ig-card-title{margin:0 0 6px;padding-right:26px;
  font:500 20px/1.2 var(--serif);letter-spacing:-.02em;color:rgb(var(--c-text))}
.ig-card-note{margin:0 0 16px;font-size:13px;line-height:1.6;color:rgb(var(--c-text-mut))}
.ig-card-btn{width:100%;justify-content:center;gap:8px;min-height:46px;font-size:14px}

.ig-card-close{position:absolute;top:12px;right:12px;width:30px;height:30px;
  display:grid;place-items:center;padding:0;cursor:pointer;
  border:0;border-radius:50%;background:transparent;color:rgb(var(--c-text-mut))}
.ig-card-close svg{width:15px;height:15px}
.ig-card-close:hover{background:rgb(var(--c-tint) / .10);color:rgb(var(--c-text))}
.ig-card-close:focus-visible{outline:2px solid var(--gold);outline-offset:2px}

@media(max-width:520px){
  .ig-card{right:12px;left:12px;bottom:12px;width:auto;padding:17px 18px 19px}
  .ig-card-title{font-size:18px}
}

/* The card is the one thing on the page that moves without being asked, so it
   gets no motion at all when motion is unwelcome. */
@media(prefers-reduced-motion:reduce){
  .ig-card{transition:none;transform:none}
  .ig-card.is-in{transform:none}
}

/* .desktop-cta carries display:none inside @media(max-width:1050px), but a
   LATER unconditional .desktop-cta{display:flex} at the same specificity wins
   at every width -- so that container has never actually hidden, and the quote
   button has always sat beside the hamburger on phones. Not untangling that
   here: it is long-standing behaviour nobody asked to change.
   What does need fixing is that adding a second button to that row tipped a
   header already tight at 390px into overflow and wrapped "Get a quote" onto
   two lines. The mobile sheet carries a full-width Instagram row of its own,
   so the desktop DM button is redundant below the breakpoint anyway. This
   layer is last in the file, so the rule stands. */
@media(max-width:1050px){
  .desktop-cta .btn-dm{display:none}
}

/* The open mobile menu was completely untappable on the homepage: all eight
   links hit-tested to .scroll-hero-stage instead of themselves.
   Same cascade trap as .desktop-cta above. .site-header is declared
   position:fixed;z-index:1000 twice, then a LATER unconditional rule at equal
   specificity resets it to position:relative;z-index:1 -- and .scroll-hero and
   .scroll-hero-stage both carry isolation:isolate, so they paint over a
   z-index of 1. Nobody saw it because .mobile-nav is display:none on desktop,
   and the menu is the only part of the header that overlaps the page.
   Measured, not guessed: z-index:1000 restores 8/8 links, position:fixed alone
   restores 0/8. So only the z-index is touched, and only at widths where the
   mobile menu can open -- the header's own positioning is left exactly as it
   is at every width.
   This is not cosmetic: the DM button added above lives in that menu, so the
   feature does not work on a phone without it. */
@media(max-width:1050px){
  .site-header{z-index:1000}
}


/* =============================
   V69 -- back to top, breadcrumbs everywhere, cookie consent
   ============================= */

/* ---- back to top ------------------------------------------------------ */
/* Sits under the Instagram card in the same corner rather than beside it, so
   the two never overlap at any width. z-index below the card and far below the
   cookie bar, which is the only one of the three that must always win. */
.to-top{position:fixed;right:22px;bottom:22px;z-index:1150;
  width:46px;height:46px;display:grid;place-items:center;padding:0;cursor:pointer;
  border:1px solid rgb(var(--c-border) / .65);border-radius:50%;
  background:rgb(var(--c-surface) / .92);color:rgb(var(--c-text));
  box-shadow:0 12px 34px -12px rgba(0,0,0,.5);backdrop-filter:blur(12px);
  opacity:0;transform:translate3d(0,10px,0);
  transition:opacity .28s var(--ease-premium),transform .28s var(--ease-premium),
             border-color .28s,color .28s}
.to-top.is-in{opacity:1;transform:translate3d(0,0,0)}
.to-top[hidden]{display:none}
.to-top svg{width:19px;height:19px}
.to-top:hover{border-color:rgb(var(--c-gold-hi) / .6);color:rgb(var(--c-gold-text))}
.to-top:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

/* The Instagram card is raised to clear the button. Declared here rather than
   edited into V68, which is the rule for this file: layers are appended. */
.ig-card{bottom:84px}
@media(max-width:520px){
  .ig-card{bottom:74px}
  .to-top{right:12px;bottom:12px;width:42px;height:42px}
}

/* ---- breadcrumbs on the non-concept pages ----------------------------- */
/* .crumbs itself is styled in V66. These pages only need the wrapper that
   carries it above a grid section, plus a little room inside the dark hero. */
.crumb-bar{margin-bottom:4px}
.page-hero-inner .crumbs{margin-bottom:20px}
.page-hero-inner .crumbs a,.page-hero-inner .crumbs [aria-current]{color:rgb(var(--c-text-mut))}
.page-hero-inner .crumbs a:hover{color:var(--ivory)}

/* ---- cookie bar ------------------------------------------------------- */
/* Bottom bar, not a centred modal: it does not block the page, does not trap
   focus, and leaves the content readable while someone decides. Highest
   z-index on the site, because a consent control that another overlay can
   cover is not a consent control. */
.cookie-bar{position:fixed;left:0;right:0;bottom:0;z-index:1400;
  border-top:1px solid rgb(var(--c-border) / .6);
  background:rgb(var(--c-surface) / .98);backdrop-filter:blur(18px);
  box-shadow:0 -18px 50px -20px rgba(0,0,0,.55);
  opacity:0;transform:translate3d(0,100%,0);
  transition:opacity .32s var(--ease-premium),transform .32s var(--ease-premium)}
.cookie-bar.is-in{opacity:1;transform:translate3d(0,0,0)}
.cookie-bar[hidden]{display:none}

.cookie-inner{max-width:1200px;margin:0 auto;padding:20px 24px;
  display:flex;align-items:center;gap:26px;flex-wrap:wrap}
.cookie-copy{flex:1 1 420px;min-width:0}
.cookie-title{margin:0 0 4px;font:500 18px/1.2 var(--serif);color:rgb(var(--c-text))}
.cookie-text{margin:0;font-size:13px;line-height:1.6;color:rgb(var(--c-text-mut))}
.cookie-text a{color:var(--gold);font-weight:700;text-decoration:underline;
  text-underline-offset:2px}
.cookie-actions{display:flex;gap:10px;flex-wrap:wrap;align-items:center}
.cookie-actions .btn{min-height:44px;padding:0 20px;font-size:13.5px}
.cookie-actions .btn[hidden]{display:none}

/* Reject must not read as the lesser option -- a refusal that looks like a
   dead end is a dark pattern. Ghost and Preferences share one weight. */
.btn-ghost{background:transparent;border:1px solid rgb(var(--c-text) / .24);
  color:rgb(var(--c-text));font-weight:750}
.btn-ghost:hover{border-color:rgb(var(--c-gold-hi) / .55);color:rgb(var(--c-gold-text))}

.cookie-prefs{flex:1 1 100%;display:grid;gap:12px;
  margin-top:4px;padding-top:16px;border-top:1px solid rgb(var(--c-border) / .45)}
.cookie-prefs[hidden]{display:none}
.cookie-pref{display:flex;gap:12px;align-items:flex-start;font-size:13px;
  line-height:1.55;color:rgb(var(--c-text-mut));cursor:pointer}
.cookie-pref input{margin-top:2px;width:17px;height:17px;flex:0 0 auto;accent-color:rgb(var(--c-accent))}
.cookie-pref input:disabled{cursor:not-allowed;opacity:.6}
.cookie-pref strong{display:block;color:rgb(var(--c-text));font-size:13px;margin-bottom:2px}

/* While the bar is up nothing else may sit in the bottom corners. */
body.has-cookie-bar .to-top,body.has-cookie-bar .ig-card{display:none}

/* Footer control to change the choice later. Consent has to be as easy to
   withdraw as it was to give. */
.footer-pref{background:none;border:0;padding:0;cursor:pointer;font:inherit;
  font-size:12px;color:rgb(var(--c-text-mut));text-decoration:underline;
  text-underline-offset:3px}
.footer-pref:hover{color:rgb(var(--c-gold-text))}
.footer-pref:focus-visible{outline:2px solid var(--gold);outline-offset:3px}

@media(max-width:720px){
  .cookie-inner{padding:18px 16px;gap:16px}
  .cookie-actions{width:100%}
  .cookie-actions .btn{flex:1 1 auto}
}

@media(prefers-reduced-motion:reduce){
  .to-top,.cookie-bar{transition:none;transform:none}
  .to-top.is-in,.cookie-bar.is-in{transform:none}
}


/* =============================
   V70 -- SEO card link moved out; service card image alignment
   ============================= */

/* The "See how we approach search visibility" link used to live inside the
   last .seo-card, which read as though it belonged to card 05 rather than to
   the whole set. It now sits below the grid as its own row. */
.seo-bento-action{margin-top:26px}

/* .bounce-demo-panel is absolutely positioned at a fixed `top`, but the text
   above it is not a fixed height. The narrow `bounce-small` cards (span 4)
   wrap their paragraph to 3 lines at 1440px and 4 lines around 1060-1150px,
   where the wide cards (span 8) only ever need 2 -- so the "Explore service"
   link ran straight into the image. Measured overlap on the small cards:
   1px at 1280, 16px at 1440, 20px at 1060, 23px at 1150. Wide cards: 0 at
   every width.
   Moving only the small cards' panels would have fixed the collision and
   broken the row: small and wide sit side by side, so their image panels have
   to start at the same height. Both move together, and the card grows by the
   same amount so the panel keeps its original height and no image is scaled
   down to buy the clearance. */
/* The small cards carry their own `.bounce-service-card.bounce-small
   .bounce-demo-panel{top:205px}` at (0,3,0), which outranks a bare
   .bounce-demo-panel no matter how late it appears -- the same specificity
   trap .desktop-cta and .site-header both hit. Matched here, not worked
   around, so the two selectors move together and the row stays aligned. */
@media(min-width:1051px){
  .bounce-service-card{min-height:471px}
  .bounce-demo-panel{top:246px}
  .bounce-service-card.bounce-small .bounce-demo-panel{top:246px}
}
