/* CX-Feedback — homepage. Spec: website-specification.md section 6. */ function HomeHero() { return (
); } const Mini = ({ label, value }) => (
{label}
{value}
); function TrustStrip() { const items = [ { value: '110', label: 'UK social landlords' }, { value: '1M+', label: 'Tenants reached every year' }, { value: '98%', label: 'Renew every year' }, { value: 'GDPR', label: 'UK compliant, EU-hosted' }, { value: '2008', label: 'Trading since. Glasgow-based.' }, ]; return (
{items.map((it, i) => (
{it.value}
{it.label}
))}
); } function PainsSection() { const cards = [ { Icon: IconBarChart, pain: 'We send surveys but never read the results properly.', answer: 'AI sentiment and triage reads every response, surfaces the urgent ones, and saves the team hundreds of hours.' }, { Icon: IconSmartphone, pain: 'We cannot reach our under-35 tenants.', answer: 'Targeted SMS and email reach the digital-native cohort in seconds. The scrutiny panel is no longer the only voice in the room.' }, { Icon: IconTarget, pain: 'One-size-fits-all communications are killing our response rates.', answer: 'Build a target group from any tenant attribute, then send only what is relevant. Mosscare St Vincents used this to move from C2 to C1.' }, { Icon: IconPound, pain: 'Print, post and phone are eating the budget.', answer: 'Switching newsletters and consultations to SMS and email delivers a substantial saving the moment you turn it on. Blairtummock saw repairs response rates lift from 5% to 25%.' }, { Icon: IconShieldAlert, pain: 'We dread an unannounced regulator inspection.', answer: 'The audit trail writes itself. Representation charts and the statement of representativeness come ready to hand to the regulator.' }, { Icon: IconFileCheck, pain: 'We need to evidence the TIAA Standard, not just promise it.', answer: 'Ask, acknowledge, show the change. Three steps, one platform, every touch tracked against the tenant.' }, ]; return (
{cards.map((c, i) => ( ))}
); } function AchievementsGrid() { const tiles = [ { value: '57% → 81%', label: 'TP07 "landlord keeps you informed", in a single year', source: 'Industrial Dwellings Society', href: 'Customers.html#ids' }, { value: '+12%', label: 'TP07 lift since adopting Engagement+', source: 'Tuntum Housing Association', href: 'Customers.html#tuntum' }, { value: '5% → 25%', label: 'Repairs satisfaction response rate', source: 'Blairtummock Housing Association', href: 'Customers.html#blairtummock' }, { value: '78%', label: 'Of customers engaged in twelve months through targeted messaging', source: 'Muir Group Housing Association', href: 'Customers.html#muir' }, { value: '10 mins', label: 'From incident to every affected tenant informed', source: 'Dacorum Borough Council', href: 'Customers.html#dacorum' }, { value: 'C2 → C1', label: 'Consumer standards grading uplift', source: 'Mosscare St Vincents', href: 'Customers.html#msv' }, ]; return (
{tiles.map((t, i) => ( ))}
); } function ClosingTheLoopBlock() { return (
}>Read the closing-the-loop guide
); } function TwoFeaturesBlock() { return (
); } function FeatureBig({ tag, Icon, title, body, bullets, quote, href }) { return (
{tag}

{title}

{body}

“{quote.text}”
{quote.name} · {quote.role}, {quote.org}
See how this works
); } function TeamSection() { return (

The team behind the platform

The platform, plus the team you wish you had.

When you sign with us, the software comes with the team. Unlimited access to our long-tenured British team. The best time of day to send a particular survey to get the highest response. Which question styles work for which tenant groups. How to phrase a sensitive question so tenants answer honestly. What other landlords have tried and what actually worked.

Eighteen years in social housing. On the phone. Included in every contract.

}>Meet the team
“The system is intuitive and easy to navigate. Customer service from CX-Feedback has been excellent, with prompt and helpful support whenever needed.”
Gillian Bell · Blairtummock Housing Association
); } // Pre-calculated logo aspect ratios to prevent Layout Shifts (CLS) and enable visual weight balancing const LOGO_ASPECTS = { "Accent.png": 1.32, "Albyn Housing Society.png": 1.53, "Almond Housing Association.png": 2.12, "Ardenglen Housing Association.png": 2.09, "Ark People Housing Care.png": 1.94, "Aspire Housing.png": 1.0, "Aster Group.png": 3.32, "Ayrshire Housing.png": 3.27, "Bernicia.png": 3.64, "Berwickshire Housing Association.png": 2.24, "Broadacres.png": 1.0, "Broadland Housing.png": 1.0, "Bury Council.png": 2.1, "Caledonia Housing Association.png": 1.5, "Calvay Housing Association.png": 3.75, "Castles and Coasts Housing Association.png": 2.18, "Cernach Housing Association.png": 1.21, "Cloch Housing Association.png": 1.08, "Clydesdale Housing Association.png": 3.59, "Cobalt Housing.png": 2.04, "Cromwood Housing Group.png": 2.08, "Cross Keys Homes.png": 0.9, "Dacorum Borough Council.png": 0.69, "Dunbritton Housing Association 30 Years.png": 1.21, "Dunbritton Housing Association.png": 1.0, "Elderpark Housing.png": 1.15, "Fairfield Housing Co-operative.png": 3.3, "Fife Council.png": 2.05, "Fife Housing Group.png": 1.07, "ForViva.png": 3.32, "Gateway Housing.png": 1.82, "Glen Oaks Housing Association.png": 5.13, "Golding Homes.png": 3.51, "Govan Housing Association.png": 2.75, "Govanhill Housing Association.png": 2.32, "Grampian Housing Association.png": 2.02, "Hammersmith and Fulham.png": 2.14, "Hexagon Housing.png": 3.4, "Highland Residential.png": 3.47, "Hillcrest.png": 2.01, "Hillhead Housing Association.png": 2.07, "Honeycomb Group.png": 1.53, "Industrial Dwellings Society.png": 1.0, "Kingdom Group.png": 1.69, "Legal and General Affordable Homes.png": 1.5, "Liberty.png": 3.54, "Link.png": 0.89, "Livin.png": 1.74, "Lochfield Park Housing Association.png": 3.5, "Maryhill Housing.png": 1.0, "Medway Council.png": 1.35, "Mid Devon District Council.png": 1.31, "Molendinar Park Housing Association.png": 2.8, "Muir Group.png": 1.11, "Muirhouse Housing Association.png": 3.62, "NG Homes.png": 0.75, "Northumberland County Council.png": 5.16, "Oak Tree Housing Association.png": 1.63, "Ochil View Housing Association.png": 1.79, "Paradigm Housing.png": 0.84, "Pineview Housing Association.png": 1.89, "Plus Dane Housing.png": 2.23, "Prima Group.png": 2.35, "Queens Cross Housing Association.png": 2.0, "Regenda Homes.png": 2.1, "Reidvale Housing Association.png": 1.36, "River Clyde Homes.png": 3.92, "Rooftop Housing Group.png": 4.06, "Rosebery Housing Association.png": 2.85, "Rural Stirling Housing Association.png": 1.35, "Rutherglen and Cambuslang Housing Association.png": 1.0, "Salix Homes.png": 2.74, "Salvation Army Homes.png": 4.09, "Saxon Weald.png": 1.88, "Scotland Map.png": 0.67, "Settle.png": 2.9, "Shire Housing.png": 1.41, "Six Town Housing.png": 1.9, "South Liverpool Homes.png": 1.51, "Southlakes Housing.png": 1.72, "Sparrow Shared Ownership.png": 1.0, "Squared.png": 2.99, "Stirling Council.png": 1.9, "Stockport Homes.png": 2.68, "The Scottish Government.png": 1.6, "The Wrekin Housing Group.png": 2.2, "Thrive Homes.png": 2.33, "Trust Housing Association.png": 2.6, "Wandle.png": 2.91, "Watford Community Housing.png": 1.45, "West Highland Housing Association.png": 1.35, "West Lothian Council.png": 2.38, "West Whitlawburn Housing Co-operative.png": 1.0, "Williamsburgh Housing Association.png": 1.7, "Wirral Methodist Housing Association.png": 2.33, "Worthing Homes.png": 1.91 }; // Aspect-ratio-based Tailwind class mapping to balance the visual weight of logos function getLogoSizingClasses(file) { const aspect = LOGO_ASPECTS[file] || 1.8; if (aspect > 3.0) { // Extremely wide logo (e.g. Glen Oaks, Aster) // Wide box, large max width, maximum height, compact padding return { container: "min-w-[190px] max-w-[250px] px-6 h-20", image: "h-full max-h-12 sm:max-h-14 w-auto max-w-[180px]" }; } else if (aspect > 2.0) { // Wide logo (e.g. Thrive, Settle) return { container: "min-w-[160px] max-w-[210px] px-5 h-20", image: "h-full max-h-12 sm:max-h-[50px] w-auto max-w-[150px]" }; } else if (aspect >= 1.3) { // Standard landscape logo return { container: "min-w-[140px] max-w-[185px] px-5 h-20", image: "h-full max-h-12 sm:max-h-[50px] w-auto max-w-[125px]" }; } else if (aspect >= 0.95) { // Square/compact logo // Scaled-down height to prevent overpowering, narrow snug card return { container: "min-w-[110px] max-w-[140px] px-4.5 h-20", image: "h-full max-h-10 sm:max-h-11 w-auto max-w-[95px]" }; } else { // Tall/portrait logo // Custom tight frame and height to sit balanced return { container: "min-w-[100px] max-w-[130px] px-4 h-20", image: "h-full max-h-10 sm:max-h-[44px] w-auto max-w-[85px]" }; } } function PartnerLogoTicker() { const fallbackLogos = [ "Accent.png", "Albyn Housing Society.png", "Almond Housing Association.png", "Ardenglen Housing Association.png", "Ark People Housing Care.png", "Aspire Housing.png", "Aster Group.png", "Ayrshire Housing.png", "Bernicia.png", "Berwickshire Housing Association.png", "Broadacres.png", "Broadland Housing.png", "Bury Council.png", "Caledonia Housing Association.png", "Calvay Housing Association.png", "Castles and Coasts Housing Association.png", "Cernach Housing Association.png", "Cloch Housing Association.png", "Clydesdale Housing Association.png", "Cobalt Housing.png", "Cromwood Housing Group.png", "Cross Keys Homes.png", "Dacorum Borough Council.png", "Dunbritton Housing Association.png", "Dunbritton Housing Association 30 Years.png", "Elderpark Housing.png", "Fairfield Housing Co-operative.png", "Fife Council.png", "Fife Housing Group.png", "ForViva.png", "Gateway Housing.png", "Glen Oaks Housing Association.png", "Golding Homes.png", "Govan Housing Association.png", "Govanhill Housing Association.png", "Grampian Housing Association.png", "Hammersmith and Fulham.png", "Hexagon Housing.png", "Highland Residential.png", "Hillcrest.png", "Hillhead Housing Association.png", "Honeycomb Group.png", "Industrial Dwellings Society.png", "Kingdom Group.png", "Legal and General Affordable Homes.png", "Liberty.png", "Link.png", "Livin.png", "Lochfield Park Housing Association.png", "Maryhill Housing.png", "Medway Council.png", "Mid Devon District Council.png", "Molendinar Park Housing Association.png", "Muir Group.png", "Muirhouse Housing Association.png", "NG Homes.png", "Northumberland County Council.png", "Oak Tree Housing Association.png", "Ochil View Housing Association.png", "Paradigm Housing.png", "Pineview Housing Association.png", "Plus Dane Housing.png", "Prima Group.png", "Queens Cross Housing Association.png", "Regenda Homes.png", "Reidvale Housing Association.png", "River Clyde Homes.png", "Rooftop Housing Group.png", "Rosebery Housing Association.png", "Rural Stirling Housing Association.png", "Rutherglen and Cambuslang Housing Association.png", "Salix Homes.png", "Salvation Army Homes.png", "Saxon Weald.png", "Settle.png", "Shire Housing.png", "Six Town Housing.png", "South Liverpool Homes.png", "Southlakes Housing.png", "Sparrow Shared Ownership.png", "Squared.png", "Stirling Council.png", "Stockport Homes.png", "The Scottish Government.png", "The Wrekin Housing Group.png", "Thrive Homes.png", "Trust Housing Association.png", "Wandle.png", "Watford Community Housing.png", "West Highland Housing Association.png", "West Lothian Council.png", "West Whitlawburn Housing Co-operative.png", "Williamsburgh Housing Association.png", "Wirral Methodist Housing Association.png", "Worthing Homes.png" ]; const [logoFiles, setLogoFiles] = React.useState(fallbackLogos); React.useEffect(() => { async function discoverLogos() { try { // Try dynamic PHP script first (works perfectly on XAMPP) const phpRes = await fetch('get-logos.php'); if (phpRes.ok) { const files = await phpRes.json(); if (Array.isArray(files) && files.length > 0) { setLogoFiles(files); return; } } } catch (e) { console.warn("PHP logo discovery failed, trying folder index...", e); } try { // Try dynamic directory listing fetch const dirRes = await fetch('assets/logos/'); if (dirRes.ok) { const html = await dirRes.text(); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const links = Array.from(doc.querySelectorAll('a')); const files = links .map(link => link.getAttribute('href')) .filter(href => href && (href.toLowerCase().endsWith('.png') || href.toLowerCase().endsWith('.jpg') || href.toLowerCase().endsWith('.jpeg') || href.toLowerCase().endsWith('.svg') || href.toLowerCase().endsWith('.webp'))) .map(href => decodeURIComponent(href.split('/').pop())) .filter((value, index, self) => self.indexOf(value) === index && value !== '.gitkeep'); if (files.length > 0) { setLogoFiles(files); return; } } } catch (e) { console.warn("Logo folder discovery failed, falling back to static list...", e); } } discoverLogos(); }, []); // Distribute the dynamic logos equally across three rows const rowLength = Math.ceil(logoFiles.length / 3); const row1 = logoFiles.slice(0, rowLength); const row2 = logoFiles.slice(rowLength, rowLength * 2); const row3 = logoFiles.slice(rowLength * 2); const renderLogo = (file, i) => { const name = file.replace('.png', ''); const sizes = getLogoSizingClasses(file); return (
{`${name}
); }; return (
{/* Dynamic Keyframes injected locally to keep index.html clean and modular */}