fix(projects): add mobile edge spacing, 1-card layout, and smooth touch drag physics
This commit is contained in:
@@ -75,6 +75,8 @@
|
||||
overscroll-behavior-inline: contain;
|
||||
touch-action: pan-y;
|
||||
user-select: none;
|
||||
container-type: inline-size;
|
||||
container-name: carousel;
|
||||
}
|
||||
|
||||
.carouselViewport::-webkit-scrollbar {
|
||||
@@ -89,23 +91,28 @@
|
||||
|
||||
.dragging {
|
||||
cursor: grabbing;
|
||||
scroll-snap-type: none !important;
|
||||
scroll-behavior: auto !important;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.carouselTrack {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
width: max-content;
|
||||
gap: 24px;
|
||||
gap: 20px;
|
||||
padding: 4px 0 8px;
|
||||
}
|
||||
|
||||
.card {
|
||||
display: flex;
|
||||
flex: 0 0 var(--size-project-width);
|
||||
flex: 0 0 clamp(300px, 24vw, 340px);
|
||||
flex-shrink: 0;
|
||||
flex-direction: column;
|
||||
width: var(--size-project-width);
|
||||
min-height: 480px;
|
||||
width: clamp(300px, 24vw, 340px);
|
||||
min-height: 460px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid var(--border-default);
|
||||
border-radius: var(--radius-lg);
|
||||
background: var(--bg-surface);
|
||||
@@ -116,13 +123,14 @@
|
||||
.mediaContainer {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: var(--size-project-media-height);
|
||||
aspect-ratio: 16 / 10;
|
||||
overflow: hidden;
|
||||
background: var(--color-blue-900);
|
||||
}
|
||||
|
||||
.projectImage {
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
pointer-events: none;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
@@ -131,7 +139,7 @@
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
padding: 18px 16px;
|
||||
}
|
||||
|
||||
.cardTitleRow {
|
||||
@@ -143,9 +151,9 @@
|
||||
|
||||
.cardTitle {
|
||||
color: var(--text-primary);
|
||||
font-size: var(--font-size-h3);
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
line-height: var(--line-height-h3);
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.titleLinkIcon {
|
||||
@@ -158,9 +166,9 @@
|
||||
}
|
||||
|
||||
.cardDate {
|
||||
margin-bottom: 14px;
|
||||
margin-bottom: 10px;
|
||||
color: var(--text-muted);
|
||||
font-size: var(--font-size-label-small);
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
line-height: var(--line-height-label-small);
|
||||
letter-spacing: var(--letter-spacing-eyebrow);
|
||||
@@ -169,21 +177,24 @@
|
||||
|
||||
.cardDesc {
|
||||
display: -webkit-box;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 16px;
|
||||
overflow: hidden;
|
||||
color: var(--text-primary);
|
||||
font-size: var(--font-size-body-small);
|
||||
font-size: 13.5px;
|
||||
font-weight: 400;
|
||||
line-height: var(--line-height-body-small);
|
||||
line-height: 1.55;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 4;
|
||||
-webkit-line-clamp: 3;
|
||||
white-space: normal;
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.tagList {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
margin-bottom: 24px;
|
||||
gap: 6px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.tagBadge {
|
||||
@@ -233,7 +244,9 @@
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
--thumb-width: 216px;
|
||||
width: 480px;
|
||||
max-width: 100%;
|
||||
height: 20px;
|
||||
margin: 0;
|
||||
appearance: none;
|
||||
@@ -248,7 +261,7 @@
|
||||
}
|
||||
|
||||
.scrollbar::-webkit-slider-thumb {
|
||||
width: 216px;
|
||||
width: var(--thumb-width, 216px);
|
||||
height: 6px;
|
||||
margin-top: 0;
|
||||
appearance: none;
|
||||
@@ -265,7 +278,7 @@
|
||||
}
|
||||
|
||||
.scrollbar::-moz-range-thumb {
|
||||
width: 216px;
|
||||
width: var(--thumb-width, 216px);
|
||||
height: 6px;
|
||||
border: 0;
|
||||
border-radius: var(--radius-pill);
|
||||
@@ -294,65 +307,192 @@
|
||||
background: var(--color-blue-300);
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
/* ================================================================
|
||||
LAPTOP 1101px – 1440px
|
||||
Comfortable ~290px-330px cards (~3 to 4 visible)
|
||||
================================================================ */
|
||||
@media (max-width: 1440px) and (min-width: 1101px) {
|
||||
.carouselTrack {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
flex: 0 0 clamp(290px, 23vw, 330px);
|
||||
width: clamp(290px, 23vw, 330px);
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
width: min(480px, 50vw);
|
||||
--thumb-width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
TABLET 651px – 1100px
|
||||
Comfortable ~310px-350px cards (~2 cards visible)
|
||||
================================================================ */
|
||||
@media (max-width: 1100px) and (min-width: 651px) {
|
||||
.projectsSection {
|
||||
padding-top: var(--space-8);
|
||||
padding-bottom: var(--space-9);
|
||||
}
|
||||
|
||||
.carouselTrack {
|
||||
gap: var(--space-4);
|
||||
}
|
||||
|
||||
.card {
|
||||
flex-basis: min(340px, calc(100vw - (2 * var(--layout-page-gutter))));
|
||||
width: min(340px, calc(100vw - (2 * var(--layout-page-gutter))));
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.headerRow {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
gap: var(--space-3);
|
||||
margin-bottom: var(--space-6);
|
||||
}
|
||||
|
||||
.arrowButtons {
|
||||
align-self: flex-end;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.navButton {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.carouselViewport {
|
||||
margin-inline: calc(-1 * var(--layout-page-gutter));
|
||||
width: calc(100% + (2 * var(--layout-page-gutter)));
|
||||
padding-inline: var(--layout-page-gutter);
|
||||
scroll-padding-inline: var(--layout-page-gutter);
|
||||
scroll-snap-type: x mandatory;
|
||||
scroll-padding-inline: 0;
|
||||
}
|
||||
|
||||
.carouselTrack {
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.card {
|
||||
flex-basis: min(320px, calc(100vw - 40px));
|
||||
width: min(320px, calc(100vw - 40px));
|
||||
min-height: 460px;
|
||||
flex: 0 0 clamp(310px, 42vw, 350px);
|
||||
width: clamp(310px, 42vw, 350px);
|
||||
min-height: 450px;
|
||||
box-sizing: border-box;
|
||||
scroll-snap-align: start;
|
||||
}
|
||||
|
||||
.mediaContainer {
|
||||
height: 200px;
|
||||
aspect-ratio: 16 / 10;
|
||||
}
|
||||
|
||||
.cardBody {
|
||||
padding: var(--space-5);
|
||||
padding: 18px 16px;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.cardDesc {
|
||||
font-size: 13.5px;
|
||||
line-height: 1.55;
|
||||
margin-bottom: 14px;
|
||||
-webkit-line-clamp: 3;
|
||||
white-space: normal;
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.tagList {
|
||||
gap: 6px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tagBadge {
|
||||
padding: 3px 9px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.scrollbarWrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 32px;
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
width: min(360px, 60vw);
|
||||
--thumb-width: 90px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
MOBILE ≤ 650px
|
||||
Comfortable ~310px-330px card (~1 card visible with clean margins)
|
||||
================================================================ */
|
||||
@media (max-width: 650px) {
|
||||
.projectsSection {
|
||||
padding-top: 48px;
|
||||
padding-bottom: 64px;
|
||||
}
|
||||
|
||||
.headerRow {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.arrowButtons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.carouselViewport {
|
||||
width: 100%;
|
||||
margin-inline: 0;
|
||||
padding-inline: 0;
|
||||
scroll-padding-inline: 0;
|
||||
scroll-snap-type: x mandatory;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.carouselTrack {
|
||||
gap: 16px;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
.card {
|
||||
flex: 0 0 calc(100vw - (2 * var(--layout-page-gutter)));
|
||||
flex: 0 0 100cqw;
|
||||
width: calc(100vw - (2 * var(--layout-page-gutter)));
|
||||
width: 100cqw;
|
||||
min-width: calc(100vw - (2 * var(--layout-page-gutter)));
|
||||
min-width: 100cqw;
|
||||
max-width: 100%;
|
||||
min-height: 420px;
|
||||
box-sizing: border-box;
|
||||
scroll-snap-align: start;
|
||||
scroll-snap-stop: always;
|
||||
}
|
||||
|
||||
.mediaContainer {
|
||||
aspect-ratio: 16 / 10;
|
||||
}
|
||||
|
||||
.cardBody {
|
||||
padding: 18px 16px;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.cardDesc {
|
||||
font-size: 13px;
|
||||
line-height: 1.5;
|
||||
margin-bottom: 14px;
|
||||
white-space: normal;
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
-webkit-line-clamp: 3;
|
||||
}
|
||||
|
||||
.tagList {
|
||||
gap: 6px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.tagBadge {
|
||||
padding: 3px 9px;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.scrollbarWrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.scrollbar {
|
||||
width: min(200px, 60vw);
|
||||
height: 16px;
|
||||
--thumb-width: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (hover: hover) and (pointer: fine) {
|
||||
|
||||
Reference in New Issue
Block a user