From 71dfde0270045d9d638a37764401b7bca1ebc717 Mon Sep 17 00:00:00 2001 From: thecozies <79979276+thecozies@users.noreply.github.com> Date: Sun, 6 Jul 2025 13:56:28 -0500 Subject: [PATCH] Refactor color usage for full theming support from one source of truth (#1) * Refactor color usage for full theming support from one source of truth * remove unused components * remove old commented out font families * override custom theme in main.cpp --- CMakeLists.txt | 2 + assets/Suplexmentary Comic NC.ttf | Bin 0 -> 118452 bytes assets/components/prompt.rml | 30 - assets/config_menu.rml | 1 - assets/config_menu/controls.rml | 4 +- assets/recomp.rcss | 531 +++++++++--------- assets/scss/styles/components/Button.scss | 28 +- .../scss/styles/components/ControlOption.scss | 8 +- assets/scss/styles/components/IconButton.scss | 28 +- .../scss/styles/components/InputConfig.scss | 2 +- .../scss/styles/components/MenuListItem.scss | 6 +- assets/scss/styles/global.scss | 14 +- assets/scss/styles/globals/_old.scss | 1 - assets/scss/styles/mixins/_typography.scss | 2 +- assets/scss/styles/vars/_colors.scss | 150 ++--- assets/scss/styles/vars/_gradients.scss | 6 +- include/recomp_ui.h | 18 +- src/main/main.cpp | 2 + src/main/theme.cpp | 88 +++ src/main/theme.h | 6 + src/ui/elements/ui_button.cpp | 109 ++-- src/ui/elements/ui_button.h | 11 +- src/ui/elements/ui_label.cpp | 4 +- src/ui/elements/ui_radio.cpp | 12 +- src/ui/elements/ui_slider.cpp | 12 +- src/ui/elements/ui_style.cpp | 39 +- src/ui/elements/ui_style.h | 12 +- src/ui/elements/ui_text_input.cpp | 2 +- src/ui/elements/ui_theme.cpp | 207 +++++++ src/ui/elements/ui_theme.h | 95 ++++ src/ui/elements/ui_toggle.cpp | 36 +- src/ui/elements/ui_types.h | 4 +- src/ui/ui_color_hack.cpp | 9 + src/ui/ui_config.cpp | 8 +- src/ui/ui_mod_details_panel.cpp | 12 +- src/ui/ui_mod_menu.cpp | 33 +- src/ui/ui_prompt.cpp | 100 +--- src/ui/ui_state.cpp | 9 +- src/ui/ui_utils.cpp | 7 +- 39 files changed, 1018 insertions(+), 630 deletions(-) create mode 100644 assets/Suplexmentary Comic NC.ttf delete mode 100644 assets/components/prompt.rml create mode 100644 src/main/theme.cpp create mode 100644 src/main/theme.h create mode 100644 src/ui/elements/ui_theme.cpp create mode 100644 src/ui/elements/ui_theme.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 921cb3a..e0ab362 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -153,6 +153,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp ${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp ${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp + ${CMAKE_SOURCE_DIR}/src/main/theme.cpp ${CMAKE_SOURCE_DIR}/src/game/input.cpp ${CMAKE_SOURCE_DIR}/src/game/controls.cpp @@ -193,6 +194,7 @@ set (SOURCES ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_span.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_text_input.cpp + ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_theme.cpp ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp ${CMAKE_SOURCE_DIR}/rsp/n_aspMain.cpp diff --git a/assets/Suplexmentary Comic NC.ttf b/assets/Suplexmentary Comic NC.ttf new file mode 100644 index 0000000000000000000000000000000000000000..65b1e6fe4f800389760d2c20a6eaa76c8a4babd1 GIT binary patch literal 118452 zcmeFadz>6qnKxdiZe3l~UDefH-PQN&O!wS-?vu<+CNoJU_Zzv9KnO`lLbwDF2!yL3 zh=Qmn$O7I`Q4tXlS$14qbXiti-j#J-UtgD9K+)HI*LCsktC0M@ `O381pSkH63U z^9ysRr%v6U^W2~3oEDfM2&QnIAPIXnZEX&|Wy7i~1c4n!@7}YH?7Qf_PsFYfgwRuh zAYFUbWtWzPNufg!;vd3s{m?~cA365X(F1~Dtj9S^&)#>*MS?4Y1@`wJ#qrqL=U;K? zTg&e^1R?p5z#jO~;e-1Q9B+T>YdH2}w9&)put&@Up4W!`w!=p*J@)>CJ>SFrR|P?p z&%f}jeK-G3_$HqB0G=-&*>~(B>7SEJaC|k+FJG|l$ie$By6AL)edR73pS$S7OD?_R zGe3S=U{7un1Z~qr7azRnF5$rc#Pzr0d`F;fMLY4-_zP!RlfM))(vQ$1eD$y1i+f`G z_)i?6c>KlaY0|ye4GSXm;vcS&?mhlHArn0&6oq2+G=3-Vn0LbU)WfcqzKY{d395g5 zP{1u>9|vxkAc<$Q+XO|B#lIA9!9}-vTlO!)pzvGWk`zTouPDgZ3BqTlh4NbL@qe3l zZP_ZI<9DL?E4;&?bT3oN{GD)mO2lXh*cJQnWMEDBvQT7a3Ptf#XwM5p>27TQ4#)0A z|69B!9zkCXeJ^1D5p3yP6Xyi}1AY%+1KZQkR5S@KgSH4Qjy8kVg>U^L8lFdegcI?HUcXq!md@|S zedsuyAKYUjU^?O3{pp9W4IF(l6+J~{9M8mtX?|Iir*p~>`TdPi=>{r7@y! zWIsa#PWU}AE*$^B$w}MG{e2pjg^k95_Oaz-_#Ey9{7CCHl?{XlJ3( zI4naW9w55^B^q!e)3<%iJC~nN^nW+nPtmSNKhf6tXhie$Oxog}QU%+4(H=*;0sGt0 zo=b@G~i!4f-UeahW!SbBAke4qvg=({X{gv zE53)(w*kM9RUX|h#a2W6Chir&_CL}77us4h`hL8V2-<9oH}J%tPse6}Z}1(BH}RhI z1ls-R{{R}j2fY(LOGm?V_;qxA5{<@iLRGj{ctChiIKc+kGPafNW5?LF?A_wu zivJ=#E}tpiE`L`3iu|nnAM#J-U&{Zt?3Av-1fEqEK7?mHglEjKEo?8IaSfjFr1%{?Ly&KiAC$i= zKP|r?zbOAg{!KYiPM7oLGJnS6S3JXB@Qed^hJa_V6DLkQf8y~Ie|6$ZC*FSI+7lO^ zIP1iQ6KhV49+zJJ`OEf8-+bxbm)`o)6)&Ct(&3j5y>#HE{m-v?e&zGC&#!oX=J`d> z_dnlw?(yf=J-7PVBhQ}u?EYu>J$u@-r#`#x+2*t9XOsW@*~-=08`Wz)9O6s`D}`0UYGIAAR#+#j7d8kRg-ya{;S^zuuvOS5Y!`M2rwTiTUBYR? z>B4T|3}KIOCcfcK!VSWkg|`Ur6z&l25k4q<0ONnJ@L}O2!pDSl*_Z{taym+#g5p6j;;zIsi(a1A*p@k zmYua-&{ucX@%ZY z|HCLZS|5UQBY1s-qdfX2Lb>^RP;R|0l*d|cdJ@WQymO3D9{+DddEz9LJAWAE$<~M9 zty6gYBuBaXCqjAp^`JcSx=@~Nz3E9P&*7c3g!24;}4^}v-Kf(>n^;0Cr5erp9tkW zuLtG5uM6dUtv5Xh%VP0(DCigWnCRz zkN1>&-q*Xj_vyZOG_%bg_g~cizW(nH{AlplP<-fz!;g#{8|@$K8M|rhdy952x@+-E z6WYXwCNExcU`m{tTl&@M2WOToYg_h}?oI7|YVUXUzOeVjy)W(4_Bs2?`+D}DyZ^HNZ`%Kk{rBv@ zZ~wz*Z9A~}!0rQw4_tcSx&yZ!yzS7nhi*A^=b?KKJ$PvD(36Mz4^JLmeR$j9y@$^~ z{M0%9=X~Pa;(7beyWqSl&%5cocc1rx^X@-?@JRj0;E|~#Yme+Wvj2kN3#Ko)`obG8 z65jCji=VpqI~Tuj@rxI~bcuGUaOuuVA3drc9Y6YkqyKu@qRSq>{Lahoz5Kyr>yPa` z_TrVit(AzvjkkZoB4v*L>pIzH7ht#{JiIU3cI07r$xc4IMW;cjL|* z54^eO&G+8)^jq$F>&~}6b@PFne|yWJx250qAIyI610OO!bjOGLKK$Ul)Av63k;#wz?4wtI^sOJg<706!SxUBeDJ`7 z7k%dZhra#L_a6GmXK#GidAR&=&%=uzUh(kehj%}G_~A<*zV6{$Key#`FMjT&N3=(r zN6L@%JhJGK6_0FwWcMS7A9>>Q#n12f`~#nV^wIH0AAR)kKfmR%s~>yxu_x#5nS1FA zd%y7GzkKmagMW3}C> zf4c$O4gPtX0dEE@;`r8QggN*kqEP9cgJ&|vx5Mx;DqzbBPH4l)ZOu9O7ZqXHjxT;p z7)I|PdIy{R1Br@VX}3)l!k>!&)vAs95;n!g@Ylyi`p}`)yu%s4dvs{f9jPQz1xDAj zE6O8AI)EBvu;;RiGdb8y&_K+;SO zUR(s8S_Ix$1RhreUR4C1Q$#p~b{X1DXm_IBhxRDilW5U1W)$I{0Q>+=JYx93z=_~uN@8HWEIu5vuzC8Bx*e_$h2)O9ORlrsMyl%kV ze*eHiY`Ex*qFHG6N!XbGYNBzDAT{Z@srmll#>jB-)nERlP{|HOjHo0t)y7%zFvsC&3zMLz!PF4&8lV;( zLn$EFApt{z!8&rzir|Mu&&c=!R$ z)Ut!wa9qocu$$z#5ebD72(8t<;Z8Ojmg-J>JDGl0vvobB#Y;+IqR@h~L)lzSVi6;+ z6-IMRPiSV|RD!NdSK4abw=iD39G5a`0@o#P6#p9ehz}zgGbj9w@b~N+L_KrZ`4T6T zNrY{PU=j!{5y5-{!xj+CB;W{!ErKCz16%-H@Zmt7&^e@Yy3kK>FW_Flbf1-gR|1{` zycY0Uz+VC!5DvkoqW@IC|1!Xr`S2Bhukc}yjOGwVFXMgMR-bfFJSUM*%+yn4bCs;3q(?PvWb+JJP#<4ZUB(83aEC_$j~%z)zEeAP!iD zwh@h#C@JHGGW0#z|1;e3VTfr$Xcr=C3V+!(xWy{mZWWGR=J(Ra1jir7aqmTGP`utb z;fWUXWDELQ3wp|j`Ugn6dh*&)lSSs@4_u>yKN?k!0fxs$h8umXL0saUKzv17JJjNs z#)#U@=J$r{P~nYgpV%PjKT-w5j*g8^uoT_ChBiVxj8nY77Nc>FZoLp509eB5Q)~n~ z-XHY+=n~e)nv5SHmRGUc!0S&j_W70oWp2ZYyJ9GuOvP9%!B~h%q9Th>&Gl8)s3|g0 z3Kh2wwPb20GuVQeJLZT{JElrb*kEDJid&kUGBctA1A{TQ*NK&^5QKn)ySV9@9kRk& zPsUT6PUk$Z9b;f{5l>>$KsLwF^MKrqUV4ch_HL_Wu|!GytS`#l?v!X+@l}mTxmb%? zENM%kWyx~Yw$+$2a?XgBiHC}IC}ikyqkkm2(iihv*n|(Ix>8C~Q&d$l44cL5c+`+} zRbxt6p3rqCp_-HjTD zrMeYO`TJBpjE-9$ zeNtM&Mn^yrQzED8qT~~Ii)4K|l6-2SU5S%BnJJ`LB%&z(x0Lh7*f780C@G#sy_?aC zk>Yk!pu|DE7m?#|9nWvaL%}LIhckzFR*^|fEfk81$+)Ro)9dPrT5?CyY1ZtnWaGB! z4j#Y8l0llP-m$0@vn46%gmqn#qS07E*OMWYF+1ukS>3Q>$z&+$Sig;%ieiOujUmdS zo-xdHTvcT?1fo)OW@MwuQl+zyaumtZBP~}YA)lr zhMq~_@e$W?MKRNFf?n}YeEBEQG}Kuks~78GN0yjmr-#@gT&_eGS1MESY(2@C7H_n7 z%e^~tNmZ6iW|^^&s)r+yRJv_?FhZ|{TZy_6%~%mriJ6&dsydLD@pvO*d#H7~xP@2Rfn!G2KjeoVtBWEh8~K;)=;kvN<@E8Q9&I9dK)_+lS;3)GNM4 z(ZtHj|H5RL>&#A@vK-c8z(zzjbX5&0VX)@kt8U&>A`w&0ha4lM%CZqciqE%=zA1hh zdCnV=kN7uFyX`=Ff(Z44AWqU$JFpG36v2TRL-1A{-wHyebMFCsj}N~e@cRMNIrowV zAb0C}G~x!&-g->f53aD0p`nM_I8nz%I*t=;0yY5`0G9!iy+&|gd=lJ;{{7g#2ZrmL z(KceAG|ZdP=e^_{awU6(8@MKU4|;FM8Mk}9=J5nKgouSa&VW$me?!DYo?=K2a?uTn zC+2e<{15s8T!1S$rDI#GhEk+Bf-cUHB5{motbwiOVa}VN7Jd_lo|hUTZWfj8^GYH{GrI`C#4c(V??SqG+*6L_-@yjce>EBr9LeH;WD z$4e8O0-ORo4tNpZMNOZNM0AqL*h7@esg#EWI1PL9*`s4lvs`76MFS-v(ce5JN^DqF z97xGjoS8j#uD1*^rnT3j?J-f6qenkB-QuqxnBpwnFtUA_ z#`fLKbjEcjuN;UKO-N=oPd9RV{~(089XEEaO}hil6>nJ=8|bf}jMHUaoMsNbxN%oeuCi4ZKbRuhYQmG|ca5;B^{!od#Z~f!Ar^ zbsBh`241Iu*JcwOoG|ieJeuvLz*KM=eQCL?eAk)oA&((37GfmKK$mZW_80aU`cu zHnJo6$z=%)k)ws9W_~CWikn`ftb1p#kv8;n(vo5kQHd8Kp8Gm-cm!ON8Ow-bR8vJa9j_EJy4#za8M9MjDi#k(A-9?B-AVFK z7{Y6fq8j1j-q==Ax)f9jsIEdg794OHtz&$vp2j>t>O0>_12LKQF@G`*5 zNaB#Rp}?t%R!8eV>%w@)P+vh0jo~JN*vbJ899@EkaFZc$QX&{n(z+Nf3P=Q;Qg77A zSe*BtpaO{maN4}6BBS)jRy-1s6-!ej&5(C>_xe$V&W_FEg5VGni%Uv=5Fs~`Q!LR= z!8Vd(den%x;}wy$VgpR9Ry1vu?>}Vng>bl5mqV--5n!s^wb9c#CvJt*{y6GIDui?3 zCD1FLB%XsE(<4Md|BxI0dwb?LDR}y7IayoE?Pt$SfNU9#C<+suY(}$8RgJq6yfh;k z)v#d{@PevjVoD7q&WzZRsH{X6FB#S}hM%T)l{U_^N9}6VN zyubgNM>Ra;kaIs8g7f~spTeO5t-z(pVDsxgjaLD&rG&-GEUH6kY*Z9SN#_IJfO9rse-rjMU_Wp!2;Ta% zAEEIStmx}lPJrBR^&MYW+T6}o5OS%*7Kd5Ry;?{W-w+~am6QzW?>ajTVa2GKc3rn` z$A+?MMZ%yM77Cl$nN52a*ZS;6y?5>S37va zGkr-KFBRIsBc2gF2#iuvYZ4fo=VL!c?2+urvek>pb2%k03>T9Hlt4CWa3o;#>%*Cd zo>UNosc-DchM`fjiJ=4iM$*uddW6zOg^KYuUo?L-8j0#R6TZSNA<%zjf5+xdIV71` zRf1nE%kiqF)f0*i(=wY#l&fQJc*AH*MnmBJJI^PPT$9DssCPYEINiqr#ZVGxWF`-z zadQq^qArqa4)8$fjWNL8pfrlqlm4Q8qQ-Imyt8m@FZTD6uHsgoZ-szn1_?Jl9Th0J zL9|t5^D%V<#;b4v=M8HfpeI8`TFMYV0nv?t?EKJ(^s!V-6yq8Q#VpROT-#wMB9MjE zXp#s^PfTyx-jUDj_~Z^Bg@^y{Tr;Xdb4g4UWf}2@P=35xS~a^Ao)SV3Of(arbUZgQ z)MOtsu@~V{lzcToq$ozB&ScJtS?N^olHT^D8D~-pwFsg_6N+luih@XjmI&qhokX$J zD8O@s?h(ae8L1}n0*xg1yM(y-DRCR>5I6bwuK|Bv{)9+gGMyHb&E`o%M!EH`QJp+}9OlPCRVrMru=kDwWF(o;GV?L?V%N(X?WA zd0Ac)eS()*dL%n}j6Kt$Y6bz4bmFC)t1H!FY9tp*ySdcRk`h8ka;#uGaA7N&B*h%y zRZe%7LWs^7c|8uNU9m%=Z!p$0=9FznT`zC-Tk)N!@jfh^FWlf`oa7|skSORv^0p2c zZ~%3yq}2}qqe0w+VEbt_oHGnK3pne;frUo>f%!-90L~%vkFMPVnBp`9?+3h}d`;jo zu)~4oSMUHKK8RX!3!V%F@DhgBm(N~c(fj{=fW;F>`2P^HSg8rJHQI-v7(WptleDBE zt8)9Ay3Y~ywROb^MdAObvaQLgrY4X@U0$!x#!?!^_e2SXm8K}jQ;AYB4%-L@2a6z< z$kdo=6vhjg%uvKg9{+2QcDrYPPhByU?4pofkV9gLwm2LHQBG(^G@f#yB0_pxhlwNW zN~+H-Eh%ODvqp?%+Eu0+W#p-l1{*y(%GkOkSN39*eY^3O;`QP=sMNi}A3^dikDy(M z_6Cd|IbCF%jiXk9wx^Q~gwcEhFdqT$1iVDN6O0hSqZpM@+=Jji%bo(*i-OG|9-S6W zKgk|tW56(iw&ZG!^ofY(LX@=xmzRDJX@rTrFcMSJ0wKr!EL_6vohgRF;{Glo4=|-z zjo;@+pUpC-_BXe?(UK7kPpz)>RTm8n<_#?ZwaYXFCXl5B*oG!c-oGL}a%qO3KisV#XMs9t#_}qymzq%&s)P79o}zs zQMK>zplKzX_HuT_?d_Ez5wp>pU07KyPj_bfx;q>rW#ro>soGXwot2}orod-fsIA9M zChvw}ig>qp5raLhChMwHY_Ell?!k1_(6w+(L%^_es!cMD?tH@0_0q(kz_cC3c9d*`g`x}&5$6FKuV6^L z*aZ(~i~-qXin73R>bhWjus=4|gOG)kZ||^1_RY+j0;Qq;zO0S9omkASlowsVzTcv7 z7KTNrg_6nq%YAF+wS0B`#?AH2ASKn{>IkSwDxUa`co*hMoq>w~_aJn0w*U3p z@kNv>-i3BLuy6!39Z1TI;Ojgu-Gj&QrDR1NLH~t-NlFp?2Ef~~eH&=`Er8#G{!ilIC(MYn~MWS6_yJLs50*GHi7m+i+ zlvF*ZaZ0Y@4>-pEYlLLNJ`p{RkEC32I;7|pSuOM*qRp_FR2EHUqlvy8NY!eu=Al1e zOVxUt_UL4}R47bd)CV;pGg*r?$C9vR8;ev)wW!83;Cx#jkDP1Ur z+dEUKM51$31z8xRUd*n`)LgY;YblK_nQ$DlJ*KIJWwlWBCwPtZu=U^*;~z4iD4;S7 zQ;y}`M94@*p{7Dkres%;@^li3_HtTHhGZ$!T~`vwfJPBeC=7SOT?wT|aY`;(YKL_| z!FBEUdyI@_*V@|Rk%Xm71`G))jUbb(>5i7lJ|UTQA}r!waBx8#`GzU0RN@7-#C_dg zh2ZYK8^6eGsZOq`WS+*L0obgq6oAtVS5^vXmyNw6{B9onFO~1CQIZrz&il% z@Zp_+cM@e_{4hAAID(;XanU^AfDkCoiXr3{28SrE$PGI`r--vDNe?>W#K69q8tCgV zqX|haXi(BlJRa9nXca|NZA+D-rv|%tFfuk+PX%pRPH!mQDx+aMZL#N&s0k# zxsu6sSc)d;@knl{+GfW`&lHy`Mm(E95U#eg+P-1^x@r=Mkx)X_qIPX#!;ULZDTdqA zHOz+3>CCyJqW)NsB5Bwo7PKMqkxVxlSuGZ3Mkb7Ki71sgZvyXc$NV;maf~C2Q1kIl zagHi*PH~PZa6E^(Mjiz3jnMIjA|BEoJK+z6L_+_sqb2O+KN3yxbSPqG_}*URLpBKw z|7*QS3I!d#m{}kH;*E%&5%l__XNf=d;jcTqHvIe1@VX;!;+y^$LdbvZWOs@s1loh> zQW7KYq79*q`1++~Ec0BvCkwrx8?g|~ZW4#wEg~zRPg)$3B2a;HIv#JURbz!Eg+w$Q zvY|3`$`-m!H`&`in2Dnp#5QeNXxNsTt zMjjG@iVK%ve=*?2K0E<kfTw|#`3MGtzOO|{n#?;Ege8&;kPEHj96N{* z)~bO5?z!yh%X)k}lVI03S5uj6VdCnEOsbgik7kOg%*0g_g>3fAEj5e?8>DVvL_z|K zf73b!*-lZR)=_WY^O^tHm~+j^O*<|j=S3oSqCA~PijwLxe9u>6S7Fd$B`L3C(Bsiy z&{v~k*TkS}u_DY%f6$R=#-PVj{-CD@{XsWl!Jzy4;)kM*Ioz8t2T_dPJP=arW8I8Y_iNQO2Lt9dQ>ZIkUa1TZsqh?9J?mlW zBghui3ovAv=v#G$%zo<)bZwwYLfqYvB@@*Z+ zw{`G5W>A0en;5G6z!sO`?laHuI_eo@o@bz)XOMZGfux;5=6MF0=NV+4XOMZGLFRb| zndcc~o@bE5mru`m*MW00>0FTj{!bLPeT8-fUgDI0r*zHxBBqy zVC;8d|DD*s9mn1U_+38yf2mG>4WbuhLEOlr6myt`OGT592{oJ?6hf{6ybc$x!-eMq zJ{R!0fNuo+Cctm<;hO;81o#u^zaQ}Z-0}peQIQ5Yw-Ak}(I9F>r{lS(5DG&c>4A-4 zQFvuco-pNJmdFLi;FRbGNV&}AuGkPa;9G>;=nF#4+!pn#to)jhASV#`)OZqE|J*YU zuEP~U?8+Ic4G+1g5*y;Y6B-^PX-@VIs{iSU#8DH>^UAs5n;5G(;whj*s^)`fi%K8Z zb+85%Q;F+ZND}Rh5c85-=}cw@i#Vu6Wz&^vu{gT9JKkT9@16C?N7jl$8LMJX*;>DYAzaUXol3b ze83rS?ONQ7*2>+>`j9n8F&LhxMMR|1Y$;JE6Brg>1Wpu%msjr|$s_zzU0iBko9|uK z2j*5gi$*e<+tgESGmK_;exRO4en^SS__Qd>u~a49C|FiD-IyJVM-*rQ9#Y@~!B`lg z*pgA{!gMv>U$)~&CdpD5^@E}vQ;y%xW7p)DeP4V|JPiKa4x4(9u)(*6f-EA%=_rRn z5mhSKAB6tgfO!+dDczvyOXSllQp@7z3qz*o^> z3EOFppZ>Yiovv)F>@MnMNmL|T<8Aij(aHX3R@V{<`}luCQ7Ymw)f7<>y5`-pRyjjH zRJl@}F7N#GcFWQ3>!F>N8dJJ z7+0V-D9@&t4n+ni0z@$R%yfJLqHr6w6oI4dDcGI@3FT7g#r8*LbPSB`{gJ{XF2@EO z54q9J$mL1Uww9y-obMQqL2xCxYeen{Or0-?TL6Klg*C&btao>)J+U~7>F;zeu z`!0S2$wO1u;ye!Xy!aOJOi+Aa^G*Y6%YfVM&|8&m9y#C$@a;7aABFE>9FQe+QVI{U z(64AE;cRj9;Z>n9po!}O569yEmfdUWkyts#N|kb18D7^!q!0hvH}+I&(dfXq>AGn% zsMt}M(skNMr8G9MamFm@n8+ZS_NJ+cP4d8=u1G^y!|dN$hOrt8>9%fL(dOE|TGcQ# zOY2(%+ewbgmTgh>CNGi_#d1YctkhDo7`JM693>HJj<&Zo+>jGibl6xFbNn@MbvEi} z&c+H2f8o*YN*o}vlt54d2#UhT1cv}qc^ko#fG3;W8dwReu7owP64t;<{@)J#{}9?` zXg8tViFO~_qi9c}`Ln84!Wvk~t$~%e<8s__IqpvI8o+C)5~PU^$`6pYVxW=iilI^5 zU^!@i8Ygml9b-UoonaaaqF5+kpXe7vfqVr_1|mruegWv;i|3%8oqT-IKSmt&Aan-) zd=2SV8%`M%sxd2PgAXLBqicKDmU^o0#By%ZaH+DfeR!(efBtZ?nKn_3kWQMI7{}Q5 z(aE7|6{>`xgeq1lguAw_TjChZ4Cxw*GGW78n$vzBV;e4f=0Y7ERxU+y2O880yGA&c zNZYk~+)gGNYo>={ZpwgmrOPxE{*)w#*#{AzS@rf+`9%fT=O~v;l!trLIWdojCkizn z{6eyk8s}<(^T)5n4Ukvch0l27oyIaEG~Qc*`Cz=$fKxy&r8x<%0VYL3=a8`3NTWmb zIT{*`%px?(ZBia|3T*}W&6|2R2lKPa9}vOCVO&fZ{1t$k7{NOBsm7;?{Z7E0KHLMC z3Wn&s8Nf5-t73FLW=joKT3%O0O)l8Ms1J_P*uzg~o#GcGVl-7RZQ3V|4EHhAk&l+e zMiPm13-wbryWDrij$b9Q3j_F*@N}($Ra;RTJ#W z>P$>7aGDeHK>xsiUvG882_A?15Am(yUPP;}1Dd^eX%PtYfF};PDj;Qm6CfA3QA}wK z*ws|^>b);FXYfJf1;88NTdrJ5wGyR~7tK$C5gwS~q<>3H8XXfCCuOLuxCMcduB7^U zO{-MNbj3|eK?HSdOIKe{v#$a(7RiljPr5HvRwBp-TB54ic6&lciX>4+~oFx6^-Vgr6J;ImIRP3NoqJAGGmTuP?jE2EE};?mD=L2f@ZL2sMI}DD3%nt zt@?u*RQfX&^Iqb}g(}ByL+F?CA}@+(iARxj{2xTe#L6_!mDk&*;iskpKb4kHO2bc0 z!%t1aiA%#zO~X%3!%t1aPff#5O~X%3!%t1aPfc?_b)m#sn7kyZl?3flz>B=ez?>~X z=upC?gg!6Hf@BQfWecmg=jq$aXH(=k$bC=a!Q6@qA z{vllA+s^EF^HZ4SNqY6WR>k^}9Q0@B&Yyw=6+#C2(fr~|#>IwT34g=!mv8Wid+Ak6 zG4Vr+iht>Mh_-*y^B6Yh3{^)Yp2p*6>``$CYB~R>Cs#TVHuG!BJHf@BkR_dvC7qBZ zoscD+kR_dvC7qBZoscD+kR_dvC7qBZoq;Urge>XAKvKb9}pbq13GU6$4BTsfENKK-9xZvlmu1OUi1oi zW1xS&JY!xS5gX&sLSaN)jRxMWs;9MhEsN5Ml(^3i-7(h}MW-l91<_7_uRK%M!y&K< zBAzy4_47=lp816{TXCS49_%uT+lIue;k&K(>W*lF@G_33EIu=h zPfp{L2@VP?D8T6%Lte0R1TCMssA3xjg+wP+zh52;|U}f_M7U#0X;-W?bm0Ot8Z`)kvv#WQ;P(qPjJ0T;C7HvJZ zh}QC1roMLM(!(P|LMS=XNl&D-JTx37g|RUF-k@P25#uSLDQU;NkTA7Go3rHDl;$7^ zgNbai64Own5D({zg>c{Ly-ROg+NvY3ty#0WimA!r1#1Ds5;3vhi;cw>E=C=D@2OoV zt%d((FvZeQHJnO@;Z>{Unab#yqpeEu;-axdB_kQ04QiXG-+1k{7!SnnPyAL~Azp#( z-a6s0yb;Mj_z=@)K%F|MQwMqojsPYiCD;ON`EVRCnf%lr$aI2T^iwi};2dB=IT?(B zTqigX5CjJWcmywf+KWIEybSOwD$l9Pg0l8rHs15YF>0O`2d@+$;Z?ASKQLq{a5G^c z8)1kLboMNOk>M#3_NHGvj1@E{;+Be<1p~uGMj(vG(UF0HgJ=89)3v3mx}mmYc+m42 z$+*<_G4X(f+6Fa(e6EO+goNv&&~E#-_O|{3WStjq4RQsz0twxmtW*ZXkrm4znLtKv zb*aG}0rLHRDE^~(0JU|8g!5R=8yQ+=nT)szo{Z)8r2w80z%y7O8f_)o4zxpPm!aK+ zb|>0>Xpf>jiRSxv0(b@lz;yyjA6hyg7-bunH-UK*jM0hbPT&k~6|90)uqv<$R>3M* zh2yJW6|90)unJbeDp&=pU=^%_Rj>+H!75kp2zkDo(;#k-$Zl(`p*Wdct- zvQWnpk9xi(Jzfz8@OZi~fcE+jvO)8_1{vth6#&0-T@IXrKfS+{%f(_~6%dckTLDNl z<2Ljs5mC?|j}4==!lg`feWY^w)m3+7 zbTk_)#@5}5EF%*;iArh6L0iv?cZ0Te3TM8Ovc|Cdr7w;D1e6t_q8d(F5l~Sbdt(6= z^?{1|0xIeQ74>15`#?o~prSrdQ6H$N4^-3#D(V9j^?{1|Kt+9^qCQX<aEJFQn#$ z*LHwfci=g@ah#sxmG$l;stTeMWS5WzSVp3VztRd}h*Q=n5PBZ8+lO93SswAslTZ=m z=bW^tYe8z(CnHhhCyq6$@S z7NV(wCK<88VFOBK?M+Lf*=YBvJ9hN=>SX<0>mbye&O|PX5Pm!nmuK$S7;krq_4azb zf7jn2N`ZnHkPpxK{{Qv=|E=}^CytA6!kX8;ut3*&ngNUFb9G43huYJi_y#DPqBY&1 z@(5Up)W!(%1Ee#_p$Zf`W!hGOaaQ>e9M6^ZC)0TZPISvB)gf;%FEObsK1BAA7nDX_ zI|)tX!>A^-C}!=5fobWDj&j*-tgjV{F=R@#aDA+n9nMc*zpNz}zmd)6vP>S?wsG^I zS*BUVYPe&#m~@=tnAn+Z*D%ix>;1#eh9lgTOAe;BwoJaWh-{MPXt(;}kG&)-&oDWf zNkaXC0qlyMDaQbWJR674S6PmzLQppy*nt%7@^D4#iHvgm(43S3;Dn?G!9hJ-81U&3 zI%nV*t>kbz_Rj=N+kM#XL*He9F9v+E4_^xSb+z=Ulz~SUMES@#V2h%!0{{=c1Y4KLsX%!lt?tWOw3~Sh?}488OH2Xn7MD&)$(pU(X+$Ba?`k zc~8InLcCf01d`c%0{)ow`C}HtGe-PD^(9nSvK0JbLS+zttl=xSdETv!aU&ObH!j!( zco*jnFPY{k0q!0E{k}6mb58v|8Z%Gy16sf_*t03d7F0ffVf^@Zkwu+I7}Eht>uQyC z4ZBciD~(OcFklC3>pMiz>2Z-~bx}!XT1H#F9O~HA)#9M*LQ#~mi|rR)d>|7?%u1`J zOVvUm-rOzXPDvD}B_b+j)1a&)zjs8_`g%s%vlZB=xxoygSxT~~h?>#X)9+%w&c1-5 zUPff^_^-i9)UeAMWX>LADKFe`0Fqr-WMkOWRc*W8{ zbiQAqSVXC#HxHbj>k|g}6j2PK5G>F6n(OMQR=ENJs=1|@rd6t4>)nnWyLNWx7iUgd zX{YP_OD5{Ic--xHt;Ky%+hZ75QAszA*uB+KAKdT0NC@z2|0qlDq&0?Cj>#giu$DD7C<*#h?lJ&?Awcs6NQ(eD3;!I{ z4y&PhtqKhJf08n$7FjBWWr7qt5-QfalSU4;`FM|Vdlgw!@T*($`-ja1L>J$oA>pDTRg zr{dp3EQn^r5Y33eot!spW4OEdG{rACe+|Ij90>f)0r;B(@HYqGZw`Ph z2jFiGz~3Bzzc~PZa{&J40Q}7X_?rXpHwU=CIe`5TvRy;&N0${bs5&2C0Xs zqO_)?B&Cda8EXhRn1ECAr`IW#q9>907CROzEuM_$Ds~uaQlVx@)Ke)LVG!H3qnPa| zh5+`udK~F=BdjV>D8G=Mlqhd2vUlNsGiiiM5#x+#VWbQP`cLo6Eh>~|W@bw13NF{n zDP-8k-ntZlw(Vcq0|)#={KjaxyXo<@eG$EVHDeF|1E zUa+(wAqGS=w6JzL2+xsB7VMM}urj*Dp&O?V6X3GeYV5q#+v7#2%nJ`pjKwK<3H`sj*vZ*2) z*5u;ynZ=2q?6J7^UCpEvkJ-8+Mf;uHXdaVx>dPyJg9X+Q zuYuEPNHV4?8agtuVJy=&!f48yPfvm>-XI>N-+)OVF~id{-eS+B2K+QNXol+p-|NOq zSl?d+J_1bvM8b|VMX#O|?1}t0tWyt%YVBM+9!oDKbc1DFJ**nh?=PM1>guwv3|-i0 z^d&dEYiXh!i%w21Tb4q_S9eed-`$PfRM(Cj-Ke7JpduMPme8l(xf8P^GimlyFk}Q% z$`g$+s-Q6Y965(%ELF=#2hW*J_PSvTY%Z*!pj{Ab2=y>(M2+XuuDRnK6EyYH=P#EX z!f#|vc=_i!EDpVx8yO@EgX}TEBIKp$)ik-#5-zla3oYS7OSllZF0_OTE#X2-xX=uHxJgzg&9S7U(fpLzniHqY1lcrLoMgVAM6Xw0(V(>f#3CYr z@vQZ)zR~#!3TGt1uY-M#-<6#zXA|*Knnp(!Kc!;|vL1o(Z5g0<9Dn9L+1$-Atruh+ zsAN5)S(d3O-(nx(JpStSO@g@5CVUUoDk{9xDwV{lrS%bloBpayWRakL0xL}V5%rdJ zL#l>5Jp@p8%=3`R#CBZvKqd-a<6<4Gn2Q%&%QiE84n%(@9>Y3?_;p7oRp_jglF_We zc##$g7qA{q+B7ooVnr}0q!XcK3T{T z2AB*zf)&6NNFvy)zvH&XpP;^<+})tIhhTDQh#cujlYl3isHCrOfjkE;@alqX9P~^c zFR>C3cm@3hTtxX!f&-tLVDBN2-Hu3EGS3QynCw1j@vT9W0TbPl9~B>IrOi;r2d5b% z%?=T9DY}_1CK8#-RMsgfk`hWMnu8fxNg(Aee!}niS1TJ=u$JJb{_*%3-%>ObV@rqv z(b^PnyGmFGL)UHCr%b##mwgXwyQ9@7qPSJpWtyf-w9Bq$KbK@IW42!CB)by)%J~uB zNU;M-|2ENxcS)laVLgE>v7El=4AxL!Ke|*rN$WsalfORiq`+a}G#?~`q((J4vetD_ z-G_B=sQ?-42gy;_C=QllrlRT*Gj2x0k*&5|4fDE6 zK6dB58?S7Kr*=uw0f(NE3G6LQg=0Ckz*CW(Og7T8RO++hHNLZ9<};~q%l;^?_r~_b z3*w}h#P6ovAiUpyI+Z$-_fO7h561LzzQoxaysUkkHD^J~0Xq`xvEv+4K|{jj+&>*c z@4(YU5s2sl9sx}GAUb;$VDjJyUJH0F;C+D40!+sH<$x~%e2EVq1$>mg9kQF`8k8{! zLeHt=1~&;lR3&o_?wvuW`cWT0Ac51lmBY;`;8 zEjzt(P0gyP#gdxEsOj;z+naLQSq@o5nqBN_`E07&&G)A)7RPFw*#uHkg;7h-hE-jn zF#W|S1c_ksN5obf*GgK5)7w}CuMp`;c6NsQc4KAQiVVX%Pw7!`cX)94RjK{wMp9_#cQ7 zZ4{8;>t#+k+u!jcp&1duP1bv`PJ*6}R2u!cdNNfirV%`lBqJOR9ZI#eJFutP zx@ZMDQ%!`egq|7hx0(21KN0sGR4b$6HNSV%O_fU{b*HZjg~O-`jJZfUhtuqoZx~oH zKn^eM$YEAZM=lbFqaU%6DE4ZTRQ3aS-dlvFKId!z&3f8=PH0CAhZI>mP*npB*Kmwt zH4}h&L>%x^z)L~fw3;GK+vi9j5~k!1H#vhce9{Pk_V;neBN!gNw;ZBCKCt&jQl>t? zil|*G*|693+DwbjLgk{4wL-9%&in+{Xk3#c6rZrhX7c&Awy6u+v3{c>YreesCHtND zE3BBcOZbRKQ*li7AVkH1kRVk?aG+lEfENQ%v|WNNr4k5U37F11{gqxk6*_tnlV)?* zaC4eXQWKVO*;KkZo zte64k?-j21se55$c)rSg4)aoX@&RlEHmUHG)|Cs~2?~@31G#Yi)E4*@<9s}J;*4!i zqhZtt_DT!DM}W^n|C!*Ac9g4oCCDT?NIZDip@3x|9yr%v1j7&326 zxhepcvGs#{2Qgj1%?x5KgJdGx>`lj`AvFeS*zSM8Ro7vgPE!CXP zyJa<0#4lu}C76g=A9L%q?g;F^m|@{p4&ZS#lw=~(U%&$Ob}?gDu~w^EK#V3v9266s z0r5*Gu4ID*cCCX1_pk@a$2>uPJW!m&u0+utvU5%D=;C98OvV*>7mC)}IZ@*2Gf#49EsTPEPC zO(0$|0WO(9ykY|JiV4IkCJ?WfK)hlC@rnt=D<*4fd0m|##ldAvpecY9GDhcZ%GPTi zh6x z_;+~cZULh7m9{hgC9{R^&Vyqod3X!n9WsR+9Y0{eeIR=K`O#^;`j9Rwax8-7+u9t| zAYl0kN_w+D_uu>F5BTpbU53CkR@8Gb4=bz}+=9t{ee!XC0p0Rb{POmQ_txH|CQNYy zab?Kjr|D3Eh2>cRRFpq1Bte6S(AUY9pLgr$r+nDtg3)ILw*P_(9Dhun6fxV`YJE(L z_zIJgi?j18xv-=>a$uxYq%n5R^O&$654|}Ulk0;~x+2~`Jdl{zxvA0I=!K)LI*i4a zg1op~c?rL1@KcNxKJAqw^*VpkV1Be-gP_EZ1^9oX|Bn81Ul6}4riB~XcJH}I`H!E` z5_ShUYY%bxHbcMIcNB8%DCF8v$hD)8Yeym1jzX>-gq3*ha5xBKuePxc*z>^m69 zzJri`2O;|oLiQbm>^lhAcM!7gAY|V`$i9P+eFq`?4np=FgzP)WW#2*Ec|Y#FA9tp= zyBIJPa}5E$iDcg~>|BXr1{Z4~^r$N8dpxg#r_k3AD~gTc^bp|hv>J0 z<6gyu7kcgR=yVu#iWMQfU$PhmoeqOehe4;qpwnT{=`iSY7<4)eIvoa`4uejIL8rr@ z(_v1h!?<%0&Z4&nxP+c~3eo9uP~B@)CS?5IC$+K7a5~N468CBHPhXQhJ%aqND(Y9$ z+<#qHzcvy5mvy#J6p(M2S0NaphV`ntf#fp;KCc3}A|V@8fv$$n&1VpDW0|XHPsx#O zg0MK8W|+t@kcmy9tX)csRWYL|5yNchp}pl)4VUL92HZ?GKeB&4!fD{;AJMXO7FOa9 zX;_s`v)5wbgL(~xY|ILW46M$L&cA&2*?KYoNr}coAaXFf&I0>iE-ya>31(%;e zZeEd=>TEtJPL5iI!{IfSkruR!k^s71J zkTv6htQm)_8HcPHhpZWgtQiLzj6>FpL)MH#){H~ej6>FpL)MH#){H~e%z0^p62!bM7@qUGO|q-; z*NS{m{INg@eWX+6*A8N`7Z65ImFYKVKXUwwANAGRl~-y}<+bCG$3F|L+Iwmb&Ch;S zAk(u4|C8M<#xd*doC~=fra+G=&|?ZHK!F}ppvM&GF$H=|fgV$!#}w!>1$s<@ z9#aB6ra+G=T#qS0vj{X3BQE4+>d&H|mI^1>GiNZi&|A zl4W_3EZdT8z{c2?0o!13SOWx%A#s2N2#^mU5J<=kFAE7FN^&okLe~wYy?H@@R>)@s%f{&d^8_hSuK`YZ82#A%@a2rFJ}vJe{F8p#*SRJlq&>FQ>hGT zz(CUNcV{M~w^fK{S;c&C_NIQeTn<}{J2%#bKmz=9BA>}^5nw)X)T(ZK9p}U0V3{uI z21DBdmX#_L?NX&xuFegbMdqQ<*v_(ZV1kp$+`t3EKWZrY@-dBZi-?B^6}wMb*YJJ7cQMJ_R7j5GmDF)_mRC15 zUUU;$+Ju%ip`}e|X%kx7gqAj;rA=sQ6I$AYmNucKO=xM;rKL@1X;abC(^FskE&PUK zqQStCDy6bg<)!BHqU3I#`@;HXQ%Q7AYH1z)n`lJAyG?yVeWIBsXxrM^jaT@XX=>IP?Z z$&-+W;8<8Z6u$6u#^_N!4XDzokmr2dffFei zzu-Ku$>Y~uH+kcSucZorrrY(6y7UY*8asFHZfYW)*uTBqErA_o7?^4aN#dN}5sCU^ zxmcO`y4Ox_JhEZ;S|vdoq>JE;%iE+;^fUZpGi&<6ZMt|E5n8U_A`u=5!?)pdJtfk~ zql9HU^%on&LdyU)R-aUCE*W;<50ZY;Ut^VIZXKZBUNNao$D^?@y*i2QN?ORDo6K4D zRDa9z&^EEXXBB0I$)(U$q;%XnyIGw_04=`j_j@O)mRx8 z5@jYKT8&C!pzN=tnKIM38*asfDC-u-5{H%-QUMlpP+DHvO;jUOAa$2kFPrDq^gBQp zRIa;=-UhNy{$Fsdq~I{yh}Ju8AQS*%+{unsI+0tX%W+}0V3+9LA4tXGW;~O#rf=@k z?Sr9}j@1#L|ES?Kw^OUF_eb+He zeSgSaSeD9M<)i&ikcy_;U zUMW6F%S@tAB&Q&2H~b^(70&PHyBh|Q^_Fu^2TkF0&oydGY(vNnpwEcx#QI>DW$unp zDzS}GHWZALj%}!Nlu-nP3;pP@rS)6g4m^ispmd0SB=kYd*|YZCtpg@5V2v=TFc9%4 z%gI`;Hk@)&qMc60wlkB*hmCX%8Bo0HPUemilM%sMCY2~ zFg1Pi65346QVtN-BdDvKNn)5_7Xjz5mE(KvTc)?|h2M4MF@hiL;Dbg=%i}&O%&|`U z$m72HZ;k&;=fs;h?&f#}$6Gkw!|^eWPjP&X!-)y@k;i@H@i|&G9`*Ir13SxuDqz=S zco0&m*5{#U4@$2)oEH@-=iMmbQPzhzFK{$jyY{TCT^sf+>$|w-F0PUFi&($NS>Mb0 zUdg1p@=3IT*tT>0A#PG{jyElEp>&p&^%CnPu~L+H(mt6IM&xs40=>v3<+x~b1cTQB zgszQI2zHDD3xlyF@lMdB(-%E4>h82E!-iD%Mxh_kEXFUpj$L&}wNfT$3(!|m>qJ55 zA(W4`GC>Nu({YDd67tidOZZ`XQHc*XB~sqcIB=evgwA}(`* zzd+Nqz{(1~dlbb_@F%zwKEV}T{@yOb-X+9iIA5JXFl$U84>xM2r}4VdQ~D^OfvHp&;1E`%q!4xwEFhH*Pyq7hcGk%M&Y z&eKR2#Ts-;mwbsL-LEk@!XL=>W%#zD+*p01T5%~ikr+U_v9FhM^A(_;)pD#^QiQ8* z8sGPs?>AnJO}^}CB$+&-JGh>skKT-W&@=3?pB)xTll2tqDRvvwi0rp=UuCbA5+=rh z5}_7_Gunl50V5J4m(~!k*JGH2R=T{WleRNP-$zTY~+aBX~S-A|AdU8nzI=N>@WI!U;7$4pa_)UPPeJNbTu?*a*SDOO%P ziE5S-JnfSTJ)hP->1mkZG@O1KPCpH&pXRdDaQbOD{WP3@8cshAr=Nz?Ps8b_T~0p@ zr=NbhMK4n^6gCrUp$QyBTk?V+xzv-&E6eC&%%-6lMeBz%j?o;+gjFpXJXTm+_aofN z)2SL<18~%zdNO0GOZ~T5V){)algkc3RzloH7zayHykGx0P19C>f z7v6>$?@ur7ZUq?hoHq93b!pjk!8~KWlvMMdXxX(+ji|^jsmo08OcQLatX&Y9thG#2 zzS%lYQcAVgd6Mfq$#tIOI!|()C%Mj(T<1xy^CZ`KlIuLlb@xfG^CZ`m%wFe?f)m}z z!+Vh5E)~~EZOM5Es_g`nDAwNwIClBNPH?#!w377=y!8gIy@R!zl$Nz9e|h~S&i4oT z{-E%r_Y~2z8UZJPR$)bi*+t-d4`D9C4sIO}YjLg0Y+Xz?Akty@k<5hAk)t8ErhxAL zRB-r9-PuxoXt&zKV-*kapWDGGm3X5_MQ13u>%rZQI-k3B4i92&)!y8U$HF0t^0{C- z)ye%GfRW%2I|k((SoB0_W_-9xx91PEI;G|5b_mrUDrLP2f|QNy4Fy`M7XKn+6;X_` zD=jcHl@tzWN06%dtjq-Sj7t-+JE3r5mjm;Q=6gWT{kYFJq1uHi&4~&f-&;0}FHtsY zvI(pm`R6)zYX7jZy;sJV4__~=igeWj;m-1Glr^qdkzy<5R+GCzYIar!dC^zTnO-!` zo1J45p-uz)W})j$CN)WvFwFr#bR^NVIswl~G@12Kwwz>RE>>^0EPHVb&=M~v{J24q z?oye`$YeF$2vIwjX0l=+0}M1krGUL5X-fQ1x>>p|5rYpf9-ME2L z1}cacTCT?Pf1z@oe2f5-x1KBSscbr_eZAlJo!+cKfvdW5SRf}ibG((~ZSZi~_cq^2 z*!moOwB6NR-s)jzHO`y5ctcQ^9!V);8bwm%{1sHmlFn30R)~kY@io>~Tc6;@9%qa3 z&RIodk{c!d_^`udvWh{uU+p?URP0QH_s-~XNm7gA>gb?dr!FJ0TaogJU1;w z$WCGUa*SoapXI8NU%-x!a-i~qr~PH^>2~?y?T!LJUT?7P@kaf)qoFxLJLFiSZtj21 zOGH--Zn;G)`K4&pkNCc#_x;RRi_basX-<1mXVA)L(8_1f%4g8ZXVA)L(8_1f%4c~0 z8MN{lwDK9W@)@-98CNTxK`Wn89{Qu)`Ha@Y;!|vJyn*9Q@|{hWPRD6}p;*EeKWA8r z`#zrJmh~yFb4|ii{Or2tvetlhu3_zJaao`EqEr=}^SzwfwhbjU9(7hyu_tb^&LD|O zK*92Zz^iow5b!0gf8#A=o~wXR#&kPwx06-S5gSqP+)ln!s2wT@!}?)tbxB2PKVOtw zme-*v6>;OVI7oCVvdm>SMOoa}jYS!jQ)yQjs9;B%yIa+rtMl2C--rc0U%YReO7K`4Z#kndjh6uoJaHm^YJaGWsDLA!84mGoFffYyLt$WKJ&RBH5~) z&IhOV=86>>{=|)UWgE=tOxX2Yf|`0%lgK9`tRYRqAdBudUq_Z>;CWPnfsp*TuKm#| zOK~@}mn9Kn$3cdlFE{!u$b)bg+T-?zE}djHmO1xwA+Nq z6uf^5-aiHJpMv*K!TYD+{ZsJ%DR}=Byno8&{ZsJ%DP@tns8M0YTlj6a@Ye|9;foSY zapU+heRG$C=logU8AOpPAwP#Bx)V)xh{2DKyqD@*dk-W*XSk3v&?yVgRyaFVhucUGQ z{Nc_*CA*{2JUG#4r1}#xr>;NRF4ZXJ492GSo?vElWjGy}{WT;&Jn0XWn>+XB^TU3w zL&~OD9fUxX)~biDyS`7i17=OO=K8%ts#!^Ai}CVSAw{t(6(rr6VK>mKRQt?s&1OT5 zb~IKjwl=FHS9EaWT&>n_?K~Q%JxwuFI?(TSL;aS`$R8Rn1AryX9kk5{DSj$u=)ND0 zPA{+60PPC%x7^sTPUg!cTnS*Y<*9agv(s$({hijeSSXx|S(#ed-m(8kr?Zo(3y)gTdfv2XggLiBxk8xmPlyZs zS?qJy*DV$Ul+LfrC#}i#>M&oesUFmUU?@VGJ{(RnRwkE2-Y`SVNSS^5&|l@dhnadW z^C~`Pp)i?bwW&ZC#LS?!y-?d;&fmaV>maUSeHYYvH?Q3-l<24t8P+IIcv+%2qwI>C zg@q*aQeX{=JScoqE~a1b5z-<;VvW!lDukZtL=qrQm&^vC@RlKNQz&e_olY%ml+4oM zGn;M_rqV1nWAVZS8N;<&+cdg+W`lGEZO;@N{cN?AYBws!nAwgx;Q1s{wQ4>uQ;l(S zPy_x{IhBsZD)aAP|9PD_vbh#Z#5(i{qk@)^JUlouif*>1n*w>1$(lx;@w~;kUL=|; zwzpQ2l;ncox8D)X#hIau;e)q9csW2hSB&wfxJLfUF5=bv3K?mxVotuH`TJ(m*D>zp z`S^`{jl+DGc>&KyGdw~(?c>_AsW}#<)YFvN{IZs}6Uf^MSKdw_Zzqtq6Uf^MNu42Y zCy=)j$lD3z?F9060(m=uyq!SaPAGXRw&WytloXNNeNLpB&P7`Hm2t>=SecJa+e5QYU&GbvMYixov ze$k=M|7gwh`DfBh??=OlWAaRz>HT~Zm+!AsOUZlQ!^eLQA79qr#rnHge~$GNte^Pz z(^yRTBE&rAu?i*9P=~@J&lG|pRp3NxKi3G>bMtsNos+nfFQ?Dyzpu8s@YjT?_O)DZ z7gRRAZL$T%0Y%K-)xBadne2AaMKt3JmF#5MN-#;zBKV(4hl($vef;j`=8B!fd9Eh& zG@APNRaO^%j4_#J(9MAN4jw$zOHoQkvjIe?nTpO-V)@|8Bh^mp*fEIa%=;~L}7%}*i&k9m{7HR9eyf}bN~dQj1`q|OffuIMAjbMYLN zQ8GcS5)Hu@t0nB(Ly}=Y+oYsvwB%~G3AG~okjz*Z;p8-RW z0{(E@YC6^HEG9##FkMfp<(j`i$AKs*{8%JbYoyAd=~?hpuT^4;v-wIg5%b%tc5A+d z?-HG(w*{$(nV~%~%V^@{4^mBI1XAI!kxoT2(P+dDMWQkUF&y^m{b07AWxgNXea81m ztra?|rHM8!U7J}9N*CQI>lQ31M&~kX*H)IbE3ss~$Te=06CGDT2e?QT@kgX8%S@Yo$W~;ahYr+fv7-pv(iMSI{%C$NW{eB=k7Jdo^rmp?!_j{Tv=)E=Q z==CRz|JVEup5VGXL3Ua2EUO%&c%kIcZc)2jVh0QCoGBBr*p6=F(B zC>i>7oB`5~qrFi!)wpG@JH9Cuy{ef&Sm1H2l3*?w35S9>;)Fsca=p21wo;uroQenH zJB|;Gn*FEF9(@*^n@k;x+m(HQrMFJi1Utdt4H=<#a|F0bOul@p6P)mx`eOs%<&$B#|3oP z3B}f>3nGd~JS#6Os~)gxDG>^d#Z#$rIbMnv78p$)PZC0?Byb4!Z95d4URtJ6oS_oFO0{oi9!w(#@fu9orP(u(>2jC`G7y*rT{b*wC`EKaKU`@DIxS@%7nyFUq{ z=H;-E%E_H20&tcHz*!;yXVDjDi2$4>0&tcHz*!;yXNdruB?54k2*6qFqqA-V;4Be< zvnu-M<8EgOy=k(N8BzB@iq4EE-Cs(Ze=mVf9^iNg8o8B##*B*B-Q%p-1yL?)BY5DV za5T+0ddZta<6Y$d{}GK`@1E5WIIoQ(cm-bcV3e|U<-;ETNiP&j9TGNls9Gr%!jan2 zWGckmQOZ$3s+5>1$P^JuzT;_Z2YLt5r7`4=vbCyp%QTXfC2jL!`FJvA*=dFkmGGyD zyt}fMuvpsoznxIg(RWjM0~?_ znJ;1_xN~lU32cFW;(=8W zcFW;(=B1z^cjvlV&qh2p37?-o$s;*-o%NBbL0BFYo6NEi6%G zT}g9}e8aTT6Z^Q($D2jw$-2c2-C~CpKWpu*y>%^M5Kd(IJUUs+XmfWAXf93f(GH%` z1c_=TgUe5?%=;(!X%Vu7oM-ryxZ^~E>??m^=k^R+5g`jI=s=|PV*3EaX zR~hE9a>s>Uskllsrn*LKwq95>9~)B)-*@3>KI%OBPZ%eD2#e~gFL!?aeba)Xwrn} zvX43<0>^qr1{#+*dB3alE65BKojAu*L!DmVMGK)Qz=dX*{xhj#lC{wBI zLSv$ocKFTr8Qfv>8oQCMO4j7AxY*Z?M4|%Fh;sq7{qgbl388 zDHVE<>a(ygH>M$s3=>1+SS~8=D+LqAVWMl)ZKWf{8cp60OtqS^SaW}Efe5Iz-Om-Q zRH`sjGyvx?-=WYj%C$DrjZ)!aAyvUx44Ef_Ajs)Hl9_HKCL5h8Ad_Y+)22qGQ0VV3 zK+$I8Av`_gdWk0dGGc;Fq@FU!0Qg{7$d8h*p~tG@G)EzjMxqO^T+ zj-0}b&s6rrZ#XL?`iQxe4XNcawt%zHc7dA?a`OR-5u_U=(m@07)^N@|uApnS^M3BW z?#Vxr3**(9YEG!zOL?V5BQ>-sB@W zn?WQ3E)tk`knV^A1g9agG@oze=;AlV$No;EF`&FH$hJA7Ac8q2K}2agld$Zs{-!50 zQ}tRU8ObHsAEYu!P9y})uI(|6myO#K=2xh}r@D?jgN+?U%i!i_Jsu55rBXgwH)$$7 zdFtd1T@2`0qG;yJH2hvJFVg)IJnGdG%d`k%hB!BmnC%O%C({tML!ksul;ZmqeZ~3X zJ;h;w({aR$T?$s3iFCPBUMy>nV`sYySJieb4)63tJEfv|8hsOl_Qxspu&iLUQ4K8I zzU16x{hrl?S0{{X-5X)El8%wcn>oFALI*5rS|Ubq;2{nkY=SqRd>N@-uUR zj@XXb@E^efdGaXbC|SNN14x)TQjdiEwR*E&EiF%t7$L~KL4PvKgb6!`1t@jL@ld?n z$|nH#AOt@Bb+drO11s>r^}Y}J{?7L+ng_PkP@8kUKl451^1?Q}unjM4!wcK+!Zy6H z4KHlN3)}F*HoUM6FKojL+wj7+%M07^!nWdtCU=$Ap319u3LW;8tHYi`hdqT3dkP)) z6guoFbl6kqu&2;rPoc4%!mD@+9rhGD>?w5EQ`{W=aRLQ(6US>fUI)iCY0Gp%>5pG? zR$?2e00nZ{i(br`(#V^hpC|`{>7IngY;bhMD7GZfcXWjlWA*SYaZA zRvBIYI`8}!;LXwbgWmajnC&t;Kf3?teShHlMHPqmGyh+j*AVCVCao#qKj~KU0{CtU znIHj)SMrz2_g$)fkJr#zCslOsKAQD6a52aaOdQU_d31OhtykK2*x~;`%Hu zYI_!7+w#kdY;E9;p+uG5v@a$5t`GaF@mQ+V%2I9 zz=Xgs_$$5B@)sLS3QO6!SiFVlY9#x|Cb{$QI_;C2kK(^Q;?4TeKDiV)9pGs*4dW6s zxGynx{iS8E+H|)-)lEn0%@h|6`Aefz*1IhD@W<@#HThUuAOOj zlgY(hRbR%ln5`Iv;{T1_=;`zSjdAvW(lX6~o zQlEdw_bX%Ph3ED8C+Imax?Xr&pTEcVlg{}s8J|-3pK|X1{;~6Ne|`QT=1%JSe2I?6 zk8&4%{t2QY&Ux-5_t)p|!ME2k;w$D~F&FAO-&U}t|l1{r8CUp}NvbJDYDXfxp znzcaxWbLNhWS!%@1OjD!i1i_7eVFxOXYCe-+{ZOHabC;;S-U7US!*Z{@=7u%Zby?6 zYrzg{bejywzFYmFck>1}(s+io`$x-pS1L7G--M%l;}Ij{S-9$&gD9CFkgg8?X4Cw&j%BYlBBzbNwA$0^AA$5n_lz5sm+?0w` z;?cVyRkdj)$lRi-lT$bJ3;kTWTFlc=A9G=1WlwA2{+0ZE$)delDKDdQ>Uzx)Nw?B}G@fqOqf;l2Zsy{Kg|p@-{RMb5lAHLOkq#bCPEN&mAyuVKwrJiY zgT>;}G*isFeaaB>gTs55)5QY8d67H}%mckeATBm_{gm-Hj7RGp#Hky}Cx4wGW_Y(D zGn#F!%#^BTt(1&YyMfCb2EGm{E8by#yI=I&yrS(dAh8s!`hYblnqSZ~ZyX;xFEp>u zKV)1zc3yZ&pML`Lb#x!Ozdrv3-n)J@pIfwPlf}nikv`h7zq8%T=VQ`dX)_&iY}e?8RWHL@-&R zX<2cp?!uS5yK2dbm8@H_0OFHYTj@|n8c%2J$&B4h#gc_#%afrChgzwIOgPL<-OZEr zAM>XY7JWlHzy__5T}x%`)@IoQA=eL1P}!c$$HFuZFhZ$7D$ZoAVm@6?Su{qls`F`2 zW)_c5r|RI$Vx{JN0HJwS;-6o~vy;wUFQa1QPVr6PVu=>{u{!RhpS`v={Jtq=T^xrG zU28$sl4iJM)a2aPuN-^$(1Kfpd}PW#lZ$}wEHyZVZ^Kw#kJx-2bK9Cw^NsE_4fsBJj7de zv7gRX=+bN?zxUhNa&nTH1hWH@WUyRNAZ!BC+KS8`?@+c86_+p^wJQ6LKW}Gy+V1wU zZR3-T{r#vN=^vORLR84d;*DJA@V+JHj|9K^)p#?PswG>S?fF}dti}|#rr)T|iT=TE z*iNM8SF0&29(&hMbofIgN>wdnDQKAnU0id^+cwZ36(01(!%u{6A+WX zbHL2?TETSFKK`L=CI5vqs4r}GN~L(b_xF)Rpt4rI>Mh%W((Iv?RDtGMiQ+(b*~e^H z#j|UgXMKO-@S2<#p4I0c65G_fUU*iYe}X4EIxoDb&)?(wpgu2i{M3DRsrx_V`yY<} z`jUBv`6%;~&iZ~+d&1K=m7>2yYmjde}eUQFW|PopEJ`7P6U#?#R2wC`?? zS8%+A<2@W70eH z43u6`G{3@Imw2n>@2_I*7R|`|Am^p9{6^NAFOWB2P#9z?WGi;@7=05bbwZ_zwzWp6HJ>8IF`U*8m(oFY)#E>I=YKE7&=FJ$C#gyN)Qj%;n=$(bNI#x4dn)YPB z9o^oM&$i0LdE%VAk6e4WRBriKvN%3cRA81A8x+3Hj!B$y1NP zu@v0wm%OgS(mW0xt1c`Ldk=VZndTBYdWVV;@iU-`1zY-Cyxe6lRmmq?^ZOUL=0)rex5gF98kbK7#i<>c0{Mm3YmWu9s z$%`Li_m!Q%94-GWGGUt&_|?Ae_ub{4-{YNs$Ow4nkNKtIS*{QHp7^Fm#_m&bt`GUX zaOAGhdGn9F``iOfT<-p#_x+&nE~Vps+5fZV(D$vr|Kj^u-%mI?&dt+i;r)-G>4fKh z$oCWKdx`Hqq5Ia{gN+ z*T(mEaqeB5lY4xW^+%o8f0Xr)I_poe{v_)k;+mgf{WH)m@<3#X^07UerBKvXi%y9+ zRIF5`TuU|96%LAl&b@by4R72 zm|0>5N+l*&7MNKV4ty?>2(~(rMx(Q@A#K26k}_={{PjkwnyecePa9NYyk2YP=5(tN zO~_=`R=YYV4{2F>nUOSCGSvp_ArY@NnSWC)w$kJ{n>#aWwSs93HZTJLv4+F`3xAoM zugCGc%PEEh)6zVUWR^=P6b&SdeV2~CQM|M!^S0mtnKBsiy`uV04sS54Nb%l5hxdNj z;SD)2yr<7U0+F@60#zE8kQf|dEQ?=Sqb;Q8m>`Mes^ zkIcQaYoW+rnN&Q&D~+HbezEqn@V#Vu->L^T@}y?bc&34VmzhHG^UpluPyhW!*}sRs zfAwkeGel>I&pP@Xm;c+J9fh{>^uPbRo)wt(^v~cgKRZ;-`5eE-bITG39B2)C+23Y4D8%mNfK{Rlt*2tWTAKmR!EA9vQDVp@dixS{PDWzQha`2x7KOomr!B1JX=>_Xl< zm@ZL9PI5;qS?#Zx%BqzBOv-?qDDheiuj7WP?r$!DQ)>%urq!8ilko>YcOpIXZ=3Ve z*K67VjX9A_@Y`Y{%WqyY8U;EDQz8XUp0-Cg+o>k)HUa&b;8W>F%lP#qIr(&<8I2Z7 z?X99!in@MYG)IIvl`Bz|Wki_fP0Al*3&R*gs2E8Tgv}Q_Y34@t_GKsiOh!J`&o7oE z`9ir^-YSOM`A%i|tpq~@!7$Q3Fj$z4(wQV`SyhrEiTJRTVsvmUT3Roba#7=h4BVt4 zE}8pGq-tZ0OM$WaeS|f`RyxagH5y&y5_Ti*dV=wamFXAid-k>Ma+%WN0>4TJllUuf z{&5qBR2e6MJEIuPbY^0P+;MN}P)^)d!c(#I;;vq^ws7IEl6*`*API7_IJet3zf0+O84mV_nhRs)Mxp=$-KpUA%I8eUU)THO?!r*wtPD{HkG1(*Rnm;^uRgATB1H2A5amtauiXHp>)3HGeb7c zwoUU;W9q;pckGOM!zjcKCBQE9hmo|k#6?3a0Ck!lx-@5*fPs?D^hIMW>QjDNoqKSb z>Q*bYYyP4c7iK6Cz8H6t2!wivx*&4k@VP@nzd1NL))R)=vY|0JPq9EB--~8p;D#HD z59wX4_)YxakZ<3s96n(_)juhlPR@sY4*~qrevq6Oe$&@KksiBV@s&P*&&}?6`lPD+ z-0Ixt_q44iGdRq@^z8*I;PfOJQrs)-B&EG>2!H6Y7R4p3XJ9j7N4aJv>z%CS{Gm%{ z1#0uO@f%%F^Czp;MN=6rp1DESiP4x2<0#WfpFV-Z{IC-_ z`3LGFn8$z@ox1$UjrgUrI((NM!J%kFdfbYgF3&FHyXOv(l`^~R%gpi0i=94h9qK-F z{~B|=o^IPXzxN-_&zjPj;aBzV9a4BF6muz+#Ce=?hcetum0V+U-geIGN3P%NqJrfb z7Zoh)X|9*XG{;!G!8lo8&H1aH^G8@qA3ZsL59@oJ^;y5|jL(VS>LT3umu{xr#-)sHH`Z1c7hm`yNAFDCFx5HM-CS8xY1c|6ZN&gyoBmKe zL)eHuBN1lDq$NfeGw-6)DJ>9aU=oT4vc)2>+bsXWH0F1@mzuH2(TTpF`ioH#Tj4^a zi$RqT-(ozPvIts<`x=X;t5_mLqk{oLg8OXrO|i43>F}SyCjSk+9*=5zDAN{PwzbT* zPP6|O-&bYtM>Pr3MZhT~|ezIF*t%gRNFHZ&y7#{hYRJh!l zh>?Z|C2x24k6I7qr}85Yt-fCO9M9_NpZi163zzQXk@Tz_fs`8el~b6(!_xJD5_PVDq?y!pr3t;g}*A4dl~?z@}g6&!Ejcn`pNJ#gSGr6A7uSOXZ<18ACgGAiz}BpH;IqS zpD9&{5snx~g2Un|-iCG(`MyH|)6aoxxK@#Y#Kcy)nRsotvA%)z4bJ)`>yysF5U+=8nz*>4P3E2q{``!HfZhn3rKfjmt zd$A8S!bRCILT9?WurR3`+x3VHql&fsh{d!#hH(kyM?ZAA3S_7Je~&qWya@roIYsqLss;5&a3c-!6BP}lczD&Z?Nanw#J|tC7b+77H3wELEoF(dI z+pXe4DbY-YarEb`Qan~|G?MXbC>^yc`Fyg_r882vUOG6)DrOWY$l)UH_Bz)AGkIjNm~VLeyK?NZCFzAY^T*ApLgZ05_&VbeKDhYnod)w97RymGOfEDu>h4xH#LIR$z1$W)%-muW>K+CnZi zf9?vyqJ=8sPW{g?+AXI>z!ADHEL5H${CeS+Mz-@6^i?#{PYa)3(VXw>Y=!c`%MOY& z)j&DOqOm}+=w%|VJH{;N=j^KZfr~voB z@Vy$`?Ax_2+$QNRx==zg8HA6hz-`v+tVM`sSj(jHm+;-SRpiMv9zRIZKLKkWC z^-e5**}vYza(`GTUHwM~NynrSr&G%==?1mRc{R=4Pavt7%@1DpjZZXB`u+Lgp4mvs z0*_0zpub8F=3u8>8>T6bh$rI8Skc4IcQRnYc)>R~@BCvo_HMp*&5sclB6%Oo#Nv@i zw#5`=(?}%en&8@i; zjOL_7Bt*|#Q51Hp_U<`DuD^4|0aodg@sGy4&0q4(;a#~E*rVL3ZZav|w@0yjTq_AG zIC2l?YaBG=XIz6hffVb2?oP#%fj~NGl1rgnvoKv?EIY-ChKGYmtn6O1ax05HqaaqK z`OW!$jJY-?GRXc!C6+8F2&?goJ#@$<*=kvJWB@c_CVg*Fefr!T7CI1Eo-n?2$cV@e zUnVAfY3DujHJ1d0xW7EZ&l|T;L*D`7UvzfD#Y5>1>vDHE((#Hl;@)FcwI>wyDXbf@ zUS$Bu<>JTmFEG5#>;Van%#H!_)EXuy$E;EQNobCieejqS#f(&`1@G}(;g{+ck zeleOgD|MS$2KB|31iG5_w(0L3$frQvM&5*-KrD<-Gyu$LkqX*Y`L4P~wdGNw?32`G zio>X5`rwE}kLm#QD37GTt1#2K-ek3yr2s4igf5oLB%-lwsg$HtDVmCXHkvL?GzxYo zn3sX1)tt>-I(o`vja(w4=;^PFC(KWcae_n`-PtkPM--lQ+&2lE`In_To!Tj_xi8vc z)VO85!V798%8gDg)9tjS?QU zb*fV$wRj|>p8fBz`O-gusV&a4cfDCRGm_=cT-C~W8k^7Q@@74G~Z2C^FiO2XxqG+@khn%dLIc!in6X z_GJsk*rN7ji-6V^DgP~i_FL4xY*G8NMeWNLfc`CNU$$_HM)9pfXxtPUH^p{^(8gQ* zyv+Am&dqX8e%@d$&{tWzFacTb=lp)oFSEW{>Tq>@TDpu#a{(Qrt`VgcGa$`Hu4^dk zEN_-)=3_m@ddgYrUrd$;(KYgJS&iy!uqGV}WN220CU{b#EDWubGy)K3Mut=vzn^q>I0=d)2GnF%)Yz*o+bm9sD2+bKru1(s95e5k0 zc-l<28?ouMWj3;(av#knjG*4@zowzW_p+w~m6Dk8Yd``>yzmcI4Z^)BDit}A&nq6O zS3Q8Z3$wi*S<&lP4}NehJS`~3DhV{P>6>1;Nys5GKifLSEkgV^3h3|lcuV?)}kp+Sqln~_+ zWWgl$0Mp2TNnUJmVT<#!?y{B`i>&*s#bW#p)^BC~R%iV-)^BsxZtzB~`F75KyL0}X ztlx>OUze5~A_Sb2zcPa`j5-7K7q*f73@5-is8{{y_`hc(2o@1_z#I5-=tKe}@_1Jq zkfK~aEj1)$fPw4kF^g_APG|ywM5tZS*EgFoHMlhPuJnThe)nPfZ= z3xSrS{9D`zT++M@gh|k+fH@?gbfjE}#p3a7*RC(LnLuDB)0snqM61zFQ#xS#iM0d* z9or72v0BBT4Np&HDw()Hnap6^@hathHhMM2%`^Cgy)#s zZ25+YGQ}0?3k8a);93cSFmNk3wxP%>IT@kIJy4SLyb@=00xFWo*^uu;u9vl&?vd+O zIWLxltaq^9;jFcK#AeeX!3m`;LuDhCH72*A9A5Gyjia}CFCwTD8pUuct5wGTKHt$; zM$r)(*9Y^#%BtJ zo`#m6Qr{ywX}m6nX9s5EHRe6OYka5mv!f1IZC{10D6tjFMQ5$s=x9HGFX#8NMdI^c z#ri5|eUSA*@$V&iI*PDjsf`%%lKmkUAq?kim3NtAyJ?P=#{7y?H4}cx*|(D)JLzm3 zt{J$8LZx=s&T6I6*fAjOP|5oPwq0sxvZ+*OGh47wIyI^YT6yD7yv;K~_}Z~pIFe~% zC78YLOs_k4^VICVIBmaX?QFnbY%^D_3S2leQE40*3?|DI!~`TTCz!G?`L8n{U{K9F zeZGrZ&q!QMVQn3fQEnSLWF&>8c34`WDQ8qXyisEaO>9bY_XpSke0r1?U(Auy-GRk| zg3Q<+nGmP0@MK;$H1f40G+$5BNLs06dYwdL{#g7qjZQpP$brfgh)JW7NHm(6TB@_k z$kC#o`BDDX;XyW+%MAxK;)zAA2<;(^9xOQ3qp6SGZCLZh$3#3B9q=Bw$P=9=%8H^} zYDEh9XdxN*Ja|ymk>SEjqJK?4L#Ae8A`eCk3yiUG)OZw%^EGMb>CZA5rPu1jCVRnD zGGSJDo(M3^mg*~Be*F!-F3Itev!~}y9;qafMkg~fKZ6rT)j=d8;NF1UWgH6aR4}U5 zbNOrkcbE^;&G{_iNo*c+VK!ITj|tp3u1YG=bR+==PvrQQ&2!kNXRgFPm7S68 z)GAdOsj3{_wbd2$Uvu`?VUE`Ai4*-;g2u-2eApStJ?gTC&)wPX6o&~z zd{Y@3O{UPFO3wjtwE{ zOgJ2ikvpZXAz!F~ZJn5?l?@rS}WZu&J-7&9k~@e7X*^cha-)0W25oj z_d3+{-uJf3%}_^J5sMqRmHTFghKsQ{!U3c2!F{EJXIk`5HI&M6_bW;bi8N z<%ZR#BSc!tD*4Rz=U3K6cdtqg17x_EkhGIrQKc98l@o{-DwXEXEXNzIbSxSS(y=?- zwT9O%h75Y@FeN@WkvaXz)48dN7cRjF6MjTwMlwBn*54y0OTGD6_BJ9}F6g^GF2|D3hQWvGTD2_2B^;I>_jXD&#!ILGfSm6rE8_QZ!A5(najm3F_ z@7MCPe0OWBikLP7o5vt5y|%8UrbC;~H#`rbRJs>;R=(q>67*HbwmIe3=w~KUmpI8v ze{X^6UBk*JB4K7V#dg1Z=hBU>2wBAG)><-ZhT63QM~_crGl_Dgvifu7N_o(?Qa6?t z=Bs69RNr?pcJP+lI>f4zt#+Z1FU=1CLlhG^G(yyFaw^`BClY(7?d3*3 zAB(k`mFZ4V!%U5`VSGOX&J6OBJ=^)&LY)?7-z7Av@|!VYe4%%SIFQiWbhR-NQn%-LIz(UgRhXmSIFQiWbhR-_zD?(g^cSfWbhRT zCKCG+V?WK-tKc;29P6A|q!K&Sxc+lww^ICitWuGt>m&QUoy)3LqgpZ$Q#VV@KrmkI z5c!248IL3dC^ha!k|Tm0T=?llS7^TJYdUxK7V|gFN66d0!?O^{f{W01TH{jB<+M%G z*?4W|s=kv-&^HV`Td_N|nnjM~b=MhAt&16>j7C@GqDNHDUt&N)Ve;{u67W^AQI!1a zA_SD$xG$fk?kdAnbo2s^BnKsW+2A%x%P@(VVO$aa&SWNfnQI3Fnx3Yy7IEvS@6tv%Y=C#H%6V z9_dXNs8B_XgsdQz{M=lzc+~+r?YBse2T6{J)snE7#-7XeW^SIDJvFWLRxns^nyrqb zrmU*!qE}h|uUNaq>0-0dnwu-F6=#r%W@xb1?N0A{;C-lOMUTYokPjz)KdkAoL=mOP zh8v+6O^^6JtX+(YtlfZyTqDeVtx%QDedzeU_>AI?hg7Q?K1+~%U!DFkc|BqZzryjxsZGhNV1(6{j z!j?Ip$CLxJc%@70ul5@+b=M#Fa29K4*PN4k_qJQD_6TJWx01@sFq^F@aSfgo8$kxe z^SadY5yJ3C6AP=0mLMM{<}pD~wXP};m8Um{@h z!Z2FbDVeHNx;FWpeUQ2kjk40bE;mzQLlynuHTAN7P1x1Bxd`DPYhGOohVm<~1ZP&w z1kxG%z>PO`{eYTB)|3^=_Hvt#?1_*q3>r2Si0KGim5J6G_2}H`*{yHc^2U934MfcJ$&`vY{uT&>lkFTje$pIPfZaVf{W?znTk3ATm46iG zAAGUk6VPY_%@?pS-HxPV5xU&75?K4DH?d)^nNx6dUp1;{;TnX1y> zop7PEgpQFt3YQnedo!i=hS+#$WhA3K?NLBSMG-CIqfVIN`TzC#xuj`V8p(-+1&~Og zaH@OfgB!)dL}%&wQ*Ma7aD1Uqs8*M5J&+h1uuL#@fvyZb&LkP-o}sw(7M` zXH)xW;*Uu$EbWgy>H9G!FM$7M-b)PN16sxlaLC5xfSqvwJL3R$#sTb%1K1e{ zurm%|XBm0iLlKE<4WjB7k zkuulBQ9LS09Zitq(Xi);cm07E@1n;$PLfBb64tuxalLA0oSai0twqvdf3aE*~Phe2DDwA+pPd z$SxluyL<>Xkl_#de)_k_@V?#rwiioOew^-gjfDLApl^|1FK={L&vRDeoedyksF8t5Y6HtQmow21(#RH_ zjk#Ez%?G1X+x`0fc7d+nWjfbJ10JCehGY22?p~zY?q!f>h~rG9ShS*}Uh>^QJP7mT`%Xlz}=|~Ev z!=bSq=lC2Y*a1v{5P&kB3jvc0wf*jB_^~YhBtos5@s5 z`U^KV+~z~ZXG$wO8*~Op$HHTMf>QazQ(d4{gRVnFu_5-gxV})Bs7?Uh{;2MjmRwhr58)q{I2FMx(QRABA>~lH_Wuz zTjrPwo+zoh@X(AyPRHJJO>?ukBNols2nNJS0AQdQkH_k*R3(#nZFX3lJ3a4Q{7tW1 zKXZn@`bLZQT=O3IUUE$r%r}}J^39T|J1TT`j7{B$;66K zbaF+8Wi-~!VP%3b_6a{7%l$?sZ}+PCrBb8^Lbj2jzAP8{R%e@xe+~qH*9aub`A~wn z0tOh(ax2Xutms1HLT(pCq2fxFuw-XWV*M$JqjEr=W6UQJ7vPH9O=`N4&#%MyvV|j% zi1`AqG1|o_k>_eI`5e#?<9~Tw(MH&i=jbH)Y?u(OQ+x)rbr>9~Ls>FCW?CefmeN|( z3+0G$A#gImedgKA0x>-yK@tB_6eZv1_&zuC&$NK*Y|?Gz5|q=J=OMYyodq1*XMibr zlq2~b<9CQrUKVV0;l(a#d_vC*At%GUvDc3KLc;jEI7Nv*9-E?Md>w6jj6w$p36Ygb zqF_;YwuuvrTNcUbR@P{v6n?psEY@0{TA~eke6m!nrc?2Fc`*;l6T)|!?i16GS5|J= z%;v0Qx0!EOE0&kUj%VY=9gG04R_o;;1NjUSfR@qR)8gV(cQAF86w33@JmlEyxtT(7 zI$KTyZpBn76m!bWN@M;;bZ`7Pv*#zL?pnI-hP~5b+eE{;ay{kcyW@2lKJ!^*9v1Py ziK%KWWtFIYG5pc!#8i0|v@i_ zwq|F`r9xp$GShRQeeCKDo5qr+84cRY`=@%-ZHAGU(Nrjx%VujkJ9T?*d9`dB_fxDh zOP_+goo&W}QTU_79oyzEXLl>fq(4#0S34c5nU3yTP4P5L2-2awmdsZ-g8BABE1iwd z7&AMOUcagr3SRgbbSu9vh^(vEt9CYOE-y#tw-%SIojVz(P_KvV3=QgYw1aSLy|0+x zLeJDAo(yv_FA{f@4mFpSVtV}{p=k&iS+0X*E@oV7Jl!x%nF>O#JO#x3D@Rku>c=PR zjn%vQZgi{n!sS+X>Quj+HM4?m&raPwTgxYf{>PxrW zXw>HY%k_G9Pd{&@;x?lw3d5_w1FYOL>4ltT9^84Lb(QnE-)Mdqn!1miDXqx*1S7<9 z(SNGY$~T@eg_1(*<6jgwN0D_x#{bDDfnIg@cX#g0W&8baD1Yjo!YCLs2n@Rw^kWK0 zGUXe~qDF?59rd!2%4F(+wmXzQHYiWLKrk#-t zGABr7;?RVM_DCey@Y5xN^DqU{L{1oHJ|Od}J*iFt*&i9+y%t(tSedM342C97Im|X_ zmvX7t9gFhs>Rk@?wn{qlZ@j-G9{^-*4mu6-a6s%Nd=Msr-Xa2Uicz+??|uGrWpm;VGfh9 zua#O}O(wVBw6CzHY|{t){}+4sPT#xXSp5+%`&q>>UmGb{q0*=Cu+)lP+4hQ3@a`rg z>u6tRZ$(Oojk=g$Up4<=ZLQP3`P9>PDfW!pPt`)@nKz#q!jS7Xs zzz#*37wy%m6a0LJCt}8oFyjTE>v1esDuHCOo=jx3?M+f-jEu^LB1v2I(uwC{lFc)c z>bd;A`Pak>b`k{zaqgt;T;Hgk0?qE!qsJ|#%GB8 zn6V0ZX{_DtmW0o%r9Ye*$Xe?fsy!=jTpHpxoFJmtcf89IzOvsV1XNR5{FLI@OaCwA?miyX2 zq;9}bklJ2C6$(rS4iTM6l-Xk&lqQ9s;_ZnsqOckw%%$7K7QjwVv}p%gV~zyQp;Gel zzWHY>8$fdf8@Yd3*}$v*jj9H8oXhl|Hy;OY^_q)lAxCY6^p@3j<|r7|G?dY<_bIGR zH;EKbM?3BWtYm^0?dUTGrbcd*WRad%n!jE*zP>0@g@fYuxV|V-b={aB;O|{?Wf7}w zhsYk;+%T?QJ>7wWE(&1vG8Z+p9tE&6bF-%%7JJl)hc>S$lBN0W56p+rqc;+O_X!Y9 ztI{>Be28d7a!Qb^4VS%h#kynNL5KKJ4l$3ahb9_9fvxA2P?LC#sZel?ACwpm63#q1 zl0Fnmb`NxoK(5;xlt#Vj>a&GVB6xPTZF-N#p;Nv$$)scz6_VbW63EtQFqu=cOhiNad^}%8HVzQcaBJIS z9VWUFCh{Tm#;;U~mu1c_a#m$LSg*2{S^~LRN7?lH2Ca4KBnUHRN{ zPVT2;z>1(W5q%(N1=AK)&meFaRX#D9nLgSxJKgTUF42uS1~RgR7e`Yvqq(ou?M5Qi z>aK(FP&m=6>^*q6n`(y|%}|9q$1<7XY#}#cRPhKRNkHq7TBR^utSuB$My481Q~;KS z>uV|ce}rOw2?ag`D4#BW^z#Ykim7~xSfFjh6ZOPQemIQIonca7J79)mHA&szYDIVU zGr4?mW>{~6aK%n8F!>2sQUYrEm3TE}FzXjef*NRs!yLsNor%PhrPPKZKzf-m7+2z} ze`?!KPgTVLpk;>j$>9$ItFF7*E+-D)OPc zs|MXv#Hdoydk=@8D)*QJxs1}z)AA@1t?#VvysurVwkC2p+wL8x)~73QSGd<$+uiCk zTK%iL(`yy7S8YK3_O^<4ihLuTC8<%`hJ~ zn9r4uoLY!aO)s48FI?Y9Zab62}K9)OP2sZa&@RfttBy^Ti|4>T8$1XLjDEStL| zJ1hH&zH#v#JVTWEI?+E2Jh{34a%;boO3#I+qxpEMP}yu|^7(qH(Ix>Ak!a5PcCb+0 zYEM!u5uduThrBYwQhPu+#~*w_W^JR{Sf0Sj3TE=5E@8Q3GMb55^)#k9@`@2F+?O6Q znFgJb6T?z8SE$f2;GZoUkQ~WHnkJ_gYq5AH(2|yZz5PH8!w3CAQfp5GaQsMem`>-TwnLEjUP0v zaU7;(5dLkkmm0LAtA~gvUkMJgD}%K~K=E|N;&O19Zkg1d^Hkiq>p*BeeF+Tn4@W4> z56I^h-hQ?D>!wXSiAeD1#)@7Por%q_xDlf9^r>7X_Uz`tw;yDBeIx+1?B@u?Tz_M7x&%4=xnb^iOpxq!AwSGy z8Pf{Qh9;*I6N8x<%c|GNLn(J2fs)Vf-(M-;b~~aZR_|;(@1zbeX{nN7#nGvz@shO_ z|I!R$gri3r8yoo@YHy|Ab{RO#^L%e`bn1B4V1$Z1M>p1+l}?r1rX-gozv;p)B|oJh z3p&54wdFZHS31}zJ$o}(oIpRGKv&B8Ce}BxKF(T~sL}!Jid!S`m{m`DdF(vjF*yU_ zDZ0~ApVzdJ)$JJ9Twyb#2^zb!SN67_p;uAw8|yvPn&}S{^Dj7cD1X`ZLgz2)7zEu5 z?)vZi$C)4S^0C~g`p|qL{ne3hp7wbO0w7)`WTN*YFDYTQGn(+(4zU%WXooZBjCoOM zqs+Wh5oP(`6znh=JQYuby9;aOIJI4ETZ$9X786)jj~{;`!>zjsG~>RFHY!^v=Fki+V0uUET%S`^nJ!@cXPjoAO++?&8z zcGQLbr_Q&Qg6RnF#^?|37bL&Ya(^Q>Us<)vv04 z^;>h%!c@T|xNjntYlN}bYmAM>s-4P5T|)l%GINXbS(e2llq-v8VQFCL$dYV%`6|T8 z${ovrXeM~Si~TQV-A>n2*@?*+r!W7-ESoDfPr;e??D&0DfzwGgH6>l-2|Qf6k=Ms` zAiIxEX-RK6yOUmVx*dmZaK>g-_M~6ae*a)Sj>Kd0XQ1&HPLEDAFMa;jTqif$5+7#e z*{R8#r;9kU*39RV$&o48*#uu2oj3o*a%}OAO4BX0=hvHf-u{mnMCYSVH&JXFoxRvzfmvVa#6E5dC}#I2b5fYFNP$?RHyAD0 z9wfu9v&V9cTrA1Fi(~fbZ4QlXsp9D9SScO%#|VMMx~0D0;=-P{>97? zIIK#g^>f{kSDof+y3CSY!d-N%o=G>8E6dB`Udy)s;v1|Pb5uo02pEq~d45a3t-j4% zTQ$0}3VKEcsED&Xl|?$=@5RJf6^|11c9W53bwiS4N2lDFOnquDKYAj52CvzDGeq-P ze$>SJqUr0yc=g*abfVa6%YWh*EDb-vaFniJ$PRj((8b#mamL^-D&8rkicJe=$se^d zVz%IoG!!RW9^?{kvQxPTR&2zp8%Yfp{cN8n-}O#EedW6A-BG{dvaMTJ^UJxJ>B!i~ z_|80`IV=KSI(Yk}dAd2liSRi(CW5mfTmxsFeJQyVzsgjUbAlfguu!3pC_iWdK$2s*rp$oz%Z4ZMY2E*-5B$VERvdL%@2DZW! zG#ZN|7Ba0^Bvd&Yg&TY9zN@~1<}_Zlv+#^$w-;o#&#T}uKkXh8euK&jB70lEr-W-8 zkci$UT0)TObP$|!=_8wfT4b3{m$1&pm^X$$i&SzrIyP6qt5vZc45P{A!)@=zkVCc# zkx-g1*G3CD?0@tlOMO0D%UhUCa@>+^So4RTxH-OOdItw@Vp3phC*o*`uMi8|BHupraU+8?Uv+1P~ zT)E3|jnGF;`bg|awgPVk-t5BLfVa_iLQAwgOCZ5YVF}1QW>a7u3wqo1nA?NwLpF}< z9@M0ntn)$)t6z#05|NE4G3nu9!eN9X%^ef0$AM(1TyBo6E^fFFE6$XU>(TTDo6@7X zbT*Y~sjmbv=m}?eJ(5G)Cy>h`z7EarYzKq2Y9xi*1!!CCtvQ~N?qmiedpiaPTdmcb zN1_ow?qa}e=`*E{s;~aPr^DsBeTnOtJ>qEVR5I8-Q?b079j zCo^Y_pHkbkYiG5(IHncigS8N&vit@)8>!) z%^S_9v1UFjl7S7oo;(K-oB9v|t|0TqZib$w#^UaATia64zc{N#XU#k=o85gaEhic0 z@ByZ;DnDK@`0H$Soge7!SWq>TaQyKezs)$;!I~Y*Kcs`voA9T0%KY+8vYM&Wsq@TU{smEO``GQh|o9Df77D_#V z=~X~NYDj1`*#<2Zd=ssz{{8Qb-%XZByvB9n_1JsPs6Z_XF@l4>$vBQvTm=( z_U`83RM6!k(re(Ew@S!Z*!`%nizWp`;Ntw#+y?ed*DC>UJGiGV<%o>i3V39PFcE03)3Lu#inx6Xi^PI^{VfNQ`AU7RQRwVm>oE zAjW&)C_c04AAiVKnklAR>CTPVf=7tzJJ39TYN%T*PDex0lrNFW#GxV6;mkma>WA}{ z8N%}7Q-c z(SyMi)<$Ge;lysgZ#((IW}ZOzzF<5O6)kLEI1^s~P%s`H##Mg8#VfuQ#+r!DkvQ3b zsB7D6``@+P8-8;v)^#On`B4v(BE zrh8_zEfWv?YRIZ3EULw&jYu8=MmUuT2BP6?b0ClQQz!VAL?lp9zG8hWSDYzka>Yt?yiKg^wO#Sp+1?3wVeUXZ9#ZK>C6SFr z;$vsH-v!HM+fq`=y>tT$oSK8StK}>jh`) z;UO8YX#dcg!Pxj*2DwH6CrJA)ogZmNqci&oCmQeKISU)-ho9!l-SGm!pFRH3NH$R@ zMdTETI}6p|Gtho*+ltK zy(WD4@0fpz{B<)D*gkzEN3g?^VKai9OZ&Bk{q(CCwD>H~Y z?S7zYAZV$OCNB^~+*w8sT9v5EV_j(FP&l!D(Mt9CNSHVXbZHq@3O_x>~ zco|1FzaE3zf9~khIg*{hd&{9O-1YW3N58WpF*A=GHrw)FVO1|&|Oxhmz@0uTCZtT+%V0$5;FKk6D_iIl= z?7H-=&4=I(Jv$&|+s6~S^6112obK|*6!2TPIPe9Edls^T@sm-!jfO+!LI;Vw+?z9I z!Aw4j-Yw*(mtER6P?$QN@KyiEogmW};Ho4Ro8O0e0=;=+vNz-qyBXr=p5b{hyXA=; z$5Xt|!}!5i*zW5utM8f(`0!VNi4MV`F-{+s1Q)&jc6mR#W7)QC3q$gV)r!up1g&slw6Ihi9P$qjCzqC|{bGHBnvU0dmO0kWR)-Q}FUn-H z130)ci{0W-D?D7nlmeuxtc5ldUMt&b*|o_;YOp#pQLflp9lm%eH!z$SYwUesue;ui zoIXM^V|%|Wg_TOprf8v?(NG#+4l3J~AM-@D8Id{;>Haovz~vuRo37 z%zwZ)$VpDzQQolR{UhMy|$abFo=$jEdGE zRu7JLp-WWpiVTVLv^d1XFv8_kY#j8Y^3kT^^`f^Eu9%6W>-|j)4Q+D0w_K^rXfD>d zZYi1eXX|Az9;e`4G7}pq1|@#9cmncA{fT-sW|ne(IC#*(DZJ^+X2{7T)O+z3CyVKUfkdM|b@4RLfZ7$L=i6Vt-5u)(-*fmz^@GQS zMzdu#=sQS!KwLsgJw!mn`^)Zot1-#M8keklX~GxAh>?<0<`C*=(1 zBa7W)saE%;vuWS(c^8~n&K9E9;LN5i%eibRSMZl6k{MCIiF@1}GbXOC0wEvgVLw4J zv*mIyF~729X*>egT$M+ra@$TxXU^N37&t|XIfFq74S^m8?gA17Q!l1Vm0EdVrafFF zYA;l8BAvq*b3C4FXFZlru9cH1z(Greo0V7wZ*2Z>B%aE}qlBFZ6ek-M8~_KKL4=4x z7yrBQZu1MoJe-oKD>nS;lz&=$9rTZr z6D{Y&Uznx+@(B*d(LrkYtVvCM=wa$a&~Z%>uP@Nb`EZMy_KDMR^;<5%@WcP%E_&8o z7}aGW@gi}@!jYlkP(rZB#;bp}-j9s-py)keNhe|(4ov7FJy+)1bp=4u7RjXP0lUMG zQ-i`J$~A#?J_BC5Jv;GH2>yYGP;5f9IUxzqH#KvWXk4s~o-3n$VUpg~NVr~Wom#JA z@EHizrYp6U1VtG+T^N0Yf5SbN8MCrhW2H7Q7)BEz5h#ioc{rT7={G5?bRK0vN4T5vDa5wn4aU)vm!1%ccC!rS>6-g zi&-7dqbus__{@LoR z_RievY^d6)hlI|>jqtNHTW$BFf2lVH^ot~0!1h+(?pJgDDO&~Ba}MsV{ZE^($LH!c z(Y6w@j7}2w6e8SbA&^zR?$Ka$l5OX^63b$QnuzvToOP%hz_M3OUL@O4nt96^kJGxD;+7FfIMF+az z_^%+iqOAYlGtV+_LId`o(RS#ApsiB?UC@F05en!mu5-B@FB(XuMa-x<6*lq9pg1lO zJnc;RwhkfzThUPOx$G$puG@pS)CuOAt`yTdM_SAXls;~Ok${I8be&{{2;!ci=Z+Ok^5WpXI9Wi~BOPMKY?B7z7#Gk1<9k){Q9>G4td3|2n$jVOIBX%cE_4A=^Lali+dC zcwFst<0YV*ZqqiRze2k4Z8vT$F#_!TUvkqQb@OApXXlr-0lnL+JQ_*z?}k6uu=C%b zOgEmb*!l_I?i42-zn<6H^XMDaQ|3Nmu-#+4!{u&>=GN6{7ERy}R5Z0-%o}pwL`*`_ zG?E}#=i%ZrjMQes6TIiQS-iG&;D5+UFCO3b0q=8R$5FJC?s;#M(k>^@jM9kvve$i_0mnM8tsQcOl!n(fummnoK_?TaqIdcIUJZ~41hTr|4$(Mt)P zp~~*h^`~qTmRc>|9$mR*#ZATOaAz?%KZ`al2L<2sMeiTmH&WkO_ebBWqQ&`Q28ljG zddx!iVyvsq*WZ1-E=NOFcjoi z@zMQblstZx&9C_1)+f-meGGNt}kWOA2vQ_-%H#dwzcuz z%P1{lt0H$VNTR?y8LgeXeF*qc;7fr&27E8@y)OJx;Fr4aPgBM+&)-7YTS${K-Us|X z_xXo`KkUN43H+PD50mHPz#j)IunN^U;OuOAx6?ZyOgG3ld+C|c}vZ-hN`uJ_>kK29D^M7at9fQCu@bU z@WOpWm2a2FVgI4F8p!5%w^PYtVYGx!t>}|PW0~|&7S|iZHOdcR4e8mK42_j==4=tH zEfK;}Wtf};MGmdW)bL7XX|Q0b_7=AOXd3pLwfU^$850UQ%wJeyJhJdwuK zj%Sc8oNV2D-gq)mE{zW0I64|6dWA~oQcFVwh?+q>=^q{`R*QvTC_R=)x032qwf(*w z*-Qw>S_JD&RL267=dP)bJ3~~RB2p#VlZAm(_FuACDHJBKE?$}%MtBh_$8v>oIs>;h zUf+!3Gn|f)IlgBoLzkPWNOUA+{w+jk%8YTcO4o-6q6KqgtJ_!qp}u6c>8oq#D<+Z5 zCWq=`0oDfgwlbkN;iLtf5Xm8jr>Y zmS&>Ak*LBNix$*tH>71253TGFmRbJ6VrHZ;eENvLQEyeNGwJ*w4(c=Yk?CqOWt#Cg zT2$EaD*sRi+nA6ltp5o!pjglOgu@gGE#7B~T`!eZkHtyXp zda#cUAiv?z0XHZwzu2g;Pb-HGxWV{OhYk?G@lw9=HMjitxaEr-mgE;EXTZ4OVvi0G zKj4!8>u&z{y7|TCNbrw0+7j4QxEFC?suL7^K12}r!POQOGSlLfum6y1KyMV*o#VT?y@Ltlz z>+6}oqWdhcLql+SWEQ$RfOvjAnX?W1i~tExcXXZIEx_Ic1R-se8GA{ukDkc!E61}F zy38G^XiM{YwUSN zNE^v-yw1%px-2rUhMoMIy!;XeP3GahyZP^N=b`9vOMZu!dBa&=e*D+j`TxVsf0LVE zbSWi&*(ra?%a4C2JO2;e{O@%0i*A+VAJXa9%9+mihWbx+HyYxb?dal;Xsr&Nmo-{; z^y(});aMIFoId8zgd20$w$5`8+(Ldc_iT?2E~({g4vmEAF{KOp&e>axmvE3WkPM5B z3n4cmK_raztFOQM8~R*}VOCI#_f-&ME?*3NXiUB^VPj#l+iiY|c25afS0{~)cIUB( zmZ;l#+M1=USu%_Qw}4x=4A$AEz)Sy0+v@Y$n%r~MjaThSo~X5ji;vuM~sOCKt z=1R-_u&bava(2yAK_0comij(pJ_8T9?$+l?;XH3HL-b$VwhQot5{^-`tc1et^yQn| z9HN#9ZI9z(j4?o9RSqSIj*=WA>@Jq5y)+1Wjk2x>-*{)fx4>FLaoX23wVMR>{|($Q{5bjXxGi z71UQ>=;)s}b?seU8Y&re!9Z_bgqlJ4sqSX^|M^>;QAofZ*zT)D^7g0E(?Vh zC1M=di*O~d$Iy^G;?sXYB3$+R?ze-gF&;Ti%d#rVDpV%37bHMnuW*5j6e1RJ61B&( z)DqaMNMOfX603q{X>!=y5RFI#Jk7m;1P_>6VWhp7=`}{Zb*yt;NAqk~mTz_W57&1( zoCH1fBvY*%QLo%sf8XG8WIxcyM0nNu54;cnuT|;SBH?w$ZN1NWr9qBDA24=qIcyFx80$mmHd1^pGpE{j>=2WxxFd&UW5KV8X17F=HYtkVFg|ls!x1APWd~ z!Vde)IR+NKQuV6{ex#D+fmX0J1%ZbWQq7-(4e>LPQXqgX!BAo#o3onbOfDE2oUO40 zIJB5)wT=7WTw-R9ooG_+=WZEE^B1`XSqt9D4)P4oFEW1B_(S7MNGZmQE8X@9w@G-2 zuj0BNT=@j02#zEfH;;z-1n}=1<06lwe+yXd-{$^p(s-`Q$GBX0K%z>Bq8pkEc6;dr`e2h|zS^U#bWk<-W=rh}Z_$ldTYYl>}2{yD*>JlI*AZF!eNWl0J6 zR+KGE{J6?pmI;p$vKhqyE5fv0Eys*~xk(lSVYQ{xXd6#gcw(c{r7}EQz-rv8;GJHAGA{apIef=eC|k zEXBN7$0YwVgPB*7$gfsZw5-a}LlIii(+~;_tTt1La&X8YyR~K8BFgG|O{nW>SzcfB00qg#VSHN~Ag(7SHiky411$ z=J~(HeBL6}GL`#dEA{$nrh-#%BHXq|CVkTvV3y>w5-OQU1p|?AELJGBwlBo&^B<&B zBpNR#W8zz`+$c2W2NCt**)95OSi;96F@GSNChksQqAjoiMd33(WR_-2V;7!( zPE*IhMNHT!&*KMfzDT%1fchE_&XNx#xLHbk>e>^$X@O_S?jou-6XH7F?*8uB;z6ZrR6i z*9gp^fcqze&}?EA=8`BD%F-wvS-w&x(`q(SLtBS7tcok$N^!QBpPpMl8Nqcc+B#)* zMH!)JFc}PB`7#s=pyw0G)-xL>#Oc9wqMj(uPq)H4j6{54%XWMH`%&K@v)-Yay_xG! zmX097o~wjMWO~|y1!vx?m+%p2SNLDRM`TcN^V=VBS}2O=ngGLBW&XM!fhhwr*9=y- z_D2*J+>c14aB*RO1Z$@7INzzBX3ac@I3M0=_c#s0h3rIKh1ncX{T}3G73_o@`6tD|vn;?+APV_yF)h z;A?=dIqs~A^Yq>ZO@SjMv61AMCMUJNSz)V2NIu(JVjpSYm{Kwz8b`rS;n6q>$o7b% zN34>{@#0~#bJ@oOnhu#T&1shgS;};GU)Y(yVj_lRY}l`-*m0p;_7p$n(j%W`o!xr( zR`*x4(QIzn6^?A(n^f)R=v~4Dg^&3r;Sw>xm8XZtDH7gIc={wdL)e;K1gCXekaan@9W{1nXuk_lC%FzkVS6DwOhlQ(@HY-4 zi9L)Z#$kMu95#reM`XssNN^7mnei}@84nYg@i6D@!$f90Y)58%G36enE{B+X ziRk8f^Zyn;Qeq?3Stlml=6KM4o%UiEVx2f{f%AJDS6j(M);o9!Jydxy;{Z+j&Ly@h zCyZWgIcq{8%=MT@edy_uK;HSB@=&>ZYXSayMj}Wgg0U!n0*Q1u7Kud)xfJdP{E1@B zA5W&j#bSZoJ)GBsFvwENg!1J?BA&+6*TDKOxTw5(?=}}NF>X$0`VK>>BrYh%aX6ZY z*|bVqsdJ} zv*&(6te1$T=#JOEY~}@KFIakT%Y5T6R@z+ zTd>&s+49bT^eF1x`;C^3JHq^Pj;7=WeudysiRM+f2DwD1YlUkw*H*4=TylEyR!o7X zsK!|}`#Fdmp#_8#5cILPNoSSwq)2^>8e)Ax!G6h;vc2qCZBAfv3K1%ozcwjsFO@b? z4hyHzF2HhWbaUP@YgZ&#v+A+d)Le0Cp;=ERX3igPj>FONr9;KUr7n^@?90ajfq*|2 zg!2_hPEC(T!#-81nGzC|4JDk74poDV+STo10%rsHjBQ9gm}O;!jf8cDMuco?@7~zj z&f;Wi2Oj4co6S$}shRNrH2BUM-~4}3lE-3+Sjvsa9}Tu5XH_PF);x|}y` zej7tGV|ue*&P=w7vycm7uxyHq&^<$f0O?U%5W|~jY%r1wPHx$`Y>UttD@bO-w5YY# z_F7~2P?xn!ScN^j)6cIhRZKTSyvZJYz9`<+OIQVOb-CIK<11P0oH6R=Hp$<^v3d==A-6)*oa?hTxDG9j%A4Ph%gQp zb53_?6^D1f!J~KRkbZp|Z+wM5k?}o;G6cQ=_yTATWYluD?ATL~HC>xtGv%DA)u$&T z%f0(A%i!5ZOJ@ZS|5hHZ3>6~5YIi78PFRGxnVHUHYW!)Pj*CSM+lXG6 z&IWzOl9^~O0ndr*+mjXSbrU zxvS@E+nb>Rl5l1|0S(RKg!%xG%ja4!uQ6Y5oTAFknk>pK;yP_7-6ka8c3^LTYm-)G zx@1Wg)_#@Wd0;vE2n<`nzI!Yu$v;WjB+s`4_naNS$By4)$M3P@_t^1!?D#!){2n`g zj~&0qj^AU)@3G_e*ztSbj^AU)@39p;W-L9cP7Jg}rWl{nH1!2}ZtP*3bTATfomv^{xjm}8|OXIbZ& z*kH+V5lzu*u4YgV8NTA0*)w7|cNqy|xgo=$H*-@p7Rr_KK=)vy&k35j2)ojU(FNnC zB6#SG#r>&T{P2z4rS(s^o2+?1D}yKqusA-n{t=JI^_UVj6`YMWnQ`KYohE*@>~pGo zz3{o@oGPJPWk-wiwFL%N22l7y9ez*nTkbv5diHtNRtXiwWZ1Quw?G&GuLp23qZM(cDsd-EC?8{mFC)+d0;d#>8}% zC?+%KtFK3*{&>`%FO*nRv=*4EukBhLNJM<$ZF_GO$;kvrH(EE8zfdh@S zU*tWN#z@Kuh8!;@rnVRGq?t-5h){>5C*%jwrq7>tzi;-E*<8w>iw>W=C0K|DLu}`< zR0djAy@egfwB8hq5<3}F-ht5I{LEy57|3JR(#=b^fAgNq{K7<(pnM=Tu4%%ljZQIh zA>Z7Uv#(kI!F|ahf=6F!{$M9RX`ZI{edG7dce8J7XJ0sC*lQNEUuJ%Vo-)O|Dtk67 zeL);$Ibtz;#=5c~*YA+6MlPMhmH~va~I6){uqCNTXNSjKUW|}x%>Q9oXa*8;T z!3f$+&gV*P==oA4jqiV~T;j!06pv)3%HWVy?aeh&f=Xf4eLoscet(fN{C)|d zmWo(u1-W4PVqtikC}f2~1!v93tM{5;!ROBxWOf`S3b<^&HZ|UY8gF^jc#Fx>f*Nl@ zjklo2TMSAIYPP1EvWI9O^wS2?(G`FSg5eT2#GD}L%`yAOW+!C z&4nAlA}|pN${O&R3!e@wQ$^DE0?U-i1E0;}c?1WF~MT~uH#lzwgM*(YLdk+QN;f`>juWhRwUG37!;m-W#SPWyT*(0 zh*=g-5g;z?(A91AQ|hnGH_8J<=-j(Gn?@DZ#Jd&Gqo}XNV%bf51F~r)FLRPwh?kI`}7d=kU(d zBA-5ue!LD#BUv+F0j(@+<}2uUZ(s#3F(7h&x*50*EWR%V9swS4;Wn_48`qIO2Q2Zz z1?~XL4z&$<3$X0#0$&I$V=3?@z?ZoB9qy7-{*9#HNV?Q@EAXwr(w=*P?{#5MM_1DC zBmF+14xI(HpFzv42PgDODkJWN2jS82TY;@X=`OF%S&!%B>SqNwE3>UgtCO8tpDpze z9^>CXo5x51p4A~w{kk#~3bv;>gK=hpbF_3#+g+Kb@7|Uu4>e223lTuN+UAnWBB<_} zz?Or<+tOUET6Pl)mGaQ0ZHZE%Pt0&a-Xt#MHaJj%Zs;9mz&Si=^)2O=YM#2bW9WDm zzC^8n?D0f){74O_@No>F6Q#Vt<)P!4{KC<6c)d@mzcXKDAOAgGufusiist?%d!PJC zIPaDojt%!_SZMWynQ|3^uasLyUdRxH4Q?+IVXLS^~le)quCxc zwf-0Df1$qjM}P1K=Ev7>S-(ZSNhQ|5wf-$u!0I#S;`87kb&vWD^~dV->L1jxIbpSjituVQsbYMos@@P=W_U30A;Rmt`)A+xi029#B~qX z&vLzk>w{ds&Gk7h_*&K@l(@)Fw~H%4$sBU*T7tkq;1}^cdh9XlKJFfWZ4ua212De_ zJkPt{PAktAj)@kCFiaPX1v(S9TYxB^1+G!9C9d6E7jRw2br;vGxqgA`{alZ7eTFN3 zIUo6#0AJ-YFF&e=>76%I-eU@NC-to-9y6DYanZ^wEf|rnp!RWUA7_c42lloANna*? znO1G(%NL~-`#V=jm8aXd!;G`jwgYo!wc*`-yY%{Lq@6~olGmje?7o9Su>0mro}WqS zXIYO}pRy6?91UHhYy1>%J6q0C<7zkcsBx3IWM%CZWf81j&Ud(5jv6Mvv&|ee-r#+` z@n%vVAeY?VevFHHf05q#mR;|=H1s}Q?`tXdI^Osoxj#tmhuj*E8jtAQk89`&4gI}a z=TVdhyz-ya&^KI&*3gotDEleOe%eb_-y-#2N&Qz+|4qO39Swb7=SYF&COs)FQXI&Y9LNRkGEUOFTS?0L6pgKccu7sWEynW^qj1^B|7%9wj)tSI&1E1}dejf07 zq;DnteBkqeCI6+sC}G(7F9W{J!Buq?@Kx@+M}Ut|d zn|NI2jv@Gk@ZGCAJw;i39~mshY{ zJ;d{e+`j!V@Q2C!Q9UA$YUnX!bFV#uA6!kr~2+(Rnn^O^Zfhnn5_e^yW{=Lv7?-h zyjjicGkrY0fxDk40k1R|Y5jR(tY$GvkbH4qSS*&jo8+C8&IuNqIiBX6y39N<hTSFjXhKSxkkW#W<|y#!>``+yoJ0wbY5>R9W{4*Z`nCnJ57jvbH6t_=9&HDU@~h=ch;Ea0-x)C*?GXs zAp6TM048jcV83}Gb6NW3V$wK}+5N?;YC_1{UwQ?weEF61+g0woIci?*waG5;dh%TF z_U|F!LzE-EaWnAEwDnf~-tFGZv){X$=XcYKBjkMz<-g6!8Y418&9}Rd(>w1V-#aMh zonEbi@8xqx?{9`#-mKO^<8bg6&sm0BZ1^f*S&b$AYT&DRk5$pS2KX8mJ_wA+$If#d@O5rFxMd;!v2OQP zR_nzsEnw4I*2{SQGTsA+tycoSlDx0;M$&rYaeedVV@IvG>VEqrZ-ut&d>8M&i*jB> zIUfN20OdTSb38)o!=ye;>W7Z2|0AS+gw#iMDs+kUIpKjDd;-gk0>zb_b7hMB3R$nR z-Y^c&!;p z&x7D5xUDh+8q)KE*c0B<0S!%PNcX+Dq|-KQXorUMD44r-+I|h4si6xrbcu$p(vTh_ z^JblPtA=jZ(A_R%si6lo^ga!J(8FjpIQ(up`#ko zbISarPWzOGKI1}8yB?=qkFz$h-fV1cx}Lw%&|e?-*55j_&ipEGf0eKLzE?VK37s{? zUK1=oYlELvkM+U|1Ba>U-M|rGWXV?4TN|vnhLXC3HFBoNnIdOFKVQ(#S;wpuo+B}{ zBrl|qCC5s>#geT^YIU}oqZamU&U(p4;;wpZBu<+1_C3xwS+C*E*HGi@^c!!~&|CGp zzvT6drB^z(3$Nr4Y3L&^WUso`M=ATGl>Mli3XgL^H0$!6#cirBj7M}&^LA3RF^gVF zBUr>qOt;sO&`-^x@H_KprokLXiJ{jiikdYh;rULtEnLwd5v3P!S5d_A6-x4=wL*UT zJuw%svp7P)Ky$PkZ1?z!@T$>8e7>1DJ>6ch(<`niXc|hE@om~ zL@v_2UU9KkY=p8KiM+v=c6;q@sz_=>1Wx&2r-v?h5idT}A+CTIFpUVdm$oU| zh-O)kZlSN>A$J%3dERUD$<#tamO7LvozmTgKj5}hC$S|dGoKq)onE6|4CEy*pHC_D z0Y7`)Vmr7{6t~0qX0a!|Q|vbBnC=3dS!_3hWJj_s?nC4|$Uz!Vwrj!ghC1b!#DFXLsw2e(ofJWXP)Xhwk;(B&8UqESvxBiC#Z<}4ltB4f1qb1Tc(gE9HvPUZ@s7}Z3d^i#+#IrG! zzXwZZB!f&iRt;7#X7+`GQFMr!IseR<1V0R^ZT^W!C={9~Mmik9t3=BQ)~SCc)EKt1 zVcci<;-f2}=pbS5(n)_LnjbD>YZ0%^Ba<$qiv?VNWhSsY;H`YwpI`qJRy^n(VCGsv zJSx#s7ghJ7Fq%q*`e`Y|qtVP*L>0_I(+m2nE&4ZG=BB1OS7@Hr6 zMT4DSEgZ|g&WGpbhlF4n$uI|fojS(5Rb?ns#aTzd#zzS>xvX`0!LFPotVo$JG|Z7h7}OrhQ0YWZse zvvZ|*qOo0+_59`q`vO)do=>$)R&bzPp9%-F?J~Yu&7waPX@^tW&2Bdp7|vvxctcUX zWH7j+7#f-QZg;*TVgQ>HK59GVk_#nD-RIX~H|*G@H4zI_A(S}^n0cv%fGGik6n zSB=b=CR!Y)H@kjKdHS&TyE zz7uT=xnF=PgWS(S5f&Mft+fYV#W*L$k^2esnr0E>NQN>Ng>tVGlTtF4$zX7THu+uW zT<@g#cok-g5#mWiKarFePvjlwV>?IAy^px*0X@;yUy-i z@7A3Mc0$@oPLJ64eBb}_>hVR5zEs6RcZWhRUH>*W^KQVqLr=7`3z{zsDh zM`kQEw|7PHt&-ZwV4<1*NI=22jjI~1R=Y>@0836UL{X_0^k4(+ALKm$+ z=%m)>*1s2O&CRLH=0df(ivZ7ae?F%OMzH$KznGt~a^TdQaY&p-a4K@Nbu6@XEKgg< z0tqa%bu5JEmf(-z4%#{v+Bz26Iu_bG7TP)%+Bz26I+m@i6Q;uh3`IaJ!x1pril1fC zmRN*%Uh1J)oC`objiM0QL{AEpGI59`VY@Ns=`6_qMRX-|1@&@u`I8xDgyxj1%+QQPk2kPf%(&yKfE@&>yZ8py#jNg{)iQpaIeo(F7e$VB#+T`S}x1W0W z)%8YuymrPy?|jFW{wed*=9iF5p32+`8hgx9*T()S^Ue5J@Y462ahZHZUYTe_I)8Q= z?{i_rRC|#No0K9NQ1Zt@gEZ*EzP>zuX40aY9x!rDK_`C@Ej_QC5Plne-c64%S-rY4 zb~%=zeB#OI)#d`V2&{}LCGu>6O_qWuUD!e+@H;N->&xRecHu?9$saJr)B`RYH15*n zgp3Bhbe%jAsq37B*WY>Lf!p>RxaY2e2Y1b^-F)EsI}hBxsdnz2x7>K}?wbzYe8+*? z?y2oOa?_z}YG>@+R9l#vpS$4TZMPpfa&v8dW^QiIPN^Nb`OqDQ4%}F~?cj|E58Qt6 zxVP<>&)9ifnl7<+==R!y+8wtYxc1;p2W~rDJ91skX-jR_OwDc0%+4dX+;iKZ>u}AfIXrVK%CAH40ZgV)Zm z7#`%bd?%jK4qzRyhyU+EPJNKSyNEHhhPKiH`}qN)U2HOH*!bUR+(Pby#@)oaILPxm z>^JY>*-o?!Z(@>M1AK<9VN!!XI%mvtT|nO3DB}=$Zsz$srO(-aH}ceYdNbD@TnDJ5 z#v2Fix}^4l&r|nC%~J1=(?+TDc4|7nbqDnwzzgOBo5e{cM&@jr}*@V4}AR)=3Pex1eov&M(;RC*2ide`Dt^&mQY ze`x%P@khoV6VvExjQ5`#$BaKUeuGhb8u8U%8GnIt#tp_djBm2=zlbqA41V0mn7s$= zxRntUyuOq1z6;N&UuRz23l_YDm=Z5#7x-o4<=Ak&!g!_e&&E^G7@s%3WPI6p#Q3oB z71TX`$M{F%pU?&QYvYT?-x^OCe`oxI@i)d7j9)@OU6%fU_?#imDaP(9hQff@XQotI zWl+<}sXU4UMO9K|RZ#8-G4ydcuHR@V*P+h04S2w6b>P70Xx>4Pv zZdOOsE$UWvo4Q@yq3%?7sTZre(IvW9y+plKy-eN5zV{0CO7&CfRqChJ{p!`~HR@;7 z&#Kp|*QwVVA2EItotfV<{+IDle2;$G_$lL4*z5ipIyAp){GRb~^#;6`zT0@a@d4u( z*`EJ}o#ZXXJMj$hM&kkFt;TQT@#~GopBbMt{%7#cn-9&+Ep+Ys;@n*Lz;%ZX&6Cpc zpzgee7BsZ+bWx{uHMFFmo`#k+wBkWay0)cxxBgxFnOE2RqAqt{mo~3Uo7bf+=+YK+ zix<37<`#527j$_Gx}6KUN*y69gDh-MP0{|Zq<^0V@bcUq~BQ5Z}fDldb%w=-Ikti zOHY^F(YAVP>YAVP>YAVP>YAVP z>YAVPzGr^U`=0r^6}NtGZp_c?x;DOHqjf9GPX3hz_ug^tJJ#I$Zs&f=oO^fY-cIlC zzPHPLzROMD<)ypj?OJr+-{r0yyO!MFZh!6azF>LLd$PmLaf*B2>E3s_cejPR+!n66 zHLSTcthwc^xizf0U%KY@(3)HRnp^&wTmG6`{%-e+cDrA++bw^$TmEjhyxl9lwL5P+ ZB8^&ues%BjLP1zY2&y7wD0JYh{|niVYpehO literal 0 HcmV?d00001 diff --git a/assets/components/prompt.rml b/assets/components/prompt.rml deleted file mode 100644 index 3de53ea..0000000 --- a/assets/components/prompt.rml +++ /dev/null @@ -1,30 +0,0 @@ - diff --git a/assets/config_menu.rml b/assets/config_menu.rml index 0666d77..8d582dc 100644 --- a/assets/config_menu.rml +++ b/assets/config_menu.rml @@ -29,7 +29,6 @@ - diff --git a/assets/config_menu/controls.rml b/assets/config_menu/controls.rml index d947ae8..3a8371e 100644 --- a/assets/config_menu/controls.rml +++ b/assets/config_menu/controls.rml @@ -71,7 +71,7 @@ data-event-blur="set_input_row_focus(-1)" data-event-focus="set_input_row_focus(i)" data-event-click="clear_input_bindings(i)" - class="icon-button icon-button--error" + class="icon-button icon-button--danger" data-attr-style="i == 0 ? 'nav-up:#cont_kb_toggle' : 'nav-up:auto'" > @@ -81,7 +81,7 @@ data-event-blur="set_input_row_focus(-1)" data-event-focus="set_input_row_focus(i)" data-event-click="reset_single_input_binding_to_default(i)" - class="icon-button icon-button--error" + class="icon-button icon-button--danger" data-attr-style="i == 0 ? 'nav-up:#cont_kb_toggle' : 'nav-up:auto'" > diff --git a/assets/recomp.rcss b/assets/recomp.rcss index eed389c..488f346 100644 --- a/assets/recomp.rcss +++ b/assets/recomp.rcss @@ -57,7 +57,7 @@ h3, .tab { font-weight: 400; } -body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p { +.config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p, body { font-size: 20dp; letter-spacing: 0dp; line-height: 20dp; @@ -184,7 +184,7 @@ h3, .tab { font-weight: 400; } -body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p { +.config-debug__select-wrapper select, .config-debug__select-wrapper input, .config-description__contents, .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper, .config__wrapper p, body { font-size: 20dp; letter-spacing: 0dp; line-height: 20dp; @@ -252,6 +252,12 @@ body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, /* @include set-color(COLOR); */ +body { + box-sizing: border-box; + color: Text; + font-family: "Suplexmentary Comic NC"; +} + /* stylelint-disable color-no-hex */ /* stylelint-disable selector-max-id */ * { @@ -261,12 +267,11 @@ body, .config-debug__select-wrapper select, .config-debug__select-wrapper input, hr { display: block; padding: 1.5dp; - background: #08070D; + background: Background1; } body { color: #fff; - font-family: LatoLatin; font-size: 20dp; font-style: normal; font-weight: normal; @@ -281,8 +286,8 @@ div#window { box-sizing: border-box; width: 100%; height: 100%; - border-color: rgba(255, 255, 255, 0.2); - background-color: #121018; + border-color: Border; + background-color: Background2; } div#content { @@ -368,12 +373,12 @@ scrollbarvertical, scrollbarhorizontal { border: 0; } scrollbarvertical slidertrack, scrollbarhorizontal slidertrack { - background: #DABAF7; + background: PrimaryL; opacity: 0.05; } scrollbarvertical sliderbar, scrollbarhorizontal sliderbar { border-radius: 5dp; - background: #DABAF7; + background: PrimaryL; opacity: 0.1; } scrollbarvertical sliderbar:hover:not(:active), scrollbarhorizontal sliderbar:hover:not(:active) { @@ -415,7 +420,7 @@ scrollbarhorizontal sliderbar { bottom: 0; left: 0; padding: 64dp; - background-color: rgba(255, 255, 255, 0.1); + background-color: BorderSoft; } .centered-page__modal { @@ -429,8 +434,8 @@ scrollbarhorizontal sliderbar { margin: auto; border-width: 1.1dp; border-radius: 16dp; - border-color: rgba(255, 255, 255, 0.2); - background: rgba(8, 7, 13, 0.9); + border-color: Border; + background: ModalOverlay; } .centered-page__modal > .tabs { display: flex; @@ -473,7 +478,7 @@ scrollbarhorizontal sliderbar { } .control-option { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out; display: flex; position: relative; @@ -487,23 +492,23 @@ scrollbarhorizontal sliderbar { background-color: rgba(0, 0, 0, 0); } .control-option svg { - image-color: #CCCCCC; + image-color: TextDim; } .control-option svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .control-option:focus-visible:not(:disabled, [disabled]), .control-option:hover:not(:disabled, [disabled]) { - color: #F2F2F2; - background-color: rgba(190, 184, 219, 0.1); + color: Text; + background-color: BGOverlay; } .control-option:focus-visible:not(:disabled, [disabled]) svg, .control-option:hover:not(:disabled, [disabled]) svg { - image-color: #F2F2F2; + image-color: Text; } .control-option:disabled, .control-option[disabled] { opacity: 0.5; } [cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] { - border-color: #F86039; + border-color: Danger; } [cur-binding-slot="0"] .control-option--active .control-option__binding[bind-slot="0"] .control-option__binding-icon { opacity: 0; @@ -512,7 +517,7 @@ scrollbarhorizontal sliderbar { opacity: 1; } [cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] { - border-color: #F86039; + border-color: Danger; } [cur-binding-slot="1"] .control-option--active .control-option__binding[bind-slot="1"] .control-option__binding-icon { opacity: 0; @@ -543,7 +548,7 @@ scrollbarhorizontal sliderbar { } .control-option__binding { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; display: flex; position: relative; @@ -556,35 +561,35 @@ scrollbarhorizontal sliderbar { padding: 8dp; border-width: 1.1dp; border-radius: 8dp; - border-color: rgba(190, 184, 219, 0.1); - background-color: rgba(190, 184, 219, 0.1); + border-color: BGOverlay; + background-color: BGOverlay; } .control-option__binding svg { - image-color: #CCCCCC; + image-color: TextDim; } .control-option__binding svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .control-option__binding:focus, .control-option__binding:hover { - color: #F2F2F2; - border-color: #F2F2F2; - background-color: rgba(255, 255, 255, 0.1); + color: Text; + border-color: Text; + background-color: BorderSoft; } .control-option__binding:focus svg, .control-option__binding:hover svg { - image-color: #F2F2F2; + image-color: Text; } .control-option__binding:active { - color: rgb(244.6, 244.6, 244.6); + color: TextActive; } .control-option__binding:active svg { - image-color: rgb(244.6, 244.6, 244.6); + image-color: TextActive; } .control-option__binding:disabled, .control-option__binding[disabled] { - color: #CCCCCC; + color: TextDim; opacity: 0.5; } .control-option__binding:disabled svg, .control-option__binding[disabled] svg { - image-color: #CCCCCC; + image-color: TextDim; } .control-option__binding:not([disabled]) { cursor: pointer; @@ -623,7 +628,7 @@ scrollbarhorizontal sliderbar { height: 24dp; animation: 1.5s sine-in-out infinite control-option__binding-recording-scale; border-radius: 24dp; - background-color: #F86039; + background-color: Danger; } .control-option__binding-recording .control-option__binding-edge { position: absolute; @@ -636,7 +641,7 @@ scrollbarhorizontal sliderbar { .control-option__binding-recording .control-option__binding-edge > svg.control-option__binding-edge-svg { width: 36dp; height: 36dp; - image-color: #F86039; + image-color: Danger; } /* @@ -661,13 +666,13 @@ scrollbarhorizontal sliderbar { transition: color 0.05s linear-in-out; opacity: 0.9; background-color: rgba(0, 0, 0, 0); - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .tab:selected { - color: #F2F2F2; + color: Text; } .tab:selected .tab__indicator { - background-color: rgba(255, 255, 255, 0.6); + background-color: BorderSolid; } .tab:selected:hover { cursor: default; @@ -681,7 +686,7 @@ scrollbarhorizontal sliderbar { } .tab:focus, .tab:hover { opacity: 1; - color: #F2F2F2; + color: Text; cursor: pointer; } @@ -710,7 +715,7 @@ scrollbarhorizontal sliderbar { .config__form { border-top-width: 1.1dp; - border-top-color: rgba(255, 255, 255, 0.1); + border-top-color: BorderSoft; display: flex; flex: 1 1 100%; flex-direction: column; @@ -729,7 +734,7 @@ scrollbarhorizontal sliderbar { border-radius: 0dp; border-bottom-right-radius: 16dp; border-bottom-left-radius: 16dp; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; text-align: left; } .config__wrapper p { @@ -738,10 +743,10 @@ scrollbarhorizontal sliderbar { white-space: pre-line; } .config__wrapper p b { - color: #B97DF2; + color: Primary; } .config__wrapper p i { - color: #E9CD35; + color: Warning; font-style: normal; } @@ -760,18 +765,18 @@ scrollbarhorizontal sliderbar { align-items: center; justify-content: space-between; width: 100%; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; } .config__header { border-bottom-width: 1.1dp; - border-bottom-color: rgba(255, 255, 255, 0.1); + border-bottom-color: BorderSoft; padding: 12dp 20dp; } .config__footer { border-top-width: 1.1dp; - border-top-color: rgba(255, 255, 255, 0.1); + border-top-color: BorderSoft; padding: 20dp 20dp; border-bottom-right-radius: 16dp; border-bottom-left-radius: 16dp; @@ -805,7 +810,7 @@ scrollbarhorizontal sliderbar { overflow-y: auto; } .config-group__title { - color: #B97DF2; + color: Primary; } .config-group__title--hidden { display: none; @@ -872,12 +877,12 @@ scrollbarhorizontal sliderbar { height: auto; margin: 4dp 12dp 0; padding: 8dp 0; - color: rgba(255, 255, 255, 0.6); + color: TextInactive; tab-index: none; } .config-option__radio-tabs .config-option__tab-label:hover, .config-option__list .config-option__tab-label:hover { - color: #F2F2F2; + color: Text; cursor: pointer; } .config-option__radio-tabs .config-option__checkbox-wrapper, @@ -888,7 +893,7 @@ scrollbarhorizontal sliderbar { margin: 4dp 12dp 0; border-radius: 8dp; opacity: 0.5; - background-color: rgba(190, 184, 219, 0.1); + background-color: BGOverlay; cursor: pointer; } .config-option__radio-tabs .config-option__checkbox-wrapper:hover, @@ -897,7 +902,7 @@ scrollbarhorizontal sliderbar { } .config-option__radio-tabs .config-option__checkbox-wrapper[checked], .config-option__list .config-option__checkbox-wrapper[checked] { - background-color: #3333FF; + background-color: A; } .config-option__radio-tabs .config-option__checkbox, .config-option__list .config-option__checkbox { @@ -916,8 +921,8 @@ scrollbarhorizontal sliderbar { .config-option__radio-tabs input.radio:not(:disabled):checked + .config-option__tab-label, .config-option__list input.radio:not(:disabled):checked + .config-option__tab-label { border-bottom: 1dp; - border-color: #F2F2F2; - color: #F2F2F2; + border-color: Text; + color: Text; } .config-option__radio-tabs input.radio:not(:disabled):checked + .config-option__tab-label:hover, .config-option__list input.radio:not(:disabled):checked + .config-option__tab-label:hover { @@ -927,13 +932,13 @@ scrollbarhorizontal sliderbar { .rmlui-window:not([mouse-active]) .config-option__list input.radio:not(:disabled):focus + .config-option__tab-label { transition: none; animation: blue-pulse 0.75s infinite; - border-color: #17D6E8; - color: #17D6E8; + border-color: Secondary; + color: Secondary; } .config-option__radio-tabs input.radio:not(:disabled):focus + .config-option__tab-label, .config-option__radio-tabs input.radio:not(:disabled):hover + .config-option__tab-label, .config-option__list input.radio:not(:disabled):focus + .config-option__tab-label, .config-option__list input.radio:not(:disabled):hover + .config-option__tab-label { - color: #F2F2F2; + color: Text; } .config-option__radio-tabs input.radio:disabled + .config-option__tab-label, .config-option__list input.radio:disabled + .config-option__tab-label { @@ -948,7 +953,7 @@ scrollbarhorizontal sliderbar { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; height: 2dp; margin-top: 8dp; - background-color: rgba(255, 255, 255, 0.2); + background-color: Border; } .config-option__radio-tabs input.range sliderbar, .config-option__list input.range sliderbar { @@ -960,24 +965,24 @@ scrollbarhorizontal sliderbar { margin-left: -8dp; transition: background-color 0.05s linear-in-out; border-radius: 8dp; - background-color: #CCCCCC; + background-color: TextDim; } .rmlui-window:not([mouse-active]) .config-option__radio-tabs input.range sliderbar:focus, .rmlui-window:not([mouse-active]) .config-option__list input.range sliderbar:focus { border-width: 1.1dp; - border-color: #3333FF; + border-color: A; animation: blue-pulse-background 0.75s infinite; } .config-option__radio-tabs input.range sliderbar:hover, .config-option__list input.range sliderbar:hover { - background-color: #F2F2F2; + background-color: Text; cursor: pointer; } .config-option__radio-tabs input.range sliderbar:active, .config-option__radio-tabs input.range slidertrack:active + sliderbar, .config-option__list input.range sliderbar:active, .config-option__list input.range slidertrack:active + sliderbar { - background-color: #17D6E8; + background-color: Secondary; } .config-option__radio-tabs input.range sliderarrowdec, .config-option__radio-tabs input.range sliderarrowinc, @@ -989,7 +994,7 @@ scrollbarhorizontal sliderbar { .config-option__details { height: 18dp; margin: 14dp 12dp 0; - color: #B97DF2; + color: Primary; } .config-option-color { @@ -1012,7 +1017,7 @@ scrollbarhorizontal sliderbar { height: 100%; border-width: 1.1dp; border-radius: 16dp; - border-color: rgba(255, 255, 255, 0.2); + border-color: Border; } .config-option-color__hsv-wrapper { display: flex; @@ -1049,7 +1054,7 @@ scrollbarhorizontal sliderbar { margin: 0 12dp; margin-right: 16dp; padding: 0; - color: #F2F2F2; + color: Text; tab-index: none; } .config-option-range__range-input { @@ -1059,7 +1064,7 @@ scrollbarhorizontal sliderbar { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; height: 2dp; margin-top: 8dp; - background-color: rgba(255, 255, 255, 0.2); + background-color: Border; } .config-option-range__range-input sliderbar { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; @@ -1070,20 +1075,20 @@ scrollbarhorizontal sliderbar { margin-left: -8dp; transition: background-color 0.05s linear-in-out; border-radius: 8dp; - background-color: #CCCCCC; + background-color: TextDim; } .rmlui-window:not([mouse-active]) .config-option-range__range-input sliderbar:focus { border-width: 1.1dp; - border-color: #3333FF; + border-color: A; animation: blue-pulse-background 0.75s infinite; } .config-option-range__range-input sliderbar:hover { - background-color: #F2F2F2; + background-color: Text; cursor: pointer; } .config-option-range__range-input sliderbar:active, .config-option-range__range-input slidertrack:active + sliderbar { - background-color: #17D6E8; + background-color: Secondary; } .config-option-range__range-input sliderarrowdec, .config-option-range__range-input sliderarrowinc { @@ -1101,7 +1106,7 @@ scrollbarhorizontal sliderbar { margin: 0 12dp; margin-right: 16dp; padding: 0; - color: #F2F2F2; + color: Text; tab-index: none; } @@ -1139,21 +1144,21 @@ scrollbarhorizontal sliderbar { .config-option-dropdown__select, .config-option-dropdown__wrapper, .config-option-textfield__select, .config-option-textfield__wrapper { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.5); + border-color: WhiteA50; position: relative; box-sizing: border-box; flex: 1 1 100%; width: auto; border-radius: 12dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; } .config-option-dropdown__select svg, .config-option-dropdown__wrapper svg, .config-option-textfield__select svg, .config-option-textfield__wrapper svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .config-option-dropdown__select:hover, .config-option-dropdown__select:focus, .config-option-dropdown__wrapper:hover, .config-option-dropdown__wrapper:focus, .config-option-textfield__select:hover, .config-option-textfield__select:focus, .config-option-textfield__wrapper:hover, .config-option-textfield__wrapper:focus { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.8); - background-color: rgba(255, 255, 255, 0.2); + border-color: WhiteA80; + background-color: WhiteA20; } .config-option-dropdown__select selectvalue, .config-option-dropdown__wrapper selectvalue, .config-option-textfield__select selectvalue, .config-option-textfield__wrapper selectvalue { display: inline; @@ -1162,28 +1167,28 @@ scrollbarhorizontal sliderbar { } .config-option-dropdown__select selectbox, .config-option-dropdown__wrapper selectbox, .config-option-textfield__select selectbox, .config-option-textfield__wrapper selectbox { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.2); + border-color: Border; margin-top: 2dp; padding: 4dp 0; border-radius: 12dp; - background-color: #191622; + background-color: Background3; } .config-option-dropdown__select selectbox option, .config-option-dropdown__wrapper selectbox option, .config-option-textfield__select selectbox option, .config-option-textfield__wrapper selectbox option { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; padding: 8dp 12dp; - background-color: rgba(0, 0, 0, 0); - color: #CCCCCC; + background-color: Transparent; + color: TextDim; font-weight: 400; } .config-option-dropdown__select selectbox option:hover, .config-option-dropdown__select selectbox option:focus, .config-option-dropdown__wrapper selectbox option:hover, .config-option-dropdown__wrapper selectbox option:focus, .config-option-textfield__select selectbox option:hover, .config-option-textfield__select selectbox option:focus, .config-option-textfield__wrapper selectbox option:hover, .config-option-textfield__wrapper selectbox option:focus { - background-color: rgba(255, 255, 255, 0.2); + background-color: WhiteA20; } .config-option-dropdown__select selectbox option:hover:not(:checked), .config-option-dropdown__wrapper selectbox option:hover:not(:checked), .config-option-textfield__select selectbox option:hover:not(:checked), .config-option-textfield__wrapper selectbox option:hover:not(:checked) { cursor: pointer; } .config-option-dropdown__select selectbox option:checked, .config-option-dropdown__wrapper selectbox option:checked, .config-option-textfield__select selectbox option:checked, .config-option-textfield__wrapper selectbox option:checked { - background-color: rgba(255, 255, 255, 0.05); - color: #FFFFFF; + background-color: WhiteA5; + color: White; } .config-description { @@ -1194,7 +1199,7 @@ scrollbarhorizontal sliderbar { border-radius: 0dp; border-bottom-right-radius: 16dp; border-bottom-left-radius: 16dp; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; text-align: left; } .config-description__contents { @@ -1203,10 +1208,10 @@ scrollbarhorizontal sliderbar { white-space: pre-line; } .config-description__contents b { - color: #B97DF2; + color: Primary; } .config-description__contents i { - color: #E9CD35; + color: Warning; font-style: normal; } @@ -1254,7 +1259,7 @@ scrollbarhorizontal sliderbar { width: 100%; margin: auto 0; padding-bottom: 75%; - background-color: rgba(0, 0, 0, 0.35); + background-color: BGShadow; } .input-config__visual { @@ -1266,7 +1271,7 @@ scrollbarhorizontal sliderbar { left: 16dp; flex-direction: column; border-radius: 108dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; } .input-config__visual-half { @@ -1452,10 +1457,10 @@ scrollbarhorizontal sliderbar { } .input-viz__button { - color: #F2F2F2; + color: Text; } .input-viz__button svg { - image-color: #F2F2F2; + image-color: Text; } .input-viz__button--sm { width: 64dp; @@ -1482,19 +1487,19 @@ scrollbarhorizontal sliderbar { height: 84dp; } .input-viz__button--C svg { - image-color: #E9CD35; + image-color: Warning; } .input-viz__button--A { margin-top: auto; } .input-viz__button--A svg { - image-color: #3333FF; + image-color: A; } .input-viz__button--B svg { - image-color: #45D043; + image-color: Success; } .input-viz__button--Start svg { - image-color: #F86039; + image-color: Danger; } .input-viz__Z { @@ -1502,7 +1507,7 @@ scrollbarhorizontal sliderbar { height: 136dp; } .input-viz__Z svg { - image-color: #E9CD35; + image-color: Warning; } .input-viz__Z > svg { width: 136dp; @@ -1515,7 +1520,7 @@ scrollbarhorizontal sliderbar { position: relative; } .input-viz.input-viz__dpad svg { - image-color: #F2F2F2; + image-color: Text; } .input-viz.input-viz__dpad > svg { width: 192dp; @@ -1530,7 +1535,7 @@ scrollbarhorizontal sliderbar { width: 200dp; height: 200dp; border-radius: 100dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; } .input-viz__dpad-split, @@ -1605,7 +1610,7 @@ scrollbarhorizontal sliderbar { height: 96dp; } .input-viz__R svg { - image-color: #FFFFFF; + image-color: White; } .input-viz__R > svg { width: 96dp; @@ -1617,7 +1622,7 @@ scrollbarhorizontal sliderbar { height: 136dp; } .input-viz__L svg { - image-color: #17D6E8; + image-color: Secondary; } .input-viz__L > svg { width: 136dp; @@ -1662,9 +1667,9 @@ scrollbarhorizontal sliderbar { } .button { - border-color: rgba(185, 125, 242, 0.8); - background-color: rgba(185, 125, 242, 0.05); - color: #CCCCCC; + border-color: PrimaryA80; + background-color: PrimaryA5; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; display: block; width: auto; @@ -1674,118 +1679,118 @@ scrollbarhorizontal sliderbar { border-radius: 12dp; } .button:focus, .button:hover { - border-color: #B97DF2; - background-color: rgba(185, 125, 242, 0.3); - color: #F2F2F2; + border-color: Primary; + background-color: PrimaryA30; + color: Text; } .button:disabled, .button[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button:active { - background-color: rgba(185, 125, 242, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: PrimaryA20; + color: TextActive; } .button--primary { - border-color: rgba(185, 125, 242, 0.8); - background-color: rgba(185, 125, 242, 0.05); - color: #CCCCCC; + border-color: PrimaryA80; + background-color: PrimaryA5; + color: TextDim; } .button--primary:focus, .button--primary:hover { - border-color: #B97DF2; - background-color: rgba(185, 125, 242, 0.3); - color: #F2F2F2; + border-color: Primary; + background-color: PrimaryA30; + color: Text; } .button--primary:disabled, .button--primary[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--primary:active { - background-color: rgba(185, 125, 242, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: PrimaryA20; + color: TextActive; } .button--secondary { - border-color: rgba(23, 214, 232, 0.8); - background-color: rgba(23, 214, 232, 0.05); - color: #CCCCCC; + border-color: SecondaryA80; + background-color: SecondaryA5; + color: TextDim; } .button--secondary:focus, .button--secondary:hover { - border-color: #17D6E8; - background-color: rgba(23, 214, 232, 0.3); - color: #F2F2F2; + border-color: Secondary; + background-color: SecondaryA30; + color: Text; } .button--secondary:disabled, .button--secondary[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--secondary:active { - background-color: rgba(23, 214, 232, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: SecondaryA20; + color: TextActive; } .button--tertiary { - border-color: rgba(242, 242, 242, 0.8); - background-color: rgba(242, 242, 242, 0.05); - color: #CCCCCC; + border-color: TextA80; + background-color: TextA5; + color: TextDim; } .button--tertiary:focus, .button--tertiary:hover { - border-color: #F2F2F2; - background-color: rgba(242, 242, 242, 0.3); - color: #F2F2F2; + border-color: Text; + background-color: TextA30; + color: Text; } .button--tertiary:disabled, .button--tertiary[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--tertiary:active { - background-color: rgba(242, 242, 242, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: TextA20; + color: TextActive; } .button--success { - border-color: rgba(69, 208, 67, 0.8); - background-color: rgba(69, 208, 67, 0.05); - color: #CCCCCC; + border-color: SuccessA80; + background-color: SuccessA5; + color: TextDim; } .button--success:focus, .button--success:hover { - border-color: #45D043; - background-color: rgba(69, 208, 67, 0.3); - color: #F2F2F2; + border-color: Success; + background-color: SuccessA30; + color: Text; } .button--success:disabled, .button--success[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--success:active { - background-color: rgba(69, 208, 67, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: SuccessA20; + color: TextActive; } -.button--error { - border-color: rgba(248, 96, 57, 0.8); - background-color: rgba(248, 96, 57, 0.05); - color: #CCCCCC; +.button--danger { + border-color: DangerA80; + background-color: DangerA5; + color: TextDim; } -.button--error:focus, .button--error:hover { - border-color: #F86039; - background-color: rgba(248, 96, 57, 0.3); - color: #F2F2F2; +.button--danger:focus, .button--danger:hover { + border-color: Danger; + background-color: DangerA30; + color: Text; } -.button--error:disabled, .button--error[disabled] { - color: rgba(255, 255, 255, 0.6); +.button--danger:disabled, .button--danger[disabled] { + color: TextInactive; } -.button--error:active { - background-color: rgba(248, 96, 57, 0.2); - color: rgb(244.6, 244.6, 244.6); +.button--danger:active { + background-color: DangerA20; + color: TextActive; } .button--warning { - border-color: rgba(233, 205, 53, 0.8); - background-color: rgba(233, 205, 53, 0.05); - color: #CCCCCC; + border-color: WarningA80; + background-color: WarningA5; + color: TextDim; } .button--warning:focus, .button--warning:hover { - border-color: #E9CD35; - background-color: rgba(233, 205, 53, 0.3); - color: #F2F2F2; + border-color: Warning; + background-color: WarningA30; + color: Text; } .button--warning:disabled, .button--warning[disabled] { - color: rgba(255, 255, 255, 0.6); + color: TextInactive; } .button--warning:active { - background-color: rgba(233, 205, 53, 0.2); - color: rgb(244.6, 244.6, 244.6); + background-color: WarningA20; + color: TextActive; } .button:not([disabled]) { cursor: pointer; @@ -1800,13 +1805,13 @@ scrollbarhorizontal sliderbar { /* */ .icon-button { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; display: flex; align-items: center; @@ -1819,35 +1824,35 @@ scrollbarhorizontal sliderbar { max-height: 53.8dp; border-width: 1.1dp; border-radius: 26.9dp; - border-color: rgba(0, 0, 0, 0); - background-color: rgba(0, 0, 0, 0); + border-color: Transparent; + background-color: Transparent; } .icon-button svg { - image-color: #CCCCCC; + image-color: TextDim; } .icon-button svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .icon-button:focus, .icon-button:hover { - color: #F2F2F2; - background-color: rgba(255, 255, 255, 0.2); + color: Text; + background-color: Border; } .icon-button:focus svg, .icon-button:hover svg { - image-color: #F2F2F2; + image-color: Text; } .icon-button:active { - color: rgb(244.6, 244.6, 244.6); - background-color: rgba(255, 255, 255, 0.1); + color: TextActive; + background-color: BorderSoft; } .icon-button:active svg { - image-color: rgb(244.6, 244.6, 244.6); + image-color: TextActive; } .icon-button:disabled, .icon-button[disabled] { - color: #CCCCCC; + color: TextDim; opacity: 0.5; } .icon-button:disabled svg, .icon-button[disabled] svg { - image-color: #CCCCCC; + image-color: TextDim; } .icon-button:not([disabled]) { cursor: pointer; @@ -1857,70 +1862,70 @@ scrollbarhorizontal sliderbar { height: 32dp; } .icon-button--primary { - border-color: rgba(185, 125, 242, 0.8); - background-color: rgba(185, 125, 242, 0.05); + border-color: PrimaryA80; + background-color: PrimaryA5; } .icon-button--primary:focus, .icon-button--primary:hover { - border-color: #B97DF2; - background-color: rgba(185, 125, 242, 0.3); + border-color: Primary; + background-color: PrimaryA30; } .icon-button--primary:active { - background-color: rgba(185, 125, 242, 0.2); + background-color: PrimaryA20; } .icon-button--secondary { - border-color: rgba(23, 214, 232, 0.8); - background-color: rgba(23, 214, 232, 0.05); + border-color: SecondaryA80; + background-color: SecondaryA5; } .icon-button--secondary:focus, .icon-button--secondary:hover { - border-color: #17D6E8; - background-color: rgba(23, 214, 232, 0.3); + border-color: Secondary; + background-color: SecondaryA30; } .icon-button--secondary:active { - background-color: rgba(23, 214, 232, 0.2); + background-color: SecondaryA20; } .icon-button--tertiary { - border-color: rgba(242, 242, 242, 0.8); - background-color: rgba(242, 242, 242, 0.05); + border-color: TextA80; + background-color: TextA5; } .icon-button--tertiary:focus, .icon-button--tertiary:hover { - border-color: #F2F2F2; - background-color: rgba(242, 242, 242, 0.3); + border-color: Text; + background-color: TextA30; } .icon-button--tertiary:active { - background-color: rgba(242, 242, 242, 0.2); + background-color: TextA20; } .icon-button--success { - border-color: rgba(69, 208, 67, 0.8); - background-color: rgba(69, 208, 67, 0.05); + border-color: SuccessA80; + background-color: SuccessA5; } .icon-button--success:focus, .icon-button--success:hover { - border-color: #45D043; - background-color: rgba(69, 208, 67, 0.3); + border-color: Success; + background-color: SuccessA30; } .icon-button--success:active { - background-color: rgba(69, 208, 67, 0.2); + background-color: SuccessA20; } -.icon-button--error { - border-color: rgba(248, 96, 57, 0.8); - background-color: rgba(248, 96, 57, 0.05); +.icon-button--danger { + border-color: DangerA80; + background-color: DangerA5; } -.icon-button--error:focus, .icon-button--error:hover { - border-color: #F86039; - background-color: rgba(248, 96, 57, 0.3); +.icon-button--danger:focus, .icon-button--danger:hover { + border-color: Danger; + background-color: DangerA30; } -.icon-button--error:active { - background-color: rgba(248, 96, 57, 0.2); +.icon-button--danger:active { + background-color: DangerA20; } .icon-button--warning { - border-color: rgba(233, 205, 53, 0.8); - background-color: rgba(233, 205, 53, 0.05); + border-color: WarningA80; + background-color: WarningA5; } .icon-button--warning:focus, .icon-button--warning:hover { - border-color: #E9CD35; - background-color: rgba(233, 205, 53, 0.3); + border-color: Warning; + background-color: WarningA30; } .icon-button--warning:active { - background-color: rgba(233, 205, 53, 0.2); + background-color: WarningA20; } .launcher { @@ -1930,7 +1935,7 @@ scrollbarhorizontal sliderbar { justify-content: space-between; width: 100%; height: 100%; - background-color: #08070D; + background-color: Background1; } .launcher__vertical-split { @@ -2027,7 +2032,7 @@ scrollbarhorizontal sliderbar { */ .menu-list-item { - color: #CCCCCC; + color: TextDim; display: flex; flex-direction: row; align-items: center; @@ -2039,7 +2044,7 @@ scrollbarhorizontal sliderbar { cursor: pointer; } .menu-list-item svg { - image-color: #CCCCCC; + image-color: TextDim; } .menu-list-item--right { flex-direction: row-reverse; @@ -2050,14 +2055,14 @@ scrollbarhorizontal sliderbar { opacity: 1; } .menu-list-item--right.menu-list-item:focus:not(:disabled, [disabled]), .menu-list-item--right.menu-list-item:hover:not(:disabled, [disabled]) { - decorator: horizontal-gradient(#7A2AC600 #DABAF714); + background-color: WhiteA5; } .menu-list-item:focus:not(:disabled, [disabled]), .menu-list-item:hover:not(:disabled, [disabled]) { - color: #B97DF2; - decorator: horizontal-gradient(#7A2AC614 #DABAF700); + color: Primary; + background-color: WhiteA5; } .menu-list-item:focus:not(:disabled, [disabled]) svg, .menu-list-item:hover:not(:disabled, [disabled]) svg { - image-color: #B97DF2; + image-color: Primary; } .menu-list-item:focus:not(:disabled, [disabled]) .menu-list-item__bullet, .menu-list-item:hover:not(:disabled, [disabled]) .menu-list-item__bullet { opacity: 1; @@ -2097,7 +2102,7 @@ scrollbarhorizontal sliderbar { height: auto; padding: 0; background-color: rgba(0, 0, 0, 0); - color: #CCCCCC; + color: TextDim; text-align: left; cursor: pointer; } @@ -2108,11 +2113,11 @@ scrollbarhorizontal sliderbar { text-align: right; } .subtitle-title[selected] { - color: #F2F2F2; + color: Text; cursor: default; } .subtitle-title:focus:not(:disabled, [disabled]), .subtitle-title:hover:not(:disabled, [disabled], [selected]) { - color: #B97DF2; + color: Primary; } .subtitle-title:disabled, .subtitle-title[disabled] { opacity: 0.5; @@ -2140,16 +2145,16 @@ scrollbarhorizontal sliderbar { height: 72dp; border-radius: 36dp; opacity: 0.9; - background: rgba(0, 0, 0, 0); + background: Transparent; cursor: pointer; } .toggle:hover, .toggle:focus-visible, .toggle:focus { opacity: 1; - background-color: rgba(23, 214, 232, 0.3); + background-color: SecondaryA30; } .toggle:active { opacity: 1; - background-color: rgba(23, 214, 232, 0.05); + background-color: SecondaryA5; } .toggle .toggle__border { position: absolute; @@ -2158,7 +2163,7 @@ scrollbarhorizontal sliderbar { bottom: 1.1dp; left: 1.1dp; border-width: 1.1dp; - border-color: #A2EFF6; + border-color: SecondaryL; display: block; border-radius: 36dp; } @@ -2170,18 +2175,18 @@ scrollbarhorizontal sliderbar { height: 64dp; transform: translateY(-50%); border-radius: 32dp; - background: #25A1AD; + background: SecondaryD; } .toggle--checked .toggle__floater { left: 78dp; } .toggle--checked .toggle__icon.toggle__icon--left { opacity: 0.9; - color: #A2EFF6; + color: SecondaryL; } .toggle--checked .toggle__icon.toggle__icon--right { opacity: 1; - color: #F2F2F2; + color: Text; } .toggle__icons { @@ -2203,11 +2208,11 @@ scrollbarhorizontal sliderbar { justify-content: center; width: 56dp; height: 56dp; - color: #F2F2F2; + color: Text; } .toggle__icon--right { opacity: 1; - color: #A2EFF6; + color: SecondaryL; } .bottom-left { @@ -2224,7 +2229,7 @@ scrollbarhorizontal sliderbar { } .prompt__overlay { - background-color: rgba(190, 184, 219, 0.1); + background-color: BGOverlay; pointer-events: auto; } .prompt__overlay, .prompt__content-wrapper { @@ -2255,8 +2260,8 @@ scrollbarhorizontal sliderbar { margin: auto; border-width: 1.1dp; border-radius: 16dp; - border-color: rgba(255, 255, 255, 0.2); - background: rgba(8, 7, 13, 0.9); + border-color: Border; + background: ModalOverlay; } .prompt__content h3, .prompt__content p { margin: 24dp; @@ -2270,7 +2275,7 @@ scrollbarhorizontal sliderbar { justify-content: center; padding: 24dp 12dp; border-top-width: 1.1dp; - border-top-color: rgba(255, 255, 255, 0.1); + border-top-color: BorderSoft; } .prompt__controls .button { min-width: 233.3333333333dp; @@ -2297,10 +2302,10 @@ scrollbarhorizontal sliderbar { } .config-debug-option { - color: #CCCCCC; + color: TextDim; transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out; border-bottom-width: 1.1dp; - border-bottom-color: rgba(255, 255, 255, 0.1); + border-bottom-color: BorderSoft; display: block; position: relative; flex-direction: column; @@ -2310,17 +2315,17 @@ scrollbarhorizontal sliderbar { background-color: rgba(0, 0, 0, 0); } .config-debug-option svg { - image-color: #CCCCCC; + image-color: TextDim; } .config-debug-option svg { transition: image-color 0.05s linear-in-out, background-color 0.05s linear-in-out; } .config-debug-option:focus:not(:disabled, [disabled]), .config-debug-option:focus-visible:not(:disabled, [disabled]), .config-debug-option:hover:not(:disabled, [disabled]) { - color: #F2F2F2; - background-color: rgba(190, 184, 219, 0.1); + color: Text; + background-color: BGOverlay; } .config-debug-option:focus:not(:disabled, [disabled]) svg, .config-debug-option:focus-visible:not(:disabled, [disabled]) svg, .config-debug-option:hover:not(:disabled, [disabled]) svg { - image-color: #F2F2F2; + image-color: Text; } .config-debug-option:disabled, .config-debug-option[disabled] { opacity: 0.5; @@ -2396,7 +2401,7 @@ scrollbarhorizontal sliderbar { .config-debug__select-wrapper select { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out, opacity 0.05s linear-in-out, border-color 0.05s linear-in-out; border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.5); + border-color: WhiteA50; display: block; position: relative; box-sizing: border-box; @@ -2405,7 +2410,7 @@ scrollbarhorizontal sliderbar { width: auto; height: 48dp; border-radius: 12dp; - background-color: rgba(255, 255, 255, 0.05); + background-color: WhiteA5; cursor: pointer; align-items: center; justify-content: flex-start; @@ -2416,8 +2421,8 @@ scrollbarhorizontal sliderbar { } .config-debug__select-wrapper select:hover, .config-debug__select-wrapper select:focus { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.8); - background-color: rgba(255, 255, 255, 0.2); + border-color: WhiteA80; + background-color: WhiteA20; } .config-debug__select-wrapper select selectvalue { display: inline; @@ -2426,8 +2431,8 @@ scrollbarhorizontal sliderbar { } .config-debug__select-wrapper select selectbox { border-width: 1.1dp; - border-color: rgba(255, 255, 255, 0.8); - background-color: #191622; + border-color: WhiteA80; + background-color: Background3; padding: 4dp 0; margin-top: 2dp; border-radius: 12dp; @@ -2435,25 +2440,19 @@ scrollbarhorizontal sliderbar { .config-debug__select-wrapper select selectbox option { transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; padding: 8dp 12dp; - background-color: rgba(0, 0, 0, 0); - color: #CCCCCC; + background-color: Transparent; + color: TextDim; font-weight: 400; } .config-debug__select-wrapper select selectbox option:hover, .config-debug__select-wrapper select selectbox option:focus { - background-color: rgba(255, 255, 255, 0.2); + background-color: WhiteA20; } .config-debug__select-wrapper select selectbox option:hover:not(:checked) { cursor: pointer; } .config-debug__select-wrapper select selectbox option:checked { - color: #FFFFFF; - background-color: rgba(255, 255, 255, 0.05); -} - -body { - box-sizing: border-box; - color: #F2F2F2; - font-family: LatoLatin; + color: White; + background-color: WhiteA5; } .rmlui-window { @@ -2471,42 +2470,42 @@ body { } button { - background-color: #7A2AC6; + background-color: PrimaryD; } @keyframes blue-pulse { 0% { - color: #17D6E8; + color: Secondary; } 50% { - color: #A2EFF6; + color: SecondaryL; } 100% { - color: #17D6E8; + color: Secondary; } } @keyframes blue-pulse-with-border { 0% { - border-color: #17D6E8; - color: #17D6E8; + border-color: Secondary; + color: Secondary; } 50% { - border-color: #A2EFF6; - color: #A2EFF6; + border-color: SecondaryL; + color: SecondaryL; } 100% { - border-color: #17D6E8; - color: #17D6E8; + border-color: Secondary; + color: Secondary; } } @keyframes blue-pulse-background { 0% { - background-color: #17D6E8; + background-color: Secondary; } 50% { - background-color: #A2EFF6; + background-color: SecondaryL; } 100% { - background-color: #17D6E8; + background-color: Secondary; } } diff --git a/assets/scss/styles/components/Button.scss b/assets/scss/styles/components/Button.scss index d5d1514..b7f8086 100644 --- a/assets/scss/styles/components/Button.scss +++ b/assets/scss/styles/components/Button.scss @@ -1,13 +1,13 @@ @use 'sass:color'; -@mixin create-button-variation($base-col) { - border-color: rgba($base-col, 0.8); - background-color: rgba($base-col, 0.05); +@mixin create-button-variation($base-col, $base-col-05, $base-col-20, $base-col-30, $base-col-80) { + border-color: $base-col-80; + background-color: $base-col-05; color: $color-text-dim; &:focus, &:hover { border-color: $base-col; - background-color: rgba($base-col, 0.3); + background-color: $base-col-30; color: $color-text; } @@ -16,15 +16,15 @@ } &:active { - background-color: rgba($base-col, 0.2); - color: color.scale($color-text, $lightness: 20%); + background-color: $base-col-20; + color: $color-text-active; } } .button { @extend %label-md; @extend %nav-all; - @include create-button-variation($color-primary); + @include create-button-variation($color-primary, $color-primary-a5, $color-primary-a20, $color-primary-a30, $color-primary-a80); @include trans-colors; display: block; @@ -38,7 +38,7 @@ // Setting it by default for convenience &--primary { - @include create-button-variation($color-primary); + @include create-button-variation($color-primary, $color-primary-a5, $color-primary-a20, $color-primary-a30, $color-primary-a80); } &--large { @@ -46,23 +46,23 @@ } &--secondary { - @include create-button-variation($color-secondary); + @include create-button-variation($color-secondary, $color-secondary-a5, $color-secondary-a20, $color-secondary-a30, $color-secondary-a80); } &--tertiary { - @include create-button-variation($color-text); + @include create-button-variation($color-text, $color-text-a5, $color-text-a20, $color-text-a30, $color-text-a80); } &--success { - @include create-button-variation($color-success); + @include create-button-variation($color-success, $color-success-a5, $color-success-a20, $color-success-a30, $color-success-a80); } - &--error { - @include create-button-variation($color-error); + &--danger { + @include create-button-variation($color-danger, $color-danger-a5, $color-danger-a20, $color-danger-a30, $color-danger-a80); } &--warning { - @include create-button-variation($color-warning); + @include create-button-variation($color-warning, $color-warning-a5, $color-warning-a20, $color-warning-a30, $color-warning-a80); } &:not([disabled]) { diff --git a/assets/scss/styles/components/ControlOption.scss b/assets/scss/styles/components/ControlOption.scss index 662fd63..16c086e 100644 --- a/assets/scss/styles/components/ControlOption.scss +++ b/assets/scss/styles/components/ControlOption.scss @@ -31,7 +31,7 @@ @each $slot in $valid-binding-slots { // global attr -> this active row -> binding slot [cur-binding-slot="#{$slot}"] & .control-option__binding[bind-slot="#{$slot}"] { - border-color: $color-error; + border-color: $color-danger; .control-option__binding-icon { opacity: 0; @@ -93,7 +93,7 @@ } &:active { - @include set-color(color.scale($color-text, $lightness: 20%)); + @include set-color($color-text-active); } &:disabled, &[disabled] { @@ -145,7 +145,7 @@ height: space($rec-size); animation: 1.5s sine-in-out infinite control-option__binding-recording-scale; border-radius: space($rec-size); - background-color: $color-error; + background-color: $color-danger; } .control-option__binding-edge { @@ -164,7 +164,7 @@ > svg.control-option__binding-edge-svg { width: space($edge-size); height: space($edge-size); - image-color: $color-error; + image-color: $color-danger; } } } diff --git a/assets/scss/styles/components/IconButton.scss b/assets/scss/styles/components/IconButton.scss index 4e1822a..fc22121 100644 --- a/assets/scss/styles/components/IconButton.scss +++ b/assets/scss/styles/components/IconButton.scss @@ -2,22 +2,22 @@ /* */ -@mixin create-icon-button-variation($base-col) { - border-color: rgba($base-col, 0.8); - background-color: rgba($base-col, 0.05); +@mixin create-icon-button-variation($base-col, $base-col-05, $base-col-20, $base-col-30, $base-col-80) { + border-color: $base-col-80; + background-color: $base-col-05; &:focus, &:hover { border-color: $base-col; - background-color: rgba($base-col, 0.3); + background-color: $base-col-30; } &:active { - background-color: rgba($base-col, 0.2); + background-color: $base-col-20; } } @@ -47,7 +47,7 @@ $icon-button-size: 56 - ($border-width-thickness-num * 2); } &:active { - @include set-color(color.scale($color-text, $lightness: 20%)); + @include set-color($color-text-active); background-color: $color-border-soft; } @@ -67,26 +67,26 @@ $icon-button-size: 56 - ($border-width-thickness-num * 2); } &--primary { - @include create-icon-button-variation($color-primary); + @include create-icon-button-variation($color-primary, $color-primary-a5, $color-primary-a20, $color-primary-a30, $color-primary-a80); } &--secondary { - @include create-icon-button-variation($color-secondary); + @include create-icon-button-variation($color-secondary, $color-secondary-a5, $color-secondary-a20, $color-secondary-a30, $color-secondary-a80); } &--tertiary { - @include create-icon-button-variation($color-text); + @include create-icon-button-variation($color-text, $color-text-a5, $color-text-a20, $color-text-a30, $color-text-a80); } &--success { - @include create-icon-button-variation($color-success); + @include create-icon-button-variation($color-success, $color-success-a5, $color-success-a20, $color-success-a30, $color-success-a80); } - &--error { - @include create-icon-button-variation($color-error); + &--danger { + @include create-icon-button-variation($color-danger, $color-danger-a5, $color-danger-a20, $color-danger-a30, $color-danger-a80); } &--warning { - @include create-icon-button-variation($color-warning); + @include create-icon-button-variation($color-warning, $color-warning-a5, $color-warning-a20, $color-warning-a30, $color-warning-a80); } } diff --git a/assets/scss/styles/components/InputConfig.scss b/assets/scss/styles/components/InputConfig.scss index 71ba960..b2cae6d 100644 --- a/assets/scss/styles/components/InputConfig.scss +++ b/assets/scss/styles/components/InputConfig.scss @@ -195,7 +195,7 @@ $all-inputs: A, } &--Start { - @include set-svgs-color($color-error); + @include set-svgs-color($color-danger); } } diff --git a/assets/scss/styles/components/MenuListItem.scss b/assets/scss/styles/components/MenuListItem.scss index 657f0ef..4fb63aa 100644 --- a/assets/scss/styles/components/MenuListItem.scss +++ b/assets/scss/styles/components/MenuListItem.scss @@ -35,14 +35,16 @@ &.menu-list-item:focus:not(:disabled, [disabled]), &.menu-list-item:hover:not(:disabled, [disabled]) { - decorator: $primary-rl-fade; + // decorator: $primary-rl-fade; + background-color: $color-white-a5; } } &:focus:not(:disabled, [disabled]), &:hover:not(:disabled, [disabled]) { @include set-color($color-primary); - decorator: $primary-lr-fade; + // decorator: $primary-lr-fade; + background-color: $color-white-a5; .menu-list-item__bullet { opacity: 1; diff --git a/assets/scss/styles/global.scss b/assets/scss/styles/global.scss index 2e98925..08242f4 100644 --- a/assets/scss/styles/global.scss +++ b/assets/scss/styles/global.scss @@ -1,10 +1,4 @@ @import "./base"; -@import "./globals/old"; -@import "./globals/scrollbars"; -@import "./components/components"; -@import "./pages/pages"; - -$font-size: 20dp; body { @@ -14,6 +8,14 @@ body font-family: $font-stack; } +@import "./globals/old"; +@import "./globals/scrollbars"; +@import "./components/components"; +@import "./pages/pages"; + +$font-size: 20dp; + + .rmlui-window { opacity: 1; diff --git a/assets/scss/styles/globals/_old.scss b/assets/scss/styles/globals/_old.scss index 706fb94..4343b32 100644 --- a/assets/scss/styles/globals/_old.scss +++ b/assets/scss/styles/globals/_old.scss @@ -13,7 +13,6 @@ hr { body { color: #fff; - font-family: LatoLatin; font-size: 20dp; font-style: normal; font-weight: normal diff --git a/assets/scss/styles/mixins/_typography.scss b/assets/scss/styles/mixins/_typography.scss index fde69e0..384154c 100644 --- a/assets/scss/styles/mixins/_typography.scss +++ b/assets/scss/styles/mixins/_typography.scss @@ -1,5 +1,5 @@ -$font-stack: LatoLatin; +$font-stack: 'Suplexmentary Comic NC'; @mixin set-font-sizing($sz, $spacing) { // font-family: $font-stack; diff --git a/assets/scss/styles/vars/_colors.scss b/assets/scss/styles/vars/_colors.scss index 0b5cfd7..37e3b1e 100644 --- a/assets/scss/styles/vars/_colors.scss +++ b/assets/scss/styles/vars/_colors.scss @@ -1,71 +1,83 @@ /* stylelint-disable color-no-hex, color-hex-length */ -$color-background-1: #08070D; -$color-background-2: #121018; -$color-background-3: #191622; -$color-bg-overlay: rgba(190, 184, 219, 0.1000); -$color-modal-overlay: rgba(8, 7, 13, 0.9000); -$color-bg-shadow: rgba(0, 0, 0, 0.3500); -$color-bg-shadow-2: rgba(8, 7, 13, 0.7200); -$color-text: #F2F2F2; -$color-text-dim: #CCCCCC; -$color-text-inactive: rgba(255, 255, 255, 0.6000); -$color-primary: #B97DF2; -$color-primary-l: #DABAF7; -$color-primary-d: #7A2AC6; -$color-primary-a5: rgba(185, 125, 242, 0.0500); -$color-primary-a20: rgba(185, 125, 242, 0.2000); -$color-primary-a30: rgba(185, 125, 242, 0.3000); -$color-primary-a50: rgba(185, 125, 242, 0.5000); -$color-primary-a80: rgba(185, 125, 242, 0.8000); -$color-secondary: #17D6E8; -$color-secondary-l: #A2EFF6; -$color-secondary-d: #25A1AD; -$color-secondary-a5: rgba(23, 214, 232, 0.0500); -$color-secondary-a20: rgba(23, 214, 232, 0.2000); -$color-secondary-a30: rgba(23, 214, 232, 0.3000); -$color-secondary-a50: rgba(23, 214, 232, 0.5000); -$color-secondary-a80: rgba(23, 214, 232, 0.8000); -$color-warning: #E9CD35; -$color-warning-l: #F9E57C; -$color-warning-d: #C5AA16; -$color-warning-a5: rgba(233, 205, 53, 0.0500); -$color-warning-a20: rgba(233, 205, 53, 0.2000); -$color-warning-a30: rgba(233, 205, 53, 0.3000); -$color-warning-a50: rgba(233, 205, 53, 0.5000); -$color-warning-a80: rgba(233, 205, 53, 0.8000); -$color-error: #F86039; -$color-error-l: #FE8667; -$color-error-d: #B23919; -$color-error-a5: rgba(248, 96, 57, 0.0500); -$color-error-a20: rgba(248, 96, 57, 0.2000); -$color-error-a30: rgba(248, 96, 57, 0.3000); -$color-error-a50: rgba(248, 96, 57, 0.5000); -$color-error-a80: rgba(248, 96, 57, 0.8000); -$color-success: #45D043; -$color-success-l: #AAEAA9; -$color-success-d: #2CA72A; -$color-success-a5: rgba(69, 208, 67, 0.0500); -$color-success-a20: rgba(69, 208, 67, 0.2000); -$color-success-a30: rgba(69, 208, 67, 0.3000); -$color-success-a50: rgba(69, 208, 67, 0.5000); -$color-success-a80: rgba(69, 208, 67, 0.8000); -$color-border: rgba(255, 255, 255, 0.2000); -$color-border-soft: rgba(255, 255, 255, 0.1000); -$color-border-hard: rgba(255, 255, 255, 0.3000); -$color-border-solid: rgba(255, 255, 255, 0.6000); -$color-transparent: rgba(0, 0, 0, 0.0000); -$color-a: #3333FF; -$color-a-l: #B2B2FF; -$color-a-d: #2020AC; -$color-a-a5: rgba(51, 51, 255, 0.0500); -$color-a-a20: rgba(51, 51, 255, 0.2000); -$color-a-a30: rgba(51, 51, 255, 0.3000); -$color-a-a50: rgba(51, 51, 255, 0.5000); -$color-a-a80: rgba(51, 51, 255, 0.8000); -$color-white: #FFFFFF; -$color-white-a5: rgba(255, 255, 255, 0.0500); -$color-white-a20: rgba(255, 255, 255, 0.2000); -$color-white-a30: rgba(255, 255, 255, 0.3000); -$color-white-a50: rgba(255, 255, 255, 0.5000); -$color-white-a80: rgba(255, 255, 255, 0.8000); +$color-background-1: Background1; +$color-background-2: Background2; +$color-background-3: Background3; +$color-bg-overlay: BGOverlay; +$color-modal-overlay: ModalOverlay; +$color-bg-shadow: BGShadow; +$color-bg-shadow-2: BGShadow2; +$color-text: Text; +$color-text-active: TextActive; +$color-text-dim: TextDim; +$color-text-inactive: TextInactive; +$color-text-a5: TextA5; +$color-text-a20: TextA20; +$color-text-a30: TextA30; +$color-text-a50: TextA50; +$color-text-a80: TextA80; +$color-primary: Primary; +$color-primary-l: PrimaryL; +$color-primary-d: PrimaryD; +$color-primary-a5: PrimaryA5; +$color-primary-a20: PrimaryA20; +$color-primary-a30: PrimaryA30; +$color-primary-a50: PrimaryA50; +$color-primary-a80: PrimaryA80; +$color-secondary: Secondary; +$color-secondary-l: SecondaryL; +$color-secondary-d: SecondaryD; +$color-secondary-a5: SecondaryA5; +$color-secondary-a20: SecondaryA20; +$color-secondary-a30: SecondaryA30; +$color-secondary-a50: SecondaryA50; +$color-secondary-a80: SecondaryA80; +$color-warning: Warning; +$color-warning-l: WarningL; +$color-warning-d: WarningD; +$color-warning-a5: WarningA5; +$color-warning-a20: WarningA20; +$color-warning-a30: WarningA30; +$color-warning-a50: WarningA50; +$color-warning-a80: WarningA80; +$color-danger: Danger; +$color-danger-l: DangerL; +$color-danger-d: DangerD; +$color-danger-a5: DangerA5; +$color-danger-a20: DangerA20; +$color-danger-a30: DangerA30; +$color-danger-a50: DangerA50; +$color-danger-a80: DangerA80; +$color-success: Success; +$color-success-l: SuccessL; +$color-success-d: SuccessD; +$color-success-a5: SuccessA5; +$color-success-a20: SuccessA20; +$color-success-a30: SuccessA30; +$color-success-a50: SuccessA50; +$color-success-a80: SuccessA80; +$color-border: Border; +$color-border-soft: BorderSoft; +$color-border-hard: BorderHard; +$color-border-solid: BorderSolid; +$color-transparent: Transparent; +$color-a: A; +$color-a-l: AL; +$color-a-d: AD; +$color-a-a5: AA5; +$color-a-a20: AA20; +$color-a-a30: AA30; +$color-a-a50: AA50; +$color-a-a80: AA80; +$color-white: White; +$color-white-a5: WhiteA5; +$color-white-a20: WhiteA20; +$color-white-a30: WhiteA30; +$color-white-a50: WhiteA50; +$color-white-a80: WhiteA80; +$color-bw-05: BW05; +$color-bw-10: BW10; +$color-bw-25: BW25; +$color-bw-50: BW50; +$color-bw-75: BW75; +$color-bw-90: BW90; diff --git a/assets/scss/styles/vars/_gradients.scss b/assets/scss/styles/vars/_gradients.scss index 1cdebd5..b3e2305 100644 --- a/assets/scss/styles/vars/_gradients.scss +++ b/assets/scss/styles/vars/_gradients.scss @@ -3,5 +3,7 @@ // $primary-lr-fade: linear-gradient(90deg, rgba($color-primary-l, 0.08) 0%, rgba($color-primary-l, 0.00) 100%); // $primary-rl-fade: linear-gradient(90deg, rgba($color-primary-l, 0.00) 0%, rgba($color-primary-l, 0.08) 100%); -$primary-lr-fade: horizontal-gradient(#{$color-primary-d}14 #{$color-primary-l}00); -$primary-rl-fade: horizontal-gradient(#{$color-primary-d}00 #{$color-primary-l}14); +// $primary-lr-fade: horizontal-gradient(#{$color-primary-d}14 #{$color-primary-l}00); +// $primary-rl-fade: horizontal-gradient(#{$color-primary-d}00 #{$color-primary-l}14); +$primary-lr-fade: horizontal-gradient(#ff000014 #ff000000); +$primary-rl-fade: horizontal-gradient(#ff000000 #ff000014); diff --git a/include/recomp_ui.h b/include/recomp_ui.h index f609a52..1856ab0 100644 --- a/include/recomp_ui.h +++ b/include/recomp_ui.h @@ -13,6 +13,8 @@ #include "../src/ui/util/hsv.h" #include "../src/ui/util/bem.h" +#include "../src/ui/elements/ui_button.h" +#include "../src/ui/elements/ui_theme.h" #include "../src/ui/core/ui_context.h" @@ -75,16 +77,6 @@ namespace recompui { void set_config_tabset_mod_nav(); void focus_mod_configure_button(); - enum class ButtonVariant { - Primary, - Secondary, - Tertiary, - Success, - Error, - Warning, - NumVariants, - }; - void init_styling(const std::filesystem::path& rcss_file); void init_prompt_context(); void open_choice_prompt( @@ -94,8 +86,8 @@ namespace recompui { const std::string& cancel_label_text, std::function confirm_action, std::function cancel_action, - ButtonVariant confirm_variant = ButtonVariant::Success, - ButtonVariant cancel_variant = ButtonVariant::Error, + ButtonStyle confirm_variant = ButtonStyle::Success, + ButtonStyle cancel_variant = ButtonStyle::Danger, bool focus_on_cancel = true, const std::string& return_element_id = "" ); @@ -104,7 +96,7 @@ namespace recompui { const std::string& content_text, const std::string& okay_label_text, std::function okay_action, - ButtonVariant okay_variant = ButtonVariant::Error, + ButtonStyle okay_variant = ButtonStyle::Danger, const std::string& return_element_id = "" ); void open_notification( diff --git a/src/main/main.cpp b/src/main/main.cpp index dc6839d..10d2902 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -29,6 +29,7 @@ #include "banjo_game.h" #include "recomp_data.h" #include "ovl_patches.hpp" +#include "theme.h" #include "librecomp/game.hpp" #include "librecomp/mods.hpp" #include "librecomp/helpers.hpp" @@ -602,6 +603,7 @@ int main(int argc, char** argv) { REGISTER_FUNC(recomp_get_analog_inverted_axes); recompui::register_ui_exports(); recomputil::register_data_api_exports(); + recomptheme::set_custom_theme(); banjo::register_bk_overlays(); banjo::register_bk_patches(); diff --git a/src/main/theme.cpp b/src/main/theme.cpp new file mode 100644 index 0000000..228f7e4 --- /dev/null +++ b/src/main/theme.cpp @@ -0,0 +1,88 @@ +#include "recomp_ui.h" +#include "theme.h" + +void recomptheme::set_custom_theme() { + recompui::set_theme_color(recompui::ThemeColor::Background1, recompui::Color{2, 7, 18, 255}); + recompui::set_theme_color(recompui::ThemeColor::Background2, recompui::Color{7, 15, 34, 255}); + recompui::set_theme_color(recompui::ThemeColor::Background3, recompui::Color{18, 24, 38, 255}); + recompui::set_theme_color(recompui::ThemeColor::BGOverlay, recompui::Color{182, 194, 221, 26}); + recompui::set_theme_color(recompui::ThemeColor::ModalOverlay, recompui::Color{2, 7, 18, 229}); + recompui::set_theme_color(recompui::ThemeColor::BGShadow, recompui::Color{0, 0, 0, 89}); + recompui::set_theme_color(recompui::ThemeColor::BGShadow2, recompui::Color{2, 7, 18, 184}); + recompui::set_theme_color(recompui::ThemeColor::Text, recompui::Color{242, 242, 242, 255}); + recompui::set_theme_color(recompui::ThemeColor::TextActive, recompui::Color{245, 245, 245, 255}); + recompui::set_theme_color(recompui::ThemeColor::TextDim, recompui::Color{204, 204, 204, 255}); + recompui::set_theme_color(recompui::ThemeColor::TextInactive, recompui::Color{255, 255, 255, 153}); + recompui::set_theme_color(recompui::ThemeColor::TextA5, recompui::Color{242, 242, 242, 13}); + recompui::set_theme_color(recompui::ThemeColor::TextA20, recompui::Color{242, 242, 242, 51}); + recompui::set_theme_color(recompui::ThemeColor::TextA30, recompui::Color{242, 242, 242, 77}); + recompui::set_theme_color(recompui::ThemeColor::TextA50, recompui::Color{242, 242, 242, 128}); + recompui::set_theme_color(recompui::ThemeColor::TextA80, recompui::Color{242, 242, 242, 204}); + recompui::set_theme_color(recompui::ThemeColor::Primary, recompui::Color{29, 93, 226, 255}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryL, recompui::Color{167, 191, 241, 255}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryD, recompui::Color{0, 38, 117, 255}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA5, recompui::Color{29, 93, 226, 13}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA20, recompui::Color{29, 93, 226, 51}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA30, recompui::Color{29, 93, 226, 77}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA50, recompui::Color{29, 93, 226, 128}); + recompui::set_theme_color(recompui::ThemeColor::PrimaryA80, recompui::Color{29, 93, 226, 204}); + recompui::set_theme_color(recompui::ThemeColor::Secondary, recompui::Color{247, 158, 8, 255}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryL, recompui::Color{255, 215, 148, 255}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryD, recompui::Color{224, 141, 0, 255}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA5, recompui::Color{247, 158, 8, 13}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA20, recompui::Color{247, 158, 8, 51}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA30, recompui::Color{247, 158, 8, 77}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA50, recompui::Color{247, 158, 8, 128}); + recompui::set_theme_color(recompui::ThemeColor::SecondaryA80, recompui::Color{247, 158, 8, 204}); + recompui::set_theme_color(recompui::ThemeColor::Warning, recompui::Color{255, 254, 0, 255}); + recompui::set_theme_color(recompui::ThemeColor::WarningL, recompui::Color{255, 254, 143, 255}); + recompui::set_theme_color(recompui::ThemeColor::WarningD, recompui::Color{197, 163, 2, 255}); + recompui::set_theme_color(recompui::ThemeColor::WarningA5, recompui::Color{255, 254, 0, 13}); + recompui::set_theme_color(recompui::ThemeColor::WarningA20, recompui::Color{255, 254, 0, 51}); + recompui::set_theme_color(recompui::ThemeColor::WarningA30, recompui::Color{255, 254, 0, 77}); + recompui::set_theme_color(recompui::ThemeColor::WarningA50, recompui::Color{255, 254, 0, 128}); + recompui::set_theme_color(recompui::ThemeColor::WarningA80, recompui::Color{255, 254, 0, 204}); + recompui::set_theme_color(recompui::ThemeColor::Danger, recompui::Color{255, 53, 31, 255}); + recompui::set_theme_color(recompui::ThemeColor::DangerL, recompui::Color{255, 149, 138, 255}); + recompui::set_theme_color(recompui::ThemeColor::DangerD, recompui::Color{163, 16, 0, 255}); + recompui::set_theme_color(recompui::ThemeColor::DangerA5, recompui::Color{255, 53, 31, 13}); + recompui::set_theme_color(recompui::ThemeColor::DangerA20, recompui::Color{255, 53, 31, 51}); + recompui::set_theme_color(recompui::ThemeColor::DangerA30, recompui::Color{255, 53, 31, 77}); + recompui::set_theme_color(recompui::ThemeColor::DangerA50, recompui::Color{255, 53, 31, 128}); + recompui::set_theme_color(recompui::ThemeColor::DangerA80, recompui::Color{255, 53, 31, 204}); + recompui::set_theme_color(recompui::ThemeColor::Success, recompui::Color{40, 238, 32, 255}); + recompui::set_theme_color(recompui::ThemeColor::SuccessL, recompui::Color{155, 247, 151, 255}); + recompui::set_theme_color(recompui::ThemeColor::SuccessD, recompui::Color{18, 157, 12, 255}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA5, recompui::Color{40, 238, 32, 13}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA20, recompui::Color{40, 238, 32, 51}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA30, recompui::Color{40, 238, 32, 77}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA50, recompui::Color{40, 238, 32, 128}); + recompui::set_theme_color(recompui::ThemeColor::SuccessA80, recompui::Color{40, 238, 32, 204}); + recompui::set_theme_color(recompui::ThemeColor::Border, recompui::Color{255, 255, 255, 51}); + recompui::set_theme_color(recompui::ThemeColor::BorderSoft, recompui::Color{255, 255, 255, 26}); + recompui::set_theme_color(recompui::ThemeColor::BorderHard, recompui::Color{255, 255, 255, 77}); + recompui::set_theme_color(recompui::ThemeColor::BorderSolid, recompui::Color{255, 255, 255, 153}); + recompui::set_theme_color(recompui::ThemeColor::Transparent, recompui::Color{0, 0, 0, 0}); + recompui::set_theme_color(recompui::ThemeColor::A, recompui::Color{51, 51, 255, 255}); + recompui::set_theme_color(recompui::ThemeColor::AL, recompui::Color{178, 178, 255, 255}); + recompui::set_theme_color(recompui::ThemeColor::AD, recompui::Color{32, 32, 172, 255}); + recompui::set_theme_color(recompui::ThemeColor::AA5, recompui::Color{51, 51, 255, 13}); + recompui::set_theme_color(recompui::ThemeColor::AA20, recompui::Color{51, 51, 255, 51}); + recompui::set_theme_color(recompui::ThemeColor::AA30, recompui::Color{51, 51, 255, 77}); + recompui::set_theme_color(recompui::ThemeColor::AA50, recompui::Color{51, 51, 255, 128}); + recompui::set_theme_color(recompui::ThemeColor::AA80, recompui::Color{51, 51, 255, 204}); + recompui::set_theme_color(recompui::ThemeColor::White, recompui::Color{255, 255, 255, 255}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA5, recompui::Color{255, 255, 255, 13}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA20, recompui::Color{255, 255, 255, 51}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA30, recompui::Color{255, 255, 255, 77}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA50, recompui::Color{255, 255, 255, 128}); + recompui::set_theme_color(recompui::ThemeColor::WhiteA80, recompui::Color{255, 255, 255, 204}); + recompui::set_theme_color(recompui::ThemeColor::BW05, recompui::Color{13, 13, 13, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW10, recompui::Color{26, 26, 26, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW25, recompui::Color{64, 64, 64, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW50, recompui::Color{128, 128, 128, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW75, recompui::Color{191, 191, 191, 255}); + recompui::set_theme_color(recompui::ThemeColor::BW90, recompui::Color{229, 229, 229, 255}); +}; + + diff --git a/src/main/theme.h b/src/main/theme.h new file mode 100644 index 0000000..deaa66b --- /dev/null +++ b/src/main/theme.h @@ -0,0 +1,6 @@ +#pragma once + +namespace recomptheme { + // Applies custom themes. recompui::apply_color_hack MUST be called after. + void set_custom_theme(); +} // namespace recomptheme diff --git a/src/ui/elements/ui_button.cpp b/src/ui/elements/ui_button.cpp index 23bbf7b..c3e51a3 100644 --- a/src/ui/elements/ui_button.cpp +++ b/src/ui/elements/ui_button.cpp @@ -20,53 +20,14 @@ namespace recompui { set_font_style(FontStyle::Normal); set_font_weight(700); set_cursor(Cursor::Pointer); - set_color(Color{ 204, 204, 204, 255 }); + set_color(ThemeColor::Text); set_tab_index(TabIndex::Auto); - hover_style.set_color(Color{ 242, 242, 242, 255 }); - focus_style.set_color(Color{ 242, 242, 242, 255 }); - disabled_style.set_color(Color{ 204, 204, 204, 128 }); - hover_disabled_style.set_color(Color{ 242, 242, 242, 128 }); + hover_style.set_color(ThemeColor::Text); + focus_style.set_color(ThemeColor::Text); + disabled_style.set_color(ThemeColor::TextDim, 128); + hover_disabled_style.set_color(ThemeColor::Text, 128); - const uint8_t border_opacity = 204; - const uint8_t background_opacity = 13; - const uint8_t border_hover_opacity = 255; - const uint8_t background_hover_opacity = 76; - switch (style) { - case ButtonStyle::Primary: { - set_border_color({ 185, 125, 242, border_opacity }); - set_background_color({ 185, 125, 242, background_opacity }); - hover_style.set_border_color({ 185, 125, 242, border_hover_opacity }); - hover_style.set_background_color({ 185, 125, 242, background_hover_opacity }); - focus_style.set_border_color({ 185, 125, 242, border_hover_opacity }); - focus_style.set_background_color({ 185, 125, 242, background_hover_opacity }); - disabled_style.set_border_color({ 185, 125, 242, border_opacity / 4 }); - disabled_style.set_background_color({ 185, 125, 242, background_opacity / 4 }); - hover_disabled_style.set_border_color({ 185, 125, 242, border_hover_opacity / 4 }); - hover_disabled_style.set_background_color({ 185, 125, 242, background_hover_opacity / 4 }); - break; - } - case ButtonStyle::Secondary: { - set_border_color({ 23, 214, 232, border_opacity }); - set_background_color({ 23, 214, 232, background_opacity }); - hover_style.set_border_color({ 23, 214, 232, border_hover_opacity }); - hover_style.set_background_color({ 23, 214, 232, background_hover_opacity }); - focus_style.set_border_color({ 23, 214, 232, border_hover_opacity }); - focus_style.set_background_color({ 23, 214, 232, background_hover_opacity }); - disabled_style.set_border_color({ 23, 214, 232, border_opacity / 4 }); - disabled_style.set_background_color({ 23, 214, 232, background_opacity / 4 }); - hover_disabled_style.set_border_color({ 23, 214, 232, border_hover_opacity / 4 }); - hover_disabled_style.set_background_color({ 23, 214, 232, background_hover_opacity / 4 }); - break; - } - default: - assert(false && "Unknown button style."); - break; - } - - add_style(&hover_style, hover_state); - add_style(&focus_style, focus_state); - add_style(&disabled_style, disabled_state); - add_style(&hover_disabled_style, { hover_state, disabled_state }); + apply_button_style(style); // transition: color 0.05s linear-in-out, background-color 0.05s linear-in-out; } @@ -111,4 +72,60 @@ namespace recompui { void Button::add_pressed_callback(std::function callback) { pressed_callbacks.emplace_back(callback); } -}; \ No newline at end of file + + void Button::apply_button_style(ButtonStyle new_style) { + style = new_style; + switch (style) { + case ButtonStyle::Primary: { + apply_theme_style(ThemeColor::Primary); + break; + } + case ButtonStyle::Secondary: { + apply_theme_style(ThemeColor::Secondary); + break; + } + case ButtonStyle::Tertiary: { + apply_theme_style(ThemeColor::Text); + break; + } + case ButtonStyle::Success: { + apply_theme_style(ThemeColor::Success); + break; + } + case ButtonStyle::Warning: { + apply_theme_style(ThemeColor::Warning); + break; + } + case ButtonStyle::Danger: { + apply_theme_style(ThemeColor::Danger); + break; + } + default: + assert(false && "Unknown button style."); + break; + } + } + + void Button::apply_theme_style(recompui::ThemeColor color) { + const uint8_t border_opacity = 204; + const uint8_t background_opacity = 13; + const uint8_t border_hover_opacity = 255; + const uint8_t background_hover_opacity = 77; + + set_border_color(color, border_opacity); + set_background_color(color, background_opacity); + hover_style.set_border_color(color, border_hover_opacity); + hover_style.set_background_color(color, background_hover_opacity); + focus_style.set_border_color(color, border_hover_opacity); + focus_style.set_background_color(color, background_hover_opacity); + disabled_style.set_border_color(color, border_opacity / 4); + disabled_style.set_background_color(color, background_opacity / 4); + hover_disabled_style.set_border_color(color, border_hover_opacity / 4); + hover_disabled_style.set_background_color(color, background_hover_opacity / 4); + + add_style(&hover_style, hover_state); + add_style(&focus_style, focus_state); + add_style(&disabled_style, disabled_state); + add_style(&hover_disabled_style, { hover_state, disabled_state }); + } +}; diff --git a/src/ui/elements/ui_button.h b/src/ui/elements/ui_button.h index 182cda3..0781936 100644 --- a/src/ui/elements/ui_button.h +++ b/src/ui/elements/ui_button.h @@ -6,7 +6,11 @@ namespace recompui { enum class ButtonStyle { Primary, - Secondary + Secondary, + Tertiary, + Success, + Warning, + Danger, }; class Button : public Element { @@ -28,6 +32,9 @@ namespace recompui { Style* get_focus_style() { return &focus_style; } Style* get_disabled_style() { return &disabled_style; } Style* get_hover_disabled_style() { return &hover_disabled_style; } + void apply_button_style(ButtonStyle new_style); + private: + void apply_theme_style(recompui::ThemeColor color); }; -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/elements/ui_label.cpp b/src/ui/elements/ui_label.cpp index 64a53b8..4138849 100644 --- a/src/ui/elements/ui_label.cpp +++ b/src/ui/elements/ui_label.cpp @@ -7,7 +7,7 @@ namespace recompui { Label::Label(Element *parent, LabelStyle label_style) : Element(parent, 0U, "div", true) { switch (label_style) { case LabelStyle::Annotation: - set_color(Color{ 185, 125, 242, 255 }); + set_color(ThemeColor::Primary); set_font_size(18.0f); set_letter_spacing(2.52f); set_line_height(18.0f); @@ -40,4 +40,4 @@ namespace recompui { set_text(text); } -}; \ No newline at end of file +}; diff --git a/src/ui/elements/ui_radio.cpp b/src/ui/elements/ui_radio.cpp index 6cd1423..6759588 100644 --- a/src/ui/elements/ui_radio.cpp +++ b/src/ui/elements/ui_radio.cpp @@ -17,16 +17,16 @@ namespace recompui { set_line_height(20.0f); set_font_weight(400); set_font_style(FontStyle::Normal); - set_border_color(Color{ 242, 242, 242, 0 }); + set_border_color(ThemeColor::Text, 0); set_border_bottom_width(1.0f); - set_color(Color{ 255, 255, 255, 153 }); + set_color(ThemeColor::TextInactive); set_padding_bottom(8.0f); set_text_transform(TextTransform::Uppercase); set_height_auto(); - hover_style.set_color(Color{ 255, 255, 255, 204 }); - checked_style.set_color(Color{ 255, 255, 255, 255 }); - checked_style.set_border_color(Color{ 242, 242, 242, 255 }); - pulsing_style.set_border_color(Color{ 23, 214, 232, 244 }); + hover_style.set_color(ThemeColor::WhiteA80); + checked_style.set_color(ThemeColor::White); + checked_style.set_border_color(ThemeColor::Text); + pulsing_style.set_border_color(ThemeColor::SecondaryA80); add_style(&hover_style, { hover_state }); add_style(&checked_style, { checked_state }); diff --git a/src/ui/elements/ui_slider.cpp b/src/ui/elements/ui_slider.cpp index c77b45d..702cae1 100644 --- a/src/ui/elements/ui_slider.cpp +++ b/src/ui/elements/ui_slider.cpp @@ -93,11 +93,11 @@ namespace recompui { queue_update(); } else { - circle_element->set_background_color(Color{ 204, 204, 204, 255 }); + circle_element->set_background_color(ThemeColor::TextDim); } } else { - circle_element->set_background_color(Color{ 102, 102, 102, 255 }); + circle_element->set_background_color(ThemeColor::BW25); } break; case EventType::Navigate: @@ -118,12 +118,12 @@ namespace recompui { if (enable_active) { set_cursor(Cursor::Pointer); set_focusable(true); - circle_element->set_background_color(Color{ 204, 204, 204, 255 }); + circle_element->set_background_color(ThemeColor::TextDim); } else { set_cursor(Cursor::None); set_focusable(false); - circle_element->set_background_color(Color{ 102, 102, 102, 255 }); + circle_element->set_background_color(ThemeColor::BW25); } } break; @@ -162,7 +162,7 @@ namespace recompui { bar_element->set_width(100.0f, Unit::Percent); bar_element->set_height(2.0f); bar_element->set_margin_top(8.0f); - bar_element->set_background_color(Color{ 255, 255, 255, 50 }); + bar_element->set_background_color(ThemeColor::WhiteA20); bar_element->add_pressed_callback([this](float x, float y){ bar_pressed(x, y); focus(); }); bar_element->add_dragged_callback([this](float x, float y, recompui::DragPhase phase){ bar_dragged(x, y, phase); focus(); }); @@ -173,7 +173,7 @@ namespace recompui { circle_element->set_margin_top(-7.0f); circle_element->set_margin_right(-8.0f); circle_element->set_margin_left(-8.0f); - circle_element->set_background_color(Color{ 204, 204, 204, 255 }); + circle_element->set_background_color(ThemeColor::TextDim); circle_element->set_border_radius(8.0f); circle_element->add_pressed_callback([this](float, float){ focus(); }); circle_element->add_dragged_callback([this](float x, float y, recompui::DragPhase phase){ circle_dragged(x, y, phase); focus(); }); diff --git a/src/ui/elements/ui_style.cpp b/src/ui/elements/ui_style.cpp index 5708ec5..5f2e6dc 100644 --- a/src/ui/elements/ui_style.cpp +++ b/src/ui/elements/ui_style.cpp @@ -388,11 +388,24 @@ namespace recompui { set_property(Rml::PropertyId::BorderBottomRightRadius, Rml::Property(radius, to_rml(unit))); } + static Color get_theme_color_with_opacity(ThemeColor color, int opacity) { + Color theme_color = get_theme_color(color); + if (opacity == recompui::ThemeDefaultOpacity) { + opacity = theme_color.a; // Use the existing opacity if not specified. + } + theme_color.a = opacity; + return theme_color; + } + void Style::set_background_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BackgroundColor, property); } + void Style::set_background_color(recompui::ThemeColor color, int opacity) { + set_background_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderTopColor, property); @@ -401,31 +414,55 @@ namespace recompui { set_property(Rml::PropertyId::BorderRightColor, property); } + void Style::set_border_color(recompui::ThemeColor color, int opacity) { + set_border_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_left_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderLeftColor, property); } + void Style::set_border_left_color(recompui::ThemeColor color, int opacity) { + set_border_left_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_top_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderTopColor, property); } + void Style::set_border_top_color(recompui::ThemeColor color, int opacity) { + set_border_top_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_right_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderRightColor, property); } + void Style::set_border_right_color(recompui::ThemeColor color, int opacity) { + set_border_right_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_border_bottom_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::BorderBottomColor, property); } + void Style::set_border_bottom_color(recompui::ThemeColor color, int opacity) { + set_border_bottom_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_color(const Color &color) { Rml::Property property(Rml::Colourb(color.r, color.g, color.b, color.a), Rml::Unit::COLOUR); set_property(Rml::PropertyId::Color, property); } + void Style::set_color(recompui::ThemeColor color, int opacity) { + set_color(get_theme_color_with_opacity(color, opacity)); + } + void Style::set_cursor(Cursor cursor) { switch (cursor) { case Cursor::None: @@ -609,4 +646,4 @@ namespace recompui { } -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/elements/ui_style.h b/src/ui/elements/ui_style.h index 372fa6d..bb6b9de 100644 --- a/src/ui/elements/ui_style.h +++ b/src/ui/elements/ui_style.h @@ -6,8 +6,11 @@ #include "../core/ui_resource.h" #include "ui_types.h" +#include "ui_theme.h" namespace recompui { + const int ThemeDefaultOpacity = -1; // Represents using the theme color's existing opacity. + class ContextId; class Style { friend class Element; // For access to property_map without making it visible to element subclasses. @@ -66,6 +69,13 @@ namespace recompui { void set_border_right_color(const Color &color); void set_border_bottom_color(const Color &color); void set_color(const Color &color); + void set_background_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_left_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_top_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_right_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_border_bottom_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); + void set_color(recompui::ThemeColor color, int opacity = ThemeDefaultOpacity); void set_cursor(Cursor cursor); void set_opacity(float opacity); void set_display(Display display); @@ -105,4 +115,4 @@ namespace recompui { ResourceId get_resource_id() { return resource_id; } }; -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/elements/ui_text_input.cpp b/src/ui/elements/ui_text_input.cpp index b496728..d5ac94d 100644 --- a/src/ui/elements/ui_text_input.cpp +++ b/src/ui/elements/ui_text_input.cpp @@ -33,7 +33,7 @@ namespace recompui { set_attribute("type", "password"); } set_min_width(60.0f); - set_border_color(Color{ 242, 242, 242, 255 }); + set_border_color(ThemeColor::Text); set_border_bottom_width(1.0f); set_padding_bottom(6.0f); set_focusable(true); diff --git a/src/ui/elements/ui_theme.cpp b/src/ui/elements/ui_theme.cpp new file mode 100644 index 0000000..7a66e18 --- /dev/null +++ b/src/ui/elements/ui_theme.cpp @@ -0,0 +1,207 @@ +#include +#include "ui_theme.h" + +using ThemeColor = recompui::ThemeColor; +using ThemeColorArray = std::array; +using ThemeColorNameArray = std::array; + +constexpr ThemeColorArray get_default_theme_color_array() { + ThemeColorArray colors; + + colors[(std::size_t)ThemeColor::Background1] = recompui::Color{2, 7, 18, 255}; + colors[(std::size_t)ThemeColor::Background2] = recompui::Color{7, 15, 34, 255}; + colors[(std::size_t)ThemeColor::Background3] = recompui::Color{18, 24, 38, 255}; + colors[(std::size_t)ThemeColor::BGOverlay] = recompui::Color{182, 194, 221, 26}; + colors[(std::size_t)ThemeColor::ModalOverlay] = recompui::Color{2, 7, 18, 229}; + + colors[(std::size_t)ThemeColor::BGShadow] = recompui::Color{0, 0, 0, 89}; + colors[(std::size_t)ThemeColor::BGShadow2] = recompui::Color{2, 7, 18, 184}; + + colors[(std::size_t)ThemeColor::Text] = recompui::Color{242, 242, 242, 255}; + colors[(std::size_t)ThemeColor::TextActive] = recompui::Color{245, 245, 245, 255}; + colors[(std::size_t)ThemeColor::TextDim] = recompui::Color{204, 204, 204, 255}; + colors[(std::size_t)ThemeColor::TextInactive] = recompui::Color{255, 255, 255, 153}; + colors[(std::size_t)ThemeColor::TextA5] = recompui::Color{242, 242, 242, 13}; + colors[(std::size_t)ThemeColor::TextA20] = recompui::Color{242, 242, 242, 51}; + colors[(std::size_t)ThemeColor::TextA30] = recompui::Color{242, 242, 242, 77}; + colors[(std::size_t)ThemeColor::TextA50] = recompui::Color{242, 242, 242, 128}; + colors[(std::size_t)ThemeColor::TextA80] = recompui::Color{242, 242, 242, 204}; + + colors[(std::size_t)ThemeColor::Primary] = recompui::Color{29, 93, 226, 255}; + colors[(std::size_t)ThemeColor::PrimaryL] = recompui::Color{167, 191, 241, 255}; + colors[(std::size_t)ThemeColor::PrimaryD] = recompui::Color{0, 38, 117, 255}; + colors[(std::size_t)ThemeColor::PrimaryA5] = recompui::Color{29, 93, 226, 13}; + colors[(std::size_t)ThemeColor::PrimaryA20] = recompui::Color{29, 93, 226, 51}; + colors[(std::size_t)ThemeColor::PrimaryA30] = recompui::Color{29, 93, 226, 77}; + colors[(std::size_t)ThemeColor::PrimaryA50] = recompui::Color{29, 93, 226, 128}; + colors[(std::size_t)ThemeColor::PrimaryA80] = recompui::Color{29, 93, 226, 204}; + + colors[(std::size_t)ThemeColor::Secondary] = recompui::Color{247, 158, 8, 255}; + colors[(std::size_t)ThemeColor::SecondaryL] = recompui::Color{255, 215, 148, 255}; + colors[(std::size_t)ThemeColor::SecondaryD] = recompui::Color{224, 141, 0, 255}; + colors[(std::size_t)ThemeColor::SecondaryA5] = recompui::Color{247, 158, 8, 13}; + colors[(std::size_t)ThemeColor::SecondaryA20] = recompui::Color{247, 158, 8, 51}; + colors[(std::size_t)ThemeColor::SecondaryA30] = recompui::Color{247, 158, 8, 77}; + colors[(std::size_t)ThemeColor::SecondaryA50] = recompui::Color{247, 158, 8, 128}; + colors[(std::size_t)ThemeColor::SecondaryA80] = recompui::Color{247, 158, 8, 204}; + + colors[(std::size_t)ThemeColor::Warning] = recompui::Color{255, 254, 0, 255}; + colors[(std::size_t)ThemeColor::WarningL] = recompui::Color{255, 254, 143, 255}; + colors[(std::size_t)ThemeColor::WarningD] = recompui::Color{197, 163, 2, 255}; + colors[(std::size_t)ThemeColor::WarningA5] = recompui::Color{255, 254, 0, 13}; + colors[(std::size_t)ThemeColor::WarningA20] = recompui::Color{255, 254, 0, 51}; + colors[(std::size_t)ThemeColor::WarningA30] = recompui::Color{255, 254, 0, 77}; + colors[(std::size_t)ThemeColor::WarningA50] = recompui::Color{255, 254, 0, 128}; + colors[(std::size_t)ThemeColor::WarningA80] = recompui::Color{255, 254, 0, 204}; + + colors[(std::size_t)ThemeColor::Danger] = recompui::Color{255, 53, 31, 255}; + colors[(std::size_t)ThemeColor::DangerL] = recompui::Color{255, 149, 138, 255}; + colors[(std::size_t)ThemeColor::DangerD] = recompui::Color{163, 16, 0, 255}; + colors[(std::size_t)ThemeColor::DangerA5] = recompui::Color{255, 53, 31, 13}; + colors[(std::size_t)ThemeColor::DangerA20] = recompui::Color{255, 53, 31, 51}; + colors[(std::size_t)ThemeColor::DangerA30] = recompui::Color{255, 53, 31, 77}; + colors[(std::size_t)ThemeColor::DangerA50] = recompui::Color{255, 53, 31, 128}; + colors[(std::size_t)ThemeColor::DangerA80] = recompui::Color{255, 53, 31, 204}; + + colors[(std::size_t)ThemeColor::Success] = recompui::Color{40, 238, 32, 255}; + colors[(std::size_t)ThemeColor::SuccessL] = recompui::Color{155, 247, 151, 255}; + colors[(std::size_t)ThemeColor::SuccessD] = recompui::Color{18, 157, 12, 255}; + colors[(std::size_t)ThemeColor::SuccessA5] = recompui::Color{40, 238, 32, 13}; + colors[(std::size_t)ThemeColor::SuccessA20] = recompui::Color{40, 238, 32, 51}; + colors[(std::size_t)ThemeColor::SuccessA30] = recompui::Color{40, 238, 32, 77}; + colors[(std::size_t)ThemeColor::SuccessA50] = recompui::Color{40, 238, 32, 128}; + colors[(std::size_t)ThemeColor::SuccessA80] = recompui::Color{40, 238, 32, 204}; + + colors[(std::size_t)ThemeColor::Border] = recompui::Color{255, 255, 255, 51}; + colors[(std::size_t)ThemeColor::BorderSoft] = recompui::Color{255, 255, 255, 26}; + colors[(std::size_t)ThemeColor::BorderHard] = recompui::Color{255, 255, 255, 77}; + colors[(std::size_t)ThemeColor::BorderSolid] = recompui::Color{255, 255, 255, 153}; + + colors[(std::size_t)ThemeColor::Transparent] = recompui::Color{0, 0, 0, 0}; + + colors[(std::size_t)ThemeColor::A] = recompui::Color{51, 51, 255, 255}; + colors[(std::size_t)ThemeColor::AL] = recompui::Color{178, 178, 255, 255}; + colors[(std::size_t)ThemeColor::AD] = recompui::Color{32, 32, 172, 255}; + colors[(std::size_t)ThemeColor::AA5] = recompui::Color{51, 51, 255, 13}; + colors[(std::size_t)ThemeColor::AA20] = recompui::Color{51, 51, 255, 51}; + colors[(std::size_t)ThemeColor::AA30] = recompui::Color{51, 51, 255, 77}; + colors[(std::size_t)ThemeColor::AA50] = recompui::Color{51, 51, 255, 128}; + colors[(std::size_t)ThemeColor::AA80] = recompui::Color{51, 51, 255, 204}; + + colors[(std::size_t)ThemeColor::White] = recompui::Color{255, 255, 255, 255}; + colors[(std::size_t)ThemeColor::WhiteA5] = recompui::Color{255, 255, 255, 13}; + colors[(std::size_t)ThemeColor::WhiteA20] = recompui::Color{255, 255, 255, 51}; + colors[(std::size_t)ThemeColor::WhiteA30] = recompui::Color{255, 255, 255, 77}; + colors[(std::size_t)ThemeColor::WhiteA50] = recompui::Color{255, 255, 255, 128}; + colors[(std::size_t)ThemeColor::WhiteA80] = recompui::Color{255, 255, 255, 204}; + + colors[(std::size_t)ThemeColor::BW05] = recompui::Color{13, 13, 13, 255}; + colors[(std::size_t)ThemeColor::BW10] = recompui::Color{26, 26, 26, 255}; + colors[(std::size_t)ThemeColor::BW25] = recompui::Color{64, 64, 64, 255}; + colors[(std::size_t)ThemeColor::BW50] = recompui::Color{128, 128, 128, 255}; + colors[(std::size_t)ThemeColor::BW75] = recompui::Color{191, 191, 191, 255}; + colors[(std::size_t)ThemeColor::BW90] = recompui::Color{229, 229, 229, 255}; + + return colors; +} + +constexpr ThemeColorNameArray get_default_theme_color_names() { + ThemeColorNameArray names = {}; + names[(std::size_t)ThemeColor::Background1] = "Background1"; + names[(std::size_t)ThemeColor::Background2] = "Background2"; + names[(std::size_t)ThemeColor::Background3] = "Background3"; + names[(std::size_t)ThemeColor::BGOverlay] = "BGOverlay"; + names[(std::size_t)ThemeColor::ModalOverlay] = "ModalOverlay"; + names[(std::size_t)ThemeColor::BGShadow] = "BGShadow"; + names[(std::size_t)ThemeColor::BGShadow2] = "BGShadow2"; + names[(std::size_t)ThemeColor::Text] = "Text"; + names[(std::size_t)ThemeColor::TextActive] = "TextActive"; + names[(std::size_t)ThemeColor::TextDim] = "TextDim"; + names[(std::size_t)ThemeColor::TextInactive] = "TextInactive"; + names[(std::size_t)ThemeColor::TextA5] = "TextA5"; + names[(std::size_t)ThemeColor::TextA20] = "TextA20"; + names[(std::size_t)ThemeColor::TextA30] = "TextA30"; + names[(std::size_t)ThemeColor::TextA50] = "TextA50"; + names[(std::size_t)ThemeColor::TextA80] = "TextA80"; + names[(std::size_t)ThemeColor::Primary] = "Primary"; + names[(std::size_t)ThemeColor::PrimaryL] = "PrimaryL"; + names[(std::size_t)ThemeColor::PrimaryD] = "PrimaryD"; + names[(std::size_t)ThemeColor::PrimaryA5] = "PrimaryA5"; + names[(std::size_t)ThemeColor::PrimaryA20] = "PrimaryA20"; + names[(std::size_t)ThemeColor::PrimaryA30] = "PrimaryA30"; + names[(std::size_t)ThemeColor::PrimaryA50] = "PrimaryA50"; + names[(std::size_t)ThemeColor::PrimaryA80] = "PrimaryA80"; + names[(std::size_t)ThemeColor::Secondary] = "Secondary"; + names[(std::size_t)ThemeColor::SecondaryL] = "SecondaryL"; + names[(std::size_t)ThemeColor::SecondaryD] = "SecondaryD"; + names[(std::size_t)ThemeColor::SecondaryA5] = "SecondaryA5"; + names[(std::size_t)ThemeColor::SecondaryA20] = "SecondaryA20"; + names[(std::size_t)ThemeColor::SecondaryA30] = "SecondaryA30"; + names[(std::size_t)ThemeColor::SecondaryA50] = "SecondaryA50"; + names[(std::size_t)ThemeColor::SecondaryA80] = "SecondaryA80"; + names[(std::size_t)ThemeColor::Warning] = "Warning"; + names[(std::size_t)ThemeColor::WarningL] = "WarningL"; + names[(std::size_t)ThemeColor::WarningD] = "WarningD"; + names[(std::size_t)ThemeColor::WarningA5] = "WarningA5"; + names[(std::size_t)ThemeColor::WarningA20] = "WarningA20"; + names[(std::size_t)ThemeColor::WarningA30] = "WarningA30"; + names[(std::size_t)ThemeColor::WarningA50] = "WarningA50"; + names[(std::size_t)ThemeColor::WarningA80] = "WarningA80"; + names[(std::size_t)ThemeColor::Danger] = "Danger"; + names[(std::size_t)ThemeColor::DangerL] = "DangerL"; + names[(std::size_t)ThemeColor::DangerD] = "DangerD"; + names[(std::size_t)ThemeColor::DangerA5] = "DangerA5"; + names[(std::size_t)ThemeColor::DangerA20] = "DangerA20"; + names[(std::size_t)ThemeColor::DangerA30] = "DangerA30"; + names[(std::size_t)ThemeColor::DangerA50] = "DangerA50"; + names[(std::size_t)ThemeColor::DangerA80] = "DangerA80"; + names[(std::size_t)ThemeColor::Success] = "Success"; + names[(std::size_t)ThemeColor::SuccessL] = "SuccessL"; + names[(std::size_t)ThemeColor::SuccessD] = "SuccessD"; + names[(std::size_t)ThemeColor::SuccessA5] = "SuccessA5"; + names[(std::size_t)ThemeColor::SuccessA20] = "SuccessA20"; + names[(std::size_t)ThemeColor::SuccessA30] = "SuccessA30"; + names[(std::size_t)ThemeColor::SuccessA50] = "SuccessA50"; + names[(std::size_t)ThemeColor::SuccessA80] = "SuccessA80"; + names[(std::size_t)ThemeColor::Border] = "Border"; + names[(std::size_t)ThemeColor::BorderSoft] = "BorderSoft"; + names[(std::size_t)ThemeColor::BorderHard] = "BorderHard"; + names[(std::size_t)ThemeColor::BorderSolid] = "BorderSolid"; + names[(std::size_t)ThemeColor::Transparent] = "Transparent"; + names[(std::size_t)ThemeColor::A] = "A"; + names[(std::size_t)ThemeColor::AL] = "AL"; + names[(std::size_t)ThemeColor::AD] = "AD"; + names[(std::size_t)ThemeColor::AA5] = "AA5"; + names[(std::size_t)ThemeColor::AA20] = "AA20"; + names[(std::size_t)ThemeColor::AA30] = "AA30"; + names[(std::size_t)ThemeColor::AA50] = "AA50"; + names[(std::size_t)ThemeColor::AA80] = "AA80"; + names[(std::size_t)ThemeColor::White] = "White"; + names[(std::size_t)ThemeColor::WhiteA5] = "WhiteA5"; + names[(std::size_t)ThemeColor::WhiteA20] = "WhiteA20"; + names[(std::size_t)ThemeColor::WhiteA30] = "WhiteA30"; + names[(std::size_t)ThemeColor::WhiteA50] = "WhiteA50"; + names[(std::size_t)ThemeColor::WhiteA80] = "WhiteA80"; + names[(std::size_t)ThemeColor::BW05] = "BW05"; + names[(std::size_t)ThemeColor::BW10] = "BW10"; + names[(std::size_t)ThemeColor::BW25] = "BW25"; + names[(std::size_t)ThemeColor::BW50] = "BW50"; + names[(std::size_t)ThemeColor::BW75] = "BW75"; + names[(std::size_t)ThemeColor::BW90] = "BW90"; + return names; +} + +static ThemeColorArray theme_colors = get_default_theme_color_array(); +static ThemeColorNameArray theme_color_names = get_default_theme_color_names(); + +void recompui::set_theme_color(ThemeColor color, const recompui::Color &value) { + theme_colors[(std::size_t)color] = value; +} + +const recompui::Color &recompui::get_theme_color(recompui::ThemeColor color) { + return theme_colors[(std::size_t)color]; +} + +const char *recompui::get_theme_color_name(recompui::ThemeColor color) { + return theme_color_names[(std::size_t)color]; +} diff --git a/src/ui/elements/ui_theme.h b/src/ui/elements/ui_theme.h new file mode 100644 index 0000000..8d57a79 --- /dev/null +++ b/src/ui/elements/ui_theme.h @@ -0,0 +1,95 @@ +#pragma once + +#include "ui_types.h" + +namespace recompui { + enum class ThemeColor { + Background1, + Background2, + Background3, + BGOverlay, + ModalOverlay, + BGShadow, + BGShadow2, + Text, + TextActive, + TextDim, + TextInactive, + TextA5, + TextA20, + TextA30, + TextA50, + TextA80, + Primary, + PrimaryL, + PrimaryD, + PrimaryA5, + PrimaryA20, + PrimaryA30, + PrimaryA50, + PrimaryA80, + Secondary, + SecondaryL, + SecondaryD, + SecondaryA5, + SecondaryA20, + SecondaryA30, + SecondaryA50, + SecondaryA80, + Warning, + WarningL, + WarningD, + WarningA5, + WarningA20, + WarningA30, + WarningA50, + WarningA80, + Danger, + DangerL, + DangerD, + DangerA5, + DangerA20, + DangerA30, + DangerA50, + DangerA80, + Success, + SuccessL, + SuccessD, + SuccessA5, + SuccessA20, + SuccessA30, + SuccessA50, + SuccessA80, + Border, + BorderSoft, + BorderHard, + BorderSolid, + Transparent, + A, + AL, + AD, + AA5, + AA20, + AA30, + AA50, + AA80, + White, + WhiteA5, + WhiteA20, + WhiteA30, + WhiteA50, + WhiteA80, + BW05, + BW10, + BW25, + BW50, + BW75, + BW90, + + size, + }; + + const char *get_theme_color_name(recompui::ThemeColor color); + void set_theme_color(ThemeColor color, const recompui::Color &value); + const recompui::Color &get_theme_color(recompui::ThemeColor color); +} // namespace recompui diff --git a/src/ui/elements/ui_toggle.cpp b/src/ui/elements/ui_toggle.cpp index 983d7ac..7f58c2e 100644 --- a/src/ui/elements/ui_toggle.cpp +++ b/src/ui/elements/ui_toggle.cpp @@ -15,19 +15,19 @@ namespace recompui { set_opacity(0.9f); set_cursor(Cursor::Pointer); set_border_width(2.0f); - set_border_color(Color{ 177, 76, 34, 255 }); - set_background_color(Color{ 0, 0, 0, 0 }); - checked_style.set_border_color(Color{ 34, 177, 76, 255 }); - hover_style.set_border_color(Color{ 177, 76, 34, 255 }); - hover_style.set_background_color(Color{ 206, 120, 68, 76 }); - focus_style.set_border_color(Color{ 177, 76, 34, 255 }); - focus_style.set_background_color(Color{ 206, 120, 68, 76 }); - checked_hover_style.set_border_color(Color{ 34, 177, 76, 255 }); - checked_hover_style.set_background_color(Color{ 68, 206, 120, 76 }); - checked_focus_style.set_border_color(Color{ 34, 177, 76, 255 }); - checked_focus_style.set_background_color(Color{ 68, 206, 120, 76 }); - disabled_style.set_border_color(Color{ 177, 76, 34, 128 }); - checked_disabled_style.set_border_color(Color{ 34, 177, 76, 128 }); + set_border_color(ThemeColor::DangerD); + set_background_color(ThemeColor::Transparent); + checked_style.set_border_color(ThemeColor::Success); + hover_style.set_border_color(ThemeColor::DangerD); + hover_style.set_background_color(ThemeColor::DangerA30); + focus_style.set_border_color(ThemeColor::DangerD); + focus_style.set_background_color(ThemeColor::DangerA30); + checked_hover_style.set_border_color(ThemeColor::Success); + checked_hover_style.set_background_color(ThemeColor::SuccessA30); + checked_focus_style.set_border_color(ThemeColor::Success); + checked_focus_style.set_background_color(ThemeColor::SuccessA30); + disabled_style.set_border_color(ThemeColor::DangerD, 128); + checked_disabled_style.set_border_color(ThemeColor::SuccessD, 128); add_style(&checked_style, checked_state); add_style(&hover_style, hover_state); add_style(&focus_style, focus_state); @@ -44,10 +44,10 @@ namespace recompui { floater->set_width(80.0f); floater->set_height(64.0f); floater->set_border_radius(32.0f); - floater->set_background_color(Color{ 177, 76, 34, 255 }); - floater_checked_style.set_background_color(Color{ 34, 177, 76, 255 }); - floater_disabled_style.set_background_color(Color{ 177, 76, 34, 128 }); - floater_disabled_checked_style.set_background_color(Color{ 34, 177, 76, 128 }); + floater->set_background_color(ThemeColor::DangerD); + floater_checked_style.set_background_color(ThemeColor::Success); + floater_disabled_style.set_background_color(ThemeColor::DangerD, 128); + floater_disabled_checked_style.set_background_color(ThemeColor::SuccessD, 128); floater->add_style(&floater_checked_style, checked_state); floater->add_style(&floater_disabled_style, disabled_state); floater->add_style(&floater_disabled_checked_style, { checked_state, disabled_state }); @@ -158,4 +158,4 @@ namespace recompui { void Toggle::add_checked_callback(std::function callback) { checked_callbacks.emplace_back(callback); } -}; \ No newline at end of file +}; diff --git a/src/ui/elements/ui_types.h b/src/ui/elements/ui_types.h index 08645ea..726b25c 100644 --- a/src/ui/elements/ui_types.h +++ b/src/ui/elements/ui_types.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #include #include @@ -279,4 +281,4 @@ namespace recompui { Auto }; -} // namespace recompui \ No newline at end of file +} // namespace recompui diff --git a/src/ui/ui_color_hack.cpp b/src/ui/ui_color_hack.cpp index cc9b6fd..edc18e4 100644 --- a/src/ui/ui_color_hack.cpp +++ b/src/ui/ui_color_hack.cpp @@ -37,6 +37,13 @@ namespace recompui { html_colours["aqua"] = Rml::Colourb(0, 255, 255); html_colours["transparent"] = Rml::Colourb(0, 0, 0, 0); html_colours["whitesmoke"] = Rml::Colourb(245, 245, 245); + + for (std::size_t i = 0; i < (std::size_t)recompui::ThemeColor::size; i++) { + const char *color_name = recompui::get_theme_color_name((recompui::ThemeColor)i); + const recompui::Color color_value = recompui::get_theme_color((recompui::ThemeColor)i); + Rml::String color_name_lower = Rml::StringUtilities::ToLower(color_name); + html_colours[color_name_lower] = Rml::Colourb(color_value.r, color_value.g, color_value.b, color_value.a); + } } PropertyParserColorHack::~PropertyParserColorHack() {} @@ -166,6 +173,8 @@ namespace recompui { PropertyParserColorHack* new_parser = new PropertyParserColorHack(); // Copy the allocated object into the color parser pointer to overwrite its vtable. memcpy((void*)Rml::StyleSheetSpecification::GetParser("color"), (void*)new_parser, sizeof(*new_parser)); + // TODO: Register the new parser with RmlUi when RmlUi supports custom parsers overrides. + // Rml::StyleSheetSpecification::RegisterParser("color", new_parser); } ColourMap PropertyParserColorHack::html_colours{}; diff --git a/src/ui/ui_config.cpp b/src/ui/ui_config.cpp index f7a00d5..0dbba71 100644 --- a/src/ui/ui_config.cpp +++ b/src/ui/ui_config.cpp @@ -200,8 +200,8 @@ void close_config_menu() { graphics_model_handle.DirtyAllVariables(); close_config_menu_impl(); }, - recompui::ButtonVariant::Success, - recompui::ButtonVariant::Error, + recompui::ButtonStyle::Success, + recompui::ButtonStyle::Danger, true, "config__close-menu-button" ); @@ -221,8 +221,8 @@ void banjo::open_quit_game_prompt() { ultramodern::quit(); }, []() {}, - recompui::ButtonVariant::Error, - recompui::ButtonVariant::Tertiary, + recompui::ButtonStyle::Danger, + recompui::ButtonStyle::Tertiary, true, "config__quit-game-button" ); diff --git a/src/ui/ui_mod_details_panel.cpp b/src/ui/ui_mod_details_panel.cpp index 9606ca3..66d5f22 100644 --- a/src/ui/ui_mod_details_panel.cpp +++ b/src/ui/ui_mod_details_panel.cpp @@ -11,7 +11,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { set_height(100.0f, Unit::Percent); set_display(Display::Flex); set_flex_direction(FlexDirection::Column); - set_background_color(Color{ 190, 184, 219, 25 }); + set_background_color(ThemeColor::BGOverlay); ContextId context = get_current_context(); @@ -19,9 +19,9 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { header_container->set_flex(0.0f, 0.0f); header_container->set_padding(16.0f); header_container->set_gap(16.0f); - header_container->set_background_color(Color{ 0, 0, 0, 89 }); + header_container->set_background_color(ThemeColor::BGShadow); header_container->set_border_bottom_width(1.1f); - header_container->set_border_bottom_color(Color{ 255, 255, 255, 25 }); + header_container->set_border_bottom_color(ThemeColor::BorderSoft); { thumbnail_container = context.create_element(header_container, FlexDirection::Column, JustifyContent::SpaceEvenly); thumbnail_container->set_flex(0.0f, 0.0f); @@ -29,7 +29,7 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { thumbnail_image = context.create_element(thumbnail_container, ""); thumbnail_image->set_width(100.0f); thumbnail_image->set_height(100.0f); - thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 }); + thumbnail_image->set_background_color(ThemeColor::BGOverlay); } header_details_container = context.create_element(header_container, FlexDirection::Column, JustifyContent::SpaceEvenly); @@ -56,8 +56,8 @@ ModDetailsPanel::ModDetailsPanel(Element *parent) : Element(parent) { buttons_container->set_padding(16.0f); buttons_container->set_justify_content(JustifyContent::SpaceBetween); buttons_container->set_border_top_width(1.1f); - buttons_container->set_border_top_color(Color{ 255, 255, 255, 25 }); - buttons_container->set_background_color(Color{ 0, 0, 0, 89 }); + buttons_container->set_border_top_color(ThemeColor::BorderSoft); + buttons_container->set_background_color(ThemeColor::BGShadow); { enable_container = context.create_element(buttons_container, FlexDirection::Row, JustifyContent::FlexStart); enable_container->set_align_items(AlignItems::Center); diff --git a/src/ui/ui_mod_menu.cpp b/src/ui/ui_mod_menu.cpp index ed92a7d..ca18455 100644 --- a/src/ui/ui_mod_menu.cpp +++ b/src/ui/ui_mod_menu.cpp @@ -27,9 +27,6 @@ static bool is_mod_enabled_or_auto(const std::string &mod_id) { } // ModEntryView -#define COL_TEXT_DEFAULT 242, 242, 242 -#define COL_TEXT_DIM 204, 204, 204 -#define COL_SECONDARY 23, 214, 232 constexpr float modEntryHeight = 120.0f; constexpr float modEntryPadding = 4.0f; @@ -45,17 +42,17 @@ ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType:: set_height_auto(); set_padding(modEntryPadding); set_border_left_width(2.0f); - set_border_color(Color{ COL_TEXT_DEFAULT, 12 }); - set_background_color(Color{ COL_TEXT_DEFAULT, 12 }); + set_border_color(ThemeColor::BorderSoft); + set_background_color(ThemeColor::BorderSoft); set_cursor(Cursor::Pointer); - set_color(Color{ COL_TEXT_DEFAULT, 255 }); + set_color(ThemeColor::Text); - checked_style.set_border_color(Color{ COL_TEXT_DEFAULT, 160 }); - checked_style.set_color(Color{ 255, 255, 255, 255 }); - checked_style.set_background_color(Color{ 26, 24, 32, 255 }); - hover_style.set_border_color(Color{ COL_TEXT_DEFAULT, 64 }); - checked_hover_style.set_border_color(Color{ COL_TEXT_DEFAULT, 255 }); - pulsing_style.set_border_color(Color{ 23, 214, 232, 244 }); + checked_style.set_border_color(ThemeColor::BorderSolid); + checked_style.set_color(ThemeColor::White); + checked_style.set_background_color(recompui::ThemeColor::Background3); + hover_style.set_border_color(ThemeColor::BorderHard); + checked_hover_style.set_border_color(ThemeColor::Text); + pulsing_style.set_border_color(ThemeColor::SecondaryA80); { thumbnail_image = context.create_element(this, ""); @@ -63,7 +60,7 @@ ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType:: thumbnail_image->set_height(modEntryHeight); thumbnail_image->set_min_width(modEntryHeight); thumbnail_image->set_min_height(modEntryHeight); - thumbnail_image->set_background_color(Color{ 190, 184, 219, 25 }); + thumbnail_image->set_background_color(ThemeColor::BGOverlay); body_container = context.create_element(this); @@ -78,7 +75,7 @@ ModEntryView::ModEntryView(Element *parent) : Element(parent, Events(EventType:: name_label = context.create_element