diff --git a/crates/fonts/src/fontdb.rs b/crates/fonts/src/fontdb.rs
--- a/crates/fonts/src/fontdb.rs
+++ b/crates/fonts/src/fontdb.rs
@@ -393,6 +393,22 @@ fn legacy_names(f: &skrifa::FontRef<'_>, family: &str) -> Option<(String, String
     Some((legacy, name(f, &[StringId::SUBFAMILY_NAME]).unwrap_or_else(|| "Regular".into())))
 }
 
+/// The Windows family and style a variable font's named instance answers to. Windows lists each
+/// instance other than Regular, Italic, Bold and Bold Italic as a family of its own, as the
+/// family's static files name themselves: "Montserrat ExtraBold" / "Regular" for the ExtraBold
+/// instance, "Montserrat ExtraBold" / "Italic" for ExtraBold Italic.
+fn instance_legacy_names(family: &str, style: &str) -> Option<(String, String)> {
+    if style.contains('{') {
+        return None;
+    }
+    let weight: Vec<&str> = style.split_whitespace().filter(|w| !matches!(norm(w).as_str(), "italic" | "oblique")).collect();
+    let weight = weight.join(" ");
+    if matches!(norm(&weight).as_str(), "" | "regular" | "bold") {
+        return None;
+    }
+    Some((format!("{family} {weight}"), if style_italic(style) { "Italic" } else { "Regular" }.into()))
+}
+
 /// The tables skrifa reads glyph outlines from: `glyf` (TrueType), `CFF `, `CFF2` and `VARC`. For a
 /// face with none of them (bitmaps only, or outlines in Apple's `hvgl` table), [`FontDb::outline`]
 /// returns an empty path for every glyph.
@@ -686,7 +702,7 @@ fn make_face(bytes: FontBytes, index: u32, family: String, style: String, coords
         .map(|v| v >= 0.5)
         .or(axis(b"slnt").map(|v| v.abs() > 0.1))
         .unwrap_or(!matches!(a.style, skrifa::attribute::Style::Normal) || style_italic(&style));
-    let legacy = if coords.is_empty() { legacy_names(&f, &family) } else { None };
+    let legacy = if coords.is_empty() { legacy_names(&f, &family) } else { instance_legacy_names(&family, &style) };
     Some(FontFace {
         id: NEXT_ID.fetch_add(1, Ordering::Relaxed),
         family,
diff --git a/crates/fonts/src/tests.rs b/crates/fonts/src/tests.rs
--- a/crates/fonts/src/tests.rs
+++ b/crates/fonts/src/tests.rs
@@ -147,6 +147,36 @@ fn windows_family_names_find_their_faces() {
     }
 }
 
+#[test]
+fn variable_font_instances_answer_to_their_windows_names() {
+    // Windows lists a variable font's named instances other than Regular, Italic, Bold and
+    // Bold Italic as families of their own, and documents name them that way ("Montserrat
+    // ExtraBold"). The bundled Montserrat is variable, so these names found no face and drew
+    // in Inter Regular, even with the family's static files installed (their faces are
+    // skipped as already present).
+    let db = FontDb::with_font_dirs(Vec::new());
+    db.set_system_fallback(false);
+    if !db.is_loaded("Montserrat") {
+        return; // built without craft-fonts
+    }
+    for (name, style, weight, italic) in [
+        ("Montserrat ExtraBold", "Regular", 800.0, false),
+        ("Montserrat SemiBold", "Regular", 600.0, false),
+        ("Montserrat Medium", "Regular", 500.0, false),
+        ("Montserrat Medium", "Italic", 500.0, true),
+        ("Montserrat Thin", "Bold", 100.0, false),
+    ] {
+        assert!(db.has_family(name), "{name}");
+        let f = db.face(name, style);
+        assert_eq!((f.family.as_str(), f.weight, f.italic), ("Montserrat", weight, italic), "{name} {style}");
+        assert_eq!(db.document_face(name, style).family, "Montserrat", "{name}: installed, so not Calibri");
+    }
+    // Regular and Bold are the family itself, not families of their own.
+    assert!(!db.has_family("Montserrat Regular"));
+    assert!(!db.has_family("Montserrat Bold"));
+    assert_eq!(db.face("Montserrat", "Bold").weight, 700.0);
+}
+
 #[test]
 fn faces_without_outlines_are_not_cataloged() {
     // Rename the Semibold's `glyf` table, as in fonts whose glyphs are bitmaps or are stored in
