/-- If there are no configurations of satellites with `N+1` points, one never uses more than `N`
distinct families in the Besicovitch inductive construction. -/
theorem color_lt {i : Ordinal.{u}} (hi : i < p.lastStep) {N : ℕ}
    (hN : IsEmpty (SatelliteConfig α N p.τ)) : p.color i < N := by
  /- By contradiction, consider the first ordinal `i` for which one would have `p.color i = N`.
    Choose for each `k < N` a ball with color `k` that intersects the ball at color `i`
    (there is such a ball, otherwise one would have used the color `k` and not `N`).
    Then this family of `N+1` balls forms a satellite configuration, which is forbidden by
    the assumption `hN`. -/
  induction' i using Ordinal.induction with i IH
  let A : Set ℕ :=
    ⋃ (j : { j // j < i })
      (_ : (closedBall (p.c (p.index j)) (p.r (p.index j)) ∩
        closedBall (p.c (p.index i)) (p.r (p.index i))).Nonempty),
      {p.color j}
  have color_i : p.color i = sInf (univ \ A) := by rw [color]
  rw [color_i]
  have N_mem : N ∈ univ \ A := by
    simp only [not_exists, true_and_iff, exists_prop, mem_iUnion, mem_singleton_iff, mem_closedBall,
      not_and, mem_univ, mem_diff, Subtype.exists, Subtype.coe_mk]
    intro j ji _
    exact (IH j ji (ji.trans hi)).ne'
  suffices sInf (univ \ A) ≠ N by
    rcases (csInf_le (OrderBot.bddBelow (univ \ A)) N_mem).lt_or_eq with (H | H)
    · exact H
    · exact (this H).elim
  intro Inf_eq_N
  have :
    ∀ k, k < N → ∃ j, j < i ∧
      (closedBall (p.c (p.index j)) (p.r (p.index j)) ∩
        closedBall (p.c (p.index i)) (p.r (p.index i))).Nonempty ∧ k = p.color j := by
    intro k hk
    rw [← Inf_eq_N] at hk
    have : k ∈ A := by
      simpa only [true_and_iff, mem_univ, Classical.not_not, mem_diff] using
        Nat.not_mem_of_lt_sInf hk
    simp only [mem_iUnion, mem_singleton_iff, exists_prop, Subtype.exists, exists_and_right,
      and_assoc] at this
    simpa only [exists_prop, mem_iUnion, mem_singleton_iff, mem_closedBall, Subtype.exists,
      Subtype.coe_mk]
  choose! g hg using this
  -- Choose for each `k < N` an ordinal `G k < i` giving a ball of color `k` intersecting
  -- the last ball.
  let G : ℕ → Ordinal := fun n => if n = N then i else g n
  have color_G : ∀ n, n ≤ N → p.color (G n) = n := by
    intro n hn
    rcases hn.eq_or_lt with (rfl | H)
    · simp only; simp only [color_i, Inf_eq_N, if_true, eq_self_iff_true]
    · simp only; simp only [H.ne, (hg n H).right.right.symm, if_false]
  have G_lt_last : ∀ n, n ≤ N → G n < p.lastStep := by
    intro n hn
    rcases hn.eq_or_lt with (rfl | H)
    · simp only; simp only [hi, if_true, eq_self_iff_true]
    · simp only; simp only [H.ne, (hg n H).left.trans hi, if_false]
  have fGn :
      ∀ n, n ≤ N →
        p.c (p.index (G n)) ∉ p.iUnionUpTo (G n) ∧ p.R (G n) ≤ p.τ * p.r (p.index (G n)) := by
    intro n hn
    have :
      p.index (G n) =
        Classical.epsilon fun t => p.c t ∉ p.iUnionUpTo (G n) ∧ p.R (G n) ≤ p.τ * p.r t :=
      by rw [index]; rfl
    rw [this]
    have : ∃ t, p.c t ∉ p.iUnionUpTo (G n) ∧ p.R (G n) ≤ p.τ * p.r t := by
      simpa only [not_exists, exists_prop, not_and, not_lt, not_le, mem_setOf_eq, not_forall] using
        not_mem_of_lt_csInf (G_lt_last n hn) (OrderBot.bddBelow _)
    exact Classical.epsilon_spec this
  -- the balls with indices `G k` satisfy the characteristic property of satellite configurations.
  have Gab :
    ∀ a b : Fin (Nat.succ N),
      G a < G b →
        p.r (p.index (G a)) ≤ dist (p.c (p.index (G a))) (p.c (p.index (G b))) ∧
          p.r (p.index (G b)) ≤ p.τ * p.r (p.index (G a)) := by
    intro a b G_lt
    have ha : (a : ℕ) ≤ N := Nat.lt_succ_iff.1 a.2
    have hb : (b : ℕ) ≤ N := Nat.lt_succ_iff.1 b.2
    constructor
    · have := (fGn b hb).1
      simp only [iUnionUpTo, not_exists, exists_prop, mem_iUnion, mem_closedBall, not_and, not_le,
        Subtype.exists, Subtype.coe_mk] at this
      simpa only [dist_comm, mem_ball, not_lt] using this (G a) G_lt
    · apply le_trans _ (fGn a ha).2
      have B : p.c (p.index (G b)) ∉ p.iUnionUpTo (G a) := by
        intro H; exact (fGn b hb).1 (p.monotone_iUnionUpTo G_lt.le H)
      let b' : { t // p.c t ∉ p.iUnionUpTo (G a) } := ⟨p.index (G b), B⟩
      apply @le_ciSup _ _ _ (fun t : { t // p.c t ∉ p.iUnionUpTo (G a) } => p.r t) _ b'
      refine' ⟨p.r_bound, fun t ht => _⟩
      simp only [exists_prop, mem_range, Subtype.exists, Subtype.coe_mk] at ht
      rcases ht with ⟨u, hu⟩
      rw [← hu.2]
      exact p.r_le _
  -- therefore, one may use them to construct a satellite configuration with `N+1` points
  let sc : SatelliteConfig α N p.τ :=
    { c := fun k => p.c (p.index (G k))
      r := fun k => p.r (p.index (G k))
      rpos := fun k => p.rpos (p.index (G k))
      h := by
        intro a b a_ne_b
        wlog G_le : G a ≤ G b generalizing a b
        · exact (this b a a_ne_b.symm (le_of_not_le G_le)).symm
        have G_lt : G a < G b := by
          rcases G_le.lt_or_eq with (H | H); · exact H
          have A : (a : ℕ) ≠ b := Fin.val_injective.ne a_ne_b
          rw [← color_G a (Nat.lt_succ_iff.1 a.2), ← color_G b (Nat.lt_succ_iff.1 b.2), H] at A
          exact (A rfl).elim
        exact Or.inl (Gab a b G_lt)
      hlast := by
        intro a ha
        have I : (a : ℕ) < N := ha
        have : G a < G (Fin.last N) := by dsimp; simp [I.ne, (hg a I).1]
        exact Gab _ _ this
      inter := by
        intro a ha
        have I : (a : ℕ) < N := ha
        have J : G (Fin.last N) = i := by dsimp; simp only [if_true, eq_self_iff_true]
        have K : G a = g a := by dsimp; simp [I.ne, (hg a I).1]
        convert dist_le_add_of_nonempty_closedBall_inter_closedBall (hg _ I).2.1 }
  -- this is a contradiction
  

Proof state:
case h
α : Type u_1
inst✝¹ : MetricSpace α
β : Type u
inst✝ : Nonempty β
p : TauPackage β α
N : ℕ
hN : IsEmpty (SatelliteConfig α N p.τ)
i : Ordinal.{u}
IH : ∀ k < i, k < lastStep p → color p k < N
hi : i < lastStep p
A : Set ℕ :=
  ⋃ j,
    ⋃ (_ :
      Set.Nonempty
        (closedBall (BallPackage.c p.toBallPackage (index p ↑j)) (BallPackage.r p.toBallPackage (index p ↑j)) ∩
          closedBall (BallPackage.c p.toBallPackage (index p i)) (BallPackage.r p.toBallPackage (index p i)))),
      {color p ↑j}
color_i : color p i = sInf (univ \ A)
N_mem : N ∈ univ \ A
Inf_eq_N : sInf (univ \ A) = N
g : ℕ → Ordinal.{u}
hg :
  ∀ k < N,
    g k < i ∧
      Set.Nonempty
          (closedBall (BallPackage.c p.toBallPackage (index p (g k))) (BallPackage.r p.toBallPackage (index p (g k))) ∩
            closedBall (BallPackage.c p.toBallPackage (index p i)) (BallPackage.r p.toBallPackage (index p i))) ∧
        k = color p (g k)
G : ℕ → Ordinal.{u} := fun n => if n = N then i else g n
color_G : ∀ n ≤ N, color p (G n) = n
G_lt_last : ∀ n ≤ N, G n < lastStep p
fGn :
  ∀ n ≤ N,
    BallPackage.c p.toBallPackage (index p (G n)) ∉ iUnionUpTo p (G n) ∧
      R p (G n) ≤ p.τ * BallPackage.r p.toBallPackage (index p (G n))
Gab :
  ∀ (a b : Fin (Nat.succ N)),
    G ↑a < G ↑b →
      BallPackage.r p.toBallPackage (index p (G ↑a)) ≤
          dist (BallPackage.c p.toBallPackage (index p (G ↑a))) (BallPackage.c p.toBallPackage (index p (G ↑b))) ∧
        BallPackage.r p.toBallPackage (index p (G ↑b)) ≤ p.τ * BallPackage.r p.toBallPackage (index p (G ↑a))
sc : SatelliteConfig α N p.τ :=
  { c := fun k => BallPackage.c p.toBallPackage (index p (G ↑k)),
    r := fun k => BallPackage.r p.toBallPackage (index p (G ↑k)),
    rpos := (_ : ∀ (k : Fin (Nat.succ N)), 0 < BallPackage.r p.toBallPackage (index p (G ↑k))),
    h :=
      (_ :
        ∀ (a b : Fin (Nat.succ N)),
          a ≠ b →
            (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) a ≤
                  dist ((fun k => BallPackage.c p.toBallPackage (index p (G ↑k))) a)
                    ((fun k => BallPackage.c p.toBallPackage (index p (G ↑k))) b) ∧
                (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) b ≤
                  p.τ * (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) a ∨
              (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) b ≤
                  dist ((fun k => BallPackage.c p.toBallPackage (index p (G ↑k))) b)
                    ((fun k => BallPackage.c p.toBallPackage (index p (G ↑k))) a) ∧
                (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) a ≤
                  p.τ * (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) b),
    hlast :=
      (_ :
        ∀ a < last N,
          BallPackage.r p.toBallPackage (index p (G ↑a)) ≤
              dist (BallPackage.c p.toBallPackage (index p (G ↑a)))
                (BallPackage.c p.toBallPackage (index p (G ↑(last N)))) ∧
            BallPackage.r p.toBallPackage (index p (G ↑(last N))) ≤
              p.τ * BallPackage.r p.toBallPackage (index p (G ↑a))),
    inter :=
      (_ :
        ∀ a < last N,
          dist ((fun k => BallPackage.c p.toBallPackage (index p (G ↑k))) a)
              ((fun k => BallPackage.c p.toBallPackage (index p (G ↑k))) (last N)) ≤
            (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) a +
              (fun k => BallPackage.r p.toBallPackage (index p (G ↑k))) (last N)) }
⊢ False

Next tactic:
exact hN.false sc