refactor: update contact page layout, optimize UI components, and document page scaffolding rules
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# Workspace Rules
|
||||
|
||||
### Creating New Thymeleaf Pages
|
||||
When creating or scaffolding a new Thymeleaf template page in this project, you MUST use the `layout:decorate` mechanism to inherit the common layout, and you MUST pass the `bodyClass` variable to maintain consistent styling with the homepage.
|
||||
|
||||
Use the following exact structure as a template:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{fragments/layout(bodyClass='umass-platform-homepage path-frontpage page-node-type-homepage homepage transparent-header')}">
|
||||
|
||||
<head>
|
||||
<title>Tiêu đề trang</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div layout:fragment="content">
|
||||
<!-- Content Top Banner -->
|
||||
<div class="content-top">
|
||||
<!-- Banner content here -->
|
||||
</div>
|
||||
|
||||
<!-- Main Content Area -->
|
||||
<div class="main-content-area">
|
||||
<!-- Specific page content here -->
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,727 +1,53 @@
|
||||
<style>
|
||||
.charity-hero {
|
||||
--red: #d7193f;
|
||||
--red-dark: #a90f2d;
|
||||
--red-soft: #fff0f4;
|
||||
--pink: #ffe3ec;
|
||||
--ink: #36363a;
|
||||
--muted: #74747a;
|
||||
--paper: #f7f7f8;
|
||||
--white: #ffffff;
|
||||
--shadow: 0 24px 70px rgba(174, 23, 55, .18);
|
||||
--shadow-strong: 0 32px 90px rgba(100, 10, 30, .28);
|
||||
}
|
||||
|
||||
.charity-hero {
|
||||
font-family: "Segoe UI", Arial, sans-serif;
|
||||
color: var(--ink);
|
||||
background: #f1f1f2;
|
||||
position: relative;
|
||||
min-height: 546px;
|
||||
overflow: hidden;
|
||||
isolation: isolate;
|
||||
background:
|
||||
radial-gradient(circle at 72% 22%, rgba(255,255,255,.92), transparent 28%),
|
||||
linear-gradient(110deg, #ffeaf0 0%, #f4f4f5 42%, #f9f9fa 100%);
|
||||
}
|
||||
|
||||
.charity-hero * {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.charity-hero a {
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.charity-hero .hero-bg {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
z-index: -2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.charity-hero .blob {
|
||||
position: absolute;
|
||||
border-radius: 999px;
|
||||
filter: blur(3px);
|
||||
opacity: .72;
|
||||
animation: blobFloat 13s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.charity-hero .blob-1 {
|
||||
width: 460px;
|
||||
height: 460px;
|
||||
background: rgba(255,207,221,.75);
|
||||
left: -150px;
|
||||
top: -170px;
|
||||
}
|
||||
|
||||
.charity-hero .blob-2 {
|
||||
width: 520px;
|
||||
height: 520px;
|
||||
background: rgba(255,236,241,.9);
|
||||
right: -180px;
|
||||
bottom: -220px;
|
||||
animation-delay: -3s;
|
||||
}
|
||||
|
||||
.charity-hero .blob-3 {
|
||||
width: 220px;
|
||||
height: 220px;
|
||||
background: rgba(215,25,63,.12);
|
||||
left: 48%;
|
||||
top: 48%;
|
||||
animation-delay: -6s;
|
||||
}
|
||||
|
||||
.charity-hero .soft-grid {
|
||||
position: absolute;
|
||||
inset: 22px 150px;
|
||||
border: 5px solid rgba(255,206,218,.68);
|
||||
border-radius: 6px;
|
||||
mask: linear-gradient(90deg,transparent,black 4%,black 96%,transparent);
|
||||
-webkit-mask: linear-gradient(90deg,transparent,black 4%,black 96%,transparent);
|
||||
opacity: .76;
|
||||
}
|
||||
|
||||
.charity-hero .soft-grid:before,
|
||||
.charity-hero .soft-grid:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
background: var(--red);
|
||||
border-radius: 50% 50% 48% 48%;
|
||||
transform: rotate(45deg);
|
||||
opacity: .9;
|
||||
}
|
||||
|
||||
.charity-hero .soft-grid:before {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
left: 22px;
|
||||
bottom: -13px;
|
||||
box-shadow: 34px -1px 0 var(--red);
|
||||
}
|
||||
|
||||
.charity-hero .soft-grid:after {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
right: 18px;
|
||||
top: 285px;
|
||||
opacity: .55;
|
||||
box-shadow: 20px 19px 0 rgba(215,25,63,.9);
|
||||
}
|
||||
|
||||
.charity-hero .hero-shell {
|
||||
width: min(1580px, calc(100% - 44px));
|
||||
min-height: 546px;
|
||||
margin: 0 auto;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(640px, 1.1fr) minmax(470px, .9fr);
|
||||
gap: 42px;
|
||||
align-items: center;
|
||||
padding: 36px 0;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-panel {
|
||||
position: relative;
|
||||
min-height: 500px;
|
||||
padding: 18px 12px 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-title {
|
||||
position: absolute;
|
||||
left: 22px;
|
||||
top: 10px;
|
||||
z-index: 22;
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
padding: 10px 16px;
|
||||
border-radius: 18px;
|
||||
background: rgba(255,255,255,.72);
|
||||
box-shadow: 0 12px 30px rgba(70,40,50,.08);
|
||||
backdrop-filter: blur(10px);
|
||||
transform: translateY(-12px);
|
||||
opacity: 0;
|
||||
animation: fadeDown .7s ease forwards .25s;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-title .eyebrow {
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 2px;
|
||||
color: var(--red);
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-title strong {
|
||||
font-size: 16px;
|
||||
color: #313136;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-stage {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
perspective: 1200px;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-light {
|
||||
position: absolute;
|
||||
left: 34%;
|
||||
top: 35%;
|
||||
width: 310px;
|
||||
height: 210px;
|
||||
border-radius: 50%;
|
||||
background: radial-gradient(circle, rgba(255,255,255,.88), rgba(255,255,255,0) 66%);
|
||||
pointer-events: none;
|
||||
opacity: .45;
|
||||
mix-blend-mode: screen;
|
||||
animation: lightPulse 4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.charity-hero .focus-frame {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 402px;
|
||||
height: 238px;
|
||||
transform: translate(-50%,-50%) scale(.86);
|
||||
border-radius: 22px;
|
||||
border: 1px solid rgba(215,25,63,.25);
|
||||
box-shadow: 0 0 0 10px rgba(255,255,255,.16), inset 0 0 42px rgba(215,25,63,.07);
|
||||
opacity: 0;
|
||||
transition: .7s ease;
|
||||
pointer-events: none;
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
.charity-hero .gallery-stage.is-playing .focus-frame {
|
||||
opacity: 1;
|
||||
transform: translate(-50%,-50%) scale(1);
|
||||
}
|
||||
|
||||
.charity-hero .photo-card {
|
||||
position: absolute;
|
||||
left: var(--x);
|
||||
top: var(--y);
|
||||
width: var(--w);
|
||||
background: #fff;
|
||||
border: 4px solid var(--red);
|
||||
border-radius: 3px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 14px 36px rgba(61,26,34,.22);
|
||||
transform: translate3d(0,0,0) rotate(var(--r)) scale(.92);
|
||||
opacity: 0;
|
||||
z-index: 5;
|
||||
will-change: left, top, width, transform, opacity, filter;
|
||||
animation: cardIntro .85s cubic-bezier(.2,.9,.25,1.12) forwards;
|
||||
animation-delay: var(--delay);
|
||||
transition:
|
||||
opacity 2.5s ease-in-out,
|
||||
filter 2.5s ease-in-out,
|
||||
box-shadow 1.5s cubic-bezier(.2,.8,.2,1),
|
||||
border-color 1.5s cubic-bezier(.2,.8,.2,1),
|
||||
left 1.5s cubic-bezier(.2,.8,.2,1),
|
||||
top 1.5s cubic-bezier(.2,.8,.2,1),
|
||||
width 1.5s cubic-bezier(.2,.8,.2,1),
|
||||
transform 1.5s cubic-bezier(.2,.8,.2,1);
|
||||
}
|
||||
|
||||
.charity-hero .photo-card img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
transform: scale(1.035);
|
||||
transition: transform 1s cubic-bezier(.18,.82,.18,1), filter .8s ease;
|
||||
}
|
||||
|
||||
.charity-hero .photo-card:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(120deg, transparent 20%, rgba(255,255,255,.34) 45%, transparent 70%);
|
||||
transform: translateX(-130%);
|
||||
z-index: 2;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.charity-hero .photo-card.is-active:before {
|
||||
animation: shine 1.3s ease .25s;
|
||||
}
|
||||
|
||||
.charity-hero .photo-card.is-active {
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: min(480px, 58vw);
|
||||
transform: translate(-50%,-50%) rotate(0deg) scale(1.06) !important;
|
||||
opacity: 1;
|
||||
z-index: 30;
|
||||
border-color: #fff;
|
||||
border-width: 8px;
|
||||
border-radius: 18px;
|
||||
box-shadow: var(--shadow-strong);
|
||||
filter: saturate(1.08) contrast(1.03);
|
||||
}
|
||||
|
||||
.charity-hero .photo-card.is-active img {
|
||||
transform: scale(1.08);
|
||||
}
|
||||
|
||||
.charity-hero .photo-card.is-dim {
|
||||
opacity: .28;
|
||||
filter: grayscale(.08) saturate(.8) blur(.2px);
|
||||
transform: translate3d(0,0,0) rotate(var(--r)) scale(.82);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.charity-hero .photo-card.is-next {
|
||||
opacity: .74;
|
||||
box-shadow: 0 17px 45px rgba(92,24,42,.18);
|
||||
}
|
||||
|
||||
.charity-hero .photo-card.is-exit {
|
||||
opacity: 0;
|
||||
transform: translateY(28px) scale(.74) rotate(var(--r));
|
||||
}
|
||||
|
||||
|
||||
|
||||
.charity-hero .gallery-controls {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 2px;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
.charity-hero .dot {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
border-radius: 999px;
|
||||
background: rgba(215,25,63,.22);
|
||||
transition: .35s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.charity-hero .dot.is-active {
|
||||
width: 28px;
|
||||
background: var(--red);
|
||||
box-shadow: 0 0 0 6px rgba(215,25,63,.09);
|
||||
}
|
||||
|
||||
.charity-hero .content-panel {
|
||||
position: relative;
|
||||
min-height: 430px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 26px 24px 26px 8px;
|
||||
}
|
||||
|
||||
.charity-hero .content-panel:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 28px 0 18px 0;
|
||||
border-radius: 34px;
|
||||
background: linear-gradient(145deg, rgba(255,255,255,.54), rgba(255,255,255,.08));
|
||||
border: 1px solid rgba(255,255,255,.55);
|
||||
box-shadow: 0 20px 70px rgba(62,45,54,.06);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.charity-hero .brand-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 170px;
|
||||
gap: 24px;
|
||||
align-items: start;
|
||||
margin-bottom: 54px;
|
||||
}
|
||||
|
||||
.charity-hero .logo-mark {
|
||||
width: 165px;
|
||||
justify-self: end;
|
||||
filter: drop-shadow(0 10px 16px rgba(215,25,63,.15));
|
||||
animation: logoBreath 3.6s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.charity-hero .brand-text {
|
||||
text-align: center;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.charity-hero .brand-text h1 {
|
||||
margin: 0 0 8px;
|
||||
text-transform: uppercase;
|
||||
line-height: 1.18;
|
||||
font-size: clamp(20px,1.72vw,30px);
|
||||
letter-spacing: -.3px;
|
||||
color: var(--red);
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.charity-hero .brand-text p {
|
||||
margin: 0;
|
||||
color: #67676c;
|
||||
text-transform: uppercase;
|
||||
font-size: clamp(16px,1.2vw,22px);
|
||||
font-weight: 800;
|
||||
letter-spacing: .3px;
|
||||
}
|
||||
|
||||
.charity-hero .slogan-card {
|
||||
width: min(560px,100%);
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding: 20px 18px 28px;
|
||||
}
|
||||
|
||||
.charity-hero .slogan-card:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 86%;
|
||||
height: 86%;
|
||||
transform: translate(-50%,-50%);
|
||||
border-radius: 38px;
|
||||
background: linear-gradient(90deg,rgba(255,255,255,.18),rgba(255,237,243,.72),rgba(255,255,255,.12));
|
||||
filter: blur(.2px);
|
||||
z-index: -1;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.charity-hero .quote-mark {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
top: -16px;
|
||||
font-size: 74px;
|
||||
line-height: 1;
|
||||
color: rgba(215,25,63,.18);
|
||||
font-family: Georgia,serif;
|
||||
}
|
||||
|
||||
.charity-hero .slogan-card h2 {
|
||||
margin: 0;
|
||||
color: #e13b5e;
|
||||
font-size: clamp(29px,2.2vw,42px);
|
||||
line-height: 1.42;
|
||||
font-family: "Segoe Script","Brush Script MT",cursive;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 8px 20px rgba(215,25,63,.12);
|
||||
}
|
||||
|
||||
.charity-hero .slogan-card h2 em {
|
||||
font-style: normal;
|
||||
font-size: .86em;
|
||||
color: #d9284c;
|
||||
}
|
||||
|
||||
.charity-hero .heart-line {
|
||||
display: block;
|
||||
width: 160px;
|
||||
height: 22px;
|
||||
margin: 12px auto 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.charity-hero .heart-line:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 34px;
|
||||
top: 11px;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg,transparent,var(--red));
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.charity-hero .heart-line:after {
|
||||
content: "♡";
|
||||
position: absolute;
|
||||
right: 6px;
|
||||
top: -8px;
|
||||
color: var(--red);
|
||||
font-size: 32px;
|
||||
transform: rotate(18deg);
|
||||
animation: heartBeat 1.7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.charity-hero .action-row {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
justify-content: center;
|
||||
margin-top: 26px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.charity-hero .btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 44px;
|
||||
padding: 0 20px;
|
||||
border-radius: 999px;
|
||||
font-weight: 800;
|
||||
font-size: 14px;
|
||||
letter-spacing: .2px;
|
||||
transition: .3s ease;
|
||||
box-shadow: 0 12px 30px rgba(115,21,43,.12);
|
||||
}
|
||||
|
||||
.charity-hero .btn.primary {
|
||||
background: linear-gradient(135deg,var(--red),#ef4769);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.charity-hero .btn.secondary {
|
||||
background: rgba(255,255,255,.74);
|
||||
color: var(--red);
|
||||
border: 1px solid rgba(215,25,63,.18);
|
||||
}
|
||||
|
||||
.charity-hero .reveal-up {
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
animation: revealUp .8s ease forwards;
|
||||
}
|
||||
|
||||
.charity-hero .brand-text.reveal-up {
|
||||
animation-delay: .2s;
|
||||
}
|
||||
|
||||
.charity-hero .logo-mark.reveal-up {
|
||||
animation-delay: .38s;
|
||||
}
|
||||
|
||||
.charity-hero .slogan-card.reveal-up {
|
||||
animation-delay: .62s;
|
||||
}
|
||||
|
||||
.charity-hero .action-row.reveal-up {
|
||||
animation-delay: .86s;
|
||||
}
|
||||
|
||||
@keyframes cardIntro {
|
||||
from { opacity: 0; transform: translate3d(-28px,22px,0) rotate(calc(var(--r) - 7deg)) scale(.78); }
|
||||
to { opacity: 1; transform: translate3d(0,0,0) rotate(var(--r)) scale(.92); }
|
||||
}
|
||||
/* Removed microFloat because animating margin-top constantly recalculates layout causing major stutter */
|
||||
@keyframes shine {
|
||||
to { transform: translateX(130%); }
|
||||
}
|
||||
@keyframes revealUp {
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@keyframes fadeDown {
|
||||
to { opacity: 1; transform: translateY(0); }
|
||||
}
|
||||
@keyframes logoBreath {
|
||||
0%,100% { transform: translateY(0) scale(1); }
|
||||
50% { transform: translateY(-6px) scale(1.025); }
|
||||
}
|
||||
@keyframes heartBeat {
|
||||
0%,100% { transform: rotate(18deg) scale(1); }
|
||||
20% { transform: rotate(18deg) scale(1.18); }
|
||||
38% { transform: rotate(18deg) scale(1); }
|
||||
}
|
||||
@keyframes blobFloat {
|
||||
to { transform: translate(26px,20px) scale(1.05); }
|
||||
}
|
||||
@keyframes lightPulse {
|
||||
0%,100% { opacity: .25; transform: scale(.96); }
|
||||
50% { opacity: .58; transform: scale(1.08); }
|
||||
}
|
||||
|
||||
@media (max-width:1200px) {
|
||||
.charity-hero .hero-shell {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 10px;
|
||||
padding: 18px 0 34px;
|
||||
}
|
||||
.charity-hero { min-height: auto; }
|
||||
.charity-hero .content-panel { min-height: auto; }
|
||||
.charity-hero .gallery-panel { min-height: 470px; }
|
||||
.charity-hero .gallery-stage { height: 430px; }
|
||||
.charity-hero .brand-row { grid-template-columns: 1fr 130px; margin-bottom: 20px; }
|
||||
.charity-hero .logo-mark { width: 130px; }
|
||||
}
|
||||
|
||||
@media (max-width:720px) {
|
||||
.charity-hero .hero-shell { width: calc(100% - 24px); }
|
||||
.charity-hero .soft-grid { inset: 12px; border-width: 3px; }
|
||||
.charity-hero .gallery-panel { padding: 12px 0; min-height: 390px; }
|
||||
.charity-hero .gallery-title { display: none; }
|
||||
.charity-hero .gallery-stage { height: 370px; overflow: hidden; }
|
||||
.charity-hero .photo-card { width: calc(var(--w) * .72); }
|
||||
.charity-hero .photo-card.is-active { width: min(86vw,380px); }
|
||||
.charity-hero .content-panel { padding: 8px; }
|
||||
.charity-hero .brand-row { display: flex; flex-direction: column-reverse; align-items: center; gap: 10px; }
|
||||
.charity-hero .brand-text h1 { text-align: center; }
|
||||
.charity-hero .slogan-card h2 { font-size: 29px; }
|
||||
.charity-hero .btn { height: 42px; padding: 0 16px; }
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion:reduce) {
|
||||
.charity-hero *,
|
||||
.charity-hero *::before,
|
||||
.charity-hero *::after {
|
||||
animation-duration: .01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
scroll-behavior: auto !important;
|
||||
transition-duration: .01ms !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="charity-hero" aria-label="Quỹ từ thiện bệnh nhân nghèo bị đột quỵ">
|
||||
<div class="hero-bg">
|
||||
<span class="blob blob-1"></span>
|
||||
<span class="blob blob-2"></span>
|
||||
<span class="blob blob-3"></span>
|
||||
<span class="soft-grid"></span>
|
||||
</div>
|
||||
|
||||
<section class="hero-shell">
|
||||
<div class="gallery-panel" aria-label="Hình ảnh hoạt động quỹ từ thiện">
|
||||
<div class="gallery-title">
|
||||
<span class="eyebrow">S.I.S Charity Foundation</span>
|
||||
<strong>Những khoảnh khắc sẻ chia</strong>
|
||||
</div>
|
||||
|
||||
<div class="gallery-stage" id="galleryStage">
|
||||
<article class="photo-card p1" data-index="0" style="--x: -4%; --y: 2%; --r: -2.5deg; --w: 205px; --delay: 0.05s;">
|
||||
<img src="/upload/charity_v4/photo-01.jpg" alt="Trao hỗ trợ bệnh nhân 1" />
|
||||
</article>
|
||||
<article class="photo-card p2" data-index="1" style="--x: 18%; --y: -2%; --r: 1.6deg; --w: 298px; --delay: 0.16s;">
|
||||
<img src="/upload/charity_v4/photo-02.jpg" alt="Trao hỗ trợ bệnh nhân 2" />
|
||||
</article>
|
||||
<article class="photo-card p3" data-index="2" style="--x: 63%; --y: 0%; --r: -1.2deg; --w: 410px; --delay: 0.27s;">
|
||||
<img src="/upload/charity_v4/photo-05.jpg" alt="Trao hỗ trợ bệnh nhân 3" />
|
||||
</article>
|
||||
<article class="photo-card p4" data-index="3" style="--x: 0%; --y: 27%; --r: 2.2deg; --w: 245px; --delay: 0.38s">
|
||||
<img src="/upload/charity_v4/photo-03.jpg" alt="Trao hỗ trợ bệnh nhân 4" />
|
||||
</article>
|
||||
<article class="photo-card p5" data-index="4" style="--x: 32%; --y: 32%; --r: -1.8deg; --w: 260px; --delay: 0.49s;">
|
||||
<img src="/upload/charity_v4/photo-04.jpg" alt="Trao hỗ trợ bệnh nhân 5" />
|
||||
</article>
|
||||
<article class="photo-card p6" data-index="5" style="--x: 57%; --y: 35%; --r: 1deg; --w: 195px; --delay: 0.6s">
|
||||
<img src="/upload/charity_v4/photo-06.jpg" alt="Trao hỗ trợ bệnh nhân 6" />
|
||||
</article>
|
||||
<article class="photo-card p7" data-index="6" style="--x: 4%; --y: 62%; --r: -1.4deg; --w: 270px; --delay: 0.71s;">
|
||||
<img src="/upload/charity_v4/photo-07.jpg" alt="Trao hỗ trợ bệnh nhân 7" />
|
||||
</article>
|
||||
<article class="photo-card p8" data-index="7" style="--x: 42%; --y: 73%; --r: 1.2deg; --w: 255px; --delay: 0.82s;">
|
||||
<img src="/upload/charity_v4/photo-08.jpg" alt="Trao hỗ trợ bệnh nhân 8" />
|
||||
</article>
|
||||
<article class="photo-card p9" data-index="8" style="--x: 77%; --y: 66%; --r: -1deg; --w: 338px; --delay: 0.93s">
|
||||
<img src="/upload/charity_v4/photo-09.jpg" alt="Trao hỗ trợ bệnh nhân 9" />
|
||||
</article>
|
||||
<div class="gallery-light" aria-hidden="true"></div>
|
||||
</div>
|
||||
|
||||
<div class="gallery-controls" aria-hidden="true">
|
||||
<span class="dot is-active"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
<span class="dot"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-panel">
|
||||
<div class="brand-row">
|
||||
<div class="brand-text reveal-up">
|
||||
<h1>Quỹ từ thiện bệnh nhân nghèo bị đột quỵ<br />khu vực Đồng bằng sông Cửu Long</h1>
|
||||
<p>S.I.S Charity Foundation</p>
|
||||
</div>
|
||||
<img class="logo-mark reveal-up" src="/upload/charity_v4/logo.png" alt="Stroke International Services Charity Foundation" />
|
||||
</div>
|
||||
|
||||
<div class="slogan-card reveal-up">
|
||||
<span class="quote-mark">“</span>
|
||||
<h2>Sẻ chia yêu thương<br /><em>đến bệnh nhân nghèo bị đột quỵ</em></h2>
|
||||
<span class="heart-line" aria-hidden="true"></span>
|
||||
</div>
|
||||
|
||||
<div class="action-row reveal-up">
|
||||
<a class="btn primary" href="#">Lan tỏa yêu thương</a>
|
||||
<a class="btn secondary" href="#">Xem hoạt động quỹ</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function(){
|
||||
const container = document.querySelector('.charity-hero');
|
||||
if(!container) return;
|
||||
const stage = container.querySelector('.gallery-stage');
|
||||
const cards = Array.from(container.querySelectorAll('.photo-card'));
|
||||
const dots = Array.from(container.querySelectorAll('.dot'));
|
||||
if(!stage || cards.length === 0) return;
|
||||
|
||||
let active = 0;
|
||||
let timer = null;
|
||||
const duration = 4500; /* Tăng thời gian chờ (autoplay) từ 2.8 giây lên 4.5 giây để nhìn rõ ảnh hơn */
|
||||
|
||||
function setActive(index){
|
||||
active = index % cards.length;
|
||||
stage.classList.add('is-playing');
|
||||
|
||||
cards.forEach((card, i) => {
|
||||
card.classList.remove('is-active','is-dim','is-next','is-exit');
|
||||
const diff = (i - active + cards.length) % cards.length;
|
||||
if(i === active){
|
||||
card.classList.add('is-active');
|
||||
}else if(diff === 1 || diff === 2){
|
||||
card.classList.add('is-next');
|
||||
}else if(diff === cards.length - 1){
|
||||
card.classList.add('is-exit');
|
||||
}else{
|
||||
card.classList.add('is-dim');
|
||||
}
|
||||
});
|
||||
|
||||
dots.forEach((dot, i) => dot.classList.toggle('is-active', i === active));
|
||||
}
|
||||
|
||||
function next(){
|
||||
setActive(active + 1);
|
||||
}
|
||||
|
||||
function start(){
|
||||
stop();
|
||||
timer = setInterval(next, duration);
|
||||
}
|
||||
|
||||
function stop(){
|
||||
if(timer) clearInterval(timer);
|
||||
}
|
||||
|
||||
// Hệ thống sẽ chạy tự động 100%
|
||||
|
||||
dots.forEach((dot, i) => {
|
||||
dot.addEventListener('click', () => {
|
||||
setActive(i);
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
// Start immediately or on load if part of a bigger page
|
||||
setTimeout(() => {
|
||||
setActive(0);
|
||||
start();
|
||||
}, 900);
|
||||
})();
|
||||
</script>
|
||||
<div layout:fragment="content-top">
|
||||
<!-- Content Top (Banner 3 lớp kết hợp Title bài Post) -->
|
||||
<div class="content-top">
|
||||
<div class="lc--layout-container lc--full">
|
||||
<div class="l--layout l--full">
|
||||
<div class="lr--layout-region lr--main">
|
||||
<div class="cc--component-container cc--homepage-hero">
|
||||
<div class="c--component c--homepage-hero"
|
||||
style="position: relative; overflow: hidden; height: 100vh; max-height: 38.125rem;">
|
||||
|
||||
<!-- ====== ẢNH NỀN (Dùng ảnh bài viết hoặc ảnh mặc định) ====== -->
|
||||
<img class="static-fallback-image" th:src="${post.featuredImage != null and !post.featuredImage.isEmpty() ? post.featuredImage : 'https://res.cloudinary.com/ipufdhda/image/upload/v1784534008/BANNER-WEB-scaled_yeox4u.jpg'}" th:alt="${post.title}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;" />
|
||||
|
||||
<!-- ====== TEXT OVERLAY (Nội dung chữ nằm trên ảnh, Hiển thị Tiêu đề bài viết) ====== -->
|
||||
<!-- Thêm một lớp nền mờ (rgba đen) để chữ luôn hiển thị rõ ràng trên mọi hình ảnh -->
|
||||
<div class="text-container centered"
|
||||
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 4; pointer-events: none; display: flex; align-items: center; justify-content: center; background-color: rgba(0, 0, 0, 0.4);">
|
||||
<div class="slide-text-container-inner" style="pointer-events: auto; text-align: center; padding: 20px;">
|
||||
<div class="f--field f--eyebrow" th:if="${post.category != null}" th:text="${post.category.name}" style="color: white; text-shadow: 0 2px 5px rgba(0,0,0,0.7); margin-bottom: 10px; font-weight: bold; text-transform: uppercase;">
|
||||
University News
|
||||
</div>
|
||||
<div class="f--field f--page-title">
|
||||
<h1 class="hero-post-title" th:text="${post.title}">Post Title</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.hero-post-title {
|
||||
color: white;
|
||||
text-shadow: 0 2px 5px rgba(0,0,0,0.7);
|
||||
line-height: 1.2;
|
||||
margin: 0 auto;
|
||||
max-width: 1000px;
|
||||
font-size: 3.5rem;
|
||||
}
|
||||
@media (max-width: 1024px) {
|
||||
.hero-post-title { font-size: 2.8rem; max-width: 800px; }
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.hero-post-title { font-size: 2.2rem; max-width: 600px; }
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.hero-post-title { font-size: 1.8rem; }
|
||||
}
|
||||
</style>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -85,4 +85,27 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// --- Search toggle ---
|
||||
var searchTrigger = document.getElementById('search-drawer-trigger');
|
||||
var searchTriggerActive = document.getElementById('search-drawer-trigger-active');
|
||||
var searchFlyout = document.getElementById('search-flyout-container');
|
||||
var siteHeader = document.querySelector('[data-component-id="umass_base:site-header"]');
|
||||
|
||||
function toggleSearch(e) {
|
||||
e.preventDefault();
|
||||
if (searchTrigger) searchTrigger.classList.toggle('active');
|
||||
if (siteHeader) siteHeader.classList.toggle('search-active');
|
||||
|
||||
if (searchFlyout) {
|
||||
if (searchFlyout.style.display === 'block') {
|
||||
fadeOut(searchFlyout);
|
||||
} else {
|
||||
fadeIn(searchFlyout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchTrigger) searchTrigger.addEventListener('click', toggleSearch);
|
||||
if (searchTriggerActive) searchTriggerActive.addEventListener('click', toggleSearch);
|
||||
});
|
||||
|
||||
@@ -23,22 +23,30 @@
|
||||
<link rel="stylesheet" th:href="@{/css/custom.css}">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body th:class="${bodyClass}">
|
||||
<!-- Skip to main content link (Accessibility) -->
|
||||
<a href="#main-content" class="visually-hidden focusable skip-link">Skip to main content</a>
|
||||
|
||||
<!-- Header Fragment -->
|
||||
<div th:replace="~{fragments/header}"></div>
|
||||
<div class="dialog-off-canvas-main-canvas" data-off-canvas-main-canvas="">
|
||||
<!-- Header Fragment -->
|
||||
<div th:replace="~{themes/umass/header}"></div>
|
||||
|
||||
<!-- Main Content Block -->
|
||||
<main id="main-content" role="main">
|
||||
<div layout:fragment="content">
|
||||
<!-- All elements will be defined in the editor page -->
|
||||
</div>
|
||||
</main>
|
||||
<!-- Main Content Block -->
|
||||
<main id="main-content" role="main">
|
||||
<div layout:fragment="content">
|
||||
<!-- All elements will be defined in the editor page -->
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- Footer Fragment -->
|
||||
<div th:replace="~{themes/umass/footer :: footer}"></div>
|
||||
<!-- Footer Fragment -->
|
||||
<div th:replace="~{themes/umass/footer :: footer}"></div>
|
||||
</div>
|
||||
|
||||
<!-- Core Scripts -->
|
||||
<script th:src="@{/js/mobile-menu.js}"></script>
|
||||
|
||||
<!-- Page Specific Scripts -->
|
||||
<th:block layout:fragment="scripts"></th:block>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -107,7 +107,7 @@
|
||||
style="display:none;visibility:hidden"></iframe></noscript>
|
||||
|
||||
<div class="dialog-off-canvas-main-canvas" data-off-canvas-main-canvas="">
|
||||
<header th:replace="~{fragments/header :: header}"></header>
|
||||
<header th:replace="~{themes/umass/header :: header}"></header>
|
||||
<main id="main-content">
|
||||
|
||||
<div class="l--content">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
|
||||
layout:decorate="~{fragments/layout}">
|
||||
layout:decorate="~{fragments/layout(bodyClass='umass-platform-homepage path-frontpage page-node-type-homepage homepage transparent-header')}">
|
||||
|
||||
<head>
|
||||
<title th:text="${page.title} + ' | S.I.S Cần Thơ'">Liên hệ | S.I.S Cần Thơ</title>
|
||||
@@ -21,10 +21,13 @@
|
||||
<!-- ====== ẢNH NỀN ====== -->
|
||||
<img class="static-fallback-image" src="http://localhost:8080/uploads/2026/07/198e5233-0e9f-4618-8111-32c4df8ae318.jpg" th:alt="${page.title}" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 1;" />
|
||||
|
||||
<!-- ====== TEXT OVERLAY ====== -->
|
||||
<!-- ====== TEXT OVERLAY (Nội dung chữ nằm trên ảnh) ====== -->
|
||||
<div class="text-container centered"
|
||||
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 4; pointer-events: none; display: flex; align-items: center; justify-content: center; background-color: rgba(0, 0, 0, 0.4);">
|
||||
<div class="slide-text-container-inner" style="pointer-events: auto; text-align: center; padding: 20px;">
|
||||
<div class="f--field f--eyebrow" style="color: white; text-shadow: 0 2px 5px rgba(0,0,0,0.7); margin-bottom: 10px; font-weight: bold; text-transform: uppercase;">
|
||||
S.I.S Cần Thơ
|
||||
</div>
|
||||
<div class="f--field f--page-title">
|
||||
<h1 class="hero-post-title" th:text="${page.title}">Liên hệ</h1>
|
||||
</div>
|
||||
|
||||
@@ -233,7 +233,7 @@
|
||||
<li class="megamenu menu-item menu-item--expanded" th:if="${not #lists.isEmpty(item.children)}">
|
||||
<div class="link-arrow-wrapper">
|
||||
<a th:href="${item.url}" th:text="${item.label}">Menu Item</a>
|
||||
<button type="button" class="has-submenu arrow-toggle" aria-expanded="false" aria-haspopup="true" data-once="site-header-arrow">
|
||||
<button type="button" class="has-submenu arrow-toggle" aria-expanded="false" aria-haspopup="true">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 7" width="16" height="7">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#881c1c" d="M7.88,7L15.75,0H0s7.88,7,7.88,7Z"></path>
|
||||
</svg>
|
||||
@@ -288,7 +288,7 @@
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<button id="search-drawer-trigger" aria-label="Open Search" data-once="header-search">
|
||||
<button id="search-drawer-trigger" aria-label="Open Search">
|
||||
<svg class="search-trigger-open" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 25 25">
|
||||
<title>Open Search</title>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#fff" d="M10.03,2.67c-4.07,0-7.36,3.29-7.36,7.36s3.29,7.36,7.36,7.36,7.36-3.29,7.36-7.36c-.01-4.07-3.3-7.36-7.36-7.36ZM10.03,0c5.54,0,10.03,4.49,10.03,10.03,0,2.29-.76,4.39-2.05,6.08l7,7-1.89,1.89-7.01-7.01c-1.68,1.29-3.79,2.05-6.08,2.05C4.49,20.04,0,15.55,0,10.03S4.49,0,10.03,0Z"></path>
|
||||
@@ -298,7 +298,7 @@
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#fff" d="M3.64,1.2l-1.21-1.2L0,2.39l1.21,1.19,7.36,7.25-7.36,7.25-1.21,1.19,2.43,2.39,1.21-1.2,7.36-7.24,7.36,7.24,1.22,1.2,2.42-2.39-1.21-1.19-7.36-7.25,7.36-7.25,1.21-1.19-2.42-2.39-1.22,1.2-7.36,7.24L3.64,1.2Z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button id="mobile-hamburger" class="mobile-hamburger hamburger--squeeze" aria-label="Open Main Navigation" data-once="site-header-hamburger">
|
||||
<button id="mobile-hamburger" class="hamburger hamburger--squeeze" type="button" aria-label="Open Main Navigation">
|
||||
<span class="hamburger-box">
|
||||
<span class="hamburger-inner"></span>
|
||||
</span>
|
||||
@@ -347,7 +347,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button id="search-drawer-trigger-active" aria-label="Open Search" data-once="header-search">
|
||||
<button id="search-drawer-trigger-active" aria-label="Open Search">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 22 22">
|
||||
<title>Close Search</title>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" fill="#fff" d="M3.64,1.2l-1.21-1.2L0,2.39l1.21,1.19,7.36,7.25-7.36,7.25-1.21,1.19,2.43,2.39,1.21-1.2,7.36-7.24,7.36,7.24,1.22,1.2,2.42-2.39-1.21-1.19-7.36-7.25,7.36-7.25,1.21-1.19-2.42-2.39-1.22,1.2-7.36,7.24L3.64,1.2Z"></path>
|
||||
|
||||
Reference in New Issue
Block a user