Case Study: Fangio’s Two-High Revolution and Macdonald’s Answer

How a sixty-year-old journeyman coordinator taught the NFL to keep two safeties back and dare offenses to be patient, and how a thirty-six-year-old built a Super Bowl defense by making every snap look the same and play differently.

Show the Python (shared drawing helpers for this chapter)
import logging
import os
import shutil

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Circle, Ellipse, FancyArrowPatch, FancyBboxPatch, Patch, Rectangle, RegularPolygon
from matplotlib.lines import Line2D
from IPython.display import HTML, Markdown, display

from gridiron import Play, Player, style
from gridiron.animate import animate
from gridiron.formations import technique as T
from gridiron.play import MARKER_R

logging.getLogger("matplotlib.font_manager").setLevel(logging.ERROR)
style.apply()
PDF = os.environ.get("RTG_FORMAT", "").lower() in ("pdf", "typst", "print")
FIELD_W = 160 / 3


# ---------------------------------------------------------------- building plays by hand
def O(key, pos, d, w, label=None):
    if label is None and pos in ("WR", "TE"):
        label = key            # receivers and tight ends wear their letters (X, Y, Z, H, U)
    return Player(key, pos, "off", d, w, label=label)


def D(key, pos, d, w, label=None):
    return Player(key, pos, "def", d, w, label=label)


def line5(d=-0.7):
    """The five offensive linemen (only the center labelled)."""
    return [O(k, k, d, w, label="C" if k == "C" else "") for k, w in
            (("LT", -3.2), ("LG", -1.6), ("C", 0.0), ("RG", 1.6), ("RT", 3.2))]


def eleven_attached(rb_w=1.6):
    """11 personnel from the shotgun, the tight end (Y) attached on the right: Z wide right off the
    ball, X wide left on the ball, H in the left slot off the ball. Seven on the line: five
    linemen, Y and X, so Y and X are the ends and everyone else is a back."""
    return line5() + [O("Y", "TE", -0.7, 4.8), O("Z", "WR", -1.5, 14.0), O("X", "WR", -0.7, -14.0),
                      O("H", "WR", -1.5, -8.5), O("QB", "QB", -5.0, 0.0, "Q"), O("RB", "RB", -5.0, rb_w, "R")]


def eleven_2x2():
    """11 personnel 2x2 from the shotgun: X and H left, the tight end flexed as the right slot (Y)
    and Z on the ball outside him. Seven on the line: five linemen, X and Z."""
    return line5() + [O("X", "WR", -0.7, -15.0), O("H", "WR", -1.5, -9.0), O("Y", "TE", -1.5, 8.5),
                      O("Z", "WR", -0.7, 15.0), O("QB", "QB", -5.0, 0.0, "Q"), O("RB", "RB", -5.0, 1.5, "R")]


def twelve_under_center():
    """12 personnel under center: two tight ends attached (U left, Y right), X and Z off the ball."""
    return line5() + [O("Y", "TE", -0.7, 4.8), O("U", "TE", -0.7, -4.8, "U"), O("X", "WR", -1.5, -14.0),
                      O("Z", "WR", -1.5, 14.0), O("QB", "QB", -1.9, 0.0, "Q"), O("RB", "RB", -7.0, 0.0, "R")]


def tite_quarters():
    """Fangio-style nickel tite against 11 personnel with the tight end on the right: a nose (0) and
    two 4i-techniques, a stand-up edge (E) outside each tackle (the right one outside the tight end),
    one linebacker (M), the nickel ($) inside the left slot, corners 7 off, safeties 12.5 deep."""
    return [D("LE", "OLB", 1.0, -5.3, "E"), D("L4", "DL", 1.0, T("4i", -1), "4i"), D("NT", "DL", 1.0, 0.0, "0"),
            D("R4", "DL", 1.0, T("4i", 1), "4i"), D("RE", "OLB", 1.0, T("9"), "E"),
            D("MIKE", "LB", 4.7, 0.8, "M"), D("NB", "NB", 5.0, -8.0, "$"),
            D("LCB", "CB", 7.0, -14.6, "CB"), D("RCB", "CB", 7.0, 14.6, "CB"),
            D("FS", "FS", 12.5, -7.0, "FS"), D("SS", "SS", 12.5, 7.0, "SS")]


def go_to(p, key, to, kind="path", **kw):
    """Post-snap movement to an absolute (d, w) spot."""
    d0, w0 = p._cur(key)
    rel = [(to[0] - d0, to[1] - w0)]
    if kind == "block":
        return p.block(key, pts=rel, **kw)
    if kind == "rush":
        return p.rush(key, pts=rel, **kw)
    return {"path": p.path, "run": p.run}[kind](key, rel, **kw)


# ---------------------------------------------------------------- drawing helpers
def no_numbers(ax):
    """Remove the painted yard numbers (in zoomed windows they sit where players stand)."""
    for t in list(ax.texts):
        if t.get_alpha() == 0.55:
            t.remove()


def P_of(fld, p):
    """(d, w) in the play's frame -> plot coordinates on this field."""
    return lambda d, w: tuple(float(v) for v in fld.xy(*p.to_abs(d, w)))


def say(ax, P, d, w, text, color=style.INK, fs=6.8, ha="center", ec=None, weight="normal"):
    x, y = P(d, w)
    ax.text(x, y, text, fontsize=fs, color=color, ha=ha, va="center", zorder=12, linespacing=1.12,
            fontweight=weight,
            bbox=dict(boxstyle="round,pad=0.22", fc=style.SURFACE, ec=ec or "none", lw=0.6, alpha=0.94))


def point_to(ax, P, at, to, text, fs=6.8, ha="center"):
    """A label at `at` with a thin leader arrow to `to` (both (d, w) yards)."""
    ax.annotate(text, xy=P(*to), xytext=P(*at), fontsize=fs, color=style.INK, ha=ha, va="center", zorder=12,
                linespacing=1.12, bbox=dict(boxstyle="round,pad=0.25", fc=style.SURFACE, ec=style.BASELINE,
                                            lw=0.6, alpha=0.96),
                arrowprops=dict(arrowstyle="-|>", color=style.INK_2, lw=0.8, shrinkA=2, shrinkB=6))


def ruler(fld, play, fs=6.0, top=30):
    """Depth labels (yards past the line of scrimmage) down the left edge of the window."""
    ax = fld.ax
    x_left = FIELD_W - fld.y1 + 0.35
    for d in range(5, top + 1, 5):
        y = play.los + d
        if fld.x0 + 0.8 <= y <= fld.x1 - 0.8:
            ax.text(x_left, y, f"{d}" + (" yd" if d == 5 else ""), fontsize=fs, color=style.INK_2,
                    ha="left", va="center", zorder=12,
                    bbox=dict(boxstyle="round,pad=0.12", fc=style.SURFACE, ec="none", alpha=0.85))


def box_outline(ax, P, d0, d1, w0, w1, text, text_at, color=style.INK_2):
    """A dashed rectangle around the box, with a caption."""
    (xa, ya), (xb, yb) = P(d0, w0), P(d1, w1)
    ax.add_patch(Rectangle((min(xa, xb), min(ya, yb)), abs(xb - xa), abs(yb - ya), fill=False,
                           ec=color, lw=1.0, ls=(0, (4, 3)), zorder=2))
    say(ax, P, text_at[0], text_at[1], text, fs=6.8, weight="bold")


def ghost_marker(ax, x, y, label, ppy, side="def"):
    """A hollow, dashed marker: where a player stood before he moved."""
    col = style.DEFENSE if side == "def" else style.OFFENSE
    if side == "def":
        pat = RegularPolygon((x, y), 4, radius=MARKER_R * 1.25, orientation=np.pi / 4, facecolor="none",
                             edgecolor=col, lw=1.0, ls=(0, (2, 1.2)), zorder=6)
    else:
        pat = Circle((x, y), MARKER_R, facecolor="none", edgecolor=col, lw=1.0, ls=(0, (2, 1.2)), zorder=6)
    ax.add_patch(pat)
    if label:
        ax.text(x, y, label, ha="center", va="center", color=col, fontweight="bold", zorder=6,
                fontsize=max(4.0, min(8.0, ppy * 0.72)))


# ---------------------------------------------------------------- animations and their print strips
def snapshot(play, t, ax=None, lateral=(-24, 24), window=(-8, 20), ghosts=(), ghost_t=None, trail_from=None):
    """Everyone where he is at time t, a faint trail behind each mover, and a hollow 'ghost'
    where each listed player stood at `ghost_t`."""
    pos = {k: play.position(k, t) for k in play.players}
    moved = [pl.moved(d=float(pos[k][0]), w=float(pos[k][1])) for k, pl in play.players.items()]
    q = Play([m for m in moved if m.side == "off"], [m for m in moved if m.side == "def"],
             los=play.los, ball_y=play.ball_y, to_go=play.to_go)
    q.highlights = dict(play.highlights)
    fld = q.draw(ax=ax, lateral=lateral, window=window, title=False)
    ax, ppy = fld.ax, fld.pts_per_yard()
    no_numbers(ax)
    P = P_of(fld, play)
    start = play._compile()[1] if trail_from is None else trail_from
    for k, pl in play.players.items():
        if pl.pos in ("LT", "LG", "C", "RG", "RT"):
            continue
        pts = np.array([play.position(k, tt) for tt in np.linspace(start, t, 50)])
        if np.ptp(pts[:, 0]) + np.ptp(pts[:, 1]) < 0.4:
            continue
        xs, ys = fld.xy(*play.to_abs(pts[:, 0], pts[:, 1]))
        col = style.OFFENSE if pl.side == "off" else style.DEFENSE
        ax.plot(xs, ys, color=col, lw=1.1, alpha=0.55, ls="-" if pl.side == "off" else (0, (3, 2)), zorder=3)
    if ghost_t is not None and t > ghost_t + 0.05:
        for k in ghosts:
            d0, w0 = play.position(k, ghost_t)
            d1, w1 = play.position(k, t)
            if abs(d1 - d0) + abs(w1 - w0) > 1.0:
                ghost_marker(ax, *P(d0, w0), play.players[k].label, ppy, play.players[k].side)
    bd, bw = play.ball_position(t)
    bx, by = P(bd, bw)
    for kind, _, t_rel in play.ball_events:
        if kind == "pass" and t > t_rel:
            sx, sy = P(*play.ball_position(t_rel))
            ax.add_patch(FancyArrowPatch((sx, sy), (bx, by), arrowstyle="-|>", mutation_scale=8, color=style.BALL,
                                         lw=1.3, ls=(0, (2, 1.5)), zorder=9))
    ax.add_patch(Ellipse((bx, by), 0.75, 1.1, facecolor=style.BALL, edgecolor="white", lw=0.6, zorder=9.5))
    for art in list(ax.texts) + list(ax.patches) + list(ax.lines):
        art.set_clip_on(True)
    return fld


def strip(play, times, labels, ncols=2, width_in=6.5, legend=True, annot=None, **kw):
    """The print version of an animation: one panel per chosen moment, each with a caption.
    `annot` maps a panel index to a function f(ax, P) that adds print-only labels to that panel."""
    lateral, window = kw.get("lateral", (-24, 24)), kw.get("window", (-8, 20))
    n = len(times)
    nrows = int(np.ceil(n / ncols))
    pw = width_in / ncols
    h = nrows * (pw * (window[1] - window[0]) / abs(lateral[1] - lateral[0]) + 0.42) + (0.35 if legend else 0.1)
    fig, axes = plt.subplots(nrows, ncols, figsize=(width_in, h), squeeze=False)
    for ax in axes.flat[n:]:
        ax.axis("off")
    for i, (ax, t, lab) in enumerate(zip(axes.flat, times, labels)):
        fld = snapshot(play, t, ax=ax, **kw)
        if annot and i in annot:
            annot[i](ax, P_of(fld, play))
        ax.set_title(lab, fontsize=7.6, color=style.INK, loc="left", pad=3, linespacing=1.15)
    fig.tight_layout(h_pad=0.6, w_pad=0.5, rect=(0, 0.05 if legend else 0, 1, 1))
    if legend:
        hs = [Line2D([], [], color=style.OFFENSE, lw=1.2, alpha=0.7, label="Offense: path so far"),
              Line2D([], [], color=style.DEFENSE, lw=1.2, ls=(0, (3, 2)), label="Defense: path so far"),
              Patch(facecolor="none", edgecolor=style.DEFENSE, lw=1.0, ls=(0, (2, 1.2)),
                    label="Dashed outline: where he started")]
        fig.legend(handles=hs, loc="lower center", ncol=3, fontsize=7.0, frameon=False, bbox_to_anchor=(0.5, 0.0))
    return fig


def show_play(play, times, labels, web_caption, annot=None, **kw):
    """Web: an animation with a caption that changes with the phase of the play.
    Print: a labelled frame strip (panel titles = `labels`)."""
    if PDF:
        strip(play, times, labels, annot=annot, **kw)
        plt.show()
        return
    df = play.to_tracking()
    tmap = df.groupby("frameId")["time"].first()
    anim = animate(df, to_go=play.to_go)
    ax = anim._fig.axes[0]
    cap = ax.text(0.01, 0.02, "", transform=ax.transAxes, ha="left", va="bottom", fontsize=9, color=style.INK,
                  zorder=21, bbox=dict(boxstyle="round,pad=0.3", fc=style.SURFACE, ec=style.THIRD, lw=1.0))
    base = anim._func

    def upd(fid, *a):
        out = base(fid, *a)
        cap.set_text(web_caption(float(tmap.get(fid, 0.0))))
        return out
    anim._func = upd
    if shutil.which("ffmpeg"):
        html = anim.to_html5_video(embed_limit=40).replace("<video ", '<video style="max-width:100%;height:auto" ')
    else:
        html = anim.to_jshtml(default_mode="once")
    plt.close(anim._fig)
    display(HTML(html))


def phases(cuts):
    """[(t_upper, caption), ...] -> function of t (seconds from the snap) for show_play."""
    def f(t):
        for up, txt in cuts:
            if t < up:
                return txt
        return cuts[-1][1]
    return f
Show the Python (load nflverse play-by-play, participation and FTN charting, 2018-2025, and compute every number quoted in the text)
import re
from gridiron.data import nfl, pbp

SEASONS = list(range(2018, 2026))
COLS = ["season", "season_type", "week", "game_id", "play_id", "posteam", "defteam", "play_type", "down",
        "ydstogo", "qtr", "time", "qb_dropback", "qb_scramble", "sack", "interception", "touchdown", "epa",
        "yards_gained", "desc", "total_home_score", "total_away_score", "home_team", "away_team", "no_huddle"]
RAW = pbp(SEASONS, columns=COLS)
PLAYS = RAW[RAW.play_type.isin(["pass", "run"]) & RAW.down.notna()].copy()
REG = PLAYS[PLAYS.season_type == "REG"].copy()
PART = pd.concat([nfl().load_participation([y]).to_pandas()[
    ["nflverse_game_id", "play_id", "defense_coverage_type", "number_of_pass_rushers", "was_pressure",
     "defenders_in_box", "defense_personnel"]] for y in SEASONS], ignore_index=True)
M = REG.merge(PART, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"], how="left")

TWO = ["COVER_2", "2_MAN", "COVER_4", "COVER_6"]
LABELS = ["COVER_0", "COVER_1", "COVER_2", "2_MAN", "COVER_3", "COVER_4", "COVER_6", "COVER_9"]
DBK = M[M.qb_dropback == 1].copy()
DBK["cv"] = DBK.defense_coverage_type.astype(str).str.upper()
DBK["two"] = DBK.cv.isin(TWO)
DBK["press"] = (DBK.was_pressure.astype(float).fillna(0) > 0) | (DBK.sack == 1)
LAB = DBK[DBK.cv.isin(LABELS)]
RUNS = M[(M.play_type == "run") & (M.qb_scramble == 0)]

TEAM = pd.DataFrame({
    "two": LAB.groupby(["season", "defteam"]).two.mean(),
    "press": DBK[DBK.was_pressure.notna()].groupby(["season", "defteam"]).press.mean(),
    "blitz": DBK[DBK.number_of_pass_rushers.notna()].groupby(["season", "defteam"]).number_of_pass_rushers
    .apply(lambda s: (s >= 5).mean()),
    "four": DBK[DBK.number_of_pass_rushers.notna()].groupby(["season", "defteam"]).number_of_pass_rushers
    .apply(lambda s: (s == 4).mean()),
    "epa": DBK.groupby(["season", "defteam"]).epa.mean(),
    "run_epa": RUNS.groupby(["season", "defteam"]).epa.mean(),
    "light": RUNS[RUNS.defenders_in_box.notna()].groupby(["season", "defteam"]).defenders_in_box
    .apply(lambda s: (s <= 6).mean()),
})
# points allowed, from the schedules
SCH = nfl().load_schedules(SEASONS).to_pandas()
RS = SCH[SCH.game_type == "REG"]
PA = pd.concat([RS.assign(t=RS.home_team, a=RS.away_score)[["season", "t", "a"]],
                RS.assign(t=RS.away_team, a=RS.home_score)[["season", "t", "a"]]]).groupby(["season", "t"]).a.sum()
PA.index.names = ["season", "defteam"]
TEAM["pa"] = PA
LOW_GOOD = {"epa", "run_epa", "pa"}
for c in ["two", "press", "blitz", "epa", "run_epa", "light", "pa", "four"]:
    TEAM[c + "_rk"] = TEAM.groupby("season")[c].rank(ascending=c in LOW_GOOD, method="min")
MED = TEAM.groupby("season").median(numeric_only=True)


def pct(x, nd=0):
    return f"{100 * x:.{nd}f}%"


def ordinal(n):
    n = int(n)
    return f"{n}{'th' if 10 <= n % 100 <= 20 else {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, 'th')}"


def tv(season, team, col):
    return TEAM.loc[(season, team), col]


# FTN charting (2022 on): rushers and "blitzers" (rushers who are not down linemen or regular edges)
FTN = pd.concat([nfl().load_ftn_charting([y]).to_pandas()[["nflverse_game_id", "nflverse_play_id", "n_blitzers",
                                                           "n_pass_rushers"]] for y in [2023, 2024, 2025]])
FD = DBK[DBK.season >= 2023].merge(FTN, left_on=["game_id", "play_id"],
                                   right_on=["nflverse_game_id", "nflverse_play_id"], how="inner")
FD = FD.dropna(subset=["n_pass_rushers", "n_blitzers"])
FD["sim"] = (FD.n_pass_rushers == 4) & (FD.n_blitzers >= 1)
SIM = FD.groupby(["season", "defteam"]).sim.mean()
SIM_RK = SIM.groupby("season").rank(ascending=False, method="min").astype(int)


# defensive personnel: defensive backs and safeties on the field (participation, 2023 on lists every position)
def dbs(s):
    if not isinstance(s, str):
        return None
    d = {pos: int(n) for n, pos in re.findall(r"(\d+)\s+([A-Z]+)", s)}
    saf = d.get("FS", 0) + d.get("SS", 0) + d.get("S", 0)
    return d.get("CB", 0) + d.get("DB", 0) + saf, saf


PG = M[M.season >= 2023][["season", "defteam", "defense_personnel"]].copy()
PG["n"] = PG.defense_personnel.map(dbs)
PG = PG.dropna(subset=["n"])
PG["dbs"] = PG.n.str[0]
PG["saf"] = PG.n.str[1]
PG["three_s"] = PG.saf >= 3
PG["kind"] = np.select([PG.dbs <= 4, (PG.dbs == 5) & (PG.saf >= 3), PG.dbs == 5, PG.dbs >= 6],
                       ["base (4 DBs)", "big nickel (5 DBs, 3+ safeties)", "nickel (5 DBs)", "dime (6+ DBs)"],
                       "other")
PERS = PG.groupby(["season", "defteam"]).kind.value_counts(normalize=True).unstack(fill_value=0)
PERS_LG = PG.groupby("season").kind.value_counts(normalize=True).unstack(fill_value=0)

# ---- Super Bowl LX (Feb 8, 2026): every New England dropback against Seattle
POST = PLAYS[PLAYS.season_type == "POST"]
LX = POST[POST.game_id == "2025_22_SEA_NE"]
P25 = nfl().load_participation([2025]).to_pandas()
LXD = LX.merge(P25, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"], how="left")
LXD = LXD[(LXD.posteam == "NE") & (LXD.qb_dropback == 1)].sort_values(["qtr", "play_id"]).reset_index(drop=True)
LXD["cv"] = LXD.defense_coverage_type.astype(str).str.upper()
LXD["fam"] = np.where(LXD.cv.isin(TWO), "two", np.where(LXD.cv.isin(["COVER_0", "COVER_1", "COVER_3", "COVER_9"]),
                                                         "one", "other"))
LXD["press"] = (LXD.was_pressure.astype(float).fillna(0) > 0) | (LXD.sack == 1)
LX_RUN = LX[(LX.posteam == "NE") & (LX.play_type == "run") & (LX.qb_scramble == 0)]
LX_LAB = LXD[LXD.fam != "other"]
S = {
    "lx_db": len(LXD), "lx_sacks": int(LXD.sack.sum()), "lx_int": int(LXD.interception.sum()),
    "lx_four": int((LXD.number_of_pass_rushers == 4).sum()), "lx_five": int((LXD.number_of_pass_rushers >= 5).sum()),
    "lx_press": int(LXD.press.sum()), "lx_two": int((LX_LAB.fam == "two").sum()), "lx_lab": len(LX_LAB),
    "lx_c2": int((LXD.cv == "COVER_2").sum()), "lx_c6": int((LXD.cv == "COVER_6").sum()),
    "lx_c1": int((LXD.cv == "COVER_1").sum()),
    "lx_epa": LXD.epa.mean(), "lx_box6": int((LX_RUN.merge(P25, left_on=["game_id", "play_id"],
                                                           right_on=["nflverse_game_id", "play_id"])
                                              .defenders_in_box <= 6).sum()), "lx_runs": len(LX_RUN),
    "lx_q4_db": int((LXD.qtr == 4).sum()),
    "lx_pre4_epa": LXD[LXD.qtr < 4].epa.mean(), "lx_q4_epa": LXD[LXD.qtr == 4].epa.mean(),
}
# first New England points
_ne = LX[LX.total_home_score > 0].iloc[0]
S["ne_first_q"], S["ne_first_t"] = int(_ne.qtr), _ne.time

# ---- Super Bowl LIX (Feb 9, 2025): every Kansas City dropback against Philadelphia
P24 = nfl().load_participation([2024]).to_pandas()
LIX = POST[POST.game_id == "2024_22_KC_PHI"].merge(P24, left_on=["game_id", "play_id"],
                                                    right_on=["nflverse_game_id", "play_id"], how="left")
LIXD = LIX[(LIX.posteam == "KC") & (LIX.qb_dropback == 1)]
S["lx_long"] = int(LXD[(LXD.qtr < 4) & (LXD.sack == 0) & (LXD.qb_scramble == 0) & (LXD.interception == 0)]
                  .yards_gained.max())
S["lx_scr"] = int(LXD.qb_scramble.sum())
S["lx_scr_y"] = int(LXD[LXD.qb_scramble == 1].yards_gained.sum())
S["lix_db"] = len(LIXD)
S["lix_le4"] = int((LIXD.number_of_pass_rushers <= 4).sum())
S["lix_c4"] = int((LIXD.defense_coverage_type.astype(str).str.upper() == "COVER_4").sum())
S["lix_sacks"] = int(LIXD.sack.sum())

# ---- Super Bowl LX details used in the bullets
_lxr = LX_RUN.merge(P25, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"])
S["lx_box7"] = int((_lxr.defenders_in_box >= 7).sum())
S["lx_c2_q4"] = int(((LXD.qtr == 4) & (LXD.cv == "COVER_2")).sum())
_qn = LXD.groupby("qtr").size()
S["lx_q13_min"], S["lx_q13_max"] = int(_qn.loc[[1, 2, 3]].min()), int(_qn.loc[[1, 2, 3]].max())
S["lx_q4_nh"] = LX[(LX.posteam == "NE") & (LX.qtr == 4)].no_huddle.mean()

# ---- other numbers quoted in the text
SIM_BAL23 = int(SIM_RK.loc[(2023, "BAL")])
_sp = DBK[DBK.season == 2023].groupby("defteam").apply(lambda g: g.sack.sum() / g.press.sum())
BAL23_SPP_RK = int(_sp.rank(ascending=False, method="min")["BAL"])     # sacks per pressure, 2023
BIGNICKEL = "big nickel (5 DBs, 3+ safeties)"
SEA_BN24, SEA_BN25 = PERS.loc[(2024, "SEA")].get(BIGNICKEL, 0.0), PERS.loc[(2025, "SEA")].get(BIGNICKEL, 0.0)


def both_ilbs(season, team, a, b):
    """Share of a defense's five-DB snaps with both named inside linebackers on the field."""
    pp = nfl().load_participation([season]).to_pandas()
    g = REG[(REG.season == season) & (REG.defteam == team)].merge(
        pp, left_on=["game_id", "play_id"], right_on=["nflverse_game_id", "play_id"])
    g = g[g.defense_personnel.map(lambda s: (dbs(s) or (0, 0))[0] == 5)]
    ro = nfl().load_rosters([season]).to_pandas()
    ids = set(ro[ro.full_name.isin([a, b])].gsis_id)
    return g.defense_players.astype(str).map(lambda s: len(ids & set(s.split(";"))) == 2).mean()


ILB_CHI18 = both_ilbs(2018, "CHI", "Danny Trevathan", "Roquan Smith")
ILB_PHI24 = both_ilbs(2024, "PHI", "Zack Baun", "Nakobe Dean")

Santa Clara, February 2026. In the days before Super Bowl LX, the Patriots’ offensive coordinator, Josh McDaniels, was asked what made Seattle’s defense so hard to prepare for. His answer wasn’t about a star pass rusher or a blitz package. It was about a picture. “If we have the ball for 70 snaps in the game,” he said, “65 of them are gonna look the same before the ball’s snapped.”1 Then the game was played, and the picture held. Drake Maye, the league’s MVP runner-up, was sacked six times. New England didn’t score until the fourth quarter. Seattle sent more than four rushers on only 8 of New England’s 53 dropbacks, and its safeties almost always started deep. A defense that looked the same every snap, rushed four, and still took the quarterback apart: how? This chapter is the story of the two coaches who built that idea, the older one who made “keep two safeties back” the league’s default and the younger one who found what was still missing from it.

You’ll be able to…

NoteYou’ll need

This case study ties together three earlier chapters and leans on several more. One line each:

The problem: one deep safety was a promise the offense could cash

To see why two coaches built what they built, start with what NFL defenses looked like in 2017.

The dominant defense of the 2010s was Seattle’s Cover 3: one safety deep in the middle, the other walked down as an eighth man near the line. It was simple, fast and physical, and for a while it was the best defense in football. But it made a promise before every snap. With one safety deep, the defense had already committed its eighth defender to the run and told the quarterback where the deep help was: in the middle, and only there.

Two kinds of offense learned to cash that promise. Sean McVay’s and Kyle Shanahan’s play-action offenses pulled the eighth man forward with a run fake and threw into the space he left, and Patrick Mahomes punished the other half: with one deep safety, any receiver outside that safety’s reach was one-on-one deep. (The Modern Era tells both stories in full.)

The defensive problem had a precise shape. A one-high defense decides before the snap who will stop the run and where the deep help is, and modern offenses had learned to make that decision cost something on every play. The fix had to do three things at once:

  1. take away the explosive pass, so a quarterback like Mahomes had to be patient;
  2. stop the run without committing an eighth man before the snap, so the play-action fake would hit nothing;
  3. give the quarterback no reliable pre-snap information, so the offense’s beautifully designed answers couldn’t be called in advance.

Two safeties back solves the first. The other two are hard. Vic Fangio spent most of a long career working out how to do them.

Vic Fangio: four decades in the room

Victor John Fangio was born in 1958 in Dunmore, Pennsylvania, a small town next to Scranton. He started coaching at his old high school in 1979, worked as a graduate assistant at North Carolina, and got his first professional job in 1984 as a defensive assistant for the Philadelphia Stars of the USFL. In 1986 he followed the Stars’ head coach, Jim Mora, to the NFL’s New Orleans Saints as linebackers coach, where he coached one of the most famous linebacker groups ever assembled (Rickey Jackson, Sam Mills, Pat Swilling and Vaughan Johnson, the “Dome Patrol”). From there he spent more than twenty years as a coordinator nobody outside the profession knew: the expansion Carolina Panthers (1995–1998), the Colts, the expansion Texans, a stint as an assistant in Baltimore, a year at Stanford under Jim Harbaugh, the 49ers (2011–2014) and the Bears (2015–2018). He was 60 when Denver made him a head coach for the first time, in 2019.2

Those who have worked for him describe a coach of the old school in most things: long meetings, padded practices, clips of hard hits in the film session. When he took over the Eagles’ defense in 2024 he told the players, in effect, that it wasn’t their fault they didn’t know how to work, “But that’s going to change now that I’m here.” At his introductory press conference he put it more broadly: “People are not expecting as much out of players as we used to expect.”3 He is also, by every account, a relentless student of the opponent’s habits, the coach who notices that a tight end’s alignment gives away the run that is coming.

What makes his career unusual is that his defense got more modern as he got older. The ideas that made him famous were not new, and he didn’t claim to have invented them: two-deep coverages and quarters had been staples in college (Michigan State, TCU and Nick Saban’s teams; see Quarters and the Two-High Match Family), and odd fronts are as old as the 3-4. What he did was assemble them into one system that answered the specific problem of the late 2010s NFL, and teach it to a generation of assistants.

NoteMadden vs. real life

In a video game you pick a defense from a menu: “Cover 4,” “Cover 3 Sky,” “Mid Blitz.” Each call has its own alignment, so the alignment is the call. A Fangio defense works the other way round. It starts from one alignment and has many calls that all begin there. The quarterback isn’t choosing between plays he can see; he is choosing between plays he has to imagine.

The scheme answer: five connected decisions

Fangio’s defense is often summed up as “two-high,” which is like summing up a car as “four wheels.” It is five decisions that only work together. Each solves one part of the problem and creates a cost that the next decision pays.

Reading the diagrams: offense is blue circles (X, Z, H receivers; Y and U tight ends; Q quarterback; R running back; C center). Defense is outlined squares: E an edge player, 0 a nose tackle on the center, 4i a lineman on a tackle’s inside shoulder, T a defensive tackle, M and W linebackers, $ the nickel back, S a third safety, CB a cornerback, FS and SS the safeties. Shaded ovals are zone areas; dashed orange arrows are zone drops; solid orange arrows are rushes. A green ring marks the player to watch, and a purple ring a second one. The thick blue line is the line of scrimmage and the thick yellow-orange line the first-down marker. The small numbers on the left edge give the depth in yards past the line of scrimmage.

Show the Python
p = Play(eleven_attached(), tite_quarters(), los=35, to_go=10)
for k, to in (("LE", (-2.4, -3.6)), ("L4", (-2.6, -1.6)), ("NT", (-2.8, 0.3)), ("R4", (-2.6, 2.0))):
    go_to(p, k, to, "rush", speed=3.0)
p.drop("RE", (6.5, 11.0), zone=(7, 10))
p.drop("MIKE", (8.0, -0.5), zone=(7, 9))
p.drop("NB", (6.5, -11.5), zone=(7, 10))
for k, to in (("LCB", (17.5, -19.5)), ("RCB", (17.5, 19.5))):
    p.drop(k, to, zone=(10, 12.6))
for k, to in (("FS", (15.0, -6.0)), ("SS", (15.0, 6.0))):     # match-quarters safeties: slow, short, reading #2
    p.drop(k, to, speed=1.5)
for w in (-6.6, 6.6):
    p.zone((17.5, w), (10, 12.6))
p.highlight("FS", "SS")
fld = p.draw(lateral=(-26.6, 26.6), window=(-8.5, 25))
no_numbers(fld.ax)
ruler(fld, p, top=20)
ax, P = fld.ax, P_of(fld, p)
box_outline(ax, P, -1.4, 6.3, -6.6, 6.9, "the box: six vs. six", (-3.0, -11.0))
point_to(ax, P, (-4.6, 17.5), (1.0, 5.7), "the TE-side edge\nlines up to rush,\nthen drops")
point_to(ax, P, (22.2, -15.0), (15.0, -6.0), "safeties ~12 deep:\nread #2, cover him\nor fit the run", ha="center")
say(ax, P, 22.6, 13.2, "deep quarters", fs=6.8, color=style.DEFENSE_DARK, weight="bold")
plt.show()
Figure 66.1: The tite front with quarters behind it, against 11 personnel (illustrative, not a specific Eagles or Bears call). The offense has three receivers, a tight end (Y) attached on the right and a back: six blockers counting the five linemen and Y. The defense is in its five-man nickel tite: a nose (0) on the center, two 4i-techniques on the tackles’ inside shoulders, and a stand-up edge (E) outside each tackle, the right one outside the tight end, with one linebacker (M) behind them. This is Fangio’s base-defense front with a nickel in place of a linebacker, and it became the everyday nickel of his former assistant Brandon Staley; Fangio’s own nickel more often kept two linebackers (decision 2). Either way: six defenders in the box (dashed rectangle) against six blockers, with nobody spare. The two safeties stand about 12 yards deep, outside the hashes; the corners (CB) are 7 to 9 yards off with outside leverage. After the snap, four rush (solid arrows), the tight-end-side edge drops into the right curl-flat area, the Mike and the nickel ($) take the middle and left underneath, and the corners bail to their deep quarters. The safeties (ringed) do not bail: they shuffle a couple of yards, flat-footed, reading the inside receiver on their side (#2: H on the left, Y on the right). If #2 runs deep, the safety takes him in his deep quarter (shaded); if #2 blocks, the safety comes downhill and fits the run.

Decision 1: keep two safeties deep, and show it every time

Two safeties at 12 to 14 yards take away the explosive pass. A receiver who runs past a corner still has a safety over the top of him on his side of the field, not one safety trying to cover all of it. That is the reason anyone plays two-high. Fangio’s twist is the every time. His safeties line up at about the same depth and width whatever the call, so the shell that answers “where is the deep help?” gives the same answer every snap. Ed Donatell, who coached with Fangio for eleven seasons, described the goal as “delayed identification”: the quarterback shouldn’t know the coverage until his first or second step of the drop.4

What it costs: two safeties back means two fewer defenders near the line. Someone else has to stop the run. That is decision 2.

Decision 2: accept a light box, and build a front that can hold it

Against 11 personnel (one back, one tight end, three receivers) a two-high nickel defense usually has six defenders in the box against six blockers. The old answer to “six against six” was “bring a safety down.” Fangio’s answer was to make the six good enough. The front he favored on early downs, the tite, puts five men on the line (in Figure 66.1: E, 4i, 0, 4i, E) so that every interior gap has a lineman in it. On paper the offense still has a spare blocker: the guards are uncovered. In practice the nose on the center and the 4is in the B gaps keep both guards busy helping on them, so neither can climb cleanly to the lone linebacker (Odd and Hybrid Fronts draws this against inside zone). The nose must hold both A gaps on his own; the 4is must take on the guards and tackles without being moved. Then the safeties fit the run late, from depth, arriving at five or six yards instead of two.

Against three receivers, Fangio’s own everyday nickel was a close cousin. His Bears and Eagles usually took the nose off and kept two inside linebackers behind four linemen, a 2-4-5: by this book’s count both inside linebackers were on the field for 80% of Chicago’s nickel snaps in 2018 (Danny Trevathan and Roquan Smith) and 84% of Philadelphia’s in 2024 (Zack Baun and Nakobe Dean). The box count is the same six against six. The five-man nickel tite with one linebacker is that idea pushed further, and it is the version Staley and others in the tree made their everyday nickel.5 Both are drawn in Figure 66.3, later in the chapter.

Why it exists: a run that gains five yards is not a disaster; a pass that gains forty is. Fangio’s whole defense prices those two outcomes honestly. He would rather give up 4.5 yards a carry than a deep touchdown, because the long drive gives the offense ten more chances to make a mistake.

What it costs: rushing yards, sometimes a lot of them, and an enormous bill for interior linemen. A light-box defense with ordinary defensive tackles gets pushed around. Every Fangio defense that worked had at least one interior lineman who didn’t need help: Justin Smith in San Francisco, Akiem Hicks and Eddie Goldman in Chicago, Jalen Carter and Jordan Davis in Philadelphia.

Decision 3: rush four, from the same places

With six in the box and two safeties deep, there is nobody left over to blitz without breaking the coverage. So the default is a four-man rush, and it has to win on its own. The 2018 Bears traded for Khalil Mack a week before the season to make sure it would. Blitzing is not banned, but it is rare: by this book’s count from the charting data, Fangio’s 2018 Bears sent five or more on 21% of dropbacks (28th-most in the league), his 2024 Eagles on 19% (28th), and his 2025 Eagles on 19% (31st).6

In the tite, four rush and the fifth man on the line drops: usually the edge on the tight-end side (as in Figure 66.1), sometimes a 4i or the nose on a creeper call that sends a linebacker in his place. That is a small disguise, but a readable one. The same five players stand on the line in the same spots every snap, so after a few series an offense knows who the dropper can be and where the four will come from. Hold on to that: it is the gap Macdonald’s defense fills.

What it costs: if the four can’t get home, a patient quarterback can sit behind good protection and pick at the underneath zones. Fangio’s defense accepts that trade too, on the theory that ten-play drives against a good rush and good tacklers usually stall.

Decision 4: play match quarters and Cover 6, so the safeties can do both jobs

The coverage behind it is the quarters family from Quarters and the Two-High Match Family, and this is where the run problem is really solved. A quarters safety reads the inside receiver on his side (#2). If #2 runs a route, the safety covers him; if #2 blocks, the safety becomes a run defender, coming downhill into the alley outside the edge (he is the alley player). So the “missing” eighth man is not missing. He is standing 12 yards deep, waiting for the offense to tell him whether the play is a run. That is the decisive difference from the old eighth-man defense: the extra run defender decides after the snap, from what the play shows him, so the play-action fake that beat the walked-down safety has a harder time fooling him.

The match in match quarters is pattern matching: each defender starts in a zone, but once the receivers show their routes he takes the one who enters his area and covers him like man coverage. The zone tells the safety where to start; #2’s route tells him whom to take.

Fangio’s family has a split-field version too, under two names. Cover 6 is quarter-quarter-half with the Cover 2 half on the side away from the passing strength (the side with more wide receivers: in Figure 66.1 the left, where the nickel lines up), the usual arrangement. Cover 8 flips it and puts the half toward the passing strength.7 The flip moves the help to where the offense has more receivers. On the two-receiver side the corner squats in the flat (a cloud corner) to sit on the quick outs and hitches that side is built to throw, with a safety taking the whole deep half over him; on the tight-end side the safety keeps his quarters read on Y, where the run strength is. The analyst Cody Alexander calls this targeted coverage. The alternative is a defense that drops each safety into a fixed zone and rotates the same way whatever the offense shows. A targeted defense decides, call by call, which side gets the Cover 2 help and puts it there. (The numbers are dialect: many college staffs, Saban’s among them, use 6 and 7 for different calls; Coverage Fundamentals has the table.)

What it costs: the read safety obeys a rule, and a rule can be used against him. A tight end who blocks for a count and then releases behind the safety who came downhill (play-action), or an RPO that reads the safety directly, punishes the rule. And the run help arrives late, at four or five yards, not at the line.

Decision 5: rotate late, so the shell lies

The last decision is what turns a sound defense into a frustrating one. Broadcasters and film-room coaches call the two-high shell middle of the field open (MOFO) and a one-high shell middle of the field closed (MOFC). From the same open picture, one safety can rotate down at the snap and the other run to the deep middle, closing it: the call has become Cover 3 (or Cover 1). One version Fangio leans on is a weak rotation: the safety on the side away from the passing strength comes down, and the other one runs to the middle. Alexander has written it up as Fangio’s “Cover 9.”8 The quarterback who saw two safeties and threw to the open middle finds a safety sitting in it.

Show the Python
def shell_play():
    return Play(eleven_attached(), tite_quarters(), los=35, to_go=None)


def ending(kind):
    p = shell_play()
    if kind == "quarters":
        p.drop("RE", (6.5, 11.0), zone=(6.5, 9.5)); p.drop("MIKE", (8.0, -0.5), zone=(6.5, 8.5))
        p.drop("NB", (6.5, -11.5), zone=(6.5, 9.5))
        for k, to in (("LCB", (17.0, -17.0)), ("RCB", (17.0, 17.0))):
            p.drop(k, to, zone=(9, 11.0))
        for k, to in (("FS", (15.0, -6.0)), ("SS", (15.0, 6.0))):
            p.drop(k, to, speed=1.5)
        for w in (-5.8, 5.8):
            p.zone((17.0, w), (9, 11.0))
    elif kind == "cover6":
        p.drop("LCB", (4.0, -17.5), zone=(5.5, 9)); p.drop("NB", (8.5, -10.0), zone=(6, 8.5))
        p.drop("FS", (17.5, -11.5), zone=(10, 22.5)); p.drop("MIKE", (8.0, 0.5), zone=(6, 8))
        p.drop("RE", (6.5, 11.0), zone=(6, 9))
        p.drop("SS", (15.0, 6.0), speed=1.5); p.zone((17.0, 5.8), (9, 11.0))
        p.drop("RCB", (17.0, 17.0), zone=(9, 11.0))
    else:  # weak rotation: SS down, FS to the middle, corners to thirds
        p.drop("SS", (8.5, 5.5), zone=(6, 8)); p.drop("FS", (17.5, 0.0), zone=(9, 15.0))
        p.drop("LCB", (17.5, -15.5), zone=(9, 14.5)); p.drop("RCB", (17.5, 15.5), zone=(9, 14.5))
        p.drop("NB", (6.5, -12.5), zone=(6, 9)); p.drop("MIKE", (8.0, -4.0), zone=(6, 7.5))
        p.drop("RE", (5.0, 13.0), zone=(5, 8))
        p.highlight("SS")
    return p


fig, axes = plt.subplots(2, 2, figsize=(6.6, 4.9))
panels = [(None, "A · Before the snap: two-high, every time"), ("quarters", "B · Quarters (Cover 4)"),
          ("cover6", "C · Cover 8: the half to the two-receiver side"),
          ("weak", "D · Weak rotation to Cover 3")]
for ax, (kind, title) in zip(axes.flat, panels):
    p = shell_play() if kind is None else ending(kind)
    if kind is None:
        p.highlight("FS", "SS")
    fld = p.draw(ax=ax, lateral=(-23.5, 23.5), window=(-7.5, 22.5), title=False)
    no_numbers(fld.ax)
    ax.set_title(title, fontsize=8.2, color=style.INK, loc="left", pad=3)
    P = P_of(fld, p)
    if kind is None:
        say(ax, P, 17.5, 0.0, "middle of the\nfield looks open", fs=6.4)
    elif kind == "quarters":
        say(ax, P, 11.0, 0.0, "safeties read #2", fs=6.0, color=style.DEFENSE_DARK)
    elif kind == "cover6":
        (xa, ya), (xb, yb) = P(2.0, -1.5), P(21.0, -1.5)
        ax.plot([xa, xb], [ya, yb], color=style.INK_2, lw=0.9, ls=(0, (3, 2)), zorder=2.5)
        say(ax, P, 20.0, -11.5, "deep half", fs=6.2, color=style.DEFENSE_DARK)
        say(ax, P, 20.0, 11.5, "quarters", fs=6.2, color=style.DEFENSE_DARK)
        say(ax, P, -5.0, -14.0, "Cover 2 side", fs=6.2, weight="bold")
        say(ax, P, -5.0, 14.0, "quarters side", fs=6.2, weight="bold")
    elif kind == "weak":
        say(ax, P, 20.0, 0.0, "middle closed", fs=6.2, color=style.DEFENSE_DARK)
        point_to(ax, P, (12.0, 13.0), (9.6, 6.0), "rotates\ndown", fs=6.0)
fig.tight_layout(h_pad=0.8, w_pad=0.6)
plt.show()
Figure 66.2: One shell, three endings (illustrative). Panel A is the picture the quarterback sees before the snap: the same as the previous figure, two safeties 12 to 13 yards deep and the corners 7 off. Panels B to D are three calls that all start from it; in each, four linemen rush (not drawn) and seven cover. B, quarters: the corners bail to deep quarters, the safeties shuffle and read #2 with the deep quarters behind them (shaded), three defenders underneath. C, Cover 8, Fangio’s name for Cover 6 with the half toward the passing strength (the two-receiver side, where the nickel is): on the left the corner squats in the flat and the free safety takes the whole deep half; on the right, quarters. D, the weak rotation to Cover 3 that Cody Alexander attributes to Fangio: the safety on the side away from the two receivers, here the strong safety (SS, ringed), comes down to the curl and hook area; the free safety runs to the deep middle and both corners bail to deep thirds, so the open middle the quarterback saw before the snap is closed. Weak here means away from the two-receiver side, which in this formation is the tight end’s side, so the rotating safety also becomes an eighth run defender where the run strength is. The defenders’ starting spots are the same in all four panels; only their first steps after the snap differ.

Why it exists: a two-high shell that is always two-high coverage is a puzzle the quarterback solves once. A shell that is two-high or one-high depending on the call is a puzzle he has to solve after the snap, every snap, while the four-man rush is coming. Rotation is what makes decision 1’s “every time” pay off.

What it costs: every rotation is a small play of its own with a way to go wrong. A safety who rotates down has a long way to travel, and a defense that rotates often sometimes busts (a bust is a blown assignment: two defenders take the same receiver, or nobody takes him). And the charting data stops calling it two-high. That point matters for the data later in this chapter, so hold on to it: Fangio’s 2024 Eagles built their calls from a two-high shell, but after the snap they played a two-high coverage on only 34% of dropbacks, 27th in the league (The Modern Era has the full film room). The coverage charts measure what was played, not what was shown.

ImportantWhy it exists: the system in one sentence

Make the offense earn it slowly. Take away the big pass with two deep safeties; stop the run with a front that wins its own fights and safeties who fit late; get pressure without sending more than four; and decide the coverage at the snap, so the offense can’t call its answer in advance. Every part is a trade: rushing yards for explosive plays, a blitz for a sound coverage, pre-snap clarity for post-snap uncertainty. It works only if the front holds and the four can rush.

CautionCommon misconception

“Fangio invented two-high defense.” He didn’t, and he has never claimed to. Quarters was a college staple in the 2000s and Saban’s pattern-match coverages go back to his years with Bill Belichick in Cleveland in the early 1990s (Quarters and the Two-High Match Family).9 Fangio’s contribution was the package: an odd front that let a light box hold, a four-man rush, a coverage family that let the safeties play the run, and a rotation habit that made the shell lie, all taught as one system to assistants who then spread it. Credit for a scheme in football is almost always shared.

Signature seasons: Chicago 2018 and Philadelphia 2024

NoteFilm room: Chicago Bears 2018 — the system arrives

Fangio’s fourth Bears defense was the one the league noticed. Chicago allowed 283 points, the fewest in the NFL; it led the league with 27 interceptions and 36 takeaways; and by this book’s count it allowed the fewest EPA per opponent dropback, while blitzing less than all but four teams. Its runs-against-light-boxes rate (62% of designed runs met six or fewer in the box) was the highest in the league. Fangio was the AP’s Assistant Coach of the Year, and Denver hired him as head coach in January 2019.10

What to notice: on 2018 Bears film, watch the front before the coverage. Against three receivers: Hicks and Goldman (or Bilal Nichols) inside, often in 4i-techniques so the guards can’t climb cleanly, Mack and Leonard Floyd standing up on the edges, and Danny Trevathan and Roquan Smith behind them: six in the box against three-receiver sets. Then watch the two safeties, Eddie Jackson and Adrian Amos, at the snap. On a run they come downhill late and arrive in the alley; on a pass they often stay deep and let the receivers come to them. That December the Bears held the Rams, the league’s best offense, to six points (the game is the film room in The Modern Era).

The Denver years (2019–2021) are the other half of the record, and they matter for the argument. As head coach, Fangio went 19–30 with no playoff appearances. His defenses were good (third-fewest points allowed in 2021) but not dominant, ranking 15th, 14th and 18th in EPA per dropback allowed. The weak link was the one the system leans on hardest: by this book’s count Denver’s pressure rate ranked 31st, 25th and 19th, so the four-man rush rarely got home. The lesson the league drew was not that the system failed. It was that a system built on a four-man rush and an interior front lives or dies on its players, and that a defensive head coach without a quarterback has a ceiling.11

NoteFilm room: Philadelphia Eagles 2024 and Super Bowl LIX — the system at full strength

After a year as an Eagles consultant (2022) and one as Miami’s coordinator (2023), Fangio took over a Philadelphia defense that had ranked 30th in scoring. In 2024 it allowed the fewest yards in the league and the second-fewest points, and, by this book’s count, ranked 1st in EPA per designed run allowed, while meeting 66% of opponents’ designed runs with six or fewer in the box (3rd-most).12

Then it played the best version of the problem the system was built for: Patrick Mahomes in the Super Bowl. In Super Bowl LIX (February 9, 2025; Eagles 40, Chiefs 22) the charting shows four or fewer rushers on 42 of Kansas City’s 42 dropbacks, and the coverage charted as quarters (Cover 4) on 25 of them. Mahomes was sacked 6 times. The Eagles didn’t need to blitz the best quarterback in football. They needed four rushers who could win and seven defenders who kept everything in front of them, and they had both.13

What to notice: in the Super Bowl LIX replay, count the rushers on each Chiefs dropback, then watch the safeties. Two deep, almost every snap; the deep ball never comes; Mahomes holds the ball looking for something downfield, and the four-man rush gets there.

Philadelphia’s 2025 defense was not as dominant (5th in points allowed), and the Eagles lost in the wild-card round to San Francisco. Fangio remains their defensive coordinator in 2026, at 68.14

The tree: how the system spread, and why results varied

A scheme spreads through people. A coaching tree is usually drawn by who worked for whom, but this one is better drawn by who took the idea: a two-high shell, a light box held by the front, four rushers, and coverage targeted to what the offense shows. Most of these coaches sat in Fangio’s meetings; one never did.

  • Brandon Staley coached Fangio’s outside linebackers in Chicago (2017–2018) and Denver (2019), then became the Rams’ coordinator for one season, 2020. With Aaron Donald inside and Jalen Ramsey moving around the secondary, the Rams allowed the fewest points in the league, 296, and, by this book’s count, the fewest EPA per dropback. The Rams under Staley added a lot of visible disguise to the system; that season is the film room of Disguise, Rotation, and Split-Field Coverage. Staley then became the Chargers’ head coach (2021–2023), and his defenses there ranked 29th, 21st and 24th in points allowed.
  • Ed Donatell, Fangio’s secondary coach for years, ran Denver’s defense under him (2019–2021) and then Minnesota’s (2022), which finished 28th in points allowed; he was let go after one season.
  • The Rams’ line of succession: Staley’s Rams staff included Ejiro Evero (safeties coach, later Denver’s coordinator in 2022 and Carolina’s since 2023) and Chris Shula (the Rams’ coordinator since 2024). Joe Barry, another Fangio-tree coach, took the system to Green Bay (2021–2023), where his defenses ranked between 10th and 17th in points allowed.
  • Sean Desai, a Bears assistant through Fangio’s years there, became Chicago’s coordinator (2021, 22nd in points allowed) and then Philadelphia’s (2023). His 2023 Eagles finished 30th; that is the defense Fangio inherited, and a year later, with largely the same ideas, it was second.
  • Jesse Minter is the branch that shows the idea traveling without the man. He never worked for Fangio; he worked beside Mike Macdonald on the Ravens’ defensive staff (2017–2020), succeeded him as Michigan’s coordinator (2022–2023), and ran the Chargers’ defense (2024–2025) with the same targeted split-field coverage. His 2024 Chargers allowed 301 points, the fewest in the league. He is the Ravens’ head coach in 2026.15

The record across the tree is uneven, and that is the most useful thing about it. The 2020 Rams (Donald, Ramsey), the 2024 Eagles (Carter, Davis, a deep secondary) and the 2024 Chargers led the league; Staley’s 2021 Chargers were 29th in points allowed and Evero’s 2024 Panthers 32nd, last. Carolina lost its best interior lineman, Derrick Brown, to a season-ending knee injury in Week 1 of 2024 and its veteran linebacker Shaq Thompson to a torn Achilles in Week 4, and by this book’s count ranked 32nd in pressure rate and 32nd in EPA per designed run.16 A light-box defense without the interior lineman who doesn’t need help is the failure case of decision 2. With Brown back for 2025, the same coordinator’s defense rose to 15th. The same ideas, run by coaches who understood them, produced the best and the worst defenses in football. The system decides how you will be beaten (slowly, on the ground, underneath), not whether. Its outcomes are set by the front four and the safeties.

There is also a reason the tree mattered more than any single coach. By 2021 offenses were facing some version of this defense almost every week. NFL Next Gen Stats counted two-high coverage on 32.9% of dropbacks in 2018 and 42.0% in 2025, the highest in its records, with every defense above 30%.17 When everyone plays the same defense, the defense that wins is the one that plays it with something the offense hasn’t seen. That is where Macdonald comes in.

Mike Macdonald: the student who added the missing piece

Mike Macdonald was born in Boston in 1987, grew up a Patriots fan, and finished high school outside Atlanta. He went to the University of Georgia to study finance, graduated summa cum laude, and stayed on as a graduate assistant and quality-control coach in the football program (2010–2013) while earning a master’s degree. He joined the Baltimore Ravens as an intern in 2014, and over seven seasons worked his way through defensive assistant, defensive backs coach and linebackers coach. In 2021 Jim Harbaugh hired him as Michigan’s defensive coordinator; Michigan’s scoring defense went from 95th in the country to 8th and the team reached the College Football Playoff. John Harbaugh brought him back to Baltimore as coordinator in 2022. In January 2024, at 36, he became the Seahawks’ head coach, the youngest in the league at the time, and he kept calling the defensive plays himself, with Aden Durde as his coordinator.18

He never worked on Fangio’s staff. But he came of age as a coach in the years when Fangio’s ideas were taking over the league, and his defenses start from the same place: two safeties back, a light box, a four-man rush most of the time. What he saw was the weakness that a universal defense creates. If everybody plays two-high, offenses learn to beat two-high. They spread it with three receivers and run into the six-man box; they put on extra tight ends and run into it with seven blockers; they throw quickly before the four-man rush arrives; they read the safeties after the snap. A Fangio defense is deliberately simple up front and complicated behind: few complex fronts, and, in the words of Eagles linebacker Zack Baun, “a lot of exotic stuff coverage-wise.”19 Offenses, once they had seen enough of it, knew exactly what the four-man rush and the six-man box would look like before the snap.

Macdonald’s answer was to make the front, the rushers and the personnel as hard to read as the coverage.

Multiplicity: one picture, many plays

Multiplicity is building a defense so that one pre-snap picture can become many different plays: several fronts, rushers and coverages that all start from the same look, and players who can play several roles, so the offense learns little before the snap. It is the opposite of a defense that wins by doing a few things the same way every snap.

Fangio’s defense is multiple mainly in one dimension, the coverage. Macdonald’s is multiple in four:

  • The coverage, decided at the snap, as in Fangio’s system. Seattle in 2025 played two-high coverage after the snap on 52% of dropbacks (3rd-most). Next Gen Stats counted 54.8% from Week 14 through the Super Bowl, the highest of any playoff team, and described Cover 6 as Macdonald’s beloved call.20
  • The front. Fangio’s front also puts five on the line and drops one, but it is the same five in the same spots, so the offense soon learns who the dropper can be (decision 3). Macdonald changes who is on the line: a linebacker walked up into an A gap, an edge standing up over a guard, a safety on the line outside the tight end. Any of the five may drop, and the protection can’t be set from the picture. In Macdonald’s own words, “We put five on the line and drop a guy.”21 Figure 66.3 draws the difference.
  • The rushers. Four rush, nearly always, but which four is not known. This is where his reputation for simulated pressure comes from, and it needs a correction, from the coach himself: “I’m going to disappoint you guys: We do not run a lot of simulated pressures,” he said on Seattle radio in November 2025. Seattle has them, and “it’s a great tool,” but by his definition a sim (simulated pressure) is a specific thing, four rushers with one of them a player the protection didn’t count, and it isn’t a major part of the plan. What is constant is the threat: a pressure look on snap after snap, with five or six who could come and four who do.22 (The data section below squares this with the 2023 Ravens’ reputation in Zone Blitzes.)
  • The personnel. Macdonald’s defenses are built on defensive backs who can play two or three positions: Kyle Hamilton in Baltimore; Devon Witherspoon, Julian Love and the rookie Nick Emmanwori in Seattle. When three safeties are on the field (a big nickel) and any of them can line up deep, in the slot or in the box, the personnel stops telling the offense what is coming. Before the Super Bowl, Macdonald said that with Emmanwori on the field, “when we go to dime, we’re really a nickel [4-3] team.”23 Decoded: Emmanwori is a safety who plays like a linebacker, so a six-DB package behaves like a five-DB one, and an offense that subs in receivers to face a light dime finds a nickel’s box instead.
Show the Python
def box_offense():
    return line5() + [O("Y", "TE", -0.7, 4.8), O("QB", "QB", -5.0, 0.0, "Q"), O("RB", "RB", -5.0, 1.6, "R")]


PURPLE = "#7b4fb8"


def front_245():
    dfn = [D("LE", "OLB", 1.0, -5.3, "E"), D("L4", "DL", 1.0, T("4i", -1), "4i"),
           D("R4", "DL", 1.0, T("4i", 1), "4i"), D("RE", "OLB", 1.0, T("9"), "E"),
           D("MIKE", "LB", 4.7, 1.6, "M"), D("WILL", "LB", 4.7, -1.8, "W")]
    p = Play(box_offense(), dfn, los=35, to_go=None)
    for k, to in (("LE", (-2.6, -4.2)), ("L4", (-2.6, -1.4)), ("R4", (-2.6, 1.4)), ("RE", (-2.6, 4.2))):
        go_to(p, k, to, "rush", speed=3.0)
    return p


def front_tite():
    dfn = [D("LE", "OLB", 1.0, -5.3, "E"), D("L4", "DL", 1.0, T("4i", -1), "4i"), D("NT", "DL", 1.0, 0.0, "0"),
           D("R4", "DL", 1.0, T("4i", 1), "4i"), D("RE", "OLB", 1.0, T("9"), "E"), D("MIKE", "LB", 4.7, 0.8, "M")]
    p = Play(box_offense(), dfn, los=35, to_go=None)
    for k, to in (("LE", (-2.6, -3.8)), ("L4", (-2.6, -1.6)), ("NT", (-2.8, 0.3)), ("R4", (-2.6, 1.8))):
        go_to(p, k, to, "rush", speed=3.0)
    p.drop("RE", (6.0, 9.5))
    p.highlight("RE", color=PURPLE)
    return p


def front_mug():
    dfn = [D("LE", "OLB", 1.0, -5.3, "E"), D("LT_", "DT", 1.0, T("3", -1), "T"), D("MIKE", "LB", 2.0, -0.8, "M"),
           D("RT_", "DT", 1.0, T("2i", 1), "T"), D("RE", "OLB", 1.0, T("9"), "E"), D("WILL", "LB", 3.5, 3.0, "W")]
    p = Play(box_offense(), dfn, los=35, to_go=None)
    for k, to in (("LE", (-2.6, -3.8)), ("LT_", (-2.6, -1.6)), ("RT_", (-2.6, 0.8)), ("WILL", (-2.6, 2.4))):
        go_to(p, k, to, "rush", speed=3.0)
    p.drop("MIKE", (6.5, -1.5)); p.drop("RE", (6.0, 9.5))
    p.highlight("WILL"); p.highlight("RE", color=PURPLE)
    return p


def front_safety():
    dfn = [D("LE", "OLB", 1.0, -5.3, "E"), D("LT_", "DT", 1.0, T("3", -1), "T"), D("RE", "OLB", 1.3, 1.6, "E"),
           D("RT_", "DT", 1.0, T("5", 1), "T"), D("S3", "SS", 1.0, 7.0, "S"), D("MIKE", "LB", 4.7, -1.0, "M")]
    p = Play(box_offense(), dfn, los=35, to_go=None)
    for k, to in (("LE", (-2.6, -3.8)), ("LT_", (-2.6, -1.6)), ("RT_", (-2.6, 2.6)), ("S3", (-2.6, 4.6))):
        go_to(p, k, to, "rush", speed=3.0)
    p.drop("RE", (6.5, 1.0)); p.drop("MIKE", (6.5, -2.6))
    p.highlight("S3"); p.highlight("RE", color=PURPLE)
    return p


fig, axes = plt.subplots(2, 2, figsize=(6.6, 4.6))
specs = [(front_245, "A · Fangio's nickel (2-4-5): four down, two off", "four on the line: they rush"),
         (front_tite, "B · Fangio's tite: the TE-side edge drops", "same five, same dropper"),
         (front_mug, "C · Macdonald: the Mike on the line", "E drops, W comes"),
         (front_safety, "D · Macdonald: a safety on the line", "E drops, S comes")]
for ax, (fn, title, note) in zip(axes.flat, specs):
    p = fn()
    fld = p.draw(ax=ax, lateral=(-12.5, 12.5), window=(-7.0, 9.5), title=False)
    no_numbers(fld.ax)
    ax.set_title(title, fontsize=7.8, color=style.INK, loc="left", pad=3)
    say(ax, P_of(fld, p), 7.6, -7.0, note, fs=6.2, color=style.DEFENSE_DARK)
fig.tight_layout(h_pad=0.8, w_pad=0.6)
plt.show()
Figure 66.3: Five on the line, two ways (illustrative; the box only, against 11 personnel with the tight end attached on the right). Top row, Fangio. A, his everyday nickel against three receivers: two linemen inside in 4i-techniques, two stand-up edges, and two inside linebackers (M, W) behind them, a 2-4-5. What you see rushes. B, the tite: five on the line and one linebacker, and the tight-end-side edge (purple) drops, as in Figure 66.1. Most snaps it is the same edge, from the same spot. Bottom row, Macdonald, from the same personnel. C, the Mike walked up into the left A gap makes five on the line; at the snap the right edge (purple) drops and the Will (green), standing in the second level, rushes. D, an edge stands up over the right guard and the third safety (S, green) walks up outside the tight end; at the snap the edge over the guard (purple) drops into the middle and the safety rushes off the edge. All four pictures send four. The difference is how much the offense can learn from who is standing where.
Show the Python
order = ["base (4 DBs)", "nickel (5 DBs)", "big nickel (5 DBs, 3+ safeties)", "dime (6+ DBs)"]
rows = [("League", PERS_LG.loc[2025]), ("Eagles (Fangio)", PERS.loc[(2025, "PHI")]),
        ("Seahawks (Macdonald)", PERS.loc[(2025, "SEA")])]
cols = [style.MUTED, style.SERIES[0], style.SERIES[1], style.SERIES[6]]
fig, ax = plt.subplots(figsize=(6.5, 2.2))
for i, (name, r) in enumerate(rows):
    left = 0.0
    for k, c in zip(order, cols):
        v = float(r.get(k, 0.0))
        ax.barh(i, v, left=left, color=c, height=0.62, edgecolor="white", lw=0.8)
        if v >= 0.07:
            ax.text(left + v / 2, i, pct(v), ha="center", va="center", fontsize=7.2,
                    color="white" if c != style.MUTED else style.INK, fontweight="bold")
        left += v
ax.set_yticks(range(len(rows)), [r[0] for r in rows], fontsize=8)
ax.invert_yaxis()
ax.set_xlim(0, 1)
ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda v, _: f"{v:.0%}"))
ax.tick_params(axis="x", labelsize=7)
ax.grid(axis="y", visible=False)
ax.legend(handles=[Patch(color=c, label=k) for k, c in zip(order, cols)], loc="upper center",
          bbox_to_anchor=(0.45, -0.18), ncol=4, fontsize=6.8, frameon=False, handlelength=1.2)
fig.tight_layout()
plt.show()
Figure 66.4: Who is on the field on defense, 2025 regular season (all opponent runs and passes with charted personnel). Fangio’s Eagles play two packages (nickel and base) on more than nine snaps in ten. Macdonald’s Seahawks played five- and six-DB packages built around a third safety: the big nickel on more than half their snaps, and dime on about one in six (every Seattle dime snap also had three or more safeties). Across the league, about a quarter of snaps had three or more safeties on the field. Same two-high philosophy, very different bodies: the Seahawks’ third safety is the piece that lets the same picture become a different front or a different rusher. Source: nflverse participation data (FTN charting), course calculation.

The personnel is also the clearest record of how Macdonald built the Seattle defense. His first Seahawks defense, in 2024, was good, not great: 11th in points allowed and 12th in EPA per dropback, by this book’s count. It played the big nickel on only 6% of snaps. In 2025, with the rookie Emmanwori, that share was 56%, and the defense was 1st in points and 1st against the run. Next Gen Stats ties the late-season jump in split-safety coverage to a second piece, Julian Love’s return from injured reserve in Week 14.24 Same coach, same ideas; the second year had the bodies that let one picture hide more.

Put the four together and you get McDaniels’s complaint. Sixty-five of seventy snaps look the same, two safeties deep, a crowded line, three safeties somewhere, and from that one picture the defense can play quarters with a four-man rush from the usual spots, Cover 6 with a linebacker rushing and an edge dropping, Cover 3 with a safety rotating down, or, rarely, a real blitz. The quarterback can’t set the protection with confidence and can’t pick a side of the field with confidence. He has to find out after the snap, which is the slowest and most dangerous time to find anything out.

ImportantWhy it exists

Fangio’s system hides the coverage; Macdonald’s hides everything. Once two-high became the league’s default, its predictability became the weakness. Offenses knew a Fangio-style defense would rush four from known spots and leave six in the box, so they could set protections, plan quick throws and build run plays for that exact box. Multiplicity takes those pre-snap certainties away without giving up the two-high coverage that stops explosive plays. The cost is complexity: a defense this multiple needs smart, versatile players (expensive and rare), a lot of practice time, and a play-caller who can manage it all in real time. The call reaches the field through one radio helmet, the green dot, and the other ten have to hear it, adjust it to motion, and check out of it together. When that communication fails, the busts are spectacular: a receiver running free because two defenders each thought the other had him.

The double lie, step by step

Here is the idea in one play: a pressure look and a two-high shell before the snap, a different rush and a different coverage after it. It is drawn the way Seattle’s own description suggests, five on the line with one of them dropping, plus a late safety rotation, and it uses panel C of Figure 66.3.

Show the Python
def double_lie():
    off = eleven_2x2()
    dfn = [D("LE", "OLB", 1.0, -5.6, "E"), D("LT_", "DT", 1.0, T("3", -1), "T"), D("RT_", "DT", 1.0, T("2i", 1), "T"),
           D("RE", "OLB", 1.0, 5.6, "E"), D("MIKE", "LB", 4.6, 0.6, "M"), D("WILL", "LB", 5.0, 3.6, "W"),
           D("NB", "NB", 5.0, -8.5, "$"), D("LCB", "CB", 8.5, -15.6, "CB"), D("RCB", "CB", 8.5, 15.6, "CB"),
           D("FS", "FS", 13.0, -7.5, "FS"), D("SS", "SS", 13.0, 7.5, "SS")]
    p = Play(off, dfn, los=40, to_go=7)
    # pre-snap: the Mike walks into the left A gap (mugged, about 2 yards off the ball), the Will creeps
    p.motion("MIKE", to=(2.0, -0.8), speed=1.6)
    p.motion("WILL", to=(3.5, 3.0), speed=0.8)
    # offense: dagger-style concept to the right (Y clears up the seam, Z digs under him), a go and a hitch left
    p.route("Z", [(4, 0), (12, 0), (12, -11)], absolute=False)
    p.route("Y", [(9, 0.0), (16.5, -1.0)]); p.route("X", [(19.5, 0)]); p.route("H", [(5, 0)])
    p.dropback(2.5)
    p.pass_to("Z", t=2.1)
    # protection: the line blocks the men on it; the back is responsible for the Will if he comes
    for k, to in (("LT", (-1.4, -4.6)), ("LG", (-1.3, -2.2)), ("C", (-1.2, -0.7)), ("RG", (-1.3, 1.5)),
                  ("RT", (-1.6, 4.4))):
        go_to(p, k, to, "block", speed=1.5)
    go_to(p, "RB", (-3.3, 2.5), "path", speed=2.0, delay=0.3)
    # the rush: both tackles, the left end and the Will
    go_to(p, "LE", (-1.0, -5.2), "rush", speed=2.0); go_to(p, "LT_", (-0.4, -2.4), "rush", speed=1.2)
    go_to(p, "RT_", (-0.4, 1.4), "rush", speed=1.2)
    go_to(p, "WILL", (-0.6, 2.6), "rush", speed=3.6, delay=0.1)
    go_to(p, "WILL", (-2.6, 2.4), "rush", speed=2.2)
    # the drops: the Mike backs out to the hook, the right edge walls Y and carries him up the seam
    p.drop("MIKE", (7.5, -1.5), speed=4.0, delay=0.15)
    p.drop("RE", (10.0, 8.6), speed=4.2, delay=0.1)
    p.drop("NB", (6.5, -12.0), speed=4.0)
    # the rotation: SS down to the hole, FS to the deep middle (shaded to the seam), corners to deep thirds
    p.drop("SS", (10.5, 3.4), speed=4.0, delay=0.15)
    p.drop("FS", (17.5, 3.0), speed=5.5, delay=0.1)
    p.drop("LCB", (17.0, -16.5), speed=4.8); p.drop("RCB", (16.0, 15.0), speed=4.8)
    p.highlight("SS")
    p.highlight("RE", color=PURPLE)
    return p


DL = double_lie()
DL_T0 = DL._compile()[1]
DL_T = [-1.8, 0.0, 1.1, 3.0]
show_play(DL, DL_T,
          ["1 · −1.8 s: two-high; the Mike walks\ninto the A gap, the Will creeps",
           "2 · Snap: five on the line,\nsix could come",
           "3 · +1.1 s: M and E drop, W rushes;\nSS down, FS to the middle",
           "4 · +3.0 s: four rushed, seven covered:\nthe dig meets the robber"],
          phases([(-0.05, "Before the snap: two-high shell; five on the line, the Will creeping"),
                  (0.6, "The snap: the Mike and the right edge drop; the Will rushes"),
                  (2.05, "The rotation: SS to the hole, FS to the deep middle (Cover 3 robber)"),
                  (9.0, "The dig to Z is thrown into the robber")]),
          annot={2: lambda ax, P: point_to(ax, P, (-6.0, 4.6), tuple(DL.position("WILL", 1.1)), "W rushes", fs=6.2),
                 3: lambda ax, P: (point_to(ax, P, (14.0, 12.0), tuple(DL.position("Z", 3.0)), "dig (Z)", fs=6.2),
                                   point_to(ax, P, (13.5, -8.5), tuple(DL.position("SS", 3.0)), "robber (SS)",
                                            fs=6.2))},
          ghosts=("MIKE", "RE", "WILL", "SS", "FS"), ghost_t=DL_T0, lateral=(-19.5, 19.5), window=(-8.5, 21.5))
Figure 66.5: The double lie (simulated, BDB-format tracking generated by gridiron; illustrative, not a specific Seahawks call). Third-and-7. 1: before the snap the defense shows two-high, and the Mike (M) walks up into the left A gap: with the four linemen that is five on the line, and the Will (W) creeps to about three and a half yards, so six could rush. The nickel ($) could just as well be Seattle’s third safety; the picture is the same. 2: at the snap nothing has moved in the secondary. 3: the lie about the rush. The Mike backs out to the hook and the right edge (E, purple ring) drops to wall off the tight end (Y), while the Will rushes through the right B gap and the back steps up to block him. Four rush: one of them (W) a player the protection had to guess about, and two of the six it counted (M, E) are in coverage. The lie about the coverage: the strong safety (SS, green ring) comes down to the hole, the short middle at about 10 yards, and the free safety runs to the deep middle, so two-high has become Cover 3 with a robber. 4: the dropped edge has carried Y up the seam until the free safety, shaded to that side, takes him. The quarterback, who saw an open middle before the snap and a blitz threat to his left, throws the dig to Z; it arrives where the robber is. Dashed outlines show where the defenders started.

Count the lies. Before the snap the quarterback saw five on the line and a creeping Will: six possible rushers for six blockers. The line takes the five men on it, which leaves the Will to the back. But nobody knows before the snap whether the Will is coming, so the back has to stay in and wait to find out; that is the guess. If the Will drops, the back blocks nobody, and either way he isn’t running a route, so four receivers face seven defenders. The quarterback also saw two safeties deep with an open middle, so the dig behind the linebackers looked like the right throw. After the snap there were four rushers, two of the “rushers” were in coverage (the Mike in the short middle, exactly where a hot throw would go), and the open middle had a robber in it. Neither lie is new. Fire zones have dropped linemen since the 1990s (Zone Blitzes), and two-high rotation is Fangio’s. The modern step is doing both from the same picture, with the same personnel, and mixing them with plays on which nothing changes at all, so the quarterback can never assume a lie.

CautionCommon misconception

“Macdonald’s defense is a blitz defense.” It’s the opposite. Seattle sent five or more rushers on 22% of dropbacks in 2025 (25th-most of 32) and his 2023 Ravens on 21%. What looks like a blitz is usually a pressure look: more players near the line than will rush. The pressure comes from where the four come from and when the offense finds out, not from how many there are.

NoteFilm room: Baltimore Ravens 2023 — multiplicity with a third safety

Macdonald’s second Ravens defense allowed 280 points, the fewest in the league, and led the NFL with 60 sacks while blitzing at a below-average rate. (Its charted pressure rate was only 18th, near the middle; the sacks came from finishing: by this book’s count Baltimore turned pressures into sacks at the 2nd-highest rate in the league.) Its signature was personnel: by this book’s count Baltimore had five defensive backs on the field, three or more of them safeties, on about three snaps in four, with Kyle Hamilton, a 6-foot-4 safety, as the piece that decided what each snap was: deep safety, slot defender, linebacker or rusher (A First Look at Defense has the personnel film room; Zone Blitzes has the pressure film room).25

What to notice: on a 2023 Ravens passing down, find number 14 before the snap, then find him one second after. Then do the same for the biggest defensive lineman. The less their pre-snap spots predict their post-snap jobs, the more multiple the defense is.

Super Bowl LX: Seattle against Drake Maye, dropback by dropback

Macdonald’s second Seattle team went 14–3, allowed 292 points (the fewest in the league) and, by this book’s count, ranked 1st in EPA per designed run allowed. It reached Super Bowl LX against a New England offense led by Drake Maye, second in the MVP vote, and coordinated by McDaniels, who had spent two weeks studying the picture he said would look the same 65 times.26

Show the Python
FAM_C = {"two": style.DEFENSE, "one": style.OFFENSE, "other": style.MUTED}
fig, ax = plt.subplots(figsize=(6.6, 2.7))
NMAX = int(LXD.groupby("qtr").size().max())
ax.set_xlim(-2.6, NMAX + 0.4); ax.set_ylim(-0.7, 4.4); ax.axis("off")
for q in (1, 2, 3, 4):
    rows = LXD[LXD.qtr == q].reset_index(drop=True)
    y = 4 - q
    ax.text(-0.9, y, f"Q{q}", ha="right", va="center", fontsize=8.5, fontweight="bold", color=style.INK)
    for i, r in rows.iterrows():
        ax.add_patch(FancyBboxPatch((i + 0.06, y - 0.32), 0.88, 0.64, boxstyle="round,pad=0,rounding_size=0.1",
                                    fc=FAM_C[r.fam], ec="white", lw=0.6))
        n = r.number_of_pass_rushers
        ax.text(i + 0.5, y, "" if pd.isna(n) else f"{int(n)}", ha="center", va="center", fontsize=6.6,
                color="white", fontweight="bold")
        mark = "S" if r.sack == 1 else "I" if r.interception == 1 else "T" if r.touchdown == 1 else ""
        if mark:
            ax.text(i + 0.5, y + 0.5, mark, ha="center", va="center", fontsize=6.4, fontweight="bold",
                    color=style.INK)
        elif r.press:
            ax.plot(i + 0.5, y + 0.47, "o", ms=2.6, color=style.INK)
ax.legend(handles=[Patch(color=style.DEFENSE, label="two-high coverage"),
                   Patch(color=style.OFFENSE, label="one-high coverage"),
                   Patch(color=style.MUTED, label="combination"),
                   Line2D([], [], marker="o", ls="", ms=3, color=style.INK, label="pressured")],
          loc="lower center", bbox_to_anchor=(0.5, -0.12), ncol=4, fontsize=7, frameon=False)
fig.tight_layout()
plt.show()
Figure 66.6: Every New England dropback in Super Bowl LX (Seahawks 29, Patriots 13), in order, one row per quarter. The fourth-quarter row is the longest because New England, trailing, went no-huddle and threw on almost every snap. Each square is one dropback: orange if Seattle’s coverage was charted as two-high after the snap (Cover 2, 2-Man, quarters, Cover 6), blue if one-high (Cover 1, Cover 3, Cover 9, Cover 0), grey if charted as a combination. The number in the square is how many rushed. Marks above the squares: S a sack, I an interception, T a New England touchdown; a dot means the quarterback was pressured. Seattle rushed four on almost every snap and played two-high on most of them; New England’s only points came in the fourth quarter, much of it in no-huddle catch-up mode. Source: nflverse play-by-play and participation (FTN charting); course calculation. Charted labels, not tracking: other charters may code some snaps differently.

Read Figure 66.6 row by row.

  • Four rushers, on six dropbacks in seven. Seattle rushed exactly four on 45 of New England’s 53 dropbacks and five or more on only 8. The pressure came anyway: Maye was pressured or sacked on 15 dropbacks and sacked 6 times: twice by defensive tackle Byron Murphy II, twice by edge rusher Derick Hall (the second a strip-sack), once by Rylie Mills and once by Witherspoon.
  • Two-high, mostly, and a lot of Cover 2. Of the dropbacks with a single coverage label, 37 of 51 were charted two-high, led by 16 Cover 2 and 13 Cover 6, with 9 Cover 1 snaps mixed in. The Cover 2 is mostly a fourth-quarter story: 10 of those snaps came in the fourth quarter, with Seattle ahead and New England in the hurry-up. Cover 2 sits the corners on the short outside throws and keeps two safeties over the top, so everything stays in front of the defense and the clock keeps running, which is what a team with a lead wants. The deep ball never came: New England’s longest completion before the fourth quarter gained 21 yards.
  • The run never mattered. Seattle didn’t stay light against the run: of New England’s 13 designed runs, 9 met seven or more defenders in the box and only 4 met six or fewer. The running backs carried 13 times for 42 yards, and once New England fell behind it stopped running. Multiplicity includes the option to be heavy (the data section below shows the 2023 Ravens doing the same all season). Seattle’s own offense, meanwhile, controlled the clock: Kenneth Walker III ran 27 times for 135 yards and was named MVP.
  • The scoreboard. Seattle led 9–0 at halftime and 12–0 after three quarters, all on Jason Myers field goals. Through three quarters New England averaged -0.67 EPA per dropback. For scale, the median NFL defense in 2025 allowed +0.05 per dropback over the season (Table 66.1), so this was a collapse. The fourth quarter looks different on Figure 66.6: trailing, New England went no-huddle on 57% of its snaps and threw on almost all of them, so the row has 28 dropbacks against 7 to 10 in the others, and its EPA per dropback rose to -0.01 against a defense content to keep everything in front of it. The first T is New England’s first points, with 12:33 left: a 35-yard touchdown pass from Maye to Mack Hollins against Cover 6. Then come the two I’s. Julian Love intercepted a deep throw down the middle against a four-man rush, and Uchenna Nwosu sealed the game with a 45-yard interception return for a touchdown, on one of Seattle’s rare five-man rushes, with Witherspoon blitzing. The last T is Rhamondre Stevenson’s late touchdown catch.27
NoteFilm room: Super Bowl LX — the picture and the plays

What to notice: watch any five New England third downs from the first half. Before the snap, look at Seattle’s safeties and count the defenders near the line. The picture barely changes: two deep, a crowded line, a third safety somewhere in the middle. Then, at the snap, count who actually rushes (almost always four) and where the safeties end up. On the third-and-15 in the first quarter, Witherspoon, a cornerback, was the sixth rusher and got the sack. On others, nobody came but the four linemen and the coverage was Cover 2 or Cover 6. Same picture, different plays: that is McDaniels’s 65 out of 70, and Maye, a quarterback who had torn the league apart in 2025, spent three quarters finding out after the snap what he was facing.

The data fingerprint: two philosophies in numbers

The case-study question is whether the two philosophies leave different fingerprints in the data, and what the data cannot see. Start with a table of the defenses in this chapter.

Show the Python
ROWS = [(2018, "CHI", "Bears 2018", "Fangio (DC)"), (2020, "LA", "Rams 2020", "Staley (DC)"),
        (2023, "BAL", "Ravens 2023", "Macdonald (DC)"), (2024, "PHI", "Eagles 2024", "Fangio (DC)"),
        (2024, "LAC", "Chargers 2024", "Minter (DC)"), (2025, "SEA", "Seahawks 2025", "Macdonald (HC)"),
        (2025, "PHI", "Eagles 2025", "Fangio (DC)")]
md = ("| Defense | Caller | Pts | EPA/db | Run EPA | Two-high | 5+ rush | Pressure | Light box |\n"
      "|:--------|:-------|----:|-----:|-----:|-----:|-----:|-----:|-----:|\n")
for season, team, name, who in ROWS:
    r = TEAM.loc[(season, team)]
    md += (f"| {name} | {who} | {int(r.pa)} ({int(r.pa_rk)}) | {r.epa:+.2f} ({int(r.epa_rk)}) | "
           f"{r.run_epa:+.2f} ({int(r.run_epa_rk)}) | "
           f"{pct(r.two)} ({int(r.two_rk)}) | {pct(r.blitz)} ({int(r.blitz_rk)}) | {pct(r.press)} ({int(r.press_rk)}) | "
           f"{pct(r.light)} ({int(r.light_rk)}) |\n")
m25 = MED.loc[2025]
md += (f"| *League median, 2025* | | *{int(m25.pa)}* | *{m25.epa:+.2f}* | *{m25.run_epa:+.2f}* | *{pct(m25.two)}* | "
       f"*{pct(m25.blitz)}* | *{pct(m25.press)}* | *{pct(m25.light)}* |\n")
FP = pd.DataFrame([TEAM.loc[(se, t)] for se, t, _, _ in ROWS])
PR_LO, PR_HI = int(FP.press_rk.min()), int(FP.press_rk.max())
RUN_TOP10 = int((FP.run_epa_rk <= 10).sum())
display(Markdown(md))
Table 66.1: The defenses of this chapter in the charting data (regular seasons). Each cell gives the value and, in parentheses, the league rank among 32 (1 = fewest points or EPA allowed, or the highest rate in the other columns). Pts is points allowed. EPA/db is EPA allowed per opponent dropback; Run EPA is EPA allowed per designed run (scrambles excluded). Two-high is the coverage played after the snap, as a share of dropbacks with a charted coverage. 5+ rush is the share of dropbacks with five or more rushers. Pressure is pressures or sacks per dropback. Light box is the share of designed runs that met six or fewer defenders in the box. The 2018-2022 charting comes from Next Gen Stats and 2023-2025 from FTN, and pressure and coverage are coded differently on each side of that break, so compare ranks within a season, not raw values across the break. Sources: nflverse play-by-play, participation and schedules; course calculation.
Defense Caller Pts EPA/db Run EPA Two-high 5+ rush Pressure Light box
Bears 2018 Fangio (DC) 283 (1) -0.11 (1) -0.21 (2) 33% (16) 21% (28) 34% (8) 62% (1)
Rams 2020 Staley (DC) 296 (1) -0.18 (1) -0.18 (2) 40% (12) 26% (17) 31% (9) 68% (1)
Ravens 2023 Macdonald (DC) 280 (1) -0.18 (2) -0.08 (15) 39% (22) 21% (21) 29% (18) 36% (27)
Eagles 2024 Fangio (DC) 303 (2) -0.05 (2) -0.17 (1) 34% (27) 19% (28) 31% (17) 66% (3)
Chargers 2024 Minter (DC) 301 (1) -0.03 (6) -0.12 (8) 47% (3) 22% (24) 30% (18) 76% (2)
Seahawks 2025 Macdonald (HC) 292 (1) -0.08 (6) -0.19 (1) 52% (3) 22% (25) 34% (4) 74% (2)
Eagles 2025 Fangio (DC) 325 (5) -0.07 (7) -0.10 (7) 36% (28) 19% (31) 33% (8) 68% (3)
League median, 2025 385 +0.05 -0.05 43% 27% 30% 55%

Three patterns stand out in Table 66.1.

  1. None of these defenses blitzes much. Every one sits in the bottom half of the league in five-man rushes, most of them near the bottom. Both philosophies are four-man-rush philosophies. Their pressure rates rank from 4th to 18th: from the top of the league to its middle, despite rarely blitzing. The point of the system is to make four rushers enough, and the middle of the league is often enough when the coverage behind it holds.
  2. Most of them play light boxes, and the best of them stopped the run anyway. Most rank near the top of the league for runs against six or fewer in the box: the light-box bargain of decision 2. Yet 6 of the seven rank in the top ten in EPA allowed per designed run (the Run EPA column), the 2025 Seahawks first. The clear exception on box count is the 2023 Ravens, who met most runs with seven or more in the box: being multiple includes the option to be heavy.
  3. The two-high column doesn’t separate them, and it can’t. The 2023 Ravens and 2024 Eagles were in the bottom half of the league in two-high coverage after the snap (22nd and 27th); the 2025 Seahawks near the top. All three are known for starting from two-high shells. That is decision 5’s warning paid off: the difference between “showed” and “played” is the disguise itself, and no column in the public data records what a defense showed.

Now the whole league: two-high rate against pressure rate, every team for the three FTN-charted seasons, with the blitz rate alongside, so you can see where the two philosophies sit in the league.

Show the Python
SC = TEAM.loc[[2023, 2024, 2025]].reset_index()
HL = {(2024, "PHI"): ("PHI '24", style.SERIES[0]), (2025, "PHI"): ("PHI '25", style.SERIES[0]),
      (2023, "BAL"): ("BAL '23", style.SERIES[1]), (2024, "SEA"): ("SEA '24", style.SERIES[1]),
      (2025, "SEA"): ("SEA '25", style.SERIES[1])}
OFFS = {"left": {(2024, "PHI"): (-0.012, 0.010), (2025, "PHI"): (-0.012, 0.010), (2023, "BAL"): (-0.012, -0.012),
                 (2024, "SEA"): (0.010, -0.011), (2025, "SEA"): (-0.010, 0.010)},
        "right": {(2024, "PHI"): (-0.010, -0.006), (2025, "PHI"): (-0.010, 0.002), (2023, "BAL"): (0.010, -0.010),
                  (2024, "SEA"): (0.011, -0.004), (2025, "SEA"): (0.011, 0.007)}}
fig, axes = plt.subplots(1, 2, figsize=(6.6, 3.3), sharey=True)
for ax, xcol, xlab, side in ((axes[0], "two", "Two-high coverage (share of dropbacks)", "left"),
                             (axes[1], "blitz", "Five or more rushers (share of dropbacks)", "right")):
    ax.scatter(SC[xcol], SC.press, s=14, color=style.BASELINE, zorder=2, lw=0)
    ax.axvline(SC[xcol].median(), color=style.MUTED, lw=0.8, ls=(0, (4, 3)), zorder=1)
    ax.axhline(SC.press.median(), color=style.MUTED, lw=0.8, ls=(0, (4, 3)), zorder=1)
    for (season, team), (lab, c) in HL.items():
        r = SC[(SC.season == season) & (SC.defteam == team)].iloc[0]
        ax.scatter(r[xcol], r.press, s=34, color=c, zorder=4, edgecolor="white", lw=0.6)
        dx, dy = OFFS[side][(season, team)]
        ax.text(r[xcol] + dx, r.press + dy, lab, fontsize=6.8, color=style.INK, zorder=5,
                ha="left" if dx > 0 else "right", va="center")
    ax.set_xlabel(xlab, fontsize=7.5)
    ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda v, _: f"{v:.0%}"))
    ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda v, _: f"{v:.0%}"))
    ax.tick_params(labelsize=7)
axes[0].set_ylabel("Pressure rate", fontsize=7.5)
axes[1].text(SC.blitz.max(), SC.press.min() + 0.002, "blitz-heavy\ndefenses", fontsize=6.4, color=style.INK_2,
             ha="right", va="bottom")
axes[1].text(SC.blitz.min(), SC.press.max(), "pressure without\nthe blitz", fontsize=6.4, color=style.INK_2,
             ha="left", va="top")
axes[0].legend(handles=[Line2D([], [], marker="o", ls="", color=style.SERIES[0], label="Fangio (Eagles)"),
                        Line2D([], [], marker="o", ls="", color=style.SERIES[1], label="Macdonald (Ravens, Seahawks)")],
               loc="upper left", fontsize=6.6, frameon=False)
fig.tight_layout(w_pad=1.0)
plt.show()
Figure 66.7: Every NFL defense, 2023-2025 (96 team-seasons, FTN charting, regular seasons). Left: two-high coverage after the snap (across) against pressure rate (up). Right: blitz rate, five or more rushers (across), against the same pressure rate. Grey dots are other teams; the Fangio and Macdonald defenses are colored and labelled. On the left the named defenses are spread across the range: two-high coverage isn’t what unites them. On the right they cluster on the low-blitz side, most of them at or above the league’s middle in pressure rate; BAL ’23 sits below it, but finished more of its pressures as sacks than almost anyone (see the Ravens film room). That side of the chart, pressure without the blitz, is the common ground of the two philosophies. Dashed lines are the medians of all 96. Source: nflverse play-by-play and participation; course calculation.

What the data can’t see: the disguise

The column every reader of this chapter most wants, how often a defense showed one shell and played another, isn’t in any free public file: the nflverse charting has no field for the safeties’ alignment before the snap. (Some charting services estimate the shell by eye, and Next Gen Stats has published a pre-snap disguise model, but neither is open data.) There is one way to measure it yourself: tracking data. The 2025 Big Data Bowl released every frame of every play from Weeks 1–9 of the 2022 season, including the frames before the snap, together with the charted coverage. With it you can call the shell from the safeties’ depth and width at the snap and compare it with the coverage label, play by play. Tracking Data and the Big Data Bowl builds this from the ground up; 06-06 shows the safety-rotation figure that comes out of it. The cell below is the core of that calculation (it isn’t run here, because the Big Data Bowl files aren’t distributed with this book).28

Show the Python (shell at the snap vs coverage after it, from real Big Data Bowl 2025 tracking: not run here)
import pandas as pd
from gridiron import bdb

trk = bdb.load_tracking("data/bdb/tracking_week_*.csv")      # BDB 2025: 2022 season, Weeks 1-9
plays = pd.read_csv("data/bdb/plays.csv")
players = pd.read_csv("data/bdb/players.csv")
# raw coordinates on purpose: absoluteYardlineNumber is in the same (unflipped) frame as x
TWO_HIGH = {"Cover-2", "2-Man", "Quarters", "Cover-6 Right", "Cover 6-Left"}
ONE_HIGH = {"Cover-0", "Cover-1", "Cover-1 Double", "Cover-3", "Cover-3 Seam", "Cover-3 Cloud Left",
            "Cover-3 Cloud Right", "Cover-3 Double Cloud"}             # drop Red Zone, Goal Line, Bracket, Prevent, Misc.
plays = plays[plays.pff_passCoverage.isin(TWO_HIGH | ONE_HIGH)]

snap = trk[trk.frameType == "SNAP"].merge(players[["nflId", "position"]], on="nflId")
snap = snap.merge(plays[["gameId", "playId", "defensiveTeam", "absoluteYardlineNumber", "pff_passCoverage"]],
                  on=["gameId", "playId"])
saf = snap[snap.position.isin(["FS", "SS"])].copy()
saf["depth"] = (saf.x - saf.absoluteYardlineNumber).abs()     # yards off the line of scrimmage
# shell at the snap: how many safeties are 10+ yards deep
shell = (saf.groupby(["gameId", "playId", "defensiveTeam", "pff_passCoverage"])
            .depth.apply(lambda d: "two-high" if (d >= 10).sum() >= 2 else "one-high").rename("shell")
            .reset_index())
shell["played"] = shell.pff_passCoverage.map(lambda c: "two-high" if c in TWO_HIGH else "one-high")
shell["lie"] = shell.shell != shell.played
print(shell.groupby("defensiveTeam").lie.mean().sort_values(ascending=False).head(10))   # each team's "lie rate"

Two cautions keep that calculation honest. Defenses that rotate before the snap (during the cadence) will be caught at the snap already in their real shell and count as honest, so the lie rate measures late rotation only. And the coverage labels are a charter’s judgment, which can differ between services: the Next Gen Stats article cited earlier says Julian Love’s fourth-quarter interception in Super Bowl LX did not come against split-safety coverage, while FTN’s charting labels the same play 2-Man, a two-high coverage. Treat any lie rate as an estimate with a few percentage points of noise either way.

You can still make a back-of-envelope guess for Seattle. If McDaniels is roughly right that about nine snaps in ten look the same (two-high before the snap), and Seattle played two-high after the snap on 52% of dropbacks, then it rotated out of its shell on at least 38% or so of dropbacks, before counting any lie about the rush. It is an estimate built on a coach’s quote, but it shows the scale.

There is one more number the data offers, as a caution. FTN’s charting counts how many rushers on each play were not regular linemen or edge rushers, and the rate of four-man rushes that included one is the closest public proxy for simulated pressure. By it, the 2025 Seahawks ranked 21st of 32 and the 2025 Eagles 2nd, the reverse of each coach’s reputation, and exactly what Macdonald said (“We do not run a lot of simulated pressures”).29

That looks like a contradiction of Zone Blitzes, whose 2023 Ravens film room calls Baltimore one of the league’s heaviest users of simulated pressure. It mostly isn’t, for three reasons. Different team and season: the same proxy puts the 2023 Ravens 13th, around the middle, not near the bottom like the 2025 Seahawks. Different counting: 07-03’s ranking came from PFF’s charting through Week 6 of 2023, as Cody Alexander reported it, while this proxy depends on how FTN’s charters tag each rusher, and a dropped tackle with a safety rushing in his place is exactly the snap two charters can code differently. Different things: much of what reporters called sim pressure was a pressure look, five or six possible rushers with four coming from the usual spots, which no public column records. The fair reading is that Macdonald’s defenses show the threat far more often than they run a true sim.

How offenses responded

The two-high era produced its own counter-revolution on offense, told as history in The Modern Era. Here is how each answer maps onto the five decisions, and how a multiple defense changes the math.

  • Run into the light box (attacks decision 2). Against six in the box, add a seventh blocker: a second tight end, a fullback, or the quarterback as a runner. In 2025, offenses used fewer than three wide receivers on 41.7% of plays, the highest since Next Gen Stats began tracking personnel, and snaps under center climbed back to about a third.30 A defense that answers by bringing a safety down is one-high again; one that stays two-high is outnumbered. Macdonald’s response was to make the extra defender a safety who looks like a deep player (the third safety of the big nickel), so the offense can’t tell from the personnel whether it has the numbers.
  • Use motion and tempo to force the picture early (attacks decisions 1 and 5). Motion at the snap makes safeties declare before they can disguise, and tempo denies them time to set the picture. New England went no-huddle on much of its fourth quarter in Super Bowl LX, partly from necessity, and moved the ball more against a defense with less time to disguise and every reason to keep it in front.
  • Throw before the rush and the rotation arrive (attacks decision 3). Quick throws and screens beat a four-man rush that needs two and a half seconds, and beat a robber who needs a second to get to the hole (the short middle, 10 to 15 yards deep). The cost is that quick throws are short throws; it is exactly what the two-high defense is willing to give up.
  • Read the safeties after the snap, and throw away from the rotation (attacks decision 5). A two-way concept pairs a route combination that beats two-high coverage on one side with one that beats one-high on the other, so the quarterback picks after the snap (Concepts Versus Coverages).
  • Make the read safety wrong (attacks decision 4). Play-action that shows the safety a blocking tight end, then releases the tight end behind him; RPOs that read the safety directly. This is the cost named in decision 4, cashed.
  • A quarterback who extends plays. Every one of these defenses is built on a timed four-man rush and zone coverage that keeps the ball in front. A quarterback who escapes the rush turns a covered play into a scramble, and zone defenders with their eyes on the quarterback can’t also chase him. In the Super Bowl, Maye’s 4 scrambles gained 38 yards, some of New England’s best plays of the night.

Defenses answered the answers. When offenses went heavy, defenses played more base and big nickel: base defense rose to 29.7% of snaps in 2025, up from 20.5% in 2023.31 When offenses moved at the snap, defenses rehearsed rotating late from motion. When offenses threw quickly, defenses taught their underneath players to break on the ball and tackle. The cycle hasn’t ended; it has just sped up.

CautionCommon misconception

“Two-high defenses are soft against the run.” By this book’s count the 2024 Eagles ranked 1st and the 2025 Seahawks 1st in EPA allowed per designed run, both while meeting most runs with six or fewer in the box. A light box is a choice about who stops the run (the front and late-arriving safeties), not a decision to stop it less. It does give up more yards per carry on average than a loaded box, and it fails badly when the interior linemen aren’t good enough.

Staffs entering 2026

Scheme lives with people, and the people move. The box below shows where the defensive coaches in this chapter stand for the 2026 season, plus the one offensive change that matters most to Seattle’s defense. (The chapter’s numbers stop at the end of the 2025 season; the 2026 season is under way as this is written, so treat everything here as the starting point, not the result.)

Show the Python
STAFF = [
    ("Seahawks", "HC, defensive play-caller", "Mike Macdonald", "Mike Macdonald", False),
    ("", "Defensive coordinator", "Aden Durde", "Aden Durde", False),
    ("", "Offensive coordinator", "Klint Kubiak", "Brian Fleury (from SF)", True),
    ("Eagles", "Defensive coordinator", "Vic Fangio", "Vic Fangio", False),
    ("Ravens", "Head coach", "John Harbaugh", "Jesse Minter (from LAC)", True),
    ("", "Defensive coordinator", "Zach Orr", "Anthony Weaver", True),
    ("Panthers", "Defensive coordinator", "Ejiro Evero", "Ejiro Evero", False),
    ("Rams", "Defensive coordinator", "Chris Shula", "Chris Shula", False),
]
n = len(STAFF)
fig, ax = plt.subplots(figsize=(6.6, 0.27 * n + 1.05))
ax.set_xlim(0, 100); ax.set_ylim(-1.3, n + 1.0); ax.axis("off")
ax.add_patch(FancyBboxPatch((0.5, -1.15), 99, n + 2.0, boxstyle="round,pad=0.2,rounding_size=0.8",
                            fc=style.SURFACE, ec=style.BASELINE, lw=1.1))
X = {"team": 2.5, "role": 17.0, "y25": 48.0, "y26": 70.0}
for key, h in (("team", "Team"), ("role", "Role"), ("y25", "2025 season"), ("y26", "2026 season")):
    ax.text(X[key], n + 0.25, h, fontsize=7.8, fontweight="bold", color=style.INK, va="center")
ax.plot([1.5, 98.5], [n - 0.25, n - 0.25], color=style.BASELINE, lw=0.8)
for i, (team, role, a, b, changed) in enumerate(STAFF):
    y = n - 1 - i
    if team and i:
        ax.plot([1.5, 98.5], [y + 0.5, y + 0.5], color=style.GRID, lw=0.7)
    if changed:
        ax.add_patch(Rectangle((X["y25"] - 1.0, y - 0.38), 98.0 - X["y25"] + 1.0, 0.76, fc=style.DEFENSE_TINT,
                               ec="none"))
    ax.text(X["team"], y, team, fontsize=7.4, fontweight="bold", color=style.INK, va="center")
    ax.text(X["role"], y, role, fontsize=7.0, color=style.INK_2, va="center")
    ax.text(X["y25"], y, a, fontsize=7.2, color=style.INK, va="center")
    ax.text(X["y26"], y, b, fontsize=7.2, color=style.INK, va="center", fontweight="bold" if changed else "normal")
ax.text(2.5, -0.8, "Shaded = changed for 2026.", fontsize=6.3, color=style.INK_2, va="center")
plt.show()
Figure 66.8: Recent staff moves for the defenses in this chapter, the 2025 season against the 2026 season (as of the start of the 2026 season). Shaded rows changed. Seattle kept its head coach, defensive play-caller and coordinator but lost the offensive coordinator who built its run game (Klint Kubiak, now the Raiders’ head coach); Philadelphia kept Fangio; and Jesse Minter, who ran the same targeted two-high coverage for the Chargers, now runs the Ravens. Sources: course fact sheet (team announcements and wire reports), cited in the notes.

The Seattle line is the one to watch. The defense’s architect and play-caller is unchanged, so the multiplicity should be too. The question for 2026 is the other side of the ball: the Kubiak run game that kept Seattle’s defense fresh and ahead on the scoreboard is now Brian Fleury’s, and the 2026 season is the first test of whether it survives the coordinator who built it.32

What survives, and what offenses do next

By 2026 the two-high counterrevolution is no longer a counter anything. It is the default. What survives of Fangio’s system is almost all of it: the two-high shell as the starting picture, the light box held by the front, the four-man rush, quarters and Cover 6 as everyday coverages, and the rotation at the snap. What survives of Macdonald’s is the next layer, which the rest of the league is now copying: three-safety personnel, pressure looks without the blitz, and the conviction that the front should be as hard to read as the coverage.

What do offenses do next? These are predictions, not facts, but each follows from the logic of this chapter, and you can check them against the 2026 season as it unfolds.

  1. More blockers the offense controls. If a multiple defense hides its run defenders among three safeties, the offense’s cleanest counter is to count blockers it controls: 12 and 13 personnel, fullbacks, and quarterbacks who run. Expect the 2025 rise in heavy personnel to continue.
  2. Faster declarations. Motion at the snap, tempo, and fake snap counts all try to make the defense show its real picture before the ball moves. Expect more of all three, especially no-huddle on early downs, which takes away the time a multiple defense needs to set its disguise.
  3. Plays that don’t care. Concepts that work against both two-high and one-high (two-way reads, quick game paired with a deep shot) take the disguise out of play by making the coverage irrelevant.
  4. Attack the dropper and the rotator. Every pressure look ends with someone dropping who doesn’t usually cover, and every rotation ends with a safety arriving late to a spot. Offenses will target the defensive lineman in coverage and the area the rotating safety left.
  5. Quarterbacks who decide after the snap. In the end, multiplicity is a test of how fast a quarterback can process what he sees after the snap. Offenses will keep paying for the quarterbacks who can, and building simpler reads for those who can’t.

And defenses will answer again. The likeliest next step is the one Macdonald has already taken: more players who can do more things, so the same personnel can play every call. The cost of that strategy is in the roster, and it is covered in Building a Roster.

Watch for it on Sunday

TipWatch for it: the disguise audit

Pick one defense (Seattle or Philadelphia is ideal) and chart one half of passing downs on paper. You need three columns and about 25 rows.

  • Column 1, at the snap: the shell. Two-high or one-high? Count the safeties 10 or more yards deep as the ball is snapped (the center’s head goes down), not when the offense first sets: many defenses spin a second before the snap, and that is a pre-snap rotation, not a lie. Note anything unusual: a linebacker in an A gap, five on the line, a safety creeping.
  • Column 2, one second after the snap: what it became. Is the middle of the field closed (one deep safety) or open (two)? How many rushed (count the defenders who crossed the line)? Did anyone who looked like a rusher drop?
  • Column 3: the lie. Mark R if the shell changed (two-high to one-high or back), P if the rush changed (a pressure look that sent four, or a quiet look that sent five), RP for both, and S for same. A worked row: “2-high, M in the A gap, 5 on the line | 1-high, 4 rushed, M dropped | RP.”

At the end, compute the defense’s lie rate: the share of rows that aren’t S. Then split it. A Fangio defense should lie mostly with R (the coverage); a Macdonald defense with both R and P. For scale, one charted NFL defense built around disguise (Evero’s Carolina, by MatchQuarters’ count) rotated out of its two-high shell on about half the snaps that started there (Disguise, Rotation, and Split-Field Coverage). Use the high, wide replay for column 2; the live angle often cuts off the safeties.

Predict the play

TipPredict the play

Drill 1: six against six. First-and-10 from your own 35. You are the offense, in 11 personnel with the tight end attached on the right. The defense shows its base picture: tite front, one linebacker, two safeties at 12 yards.

Show the Python
p1 = Play(eleven_attached(), tite_quarters(), los=35, to_go=10)
p1.highlight("FS", "SS")
fld = p1.draw(lateral=(-26.6, 26.6), window=(-8, 17))
no_numbers(fld.ax)
ruler(fld, p1, top=15)
plt.show()
Figure 66.9: Drill 1: first-and-10. 11 personnel, tight end (Y) attached on the right, back (R) offset right. The defense: nickel tite (E, 4i, 0, 4i, E), one linebacker (M), the nickel ($) inside the left slot, corners 7 off, safeties about 12 deep (ringed). Count the box.

The numbers say run: six blockers, six in the box, and the two deep safeties are 12 yards away. Which run do you call, and what is the defense counting on to stop it?

A run that doesn’t go where the tite is strongest: wide, or with a seventh blocker. The tite is built to stop inside runs. The nose and the two 4is wall off the A and B gaps, and the Mike is free to fill whatever gap is left. An inside zone into that wall is the run the defense wants you to call. Two better choices:

  • Outside zone or a toss to the tight-end side, which asks the edge (E) to hold up against Y and puts the ball in the alley, where the strong safety has to come 12 yards to tackle. A tite pulls its linemen inside to choke the inside runs, which empties the gaps outside the tackles (05-03’s section “Inside zone or outside zone? How a front chooses” in Odd and Hybrid Fronts draws it). It may gain five; that is the bargain.
  • Add a seventh blocker without changing personnel: motion Z down into a wing or a crack block, or read the backside edge with the quarterback (a zone read), so one defender is left unblocked on purpose. The motion isn’t free, though: a match-quarters corner usually travels with Z or trades assignments with his safety, so the extra blocker brings an extra defender with him.

What the defense is counting on: that its interior linemen win their one-on-ones, and that the safeties tackle in space. And there is a trap. If Y blocks, the strong safety’s read says “run” and he comes downhill, so the same picture is a play-action opportunity: fake the run, release Y behind the safety.

TipPredict the play

Drill 2: the crowded line. Third-and-7 at midfield. Seattle shows two safeties deep, both linebackers walked up, and five defenders on the line.

Show the Python
d2 = double_lie()
p2 = Play([pl for pl in d2.players.values() if pl.side == "off"],
          [pl.moved(d=2.0, w=-0.8) if pl.key == "MIKE" else pl.moved(d=3.5, w=2.2) if pl.key == "WILL" else pl
           for pl in d2.players.values() if pl.side == "def"], los=50, to_go=7)
p2.highlight("WILL")
fld = p2.draw(lateral=(-25, 25), window=(-8, 17))
no_numbers(fld.ax)
ruler(fld, p2, top=15)
plt.show()
Figure 66.10: Drill 2: third-and-7. 11 personnel, 2x2. The defense: two safeties 13 deep; four linemen, plus the Mike (M) walked up into the left A gap about two yards off the ball, for five on the line; the Will (W, ringed) at about three and a half yards over the right guard; the nickel ($) over the left slot. Six possible rushers against six blockers (five linemen and the back).

How many will rush, and what should the quarterback plan to do?

Most likely four, and the coverage is unknown until the snap. Seattle rushed exactly four on 76% of opponents’ dropbacks in 2025 and on 45 of 53 in the Super Bowl. Six could come, so the protection has to account for six (five linemen and the back), but expect one or two of the crowded players to drop, and expect the dropper to land in the short middle, right where a quick hot throw against a blitz would go.

The plan, then:

  • Don’t throw hot to the short middle the Mike appears to vacate. That is exactly where he drops.
  • Protect six, and give the back the Will. The line takes the five on it, and the back is responsible for the Will if he comes; if the Will drops, the back check-releases (waits a beat, then runs a short route).
  • Attack the dropper. If a lineman or edge drops (here, most likely the right edge), throw into his zone: a quick out or stick route by Y, or a seam the dropped edge has to carry. An edge rusher is rarely the quickest man in coverage.
  • Then read the safeties. If one rotates down (as in Figure 66.5), throw away from him, outside the numbers on the side he left. If both stay deep, the throws that beat two-high are open: a curl-flat combination outside, or a dig under the safeties if the Mike drops shallow.

This is what “finding out after the snap” means, and it is the moment the defense was built to win.

TipPredict the play

Drill 3: the heavy answer. First-and-10. The offense comes out in 12 personnel, quarterback under center, both tight ends attached. The defense stays in its nickel two-high shell.

Show the Python
dfn3 = [D("LE", "DE", 1.0, -5.7, "E"), D("L3", "DT", 1.0, T("3", -1), "T"), D("R1", "DT", 1.0, T("1", 1), "T"),
        D("RE", "DE", 1.0, 5.7, "E"), D("MIKE", "LB", 4.6, 1.5, "M"), D("WILL", "LB", 4.6, -2.5, "W"),
        D("NB", "NB", 5.5, -9.0, "$"), D("LCB", "CB", 7.0, -14.6, "CB"), D("RCB", "CB", 7.0, 14.6, "CB"),
        D("FS", "FS", 12.5, -7.5, "FS"), D("SS", "SS", 12.5, 7.5, "SS")]
p3 = Play(twelve_under_center(), dfn3, los=30, to_go=10)
p3.highlight("FS", "SS")
fld = p3.draw(lateral=(-26.6, 26.6), window=(-9, 17))
no_numbers(fld.ax)
ruler(fld, p3, top=15)
plt.show()
Figure 66.11: Drill 3: first-and-10. 12 personnel under center: tight ends U (left) and Y (right) attached, X and Z off the ball, a single back. The defense is still in nickel: a four-man line, two linebackers (M, W), the nickel ($), corners, and two safeties about 12 deep (ringed). Count blockers and box defenders.

Who has the numbers in the run game, and what are the defense’s options before the ball is snapped?

The offense does, before the snap: seven blockers (five linemen and two tight ends) against six in the box (four linemen and two linebackers; the nickel is outside the box over the left side). The defense has four answers, and each one is the trade this chapter has been about:

  • Let the reads do it. This is the main reason quarters exists. Each safety’s #2 is a tight end: U for the free safety, Y for the strong safety. If U and Y block, both safeties read run at once and fit (Y’s side into the alley, U’s side into the cutback), so the defense has eight run defenders after the snap without showing them before it. The price: the safeties arrive at four or five yards, not at the line, and the play-action trap from Drill 1 is now available on both sides.
  • Match the personnel. Sub to base (a third linebacker, or Fangio’s 3-4 tite) when 12 personnel comes on. Across the league, base defense rose to 29.7% of snaps in 2025 for exactly this reason (see “How offenses responded”). The cost is a slower defense on the field if the offense then spreads out.
  • Bring a safety down before the snap to make it seven against seven. Now the defense is one-high, and 12 personnel under center is the formation built for play-action shots against exactly that (the safety who came down is the one the fake pulls forward).
  • Rotate a safety down at the snap: stay two-high in the picture and add a seventh run defender only after the snap. That only works if the front can hold for the half-second the safety needs, which is why these defenses pay so much for interior linemen.

If the defense simply stays as it is and loses the numbers, the likeliest run goes to the right, away from the nickel: on the left, the nickel is a seventh defender close enough to fit; on the right, nobody is outside the edge but a safety 12 yards away. A Macdonald defense has one more answer you can’t see here: a third safety in the nickel’s spot, a safety who can play like a linebacker, so the box count the offense made before the snap may be wrong. That is what the big nickel is for.

TipPredict the play

Drill 4: whose defense is it? Two third-and-9 pictures against the same 2x2 formation. One is the kind of picture a Fangio defense shows, the other the kind a Macdonald defense shows.

Show the Python
def picture_mac():
    dfn = [D("LE", "OLB", 1.0, -5.6, "E"), D("LT_", "DT", 1.0, T("3", -1), "T"), D("RT_", "DT", 1.0, T("2i", 1), "T"),
           D("RE", "OLB", 1.0, 5.6, "E"), D("MIKE", "LB", 2.0, -0.8, "M"), D("WILL", "LB", 3.5, 2.6, "W"),
           D("S3", "SS", 5.5, -8.5, "S"), D("LCB", "CB", 7.0, -15.6, "CB"), D("RCB", "CB", 7.0, 15.6, "CB"),
           D("FS", "FS", 13.0, -7.5, "FS"), D("SS", "SS", 13.0, 7.5, "SS")]
    return Play(eleven_2x2(), dfn, los=40, to_go=9)


def picture_fangio():
    dfn = [D("LE", "OLB", 1.0, -5.6, "E"), D("L4", "DL", 1.0, T("4i", -1), "4i"), D("R4", "DL", 1.0, T("4i", 1), "4i"),
           D("RE", "OLB", 1.0, 5.6, "E"), D("MIKE", "LB", 4.7, 1.6, "M"), D("WILL", "LB", 4.7, -1.8, "W"),
           D("NB", "NB", 5.0, -8.5, "$"), D("LCB", "CB", 7.0, -15.6, "CB"), D("RCB", "CB", 7.0, 15.6, "CB"),
           D("FS", "FS", 12.5, -7.5, "FS"), D("SS", "SS", 12.5, 7.5, "SS")]
    return Play(eleven_2x2(), dfn, los=40, to_go=9)


fig, axes = plt.subplots(1, 2, figsize=(6.6, 2.75))
for ax, (fn, title) in zip(axes, ((picture_mac, "Picture 1"), (picture_fangio, "Picture 2"))):
    p4 = fn()
    fld = p4.draw(ax=ax, lateral=(-19.5, 19.5), window=(-7.5, 16.5), title=False)
    no_numbers(fld.ax)
    ax.set_title(title, fontsize=8.4, color=style.INK, loc="left", pad=3, fontweight="bold")
fig.tight_layout(w_pad=0.8)
plt.show()
Figure 66.12: Drill 4: two pre-snap pictures. Picture 1: four linemen, the Mike (M) walked up into the left A gap, the Will (W) creeping over the right guard, a third safety (S) over the left slot, two safeties deep. Picture 2: two linemen in 4i-techniques with a stand-up edge (E) outside each, two linebackers (M, W) off the ball, the nickel ($) over the left slot, two safeties deep. Both are two-high.

Which picture belongs to which coach, and what is the one thing you would watch at the snap in each?

Picture 1 is the Macdonald picture; Picture 2 is the Fangio picture. Picture 2 is honest up front: four on the line, two linebackers off the ball, a cornerback at nickel. The protection can be set from it, and the four who rush are the four on the line. The question it poses is the coverage, so at the snap watch the two safeties: do both stay deep (quarters or Cover 6/8), or does one come down (a rotation to Cover 3)?

Picture 1 poses three questions at once. There is a linebacker on the line, a creeping Will and a third safety where the nickel would be, so six could rush and the third safety could be a blitzer, a slot defender or a deep player. At the snap, watch the Mike and the third safety first. Whoever doesn’t rush tells you where the dropper is, and that is where the hot throw would go and where the quarterback must not throw. Then watch the safeties, because the coverage is still undecided.

Both coaches show both kinds of picture sometimes; this is a tendency, not a rule. But if you can tell which question a defense is asking, you know where to look.

Takeaways

  • The problem was the pre-snap commitment. One-high defenses had to decide the eighth run defender and the deep help before the snap, and McVay-era offenses and Mahomes punished that commitment every week.
  • Fangio’s answer is five decisions that pay for each other: two safeties back to stop explosive plays; a light box held by a tite front that wins its own fights; a four-man rush; quarters and Cover 6 so the safeties fit the run after the snap; and late rotation so the shell can lie. It works only when the interior linemen and the four rushers are good enough, which is why his tree produced both the best and the worst defenses in the league.
  • Macdonald’s answer is multiplicity: keep the two-high coverage, but make the front, the rushers and the personnel as hard to read as the coverage. Fangio puts the same five on the line; Macdonald changes who the five are. Same picture, many plays. It is a four-man-rush defense, not a blitz defense, and by his own account not even a heavy simulated-pressure defense; its pressure comes from pressure looks and uncertainty.
  • Super Bowl LX was the system on the biggest stage: four rushers on nearly every snap, mostly two-high coverage, six sacks, and no New England points for three quarters.
  • The public data shows the common ground (low blitz rates, pressure without the blitz, light boxes, strong run defense) but not the disguise. Measuring the lie takes tracking data or your own eyes.
  • Offenses answer by counting blockers they control, forcing early declarations and deciding after the snap. Heavy personnel, motion at the snap, tempo and quarterbacks who process fast are the counters, and defenses will answer them with even more versatile players.

Connections

Builds on: The Modern Era (the two-high counterrevolution and the offensive answers, as history); Disguise, Rotation, and Split-Field Coverage (rotation, the tells, split-field coverage); Zone Blitzes, Fire Zones, and Simulated Pressure (droppers, pressure looks and sims); Quarters and the Two-High Match Family (the coverages); Odd and Hybrid Fronts and Run Fits and Box Math (the tite and the light box).

Sets up: Tracking Data and the Big Data Bowl, where you build the shell-versus-coverage measurement sketched here; Tendencies, PROE, and Charting, for the charting habits behind the disguise audit; Building a Roster, on what versatile defensive backs and interior linemen cost; and Watching Live, where the disguise audit becomes part of the master checklist.

See also: Game-Planning Week, which rebuilds a tendency report on the 2025 Seahawks’ defense from public data, and Case Study: Belichick and Game-Plan Football, the earlier master of changing the defense to fit the opponent.

NoteGo deeper
  • Cody Alexander’s MatchQuarters newsletter (matchquarters.com) has the most detailed public writing on Fangio’s coverages (his “Cover 8” and weak-rotation “Cover 9”), targeted split-field coverage and the Fangio tree; his book Match Quarters: A Modern Guidebook to Split-Field Coverages (2019) is the coach’s-eye foundation.
  • Tim McManus, “The mind of Eagles DC Fangio is where the defensive magic lives,” ESPN (Jan. 22, 2025): the best profile of how Fangio works.
  • James Reber and the Next Gen Stats team on NFL.com, for split-safety and coverage trends measured with tracking data.
  • Chris B. Brown, The Art of Smart Football (2015): short essays on the offense-defense arms race that this chapter is the latest round of.

  1. Phil Perry, “Super Bowl 60 preview: Four matchups that will decide Patriots-Seahawks,” NBC Sports Boston (Feb. 8, 2026): https://www.nbcsportsboston.com/nfl/new-england-patriots/super-bowl-2026-preview-matchups-drake-maye-seahawks/766995 (McDaniels: “if we have the ball for 70 snaps in the game, 65 of them are gonna look the same before the ball’s snapped,” and on Seattle’s safeties, “if they’re rotating, they rotate late, they drop down late, they spin the coverage”). Maye finished second in the 2025 MVP vote to Matthew Stafford (AP awards, NFL.com: https://amp.nfl.com/news/list-of-nfl-honors-award-winners-from-2025-nfl-season ).↩︎

  2. “Vic Fangio,” Wikipedia: https://en.wikipedia.org/wiki/Vic_Fangio (born Aug. 22, 1958, Dunmore, Pennsylvania; Dunmore HS 1979–1981; North Carolina graduate assistant 1983; USFL Philadelphia/Baltimore Stars 1984–1985; Saints linebackers coach 1986–1994; coordinator of the Panthers 1995–1998, Colts 1999–2001 and Texans 2002–2005; Ravens 2006–2009; Stanford 2010; 49ers 2011–2014; Bears 2015–2018; Broncos head coach 2019–2021). Tim McManus, ESPN (Jan. 22, 2025; full citation in the next note) confirms the Stars job and the Dunmore roots. That Mora brought him from the Stars to New Orleans: Stanford Athletics coaching bio (Apr. 17, 2013): https://gostanford.com/news/2013/04/17/player-bio-vic-fangio and Crescent City Sports, “Fangio back in New Orleans where he made his name”: https://crescentcitysports.com/?p=279031 . Wikipedia dates his high-school coaching from 1979.↩︎

  3. Tim McManus, “The mind of Eagles DC Fangio is where the defensive magic lives,” ESPN (Jan. 22, 2025): https://www.espn.com/nfl/story/_/id/43508406/philadelphia-eagles-vic-fangio-defensive-coordinator-created-force-philly-cusp-super-bowl (“It’s not your fault you don’t work hard … It’s not your fault, you just don’t know how … But that’s going to change now that I’m here”; “People are not expecting as much out of players as we used to expect”; long meetings, added padded practices, clips of hard hits, the study of opponents’ tells such as a tight end’s alignment).↩︎

  4. McManus, ESPN (Jan. 22, 2025), cited above: Donatell, who coached alongside Fangio for 11 seasons and worked under him in Denver, describes the defense as giving no pre-snap tells and delaying identification so the quarterback is uncertain into his first or second step.↩︎

  5. Two-linebacker shares: course calculation from nflverse load_participation() (player IDs or names on the field) joined to load_rosters(), regular-season snaps with five defensive backs (2018 Bears, 2024 Eagles). That Staley’s branch of the tree made the five-man nickel its everyday front: Cody Alexander, “The Fangio System’s Penny Sam 8,” MatchQuarters (June 19, 2023): https://www.matchquarters.com/p/fanigio-penny-sam-8 (“Staley and his offshoots favor the Penny Front,” a nickel with a nose); and in Denver Fangio used his four-down front more often while Staley preferred the five-man front: Alexander, “Flipping the Script,” MatchQuarters: https://www.matchquarters.com/p/flipping-the-script . Both are cited in Odd and Hybrid Fronts.↩︎

  6. Course calculation from nflverse load_participation() (number_of_pass_rushers), regular-season dropbacks, ranked among 32 teams each season. Next Gen Stats supplies the charting through 2022 and FTN from 2023; rank within a season rather than comparing raw rates across the break. ESPN (McManus, above) gives a 19.1% blitz rate for the 2024 Eagles, 28th, from a different charting source.↩︎

  7. Cody Alexander, “Running ‘Targeted’ Coverage from a Split-Field Structure,” MatchQuarters (Apr. 15, 2024): https://www.matchquarters.com/p/targeted-coverage-from-a-split-field-structure (in Fangio’s terminology Cover 6 is “Quarter-Quarter-Half,” the traditional form with the Cover 2 side away from the passing strength, and Cover 8 is the rotation to the nickel, “Half-Quarter-Quarter”; “Instead of dropping Safeties into specific zones, the defense places the Cover 2 side where they want it”; Jesse Minter and Mike Macdonald named as using the same targeted approach).↩︎

  8. Cody Alexander, “Fangio’s Cover 9: The Eagles’ Weak-Rotation Cover 3,” MatchQuarters (Aug. 3, 2026): https://www.matchquarters.com/p/fangio-cover-9-eagles-two-high-disguise (“weak rotation Cover 3 (away from the passing strength)”); and “Cover 3? Quarters? How Fangio’s Defense Makes QBs Guess Wrong,” MatchQuarters (Nov. 7, 2025): https://www.matchquarters.com/p/how-fangio-defense-disguises-coverage (“how the influential scheme uses a two-high shell and post-snap rotation to make everything look the same”). Both are partly paywalled.↩︎

  9. Saban was Belichick’s defensive coordinator in Cleveland (1991–1994), where the two built pattern-matching rules into their Cover 3 to deal with Pittsburgh’s routes; Saban: “how we can play Cover 1 and Cover 3 at the same time.” Eleven Warriors, “Film Study: Nick Saban’s Pattern-Matching Pass Defense” (Dec. 2014): https://www.elevenwarriors.com/ohio-state-football/2014/12/46950/film-study-nick-sabans-pattern-matching-pass-defense ; Chris B. Brown, The Art of Smart Football (2015).↩︎

  10. Points allowed and ranks: course calculation from nflverse schedules and play-by-play (2018 regular season). The front personnel in “What to notice” (Trevathan and Smith both on the field on most nickel snaps; Goldman, Nichols and Bullard rotating inside): course calculation from nflverse participation joined to 2018 rosters, as in decision 2. Interceptions (27), takeaways (36), the AP Assistant Coach of the Year award and the Broncos hiring: “Vic Fangio,” Wikipedia (cited above). The Khalil Mack trade was completed on Sept. 1, 2018, eight days before the opener: Sports Illustrated (Sept. 1, 2018): https://www.si.com/nfl/2018/09/01/khalil-mack-trade-chicago-bears-oakland-raiders .↩︎

  11. Denver record (7–9, 5–11, 7–10; 19–30, no playoffs): “Vic Fangio,” Wikipedia (cited above). Points-allowed and EPA ranks: course calculation from nflverse schedules and play-by-play.↩︎

  12. Consultant (2022), Dolphins coordinator (2023) and the Eagles’ 2023 and 2024 ranks (26th and 30th in total and scoring defense in 2023, first and second in 2024): “Vic Fangio,” Wikipedia (cited above); McManus, ESPN (cited above), on his hiring on Jan. 25, 2024. EPA per designed run and light-box shares: course calculation from nflverse play-by-play and participation, as in Run Fits and Box Math.↩︎

  13. Course calculation from nflverse play-by-play and load_participation() for Super Bowl LIX (game 2024_22_KC_PHI), Kansas City dropbacks including sacks and scrambles. Score and date: course fact sheet (planning/FACTS-current.md §1). Wikipedia (“Vic Fangio”) also gives six sacks and three takeaways. The participation data also shows two five-man rushes, but neither counts as a dropback here: one came on a Chiefs touchdown wiped out by offensive pass interference, the other on a two-point try. That agrees with Next Gen Stats’ count of zero blitzes on 42 dropbacks, used in A First Look at Defense.↩︎

  14. Course fact sheet (planning/FACTS-current.md §§0, 2 and 9, checked Oct. 2026): Fangio remains Eagles DC in 2026; Sean Mannion is the 2026 offensive coordinator; the Eagles lost 23–19 to San Francisco in the 2025 wild-card round. Points allowed and rank: course calculation from nflverse schedules.↩︎

  15. Staley, Barry and Desai as members of the Fangio tree: Diante Lee, “Checking in on the Vic Fangio coaching tree after Week 1 of the 2021 NFL season,” PFF (Sept. 15, 2021): https://www.pff.com/news/nfl-vic-fangio-coaching-tree-week-1-2021 ; Staley’s career and the Rams’ 2020 ranks: Kaelen Jones, The Ringer (Jan. 13, 2021): https://theringer.com/2021/01/13/nfl/rams-defense-los-angeles-brandon-staley-aaron-donald-jalen-ramsey . Evero: Panthers.com (Feb. 1, 2026): https://www.panthers.com/news/with-all-10-head-coaching-vacancies-filled-ejiro-evero-set-to-return-defensive-coordinator . Macdonald and Minter on the Ravens’ staff and Minter’s career: “Mike Macdonald (American football),” Wikipedia (cited below) and NFL.com on Minter’s Ravens hiring: https://www.nfl.com/news/jesse-minter-ravens-hire-head-coach-chargers-dc . Donatell (11 seasons alongside Fangio; Denver coordinator 2019–2021): McManus, ESPN (cited above); his one Vikings season: NFL.com, “Vikings fire defensive coordinator Ed Donatell after one season” (Jan. 2023): https://www.nfl.com/news/vikings-fire-defensive-coordinator-ed-donatell-after-one-season . Evero (Rams safeties coach 2017–2020) and Shula (Rams outside linebackers coach 2019–2020, coordinator from 2024): “Ejiro Evero” and “Chris Shula,” Wikipedia. Minter (Ravens 2017–2020, Vanderbilt coordinator 2021, then Michigan): Vanderbilt Athletics bio: https://vucommodores.com/coach/jesse-minter . Points-allowed ranks for every coach in the list (Staley’s Chargers, Donatell’s 2022 Vikings, Barry’s Packers, Desai’s 2021 Bears and 2023 Eagles): course calculation from nflverse schedules.↩︎

  16. Derrick Brown’s torn meniscus in the 2024 opener and his move to injured reserve for the season: CBS Sports, “Panthers Pro Bowler Derrick Brown to miss the rest of 2024 NFL season with knee injury suffered in Week 1” (Sept. 2024): https://www.cbssports.com/nfl/news/panthers-pro-bowler-derrick-brown-to-miss-the-rest-of-2024-nfl-season-with-knee-injury-suffered-in-week-1/ . Shaq Thompson’s torn Achilles in Week 4 against Cincinnati: WBTV (AP), “Panthers linebacker Shaq Thompson out for the season with a torn Achilles tendon” (Sept. 30, 2024): https://www.wbtv.com/2024/09/30/panthers-linebacker-shaq-thompson-out-season-with-torn-achilles-tendon/ . Brown’s 2025 season (on the field in 17 games): nflverse participation. Ranks: course calculation from nflverse schedules, play-by-play and participation.↩︎

  17. James Reber and the Next Gen Stats Analytics Team, “The coverage that turned the Seahawks into Super Bowl winners and is taking the NFL by storm,” NFL.com (2026): https://www.nfl.com/news/the-coverage-that-turned-the-seahawks-into-super-bowl-winners-and-is-taking-the-nfl-by-storm (split-safety coverage on 32.9% of dropbacks in 2018, 37.8% in 2021, 40.4% in 2024 and 42.0% in 2025; every defense above 30% in 2025).↩︎

  18. “Mike Macdonald (American football),” Wikipedia: https://en.wikipedia.org/wiki/Mike_Macdonald_(American_football) (born June 26, 1987, in Boston; a Patriots fan growing up; Centennial High School, Roswell, Georgia; Georgia finance degree, summa cum laude, 2010, and master’s 2013; Georgia graduate assistant and quality-control coach 2010–2013; Ravens intern 2014, defensive assistant 2015–2016, defensive backs coach 2017, linebackers coach 2018–2020; Michigan coordinator 2021, scoring defense from 95th to 8th; Ravens coordinator 2022–2023; Seahawks head coach from 2024, the league’s youngest at 36; calls the defensive plays). Durde as Seattle’s coordinator: course fact sheet (planning/FACTS-current.md §§1, 9).↩︎

  19. McManus, ESPN (Jan. 22, 2025), cited above: Baun says Fangio “does a lot of exotic stuff coverage-wise”; the article notes that Fangio doesn’t use many complex fronts.↩︎

  20. Reber, NFL.com (cited above): from Week 14 (Julian Love’s return from injured reserve) through Super Bowl LX, Seattle used split-safety coverage on 54.8% of pass plays, the highest of any playoff team in that span; Love’s play in “Macdonald’s beloved Cover 6 scheme”; Cover 6 a hallmark of the last four Super Bowl champion defenses. Seattle’s full-season figure and rank: course calculation (nflverse participation, FTN charting), a different charting source from NGS.↩︎

  21. Connor Benintendi, All Seahawks / Sports Illustrated (Nov. 25, 2025): https://www.si.com/nfl/seahawks/onsi/seahawks-news/mike-macdonald-dispels-huge-myth-about-seahawks-pass-rush (Macdonald on Seattle Sports 710 AM: “We put five on the line and drop a guy”).↩︎

  22. Same article: “I’m going to disappoint you guys: We do not run a lot of simulated pressures”; “We have [simulated pressures], and it’s a great tool”; “The way we define simulated pressures is you’re rushing four,” with an unaccounted-for rusher replacing an accounted-for one.↩︎

  23. Ted Nguyen, “Mike Macdonald’s defensive evolution: The tweaks that sparked a Seahawks Super Bowl run,” The New York Times (Feb. 4, 2026), as quoted in “Mike Macdonald (American football),” Wikipedia (cited above); the bracketed “4-3” is Wikipedia’s editorial insertion. The NYT original is paywalled and was not seen directly.↩︎

  24. Love’s Week 14 return and the late-season split-safety rate: Reber, NFL.com (cited above). Seattle’s 2024 and 2025 ranks and big-nickel shares: course calculation from nflverse schedules, play-by-play and participation. Emmanwori’s 2025 rookie season: “Mike Macdonald (American football),” Wikipedia (cited above), quoting Ted Nguyen, The New York Times (Feb. 4, 2026).↩︎

  25. Points allowed, sacks (60, most in the NFL), pressure rate, sacks per pressure (sacks divided by dropbacks with a pressure or sack) and blitz rate: course calculation from nflverse schedules, play-by-play and participation (2023 regular season). Three-safety share: A First Look at Defense, same data.↩︎

  26. Seattle’s 2025 record, points allowed and the Super Bowl result: course fact sheet (planning/FACTS-current.md §§1–2) and course calculation from nflverse schedules; run defense by EPA per designed run: course calculation (NBC Sports Boston, cited above, also calls Seattle “the best run defense in football this season from an EPA per play standpoint”).↩︎

  27. Course calculation from nflverse play-by-play and load_participation() (FTN charting) for Super Bowl LX (game 2025_22_SEA_NE, Feb. 8, 2026), New England dropbacks on downs 1–4 (sacks and scrambles included; the failed two-point try excluded). Sack credits, the scoring sequence, Walker’s 27 carries for 135 yards and Nwosu’s 45-yard return come from the official play descriptions in the same data; Walker’s MVP award and Myers’s record five field goals from the course fact sheet (§1). Line score (Seattle 3, 6, 3, 17; New England 0, 0, 0, 13), New England’s 18 official rushes for 79 yards (Stevenson 7 for 23, Henderson 6 for 19, the rest Maye’s scrambles and a kneel-down) and Witherspoon’s pressure on Nwosu’s interception: “Super Bowl LX,” Wikipedia: https://en.wikipedia.org/wiki/Super_Bowl_LX .↩︎

  28. NFL Big Data Bowl 2025: pre-snap tracking for the 2022 season, Weeks 1–9, with plays.csv coverage labels (pff_passCoverage) and player_play.csv; course fact sheet (planning/FACTS-current.md §8) and https://operations.nfl.com/gameday/analytics/big-data-bowl . The pff_passCoverage strings in the code (including the irregular “Cover 6-Left” beside “Cover-6 Right”) match those used in public BDB 2025 solution code, e.g. https://github.com/sepollack/nfl-bdb-25 ; Red Zone, Goal Line, Bracket, Prevent and Miscellaneous labels are left out. Next Gen Stats’ own tracking-based pre-snap model, which flags a split-safety look that becomes single-high man or Cover 0 as a disguise: “Next Gen Stats: New advanced metrics you need to know for the 2025 NFL season,” NFL.com: https://www.nfl.com/news/next-gen-stats-new-advanced-metrics-you-need-to-know-for-the-2025-nfl-season .↩︎

  29. Course calculation from nflverse play-by-play and FTN charting (load_ftn_charting()), 2025 regular-season dropbacks with n_pass_rushers and n_blitzers recorded: the share of dropbacks with exactly four rushers of whom at least one is a “blitzer.” Reading n_blitzers as rushers who are not down linemen or regular edge rushers is the course’s interpretation of FTN’s definition (see Zone Blitzes). The same calculation for the 2023 Ravens gives their rank in the text; Zone Blitzes notes the same gap between this proxy and Alexander’s PFF-based early-season ranking of the 2023 Ravens (4th through Week 6). Quote: Benintendi, SI (cited above).↩︎

  30. James Reber, NFL Next Gen Stats, “NFL trend watch: Heavy personnel could shape Super Bowl LX showdown between Patriots and Seahawks,” NFL.com: https://www.nfl.com/news/nfl-trend-watch-heavy-personnel-could-shape-super-bowl-lx-showdown-between-patriots-and-seahawks (41.7% of 2025 plays with fewer than three wide receivers). Under-center share: course fact sheet (planning/FACTS-current.md §10, nflverse calculation: 33.6% of plays in 2025 by FTN’s qb_location).↩︎

  31. Reber, NFL.com (cited in the previous note): base defense on 29.7% of 2025 snaps, against a low of 20.5% in 2023.↩︎

  32. Course fact sheet (planning/FACTS-current.md §§0 and 9, checked Oct. 2026): Fleury from the 49ers’ staff replaced Kubiak, who became the Raiders’ head coach (Pete Carroll was fired after one season); Mannion replaced Patullo in Philadelphia; Minter is the Ravens’ head coach and Anthony Weaver their coordinator; Zak Kuhr was named New England’s coordinator in February 2026 (Terrell Williams, the 2025 coordinator on paper, missed the season for cancer treatment). Baltimore’s 2024–2025 coordinator, Zach Orr (promoted when Macdonald left, replaced by Weaver in 2026): Baltimoreravens.com (Feb. 2024): https://www.baltimoreravens.com/news/zachary-orr-hired-ravens-defensive-coordinator-zach-linebacker-former-neck and ESPN (Jan. 2026): https://www.espn.com/nfl/story/_/id/47808544 .↩︎