Skip to content

Instantly share code, notes, and snippets.

@lexrus
Last active August 7, 2026 06:31
Show Gist options
  • Select an option

  • Save lexrus/eadc04582835d9f16ea4d4448d0e8b2c to your computer and use it in GitHub Desktop.

Select an option

Save lexrus/eadc04582835d9f16ea4d4448d0e8b2c to your computer and use it in GitHub Desktop.
[Animated SVG] Avaiable on TestFlight Badge

Available on TestFlight — animated badge

The concept for this badge comes from a X post by Nob Nukui(https://x.com/nobtaka/status/2084928872152539163)

This animated SVG source code was generated with Grok 4.5. You are free to use this SVG however you like. No attribution is necessary. If you have a moment, I'd appreciate it if you could drop a like on the original post to show your support.

Thanks.

Display the source blob
Display the rendered blob
Raw
<!--
Available on TestFlight — animated badge
Generated by Lex Tang via vibe coding.
https://lex.sh
Typography is SF Pro Display Medium converted to vector outlines
so rendering is identical on every system (no web font required).
Glyphs are laid out with Core Text pair-kerning (Av, Te, etc.).
Avoid SVG filters on text — they rasterize and look soft on GitHub.
-->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 333 140" width="333" height="140" role="img" aria-label="Available on TestFlight">
<!--
Grid pitch = 27, square cells.
Badge width = 11 × 27 = 297 → exactly 1 full cell on left and right.
badge: x=12 y=16 w=297 h=108 (h = 4 × 27)
right edge = 309
-->
<defs>
<linearGradient id="bgFill" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#92D3FF"/>
<stop offset="40%" stop-color="#4DACFF"/>
<stop offset="100%" stop-color="#1A6BE8"/>
</linearGradient>
<!-- Inner rim: sky blue (top) → deep blue (bottom) -->
<linearGradient id="innerBorder" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#B6E6FF"/>
<stop offset="45%" stop-color="#4A9EE8"/>
<stop offset="100%" stop-color="#0C419F"/>
</linearGradient>
<radialGradient id="hubDisc" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#C8ECFF" stop-opacity="0.55"/>
<stop offset="40%" stop-color="#8ED0FF" stop-opacity="0.32"/>
<stop offset="72%" stop-color="#5AB0F5" stop-opacity="0.12"/>
<stop offset="100%" stop-color="#3A9BFF" stop-opacity="0"/>
</radialGradient>
<!-- Fan residual: sky blue, bright at blade → fade through trail -->
<linearGradient id="fanGrad" gradientUnits="objectBoundingBox" x1="1" y1="0.2" x2="0" y2="0.55">
<stop offset="0%" stop-color="#C8ECFF" stop-opacity="0.78"/>
<stop offset="40%" stop-color="#8ED4FF" stop-opacity="0.38"/>
<stop offset="100%" stop-color="#6AB8F0" stop-opacity="0"/>
</linearGradient>
<filter id="badgeShadow" x="-10%" y="-12%" width="120%" height="140%">
<feDropShadow dx="0" dy="4" stdDeviation="6" flood-color="#1A4A96" flood-opacity="0.26"/>
</filter>
<clipPath id="badgeClip">
<rect id="badgeShape" x="12" y="16" width="297" height="108" rx="32" ry="32"/>
</clipPath>
<!--
Blade geometry:
outer tip = (0, -33)
inner tip = (0, -7.5)
Stroke rounds both ends (visual tips extend ~1.25 beyond path).
-->
<path id="blade"
d="M 0 -33 L 3.4 -18.2 L 0 -7.5 L -3.4 -18.2 Z"
fill="#FFFFFF"
stroke="#FFFFFF"
stroke-width="2.5"
stroke-linejoin="round"
stroke-linecap="round"/>
<!--
Residual fan aligned to the blade’s visual tips:
outer tip = y = -35
apex/center = y = -5.5
radius = 35 − 5.5 = 29.5
Clockwise spin → trail sweeps CCW (~52°) behind the blade.
-->
<path id="fanTrail"
d="M 0 -5.5
L 0 -35
A 29.5 29.5 0 0 0 -23.25 -23.66
Z"/>
<!-- SF Pro Display Medium outlines with Core Text pair-kerning -->
<path id="textAvailable" d="M0.30 0.00L3.06 0.00L4.62 -4.57L11.13 -4.57L12.68 0.00L15.43 0.00L9.29 -16.91L6.46 -16.91ZM7.85 -14.11L7.90 -14.11L10.42 -6.68L5.32 -6.68ZM19.38 0.00L22.10 0.00L26.52 -12.33L23.88 -12.33L20.79 -2.47L20.73 -2.47L17.64 -12.33L14.94 -12.33ZM31.34 0.22C32.96 0.22 34.39 -0.62 35.11 -1.95L35.16 -1.95L35.16 0.00L37.70 0.00L37.70 -8.50C37.70 -10.97 35.79 -12.56 32.78 -12.56C29.74 -12.56 27.90 -10.93 27.73 -8.81L27.71 -8.68L30.11 -8.68L30.13 -8.79C30.34 -9.77 31.24 -10.46 32.71 -10.46C34.28 -10.46 35.16 -9.64 35.16 -8.29L35.16 -7.36L31.80 -7.16C28.89 -6.98 27.22 -5.67 27.22 -3.53L27.22 -3.50C27.22 -1.29 28.88 0.22 31.34 0.22ZM29.78 -3.56L29.78 -3.59C29.78 -4.63 30.62 -5.30 32.14 -5.39L35.16 -5.58L35.16 -4.62C35.16 -3.01 33.81 -1.80 32.03 -1.80C30.67 -1.80 29.78 -2.48 29.78 -3.56ZM41.52 -14.23C42.35 -14.23 43.00 -14.88 43.00 -15.68C43.00 -16.49 42.35 -17.14 41.52 -17.14C40.70 -17.14 40.04 -16.49 40.04 -15.68C40.04 -14.88 40.70 -14.23 41.52 -14.23ZM40.25 0.00L42.79 0.00L42.79 -12.33L40.25 -12.33ZM45.49 0.00L48.02 0.00L48.02 -16.91L45.49 -16.91ZM54.25 0.22C55.88 0.22 57.30 -0.62 58.02 -1.95L58.07 -1.95L58.07 0.00L60.61 0.00L60.61 -8.50C60.61 -10.97 58.70 -12.56 55.69 -12.56C52.65 -12.56 50.81 -10.93 50.64 -8.81L50.62 -8.68L53.02 -8.68L53.04 -8.79C53.25 -9.77 54.15 -10.46 55.62 -10.46C57.19 -10.46 58.07 -9.64 58.07 -8.29L58.07 -7.36L54.71 -7.16C51.80 -6.98 50.13 -5.67 50.13 -3.53L50.13 -3.50C50.13 -1.29 51.79 0.22 54.25 0.22ZM52.69 -3.56L52.69 -3.59C52.69 -4.63 53.53 -5.30 55.05 -5.39L58.07 -5.58L58.07 -4.62C58.07 -3.01 56.72 -1.80 54.94 -1.80C53.58 -1.80 52.69 -2.48 52.69 -3.56ZM69.61 0.25C72.74 0.25 74.77 -2.24 74.77 -6.16L74.77 -6.18C74.77 -10.10 72.73 -12.56 69.63 -12.56C67.89 -12.56 66.48 -11.68 65.74 -10.23L65.68 -10.23L65.68 -16.91L63.15 -16.91L63.15 0.00L65.68 0.00L65.68 -2.09L65.74 -2.09C66.47 -0.64 67.84 0.25 69.61 0.25ZM68.94 -1.93C67.02 -1.93 65.67 -3.60 65.67 -6.16L65.67 -6.18C65.67 -8.73 67.03 -10.39 68.94 -10.39C70.93 -10.39 72.18 -8.78 72.18 -6.18L72.18 -6.16C72.18 -3.54 70.93 -1.93 68.94 -1.93ZM76.82 0.00L79.35 0.00L79.35 -16.91L76.82 -16.91ZM87.21 0.25C90.20 0.25 92.10 -1.54 92.50 -3.49L92.52 -3.62L90.12 -3.62L90.08 -3.53C89.77 -2.60 88.77 -1.83 87.27 -1.83C85.25 -1.83 83.98 -3.19 83.93 -5.52L92.66 -5.52L92.66 -6.38C92.66 -10.08 90.54 -12.56 87.08 -12.56C83.62 -12.56 81.40 -9.98 81.40 -6.13L81.40 -6.12C81.40 -2.23 83.59 0.25 87.21 0.25ZM87.09 -10.49C88.75 -10.49 89.94 -9.45 90.15 -7.31L83.96 -7.31C84.19 -9.38 85.45 -10.49 87.09 -10.49ZM104.78 0.25C108.30 0.25 110.62 -2.19 110.62 -6.16L110.62 -6.19C110.62 -10.14 108.28 -12.56 104.77 -12.56C101.26 -12.56 98.93 -10.12 98.93 -6.19L98.93 -6.16C98.93 -2.20 101.24 0.25 104.78 0.25ZM104.79 -1.88C102.81 -1.88 101.52 -3.43 101.52 -6.16L101.52 -6.19C101.52 -8.88 102.82 -10.44 104.77 -10.44C106.75 -10.44 108.04 -8.88 108.04 -6.19L108.04 -6.16C108.04 -3.45 106.77 -1.88 104.79 -1.88ZM112.58 0.00L115.11 0.00L115.11 -7.18C115.11 -9.11 116.26 -10.39 118.04 -10.39C119.80 -10.39 120.67 -9.35 120.67 -7.50L120.67 0.00L123.21 0.00L123.21 -7.98C123.21 -10.82 121.65 -12.56 118.95 -12.56C117.08 -12.56 115.82 -11.72 115.17 -10.46L115.11 -10.46L115.11 -12.33L112.58 -12.33Z"/>
<path id="textTestFlight" d="M9.59 0.00L13.96 0.00L13.96 -24.41L22.58 -24.41L22.58 -28.18L0.96 -28.18L0.96 -24.41L9.59 -24.41ZM29.38 0.41C34.36 0.41 37.52 -2.56 38.18 -5.82L38.22 -6.04L34.22 -6.04L34.16 -5.88C33.63 -4.34 31.97 -3.05 29.47 -3.05C26.11 -3.05 23.98 -5.31 23.91 -9.20L38.46 -9.20L38.46 -10.62C38.46 -16.80 34.92 -20.94 29.16 -20.94C23.40 -20.94 19.69 -16.64 19.69 -10.21L19.69 -10.20C19.69 -3.71 23.34 0.41 29.38 0.41ZM29.18 -17.48C31.93 -17.48 33.93 -15.74 34.28 -12.19L23.96 -12.19C24.34 -15.62 26.45 -17.48 29.18 -17.48ZM49.41 0.41C54.26 0.41 57.77 -2.17 57.77 -5.92L57.77 -5.94C57.77 -8.89 56.17 -10.55 51.97 -11.52L48.63 -12.29C46.43 -12.81 45.59 -13.67 45.59 -14.94L45.59 -14.96C45.59 -16.60 47.01 -17.68 49.28 -17.68C51.66 -17.68 53.07 -16.43 53.32 -14.63L53.34 -14.49L57.30 -14.49L57.29 -14.73C57.07 -18.22 54.14 -20.94 49.28 -20.94C44.55 -20.94 41.35 -18.42 41.35 -14.75L41.35 -14.73C41.35 -11.74 43.28 -9.86 47.19 -8.96L50.55 -8.20C52.75 -7.68 53.50 -6.91 53.50 -5.59L53.50 -5.57C53.50 -3.91 51.97 -2.85 49.43 -2.85C46.84 -2.85 45.43 -3.96 45.04 -5.86L45.00 -6.05L40.82 -6.05L40.84 -5.88C41.27 -2.13 44.28 0.41 49.41 0.41ZM68.24 0.41C69.10 0.41 69.90 0.31 70.39 0.23L70.39 -3.03C70.08 -2.99 69.71 -2.95 69.26 -2.95C67.48 -2.95 66.54 -3.57 66.54 -5.66L66.54 -17.19L70.39 -17.19L70.39 -20.55L66.54 -20.55L66.54 -25.90L62.23 -25.90L62.23 -20.55L59.28 -20.55L59.28 -17.19L62.23 -17.19L62.23 -5.41C62.23 -1.31 64.18 0.41 68.24 0.41ZM74.38 0.00L78.75 0.00L78.75 -11.80L90.86 -11.80L90.86 -15.49L78.75 -15.49L78.75 -24.41L91.97 -24.41L91.97 -28.18L74.38 -28.18ZM95.43 0.00L99.65 0.00L99.65 -28.18L95.43 -28.18ZM106.27 -23.71C107.66 -23.71 108.73 -24.80 108.73 -26.13C108.73 -27.48 107.66 -28.57 106.27 -28.57C104.90 -28.57 103.81 -27.48 103.81 -26.13C103.81 -24.80 104.90 -23.71 106.27 -23.71ZM104.16 0.00L108.38 0.00L108.38 -20.55L104.16 -20.55ZM121.74 7.25C127.54 7.25 131.17 4.12 131.17 -0.57L131.17 -20.55L126.93 -20.55L126.93 -17.05L126.84 -17.05C125.62 -19.38 123.36 -20.94 120.47 -20.94C115.25 -20.94 111.82 -16.89 111.82 -10.45L111.82 -10.43C111.82 -4.02 115.21 0.02 120.37 0.02C123.32 0.02 125.66 -1.41 126.84 -3.63L126.93 -3.63L126.93 -0.82C126.93 2.05 125.08 3.85 121.72 3.85C119.08 3.85 117.30 2.95 116.74 1.64L116.66 1.48L112.48 1.48L112.50 1.66C113.12 4.80 116.46 7.25 121.74 7.25ZM121.56 -3.42C118.22 -3.42 116.13 -6.07 116.13 -10.37L116.13 -10.39C116.13 -14.63 118.22 -17.32 121.56 -17.32C124.77 -17.32 126.93 -14.61 126.93 -10.39L126.93 -10.37C126.93 -6.13 124.79 -3.42 121.56 -3.42ZM135.49 0.00L139.71 0.00L139.71 -11.89C139.71 -15.10 141.64 -17.32 144.55 -17.32C147.52 -17.32 149.24 -15.29 149.24 -11.89L149.24 0.00L153.46 0.00L153.46 -12.70C153.46 -17.66 150.57 -20.94 146.17 -20.94C143.11 -20.94 140.90 -19.55 139.80 -17.17L139.71 -17.17L139.71 -28.18L135.49 -28.18ZM164.75 0.41C165.61 0.41 166.41 0.31 166.89 0.23L166.89 -3.03C166.58 -2.99 166.21 -2.95 165.76 -2.95C163.98 -2.95 163.05 -3.57 163.05 -5.66L163.05 -17.19L166.89 -17.19L166.89 -20.55L163.05 -20.55L163.05 -25.90L158.73 -25.90L158.73 -20.55L155.78 -20.55L155.78 -17.19L158.73 -17.19L158.73 -5.41C158.73 -1.31 160.68 0.41 164.75 0.41Z"/>
</defs>
<!-- Badge body: width = 11 grid cells -->
<g filter="url(#badgeShadow)">
<rect x="12" y="16" width="297" height="108" rx="32" ry="32" fill="url(#bgFill)"/>
</g>
<!-- Interior grid: pitch 27, 1 full cell inset on every side -->
<g clip-path="url(#badgeClip)">
<g stroke="#9AD4FF" stroke-opacity="0.42" stroke-width="1" fill="none" shape-rendering="crispEdges">
<line x1="39" y1="16" x2="39" y2="124"/>
<line x1="66" y1="16" x2="66" y2="124"/>
<line x1="93" y1="16" x2="93" y2="124"/>
<line x1="120" y1="16" x2="120" y2="124"/>
<line x1="147" y1="16" x2="147" y2="124"/>
<line x1="174" y1="16" x2="174" y2="124"/>
<line x1="201" y1="16" x2="201" y2="124"/>
<line x1="228" y1="16" x2="228" y2="124"/>
<line x1="255" y1="16" x2="255" y2="124"/>
<line x1="282" y1="16" x2="282" y2="124"/>
<line x1="12" y1="43" x2="309" y2="43"/>
<line x1="12" y1="70" x2="309" y2="70"/>
<line x1="12" y1="97" x2="309" y2="97"/>
</g>
</g>
<!-- Inner rim border -->
<rect x="13.25" y="17.25" width="294.5" height="105.5" rx="30.75" ry="30.75"
fill="none" stroke="url(#innerBorder)" stroke-width="1.75"/>
<!-- Propeller -->
<g transform="translate(68, 70)">
<circle r="33" fill="url(#hubDisc)"/>
<g>
<use href="#fanTrail" fill="url(#fanGrad)"/>
<use href="#fanTrail" fill="url(#fanGrad)" transform="rotate(120)"/>
<use href="#fanTrail" fill="url(#fanGrad)" transform="rotate(240)"/>
<use href="#blade"/>
<use href="#blade" transform="rotate(120)"/>
<use href="#blade" transform="rotate(240)"/>
<animateTransform
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 0 0"
to="360 0 0"
dur="1.55s"
repeatCount="indefinite"
calcMode="linear"/>
</g>
</g>
<!--
Text as SF Pro Display Medium vector outlines with pair-kerning.
Soft depth via a pure-vector offset copy (no feDropShadow on text).
-->
<g transform="translate(112, 70)" shape-rendering="geometricPrecision">
<g transform="translate(0, 1)" fill="#0A3478" fill-opacity="0.22">
<use href="#textAvailable" transform="translate(0, -9.551)"/>
<use href="#textTestFlight" transform="translate(0, 26.664)"/>
</g>
<g fill="#ffffff">
<use href="#textAvailable" transform="translate(0, -9.551)"/>
<use href="#textTestFlight" transform="translate(0, 26.664)"/>
</g>
</g>
</svg>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment