diff --git a/R/build.R b/R/build.R
index 1889c4a9b..4870f6dfc 100644
--- a/R/build.R
+++ b/R/build.R
@@ -430,7 +430,11 @@ build_site_local <- function(pkg = ".",
 
   pkgdown_sitrep(pkg)
 
-  init_site(pkg)
+  if (!lazy) {
+    # Only force init_site() if `!lazy`
+    # if site is not initialized, it will be in build_home()
+    init_site(pkg, override)
+  }
 
   build_home(pkg, override = override, preview = FALSE)
   build_reference(
diff --git a/R/context.R b/R/context.R
index a0fd58e45..16f761187 100644
--- a/R/context.R
+++ b/R/context.R
@@ -20,10 +20,17 @@ section_init <- function(pkg,
 
   local_envvar_pkgdown(pkg, .frame)
   local_options_link(pkg, depth = depth, .frame = .frame)
+  cache_cli_colours(.frame = .frame)
 
   pkg
 }
 
+cache_cli_colours <- function(.frame = parent.frame()) {
+  # https://github.com/r-lib/cli/issues/607
+  num_col <- getOption("cli.num_colors", default = cli::num_ansi_colors())
+  withr::local_options(cli.num_colors = num_col, .local_envir = .frame)
+}
+
 local_options_link <- function(pkg, depth, .frame = parent.frame()) {
   article_index <- article_index(pkg)
   Rdname <- get_rdname(pkg$topics)
diff --git a/R/init.R b/R/init.R
index 25516ec32..f36ecbd0f 100644
--- a/R/init.R
+++ b/R/init.R
@@ -8,6 +8,14 @@
 #' * copies CSS/JS assets and extra files, and
 #' * runs `build_favicons()`, if needed.
 #'
+#' Typically, you will not need to call this function directly, as all `build_*()`
+#' functions will run `init_site()` if needed.
+#'
+#' The only good reasons to call `init_site()` directly are the following:
+#' * If you add or modify a package logo.
+#' * If you add or modify `pkgdown/extra.scss`.
+#' * If you modify `template.bslib` variables in `_pkgdown.yml`.
+#'
 #' See `vignette("customise")` for the various ways you can customise the
 #' display of your site.
 #'
@@ -24,6 +32,7 @@ init_site <- function(pkg = ".", override = list()) {
   # This is the only user facing function that doesn't call section_init()
   # because section_init() can conditionally call init_site()
   rstudio_save_all()
+  cache_cli_colours()
   pkg <- as_pkgdown(pkg, override = override)
 
   cli::cli_rule("Initialising site")
diff --git a/R/theme.R b/R/theme.R
index 235a3bba1..2c7bafaf8 100644
--- a/R/theme.R
+++ b/R/theme.R
@@ -29,8 +29,10 @@ build_bslib <- function(pkg = ".", call = caller_env()) {
 
 data_deps <- function(pkg, depth) {
   if (!file_exists(data_deps_path(pkg))) {
+    # this is unlikely to occur after #2439 and #2571
     cli::cli_abort(
       "Run {.fn pkgdown::init_site} first.",
+      .internal = TRUE,
       call = caller_env()
     )
   }
diff --git a/man/init_site.Rd b/man/init_site.Rd
index 9d44cc1aa..b769b65a9 100644
--- a/man/init_site.Rd
+++ b/man/init_site.Rd
@@ -21,6 +21,16 @@ values in \verb{_pkgdown.yml}}
 \item runs \code{build_favicons()}, if needed.
 }
 
+Typically, you will not need to call this function directly, as all \verb{build_*()}
+functions will run \code{init_site()} if needed.
+
+The only good reasons to call \code{init_site()} directly are the following:
+\itemize{
+\item If you add or modify a package logo.
+\item If you add or modify \code{pkgdown/extra.scss}.
+\item If you modify \code{template.bslib} variables in \verb{_pkgdown.yml}.
+}
+
 See \code{vignette("customise")} for the various ways you can customise the
 display of your site.
 }
diff --git a/pkgdown.Rproj b/pkgdown.Rproj
index 8eb3054db..1a7bd8269 100644
--- a/pkgdown.Rproj
+++ b/pkgdown.Rproj
@@ -14,6 +14,7 @@ LaTeX: pdfLaTeX
 
 AutoAppendNewline: Yes
 StripTrailingWhitespace: Yes
+LineEndingConversion: Posix
 
 BuildType: Package
 PackageUseDevtools: Yes