Positioned along one of Paradise Valley's most prestigious enclaves, this privately gated 1.1-acre estate showcases uninterrupted panoramic views of Camelback Mountain, including the iconic Praying Monk. Designed to maximize natural light, volume, and seamless indoor-outdoor living, the residence offers a refined blend of modern elegance and resort-style amenities. The main home features five spacious bedrooms, 5.5 bathrooms, and a versatile bonus room ideal for a home office, gym, or studio. A detached guest house provides two bedrooms, 2.5 bathrooms, a full kitchen, and private laundry--perfect for extended stays or hosting with complete independence. Inside, soaring ceilings, expansive walls of glass, and wide-plank oak flooring create a bright, open atmosphere. The great room serves as the centerpiece, highlighted by dramatic sliding glass doors and a sleek marble fireplace, effortlessly connecting to the outdoor living spaces. The open-concept kitchen, dining, and living areas are designed for both everyday living and elevated entertaining. The chef's kitchen is equipped with premium Wolf and Sub-Zero appliances, a gas range, dual ovens and dishwashers, built-in coffee and ice makers, and a striking climate-controlled wine wall. The primary suite offers a serene retreat with tranquil views and private access to the backyard, along with a spa-inspired bathroom featuring a sculptural stone soaking tub, oversized steam shower, dual vanities, custom wood cabinetry with abundant storage, and a private water closet. Outdoors, the showstopping custom pool and spa include an extended lap lane, surrounded by multiple lounging and dining areas, fire features, and a covered steel-and-wood patio with a fully equipped outdoor kitchen. Added amenities include a pickleball court and putting green. Additional highlights include a six-car garage and a prime location just minutes from Arizona's premier resorts, spas, fine dining, and shopping.
Save
Ask
Tour
Hide
Share
Listing Snapshot
Price
$13,000,000
Days On Site
32 Days
Bedrooms
7
Inside Area (SqFt)
9,550 sqft
Total Baths
9
Full Baths
7
Partial Baths
2
Lot Size
1.1 Acres
Year Built
2025
MLS® Number
7010266
Status
Active
Property Tax
$19,869
HOA/Condo/Coop Fees
N/A
Sq Ft Source
Owner
Friends & Family
React
Invite
Recent Activity
6 days ago
Listing updated with changes from the MLS®
a month ago
Listing first seen on site
General Features
Acres
1.1
Cross Street
McDonald & Casa Blanca South
Disclosures
Agency Discl ReqSeller Discl Avail
Garage
Yes
Garage Spaces
6
Land Lease
No
Levels
Two
Number Of Stories
2
Parking
GatedGarage Door OpenerDirect AccessCircular DrivewayElectric Vehicle Charging Station(s)
Listing courtesy of Local Luxury Christie's International Real Estate.
All information should be verified by the recipient and none is guaranteed as accurate by ARMLS. Copyright 2026 Arizona Regional Multiple Listing Service, Inc. All rights reserved.
Last checked: 2026-05-10 10:44 AM UTC
Neighborhood & Commute
Source: Walkscore
Disclosure: Community information and market data powered by Constellation Data Labs. Information is deemed reliable but not guaranteed.
document.addEventListener('DOMContentLoaded', function() {
var lastData = null;
function v(id) { var el = document.getElementById(id); return el ? (parseFloat(el.value) || 0) : 0; }
function vs(id) { var el = document.getElementById(id); return el ? (el.value || '') : ''; }
function fmt(n, dec) { dec=dec||0; if(isNaN(n)||!isFinite(n)) return '—'; return n.toLocaleString('en-US',{minimumFractionDigits:dec,maximumFractionDigits:dec}); }
function fmtPct(n) { return (isNaN(n)||!isFinite(n)) ? '—' : n.toFixed(1)+'%'; }
function fmtD(n) { if(isNaN(n)||!isFinite(n)) return '—'; return (n<0?'-$':'$')+fmt(Math.abs(Math.round(n))); }
function cfTdClass(n){ return n>=200?'td-good':n>=0?'td-warn':'td-bad'; }
// ── IRR: multi-seed Newton's method ──
function calcIRR(cashFlows) {
var TOLERANCE = 1e-7, MAX_ITER = 150;
function npvAt(rate) {
var n = 0;
for (var t = 0; t < cashFlows.length; t++) n += cashFlows[t] / Math.pow(1 + rate, t);
return n;
}
function dnpvAt(rate) {
var d = 0;
for (var t = 1; t < cashFlows.length; t++) d += -t * cashFlows[t] / Math.pow(1 + rate, t + 1);
return d;
}
function tryNewton(seed) {
var rate = seed;
for (var i = 0; i < MAX_ITER; i++) {
var n = npvAt(rate), d = dnpvAt(rate);
if (Math.abs(d) < 1e-14) return null;
var next = rate - n / d;
if (next < -0.9999) next = -0.9999;
if (Math.abs(next - rate) < TOLERANCE) return isFinite(next) ? next : null;
rate = next;
}
return null;
}
var seeds = [0.10, 0.0, -0.10, 0.25, 0.50, -0.30, 0.01];
var best = null;
for (var s = 0; s < seeds.length; s++) {
var r = tryNewton(seeds[s]);
if (r !== null && isFinite(r) && Math.abs(npvAt(r)) < 1.0) {
if (best === null || Math.abs(r - 0.08) < Math.abs(best - 0.08)) best = r;
}
}
return best !== null ? best * 100 : NaN;
}
// ── Core year calculator ──
function calcYear(yr, params) {
var rent = params.baseRent * Math.pow(1 + params.rentGrowth, yr - 1);
var otherInc = params.baseOther * Math.pow(1 + params.rentGrowth, yr - 1);
var grossInc = rent + otherInc;
var effInc = grossInc * (1 - params.vacancy);
var taxes = params.baseTaxes * Math.pow(1.02, yr - 1);
var insurance = params.baseInsurance * Math.pow(1.03, yr - 1);
var hoa = params.baseHoa * Math.pow(1.02, yr - 1);
var mgmtCost = effInc * params.mgmtPct;
var capexCost = effInc * params.capexPct;
var maintCost = effInc * params.maintPct;
var otherCosts= params.baseOtherCosts * Math.pow(1.02, yr - 1);
var totalOpEx = taxes + insurance + hoa + mgmtCost + capexCost + maintCost + otherCosts;
var noi = effInc - totalOpEx;
var cashFlow = noi - params.pi;
return { rent:rent, grossInc:grossInc, effInc:effInc,
taxes:taxes, insurance:insurance, hoa:hoa,
mgmtCost:mgmtCost, capexCost:capexCost, maintCost:maintCost,
otherCosts:otherCosts, totalOpEx:totalOpEx, noi:noi, cashFlow:cashFlow };
}
// ── Analyze ──
function praAnalyze() {
var price = v('pra-price');
var rent = v('pra-rent');
var taxes = v('pra-taxes');
var ins = v('pra-insurance');
var missing = [];
if (!price) missing.push('Purchase price');
if (!rent) missing.push('Monthly gross rent');
if (!taxes) missing.push('Property taxes');
if (!ins) missing.push('Insurance');
if (missing.length) { alert('Please fill in the required fields:\n\n• ' + missing.join('\n• ')); return; }
var rawDown = v('pra-downPct');
var rawRate = v('pra-rate');
var termMo = v('pra-term') * 12;
var downPct = rawDown / 100;
var rentRatio = (rent / price) * 100;
if (rawDown < 3.5 && rawDown > 0) {
alert('Warning: A down payment below 3.5% is below minimum conventional lending thresholds. Results may not reflect a financeable deal. Proceeding with entered value.');
}
if (rentRatio > 1.5) {
alert('Warning: Rent-to-price ratio of ' + rentRatio.toFixed(2) + '% is above 1.5% — unusually high for Phoenix SFR. Please verify rent and price inputs before proceeding.');
}
var rehab = v('pra-rehab');
var downAmt = price * downPct;
var loanAmt = price * (1 - downPct);
var closing = v('pra-closing');
var totalCash = downAmt + closing + rehab;
var pi;
var mRate;
if (rawRate === 0) {
pi = loanAmt / termMo;
mRate = 0;
} else {
mRate = rawRate / 100 / 12;
pi = loanAmt * (mRate * Math.pow(1 + mRate, termMo)) / (Math.pow(1 + mRate, termMo) - 1);
}
var yearBuilt = v('pra-yearBuilt') || 2000;
var holdYears = v('pra-holdPeriod');
var appreciation = v('pra-appreciation') / 100;
var sellCostPct = v('pra-sellCost') / 100;
var ltcgRate = v('pra-taxRate') / 100;
var RECAPTURE_RATE = 0.25;
var landPct = 0.20;
var deprBasis = price * (1 - landPct);
var annualDepr = deprBasis / 27.5;
var params = {
baseRent: rent,
baseOther: v('pra-otherIncome'),
vacancy: v('pra-vacancy') / 100,
rentGrowth: v('pra-rentGrowth') / 100,
baseTaxes: taxes,
baseInsurance: ins,
baseHoa: v('pra-hoa'),
mgmtPct: v('pra-mgmt') / 100,
capexPct: v('pra-capex') / 100,
maintPct: v('pra-maint') / 100,
baseOtherCosts: v('pra-other-costs'),
pi: pi,
};
var yr1 = calcYear(1, params);
var capRate = (yr1.noi * 12) / price * 100;
var coC = totalCash > 0 ? (yr1.cashFlow * 12) / totalCash * 100 : 0;
var dscr = pi > 0 ? yr1.noi / pi : Infinity;
var grm = rent > 0 ? price / (rent * 12) : 0;
var balance = loanAmt;
var projRows = [], cumCF = 0, cumDepr = 0;
var irrCFpre = [-totalCash];
var irrCFpost = [-totalCash];
for (var yr = 1; yr <= holdYears; yr++) {
var yd = calcYear(yr, params);
var yearCF = yd.cashFlow * 12;
cumCF += yearCF;
cumDepr += annualDepr;
var yearEndBal = balance;
for (var m = 0; m < 12; m++) {
if (mRate === 0) { yearEndBal -= pi; }
else { yearEndBal -= (pi - yearEndBal * mRate); }
}
var principalPaid = balance - Math.max(yearEndBal, 0);
balance = Math.max(yearEndBal, 0);
var propVal = price * Math.pow(1 + appreciation, yr);
var equity = propVal - balance;
var grossProc = propVal * (1 - sellCostPct);
var netProc = grossProc - balance;
var adjBasis = price + closing - cumDepr;
var totalGain = Math.max(grossProc - adjBasis, 0);
var recapPortion = Math.min(cumDepr, totalGain);
var ltcgPortion = Math.max(totalGain - recapPortion, 0);
var recaptureTax = recapPortion * RECAPTURE_RATE;
var ltcgTax = ltcgPortion * ltcgRate;
var totalTaxOwed = recaptureTax + ltcgTax;
var netAfterTax = netProc - totalTaxOwed;
var totalReturnPreTax = cumCF + netProc;
var totalReturnAfterTax = cumCF + netAfterTax;
var roiPreTax = totalCash > 0 ? (totalReturnPreTax / totalCash) * 100 : 0;
var roiAfterTax = totalCash > 0 ? (totalReturnAfterTax / totalCash) * 100 : 0;
var annROIpre = (Math.pow(1 + roiPreTax / 100, 1 / yr) - 1) * 100;
var annROIpost = (Math.pow(1 + roiAfterTax / 100, 1 / yr) - 1) * 100;
irrCFpre.push(yearCF + (yr === holdYears ? netProc : 0));
irrCFpost.push(yearCF + (yr === holdYears ? netAfterTax : 0));
projRows.push({
yr:yr, rent:yd.rent, grossInc:yd.grossInc, effInc:yd.effInc,
totalOpEx:yd.totalOpEx, noi:yd.noi, cashFlow:yd.cashFlow,
yearCF:yearCF, cumCF:cumCF, principalPaid:principalPaid,
balance:balance, propVal:propVal, equity:equity,
netProc:netProc, netAfterTax:netAfterTax,
recaptureTax:recaptureTax, ltcgTax:ltcgTax, totalTaxOwed:totalTaxOwed,
ltcgPortion:ltcgPortion, recapturePortion:recapPortion,
totalReturnPreTax:totalReturnPreTax, totalReturnAfterTax:totalReturnAfterTax,
roiPreTax:roiPreTax, roiAfterTax:roiAfterTax,
annROIpre:annROIpre, annROIpost:annROIpost,
cumDepr:cumDepr, adjBasis:adjBasis
});
}
var irrPre = calcIRR(irrCFpre);
var irrPost = calcIRR(irrCFpost);
var stressVacancies = [0, 0.05, 0.10];
var stressResults = stressVacancies.map(function(vac) {
var sp = {};
for (var k in params) sp[k] = params[k];
sp.vacancy = vac;
return calcYear(1, sp);
});
lastData = {
address:vs('pra-address'), price:price, downAmt:downAmt, loanAmt:loanAmt,
closing:closing, rehab:rehab, totalCash:totalCash, pi:pi, yearBuilt:yearBuilt,
yr1:yr1, capRate:capRate, coC:coC, dscr:dscr, grm:grm,
annualDepr:annualDepr, deprBasis:deprBasis, landPct:landPct,
holdYears:holdYears, projRows:projRows,
irrPre:irrPre, irrPost:irrPost,
stressResults:stressResults, params:params,
ltcgRate:ltcgRate, mRate:mRate, sqft:v('pra-sqft')
};
praRender(lastData);
}
// ── Render ──
function praRender(d) {
var res = document.getElementById('pra-results');
res.style.display = 'block';
res.scrollIntoView({behavior:'smooth', block:'start'});
document.getElementById('pra-address-line').textContent = d.address || '';
var flags=[], score=0;
var cf=d.yr1.cashFlow, cr=d.capRate, co=d.coC, ds=d.dscr, gr=d.grm;
var ageYrs = new Date().getFullYear() - d.yearBuilt;
var negativeCF = cf < 0;
if(cf>=200){score+=2;flags.push({t:'good',msg:'Positive cash flow: '+fmtD(cf)+'/mo in Year 1 — covers expenses with margin'});}
else if(cf>=0){score+=1;flags.push({t:'warn',msg:'Breakeven cash flow: '+fmtD(cf)+'/mo in Year 1 — no buffer for surprises'});}
else{score-=2;flags.push({t:'bad',msg:'Negative cash flow: '+fmtD(cf)+'/mo in Year 1 — you are feeding this property every single month'});}
if(cr>=6){score+=2;flags.push({t:'good',msg:'Cap rate '+fmtPct(cr)+' — strong income return relative to price'});}
else if(cr>=4){score+=1;flags.push({t:'warn',msg:'Cap rate '+fmtPct(cr)+' — acceptable, but thin margin if expenses rise'});}
else{flags.push({t:'bad',msg:'Cap rate '+fmtPct(cr)+' — appreciation-dependent play; income alone does not carry this deal'});}
if(!isFinite(ds)){flags.push({t:'good',msg:'No debt — DSCR not applicable (all-cash purchase)'});score+=1;}
else if(ds>=1.25){score+=1;flags.push({t:'good',msg:'DSCR '+ds.toFixed(2)+' — NOI comfortably covers debt service'});}
else if(ds>=1.0){flags.push({t:'warn',msg:'DSCR '+ds.toFixed(2)+' — income barely covers debt; any vacancy could flip this negative'});}
else{score-=1;flags.push({t:'bad',msg:'DSCR '+ds.toFixed(2)+' — NOI does not cover debt service; lender risk flag'});}
if(co>=8){score+=1;flags.push({t:'good',msg:'Cash-on-cash '+fmtPct(co)+' — strong return on invested capital'});}
else if(co>=4){flags.push({t:'warn',msg:'Cash-on-cash '+fmtPct(co)+' — modest; compare against alternative capital deployments'});}
else{score-=1;flags.push({t:'bad',msg:'Cash-on-cash '+fmtPct(co)+' — weak Year 1 return on invested capital'});}
if(gr<=14){score+=1;flags.push({t:'good',msg:'GRM '+gr.toFixed(1)+' — price is reasonable relative to rental income for Phoenix SFR'});}
else if(gr<=18){flags.push({t:'warn',msg:'GRM '+gr.toFixed(1)+' — in the upper range for Phoenix; rent growth needed to justify price'});}
else{flags.push({t:'bad',msg:'GRM '+gr.toFixed(1)+' — price is expensive relative to rent; appreciation must do heavy lifting'});}
if(!isNaN(d.irrPre)){
if(d.irrPre>=12){score+=1;flags.push({t:'good',msg:'Pre-tax IRR '+fmtPct(d.irrPre)+' — strong risk-adjusted return over hold period'});}
else if(d.irrPre>=7){flags.push({t:'warn',msg:'Pre-tax IRR '+fmtPct(d.irrPre)+' — acceptable but below typical investor hurdle of 10–12%'});}
else{score-=1;flags.push({t:'bad',msg:'Pre-tax IRR '+fmtPct(d.irrPre)+' — low total return; capital likely better deployed elsewhere'});}
}
var lastProjRow = d.projRows[d.projRows.length-1];
if(lastProjRow && lastProjRow.netProc < 0){
score-=2;
flags.push({t:'bad',msg:'Net sale proceeds are negative at exit ('+fmtD(lastProjRow.netProc)+') — loan balance exceeds sale price after selling costs. You cannot exit this deal without bringing cash to the table.'});
}
if(ageYrs>=20){flags.push({t:'warn',msg:'Property is '+ageYrs+' years old — HVAC, roof, and water heater replacement cycles are near-term risks; verify CapEx reserve is adequate'});}
else if(ageYrs>=10){flags.push({t:'warn',msg:'Property is '+ageYrs+' years old — mid-cycle on major systems; review CapEx reserve adequacy'});}
else if(d.yearBuilt>1990){flags.push({t:'good',msg:'Property is '+ageYrs+' years old — newer build reduces near-term CapEx risk'});}
var verdict, vClass, vSub;
var lastPR2 = d.projRows[d.projRows.length-1];
var negProc = lastPR2 && lastPR2.netProc < 0;
if(negProc){
verdict='No-Go'; vClass='pra-verdict-no';
vSub='Loan balance exceeds sale price at exit ('+fmtD(lastPR2.netProc)+'). You cannot sell this property at the end of your hold period without bringing cash to the closing table.';
} else if(negativeCF){
verdict='Proceed with Caution'; vClass='pra-verdict-maybe';
vSub='Negative cash flow means you pay to own this property every month. This is a pure appreciation bet — only acceptable with a very strong Phoenix market conviction and reserves to sustain losses.';
} else if(score>=7){verdict='Strong Go';vClass='pra-verdict-go';vSub='Multiple metrics align. This property earns its place in a long-term portfolio.';}
else if(score>=5){verdict='Go with Eyes Open';vClass='pra-verdict-go';vSub='Solid fundamentals with areas to monitor. Negotiate or improve terms before closing.';}
else if(score>=2){verdict='Proceed with Caution';vClass='pra-verdict-maybe';vSub='This deal leans on appreciation more than income. Acceptable only if your Phoenix market thesis is strong.';}
else{verdict='No-Go';vClass='pra-verdict-no';vSub='Numbers do not support a long-term hold at this price and terms. Walk or renegotiate significantly.';}
document.getElementById('pra-verdict').className='pra-verdict '+vClass;
document.getElementById('pra-verdict-label').textContent=verdict;
document.getElementById('pra-verdict-sub').textContent=vSub;
var lastRow = d.projRows[d.projRows.length-1];
var metrics=[
{label:'Year 1 cash flow/mo', value:fmtD(cf), flag:cf>=200?'good':cf>=0?'warn':'bad'},
{label:'Cash-on-cash Yr 1', value:fmtPct(co), flag:co>=8?'good':co>=4?'warn':'bad'},
{label:'Cap rate', value:fmtPct(cr), flag:cr>=6?'good':cr>=4?'warn':'bad'},
{label:'DSCR', value:isFinite(ds)?ds.toFixed(2):'N/A', flag:isFinite(ds)&&ds>=1.25?'good':isFinite(ds)&&ds>=1.0?'warn':'bad'},
{label:'IRR (pre-tax)', value:fmtPct(d.irrPre), flag:d.irrPre>=12?'good':d.irrPre>=7?'warn':'bad'},
{label:'IRR (after-tax)', value:fmtPct(d.irrPost), flag:d.irrPost>=8?'good':d.irrPost>=4?'warn':'bad'},
{label:'Total cash in', value:fmtD(d.totalCash), flag:'neut'},
{label:'Equity at exit', value:fmtD(lastRow.equity), flag:'neut'},
];
document.getElementById('pra-metrics').innerHTML=metrics.map(function(m){
return '
';
}).join('');
var stressLabels=['0% vacancy (best case)','5% vacancy (base case)','10% vacancy (stress)'];
document.getElementById('pra-stress-grid').innerHTML=d.stressResults.map(function(s,i){
var cfClass=s.cashFlow>=200?'clr-good':s.cashFlow>=0?'clr-warn':'clr-bad';
var dscr2 = d.pi>0 ? s.noi/d.pi : Infinity;
return '
'+
'
'+stressLabels[i]+'
'+
'
Monthly CF'+fmtD(s.cashFlow)+'
'+
'
Annual CF'+fmtD(s.cashFlow*12)+'
'+
'
NOI/mo'+fmtD(s.noi)+'
'+
'
DSCR'+(isFinite(dscr2)?dscr2.toFixed(2):'N/A')+'
'+
'
';
}).join('');
document.getElementById('pra-depr-note').innerHTML=
'Depreciation note — Estimated annual depreciation: '+fmtD(d.annualDepr)+' '+
'(assumes '+Math.round(d.landPct*100)+'% land value; '+Math.round((1-d.landPct)*100)+'% improvement basis ÷ 27.5 years). '+
'Land allocation is an assumption — actual basis depends on your purchase allocation. '+
'At exit, accumulated depreciation is subject to 25% recapture tax, separate from long-term capital gains. '+
'Consult your CPA on actual depreciation basis, cost segregation opportunities, and recapture planning.';
document.getElementById('pra-tab-cashflow').innerHTML='
* Simple annualized ROI does not account for time value of money. True IRR (shown in Key Metrics above) is the accurate measure. ⚠ = negative net proceeds.
Recapture tax applies to accumulated depreciation at 25%. LTCG tax applies to remaining gain. Consult your CPA — a 1031 exchange eliminates both at exit.
';
}
// ── Tab switching ──
function praSwitchTab(name) {
document.querySelectorAll('.pra-tab').forEach(function(t){ t.classList.remove('active'); });
document.querySelectorAll('.pra-tab-content').forEach(function(t){ t.classList.remove('active'); });
var btn = document.getElementById('pra-tab-btn-' + name);
if (btn) btn.classList.add('active');
var content = document.getElementById('pra-tab-' + name);
if (content) content.classList.add('active');
}
// ── Reset ──
function praReset() {
document.getElementById('pra-results').style.display = 'none';
lastData = null;
window.scrollTo({top: 0, behavior: 'smooth'});
}
// ── PDF Export ──
function praExportPDF() {
if (!lastData) return;
var d = lastData;
var jsPDF = window.jspdf ? window.jspdf.jsPDF : null;
if (!jsPDF) { alert('PDF library not loaded. Please refresh the page and try again.'); return; }
var doc = new jsPDF({unit:'pt', format:'letter'});
var pw = doc.internal.pageSize.getWidth();
var ph = doc.internal.pageSize.getHeight();
var mg = 48, cw = pw - mg*2, y = 0;
function newPage() {
doc.addPage(); y = 0;
doc.setFillColor('#1a2332'); doc.rect(0,0,pw,28,'F');
doc.setFont('helvetica','bold'); doc.setFontSize(7); doc.setTextColor('#c8a96e');
doc.text('CAPSTONE REALTY PROFESSIONALS | PROPERTY INVESTMENT ANALYSIS',mg,18);
y = 44;
}
function checkPage(needed) { if (y + needed > ph - 40) newPage(); }
function hRule(w, color) { doc.setDrawColor(color||'#1a2332'); doc.setLineWidth(w||1); doc.line(mg,y,pw-mg,y); y+=(w>=1.5?12:8); }
function sTitle(txt) {
checkPage(28); y+=8;
doc.setFont('helvetica','bold'); doc.setFontSize(7); doc.setTextColor('#c8a96e');
doc.text(txt.toUpperCase(),mg,y); y+=4; hRule(0.5,'#e2e0db');
}
function kv(lbl, val, valColor) {
checkPage(16);
doc.setFont('helvetica','normal'); doc.setFontSize(9); doc.setTextColor('#4a5568'); doc.text(lbl,mg,y);
doc.setFont('helvetica','bold'); doc.setTextColor(valColor||'#1a2332'); doc.text(String(val),pw-mg,y,{align:'right'});
y+=16;
}
doc.setFillColor('#1a2332'); doc.rect(0,0,pw,60,'F');
doc.setFont('helvetica','bold'); doc.setFontSize(18); doc.setTextColor('#ffffff');
doc.text('Property Investment Analysis',mg,32);
doc.setFont('helvetica','normal'); doc.setFontSize(8); doc.setTextColor('#c8a96e');
doc.text('Capstone Realty Professionals | capstonerealtypros.com | 602-354-4660',mg,48);
y = 76;
doc.setFont('helvetica','bold'); doc.setFontSize(12); doc.setTextColor('#1a2332');
doc.text(d.address||'Address not provided',mg,y);
doc.setFont('helvetica','normal'); doc.setFontSize(8); doc.setTextColor('#4a5568');
doc.text('Generated '+new Date().toLocaleDateString('en-US',{year:'numeric',month:'long',day:'numeric'}),pw-mg,y,{align:'right'});
y+=8; hRule(2);
var cf=d.yr1.cashFlow, cr=d.capRate, co=d.coC, ds=d.dscr, sc=0;
var negCF=cf<0;
if(cf>=200)sc+=2;else if(cf>=0)sc+=1;else sc-=2;
if(cr>=6)sc+=2;else if(cr>=4)sc+=1;
if(isFinite(ds)&&ds>=1.25)sc+=1;else if(isFinite(ds)&&ds<1)sc-=1;
if(co>=8)sc+=1;else if(co<4)sc-=1;
if(d.grm<=14)sc+=1;
if(!isNaN(d.irrPre)){if(d.irrPre>=12)sc+=1;else if(d.irrPre<7)sc-=1;}
var lastPR=d.projRows[d.projRows.length-1];
if(lastPR&&lastPR.netProc<0)sc-=2;
var vLabel,vColor,vBg,vSub;
if(lastPR&&lastPR.netProc<0){vLabel='NO-GO';vColor='#8a2020';vBg='#fdf0f0';vSub='Loan balance exceeds sale price at exit — you cannot sell without bringing cash to closing.';}
else if(negCF){vLabel='PROCEED WITH CAUTION';vColor='#8a5e1a';vBg='#fdf5e6';vSub='Negative cash flow — you pay to own this property monthly. Pure appreciation bet.';}
else if(sc>=7){vLabel='STRONG GO';vColor='#2d6a2d';vBg='#edf6ed';vSub='Multiple metrics align. This property earns its place in a long-term portfolio.';}
else if(sc>=5){vLabel='GO WITH EYES OPEN';vColor='#2d6a2d';vBg='#edf6ed';vSub='Solid fundamentals with areas to monitor. Negotiate terms before closing.';}
else if(sc>=2){vLabel='PROCEED WITH CAUTION';vColor='#8a5e1a';vBg='#fdf5e6';vSub='Leans on appreciation more than income. Acceptable only with strong market thesis.';}
else{vLabel='NO-GO';vColor='#8a2020';vBg='#fdf0f0';vSub='Numbers do not support a long-term hold. Walk or renegotiate significantly.';}
doc.setFillColor(vBg); doc.roundedRect(mg,y,cw,54,3,3,'F');
doc.setDrawColor(vColor); doc.setLineWidth(4); doc.line(mg,y,mg,y+54);
y+=16; doc.setFont('helvetica','bold'); doc.setFontSize(13); doc.setTextColor(vColor); doc.text(vLabel,mg+12,y);
y+=14; doc.setFont('helvetica','normal'); doc.setFontSize(8.5); doc.setTextColor(vColor); doc.text(vSub,mg+12,y,{maxWidth:cw-20});
y+=30;
sTitle('Key metrics');
var met=[
{l:'Year 1 monthly cash flow',v:fmtD(cf),c:cf>=200?'#2d6a2d':cf>=0?'#8a5e1a':'#8a2020'},
{l:'Cash-on-cash (Year 1)',v:fmtPct(co),c:co>=8?'#2d6a2d':co>=4?'#8a5e1a':'#8a2020'},
{l:'Cap rate',v:fmtPct(cr),c:cr>=6?'#2d6a2d':cr>=4?'#8a5e1a':'#8a2020'},
{l:'DSCR',v:isFinite(ds)?ds.toFixed(2):'N/A',c:isFinite(ds)&&ds>=1.25?'#2d6a2d':isFinite(ds)&&ds>=1.0?'#8a5e1a':'#8a2020'},
{l:'IRR (pre-tax)',v:fmtPct(d.irrPre),c:d.irrPre>=10?'#2d6a2d':d.irrPre>=6?'#8a5e1a':'#8a2020'},
{l:'IRR (after-tax)',v:fmtPct(d.irrPost),c:d.irrPost>=8?'#2d6a2d':d.irrPost>=4?'#8a5e1a':'#8a2020'},
];
var mw=cw/3-6;
met.forEach(function(m,i){
var col=i%3, row=Math.floor(i/3);
var mx=mg+col*(mw+9), my=y+row*46;
doc.setFillColor('#f7f7f5'); doc.roundedRect(mx,my,mw,38,2,2,'F');
doc.setFont('helvetica','bold'); doc.setFontSize(6); doc.setTextColor('#4a5568'); doc.text(m.l.toUpperCase(),mx+8,my+12);
doc.setFont('helvetica','bold'); doc.setFontSize(12); doc.setTextColor(m.c); doc.text(m.v,mx+8,my+28);
});
y+=Math.ceil(met.length/3)*46+14;
sTitle('Year 1 income & expense breakdown');
kv('Down payment',fmtD(d.downAmt));
kv('Closing costs',fmtD(d.closing));
if(d.rehab>0) kv('Rehab / initial repairs',fmtD(d.rehab));
kv('Total cash invested',fmtD(d.totalCash));
kv('Gross monthly rent',fmtD(d.yr1.rent));
kv('Effective income after vacancy',fmtD(d.yr1.effInc));
kv('Property taxes',fmtD(d.yr1.taxes));
kv('Insurance',fmtD(d.yr1.insurance));
kv('HOA',fmtD(d.yr1.hoa));
kv('Property management',fmtD(d.yr1.mgmtCost));
kv('CapEx reserve',fmtD(d.yr1.capexCost));
kv('Maintenance reserve',fmtD(d.yr1.maintCost));
kv('Other carrying costs',fmtD(d.yr1.otherCosts));
kv('Net operating income (monthly)',fmtD(d.yr1.noi));
kv('Mortgage P&I',fmtD(d.pi));
kv('Monthly cash flow Year 1',fmtD(cf),cf>=0?'#2d6a2d':'#8a2020');
kv('Annual depreciation (est. — '+Math.round(d.landPct*100)+'% land assumed)',fmtD(d.annualDepr),'#8a5e1a');
sTitle('Vacancy stress test — Year 1');
var stressLbls=['0% vacancy','5% vacancy','10% vacancy'];
d.stressResults.forEach(function(s,i){
kv(stressLbls[i]+' — monthly CF',fmtD(s.cashFlow),s.cashFlow>=200?'#2d6a2d':s.cashFlow>=0?'#8a5e1a':'#8a2020');
});
newPage();
sTitle(d.holdYears+'-year cash flow projection (rent & expenses inflated annually)');
var cfCols=['Yr','Monthly Rent','Eff. Income','Total Expenses','NOI/mo','Monthly CF','Annual CF','Cumulative CF'];
var cfW=[20,76,76,82,68,72,72,88];
doc.setFillColor('#1a2332'); doc.rect(mg,y,cw,18,'F');
var hx2=mg+5;
cfCols.forEach(function(c,i){doc.setFont('helvetica','bold');doc.setFontSize(6.5);doc.setTextColor('#ffffff');doc.text(c,hx2,y+12);hx2+=cfW[i];});
y+=18;
d.projRows.forEach(function(r,ri){
checkPage(15);
if(ri%2===0){doc.setFillColor('#f7f7f5');doc.rect(mg,y,cw,15,'F');}
var rx=mg+5;
[String(r.yr),fmtD(r.rent),fmtD(r.effInc),fmtD(r.totalOpEx),fmtD(r.noi),fmtD(r.cashFlow),fmtD(r.yearCF),fmtD(r.cumCF)].forEach(function(val,i){
var color=i===5||i===6?(r.cashFlow>=200?'#2d6a2d':r.cashFlow>=0?'#8a5e1a':'#8a2020'):'#1a2332';
doc.setFont('helvetica',i===5||i===6?'bold':'normal');doc.setFontSize(8);doc.setTextColor(color);
doc.text(val,rx,y+10);rx+=cfW[i];
});
y+=15;
});
y+=10;
sTitle('After-tax exit analysis by year');
var retCols=['Yr','Net Proceeds','Recap. Tax','LTCG Tax','Total Tax','After-Tax Proceeds','After-Tax IRR'];
var retW=[20,80,76,72,66,96,74];
doc.setFillColor('#1a2332'); doc.rect(mg,y,cw,18,'F');
var hx3=mg+5;
retCols.forEach(function(c,i){doc.setFont('helvetica','bold');doc.setFontSize(6.5);doc.setTextColor('#ffffff');doc.text(c,hx3,y+12);hx3+=retW[i];});
y+=18;
d.projRows.forEach(function(r,ri){
checkPage(15);
if(ri%2===0){doc.setFillColor('#f7f7f5');doc.rect(mg,y,cw,15,'F');}
var rx=mg+5;
[String(r.yr),fmtD(r.netProc),fmtD(r.recaptureTax),fmtD(r.ltcgTax),fmtD(r.totalTaxOwed),fmtD(r.netAfterTax),r.yr===d.holdYears?fmtPct(d.irrPost):'—'].forEach(function(val,i){
doc.setFont('helvetica','normal');doc.setFontSize(8);doc.setTextColor('#1a2332');
doc.text(val,rx,y+10);rx+=retW[i];
});
y+=15;
});
var fp=ph-36;
doc.setDrawColor('#e2e0db');doc.setLineWidth(0.5);doc.line(mg,fp-8,pw-mg,fp-8);
doc.setFont('helvetica','normal');doc.setFontSize(6.5);doc.setTextColor('#aaaaaa');
doc.text('For informational purposes only. Does not constitute financial, legal, or investment advice. Depreciation recapture taxed at 25%; LTCG rate as entered. Consult a licensed CPA.',mg,fp);
doc.text('Capstone Realty Professionals | Licensed in Arizona | 602-354-4660 | capstonerealtypros.com',mg,fp+10);
var fn=(d.address?d.address.replace(/[^a-zA-Z0-9]/g,'-').substring(0,40):'property')+'-capstone-analysis.pdf';
doc.save(fn);
}
// ── Bind all events via addEventListener — WordPress safe ──
var analyzeBtn = document.getElementById('pra-analyze-btn');
if (analyzeBtn) analyzeBtn.addEventListener('click', praAnalyze);
var pdfBtn = document.getElementById('pra-pdf-btn');
if (pdfBtn) pdfBtn.addEventListener('click', praExportPDF);
var resetBtn = document.getElementById('pra-reset-btn');
if (resetBtn) resetBtn.addEventListener('click', praReset);
document.querySelectorAll('.pra-tab').forEach(function(btn) {
btn.addEventListener('click', function() {
praSwitchTab(btn.getAttribute('data-tab'));
});
});
}); // end DOMContentLoaded
We use cookies to enhance your browsing experience and analyze our traffic. By clicking "Accept", you consent to our use of cookies.