Compare commits
6 Commits
c6c9819ab0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b24cfeeac | |||
| 9d326c7f29 | |||
| f7d1620d08 | |||
| 3f2c39e000 | |||
| 02e15ea222 | |||
| 3680a12761 |
@@ -18,6 +18,23 @@
|
|||||||
<i class="cs-fx-corner cs-fx-corner--tr"></i>
|
<i class="cs-fx-corner cs-fx-corner--tr"></i>
|
||||||
<i class="cs-fx-corner cs-fx-corner--bl"></i>
|
<i class="cs-fx-corner cs-fx-corner--bl"></i>
|
||||||
<i class="cs-fx-corner cs-fx-corner--br"></i>
|
<i class="cs-fx-corner cs-fx-corner--br"></i>
|
||||||
|
|
||||||
|
<div class="cs-hud">
|
||||||
|
<div class="cs-hud-item cs-hud--tl">0x00 // ADDR</div>
|
||||||
|
<div class="cs-hud-item cs-hud--tr">SYS.PTR // 0.0, 0.0</div>
|
||||||
|
<div class="cs-hud-item cs-hud--bl">MEM.DUMP // OK</div>
|
||||||
|
<div class="cs-hud-item cs-hud--br">ATELIER.V6 // #0F2A</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="cs-boot">
|
||||||
|
<div class="cs-boot-log">
|
||||||
|
<p>> INITIALIZING ARCHIVE...</p>
|
||||||
|
<p>> LOADING CYBERSIGIL.SYS... [ OK ]</p>
|
||||||
|
<p>> ALLOCATING BUFFER 0x8F2A... [ OK ]</p>
|
||||||
|
<p>> DECRYPTING BIOMETRICS... [ OK ]</p>
|
||||||
|
<p>> ACCESS GRANTED.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -84,6 +101,10 @@
|
|||||||
let depth = 0, raf = 0;
|
let depth = 0, raf = 0;
|
||||||
let mx = 0, my = 0; // mouse relative (-1..1)
|
let mx = 0, my = 0; // mouse relative (-1..1)
|
||||||
|
|
||||||
|
const hudTL = fx.querySelector('.cs-hud--tl');
|
||||||
|
const hudTR = fx.querySelector('.cs-hud--tr');
|
||||||
|
const hudBL = fx.querySelector('.cs-hud--bl');
|
||||||
|
|
||||||
const apply = () => {
|
const apply = () => {
|
||||||
raf = 0;
|
raf = 0;
|
||||||
fx.style.opacity = String(1 - 0.5 * depth);
|
fx.style.opacity = String(1 - 0.5 * depth);
|
||||||
@@ -93,7 +114,51 @@
|
|||||||
root.style.setProperty('--cs-py', `${(my * 15).toFixed(1)}px`);
|
root.style.setProperty('--cs-py', `${(my * 15).toFixed(1)}px`);
|
||||||
root.style.setProperty('--cs-cx', `${(mx * -8).toFixed(1)}px`);
|
root.style.setProperty('--cs-cx', `${(mx * -8).toFixed(1)}px`);
|
||||||
root.style.setProperty('--cs-cy', `${(my * -8).toFixed(1)}px`);
|
root.style.setProperty('--cs-cy', `${(my * -8).toFixed(1)}px`);
|
||||||
|
|
||||||
|
// update HUD
|
||||||
|
if (hudTL) hudTL.textContent = `0x${Math.floor(depth * 255).toString(16).toUpperCase().padStart(2, '0')} // ADDR`;
|
||||||
|
if (hudTR) hudTR.textContent = `SYS.PTR // ${mx.toFixed(2)}, ${my.toFixed(2)}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ─── Terminal Command Echo ─── */
|
||||||
|
const onBtnClick = (e: MouseEvent) => {
|
||||||
|
const btn = (e.target as HTMLElement).closest('button, a.btn');
|
||||||
|
if (!btn || !hudBL) return;
|
||||||
|
const label = btn.textContent?.trim().slice(0, 12).toUpperCase() || 'NULL';
|
||||||
|
hudBL.textContent = `> CMD: [${label}] ... [OK]`;
|
||||||
|
hudBL.classList.remove('cs-hud-flicker');
|
||||||
|
void hudBL.offsetWidth;
|
||||||
|
hudBL.classList.add('cs-hud-flicker');
|
||||||
|
};
|
||||||
|
window.addEventListener('click', onBtnClick);
|
||||||
|
off.push(() => window.removeEventListener('click', onBtnClick));
|
||||||
|
|
||||||
|
/* ─── Character Scramble ─── */
|
||||||
|
const scrambleChars = '!@#$%^&*()_+{}:"<>?-=[];\',./';
|
||||||
|
const onHover = (e: MouseEvent) => {
|
||||||
|
const el = (e.target as HTMLElement).closest('.font-display, .btn, .prose h1, .prose h2');
|
||||||
|
if (!el || el.classList.contains('cs-is-scrambling')) return;
|
||||||
|
|
||||||
|
const original = el.textContent || '';
|
||||||
|
if (!original.trim()) return;
|
||||||
|
|
||||||
|
el.classList.add('cs-is-scrambling');
|
||||||
|
let iterations = 0;
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
el.textContent = original.split('').map((char, index) => {
|
||||||
|
if (index < iterations) return original[index];
|
||||||
|
return scrambleChars[Math.floor(Math.random() * scrambleChars.length)];
|
||||||
|
}).join('');
|
||||||
|
|
||||||
|
if (iterations >= original.length) {
|
||||||
|
clearInterval(interval);
|
||||||
|
el.classList.remove('cs-is-scrambling');
|
||||||
|
}
|
||||||
|
iterations += 1 / 3;
|
||||||
|
}, 30);
|
||||||
|
};
|
||||||
|
window.addEventListener('mouseover', onHover);
|
||||||
|
off.push(() => window.removeEventListener('mouseover', onHover));
|
||||||
const schedule = () => { if (!raf) raf = requestAnimationFrame(apply); };
|
const schedule = () => { if (!raf) raf = requestAnimationFrame(apply); };
|
||||||
|
|
||||||
const onScroll = () => {
|
const onScroll = () => {
|
||||||
|
|||||||
@@ -65,14 +65,46 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
|
|||||||
const ax = Math.abs(x);
|
const ax = Math.abs(x);
|
||||||
if (ax > maxX) maxX = ax;
|
if (ax > maxX) maxX = ax;
|
||||||
};
|
};
|
||||||
const emit = (d: string, cls: string) => {
|
const emit = (d: string, cls: string, style?: string) => {
|
||||||
if (strokeCount >= MAX_PATHS) return;
|
if (strokeCount >= MAX_PATHS) return;
|
||||||
|
const s = style ? ` style="${style};--i:${strokeCount % 16}"` : ` style="--i:${strokeCount % 16}"`;
|
||||||
|
parts.push(
|
||||||
|
`<path class="${cls}" d="${d}" pathLength="1"${s} filter="url(#cs-erosion)"/>`,
|
||||||
|
);
|
||||||
|
strokeCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
const emitRect = (x: number, y: number, sz: number, cls: string) => {
|
||||||
|
parts.push(
|
||||||
|
`<rect x="${n(x)}" y="${n(y)}" width="${n(sz)}" height="${n(sz)}" class="${cls}" style="--i:${strokeCount % 16}"/>`,
|
||||||
|
);
|
||||||
|
strokeCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
const emitHUD = (d: string, cls: string) => {
|
||||||
parts.push(
|
parts.push(
|
||||||
`<path class="${cls}" d="${d}" pathLength="1" style="--i:${strokeCount % 16}"/>`,
|
`<path class="${cls}" d="${d}" pathLength="1" style="--i:${strokeCount % 16}"/>`,
|
||||||
);
|
);
|
||||||
strokeCount++;
|
strokeCount++;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const emitText = (x: number, y: number, txt: string, cls: string) => {
|
||||||
|
parts.push(
|
||||||
|
`<text x="${n(x)}" y="${n(y)}" class="${cls}" style="--i:${strokeCount % 16}">${txt}</text>`,
|
||||||
|
);
|
||||||
|
strokeCount++;
|
||||||
|
};
|
||||||
|
|
||||||
|
const microFilaments = (at: Pt, ang: number) => {
|
||||||
|
const num = 5 + Math.floor(rng() * 5);
|
||||||
|
for (let i = 0; i < num; i++) {
|
||||||
|
const a = ang + rnd(-0.5, 0.5);
|
||||||
|
const l = rnd(2, 8);
|
||||||
|
const tip: Pt = [at[0] + Math.cos(a) * l, at[1] + Math.sin(a) * l];
|
||||||
|
emit(`M${n(at[0])} ${n(at[1])} L${n(tip[0])} ${n(tip[1])}`, 'cs-sig-micro');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Catmull-Rom → cubic Bézier through an ordered point list (organic sweep).
|
// Catmull-Rom → cubic Bézier through an ordered point list (organic sweep).
|
||||||
const spline = (pts: Pt[], tension = 6): string => {
|
const spline = (pts: Pt[], tension = 6): string => {
|
||||||
if (pts.length < 2) return '';
|
if (pts.length < 2) return '';
|
||||||
@@ -144,10 +176,25 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
|
|||||||
];
|
];
|
||||||
const tail: Pt = [Math.max(-2, hook[0] - L * rnd(0.25, 0.45)), hook[1] + rnd(-4, 12)];
|
const tail: Pt = [Math.max(-2, hook[0] - L * rnd(0.25, 0.45)), hook[1] + rnd(-4, 12)];
|
||||||
const pts: Pt[] = [[ox, oy], mid, peak, hook, tail];
|
const pts: Pt[] = [[ox, oy], mid, peak, hook, tail];
|
||||||
emit(spline(pts, 5.5), 'cs-sig-main');
|
|
||||||
|
// Depth shading: background limbs are thinner and fainter
|
||||||
|
const sw = depth === 0 ? 1.6 : 2.6;
|
||||||
|
const op = depth === 0 ? 0.45 : 0.9;
|
||||||
|
emit(spline(pts, 5.5), 'cs-sig-main', `stroke-width:${sw};opacity:${op}`);
|
||||||
|
|
||||||
|
// Bifurcation: split at the mid point with a secondary branch
|
||||||
|
if (depth > 0 && rng() < 0.45) {
|
||||||
|
const bAng = ang + (rng() < 0.5 ? 0.8 : -0.8) + rnd(-0.3, 0.3);
|
||||||
|
const bL = L * rnd(0.4, 0.7);
|
||||||
|
const bPeak: Pt = [mid[0] + Math.cos(bAng) * bL, mid[1] + Math.sin(bAng) * bL];
|
||||||
|
const bPts: Pt[] = [mid, bPeak, [bPeak[0] + rnd(-10, 10), bPeak[1] + rnd(10, 20)]];
|
||||||
|
emit(spline(bPts, 4), 'cs-sig-main', `stroke-width:${sw * 0.8};opacity:${op}`);
|
||||||
|
if (rng() < 0.3) ornament(bPeak, bAng, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
// terminal spike off the outermost point
|
// terminal spike off the outermost point
|
||||||
barb(peak, ang + rnd(-0.4, 0.4), scale * rnd(10, 22));
|
barb(peak, ang + rnd(-0.4, 0.4), scale * rnd(10, 22));
|
||||||
|
if (rng() < 0.3) microFilaments(peak, ang);
|
||||||
|
|
||||||
// denser filament shadows trailing the main sweep
|
// denser filament shadows trailing the main sweep
|
||||||
const numFilaments = rng() < 0.5 ? 2 : 1;
|
const numFilaments = rng() < 0.5 ? 2 : 1;
|
||||||
@@ -198,15 +245,31 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
|
|||||||
if (depth === 0 && rng() < 0.35) ornament(peak, ang, 0.9);
|
if (depth === 0 && rng() < 0.35) ornament(peak, ang, 0.9);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ── Wavering spine: a curve from top to bottom, gently bowing in +x.
|
// ── Harmonic spine: a weighted wave from top to bottom
|
||||||
const spineNodes = 6 + Math.floor(rng() * 3);
|
const spineNodes = 8 + Math.floor(rng() * 4);
|
||||||
const spinePts: Pt[] = [];
|
const spinePts: Pt[] = [];
|
||||||
|
const sFreq = rnd(0.8, 1.8);
|
||||||
|
const sAmp = rnd(8, 15);
|
||||||
for (let i = 0; i <= spineNodes; i++) {
|
for (let i = 0; i <= spineNodes; i++) {
|
||||||
const y = (H * i) / spineNodes;
|
const t = i / spineNodes;
|
||||||
const x = i === 0 || i === spineNodes ? 0 : rnd(0, 14);
|
const y = H * t;
|
||||||
|
const x = (i === 0 || i === spineNodes) ? 0 :
|
||||||
|
Math.sin(t * Math.PI * sFreq) * sAmp +
|
||||||
|
Math.sin(t * Math.PI * sFreq * 2.3) * (sAmp * 0.4);
|
||||||
spinePts.push([x, y]);
|
spinePts.push([x, y]);
|
||||||
}
|
}
|
||||||
emit(spline(spinePts, 5), 'cs-sig-main cs-sig-spine');
|
emit(spline(spinePts, 5), 'cs-sig-main cs-sig-spine');
|
||||||
|
|
||||||
|
// ── Vascular Filaments: high-frequency "shiver" paths tracking the spine
|
||||||
|
for (let j = 0; j < 2; j++) {
|
||||||
|
const vPts = spinePts.map(([x, y], i) => {
|
||||||
|
const t = i / spineNodes;
|
||||||
|
const off = Math.sin(t * 22 + rng() * 6) * 1.8;
|
||||||
|
return [x + off + (j === 0 ? -2.5 : 2.5), y] as Pt;
|
||||||
|
});
|
||||||
|
emit(spline(vPts, 6.5), 'cs-sig-vessel');
|
||||||
|
}
|
||||||
|
|
||||||
// ── Chromatic Aberration: two faint, offset echoes of the spine
|
// ── Chromatic Aberration: two faint, offset echoes of the spine
|
||||||
emit(spline(spinePts.map(([x, y]) => [x - 1.5, y] as Pt), 5), 'cs-sig-spine-ab cs-sig-spine-ab--1');
|
emit(spline(spinePts.map(([x, y]) => [x - 1.5, y] as Pt), 5), 'cs-sig-spine-ab cs-sig-spine-ab--1');
|
||||||
emit(spline(spinePts.map(([x, y]) => [x + 1.5, y] as Pt), 5), 'cs-sig-spine-ab cs-sig-spine-ab--2');
|
emit(spline(spinePts.map(([x, y]) => [x + 1.5, y] as Pt), 5), 'cs-sig-spine-ab cs-sig-spine-ab--2');
|
||||||
@@ -245,6 +308,13 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
|
|||||||
if (isTangle && rng() < 0.5) {
|
if (isTangle && rng() < 0.5) {
|
||||||
ornament(node, bias, 0.8);
|
ornament(node, bias, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isTangle) {
|
||||||
|
// Digital Sediment: tiny bit-dust squares at tangle nodes
|
||||||
|
for (let j = 0; j < 6; j++) {
|
||||||
|
emitRect(node[0] + rnd(-12, 12), node[1] + rnd(-12, 12), rnd(1, 3), 'cs-sig-dust');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Technical Connectors: sparse, straight circuit lines
|
// ── Technical Connectors: sparse, straight circuit lines
|
||||||
@@ -256,6 +326,20 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
|
|||||||
emit(`M${n(n1[0])} ${n(n1[1])} L${n(n2[0])} ${n(n2[1])}`, 'cs-sig-connect');
|
emit(`M${n(n1[0])} ${n(n1[1])} L${n(n2[0])} ${n(n2[1])}`, 'cs-sig-connect');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Ghost Symbols: tiny technical fragments
|
||||||
|
const symbols = ['0x00', 'NULL', 'VOID', 'ERR', 'INIT', 'HALT', 'RECLAIM', 'DEAD'];
|
||||||
|
const numSymbols = 2 + Math.floor(rng() * 3);
|
||||||
|
for (let i = 0; i < numSymbols; i++) {
|
||||||
|
const pt = pick(nodePoints);
|
||||||
|
emitText(pt[0] + rnd(4, 12), pt[1] + rnd(-4, 4), pick(symbols), 'cs-sig-text');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Calibration HUD: geometric framing arcs and crosshairs
|
||||||
|
const hudR = maxX + PAD * 1.5;
|
||||||
|
emitHUD(`M${n(-hudR)} 0 A${n(hudR)} ${n(hudR)} 0 0 1 ${n(hudR)} 0`, 'cs-sig-hud');
|
||||||
|
emitHUD(`M${n(-hudR)} ${H} A${n(hudR)} ${n(hudR)} 0 0 0 ${n(hudR)} ${H}`, 'cs-sig-hud');
|
||||||
|
emitHUD(`M0 ${n(-PAD)} L0 ${n(H + PAD)}`, 'cs-sig-hud cs-sig-hud--v');
|
||||||
|
|
||||||
const half = parts.join('');
|
const half = parts.join('');
|
||||||
const minX = -(maxX + PAD);
|
const minX = -(maxX + PAD);
|
||||||
const vbW = 2 * (maxX + PAD);
|
const vbW = 2 * (maxX + PAD);
|
||||||
@@ -263,6 +347,12 @@ export function buildCybersigil(opts: SigilOptions = {}): string {
|
|||||||
`<svg class="cs-sigil" viewBox="${n(minX)} ${-PAD} ${n(vbW)} ${H + 2 * PAD}" ` +
|
`<svg class="cs-sigil" viewBox="${n(minX)} ${-PAD} ${n(vbW)} ${H + 2 * PAD}" ` +
|
||||||
`preserveAspectRatio="xMidYMid meet" aria-hidden="true" focusable="false" ` +
|
`preserveAspectRatio="xMidYMid meet" aria-hidden="true" focusable="false" ` +
|
||||||
`xmlns="http://www.w3.org/2000/svg">` +
|
`xmlns="http://www.w3.org/2000/svg">` +
|
||||||
|
`<defs>` +
|
||||||
|
`<filter id="cs-erosion" x="-20%" y="-20%" width="140%" height="140%">` +
|
||||||
|
`<feTurbulence type="fractalNoise" baseFrequency="0.6" numOctaves="3" result="noise" />` +
|
||||||
|
`<feDisplacementMap in="SourceGraphic" in2="noise" scale="1.5" xChannelSelector="R" yChannelSelector="G" />` +
|
||||||
|
`</filter>` +
|
||||||
|
`</defs>` +
|
||||||
`<g class="cs-sig-half">${half}</g>` +
|
`<g class="cs-sig-half">${half}</g>` +
|
||||||
`<g class="cs-sig-half" transform="scale(-1 1)">${half}</g>` +
|
`<g class="cs-sig-half" transform="scale(-1 1)">${half}</g>` +
|
||||||
`</svg>`
|
`</svg>`
|
||||||
|
|||||||
@@ -61,6 +61,85 @@ html.cybersigil body::after {
|
|||||||
.cybersigil .salon-atmosphere::before { background: var(--sky); opacity: 0.06; }
|
.cybersigil .salon-atmosphere::before { background: var(--sky); opacity: 0.06; }
|
||||||
.cybersigil .salon-atmosphere::after { background: var(--mauve); opacity: 0.05; }
|
.cybersigil .salon-atmosphere::after { background: var(--mauve); opacity: 0.05; }
|
||||||
|
|
||||||
|
/* HUD Overlay */
|
||||||
|
.cybersigil .cs-hud {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
padding: 1.5rem;
|
||||||
|
pointer-events: none;
|
||||||
|
z-index: 10;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-size: 0.65rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.12em;
|
||||||
|
color: var(--sky);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.cybersigil .cs-hud-item { position: absolute; }
|
||||||
|
.cybersigil .cs-hud--tl { top: 1.5rem; left: 1.5rem; }
|
||||||
|
.cybersigil .cs-hud--tr { top: 1.5rem; right: 1.5rem; }
|
||||||
|
.cybersigil .cs-hud--bl { bottom: 1.5rem; left: 1.5rem; }
|
||||||
|
.cybersigil .cs-hud--br { bottom: 1.5rem; right: 1.5rem; }
|
||||||
|
|
||||||
|
.cs-hud-flicker {
|
||||||
|
animation: cs-flicker 0.4s steps(4) 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Barbed Borders (Stitched Wire) */
|
||||||
|
.cybersigil .plate,
|
||||||
|
.cybersigil .btn,
|
||||||
|
.cybersigil .glass {
|
||||||
|
border-image-source: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'><path d='M0 0 H100 V100 H0 Z' fill='none' stroke='%234fe9ff' stroke-width='1.5' stroke-dasharray='4 12'/><path d='M10 0 L15 -5 M30 0 L25 -5 M50 0 L50 -8 M70 0 L75 -5 M90 0 L85 -5' fill='none' stroke='%234fe9ff' stroke-width='1'/><path d='M10 100 L15 105 M30 100 L25 105 M50 100 L50 108 M70 100 L75 105 M90 100 L85 105' fill='none' stroke='%234fe9ff' stroke-width='1'/></svg>");
|
||||||
|
border-image-slice: 10;
|
||||||
|
border-image-repeat: stretch;
|
||||||
|
}
|
||||||
|
.cybersigil .plate:hover,
|
||||||
|
.cybersigil .btn:hover {
|
||||||
|
border-image-source: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'><path d='M0 0 H100 V100 H0 Z' fill='none' stroke='%23c8327a' stroke-width='2' stroke-dasharray='1 4'/><path d='M5 0 L15 -10 M25 0 L35 -10 M45 0 L55 -10 M65 0 L75 -10 M85 0 L95 -10' fill='none' stroke='%23c8327a' stroke-width='1.5'/></svg>");
|
||||||
|
animation: cs-flicker 0.2s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Boot Overlay */
|
||||||
|
.cybersigil .cs-boot {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 100;
|
||||||
|
background: var(--crust);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
pointer-events: none;
|
||||||
|
animation: cs-boot-fade 0.8s steps(1) 0.6s forwards;
|
||||||
|
}
|
||||||
|
.cybersigil .cs-boot-log {
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: clamp(0.9rem, 4vw, 1.2rem);
|
||||||
|
color: var(--sky);
|
||||||
|
line-height: 1.4;
|
||||||
|
text-shadow: 0 0 8px var(--sky);
|
||||||
|
max-width: 90vw;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.cybersigil .cs-boot-log p {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
width: 0;
|
||||||
|
animation: cs-boot-type 0.1s steps(20) forwards;
|
||||||
|
}
|
||||||
|
.cybersigil .cs-boot-log p:nth-child(2) { animation-delay: 0.1s; }
|
||||||
|
.cybersigil .cs-boot-log p:nth-child(3) { animation-delay: 0.2s; }
|
||||||
|
.cybersigil .cs-boot-log p:nth-child(4) { animation-delay: 0.3s; }
|
||||||
|
.cybersigil .cs-boot-log p:nth-child(5) { animation-delay: 0.4s; }
|
||||||
|
|
||||||
|
@keyframes cs-boot-fade {
|
||||||
|
0% { opacity: 1; visibility: visible; }
|
||||||
|
99% { opacity: 0; visibility: visible; }
|
||||||
|
100% { opacity: 0; visibility: hidden; display: none; }
|
||||||
|
}
|
||||||
|
@keyframes cs-boot-type {
|
||||||
|
to { width: 100%; }
|
||||||
|
}
|
||||||
|
|
||||||
/* ─── cs-fx overlay system (DOM in CyberFx.astro) ─────────────────────────
|
/* ─── cs-fx overlay system (DOM in CyberFx.astro) ─────────────────────────
|
||||||
* Inert everywhere; only the cybersigil theme switches it on. Decorative
|
* Inert everywhere; only the cybersigil theme switches it on. Decorative
|
||||||
* layers ride above content at low opacity (pointer-events:none); the sigil
|
* layers ride above content at low opacity (pointer-events:none); the sigil
|
||||||
@@ -131,8 +210,7 @@ html.cybersigil body::after {
|
|||||||
}
|
}
|
||||||
.cybersigil .cs-fx-wire .cs-sigil path {
|
.cybersigil .cs-fx-wire .cs-sigil path {
|
||||||
animation:
|
animation:
|
||||||
cs-redraw 6.5s cubic-bezier(0.4, 0, 0.2, 1) infinite,
|
cs-redraw 6.5s cubic-bezier(0.4, 0, 0.2, 1) infinite;
|
||||||
cs-shimmer 4s ease-in-out infinite alternate;
|
|
||||||
/* negative, per-stroke offset: the field is always mid-carve, never blank */
|
/* negative, per-stroke offset: the field is always mid-carve, never blank */
|
||||||
animation-delay: calc(var(--i, 0) * -0.4s);
|
animation-delay: calc(var(--i, 0) * -0.4s);
|
||||||
}
|
}
|
||||||
@@ -205,7 +283,6 @@ html.cybersigil body::after {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
animation: cs-jitter 12s step-end infinite;
|
|
||||||
}
|
}
|
||||||
@keyframes cs-jitter {
|
@keyframes cs-jitter {
|
||||||
0%, 95% { transform: translate(0,0) scale(1); }
|
0%, 95% { transform: translate(0,0) scale(1); }
|
||||||
@@ -241,10 +318,56 @@ html.cybersigil body::after {
|
|||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Vascular Vessels */
|
||||||
|
.cybersigil .cs-sig-vessel {
|
||||||
|
stroke: var(--sky);
|
||||||
|
stroke-width: 0.2;
|
||||||
|
opacity: 0.25;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Micro-filaments */
|
||||||
|
.cybersigil .cs-sig-micro {
|
||||||
|
stroke: var(--sky);
|
||||||
|
stroke-width: 0.1;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ghost Symbols */
|
||||||
|
.cybersigil .cs-sig-text {
|
||||||
|
fill: var(--sky);
|
||||||
|
font-family: var(--font-display);
|
||||||
|
font-size: 7px;
|
||||||
|
opacity: 0.45;
|
||||||
|
letter-spacing: 0.05em;
|
||||||
|
pointer-events: none;
|
||||||
|
filter: drop-shadow(0 0 1px var(--sky));
|
||||||
|
animation: cs-flicker 4s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digital Sediment */
|
||||||
|
.cybersigil .cs-sig-dust {
|
||||||
|
fill: var(--sky);
|
||||||
|
opacity: 0.4;
|
||||||
|
filter: drop-shadow(0 0 1px var(--sky));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Calibration HUD */
|
||||||
|
.cybersigil .cs-sig-hud {
|
||||||
|
fill: none;
|
||||||
|
stroke: var(--sky);
|
||||||
|
stroke-width: 0.3;
|
||||||
|
opacity: 0.12;
|
||||||
|
stroke-dasharray: 2 6;
|
||||||
|
}
|
||||||
|
.cybersigil .cs-sig-hud--v {
|
||||||
|
stroke-dasharray: 1 15;
|
||||||
|
opacity: 0.08;
|
||||||
|
}
|
||||||
|
|
||||||
/* Stroke-weight tiers — heavy growth, hair filaments, prickly barbs, motifs. */
|
/* Stroke-weight tiers — heavy growth, hair filaments, prickly barbs, motifs. */
|
||||||
.cybersigil .cs-sigil .cs-sig-main { stroke-width: 2.8; }
|
.cybersigil .cs-sigil .cs-sig-main { stroke-width: 2.8; }
|
||||||
.cybersigil .cs-sigil .cs-sig-spine {
|
.cybersigil .cs-sigil .cs-sig-spine {
|
||||||
animation: cs-haptic 3s ease-in-out infinite;
|
/* Haptic pulse removed for a more static look */
|
||||||
}
|
}
|
||||||
@keyframes cs-haptic {
|
@keyframes cs-haptic {
|
||||||
0%, 100% { stroke-width: 2.8; filter: drop-shadow(0 0 2px var(--sky)); }
|
0%, 100% { stroke-width: 2.8; filter: drop-shadow(0 0 2px var(--sky)); }
|
||||||
|
|||||||
Reference in New Issue
Block a user