Skip to content
Draft
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
198 changes: 198 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TOGY Hero</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: system-ui, -apple-system, sans-serif; background: #000; overflow: hidden; }
.hero { position: relative; width: 100vw; height: 100vh; overflow: hidden; }
#canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.noise { position: absolute; inset: 0; pointer-events: none; opacity: 0.12; mix-blend-mode: soft-light; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 512 512' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-repeat: repeat; }
.content { position: relative; z-index: 10; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 2rem; text-align: center; }
.logo { font-size: clamp(3rem, 8vw, 5rem); font-weight: 800; letter-spacing: -0.02em; color: #F8F7F3; margin-bottom: 1.5rem; }
.tagline { font-size: clamp(1rem, 3vw, 1.75rem); font-weight: 500; color: #F8F7F3; max-width: 700px; line-height: 1.4; margin-bottom: 2.5rem; }
.tagline span { color: #FF3C02; }
.chat-box { display: flex; align-items: center; gap: 0.75rem; width: 100%; max-width: 480px; border-radius: 12px; padding: 0.875rem 1.25rem; background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); }
.chat-box input { flex: 1; background: transparent; border: none; outline: none; font-size: 1rem; color: #F8F7F3; }
.chat-box input::placeholder { color: #6A6A6A; }
.chat-box button { padding: 0.5rem 1rem; border-radius: 8px; font-weight: 600; font-size: 1.1rem; border: none; cursor: pointer; background: #FF3C02; color: #F8F7F3; }
.actions { display: flex; gap: 0.5rem; margin-top: 1.25rem; flex-wrap: wrap; justify-content: center; }
.actions button { padding: 0.5rem 0.875rem; border-radius: 20px; font-size: 0.85rem; background: transparent; cursor: pointer; border: 1px dashed #6A6A6A; color: #F8F7F3; }
.badge { position: absolute; bottom: 0.75rem; left: 0.75rem; padding: 0.5rem 0.75rem; border-radius: 6px; font-size: 0.7rem; background: rgba(0, 0, 0, 0.6); color: #6A6A6A; }
.webgl-error { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, #1a0500 0%, #000 100%); color: #FF3C02; font-size: 1rem; text-align: center; padding: 2rem; }
</style>
</head>
<body>
<div class="hero">
<canvas id="canvas"></canvas>
<div class="noise"></div>
<div class="content">
<div class="logo">TOGY</div>
<h1 class="tagline">FACTORIES WERE BUILT TO PRODUCE.<br><span>TOGY MAKES THEM THINK.</span></h1>
<div class="chat-box">
<input type="text" placeholder="Ask TOGY anything...">
<button>→</button>
</div>
<div class="actions">
<button>Connect machines</button>
<button>Plan production</button>
<button>Correct deviations</button>
</div>
</div>
<div class="badge">WebGL Lava + Noise • 25s cycle</div>
</div>

<script>
const canvas = document.getElementById('canvas');
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');

if (!gl) {
const errorDiv = document.createElement('div');
errorDiv.className = 'webgl-error';
errorDiv.textContent = 'WebGL is not supported in your browser.';
document.querySelector('.hero').appendChild(errorDiv);
} else {
const vs = `attribute vec2 a_position; void main() { gl_Position = vec4(a_position, 0.0, 1.0); }`;

const fs = `
precision highp float;
uniform float u_time;
uniform vec2 u_resolution;

vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
vec3 permute(vec3 x) { return mod289(((x * 34.0) + 1.0) * x); }

float snoise(vec2 v) {
const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);
vec2 i = floor(v + dot(v, C.yy));
vec2 x0 = v - i + dot(i, C.xx);
vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
vec4 x12 = x0.xyxy + C.xxzz;
x12.xy -= i1;
i = mod289(i);
vec3 p = permute(permute(i.y + vec3(0.0, i1.y, 1.0)) + i.x + vec3(0.0, i1.x, 1.0));
vec3 m = max(0.5 - vec3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
m = m * m; m = m * m;
vec3 x = 2.0 * fract(p * C.www) - 1.0;
vec3 h = abs(x) - 0.5;
vec3 ox = floor(x + 0.5);
vec3 a0 = x - ox;
m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
vec3 g;
g.x = a0.x * x0.x + h.x * x0.y;
g.yz = a0.yz * x12.xz + h.yz * x12.yw;
return 130.0 * dot(m, g);
}

float fbm(vec2 p) {
float v = 0.0, a = 0.5, f = 1.5;
for (int i = 0; i < 2; i++) { v += a * snoise(p * f); f *= 1.6; a *= 0.65; }
return v;
}

float lava(vec2 p, float t) {
vec2 q = vec2(fbm(p + t * 0.015), fbm(p + vec2(5.2, 1.3) + t * 0.012));
vec2 r = vec2(fbm(p + 2.5 * q + vec2(1.7, 9.2) + t * 0.008), fbm(p + 2.5 * q + vec2(8.3, 2.8) + t * 0.01));
return fbm(p + 2.5 * r);
}

void main() {
vec2 uv = gl_FragCoord.xy / u_resolution;
float aspect = u_resolution.x / u_resolution.y;
vec2 p = vec2(uv.x * aspect, uv.y);

float t = u_time * 0.04;
float pattern = lava(p * 1.5, t);
float hotSpots = fbm(p * 0.8 + t * 0.2);

float t1 = smoothstep(-0.5, 0.8, pattern);
float t2 = smoothstep(-0.3, 0.6, hotSpots);

vec3 black = vec3(0.0);
vec3 dark = vec3(0.012);
vec3 orange = vec3(1.0, 0.045, 0.0006);
vec3 darkOrange = vec3(0.15, 0.02, 0.001);

vec3 color = mix(black, dark, t1 * 0.5);
color = mix(color, darkOrange, t2 * t1 * 0.7);
color = mix(color, orange, pow(t2 * t1, 2.5) * 0.9);

float vignette = 1.0 - length(uv - 0.5) * 0.4;
color *= vignette;

vec3 lo = color * 12.92;
vec3 hi = 1.055 * pow(color, vec3(1.0 / 2.4)) - 0.055;
color = mix(lo, hi, step(vec3(0.0031308), color));

gl_FragColor = vec4(color, 1.0);
}
`;

function createShader(type, source) {
const shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
console.error('Shader compile error:', gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
return null;
}
return shader;
}

const vShader = createShader(gl.VERTEX_SHADER, vs);
const fShader = createShader(gl.FRAGMENT_SHADER, fs);

if (vShader && fShader) {
const prog = gl.createProgram();
gl.attachShader(prog, vShader);
gl.attachShader(prog, fShader);
gl.linkProgram(prog);

if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
console.error('Program link error:', gl.getProgramInfoLog(prog));
} else {
gl.useProgram(prog);

const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1]), gl.STATIC_DRAW);

const pos = gl.getAttribLocation(prog, 'a_position');
gl.enableVertexAttribArray(pos);
gl.vertexAttribPointer(pos, 2, gl.FLOAT, false, 0, 0);

const timeLoc = gl.getUniformLocation(prog, 'u_time');
const resLoc = gl.getUniformLocation(prog, 'u_resolution');

const start = performance.now();

function resize() {
const dpr = Math.min(window.devicePixelRatio || 1, 2);
const w = canvas.clientWidth * dpr;
const h = canvas.clientHeight * dpr;
if (canvas.width !== w || canvas.height !== h) {
canvas.width = w;
canvas.height = h;
gl.viewport(0, 0, w, h);
}
}

function render() {
resize();
gl.uniform1f(timeLoc, (performance.now() - start) / 1000);
gl.uniform2f(resLoc, canvas.width, canvas.height);
gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(render);
}

render();
}
}
}
</script>
</body>
</html>