Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
16 kB · 409 lines
HTML
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410<!doctype html><html><head><meta charset="utf-8"><style> /* Black-and-white variant of the notepat keymap FIGURE (figure.html). Piano octaves + QWERTY + connectors ONLY. Fully monochrome — black, white, and grays. Built for Casey's social-software thread; note identity is carried by the letter + note-name labels rather than by color. Key geometry stays in sync with figure.html / template.html. */ @font-face { font-family: "Berkeley Mono"; src: url("__BERKELEY__") format("woff2"); font-weight: normal; font-style: normal; } @font-face { font-family: "YWFT Processing"; src: url("__YWFT_BOLD__") format("woff2"); font-weight: 800; font-style: normal; }
html, body { margin: 0; padding: 0; } body { width: 2400px; height: 860px; background: #ffffff; color: #121212; font-family: "YWFT Processing", -apple-system, "Helvetica Neue", sans-serif; box-sizing: border-box; padding: 36px 40px; overflow: hidden; display: flex; flex-direction: column; position: relative; } .connectors { position: absolute; inset: 0; width: 2400px; height: 860px; pointer-events: none; z-index: 50; }
/* ---------------- Piano ---------------- */ .piano-wrap { display: flex; justify-content: center; margin-bottom: 26px; } .piano { position: relative; height: 340px; width: 2076px; padding-left: 36px; box-sizing: border-box; } .wkey, .bkey { position: absolute; box-sizing: border-box; border-radius: 0 0 10px 10px; border: 2px solid #121212; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; padding-bottom: 16px; } .wkey { width: 120px; height: 320px; background: #fff; color: #121212; overflow: hidden; } /* Uniform light-gray foot band — a design element, not color-coding. */ .wkey .keyswatch { position: absolute; left: 0; right: 0; bottom: 0; height: 44px; background: #ececec; border-top: 2px solid rgba(0,0,0,0.22); } .wkey .qkey { font-family: "Berkeley Mono", "SF Mono", monospace; font-size: 64px; font-weight: 800; line-height: 1; color: #121212; position: absolute; top: 96px; left: 0; right: 0; text-align: center; } .wkey .nname { position: absolute; bottom: 60px; left: 0; right: 0; text-align: center; font-family: "Berkeley Mono", "SF Mono", monospace; font-size: 22px; color: #2a2a2a; letter-spacing: 0.05em; margin: 0; font-weight: 700; z-index: 2; }
.bkey { width: 72px; height: 210px; background: #0a0a0a; color: #fff; border-color: #000; z-index: 2; } .bkey .qkey { font-family: "Berkeley Mono", "SF Mono", monospace; font-size: 38px; font-weight: 800; line-height: 1; } .bkey .nname { font-family: "Berkeley Mono", "SF Mono", monospace; font-size: 16px; color: #bbb; letter-spacing: 0.05em; margin-top: 6px; font-weight: 700; }
/* Extended keys — dashed gray, clearly outside the core tonal map. */ .wkey.ext { background: #f4f4f4; color: #7a7a7a; border: 2px dashed #b8b8b8; opacity: 0.9; } .wkey.ext .qkey { color: #7a7a7a; text-shadow: none; position: static; padding-top: 22px; } .wkey.ext .keyswatch { display: none; } .wkey.ext .nname { position: static; color: #9a9a9a; text-shadow: none; font-size: 22px; font-weight: 700; } .bkey.ext { background: #3a3a3a; color: #d8d8d8; border: 2px dashed #6a6a6a; opacity: 0.9; } .bkey.ext .nname { color: #b8b8b8; } .wkey.ext .ext-tag, .bkey.ext .ext-tag { font-family: "Berkeley Mono", monospace; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; margin-top: 4px; opacity: 0.85; font-weight: 700; }
/* ---------------- QWERTY ---------------- */ .below { display: flex; justify-content: center; } .below-left { flex: 0 0 1380px; display: flex; flex-direction: column; }
.hand-labels { display: flex; justify-content: space-between; margin-bottom: 10px; font-family: "YWFT Processing"; font-size: 22px; letter-spacing: 0.22em; text-transform: uppercase; font-weight: 800; padding: 0 24px; } .hand-labels .l { color: #121212; } .hand-labels .r { color: #121212; } /* YWFT Processing has no arrow/middle-dot glyphs; use system font for those. */ .glyph { font-family: -apple-system, "Helvetica Neue", "Arial Unicode MS", sans-serif; font-weight: 800; }
/* Hand split rendered as a subtle light→slightly-darker gray gradient. */ .qwerty-bg { position: relative; padding: 18px 20px; border-radius: 16px; background: linear-gradient(to right, rgba(0, 0, 0, 0.045) 0%, rgba(0, 0, 0, 0.045) 48%, rgba(0, 0, 0, 0.10) 52%, rgba(0, 0, 0, 0.10) 100%); box-sizing: border-box; display: flex; align-items: center; } .qwerty-wrap { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; width: 100%; } .qrow { display: flex; gap: 12px; } .qrow.r0 { padding-left: 0; } .qrow.r1 { padding-left: 28px; } .qrow.r2 { padding-left: 84px; } .qcap { width: 100px; height: 100px; border-radius: 14px; border: 3px solid #121212; display: flex; align-items: center; justify-content: center; font-family: "Berkeley Mono", "SF Mono", monospace; font-size: 46px; font-weight: 800; text-transform: uppercase; flex-shrink: 0; box-shadow: 0 4px 0 rgba(0,0,0,0.18); } .qcap.white { background: #fff; color: #121212; } .qcap.black { background: #121212; color: #fff; border-color: #000; }
/* Naturals: white cap, black label. */ .qcap[data-qn] { background: #fff; color: #121212; border-color: #121212; text-shadow: none; } /* Sharps: solid black cap. */ .qcap.sharp { background: #121212; color: #fff; border-color: #000; }
.qcap.ext-white { background: #f4f4f4; color: #7a7a7a; border: 3px dashed #b8b8b8; opacity: 0.9; flex-direction: column; } .qcap.ext-black { background: #3a3a3a; color: #d8d8d8; border: 3px dashed #6a6a6a; opacity: 0.9; flex-direction: column; } .qcap .ext-tag { font-family: "Berkeley Mono", monospace; font-size: 12px; letter-spacing: 0.18em; text-transform: uppercase; margin-top: 5px; opacity: 0.9; font-weight: 700; } .qcap.ghost { background: transparent; color: #c8c8c8; border: 2.5px dashed #d4d4d4; font-weight: 600; font-size: 30px; box-shadow: none; } .qcap.octshift { background: #ededed; color: #4a4a4a; border: 2.5px solid #b0b0b0; font-weight: 800; font-size: 26px; flex-direction: column; } .qcap.octshift .lbl { font-size: 13px; letter-spacing: 0.1em; opacity: 0.75; margin-top: 3px; font-family: "YWFT Processing"; }</style></head><body> <!-- PIANO --> <div class="piano-wrap"> <div class="piano"> <div class="wkey ext" style="left:36px;"> <div class="qkey">X</div><div class="nname">B3</div><div class="ext-tag">ext</div></div> <div class="wkey" data-pn="c" style="left:156px;"> <div class="keyswatch"></div><div class="qkey">C</div><div class="nname">C4</div></div> <div class="wkey" data-pn="d" style="left:276px;"> <div class="keyswatch"></div><div class="qkey">D</div><div class="nname">D4</div></div> <div class="wkey" data-pn="e" style="left:396px;"> <div class="keyswatch"></div><div class="qkey">E</div><div class="nname">E4</div></div> <div class="wkey" data-pn="f" style="left:516px;"> <div class="keyswatch"></div><div class="qkey">F</div><div class="nname">F4</div></div> <div class="wkey" data-pn="g" style="left:636px;"> <div class="keyswatch"></div><div class="qkey">G</div><div class="nname">G4</div></div> <div class="wkey" data-pn="a" style="left:756px;"> <div class="keyswatch"></div><div class="qkey">A</div><div class="nname">A4</div></div> <div class="wkey" data-pn="b" style="left:876px;"> <div class="keyswatch"></div><div class="qkey">B</div><div class="nname">B4</div></div> <div class="wkey" data-pn="C5" style="left:996px;"> <div class="keyswatch"></div><div class="qkey">H</div><div class="nname">C5</div></div> <div class="wkey" data-pn="D5" style="left:1116px;"><div class="keyswatch"></div><div class="qkey">I</div><div class="nname">D5</div></div> <div class="wkey" data-pn="E5" style="left:1236px;"><div class="keyswatch"></div><div class="qkey">J</div><div class="nname">E5</div></div> <div class="wkey" data-pn="F5" style="left:1356px;"><div class="keyswatch"></div><div class="qkey">K</div><div class="nname">F5</div></div> <div class="wkey" data-pn="G5" style="left:1476px;"><div class="keyswatch"></div><div class="qkey">L</div><div class="nname">G5</div></div> <div class="wkey" data-pn="A5" style="left:1596px;"><div class="keyswatch"></div><div class="qkey">M</div><div class="nname">A5</div></div> <div class="wkey" data-pn="B5" style="left:1716px;"><div class="keyswatch"></div><div class="qkey">N</div><div class="nname">B5</div></div> <div class="wkey ext" style="left:1836px;"><div class="qkey">;</div><div class="nname">C6</div><div class="ext-tag">ext</div></div> <div class="wkey ext" style="left:1956px;"><div class="qkey">]</div><div class="nname">D6</div><div class="ext-tag">ext</div></div>
<!-- Sharps --> <div class="bkey ext" style="left:0px;"> <div class="qkey">Z</div><div class="nname">A♯3</div></div> <div class="bkey" style="left:240px;"> <div class="qkey">V</div><div class="nname">C♯4</div></div> <div class="bkey" style="left:360px;"> <div class="qkey">S</div><div class="nname">D♯4</div></div> <div class="bkey" style="left:600px;"> <div class="qkey">W</div><div class="nname">F♯4</div></div> <div class="bkey" style="left:720px;"> <div class="qkey">R</div><div class="nname">G♯4</div></div> <div class="bkey" style="left:840px;"> <div class="qkey">Q</div><div class="nname">A♯4</div></div> <div class="bkey" style="left:1080px;"> <div class="qkey">T</div><div class="nname">C♯5</div></div> <div class="bkey" style="left:1200px;"> <div class="qkey">Y</div><div class="nname">D♯5</div></div> <div class="bkey" style="left:1440px;"> <div class="qkey">U</div><div class="nname">F♯5</div></div> <div class="bkey" style="left:1560px;"> <div class="qkey">O</div><div class="nname">G♯5</div></div> <div class="bkey" style="left:1680px;"> <div class="qkey">P</div><div class="nname">A♯5</div></div> <div class="bkey ext" style="left:1920px;"> <div class="qkey">'</div><div class="nname">C♯6</div></div> </div> </div>
<!-- QWERTY --> <div class="below"> <div class="below-left"> <div class="hand-labels"> <div class="l"><span class="glyph">←</span> Left hand <span class="glyph">·</span> lower octave</div> <div class="r">Right hand <span class="glyph">·</span> upper octave <span class="glyph">→</span></div> </div> <div class="qwerty-bg"> <div class="qwerty-wrap"> <div class="qrow r0"> <div class="qcap sharp" data-sharp-of="a">Q</div> <div class="qcap sharp" data-sharp-of="f">W</div> <div class="qcap" data-qn="e">E</div> <div class="qcap sharp" data-sharp-of="g">R</div> <div class="qcap sharp" data-sharp-of="c">T</div> <div class="qcap sharp" data-sharp-of="d">Y</div> <div class="qcap sharp" data-sharp-of="f">U</div> <div class="qcap" data-qn="D5">I</div> <div class="qcap sharp" data-sharp-of="g">O</div> <div class="qcap sharp" data-sharp-of="a">P</div> <div class="qcap ghost">[</div> <div class="qcap ext-white">]<div class="ext-tag">ext</div></div> </div> <div class="qrow r1"> <div class="qcap" data-qn="a">A</div> <div class="qcap sharp" data-sharp-of="d">S</div> <div class="qcap" data-qn="d">D</div> <div class="qcap" data-qn="f">F</div> <div class="qcap" data-qn="g">G</div> <div class="qcap" data-qn="C5">H</div> <div class="qcap" data-qn="E5">J</div> <div class="qcap" data-qn="F5">K</div> <div class="qcap" data-qn="G5">L</div> <div class="qcap ext-white">;<div class="ext-tag">ext</div></div> <div class="qcap ext-black">'<div class="ext-tag">ext</div></div> </div> <div class="qrow r2"> <div class="qcap ext-black">Z<div class="ext-tag">ext</div></div> <div class="qcap ext-white">X<div class="ext-tag">ext</div></div> <div class="qcap" data-qn="c">C</div> <div class="qcap sharp" data-sharp-of="c">V</div> <div class="qcap" data-qn="b">B</div> <div class="qcap" data-qn="A5">N</div> <div class="qcap" data-qn="B5">M</div> <div class="qcap octshift">,<div class="lbl">oct−</div></div> <div class="qcap octshift">.<div class="lbl">oct+</div></div> <div class="qcap ghost">/</div> </div> </div> </div> </div> </div>
<!-- Connector overlay: piano white key → QWERTY note cap, monochrome --> <svg class="connectors" id="connectors"></svg>
<script> document.fonts.ready.then(() => { drawConnectors(); });
function drawConnectors() { const svg = document.getElementById("connectors"); // Monochrome: a single ink color, depth carried by graduated opacity. const INK = "#121212"; const naturals = [ { pn: "c", qn: "c", op: 0.85 }, { pn: "d", qn: "d", op: 0.72 }, { pn: "e", qn: "e", op: 0.62 }, { pn: "f", qn: "f", op: 0.55 }, { pn: "g", qn: "g", op: 0.50 }, { pn: "a", qn: "a", op: 0.45 }, { pn: "b", qn: "b", op: 0.42 }, { pn: "C5", qn: "C5", op: 0.62 }, { pn: "D5", qn: "D5", op: 0.52 }, { pn: "E5", qn: "E5", op: 0.47 }, { pn: "F5", qn: "F5", op: 0.45 }, { pn: "G5", qn: "G5", op: 0.45 }, { pn: "A5", qn: "A5", op: 0.42 }, { pn: "B5", qn: "B5", op: 0.40 }, ]; const NS = "http://www.w3.org/2000/svg"; for (const { pn, qn, op } of naturals) { const piano = document.querySelector(`.wkey[data-pn="${pn}"]`); const qwerty = document.querySelector(`.qcap[data-qn="${qn}"]`); if (!piano || !qwerty) continue; const pr = piano.getBoundingClientRect(); const qr = qwerty.getBoundingClientRect(); const x1 = pr.left + pr.width / 2; const y1 = pr.bottom - 12; const x2 = qr.left + qr.width / 2; const y2 = qr.top + 12; const line = document.createElementNS(NS, "line"); line.setAttribute("x1", x1); line.setAttribute("y1", y1); line.setAttribute("x2", x2); line.setAttribute("y2", y2); line.setAttribute("stroke", INK); line.setAttribute("stroke-width", "4"); line.setAttribute("stroke-dasharray", "10 8"); line.setAttribute("stroke-linecap", "round"); line.setAttribute("opacity", op); svg.appendChild(line); const dotOp = Math.min(0.8, op * 0.9); for (const [cx, cy] of [[x1, y1], [x2, y2]]) { const dot = document.createElementNS(NS, "circle"); dot.setAttribute("cx", cx); dot.setAttribute("cy", cy); dot.setAttribute("r", 5); dot.setAttribute("fill", INK); dot.setAttribute("opacity", dotOp); svg.appendChild(dot); } } } </script></body></html>