Some AI papers have a finding so good you just want to quote it everywhere. But many turn out to be trash. They’ve got bad statistics, they’ve got bad methodology, they’re really sales pieces, or they just don’t prove their claimed result. If you see a finding you love, you can’t skip reading the paper before you post about it.
Today’s is “Evaluating Artificial Intelligence Use and Its Psychological Correlates via Months of Web-Browsing Data.” It’s a peer-reviewed journal article, published in Cyberpsychology, Behavior, and Social Networking, September 2025. [Liebert; archive, PDF]
The researchers measured 14 million website visits by 499 students and 455 members of the general public over a 90-day period.
Firstly, nobody used AI very much — 1% of student web-browsing was AI, 0.44% of the general public study. Secondly, the AI users were not very nice people:
The most consistent predictors of AI use across studies were aversive personality traits (e.g., Machiavellianism, narcissism, psychopathy).
So AI is not actually popular, and AI users are unpleasant assholes.
Now you might go “yeah, figures.” But let’s dive in and see how well it backs it up.
The first thing the researchers did was not trust the users to self-report. They measured their web browsing by getting 90 days of browser history from Chrome on a desktop — so no mobile or app usage. They did collect the users’ self-reports, which were just incorrect:
we observed that self-reported AI use and actual AI use were only moderately correlated (ρ = 0.329).
If the users went to a chatbot site, that’s obviously AI. For other sites, the researchers picked the Interactive Advertising Bureau category by … running the addresses through a chatbot, GPT-4o. That’s not so great, though they tested GPT-4o against a random 200 of the addresses and it was correct on all but one. So they figured it’d do.
The researchers were surprised how low AI usage actually was. The lead author, Emily McKinley, said: [PsyPost]
We were genuinely surprised by how infrequent AI use was, even among students who typically serve as early adopters of emerging technologies.
For the personality testing, the researchers used the Big Five test, which is reasonably regarded in psychology, and the Short Dark Triad test of aversive personality traits, which is not diagnostic, but it gets used a lot by psychology researchers. In particular, the prolific AI users — where more than 4% of their browsing was AI sites — came out as the most noxious people:
Students with more AI use in their browsing history tend to be high on extraversion and aversive personality traits like narcissism and psychopathy (Table 1). These individuals also tend to have more positive views of AI, in general.
… The most consistent finding across Study 1 (students) and Study 2 (general public participants) was the general connection between AI use and aversive personality traits.
For the general public group:
the most systematic link between personality and AI use was via Machiavellianism for this group.
That is, being a strategically manipulative sort.
So this paper seems okay? It’s a single study, in psychology. It needs to be replicated. It’s not rock solid yet. There’s a lot of holes you could pick in it, and it notes a lot of the holes.
But it does have the important characteristic that it’s showing a result to be true — AI’s not all that popular and AI users are unpleasant assholes — that you and I previously thought was only 99% true.
If you’ve spent any time in Excel, you’ll know the struggle of working with a messy dataset. You’ve got an inventory list with product codes buried in long strings of text; there’s customer notes where the phone number might be formatted five different ways; and you have a column of web links where you need to extract only the unique tracking ID buried deep in the URL. These are the sort of routine tasks that can easily turn into hours of frustrating, error-prone, manual work.
Regular Expressions (RegEx) are designed to solve this exact problem. They allow us to define complex patterns in text data leading to clean and simple, data extraction, validation and processing.
In the world of business, analytics, and data, Excel is perhaps the most divisive tool. It has a diehard fanbase who will defend it to the end of the Earth, yet, it’s criticized by others for not being a “proper data science tool”: slow, error prone, and incapable of facilitating any complex data handling tasks. In this article, we’ll see how using Regular Expressions can bridge the gap between lowly spreadsheet software and a professional data analysis pipeline – at least when it comes to text data. We’ll explore some of the theory behind Regular Expressions and show how we can implement this technique to substantially improve the efficacy and efficiency of text data processing right inside of Excel.
Types of Formal Grammar
In my previous article, The Hidden Mathematics of Language, I introduced the idea of formal grammars. Somewhat akin to the grammar rules for natural language or the syntax rules for a programming language, formal grammars consist of systems of rules that define which combinations of symbols form valid sentences in a language. These production rules describe how smaller components combine into larger structures, such as words into clauses or clauses into sentences. A language, is the set of all possible sentences that the grammar rules can produce.
There are 4 main, distinct types of grammar, each with a different level of expressiveness, and each corresponding to a different class of machine that is capable of recognising it. These machines are sometimes known as automata. For today, we’re just going to focus on Regular Grammars.
Regular grammars, are the simplest type of formal grammar. They can be represented using set-definitions, sets of production rules, or regular expressions. Regular languages can contain sentences including:
This makes them useful for recognising – or parsing – strings such as ID numbers, postcodes and email addresses. The automata for a regular grammar is called a Finite State Machine (FSM).
Finite State Machines
These automata parse strings by moving from state to state. We start at the start state, \( S_0 \), then read through the input string, choosing the next state based on the character being read. If the end state, \( S_5\) in the FSM above, is reached, then the parse was successful and the string is valid within the language. If the machine reaches a state from which it cannot transition out of, then the parse has failed and the string is invalid.
The FSM above is designed to recognise precisely 2 strings, \( abdca, aca \). There are 2 possible routes we can take from \( S_0 \) to \( S_5 \) giving us the 2 possible strings that can be parsed. If you tried to parse the string “abca” using this FSM, we would get to state \( S_2 \) and the parse would fail as the next character being read is not a “d”.
Finite State Machines have no memory so the decision about which characters can be parsed next is determined only by the current state. As a result, regular grammars cannot represent recursive structures – think pairs of nested brackets. With no memory, the machine has no knowledge of how many open brackets have come before, and therefore has no way of knowing how many closing brackets are required in order to parse a valid expression. We could design a machine that requires a finite, known number of brackets, but it is not possible to parse sentences with an unknown number of bracket pairs.
Regular Expressions
As mentioned, regular grammars are part of a wider landscape of formal grammars. Other types allow for greater expression, but come with their own limitations. The beauty of a regular grammar is that it can be represented by a regular expression.
A regular expression is another way to describe the set of sentences that can be parsed by a regular grammar. Let’s take a look at some basic syntax to get us started:
Above: Table of basic Regex syntax
We can write a regular expression by combining these symbols to indicate which characters we should expect in a valid string. The quantifiers refer to the character (or group of characters if using brackets) directly preceding. As such,
“b” means we should expect a “b” in the string
“b?” means there may or may not be a “b”
“b+” means we should expect at least one “b”
“b*” means we should expect any number of “b”s (including none at all!)
Where we have multiple characters in the string,
“ab” means we should expect an “a” followed directly by a “b”
“ab+” means we will have an “a” followed by at least one “b”
“(ab)+” means we should expect at least one “ab” pair (so “abab” would also be allowed”)
“bb*” is equivalent to writing “b+”
Using this method, we can construct Regex expressions such as
\[ “ab?c*\backslash d” \]
…which will be able to parse strings including “abc1”, “ac4”, “a9”, “acccc6”, “abcc0” – an “a”, an optional “b”, any number of “c”s and then a digit, 0-9.
Equivalence of the two forms
An equivalent, FSM for this Regex expression could look like this:
You may notice the addition of the \( \backslash \epsilon \) between \( S_2 \) and \( S_3 \), and \( S_1 \) and \( S_3 \). This allows the machine to transition between states without reading a symbol from the input string.
A Finite State Machine for a given grammar may not be unique. There can be multiple different machines that parse the same set of sentences. A well designed FSM should be deterministic, meaning there are never multiple options for which state should be chosen next. It is always possible to transform a non-deterministic FSM into a deterministic one using the Subset Construction Algorithm.
In the example above, in state \( S_1 \), the machine could either parse a \( b \) and move to state \( S_2 \), or move directly to \( S_3 \) without reading a character. The machine has a choice and hence, is non-deterministic.
We can construct an equivalent machine that will recognise precisely the same set of sentences, but that is deterministic:
We are never presented with a choice over which state to transition into next. There are no \( \backslash \epsilon \) transitions, and no states with multiple outbound arrows of the same label. Therefore, this machine is deterministic.
Additional Syntax
To really make use of the power of regular expressions, we need a little more notation:
Regex in Excel
Excel allows us to work with regex natively through the use of 3 different functions:
REGEXTEST(text, pattern, [case_sensitivity])
Tests if the text (or a substring of the text) matches the regex pattern
Replaces the substring matching the given pattern with the replacement text provided
The occurrence number indicates which match should be replaced if there are multiple. If not provided, replaces all instances.
Excel also provides the additional quantifier of \( \{n, m\} \) which indicates that between \( n \) and \( m \) (inclusive) of the previous symbol should be matched. If \( m \) is left blank, then it will match any number greater than or equal to \( n \).
So what can we do with it?
Removing non-alphanumeric characters
Using REGEXREPLACE, we can find all occurrences of non-alphanumeric characters and replace them with an empty string – effectively removing them from the text.
=REGEXREPLACE(A1,"[^A-Za-z0-9]","")
Removing double spaces
Similarly, we can search for all occurrences of double (or more) spaces and replace them with a single space.
=REGEXREPLACE(A1," {2,}"," ")
(You might have to take my word for it with the trailing spaces)
Extracting or validating email addresses
We can search for a valid email address format by looking for:
A set of characters, underscore or other acceptable character
An @ symbol
Another set of characters
A ‘.’
And then another set of characters of length at least 2
Parsing JSON to extract all fields (multiple matches)
Taking this one step further, we can extract multiple matches into a #SPILL range and handle them separately. This is useful if your JSON always returns arguments in the same, known order.
Each group stores whatever substring matches that portion of the regex pattern, in the order in which they appear. During the REGEXREPLACE() function, we can refer back to these captured groups using “$1”, “$2”, “$3”, etc… .
=REGEXREPLACE("Doe, John", "(\w+), (\w+)", "$2 $1")
>>> John Doe
It’s worth noting that is a feature of Excel, rather than a mechanism built into regular grammars themselves. Regardless, it’s quite useful for reformatting text data where you don’t know the exact contents or length.
Removing duplicate words
We can also use this technique to search for multiple consecutive occurrences of the same word and remove them.
=REGEXREPLACE(A1,"\b(\w+)(\s+\1\b)+","$1")
Text transformation / reformatting
…and we can add characters in-between the groups to put them into a required format.
Beyond Regular Grammars: Context Sensitive Data Extraction
While these are “Regex” functions, Excel doesn’t seem to have stayed within the bounds of a regular language. But we’re not complaining; the lookahead and lookbehind assertions are quite useful.
As the name suggests, these constructs let a regular expression match text based on its surrounding context, For instance:
\( (?<=Score:\backslash s*) \backslash d+\) matches a digit only if it’s preceded by \( Score: \)
\( \backslash w+(?=\backslash .jpg) \) matches a word only if it’s followed by \( .jpg \)
Building on the idea of capturing groups from earlier, we can also do the following
\( \backslash b(\backslash w+) \backslash s+ \backslash 1\backslash b \) matches two repeated words. The first capturing group matches a word, then the \( \backslash 1 \) is a backreference that requires that same sequence of characters to appear again
This ability takes us out of the realm of regular grammars, and into the world of Context Free or Context Sensitive ones; we’re matching based the specified, context, elsewhere in the text. You can also think of it as introducing a form of memory or dependency which would exceed of the capabilities of a finite state machine.
Context Type
Syntax
Meaning
Positive Lookahead
(?= … )
Only if the next part matches \( \dots \)
Negative Lookahead
(?! … )
Only if the next part doesn’t match \( \dots \)
Positive Lookbehind
(?< … )
Only if the preceding part matches \( \dots \)
Negative Lookbehind
(?<! … )
Only if the preceding part doesn’t match \( \dots \)
Obfuscating sensitive data
We can look for characters that have a given number of characters ahead or behind them to make sure we obscure the data, but leave some visible.
=REGEXREPLACE(A1,"(?<\w{2})\w(?\w{2})","*")
Wrapping up
Regex brings a surprising amount of sophistication to Excel. While some of these tasks can still be done using LEFT(), RIGHT(), MID(), etc… utilising regular expressions makes this process a lot smoother and cleaner. With just a few formulas, we can extract structured data from (almost) whatever mess you throw at it,. Data validation and transformations that would have taken hours can now be done in seconds. And if you ever get stuck, sketching out a quick finite state machine can definitely help.
Excel’s new regex functions bring the logic of regular grammars into everyday data workflows. The same rules that define the behaviour of formal languages now sit quietly behind familiar formulas, letting us recognise, extract, and transform text with precision. It’s a small but meaningful shift, not because it turns Excel into something it isn’t, but because it shows how much can be achieved when old tools meet a bit of formal thinking.
Sometimes, you don’t need a lawyer, you just need to look like you have one.
That’s the idea behind Heavyweight, a project that democratizes the aesthetics of (in lieu of access to) legal representation. Heavyweight is a free, online, and open-source tool that lets you give any complaint you have extremely law-firm-looking formatting and letterhead. Importantly, it does so without ever using any language that would actually claim that the letter was written by a lawyer.
Let’s back up for a second. Last month, I had the incredible honor of participating in Rhizome’s 7x7. Rhizome, for folks who don’t know, is an NYC-based organization dedicated to making, celebrating, and preserving web art. And 7x7 is their yearly event where they invite technologists to collaborate with artists to make something new. This year, instead of pairing artists with technologists, they decided, inspired by art collective provocateurs MSCHF, to pair artists with lawyers.1
The artist I got paired with was the incredible Morry Kolman. If you’ve heard about Morry’s work, it’s probably because of the reporting on how his “traffic cam selfie” project got a cease and desist from the New York Department of Transportation and his incredible response.2
In addition to this stunt, he also told me that he sent a proper letter back to the DoT as well, and - in order to make it look like he had more legal power on his side than just a few calls with friends that were lawyers - made his own letterhead to make it seem more legit. I’d done something similar earlier this year, with my firm putting out an “official statement on the Trump administration’s attack on the rule of law” under our letterhead as well. Taking those together, we knew that we had keyed into something interesting, a decidedly visual and subjective aspect of an otherwise pretty language-driven and objectivity-seeking profession. We became determined to make our contribution to the 7x7 canon based around the most thrilling thing that comes to mind when you think of the law: document formatting.
Lawyers like to think that we’re all about the facts and legal reasoning, but there’s a reason courtroom dramas feature the dramatic closing argument. It’s why lawyers swap stories about rushing to court, closing a big deal last minute, or some other “big moment.” Lawyers are not just not above spectacle, but on some level, it’s what we’re selling.
Having a lawyer show up, or send a letter, instantly changes the power dynamic in a situation. As Morry put it, it’s why getting a cease and desist letter (which is just a letter, it’s not a legal document) causes a moment of “pants shitting.” The contents of the letter, for most people, is beside the point.3 What’s scary is the sense of being targeted by someone who has the power to make your life miserable. That’s part of why lawyer behavior is ethically regulated, including, actually, who is allowed to be on a law firm’s letterhead.4
But it’s not just about creating emotion in an opponent— lawyers sell spectacle to their clients. Law is a credence good, which means that it is often quite difficult to tell whether someone is a good lawyer, especially if one isn’t an attorney. People look to external cues to evaluate whether to take someone seriously—from billing rate, email provider, or even the fanciness of an organization’s office.5 This often corresponds to looking for qualities that individuals associate with big and fancy law firms, as that’s what a law firm is “supposed” to feel like, and it results in some hilarious aesthetic choices. Take a look at this letterhead from Wachtell (a very fancy law firm) from 2022!
It’s SO UGLY. But it screams law firm.
Heavyweight plays on this phenomenon by making lots of aesthetic choices that law firms make, while not actually using any words that formally indicate “lawyer” (LLP, Esq, etc.). As Morry likes to say, Heavyweight bestows the representation (appearance) of representation (counsel) by avoiding any representation (statement of fact) of legitimacy. Basically, you can have the power dynamic change just based on the aesthetic elements alone, at least if the person who receives the letter isn’t really looking too closely. (Heavyweight letterhead doesn’t have phone numbers or email addresses, which is probably a pretty good indicator that something is amiss in 2025.)
Is that really so different than Wachtell?
People keep asking me “do you actually want people to use it?” To be honest, I’m not sure.
I worry about people using it because I’m not sure it will work. I don’t actually think the letterhead will pass an inspection from anyone who is really paying attention, which is part of what makes it an ethical project, but also less useful for faking a lawyer.
If it does work, I don’t know how to feel. The more successful the letter is at fooling people (and we do have reports of it doing so), the more likely it is that someone might face adverse consequences for pretending that they are legally represented. When I was doing the initial legal research for this project, I could find almost no examples of legal action against non-lawyers for unauthorized practice of law for pretending to be represented by an attorney.
But ultimately, sometimes, having a lawyer-shaped entity show up is all it takes to get assholes to back down or go away. I’m not heartbroken at the idea that someone who doesn’t have the resources to get an attorney might be able to tap into the power of the law via aesthetics. After all, I can’t represent everyone who gets a silly letter.
The traffic cam selfie thing is why I thought we might get along, but to be honest, these days, my favorite work of Morry’s is his First Light project, where you can be the first person to see a star. ↩
To quote Annelise Riles’ work on documents, “As we will see, the document’s principal aesthetic device involves an alternation between concreteness (the document as object) and abstraction (the document as pattern).” ↩
See this opinion from the New York County Lawyers Association, specifying that letterhead must differentiate between partners and associates. ↩
When Andy Sellars and I were thinking about how to present our law firm, I looked at a lot of law firm websites, and quickly discovered that there were a lot of solo or small firms that seemed to be presenting themselves as much bigger. (We ended up going the opposite direction.) ↩
Syntax highlighting is a tool. It can help you read code faster. Find things quicker. Orient yourself in a large file.
Like any tool, it can be used correctly or incorrectly. Let’s see how to use syntax highlighting to help you work.
Christmas Lights Diarrhea
Most color themes have a unique bright color for literally everything: one for variables, another for language keywords, constants, punctuation, functions, classes, calls, comments, etc.
Sometimes it gets so bad one can’t see the base text color: everything is highlighted. What’s the base text color here?
The problem with that is, if everything is highlighted, nothing stands out. Your eye adapts and considers it a new norm: everything is bright and shiny, and instead of getting separated, it all blends together.
Here’s a quick test. Try to find the function definition here:
and here:
See what I mean?
So yeah, unfortunately, you can’t just highlight everything. You have to make decisions: what is more important, what is less. What should stand out, what shouldn’t.
Highlighting everything is like assigning “top priority” to every task in Linear. It only works if most of the tasks have lesser priorities.
If everything is highlighted, nothing is highlighted.
Enough colors to remember
There are two main use-cases you want your color theme to address:
Look at something and tell what it is by its color (you can tell by reading text, yes, but why do you need syntax highlighting then?)
Search for something. You want to know what to look for (which color).
1 is a direct index lookup: color → type of thing.
2 is a reverse lookup: type of thing → color.
Truth is, most people don’t do these lookups at all. They might think they do, but in reality, they don’t.
Let me illustrate. Before:
After:
Can you see it? I misspelled return for retunr and its color switched from red to purple.
I can’t.
Here’s another test. Close your eyes (not yet! Finish this sentence first) and try to remember what color your color theme uses for class names?
Can you?
If the answer for both questions is “no”, then your color theme is not functional. It might give you comfort (as in—I feel safe. If it’s highlighted, it’s probably code) but you can’t use it as a tool. It doesn’t help you.
What’s the solution? Have an absolute minimum of colors. So little that they all fit in your head at once. For example, my color theme, Alabaster, only uses four:
Green for strings
Purple for constants
Yellow for comments
Light blue for top-level definitions
That’s it! And I was able to type it all from memory, too. This minimalism allows me to actually do lookups: if I’m looking for a string, I know it will be green. If I’m looking at something yellow, I know it’s a comment.
Limit the number of different colors to what you can remember.
If you swap green and purple in my editor, it’ll be a catastrophe. If somebody swapped colors in yours, would you even notice?
What should you highlight?
Something there isn’t a lot of. Remember—we want highlights to stand out. That’s why I don’t highlight variables or function calls—they are everywhere, your code is probably 75% variable names and function calls.
I do highlight constants (numbers, strings). These are usually used more sparingly and often are reference points—a lot of logic paths start from constants.
Top-level definitions are another good idea. They give you an idea of a structure quickly.
Punctuation: it helps to separate names from syntax a little bit, and you care about names first, especially when quickly scanning code.
Please, please don’t highlight language keywords. class, function, if, elsestuff like this. You rarely look for them: “where’s that if” is a valid question, but you will be looking not at the if the keyword, but at the condition after it. The condition is the important, distinguishing part. The keyword is not.
Highlight names and constants. Grey out punctuation. Don’t highlight language keywords.
Comments are important
The tradition of using grey for comments comes from the times when people were paid by line. If you have something like
of course you would want to grey it out! This is bullshit text that doesn’t add anything and was written to be ignored.
But for good comments, the situation is opposite. Good comments ADD to the code. They explain something that couldn’t be expressed directly. They are important.
So here’s another controversial idea:
Comments should be highlighted, not hidden away.
Use bold colors, draw attention to them. Don’t shy away. If somebody took the time to tell you something, then you want to read it.
Two types of comments
Another secret nobody is talking about is that there are two types of comments:
Explanations
Disabled code
Most languages don’t distinguish between those, so there’s not much you can do syntax-wise. Sometimes there’s a convention (e.g. -- vs /* */ in SQL), then use it!
Here’s a real example from Clojure codebase that makes perfect use of two types of comments:
Disabled code is gray, explanation is bright yellow
Light or dark?
Per statistics, 70% of developers prefer dark themes. Being in the other 30%, that question always puzzled me. Why?
And I think I have an answer. Here’s a typical dark theme:
and here’s a light one:
On the latter one, colors are way less vibrant. Here, I picked them out for you:
Notice how many colors there are. No one can remember that many.
This is because dark colors are in general less distinguishable and more muddy. Look at Hue scale as we move brightness down:
Basically, in the dark part of the spectrum, you just get fewer colors to play with. There’s no “dark yellow” or good-looking “dark teal”.
Nothing can be done here. There are no magic colors hiding somewhere that have both good contrast on a white background and look good at the same time. By choosing a light theme, you are dooming yourself to a very limited, bad-looking, barely distinguishable set of dark colors.
So it makes sense. Dark themes do look better. Or rather: light ones can’t look good. Science ¯\_(ツ)_/¯
But!
But.
There is one trick you can do, that I don’t see a lot of. Use background colors! Compare:
The first one has nice colors, but the contrast is too low: letters become hard to read.
The second one has good contrast, but you can barely see colors.
The last one has both: high contrast and clean, vibrant colors. Lighter colors are readable even on a white background since they fill a lot more area. Text is the same brightness as in the second example, yet it gives the impression of clearer color. It’s all upside, really.
UI designers know about this trick for a while, but I rarely see it applied in code editors:
If your editor supports choosing background color, give it a try. It might open light themes for you.
Bold and italics
Don’t use. This goes into the same category as too many colors. It’s just another way to highlight something, and you don’t need too many, because you can’t highlight everything.
In theory, you might try to replace colors with typography. Would that work? I don’t know. I haven’t seen any examples.
Using italics and bold instead of colors
Myth of number-based perfection
Some themes pay too much attention to be scientifically uniform. Like, all colors have the same exact lightness, and hues are distributed evenly on a circle.
This could be nice (to know if you have OCR), but in practice, it doesn’t work as well as it sounds:
The idea of highlighting is to make things stand out. If you make all colors the same lightness and chroma, they will look very similar to each other, and it’ll be hard to tell them apart.
Our eyes are way more sensitive to differences in lightness than in color, and we should use it, not try to negate it.
Let’s design a color theme together
Let’s apply these principles step by step and see where it leads us. We start with the theme from the start of this post:
First, let’s remove highlighting from language keywords and re-introduce base text color:
Next, we remove color from variable usage:
and from function/method invocation:
The thinking is that your code is mostly references to variables and method invocation. If we highlight those, we’ll have to highlight more than 75% of your code.
Notice that we’ve kept variable declarations. These are not as ubiquitous and help you quickly answer a common question: where does thing thing come from?
Next, let’s tone down punctuation:
I prefer to dim it a little bit because it helps names stand out more. Names alone can give you the general idea of what’s going on, and the exact configuration of brackets is rarely equally important.
But you might roll with base color punctuation, too:
Okay, getting close. Let’s highlight comments:
We don’t use red here because you usually need it for squiggly lines and errors.
This is still one color too many, so I unify numbers and strings to both use green:
Finally, let’s rotate colors a bit. We want to respect nesting logic, so function declarations should be brighter (yellow) than variable declarations (blue).
Compare with what we started:
In my opinion, we got a much more workable color theme: it’s easier on the eyes and helps you find stuff faster.
It’s also been ported to many other editors and terminals; the most complete list is probably here. If your editor is not on the list, try searching for it by name—it might be built-in already! I always wondered where these color themes come from, and now I became an author of one (and I still don’t know).
Feel free to use Alabaster as is or build your own theme using the principles outlined in the article—either is fine by me.
As for the principles themselves, they worked out fantastically for me. I’ve never wanted to go back, and just one look at any “traditional” color theme gives me a scare now.
I suspect that the only reason we don’t see more restrained color themes is that people never really thought about it. Well, this is your wake-up call. I hope this will inspire people to use color more deliberately and to change the default way we build and use color themes.