palette
This commit is contained in:
parent
d0099fbf19
commit
815ef5c23f
10 changed files with 256 additions and 131 deletions
6
Makefile
6
Makefile
|
@ -5,7 +5,8 @@ MEDIA = \
|
||||||
$(wildcard media/*.png) $(wildcard media/*.gif) $(wildcard media/*.webp) \
|
$(wildcard media/*.png) $(wildcard media/*.gif) $(wildcard media/*.webp) \
|
||||||
$(wildcard media/flags/*) $(wildcard media/buttons/*) \
|
$(wildcard media/flags/*) $(wildcard media/buttons/*) \
|
||||||
$(wildcard media/icons/*) $(wildcard media/bg/*) 8831.png 8831-quox.png \
|
$(wildcard media/icons/*) $(wildcard media/bg/*) 8831.png 8831-quox.png \
|
||||||
$(wildcard rainbow-quox/front/*) $(wildcard rainbow-quox/back/*)
|
$(wildcard rainbow-quox/front/*) $(wildcard rainbow-quox/back/*) \
|
||||||
|
rainbow-quox/palette.svg
|
||||||
SCRIPTS = $(patsubst %.ts,%.js,$(wildcard script/*.ts rainbow-quox/*.ts))
|
SCRIPTS = $(patsubst %.ts,%.js,$(wildcard script/*.ts rainbow-quox/*.ts))
|
||||||
MISC = $(shell find .well-known -type f)
|
MISC = $(shell find .well-known -type f)
|
||||||
ALL = $(CSS) $(PAGES) $(MEDIA) $(SCRIPTS) $(MISC)
|
ALL = $(CSS) $(PAGES) $(MEDIA) $(SCRIPTS) $(MISC)
|
||||||
|
@ -59,6 +60,9 @@ $(BUILDDIR)/%.js: %.ts
|
||||||
--lib dom,es2023 --target es2015 \
|
--lib dom,es2023 --target es2015 \
|
||||||
--outDir $(dir $@) $^
|
--outDir $(dir $@) $^
|
||||||
|
|
||||||
|
$(BUILDDIR)/rainbow-quox/palette.svg: rainbow-quox/palette.svg.raku
|
||||||
|
raku $^ $@
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) -r $(TMPDIR) $(BUILDDIR)
|
$(RM) -r $(TMPDIR) $(BUILDDIR)
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
"static": [219, 41],
|
"static": [219, 41],
|
||||||
"stripes": [219, 221],
|
"stripes": [219, 221],
|
||||||
"vitiligo1": [4, 22],
|
"vitiligo1": [4, 22],
|
||||||
"vitiligo2": [46, 48],
|
"vitiligo2": [102, 134],
|
||||||
"vitiligo3": [101, 134],
|
"vitiligo3": [46, 129],
|
||||||
"vitiligo4": [221, 56]
|
"vitiligo4": [221, 56]
|
||||||
}
|
}
|
||||||
|
|
BIN
rainbow-quox/back/vitiligo2.webp
(Stored with Git LFS)
BIN
rainbow-quox/back/vitiligo2.webp
(Stored with Git LFS)
Binary file not shown.
BIN
rainbow-quox/back/vitiligo3.webp
(Stored with Git LFS)
BIN
rainbow-quox/back/vitiligo3.webp
(Stored with Git LFS)
Binary file not shown.
|
@ -38,7 +38,6 @@ type Rgbs = Record<Color.Layer, Rgb>;
|
||||||
let rgbBuf = new OffscreenCanvas(1, 1).getContext('2d')!;
|
let rgbBuf = new OffscreenCanvas(1, 1).getContext('2d')!;
|
||||||
|
|
||||||
function toRgb(col: Color.Oklch): Rgb {
|
function toRgb(col: Color.Oklch): Rgb {
|
||||||
// :)
|
|
||||||
rgbBuf.fillStyle = col.css();
|
rgbBuf.fillStyle = col.css();
|
||||||
rgbBuf.fillRect(0, 0, 1, 1);
|
rgbBuf.fillRect(0, 0, 1, 1);
|
||||||
const rgb = rgbBuf.getImageData(0, 0, 1, 1).data;
|
const rgb = rgbBuf.getImageData(0, 0, 1, 1).data;
|
||||||
|
@ -49,6 +48,14 @@ function toRgbs(col: Color.Colors): Rgbs {
|
||||||
return Color.makeColorInfo(l => toRgb(col[l]));
|
return Color.makeColorInfo(l => toRgb(col[l]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toHex([r, g, b]: Rgb): string {
|
||||||
|
function chan(n: number) {
|
||||||
|
let a = Math.floor(n).toString(16);
|
||||||
|
return a.length == 1 ? `0${a}` : a;
|
||||||
|
}
|
||||||
|
return `#${chan(r)}${chan(g)}${chan(b)}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function setImageDataRgb({ data }: ImageData, [r, g, b]: Rgb, a: number = -1) {
|
function setImageDataRgb({ data }: ImageData, [r, g, b]: Rgb, a: number = -1) {
|
||||||
for (let i = 0; i < data.length; i += 4) {
|
for (let i = 0; i < data.length; i += 4) {
|
||||||
|
@ -84,7 +91,6 @@ async function loadSide(buf: OffscreenCanvasRenderingContext2D,
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
allLayers.map(l => load(buf, side, l).then(res => [l, res])))
|
allLayers.map(l => load(buf, side, l).then(res => [l, res])))
|
||||||
) as Record<Layer, ImageData>;
|
) as Record<Layer, ImageData>;
|
||||||
console.log(images);
|
|
||||||
for (const l of allLayers) {
|
for (const l of allLayers) {
|
||||||
layers[l] = { data: images[l], pos: pos[l] };
|
layers[l] = { data: images[l], pos: pos[l] };
|
||||||
}
|
}
|
||||||
|
@ -131,7 +137,7 @@ function message(msg: string, ctx: CanvasRenderingContext2D) {
|
||||||
ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
ctx.clearRect(0, 0, WIDTH, HEIGHT);
|
||||||
ctx.font = 'bold 100px Muller, sans-serif';
|
ctx.font = 'bold 100px Muller, sans-serif';
|
||||||
ctx.textAlign = 'center';
|
ctx.textAlign = 'center';
|
||||||
ctx.fillText(msg, WIDTH/2, HEIGHT/2);
|
ctx.fillText(msg, WIDTH/2, HEIGHT/2, WIDTH-10);
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,13 +173,14 @@ class Side {
|
||||||
layers() { return this.cur == 'front' ? this.fronts : this.backs; }
|
layers() { return this.cur == 'front' ? this.fronts : this.backs; }
|
||||||
|
|
||||||
async recolorOn(ctx: CanvasRenderingContext2D,
|
async recolorOn(ctx: CanvasRenderingContext2D,
|
||||||
buf: OffscreenCanvasRenderingContext2D) {
|
buf: OffscreenCanvasRenderingContext2D):
|
||||||
|
Promise<[Color.Colors, Rgbs]> {
|
||||||
const cols = Color.colors();
|
const cols = Color.colors();
|
||||||
const rgbs = toRgbs(cols);
|
const rgbs = toRgbs(cols);
|
||||||
setColors(rgbs, this.fronts);
|
setColors(rgbs, this.fronts);
|
||||||
setColors(rgbs, this.backs);
|
setColors(rgbs, this.backs);
|
||||||
await redraw(ctx, buf, this.layers());
|
await redraw(ctx, buf, this.layers());
|
||||||
return cols.outer.h;
|
return [cols, rgbs];
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureComposed(buf: OffscreenCanvasRenderingContext2D) {
|
async ensureComposed(buf: OffscreenCanvasRenderingContext2D) {
|
||||||
|
@ -187,15 +194,53 @@ function setBg(hue: number) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getPalette(): XMLDocument | null {
|
||||||
|
const palette = document.getElementById('palette') as HTMLObjectElement;
|
||||||
|
return palette.contentDocument;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setPalette(oklch: Color.Colors, rgb: Rgbs) {
|
||||||
|
const palette = getPalette();
|
||||||
|
|
||||||
|
if (!palette) {
|
||||||
|
setTimeout(() => setPalette(oklch, rgb), 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
palette.documentElement.style.setProperty('--hue', `${oklch.outer.h}`);
|
||||||
|
console.log(palette);
|
||||||
|
|
||||||
|
for (const l of Color.allLayers) {
|
||||||
|
let col = toHex(rgb[l]);
|
||||||
|
|
||||||
|
const swatch = palette.getElementById(`s-${l}`);
|
||||||
|
if (swatch) swatch.style.fill = col;
|
||||||
|
|
||||||
|
const text = palette.getElementById(`c-${l}`);
|
||||||
|
if (text) text.innerHTML = col;
|
||||||
|
|
||||||
|
const bg = palette.getElementById(`p-${l}`);
|
||||||
|
if (bg) bg.style.fill = col;
|
||||||
|
|
||||||
|
const item = palette.getElementById(`i-${l}`);
|
||||||
|
if (item) {
|
||||||
|
const textCol = oklch[l].l < 0.6 ? 'white' : 'black';
|
||||||
|
item.style.setProperty('--text', textCol);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async function animateReroll(ctx1: CanvasRenderingContext2D,
|
async function animateReroll(ctx1: CanvasRenderingContext2D,
|
||||||
ctx2: CanvasRenderingContext2D,
|
ctx2: CanvasRenderingContext2D,
|
||||||
buf: OffscreenCanvasRenderingContext2D,
|
buf: OffscreenCanvasRenderingContext2D,
|
||||||
side: Side,
|
side: Side, done: () => void) {
|
||||||
done: () => void) {
|
|
||||||
const duration = 200;
|
const duration = 200;
|
||||||
const hue = await side.recolorOn(ctx2, buf);
|
const [oklch, rgb] = await side.recolorOn(ctx2, buf);
|
||||||
ctx2.canvas.style.animation = `${duration}ms ease fade-in`;
|
ctx2.canvas.style.animation = `${duration}ms ease fade-in`;
|
||||||
setBg(hue);
|
setBg(oklch.outer.h);
|
||||||
|
setPalette(oklch, rgb);
|
||||||
setTimeout(finish, duration);
|
setTimeout(finish, duration);
|
||||||
|
|
||||||
async function finish() {
|
async function finish() {
|
||||||
|
@ -255,8 +300,9 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||||
throw err;
|
throw err;
|
||||||
});
|
});
|
||||||
|
|
||||||
let hue = await side.recolorOn(picCtx, buf);
|
let [oklch, rgb] = await side.recolorOn(picCtx, buf);
|
||||||
setBg(hue);
|
setBg(oklch.outer.h);
|
||||||
|
setPalette(oklch, rgb);
|
||||||
await redraw(picCtx, buf, side.layers());
|
await redraw(picCtx, buf, side.layers());
|
||||||
|
|
||||||
const reroll = document.getElementById('reroll')!;
|
const reroll = document.getElementById('reroll')!;
|
||||||
|
@ -264,6 +310,19 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||||
|
|
||||||
addListeners();
|
addListeners();
|
||||||
|
|
||||||
|
type Done = (finish: () => void) => void;
|
||||||
|
|
||||||
|
function handleReroll(e: Event) {
|
||||||
|
wrap(reroll,
|
||||||
|
done => animateReroll(picCtx, pic2Ctx, buf, side, done),
|
||||||
|
'reroll', e);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSwap(e: Event) {
|
||||||
|
wrap(swap, done => animateSwap(picCtx, pic2Ctx, side, buf, done),
|
||||||
|
'swap', e);
|
||||||
|
}
|
||||||
|
|
||||||
function addListeners() {
|
function addListeners() {
|
||||||
reroll.addEventListener('click', handleReroll);
|
reroll.addEventListener('click', handleReroll);
|
||||||
swap.addEventListener('click', handleSwap);
|
swap.addEventListener('click', handleSwap);
|
||||||
|
@ -274,19 +333,7 @@ document.addEventListener('DOMContentLoaded', async function() {
|
||||||
swap.removeEventListener('click', handleSwap);
|
swap.removeEventListener('click', handleSwap);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleReroll(e: Event) {
|
function wrap(elem: Element, f: Done, name: string, e: Event) {
|
||||||
wrap(reroll, done => animateReroll(picCtx, pic2Ctx, buf, side, done),
|
|
||||||
'reroll', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleSwap(e: Event) {
|
|
||||||
wrap(swap, done => animateSwap(picCtx, pic2Ctx, side, buf, done),
|
|
||||||
'swap', e);
|
|
||||||
}
|
|
||||||
|
|
||||||
type Handler = (finish: () => void) => void;
|
|
||||||
|
|
||||||
function wrap(elem: Element, f: Handler, name: string, e: Event) {
|
|
||||||
if (elem != e.target) return;
|
if (elem != e.target) return;
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (isRunning()) return;
|
if (isRunning()) return;
|
||||||
|
|
|
@ -108,7 +108,11 @@ export class Oklch {
|
||||||
}
|
}
|
||||||
|
|
||||||
css(alpha: number = 1): string {
|
css(alpha: number = 1): string {
|
||||||
return `oklch(${this.l} ${this.c} ${this.h} / ${alpha})`;
|
const l = (this.l * 100).toFixed(0);
|
||||||
|
const c = (this.c * 250).toFixed(0);
|
||||||
|
const h = this.h.toFixed(0);
|
||||||
|
if (alpha != 1) { return `oklch(${l}% ${c}% ${h} / ${alpha})`; }
|
||||||
|
else { return `oklch(${l}% ${c}% ${h})`; }
|
||||||
}
|
}
|
||||||
|
|
||||||
with(lch: Partial<Record<Oklch.Channel, number | Oklch.ChannelMap>>): Oklch {
|
with(lch: Partial<Record<Oklch.Channel, number | Oklch.ChannelMap>>): Oklch {
|
||||||
|
|
|
@ -8,6 +8,11 @@
|
||||||
<link rel=stylesheet href=style.css>
|
<link rel=stylesheet href=style.css>
|
||||||
<script src=canvas.js type=module></script>
|
<script src=canvas.js type=module></script>
|
||||||
|
|
||||||
|
<div id=buttons>
|
||||||
|
<button id=reroll>new quox</button>
|
||||||
|
<button id=swap>swap view</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id=pic-holder>
|
<div id=pic-holder>
|
||||||
<canvas id=pic width=1000 height=673>
|
<canvas id=pic width=1000 height=673>
|
||||||
if the canvas isn't working,
|
if the canvas isn't working,
|
||||||
|
@ -17,11 +22,13 @@
|
||||||
</canvas>
|
</canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id=buttons>
|
<div id=palette-holder>
|
||||||
<button id=reroll>new quox</button>
|
<object type='image/svg+xml' data=palette.svg id=palette
|
||||||
<button id=swap>swap view</button>
|
width=1152 height=179>
|
||||||
|
there should be a palette here but it failed to load for some reason
|
||||||
|
</object>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav>
|
<nav id=back>
|
||||||
<a href=/>back</a>
|
<a href=/>back</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
BIN
rainbow-quox/kra/back.kra
(Stored with Git LFS)
BIN
rainbow-quox/kra/back.kra
(Stored with Git LFS)
Binary file not shown.
125
rainbow-quox/palette.svg.raku
Normal file
125
rainbow-quox/palette.svg.raku
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
unit sub MAIN($out);
|
||||||
|
|
||||||
|
|
||||||
|
my $doc = q:to/EOP/;
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="1152" height="179"
|
||||||
|
viewBox="-53 -1 1151 175"
|
||||||
|
preserveAspectRatio="xMinYMin meet">
|
||||||
|
|
||||||
|
<style><![CDATA[
|
||||||
|
@import url(../fonts/muller/muller.css);
|
||||||
|
|
||||||
|
:root { --hue: 300; }
|
||||||
|
|
||||||
|
rect, .textbg {
|
||||||
|
filter: drop-shadow(6px 6px 2px oklch(0.4 0.2 var(--hue) / 0.45));
|
||||||
|
transition: fill 0.2s ease;
|
||||||
|
fill: lightgray;
|
||||||
|
stroke: black;
|
||||||
|
stroke-width: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
text {
|
||||||
|
font-family: 'Muller', sans-serif;
|
||||||
|
text-anchor: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item { --text: black; }
|
||||||
|
.item :is(text, use) { fill: var(--text); }
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-weight: 700;
|
||||||
|
font-size: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hex {
|
||||||
|
font-family: monospace;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
]]></style>
|
||||||
|
EOP
|
||||||
|
|
||||||
|
sub make-item($layer, :$display = $layer, :$use-vit?, :$vit?) { ... }
|
||||||
|
|
||||||
|
make-item 'outer', upper => 'vitiligo1';
|
||||||
|
make-item 'spines', use => 'vitiligo1';
|
||||||
|
make-item 'stripes', upper => 'cuffs', display => 'socks';
|
||||||
|
make-item 'belly1', upper => 'vitiligo2';
|
||||||
|
make-item 'belly2', upper => 'vitiligo3';
|
||||||
|
make-item 'fins1', upper => 'vitiligo4';
|
||||||
|
make-item 'fins2', use => 'vitiligo4';
|
||||||
|
make-item 'fins3', use => 'vitiligo4';
|
||||||
|
make-item 'masks';
|
||||||
|
make-item 'claws';
|
||||||
|
make-item 'eyes';
|
||||||
|
|
||||||
|
$doc ~= '</svg>';
|
||||||
|
|
||||||
|
$out.IO.spurt: $doc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sub make-item($layer, :$display = $layer, :$use?, :$upper?) {
|
||||||
|
state $index = 0;
|
||||||
|
my $str =
|
||||||
|
qq[<g class="item" id="i-$layer" transform="translate({$index * 100} 0)">\n];
|
||||||
|
with $upper {
|
||||||
|
$str ~= qq{}
|
||||||
|
<rect width="80" height="25" id="s-$upper" />
|
||||||
|
<rect width="80" height="50" y="30" id="s-$layer" />
|
||||||
|
};
|
||||||
|
} orwith $use {
|
||||||
|
$str ~= qq{}
|
||||||
|
<use href="#s-$use" />
|
||||||
|
<rect width="80" height="50" y="30" id="s-$layer" />
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$str ~= qq{ <rect width="80" height="80" id="s-$layer" /> };
|
||||||
|
}
|
||||||
|
|
||||||
|
$str ~= qq{}
|
||||||
|
<polygon id="p-$layer" class="textbg" points="0,85 80,85 28,175 -52,175" />
|
||||||
|
};
|
||||||
|
|
||||||
|
with $upper {
|
||||||
|
$str ~= qq{}
|
||||||
|
<text class="name" x="20" y="100" transform="rotate(-60 20 100)">
|
||||||
|
$display
|
||||||
|
</text>
|
||||||
|
<text id="c-$layer" class="hex" x="42" y="102" transform="rotate(-60 42 102)">
|
||||||
|
#??????
|
||||||
|
</text>
|
||||||
|
<text id="c-$upper" class="hex" x="64" y="102" transform="rotate(-60 64 102)">
|
||||||
|
#??????
|
||||||
|
</text>
|
||||||
|
};
|
||||||
|
} orwith $use {
|
||||||
|
$str ~= qq{}
|
||||||
|
<text class="name" x="20" y="100" transform="rotate(-60 20 100)">
|
||||||
|
$layer
|
||||||
|
</text>
|
||||||
|
<text id="c-$layer" class="hex" x="42" y="102" transform="rotate(-60 42 102)">
|
||||||
|
#??????
|
||||||
|
</text>
|
||||||
|
<use href="#c-$use" />
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$str ~= qq{}
|
||||||
|
<text class="name" x="25" y="100" transform="rotate(-60 25 100)">
|
||||||
|
$layer
|
||||||
|
</text>
|
||||||
|
<text id="c-$layer" class="hex" x="47" y="102" transform="rotate(-60 47 102)">
|
||||||
|
#??????
|
||||||
|
</text>
|
||||||
|
};
|
||||||
|
}
|
||||||
|
$str ~= qq{ </g> };
|
||||||
|
|
||||||
|
$index++;
|
||||||
|
|
||||||
|
$doc ~= $str
|
||||||
|
}
|
|
@ -33,7 +33,7 @@
|
||||||
:root {
|
:root {
|
||||||
--hue: 300;
|
--hue: 300;
|
||||||
--c-hue: calc(180 + var(--hue));
|
--c-hue: calc(180 + var(--hue));
|
||||||
min-height: 100vh; display: flex;
|
min-height: 100vh;
|
||||||
align-items: center; justify-content: center;
|
align-items: center; justify-content: center;
|
||||||
|
|
||||||
--font: Muller, sans-serif;
|
--font: Muller, sans-serif;
|
||||||
|
@ -51,10 +51,16 @@
|
||||||
:root { background: oklch(0.3 0.12 var(--hue)); }
|
:root { background: oklch(0.3 0.12 var(--hue)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
}
|
||||||
|
|
||||||
#pic-holder, #pic, #pic2 {
|
#pic-holder, #pic, #pic2 {
|
||||||
width: min(1000px, 75vw);
|
width: min(1000px, 75vw);
|
||||||
margin: auto;
|
margin: auto;
|
||||||
aspect-ratio: 2000/1346;
|
aspect-ratio: 2000/1346;
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pic-holder { position: relative; }
|
#pic-holder { position: relative; }
|
||||||
|
@ -65,94 +71,17 @@
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#front .static { background: url(ufront/static.png) 0 0 / contain; }
|
|
||||||
#back .static { background: url(uback/static.png) 0 0 / contain; }
|
|
||||||
|
|
||||||
.spines { background: oklch(30.77% 0.1306 298.19); }
|
|
||||||
#front .spines { mask-image: url(ufront/spines.png); }
|
|
||||||
#back .spines { mask-image: url(uback/spines.png); }
|
|
||||||
|
|
||||||
.stripes { background: oklch(88.2% 0.0613 209.07); }
|
|
||||||
#front .stripes { mask-image: url(ufront/stripes.png); }
|
|
||||||
#back .stripes { mask-image: url(uback/stripes.png); }
|
|
||||||
|
|
||||||
.cuffs { background: oklch(72.74% 0.1008 225.69); }
|
|
||||||
#front .cuffs { mask-image: url(ufront/cuffs.png); }
|
|
||||||
#back .cuffs { mask-image: url(uback/cuffs.png); }
|
|
||||||
|
|
||||||
.outer { background: oklch(38.37% 0.1437 306.27); }
|
|
||||||
#front .outer { mask-image: url(ufront/outer.png); }
|
|
||||||
#back .outer { mask-image: url(uback/outer.png); }
|
|
||||||
|
|
||||||
.fins1 { background: oklch(85.06% 0.0961 81.4); }
|
|
||||||
#front .fins1 { mask-image: url(ufront/fins1.png); }
|
|
||||||
#back .fins1 { mask-image: url(uback/fins1.png); }
|
|
||||||
|
|
||||||
.fins2 { background: oklch(79.59% 0.1208 73.56); }
|
|
||||||
#front .fins2 { mask-image: url(ufront/fins2.png); }
|
|
||||||
#back .fins2 { mask-image: url(uback/fins2.png); }
|
|
||||||
|
|
||||||
.fins3 { background: oklch(74.11% 0.1268 64.62); }
|
|
||||||
#front .fins3 { mask-image: url(ufront/fins3.png); }
|
|
||||||
#back .fins3 { mask-image: url(uback/fins3.png); }
|
|
||||||
|
|
||||||
.belly1 { background: oklch(87.26% 0.0699 80.94); }
|
|
||||||
#front .belly1 { mask-image: url(ufront/belly1.png); }
|
|
||||||
#back .belly1 { mask-image: url(uback/belly1.png); }
|
|
||||||
|
|
||||||
.belly2 { background: oklch(76.92% 0.0954 58.36); }
|
|
||||||
#front .belly2 { mask-image: url(ufront/belly2.png); }
|
|
||||||
#back .belly2 { mask-image: url(uback/belly2.png); }
|
|
||||||
|
|
||||||
.eyes { background: oklch(36.26% 0.1107 145.78); }
|
|
||||||
#front .eyes { mask-image: url(ufront/eyes.png); }
|
|
||||||
#back .eyes { mask-image: url(uback/eyes.png); }
|
|
||||||
|
|
||||||
.masks { background: oklch(77.1% 0.0243 317.12); }
|
|
||||||
#front .masks { mask-image: url(ufront/masks.png); }
|
|
||||||
#back .masks { mask-image: url(uback/masks.png); }
|
|
||||||
|
|
||||||
.claws { background: oklch(88.92% 0.0207 325.75); }
|
|
||||||
#front .claws { mask-image: url(ufront/claws.png); }
|
|
||||||
#back .claws { mask-image: url(uback/claws.png); }
|
|
||||||
|
|
||||||
.vitiligo1 { background: oklch(79.4% 0.0588 309.27); }
|
|
||||||
#front .vitiligo1 { mask-image: url(ufront/vitiligo1.png); }
|
|
||||||
#back .vitiligo1 { mask-image: url(uback/vitiligo1.png); }
|
|
||||||
|
|
||||||
.vitiligo2 { background: oklch(93.14% 0.0331 83.71); }
|
|
||||||
#front .vitiligo2 { mask-image: url(ufront/vitiligo2.png); }
|
|
||||||
#back .vitiligo2 { mask-image: url(uback/vitiligo2.png); }
|
|
||||||
|
|
||||||
.vitiligo3 { background: oklch(95.7% 0.0296 94.35); }
|
|
||||||
#front .vitiligo3 { mask-image: url(ufront/vitiligo3.png); }
|
|
||||||
#back .vitiligo3 { mask-image: url(uback/vitiligo3.png); }
|
|
||||||
|
|
||||||
.vitiligo4 { background: oklch(95.7% 0.0296 94.35); }
|
|
||||||
#front .vitiligo4 { mask-image: url(ufront/vitiligo4.png); }
|
|
||||||
#back .vitiligo4 { mask-image: url(uback/vitiligo4.png); }
|
|
||||||
|
|
||||||
.lines { background: oklch(21.96% 0.0661 296.36); }
|
|
||||||
#front .lines { mask-image: url(ufront/lines.png); }
|
|
||||||
#back .lines { mask-image: url(uback/lines.png); }
|
|
||||||
|
|
||||||
.eye-shine { mask: none; mix-blend-mode: luminosity; }
|
|
||||||
#front .eye-shine { background: url(ufront/eyes.png) 0 0 / contain; }
|
|
||||||
#back .eye-shine { background: url(uback/eyes.png) 0 0 / contain; }
|
|
||||||
|
|
||||||
|
|
||||||
#buttons {
|
#buttons {
|
||||||
margin-top: 3rem;
|
flex: none;
|
||||||
display: flex; gap: 20px;
|
display: flex; gap: 20px;
|
||||||
z-index: -1;
|
max-width: 40em;
|
||||||
|
margin: 1.5rem auto 2.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
--fg: var(--c-hue);
|
--fg: var(--c-hue);
|
||||||
--bg: var(--hue);
|
--bg: var(--hue);
|
||||||
font: 700 25pt var(--font);
|
font: 700 20pt var(--font);
|
||||||
flex: 30%;
|
|
||||||
background: oklch(0.5 0.2 var(--bg));
|
background: oklch(0.5 0.2 var(--bg));
|
||||||
color: oklch(0.95 0.075 var(--fg));
|
color: oklch(0.95 0.075 var(--fg));
|
||||||
border: 3px solid oklch(0.2 0.05 var(--bg));
|
border: 3px solid oklch(0.2 0.05 var(--bg));
|
||||||
|
@ -162,8 +91,8 @@ button {
|
||||||
color 0.4s ease,
|
color 0.4s ease,
|
||||||
background 0.4s ease,
|
background 0.4s ease,
|
||||||
border 0.4s ease,
|
border 0.4s ease,
|
||||||
translate 0.025s ease-in,
|
translate 0.015s linear,
|
||||||
box-shadow 0.025s ease-in;
|
box-shadow 0.015s linear;
|
||||||
|
|
||||||
:root:not([data-running]) &:active,
|
:root:not([data-running]) &:active,
|
||||||
[data-running=swap] &#swap,
|
[data-running=swap] &#swap,
|
||||||
|
@ -173,18 +102,27 @@ button {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
#back {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 15px; left: 22px;
|
bottom: 15px; left: 22px;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: oklch(0.4 0.15 var(--c-hue));
|
||||||
|
text-decoration: 3px solid underline;
|
||||||
|
text-decoration-color: oklch(0.6 0.1 var(--c-hue));
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
color: oklch(0.9 0.19 var(--c-hue));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a {
|
/* #palette-holder { */
|
||||||
color: oklch(0.4 0.15 var(--c-hue));
|
/* overflow: auto; */
|
||||||
text-decoration: 3px solid underline;
|
/* } */
|
||||||
text-decoration-color:
|
|
||||||
oklch(0.6 0.1 var(--c-hue));
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-color-scheme: dark) {
|
#palette-holder {
|
||||||
nav a { color: oklch(0.9 0.19 var(--c-hue)); }
|
width: min(90vw, 1126px);
|
||||||
|
margin: 2.5rem auto 0;
|
||||||
}
|
}
|
||||||
|
#palette { width: 100%; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue