(int) ( $weight_title ?? 25 ), 'meta' => (int) ( $weight_meta ?? 20 ), 'headings' => (int) ( $weight_headings ?? 20 ), 'readability' => (int) ( $weight_readability ?? 15 ), 'links' => (int) ( $weight_links ?? 10 ), 'images' => (int) ( $weight_images ?? 10 ), ]; $total_weight = max( 1, array_sum( $weights ) ); $score = 0; foreach ( $weights as $key => $w ) { $signal = (float) ( $signals[ $key ] ?? 0 ); // 0..1 $score += ( $signal * $w ); } $final = max( 0, min( 100, ( $score / $total_weight ) * 100 ) ); return [ 'score' => round( $final, 1 ), 'breakdown' => $this->build_breakdown( $signals, $weights ), ]; } private function build_breakdown( array $signals, array $weights ): array { $out = []; foreach ( $weights as $k => $w ) { $out[ $k ] = [ 'weight' => $w, 'value' => round( 100 * (float) ( $signals[ $k ] ?? 0 ), 1 ), ]; } return $out; } }