Files
site-portfolio/public/_lab/lab.css
T
root a0dda98b83 i18n: build-time ru/en localization + EN homepage & cookie-policy
- build-pages.mjs: per-locale page/partial overrides (*.en.html), i18n token
  resolution with ru fallback, <html lang> + assetPrefix per locale
- UI dictionaries src/i18n/{ru,en}.json; lang-switch partial
- headers/footer/partials converted to {{i18n:…}} tokens
- root-absolute static asset refs so /en/ subpath loads css/js/vendor
- EN content: homepage (index.en.html + partials) and cookie-policy.en.html
  (cookie-policy body translated via apinex.bond /v1/tools/translator)
2026-09-15 22:27:51 +02:00

405 lines
10 KiB
CSS
Raw 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.
/* Обвязка стенда. Сюда не пишем стили компонента — только рамки, сетки,
подписи и подложки. Стили neu-card живут в public/css/main.css. */
.lab {
max-width: 62rem;
margin: 0 auto;
padding: clamp(2rem, 5vw, 3.5rem) var(--space) 8rem;
}
.lab__head {
margin-bottom: clamp(2.5rem, 6vw, 4rem);
}
.lab__h1 {
margin: 0 0 0.5rem;
font-family: var(--font-accent);
font-size: clamp(1.8rem, 4vw, 2.5rem);
font-weight: 700;
line-height: 1.1;
}
.lab__sub {
margin: 0 0 1.25rem;
max-width: 42rem;
color: var(--text-muted);
line-height: 1.6;
}
.lab__nav {
display: flex;
flex-wrap: wrap;
gap: 0.4rem 0.75rem;
font-size: 0.85rem;
}
.lab__nav a {
color: var(--accent-text);
text-decoration: none;
border-bottom: 1px solid transparent;
}
.lab__nav a:hover {
border-bottom-color: currentColor;
}
.lab__sec {
padding-top: clamp(2rem, 5vw, 3rem);
margin-bottom: clamp(2rem, 5vw, 3rem);
scroll-margin-top: 1.5rem;
}
.lab__h2 {
margin: 0 0 0.5rem;
font-family: var(--font-accent);
font-size: clamp(1.25rem, 2.5vw, 1.6rem);
font-weight: 700;
line-height: 1.2;
}
.lab__h3 {
margin: 2.5rem 0 0.5rem;
font-family: var(--font-accent);
font-size: 1rem;
font-weight: 700;
line-height: 1.2;
color: var(--text);
}
.lab__note {
margin: 0 0 1.5rem;
max-width: 46rem;
font-size: 0.9rem;
line-height: 1.6;
color: var(--text-muted);
}
.lab__caption {
margin: 0.75rem 0 0;
font-size: 0.78rem;
line-height: 1.4;
color: var(--text-muted);
}
.lab code {
font-family: var(--font);
font-size: 0.92em;
padding: 0.1em 0.35em;
border-radius: var(--radius-sm);
background: color-mix(in srgb, var(--text) 8%, transparent);
}
.lab__row {
display: flex;
flex-wrap: wrap;
gap: 1.5rem;
align-items: flex-start;
}
.lab__row--wrap .neu-card {
flex: 0 0 auto;
}
/* ── Токены ─────────────────────────────────────────────────────── */
.lab__tokens {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
gap: 0.75rem;
}
.lab__token {
margin: 0;
padding: 0.9rem 1rem;
border-radius: var(--radius-md);
background: var(--bg-elevated);
border: 1px solid var(--line);
}
.lab__token dt {
font-size: 0.82rem;
margin-bottom: 0.3rem;
}
.lab__token dt span {
color: var(--text-muted);
margin-left: 0.35rem;
}
.lab__token dd {
margin: 0;
font-size: 0.82rem;
line-height: 1.5;
color: var(--text-muted);
}
/* ── Фоны ───────────────────────────────────────────────────────── */
.lab__bg-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
gap: 1.5rem;
}
.lab__bg-cell {
padding: 1.75rem;
border-radius: var(--radius-md);
border: 1px solid var(--line);
}
.lab__bg-cell[data-bg="page"] {
background: var(--bg);
}
.lab__bg-cell[data-bg="elevated"] {
background: var(--bg-elevated);
}
.lab__bg-cell[data-bg="surface"] {
background: var(--surface);
}
.lab__bg-cell[data-bg="accent"] {
background: var(--accent);
color: var(--on-accent, var(--text));
}
.lab__bg-cell[data-bg="accent"] .lab__caption {
color: color-mix(in srgb, var(--on-accent, var(--text)) 78%, transparent);
}
.lab__bg-cell[data-bg="media"] {
background-image: url("/assets/template-elements-demo/img-long.webp");
background-size: cover;
background-position: center;
color: #fff;
}
.lab__bg-cell[data-bg="media"] .lab__caption {
color: rgba(255, 255, 255, 0.85);
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.lab__bg-cell[data-bg="media"] .neu-card {
background: var(--surface);
color: var(--text);
}
/* ── Состояния ──────────────────────────────────────────────────── */
.lab__state {
display: flex;
flex-direction: column;
}
.lab__depth {
gap: 1.25rem;
}
.lab__depth .neu-card {
min-width: 150px;
}
/* ── Сетка ──────────────────────────────────────────────────────── */
.lab__grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
gap: 1rem;
margin-bottom: 1.5rem;
}
.lab__grid--3 {
grid-template-columns: repeat(3, 1fr);
}
.lab__grid--tight {
gap: 0.5rem;
}
@media (max-width: 640px) {
.lab__grid--3 {
grid-template-columns: 1fr;
}
}
/* ── Переключатель стенда ───────────────────────────────────────── */
.lab-switch {
position: fixed;
right: max(1rem, env(safe-area-inset-right, 0px));
bottom: max(1rem, env(safe-area-inset-bottom, 0px));
z-index: 200;
display: flex;
align-items: center;
gap: 0.25rem;
padding: 0.35rem;
border-radius: 999px;
background: var(--surface);
border: 1px solid var(--line);
box-shadow: 0 8px 24px hsla(0, 0%, 0%, 0.25);
font-size: 0.78rem;
}
.lab-switch__btn {
appearance: none;
border: 0;
padding: 0.35rem 0.7rem;
border-radius: 999px;
background: transparent;
color: var(--text-muted);
font: inherit;
font-family: var(--font-accent);
cursor: pointer;
}
.lab-switch__btn:hover {
color: var(--text);
background: color-mix(in srgb, var(--text) 8%, transparent);
}
.lab-switch__btn[aria-pressed="true"] {
background: var(--accent);
color: var(--on-accent, #fff);
}
.lab-switch__sep {
width: 1px;
height: 1.25rem;
margin: 0 0.15rem;
background: var(--line);
}
/* ── Карточка в карточке ────────────────────────────────────────── */
.lab__nest {
margin-bottom: 1.5rem;
}
/* Внешняя карточка: увеличенные поля и минимум, чтобы вместить вложенные */
.neu-card--nest {
--neu-pad: 1.75rem;
--neu-min-w: 0;
--neu-min-h: 0;
gap: 1rem;
justify-content: flex-start;
}
.neu-card__nest-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
.neu-card__nest-row {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
@media (max-width: 640px) {
.neu-card__nest-grid {
grid-template-columns: 1fr;
}
}
/* ── Шейдер-карточка (прототип Paper Shaders) ───────────────────── */
/* canvas шейдера — фоновый слой ВНУТРИ карточки, под контентом.
pointer-events:none — чтобы клик/hover доходили до самой карточки. */
.contact-card--shader {
overflow: hidden;
isolation: isolate;
}
.card-shader {
position: absolute;
inset: 0;
z-index: 0;
border-radius: inherit;
overflow: hidden;
pointer-events: none;
/* нейтральный фон-запас: если WebGL не отрисовал, карточка выглядит как
обычная neu-card (--neu-bg). Когда шейдер рисует — он перекрывает этот фон. */
background: var(--neu-bg);
}
/* ── neu-card + живой шейдер-слой под бликом ───────────────────────────────
Обычная неуморфная карточка (тени снаружи + блик) с анимированным шейдером
ВНУТРИ, под бликом. Слои (снизу вверх):
0 — .card-shader (canvas шейдера)
1 — ::before (блик --neu-glow) И ::after (внутренний объём inset-теней)
2 — контент карточки
Важно: box-shadow родителя рисуется НИЖЕ дочерних слоёв, поэтому шейдер (z:0)
перекрыл бы внутренние тени. Чтобы объём был виден ПОВЕРХ шейдера, внешние
тени (drop) оставляем на карточке, а внутренний объём (inset) выносим на
::after с z-index:1 — он рисуется поверх шейдера. */
.neu-card--shader {
background: transparent; /* фон уходит, шейдер снизу */
isolation: isolate;
/* только внешний объём (приподнятость) */
box-shadow: var(--neu-drop-1), var(--neu-drop-2), var(--neu-drop-3);
}
.neu-card--shader::before {
content: "";
position: absolute;
inset: 0;
z-index: 1; /* поверх шейдера (z:0) */
border-radius: inherit;
pointer-events: none;
background: var(--neu-glow); /* блик из левого верхнего угла */
}
.neu-card--shader::after {
content: "";
position: absolute;
inset: 0;
z-index: 1; /* поверх шейдера, рядом с бликом */
border-radius: inherit;
pointer-events: none;
/* внутренний объём (выпуклость): белая кайма сверху-слева + тёмная снизу-справа */
box-shadow:
var(--neu-in-light-1), var(--neu-in-light-2),
var(--neu-in-dark-1), var(--neu-in-dark-2);
}
.neu-card--shader > *:not(.card-shader) {
position: relative;
z-index: 2; /* контент над бликом/объёмом и шейдером */
}
.contact-card--shader .contact-card__icon,
.contact-card--shader .contact-card__body,
.contact-card--shader .contact-card__corner {
position: relative;
z-index: 1;
}
/* отдельная демо-карточка шейдера */
.shader-demo-card {
position: relative;
overflow: hidden;
isolation: isolate;
width: 100%;
max-width: 360px;
min-height: 220px;
border-radius: var(--radius-card);
background: var(--neu-bg);
box-shadow: var(--neu-shadow);
}
.shader-demo-card--wide {
max-width: 420px;
min-height: 260px;
}
.shader-demo-card__label {
position: absolute;
left: 1rem;
bottom: 0.85rem;
z-index: 1;
font-family: var(--font-accent);
font-size: 0.95rem;
font-weight: 600;
color: #fff;
text-shadow: 0 1px 6px rgba(0, 0, 0, 0.55);
pointer-events: none;
}