Join Us On The Dark Side

For April Fools Day this year, the engineering team at Grata decided to surprise users with a dark theme of our app. Join us on the Dark Side!
No items found.
Join Us On The Dark Side

For April Fools Day this year, the engineering team at Grata decided to surprise users with a dark theme of our app, welcoming them with a message from well known dark theme enthusiast:

Grata home screen on April Fools' Day

To convert the entire application to a dark theme as quickly as possible, while still allowing users the ability to switch back to a light theme, we took advantage of a new technique for our codebase: CSS Variables.

To avoid having to individually add a dark version for every element and style in our platform, we decided to convert all existing color-related styling to reference variables instead. Doing so allows us to edit a color once and all areas in the platform where that is used would change together.

Given the inheritance rules for CSS variables, we were able to add a single class to <body> and override all existing colors with dark versions for each. And because our platform mainly uses different shades of grays, we can simply inverse the RGB values to achieve similar effects coming from the dark direction. So if we start with the value rgb(245,245,255) in the existing theme, we can calculate the distance from white for each color (so 255 - 245 = 10) and map that as a starting point from 0. Our example becomes rgb(10,10,20).

You may have noticed we didn't do that for the blue value; that is because we tend to add a bit of blue to all of our grays in the platform, and if we were to use the same logic as we do for red and green, it would change the tone of the platform to be more purple.

Comparison of dark and light themes
Alternating between Dark Mode and Light Mode

There were some cases where the grays had to be changed a bit to create a more natural look, and we ended up adding an offset value of 10 to prevent the platform from becoming too black. This allows for a more pleasant, dark-blue theme rather than a high-contrast, black theme, and also maintains the ability to add black shadows behind popups and tiles (a valuable UI aspect that is necessary to have elements stand out from each other). We also had to manually touch up a few elements that didn't stand out enough or looked odd with this mathematical inversion approach, stepping in for individually selected dark theme colors. So now, our platform looks a bit like this. We first define the raw RGB values upfront, and reference them in our color variables.

 /* brand colors */
 --grata-green: #26d9ca; /* darkened version of logo color */
 --grata-blue: #00a3d0; /* middle color in logo */
 --grata-dark-blue: #1072bd; /* dark blue in logo */
 --logo-text: #0b568f; /* text in logo */

 /* platform colors */
 --rgb-black:      0, 0, 0;
 --rgb-white:      255, 255, 255;
 --rgb-gray:       115, 115, 130;
 --rgb-gray-50:    50, 50, 60;
 ...
 --rgb-gray-253:   253, 253, 255;

 --black:          rgb(var(--rgb-black));
 --white:          rgb(var(--rgb-white));
 --gray:           rgb(var(--rgb-gray));
 --gray-50:        rgb(var(--rgb-gray-50));
 ...
 --gray-253:       rgb(var(--rgb-gray-253));
 --green:          #00C086;
 --limegreen:      #67CE1E;
 --seagreen:       #0D8BA5;
 --blue:           #08a1dd;
 --darkblue:       #3284E3;
 --orange:         #FF7F1D;
 --purple:         #574FB9;
 --magenta:        #BB62D3;
 --lilac:          #818AFE;
 --yellow:         #FFA400;
 --teal:           #13C2C2;
 --pink:           #E1528D;
 --red:            #F4342A;

Then for the dark theme, we override the raw RGB values, which are still referenced above by the color variables. By keeping the black-point offset a variable, we're able to dynamically shift the brightness of the dark theme without having to individually calculate or update each gray value.

html.dark {
 color: white;
 --logo-text:              var(--grata-dark-blue);
 --grata-dark-blue:        var(--grata-blue);
 --c-offset:       10;

 /* platform colors */
 --rgb-white:      20, 20, 30;
 --rgb-black:      calc(var(--c-offset) + 255), calc(var(--c-offset) + 255), calc(var(--c-offset) + 255);
 --rgb-gray:       calc(var(--c-offset) + 140), calc(var(--c-offset) + 140), calc(var(--c-offset) + 150);
 --rgb-gray-50:    calc(var(--c-offset) + 205), calc(var(--c-offset) + 205), calc(var(--c-offset) + 215);
 ...
 --rgb-gray-253:   calc(var(--c-offset) + 2), calc(var(--c-offset) + 2), calc(var(--c-offset) + 4);

 --box-shadow:     0 1px 6px 0 rgba(0, 0, 0, 0.56), 0 2px 32px 0 rgba(0, 0, 0, 0.66), inset 0 0 0 3px var(--gray-240);
 --tile-shadow:    0 -1px 3px rgba(0,0,0,0.55), 0 1px 2px rgba(0,0,0,0.62);
 ...
}

We'll be highlighting more of our engineering process, explorations through new technologies, challenges and more soon!


Subscribe to our newsletter

Monthly tactics from Grata’s team and operators.

Related
Articles

From market trends to career advice, Grata’s content fuels smarter decisions.

How to Identify Companies Preparing to Sell Before the Competition
Sourcing

How to Identify Companies Preparing to Sell Before the Competition

Learn how to identify companies preparing to sell before a formal process starts, using behavioral signals that flag seller intent 6–12 months early.
The New Deal Team: How AI Is Changing Every Role in M&A
AI & Automation

The New Deal Team: How AI Is Changing Every Role in M&A

AI is reshaping every role on the M&A deal team — from analyst to partner. Here's what that means for the firms building for the next generation of dealmaking.
Early Deal Intelligence: The New Private Market Competitive Advantage
Business Development
Data/Analytics

Early Deal Intelligence: The New Private Market Competitive Advantage

What is early deal intelligence? Learn how Grata's Seller Intent flags companies preparing to sell, 6-12 months before a formal process begins.
Hidden Gems: Actionable, Undiscovered Opportunities in the HVAC Industry
Industrials
Data/Analytics

Hidden Gems: Actionable, Undiscovered Opportunities in the HVAC Industry

Discover 79 undiscovered HVAC companies with high Seller Intent scores. See ownership, geographic, and sector breakdowns from Grata's proprietary private market data.
Grata Expands Global Intelligence Platform with Integrated Valu8 Data, MCP Launch, and Customers in 26 Countries
UK & Ireland
Acquisition
DACH

Grata Expands Global Intelligence Platform with Integrated Valu8 Data, MCP Launch, and Customers in 26 Countries

Platform surpasses 23 million companies and 1 million transaction events following successful Valu8 integration
The PE Playbook: HVAC
Industrials
Private Equity
Market Trends

The PE Playbook: HVAC

Discover the top HVAC trends for middle market dealmakers - fragmentation, consolidation, growth areas, and recent acquisitions shaping the sector.
How Dealmakers Win Now That AI Is Table Stakes
AI & Automation

How Dealmakers Win Now That AI Is Table Stakes

New research from Financial Times Longitude and Datasite shows AI is becoming standard across M&A workflows. Learn why the next competitive advantage won't be the technology itself — but the quality of the private-market intelligence powering it.
Blue backgound