improving responsiviness
All checks were successful
Homepage Build and Deploy / Build Homepage Image (push) Successful in 10m21s
Homepage Build and Deploy / Deploy Homepage (push) Successful in 31s

This commit is contained in:
2025-08-28 17:41:49 -03:00
parent 552ae580ea
commit 0293a5fa9d
9 changed files with 332 additions and 99 deletions

View File

@@ -1,85 +0,0 @@
name: (Matrix) Homepage Build and Deploy
on:
push:
workflow_dispatch:
env:
REGISTRY_HOST: git.ivanch.me
REGISTRY_USERNAME: ivanch
IMAGE_NAME: ${{ env.REGISTRY_HOST }}/ivanch/mainpage
jobs:
build:
strategy:
matrix:
include:
- platform: linux/amd64
runner: ubuntu-slim
arch: amd64
- platform: linux/arm64
runner: ubuntu-arm64 # Your ARM64 runner label
arch: arm64
runs-on: ${{ matrix.runner }}
name: Build Homepage Image (${{ matrix.arch }})
steps:
- name: Check out repository
uses: actions/checkout@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" \
| docker login "${{ env.REGISTRY_HOST }}" \
-u "${{ env.REGISTRY_USERNAME }}" \
--password-stdin
- name: Build and Push Multi-Arch Image
uses: docker/build-push-action@v6
with:
push: true
context: .
platforms: ${{ matrix.platform }}
tags: |
${{ env.IMAGE_NAME }}:${{ matrix.arch }}
cache-from: type=gha
cache-to: type=gha,mode=max
create-manifest:
needs: build
runs-on: ubuntu-latest
steps:
- name: Log in to Container Registry
run: |
echo "${{ secrets.REGISTRY_PASSWORD }}" \
| docker login "${{ env.REGISTRY_HOST }}" \
-u "${{ env.REGISTRY_USERNAME }}" \
--password-stdin
- name: Create and push manifest
run: |
docker manifest create ${{ env.IMAGE_NAME }}:latest \
${{ env.IMAGE_NAME }}:amd64 \
${{ env.IMAGE_NAME }}:arm64
docker manifest push ${{ env.IMAGE_NAME }}:latest
deploy_ivanch_me:
name: Deploy Homepage
runs-on: ubuntu-amd64
needs: build_ivanch_me
steps:
- name: Recreate Container
uses: appleboy/ssh-action@v0.1.7
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.KEY }}
port: ${{ secrets.PORT }}
script: |
cd ${{ secrets.DIR }}
docker compose pull
docker compose up -d --force-recreate

View File

@@ -12,6 +12,11 @@
transition: all 0.3s ease; transition: all 0.3s ease;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 44px; /* Minimum touch target size for mobile */
text-align: center;
} }
.btn:hover { .btn:hover {
@@ -19,3 +24,19 @@
transform: translateY(-1px); transform: translateY(-1px);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15), 0 3px 6px rgba(0, 0, 0, 0.1); box-shadow: 0 8px 12px rgba(0, 0, 0, 0.15), 0 3px 6px rgba(0, 0, 0, 0.1);
} }
/* Mobile button improvements */
@media (max-width: 768px) {
.btn {
min-height: 48px;
padding: 12px 20px;
font-size: 14px;
}
}
@media (max-width: 480px) {
.btn {
padding: 10px 16px;
font-size: 13px;
}
}

View File

@@ -13,6 +13,12 @@ body {
min-height: 100vh; min-height: 100vh;
overflow-x: hidden; overflow-x: hidden;
position: relative; position: relative;
/* Improve text rendering on mobile */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Prevent text size adjust on orientation change */
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
} }
h1, h1,
@@ -119,9 +125,26 @@ img {
max-width: 26rem; max-width: 26rem;
} }
@media (max-width: 768px) { /* Mobile responsive content */
@media (max-width: 1024px) {
.content {
min-width: unset;
max-width: unset;
width: 100%;
padding: 24px 20px;
}
.main-container { .main-container {
padding: 0 15px; position: relative;
top: auto;
left: auto;
transform: none;
padding: 20px 15px;
min-height: 100vh;
display: flex;
align-items: flex-start;
padding-top: 40px;
padding-bottom: 40px;
} }
} }
@@ -129,6 +152,19 @@ img {
body { body {
font-size: 14px; font-size: 14px;
} }
.main-container {
padding: 15px 10px;
padding-top: 30px;
padding-bottom: 30px;
}
.content {
padding: 20px 16px;
min-width: unset;
max-width: unset;
width: 100%;
}
} }
/* Accessibility: disable animated shadows for users who prefer reduced motion */ /* Accessibility: disable animated shadows for users who prefer reduced motion */
@@ -137,3 +173,22 @@ img {
animation: none !important; animation: none !important;
} }
} }
/* High DPI display optimizations */
@media only screen and (-webkit-min-device-pixel-ratio: 2),
only screen and (min--moz-device-pixel-ratio: 2),
only screen and (-o-min-device-pixel-ratio: 2/1),
only screen and (min-device-pixel-ratio: 2),
only screen and (min-resolution: 192dpi),
only screen and (min-resolution: 2dppx) {
.glass {
/* Enhanced blur for high DPI screens */
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
.content {
backdrop-filter: blur(40px) saturate(180%) brightness(1.1);
-webkit-backdrop-filter: blur(40px) saturate(180%) brightness(1.1);
}
}

View File

@@ -57,8 +57,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 24px; gap: 24px;
flex: 1 1 0;
min-width: 0;
} }
.hero-card { .hero-card {
@@ -92,6 +90,8 @@
display: flex; display: flex;
gap: 16px; gap: 16px;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center;
align-items: center;
} }
.social-link { .social-link {
display: inline-flex; display: inline-flex;
@@ -99,13 +99,37 @@
gap: 8px; gap: 8px;
} }
@media (max-width: 900px) { /* Responsive Design - Mobile First Approach */
@media (max-width: 1024px) {
.hero-details { .hero-details {
flex-direction: column; flex-direction: column;
gap: 24px; gap: 24px;
} }
.hero-card { .hero-card {
grid-template-columns: 1fr; grid-template-columns: 1fr;
text-align: center;
}
}
/* Ensure hero main column and its boxes fill available width on tablet/mobile */
@media (max-width: 1024px) {
.hero-main-column {
width: 100%;
align-items: stretch;
}
/* Override .content fixed min/max so it can expand to the container */
.content {
min-width: unset;
max-width: unset;
width: 100%;
}
.homelab-section {
min-width: unset;
max-width: unset;
width: 100%;
} }
} }
@@ -123,10 +147,12 @@
.description { .description {
font-size: 1.1rem; font-size: 1.1rem;
margin-bottom: 24px;
} }
.social-links { .social-links {
justify-content: center; justify-content: center;
gap: 14px;
} }
} }
@@ -139,12 +165,37 @@
font-size: 1.8rem; font-size: 1.8rem;
} }
.description {
font-size: 1rem;
margin-bottom: 20px;
}
.social-links { .social-links {
gap: 12px; gap: 12px;
flex-wrap: wrap;
} }
.social-link { .social-link {
padding: 10px 16px; padding: 10px 14px;
font-size: 13px; font-size: 13px;
min-width: 0;
flex: 1;
max-width: calc(50% - 6px);
justify-content: center;
}
.social-link span {
display: none;
}
.social-link i {
font-size: 16px;
}
}
@media (max-width: 380px) {
.social-link {
max-width: calc(100% / 2 - 6px);
padding: 12px;
} }
} }

View File

@@ -14,6 +14,53 @@
gap: 18px; gap: 18px;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
text-align: center;
}
/* Mobile responsive homelab section */
@media (max-width: 768px) {
.homelab-section {
min-width: unset;
max-width: unset;
width: 100%;
padding: 28px 20px;
}
.homelab-title {
font-size: 1.3rem;
text-align: center;
}
.homelab-buttons {
justify-content: center;
}
}
@media (max-width: 480px) {
.homelab-section {
padding: 24px 16px;
gap: 16px;
min-width: unset;
max-width: unset;
width: 100%;
}
.homelab-title {
font-size: 1.2rem;
}
.homelab-buttons {
gap: 12px;
flex-direction: column;
align-items: center;
}
.homelab-btn {
width: 100%;
max-width: 200px;
text-align: center;
justify-content: center;
}
} }
.homelab-background { .homelab-background {

View File

@@ -10,6 +10,7 @@
.profile-info-item { .profile-info-item {
display: flex; display: flex;
flex-direction: row;
align-items: center; align-items: center;
gap: 0.6rem; gap: 0.6rem;
font-size: 0.95rem; font-size: 0.95rem;
@@ -76,19 +77,71 @@
border-radius: var(--border-radius-large); border-radius: var(--border-radius-large);
} }
@media (max-width: 768px) { @media (max-width: 1024px) {
.profile-info {
align-items: center;
margin-top: 1.5rem;
}
.avatar {
width: 140px;
height: 140px;
margin: 0 auto;
}
}
@media (max-width: 768px) {
.profile-container {
text-align: center;
}
.profile-info {
align-items: center;
margin-top: 1.5rem;
}
.profile-info-item {
justify-content: center;
text-align: center;
}
.avatar { .avatar {
width: 140px; width: 140px;
height: 140px; height: 140px;
margin: 0 auto; margin: 0 auto;
font-size: 40px;
} }
} }
@media (max-width: 480px) { @media (max-width: 480px) {
.profile-info {
gap: 0.8rem;
margin-top: 1.2rem;
}
.profile-info-item {
font-size: 0.9rem;
flex-direction: row;
gap: 0.4rem;
}
.profile-info-item i {
font-size: 1.2rem;
margin-right: 0.2rem;
}
.avatar { .avatar {
width: 120px; width: 120px;
height: 120px; height: 120px;
font-size: 32px; }
}
@media (max-width: 380px) {
.avatar {
width: 100px;
height: 100px;
}
.profile-info-item {
font-size: 0.85rem;
} }
} }

View File

@@ -66,12 +66,24 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
gap: 8px;
} }
.project-icons { .project-icons {
display: flex; display: flex;
gap: 8px; gap: 8px;
align-items: center; align-items: center;
flex: 0 0 auto;
flex-wrap: nowrap;
}
/* Ensure long titles don't push icons to a new line */
.project-title > span:first-child {
flex: 1 1 auto;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
} }
.project-icon-link { .project-icon-link {
@@ -94,12 +106,66 @@
} }
@media (max-width: 900px) { @media (max-width: 1024px) {
.projects-section { .projects-section {
flex: unset; flex: unset;
max-width: 100%; max-width: 100%;
margin-left: 0; margin-left: 0;
margin-top: 24px; margin-top: 24px;
max-width: 100%; min-width: unset;
}
}
@media (max-width: 768px) {
.projects-section {
padding: 28px 20px;
gap: 16px;
}
.projects-title {
font-size: 1.5rem;
text-align: center;
margin-bottom: 12px;
}
}
@media (max-width: 480px) {
.projects-section {
padding: 24px 16px;
gap: 14px;
}
.projects-title {
font-size: 1.4rem;
}
.project {
padding: 16px 14px;
}
.project-title {
font-size: 1.1rem;
}
.project-desc {
font-size: 0.95rem;
}
.project-icons {
gap: 6px;
}
}
@media (max-width: 380px) {
.project {
padding: 14px 12px;
}
.project-title {
font-size: 1.05rem;
/* Keep a single row layout even on very small screens */
flex-direction: row;
align-items: center;
gap: 8px;
} }
} }

View File

@@ -2,10 +2,16 @@
<html lang="en"> <html lang="en">
<head> <head>
<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, maximum-scale=5.0, user-scalable=yes">
<meta name="description" content="ivanch's personal portfolio showcasing projects and homelab setup."> <meta name="description" content="ivanch's personal portfolio showcasing projects and homelab setup.">
<meta name="author" content="ivanch"> <meta name="author" content="ivanch">
<!-- Mobile optimization -->
<meta name="format-detection" content="telephone=no">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<link rel="icon" href="/assets/favicon.ico" type="image/x-icon"> <link rel="icon" href="/assets/favicon.ico" type="image/x-icon">
<title>ivanch</title> <title>ivanch</title>

View File

@@ -5,11 +5,11 @@ class MatrixBackground {
this.dots = []; this.dots = [];
this.connections = []; this.connections = [];
this.config = { this.config = {
dotCount: 50, dotCount: this.getMobileDotCount(),
dotSpeed: 0.2, dotSpeed: 0.2,
connectionDuration: { min: 2000, max: 6000 }, connectionDuration: { min: 2000, max: 6000 },
connectionChance: 0.0002, connectionChance: 0.0002,
maxConnections: 8, maxConnections: this.getMobileMaxConnections(),
dotSize: 3, dotSize: 3,
colors: { colors: {
dotDefault: 'rgba(255, 255, 255, 0.8)', dotDefault: 'rgba(255, 255, 255, 0.8)',
@@ -27,6 +27,20 @@ class MatrixBackground {
this.init(); this.init();
} }
getMobileDotCount() {
// Reduce dot count on mobile devices for better performance
if (window.innerWidth <= 480) return 25;
if (window.innerWidth <= 768) return 35;
return 50;
}
getMobileMaxConnections() {
// Reduce max connections on mobile devices
if (window.innerWidth <= 480) return 4;
if (window.innerWidth <= 768) return 6;
return 8;
}
init() { init() {
this.handleResize(); this.handleResize();
this.animate(); this.animate();
@@ -36,6 +50,11 @@ class MatrixBackground {
handleResize() { handleResize() {
this.canvas.width = window.innerWidth; this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight; this.canvas.height = window.innerHeight;
// Update mobile-specific configurations
this.config.dotCount = this.getMobileDotCount();
this.config.maxConnections = this.getMobileMaxConnections();
this.createDots(); this.createDots();
} }