improving responsiviness
This commit is contained in:
@@ -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
|
@@ -12,10 +12,31 @@
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
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 {
|
||||
background: var(--button-hover-gradient);
|
||||
transform: translateY(-1px);
|
||||
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;
|
||||
}
|
||||
}
|
59
css/main.css
59
css/main.css
@@ -13,6 +13,12 @@ body {
|
||||
min-height: 100vh;
|
||||
overflow-x: hidden;
|
||||
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,
|
||||
@@ -119,9 +125,26 @@ img {
|
||||
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 {
|
||||
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 {
|
||||
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 */
|
||||
@@ -136,4 +172,23 @@ img {
|
||||
.glass {
|
||||
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);
|
||||
}
|
||||
}
|
@@ -57,8 +57,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
@@ -92,6 +90,8 @@
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.social-link {
|
||||
display: inline-flex;
|
||||
@@ -99,13 +99,37 @@
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
/* Responsive Design - Mobile First Approach */
|
||||
@media (max-width: 1024px) {
|
||||
.hero-details {
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.hero-card {
|
||||
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 {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.social-links {
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,13 +164,38 @@
|
||||
.name {
|
||||
font-size: 1.8rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-size: 1rem;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.social-links {
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.social-link {
|
||||
padding: 10px 16px;
|
||||
padding: 10px 14px;
|
||||
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;
|
||||
}
|
||||
}
|
@@ -14,6 +14,53 @@
|
||||
gap: 18px;
|
||||
position: relative;
|
||||
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 {
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
.profile-info-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
font-size: 0.95rem;
|
||||
@@ -76,19 +77,71 @@
|
||||
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 {
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
margin: 0 auto;
|
||||
font-size: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
@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 {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
font-size: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 380px) {
|
||||
.avatar {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.profile-info-item {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
}
|
@@ -66,12 +66,24 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.project-icons {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
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 {
|
||||
@@ -94,12 +106,66 @@
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 900px) {
|
||||
@media (max-width: 1024px) {
|
||||
.projects-section {
|
||||
flex: unset;
|
||||
max-width: 100%;
|
||||
margin-left: 0;
|
||||
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;
|
||||
}
|
||||
}
|
@@ -2,9 +2,15 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<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="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">
|
||||
|
||||
|
23
js/matrix.js
23
js/matrix.js
@@ -5,11 +5,11 @@ class MatrixBackground {
|
||||
this.dots = [];
|
||||
this.connections = [];
|
||||
this.config = {
|
||||
dotCount: 50,
|
||||
dotCount: this.getMobileDotCount(),
|
||||
dotSpeed: 0.2,
|
||||
connectionDuration: { min: 2000, max: 6000 },
|
||||
connectionChance: 0.0002,
|
||||
maxConnections: 8,
|
||||
maxConnections: this.getMobileMaxConnections(),
|
||||
dotSize: 3,
|
||||
colors: {
|
||||
dotDefault: 'rgba(255, 255, 255, 0.8)',
|
||||
@@ -27,6 +27,20 @@ class MatrixBackground {
|
||||
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() {
|
||||
this.handleResize();
|
||||
this.animate();
|
||||
@@ -36,6 +50,11 @@ class MatrixBackground {
|
||||
handleResize() {
|
||||
this.canvas.width = window.innerWidth;
|
||||
this.canvas.height = window.innerHeight;
|
||||
|
||||
// Update mobile-specific configurations
|
||||
this.config.dotCount = this.getMobileDotCount();
|
||||
this.config.maxConnections = this.getMobileMaxConnections();
|
||||
|
||||
this.createDots();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user