인터랙티브 아트워크 30종과 시간 기반 전환 및 개발 문서 추가

This commit is contained in:
2026-10-07 11:34:28 +09:00
commit a64a3e9fe9
9 changed files with 2077 additions and 0 deletions

728
index.html Normal file
View File

@@ -0,0 +1,728 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="color-scheme" content="light dark">
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#111111" media="(prefers-color-scheme: dark)">
<meta name="description" content="NO NAME COMPANY.">
<meta property="og:title" content="NO NAME COMPANY.">
<meta property="og:description" content="NONAME.COMPANY">
<meta property="og:type" content="website">
<title>NO NAME COMPANY.</title>
<link rel="icon" href="favicon.png" type="image/png">
<link rel="apple-touch-icon" href="favicon.png">
<style>
:root {
color-scheme: light dark;
--paper: #fff;
--ink: #181818;
--contour: #414141;
--muted: #737373;
--line: #dedede;
--axis: rgb(0 0 0 / 9%);
--marker: #b6b6b6;
--gutter: clamp(24px, 5.5vw, 112px);
--inset: clamp(20px, 2.2vw, 40px);
}
@media (prefers-color-scheme: dark) {
:root {
--paper: #111;
--ink: #eee;
--contour: #929292;
--muted: #a3a3a3;
--line: #343434;
--axis: rgb(255 255 255 / 10%);
--marker: #606060;
}
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
background: var(--paper);
}
body {
margin: 0;
color: var(--ink);
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
-webkit-font-smoothing: antialiased;
}
::selection {
background: var(--ink);
color: var(--paper);
}
.page {
display: grid;
grid-template-rows: 1fr auto;
min-height: 100vh;
min-height: 100svh;
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
}
main {
display: grid;
grid-template-rows: auto minmax(360px, 1fr);
min-width: 0;
}
/* 제목, 식별 정보, 푸터는 동일한 12열 격자를 사용합니다. */
.intro,
.colophon {
display: grid;
grid-template-columns: repeat(12, minmax(0, 1fr));
margin-inline: var(--gutter);
border-inline: 1px solid var(--line);
}
.intro {
min-height: clamp(254px, 34vh, 368px);
}
.wordmark {
grid-column: 1 / 8;
align-self: center;
margin: 0;
padding: 40px var(--inset) 44px;
font-size: clamp(52px, 6.4vw, 116px);
font-weight: 400;
line-height: 0.94;
letter-spacing: -0.065em;
}
.wordmark span {
display: block;
white-space: nowrap;
}
.identity {
grid-column: 8 / -1;
display: grid;
grid-template-columns: 1fr auto;
grid-template-rows: auto 1fr minmax(28px, auto);
align-items: start;
gap: 24px 16px;
padding: 38px var(--inset) 35px;
border-left: 1px solid var(--line);
}
.micro {
margin: 0;
font-size: 10px;
font-weight: 400;
line-height: 1.4;
letter-spacing: 0.065em;
}
.identifier {
grid-column: 1;
}
.domain {
grid-column: 2;
grid-row: 3;
align-self: end;
text-align: right;
}
/* 캔버스가 준비되기 전에는 정적인 선 패턴을 표시합니다. */
.artwork {
position: relative;
isolation: isolate;
min-height: 360px;
margin: 0;
border-block: 1px solid var(--line);
}
.contours {
position: absolute;
inset: 0;
overflow: hidden;
overflow: clip;
}
.artwork canvas {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
pointer-events: none;
}
.artwork[data-artwork="orbit"] {
--contour: #a65327;
background: radial-gradient(ellipse at 66% 58%, #f4ba77, #eed8b9 55%, #ede6da);
}
.artwork[data-artwork="wave"] {
--contour: #326f96;
background: radial-gradient(ellipse at 40% 65%, #a5d2e5, #d4e4e8 65%, #e5e9e7);
}
.artwork[data-artwork="mesh"] {
--contour: #76609a;
background: radial-gradient(ellipse at 54% 48%, #c7b0e1, #e0d6e8 60%, #eae5e9);
}
.artwork[data-artwork="bloom"] {
background: #eee9e2;
}
.artwork[data-artwork="particles"] {
--contour: #215950;
background: radial-gradient(ellipse at center, #d8e7cf, #e9eee1 70%);
}
.artwork[data-artwork="type"] {
--contour: #b53627;
background: #f0d4b9;
}
.artwork[data-artwork="moire"] {
--contour: #775436;
background: #e9decb;
}
.artwork[data-artwork="slits"] {
background: #e5d9cc;
}
.artwork[data-artwork="trails"] {
background: radial-gradient(ellipse at center, #e0e7ed, #efe9e1);
}
.artwork[data-artwork="pixels"] {
background: #d5e3df;
}
.artwork[data-artwork="negative"] {
background: linear-gradient(135deg, #eab48f, #f4d7a0 55%, #dd7655);
}
.artwork[data-artwork="eclipse"] {
background: #e5ddd0;
}
.artwork[data-artwork="hexagons"] {
background: #ebdfe0;
}
.artwork[data-series="extended"] {
--contour: hsl(var(--art-hue) 30% 38%);
background: hsl(var(--art-hue) 22% 89%);
}
@media (prefers-color-scheme: dark) {
.artwork[data-artwork="orbit"] {
--contour: #d3955d;
background: radial-gradient(ellipse at 66% 58%, #573623, #261e19 65%, #171513);
}
.artwork[data-artwork="wave"] {
--contour: #7aaec8;
background: radial-gradient(ellipse at 40% 65%, #173e51, #17262d 65%, #13191d);
}
.artwork[data-artwork="mesh"] {
--contour: #b29bcf;
background: radial-gradient(ellipse at 54% 48%, #3a2b51, #241e2e 60%, #19161e);
}
.artwork[data-artwork="bloom"] {
background: #14121b;
}
.artwork[data-artwork="particles"] {
--contour: #b9d9a4;
background: radial-gradient(ellipse at center, #23392f, #111e1a 70%);
}
.artwork[data-artwork="type"] {
--contour: #f08560;
background: #311c21;
}
.artwork[data-artwork="moire"] {
--contour: #bca588;
background: #25211d;
}
.artwork[data-artwork="slits"] {
background: #1b2028;
}
.artwork[data-artwork="trails"] {
background: radial-gradient(ellipse at center, #202b3c, #171b24);
}
.artwork[data-artwork="pixels"] {
background: #111f27;
}
.artwork[data-artwork="negative"] {
background: linear-gradient(135deg, #c46d50, #e1ab73 55%, #974f46);
}
.artwork[data-artwork="eclipse"] {
background: #182631;
}
.artwork[data-artwork="hexagons"] {
background: #30232e;
}
.artwork[data-series="extended"] {
--contour: hsl(var(--art-hue) 28% 72%);
background: hsl(var(--art-hue) 22% 13%);
}
}
.artwork.is-ready .contours {
visibility: hidden;
}
.ring {
position: absolute;
left: calc(66% - var(--i) * 0.28%);
top: calc(58% - var(--i) * 0.46%);
width: calc(17% + var(--i) * 2.8%);
height: calc(22% + var(--i) * 4.6%);
border: 1px solid var(--contour);
border-radius: 48% 52% 49% 51% / 43% 44% 56% 57%;
transform: translate(-50%, -50%) rotate(-24deg);
}
.axis {
position: absolute;
z-index: 1;
inset-block: 0;
width: 1px;
background: var(--axis);
}
.axis-left {
left: var(--gutter);
}
.axis-right {
right: var(--gutter);
}
.cross {
position: absolute;
z-index: 2;
top: -5px;
width: 9px;
height: 9px;
background: var(--paper);
border: 1px solid var(--marker);
}
.cross-left {
left: calc(var(--gutter) - 4px);
}
.cross-right {
right: calc(var(--gutter) - 4px);
}
.colophon {
min-height: 64px;
align-items: center;
padding-inline: var(--inset);
}
.credit {
grid-column: 8 / -1;
margin: 0;
color: var(--muted);
text-align: right;
}
.developer-trigger {
padding: 0;
border: 0;
background: transparent;
color: inherit;
font: inherit;
letter-spacing: inherit;
touch-action: none;
user-select: none;
-webkit-user-select: none;
-webkit-touch-callout: none;
}
.developer-trigger:focus-visible {
outline: 1px solid var(--muted);
outline-offset: 4px;
}
/* 개발용 작품 선택 패널은 푸터의 zenn을 길게 눌러 열 수 있습니다. */
.artwork-controls {
position: fixed;
z-index: 10;
right: 16px;
bottom: calc(76px + env(safe-area-inset-bottom));
width: min(252px, calc(100vw - 32px));
border: 1px solid var(--line);
border-radius: 12px;
background: var(--paper);
color: var(--ink);
box-shadow: 0 6px 24px rgb(0 0 0 / 12%);
font-size: 11px;
}
.artwork-controls:not([open]) {
width: auto;
}
.artwork-controls[hidden] {
display: none;
}
.artwork-controls summary {
padding: 12px 48px 12px 14px;
cursor: pointer;
font-size: 10px;
letter-spacing: 0.04em;
}
.artwork-controls-panel {
padding: 0 12px 12px;
}
.artwork-controls label {
display: block;
margin-bottom: 6px;
color: var(--muted);
font-size: 10px;
}
.artwork-controls select,
.artwork-controls button {
min-height: 36px;
border: 1px solid var(--line);
border-radius: 6px;
background: var(--paper);
color: var(--ink);
font: inherit;
}
.artwork-controls select {
width: 100%;
padding: 6px;
}
.artwork-controls-actions {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 6px;
margin-top: 8px;
}
.artwork-controls button {
cursor: pointer;
}
.artwork-controls .artwork-controls-close {
position: absolute;
top: 4px;
right: 5px;
width: 32px;
min-height: 32px;
border: 0;
background: transparent;
font-size: 18px;
line-height: 1;
}
.artwork-controls button:hover {
background: var(--line);
}
.artwork-controls :focus-visible {
outline: 2px solid var(--muted);
outline-offset: 3px;
}
/* 좁은 화면에서는 작품 영역을 확보하고 패턴의 중심 위치를 조정합니다. */
@media (max-width: 680px) {
:root {
--gutter: 20px;
--inset: 16px;
}
html,
body {
height: 100%;
overflow: hidden;
overscroll-behavior: none;
}
.page {
height: 100svh;
height: 100dvh;
overflow: hidden;
}
main {
min-height: 0;
grid-template-rows: auto minmax(0, 1fr);
}
.intro {
min-height: 0;
}
.wordmark {
grid-column: 1 / -1;
padding-block: 38px 32px;
font-size: clamp(44px, 11.8vw, 80px);
}
.identity {
grid-column: 1 / -1;
grid-template-columns: 25px 1fr auto;
grid-template-rows: auto auto;
align-items: center;
gap: 9px 16px;
padding-block: 17px;
border-top: 1px solid var(--line);
border-left: 0;
}
.micro {
font-size: 9px;
}
.identifier {
grid-column: 2;
grid-row: 1;
}
.domain {
grid-column: 2 / -1;
grid-row: 2;
color: var(--muted);
text-align: left;
}
.credit {
grid-column: 7 / -1;
text-align: right;
}
.artwork {
min-height: 0;
overflow-x: clip;
}
.contours {
inset-inline: -42%;
}
.ring {
left: calc(56% - var(--i) * 0.28%);
top: calc(56% - var(--i) * 0.46%);
}
.colophon {
min-height: 52px;
}
}
/* 모바일 가로 화면처럼 높이가 낮은 경우에도 한 화면에 전체를 표시합니다. */
@media (max-height: 520px) {
html,
body {
height: 100%;
overflow: hidden;
overscroll-behavior: none;
}
.page {
height: 100svh;
height: 100dvh;
overflow: hidden;
}
main {
min-height: 0;
grid-template-rows: auto minmax(0, 1fr);
}
.intro,
.artwork {
min-height: 0;
}
.artwork {
overflow-x: clip;
}
}
@media (max-width: 680px) and (max-height: 520px) {
.wordmark {
padding-block: 18px 14px;
font-size: clamp(32px, 9vw, 48px);
}
.identity {
gap: 6px 12px;
padding-block: 10px;
}
.colophon {
min-height: 44px;
}
}
@media (prefers-reduced-motion: no-preference) {
.intro,
.colophon {
animation: appear 600ms ease-out both;
}
.contours {
animation: develop 700ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes appear {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes develop {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
}
</style>
</head>
<body>
<div class="page">
<main>
<header class="intro">
<h1 class="wordmark">
<span>NO NAME</span>
<span>COMPANY.</span>
</h1>
<div class="identity">
<p class="identifier micro">NNC</p>
<p class="domain micro">NONAME.COMPANY</p>
</div>
</header>
<div class="artwork" aria-hidden="true">
<div class="contours">
<span class="ring" style="--i: 0"></span>
<span class="ring" style="--i: 1"></span>
<span class="ring" style="--i: 2"></span>
<span class="ring" style="--i: 3"></span>
<span class="ring" style="--i: 4"></span>
<span class="ring" style="--i: 5"></span>
<span class="ring" style="--i: 6"></span>
<span class="ring" style="--i: 7"></span>
<span class="ring" style="--i: 8"></span>
<span class="ring" style="--i: 9"></span>
<span class="ring" style="--i: 10"></span>
<span class="ring" style="--i: 11"></span>
<span class="ring" style="--i: 12"></span>
<span class="ring" style="--i: 13"></span>
<span class="ring" style="--i: 14"></span>
<span class="ring" style="--i: 15"></span>
<span class="ring" style="--i: 16"></span>
<span class="ring" style="--i: 17"></span>
<span class="ring" style="--i: 18"></span>
<span class="ring" style="--i: 19"></span>
<span class="ring" style="--i: 20"></span>
<span class="ring" style="--i: 21"></span>
<span class="ring" style="--i: 22"></span>
<span class="ring" style="--i: 23"></span>
<span class="ring" style="--i: 24"></span>
<span class="ring" style="--i: 25"></span>
<span class="ring" style="--i: 26"></span>
<span class="ring" style="--i: 27"></span>
<span class="ring" style="--i: 28"></span>
<span class="ring" style="--i: 29"></span>
<span class="ring" style="--i: 30"></span>
<span class="ring" style="--i: 31"></span>
<span class="ring" style="--i: 32"></span>
<span class="ring" style="--i: 33"></span>
<span class="ring" style="--i: 34"></span>
<span class="ring" style="--i: 35"></span>
<span class="ring" style="--i: 36"></span>
<span class="ring" style="--i: 37"></span>
<span class="ring" style="--i: 38"></span>
<span class="ring" style="--i: 39"></span>
<span class="ring" style="--i: 40"></span>
<span class="ring" style="--i: 41"></span>
<span class="ring" style="--i: 42"></span>
<span class="ring" style="--i: 43"></span>
<span class="ring" style="--i: 44"></span>
<span class="ring" style="--i: 45"></span>
<span class="ring" style="--i: 46"></span>
<span class="ring" style="--i: 47"></span>
<span class="ring" style="--i: 48"></span>
<span class="ring" style="--i: 49"></span>
<span class="ring" style="--i: 50"></span>
<span class="ring" style="--i: 51"></span>
<span class="ring" style="--i: 52"></span>
<span class="ring" style="--i: 53"></span>
<span class="ring" style="--i: 54"></span>
<span class="ring" style="--i: 55"></span>
<span class="ring" style="--i: 56"></span>
<span class="ring" style="--i: 57"></span>
<span class="ring" style="--i: 58"></span>
<span class="ring" style="--i: 59"></span>
<span class="ring" style="--i: 60"></span>
<span class="ring" style="--i: 61"></span>
<span class="ring" style="--i: 62"></span>
<span class="ring" style="--i: 63"></span>
</div>
<span class="axis axis-left"></span>
<span class="axis axis-right"></span>
<span class="cross cross-left"></span>
<span class="cross cross-right"></span>
</div>
</main>
<footer class="colophon">
<p class="credit micro">Designed by <button class="developer-trigger" id="developer-trigger" type="button" aria-label="Hold for 5 seconds to open artwork controls">zenn</button></p>
</footer>
</div>
<details class="artwork-controls" hidden open>
<summary>ARTWORKS / 30 · TEST<button id="artwork-close" class="artwork-controls-close" type="button" aria-label="Close artwork controls">×</button></summary>
<div class="artwork-controls-panel">
<label for="artwork-picker">Choose artwork</label>
<select id="artwork-picker"></select>
<div class="artwork-controls-actions">
<button id="artwork-previous" type="button" aria-label="Previous artwork">← Prev</button>
<button id="artwork-random" type="button">Random</button>
<button id="artwork-next" type="button" aria-label="Next artwork">Next →</button>
</div>
</div>
</details>
<script src="artwork-schedule.js" defer></script>
<script src="artwork.js" defer></script>
</body>
</html>