If you want a take-home tag line for DTLs, here you go:
A dependently-typed language is one where the type system is the same as the language itself.
This means that types are first-class objects. You can pass them as arguments. You can return them as return values.
In a function signature, you may give names for all your arguments. For example: index : (n : Nat) -> List Int -> Int
.
The names are brought into scope inside the type. This means that arbitrary values may end up living "inside the types". A "better" version of the type above might be index : (n : Nat) -> Vect n Int -> Int. Here, we use Vect instead of List -- the difference is that a Vect n A is known to have exactly n elements of type A. (In constrast, a List A might have fewer or more than n elements).