From 10a1f7b71f2208f68924693eb4512276af3684a3 Mon Sep 17 00:00:00 2001 From: Warp Date: Mon, 16 Mar 2026 22:33:56 +0000 Subject: [PATCH] Add Warp incident Slack icon assets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - warp_incident_icon.png (512x512) — primary Slack app icon - warp_incident_icon_128.png (128x128) — small/thumbnail variant - generate_icon.py — reproducible generation script Brand tokens: #121212 (black bg), #C6372A (red alert), #A43787 (pink accent) Co-Authored-By: Oz --- generate_icon.py | 107 +++++++++++++++++++++++++++++++++++++ warp_incident_icon.png | Bin 0 -> 4756 bytes warp_incident_icon_128.png | Bin 0 -> 1059 bytes 3 files changed, 107 insertions(+) create mode 100644 generate_icon.py create mode 100644 warp_incident_icon.png create mode 100644 warp_incident_icon_128.png diff --git a/generate_icon.py b/generate_icon.py new file mode 100644 index 0000000..6777064 --- /dev/null +++ b/generate_icon.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +"""Generate Warp-branded Slack icons for incident creation. + +Outputs: + warp_incident_icon.png – 512x512 (primary) + warp_incident_icon_128.png – 128x128 (small/thumbnail) + +Brand tokens used: + Background: #121212 (Warp black) + Alert: #C6372A (Warp red – error/destructive states) + Accent: #A43787 (Warp pink – primary expressive accent) +""" + +from PIL import Image, ImageDraw +import math + +# Warp brand tokens +BLACK = "#121212" +RED = "#C6372A" +PINK = "#A43787" + + +def inset_triangle(verts, px): + """Shrink a triangle toward its centroid by px pixels.""" + cx = sum(v[0] for v in verts) / 3 + cy = sum(v[1] for v in verts) / 3 + result = [] + for x, y in verts: + dx, dy = cx - x, cy - y + dist = math.hypot(dx, dy) + if dist == 0: + result.append((x, y)) + else: + result.append((x + dx / dist * px, y + dy / dist * px)) + return result + + +def generate_icon(size, output_path): + """Generate the incident icon at a given size.""" + img = Image.new("RGBA", (size, size), (0, 0, 0, 0)) + draw = ImageDraw.Draw(img) + + # Rounded-rect background (Slack crops to rounded square) + corner_radius = int(size * 0.156) # ~80/512 + draw.rounded_rectangle( + [(0, 0), (size - 1, size - 1)], + radius=corner_radius, + fill=BLACK, + ) + + # Warning triangle + pad = int(size * 0.156) + tri_top = pad + int(size * 0.02) + tri_bottom = size - pad - int(size * 0.04) + tri_left = pad + tri_right = size - pad + tri_cx = size // 2 + + vertices = [ + (tri_cx, tri_top), + (tri_left, tri_bottom), + (tri_right, tri_bottom), + ] + + # Outer triangle (filled red) + draw.polygon(vertices, fill=RED) + + # Inner triangle (cut out to make outline) + inset = int(size * 0.055) + inner_verts = inset_triangle(vertices, inset) + draw.polygon(inner_verts, fill=BLACK) + + # Exclamation mark + exc_cx = tri_cx + exc_top = tri_top + int(size * 0.254) + exc_bar_bottom = tri_bottom - int(size * 0.215) + exc_dot_top = tri_bottom - int(size * 0.156) + exc_dot_bottom = tri_bottom - int(size * 0.107) + bar_hw = int(size * 0.031) + dot_r = int(size * 0.035) + + draw.rounded_rectangle( + [(exc_cx - bar_hw, exc_top), (exc_cx + bar_hw, exc_bar_bottom)], + radius=max(2, int(size * 0.016)), + fill=RED, + ) + draw.ellipse( + [(exc_cx - dot_r, exc_dot_top), (exc_cx + dot_r, exc_dot_bottom)], + fill=RED, + ) + + # Subtle pink accent line at bottom + accent_y = size - int(size * 0.082) + accent_margin = int(size * 0.273) + draw.rounded_rectangle( + [(accent_margin, accent_y), (size - accent_margin, accent_y + max(2, int(size * 0.006)))], + radius=max(1, int(size * 0.004)), + fill=PINK, + ) + + img.save(output_path, "PNG") + print(f"Saved {size}x{size} icon to {output_path}") + + +if __name__ == "__main__": + generate_icon(512, "/workspace/.github/warp_incident_icon.png") + generate_icon(128, "/workspace/.github/warp_incident_icon_128.png") diff --git a/warp_incident_icon.png b/warp_incident_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..bc9781b47001ae93838a6132188afffa537216a0 GIT binary patch literal 4756 zcmbVPdpOkT+rPix8H__?P!p{fhsyqzShGnMGY&=NSQ1TTM6@-flolmlIv^_5#)yUv zJKF7}lxmku>7>N$s!&8JOcFAVnVH`+rtSS*@B3cYdtL8eGtcwf-_L#DpZj_4Lq>p~ z*CefJS^zL7!h3wm0f99#NQj|iNTN%_GXyJAMK zGu|70a4*lB2rL$xa9untu5IgeVJ#~j5;SeVma{GlEL(VCIQGrOfzfe?&(ol>cW`iU z?a&<0W%7et9+I90xlkXq#A~?1^&sukcQNNlri4qdZt9Gf0uNInCpatR*G<{GO$kA; zR*H1)-IKZ^ou&vz&%GZQrk9q8Vk;)Ckpree&p=W`f!!@(>JszQd^$}H|}ulA2f_6p<;yKR6)Yh z<$8f1$-ocq;NbNRKuw0<^AqTPnt%Yt?Yn)9O_X~h^;xA`8h7YYcR@VwX(zsq2gY*f zD+r8^8ivgyB$0zfZS6%2;S))Tg(q8Z(Q93JAa!2+Cz+@+g%@3MLI+(XYt2qCHv$wfF!Ys751uQaL^vE>J_%s5<=1@!c%?wHs|p8|pJoFx zhl~WIl5L;lEC|{%Z{RD2Qk6FV+YPa$rLRZQ!$bpbTAnx_J)XazTzA8le_HFyGs}XT3n?$Ep`1Y1T$xJ0(nh+Au{aXti zo?ED#%aqKy@DdlTP;z4lT(gSeZ3r?Ai1}Gg1qjmZ3#47*zYyfON{n$cwEl(-yqyU} zB{8gBwYSJzeGD?D=iRYQQyiw0s1fB~1b?H~D=HK&@12N*FFPl5>J_II3ZpW}J_JPM zDU-6mOWHSlfo*n3xU-T@iKBqG<=8LNWn)Au8UD*-Z}Z37PP}tE>4bqA@5K9!7&i$A z{jUBE$rbWuNu)LyePLxYQ>dUPzoNq$0~Lp&C_jab+=K(^i-8?*&RB4+nHq8c2(@eS zIj%@!w;s^M>z59!zpfF?0Pgn{!Z<`hCJyjr5Q-@*?Q!^M+vN}J z&7sAT^9_@hQJ{$YFGy1eE|CmobAwkRrgUuG~uExIPl#^L@RNi+RJ)7ze^1_!9c@tPe-hx zY8MVOe?y+#Fy&G)_%Y8lqR&y}iZ<;A<<&B*T@xB_Ybe%SRwH`IKufhty-WsPd^X1XLJ5`1ZBh0}4E1${HfI*>N~{FD7p9!im3q6xW*YfINUD z25U+VL6LR6!fEGxJKij?s?Kz6a5g>b4Wb1?1>bpg$pI)bK9{`dvRctJ46HqhZV!;* zSH65S-3E?PfcvfcB!LB3RY~iZJnXDHz+*jLA0LXy^(;;!9*_c%W7*smVcR({x^ZYe z+kaWHB4;V@*=MtXo_$_C2w8D&*~j5aVaHoPnj}Z7Pl;iohkL`KUE1(j^eCPYwbMA9 zjES!Neqoo_^jaf}w)FMabDhXw&6S!R>j|ha+$PQk?!srnWw18LoU9+tiUzukXziRwLj)ktNmplp;hpz|i+I>WHo!K<$_zgcpOBcAm8uoZ z#Xy`v%&^DU%Z15}b#y|2@Vwk}&XS>pFMsXGfkZ^>3C$Je`mim0ENwdv>v98eL6xbz z<8g|T0aTd@p^sv7p$!~H{HE-g9Y}%W-^)Cb%iyXxfVx4sCj-_Y``a6FaVh|xJz}2^ zZFcpntY~dfAfikktMS1J4pRaCaN>!Nf`;TdsBDV5O7vqS;89@iP#Xo8%(h=>~TLDXJ#GulT6M)E=b< zH4L(|`#P*J)bwdxQA4q_oFSU$4wIwD(*EFK>(S-S(A+Yl4|~xi;t+q3A%EVu8J%_X zgBk2!A`|Ux*nOPLb_-UNn1oU92CE#n$Crn%Dg&Mw0Nwm)LJnBnmFhaL(N?xGAz9o` zqr&Jgh~UfToe=CWi7y|O4`z0{VK~ssW{tm67-_iqweA|fTHERICHaVRC6xjb+i`*R zsBw}>d`&|K6Pn+pv5HqOE&R#elvTCU6Rc}9w@+`a+$E969~zmPUKLT{fR)&tQ#dWC z4EWLTQ{Ovwvjw2O#a2vJf9MO=kEFUQ8}ZGk%HNHuw5yX3CkRS9U9b{HJxhGNk%L;3 zGpEWKUN@;G1|usCAoF_}sUp4N8U+w_Ri?l9mDcWskaQ=F!~v&L)Zu5q{(fei#1e8& zK1vBJe}(!cYmtUx{r*pl^KVki`roltCEPN4?9#@e2*=N@orWCZh3fL@Gi6(yp6sx8 zNqf%K4#-8FNtSEYboqw<_~+7C*TUAQF!IYh`OV@^&yJg=7f;uHQ+Hq|4=MEc1=b?5e;ca1Kv%W=$gFIW6DAyQ}sD)T$s%LfkOVw zWtW+X$P8@4&!e^qy=(>z9iFfeIibURL&xU~NJR-{StEXz0Y|oukeKm3)&4*(+LyAv z{Ns~ZFtZeC{*)qWR)Nj5myw#9@V7H2`dPaSiD}4Q8@8Y7CK~YNDbE`5w-%tkWrTD% z;lQK$pd*aMHVuq9=76_*D9I@P!XppRIkO3K?TCvt#_ZB{<=C;E4k&HrO!QBDj0Z7}+ZB9% zUgng(h*rAei=ii)|IGYuXXn+67ow#XNwS@;l|7?dfxTmg`nDJhasDSR;$T3ldc{l_ zR%fH~ywa=ojYkZYjtWzImyv3QehnpRKwMr?P~qzU<|v5k;yN65Xd`iUm`&XaVIf9C zbPMV+Ic=FJ=Dx)#>OoL2Zk`X*_K^Y{+nk)X|=S$qH6FtQ~MZMmV*Z?4AR zlQ9UIJ7BG|h4OhNz%ft5RFCoNVBV|;cJ9A0Z9SpDZ_7s-bj|oXbZUqD#e~H`9P@M< zvAx5Ci}TA*1NYF`=oJq$|A_hq*b4%6<(cBCKl@T3+fBM#VSaD^Y6BcRe|gtd=^b~u zVGn>_ z!ExI#6htXbD$vOdxEt4!TdK${wYVEK;1gR&4jzsmhM)iuz~BFO-_eqW6#v^LNROn; zbb{;k`uEK1MH`l7xxD(?>KAJ0*wo5U{A3N@7o{T1B~Q}u{ZTrzLrXOH7#y`hwgEK! zI2_G#R{#w^9=VzRCxC_@m%Z5*EdoVc9t2SOf0OZgM@cI5`y$hyL3$PBKSpsSS1hD|y)U&n#tpMU1 zN&#|dXKVpV0mL0T0k$dsxP2Wy9vwOXQr6*bC18R|fYNj`wE&d>DcjVuwg8O)wW(%l z0SW=0E&OtSXOMtG0FfuW0Hx{AJs!OU!V4gd2`xZv`g6~V+ybEmNMXIqdq!9R&Zd^7 z1;PrDqV(qpDL|{VGPFQQ0aDJUKYDwF6QFlWqqRUd0a99}H*yPv5@1w1Beg&n0baf7 zQ%ckYVHg2YB3E{6LI^M_jS*WQga9c@e;w`x7@fjsE#O{&6s5l&*8*6jFH#G*79gcI z{h#k|4<8S&9b%NWaVx-?)b;pmpw|{~D?o}>8Y8rTO99ffAq~M}3%C;i?I3$!5V{i} z1u6YraU}q1x;(dlD*;lJ{x-M~06kS+TfmI~DN27kTnOMLO&(jog#al^e_P-MK)vac z!&?i$3*ZqCqOL#-;4S?*kXry+0MB?47FK{L>0d!@0Z0K*4^}N67KD%jq(n$RGH?PQ zrsNFhEdVD#iqhX7C;_4^{8o@#07?Kc9vA_lrhf&s1z-diN$Gb5kJ_#!5I-LuJ^d-Y zzsH~!$_B8+df;2k1z<}59@c9CQvs~sycI|bLh}Y#VN5>)W&*HRKS~S0G=Q+d9_iCU=5>M;Kz`yB%mB*l>JEgxP8T31TtP;wP3_?>n;FN^?P9Sf{<T#!Y5_F>Ib8%$`r9y~1-jn|(meodnm2$3-j~+LS8D)rnhK!wkD=vp zhWKchutTQ+awGsb5`Y{DK#l|;M*@%|0mzw`Ww}`Igs@>*mWvvI90@?qJWbzKV7((^ zEbGkG0OUL*-})azf8KvtZhj~~Z@-8R?Pqa002ovPDHLkV1gl1yQu&G literal 0 HcmV?d00001