<!DOCTYPE html> <html lang="it"> <head> <meta charset="UTF-8" /> <title> Salvatore Malatesta Reddit </title> <!--meta name="description" content="Reddit "/--> <meta name="description" content="" /> <meta http-equiv="x-ua-compatible" content="ie=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover" /> <!-- OPEN GRAPH ESSENTIALS --> <meta property="og:title" content="Reddit · Salvatore Malatesta" /> <meta property="og:type" content="website" /> <meta property="og:image" content="https://www./i/opengraph.jpg" /> <meta property="og:url" content="https://www./socials/reddit" /> <!-- OPEN GRAPH OPTIONALS --> <meta property="og:site_name" content="Salvatore Malatesta" /> <meta property="og:description" content="The official website of Salvatore Malatesta — famed entrepreneur and pioneer of Melbourne's coffee and culture scene." /> <!-- hosted fonts aren't working in safari 🤷🏾 --> <!--link rel="preload" href="/fonts/Barriecito-Regular.ttf" as="font" type="font/ttf" crossorigin--> <!-- Preload fonts for font switcher to prevent FOUT --> <link rel="preload" href="/fonts/Barriecito-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/Grez-Regular.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/DynaPuff-Variable.ttf" as="font" type="font/ttf" crossorigin /> <!-- Fallback formats --> <link rel="preload" href="/fonts/Barriecito-Regular.woff" as="font" type="font/woff" crossorigin /> <link rel="preload" href="/fonts/Grez-Regular.woff" as="font" type="font/woff" crossorigin /> <!-- so gfonts it is; with a wierd → workaround --> <!--link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Barriecito&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Barriecito&display=swap&text=%E2%86%92" rel="stylesheet"--> <link rel="stylesheet" href="/style.css?v=1757473313366" /> <script defer src="/js/alpine.js?v=1757473313366"></script> </head> <body class="quote bg-white font-barri font-normal not-italic text-4xl sm:text-6xl tracking-ss leading-0 bg-white font-barri font-normal not-italic text-4xl sm:text-6xl tracking-ss leading-0" > *** <!-- HERO --> <div class="bg-white"> <div class="container-space container px-6 w-full sm:w-4/5 sm:mx-auto"> <!--a href="/"> <h1 class="text-black text-7xl sm:text-10xl uppercase"> </h1> </a--> </div> </div> <!-- HERO --> <div class=" bg- text-"> <div class="container px-6 w-full sm:w-4/5 sm:mx-auto "> <!-- TITLE --> <a href="/"> <h1 class="mb-1 text-7xl sm:text-10xl uppercase"> Salvatore </h1> </a> <!-- SUBTITLE --> <!-- FONT SWITCHER SUBTITLE COMPONENT --> <!-- Original inline version - preserved for rollback --> <!-- <div x-data="fontToggle()" x-init="init()"> <p class="mb-5 sm:mb-16"> Malatesta's <button @click="toggleFont()" class="cursor-pointer font-bold underline" x-text="getCurrentFontName()" ></button> website. </p> </div> --> <!-- Dynamic subtitle with i18n support --> <div x-data> <p class="mb-5 sm:mb-16"> Malatesta's <span class="font-bold underline" x-text="$store.fontToggle.getCurrentLocalizedSubtitle()" ></span>. </p> </div> <!-- MENU--> <div class="grid grid-flow-col grid-cols-2 grid-rows-4 sm:grid-cols-2 sm:grid-rows-4 sm:grid-flow-col gap-y-3 sm:gap-y-4 uppercase"> <div class=""><span class="text-black mr-2">·</span><a class="underline text-black" href="/about/">about</a></div> <div class=""><span class="text-gold mr-2">·</span><a class="underline text-gold" href="/photos/">photos</a></div> <div class=""><span class="text-lblue mr-2">·</span><a class="underline text-lblue" href="/video/">Videos</a></div> <div class=""><span class="text-darkRust mr-2">·</span><a class="underline text-darkRust" href="/socials/">socials</a></div> <div class=""><span class="text-orange mr-2">·</span><a class="underline text-orange" href="/wife/">Wife</a></div> <div class=""><span class="text-blue mr-2">·</span><a class="underline text-blue" href="/family/">Family</a></div> <div class=""><span class="text-purple mr-2">·</span><a class="underline text-purple" href="/quotes/">Quotes</a></div> <div class=""><span class="text-greenCrayola mr-2">·</span><a class="underline text-greenCrayola" href="/contact/">contact</a></div> </div> <div class="grid grid-flow-row grid-cols-1 auto-rows-max sm:grid-cols-1 gap-y-3 sm:gap-y-4 uppercase mt-20"> <div class=""><span class=" text-black" >© 2025 · <a class="text-black" href="https://www.lanebrain.co" target="_blank"><!--span class="text-gray-200">hand</span-->Made by LaneBrain</a></span></div> </div> </div> </div> <!-- Multi-Selector Font Switcher (commented out - can be restored later) --> <!-- <div x-data="fontSwitcher()" x-init="init()" class="fixed bottom-4 left-4 z-50" > <div class="relative"> <button @click="open = !open" class="bg-black text-white p-3 rounded-full shadow-lg hover:bg-gray-800 transition-colors" aria-label="Change font" > <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path> </svg> </button> <div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="opacity-0 transform scale-90" x-transition:enter-end="opacity-100 transform scale-100" x-transition:leave="transition ease-in duration-100" x-transition:leave-start="opacity-100 transform scale-100" x-transition:leave-end="opacity-0 transform scale-90" @click.away="open = false" class="absolute bottom-16 left-0 bg-white border-2 border-black rounded-lg shadow-xl p-4 min-w-[200px]" > <div class="space-y-2"> <button @click="setFont('barri')" :class="{'bg-black text-white': currentFont === 'barri'}" class="w-full text-left px-4 py-2 rounded hover:bg-gray-100 transition-colors font-barri" > Barriecito </button> <button @click="setFont('bebas')" :class="{'bg-black text-white': currentFont === 'bebas'}" class="w-full text-left px-4 py-2 rounded hover:bg-gray-100 transition-colors font-bebas" > Bebas Neue </button> <button @click="setFont('georgia')" :class="{'bg-black text-white': currentFont === 'georgia'}" class="w-full text-left px-4 py-2 rounded hover:bg-gray-100 transition-colors font-georgia" > Georgia </button> <button @click="setFont('rancho')" :class="{'bg-black text-white': currentFont === 'rancho'}" class="w-full text-left px-4 py-2 rounded hover:bg-gray-100 transition-colors font-rancho" > Rancho </button> </div> </div> </div> </div> --> <!-- FONT SWITCHER - COMMENTED OUT WHILE TESTING INLINE VERSION --> <!-- <div x-data="fontToggle()" x-init="init()" class="fixed z-50" style="position: fixed !important; top: 16px !important; right: 16px !important; bottom: auto !important; left: auto !important;" > <button @click="toggleFont()" class="relative group" aria-label="Toggle font mode" > <div class="absolute inset-0 bg-black rounded-full blur-sm opacity-10 group-hover:opacity-20 transition-opacity"></div> <div class="relative bg-white border-2 border-black rounded-full transition-all duration-300 group-hover:scale-110 group-hover:border-gray-600" style="width: 64px; height: 64px; min-width: 64px; min-height: 64px;"> <span class="absolute text-3xl" :style="` top: 50%; left: 50%; transform: translate(-50%, ${getCurrentFont() === 'bebas' ? '-52%' : getCurrentFont() === 'rancho' ? '-48%' : '-50%'}); line-height: 1; font-style: normal; `" x-text="getCurrentFontEmoji()"></span> </div> </button> </div> --> <!-- NEW CHANGE MOOD BADGE - Always show for local development --> <div x-data x-init="$store.fontToggle.init()" class="fixed z-50" style=" position: fixed !important; top: 20px !important; right: 20px !important; " > <button @click="$store.fontToggle.toggleFont()" class="relative group" aria-label="Change mood" > <!-- Animated gradient border --> <div class="absolute inset-0 rounded-full p-[2px] overflow-hidden"> <div class="absolute inset-0 rounded-full animate-spin-slow" style=" background: conic-gradient( from 0deg, #ff0066, #fff116, #23f788, #00b2f0, #ff0066 ); transform-origin: center; " ></div> </div> <!-- Badge --> <div class="relative bg-black text-white rounded-full transition-all duration-300 group-hover:scale-105" style=" width: 80px; height: 80px; display: flex; align-items: center; justify-content: center; transform-origin: center; margin: 2px; " > <div class="text-center mood-badge-text"> <span class="block font-medium uppercase tracking-wider leading-tight" style="font-size: 0.75rem" >Mood</span > <span class="block font-medium uppercase tracking-wider leading-tight" style="font-size: 0.75rem" >Change</span > </div> </div> </button> </div> <script> // Original fontSwitcher function (for multi-selector - preserved for rollback) function fontSwitcher() { return { open: false, currentFont: 'barri', init() { const savedFont = localStorage.getItem('preferredFont') || 'barri'; this.currentFont = savedFont; this.applyFont(savedFont); }, setFont(font) { this.currentFont = font; this.applyFont(font); localStorage.setItem('preferredFont', font); this.open = false; }, applyFont(font) { const body = document.body; body.classList.remove('font-barri', 'font-bebas', 'font-georgia', 'font-rancho', 'font-rocksalt', 'font-zeyada', 'font-caprasimo'); body.classList.add(`font-${font}`); } } } // Original Font toggle function - preserved for rollback function fontToggle() { return { fonts: ['barri', 'georgia', 'bebas', 'rancho', 'rocksalt', 'zeyada', 'caprasimo'], fontNames: { 'barri': 'very serious', 'grez': 'very Grez', 'bebas': 'uppercase everything', 'georgia': 'very academic', 'rancho': 'very silly', 'rocksalt': 'squiqqly wiggly', 'zeyada': 'light delight', 'caprasimo': 'Wild West' }, fontEmojis: { 'barri': '🎉', 'grez': '🎉', 'bebas': '😴', 'georgia': '🤓', 'rancho': '🤪', 'rocksalt': '✍️', 'zeyada': '✒️', 'caprasimo': '🎨' }, currentFontIndex: 0, init() { // Load saved font preference or default to 'barri' const savedFont = localStorage.getItem('preferredFont') || 'barri'; this.currentFontIndex = this.fonts.indexOf(savedFont); if (this.currentFontIndex === -1) this.currentFontIndex = 0; this.applyFont(this.getCurrentFont()); }, setFont(font) { // Direct font selection this.currentFontIndex = this.fonts.indexOf(font); this.applyFont(font); localStorage.setItem('preferredFont', font); }, toggleFont() { // Cycle to next font this.currentFontIndex = (this.currentFontIndex + 1) % this.fonts.length; const newFont = this.getCurrentFont(); this.applyFont(newFont); localStorage.setItem('preferredFont', newFont); }, getCurrentFont() { return this.fonts[this.currentFontIndex]; }, getCurrentFontName() { return this.fontNames[this.getCurrentFont()]; }, getCurrentFontEmoji() { return this.fontEmojis[this.getCurrentFont()]; }, applyFont(font) { const body = document.body; body.classList.remove('font-barri', 'font-grez', 'font-bebas', 'font-georgia', 'font-rancho', 'font-rocksalt', 'font-zeyada', 'font-caprasimo'); body.classList.add(`font-${font}`); } } } // Create Alpine store for shared font state - always show for local development document.addEventListener('alpine:init', () => { Alpine.store('fontToggle', { fonts: ['barri', 'grez', 'dynapuff'], fontNames: { 'barri': 'very serious', 'grez': 'very Grez', 'bebas': 'uppercase everything', 'georgia': 'very academic', 'dynapuff': 'very bouncy', 'rocksalt': 'squiqqly wiggly', 'zeyada': 'light delight', 'caprasimo': 'Wild West' }, // i18n subtitle data i18nSubtitles: {"en":{"fontNames":{"barri":"very serious website","grez":"even more serious website","dynapuff":"most serious website ever","rancho":"boringly beautiful website","bebas":"uppercase everything website","georgia":"very academic website","rocksalt":"squiqqly wiggly website","zeyada":"light delight website","caprasimo":"Wild West website"},"minimalNames":{"barri":"And his very serious website","grez":"And his even more serious website","rancho":"And his most serious website, ever"}},"it":{"fontNames":{"barri":"Il sito molto serio","grez":"Il sito ancora più serio","dynapuff":"Il sito più serio di sempre","bebas":"Il sito tutto maiuscolo","georgia":"Il sito molto accademico","rocksalt":"Il sito tutto scarabocchiato","zeyada":"Il sito leggero e delizioso","caprasimo":"Il sito del Far West"},"minimalNames":{"barri":"molto serio","grez":"ancora più serio","dynapuff":"più rimbalzante di sempre"}}}, fontEmojis: { 'barri': '🎉', 'grez': '🎉', 'bebas': '😴', 'georgia': '🤓', 'dynapuff': '🎈', 'rocksalt': '✍️', 'zeyada': '✒️', 'caprasimo': '🎨' }, currentFontIndex: 0, audio: null, init() { // Initialize audio try { this.audio = new Audio('/sounds/enter.wav'); this.audio.preload = 'auto'; this.audio.volume = 0.5; } catch (e) { console.error('Failed to initialize mood change audio:', e); } // Load saved font preference or default to 'barri' const savedFont = localStorage.getItem('preferredFont') || 'barri'; this.currentFontIndex = this.fonts.indexOf(savedFont); if (this.currentFontIndex === -1) this.currentFontIndex = 0; this.applyFont(this.getCurrentFont()); }, toggleFont() { // Play sound effect if (this.audio) { this.audio.currentTime = 0; this.audio.play().catch(e => console.log('Mood change sound failed to play:', e)); } // Add fade transition document.body.style.transition = 'opacity 0.15s ease-in-out'; document.body.style.opacity = '0'; setTimeout(() => { // Cycle to next font this.currentFontIndex = (this.currentFontIndex + 1) % this.fonts.length; const newFont = this.getCurrentFont(); this.applyFont(newFont); localStorage.setItem('preferredFont', newFont); // Fade back in document.body.style.opacity = '1'; // Clean up transition after animation completes setTimeout(() => { document.body.style.transition = ''; }, 150); }, 150); }, getCurrentFont() { return this.fonts[this.currentFontIndex]; }, getCurrentFontName() { return this.fontNames[this.getCurrentFont()]; }, getCurrentFontEmoji() { return this.fontEmojis[this.getCurrentFont()]; }, getCurrentLocalizedSubtitle() { // Get current locale from URL path const currentPath = window.location.pathname; const locale = currentPath.startsWith('/it/') ? 'it' : 'en'; // Get current font const currentFont = this.getCurrentFont(); // Return localized subtitle text for current font and locale if (this.i18nSubtitles && this.i18nSubtitles[locale] && this.i18nSubtitles[locale].fontNames) { return this.i18nSubtitles[locale].fontNames[currentFont] || "website"; } // Fallback to default if i18n data not available return this.fontNames[currentFont] + " website"; }, getCurrentMinimalSubtitle() { // Get current locale from URL path const currentPath = window.location.pathname; const locale = currentPath.startsWith('/it/') ? 'it' : 'en'; // Get current font const currentFont = this.getCurrentFont(); // Return minimal taglines (no 's or "website") if (this.i18nSubtitles && this.i18nSubtitles[locale] && this.i18nSubtitles[locale].minimalNames) { return this.i18nSubtitles[locale].minimalNames[currentFont] || "serious"; } // Fallback to simple version return this.fontNames[currentFont].replace(" website", ""); }, applyFont(font) { const body = document.body; body.classList.remove('font-barri', 'font-grez', 'font-dynapuff', 'font-bebas', 'font-georgia', 'font-rocksalt', 'font-zeyada', 'font-caprasimo'); body.classList.add(`font-${font}`); } }); }); </script> <!-- ORIGINAL Language Toggle Switch - PRESERVED FOR ROLLBACK --> <!-- <div x-data="languageSwitcher()" x-init="init()" class="fixed bottom-4 right-4 z-50" > <div class="bg-white border-2 border-black rounded-lg shadow-lg p-3"> <div class="flex items-center space-x-3"> <button @click="switchLanguage('en')" class="flex items-center justify-center px-4 py-2 rounded-md transition-all duration-200 font-medium" :class="currentLocale === 'en' ? 'bg-black text-white scale-105' : 'bg-transparent text-black opacity-60 hover:opacity-100 hover:bg-gray-100'" aria-label="Switch to English" > <span class="text-lg mr-2">🇦🇺</span> <span class="text-sm">EN</span> </button> <button @click="switchLanguage('it')" class="flex items-center justify-center px-4 py-2 rounded-md transition-all duration-200 font-medium" :class="currentLocale === 'it' ? 'bg-black text-white scale-105' : 'bg-transparent text-black opacity-60 hover:opacity-100 hover:bg-gray-100'" aria-label="Switch to Italian" > <span class="text-lg mr-2">🇮🇹</span> <span class="text-sm">IT</span> </button> </div> </div> </div> --> <!-- NEW Toggle Switch Language Switcher --> <div x-data="languageSwitcher()" x-init="init()" class="fixed z-50" style="position: fixed !important; bottom: 20px !important; right: 20px !important;" > <div class="flex items-center bg-white rounded-full shadow-lg border-2 border-black p-1"> <!-- G'DAY button --> <button @click="switchLanguage('en')" class="px-4 py-2 text-sm font-bold rounded-full transition-all duration-200" :class="currentLocale === 'en' ? 'bg-blue text-white' : 'text-black hover:text-gray-700'" aria-label="Switch to English" > G'DAY </button> <!-- CIAO button --> <button @click="switchLanguage('it')" class="px-4 py-2 text-sm font-bold rounded-full transition-all duration-200" :class="currentLocale === 'it' ? 'bg-jade text-white' : 'text-black hover:text-gray-700'" aria-label="Switch to Italian" > CIAO </button> </div> </div> <!-- PRESERVED: Circular Language Switcher (commented out for easy rollback) --> <!-- <div x-data="languageSwitcher()" x-init="init()" class="fixed z-50" style="position: fixed !important; bottom: 20px !important; right: 20px !important;" > <div class="relative" style="width: 80px; height: 80px; font-size: 1rem; transform: scale(1); font-family: system-ui, sans-serif;"> <button @click="switchLanguage('en')" class="absolute transition-all duration-300 hover:brightness-90" style=" top: 0; left: 0; width: 80px; height: 40px; background-color: #012169; border: 2px solid #000; border-radius: 40px 40px 0 0; border-bottom: 1px solid #000; box-sizing: border-box; cursor: pointer; " aria-label="Switch to English" > <span style="color: white; font-size: 16px; font-weight: bold;">G'DAY</span> </button> <button @click="switchLanguage('it')" class="absolute transition-all duration-300 hover:brightness-90" style=" bottom: 0; left: 0; width: 80px; height: 40px; background-color: #009246; border: 2px solid #000; border-radius: 0 0 40px 40px; border-top: none; box-sizing: border-box; cursor: pointer; " aria-label="Switch to Italian" > <span style="color: white; font-size: 16px; font-weight: bold;">CIAO</span> </button> </div> </div> --> <script> function languageSwitcher() { return { open: false, currentLocale: 'en', pageMappings: [{"slug":"home","translations":{"en":{"title":"Salvatore Malatesta","metaTitle":"Salvatore Malatesta","metaDescription":"The official website of Salvatore Malatesta — famed entrepreneur and pioneer of the Melbourne coffee & culture scene.","pagetitle":"Salvatore","pagesubtitle":"Malatesta (aka \"Sal\")","postTitle":"","url":"/"},"it":{"title":"Salvatore Malatesta","metaTitle":"Salvatore Malatesta","metaDescription":"Il sito ufficiale di Salvatore Malatesta — famoso imprenditore e pioniere della scena del caffè e della cultura di Melbourne.","pagetitle":"Salvatore","pagesubtitle":"Malatesta (detto \"Sal\")","postTitle":"","url":"/it/"}},"template":"home","heroBgColor":"white","heroTextColor":"black"},{"slug":"about","translations":{"en":{"title":"About","metaTitle":"About Salvatore Malatesta","metaDescription":"Everything you need to know about Salvatore Malatesta","pagetitle":"About","pagesubtitle":"Salvatore Malatesta","postTitle":"📽","url":"/about/","shortBio":"Famed entrepreneur Salvatore Malatesta is actively looking for investment opportunities and board positions.","fullBio":"Famed entrepreneur Salvatore Malatesta is a pioneer of Melbourne's coffee and culture scene and the proud husband of <a href=\"/wife/\">wife Joanne</a>.<br><br> A former lawyer and forever family man, Salvatore is actively looking for investment opportunities and board positions.<br><br>","ctaText":"Click here to contact Sal","ctaTextShort":"Click here to connect"},"it":{"title":"Chi Sono","metaTitle":"Chi è Salvatore Malatesta","metaDescription":"Tutto quello che devi sapere su Salvatore Malatesta","pagetitle":"Chi Sono","pagesubtitle":"Sal","postTitle":"📽","url":"/it/chi-sono/","shortBio":"Il famoso imprenditore Salvatore Malatesta sta attivamente cercando opportunità di investimento e posizioni nel consiglio di amministrazione.","fullBio":"Il famoso imprenditore Salvatore Malatesta è un pioniere della scena del caffè e della cultura di Melbourne e il fiero marito della <a href=\"/it/wife/\">moglie Joanne</a>.<br><br> Ex avvocato e sempre uomo di famiglia, Salvatore sta attivamente cercando opportunità di investimento e posizioni nel consiglio di amministrazione.<br><br>","ctaText":"Clicca qui per contattare Sal","ctaTextShort":"Clicca qui per connetterti"}},"template":"about","heroBgColor":"black","heroTextColor":"white"},{"slug":"photos","translations":{"en":{"title":"Photos","metaTitle":"Photos by Salvatore Malatesta","metaDescription":"Photo collection by Salvatore Malatesta","pagetitle":"Photos","pagesubtitle":"Salvatore Malatesta","postTitle":"📸","url":"/photos/"},"it":{"title":"Foto","metaTitle":"Foto di Salvatore Malatesta","metaDescription":"Collezione di foto di Salvatore Malatesta","pagetitle":"Foto","pagesubtitle":"Salvatore Malatesta","postTitle":"📸","url":"/it/photos/"}},"template":"photos","heroBgColor":"gold","heroTextColor":"black"},{"slug":"video","translations":{"en":{"title":"Videos","metaTitle":"Videos by Salvatore Malatesta","metaDescription":"Video collection by Salvatore Malatesta","pagetitle":"Video","pagesubtitle":"Salvatore Malatesta","postTitle":"📽️","url":"/video/","youtubeText":"The OFFICIAL YouTube channel for Salvatore Malatesta is","youtubeLinkText":"here","youtubeUrl":"https://www.youtube.com/channel/UCpTlABn1MHjwyJRoUqNOcHA"},"it":{"title":"Video","metaTitle":"Video di Salvatore Malatesta","metaDescription":"Collezione di video di Salvatore Malatesta","pagetitle":"Video","pagesubtitle":"Salvatore Malatesta","postTitle":"📽️","url":"/it/video/","youtubeText":"Il canale YouTube UFFICIALE di Salvatore Malatesta è","youtubeLinkText":"qui","youtubeUrl":"https://www.youtube.com/channel/UCpTlABn1MHjwyJRoUqNOcHA"}},"template":"video","heroBgColor":"lblue","heroTextColor":"white"},{"slug":"socials","translations":{"en":{"title":"Socials","metaTitle":"Salvatore Malatesta Social Media Accounts","metaDescription":"See the social media accounts for Salvatore Malatesta","pagetitle":"Socials","pagesubtitle":"Salvatore Malatesta","postTitle":"🫂","url":"/socials/"},"it":{"title":"Social","metaTitle":"Account Social di Salvatore Malatesta","metaDescription":"Vedi gli account social di Salvatore Malatesta","pagetitle":"Social","pagesubtitle":"Salvatore Malatesta","postTitle":"🫂","url":"/it/socials/"}},"template":"socials","heroBgColor":"darkRust","heroTextColor":"white"},{"slug":"wife","translations":{"en":{"title":"Mrs Malatesta","metaTitle":"Salvatore Malatesta's Wife","metaDescription":"About Salvatore Malatesta's wife","pagetitle":"Mrs Malatesta","pagesubtitle":"aka: Joanne","postTitle":"💒","url":"/wife/","wifeBio":"Joanne Malatesta is Salvatore’s partner in life and an entrepreneur with a love of food and community. While she has always played a supportive role in Salvatore’s life, she has also carved out her own path, building ventures that reflect her creativity and eye for detail.<br><br>In 2020, she founded <a href=\"https://reallygoodcoffee.com.au/\" target=\"_blank\" class=\"text-orange underline\">Really Good People</a>, a food distribution company that brings together exciting local and international brands for the Australian and New Zealand markets. From helping chefs turn their ideas into products on supermarket shelves to curating beautiful food hampers, and stocking the shelves of grocery stores, Joanne has built a business that connects people through great food. She is also the founder of Sweet Chilli Gummies, a playful confectionery brand shaking up the lolly aisle with bold flavours and a fresh personality. Both ventures highlight Joanne’s passion for brand-building and creating experiences that make people smile.<br><br>Away from business, Joanne is a proud wife and mother and finds balance in family life, travel, and good food."},"it":{"title":"La signora Malatesta","metaTitle":"La Moglie di Salvatore Malatesta","metaDescription":"Sulla moglie di Salvatore Malatesta","pagetitle":"La signora Malatesta","pagesubtitle":"alias: Joanne","postTitle":"💒","url":"/it/wife/","wifeBio":"Imprenditrice nata, la leadership, l'intuizione e l'influenza di Joanne Malatesta stanno trasformando le industrie di importazione e distribuzione a Melbourne, Sydney, Brisbane e in ogni città intermedia."}},"template":"wife","heroBgColor":"orange","heroTextColor":"white"},{"slug":"family","translations":{"en":{"title":"Family","metaTitle":"Salvatore Malatesta's Family","metaDescription":"About Salvatore Malatesta's family","pagetitle":"Family","pagesubtitle":"Salvatore Malatesta","postTitle":"👪","url":"/family/","businessBio":"Having founded and forfathered countless companies, Salvatore Malatesta now advises and invests in the coffee, technology, products, fashion, e-commerce, travel, and food & beverage industries."},"it":{"title":"Famiglia","metaTitle":"La Famiglia di Salvatore Malatesta","metaDescription":"Sulla famiglia di Salvatore Malatesta","pagetitle":"Famiglia","pagesubtitle":"Salvatore Malatesta","postTitle":"👪","url":"/it/family/","businessBio":"Avendo fondato e dato vita a innumerevoli aziende, Salvatore Malatesta ora consiglia e investe nelle industrie del caffè, tecnologia, prodotti, moda, e-commerce, viaggi e settore alimentare."}},"template":"family","heroBgColor":"blue","heroTextColor":"white"},{"slug":"quotes","translations":{"en":{"title":"Quotes","metaTitle":"Quotes by Salvatore Malatesta","metaDescription":"Quotes by Salvatore Malatesta","pagetitle":"Quotes","pagesubtitle":null,"postTitle":"💬","url":"/quotes/","byText":"by","moreQuotesText":"More","quotesBy":"quotes by Sal"},"it":{"title":"Citazioni","metaTitle":"Citazioni di Salvatore Malatesta","metaDescription":"Citazioni e detti di Salvatore Malatesta","pagetitle":"Citazioni","pagesubtitle":null,"postTitle":"💬","url":"/it/quotes/","byText":"di","moreQuotesText":"Altre","quotesBy":"citazioni di Sal"}},"template":"quotes","heroBgColor":"purple","heroTextColor":"white"},{"slug":"contact","translations":{"en":{"title":"Contact","metaTitle":"Contact Salvatore Malatesta","metaDescription":"Want to contact Sal? Here's how...","pagetitle":"Contact","pagesubtitle":"Salvatore Malatesta","postTitle":"📧","url":"/contact/"},"it":{"title":"Contatto","metaTitle":"Contatta Salvatore Malatesta","metaDescription":"Vuoi contattare Sal? Ecco come...","pagetitle":"Contatto","pagesubtitle":"Salvatore Malatesta","postTitle":"📧","url":"/it/contact/"}},"template":"contact","heroBgColor":"greenCrayola","heroTextColor":"white"},{"slug":"thank-you","translations":{"en":{"title":"Thank You","metaTitle":"Salvatore Malatesta Thank You","metaDescription":"","pagetitle":"Thank you","pagesubtitle":"Salvatore Malatesta","postTitle":"","url":"/thank-you/","thankYouMessage":"Thanks for sending your message. I'll read it as soon as possible."},"it":{"title":"Grazie","metaTitle":"Salvatore Malatesta Grazie","metaDescription":"","pagetitle":"Grazie","pagesubtitle":"Salvatore Malatesta","postTitle":"","url":"/it/grazie/","thankYouMessage":"Grazie per aver inviato il tuo messaggio. Lo leggerò il prima possibile."}},"template":"thank-you-page","heroBgColor":"white","heroTextColor":"black"}], audio: null, init() { // Initialize audio try { this.audio = new Audio('/sounds/arrow.wav'); this.audio.preload = 'auto'; this.audio.volume = 0.5; // Set volume to 50% for better experience // Test if audio can be loaded this.audio.addEventListener('canplaythrough', () => { console.log('Audio loaded successfully'); }); this.audio.addEventListener('error', (e) => { console.error('Audio loading error:', e); console.error('Audio error code:', this.audio.error?.code); console.error('Audio error message:', this.audio.error?.message); }); } catch (e) { console.error('Failed to create audio object:', e); } // Auto-close when clicking outside document.addEventListener('click', (e) => { if (!this.$el.contains(e.target)) { this.open = false; } }); // Don't auto-redirect on homepage load to avoid forcing users to Italian // Only auto-redirect on non-homepage pages if they have a saved preference const currentPath = window.location.pathname; if (currentPath !== '/' && currentPath !== '/it/') { this.checkLanguagePreference(); } }, checkLanguagePreference() { const savedLocale = localStorage.getItem('preferredLocale'); const currentPath = window.location.pathname; // If user has a saved preference and it's different from current page if (savedLocale && savedLocale !== this.currentLocale) { // Redirect to the preferred language version const newPath = this.getLocalizedPath(currentPath, savedLocale); if (newPath !== currentPath) { window.location.href = newPath; } } }, switchLanguage(targetLocale) { console.log('Switching language to:', targetLocale); console.log('Audio object:', this.audio); // Play sound effect if (this.audio) { this.audio.currentTime = 0; console.log('Attempting to play sound...'); this.audio.play().then(() => { console.log('Sound playing successfully'); // Navigate after sound starts playing setTimeout(() => { // Save the language preference localStorage.setItem('preferredLocale', targetLocale); // Get the current path and convert it to the target language const currentPath = window.location.pathname; const newPath = this.getLocalizedPath(currentPath, targetLocale); // Navigate to the new path window.location.href = newPath; }, 300); // Increased delay to hear the sound better }).catch(e => { console.error('Audio play failed:', e); console.error('Error details:', e.message, e.name); // If audio fails, navigate immediately localStorage.setItem('preferredLocale', targetLocale); const currentPath = window.location.pathname; const newPath = this.getLocalizedPath(currentPath, targetLocale); window.location.href = newPath; }); } else { console.log('No audio object available'); // If no audio, navigate immediately localStorage.setItem('preferredLocale', targetLocale); const currentPath = window.location.pathname; const newPath = this.getLocalizedPath(currentPath, targetLocale); window.location.href = newPath; } this.open = false; }, getLocalizedPath(currentPath, targetLocale) { // Build URL mapping from pages data const urlMap = {}; // Create bidirectional mapping between URLs this.pageMappings.forEach(page => { if (page.translations.en && page.translations.it) { const enUrl = page.translations.en.url; const itUrl = page.translations.it.url; // Map English to Italian urlMap[enUrl] = { it: itUrl, en: enUrl }; // Map Italian to English urlMap[itUrl] = { it: itUrl, en: enUrl }; } }); // Handle special case for /en/ path (redirect to /) if (currentPath === '/en/') { return targetLocale === 'it' ? '/it/' : '/'; } // Look up the current path in our mapping const mapping = urlMap[currentPath]; if (mapping && mapping[targetLocale]) { return mapping[targetLocale]; } // If no mapping found, return current path return currentPath; } } } </script> <!-- Language Persistence Script for Non-Localized Pages --> <script> // Check if user has a language preference and redirect if there's a localized version document.addEventListener('DOMContentLoaded', function() { const savedLocale = localStorage.getItem('preferredLocale'); const currentPath = window.location.pathname; // Don't auto-redirect the homepage to preserve user choice if (currentPath === '/') { return; } // Only redirect if user has a saved preference that's not English (default) if (savedLocale && savedLocale === 'it') { // Map of regular pages to their Italian equivalents const italianPages = { '/about/': '/it/chi-sono/', // Add more mappings as you create Italian versions of pages }; // Check if current page has an Italian version if (italianPages[currentPath]) { window.location.href = italianPages[currentPath]; } } // If user prefers English and is on an Italian page, redirect to English equivalent if (savedLocale === 'en' || !savedLocale) { const englishPages = { '/it/chi-sono/': '/about/', // Add more mappings as you create Italian versions of pages }; if (englishPages[currentPath]) { window.location.href = englishPages[currentPath]; } } }); </script> </body> </html>