Skip to content

Colour system

Gradients

Two natural-law gradients, atmospheric extinction and the Moffat profile, built only from opacity ladder steps.

Shared rules

Both gradients take their colour from --grad-color, which accepts any colour stop, and their direction from --grad-dir where it applies. Every alpha is one of the --mag-* steps, and interpolation happens in sRGB so a Flutter gradient renders identically.

A computed alpha is snapped to the nearest step:

n∗=clamp⁡(round⁡(−5log⁡10α), 0, 10)n^{*} = \operatorname{clamp}\bigl(\operatorname{round}(-5\log_{10}\alpha),\,0,\,10\bigr)

Beyond the last step there is a floor: when −5log⁡10α≥10.5-5\log_{10}\alpha \ge 10.5 the stop is fully transparent instead of --mag-10.

Atmospheric extinction

Light from a star loses brightness as it crosses more atmosphere. The loss in magnitudes is proportional to the relative airmass XX minus one, with an extinction coefficient kk:

α(z)=10−0.4 k (X(z)−1),k=0.2\alpha(z) = 10^{-0.4\,k\,(X(z)-1)},\qquad k = 0.2

The airmass for a zenith angle zz in degrees comes from the Kasten and Young approximation:

X(z)=1cos⁡z+0.50572 (96.07995∘−z)−1.6364X(z) = \frac{1}{\cos z + 0.50572\,\left(96.07995^{\circ} - z\right)^{-1.6364}}

Stops sit at z = 0, 60, 70, 78, 84, 88 and 90 degrees. Each stop's position along the gradient is p=z/90∘p = z / 90^{\circ}, so the zenith is at 0% and the horizon at 100%.

gradient-extinction [--grad-color:var(--color-deep-space-300)]

With the default direction the top edge is the zenith and the bottom edge is the horizon.

Alpha snaps to the nearest --mag step; a stop below the 10.5 half-step floor becomes transparent. Every row is verified against globals.css at build time.
z (deg)Airmass XPositionRaw alphaSnapped stepSnapped alphaCSS stopMatch
01.0000%1.0000--mag-0100.00%--mag-0 @ 0%✓
601.99466.7%0.8326--mag-0100.00%--mag-0 @ 66.7%✓
702.90377.8%0.7043--mag-163.10%--mag-1 @ 77.8%✓
784.70986.7%0.5050--mag-163.10%--mag-1 @ 86.7%✓
848.84193.3%0.2359--mag-325.12%--mag-3 @ 93.3%✓
8819.43397.8%0.0335--mag-73.98%--mag-7 @ 97.8%✓
9037.920100%0.0011transparent0.00%transparent @ 100%✓

Moffat profile

A point source blurred by the atmosphere spreads into a glow described by the Moffat function of radius rr and width aa:

I(r)=(1+(r/a)2)−β,β=3I(r) = \left(1 + (r/a)^2\right)^{-\beta},\qquad \beta = 3

The gradient reaches full transparency at a radius of four widths:

R=4aR = 4a

so a stop at position pp sits at r=4a pr = 4a\,p, where the position is measured as p=r/(4a)p = r / (4a).

gradient-moffat [--grad-color:var(--color-deep-space-300)]

The centre is the source; intensity falls off to transparent at 60% of the radius.

Alpha snaps to the nearest --mag step; a stop below the 10.5 half-step floor becomes transparent. Every row is verified against globals.css at build time.
Position pr / aI(r)Snapped stepSnapped alphaCSS stopMatch
0%0.001.0000--mag-0100.00%--mag-0 @ 0%✓
10%0.400.6407--mag-163.10%--mag-1 @ 10%✓
20%0.800.2267--mag-325.12%--mag-3 @ 20%✓
30%1.200.0688--mag-66.31%--mag-6 @ 30%✓
40%1.600.0222--mag-82.51%--mag-8 @ 40%✓
50%2.000.0080--mag-101.00%--mag-10 @ 50%✓
60%2.400.0032transparent0.00%transparent @ 60%✓
100%4.000.0002transparent0.00%transparent @ 100%✓

Usage

html
<div class="gradient-extinction [--grad-color:var(--color-deep-space-300)]"></div><div class="gradient-moffat [--grad-color:var(--color-space-grey-200)]"></div>
globals.css
@utility gradient-extinction {  background-image: linear-gradient(    in srgb var(--grad-dir, to bottom),    color-mix(in srgb, var(--grad-color) var(--mag-0), transparent) 0%,    color-mix(in srgb, var(--grad-color) var(--mag-0), transparent) 66.7%,    color-mix(in srgb, var(--grad-color) var(--mag-1), transparent) 77.8%,    color-mix(in srgb, var(--grad-color) var(--mag-1), transparent) 86.7%,    color-mix(in srgb, var(--grad-color) var(--mag-3), transparent) 93.3%,    color-mix(in srgb, var(--grad-color) var(--mag-7), transparent) 97.8%,    transparent 100%  );}
globals.css
@utility gradient-moffat {  background-image: radial-gradient(    in srgb circle closest-side,    color-mix(in srgb, var(--grad-color) var(--mag-0), transparent) 0%,    color-mix(in srgb, var(--grad-color) var(--mag-1), transparent) 10%,    color-mix(in srgb, var(--grad-color) var(--mag-3), transparent) 20%,    color-mix(in srgb, var(--grad-color) var(--mag-6), transparent) 30%,    color-mix(in srgb, var(--grad-color) var(--mag-8), transparent) 40%,    color-mix(in srgb, var(--grad-color) var(--mag-10), transparent) 50%,    transparent 60%,    transparent 100%  );}