Files
f1den 29d10ce4cf Тема магазина по макету Figma
Каталог, карточка товара, корзина, оформление заказа и блог на WooCommerce.

Стили разложены по слоям: токены из Figma, база, компоненты, страницы,
брейкпоинты. Цвета, типографика, радиусы и отступы взяты из Variables и
текстовых стилей макета, ниже по слоям хардкода нет.

Иконки — Phosphor, вставляются инлайном как SVG, символами ничего не рисуется.
Стили WooCommerce отключены, вёрстка своя, !important не используется.
2026-07-30 22:38:49 +03:00

259 lines
5.8 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Drawn separators, interaction states, the mobile filter sheet and checkout validation
*/
/* ------------------------------------------------- glyph-free separators --- */
/*
* These were literal "•", "–" and "×" characters in the markup. They are
* separators, not content, so they are drawn instead of typed — which also
* keeps them out of the accessibility tree and out of copied text.
*/
.meta-separator {
display: inline-block;
width: 4px;
height: 4px;
margin: 0 10px;
border-radius: 50%;
background: currentColor;
opacity: 0.4;
vertical-align: middle;
}
.price-fields-separator {
width: 8px;
height: 1px;
flex: 0 0 8px;
background: var(--text-caption);
}
.multiply {
display: inline-block;
width: 8px;
height: 8px;
margin: 0 2px;
background: currentColor;
vertical-align: baseline;
-webkit-mask: var(--icon-x) center / contain no-repeat;
mask: var(--icon-x) center / contain no-repeat;
}
/* ------------------------------------------------------------ interaction --- */
/*
* Hover feedback the design specifies through its own state tokens: list rows
* pick up bg-select-unit-hover, muted tabs and links resolve toward
* text-main / text-link-hover.
*/
.filter-option {
padding: 0 8px;
margin-inline: -8px;
border-radius: var(--br-control-m);
transition: background-color var(--motion-fast);
cursor: pointer;
}
.filter-option:hover {
background: var(--bg-select-unit-hover);
}
.tab-list a {
transition: color var(--motion-fast);
}
.tab-list a:hover {
color: var(--text-main);
}
.main-nav a {
transition: color var(--motion-fast);
}
.main-nav a:hover {
color: var(--text-body);
}
.breadcrumbs a {
transition: color var(--motion-fast);
}
.breadcrumbs a:hover {
color: var(--text-main);
}
.product-card-title,
.cart-item-title a {
transition: color var(--motion-fast);
}
.product-card:hover .product-card-title {
color: var(--text-body);
}
.cart-item-remove {
transition:
background-color var(--motion-fast),
color var(--motion-fast);
}
.cart-item-remove:hover {
color: var(--notice-error);
}
/* ------------------------------------------------- mobile filter sheet --- */
/*
* The design keeps filters in a sidebar on desktop but moves them into a
* sheet on mobile, opened by a "Фильтр" button next to the sort control.
* The sheet reuses the same form, so filtering behaves identically.
*/
.filters-open,
.filters-sheet-head,
.filters-sheet-foot {
display: none;
}
@media (max-width: 767px) {
.filters-open {
display: inline-flex;
align-items: center;
gap: 8px;
padding: var(--pad-h-btn-m) var(--pad-w-text-m) var(--pad-h-btn-m) var(--pad-w-icon-m);
border: 0;
border-radius: var(--br-btn-l);
color: var(--text-main);
background: var(--bg-button-light);
font: var(--control-m);
transition: background-color var(--motion-fast);
}
.filters-open:hover {
background: var(--bg-button-light-hover);
}
.filters-open:active {
background: var(--bg-button-light-pressed);
}
.filters {
position: fixed;
z-index: 60;
inset: 0;
display: flex;
flex-direction: column;
/* The desktop rule sets align-self: start. On an absolutely positioned
box that means "size to content" instead of stretching between top and
bottom, which would make the sheet taller than the viewport. */
align-self: stretch;
overflow: hidden;
border-radius: var(--br-modal) var(--br-modal) 0 0;
background: var(--bg-main);
/* Kept in the DOM so the form state survives; moved out of reach until
the sheet is opened. */
visibility: hidden;
opacity: 0;
transform: translateY(2%);
transition:
opacity var(--motion-slow-duration) var(--motion-slow),
transform var(--motion-slow-duration) var(--motion-slow),
visibility 0s linear var(--motion-slow-duration);
}
.filters.is-open {
visibility: visible;
opacity: 1;
transform: none;
transition-delay: 0s;
}
.filters-sheet-head {
display: flex;
padding: 16px var(--container-gutter);
align-items: center;
justify-content: space-between;
gap: 16px;
border-bottom: 1px solid var(--border-main);
}
.filters-sheet-title {
margin: 0;
font: var(--h4);
letter-spacing: var(--ls-tight);
}
.filters-close {
width: 44px;
height: 44px;
}
.filters form {
flex: 1 1 auto;
padding: 0 var(--container-gutter);
overflow-y: auto;
overscroll-behavior: contain;
}
.filters .filter-group {
padding: 16px 0;
border-bottom: 1px solid var(--border-main);
}
.filters-sheet-foot {
display: block;
padding: 16px var(--container-gutter) calc(16px + env(safe-area-inset-bottom));
border-top: 1px solid var(--border-main);
}
.filters-apply {
width: 100%;
}
body.filters-open-lock {
overflow: hidden;
}
}
.filter-input::-webkit-outer-spin-button,
.filter-input::-webkit-inner-spin-button {
margin: 0;
appearance: none;
}
/* --------------------------------------------------- checkout validation --- */
/*
* The design puts validation on the field itself: a red edge plus red caption
* text under it, per field. It does not use a banner listing every problem, so
* the WooCommerce notice group is suppressed once its errors have been mapped
* onto the fields.
*/
.checkout-input {
position: relative;
}
.checkout-input .field-error {
display: block;
margin-top: 4px;
color: var(--text-negative);
font: var(--caption);
}
.checkout-input .field-error:empty {
display: none;
}
.checkout-input.is-error input {
border-color: var(--border-input-error);
box-shadow: inset 0 0 0 1px var(--border-input-error);
}
.checkout-input input:focus {
box-shadow: inset 0 0 0 1px var(--border-input-focus);
}
.woocommerce-NoticeGroup-checkout.is-field-level,
.checkout .woocommerce-error.is-field-level {
display: none;
}