From 47bd40f6b6b03e29cbcebe7ec9e6bd13537c9f8b Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Sun, 31 May 2026 22:12:32 -0400 Subject: [PATCH 1/2] fix(web): always-visible wordmark in navbar The header used followed by a "Code for Philly" wordmark gated with `hidden md:inline`. The image asset has never existed in the repo, so it rendered as an invisible broken-image on every viewport. Desktop nobody noticed because the wordmark text filled the spot; mobile (where hidden md:inline hides the wordmark) showed an empty home link with no tappable visual. Drop the broken and unhide the wordmark at all breakpoints. The home link is now always visible, always labeled, always tappable. The actual logo asset is a future TODO; the wordmark covers the functional need. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/src/components/AppHeader.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/web/src/components/AppHeader.tsx b/apps/web/src/components/AppHeader.tsx index 26da256..4da04a4 100644 --- a/apps/web/src/components/AppHeader.tsx +++ b/apps/web/src/components/AppHeader.tsx @@ -187,16 +187,16 @@ export function AppHeader() { return (
- {/* Logo */} + {/* Wordmark — always visible. The image asset is a future TODO, + but the wordmark alone gives the home link a tappable target + on every viewport, including mobile where the desktop nav + isn't present. */} - - - Code for Philly - + Code for Philly {/* Desktop nav */} From 57c92709363ca2776f3ead9f592c675e071a06ff Mon Sep 17 00:00:00 2001 From: Chris Alfano Date: Sun, 31 May 2026 22:55:54 -0400 Subject: [PATCH 2/2] feat(web): real Code for Philly logo + favicon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds three brand assets sourced from the project's design files: apps/web/public/img/logo-horizontal.png — icon + wordmark lockup (navbar) apps/web/public/img/logo.png — standalone icon apps/web/public/favicon.png — favicon AppHeader now renders the horizontal lockup in place of the bare "Code for Philly" text wordmark. Image is set as h-8 w-auto so it scales naturally; aria-label stays on the Link for screen readers. index.html picks up the favicon via . Test updated to assert the home link's accessible label + alt text since the wordmark is now part of the image instead of separate text. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/index.html | 1 + apps/web/public/favicon.png | Bin 0 -> 6205 bytes apps/web/public/img/logo-horizontal.png | Bin 0 -> 7151 bytes apps/web/public/img/logo.png | Bin 0 -> 6214 bytes apps/web/src/components/AppHeader.tsx | 14 ++++++++------ apps/web/tests/AppHeader.test.tsx | 7 +++++-- 6 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 apps/web/public/favicon.png create mode 100644 apps/web/public/img/logo-horizontal.png create mode 100644 apps/web/public/img/logo.png diff --git a/apps/web/index.html b/apps/web/index.html index 3a97171..1eebeb2 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -3,6 +3,7 @@ + Code for Philly diff --git a/apps/web/public/favicon.png b/apps/web/public/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..14831edd9d55ac620abe0c5cd88436acf9161a04 GIT binary patch literal 6205 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 literal 0 HcmV?d00001 diff --git a/apps/web/public/img/logo-horizontal.png b/apps/web/public/img/logo-horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..e1ae0e7abe68da346a8110fce56e0f58386a90de GIT binary patch literal 7151 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 P=Ufd{U6l$Y+wlJf-L9lj literal 0 HcmV?d00001 diff --git a/apps/web/public/img/logo.png b/apps/web/public/img/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..7f9d470f713f1b98d6a2069d395753371e9fe2b1 GIT binary patch literal 6214 zcmaJ_2RK|?yBpuVhRM*eZpIJLBFMoG`_`+>`EwHzI1Dx>~fDRh#f&m(OI=f=bG0x~9?;eZ>06+tB zx3uxKF+oC6SWh|U-#&7Ip13nK0HAR-5a*2Y!1w}PFs|-inxM^w77)-KtqHPLHc>Fa z>0#X55qI$zi@TwY=uGKMANj;QIRdU}YV!nvN>?Z!8Rp^7F)a`TmVX{}&eWkJ#U(;E6kn z48!2v{V`~LJk}HV*OH;`|ELA7|BrnC!lM6Ki^4x*<(|K8aDw$Xo2omJ0o^WSBA zHu!hpW4z9)9e-BV3}3&90{{XNhA(ZSGe3O+XywS!I`PYVaQ^4j1Wq$lmZQD&K>B##w87tOUb-r(EcYe-D_4liuCiKk1X={dc8 zFI|k=;X7K&t=T^5;>!zTC89*W2Zg6)zQN(b=90DR%V#PT9$Etz6HJO4%zP=C{!uYt>9B79t$_wEnYxik zPK-KlNiuPep>NoJ%b?*VtfMPe5Ae>QjNm;%M)QT z%R!DANC-)7t0HAszWeFopokhIXe1a0v}3rdPCCpEtfxaVDBvWS|mwDCGLKJ>+=%)I-Ui4L^gzPhn;#qLgli>*o;;8ys*G} zrWt=S8eeikd6J#QrEg-cZYy1EEXGFWQi@K`qbz13OvhQ34h4N?g$>cv$u@^cpPuq8{_G^W>Q6aZQA2N$(^MmRuL za!yOMLnS)1{OnSx=ZCT$OgWx=-Kx)Imx27)uo=xjfuB;NTjE%|Z5!RAAc5rgZaZV z!}J@UqDp&|lRM(TndZk=Yt3;a3-&L)n1wpP7LoNA;= zdQVwLwGa@D_XcVwK4Of#IVAOM^7>b^x1+|=wU?fG6$7PlvUfhd?U)u^vn%B1xpjjo za=AW&Cw72s1>JCkuQ;Ubl* z%m%OGLQ=@@y!9W_1Kgr9^{F;{H`ELU-J>3OksMOa^AZ4(h4hq@uw`|qOai3W~*&GDUl(F22~L z;y{|a2qreJBW9GLMBfGWH(F7CX|5OmUu2-&(?s9VF8n~V5P_87hCDsKkKWM=gXAf2 zJ4o$vg>IYd_oTK$V&ZN%gc?Pq>n?~?BD?{pJA~fsJ30~GzCX(M)b+io8!x|e}OXe!Bh;Q+Qp(41FU<>XeE$%T$jJSCrD|GU^}B$N z$fb4rf(N~@K>z8N>_73AD2rG%2%Cs}l>Z0Vulu5cDo`~3+v;U_@MDA+hZ3vqk;Iq4 zGHCkg1gjRIC!$#OVet=p1uwk)zTHisZmGsT$04cGDoRJ7?{q8JZP!Pf+{5c4E&H{V zA*YO5u#ou2&@83n^yX@LSdD=AQ0S+esL!xSB@q1GX3(5T@?tii*rt#e{EQCP=r#@q z!Pm#qY?q-6TT+J3FL8P9?`tSK=kx*1vDR9Y(PQCmaS{n{F7yuU29DU8von8MeM zxZ5vEdy#|MJz5HHm69(iEA2Jrgsr;8>PnS%3;*gP7GHLmzX~oU`#_t^vXIU}s8O`mHWfhT2)mFvpex~Ah$Le4HIllaI zXa5zuqxorb+BV~;+O3g2Gvg?H<0pXmUeY07M8*pJ&5P&!cqC$w_RsY;auScg_$Q() zjg~KY#S6N6Ix?lNiYJ(#-{UgxVRwDieC3gCS(=kS_H+4W%6pn|_%~^Td)&0#(jn1~ zgZV*op*ZnWm`HA#=#MYkX28CRC2N8Ck6LcSJI4xiP=oS)F{5vsjzJ2`IZ(s&81s@@ z^-oem1wMk}xZ`}qpVHYIg2Y2f97tKqpxjyyC!#d_buCqPbTXr0zDM0>Zp`eLR_^v^ z+qM!VvA8YaW+om23yrur>f1izS*|oMm66zJ9oAzwP%qM)|;>* zcp>$(W@+2Cb6lK*rk@k&z8S|ZJQOz(@gpcRrrkJx%v+9-W+PuFF>xa2Px5H9BrKJm zSUyqGFnoACXgW8cC&X#BQ|M!&+eA0DdZPW#vA=>?ZHw~f z#=%n?ZTk$9_caT&L6EY6$>+rF;iZu`YOUCZmjz%SusX`4PiJWSYI~lNLZ_C8Nq9UhI^_+|s2r`4Th1wH>$UC>#&tC*hvyx|i1tqQv*rUZQpGu~ zI*sPRvBqm`E2ZY2_T|PBrR#4lPIGDyltP0>tGTRky;_GJ_KcPg!MeP-OFaj+Df}-Q}-U0;e)i`Poqt_w@WM=`={P}EJ^uDCKtf0E*9fMB3M zcb)ucAv;a%y~)a8)w$rv>5Lf?HQwZkwA*oHOqzXxEQ~gl3Jr~CwSx$cn?9IsV#ZSe zEofBH9jwW5)4E358sRno%E+{AKK0BMvGj3NH{g#IJzD)o@E8CT=rdZy&qhV)Ntafm zC(nJMx}}rP=Nh?PEuhV7jyau=zWs0Sa4{eZdC#cRFb#o$aPt}7@-5J~#Q#|Nu(F-@9pk;>8ZO1R>10tnVh^BZfKiU0#%#oMW6Hsyz);oGbW>r>_LkH-6*Y8n!3AX*tB1T zP$tvU{CNu3aJ5VS>Gafosj*C|w60&%Po(p7?%FnBq=rb49VKIy6Vir5-4wD^Z}H`j`97^ ztDTOiHH#)hAn^|o!I_}ZKW$mH3;h>H-(J~Ce0NBVzOCALDSLFt2c!?QI9d=BTHzwu z1i^ru^J4sJo0;*hDf|qOsBf!&VwyR&1y{bN^P(ZqzwQRQj zt|W)6ZJ&=S3$^4}TBfJBfYL!odaGZXD&&jZVqjbhGZMeX^TUzNtw-6wN4Gm-)HZ~v zpS*TCr*eUo)NXL@t9SjQn`8T7+SH)?bI5Z9avB0iO<)87&YHFu06;oB3_ELR>c1z7 z086k?W|7sCLDJQcS1buMqm}&$K%#Aj;0%c#m@&R4^sD~rE{&YOsQD0C@69I=H3@Lz zCp&)OfSUU5O6FHdtp8&&fHh91k4wwnbM?IALxQF+e`f(x$rw8tLYt&|=s6|vo|;?; zwD>V6ooPBHGZJrRytG`%P9S@%Pzqd$Y}2-co=f*>`wV$#*S2)M2tAxyZJn=U3w+mT zAyEQ~P5$uOJ5N-AoD^Es_vdqT3e(?yAQ!naU>&Y$7w#`GarTmmGs2PI9wrIj&%Gk$ zK_GX^33eK>%WzU6b;rNd?tLF%Y0z+ttZJV@f@g{kd5T2Kk^Pa^_5x9?uYx0YKYyuW z(HeL^gSqbh!I`vq#%U`WOWe?Cy!**}2&+@L-!|^)&&t-M{5S%+QOZ%!juN^~j$p2m z0|Q9Y4FSz192~58i-lJ}3(X$`-DP%@L0P_zKhtG>o_lvfEtHFWUmXkVg1gThi&(xN zwpNw8{t#1iQT(9Z2v1YI*zv#`Xwk4B($4k#rhp!yM=P0<6l{LFk@!S7Vwsi)NPHlZ z+D(j3d=kmT+fBJbLjKGOFXgE7N99&jcWx%O=H@P3$|gj|+?gqlY8NPnZySo>H}9km zOo!@Ubrz{Wha+obh0Qy_Dc3}kCww;pS+AeJ(A48{2XV0>`0c~^NhJx}ke9f z`lp65$<~KP80VF>YF8FMUB3IH9M8IPI9aY%@w4}Q>AISujbi(1;w^^^Ubc;(+OoQi zg2?f`PETix=M0nc>@u8Qw(2%Sn|SApqIYGKKwGePs3>OV4Kg#x@DbgE#9xoNUsQQt zEmmOsswO?F+5mSDdJ!=Xnl@87DCLN0dNfs5=RdtUpAb3L-C|8~*p!Ms327R^A8!NTBnL7bi{0gTLBU=w2+T%cX*B?P*x=pR za%oQA_P#d&eVc`&T4Od-+rHLIn-d}`E8dF*Uo&>7GN{h^>k#^X-3C2(o9`cR=$!`) z@?u@J8?`T-8H@w{GyuJ`m$a3Q(x3g;GfCM0gocWpZr6mwU#5G?;$zUB_YK5p6iKGC z6yb0@yiWr;;Xstk$nPeAHA7=-^MZ)|&!{N7#=y>NfI)a!r~&YUflj=LJFj+QoNAvI z$UU}J9tO-)Iu8`=v@whaZ7{Q+bI^R6XdrCFo@>Z)&OI~a*UqNXd%*iiGtBEn6_3p~ zU+&S%(3peZ(r4ctX4;j*EI-a5^rp?$5B+;it*7@?KHeJ!I5y^ioC1a+0_=~tSU9Z% zA1WVR9nflaeII+|kP6TF_L2l*fg_5c6? literal 0 HcmV?d00001 diff --git a/apps/web/src/components/AppHeader.tsx b/apps/web/src/components/AppHeader.tsx index 4da04a4..c6946ef 100644 --- a/apps/web/src/components/AppHeader.tsx +++ b/apps/web/src/components/AppHeader.tsx @@ -187,16 +187,18 @@ export function AppHeader() { return (
- {/* Wordmark — always visible. The image asset is a future TODO, - but the wordmark alone gives the home link a tappable target - on every viewport, including mobile where the desktop nav - isn't present. */} + {/* Wordmark — always visible. The horizontal lockup includes + the icon + text, so no separate text node is needed. */} - Code for Philly + Code for Philly {/* Desktop nav */} diff --git a/apps/web/tests/AppHeader.test.tsx b/apps/web/tests/AppHeader.test.tsx index 9d040c4..5b58ff4 100644 --- a/apps/web/tests/AppHeader.test.tsx +++ b/apps/web/tests/AppHeader.test.tsx @@ -28,9 +28,12 @@ describe('AppHeader', () => { vi.restoreAllMocks(); }); - it('renders the site name', async () => { + it('renders a labelled home link with the logo image', async () => { renderWithRouter(); - expect(screen.getByText('Code for Philly')).toBeInTheDocument(); + const home = screen.getByRole('link', { name: /code for philly home/i }); + expect(home).toBeInTheDocument(); + expect(home).toHaveAttribute('href', '/'); + expect(home.querySelector('img')).toHaveAttribute('alt', 'Code for Philly'); }); it('renders primary nav links', async () => {