id 0!==r?a.value=r:n?a.get=n:i&&(a.set=i);try{let t=o({context:u,property:e,...a,enumerable:c});p[e]=t}catch(r){if(r instanceof TypeError)try{p[e]=t.value||t.get||t.set}catch{}else throw r}}}});let d={originalObject:u,originalProperties:p};if(!a&&u?.prototype!==void 0){let e=c({context:u,property:"prototype",propertiesToExclude:s,skipPrototype:!0});e instanceof Error||(d.originalPrototype=e?.originalObject,d.originalPrototypeProperties=e?.originalProperties)}return o({context:t,property:r,value:u,enumerable:f?.enumerable}),d}function a(e,t){let r=(t||globalThis)[e],n=l(t||globalThis,e);return r&&n&&(n.writable||n.configurable)?(Object.freeze(r),o({context:globalThis,property:e,value:r})):r}function l(e,t){if(!(!e||!t))try{return Reflect.getOwnPropertyDescriptor(e,t)}catch{return}}function s(e){if("string"!=typeof e)return e;try{return decodeURIComponent(e).toLowerCase().trim()}catch{return e.toLowerCase().trim()}}function u(e,t){return e instanceof Headers?e.forEach((r,o)=>{p(o,t)||e.delete(o)}):Object.keys(e).forEach(r=>{p(r,t)||delete e[r]}),e}function p(e,t){return!t.has(s(e)||"")}function f(e,t){let r=!0,o=s(function(e){let t,r;if(globalThis.Request&&e instanceof Request)t=e.url;else if("function"==typeof e?.toString)t=e.toString();else throw Error("Unsupported type for url");try{return new URL(t).pathname}catch{return(r=t.replace(/#.+/gi,"").split("?").shift()).startsWith("/")?r:`/${r}`}}(e));return o&&t.some(e=>o.includes(e))&&(r=!1),r}performance.mark("overrideGlobals started");let{experiments:d}=window.viewerModel,y=d["specs.thunderbolt.securityExperiments"];try{let e,t,r,n,i,l=globalThis.open,h=document.open;function b(e,t,r){var o;let n="string"!=typeof e,i=l.call(window,e,t,r);return n||e&&((o=e).startsWith("//")&&/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/g.test(`${location.protocol}:${o}`)&&(o=`${location.protocol}${o}`),!o.startsWith("http")||new URL(o).hostname===location.hostname)?{}:i}o({property:"open",value:b,context:globalThis,enumerable:!0}),o({property:"open",value:function(e,t,r){return e?b(e,t,r):h.call(document,e||"",t||"",r||"")},context:document,enumerable:!0}),y&&(e=document.createElement,t=Element.prototype.setAttribute,r=Element.prototype.setAttributeNS,o({property:"createElement",context:document,value:function(n,i){let c=e.call(document,n,i);return"iframe"===s(n)&&(o({property:"srcdoc",context:c,get:()=>"",set:()=>{console.warn("`srcdoc` is not allowed in iframe elements.")}}),c.setAttribute=function(e,r){"srcdoc"===e.toLowerCase()?console.warn("`srcdoc` attribute is not allowed to be set."):t.call(c,e,r)},c.setAttributeNS=function(e,t,o){"srcdoc"===t.toLowerCase()?console.warn("`srcdoc` attribute is not allowed to be set."):r.call(c,e,t,o)}),c},enumerable:!0})),d["specs.thunderbolt.hardenFetchAndXHR"]&&y&&function(e,t,r){let n=fetch,i=XMLHttpRequest,c=new Set(t);function a(){let t=new i,o=t.open,n=t.setRequestHeader;return t.open=function(){let n=Array.from(arguments),i=n[1];if(n.length<2||f(i,e))return o.apply(t,n);throw Error(r||`Request not allowed for path ${i}`)},t.setRequestHeader=function(e,r){p(decodeURIComponent(e),c)&&n.call(t,e,r)},t}o({property:"fetch",value:function(){var t;let o=(t=arguments,globalThis.Request&&t[0]instanceof Request&&t[0]?.headers?u(t[0].headers,c):t[1]?.headers&&u(t[1].headers,c),t);return f(arguments[0],e)?n.apply(globalThis,Array.from(o)):new Promise((e,t)=>{let o=Error(r||`Request not allowed for path ${arguments[0]}`);t(o)})},enumerable:!0}),o({property:"XMLHttpRequest",value:a,enumerable:!0}),Object.keys(i).forEach(e=>{a[e]=i[e]})}(["/_api/v1/access-tokens","/_api/v2/dynamicmodel","/_api/one-app-session-web/v3/businesses"],["client-binding"]),function(){if(navigator&&"serviceWorker"in navigator)navigator.serviceWorker.register,o({context:navigator.serviceWorker,property:"register",value:function(){console.log("Service worker registration is not allowed")},enumerable:!0})}(),n=[],i=(i=[]).concat(["TextEncoder","TextDecoder"]),y&&(i=i.concat(["XMLHttpRequestEventTarget","EventTarget"])),i=i.concat(["URL","JSON"]),y&&(n=n.concat(["addEventListener","removeEventListener"])),n=n.concat(["encodeURI","encodeURIComponent","decodeURI","decodeURIComponent"]),i=i.concat(["String","Number"]),y&&i.push("Object"),i=i.concat(["Reflect"]),n.forEach(e=>{a(e),["addEventListener","removeEventListener"].includes(e)&&a(e,document)}),i.forEach(e=>{c({property:e})}),y&&function(){return e("setTimeout",0,globalThis),e("setInterval",0,globalThis);function e(e,t,r){let n=r||globalThis,i=n[e];if(!i||"function"!=typeof i)throw Error(`Function ${e} not found or is not a function`);o({property:e,value:function(){let r=Array.from(arguments);if("string"!=typeof r[t])return i.apply(n,r);console.warn(`Calling ${e} with a String Argument at index ${t} is not allowed`)},context:r,enumerable:!0})}}()}catch(t){window?.viewerModel?.mode.debug&&console.error(t);let e=Error("TB006");window.fedops?.reportError(e,"security_overrideGlobals"),window.Sentry?window.Sentry.captureException(e):globalThis.defineStrictProperty("sentryBuffer",[e],window,!1)}performance.mark("overrideGlobals ended")})();
//# sourceMappingURL=overrideGlobals.inline.306e90d8.bundle.min.js.map
Homeowners undertaking extensions, renovations, or refurbishments
Clients requiring cost plans for lending or funding purposes
Architects seeking independent cost advice
Homeowners involved in disputes or stalled projects
Clients who want clarity before committing to construction
If you value clear thinking, proper documentation, and independent advice, this will be a good fit.
Projects Completed
500+
Built From Experience, Not Theory
My background includes hands-on construction and restoration work, operating trade and construction businesses, residential project delivery across multiple markets, and formal training in quantity surveying.
Understand construction practically
Identify risk early
Communicate clearly with contractors
Translate drawings into realistic costs
POSITIONING
Independent by Design
Independent advice that protects your budget — before you build.
My role is to:
Establish realistic costs
Define scope clearly
Reduce risk before work begins
Support informed decision-making
This independence allows me to act solely in your interest — without pressure, commission, or sales incentives.
SIMPLE PROCESS
How the Process Works
While each project is different, the approach is consistent. There is no upselling, no unnecessary meetings, and no pressure to proceed beyond what makes sense.
01
Review
Review drawings, scope, or existing information
02
Clarify
Clarify what is included and excluded
03
Document
Prepare clear cost documentation
04
Support
Support decisions with objective analysis
Services
Services may include:
Pre-construction cost plans
Budget advice for lending
Tender documentation and analysis
Pre-construction cost plans
Dispute and cost clarity support
Details and fees are discussed only once the nature of the project is understood.
If you believe professional cost clarity would be useful for your project, the next step is straightforward.
You can make contact with a brief outline of your project and the information you currently have available. I will confirm whether I can assist and what the appropriate scope would be.
If you'd like to explore whether this service suits your project: