CORPORATE DESIGN
How this site is built to look
Colours, type, spacing and the components they live in. Everything here is read from the files, so it stays true when the files change.
Start here
This is the English site, kagels-trading.com, built new in Astro. Pages are plain files in this repository and the whole site is generated at build time, so there is no theme, no page builder and no database.
The design is deliberately quiet
A dark blue box, real numbers, plain cards. No gradients, no glow, no dotted backgrounds, no generic icons. The charts and the figures are the decoration.
Five colours and one width
The shared values live in the
:rootblock ofBase.astro. Everything else is styled inside the component it belongs to.No web font
The site uses the reader's system font. Nothing is downloaded, and the page looks slightly different on a Mac than on a Windows PC. That is intended.
Content beats decoration
Karsten's charts, his photo and the price levels carry the pages. When something new is added, it is added in small steps and it has to earn its place.
Logo
Two colours, no more. The wordmark is blue and black on white, and it is never recoloured, tinted or put on a busy background.
- Logo blue#084ec5The two bulls above the name
- Logo black#000000The whole wordmark, both words
The logo blue is not the site blue. The logo carries #084ec5, the site works with --color-accent-dark #0f2a5c, which is much darker. They sit next to each other on every page and neither replaces the other. Do not use #084ec5 for text, buttons or surfaces, and do not repaint the logo in #0f2a5c.
Where the files are
| File | Size | Used for |
|---|---|---|
src/assets/kagels-trading-logo.svg | 175 x 51 | The header. Shown 44px high, 52px from 640px up, 60px from 1024px up |
src/assets/kagels-trading-logo.png | 640 x 243 | The structured data, so Google has a logo it can read |
src/assets/kagels-trading-logo-white.svg | 175 x 51 | Dark surfaces. Same paths as the SVG above, white fills |
Two versions, one geometry
On white the logo blue reaches 7.23:1, which is comfortable. On the dark blue it would fall to 1.93:1 and the bulls would disappear, so dark surfaces get the white version instead. Both files hold the same 35 paths in the same places: only the fills differ, and the shapes are never redrawn.
Left, the original on white and on any light surface. Right, kagels-trading-logo-white.svg on the dark blue. The white version is for dark grounds only: on white it is invisible.
Colour
Five colour variables, declared once in src/layouts/Base.astro, used everywhere. The chips fill from the variables themselves.
- --color-text#111111Body text, headings
- --color-text-soft#555555Captions, meta lines, secondary text
- --color-accent-dark#0f2a5cHero box, figures, active borders
- --color-border#e5e5e5Every hairline and card edge
- --color-background#ffffffPage background
Colours that are not variables yet
Four more colours are written directly into the components that use them. They are part of the look, so they belong here even though they do not have a name yet. Two more sit outside the stylesheet altogether: the logo blue above, which lives in the logo file, and the chart background #0d1b33, which lives in TradingView and is baked into every exported chart.
| Value | Where | What it does |
|---|---|---|
| #b9ccff | Homepage and forecast hero | The small label above the headline, on dark blue |
| #dbe4ff | Forecast hero | The date line under the headline, on dark blue |
| #e6ecff | Homepage button | Hover state of the white button on dark blue |
| #f4f6fa | Tables in forecasts and posts | Header row background |
Contrast
Text has to stay readable, so these are the pairs the site actually uses, measured against the WCAG rule of 4.5:1 for normal text.
| Pair | Ratio | Verdict |
|---|---|---|
| #111111 on white | 18.88:1 | Body text, passes |
| #555555 on white | 7.46:1 | Secondary text, passes |
| White on #0f2a5c | 13.94:1 | Hero copy, passes |
| #b9ccff on #0f2a5c | 8.73:1 | Hero label, passes |
| #dbe4ff on #0f2a5c | 10.99:1 | Hero date line, passes |
| #0f2a5c on white | 13.94:1 | Figures and links on light, passes |
Type
One family, the system stack: system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif. Body text is 1.125rem with a line height of 1.6.
Sizes are set per page rather than in one scale, so the same level can differ between a text page and a forecast. These are the sizes in use.
| Where | Level | Size |
|---|---|---|
| Homepage hero | h1 | clamp(2.1rem, 5vw, 3.4rem), line height 1.15 |
| Forecast hero | h1 | clamp(2rem, 5vw, 3rem), line height 1.15 |
| Text pages | h1 | clamp(2rem, 5vw, 2.8rem), line height 1.15 |
| Homepage and forecast | Section h2 | 1.9rem |
| Text pages | h2 | 1.4rem |
| Cards and tables of contents | h3 | 1.2rem, homepage cards 1.25rem |
| Lead paragraph | p | 1.3rem, forecast hero 1.25rem |
| Label above a headline | p | 0.95rem, weight 600, letter spacing 0.08em |
| Captions, meta, breadcrumbs | p | 0.95rem to 1rem |
Prices and price levels always use font-variant-numeric: tabular-nums, so the digits line up in a column. How a price is written (decimals, currency sign, points) is decided in src/lib/prices.ts, not in the markup.
Layout and spacing
| Value | What it does |
|---|---|
| 1100px | --content-width, the width of the page, centred |
| 2rem 1.5rem | Padding around the main column, 2.5rem on top from 1024px up |
| 70ch | Reading column for running text |
| 60ch | Lead paragraph under a headline |
| 22ch to 24ch | Headline in a hero box, so it breaks into two or three lines |
| 1rem | Gap in every card grid |
| 1px solid #e5e5e5 | Every border on the site |
Corners
Four radii are in use, and they are not interchangeable: 12px for a hero box and the author box, 10px for cards, images and the level list, 8px for buttons and range rows, 6px for the small hint on a chart.
Grids
Card rows are repeat(auto-fit, minmax(...)) with a minimum between 200px and 260px, so they fold from three columns to two to one without a media query. Only the layouts that carry a photo or a sidebar switch at 1024px and 700px.
Components
Nine components and two layouts. Build with these before writing anything new.
| File | What it is |
|---|---|
Base.astro | The frame of every page: head, structured data, header, footer. Title and description are required |
Page.astro | Simple text pages: about, contact, imprint, privacy |
Header.astro | Logo and navigation, one hairline underneath |
Footer.astro | Legal links and the year, set automatically |
Breadcrumbs.astro | The trail above the headline, also reported to Google |
ChartFigure.astro | Every chart on the site. Image, caption, and the click that opens it larger |
Lightbox.astro | The enlarged chart: a <dialog> that closes on click, Escape or the round button |
LevelList.astro | Support and resistance levels, with the current price highlighted in dark blue |
ForecastCards.astro | The row of forecast cards, on the homepage and the hub |
AuthorBox.astro | Photo, name, role and profile links under an article |
ExternalLink.astro | A link that leaves the site. Opens in a new tab and carries rel="noopener" |
Patterns
Six shapes carry almost every page. They are shown here as they are built, not as pictures of themselves.
Hero box
GOLD FORECAST
Gold holds above its March range
What the levels say, and what would change the picture.
Dark blue, 12px corners, white text, a label in #b9ccff above the headline. It opens the homepage and every forecast.
Figure tiles
- 1980First shares bought
- 1986Trading actively
- 2015Forecasts published
The number is 2.2rem in dark blue, the label sits underneath in the soft grey. Used for facts a reader should remember.
Card
Silver price forecast
Updated twice a day, with six charts from hour to year.
Copper price forecast
Three charts, the contango explained in plain words.
1px border, 10px corners, heading and one soft grey line. On hover the border turns dark blue. Nothing else moves.
Price levels
Resistance
- $3,700
- $3,790
Support
- $3,560
- $3,480
The current price sits in the dark blue row at the top, the levels underneath in tabular figures.
Range row
- This week$3,560 to $3,700
- This month$3,480 to $3,790
A thin border with a 4px dark blue edge on the left. Used for forecast ranges.
Table
| Period | Low | High |
|---|---|---|
| Week | 3,560 | 3,700 |
| Month | 3,480 | 3,790 |
Header row on #f4f6fa, every cell framed, and the whole table scrolls sideways on a phone instead of breaking the page.
Charts
Charts are the most valuable thing on this site, so they get their own rule. Karsten draws them in TradingView and exports them as images, which means the background colour is baked into every file. It is decided once and then left alone.
The chart background is #0d1b33, a near black with a blue cast. Not the hero blue and not plain black: it sits at the brightness of a black background, which is what hours of chart reading need, and it still belongs to the blue family the rest of the site is built from. Black backgrounds are no longer used.
It was weighed, not picked. The same setting produces the charts Karsten works in all day and the charts a reader sees for half a minute, so daily comfort counted for more than branding. Against the hero blue, this background gains three points of contrast on white bars and about a point on every coloured marker, which is what a long session notices. Do not change it for looks.
What can be drawn on it
Measured against the chart background, so nothing is chosen by eye.
| Element | Colour | Ratio | Verdict |
|---|---|---|---|
| Bars and candles | white | 17.19:1 | The default. Direction is carried by shape, not colour |
| Axis labels, dates, prices | #dbe4ff | 13.55:1 | Reads clearly without shouting |
| Secondary labels | #b9ccff | 10.76:1 | For anything below the main scale |
| Up marker | #26a69a | 5.73:1 | Works, and it holds as a thin line too |
| Down marker | #ef5350 | 4.93:1 | Works. Still worth drawing thick on a busy chart |
| Indicator lines | #ffd814 or #ffa500 | 12.35:1, 8.70:1 | Yellow and orange. White works too |
| Any blue line | #2962ff | 3.51:1 | Never. TradingView's default blue for moving averages sits too close to the background, so indicators are recoloured instead |
| Logo blue | #084ec5 | 2.38:1 | Never. It disappears on this background |
Line colours for levels
Horizontal levels are the one thing drawn on almost every chart, so they get a small fixed set. All three clear 8:1 on the background, which means a one pixel line still reads.
| Colour | Ratio | Use |
|---|---|---|
| #ffd814 yellow | 12.35:1 | The level that matters most on this chart |
| #9be870 light green | 11.60:1 | Support, and levels that held |
| #ffa500 orange | 8.70:1 | Resistance, and levels still to be tested |
Three colours are enough. A fourth and a fifth turn a chart into a colour code the reader has to learn, and the price action stops being the loudest thing on the screen.
How to keep them identical
- Save a TradingView template and load it for every export.Six charts in one forecast have to look like six pictures of the same screen, not six settings.
- Grid lines stay quiet. A faint white is enough on this background. Visible grid lines compete with the price itself.
- The background is never edited afterwards. Changing it later means exporting every chart on the site again.
- Labels in English. Text inside the image cannot be translated later, so it has to be right when the chart is exported.
- Charts go through
ChartFigure.astro, which gives them the 10px corners, the caption and the click that opens them larger.
Rules
Decisions that are already made. They are in AGENTS.md in full, with the date and the reason.
- Design direction
- The current look is the starting point and gets developed in small steps, not reinvented. Modern touches sparingly: no gradients, no glow, no dot or grid backgrounds, no generic icons, no "Get started".
- Charts
- Every chart goes through
ChartFigure.astroand can be opened larger by clicking it. Charts carry German and English labels for now. - External links
- Always a new tab, always through
ExternalLink.astroor the markdown plugin, alwaysrel="noopener"without noreferrer, so a linked provider can see where the visitor came from. - No affiliate links
- Providers are linked directly, never through the German redirects.
- Copy
- English, plain, no dashes as punctuation. Write two sentences instead of one with an insert.
- Prices
- Formatted by
src/lib/prices.ts, which knows dollars, points and exchange rates. Never formatted by hand in a page. - Addresses
- Forecasts keep the addresses the old WordPress site used, so their rankings survive without a redirect.
- Internal links
- A new article links to the ones it belongs with, and they link back to it. A dead internal link breaks the build.
- Translations
- Every translation from the German site follows
docs/translation-checklist.md. Where it disagrees with AGENTS.md, AGENTS.md wins.
Where things live
| Path | What is in it |
|---|---|
src/layouts/Base.astro | The colour variables, the page width, the global styles |
src/components/ | The nine components, each with its own styles |
src/pages/ | One file per page, styles included |
src/content/ | Blog posts and forecasts as markdown |
src/data/site.ts | Company facts, team, dates. Edited by hand, never guessed |
src/lib/prices.ts | How every price on the site is written |
src/assets/charts/ | Karsten's chart images, one folder per market |
AGENTS.md | Every decision, with its date |
docs/translation-checklist.md | What a translation has to clear before it goes live |
Not settled yet
An honest list, so nobody designs into a gap that is already known.
- The palette is only half named. Five colours are variables, four more are written into the components that use them. If the dark blue ever changes, those four have to be found by hand.
- There is no type scale. Sizes are chosen per page, so an h2 is 1.9rem on the homepage and 1.4rem on a text page. It works, but it is a decision each time rather than a rule.
- Older charts still carry German labels in their pixels.New exports are English. The old ones are replaced market by market, whenever a forecast gets new charts anyway.
- The site is not on its own domain yet. It runs on the workers.dev address until the old WordPress site is redirected.
- This page has no mockup. It was built from the files it documents, which is the one place where that is the right way round.