Re: CSS, it is indeed declarative, that was a bit sloppy of me. My comparison rests on observed difficulties. Valid CSS can contain duplicates, overwrites, or coupled parent-child pairs as in a grid, or mistaken use of properties that have no effect without other properties. CSS allows disciplined decomposition and separation of concerns, but does not enforce it. We all seem to agree this is the RightThing(tm), but it means CSS fails on practical grounds when compared to, for example, SQL DDL. Disciplined use of DDL is baked in, in CSS it must be enforced and requires decisions on how to do so.
It may be easier to describe "what I'm really talking about" by going more concrete. For a browser app, we have two declarative languages and one imperative. A tool like React with jsx allows me to think entirely in terms of code, folding the HTML into code, and tying off CSS to be dealt with on its own. It's a delightful simplification at first glance, that happens to leak like a sieve and forces people to become React programmers instead of browser programmers. I tend to think it is successful because it lets us think in terms of telling the computer to do things, and imposes no required mental model on how you craft your components. React says, "make it more imperative, use more code, think of your HTML in terms of code."
So I go the other way, where I add data binding attributes to HTML. A server request that modifies data always gets a response in terms of data that a small bit of framework code uses to update the DOM according to the data bindings. It is highly constrained in the same sense as SQL, there is only a small fixed set of allowed operations.
This is what I mean by declarative. My HTML data binding attributes say what should be displayed, no app code required. Naturally there are more details, but that should make the idea clear. The driving motivation is performance and developer ergonomics. Performance is amazing. Ergonomics, I can't say - it's easy for me, but I wrote it.
But solutions like these do not gain traction usually. I believe it is because people prefer the open-ended nature of React, which does not require a mapping exercise into the supported patterns before it can be used.
This is probably what I was trying to say about declarative vs imperative. React does not constrain my choices (not at first glance), and allows me to mix declarative HTML into my code. I can write any code I want, and like an LLM, I can fix anything with more code. Declarative solutions, like my own HTML data binding attributes, constrain the user to fixed supported patterns, which may not map to how the programmer thinks of the problem.