float secondsOfDay(float seconds)
{
    return seconds - floor(seconds / 86400.0) * 86400.0;
}

float lineMask(float2 p, float angle, float innerRadius, float outerRadius, float width)
{
    float2 direction = float2(sin(angle), cos(angle));
    float along = dot(p, direction);
    float across = length(p - direction * along);
    float body = smoothstep(width, width * 0.35, across);
    float start = smoothstep(innerRadius - width, innerRadius + width, along);
    float end = 1.0 - smoothstep(outerRadius - width, outerRadius + width, along);
    return body * start * end;
}

float ringMask(float radius, float target, float width)
{
    return smoothstep(width, 0.0, abs(radius - target));
}

float tickMask(float2 p, int tick)
{
    float angle = (float(tick) / 60.0) * 6.28318530718;
    float2 direction = float2(sin(angle), cos(angle));
    float along = dot(p, direction);
    float across = length(p - direction * along);
    float major = (tick % 5) == 0 ? 1.0 : 0.0;
    float inner = lerp(0.82, 0.76, major);
    float outer = 0.9;
    float width = lerp(0.006, 0.011, major);
    float body = smoothstep(width, width * 0.35, across);
    float start = smoothstep(inner, inner + 0.025, along);
    float end = 1.0 - smoothstep(outer - 0.025, outer, along);
    return body * start * end;
}

float4 shadeVideo(ShaderContext context)
{
    float2 aspect = float2(context.outputResolution.x / max(context.outputResolution.y, 1.0), 1.0);
    float2 p = (context.uv * 2.0 - 1.0) * aspect / max(clockScale, 0.01);
    float radius = length(p);

    float seconds = showLocalTime
        ? secondsOfDay(context.utcTimeSeconds + context.utcOffsetSeconds)
        : secondsOfDay(context.utcTimeSeconds);
    float hour = floor(seconds / 3600.0);
    float minute = floor((seconds - hour * 3600.0) / 60.0);
    float second = seconds - hour * 3600.0 - minute * 60.0;

    float secondAngle = second / 60.0 * 6.28318530718;
    float minuteAngle = (minute + second / 60.0) / 60.0 * 6.28318530718;
    float hour12 = hour - floor(hour / 12.0) * 12.0;
    float hourAngle = (hour12 + minute / 60.0) / 12.0 * 6.28318530718;

    float4 color = context.sourceColor;
    float face = smoothstep(1.0, 0.97, radius);
    color = lerp(color, faceColor, face * faceColor.a);

    float ring = ringMask(radius, 0.92, 0.01);
    float ticks = 0.0;
    for (int i = 0; i < 60; ++i)
        ticks = max(ticks, tickMask(p, i));

    float hourHand = lineMask(p, hourAngle, -0.05, 0.48, 0.028);
    float minuteHand = lineMask(p, minuteAngle, -0.07, 0.72, 0.018);
    float secondHand = lineMask(p, secondAngle, -0.12, 0.8, 0.009);
    float hub = smoothstep(0.07, 0.0, radius);

    float whiteDetail = max(max(ring, ticks), max(hourHand, minuteHand));
    color.rgb = lerp(color.rgb, float3(0.92, 0.96, 1.0), whiteDetail);
    color.rgb = lerp(color.rgb, accentColor.rgb, max(secondHand, hub) * accentColor.a);

    return color;
}
