Initial commit
This commit is contained in:
49
src/css/animations.css
Normal file
49
src/css/animations.css
Normal file
@@ -0,0 +1,49 @@
|
||||
/* ===== IntersectionObserver fallback ===== */
|
||||
[data-reveal] {
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
transition: opacity 0.6s ease, transform 0.6s ease;
|
||||
}
|
||||
|
||||
[data-reveal].is-visible {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* ===== Scroll-driven animations (progressive enhancement) ===== */
|
||||
.has-scroll-driven [data-reveal] {
|
||||
opacity: 1;
|
||||
transform: none;
|
||||
transition: none;
|
||||
|
||||
animation: reveal-in linear both;
|
||||
animation-timeline: view();
|
||||
animation-range: entry 0% entry 30%;
|
||||
}
|
||||
|
||||
@keyframes reveal-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(24px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Details open/close transition */
|
||||
.services__content {
|
||||
animation: accordion-open 0.25s ease;
|
||||
}
|
||||
|
||||
@keyframes accordion-open {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
53
src/css/base.css
Normal file
53
src/css/base.css
Normal file
@@ -0,0 +1,53 @@
|
||||
body {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--body-size);
|
||||
line-height: var(--body-lh);
|
||||
color: var(--color-dark);
|
||||
background-color: var(--color-bg);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.h1 {
|
||||
font-family: var(--font-headline);
|
||||
font-size: var(--h1-size);
|
||||
line-height: var(--h1-lh);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.h2 {
|
||||
font-family: var(--font-headline);
|
||||
font-size: var(--h2-size);
|
||||
line-height: var(--h2-lh);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
.h3 {
|
||||
font-family: var(--font-headline);
|
||||
font-size: var(--h3-size);
|
||||
line-height: var(--h3-lh);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.body-text {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--body-size);
|
||||
line-height: calc(var(--body-lh) + 6px);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.caption {
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--caption-size);
|
||||
line-height: var(--caption-lh);
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
52
src/css/cases.css
Normal file
52
src/css/cases.css
Normal file
@@ -0,0 +1,52 @@
|
||||
.cases {
|
||||
padding: var(--section-gap) 0;
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.cases__heading {
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
.cases__grid {
|
||||
row-gap: var(--grid-gutter);
|
||||
}
|
||||
|
||||
.cases__tile {
|
||||
display: grid;
|
||||
grid-template: 1fr / 1fr;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cases__tile-image {
|
||||
grid-area: 1 / 1;
|
||||
width: 100%;
|
||||
aspect-ratio: 4 / 3;
|
||||
transition: transform 0.4s ease;
|
||||
}
|
||||
|
||||
.cases__tile:hover .cases__tile-image {
|
||||
transform: scale(1.03);
|
||||
}
|
||||
|
||||
.cases__tile-title {
|
||||
grid-area: 1 / 1;
|
||||
align-self: end;
|
||||
padding: 24px;
|
||||
color: var(--color-white);
|
||||
mix-blend-mode: difference;
|
||||
z-index: 1;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.cases__heading {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.cases__tile-title {
|
||||
padding: 16px;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
89
src/css/components.css
Normal file
89
src/css/components.css
Normal file
@@ -0,0 +1,89 @@
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
padding: 14px 32px;
|
||||
border-radius: var(--btn-radius);
|
||||
border: 1.5px solid transparent;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s, color 0.2s, border-color 0.2s;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn--primary {
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
border-color: var(--color-dark);
|
||||
}
|
||||
|
||||
.btn--primary:hover {
|
||||
background-color: transparent;
|
||||
color: var(--color-dark);
|
||||
}
|
||||
|
||||
.btn--outline {
|
||||
background-color: transparent;
|
||||
color: var(--color-dark);
|
||||
border-color: var(--color-dark);
|
||||
}
|
||||
|
||||
.btn--outline:hover {
|
||||
background-color: var(--color-dark);
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.btn--light {
|
||||
background-color: var(--color-white);
|
||||
color: var(--color-dark);
|
||||
border-color: var(--color-white);
|
||||
}
|
||||
|
||||
.btn--light:hover {
|
||||
background-color: transparent;
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
||||
.hairline {
|
||||
width: 1px;
|
||||
background-color: var(--color-dark);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.hairline--h {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.annotation {
|
||||
position: relative;
|
||||
padding-left: 16px;
|
||||
}
|
||||
|
||||
.annotation::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
width: 1px;
|
||||
background-color: var(--color-dark);
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.annotation__label {
|
||||
font-family: var(--font-body);
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
opacity: 0.5;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.annotation__text {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
line-height: 1.4;
|
||||
}
|
||||
31
src/css/footer.css
Normal file
31
src/css/footer.css
Normal file
@@ -0,0 +1,31 @@
|
||||
.footer {
|
||||
padding: 40px 0;
|
||||
border-top: 1px solid rgba(26, 26, 26, 0.15);
|
||||
}
|
||||
|
||||
.footer__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.footer__copy,
|
||||
.footer__telegram,
|
||||
.footer__privacy {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.footer__telegram:hover,
|
||||
.footer__privacy:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.footer__inner {
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
76
src/css/grid.css
Normal file
76
src/css/grid.css
Normal file
@@ -0,0 +1,76 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: var(--grid-max);
|
||||
margin: 0 auto;
|
||||
padding: 0 var(--grid-margin);
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--grid-columns), 1fr);
|
||||
gap: var(--grid-gutter);
|
||||
}
|
||||
|
||||
/* Column span utilities */
|
||||
.col-span-1 { grid-column: span 1; }
|
||||
.col-span-2 { grid-column: span 2; }
|
||||
.col-span-3 { grid-column: span 3; }
|
||||
.col-span-4 { grid-column: span 4; }
|
||||
.col-span-5 { grid-column: span 5; }
|
||||
.col-span-6 { grid-column: span 6; }
|
||||
.col-span-7 { grid-column: span 7; }
|
||||
.col-span-8 { grid-column: span 8; }
|
||||
.col-span-9 { grid-column: span 9; }
|
||||
.col-span-10 { grid-column: span 10; }
|
||||
.col-span-11 { grid-column: span 11; }
|
||||
.col-span-12 { grid-column: span 12; }
|
||||
|
||||
/* Column start utilities */
|
||||
.col-start-1 { grid-column-start: 1; }
|
||||
.col-start-2 { grid-column-start: 2; }
|
||||
.col-start-3 { grid-column-start: 3; }
|
||||
.col-start-4 { grid-column-start: 4; }
|
||||
.col-start-5 { grid-column-start: 5; }
|
||||
.col-start-6 { grid-column-start: 6; }
|
||||
.col-start-7 { grid-column-start: 7; }
|
||||
.col-start-8 { grid-column-start: 8; }
|
||||
.col-start-9 { grid-column-start: 9; }
|
||||
.col-start-10 { grid-column-start: 10; }
|
||||
.col-start-11 { grid-column-start: 11; }
|
||||
.col-start-12 { grid-column-start: 12; }
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 0 var(--grid-margin);
|
||||
}
|
||||
|
||||
.col-span-1,
|
||||
.col-span-2,
|
||||
.col-span-3,
|
||||
.col-span-4,
|
||||
.col-span-5,
|
||||
.col-span-6,
|
||||
.col-span-7,
|
||||
.col-span-8,
|
||||
.col-span-9,
|
||||
.col-span-10,
|
||||
.col-span-11,
|
||||
.col-span-12 {
|
||||
grid-column: span 4;
|
||||
}
|
||||
|
||||
.col-start-1,
|
||||
.col-start-2,
|
||||
.col-start-3,
|
||||
.col-start-4,
|
||||
.col-start-5,
|
||||
.col-start-6,
|
||||
.col-start-7,
|
||||
.col-start-8,
|
||||
.col-start-9,
|
||||
.col-start-10,
|
||||
.col-start-11,
|
||||
.col-start-12 {
|
||||
grid-column-start: 1;
|
||||
}
|
||||
}
|
||||
59
src/css/header.css
Normal file
59
src/css/header.css
Normal file
@@ -0,0 +1,59 @@
|
||||
.header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
height: var(--header-height);
|
||||
background-color: rgba(231, 242, 234, 0.85);
|
||||
border-bottom: 1px solid rgba(26, 26, 26, 0.1);
|
||||
transition: backdrop-filter 0.3s;
|
||||
}
|
||||
|
||||
.header--scrolled {
|
||||
backdrop-filter: blur(8px);
|
||||
-webkit-backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.header__inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.header__wordmark {
|
||||
font-family: var(--font-headline);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
font-size: 14px;
|
||||
letter-spacing: 0.05em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.header__nav {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.header__link {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
letter-spacing: 0.03em;
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.header__link:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.header__nav {
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.header__link {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
72
src/css/hero.css
Normal file
72
src/css/hero.css
Normal file
@@ -0,0 +1,72 @@
|
||||
.hero {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-top: var(--header-height);
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.hero__inner {
|
||||
align-items: start;
|
||||
row-gap: 60px;
|
||||
}
|
||||
|
||||
.hero__headline-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.hero__title {
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
.hero__subtitle {
|
||||
max-width: 420px;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.hero__editorial {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-top: 80px;
|
||||
}
|
||||
|
||||
.hero__image-placeholder {
|
||||
width: 100%;
|
||||
aspect-ratio: 3 / 4;
|
||||
background-color: var(--color-primary);
|
||||
max-height: 500px;
|
||||
}
|
||||
|
||||
.hero__annotations {
|
||||
display: flex;
|
||||
gap: 40px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.hero {
|
||||
min-height: auto;
|
||||
padding-top: calc(var(--header-height) + 40px);
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
|
||||
.hero__headline-block {
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.hero__editorial {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.hero__image-placeholder {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.hero__annotations {
|
||||
flex-direction: column;
|
||||
gap: 24px;
|
||||
}
|
||||
}
|
||||
73
src/css/journal.css
Normal file
73
src/css/journal.css
Normal file
@@ -0,0 +1,73 @@
|
||||
.journal {
|
||||
padding: var(--section-gap) 0;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.journal::after {
|
||||
content: attr(data-number);
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
right: 5%;
|
||||
font-family: var(--font-headline);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
font-size: clamp(200px, 30vw, 400px);
|
||||
line-height: 1;
|
||||
color: var(--color-dark);
|
||||
opacity: 0.04;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.journal__inner {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
align-items: end;
|
||||
}
|
||||
|
||||
.journal__image-block {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.journal__image-placeholder {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
background-color: var(--color-surface);
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.journal__text-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
align-self: end;
|
||||
}
|
||||
|
||||
.journal__body {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.journal__buttons {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.journal__image-placeholder {
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.journal__text-block {
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
.journal__buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.journal__buttons .btn {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
39
src/css/manifest.css
Normal file
39
src/css/manifest.css
Normal file
@@ -0,0 +1,39 @@
|
||||
.manifest {
|
||||
padding: var(--section-gap) 0;
|
||||
}
|
||||
|
||||
.manifest__inner {
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.manifest__text {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.manifest__heading {
|
||||
color: var(--color-dark);
|
||||
}
|
||||
|
||||
.manifest__body {
|
||||
opacity: 0.7;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.manifest__caption {
|
||||
text-align: right;
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.manifest__caption .caption {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.manifest__caption {
|
||||
text-align: left;
|
||||
order: -1;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
61
src/css/reset.css
Normal file
61
src/css/reset.css
Normal file
@@ -0,0 +1,61 @@
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
-moz-text-size-adjust: none;
|
||||
-webkit-text-size-adjust: none;
|
||||
text-size-adjust: none;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
img,
|
||||
picture,
|
||||
video,
|
||||
svg {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
input,
|
||||
button,
|
||||
textarea,
|
||||
select {
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
overflow-wrap: break-word;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
details summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
details summary::marker {
|
||||
content: '';
|
||||
}
|
||||
150
src/css/services.css
Normal file
150
src/css/services.css
Normal file
@@ -0,0 +1,150 @@
|
||||
.services {
|
||||
padding: var(--section-gap) 0;
|
||||
}
|
||||
|
||||
.services__heading {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
|
||||
.services__item {
|
||||
border-top: 1px solid rgba(26, 26, 26, 0.2);
|
||||
}
|
||||
|
||||
.services__item:last-of-type {
|
||||
border-bottom: 1px solid rgba(26, 26, 26, 0.2);
|
||||
}
|
||||
|
||||
.services__summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
padding: 24px 0;
|
||||
list-style: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.services__number {
|
||||
font-family: var(--font-body);
|
||||
font-size: 13px;
|
||||
opacity: 0.4;
|
||||
min-width: 28px;
|
||||
}
|
||||
|
||||
.services__title {
|
||||
font-family: var(--font-headline);
|
||||
font-size: clamp(16px, 1.5vw, 20px);
|
||||
font-weight: 900;
|
||||
font-stretch: 125%;
|
||||
text-transform: uppercase;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.services__icon {
|
||||
font-size: 24px;
|
||||
font-weight: 300;
|
||||
opacity: 0.5;
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.services__item[open] .services__icon {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.services__content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 40px;
|
||||
padding: 8px 0 40px 52px;
|
||||
}
|
||||
|
||||
.services__section {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.services__section-title {
|
||||
font-family: var(--font-body);
|
||||
font-size: 12px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
opacity: 0.5;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.services__list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.services__list li {
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
padding-left: 12px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.services__list li::before {
|
||||
content: '\2022';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.services__steps {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
counter-reset: step;
|
||||
}
|
||||
|
||||
.services__steps li {
|
||||
font-family: var(--font-body);
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
counter-increment: step;
|
||||
}
|
||||
|
||||
.services__steps li::before {
|
||||
content: counter(step) '.';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.services__cta {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.services__footer {
|
||||
margin-top: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.services__footer-text {
|
||||
opacity: 0.7;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.services__block {
|
||||
grid-column: span 4;
|
||||
grid-column-start: 1;
|
||||
}
|
||||
|
||||
.services__content {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 24px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.services__summary {
|
||||
gap: 12px;
|
||||
padding: 20px 0;
|
||||
}
|
||||
}
|
||||
60
src/css/tokens.css
Normal file
60
src/css/tokens.css
Normal file
@@ -0,0 +1,60 @@
|
||||
:root {
|
||||
/* Colors */
|
||||
--color-primary: #007DDA;
|
||||
--color-bg: #E7F2EA;
|
||||
--color-surface: #FCC3C3;
|
||||
--color-ink: #BD5E24;
|
||||
--color-accent: #FB9322;
|
||||
--color-dark: #1A1A1A;
|
||||
--color-white: #FFFFFF;
|
||||
|
||||
/* Typography — Families */
|
||||
--font-headline: 'Archivo', sans-serif;
|
||||
--font-body: 'Inter', sans-serif;
|
||||
|
||||
/* Typography — Sizes (Desktop) */
|
||||
--h1-size: clamp(32px, 4vw, 48px);
|
||||
--h1-lh: 40px;
|
||||
--h2-size: clamp(24px, 2.5vw, 31px);
|
||||
--h2-lh: 30px;
|
||||
--h3-size: clamp(18px, 2vw, 24px);
|
||||
--h3-lh: 20px;
|
||||
--body-size: 16px;
|
||||
--body-lh: 18px;
|
||||
--caption-size: 16px;
|
||||
--caption-lh: 44px;
|
||||
|
||||
/* Grid */
|
||||
--grid-columns: 12;
|
||||
--grid-container: 1200px;
|
||||
--grid-max: 1424px;
|
||||
--grid-gutter: 32px;
|
||||
--grid-margin: 96px;
|
||||
|
||||
/* Spacing */
|
||||
--section-gap: clamp(120px, 15vw, 220px);
|
||||
--headline-spacing: 160px;
|
||||
|
||||
/* Misc */
|
||||
--btn-radius: 3px;
|
||||
--header-height: 64px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
:root {
|
||||
--h1-size: 32px;
|
||||
--h1-lh: 40px;
|
||||
--h2-size: 34px;
|
||||
--h2-lh: 30px;
|
||||
--h3-size: 20px;
|
||||
--h3-lh: 80px;
|
||||
--body-size: 16px;
|
||||
--body-lh: 14px;
|
||||
--caption-size: 14px;
|
||||
--caption-lh: 12px;
|
||||
|
||||
--grid-columns: 4;
|
||||
--grid-gutter: 16px;
|
||||
--grid-margin: 20px;
|
||||
}
|
||||
}
|
||||
75
src/main.js
Normal file
75
src/main.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import './style.css'
|
||||
|
||||
function initScrollReveal() {
|
||||
const supportsScrollDriven = CSS.supports('animation-timeline', 'view()')
|
||||
|
||||
if (supportsScrollDriven) {
|
||||
document.documentElement.classList.add('has-scroll-driven')
|
||||
return
|
||||
}
|
||||
|
||||
const reveals = document.querySelectorAll('[data-reveal]')
|
||||
if (!reveals.length) return
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('is-visible')
|
||||
observer.unobserve(entry.target)
|
||||
}
|
||||
})
|
||||
},
|
||||
{ threshold: 0.15 }
|
||||
)
|
||||
|
||||
reveals.forEach((el) => observer.observe(el))
|
||||
}
|
||||
|
||||
function initSmoothScroll() {
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener('click', (e) => {
|
||||
const targetId = anchor.getAttribute('href')
|
||||
if (targetId === '#') return
|
||||
|
||||
const target = document.querySelector(targetId)
|
||||
if (!target) return
|
||||
|
||||
e.preventDefault()
|
||||
const headerOffset = parseInt(
|
||||
getComputedStyle(document.documentElement)
|
||||
.getPropertyValue('--header-height'),
|
||||
10
|
||||
)
|
||||
const top = target.getBoundingClientRect().top + window.scrollY - headerOffset - 20
|
||||
|
||||
window.scrollTo({ top, behavior: 'smooth' })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function initHeaderScroll() {
|
||||
const header = document.getElementById('header')
|
||||
if (!header) return
|
||||
|
||||
let ticking = false
|
||||
window.addEventListener(
|
||||
'scroll',
|
||||
() => {
|
||||
if (!ticking) {
|
||||
requestAnimationFrame(() => {
|
||||
header.classList.toggle('header--scrolled', window.scrollY > 100)
|
||||
ticking = false
|
||||
})
|
||||
ticking = true
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
)
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initScrollReveal()
|
||||
initSmoothScroll()
|
||||
initHeaderScroll()
|
||||
})
|
||||
13
src/style.css
Normal file
13
src/style.css
Normal file
@@ -0,0 +1,13 @@
|
||||
@import './css/reset.css';
|
||||
@import './css/tokens.css';
|
||||
@import './css/base.css';
|
||||
@import './css/grid.css';
|
||||
@import './css/components.css';
|
||||
@import './css/header.css';
|
||||
@import './css/hero.css';
|
||||
@import './css/manifest.css';
|
||||
@import './css/journal.css';
|
||||
@import './css/cases.css';
|
||||
@import './css/services.css';
|
||||
@import './css/footer.css';
|
||||
@import './css/animations.css';
|
||||
Reference in New Issue
Block a user