Here's my idea:
ResourceType: -- 2 rows: hotel, city
ResourceTypeID not null autoincrement primary key
ResourceType not null unique key
Resource: -- both hotels & cities
ResourceID not null autoincrement primary key
ResourceTypeID not null foreign key references ResourceType (ResourceTypeID)
Name not null unique --can repeat the city name or be blank
PackageID not null autoincrement primary key
DestinationResourceID not null foreign key references Resource (ResourceID)
PackageName not null unique key
PackageID not null foreign key references Package (PackageID)
OfferingID not null autoincrement primary key
OriginatingCityID null foreign key references Resource (ResourceID)
PackageID not null unique key
OfferingID not null
foreign key (PackageID, OfferingID) references Offering (PackageID, OfferingID)
If a PK column can also be part of a multi-column FK (I just don't have time to check right now), then eliminate the DefaultOffering table and put DefaultOfferingID in the Package table with the same FK.
In the Offering table, you could replace OfferingID with an OfferingNumber that starts at 1 for each package. I would play around with it being unique, or primary key, or possibly make the primary key (PackageID, OfferingID). In SQL Server I would make the clustered index those two columns, but I am not experienced in mysql.
Regarding the Resource table, A hotel is in a city so it seems the only one to have many extra attributes. Leave inappropriate columns blank. If that is of concern, create a subtype Hotel table, and possibly also a subtype City table, similar to another answer here.
If the number of extra columns is not large, it may be worth not creating subtype tables in order to save a lot of complexity. A check constraint can enforce only the right type of data being stored for City & Hotel.
Don't let abstract ideals prevent you from practical design! I used to use NULLs for "no end date" but it caused awful complexity in my queries--and poor performance too when the OR condition forced a scan. Now I use '12/31/9999' and it is SO much better. When I first heard of a numbers table it felt dirty and wrong somehow, but now it is an indispensable basic tool.
One more thing: do you actually need a Package table? All it really does is hold a name, but can't the name be the destination city? You might be able to move ResourceID to Offering.DestinationResourceID. If that is impractical because the "destination" can be a Hotel rather than a City, you could rename OriginatingCityID to OriginatingResourceID and treat hotel stays as "trips" from the hotel to the city. Then the concept of Package is simply a collection of Offerings in the same city, and the Package name is simply the City name.
You haven't given much detail about how hotels will be handled, or info on the extra columns needed for cities and hotels. Please provide more detail if you would like a more structured answer on how to accommodate the data.