Каталог, карточка товара, корзина, оформление заказа и блог на WooCommerce. Стили разложены по слоям: токены из Figma, база, компоненты, страницы, брейкпоинты. Цвета, типографика, радиусы и отступы взяты из Variables и текстовых стилей макета, ниже по слоям хардкода нет. Иконки — Phosphor, вставляются инлайном как SVG, символами ничего не рисуется. Стили WooCommerce отключены, вёрстка своя, !important не используется.
373 lines
6.4 KiB
CSS
373 lines
6.4 KiB
CSS
/*
|
|
* Home page: hero, product cards, category cards, news cards
|
|
*/
|
|
|
|
/* Home hero */
|
|
.home .site-header {
|
|
height: 120px;
|
|
}
|
|
|
|
.hero {
|
|
height: 654px;
|
|
min-height: 654px;
|
|
padding: 48px 0 0;
|
|
background: var(--bg-secondary);
|
|
}
|
|
|
|
.hero-copy {
|
|
display: flex;
|
|
width: 100%;
|
|
max-width: 1008px;
|
|
flex-direction: column;
|
|
gap: 32px;
|
|
}
|
|
|
|
.hero-main {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 24px;
|
|
}
|
|
|
|
.hero-title-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 16px;
|
|
}
|
|
|
|
.hero h1 {
|
|
max-width: 1008px;
|
|
margin: 0;
|
|
font: var(--h1);
|
|
letter-spacing: var(--ls-tight);
|
|
}
|
|
|
|
.hero-copy > p,
|
|
.hero-title-group > p {
|
|
max-width: 656px;
|
|
min-height: 84px;
|
|
margin: 0;
|
|
color: var(--text-main);
|
|
font: var(--lead);
|
|
}
|
|
|
|
.hero-features {
|
|
display: grid;
|
|
width: 100%;
|
|
max-width: 656px;
|
|
margin: 0;
|
|
grid-template-columns: repeat(3, 1fr);
|
|
gap: 32px;
|
|
}
|
|
|
|
.hero-feature {
|
|
display: flex;
|
|
min-width: 0;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
font: var(--control-m);
|
|
}
|
|
|
|
.feature-mark {
|
|
--icon-size: 24px;
|
|
|
|
display: block;
|
|
}
|
|
|
|
.hero-button {
|
|
width: 144px;
|
|
height: 72px;
|
|
min-height: 72px;
|
|
padding: 0 28px;
|
|
font: var(--control-m);
|
|
}
|
|
|
|
/* Product cards */
|
|
.products-section {
|
|
height: 555px;
|
|
padding-top: 16px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.products-section .section-head {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.product-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
gap: 24px;
|
|
}
|
|
|
|
.product-card {
|
|
container-type: inline-size;
|
|
min-width: 0;
|
|
padding: 16px;
|
|
border: 0;
|
|
border-radius: 16px;
|
|
background: var(--bg-main);
|
|
box-shadow: inset 0 0 0 1px var(--border-main);
|
|
transition: box-shadow 400ms var(--motion-slow);
|
|
}
|
|
|
|
.product-card:hover,
|
|
.product-card:focus-within {
|
|
box-shadow: inset 0 0 0 1px var(--border-secondary);
|
|
}
|
|
|
|
.product-card-media {
|
|
position: relative;
|
|
display: block;
|
|
height: 220px;
|
|
overflow: hidden;
|
|
border-radius: 8px;
|
|
background: var(--bg-select-unit-selected);
|
|
}
|
|
|
|
.product-card-media img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
.product-badge {
|
|
display: inline-block;
|
|
padding: 3px 6px;
|
|
color: var(--text-main-contrast);
|
|
background: var(--text-main);
|
|
font: var(--upper-s);
|
|
letter-spacing: var(--ls-upper);
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.product-card-media .product-badge {
|
|
position: absolute;
|
|
z-index: 2;
|
|
top: 10px;
|
|
left: 10px;
|
|
}
|
|
|
|
.product-card-body {
|
|
padding: 12px 0 0;
|
|
}
|
|
|
|
.stock {
|
|
color: var(--text-positive);
|
|
font: var(--control-s);
|
|
}
|
|
|
|
.product-card-title {
|
|
margin: 5px 0 1px;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
font: var(--control-m);
|
|
}
|
|
|
|
.price {
|
|
display: flex;
|
|
min-height: 27px;
|
|
align-items: baseline;
|
|
gap: 10px;
|
|
font: var(--h5);
|
|
letter-spacing: var(--ls-tight-s);
|
|
}
|
|
|
|
.price ins {
|
|
order: -1;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.price del {
|
|
color: var(--text-caption);
|
|
font: var(--control-s);
|
|
}
|
|
|
|
/*
|
|
* The stepper is 132px at the design width and gives that space back as the
|
|
* card narrows; min-content on the button track is its natural width, so the
|
|
* label is never squeezed. Below the point where both still fit they stack,
|
|
* ending up the same width as each other rather than one starving the other.
|
|
*/
|
|
.card-buy {
|
|
display: grid;
|
|
margin-top: 12px;
|
|
grid-template-columns: minmax(104px, 132px) minmax(min-content, 1fr);
|
|
gap: 8px;
|
|
}
|
|
|
|
@container (max-width: 251px) {
|
|
.card-buy {
|
|
grid-template-columns: minmax(0, 1fr);
|
|
}
|
|
}
|
|
|
|
.add-cart {
|
|
min-width: 0;
|
|
min-height: 52px;
|
|
padding: 10px 12px;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.add-cart .icon {
|
|
width: 20px;
|
|
height: 20px;
|
|
}
|
|
|
|
/* Category cards */
|
|
.categories-section {
|
|
padding-top: 60px;
|
|
}
|
|
|
|
.category-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
gap: 24px;
|
|
}
|
|
|
|
.category-card {
|
|
position: relative;
|
|
display: grid;
|
|
height: 260px;
|
|
grid-template-columns: 400px 260px;
|
|
overflow: hidden;
|
|
border-radius: var(--br-section-m);
|
|
background: var(--bg-secondary);
|
|
}
|
|
|
|
.category-card::after {
|
|
position: absolute;
|
|
z-index: 2;
|
|
inset: 0;
|
|
border: 1px solid var(--border-secondary);
|
|
border-radius: inherit;
|
|
content: "";
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
transition: opacity 400ms var(--motion-slow);
|
|
}
|
|
|
|
.category-card-copy {
|
|
display: flex;
|
|
padding: 24px;
|
|
align-items: flex-start;
|
|
flex-direction: column;
|
|
transition: background-color 400ms var(--motion-slow);
|
|
}
|
|
|
|
.category-card:hover,
|
|
.category-card:focus-visible {
|
|
outline: 0;
|
|
}
|
|
|
|
.category-card:hover::after,
|
|
.category-card:focus-visible::after {
|
|
opacity: 1;
|
|
}
|
|
|
|
.category-card:hover .category-card-copy,
|
|
.category-card:focus-visible .category-card-copy {
|
|
background: var(--bg-main);
|
|
}
|
|
|
|
.category-card h3 {
|
|
margin: 0 0 3px;
|
|
font: var(--h4);
|
|
letter-spacing: var(--ls-tight);
|
|
}
|
|
|
|
.category-card p {
|
|
margin: 0;
|
|
color: var(--text-caption);
|
|
font: var(--control-m);
|
|
}
|
|
|
|
.category-card .text-link {
|
|
margin-top: auto;
|
|
}
|
|
|
|
.category-card-media {
|
|
background: var(--bg-select-unit-selected);
|
|
}
|
|
|
|
/* News cards */
|
|
.news-section {
|
|
padding-top: 24px;
|
|
padding-bottom: 64px;
|
|
}
|
|
|
|
.news-section .section-head {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
.news-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
gap: 24px;
|
|
}
|
|
|
|
.news-card {
|
|
position: relative;
|
|
display: flex;
|
|
height: 408px;
|
|
padding: 24px;
|
|
justify-content: flex-end;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
border-radius: 10px;
|
|
color: var(--text-main-contrast);
|
|
background: linear-gradient(to bottom, var(--bg-select-unit-selected) 0 43%, var(--bg-select-unit-selected) 48%, #000 100%);
|
|
}
|
|
|
|
.news-card > * {
|
|
position: relative;
|
|
z-index: 1;
|
|
transition: transform 400ms var(--motion-slow);
|
|
}
|
|
|
|
.news-card:hover > *,
|
|
.news-card:focus-visible > * {
|
|
transform: translateY(-8px);
|
|
}
|
|
|
|
.news-card h3 {
|
|
margin: 0 0 4px;
|
|
font: var(--h5);
|
|
letter-spacing: var(--ls-tight-s);
|
|
}
|
|
|
|
.news-card p {
|
|
max-width: 340px;
|
|
margin: 0;
|
|
color: var(--text-main-contrast);
|
|
font: var(--control-s);
|
|
}
|
|
|
|
.all-news-link {
|
|
display: flex;
|
|
height: 56px;
|
|
margin-top: 24px;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
border-radius: var(--br-btn-m);
|
|
color: var(--text-main);
|
|
background: var(--bg-secondary);
|
|
font: var(--control-m);
|
|
transition: background-color 100ms ease-in-out;
|
|
}
|
|
|
|
.all-news-link:hover,
|
|
.all-news-link:focus-visible {
|
|
background: var(--bg-button-light-hover);
|
|
}
|
|
|
|
.all-news-link:active {
|
|
background: var(--bg-button-light-pressed);
|
|
}
|
|
|
|
/* The two home grids double as carousels; the track replaces the grid flow. */
|
|
.product-grid.is-carousel,
|
|
.news-grid.is-carousel {
|
|
display: block;
|
|
}
|