feat: implement CSS sprite system for image optimization
Reduces HTTP requests from 44+ individual images to 3 sprite sheets (~93% reduction). Includes Go sprite generator tool, CSS classes, template integration, and E2E tests. - Add cmd/sprites/main.go for sprite generation (60x60px + 120x120px @2x) - Add _sprites.css with responsive sizing and retina support - Update templates to use sprites with logoIndex fallback - Add Makefile targets: sprites, sprites-clean - Add 9-test E2E suite for sprite functionality - Add doc/22-SPRITES.md with usage documentation
This commit is contained in:
@@ -13,15 +13,15 @@
|
||||
</summary>
|
||||
{{range .CV.Courses}}
|
||||
<div class="course-item" id="course-{{.CourseID}}" data-course="{{.CourseID}}" data-title="{{.Title}}" data-institution="{{.Institution}}">
|
||||
{{if .CourseLogo}}
|
||||
<div class="course-icon">
|
||||
{{if .LogoIndex}}
|
||||
<span class="icon-sprite icon-section icon-course" style="--icon-index: {{.LogoIndex}};" role="img" aria-label="{{.Title}} logo"></span>
|
||||
{{else if .CourseLogo}}
|
||||
<img src="/static/images/courses/{{.CourseLogo}}" alt="{{.Title}} logo" onerror="this.parentElement.innerHTML='<iconify-icon icon=\'mdi:school\' width=\'80\' height=\'80\' class=\'default-course-icon\'></iconify-icon>'">
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="course-icon">
|
||||
{{else}}
|
||||
<iconify-icon icon="mdi:school" width="80" height="80" class="default-course-icon"></iconify-icon>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="course-content">
|
||||
<strong>{{.Title}}</strong><br>
|
||||
<small>{{.Institution}} - {{.Date}} - ({{.Location}})</small>
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
{{range .CV.Experience}}
|
||||
<div class="experience-item" id="exp-{{.CompanyID}}" data-company="{{.CompanyID}}" data-title="{{.Company}}" data-position="{{.Position}}">
|
||||
<div class="company-logo">
|
||||
{{if .CompanyLogo}}
|
||||
{{if .LogoIndex}}
|
||||
<span class="icon-sprite icon-section icon-company" style="--icon-index: {{.LogoIndex}};" role="img" aria-label="{{.Company}} logo"></span>
|
||||
{{else if .CompanyLogo}}
|
||||
<img src="/static/images/companies/{{.CompanyLogo}}" alt="{{.Company}} logo" onerror="this.parentElement.innerHTML='<iconify-icon icon=\'mdi:office-building\' width=\'80\' height=\'80\' class=\'default-company-icon\'></iconify-icon>'">
|
||||
{{else}}
|
||||
<iconify-icon icon="mdi:office-building" width="80" height="80" class="default-company-icon"></iconify-icon>
|
||||
|
||||
@@ -13,15 +13,15 @@
|
||||
</summary>
|
||||
{{range .CV.Projects}}
|
||||
<div class="project-item" id="proj-{{.ProjectID}}" data-project="{{.ProjectID}}" data-title="{{if .ProjectName}}{{.ProjectName}}{{else}}{{.Title}}{{end}}">
|
||||
{{if .ProjectLogo}}
|
||||
<div class="project-icon">
|
||||
{{if .LogoIndex}}
|
||||
<span class="icon-sprite icon-section icon-project" style="--icon-index: {{.LogoIndex}};" role="img" aria-label="{{.Title}} logo"></span>
|
||||
{{else if .ProjectLogo}}
|
||||
<img src="/static/images/projects/{{.ProjectLogo}}" alt="{{.Title}} logo" onerror="this.parentElement.innerHTML='<iconify-icon icon=\'mdi:web\' width=\'80\' height=\'80\' class=\'default-project-icon\'></iconify-icon>'">
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="project-icon">
|
||||
{{else}}
|
||||
<iconify-icon icon="mdi:web" width="80" height="80" class="default-project-icon"></iconify-icon>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="project-content">
|
||||
<strong>
|
||||
{{if .ProjectName}}
|
||||
|
||||
Reference in New Issue
Block a user