// Geometric family: a kaleidoscopic tunnel. The default drop scene — strong
// forward motion, hard symmetry, and it takes the beat well.

export const kaleidoTunnel = {
    name: 'Kaleido Tunnel',
    family: 'geometric',
    kind: 'fragment',
    // Personality: see look/Personality.js.
    // Hard grid lines on flat colour: grain reads as dirt on the lens.
    texture: 0,
    consumes: ['cast', 'ink'],
    traits: ['shape', 'camera', 'style'],

    params: {
        sides:    { type: 'int',   range: [2, 12],   default: 6,   uniform: 'u_sides' },
        depth:    { type: 'float', range: [1, 8],    default: 3.0, uniform: 'u_depth', bias: 'density' },
        speed:    { type: 'float', range: [0.1, 1.5], default: 0.45, uniform: 'u_speed', bias: 'motion', rate: true },
        twist:    { type: 'float', range: [0, 2],    default: 0.5, uniform: 'u_twist'  },
        rings:    { type: 'float', range: [2, 24],   default: 8,   uniform: 'u_rings', bias: 'density' },
        palette:  { type: 'palette', count: 6 },
    },

    reactive: {
        twist: { feature: 'bandLow',  amount: 0.3 },
        rings: { feature: 'bandHigh', amount: 0.2 },
    },

    shader: `
vec4 scene(vec2 uv, vec2 p) {
    float t = u_time * u_speed + u_seed;
    p = sigCamera(p);

    // A track with a signature polygon dictates the fold count — this is the
    // scene where that reads most strongly, so its own sides yields to it.
    float sides = u_sigSides > 2.5 ? u_sigSides : float(u_sides);

    // Cross-section measured in the signature form: the tunnel mouth is the
    // track's shape rather than a circle.
    float radius = max(castMain(p) + 1.0, 1e-4);
    vec2 folded = kaleido(p, sides);
    float angle = atan(folded.y, folded.x);

    // Tunnel coordinates: 1/r is depth, angle is the wall.
    float z = u_depth / radius + t * 2.0;
    float wall = angle / 3.14159265 + sin(z * 0.5 + t) * u_twist * 0.25;

    float ringLines = abs(fract(z * u_rings * 0.1) - 0.5) * 2.0;
    float wallLines = abs(fract(wall * sides) - 0.5) * 2.0;

    // TRAIT style: the grid is the whole image, so the track draws it. The
    // threshold was a bare 0.42 — a line weight with no name. u_sigLine sets how
    // much of the cell the line occupies, u_sigSoft how far it feathers.
    float weight = mix(0.22, 0.6, sat(u_sigLine));
    float feather = weight * mix(0.15, 1.0, sat(u_sigSoft));
    float grid = smoothstep(weight, max(weight - feather, 0.0), ringLines)
               + smoothstep(weight, max(weight - feather, 0.0), wallLines);

    vec3 col = palRamp(z * 0.05 + wall * 0.2) * 0.35;
    col += pal(int(mod(floor(z * u_rings * 0.1), 6.0))) * grid * 0.7;

    // Depth cue: far end of the tunnel darkens, mouth glows.
    float fade = smoothstep(0.0, 1.1, radius);
    col *= 0.25 + 0.9 * fade;
    col += pal(3) * (1.0 - fade) * 0.5 * 0.6;

    return vec4(inkValue(col), 1.0);
}
`,
};

export default kaleidoTunnel;
