With positive count data in both the numerator and the denominator of your fecundity measure, it might not be surprising that residuals don't follow a normal distribution. Poisson count data have a variance equal to the mean, necessarily smaller in magnitude at low counts and larger at high counts. That might explain the heavy-tailed nature of your qq plots. Here's a qq plot for a lm() fit of 450 Poisson-distributed Y values versus corresponding X mean values ranging from 1 to 15; code below. It has the same overall shape as yours.
Even if you eventually present the results in terms of that measure, your statistical analysis might best be done directly at the count level. That means starting with a Poisson generalized linear model (log link) and working from there, perhaps moving to a quasi-Poisson or negative binomial model.
You would model the actual egg counts, using the log of the number of females as an offset for this rate-type analysis. Time and population type would still be fixed effects (with their interaction, which seems to be of interest), and the "blocks" (as I understand, 10 total, 5 for each population type) treated as random effects. The R DHARMa package provides useful tools for residual diagnostics.
One potential problem in the design: this assumes that per-capita fecundity is independent of the number of females alive at the start of each time point. If crowding affects fertility, then neither your fecundity index nor using the log of the number of females as an offset (fixed regression coefficient of 1) would be valid. Check that mortality is the same for the 2 population types at a minimum, and see if there's evidence of non-proportionality of egg counts against number of females under otherwise similar circumstances.
Code for the plot
> myX <- rep(1:15,30)
> length(myX)
[1] 450
> set.seed(1234)
> myY <- rpois(450, myX)
> poisDF <- data.frame(x=myX, y=myY)
> plot(lm(y ~ x,poisDF))
