Articles
-
-
-
-
-
-
-
-
Sic transit gloria mundi
β
li { position: relative; padding-inline-start: calc(1em * 5 / 4); }
& > li:before { content: "β§"; font-family: sans-serif; position: absolute; top: 0; left: 0; color: var(--c-sepia2); }
}
.home {
--bottom-height: calc(1em * 3 * var(--line-height));
position: relative; z-index: 1; pointer-events: none;
container-name: layout; container-type: inline-size;
max-width: var(--layout-width); margin-inline: auto; display: grid;
grid-template-columns: 1fr 6fr 3fr;
grid-template-rows: calc(100vh - var(--bottom-height)) var(--bottom-height);
column-gap: calc(1em * 3 * var(--line-height));
padding-inline: calc(1em * 2 * var(--line-height));
p { margin-block-end: calc(1em * 1 * var(--line-height)); }
.logo {
width: auto; height: calc(1em * 2 * var(--line-height)); display: block; transition: opacity 0.2s ease; position: sticky; top: calc(1em * 3 / 2 * var(--line-height)); z-index: 2;
&:hover {
&:first-of-type { opacity: 0; }
& + * { opacity: 1 !important; }
}
&:not(:first-of-type) { margin-block-start: calc(1em * -2 * var(--line-height)); opacity: 0; pointer-events: none; }
}
h2 {
--scalar: calc(5 / 6);
--border: calc((1em / 6) / var(--scalar));
/*--border: 1px;*/
/*--border: 0;*/
font-size: calc(1em * var(--scalar));
line-height: calc(var(--line-height) / var(--scalar));
margin-block-end: calc((1em / var(--scalar)) * var(--line-height)) !important;
padding-block-start: calc((1em / var(--scalar)) * var(--line-height) - var(--border)); border-block-start: var(--border) var(--c-sepia2) solid;
display: flex; align-items: center;
&:not(:first-of-type) {
margin-block-start: calc((1em * 3 / 2 / var(--scalar)) * var(--line-height));
/*--border: 0;*/
}
svg { height: calc((1em / var(--scalar)) * var(--line-height)); width: auto; display: block; }
}
span { color: var(--c-sepia2); }
.pages {
ul.menu {
columns: 2; column-gap: calc(1em * 1 * var(--line-height));
margin-block: calc(-1em / 4 * var(--line-height));
& > * {
padding-inline: 0; padding-block: calc(1em / 4 * var(--line-height)); font-weight: 700;
&:before { content: " "; position: absolute; top: 0; left: 0; width: 100%; border-block-end: 1px var(--c-sepia3) dotted; }
}
}
}
.wrapper {
position: relative; padding-block: calc(1em * 1 * var(--line-height)) 0;
&:before {
content: " "; position: absolute; left: calc(1em * -3 / 2 * var(--line-height)); top: 0; width: 0; height: 100%; border-inline-start: 1px var(--c-sepia3) dotted;
}
}
.gutter, .intro {
.wrapper:before { display: none; }
}
.intro, .pages {
h2 { border-block-start-color: transparent; }
}
/*.gutter, .intro, .pages {
.wrapper { padding-block: calc(1em * var(--line-height) / 2) 0; }
}*/
.gutter {
.wrapper { height: 100%; display: flex; flex-direction: column; align-items: flex-start; }
}
.journal {
& > * {
white-space: nowrap;
display: inline; padding-inline-start: 0;
span { color: inherit; }
&:before { position: static; content: " β"; margin-inline: 0.25em 0.5em; color: var(--c-sepia2); }
&:first-of-type {
&:before { content: "β―"; position: static; margin-inline: 0 0.25em; }
}
&:not(:first-of-type) {
a:before { content: "'"; }
span { display: none; }
}
}
}
.journal-update {
margin-block-start: calc(1em / 2 * var(--line-height)); color: var(--c-sepia2);
a {
font-weight: 700; text-decoration-color: var(--c-sepia3);
}
}
.controls {
display: flex; flex-direction: column; margin-block: calc(1em * 2 * var(--line-height)) calc(1em * 3 / 2 * var(--line-height)); position: sticky; bottom: calc(1em * 2 * var(--line-height)); gap: calc(1em * 1 / 4 * var(--line-height));
}
.documents {
margin-block: calc(1em * 0 * var(--line-height)) calc(1em * 1 * var(--line-height));
li {
white-space: nowrap; counter-increment: opus-no; display: inline; padding-inline-start: 0;
&:before {
font-size: calc(1em * 3 / 4); margin-inline-end: 0.2em; content: "#"counter(opus-no)" "; position: static;
}
&:not(:last-child):after {
content: ","; margin-inline-end: 0.2em; color: var(--c-sepia2);
}
}
}
& > * > * > * { pointer-events: auto; }
& > * {
position: relative;
z-index: 1;
&.gutter {
grid-column: 1 / span 1;
grid-row: 1 / 6;
}
&.intro {
grid-row: 1 / span 1;
grid-column: 2 / span 1;
}
&.pages {
grid-row: 1 / span 1;
grid-column: 3 / span 1;
}
&.hint {
grid-column: 2 / span 2;
grid-row: 2;
}
&.spacer {
grid-column: 1 / 4;
grid-row: 3;
}
&.art {
grid-column: 2 / span 2;
grid-row: 4;
}
&.articles {
grid-column: 2 / span 1;
grid-row: 5;
}
&.floater {
grid-column: 3 / span 1;
grid-row: 5;
}
& > * {
margin-block-end: calc(1em * var(--line-height));
}
}
.spacer {
position: relative; z-index: 0; opacity: 0.4;
& > * {
position: absolute; bottom: calc(1em * var(--line-height)); left: 0; width: 100%; height: auto; color: var(--c-bg); margin-block-end: 0;
}
}
.hint > * { pointer-events: auto; color: inherit; }
.floater {
.wrapper {
position: sticky; top: 0;
&:before { display: none; }
}
}
.toggle {
--c-border: var(--c-sepia2);
--c-fill: var(--c-sepia3);
--w: 2em; --h: 0.8em;
display: inline-block; position: relative; padding-inline-start: calc(var(--w) + 0.5em);
color: var(--c-sepia2); margin-inline-end: calc(1em * 2 / 3 * var(--line-height));
input { display: none; }
&:before {
position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: 0; width: var(--w); height: var(--h); border: 1px var(--c-border) solid; border-radius: 1em;
}
&:after {
--spacing: 3px; --w2: 0.66;
position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: var(--spacing); width: calc(var(--w) * var(--w2) - var(--spacing) * 2); height: calc(var(--h) - var(--spacing) * 2); border: 1px var(--c-border) solid; border-radius: 1em; background: var(--c-fill); transition: left 0.15s ease;
}
&:has(input:checked) {
color: var(--c-sepia);
&:after {
left: calc(var(--w) * (1 - var(--w2)) + var(--spacing));
}
}
}
.color {
--c-border: var(--c-sepia2);
--c-fill: var(--c-sepia3);
--w: 1.2em; --h: 0.8em;
display: inline-block; position: relative; padding-inline-start: calc(var(--w) + 0.5em);
color: var(--c-sepia2);
input { opacity: 0; position: absolute; left: 0; top: 0; height: 100%; width: 100%; z-index: 1; }
.reset { position: relative; z-index: 2; cursor: pointer; color: var(--c-sepia3); }
&:before {
position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: 0; width: var(--w); height: var(--h); border: 1px var(--c-border) solid; border-radius: 1em;
}
&:after {
--spacing: 3px;
position: absolute; content: " "; display: block; top: 50%; transform: translateY(-50%); left: var(--spacing); width: calc(var(--w) - var(--spacing) * 2); height: calc(var(--h) - var(--spacing) * 2); border: 1px var(--c-sepia2) solid; border-radius: 1em; background: var(--c-accent);/*background: linear-gradient(to bottom, var(--c-accent), transparent)*/;
}
}
.art {
margin-block-end: calc(1em * var(--line-height) * 2);
}
.articles {
padding-block: 0 !important;
.wrapper {
&:before { display: none; }
}
ul {
display: flex;
flex-direction: column-reverse;
& > li {
--scalar: calc(7 / 3);
padding-inline-start: 0; position: relative;
font-size: calc(1em * var(--scalar)); /*font-family: var(--font-alt);*/
padding-block: calc(1em * var(--line-height) / var(--scalar) * 1 / 3);
&:before { content: " "; position: absolute; top: 100%; left: 0; width: 100%; height: 1px; background: linear-gradient(to right, color-mix(in oklch, var(--c-sepia4) 80%, transparent), transparent); }
&:first-of-type:before { display: none; }
a { text-decoration: none; }
}
}
}
footer {
border-block-start: calc(1em / 6) var(--c-sepia4) solid;
color: var(--c-sepia2); display: flex; align-items: flex-end; gap: calc(1em * 1 * var(--line-height));
margin-block-start: calc(1em * 3 * var(--line-height)); padding-block: calc(1em * 2 * var(--line-height));
grid-column: 2 / span 2;
grid-row: 6;
& > * {
margin-block-end: 0;
}
a:has(img) {
border: calc(1em / 6) var(--c-accent) solid;
}
img {
display: block; width: auto; height: calc(1em * 3 * var(--line-height));
}
ul {
li {
padding-inline-start: 0; display: inline;
&:before { display: none; }
&:not(:last-of-type):after { content: " β"; margin-inline: 0.25em; color: var(--c-sepia2); }
}
}
p { margin-block-end: 0; }
}
}
.visual-container {
--b: calc(1em * var(--line-height));
/*background: color-mix(in lch, var(--c-bg), var(--c-sepia) 8%);*/
background: hsla(60, 20%, 83%, 0.04); position: fixed; top: var(--b); left: var(--b); width: calc(100% - var(--b) * 2); height: calc(100% - var(--b) * 2); user-select: none; border-radius: calc(1em * var(--line-height) * 1 / 2); overflow: hidden;
& > * { position: absolute; top: 0; left: 0; }
& > img { display: block; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); width: 10em; height: 10em; }
&:has(canvas) > img { display: none; }
}
@media (max-width: 1200px) {
.home {
column-gap: calc(1em * 2 * var(--line-height));
padding-inline: calc(1em * 3 / 2 * var(--line-height));
.wrapper:before { left: calc(1em * -1 * var(--line-height)); }
}
}
@media (max-width: 960px) {
.visual-container {
--b: calc(1em * var(--line-height) / 2);
}
.home {
display: flex; flex-direction: column; pointer-events: auto;
& > div:first-of-type {
h2 { margin-block-start: 0; }
}
& > * { order: 444; }
.logo { position: static; }
.intro, .gutter, .pages { order: 0; }
.gutter {
.wrapper { align-items: center; }
}
.wrapper {
padding-block: 0;
&:before { display: none; }
}
.floater { display: block; margin-block: calc(1em / var(--scalar) * 1 * var(--line-height)); }
.documents { margin-block: calc(1em * 1 * var(--line-height)); }
.hint { margin-block: calc(1em * 1 * var(--line-height)) 0; }
.hint, .art { order: 1; }
.art { margin-block-end: 0; }
.spacer { order: 666; & > * { bottom: calc(1em * var(--line-height) * 1 / 2); } }
h2 {
margin-block-start: calc(1em * 1 * var(--line-height));
}
.articles ul > li { --scalar: 1.6666; padding-block: calc(1em * var(--line-height) / var(--scalar) * 1 / 4); }
.controls { flex-direction: row; margin-block: calc(1em * 1 * var(--line-height)) 0; }
}
tml>
import {
Box3,
Float32BufferAttribute,
InstancedBufferGeometry,
InstancedInterleavedBuffer,
InterleavedBufferAttribute,
Sphere,
Vector3,
WireframeGeometry
} from 'three';
const _box = new Box3();
const _vector = new Vector3();
class LineSegmentsGeometry extends InstancedBufferGeometry {
constructor() {
super();
this.isLineSegmentsGeometry = true;
this.type = 'LineSegmentsGeometry';
const positions = [ - 1, 2, 0, 1, 2, 0, - 1, 1, 0, 1, 1, 0, - 1, 0, 0, 1, 0, 0, - 1, - 1, 0, 1, - 1, 0 ];
const uvs = [ - 1, 2, 1, 2, - 1, 1, 1, 1, - 1, - 1, 1, - 1, - 1, - 2, 1, - 2 ];
const index = [ 0, 2, 1, 2, 3, 1, 2, 4, 3, 4, 5, 3, 4, 6, 5, 6, 7, 5 ];
this.setIndex( index );
this.setAttribute( 'position', new Float32BufferAttribute( positions, 3 ) );
this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) );
}
applyMatrix4( matrix ) {
const start = this.attributes.instanceStart;
const end = this.attributes.instanceEnd;
if ( start !== undefined ) {
start.applyMatrix4( matrix );
end.applyMatrix4( matrix );
start.needsUpdate = true;
}
if ( this.boundingBox !== null ) {
this.computeBoundingBox();
}
if ( this.boundingSphere !== null ) {
this.computeBoundingSphere();
}
return this;
}
setPositions( array ) {
let lineSegments;
if ( array instanceof Float32Array ) {
lineSegments = array;
} else if ( Array.isArray( array ) ) {
lineSegments = new Float32Array( array );
}
const instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz
this.setAttribute( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz
this.setAttribute( 'instanceEnd', new InterleavedBufferAttribute( instanceBuffer, 3, 3 ) ); // xyz
this.instanceCount = this.attributes.instanceStart.count;
//
this.computeBoundingBox();
this.computeBoundingSphere();
return this;
}
setColors( array ) {
let colors;
if ( array instanceof Float32Array ) {
colors = array;
} else if ( Array.isArray( array ) ) {
colors = new Float32Array( array );
}
const instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb
this.setAttribute( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb
this.setAttribute( 'instanceColorEnd', new InterleavedBufferAttribute( instanceColorBuffer, 3, 3 ) ); // rgb
return this;
}
fromWireframeGeometry( geometry ) {
this.setPositions( geometry.attributes.position.array );
return this;
}
fromEdgesGeometry( geometry ) {
this.setPositions( geometry.attributes.position.array );
return this;
}
fromMesh( mesh ) {
this.fromWireframeGeometry( new WireframeGeometry( mesh.geometry ) );
// set colors, maybe
return this;
}
fromLineSegments( lineSegments ) {
const geometry = lineSegments.geometry;
this.setPositions( geometry.attributes.position.array ); // assumes non-indexed
// set colors, maybe
return this;
}
computeBoundingBox() {
if ( this.boundingBox === null ) {
this.boundingBox = new Box3();
}
const start = this.attributes.instanceStart;
const end = this.attributes.instanceEnd;
if ( start !== undefined && end !== undefined ) {
this.boundingBox.setFromBufferAttribute( start );
_box.setFromBufferAttribute( end );
this.boundingBox.union( _box );
}
}
computeBoundingSphere() {
if ( this.boundingSphere === null ) {
this.boundingSphere = new Sphere();
}
if ( this.boundingBox === null ) {
this.computeBoundingBox();
}
const start = this.attributes.instanceStart;
const end = this.attributes.instanceEnd;
if ( start !== undefined && end !== undefined ) {
const center = this.boundingSphere.center;
this.boundingBox.getCenter( center );
let maxRadiusSq = 0;
for ( let i = 0, il = start.count; i < il; i ++ ) {
_vector.fromBufferAttribute( start, i );
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
_vector.fromBufferAttribute( end, i );
maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector ) );
}
this.boundingSphere.radius = Math.sqrt( maxRadiusSq );
if ( isNaN( this.boundingSphere.radius ) ) {
console.error( 'THREE.LineSegmentsGeometry.computeBoundingSphere(): Computed radius is NaN. The instanced position data is likely to have NaN values.', this );
}
}
}
toJSON() {
// todo
}
applyMatrix( matrix ) {
console.warn( 'THREE.LineSegmentsGeometry: applyMatrix() has been renamed to applyMatrix4().' );
return this.applyMatrix4( matrix );
}
}
export { LineSegmentsGeometry };