favicons added

This commit is contained in:
2026-05-02 16:40:26 -05:00
parent 3917c1bded
commit 9b489462eb
10 changed files with 451 additions and 536 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

+93
View File
@@ -0,0 +1,93 @@
%PDF-1.4
%“Œ‹ž ReportLab Generated PDF document (opensource)
1 0 obj
<<
/F1 2 0 R /F2 3 0 R
>>
endobj
2 0 obj
<<
/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
>>
endobj
3 0 obj
<<
/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
>>
endobj
4 0 obj
<<
/Contents 9 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
5 0 obj
<<
/Contents 10 0 R /MediaBox [ 0 0 612 792 ] /Parent 8 0 R /Resources <<
/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
>> /Rotate 0 /Trans <<
>>
/Type /Page
>>
endobj
6 0 obj
<<
/PageMode /UseNone /Pages 8 0 R /Type /Catalog
>>
endobj
7 0 obj
<<
/Author (\(anonymous\)) /CreationDate (D:20260502182436+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20260502182436+00'00') /Producer (ReportLab PDF Library - \(opensource\))
/Subject (\(unspecified\)) /Title (\(anonymous\)) /Trapped /False
>>
endobj
8 0 obj
<<
/Count 2 /Kids [ 4 0 R 5 0 R ] /Type /Pages
>>
endobj
9 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2874
>>
stream
Gb!SmgN)%.&q0LUoM\eYQ"42Il>79h:,K5HN29,5<qunG+UK*Ni..UD:$ou>2ZZfUXG^Abg+#m'YpC#r!/IIJ?YG(G5Bc]]9E79#iV^h&gO]/%Cp3<Dr#.3NB7HH)Au%NTHQES"Ibu7*'YMo(HtsE]h\oYkBE3J8*s;Z^eFG00)1`/Zc9[@Or2;S+IQ=_a><&9^cDm1OSh4ObE"dP_(XKA%$1nq$/=7lU]0=FP[,?I5*RYggL!F5JEXimsP-(O;hS]9K0`Qh8s+WaTj0l.NDqXd(VX9Nmg=qDlpK`FQXnP>:jc1>E#IkN4>_o4)=:DNY?LT4qbB,12c5#-h_]__&Kjo>$b-39+X*8e3.e1-d)<8#a#qL[&p"5=l0]l!i)%686%6LrUm;(:U1\@7''Ma(6+mt`C1%9h2nXr,=SWRRF3Uem#@-B:OIOl&40&4YNW\&>lU]1<L`9B:jf5hq`IWdLmZm,\H5F)ThEBf]0ZZ-9$WdLIDk95mK,hB:FYt2Y$8>OcYOe*@e<n;W*q88->ZtJ=qp=%n;,gWU&n(6@PER/LtKh_PsJ@Xkb('<]H[QPTm,G[[dCJ#*6g@;8%PNV*_qu,YhI.shXO4UIJ%q"7ScP]AK)HS"[.t1K=_=JWq7LUl4KW4XL[B76G]n>fu+3tpOWcZ%2"FS6;+g;!,mkj.m"dUuU"74D)]b0lWca@%`d&m<GF@HD\+)"C_RfgoImA0Wmn-Ktf;u[>Cc;Y9o!W5I-Q/HAtJVE<*3J`YjZGn9(OKc)s0QLE\/g8i4]>2i#,$(pSUr4KRCH+CbbLQJD.@&n,&[+L[JnPgWcu)5Y`JSSZ44N#WF-^nkcZk88&V&4C*1jAGBCT_:r*Jlh10]]>^3YlW,B0305Oqog$*LA=WqY>-krLqa>WdgE'^PV^R?A0MQpcb.O$^sQVWN=%KTl!K?J[j^N\\\U1/2J8aKZhDr6^5EDVf7(0io[9*RF@!`aA1HE-DIJ>4NS&\9F$=%n]5_ZBD?@\HicKr^SE;mH[9/aG?l2+p1XWZN;F&_$s/g:iVf]A;%HY"\juSbq;gT@_.4kbdnA-YU&fE61_lP5#]:`WQY_^RYUedeb;K`T+J#aa'<-25N4l@'D/DTS@@d1-PDX=Gk1[OI_:fnXLTRo%<QQfARhpr?pL"Pn7UWI*9S0YjucnF16tSLo4'ifCpSco=\uc)^B7`3_76qg!I'4;7f/s32oKLA*X[g,B/'%pC/Pnh1+>n\>>ui[*@$R]FcIBJ?>VMYAolQq%\)6rZ7V9PcLKn!NRGFEq35Z8&\FoESVuk-JrQS@K+$2B]d0rSCprNo>Vt).J-,+'qnijq=plfb["\-a5*9R%6i(K7Qo5*])94kh9(M*0%)*%*[8iYc,-GjW5_^,/iCd4-7/U30aPPr"Jr]jlM/_dRfYFM,mVF8CLCnX@f>QYQg_Qt0kDfiRnEmLhf-2e$0Jp$7,6ZeG5*ld.l+GsMrVJ3PaRD8m?+@j-n=p=;CW&2D9=d*>AJm(/L,>E1\Dct,YsI<L;ZV(e;c-'mqhIJD:'K?A`>3^\MCT"RoUs,>oK2Ss_riek)\^Fl0VQ5Z14]m)mlM1(r@OqJp[8V8':]Ds>@(-*49eJu.U9\nO)NDZF0S+t\jMNX=O^=j6/p\Fg&s^S;K4"oE$Z3J@W@@PR4cGWN=IZ45ESpQMRn#=Cn]njV@l4JPI]H@"DKPZ)+o5t'T6F\d*)V_h5]8re'7N42Aok\&O6(6F`q8*W_SkB7WOo;9&]Q6''"UTnkMWNQGO]]au^JAlXE;7quIh:$bru;2@Gek:t._SDm%D61F1I?;&J+M!.f2@if'd+Qq\[\+:KVrkXj"@L_FRP@\mT^66aSFohCKUWL-U:I'K4fO/Jl-_*Xu`,a2>A78mtB;M>.AMD^Uj"0"PA<EZTAQE>CQU7B#T*mDj&?/mnH,,pAs%>7kM'/:nB_:YVX.b''3B>npDf\MBL9_K54:,"_CnSn<MYEsI^bM1/#Oo4#Qg7*dler7+TWpjNA&"HR`%urm,><^tdDbg+cf&X!RS(m\lm6_+JFJ0u`[\fK6"HMg:Ca+lO,5eBTjA0QkP0mXk>lphT'ao.5hf?L7b3f"2h^*76PB:ouY9nSQX1NmD+!itj"p6DrI=r#+M4im2W.qh.!QkGh>?]m!%m*+*a0f8KD?DZq*,'lgAEkIh<3pJCB\_-#rV>\"OGR$Im81F(g)4eo`Q^&SDssaLO*%_+bVH/TG(6OV[nmTG];;q"#'I2tUPY8%OWi2ZWa%F@@?iM<&p>u#1QYd@e(B#bOB/@&VSAEuW&,VS]cdi#Ah#nGNLEcS<NQY'.02`#7912$XgDe]7>L/3NM[^)hEF6'VE)[UF``<?<QpL=[E_uaeU/qoL]iigjA77HAQC`BEFoY>?S#k+dN$"BK+d4sRj[@B34L`SI"fS;BoSo%Kj]R)%\\WGkh>GID_VnO]8UN;[[k,Upb>bHiS,aD=/Lk>X1BZb2k(,;73,q7-HJN)!I0NqVRNXO/6K$QH-#"-$^iJcoCXN-erJ?/3_ck`Y>&>qVX2Pmp-r)H\eps?"HOeOK@Q_&\aBKV:p:Y2;k9qq$K4%20oZ&qUa9nDL753^el`=@-V[4])KI)J6%iSCibra)dKgu''c0u?o;7nRQnaeE8Ubm5fs!Ybo+ErUF*+S;Pa8"B8kV-4=!gnu#WtT7[(;b]HF]5;:p#?:Jk1\g[boe9l;If=`7H5ANrB*ZT5cJOj3u8[Jq<ba/B_K7l@9H9/=()-`@dB++(ChFUtfL,AVNL%dn<LCWu`MN@/E[V&JTl45dkl(%)`)N,H#_!Wa8*UiJLQ5V+sOSV2g^I`L[W&'/:;7N!#%\DS918!o)(;.T&2&08mU56N~>endstream
endobj
10 0 obj
<<
/Filter [ /ASCII85Decode /FlateDecode ] /Length 2700
>>
stream
Gb!TY>C5)6(5D;L/(R^EAl!An2GC:[8QquO23?MgU,TrT5uZJ-82^eSIP8e[aFUp>nhcgm:BRj*Q9MGDY(Q+lNB`I!*G5@B@lQSn^i<eQK&^'!N6gEm]_BaDZQ/3uQL@3%"]c2o8+;IScH,6Vo3pC$fR<D>qBC.a#Hj,5<WM.g*)DV[4E[?q&#<Sn[aPU)I!#P+LG.JdlNMMRfH4*^+_1oJi0Y9b/2EZ\E0="":9".#`dbo$htkcnnRm8q5O^8N`A_B=QL"3K-NqUKs1n3k^[$$DVs!Bfl","hX7EjuMf>'jm(9]A_\^o6!T,o^`B,#+<YP<,E'g.Yde-X=Y1Dsm]rpaT(&3e&4eC/$1Ta]e<i_hErhq)?bub!V)UEH?`KX6-?'0F7G-m^RrM<_9ZhVd.[@F2P&_Has03Tf\47`PApV/[bA7gSFg-0Cq7aA[rFffs[N8<im':,![T-c7eKU4J;Glj.l"HOu8+pA$H/gc6=asepeOfB,+a@)jITq'B,>_!M%;79%3p,pOTFifX]RH?i0@^T0-n@=jGaQ/XXH2pR5Ac5@7@!O5Y.V0?]Q))3[Wi1MKM@<+W9)M+5r"e[eXn"p:h7'lp)HVcAPu:Qp:=W$oP3#W`86un2N+Rp&.h*k(16I2mW01bkR?4)-#SRB,k%qYAmaC/[5GE-7oN(,Lj##U"g9&S%&pi%"BMS,cf%=Cc,<60f^RW5;Dae.4-V,6Rd7VDkPIR7/[3E_]`![DZ3G3=^O@.@IICcN25=%O0g.BtgnVF5e5YnmN)lNjp76[UW+n;[$AOPQ$#>5?SgmKt+iB1u*3T9CiV-aq,TlPj_$&_H89*gfJO8T+@N62Rh(s<2^4OXD2G_p)Lk]d<Nk*SOV5tias;+8><MR@54D^A*(MdDN"+#/_l$)_bl%9n9E=J?!N:@BRG&p/bm"3W!gE/r<^qW3[b')*B0?m85aB3KI<#^a/oQAnSAc<CXmcr#<Gm/nA]r_p)='EobJ!i7*2"'Nd#nX%1QZa)_M%a^_hSgNXar_q<:<$f9D4KlP:K,X86$dg+hkCD9>3[Mrt,/hE=e5;JV:"qMq]A'=D"g:IVCE5h8I]nru?Or0)"cheZ^u9Sm#EHP%_m3sC-P^7`%(CF*EGO<>4*jQX_!"<:($"C2_]YHq-C<<f@:n@j/!f,:SBb5qaZYji_m)b:pbBl]M4_[HW=9u!ceX#">Y-tHQ9Ii,N,fGE+-^@hU&M1]X>@bf>bD#0*7"#-:Cq)_/e!6^+^D^Lg*%Z@DJ\!<@>BVWFaa)Ka^@5GS'hXaGZd,Dl[`XAo]:'7K!61Xe8rS5\*9`Ck)uWE1KHP?>tOQF`iE,l]I%)l*aZk*rPQ#eN;sc;rF+$+gV)C$cO^imU(Z@((d7[phH!JMY5O6N*mitT$8*q9R["JTBhKE%ml"EGFG2t,3c6V/R&J\+T`=rlSqgF+iQrM,I?TYo5e_NHL#fu(I6!JR,.?JK_6@3V`D"@kMF@a'lX>[0Y9s,76S,s!Zq^M!3\umq:*qRTL9g/0kDqIQJ`u5<Y;;W;QFB20h.X5^N'sF=1O[O]bpM9G1UZAn`Xm4nQE!+3IC4nK]n(XtT;0Sf:*NQ"*&'8`81@Fe@B/6rTp?tUENlOK:?RH04C6N[4N$)RpL*=V8iW(^k`c1uc]*T?(J/BHmY,SPdFuX&fTA#0e9e&em:HX53YbR1=!cR(B0o9.f'$(pSFZE)d]f^RER5%K-Dcfnq1iRY[cis6gK"XZ2pcA('br'#B'm0VRT=)d+!aF_[Xm=Y0[48kUQkn#02S<i`a?,(dqS4En7A6R>0/42LALIFX*36eY+GNZ:"MF<I`-B$+eMH`4OHPI,Z\ssUZ^=>_#OEM.6Zht]<EmGY`>-46>;ohfPdEI)g4&f[HlUZiXTFX<?VQ7%;a(ec[G?uI&\[email protected]#:1nFA5_ca5mB*=Gp:!pC24T:Gm&GOg@qV;oiXTr6Z)>?irY!E)W-oj&;5*2JJmEODXr=f"^Ds3n<UU$s-0'2.m&0Ed#U^A!i03K]jEp:JNmH!3s6_X%*T.W03AY4?]if%"&CrIPGF0?(5qEoDHF70Y;o5N+Wfq$g.H=oa'1T9Sd(U-V4Nff;ESN9UfP(6Y"`W?gd03D)<Sn<#mkcc.]V^I00r3isP)b"5)qg%VCGV4jf&h/\ir@5c$;I2Ap;7I*<kL'g)Y0@cNA4Rok]aqfkCXR(chBKT=N_cMrQ0/>Aq*%&7bJND\!q7[VJ?"BE9@NXWek3n61;FB])HbY$WAQ.$+ahnGPTn39HN`+^PP)9.P-Pc>9@UkE`=b.MXfkXK5`(F1BgO.Dcf;<Qua;<R06^PH^-7eGNg2VG[TXW9K9j.=^mFR2b_D[-11nFE;j:;O@abrfhY2G]gmmCB>n4kN!8U8tF;hSB1B1c23,]:RYo<lMt_HZtLZ]d;sRY?iD;Bpd-II4Opef!c[i8sa4Y((<Ts<Oja=hDI60d*W)MF,Jr*`6u@t,%_*RXFQ?$A$dh(3;+:>JPheD4RBsVVc0P?mo[aCF.IV0CY?:dBnfpCM3o?,`<k[-8Sb`go3^76T!-T3C=%2SJq$`r1_e57\J/\!k+%fBk1\TRriS>9os9h;-dp<%.K>momU.A@qn!RHCQI(s4RMaf;bpmST@?sJp?t]fh'OLj&?3JaWK-FOh6,5^Z/!c-rh5)<.a>X+h+L1FmscnqLjf~>endstream
endobj
xref
0 11
0000000000 65535 f
0000000061 00000 n
0000000102 00000 n
0000000209 00000 n
0000000321 00000 n
0000000514 00000 n
0000000708 00000 n
0000000776 00000 n
0000001056 00000 n
0000001121 00000 n
0000004086 00000 n
trailer
<<
/ID
[<451d734656bfda21b00c95ac21a36c22><451d734656bfda21b00c95ac21a36c22>]
% ReportLab generated PDF document -- digest (opensource)
/Info 7 0 R
/Root 6 0 R
/Size 11
>>
startxref
6878
%%EOF
+341 -371
View File
@@ -4,472 +4,442 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Chase Dumphord | Digital Systems & Infrastructure</title> <title>Ced's NOC | Live Systems Dashboard</title>
<meta <meta
name="description" name="description"
content="Chase Dumphord portfolio - digital systems, infrastructure, networking, automation, homelab engineering, and real-world technical projects." content="Ced's NOC — live network operations center dashboard showing real-time infrastructure health, service status, and edge system monitoring."
/> />
<link rel="stylesheet" href="style.css" /> <!-- Open Graph -->
<meta property="og:title" content="Ced's NOC | Live Systems Dashboard" />
<meta property="og:description" content="Live infrastructure visibility — Proxmox, K3s, TrueNAS, APRS edge systems." />
<meta property="og:type" content="website" />
<meta property="og:url" content="https://noc.chasedumphord.com" />
<!-- Favicons (path up one level since we're in /noc/) -->
<link rel="icon" type="image/png" sizes="32x32" href="../assets/favicons/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="../assets/favicons/favicon-16x16.png" />
<link rel="icon" type="image/png" sizes="192x192" href="../assets/favicons/favicon-192x192.png" />
<link rel="apple-touch-icon" sizes="512x512" href="../assets/favicons/favicon-512x512.png" />
<link rel="shortcut icon" href="../assets/favicons/favicon.ico" />
<meta name="robots" content="index, follow" />
<meta name="author" content="Chase Dumphord" />
<!-- Fonts — same as main site -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Syne:wght@700;800&family=DM+Sans:wght@400;500;700&display=swap" rel="stylesheet" />
<!-- Shared stylesheet (up one level) -->
<link rel="stylesheet" href="../style.css" />
<!-- NOC-specific styles -->
<style>
/* ── NOC page overrides & extras ── */
.noc-page-hero {
padding: 3.5rem 0 2rem;
border-bottom: 1px solid var(--line);
}
.noc-page-hero .eyebrow {
margin-bottom: 0.6rem;
}
.noc-page-title {
font-family: var(--font-display);
font-size: clamp(2rem, 4vw, 3.2rem);
font-weight: 800;
margin: 0 0 0.75rem;
line-height: 1.1;
}
.noc-page-title span {
color: var(--accent-2);
}
.noc-page-lead {
color: var(--muted);
font-size: 1rem;
max-width: 60ch;
margin: 0 0 1.5rem;
}
.noc-page-meta {
display: flex;
flex-wrap: wrap;
gap: 0.6rem 1.4rem;
font-family: var(--font-mono);
font-size: 0.78rem;
color: var(--muted);
list-style: none;
padding: 0;
margin: 0;
}
.noc-page-meta a { color: var(--muted); }
.noc-page-meta a:hover { color: var(--accent-2); }
/* Full-width NOC content area */
.noc-full {
padding: 2.5rem 0 4rem;
}
/* Uptime summary bar */
.uptime-bar {
display: flex;
flex-wrap: wrap;
gap: 0.75rem;
margin-bottom: 1.5rem;
}
.uptime-pill {
font-family: var(--font-mono);
font-size: 0.76rem;
padding: 0.35rem 0.75rem;
border-radius: 999px;
border: 1px solid var(--line);
color: var(--muted);
background: rgba(255,255,255,0.03);
}
.uptime-pill.online {
color: var(--accent-2);
border-color: rgba(94, 250, 204, 0.3);
background: rgba(94, 250, 204, 0.06);
}
.uptime-pill.warning {
color: var(--warning);
border-color: rgba(242, 204, 96, 0.3);
background: rgba(242, 204, 96, 0.06);
}
.uptime-pill.offline {
color: var(--danger);
border-color: rgba(255, 95, 86, 0.3);
background: rgba(255, 95, 86, 0.06);
}
/* Layer filter tabs */
.layer-tabs {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 1.5rem;
}
.layer-tab {
font-family: var(--font-mono);
font-size: 0.76rem;
font-weight: 700;
padding: 0.35rem 0.85rem;
border-radius: 999px;
border: 1px solid var(--line);
color: var(--muted);
background: transparent;
cursor: pointer;
transition: all 0.15s;
}
.layer-tab:hover,
.layer-tab.active {
color: var(--accent-2);
border-color: rgba(94, 250, 204, 0.35);
background: rgba(94, 250, 204, 0.07);
}
/* Roadmap section on NOC page */
.noc-roadmap {
margin-top: 3rem;
padding-top: 2.5rem;
border-top: 1px solid var(--line);
}
/* Stack info footer on NOC page */
.noc-stack-bar {
margin-top: 2.5rem;
padding: 1rem 1.25rem;
border-radius: var(--radius);
background: rgba(0,0,0,0.2);
border: 1px solid var(--line);
font-family: var(--font-mono);
font-size: 0.78rem;
color: var(--muted);
display: flex;
flex-wrap: wrap;
gap: 0.5rem 1.5rem;
align-items: center;
}
.noc-stack-bar strong {
color: var(--accent-2);
}
@media (max-width: 620px) {
.layer-tabs { gap: 0.4rem; }
.layer-tab { font-size: 0.7rem; padding: 0.3rem 0.65rem; }
}
</style>
</head> </head>
<body> <body>
<!-- ═══════════════════════════════ NAV ═══════════════════════════════ -->
<header class="site-header"> <header class="site-header">
<div class="container nav"> <div class="container nav">
<a href="#top" class="logo">Chase Dumphord</a> <a href="https://chasedumphord.com" class="logo">Ced<span class="logo-cursor">_</span></a>
<nav> <nav>
<ul class="nav-links"> <ul class="nav-links">
<li><a href="#snapshot">Snapshot</a></li> <li><a href="https://chasedumphord.com/#snapshot">Snapshot</a></li>
<li><a href="#noc">NOC</a></li> <li><a href="https://chasedumphord.com/#about">About</a></li>
<li><a href="#about">About</a></li> <li><a href="https://chasedumphord.com/#projects">Projects</a></li>
<li><a href="#projects">Projects</a></li> <li><a href="https://chasedumphord.com/#stack">Stack</a></li>
<li><a href="#resume">Resume</a></li> <li><a href="https://chasedumphord.com/#contact">Contact</a></li>
<li><a href="#contact">Contact</a></li> <li><a href="https://chasedumphord.com/assets/images/ChaseD_Resume.pdf" target="_blank" rel="noopener noreferrer">Resume</a></li>
</ul> </ul>
</nav> </nav>
</div> </div>
</header> </header>
<main id="top"> <main id="top">
<section class="hero">
<div class="container hero-grid">
<div class="hero-text">
<p class="eyebrow">Digital Systems • Infrastructure • Networking • Automation • Edge Systems</p>
<h1>I build practical systems that connect hardware, networks, software, and operations.</h1> <!-- ═══════════════════════════════ NOC HERO ═══════════════════════════════ -->
<div class="noc-page-hero">
<p class="lead"> <div class="container">
Im Chase Dumphord — a hands-on systems builder focused on digital infrastructure, <p class="eyebrow">
Linux systems, homelab engineering, Raspberry Pi deployments, networking, automation, <span class="eyebrow-dot"></span>
and real-world technical problem solving. Ced's NOC • Live Infrastructure Dashboard • Auto-refresh: 30s
</p> </p>
<div class="hero-actions"> <h1 class="noc-page-title">
<a class="btn btn-primary" href="#projects">View Projects</a> Live Systems <span>Dashboard</span>
<a class="btn btn-secondary" href="#contact">Contact Me</a> </h1>
</div>
<ul class="quick-facts"> <p class="noc-page-lead">
<li>Oxford, MS</li> Real-time visibility into Ced's HomeLab infrastructure — Proxmox, K3s,
<li> TrueNAS, APRS RF edge systems, and self-hosted services.
GitHub: Not simulated. Not a demo. Running hardware.
<a href="https://github.com/ced4568" target="_blank" rel="noopener noreferrer">ced4568</a> </p>
</li>
<li> <ul class="noc-page-meta">
Email: <li>📍 Oxford, MS</li>
<a href="mailto:chasedumphord@gmail.com">[email protected]</a> <li><a href="https://chasedumphord.com">← Portfolio</a></li>
</li> <li><a href="https://github.com/ced4568" target="_blank" rel="noopener noreferrer">github/ced4568</a></li>
</ul> </ul>
</div> </div>
<div class="hero-panel">
<img
src="assets/images/ChaseD_headshot.jpg"
alt="Headshot of Chase Dumphord"
class="hero-image"
/>
<div class="terminal-card">
<div class="terminal-top">
<span></span>
<span></span>
<span></span>
</div> </div>
<pre><code>$ whoami <!-- ═══════════════════════════════ NOC DASHBOARD ═══════════════════════════════ -->
systems_builder <div class="noc-full">
$ focus
infrastructure
networking
automation
edge_systems
$ status
building_real_systems</code></pre>
</div>
</div>
</div>
</section>
<section id="snapshot" class="section section-alt">
<div class="container"> <div class="container">
<div class="section-heading">
<p class="section-label">Environment</p>
<h2>Systems Snapshot</h2>
<p class="section-intro">
A quick look at the infrastructure and systems Im actively building and documenting.
</p>
</div>
<div class="stats-grid">
<div class="stat-card">
<h3>12+</h3>
<p>Nodes</p>
<span>K3s cluster environment</span>
</div>
<div class="stat-card">
<h3>10+</h3>
<p>Services</p>
<span>Self-hosted stack</span>
</div>
<div class="stat-card">
<h3>4</h3>
<p>VLANs</p>
<span>Segmented network design</span>
</div>
<div class="stat-card">
<h3>2</h3>
<p>iGate Nodes</p>
<span>Home + mobile APRS</span>
</div>
</div>
</div>
</section>
<section id="noc" class="section noc-dashboard">
<div class="container">
<div class="section-heading">
<p class="section-label">Ceds NOC</p>
<h2>Live Systems Overview</h2>
<p class="section-intro">
Real infrastructure inventory from Ceds HomeLab, K3s cluster, and APRS edge systems.
</p>
</div>
<!-- Status command bar -->
<div class="noc-command-bar"> <div class="noc-command-bar">
<span class="status-dot"></span> <span class="status-dot" id="noc-dot"></span>
<span id="noc-status-text">Loading NOC status...</span> <span id="noc-status-text">Connecting to NOC feed...</span>
<span class="noc-refresh-badge" id="noc-refresh-badge"></span>
</div> </div>
<p class="noc-proof"> <p class="noc-proof">
Built using real infrastructure: Proxmox • K3s • TrueNAS • VLAN segmentation • APRS RF Edge Systems Proxmox • K3s • TrueNAS • VLAN Segmentation • APRS RF Edge Systems
</p> </p>
<!-- Uptime summary pills (populated by JS) -->
<div class="uptime-bar" id="uptime-bar"></div>
<!-- Metrics -->
<div class="noc-metrics-grid"> <div class="noc-metrics-grid">
<div class="noc-metric"> <div class="noc-metric">
<h3 id="metric-nodes">--</h3> <h3 id="metric-nodes">--</h3>
<p>Infrastructure Nodes</p> <p>Infrastructure Nodes</p>
</div> </div>
<div class="noc-metric"> <div class="noc-metric">
<h3 id="metric-services">--</h3> <h3 id="metric-services">--</h3>
<p>Services Online</p> <p>Services Online</p>
</div> </div>
<div class="noc-metric"> <div class="noc-metric">
<h3 id="metric-vlans">--</h3> <h3 id="metric-vlans">--</h3>
<p>Network Segments</p> <p>Network Segments</p>
</div> </div>
<div class="noc-metric"> <div class="noc-metric">
<h3 id="metric-edge">--</h3> <h3 id="metric-edge">--</h3>
<p>Edge Systems</p> <p>Edge Systems</p>
</div> </div>
</div> </div>
<!-- Alert panel -->
<div class="noc-alert-panel"> <div class="noc-alert-panel">
<div class="noc-alert-header"> <div class="noc-alert-header">
<h3>🚨 NOC Alert Panel</h3> <h3>🚨 Alert Panel</h3>
<span>Top 3 System Notes</span> <span>Top 3 Priority Systems</span>
</div> </div>
<div id="noc-alert-list" class="noc-alert-list"> <div id="noc-alert-list" class="noc-alert-list">
<p>Loading alerts...</p> <p class="noc-loading">Awaiting data feed...</p>
</div> </div>
</div> </div>
<!-- Layer filter tabs -->
<div class="layer-tabs" id="layer-tabs">
<button class="layer-tab active" data-layer="all">All Systems</button>
</div>
<!-- System cards grid -->
<div id="noc-system-grid" class="noc-system-grid"></div> <div id="noc-system-grid" class="noc-system-grid"></div>
</div>
</section>
<section id="about" class="section"> <!-- Fallback -->
<div class="container"> <div id="noc-fallback" class="noc-fallback" style="display:none;">
<div class="section-heading"> <p class="noc-fallback-msg">
<p class="section-label">About</p> 📡 NOC feed unavailable from this context — systems run locally.<br/>
<h2>Hands-on systems builder with a digital infrastructure mindset</h2> Data updates when the local pipeline pushes a fresh noc-status.json.
</div>
<div class="content-grid">
<div class="card">
<p>
Im a technical professional focused on digital systems, infrastructure, networking,
automation, and hands-on system integration. I enjoy building systems that are practical,
reliable, and well documented — from homelab services and dashboards to Raspberry Pi
deployments, APRS iGates, and troubleshooting workflows.
</p>
<p>
My background blends field engineering, industrial technology, software-oriented thinking,
and infrastructure problem solving. Im especially interested in projects that connect the
physical and digital worlds through monitoring, networking, automation, and resilient design.
</p> </p>
</div> </div>
<div class="card"> <!-- Stack info bar -->
<h3>Core Focus Areas</h3> <div class="noc-stack-bar">
<span><strong>Stack:</strong> Python health checks → JSON → JS dashboard</span>
<ul class="clean-list"> <span><strong>Next:</strong> Grafana + Prometheus integration</span>
<li>Digital systems and infrastructure</li> <span><strong>Source:</strong>
<li>Linux systems and service management</li> <a href="https://github.com/ced4568/ceds-homelab" target="_blank" rel="noopener noreferrer">
<li>Networking, VLANs, failover, and connectivity troubleshooting</li> github/ceds-homelab
<li>Raspberry Pi and edge-device deployments</li>
<li>Documentation, process building, and reproducible project design</li>
</ul>
</div>
</div>
</div>
</section>
<section id="projects" class="section section-alt">
<div class="container">
<div class="section-heading">
<p class="section-label">Projects</p>
<h2>🔧 Infrastructure & Systems Projects</h2>
<p class="section-intro">
These projects are built around real systems, networking, Linux services, edge devices,
and practical documentation.
</p>
</div>
<div class="projects-grid">
<article class="project-card featured-project">
<div class="project-top">
<h3>🧠 Ceds HomeLab Infrastructure</h3>
<span class="status-pill">Flagship</span>
</div>
<p class="tags">Infrastructure • Networking • Virtualization • Monitoring • Self-Hosting</p>
<p class="project-impact">
Designed as a practical infrastructure environment for networking, monitoring,
service hosting, and documentation.
</p>
<p>
Personal infrastructure lab focused on network segmentation, virtualization,
self-hosted services, monitoring, and architecture documentation.
</p>
<ul class="clean-list">
<li>VLAN segmentation and network design</li>
<li>Proxmox virtualization</li>
<li>Self-hosted services and monitoring</li>
<li>System architecture documentation</li>
</ul>
<a href="https://github.com/ced4568/ceds-homelab" target="_blank" rel="noopener noreferrer" class="project-link">
View Project →
</a> </a>
</article> </span>
<article class="project-card">
<div class="project-top">
<h3>☸️ K3s Kubernetes Cluster</h3>
<span class="status-pill">Infrastructure</span>
</div> </div>
<p class="tags">Kubernetes • Containers • Linux • Infrastructure • Automation</p> <!-- NOC Roadmap -->
<div class="noc-roadmap">
<p class="project-impact"> <p class="section-label">// noc roadmap</p>
Built to simulate distributed infrastructure, container orchestration, and scalable service deployment. <h2 class="section-h2" style="font-family:var(--font-display);font-size:1.6rem;margin:0 0 1.25rem;">Build Stages</h2>
</p>
<p>
Multi-node K3s cluster built for container orchestration, service deployment,
and infrastructure experimentation.
</p>
<ul class="clean-list">
<li>Multi-node cluster setup</li>
<li>Containerized workloads</li>
<li>Service deployment</li>
<li>Infrastructure automation</li>
</ul>
<a href="https://github.com/ced4568/ced-k3s-homelab" target="_blank" rel="noopener noreferrer" class="project-link">
View Project →
</a>
</article>
<article class="project-card">
<div class="project-top">
<h3>📡 APRS iGate System</h3>
<span class="status-pill">Edge System</span>
</div>
<p class="tags">RF • Linux • Raspberry Pi • Networking • APRS-IS • Edge Systems</p>
<p class="project-impact">
Bridges RF communication into IP-based infrastructure using Linux, Direwolf, and APRS-IS.
</p>
<p>
Operational dual-node APRS iGate system built with Raspberry Pi, Direwolf, APRS-IS,
RF radios, HomeLab network integration, and planned mobile GPS support.
</p>
<ul class="clean-list">
<li>RF packet decoding with Direwolf</li>
<li>APRS-IS uplink verified on aprs.fi</li>
<li>HomeLab WiFi + mobile hotspot failover</li>
<li>Mobile build includes ETH-USB-HUB-BOX expansion</li>
<li>Documented configs, architecture, and troubleshooting</li>
</ul>
<a href="https://github.com/ced4568/ceds-aprs-igate" target="_blank" rel="noopener noreferrer" class="project-link">
View Project →
</a>
</article>
</div>
</div>
</section>
<section class="section noc-section">
<div class="container">
<div class="section-heading">
<p class="section-label">NOC Roadmap</p>
<h2>📊 Ceds NOC Vision</h2>
<p class="section-intro">
Ceds NOC is being built as a staged monitoring and systems-visibility platform for HomeLab,
Kubernetes, edge devices, and future production-style dashboards.
</p>
</div>
<div class="noc-grid"> <div class="noc-grid">
<div class="noc-card"> <div class="noc-card">
<h3>✅ Current: Portfolio NOC</h3> <div class="noc-card-badge done">✅ Live</div>
<h3>Portfolio NOC</h3>
<p> <p>
JSON-driven dashboard that displays real inventory, online/offline checks, service labels, JSON-driven dashboard showing real inventory, online/offline checks,
latency, and last-check timestamps. service labels, latency, and last-check timestamps.
</p> </p>
</div> </div>
<div class="noc-card"> <div class="noc-card">
<h3>⚙️ Next: Automated Data Updates</h3> <div class="noc-card-badge next">⚙️ Next</div>
<h3>Automated Data Updates</h3>
<p> <p>
Scheduled local script updates will refresh system status data automatically and push dashboard-ready Scheduled scripts auto-refresh system status and push dashboard-ready
JSON into the portfolio. JSON on a cron interval — no manual updates.
</p> </p>
</div> </div>
<div class="noc-card"> <div class="noc-card">
<h3>📈 Future: Grafana + Prometheus</h3> <div class="noc-card-badge future">📈 Future</div>
<h3>Grafana + Prometheus</h3>
<p> <p>
Deeper monitoring stack for Proxmox, TrueNAS, K3s, Raspberry Pi nodes, Uptime Kuma, Full observability stack for Proxmox, TrueNAS, K3s, Raspberry Pi,
and APRS edge systems. Uptime Kuma, and APRS edge systems with real-time metrics.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</section>
<section id="resume" class="section">
<div class="container">
<div class="section-heading">
<p class="section-label">Resume Snapshot</p>
<h2>Technical experience that bridges field work and digital systems</h2>
</div>
<div class="content-grid">
<div class="card">
<h3>What I Bring</h3>
<ul class="clean-list">
<li>Industrial and field-service technical experience</li>
<li>Linux, Raspberry Pi, and systems administration work</li>
<li>Networking, connectivity, and troubleshooting depth</li>
<li>Documentation, process building, and reproducible project design</li>
</ul>
</div>
<div class="card">
<h3>Current Direction</h3>
<p>
Im positioning myself around digital systems, infrastructure, networking,
automation, and technical operations — especially roles where hands-on problem
solving and system integration matter.
</p>
<p>
More detailed resume content will be added here as the portfolio grows.
</p>
</div> </div>
</div> </div>
</div>
</section>
<section class="section section-alt personal-section">
<div class="container personal-grid">
<div class="personal-image-wrap">
<img
src="assets/images/lakephotopinkpants.png"
alt="Chase Dumphord standing by a fence with a lake view in the background"
class="personal-image"
/>
</div>
<div class="card">
<p class="section-label">Personal Note</p>
<h2>Technical, curious, and always building</h2>
<p>
Outside of work, I enjoy electronics, self-hosting, coding, drones, radio, and
hands-on technical projects that push me to learn something useful. That curiosity
carries directly into the way I build and document systems.
</p>
</div>
</div>
</section>
<section id="contact" class="section">
<div class="container">
<div class="section-heading">
<p class="section-label">Contact</p>
<h2>Lets connect</h2>
</div>
<div class="contact-grid">
<div class="card">
<h3>Contact Info</h3>
<p>Email: <a href="mailto:[email protected]">[email protected]</a></p>
<p>Phone: <a href="tel:+16622142231">662-214-2231</a></p>
<p>Location: Oxford, MS</p>
<p>
GitHub:
<a href="https://github.com/ced4568" target="_blank" rel="noopener noreferrer">github.com/ced4568</a>
</p>
</div>
<div class="card">
<h3>What Im Open To</h3>
<ul class="clean-list">
<li>Digital systems and infrastructure roles</li>
<li>Networking and technical operations work</li>
<li>Automation and monitoring projects</li>
<li>Projects involving hardware + software integration</li>
</ul>
</div>
</div>
</div>
</section>
</main> </main>
<!-- ═══════════════════════════════ FOOTER ═══════════════════════════════ -->
<footer class="site-footer"> <footer class="site-footer">
<div class="container footer-content"> <div class="container footer-content">
<p>© <span data-year></span> Chase Dumphord</p> <p>© <span data-year></span> Chase Dumphord<span class="footer-mono">noc.chasedumphord.com</span></p>
<a href="#top" class="back-to-top">Back to top</a> <a href="#top" class="back-to-top">↑ back to top</a>
</div> </div>
</footer> </footer>
<script src="script.js"></script> <!-- Shared script (up one level) -->
<script src="../script.js"></script>
<!-- NOC page extras — layer filter tabs + uptime pills -->
<script>
// ── Layer filter tabs ──────────────────────────────────────────
// Populated after NOC data loads. Filters the system grid by layer.
let allSystems = [];
const originalLoad = window.loadNocStatus;
document.addEventListener("DOMContentLoaded", () => {
// Hook into data after the shared script loads it
const observer = new MutationObserver(() => {
const cards = document.querySelectorAll(".noc-system-card");
if (cards.length > 0) {
buildLayerTabs();
buildUptimePills();
observer.disconnect();
}
});
const grid = document.getElementById("noc-system-grid");
if (grid) observer.observe(grid, { childList: true });
});
function buildLayerTabs() {
const cards = document.querySelectorAll(".noc-system-card");
const layers = new Set(["all"]);
cards.forEach(card => {
const layerEl = card.querySelector(".noc-system-top span:last-child");
if (layerEl) layers.add(layerEl.textContent.trim());
});
const tabContainer = document.getElementById("layer-tabs");
tabContainer.innerHTML = "";
layers.forEach(layer => {
const btn = document.createElement("button");
btn.className = "layer-tab" + (layer === "all" ? " active" : "");
btn.dataset.layer = layer;
btn.textContent = layer === "all" ? "All Systems" : layer;
btn.addEventListener("click", () => filterByLayer(layer, btn));
tabContainer.appendChild(btn);
});
}
function filterByLayer(layer, activeBtn) {
document.querySelectorAll(".layer-tab").forEach(t => t.classList.remove("active"));
activeBtn.classList.add("active");
document.querySelectorAll(".noc-system-card").forEach(card => {
if (layer === "all") {
card.style.display = "";
return;
}
const layerEl = card.querySelector(".noc-system-top span:last-child");
card.style.display =
layerEl && layerEl.textContent.trim() === layer ? "" : "none";
});
}
function buildUptimePills() {
const bar = document.getElementById("uptime-bar");
if (!bar) return;
const cards = document.querySelectorAll(".noc-system-card");
let online = 0, warning = 0, offline = 0;
cards.forEach(card => {
const dot = card.querySelector(".mini-status");
if (!dot) return;
if (dot.classList.contains("online")) online++;
else if (dot.classList.contains("warning")) warning++;
else if (dot.classList.contains("offline")) offline++;
});
bar.innerHTML = `
<span class="uptime-pill online">● ${online} Online</span>
${warning > 0 ? `<span class="uptime-pill warning">● ${warning} Degraded</span>` : ""}
${offline > 0 ? `<span class="uptime-pill offline">● ${offline} Offline</span>` : ""}
<span class="uptime-pill">${online + warning + offline} Total Systems</span>
`;
}
</script>
</body> </body>
</html> </html>
-148
View File
@@ -1,148 +0,0 @@
document.addEventListener("DOMContentLoaded", () => {
const yearSpan = document.querySelector("[data-year]");
if (yearSpan) {
yearSpan.textContent = new Date().getFullYear();
}
loadNocStatus();
setInterval(loadNocStatus, 30000);
});
async function loadNocStatus() {
try {
const response = await fetch("data/noc-status.json");
if (!response.ok) {
throw new Error(`HTTP error: ${response.status}`);
}
const data = await response.json();
const statusText = document.getElementById("noc-status-text");
const nodes = document.getElementById("metric-nodes");
const services = document.getElementById("metric-services");
const vlans = document.getElementById("metric-vlans");
const edge = document.getElementById("metric-edge");
const grid = document.getElementById("noc-system-grid");
const alertList = document.getElementById("noc-alert-list");
if (!statusText || !nodes || !services || !vlans || !edge || !grid) {
return;
}
statusText.textContent = `${data.nocName}${data.status} — Last updated: ${data.lastUpdated}`;
animateMetric(nodes, data.summary.nodes);
animateMetric(services, data.summary.services);
animateMetric(vlans, data.summary.vlans);
animateMetric(edge, data.summary.edgeSystems);
grid.innerHTML = "";
data.systems.forEach((system) => {
const card = document.createElement("article");
card.className = "noc-system-card";
const status = system.status.toLowerCase();
const statusClass =
status.includes("online") || status.includes("operational")
? "online"
: status.includes("building") || status.includes("tuning") || status.includes("active")
? "warning"
: "offline";
card.innerHTML = `
<div class="noc-system-top">
<span class="mini-status ${statusClass}"></span>
<span>${system.layer}</span>
</div>
<div class="system-label">${system.label || "System"}</div>
<div class="severity-pill ${system.severity?.toLowerCase() || "unknown"}">
${system.severity || "Unknown"}
</div>
<h3>${system.name}</h3>
<p>${system.type}</p>
<code>${system.address}</code>
<div class="system-meta">
<small>Status: ${system.status}</small>
<small>Latency: ${system.latency || "N/A"}</small>
<small>Last Check: ${system.lastCheck || "Manual"}</small>
</div>
`;
grid.appendChild(card);
});
if (alertList) {
renderAlerts(data.systems, alertList);
}
} catch (error) {
const statusText = document.getElementById("noc-status-text");
if (statusText) {
statusText.textContent = "Ceds NOC data unavailable";
}
console.error("Failed to load NOC status:", error);
}
}
function animateMetric(element, value) {
element.classList.remove("metric-pop");
element.textContent = value;
void element.offsetWidth;
element.classList.add("metric-pop");
}
function renderAlerts(systems, alertList) {
const priority = systems
.map((system) => {
const severity = (system.severity || "Unknown").toLowerCase();
const status = (system.status || "").toLowerCase();
let score = 0;
if (severity.includes("critical") || status.includes("offline")) {
score = 3;
} else if (severity.includes("degraded")) {
score = 2;
} else if (severity.includes("unknown")) {
score = 1;
}
return { ...system, score };
})
.filter((system) => system.score > 0)
.sort((a, b) => b.score - a.score)
.slice(0, 3);
if (priority.length === 0) {
alertList.innerHTML = `
<div class="noc-alert healthy">
<strong>All monitored systems healthy</strong>
<span>No critical or degraded systems detected.</span>
</div>
`;
return;
}
alertList.innerHTML = priority
.map((system) => {
const alertClass =
system.score === 3 ? "critical" : system.score === 2 ? "degraded" : "unknown";
return `
<div class="noc-alert ${alertClass}">
<strong>${system.name}</strong>
<span>${system.severity || system.status}${system.layer}${system.latency || "N/A"}</span>
</div>
`;
})
.join("");
}