- function ms(v) { return v != null ? (v/1000).toFixed(2)+'s' : '—'; } - function raw(v, unit) { return v != null ? v.toFixed(unit === 'ms' ? 0 : 3)+unit : '—'; } - function cwvClass(metric, val) { - if (val == null) return 'bg-gray-50 border-gray-200'; - const thresholds = { lcp: [2500, 4000], fcp: [1800, 3000], tbt: [200, 600], cls: [0.1, 0.25], ttfb: [800, 1800] }; - const t = thresholds[metric]; - if (!t) return 'bg-gray-50 border-gray-200'; - return val <= t[0] ? 'bg-green-50 border-green-300' : val <= t[1] ? 'bg-yellow-50 border-yellow-300' : 'bg-red-50 border-red-300'; - } div(class='bg-white border border-gray-200 rounded-xl p-5') h2(class='text-base font-semibold mb-4') Core Web Vitals div(class='grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-3') each item in [['LCP', 'lcp', ms(job.lcp)], ['FCP', 'fcp', ms(job.fcp)], ['TBT', 'tbt', raw(job.tbt,'ms')], ['CLS', 'cls', raw(job.cls,'')], ['TTFB', 'ttfb', ms(job.ttfb)]] div(class=`metric-card border ${cwvClass(item[1], job[item[1]])} text-center`) div(class='text-2xl font-bold')= item[2] div(class='text-xs text-gray-500 mt-1')= item[0]