Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
174 changes: 143 additions & 31 deletions web/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
--kanji: "Noto Serif CJK JP", "Noto Serif JP", "Hiragino Mincho ProN", "Yu Mincho", serif;
--margin: clamp(1.1rem, 3.4vw, 2.75rem);
--counter-w: min(23rem, 30vw);
/* One seigaiha tile, shared by the ground and the noren cloth. Same geometry
as the engine's pattern: overlapping upper semicircles in three concentric
radii, rows offset by half a period. */
--seigaiha: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cpath fill='none' stroke='white' stroke-width='2' d='M-120,0%20A60,60%200%200%200%200,0%20M-100,0%20A40,40%200%200%200%20-20,0%20M-80,0%20A20,20%200%200%200%20-40,0%20M0,0%20A60,60%200%200%200%20120,0%20M20,0%20A40,40%200%200%200%20100,0%20M40,0%20A20,20%200%200%200%2080,0%20M120,0%20A60,60%200%200%200%20240,0%20M140,0%20A40,40%200%200%200%20220,0%20M160,0%20A20,20%200%200%200%20200,0%20M-60,60%20A60,60%200%200%200%2060,60%20M-40,60%20A40,40%200%200%200%2040,60%20M-20,60%20A20,20%200%200%200%2020,60%20M60,60%20A60,60%200%200%200%20180,60%20M80,60%20A40,40%200%200%200%20160,60%20M100,60%20A20,20%200%200%200%20140,60%20M-120,120%20A60,60%200%200%200%200,120%20M-100,120%20A40,40%200%200%200%20-20,120%20M-80,120%20A20,20%200%200%200%20-40,120%20M0,120%20A60,60%200%200%200%20120,120%20M20,120%20A40,40%200%200%200%20100,120%20M40,120%20A20,20%200%200%200%2080,120%20M120,120%20A60,60%200%200%200%20240,120%20M140,120%20A40,40%200%200%200%20220,120%20M160,120%20A20,20%200%200%200%20200,120'/%3E%3C/svg%3E");
}

* {
Expand Down Expand Up @@ -128,21 +132,35 @@ a {
pointer-events: none;
}

/* Seigaiha fans as an alpha mask, painted with the live tint. Same geometry as
the engine's pattern: overlapping upper semicircles in three concentric radii,
rows offset by half a period. */
/* Seigaiha fans as an alpha mask, painted with the live tint. */
.ground {
/* Bleeds past the viewport so the parallax drift never exposes an edge. */
/* Bleeds past the viewport so the parallax drift never exposes an edge.
The tint sits in the background color (not element opacity) so the press
waves below can ride the same mask at full strength. */
inset: -16px;
background: var(--tint);
opacity: 0.05;
background: color-mix(in srgb, var(--tint) 5%, transparent);
will-change: transform;
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cpath fill='none' stroke='white' stroke-width='2' d='M-120,0%20A60,60%200%200%200%200,0%20M-100,0%20A40,40%200%200%200%20-20,0%20M-80,0%20A20,20%200%200%200%20-40,0%20M0,0%20A60,60%200%200%200%20120,0%20M20,0%20A40,40%200%200%200%20100,0%20M40,0%20A20,20%200%200%200%2080,0%20M120,0%20A60,60%200%200%200%20240,0%20M140,0%20A40,40%200%200%200%20220,0%20M160,0%20A20,20%200%200%200%20200,0%20M-60,60%20A60,60%200%200%200%2060,60%20M-40,60%20A40,40%200%200%200%2040,60%20M-20,60%20A20,20%200%200%200%2020,60%20M60,60%20A60,60%200%200%200%20180,60%20M80,60%20A40,40%200%200%200%20160,60%20M100,60%20A20,20%200%200%200%20140,60%20M-120,120%20A60,60%200%200%200%200,120%20M-100,120%20A40,40%200%200%200%20-20,120%20M-80,120%20A20,20%200%200%200%20-40,120%20M0,120%20A60,60%200%200%200%20120,120%20M20,120%20A40,40%200%200%200%20100,120%20M40,120%20A20,20%200%200%200%2080,120%20M120,120%20A60,60%200%200%200%20240,120%20M140,120%20A40,40%200%200%200%20220,120%20M160,120%20A20,20%200%200%200%20200,120'/%3E%3C/svg%3E");
mask-image: var(--seigaiha);
mask-repeat: repeat;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cpath fill='none' stroke='white' stroke-width='2' d='M-120,0%20A60,60%200%200%200%200,0%20M-100,0%20A40,40%200%200%200%20-20,0%20M-80,0%20A20,20%200%200%200%20-40,0%20M0,0%20A60,60%200%200%200%20120,0%20M20,0%20A40,40%200%200%200%20100,0%20M40,0%20A20,20%200%200%200%2080,0%20M120,0%20A60,60%200%200%200%20240,0%20M140,0%20A40,40%200%200%200%20220,0%20M160,0%20A20,20%200%200%200%20200,0%20M-60,60%20A60,60%200%200%200%2060,60%20M-40,60%20A40,40%200%200%200%2040,60%20M-20,60%20A20,20%200%200%200%2020,60%20M60,60%20A60,60%200%200%200%20180,60%20M80,60%20A40,40%200%200%200%20160,60%20M100,60%20A20,20%200%200%200%20140,60%20M-120,120%20A60,60%200%200%200%200,120%20M-100,120%20A40,40%200%200%200%20-20,120%20M-80,120%20A20,20%200%200%200%20-40,120%20M0,120%20A60,60%200%200%200%20120,120%20M20,120%20A40,40%200%200%200%20100,120%20M40,120%20A20,20%200%200%200%2080,120%20M120,120%20A60,60%200%200%200%20240,120%20M140,120%20A40,40%200%200%200%20220,120%20M160,120%20A20,20%200%200%200%20200,120'/%3E%3C/svg%3E");
-webkit-mask-image: var(--seigaiha);
-webkit-mask-repeat: repeat;
}

/* A press wave: ink meeting water. A child of the ground, so it is clipped by
the same seigaiha mask and drifts with the same parallax. */
.ground__wave {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 40px;
margin: -20px 0 0 -20px;
border-radius: 50%;
background: radial-gradient(closest-side, transparent 55%, var(--tint) 80%, transparent 100%);
opacity: 0;
pointer-events: none;
}

.grain {
z-index: 1;
opacity: 0.09;
Expand Down Expand Up @@ -675,9 +693,9 @@ a {
bottom: calc(var(--margin) - 0.15rem);
}

/* ---- The brush cursor: a registration ring, a vermilion stroke that trails
the hand, and hanko stamps on every press. JS adds `cursor-live` only on
fine pointers with motion allowed, replacing the native arrow. ---- */
/* ---- The brush cursor: a registration ring and a vermilion stroke that
trails the hand. JS adds `cursor-live` only on fine pointers with motion
allowed, replacing the native arrow. ---- */
.cursor-live,
.cursor-live * {
cursor: none;
Expand Down Expand Up @@ -709,32 +727,113 @@ a {
opacity: 0;
}

/* The house seal, pressed wherever the visitor presses. */
.stamp {
@media not (pointer: fine) {
.cursor {
display: none;
}
}

/* ---- The noren: the entrance curtain, hung while the engine warms up.
Five bands of ink-dyed cloth on a vermilion rod; the house crest presses
rhythmically until boot() parts the curtain and removes it. ---- */
.noren {
position: fixed;
z-index: 99;
top: 0;
left: 0;
width: 1.6rem;
height: 1.6rem;
margin: -0.8rem 0 0 -0.8rem;
inset: 0;
z-index: 90;
display: none;
gap: 2px;
}
.js .noren {
display: flex;
/* Safety valve: if the module script never lifts it, pure CSS does. */
animation: noren-rescue 0.6s ease 9s forwards;
}
.noren__band {
position: relative;
flex: 1;
background: linear-gradient(180deg, #0f0c09, #191410);
border-top: 5px solid var(--vermilion);
overflow: hidden;
}
/* The dye runs across the whole cloth, continuous over the slits. */
.noren__band::before {
content: "";
position: absolute;
inset: 0;
background: var(--text);
opacity: 0.05;
mask-image: var(--seigaiha);
mask-repeat: repeat;
mask-position: calc(var(--band) * -20vw) 0;
-webkit-mask-image: var(--seigaiha);
-webkit-mask-repeat: repeat;
-webkit-mask-position: calc(var(--band) * -20vw) 0;
}
.noren__crest {
position: absolute;
inset: 0;
z-index: 1;
display: grid;
place-content: center;
justify-items: center;
gap: 0.55rem;
color: var(--text);
text-align: center;
}
.noren__seal {
position: relative;
width: 4.2rem;
height: 4.2rem;
display: grid;
place-items: center;
background: var(--vermilion);
color: var(--paper);
font-family: var(--display);
font-weight: 900;
font-size: 0.9rem;
border-radius: 50%;
font-family: var(--kanji);
font-size: 2rem;
line-height: 1;
border-radius: 3px;
pointer-events: none;
box-shadow:
inset 0 0 0 2px rgba(242, 236, 221, 0.22),
0 4px 14px rgba(8, 6, 4, 0.4);
animation: noren-press 1.7s ease-in-out infinite;
}

@media not (pointer: fine) {
.cursor {
display: none;
.noren__seal::after {
content: "";
position: absolute;
inset: 0;
border: 1px solid var(--vermilion);
border-radius: 50%;
opacity: 0;
animation: seal-radiate 1.7s ease-out infinite;
}
@keyframes noren-press {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(0.92);
}
}
@keyframes noren-rescue {
to {
opacity: 0;
visibility: hidden;
}
}
.noren__label {
margin-top: 0.3rem;
font-weight: 900;
font-size: 1.05rem;
letter-spacing: 0.32em;
text-indent: 0.32em; /* recenters the tracked wordmark */
}
.noren__note {
font-size: 0.6rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--dim);
}

/* ---- The live engine is unavailable: the poster stands in, controls bow out ---- */
.no-live .field,
Expand Down Expand Up @@ -825,9 +924,16 @@ a {
}
}

/* Reveal baseline: JS fades the counter in. Without JS it stays visible. */
/* Reveal baseline: JS fades the counter in. Without JS it stays visible. The
delayed animation is a safety valve: if reveal() never runs, CSS un-hides. */
.js [data-reveal] {
opacity: 0;
animation: reveal-rescue 0.6s ease 7s forwards;
}
@keyframes reveal-rescue {
to {
opacity: 1;
}
}

@media (prefers-reduced-motion: reduce) {
Expand All @@ -846,8 +952,14 @@ a {
.omakase:active .omakase__seal::after {
animation: none;
}
.cursor,
.stamp {
.cursor {
display: none;
}
.noren__seal,
.noren__seal::after {
animation: none;
}
.noren__seal::after {
opacity: 0;
}
}
25 changes: 23 additions & 2 deletions web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@
<link rel="manifest" href="./site.webmanifest" />

<link rel="stylesheet" href="./css/style.css" />
<!-- Synchronous, before first paint: reveal-hidden elements and the noren
curtain must never flash in or out of existence. -->
<script>
document.documentElement.classList.add("js");
</script>

<script type="application/ld+json">
{
Expand All @@ -72,6 +77,22 @@
</script>
</head>
<body>
<!-- The noren: the entrance curtain hangs while the engine warms up, then
parts to open the counter. Painted only when JS runs (the head script
adds `js`); boot() lifts and removes it. -->
<div class="noren" id="noren" aria-hidden="true">
<div class="noren__band" style="--band: 0"></div>
<div class="noren__band" style="--band: 1"></div>
<div class="noren__band" style="--band: 2"></div>
<div class="noren__band" style="--band: 3"></div>
<div class="noren__band" style="--band: 4"></div>
<div class="noren__crest">
<span class="noren__seal" lang="ja">任</span>
<span class="noren__label">acag</span>
<span class="noren__note">the house is opening</span>
</div>
</div>

<a class="skip-link" href="#source">Skip to source</a>

<!-- The sheet: a faint wagara ground and film grain, tinted by the current theme. -->
Expand Down Expand Up @@ -196,8 +217,8 @@ <h1 class="visually-hidden">
Read the source, build it yourself
</a>

<!-- The brush cursor: a registration ring whose vermilion stroke trails the
hand's motion; every press stamps the sheet with the house seal. -->
<!-- The brush cursor: a registration ring whose vermilion stroke trails
the hand's motion. Presses send a wave through the wagara ground. -->
<div class="cursor" id="cursor" aria-hidden="true">
<span class="cursor__ring"></span>
<span class="cursor__bar"></span>
Expand Down
Loading
Loading