fix(badges): tri-phase rainbow cycling for punch hole markers
Each slot gets a fixed animation-delay (left: 0s, right: -0.833s, center: -1.667s) so they are 120° apart in the hue cycle — same speed, different start points. Replaces the shared-wrapper approach (all same phase) with per-slot CSS classes that encode the phase offset, giving a proper tri-phase RGB cycling effect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -695,13 +695,19 @@ const code_to_icon: {
|
||||
|
||||
<!-- Punch-out hole markers: X overlays at physical badge clip slot positions.
|
||||
Slots: 5/8in wide × 1/8in tall, 1/4in from top, 3/8in from left/right edges.
|
||||
Center slot: horizontally centered. Markers print so attendees know to push them out.
|
||||
z-index: 10 keeps markers above the header image regardless of DOM order.
|
||||
Inset ~1mm on all sides from the physical hole boundary — safety margin for printer
|
||||
registration variance (slots are only 3mm tall, registration matters). -->
|
||||
{#if punch_holes_left}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
class:punch_hole_rainbow={punch_holes_left_rainbow}
|
||||
Inset ~1mm on all sides — safety margin for printer registration variance.
|
||||
|
||||
Rainbow sync: rainbow markers share ONE wrapper div with the hue-rotate animation.
|
||||
A single CSS animation on the wrapper drives all children simultaneously — no
|
||||
start-time drift between slots. Non-rainbow markers are rendered outside the
|
||||
wrapper so they're unaffected by the rotating filter. -->
|
||||
|
||||
<!-- RAINBOW markers: per-slot class carries a fixed animation-delay so each slot
|
||||
starts at a different phase (0°, 120°, 240°) and they cycle in unison
|
||||
at the same speed — tri-phase RGB rather than drifting randomly. -->
|
||||
{#if punch_holes_left && punch_holes_left_rainbow}
|
||||
<div class="punch_hole_marker punch_hole_rainbow_left pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -710,7 +716,6 @@ const code_to_icon: {
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke={punch_holes_colors.left.fg} stroke-width="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
{#if punch_holes_left_rainbow}
|
||||
<div class="punch_hole_marker punch_hole_print_rgb pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
@@ -721,11 +726,9 @@ const code_to_icon: {
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke="#000" stroke-width="1" stroke-opacity="0.45"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if punch_holes_right}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
class:punch_hole_rainbow={punch_holes_right_rainbow}
|
||||
{#if punch_holes_right && punch_holes_right_rainbow}
|
||||
<div class="punch_hole_marker punch_hole_rainbow_right pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -734,7 +737,6 @@ const code_to_icon: {
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke={punch_holes_colors.right.fg} stroke-width="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
{#if punch_holes_right_rainbow}
|
||||
<div class="punch_hole_marker punch_hole_print_rgb pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
@@ -745,11 +747,9 @@ const code_to_icon: {
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke="#000" stroke-width="1" stroke-opacity="0.45"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
{#if punch_holes_center}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
class:punch_hole_rainbow={punch_holes_center_rainbow}
|
||||
{#if punch_holes_center && punch_holes_center_rainbow}
|
||||
<div class="punch_hole_marker punch_hole_rainbow_center pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -758,7 +758,6 @@ const code_to_icon: {
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke={punch_holes_colors.center.fg} stroke-width="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
{#if punch_holes_center_rainbow}
|
||||
<div class="punch_hole_marker punch_hole_print_rgb pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
@@ -769,7 +768,41 @@ const code_to_icon: {
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke="#000" stroke-width="1" stroke-opacity="0.45"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<!-- SOLID (non-rainbow) markers: individually positioned, no animation -->
|
||||
{#if punch_holes_left && !punch_holes_left_rainbow}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.left.bg} stroke={punch_holes_colors.left.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.left.fg} stroke-width="1"/>
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke={punch_holes_colors.left.fg} stroke-width="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
{#if punch_holes_right && !punch_holes_right_rainbow}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); right: calc(0.375in + 1mm); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.right.bg} stroke={punch_holes_colors.right.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.right.fg} stroke-width="1"/>
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke={punch_holes_colors.right.fg} stroke-width="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
{#if punch_holes_center && !punch_holes_center_rainbow}
|
||||
<div class="punch_hole_marker pointer-events-none absolute"
|
||||
aria-hidden="true"
|
||||
style="top: calc(0.25in + 1mm); left: 50%; transform: translateX(-50%); width: calc(0.625in - 2mm); height: calc(0.125in - 2mm); z-index: 10;">
|
||||
<svg width="100%" height="100%" viewBox="0 0 50 8" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="49" height="7" fill={punch_holes_colors.center.bg} stroke={punch_holes_colors.center.fg} stroke-width="1" stroke-dasharray="4,2"/>
|
||||
<line x1="0" y1="0" x2="50" y2="8" stroke={punch_holes_colors.center.fg} stroke-width="1"/>
|
||||
<line x1="50" y1="0" x2="0" y2="8" stroke={punch_holes_colors.center.fg} stroke-width="1"/>
|
||||
</svg>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Background image bleed container.
|
||||
@@ -1373,24 +1406,25 @@ const code_to_icon: {
|
||||
<style>
|
||||
/*
|
||||
* Punch-hole rainbow: animated hue-rotate on screen; static SVG gradient on print.
|
||||
* .punch_hole_rainbow — screen display, cycling animation
|
||||
* .punch_hole_print_rgb — print-only companion div with built-in linearGradient SVG
|
||||
*
|
||||
* On print: the animated div is hidden; the gradient div appears in its place.
|
||||
* The gradient is defined inside each SVG so it's self-contained per slot.
|
||||
* Phase offsets: slots are 120° apart (2.5s ÷ 3 ≈ 0.833s) so when all three are
|
||||
* active they form a proper tri-phase RGB cycle. Two active slots are 120° apart.
|
||||
* Negative animation-delay starts each slot mid-cycle at its designated phase.
|
||||
*/
|
||||
@keyframes ae_punch_hole_rainbow {
|
||||
from { filter: hue-rotate(0deg); }
|
||||
to { filter: hue-rotate(360deg); }
|
||||
}
|
||||
.punch_hole_rainbow {
|
||||
animation: ae_punch_hole_rainbow 2.5s linear infinite;
|
||||
}
|
||||
.punch_hole_print_rgb {
|
||||
display: none;
|
||||
}
|
||||
.punch_hole_rainbow_left { animation: ae_punch_hole_rainbow 2.5s 0.000s linear infinite; }
|
||||
.punch_hole_rainbow_right { animation: ae_punch_hole_rainbow 2.5s -0.833s linear infinite; }
|
||||
.punch_hole_rainbow_center { animation: ae_punch_hole_rainbow 2.5s -1.667s linear infinite; }
|
||||
|
||||
.punch_hole_print_rgb { display: none; }
|
||||
@media print {
|
||||
.punch_hole_rainbow { display: none; }
|
||||
.punch_hole_rainbow_left,
|
||||
.punch_hole_rainbow_right,
|
||||
.punch_hole_rainbow_center { display: none; }
|
||||
.punch_hole_print_rgb { display: block; }
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user