/* L Medical — generated by layouts/styles.css.liquid from styles/.
 * Do not edit: change the part, not the bundle. */
/* ═══ vendor/lenis ═══ */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis:not(.lenis-autoToggle).lenis-stopped {
  overflow: clip;
}

.lenis [data-lenis-prevent],
.lenis [data-lenis-prevent-wheel],
.lenis [data-lenis-prevent-touch],
.lenis [data-lenis-prevent-vertical],
.lenis [data-lenis-prevent-horizontal] {
  overscroll-behavior: contain;
}

.lenis.lenis-smooth iframe {
  pointer-events: none;
}

.lenis.lenis-autoToggle {
  transition-property: overflow;
  transition-duration: 1ms;
  transition-behavior: allow-discrete;
}

/* ═══ aside-card ═══ */
/* Карето с видео или снимка за фон, текст на дъното и бял градиент между тях.
 *
 * НЕСКОУПНАТО, на корена на styles/, защото го ползват две секции: обхватът от
 * типове кожа в `satisfaction` и физиката на въздействието в `results`. Стоеше
 * в results.css, вътре в `@scope (.tech-sec)` — оттам втората секция би го
 * получила без нито едно негово правило. Същият ход и същата причина като при
 * rf-card.css и spec-card.css.
 *
 * Само карето. Колко широко е и къде стои е на секцията, която го поставя. */
.tech-aside{position:sticky;top:var(--space-6);min-height:90vh;border-radius:var(--radius-lg);overflow:hidden;background:var(--white);display:flex;flex-direction:column;gap:var(--space-6);padding:var(--space-6)}
.tech-aside__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0;pointer-events:none}
.tech-aside::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background:linear-gradient(to top,rgba(255,255,255,.55),rgba(255,255,255,0) 45%)}
.tech-aside .tag--dark{align-self:flex-start;position:relative;z-index:1}
.tech-aside__body{margin-top:auto;position:relative;z-index:1;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-3)}
.tech-aside__body h3{font-size:var(--text-h3);margin:0}
.tech-aside__body p{margin:0;color:var(--ink);max-width:52ch}
/* `relative`, НЕ `static`. Целта на правилото е да спре лепенето, не карето да
   спре да е котва за абсолютните си деца — видеото и белия градиент, и двете
   `inset: 0`. Със `static` те се мерят спрямо най-близкия позициониран
   предшественик, а това е <main>, който е `relative` и висок колкото цялата
   страница: мерено, видеото ставаше 17 938px вместо 576.

   Бъгът се появяваше чак СЛЕД разкриването и затова беше труден за хващане:
   `scripts/page/interactions.js` слага `will-change: opacity, transform` за
   времето на прехода, а will-change с transform прави контейниращ блок точно
   както истинският transform. Махне ли се на transitionend, котвата изчезва.

   `top: auto` върви задължително с него: `top: var(--space-6)` горе важи за
   sticky-то, а `static` го пренебрегваше. `relative` обаче го ЧЕТЕ и избутваше
   карето 24px по-надолу — точно толкова по-далеч от картите над него,
   отколкото те са една от друга. */
@media (max-width:1024px){.tech-aside{position:relative;top:auto}}

/* ═══ base ═══ */
:root{
  /* --leading-body НЕ е тук. Стоеше, с 1.4, и не правеше нищо: бандълът се
     сглобява по азбучен ред (виж layouts/styles.css.liquid), tokens/ е
     последна, и typography.css го предекларира. Един токен, едно място —
     иначе смяната на този ред изглежда като че не е подействала. */
  /* The vertical rhythm between sections. Every section pads top and
     bottom with this, so a boundary is twice it — the design used
     --space-9 (96px) throughout, giving 208px with the heading's line box,
     which reads as too much air. One token so it stays uniform: change it
     here, not per section. */
  --section-pad:var(--space-8);

  /* Заглавието на страница е една роля, независимо дали стои в компактен
     хедър над решетка (Апарати) или само̀ на цял екран (Козметика). Дизайнът
     ги беше нарисувал с различен кегел; тук стойността е една, за да не могат
     да се разминат отново. Регистърът е изреченски — концепцията пише
     заглавията с главни букви, но това е стил на документа, не на страницата,
     и дизайнът също ги рендира изреченски. */
  --text-page-title:var(--text-h1);
  --leading-page-title:1.15;
  /* Мярката е в ch, за да се мери в знаци, а не в пиксели: щом кеглите се
     сменя на тесен екран, редът се пречупва на същата дължина в думи.
     Без нея заглавието се разтяга колкото е широк прозорецът — на 1440
     Апарати стоеше на един ред, а Козметика се пречупваше на два. */
  --measure-page-title:22ch;
  /* Въвеждащият абзац под заглавието. Стойностите са от .page-head p в
     proizvoditeli.html — най-новият хедър на секционна страница в дизайна, и
     единственият, който ползва същото име на класа. Без цвят: там абзацът е
     мастилен, а --text-secondary в devices.html е по-ранният вариант. */
  --measure-lede:60ch;
  --leading-lede:1.5}
@media (max-width:768px){:root{--text-page-title:var(--text-h2)}}
*{box-sizing:border-box}
body{margin:0;background:var(--white)}
/* The default for anchors nothing else styles. With the link colour now the
   same ink as body text, the underline is the only thing marking a link — so
   it stays, tinted to the accent so it reads as an affordance rather than a
   rule.

   :where() zeroes the specificity so any component rule wins in both states.
   A bare `a:hover` would be 0,1,1 and would start overriding the components
   that colour their own anchor at 0,1,0 — .pcs, .dl-row, .maker-link — none
   of which want a link hover on top of the hover they already have. */
:where(a){color:var(--link);text-decoration-color:var(--accent-500);text-underline-offset:2px}
:where(a:hover){color:var(--link-hover);text-decoration-color:currentColor}


/* Reveal on scroll (тихо, само opacity/transform) */
/* Reveal-on-scroll is an enhancement, never a gate on the content. The
   design hid .rv unconditionally, so with scripting off the page rendered
   blank — unacceptable when the HTML is the product. The hidden state now
   applies only once the document has announced that script is running. */
.rv{opacity:0;transform:translateY(16px);transition:opacity .7s cubic-bezier(0.15,0,0,1),transform .7s cubic-bezier(0.15,0,0,1)}
.rv.in{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){.rv{opacity:1;transform:none;transition:none}html{scroll-behavior:auto}}

/* Present to assistive technology, absent from layout. page.liquid emits an
   h1 with this class on pages whose first section carries no visible one, so
   the document outline still starts at h1. Without the rule the heading is a
   full-size 53px block that pushes the page down — on contacts it happened to
   be masked by the fixed .mapbg, which made it look like a spacing bug rather
   than a missing class. */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* Lifts page content above a fixed backdrop such as the contacts map.
   Harmless on pages that have none. */
main{position:relative;z-index:1}

/* ═══ components ═══ */
/* L Medical — design-system component styles.
 *
 * Extracted from the component JS, which upstream injects at upgrade time.
 * On a JS-built page that is fine; here it is not — the pages are server-
 * rendered, so JS-injected CSS means unstyled markup until the scripts run
 * (FOUC + layout shift). Shipped as a real stylesheet instead.
 *
 * The injection is REMOVED from scripts/components/*.js rather than left as a
 * harmless duplicate, and that is not tidiness. Three templates hand an
 * asset path to a CSS custom property — --icon-btn-src, --sf-type-src,
 * --sf-mark-src. A url() inside a custom property is resolved against the
 * stylesheet that SUBSTITUTES it, not against the document. While both
 * copies of a rule existed they had different base URLs — this bundle at
 * {lang}/styles/, the injected <style> at the document — so no single path
 * could satisfy both, and which one won was a race the page usually lost on
 * the language-root pages. Without JS only this copy exists, so /bg/ and
 * /en/ rendered the footer wordmark and social icons as blanks.
 *
 * One consumer, one base: the paths come from data.cssAsset / data.cssRoot,
 * which are relative to THIS file (a constant '../'), not to the page.
 * If a component ever needs to inject CSS again, that breaks — read
 * layouts/lib/context.js before doing it.
 *
 * Generated from the rendered design page — do not hand-edit. Re-port by
 * re-running the DOM capture against lmed-design.
 */
/* ── tags ─────────────────────────────────────────────── */
.tags-stack{display:flex;flex-direction:column;gap:var(--space-2)}.tags{display:flex;flex-wrap:nowrap;overflow:hidden;gap:var(--space-2)}.tag{background:rgba(211,229,229,.5);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--ink);border-radius:var(--radius-pill);padding:var(--space-1) var(--space-3);font-family:var(--font-body);font-size:0.75rem;white-space:nowrap;flex-shrink:0}.tag--dark{background:var(--ink);color:var(--white);-webkit-backdrop-filter:none;backdrop-filter:none}lmed-tag,lmed-tag-dark{display:contents}

/* ── icon-tag ─────────────────────────────────────────── */
icon-tag{display:inline-flex;max-width:100%}.tag--icon{display:inline-flex;align-items:center;gap:var(--space-2);padding-left:2px}.tag__ico{flex:0 0 auto;width:1.75em;height:1.75em;margin-block:-0.18em;border-radius:50%;overflow:hidden;background:var(--white);display:flex;align-items:center;justify-content:center}.tag__ico img{display:block;width:100%;height:100%;object-fit:cover}.tag__ico--glyph img{width:60%;height:60%;object-fit:contain}

/* ── regular-btn ──────────────────────────────────────── */
regular-btn{display:inline-flex;max-width:100%}.regular-btn{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-4);font-family:var(--font-body);font-weight:var(--weight-body-semibold);font-size:1rem;line-height:1;color:var(--ink);text-decoration:none;cursor:pointer;background:rgba(211,229,229,.45);border:1px solid var(--accent-200);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-radius:var(--radius-pill);transition:background var(--duration-base) var(--ease-standard),color var(--duration-base) var(--ease-standard),border-color var(--duration-base) var(--ease-standard)}.regular-btn img{width:1rem;height:1rem;display:block;transition:transform var(--duration-base) var(--ease-standard),filter var(--duration-base) var(--ease-standard)}.regular-btn:hover{background:var(--ink);border-color:var(--ink);color:var(--white)}.regular-btn:hover img{filter:brightness(0) invert(1);transform:translateY(2px)}

/* ── check-pill ───────────────────────────────────────── */
/* The same anatomy as .lmed-btn--primary — 16px between mark and label, badge
   1rem+16px — with the two colours the other way round: an accent body with an
   INK circle and an ink label, inverted on request from the button's ink body
   and accent circle.

   Тялото е СТЪКЛО: акцентът на 65% с размиване отзад. Беше плътен акцент —
   `var(--accent-200)` без прозрачност, — защото преди това стоеше на 45% и
   върху снимка ставаше нечетимо. 65% с `blur(4px)` е средата между двете:
   достатъчно плътно, за да носи текста, и достатъчно прозрачно, за да личи, че
   лежи върху нещо. Размиването е това, което го прави четимо там, където
   плътността сама не стига — то маха детайла отзад, а не светлината.

   Цената е един композитен слой на хапче; затова се плаща веднъж, тук, а не по
   секции. Таблицата за сравнение си държи своето в sections/compare.css, където
   цветът носи значение (бледо „да" срещу розово „не").

   Рамката остава светлият акцент, а не ink заедно с тялото — .lmed-btn няма
   такава, но бутонът стои на страница, а тези стоят върху снимка, където
   светлият ръб е това, което ги отделя от нея. */
check-pill{display:flex;align-items:center;gap:var(--space-4);background:rgba(211,229,229,.65);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border:none;border-radius:var(--radius-pill);padding:var(--space-2) var(--space-4) var(--space-2) var(--space-2);font-family:var(--font-body);font-weight:var(--weight-body-semibold);color:var(--ink);line-height:1.25;width:fit-content;max-width:34ch}check-pill .check-pill__mark{width:calc(1rem + 16px);height:calc(1rem + 16px);border-radius:50%;background:var(--ink);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:var(--white);font-size:.9rem}

/* ── icon-btn ─────────────────────────────────────────── */
icon-btn{display:inline-flex;flex-shrink:0}icon-btn .icon-btn__el{display:inline-flex;align-items:center;justify-content:center;padding:var(--space-3);border-radius:50%;border:1px solid var(--accent-200);background:rgba(211,229,229,.45);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);color:var(--ink);cursor:pointer;text-decoration:none;transition:background var(--duration-base) var(--ease-standard),border-color var(--duration-base) var(--ease-standard),color var(--duration-base) var(--ease-standard)}icon-btn .icon-btn__icon{width:1rem;height:1rem;display:block;background:currentColor;-webkit-mask:var(--icon-btn-src) no-repeat center/contain;mask:var(--icon-btn-src) no-repeat center/contain;transition:transform var(--duration-base) var(--ease-standard)}icon-btn:hover .icon-btn__el,icon-btn.is-hover .icon-btn__el{background:var(--ink);border-color:var(--ink);color:var(--white)}icon-btn[data-state="open"] .icon-btn__icon{transform:rotate(180deg)}

/* ── case-card ────────────────────────────────────────── */
case-card{display:flex;flex-direction:column;gap:var(--space-4);background:var(--white);border:1px solid var(--ink);border-radius:var(--radius-lg);padding:var(--space-3)}case-card .cc-pair{display:grid;grid-template-columns:1fr 1fr;border-radius:var(--radius-md);overflow:hidden}case-card .cc-half{position:relative;aspect-ratio:4/5;overflow:hidden}case-card .cc-half image-slot,case-card .cc-half img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}case-card .cc-half .tag{position:absolute;left:var(--space-2);bottom:var(--space-2);z-index:2}case-card .cc-specs{margin:0;padding:0 var(--space-2);display:flex;flex-direction:column;gap:var(--space-2);font-size:0.85rem}case-card .cc-specs > div{display:flex;align-items:baseline;gap:var(--space-1)}case-card .cc-specs dt{margin:0;color:var(--text-primary);white-space:nowrap;flex:0 0 auto}case-card .cc-specs > div::after{content:"";flex:1;min-width:var(--space-4);margin:0 2px 4px;border-bottom:1px dotted var(--border-strong);order:1}case-card .cc-specs dd{margin:0;color:var(--text-primary);white-space:nowrap;order:2}case-card .cc-tags{display:flex;flex-wrap:wrap;gap:var(--space-2);padding:0 var(--space-2) var(--space-2)}

/* ── product-cards ────────────────────────────────────── */
product-card-compact,product-card-wide{display:block;height:100%}product-card-compact{grid-column:span 1}product-card-wide{grid-column:span 2}.card{position:relative;border-radius:var(--radius-lg);overflow:hidden;border:1px solid var(--ink);height:100%;color:var(--text-primary);text-decoration:none}.card.wide{border:none}a.card{display:block}a.card:hover{color:var(--text-primary)}.card.compact{display:flex;flex-direction:column;background:var(--white)}.card.compact .media{position:relative;flex:1;min-height:0}.card.compact .photo{position:absolute;inset:0;background:var(--white);padding:var(--space-4);display:flex;align-items:center;justify-content:center}.card.compact .photo img{height:98%;display:block;transition:height .5s cubic-bezier(.14,0,0,1)}.card.compact:hover .photo img{height:100%}.card.compact .media .tags-stack{position:absolute;top:var(--space-4);left:var(--space-4);right:var(--space-4);padding:0;z-index:2}.card.compact .media h4{position:absolute;left:var(--space-4);bottom:var(--space-3);margin:0;z-index:2}.card .pc-badge{position:absolute;top:var(--space-4);left:var(--space-4);z-index:2;background:var(--white);border-radius:var(--radius-pill);padding:2px var(--space-3);font-size:.75rem;font-weight:var(--weight-body-semibold)}.card h4{font-size:var(--text-h5);margin:var(--space-2) 0 var(--space-1)}.card.compact .body{display:flex;align-items:end;gap:var(--space-1);padding:0 var(--space-4) var(--space-4)}.card .pc-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1)}.card .pc-meta{font-weight:var(--weight-body-semibold);font-size:.9rem}.card p.desc{font-size:1rem;color:var(--ink);margin:0;max-width:90%}.card.compact .desc{max-width:none}.card.compact .tag--cat{background:var(--ink);color:var(--white);-webkit-backdrop-filter:none;backdrop-filter:none}.card .plus-btn{display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0}.card .plus-btn img{height:12px;transition:transform .5s cubic-bezier(.14,0,0,1)}.card.compact:hover .plus-btn img{transform:rotate(180deg)}.card.wide .card__photo{position:absolute;inset:0;width:100%;height:100%;z-index:0;object-fit:contain;object-position:92% 95%;transition:transform .5s cubic-bezier(.14,0,0,1)}.card.wide:hover .card__photo{transform:scale(1.04)}.card.wide.scene .card__photo{object-fit:cover;object-position:center}.card.wide .tags-stack{position:absolute;top:var(--space-4);left:var(--space-4);right:var(--space-4);padding:0;z-index:2}.card.wide .panel{position:absolute;z-index:1;left:var(--space-4);bottom:var(--space-4);width:calc(50% - var(--space-4));background:rgba(255,255,255,.45);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);border-radius:var(--radius-md);padding:var(--space-4)}.card.wide .panel h4{margin:0 0 var(--space-1)}.card.wide .panel p.desc{max-width:100%}.card.wide .panel .lmed-btn{margin-top:var(--space-3)}@media(max-width:768px){.card.compact{min-height:440px}.card.wide{min-height:560px}.card.wide .panel{width:auto;right:var(--space-4)}}

/* ── tabs ─────────────────────────────────────────────── */
/* lmed-tabs — badges, clear-all and toggle came with the aparati-v2 tab bar.
 * The masks resolve against the BUNDLE, not the page: a url() in a stylesheet
 * always does, which is why the path is ../media/… and not rooted. */
lmed-tabs{display:inline-flex;position:relative;align-items:stretch;border:1px solid var(--ink);border-radius:var(--radius-pill);background:var(--white);width:max-content;flex:0 0 auto}
/* Докато барът се влачи с мишката: курсорът казва какво става, а изборът на
   текст би се проточил след показалеца вместо лентата да се мести. Класът
   го слага scripts/components/tabs.js за времето на влаченето. */
lmed-tabs[data-dragging]{cursor:grabbing;user-select:none}lmed-tabs .lmed-tabs__pill{position:absolute;top:0;left:0;height:100%;background:var(--ink);border-radius:var(--radius-pill);pointer-events:none;opacity:0;transition:transform var(--duration-slow,.4s) var(--ease-emphasized,cubic-bezier(.2,.8,.2,1)),width var(--duration-slow,.4s) var(--ease-emphasized,cubic-bezier(.2,.8,.2,1)),opacity var(--duration-base) var(--ease-standard)}lmed-tabs button{position:relative;z-index:1;appearance:none;border:0;background:none;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center;padding:var(--space-3) var(--space-5);border-radius:var(--radius-pill);font-family:var(--font-body);font-weight:var(--weight-heading,600);line-height:1.2;color:var(--text-secondary);white-space:nowrap;transition:color var(--duration-base) var(--ease-standard)}lmed-tabs button small{font-weight:400;font-size:.8rem;color:inherit;opacity:.85}lmed-tabs button:hover{color:var(--ink)}lmed-tabs button[aria-selected="true"]{color:var(--white)}lmed-tabs button:focus-visible{outline:2px solid var(--accent-700);outline-offset:2px}lmed-tabs .lmed-tabs__row{display:flex;align-items:center;gap:var(--space-2)}lmed-tabs .lmed-tabs__label{display:flex;flex-direction:column;align-items:center;gap:2px}lmed-tabs .lmed-tabs__badge{position:relative;appearance:none;border:0;padding:0;cursor:pointer;flex:0 0 20px;width:20px;height:20px;border-radius:50%;display:none;background:var(--ink);color:var(--white);transition:background var(--duration-base) var(--ease-standard),color var(--duration-base) var(--ease-standard)}lmed-tabs button[data-badge] .lmed-tabs__badge{display:block}lmed-tabs button[aria-selected="true"] .lmed-tabs__badge{background:var(--white);color:var(--ink)}lmed-tabs .lmed-tabs__num,lmed-tabs .lmed-tabs__x{position:absolute;inset:0;display:grid;place-items:center;transition:opacity var(--duration-base) var(--ease-standard)}lmed-tabs .lmed-tabs__num{font-family:var(--font-body);font-size:.7rem;font-weight:var(--weight-body-semibold,600);line-height:1}lmed-tabs .lmed-tabs__x{opacity:0}lmed-tabs .lmed-tabs__x::before{content:"";width:10px;height:10px;background:currentColor;transform:rotate(45deg);-webkit-mask-image:url(../media/raw/icons/plus.svg);mask-image:url(../media/raw/icons/plus.svg);mask-repeat:no-repeat;mask-position:center;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;-webkit-mask-size:100% 100%}lmed-tabs .lmed-tabs__badge:hover .lmed-tabs__num{opacity:0}lmed-tabs .lmed-tabs__badge:hover .lmed-tabs__x{opacity:1}lmed-tabs .lmed-tabs__badge:focus-visible{outline:2px solid var(--accent-700);outline-offset:2px}lmed-tabs .lmed-tabs__clear{flex:0 0 28px;width:28px;height:28px;border-radius:50%;border:0;padding:0;margin:auto var(--space-3) auto 0;cursor:pointer;position:relative;z-index:1;background:var(--accent-200);color:var(--ink);display:none;place-items:center;opacity:0;transform:scale(.6);transition:opacity var(--duration-base) var(--ease-standard),transform var(--duration-base) var(--ease-standard),background var(--duration-base) var(--ease-standard)}lmed-tabs[data-clear-all] .lmed-tabs__clear{display:grid;opacity:1;transform:none}lmed-tabs .lmed-tabs__clear:hover{background:var(--ink);color:var(--white)}lmed-tabs .lmed-tabs__clear::before{content:"";width:12px;height:12px;background:currentColor;transform:rotate(45deg);-webkit-mask-image:url(../media/raw/icons/plus.svg);mask-image:url(../media/raw/icons/plus.svg);mask-repeat:no-repeat;mask-position:center;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;-webkit-mask-size:100% 100%}@media(prefers-reduced-motion:reduce){lmed-tabs .lmed-tabs__pill,lmed-tabs .lmed-tabs__clear{transition:none}.card.wide .card__photo{transition:none}.card.wide:hover .card__photo{transform:none}}

/* The wide card's photo is an <img>, and it zooms by transform.
 *
 * It used to be a CSS background, which forced the zoom to animate
 * `background-size` — and that cannot interpolate from the `cover` keyword, so
 * it jumped. No fixed length works at both shapes either: the same square photo
 * is width-constrained in the 955x699 desktop card and height-constrained in
 * the 365x560 phone one.
 *
 * object-fit settles that, and a real element can be scaled. Two fits, because
 * the two kinds of picture want opposite things: a scene photo COVERS the card,
 * a product cut-out on white is CONTAINED and sits against the right edge.
 * .card is overflow:hidden, so the scaled edge is clipped.
 */

/* lmed-checkbox — the square multi-select used in the filter panels.
 * Ported from the design, which injected it; here it belongs to the bundle.
 * The tick mask resolves against the BUNDLE, hence ../media/… */
lmed-checkbox .lmed-choice__el,lmed-radio-btn .lmed-choice__el{display:flex;align-items:center;gap:var(--space-2);cursor:pointer}
lmed-checkbox .lmed-choice__input,lmed-radio-btn .lmed-choice__input{position:absolute;opacity:0;width:0;height:0}
lmed-checkbox .lmed-choice__box,lmed-radio-btn .lmed-choice__box{flex:0 0 28px;width:28px;height:28px;border:1px solid var(--ink);background:transparent;box-sizing:border-box;border-radius:12px;display:grid;place-items:center;color:transparent;transition:background var(--duration-base) var(--ease-standard),color var(--duration-base) var(--ease-standard),border-color var(--duration-base) var(--ease-standard)}
lmed-checkbox .lmed-choice__box::after,lmed-radio-btn .lmed-choice__box::after{content:'';width:1rem;height:1rem;background:currentColor;-webkit-mask-image:url(../media/raw/icons/check.svg);mask-image:url(../media/raw/icons/check.svg);mask-repeat:no-repeat;mask-position:center;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-position:center;-webkit-mask-size:100% 100%}
lmed-checkbox .lmed-choice__el:hover .lmed-choice__box,lmed-radio-btn .lmed-choice__el:hover .lmed-choice__box{color:var(--grey-400)}
lmed-checkbox .lmed-choice__input:checked + .lmed-choice__box,lmed-radio-btn .lmed-choice__input:checked + .lmed-choice__box{background:var(--ink);border-color:var(--ink);color:var(--white)}
lmed-checkbox .lmed-choice__input:focus-visible + .lmed-choice__box,lmed-radio-btn .lmed-choice__input:focus-visible + .lmed-choice__box{outline:2px solid var(--ink);outline-offset:2px}
lmed-checkbox .lmed-choice__txt,lmed-radio-btn .lmed-choice__txt{font-weight:var(--weight-body-semibold);color:var(--ink)}
lmed-checkbox[disabled],lmed-radio-btn[disabled]{opacity:.5;pointer-events:none}
@media (prefers-reduced-motion: reduce){lmed-checkbox .lmed-choice__box,lmed-radio-btn .lmed-choice__box{transition:none}}

/* ── attachment-serie ─────────────────────────────────── */
attachment-serie{display:flex;align-items:stretch;flex-shrink:0;height:var(--serie-h,560px)}.serie-lead__photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;z-index:0}/* И `.tag--dark` изрично, освен децата. `lmed-tag-dark` е `display: contents`,
   тоест кутия няма: правилото за `> :not(…)` вдига обвивка, която не
   съществува, а спанът вътре остава `position: static; z-index: auto` и се
   рисува ПОД снимката, която е абсолютна с z-index: 0. Тагът беше в HTML-а, с
   размер 131×23, и не се виждаше. */
.serie-lead > :not(.serie-lead__photo),
.serie-lead .tag--dark{position:relative;z-index:1}.serie-lead{position:relative;width:var(--serie-lead-w,560px);flex-shrink:0;overflow:hidden;border:1px solid var(--ink);border-radius:var(--radius-lg) 0 0 var(--radius-lg);display:flex;flex-direction:column;justify-content:flex-start;gap:var(--space-3);padding:var(--space-6);color:var(--ink)}.serie-lead .tag--dark{align-self:flex-start}.serie-lead h4{font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h3);margin:0;line-height:1.05}.serie-lead > p{margin:0;font-size:1rem}.serie-checks{display:flex;flex-direction:column;gap:var(--space-2);margin-top:var(--space-2)}.serie-panel{display:flex;flex-shrink:0;background:var(--white);border:1px solid var(--ink);border-left:0;border-radius:0 var(--radius-lg) var(--radius-lg) 0;overflow:hidden}.serie-item{display:flex;flex-direction:column;gap:var(--space-1);width:var(--serie-item-w,300px);flex-shrink:0;padding:var(--space-5);border-left:1px solid var(--ink)}.serie-item:first-child{border-left:0}.serie-item__photo{position:relative;flex:1;min-height:0;margin:var(--space-2) 0}.serie-item__photo image-slot{position:absolute;inset:0}.serie-item h5{font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h5);margin:0}.serie-item > p{margin:0;line-height:1.4}@media(max-width:1023px){.serie-lead{padding:var(--space-5);gap:var(--space-2);scroll-snap-align:start;overflow-y:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none}.serie-lead::-webkit-scrollbar{display:none}.serie-lead h4{font-size:var(--text-h4)}.serie-lead > p{font-size:0.95rem}.serie-checks{margin-top:var(--space-1)}.serie-item{padding:var(--space-4);scroll-snap-align:start}.serie-item h5{font-size:var(--text-h6)}.serie-item > p{font-size:0.9rem}.serie-item .tags{flex-wrap:wrap;overflow:visible}.serie-item .tags > *{flex-shrink:0}.serie-item .tag{font-size:0.75rem}}

/* ── attachment-serie-card ────────────────────────────── */
attachment-serie-card{display:grid;grid-template-columns:2fr 1fr;position:relative;overflow:hidden;height:var(--card-h,560px);border-radius:var(--radius-lg);color:var(--ink);background-image:var(--asc-bg);background-size:cover;background-position:center;background-repeat:no-repeat}.asc-lead{position:relative;z-index:1;display:flex;flex-direction:column;justify-content:flex-start;gap:var(--space-3);padding:var(--space-7)}.asc-lead > *{position:relative}.asc-lead .tag--dark{align-self:flex-start}.asc-lead h4{font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h3);margin:0;line-height:1.05}.asc-lead > p{margin:0;font-size:1rem}.asc-checks{display:flex;flex-direction:column;gap:var(--space-2);margin-top:var(--space-2)}.asc-deck{position:relative;z-index:2}.asc-card{position:absolute;inset:var(--space-6);display:flex;flex-direction:column;padding:var(--space-4);border-radius:var(--radius-md);background:rgba(255,255,255,.55);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border:1px solid rgba(255,255,255,.65);box-shadow:var(--shadow-md);transform-origin:center center;opacity:var(--op,1);transform:translateX(var(--tx,0)) scale(var(--sc,1));transition:transform var(--duration-base) var(--ease-standard),opacity var(--duration-base) var(--ease-standard)}.asc-card__tags{display:flex;flex-wrap:wrap;gap:var(--space-2);flex-shrink:0}.asc-card__photo{position:relative;flex:1;min-height:0;margin:var(--space-2) 0}.asc-card__photo image-slot{position:absolute;inset:0}.asc-card__photo image-slot::part(frame){background:transparent}.asc-card h5{font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h5);margin:0;flex-shrink:0}.asc-card > p{margin:0;line-height:1.4;flex-shrink:0}.asc-card--front{cursor:pointer}.asc-card--front:focus-visible{outline:2px solid var(--accent-700);outline-offset:3px}.asc-card--front:hover{transform:translateX(calc(var(--tx,0) - 8px)) scale(var(--sc,1))}.asc-card--exiting{transform:translateX(-48px) scale(1)!important;opacity:0!important}@media(prefers-reduced-motion:reduce){.asc-card{transition:none}.asc-card--front:hover{transform:translateX(var(--tx,0)) scale(var(--sc,1))}}@media(max-width:1023px){attachment-serie-card{display:flex;grid-template-columns:none;height:auto;overflow-x:auto;scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;gap:var(--space-4);background-image:none;padding-bottom:var(--space-2)}.asc-lead{flex:0 0 86%;scroll-snap-align:start;min-height:440px;overflow:hidden;border-radius:var(--radius-lg);background-image:var(--asc-bg);background-size:cover;background-position:center;padding:var(--space-6)}.asc-deck{display:contents}.asc-card{position:static;inset:auto;flex:0 0 78%;scroll-snap-align:start;min-height:440px;transform:none!important;opacity:1!important;transition:none;pointer-events:auto!important}}

/* ── zone-card ────────────────────────────────────────── */
zone-card{display:block;position:relative;border-radius:var(--radius-lg);overflow:visible;min-height:min(64vh,560px);isolation:isolate;color:var(--ink)}.zone-card__bg{position:absolute;inset:0;border-radius:var(--radius-lg);overflow:hidden;z-index:0}.zone-card__bg image-slot,.zone-card__bg img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.zone-card__title{position:relative;z-index:2;margin:0;padding:var(--space-6);font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h4)}.zone-pills{position:absolute;bottom:var(--space-6);left:var(--space-6);right:var(--space-6);z-index:3;display:flex;flex-direction:column;gap:var(--space-3)}.zone-pill{will-change:transform;width:fit-content;max-width:100%}/* На телефон картата е лента със снимка, заглавие ВЪРХУ нея и хапчета отдолу.
   Лентата беше 77px — колкото един ред заглавие, каквито са зоните на HERA
   („Лице", „Тяло", „Коса"). Заглавие на два реда излиза изпод нея върху
   бялото: мерено на 360px, „Лимфен дренаж и целулит" прави кутия от 125px
   срещу лента от 77.

   Сега снимката следва заглавието, а не обратното: двете седят в една и съща
   клетка на решетка, снимката спира да е абсолютна и клетката се мери по
   заглавието. Замисълът е непроменен — надпис върху снимка, — но лентата е
   висока точно колкото надписа, на един ред или на три.

   В компонента, а не в стилницата на секцията: сложено там, то биеше този
   ред навсякъде и `check:scopes` докладваше правило, което вече не може да
   спечели никъде.

   `relative`, НЕ `static`. Снимката вътре е `position:absolute; inset:0` и се
   мери спрямо най-близкия ПОЗИЦИОНИРАН предшественик. Със `static` каретата
   спира да е такъв, следващият е самата карта, и снимката се разпъва зад
   хапчетата вместо да остане в лентата. Мерено: на HERA фонът избиваше под
   всичките четири хапчета. */
@media(max-width:768px){zone-card{min-height:0;border:1px solid var(--ink);display:grid;grid-template-rows:auto auto}.zone-card__bg{position:relative;height:auto;grid-area:1 / 1}.zone-card__title{grid-area:1 / 1;padding:var(--space-6) var(--space-6) var(--space-8)}.zone-pills{position:static;left:auto;right:auto;bottom:auto;grid-area:2 / 1;padding:0 var(--space-4) var(--space-5)}.zone-pill{transform:none!important}}

/* ── product-card-small ───────────────────────────────── */
product-card-small{display:block;width:100%;max-width:420px;min-height:170px}.pcs{position:relative;display:block;height:100%;min-height:inherit;background:rgba(211,229,229,.65);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border-radius:var(--radius-md);padding:var(--space-4);color:var(--ink);text-decoration:none}.pcs:focus-visible{outline:2px solid var(--ink);outline-offset:3px}.pcs__text{position:relative;z-index:1;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-1);height:100%}.pcs__name{margin:0;font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h5)}.pcs__desc{margin:0;max-width:70%;color:var(--ink)}.pcs__meta{margin-top:auto;font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h6);color:var(--ink)}.pcs__img{position:absolute;right:0;top:0;z-index:0;height:100%;width:auto;pointer-events:none}@media(max-width:768px){.pcs__desc{max-width:60%}}

/* ── site-footer ──────────────────────────────────────── */
site-footer{display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-9) var(--page-pad,48px) var(--space-6)}.sf-brand{position:relative}.sf-type{width:100%;aspect-ratio:543.9/110.5;background:var(--accent-200);-webkit-mask:var(--sf-type-src) no-repeat center / 100% 100%;mask:var(--sf-type-src) no-repeat center / 100% 100%}.sf-social{position:absolute;right:var(--space-4);bottom:var(--space-4);display:flex;gap:var(--space-2)}.sf-social .icon-btn__el{background:rgba(255,255,255,.45)}.sf-social icon-btn:hover .icon-btn__el{background:var(--ink)}.sf-bottom{display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-6);flex-wrap:wrap}.sf-copy{display:flex;align-items:center;gap:var(--space-3)}.sf-mark{width:40px;height:40px;flex:0 0 auto;background:var(--ink);-webkit-mask:var(--sf-mark-src) no-repeat center / contain;mask:var(--sf-mark-src) no-repeat center / contain}.sf-copy p{margin:0;font-size:0.8rem;line-height:1.35;color:var(--text-secondary)}.sf-sitemap{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-6)}.sf-sitemap a{color:var(--text-primary);text-decoration:none;font-weight:var(--weight-body-semibold)}.sf-sitemap a:hover{color:var(--accent-600,var(--text-primary));text-decoration:underline}@media(max-width:768px){site-footer{gap:var(--space-5)}.sf-social{position:static;justify-content:flex-end;margin-top:-20px}.sf-bottom{flex-direction:column-reverse;align-items:flex-start;gap:var(--space-5)}.sf-sitemap{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2) var(--space-5);width:100%}}

/* ── site-nav ─────────────────────────────────────────── */
site-nav{display:contents}

/* ── contact-card ─────────────────────────────────── */
contact-card{position:relative;display:block;border:1px solid var(--ink);border-radius:var(--radius-md);padding:var(--space-4)}contact-card::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:rgba(255,255,255,.45);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.cc-tag{display:flex;margin-bottom:var(--space-3)}.cc-row{display:flex;align-items:center;gap:var(--space-4)}.cc-main{flex:1 1 auto;min-width:0}.cc-name{margin:0 0 var(--space-1);font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h5);line-height:1.2}.cc-line{font-size:1rem;line-height:1.5;color:var(--text-primary);word-break:break-word}.cc-actions{display:flex;gap:var(--space-2);flex:0 0 auto}.cc-ph{color:var(--grey-500)}.cc-off{opacity:.35;pointer-events:none}

/* ── address-card ─────────────────────────────────── */
address-card{position:relative;display:block;overflow:hidden;border:1px solid var(--ink);border-radius:var(--radius-md);padding:var(--space-4);aspect-ratio:408/264}address-card::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;background:rgba(255,255,255,.45);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.ac-map{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center}.ac-tag{position:relative;z-index:2;display:flex}.ac-pin{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);height:22px;width:auto;display:block;z-index:2}.ac-foot{position:absolute;z-index:2;left:var(--space-4);right:var(--space-4);bottom:var(--space-4);display:flex;align-items:flex-end;justify-content:space-between;gap:var(--space-4)}.ac-addr{margin:0;font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h6);line-height:1.25;max-width:20ch}.ac-ph{color:var(--grey-600)}.ac-off{opacity:.35;pointer-events:none}@media(max-width:768px){address-card{aspect-ratio:320/230}}

/* ── manufacturer-band ──────────────────────────────────
   Пренесен от дизайн системата. Компонентът само пренарежда децата си, така
   че тук идва готовият DOM от сървъра и js/components/ не получава файл.
   Зоната .mb__devices от оригинала не се пренася — засега никоя страница не
   слага апарати под лентата. */
manufacturer-band{display:block;scroll-margin-top:calc(84px + var(--space-5))}
manufacturer-band .mb__top{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-5);border:1px solid var(--ink);border-radius:var(--radius-lg);background:var(--white);padding:var(--space-5)}
manufacturer-band .mb__body{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-4);padding:var(--space-4)}
manufacturer-band .mb__body h2{margin:0;font-size:var(--text-h3);line-height:1.15}
manufacturer-band .mb__body p{margin:0;line-height:1.5;color:var(--ink);max-width:48ch}
manufacturer-band .mb-stats{display:flex;flex-wrap:wrap;gap:var(--space-7);margin-top:auto}
manufacturer-band .mb-stat{display:flex;flex-direction:column;gap:var(--space-1)}
manufacturer-band .mb-num{font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h4);line-height:1}
manufacturer-band .mb-label{font-size:1rem;line-height:1.2;color:var(--text-secondary)}
manufacturer-band .mb__media{position:relative;min-height:420px;border-radius:var(--radius-lg);overflow:hidden}
manufacturer-band .mb__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
@media (max-width:1024px){
manufacturer-band .mb__top{grid-template-columns:1fr;padding:var(--space-4)}
manufacturer-band .mb__media{min-height:280px;order:-1}
manufacturer-band .mb__body{padding:var(--space-3)}}
@media (max-width:768px){
manufacturer-band .mb-stats{gap:var(--space-6)}}

/* ── ленти, влачени с мишка ─────────────────────────────────────────────
   Класът се слага от scripts/page/interactions.js, само докато жестът
   тече, и е един за трите ленти (.at-strip, .related-strip, .series-strip),
   защото поведението е едно. При тъч не се стига дотук.

   Курсорът е само за времето на влаченето: в покой картите са линкове и
   показалецът трябва да си остане показалец. */
.is-dragging{cursor:grabbing;user-select:none;-webkit-user-select:none}
.is-dragging a,.is-dragging img{-webkit-user-drag:none}

/* ── cosmetics-lead ───────────────────────────────────── */
/* Картата-лийд на марка. Некскоупната, защото я ползват ДВЕ секции —
 * cosmetics-brand и cosmetics-invite — а @scope стига само надолу от един
 * корен. Тук е самата карта; къде се закача и колко е висока е решение на
 * секцията, която я показва.
 *
 * От стария експорт (components/cosmetics-lead.js), който инжектираше тези
 * правила от JS. Сега пътуват в бъндъла като всичко останало. */
.cos-lead{position:relative;display:block;border-radius:var(--radius-lg);background:var(--white);padding:var(--space-5);overflow:hidden;scroll-margin-top:calc(84px + var(--space-5))}
/* object-position `center 100%` е точният аналог на background-position, с
   което компонентът лепеше снимката: кадърът стъпва на ДОЛНИЯ ръб. */
.cos-lead__bg{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:cover;object-position:center 100%}
.cos-lead__badge{position:absolute;top:var(--space-5);right:var(--space-5);z-index:2}
.cos-lead__body{position:relative;z-index:1;height:100%;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-4)}
@media(min-width:1024px){.cos-lead__body{width:50%}}
.cos-lead__body h2{margin:0;font-size:var(--text-h2);line-height:1.15}
/* Отрицателният марж изяжда gap-а на колоната: надписът е подзаглавие и стои
   плътно под h2, а не на разстоянието между два отделни блока. */
.cos-lead__mark{font-family:var(--font-body);font-weight:var(--weight-body-semibold);font-size:1rem;color:var(--ink);margin-top:calc(var(--space-2) - var(--space-4))}
.cos-lead__copy{margin:0;line-height:1.3;color:var(--ink);max-width:30rem}
.cos-lead__creds{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-4)}
.cos-lead .lmed-btn{margin-top:var(--space-5);align-self:flex-start}
@media(max-width:1024px){.cos-lead{padding:var(--space-4)}.cos-lead__body{gap:var(--space-2)}.cos-lead__badge{top:auto;bottom:var(--space-4);right:var(--space-4)}}
/* На телефон колоната е през цялата ширина, така че кадърът се мести вдясно —
   иначе текстът ляга точно върху продуктите в средата му. */
@media(max-width:768px){.cos-lead__bg{object-position:76% 100%}}

/* ── link-tag ─────────────────────────────────────────── */
/* Стъклен pill-линк към апарат: снимката стъпва на долния ръб, после етикетът.
 * 44px висок — колкото check-pill, за да стоят на един ред. */
link-tag{display:inline-flex;width:fit-content}
link-tag a{display:inline-flex;align-items:center;width:fit-content;height:44px;padding:0 var(--space-4);gap:var(--space-4);overflow:hidden;background:rgba(211,229,229,.45);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border:1px solid var(--accent-200);border-radius:var(--radius-pill);text-decoration:none;color:var(--ink);font-family:var(--font-body);font-weight:var(--weight-body-semibold);font-size:var(--text-h6);line-height:1.25;transition:background var(--duration-base) var(--ease-standard)}
link-tag a:hover{background:rgba(211,229,229,1)}
link-tag a:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
link-tag .link-tag__img{height:100%;width:auto;flex:0 0 auto;object-fit:contain;object-position:bottom;display:block}

/* ── lmed-radio-btn ───────────────────────────────────── */
/* Един избор от няколко. Анатомията е на lmed-checkbox и селекторите по-горе я
 * поемат и за него — разликата е ЕДНА: кръг вместо заоблен квадрат. Второ копие
 * на деветте правила беше второ място, което да остане старо. */
lmed-radio-btn .lmed-choice__box{border-radius:50%}

/* ── lmed-input ───────────────────────────────────────── */
/* Текстово поле с ляв етикет, който се вдига, когато полето получи фокус или
 * съдържание, и двуслойно подчертаване — мастилена линия при фокус, червена при
 * грешка. От стария експорт (components/lmed-input.js), който инжектираше тези
 * правила от JS; тук пътуват в бъндъла като всичко останало. */
lmed-input{--input-label-w:7.75rem;--input-lift:16px;display:grid;grid-template-columns:var(--input-label-w) 1fr;align-items:end;column-gap:0;font-family:var(--font-body)}
lmed-input .lmed-input__label{position:relative;align-self:end;transform-origin:left bottom;font-size:var(--text-small);color:var(--grey-700);line-height:1.2;cursor:pointer;padding-right:var(--space-2);transform:translateY(0);transition:font-size var(--duration-base) var(--ease-standard),color var(--duration-base) var(--ease-standard),transform var(--duration-base) var(--ease-standard)}
lmed-input.is-focus .lmed-input__label,lmed-input.is-filled .lmed-input__label,lmed-input.is-invalid .lmed-input__label{font-size:var(--text-p);color:var(--ink);transform:translateY(calc(-1 * var(--input-lift)))}
lmed-input.is-invalid .lmed-input__label{color:var(--error-500)}
lmed-input .lmed-input__field{position:relative;padding-bottom:var(--space-3)}
lmed-input .lmed-input__control{display:block;width:100%;border:0;background:transparent;padding:0;margin:0;font:inherit;font-family:var(--font-display);font-size:var(--text-h6);line-height:1.6;color:var(--ink);caret-color:var(--ink)}
lmed-input .lmed-input__control:focus{outline:none}
/* Многоредовото поле е същият контрол с друг таг — наследява шрифта и
   съобщението под себе си, — но не и линията: тя е за един ред, а под пет виси
   далеч от текста и не чете като поле. Затова рамка от четирите страни, на
   самия контрол, и двете линии се махат. `:has()` ги намира по контрола, който
   полето съдържа — същият похват като `body:has(.breadcrumb)` в range-head.
   Цветът и дебелината са на линията, която рамката замества, тъй че невалидно
   поле почервенява както всяко друго. */
lmed-input .lmed-input__control--area{
  border:1px solid var(--border-default);border-radius:var(--radius-md);
  padding:var(--space-3);resize:vertical;
  min-height:calc(var(--text-h6) * 1.6 * 3);overflow:auto;
  transition:border-color var(--duration-base) var(--ease-standard)}
/* Мастилото е за ФОКУС, както линията на едноредовото поле се чертае при него.
   В покой рамката е светлата — на пет реда плътен черен правоъгълник тежи
   повече от всичко останало на панела. */
lmed-input .lmed-input__control--area:focus{border-color:var(--ink)}
/* Линията отдолу си отива, иначе полето има две рамки — рамка и черта.
   ТРИ слоя я чертаят, не един: двата `span`-а (мастилото и червеното, които се
   разтягат при фокус и грешка) и `::after` на полето — релсата в accent-200,
   която стои под тях в покой. Тя е псевдоелемент, тъй че не се вижда нито в
   DOM-а, нито през elementFromPoint: търсих я в разметката два пъти и я
   намерих чак като попитах getComputedStyle за `::after`.
   Братски селектор за `span`-ите — стоят СЛЕД контрола, — и `:has()` за
   релсата, защото до чуждия псевдоелемент се стига само през родителя му. */
lmed-input .lmed-input__control--area ~ .lmed-input__line{display:none}
lmed-input .lmed-input__field:has(.lmed-input__control--area)::after{display:none}
lmed-input.is-invalid .lmed-input__control--area{border-color:var(--error-500)}
/* Етикетът върви с ГОРНИЯ ръб на многоредовото поле. Хостът е грид с
   `align-items: end` — за един ред това слага етикета на линията на текста, а
   тук би го залепило за дъното, на три реда от онова, което назовава.
   Отместването е рамката плюс вътрешното поле, за да легне на първия ред вътре.
   Вдигането при попълнено поле отпада: то е за етикет, който стои НА линията. */
lmed-input:has(.lmed-input__control--area){align-items:start}
lmed-input:has(.lmed-input__control--area) .lmed-input__label{
  align-self:start;padding-top:calc(var(--space-3) + 1px);transform:none}
lmed-input.is-filled .lmed-input__control,lmed-input.is-invalid .lmed-input__control{font-weight:var(--weight-body-semibold)}
/* Двата слоя: ::after е спокойната линия, .lmed-input__line се разгръща отгоре ѝ. */
lmed-input .lmed-input__field::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--accent-200)}
lmed-input .lmed-input__line{position:absolute;left:0;right:0;bottom:0;height:1px;z-index:1;background:var(--ink);transform:scaleX(0);transform-origin:left center;transition:transform var(--duration-base) var(--ease-standard)}
lmed-input .lmed-input__line--error{background:var(--error-500)}
lmed-input.is-focus .lmed-input__line:not(.lmed-input__line--error){transform:scaleX(1)}
lmed-input.is-invalid .lmed-input__line--error{transform:scaleX(1)}
lmed-input .lmed-input__msg{grid-column:2;margin:var(--space-2) 0 0;font-size:var(--text-small);line-height:1.4;color:var(--text-primary);opacity:0;transition:opacity var(--duration-base) var(--ease-standard)}
lmed-input .lmed-input__msg > span{color:var(--error-500)}
lmed-input.is-invalid .lmed-input__msg{opacity:1}
lmed-input[disabled]{opacity:.5;pointer-events:none}
@media (prefers-reduced-motion: reduce){lmed-input .lmed-input__label,lmed-input .lmed-input__line,lmed-input .lmed-input__msg{transition:none}}

/* ── device-card ──────────────────────────────────────── */
/* Картата на апарат. НЕКСКОУПНАТА, защото я ползват две секции — решетката по
 * категории в /aparati/ (sections/categories) и лентата „Разгледай още" на
 * страницата на апарат (sections/related) — а @scope стига само надолу от един
 * корен. Същата причина, поради която .cos-lead и .rf-card са тук.
 *
 * Само картата. Колко е голяма и как е подредена остава на секцията: решетката
 * е в categories.css, ширината в лентата — в related.css.
 *
 * Дотук лентата имаше СВОЯ карта, product-card-compact, която си приличаше с
 * тази, без да е тя. Оттам и разместването: две карти, които трябва да се
 * разбират една с друга, са две карти, които няма да се разберат. */
.dcard{ --dcard-pad: var(--space-5); }
/* Цялата карта е връзката, затова няма бутон. Рамката е мастилена и се избелва,
   когато картата е активна — върху бялата решетка това я изтрива, което е
   ефектът в дизайна: картата се отваря, вместо да се очертава. Кога е активна
   решава --dcard-on веднага под това правило. */
.dcard{
  position: relative;
  display: block;
  /* 3/4 е мярката на картата НАВСЯКЪДЕ — решетката по категории, лентата
     „Разгледай още", каквото дойде после. Единственото изключение е решетка от
     ДВЕ колони на /aparati/; то живее в categories.css, защото е решение на
     подредбата, не на картата.
     
     По подразбиране е РЕЗЕРВА на var(), а не декларация върху .dcard. Беше
     декларация и изключението не важеше: стойност, обявена върху самия
     елемент, бие всяка наследена от родител, тоест решетката нямаше как да я
     надговори. */
  aspect-ratio: var(--dcard-ratio, 3 / 4);
  /* Рамката идва от превключвателя: 0 е мастилена, 1 е бяла. color-mix, а не
     две правила, за да няма втори ред, който да остане стар. */
  border: 1px solid color-mix(in srgb, var(--white) calc(var(--dcard-on) * 100%), var(--ink));
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--white);
  color: var(--text-primary);
  text-decoration: none;
  transition: border-color var(--duration-base) var(--ease-standard);
}
/* ЕДИН превключвател, два повода да се вдигне. Ефектът — кадър, мащаб, рамка —
   е изписан по веднъж и се чете изцяло от --dcard-on, така че двата повода не
   могат да се разминат: тук стояха два отделни набора правила и вторият вече
   веднъж изостана от първия.

   Ховърът е зад (hover: hover), задържането не е зад нищо. На тъч Chrome
   залепва :hover след тап и картата остава сменена, докато не се тапне
   другаде — оттам и заявката. Допълващата ѝ, (hover: none), е гейтът в
   scripts/page/categories.js, тоест точно един повод е активен на устройство. */
.dcard{ --dcard-on: 0; }
@media (hover: hover){
.dcard:hover{ --dcard-on: 1; }
}
/* Пише се от scripts/page/categories.js, когато картата е стояла ЦЯЛА в екрана
   когато скролът е спрял за секунда, и се маха, когато излезе изцяло от екрана.
   Атрибут, а не клас, като
   data-state на icon-btn и data-clear-all на lmed-tabs. */
.dcard[data-dwell]{ --dcard-on: 1; }

.dcard__art{ position: absolute; inset: 0; z-index: 0; display: block; }
/* И ДВАТА кадъра покриват картата. Ресурсите са 753×774, а кутията е 3/4 или
   квадрат според подредбата — тоест двете почти никъде не съвпадат и нещо
   трябва да отстъпи: `cover` изрязва по дългата страна, `contain` оставя бели
   ленти. Базата беше `contain` и лентите ѝ не се виждаха, защото е изрезка на
   бял фон; същото върху снимка на стая се вижда веднага, затова ховърът от
   самото начало е `cover`.

   Сега двата са еднакви и картата не сменя начина, по който показва кадъра, в
   мига, в който сменя самия кадър.

   Центрирането е изрично: ресурсът решава къде стои апаратът, не тази таблица. */
.dcard__img{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  transition: transform .5s cubic-bezier(.14, 0, 0, 1),
              opacity var(--duration-base) var(--ease-standard);
}
/* Двете действия на превключвателя. Няма ги в правило за :hover и в друго за
   [data-dwell] — има ги веднъж, а кой го е вдигнал не ги интересува. */
/* 1.04 — същото число като .card.wide, която мащабира снимката си със
   `scale(1.04)` и същата крива. Беше .06; двете карти стоят една до друга в
   лентата „Разгледай още" и разликата личеше. */
.dcard__img{ transform: scale(calc(1 + var(--dcard-on) * .04)); }
.dcard__img--hover{ opacity: var(--dcard-on); }
/* Смяната ОСТАВА при reduce, но става мигновено. Тя е информация — вторият
   кадър показва апарата в употреба — а плавното ѝ появяване е украсата. */
@media (prefers-reduced-motion: reduce){
.dcard__img{ transition: none; }
}

/* И ЛЯВ ръб, не само десен. Само с `right` кутията е shrink-to-fit срещу
   свободното място, а свободното място стига до лявия ръб на картата: тя няма
   собствен padding — --dcard-pad е отместване на всяко дете поотделно — така че
   четири тага се подреждаха на 305px в карта с 288px полезна ширина, започваха
   на 2px от ръба и не се пренасяха, защото им СТИГАШЕ.

   С двата ръба кутията е широка точно колкото полето, редът се пренася, а
   justify-content: flex-end по-долу лепи и двата реда вдясно. */
/* Стрелката в средата на картата. Чете СЪЩИЯ превключвател, с който се сменя
   кадърът — един повод, четири ефекта — така че на десктоп идва с ховъра, а на
   телефон с двете секунди задържане, без да знае за нито едното.

   Не приема клика: картата е връзката, а кръгът е само знакът за нея. Без това
   `pointer-events` курсорът щеше да сменя вида си в средата на картата, все
   едно там има отделен бутон. */
.dcard__go{
  position: absolute; z-index: 3;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%) scale(calc(.88 + var(--dcard-on) * .12));
  opacity: var(--dcard-on);
  pointer-events: none;
  transition: opacity var(--duration-base) var(--ease-standard),
              transform var(--duration-base) var(--ease-standard);
}

.dcard__tags{
  position: absolute; z-index: 2;
  top: var(--dcard-pad); right: var(--dcard-pad); left: var(--dcard-pad);
}
.dcard__tags .tags{ flex-wrap: wrap; justify-content: flex-end; overflow: visible; }

.dcard__body{
  position: absolute; z-index: 2;
  left: var(--dcard-pad); right: var(--dcard-pad); bottom: var(--dcard-pad);
  display: flex; flex-direction: column; gap: var(--space-1);
}
.dcard__name{
  font-family: var(--font-display); font-weight: var(--weight-heading);
  line-height: var(--leading-heading); font-size: var(--text-h4);
}
/* Таван от три реда, без под. Описанията са с много различна дължина —
   NOVAPRESS е три изречения, LEASEIR MHR е половин ред — и блокът е закачен за
   ДОЛНИЯ ръб на картата, така че къс текст сваля заглавието надолу, а не
   вдига дупка под него.

   Тук стоеше min-height, за да се изравнят заглавията в един ред. Беше
   грешната сметка: резервираните три реда бутаха заглавието на LEASEIR два
   реда нагоре, право в колелата на апарата. Долното подравняване държи текста
   далеч от апарата точно защото НЕ е с фиксирана височина. */
.dcard__desc{
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;
  line-clamp: 3; overflow: hidden;
}

/* Трите колони стесняват картата, а с нея и всичко в нея — иначе заглавието

/* ── tech-card ────────────────────────────────────────── */
/* Номерирана карта: номер, рисунка, заглавие, удебелен ред, обяснение.
 * НЕСКОУПНАТА, макар че днес я ползва само една секция — технологиите на HERA.
 * Втората беше типовете кожа на Leaseir MHR (sections/skin-types) и я няма
 * вече: секцията се сви до едно каре в `results`. Остава тук, защото това е
 * правилното място за карта, която може да потрябва пак — а върната в
 * technologies.css, следващата секция, която я поиска, ще я получи без нито
 * едно нейно правило. Точно това се беше случило: рисунката оставаше в потока,
 * в естествения си размер, и разпъваше страницата настрани.
 *
 * Само картата. Мрежата и праговете ѝ са на секцията, която я подрежда. */
/* В покой е акцентна и става БЯЛА под курсора. Обратното на предишната карта,
   и обратното на интуицията — но върху бяла страница светването изважда
   картата напред, вместо да я потапя. */
.tech-card{
  position: relative; overflow: hidden;
  display: flex; flex-direction: column;
  min-height: 340px;
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid transparent;
  background-color: var(--accent-100);
  /* ЕДНА декларация за четирите прехода — влизането и ховърът заедно.
     Влизането е `.rv`/`.in` от base.css; там преходът е само opacity и
     transform, без закъснение. Тук се преобявява цял, защото transition е
     съкратен запис: втора декларация за delay би се приложила върху ЧУЖДИЯ
     списък свойства и би забавила ховъра вместо влизането.

     Печели, макар и с еднаква специфичност, защото кошираното правило бие
     некошираното — виж правило 3 в CLAUDE.md. */
  transition: opacity .7s cubic-bezier(.15, 0, 0, 1) var(--d, 0s),
              transform .7s cubic-bezier(.15, 0, 0, 1) var(--d, 0s),
              background-color .4s var(--ease-standard),
              border-color .4s var(--ease-standard);
}
.tech-card__n{
  position: relative; z-index: 1;
  font-family: var(--font-body); font-weight: var(--weight-body-semibold);
  font-size: var(--text-small); color: var(--ink);
}

/* Рисунката е ДЯСНАТА половина и виси на горния ръб. Абсолютна, защото не
   участва в потока: текстът расте нагоре в нейното място, а тя не се мести.

   Мери се по ВИСОЧИНА, защото ограничението е вертикално: височината е тази на
   картата минус двата отстъпа, а ширината идва от съотношението. Така рисунката
   не може да прелее под долния ръб — с `width: 58%` излизаше 334px в карта от
   340 с 24 отгоре, тоест 18px отрязани от overflow: hidden.

   `bottom` НЕ върши тази работа. Абсолютно позициониран ЗАМЕСТВАЩ елемент с
   `height: auto` не се разтяга между top и bottom — взима собствената си
   височина, а тя е НУЛА, докато файлът не дойде. Кутията се срина точно така.

   Съотношението е едно число, защото всичките пет svg-та делят един viewBox
   (426.65 × 346.61). То и РЕЗЕРВИРА кутията преди зареждането: картата е с
   крайния си вид от първото рисуване, а рисунка, която не се появи, оставя
   празно място вместо да събере всичко нагоре. */
.tech-card__art{
  position: absolute; z-index: 0;
  top: var(--space-5); right: var(--space-5);
  height: calc(100% - var(--space-5) * 2); width: auto;
  aspect-ratio: 426.65 / 346.61;
  object-fit: contain; object-position: top right;
}

/* `margin-top: auto` го лепи за дъното — там свършва картата и в двете
   състояния. */
.tech-card__body{
  position: relative; z-index: 1;
  margin-top: auto;
  display: flex; flex-direction: column; gap: var(--space-2);
  max-width: 34ch;
}
.tech-card__body h3{ font-size: var(--text-h5); margin: 0; }
.tech-card__lead{ margin: 0; font-weight: var(--weight-body-semibold); color: var(--ink); }

/* Обяснението стои отворено от самото начало. Беше зад ховър и се разгъваше
   през `grid-template-rows: 0fr → 1fr`; онази обвивка си отиде с него. */
.tech-card__text{ margin: 0; line-height: var(--leading-body); }

/* Зад (hover: hover): на тъч :hover залепва след тап и картата остава бяла,
   докато не се тапне другаде. */
@media (hover: hover){
.tech-card:hover{ background-color: var(--white); border-color: var(--ink); }
}

/* При reduced-motion пада ВЛИЗАНЕТО, не преливането на цвета.
   base.css гаси `.rv{transition:none}` изцяло, а картата носи и двете в една
   декларация — тоест с включена настройка ховърът щеше да щрака, вместо да
   прелива. Смяна на цвят не е движение и няма причина да си отива с него.

   Правилото бие некошираното от base.css при еднаква специфичност — правило 3
   в CLAUDE.md. */
@media (prefers-reduced-motion: reduce){
.tech-card{
  transition: background-color .4s var(--ease-standard),
              border-color .4s var(--ease-standard);
}
}

@media (max-width: 1024px){
.tech-card__art{ width: 56%; }
}
/* На телефон обратното: ширината командва, височината идва от съотношението. */
@media (max-width: 768px){
.tech-card{ min-height: 0; }
.tech-card__art{
  position: relative; top: auto; right: auto;
  width: 100%; height: auto; order: -1;
  object-position: center;
  margin-bottom: var(--space-4);
}
.tech-card__n{ order: -2; }
.tech-card__body{ margin-top: 0; max-width: none; }
}

/* ── ac (стек карта) ──────────────────────────────────── */
/* Картата от стека: sticky, следващата бута предходната нагоре и оставя лента,
 * в която се вижда само горният ѝ ред.
 *
 * НЕСКОУПНАТА, защото я ползват две секции — „За LMedical" на страницата с
 * производителите (sections/mfr-about) и трите аргумента на Leaseir MHR
 * (sections/about) — а @scope стига само надолу от един корен. Стоеше в
 * mfr-about.css; оттам на страницата на апарата не би важало нито едно от
 * правилата ѝ. Същата грешка вече беше правена с .dcard и с .tech-card.
 *
 * Само картата. Мрежата, лийдът и праговете --ac-top / --ac-step са на
 * секцията, която я подрежда — стойностите им се различават, защото се
 * различава и височината на това, над което картите кацат.
 *
 * Горният ред има два облика. На производителите е ЦИФРА (.ac__num) — позиция
 * в стека, не текст. На апарата е иконка вляво и акцентна стойност вдясно
 * (.ac__head), защото там картата носи число, което значи нещо: 14,8 cm²/сек.
 * Двата облика не се смесват в една карта. */
.ac{
  position: sticky;
  /* Fallback в var(), а не декларация върху .ac: свойство, обявено ВЪРХУ
     елемента, бие наследеното и секцията после не може да го смени. */
  top: var(--ac-top, 148px);
  display: flex;
  border: 1px solid var(--ink); border-radius: var(--radius-md); overflow: clip;
  background: var(--white); will-change: transform;
}
/* Задава пропорцията, без да пипа височината на текста: празен flex елемент с
   padding-top в проценти от ШИРИНАТА. Картата не може да стане по-ниска от
   съдържанието си. */
.ac::before{ content: ""; flex: 0 0 auto; width: 0; padding-top: 46.4%; }
.ac + .ac{ margin-top: var(--space-6); }
/* Гасненето е ЕДНО число за цялата карта, не свойство на фона: щом фонът
   гасне, докато следващата карта го покрива, акцентът трябва да гасне с него —
   иначе числото остава да виси самò върху свитата лента. Скриптът пише
   --ac-fade на картата, а кой го слуша е решение на стила. */
.ac__bg{ position: absolute; inset: 0; z-index: 0; background: var(--grey-200); opacity: var(--ac-fade, 1); will-change: opacity; }
.ac__img{ position: absolute; right: 0; top: 0; height: 100%; width: auto; display: block; }
.ac__body{
  position: relative; z-index: 1; flex: 1; min-width: 0; padding: var(--space-6);
  display: flex; flex-direction: column; justify-content: space-between; align-items: flex-start;
  gap: var(--space-5);
}
.ac__num{ font-family: var(--font-display); font-size: var(--text-h4); font-weight: 700; line-height: var(--leading-heading); }

/* Горният ред на варианта с иконка. `align-self: stretch`, защото .ac__body
   подравнява децата си вляво — без него редът се свива до иконката и акцентът
   застава до нея вместо на десния ръб. */
.ac__head{ align-self: stretch; display: flex; align-items: flex-start; justify-content: space-between; gap: var(--space-5); }
/* Същото кръгче като отметката в usp картата — 28px, акцентен фон, иконка
   1rem. Маска, а не <img>: иконката се оцветява от currentColor и не зависи от
   това какъв цвят е вписан в самия svg. url-ът идва от style атрибут, тоест се
   решава спрямо СТРАНИЦАТА — в custom property би се решавал спрямо бъндъла. */
.ac__ico{
  flex: 0 0 28px; width: 28px; height: 28px; border-radius: 50%;
  background: var(--accent-200); display: grid; place-items: center; color: var(--ink);
}
/* Самата маска идва от style атрибут на този span — url() през custom
   property би се решавал спрямо бъндъла, не спрямо страницата. Тук стои само
   останалото от маската, което е еднакво за всички иконки. */
.ac__ico-m{
  width: 1rem; height: 1rem; background: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
/* Акцентът е дясно подравнен и излиза ВЪРХУ снимката — тя идва от десния ръб,
   а числото е най-силното нещо в картата. Затова и .ac__body е цялата ширина:
   при flex:1 и нулева ширина на ::before редът стига до дясното поле. */
.ac__accent{ text-align: right; min-width: 0; opacity: var(--ac-fade, 1); will-change: opacity; }
/* Над стълбицата: най-едрото стъпало е 53px, а тук числото е колкото
   заглавието на страницата. clamp, за да не изяде картата на тесен екран. */
.ac__accent b{
  display: block; font-family: var(--font-display); font-weight: var(--weight-heading);
  font-size: clamp(3rem, 5.6vw, 6.4rem); line-height: .9; letter-spacing: -.02em;
}
.ac__accent span{ display: block; margin-top: var(--space-2); font-weight: var(--weight-body-semibold); line-height: 1.25; }

/* Текстът стои вляво от снимката, която идва от десния ръб. */
.ac__txt{ max-width: 48%; }
.ac__txt h3{ margin: 0; font-size: var(--text-h4); line-height: var(--leading-heading); }
.ac__txt p{ margin: var(--space-3) 0 0; line-height: 1.5; }

@media (max-width: 1240px){
  .ac__txt{ max-width: 62%; }
  .ac__accent b{ font-size: clamp(2.6rem, 6vw, 4.6rem); }
}

@media (max-width: 768px){
  .ac::before{ padding-top: 125%; }
  .ac + .ac{ margin-top: var(--space-5); }
  .ac__body{ padding: var(--space-5); justify-content: flex-start; gap: var(--space-5); }
  .ac__txt{ max-width: none; margin-top: auto; }
  /* Горе ВДЯСНО, залепена за ъгъла — както на десктоп, само че ширината
     командва вместо височината. Дотук беше центрирана по хоризонтала на 18%
     от горния ръб и с височина 34%: две мерки, вързани за височината на
     картата, която на телефон е 125% от ширината. Резултатът беше изрезка,
     която плува в средата и се мени с всяко пренареждане на текста.

     Ширина, а не височина, защото всички изрезки са 1494×1510 — практически
     квадрат — тъй че процент от ширината дава същия процент височина спрямо
     ШИРИНАТА на картата. Едно число, което не зависи от това колко текст има
     отдолу. */
  .ac__img{ left: auto; right: 0; top: 0; transform: none; width: 80%; height: auto; }
  /* По-едро, отколкото стълбицата стига: на телефон акцентът е и единственото,
     което се вижда от картата, докато тя минава. */
  .ac__accent b{ font-size: clamp(2.9rem, 13vw, 4rem); }
}

@media (prefers-reduced-motion: reduce){
  /* Скриптът излиза рано, така че картите трябва да са четими без него:
     обикновен списък, всяка със своя фон. */
  .ac{ position: static; transform: none; will-change: auto; }
  .ac::before{ padding-top: 0; }
  .ac__bg, .ac__accent{ opacity: 1; }
}

/* ── usp-card ─────────────────────────────────────────── */
/* Кутия с кръгче горе вдясно и текст, залепен за дъното. Кръгчето е отметка
 * или иконка; текстът е ред или ред плюс параграф — това е цялата разлика
 * между двата ѝ облика.
 *
 * НЕСКОУПНАТА, защото я ползват две секции — трите USP-та над описанието на
 * апарата (sections/about) и финансовите условия (sections/finance). Стоеше в
 * about.css; оттам втората секция би я получила без нито едно нейно правило.
 *
 * `justify-content: space-between` е това, което държи текста долу, каквато и
 * да е дължината му: кръгчето остава горе, а блокът пада на дъното. Затова и
 * трите карти в един ред четат от една линия, а не всяка от своята. */
.usp-card{
  border: 1px solid var(--ink); border-radius: var(--radius-lg);
  background: var(--white); padding: var(--space-5); min-height: 175px;
  display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-5);
}
.usp-check, .usp-ico{
  width: 28px; height: 28px; border-radius: 50%; background: var(--accent-200);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.9rem; color: var(--ink); flex-shrink: 0; align-self: flex-end;
}
/* Маска, а не <img>: иконката се оцветява от картата и не зависи от това
   какъв цвят е вписан в самия svg. Самият url идва от style атрибут на
   вътрешния span — през custom property би се решавал спрямо бъндъла, не
   спрямо страницата. */
.usp-ico__m{
  width: 1rem; height: 1rem; background: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: center; mask-position: center;
  -webkit-mask-size: contain; mask-size: contain;
}
.usp-card__body{ display: flex; flex-direction: column; gap: var(--space-2); }
.usp-card .usp-label{ font-family: var(--font-display); font-weight: var(--weight-heading);
  font-size: var(--text-h4); line-height: 1.25; }
/* Нормален кегел и пълен цвят: дребният е за надписи под стойност — мерна
   единица, бележка — а това тук е изречение, което се чете. */
.usp-card__text{ margin: 0; font-size: var(--text-p); color: var(--ink);
  line-height: var(--leading-body); }

/* ═══ product-row ═══ */
/* Продуктов ред: миниатюра вляво, име и изречение вдясно, по избор таг накрая.
 *
 * НЕСКОУПНАТ, на корена на styles/, защото го ползват две секции: индексът на
 * марката в `cosmetics-brand` и списъкът със съвместими продукти в
 * `consumables`. Стоеше в styles/sections/cosmetics-brand.css, вътре в
 * `@scope (.cos-brand-sec)` — оттам втората секция би го получила без нито едно
 * негово правило. Същият ход и същата причина като при rf-card.css,
 * spec-card.css и aside-card.css.
 *
 * Само редът. Колоната, в която стои, е на секцията, която го поставя. */
.cos-item{
  display: flex; align-items: center; gap: var(--space-4);
  padding: var(--space-5) 0;
  border-bottom: 1px solid var(--border-default);
}
.cos-item__thumb{ flex: 0 0 90px; height: 128px; position: relative; display: block; }
.cos-item__thumb img{ position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: contain; object-position: center; }
.cos-item__main{ flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; gap: var(--space-1); }
.cos-item__main h4{ margin: 0; font-family: var(--font-display);
  font-weight: var(--weight-heading); font-size: var(--text-h6); line-height: 1.25; }
.cos-item__main p{ margin: 0; font-size: 1rem; line-height: 1.4; }
.cos-item__tags{ flex: 0 0 auto; display: flex; align-items: center; gap: var(--space-2); }

/* Prices, rightmost in the row.
 *
 * LAST, so they line up as one column down the whole list: the price is what
 * the eye scans vertically, where the tag qualifies the product beside it.
 *
 * A `dl`, because these are pairs — a package and its price. One line per
 * package, so a product with one gives one line and a product with two gives
 * two, with nothing decided in the template.
 *
 * `tabular-nums` keeps the figures in columns so the sums do not dance against
 * each other; `nowrap` keeps "2 x 50ml" on one line. */
.cos-item__packs{
  flex: 0 0 auto; margin: 0;
  display: flex; flex-direction: column; gap: var(--space-1);
  text-align: right; min-width: 7.5rem;
}
.cos-pack{ display: flex; align-items: baseline; justify-content: flex-end; gap: var(--space-2); white-space: nowrap; }
.cos-pack dt{ font-size: .875rem; color: var(--text-secondary); }
.cos-pack dd{ margin: 0; font-weight: var(--weight-heading); font-variant-numeric: tabular-nums; }

@media (max-width: 768px){
  /* Below 768px the row is already tight, so the price drops under the text and
     aligns left with it rather than eating the width of the name. */
  .cos-item{ flex-wrap: wrap; }
  .cos-item__packs{ flex-basis: 100%; text-align: left; min-width: 0; padding-left: calc(64px + var(--space-4)); }
  .cos-pack{ justify-content: flex-start; }
}

@media (max-width: 768px){
  .cos-item__thumb{ flex: 0 0 64px; height: 96px; }
}

/* ═══ range-stage ═══ */
/* Сцената с апарати (layouts/ui/range-stage.liquid).
 *
 * НЕСКОУПНАТА, на корена на styles/, защото я ползват две секции: отварянето
 * на страница за серия (`range-head`) и четирите групи апарати на началната
 * (`groups`). Стоеше вътре в `@scope (.range-head)`, откъдето втората секция
 * не би получила нито едно нейно правило. Същият ход и същата причина като при
 * rf-card.css, aside-card.css и product-row.css.
 *
 * Само сцената. Каква е рамката около нея — цял екран или не, колко отстояние
 * отгоре — е на секцията, която я поставя.
 *
 * Пренесена от serie-rf-v2. Подредбата е един стенд с текста, абсолютно
 * позициониран върху колоните с апарати, тъй че заглавието стои в празния
 * горен ляв ъгъл, а апаратите стъпват по дъното.
 *
 * Зоната е четири слоя и в покой се вижда само апаратът. `.is-active` — слага
 * се при посочване от scripts/components/zone.js — докарва стаята зад него,
 * тага и стъклената карта, стъпаловидно през transition-delay, а не през
 * animation, тъй че излизането се връща чисто от където е стигнало.
 *
 * `--par-*` са амплитудите на паралакса, които скриптът чете. Стоят тук,
 * защото колко далеч пътува един слой е дизайнерско решение; скриптът само
 * интерполира към каквото пишат.
 */
.range-stage { position: relative; flex: 1; }

/* ---------- текстът, върху колоните ---------- */
.range-stage__copy { position: absolute; top: 0; left: 0; z-index: 1; }
.range-stage__copy h1,
.range-stage__copy h2,
.range-stage__copy p { opacity: 0; animation: rangeStageCopyIn .8s cubic-bezier(.15, 0, 0, 1) forwards; }
.range-stage__copy h1,
.range-stage__copy h2 {
  font-family: var(--font-display);
  font-weight: var(--weight-heading);
  font-size: var(--text-h1);
  line-height: 1.15;
  margin: 0;
  max-width: 50%;
  animation-delay: .1s;
}
.range-stage__copy p {
  margin: var(--space-5) 0 0;
  line-height: 1.4;
  max-width: 30%;
  animation-delay: .2s;
}

/* ---------- колоните ---------- */
/* Колко са казва документът: три апарата заемат по трета, два — по половина,
   един — цялата ширина. Стойността идва в style атрибут от партиала; `3` тук е
   само предпазна мрежа, ако някой ден зоните дойдат без брой. */
/* pointer-events изключени върху решетката, включени обратно на всяка зона:
   решетката покрива текста, а заглавие, което не можеш да маркираш, е по-лошо
   от колона, която свършва там, където дизайнът казва. */
.range-stage__zones {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(var(--zone-cols, 3), minmax(0, 1fr));
  gap: var(--space-4);
  pointer-events: none;
}
.zone {
  position: relative;
  pointer-events: auto;
  /* Чете се от скрипта — колко далеч плува всеки слой спрямо показалеца. */
  --par-bg: 8px;
  --par-tag: 18px;
  --par-card: 28px;
}

/* апаратът: винаги там, единственият видим слой в покой */
.zone__slot {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  justify-content: center;
  z-index: 1;
}
.zone__device {
  position: relative;
  height: min(48svh, 430px);
  /* Изрезките са 1116x1248; изричната пропорция пази колоната от преливане,
     докато изображението се декодира. */
  aspect-ratio: 1116 / 1248;
  opacity: 0;
  animation: rangeStageDeviceIn .8s cubic-bezier(.15, 0, 0, 1) forwards;
}
/* `> img`, а не низходящ селектор. Хапчето вътре носи свой <img> — плюса, — а
   низходящо правило го разпъваше до целия апарат, 158px плюс. Дизайнът може да
   си позволи хлабавото правило, защото неговият <regular-btn> рисува в shadow
   root, до който правило на страницата не стига; нашият е сървърно рисуван
   светъл DOM и стига. */
.zone__device > img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  user-select: none;
  -webkit-user-drag: none;
}
.zone__device regular-btn {
  position: absolute;
  left: 50%;
  bottom: 26%;
  transform: translateX(-50%);
  z-index: 2;
}
/* Пристигат отляво надясно. */
.zone:nth-child(1) .zone__device { animation-delay: .15s; }
.zone:nth-child(2) .zone__device { animation-delay: .30s; }
.zone:nth-child(3) .zone__device { animation-delay: .45s; }

/* стаята зад него */
.zone__bg {
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: var(--radius-lg);
  overflow: hidden;
  pointer-events: none;
  opacity: 0;
  transform: translateY(28px);
  transition: opacity .5s cubic-bezier(.15, 0, 0, 1),
              transform .5s cubic-bezier(.15, 0, 0, 1);
}
.zone__bg-shift { position: absolute; inset: 0; will-change: transform; }
/* Кутията на снимката е по-ВИСОКА от зоната, и това не е украса.
   `cover` мащабира по по-стегнатата страна; при тясна колона това е височината,
   тъй че излишъкът е по хоризонтала и `object-position` има какво да мести. Но
   при `inset: -32px` излишъкът беше твърде малък: апаратите стоят на 65–76% от
   ширината на тези снимки, а за да дойде такава точка в средата на колоната,
   трябваше отместване отвъд 100% — невъзможно. Затова кадърът излизаше вдясно
   и се режеше. По-високата кутия го приближава и дава ход.

   Хоризонталният презапас остава заради паралакса (`--par-bg: 8px`), за да не
   оголи ръб; вертикалният идва даром от височината.

   При ШИРОКА зона — група с един апарат — `cover` мери по ширината, излишъкът
   е по вертикала и `object-position` по хоризонтала няма какво да прави:
   снимката се вижда по цялата си ширина. Същото правило служи и на двата
   случая, без разклонение.

   `--zone-focus` е къде да гледа кадърът. 91% не е избрано на око: апаратите
   стоят на 65–76% от ширината на тези шест снимки (средно ~72%), а котвата,
   която докарва такава точка в средата на колоната, зависи и от ширината ѝ —
   мерено 0.876 при екран 1360, 0.934 при 1600, 0.922 при 1920. 91% е най-близо
   до трите наведнъж; отклонението остава под 5% от ширината на колоната.

   Разликата между самите снимки тежи повече от тази между ширините: ±0.05 в
   положението на апарата са ±11% от колоната. Зона, чиято снимка се откроява,
   може да си зададе своя котва. */
.zone__bg-img {
  position: absolute;
  left: -8px;
  top: 50%;
  width: calc(100% + 16px);
  height: var(--zone-bg-h, 140%);
  transform: translateY(-50%);
  object-fit: cover;
  object-position: var(--zone-focus, 91% 50%);
}

/* за кого е */
.zone__tag {
  position: absolute;
  top: var(--space-5);
  right: var(--space-5);
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .45s cubic-bezier(.15, 0, 0, 1),
              transform .5s cubic-bezier(.15, 0, 0, 1);
}
.zone__tag-shift { will-change: transform; }

/* стъклената карта */
/* Издърпана наляво извън собствената си колона нарочно, за да чете като част
   от апарата, а не от решетката. Първата зона не може — вляво от нея няма
   страница. */
.zone__card {
  position: absolute;
  left: calc(-1 * var(--space-8));
  bottom: var(--space-6);
  width: min(90%, 380px);
  z-index: 4;
  pointer-events: none;
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .45s cubic-bezier(.15, 0, 0, 1),
              transform .5s cubic-bezier(.15, 0, 0, 1);
}
.zone:first-child .zone__card { left: 0; }
.zone__card-shift { will-change: transform; }
.zone__card-glass {
  background: rgba(211, 229, 229, .45);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--accent-200);
  border-radius: var(--radius-md);
  padding: var(--space-5);
}
.zone__card-glass h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-heading);
  font-size: var(--text-h4);
  margin: 0;
}
.zone__desc { margin: var(--space-1) 0 0; line-height: 1.4; }
.zone__price {
  font-family: var(--font-display);
  font-weight: var(--weight-heading);
  font-size: var(--text-h5);
  margin: var(--space-2) 0 0;
}
.zone__card-glass .lmed-btn { margin-top: var(--space-4); }

/* ---------- разкрито ---------- */
.zone.is-active .zone__bg   { opacity: 1; transform: none; transition-delay: 0s; }
.zone.is-active .zone__tag  { opacity: 1; transform: none; transition-delay: .06s; }
.zone.is-active .zone__card { opacity: 1; transform: none; transition-delay: .12s; pointer-events: auto; }

/* ---------- по-тясно ---------- */
@media (max-width: 1439px) {
  .range-stage__copy h1,
  .range-stage__copy h2 { max-width: 65%; }
  .range-stage__copy p { max-width: 45%; }
}
@media (max-width: 1024px) {
  .range-stage__copy h1,
  .range-stage__copy h2,
  .range-stage__copy p { max-width: 100%; }
}
/* На телефон колоните си отиват. Панели, които значат нещо само при посочване,
   тук не значат нищо, а сравнението отдолу носи същите факти. */
@media (max-width: 768px) {
  .range-stage { flex: none; }
  .range-stage__zones { display: none; }
  .range-stage__copy { position: static; }
}

@media (prefers-reduced-motion: reduce) {
  .range-stage__copy h1,
  .range-stage__copy h2,
  .range-stage__copy p,
  .zone__device { opacity: 1; animation: none; }
  .zone__bg,
  .zone__tag,
  .zone__card { transition: none; }
  .zone__bg-shift,
  .zone__tag-shift,
  .zone__card-shift { transform: none !important; }
}

/* Префиксирани, защото голо `copyIn` в един бъндъл е на всяка секция. */
@keyframes rangeStageCopyIn {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
@keyframes rangeStageDeviceIn {
  from { opacity: 0; transform: translateX(-48px); }
  to   { opacity: 1; transform: none; }
}

/* ═══ rf-card ═══ */
/* The bordered technology / nozzle card and its row of tags.
 *
 * UNSCOPED, at the styles root, because two sections use it: the technologies
 * section and the platform's masonry of nozzles. It lived inside
 * `@scope (.platform-sec)`, which meant the second one could not have it — a
 * scoped rule reaches only its own root. Same move, and same reason, as
 * spec-card.css.
 *
 * Only the card is here. How the cards are ARRANGED belongs to each section:
 * `.rf-col` and the masonry offset stay in platform.css, the three-column grid
 * lives in technologies.css.
 *
 * `.tags-wrap` was `:scope .tags-wrap` in platform.css and is the card's own
 * row — nothing else uses the class — so it comes along, named for the card
 * rather than for a scope it no longer has. */
.rf-card{position:relative;background:var(--white);border:1px solid var(--ink);border-radius:var(--radius-lg);padding:var(--space-5);display:flex;flex-direction:column;gap:var(--space-4);transition:background var(--duration-slow,.4s) var(--ease-standard),border-color var(--duration-slow,.4s) var(--ease-standard)}
.rf-card:hover{background:var(--accent-200);border:1px solid var(--accent-200)}
/* Full width: the 52px used to be kept clear for an arrow badge in the
   corner, which is gone. */
.rf-card h3{font-size:var(--text-h5);margin:0}
/* One box for every diagram, whatever the drawing inside it.
   The four svgs share a viewBox WIDTH (533.96) and differ in height — 334.55,
   365.47, 338.26, 365.47 — so `height:auto` gave four different heights and,
   with the cards equalised, four different amounts of slack underneath.
   aspect-ratio takes the tallest of the four, so nothing has to shrink to fit;
   `contain` fits each drawing inside without distorting it, and centres it.
   The ratio also RESERVES the box before the file arrives, which is the
   placeholder: the card is its final height from the first paint, and a
   drawing that never loads leaves a gap rather than collapsing the card.
   No tint on the box: the card turns accent-200 on hover, and a grey panel
   inside it would read as a hole. */
.rf-card img.rf-diagram{width:100%;aspect-ratio:534/366;height:auto;object-fit:contain;object-position:center;display:block}
/* Снимката СПАЗВА падинга на картата и е заоблена. Дотук излизаше до двата
   ръба — `margin:0 calc(var(--space-5)*-1)`, отрицателен отстъп точно колкото
   падинга, — и картата се разпадаше на лента и текст под нея.

   Пропорцията е тук, а не в разметката: тя РЕЗЕРВИРА кутията, преди файлът да
   пристигне, тъй че картата е с крайната си височина от първата рисунка и
   колоната не подскача. `cover` вместо `contain`, защото това са снимки в
   кадър, не изрезки върху нищо; сивото под тях се вижда само докато файл няма
   — по същия начин, по който празният кръг в стековата карта се чете като
   „липсва иконка".

   3/2 е пропорцията на накрайниците на HERA (629×426 — разликата до 3:2 е под
   процент и `cover` я изяжда, без да личи). */
.rf-card__photo{border-radius:var(--radius-md);overflow:hidden;background:var(--grey-200)}
.rf-card__photo img{width:100%;aspect-ratio:3/2;height:auto;object-fit:cover;display:block}
.rf-card p{color:var(--ink);margin:0}
.rf-card .tags-wrap{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:auto}

/* ═══ spec-card ═══ */
/* The bordered card and its rows of downloadable documents.
 *
 * UNSCOPED, at the styles root, because three sections use it: the device
 * specifications, the CTA on a device page, and the manufacturer certificates.
 * It lived inside `@scope (.specs-sec)`, which meant the third one could not
 * have it — a scoped rule reaches only its own root, so a shared component
 * cannot live in one section's file.
 *
 * Only the shell and the rows are here. `.spec-card--table` and
 * `.spec-card--brand` stay in specs.css: they are that section's variants, and
 * a modifier is free to be scoped when the thing it modifies is not.
 */
.spec-card{position:relative;flex-shrink:0;border:1px solid var(--ink);
  border-radius:var(--radius-lg);padding:var(--space-5)}
.spec-card > h4{margin:0 0 var(--space-4)}

/* A row is a whole link — logo, text, download button — so the hover moves
   together rather than only under the cursor. */
.dl-rows{display:flex;flex-direction:column}
.dl-row{display:flex;align-items:center;gap:var(--space-4);padding:var(--space-4) 0;
  text-decoration:none;color:var(--text-primary)}
.dl-row:last-child{padding-bottom:0}
.dl-row + .dl-row{border-top:1px solid var(--ink)}
.dl-row .dl-logo{width:64px;flex-shrink:0;display:flex;align-items:center;justify-content:center}
.dl-row .dl-logo img{max-width:100%;max-height:30px;display:block}
.dl-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.dl-txt h6{margin:0;transition:letter-spacing var(--duration-base) var(--ease-standard)}
.dl-row:hover .dl-txt h6{letter-spacing:0.5px}
.dl-txt p{margin:0;transition:color var(--duration-base) var(--ease-standard)}
.dl-row:hover .dl-txt p{color:var(--ink)}
/* Ред без адрес е ТЕКСТ. Рендира се като <div> (виж sections/specs.liquid) и
   тук му се отнема всичко, което обещава клик: курсорът и ховърът. Leaseir MHR
   е случаят — имената на стандартите са известни, самите сертификати още не. */
.dl-row--plain{cursor:default}
.dl-row--plain:hover .dl-txt h6{letter-spacing:normal}
.dl-row--plain:hover .dl-txt p{color:var(--ink)}

/* Тесен екран. Тук, не в specs.css: този компонент се ползва от три секции и
   правило, вързано за scope-а на едната, не важи за другите две. */
@media (max-width:768px){
.spec-card{padding:var(--space-4);min-width:0}
.dl-row{gap:var(--space-3)}
.dl-row:has(.dl-logo){display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--space-3);row-gap:var(--space-2);align-items:center}
.dl-row:has(.dl-logo) .dl-logo{grid-column:1;grid-row:1;justify-content:flex-start}
.dl-row:has(.dl-logo) .dl-txt{grid-column:1;grid-row:2}
.dl-row:has(.dl-logo) icon-btn{grid-column:2;grid-row:1 / span 2}
}

/* ═══ chrome/backdrop ═══ */
/* The fixed map behind the contacts page. Rendered by page.liquid as the
 * page-level backdrop, not by a section — which is why it lives in chrome/.
 *
 * The design animates 138 frames through a canvas as you scroll; that set is
 * 5.1 MB against a page total of 0.4 MB everywhere else, so the static last
 * frame is the background here and scripts/page/contacts.js draws over it.
 * Under prefers-reduced-motion or Save-Data that script returns early and this
 * frame is what stays — so the background belongs to the CSS, not to the JS.
 *
 * Scoped to .mapbg: a rule here cannot reach an element outside the backdrop. */
@scope (.mapbg) {
:scope{position:fixed;inset:0;z-index:0;pointer-events:none;
  background:url("../media/raw/backgrounds/map-1280.webp") right center / cover no-repeat;
  transition:opacity .6s var(--ease-standard)}
:scope canvas{display:block;width:100%;height:100%}
@media (max-width:768px){
  :scope{top:17vh;height:100vh}
}
@media (prefers-reduced-motion: reduce){
  :scope{transition:none}
}
}

/* ═══ chrome/breadcrumb ═══ */
/* Пътеката сама разчиства фиксираното меню, затова нейната височина е това, с
   което започва всяка вложена страница. Изведена е от същите числа, от които е
   и подплатата ѝ, за да не могат да се разминат: страница, чийто първи екран
   трябва да свърши точно на ръба на прозореца, я изважда — виж .cos-hero.

   Мобилната стойност стоеше в sections/cta3d.css — правило за chrome, попаднало
   в лист на секция при пренасянето. Прилагаше се навсякъде и оттам; тук само си
   идва на мястото. */
:root {
  --crumb-clear: 84px;                      /* колкото трябва, за да мине под менюто */
  --crumb-line: calc(1.4 * 0.85rem);        /* font-size × line-height по-долу */
  --crumb-h: calc(var(--crumb-clear) + var(--space-4) + var(--crumb-line) + var(--space-4));
}
@media (max-width: 768px) { :root { --crumb-clear: 54px } }

.breadcrumb{font-size:0.85rem;line-height:1.4;color:var(--text-secondary);
  padding:calc(var(--crumb-clear) + var(--space-4)) var(--page-pad,48px) var(--space-4)}
.breadcrumb a{color:var(--text-secondary);text-decoration:none}
.breadcrumb a:hover{color:var(--text-primary)}

/* ═══ chrome/modal ═══ */
/* ---- Модал ---- */
.modal-backdrop{position:fixed;inset:0;background:rgba(23,23,23,.4);z-index:60;display:none;align-items:center;justify-content:center;padding:var(--space-5)}
.modal-backdrop.open{display:flex}
.modal{background:var(--white);border-radius:var(--radius-lg);padding:var(--space-6);width:min(480px,100%);position:relative;max-height:90vh;overflow-y:auto}
.modal h4{margin:0 0 var(--space-2)}
.modal .modal-sub{margin:0 0 var(--space-5)}
.modal-close{position:absolute;top:var(--space-4);right:var(--space-4);width:36px;height:36px;border-radius:50%;border:none;background:var(--grey-200);display:flex;align-items:center;justify-content:center;cursor:pointer}
.modal-close:hover{background:var(--accent-200)}
.modal-close img{width:12px;height:12px}
.field{display:flex;flex-direction:column;gap:var(--space-2);margin-bottom:var(--space-4)}
.field label{font-size:0.9rem;font-weight:var(--weight-body-semibold)}
.field input{font-family:var(--font-body);font-size:1rem;color:var(--text-primary);border:1px solid var(--border-default);border-radius:var(--radius-sm);padding:var(--space-3) var(--space-4);background:var(--white);transition:border-color var(--duration-fast) var(--ease-standard)}
.field input:focus{outline:none;border-color:var(--accent-500)}
.modal .lmed-btn{margin-top:var(--space-2)}
.modal-success{display:none;text-align:center;padding:var(--space-6) 0}
.modal-success .usp-check{width:44px;height:44px;margin:0 auto var(--space-4);background:var(--accent-200)}
.modal.sent form{display:none}
.modal.sent .modal-success{display:block}

/* ═══ sections/about ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .about-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.about-sec) {
/* ---- Описание + USP: асиметрия 5/7, снимката излиза от реда ---- */
:scope{padding:var(--section-pad) var(--page-pad,48px)}
/* Последна на страницата (Технология на Leaseir) — въздухът над футъра е
   неговият горен отстъп, както след related на страниците на апаратите. */
:scope:last-child{padding-bottom:0}
.about{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-6) var(--space-5);align-items:start}
/* Самата карта е в components.css, нескоупната: ползва я и секция `finance`,
   а @scope стига само надолу от един корен. Тук остава само мрежата. */
.about .lede{grid-column:1 / span 2;font-size:var(--text-h3);font-family:var(--font-display);font-weight:var(--weight-heading);line-height:1.3;margin:var(--space-6) 0 0}
/* No bottom margin: the lede is a grid item and the row-gap already spaces
   it from the body copy. With both it sat 56px clear - the grid's 32 plus
   its own 24 - the largest gap of its kind on the page. In a grid the gap
   owns the space between rows; an item margin double-counts it. */
/* Двата параграфа на равни половини, на цялата ширина под USP картите.
   Дотук бяха 1/3 и 2/3 — така е в макета (HERA v8), — а `display:contents`
   разпръскваше самите <p> по решетката на секцията, за да може всеки да си
   заеме колони. Сега кутията е истински елемент, взима целия ред и си носи
   собствена решетка от две колони; gap-ът е същият като на родителя, тъй че
   двете половини съвпадат с колоните отгоре.

   ПРОМЯНА СПРЯМО МАКЕТА, и важи и за HERA: една стилница, без разлики между
   страниците на апаратите. */
.about .body-copy{grid-column:1 / -1;display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-5)}
.about .body-copy p{line-height:1.5;margin:0}
.about .maker-link{grid-column:1;margin-top:var(--space-5)}
.maker-link{display:inline-flex;align-items:center;gap:var(--space-2);font-size:0.9rem;color:var(--text-secondary);text-decoration:none;border-bottom:1px solid var(--border-default);padding-bottom:2px}
.maker-link:hover{color:var(--text-primary);border-color:var(--border-strong)}

/* ---- Вариантът със стек: параграфът вляво, картите вдясно ----
 *
 * Картата (.ac) е в components.css — ползва я и mfr-about. Тук е само
 * подредбата ѝ на тази страница и двата прага, на които стекът каца.
 * Скриптът е scripts/components/card-stack.js. */
:scope{
  /* Нивото, на което каца активната карта. Скриптът го смята от sticky top на
     параграфа; тази стойност важи само докато не е мерил. */
  --ac-top:148px;
  /* Височината на свитата лента — същата като при производителите. Едно време
     тук стоеше 128, за да се побере цялото число; това отпадна, щом акцентът
     започна да гасне заедно с фона (--ac-fade). Сгъната, картата вече показва
     само кръгчето с иконката, числото си е отишло само, и стекът може да е
     толкова събран, колкото е отсреща. */
  --ac-step:84px;
  /* Под фиксираната лента, не под 48px. Тук лийдът е САМО параграф, тоест
     скриптът смята --ac-top = този top + 0 и картите биха кацали на 48px —
     зад лентата, която е 96px висока и с z-index 100. При производителите
     същите 48px работят, защото над параграфа стои заглавие и отстоянието до
     него вдига прага до 151px.

     84 + space-5 е константата, с която сайтът вече разчиства лентата —
     manufacturer-band и .cos-lead я ползват за scroll-margin-top. */
  --about-lead-top:calc(84px + var(--space-5))}

/* `display:contents` разпръсква параграфите по решетката — правилното, докато
   текстът Е съдържанието. Със стек параграфът е ЕДНА колона и трябва да е
   истински елемент, за да може да е sticky. */
/* Отстояние под заглавието, ВЪПРЕКИ бележката горе за двойното броене.
   Там margin-bottom беше грешка, защото само дублираше разстоянието, което
   решетката вече дава. Тук е решение: заглавието е на цял ред самò и трябва
   да се отдели от това, което започва под него — параграфа и стека
   едновременно. Решетката не може да го направи, без да разреди и реда с
   USP картите отгоре. */
.about--stack .lede{margin-bottom:var(--space-7)}
.about--stack .body-copy{display:flex;flex-direction:column;gap:var(--space-5);
  grid-column:1;align-self:start;position:sticky;top:var(--about-lead-top)}
/* Първата карта тръгва ПОД параграфа и се качва, докато се изравни с него —
   там е нейният sticky праг и там я застига следващата. Дотук колоната с
   картите започваше на същия ред като параграфа, тоест първата карта беше
   изравнена с него от самото начало и стекът нямаше откъде да дойде.

   Скриптът мери височината на параграфа и я подава като --stack-lead-h;
   fallback-ът е измереното (171px при две изречения), за да не подскочи, ако
   закъснее. Същото прави и mfr-about — там мярката е на целия лийд, защото
   там заглавието е вътре в него. */
.about--stack .about__cards{grid-column:2 / -1;padding-top:calc(var(--stack-lead-h, 171px) + var(--space-7))}

/* Отзивчивите правила за тази секция. Стояха в cta.css, извън всякакъв scope —
   остатък от разделянето на слетите стилове. Там не важаха: некоширано
   `.x` губи от коширано `.x` в собствения му файл, защото близостта по scope
   тежи над реда, а медия заявката не добавя тежест. */
@media (max-width:1024px){
.about{grid-template-columns:1fr}
.about .lede{grid-column:1}
/* Половинките си отиват заедно с колоните на секцията. */
.about .body-copy{grid-template-columns:1fr}
/* Една колона: параграфът и картите вече са един под друг, тъй че и бутането
   надолу, и sticky лийдът отпадат — иначе параграфът щеше да виси залепен за
   горния ръб, докато картите минават под него. */
.about--stack .body-copy, .about--stack .about__cards{grid-column:1}
.about--stack .body-copy{position:static}
.about--stack .about__cards{padding-top:0}
}
@media (max-width:768px){
/* Лийдът спира да е sticky и картите тръгват под него — същото, което прави и
   mfr-about на тесен екран. Прагът е по-нисък, защото тук над стека стоят и
   USP картите, и лийдът. */
/* По същата причина като горе — акцентът гасне, лентата носи само кръгчето —
   прагът е този на производителите. */
:scope{--ac-top:calc(var(--space-9) * 2.5);--ac-step:70px}
.about--stack .body-copy{position:static}
}
}

/* ═══ sections/attachments ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .attachments-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.attachments-sec) {
/* ---- Специализирани накрайници ---- */
:scope{position:relative;padding:var(--section-pad) 0}
.attachments-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-5);padding:0 var(--page-pad,48px) var(--space-6)}
.attachments-head h2{font-size:var(--text-h3);margin:0}
.at-nav{display:flex;gap:var(--space-3)}
.at-nav icon-btn[disabled]{opacity:.35;pointer-events:none}
.at-strip{display:flex;gap:var(--space-5);overflow-x:auto;scroll-behavior:smooth;scrollbar-width:none;padding:0 var(--page-pad,48px) var(--space-3)}
.at-strip::-webkit-scrollbar{display:none}
.at-strip attachment-serie{flex-shrink:0;--serie-h:560px;--serie-lead-w:min(880px,62vw);--serie-item-w:min(360px,27vw)}
@media(max-width:1023px){
.at-strip attachment-serie{--serie-h:70vh;--serie-item-w:calc(100vw - 3 * var(--page-pad,48px));--serie-lead-w:var(--serie-item-w)}
}
/* без сивия fill на image-slot зад продуктовите рендери */
.serie-item__photo image-slot::part(frame){background:transparent}

/* <image-slot> was the design's authoring control for dropping images in;
   it is not shipped, so these panels hold a plain <img>. The design sized
   the slot and only the slot — case-card and zone-card list `img` beside
   it, these two do not — so the image fell back to its intrinsic size. The
   nozzle renders are ~4800px wide, which burst the strip and pushed the
   whole page sideways.

   `fit="contain"` was the attribute on the slot; object-fit is the same
   thing for an img. */
.serie-item__photo img,
.asc-card__photo img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}
}

/* ═══ sections/catalog ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .grid.
 *
 * One root now, not two. The old chip bar was a sibling .filters, so this file
 * legitimately had both; aparati-v2 replaced it with the tab bar and panels,
 * whose CSS lives in tokens/filters.css because .fzone wraps BOTH the bar and
 * this grid and a scope here could not reach it. */
@scope (.grid) {
/* Редовете са с фиксирана височина, за да съвпадат тесните и широките карти;
   max() пази картата използваема и на нисък екран. */
:scope.grid{
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: max(72vh, 440px);
  gap: var(--grid-gap, var(--space-5));
  padding: 0 var(--page-pad, 48px) var(--section-pad);
}
:scope.grid product-card-wide{ grid-column: span 2; }

/* Само за карта БЕЗ своя снимка на сцена.
   Апарат със собствена страница носи пейзажна снимка (hero.background) и
   получава .scene: тя покрива картата. Каталожните записи имат само продуктова
   изрезка, портретна (1172×1303) — тя се побира цяла и се долепва вдясно, за да
   остане мястото отляво за стъкления панел. */
:scope.grid .card.wide:not(.scene) .card__photo{ object-position: right center; padding: var(--space-5) 0; }
.grid product-card-compact,
:scope.grid product-card-wide{ display: block; min-width: 0; }

/* Скрито от филтрите. `display:none` изважда картата от решетката, така че
   останалите се преподреждат — точно каквото се иска. */
:scope.grid > [hidden]{ display: none; }
.grid-empty{ grid-column: 1 / -1; align-self: start; margin: 0;
  color: var(--text-secondary); font-size: 1rem; }

@media (max-width: 1024px){
:scope.grid{ grid-auto-rows: max(58vh, 440px); }
}

/* Мобилната подредба на каталога. Стоеше в page-head.css, некоширана, като
   `.grid{...}` — и не важеше: `:scope.grid` горе е и по-специфично, и по-близко
   по scope, а медия заявката не добавя тежест. Резултатът беше решетка, която
   на телефон остава на три колони с фиксирани редове и картите се застъпват.
   Тук важи, защото се мери със същото `:scope`. */
@media (max-width: 768px){
:scope.grid{ grid-template-columns: repeat(2, 1fr); grid-auto-rows: auto; }
/* Обратното на десктопа: тук тясната карта заема целия ред, защото широката
   вече е с ръст по съдържание. */
:scope.grid product-card-compact{ grid-column: span 2; }
}
}

/* OUTSIDE the scope, necessarily: these selectors start above the root
 * (body:has(...)), beside it (an adjacent sibling), or target an element in a
 * DIFFERENT section. @scope only reaches DOWNWARD from its root, so inside the
 * block they would match nothing at all — silently. */

/* ═══ sections/categories ═══ */
/* Апарати v4 — категориите. Scoped към собствения си корен: правило оттук не
 * стига до нищо извън .devcats.
 *
 * Секцията не рисува почти нищо ново. Таговете са .tag--dark на дизайн
 * системата, радиусите и отстъпите са токени, а картата е същата анатомия
 * като .card.compact — снимка, тагове горе, име и абзац долу. Тук стои само
 * това, което ги ПОДРЕЖДА: закаченият lead, решетката над него и двата кадъра
 * на картата. */
@scope (.devcats) {

:scope{
  /* Докъде се закача lead-ът. Менюто се скрива при скрол надолу, тоест точно
     когато закачането почва, затова резервът е въздух, а не височина на
     лента. */
  --devcat-stick: var(--space-6);
  /* Дизайнът дава lead-а като съотношение, не като височина: 8/3 показва
     един и същ кадър на всяка ширина. */
  --devcat-lead-ratio: 8 / 3;
  display: flex; flex-direction: column;
  gap: var(--space-7);
  padding: var(--section-pad) var(--page-pad, 48px);
}

/* ---- Категорията: закачен lead, решетка отгоре ---- */
/* Обхватът на закачането е самата категория: lead-ът стои, докато нейната
   решетка минава, и се пуска, щом свърши. Оттам и подредбата — един sticky в
   един контейнер, а не един за цялата страница. */
.devcat{ position: relative; }

/* Двете колони са по 50%: заглавие вляво, процедури вдясно, подравнени горе.
   Снимката е <img> под тях, а не background — тя е съдържание на категорията,
   различно за всяка, и markup-ът трябва да я назовава. */
.devcat__lead{
  position: sticky; top: var(--devcat-stick); z-index: 0;
  display: grid; grid-template-columns: 1fr 1fr;
  align-items: start; gap: var(--space-5);
  aspect-ratio: var(--devcat-lead-ratio);
  padding: var(--space-6);
  border-radius: var(--radius-lg);
  overflow: hidden;
}
.devcat__bg{
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
}
.devcat__title{ position: relative; z-index: 1; font-size: var(--text-h2); margin: 0; }
/* Таговете се събират вдясно и се пренасят надолу, ако не стигне ширина.
   .tags на компонента е nowrap с overflow:hidden — правилно за един ред в
   карта, но тук отрязва процедура, а процедурите са съдържание. */
.devcat__tags{ position: relative; z-index: 1; justify-self: end; }
.devcat__tags .tags{ flex-wrap: wrap; justify-content: flex-end; overflow: visible; }

/* Решетката покрива lead-а, докато се качва. Бялото е нейно, не на
   страницата: то е това, което скрива снимката отдолу. Радиусът е само горе —
   долният ръб никога не се вижда над нещо. */
/* Съотношението на картата следва броя РЕНДИРАНИ колони, затова живее на
   решетката, а не на секцията: тя е най-близкият общ родител на картите, който
   знае колко са. Всеки праг по-долу го преобявява, защото при него се сменя
   точно това — не ширината на картата, а на колко колони е разбита решетката.

   Затова и не е на :scope с един overwrite: наследяването взима НАЙ-БЛИЗКИЯ
   родител, който го обявява, тоест решетката пак щеше да бие секцията и двата
   реда щяха да се бият вместо да се допълват. */
.devcat__grid{
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: repeat(var(--devcat-cols, 3), minmax(0, 1fr));
  gap: var(--space-5);
  margin-top: var(--space-4);
  padding: var(--space-6);
  background: var(--white);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}

/* ЕДИНСТВЕНОТО изключение от 3/4: решетка от две колони. Там картата е широка
   и квадратът ѝ стои; при три колони и при една тя е тясна и 3/4 е нейната
   мярка — резервата в aspect-ratio на самата карта. */
.devcat__grid[data-cols="2"]{ --dcard-ratio: 1 / 1; }
/* Трите колони стесняват картата, а с нея и всичко в нея — иначе заглавието
   изяжда реда, който абзацът трябва да получи. */
.devcat__grid[data-cols="3"] .dcard__name{ font-size: var(--text-h5); }

/* Тук остава само ПОДРЕДБАТА на картите. Самата карта се премести в
   styles/components.css: ползва я и лентата „Разгледай още" на страницата на
   апарат, а @scope стига само надолу от един корен. Същият ход и същата
   причина като при .cos-lead. */

/* ---- Под 1024px: три колони стават две ---- */
@media (max-width: 1024px){
.devcat__grid{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* data-cols остава каквото е — то е решението на документа, не на екрана — но
   тук ВСЯКА решетка рендира две колони, тоест всяка карта минава на квадрата.
   Изброени са двата селектора, защото по-специфичният отвън иначе би надделял
   над голия. */
.devcat__grid,
.devcat__grid[data-cols="2"]{ --dcard-ratio: 1 / 1; }
.devcat__title{ font-size: var(--text-h3); }
}

/* ---- Под 768px ---- */
/* Една колона, и lead-ът се изправя: 8/3 на телефон е ивица, в която нито
   заглавието, нито процедурите се побират. Двете колони стават редове.

   Секцията губи страничния си отстъп ИЗЦЯЛО. Не с отрицателен марж върху
   lead-а — така само той щеше да излезе до ръба — а от самата секция, така че
   и решетката под него тръгва от там. Картите остават 16px навътре заради
   собствения ѝ padding, тоест стават 32px по-широки, отколкото бяха. */
@media (max-width: 768px){
/* Lead-ът лепне плътно до горния ръб — на телефон въздухът над него е само
   изгубена височина от снимката. */
:scope{ gap: var(--space-6); padding-inline: 0; --devcat-stick: 0px; }
.devcat__lead{
  grid-template-columns: 1fr;
  /* Редовете се ПАКЕТИРАТ горе. Без това двата auto реда се разтягат на
     половин lead всеки — align-items ги подравнява в рамките на разтегнатия
     ред, не го свива — и таговете увисваха по средата на снимката вместо
     точно под заглавието. При 8/3 на десктоп редът е един и разликата не се
     вижда; при 4/6 лийдът е 518px висок и се вижда веднага. */
  align-content: start;
  aspect-ratio: 4 / 6;
  padding: var(--space-5);
}
.devcat__tags{ justify-self: start; }
.devcat__tags .tags{ justify-content: flex-start; }
/* Една колона. Кутията се удължава: `contain` мери по ТЯСНАТА страна, тоест
   апаратът е широк колкото картата и височината над него е свободна — по-висока
   кутия не го уголемява, а го отмества нагоре, далеч от текста. На телефон
   текстът е три реда върху една колона и иска точно този въздух. */
.devcat__grid,
.devcat__grid[data-cols="2"]{ --dcard-ratio: 3 / 4; }
.devcat__grid{
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-4);
  padding: var(--space-4);
}
.devcat__title{ font-size: var(--text-h3); }
.devcat__grid[data-cols="3"] .dcard__name,
.dcard__name{ font-size: var(--text-h4); }
}

}

/* ═══ sections/compare ═══ */
/* L Medical — the range comparison (sections/compare.liquid).
 *
 * Ported from serie-rf-v2, after a first version I built from the content spec
 * and got structurally wrong in three ways worth stating, because each one was
 * a bug I then went and solved:
 *
 * A ROW LABEL is a centred heading ABOVE its three cells, not a column beside
 * them. Both the column heads and the cells are therefore the same plain
 * three-column grid with the same page padding, and they line up with no
 * arithmetic. My label column made them disagree by 108px, and the
 * `--cmp-label-w` variable and spacer element I added to fix that are gone
 * with it.
 *
 * A COLUMN HEAD is a fixed 96px bar. It never changes size, so nothing can
 * collapse and the page height cannot move while you read — which is the bug
 * that produced backward scrolling and a nav that popped out. There is no
 * wrapper holding a reserved height any more, because nothing needs one.
 *
 * `.cmp-cols` is NOT the heads. It is three empty spans, fixed behind the page
 * at z-index -1, putting a gradient down the odd columns; the script fades
 * them in while the comparison holds the viewport.
 */
@scope (.cmp) {
  :scope {
    position: relative;
    /* The column head's height. The banner preset's ratio is cut to match it,
       so the crop smartcrop picked is the crop you see rather than a further
       centre-crop of it — keep the two in step. */
    --cmp-head-h: 132px;
  }

  /* ---------- the shared three-column grid ---------- */
  /* One definition for the heads and for every row's cells. That is what keeps
     a cell under its own appliance. */
  .cmp-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-1);
    padding-inline: var(--page-pad);
  }

  /* ---------- the column striping ---------- */
  /* Fixed and behind everything, so it reads as the page's own columns rather
     than as part of the table. pointer-events off: it is under the content but
     covers the viewport. */
  .cmp-cols {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
    padding-inline: var(--page-pad);
    opacity: 0;
    transition: opacity .6s cubic-bezier(.15, 0, 0, 1);
  }
  .cmp-cols.is-on { opacity: 1; }
  .cmp-cols span:nth-child(odd) {
    background: linear-gradient(0deg, rgba(242, 242, 242, .36) 0%, rgba(255, 255, 255, 1) 100%);
  }

  /* ---------- the column heads ---------- */
  .cmp-sticky {
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--white);
    padding: var(--space-6) 0;
  }
  .cmp-sticky .cmp-grid { gap: var(--space-4); }
  .cmp-card {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    height: var(--cmp-head-h);
    padding: 0 var(--space-4) 0 var(--space-5);
    border-radius: var(--radius-md);
    overflow: hidden;
    text-decoration: none;
    color: var(--ink);
  }
  /* The design's `background-size: cover` as an element, because the photograph
     is document content. The POSITION is not here: each card carries its own
     `object-position` inline, from the document's `focus`, because a nearly
     square room in a 3.57:1 slot has to be told which band to show and the
     answer differs per photograph. This is only the fallback. */
  .cmp-card__photo {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center 50%;
  }
  .cmp-card__title {
    position: relative;
    z-index: 1;
    font-family: var(--font-display);
    font-weight: var(--weight-heading);
    font-size: var(--text-h5);
    line-height: 1.2;
  }
  .cmp-card icon-btn { position: relative; z-index: 1; }

  /* The phone's head is three separate layers in the markup, off above the
     breakpoint. Declared here so the default is "not there" and the media
     query only has to turn them on — the same way the design does it. */
  .cmp-mbar,
  .cmp-cards--m,
  .cmp-fronts--m { display: none; }

  /* ---------- rows ---------- */
  .cmp-h {
    text-align: center;
    font-family: var(--font-display);
    font-weight: var(--weight-heading);
    font-size: var(--text-h3);
    margin: var(--space-8) 0 var(--space-6);
  }
  .cmp-row { position: relative; padding: var(--space-5) 0; }
  .cmp-row__label {
    text-align: center;
    margin: 0 0 var(--space-4);
    padding: 0 var(--page-pad);
    font-weight: var(--weight-body-semibold);
    font-size: 1rem;
    line-height: 1.3;
  }
  .cmp-cell {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    text-align: center;
    min-width: 0;
  }
  .cmp-cell__value { font-size: .9rem; line-height: 1.4; text-wrap: pretty; }

  /* ---------- yes / no cells ---------- */
  /* One component, three states — ui/check-pill, restyled per cell.
   *
   * A "yes" keeps the component's own ✓ on accent. A "no" is PINK with a cross,
   * which is the design's answer and not the muted grey dash I had first: at a
   * glance down a column, absence has to read as absence rather than as a
   * fainter presence.
   *
   * The cross is plus.svg rotated 45°, not a glyph. The mark character is a
   * space, so the circle is empty and the icon is masked over it — one icon
   * doing two jobs, and no font dependency for a symbol that has to line up
   * with a ✓ of the same size. */
  .cmp-cell check-pill { padding: var(--space-2); gap: 0; max-width: none; }
  /* The cells keep the glass the pill used to have for everyone.
   check-pill went ink in components.css so it can be read on a photograph;
   here colour carries the meaning — a pale yes against a pink no — and an ink
   body would make every yes cell read as a button. Stated once for both the
   cells and the temperature row, which is the other place in this section
   that leans on the base look. */
.cmp-cell check-pill,
.usp-temp check-pill {
  background: rgba(211, 229, 229, .45);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  /* The full shorthand: the base pill has no border at all now, so a colour
     on its own would have nothing to paint. */
  border: 1px solid var(--accent-200);
  color: var(--ink);
}

/* The mark too, for the same reason: the base circle went ink when the pill
   inverted, and a black circle in every yes cell is not this table. `.cp--no`
   carries an extra class, so its pink circle still wins over this. */
.cmp-cell check-pill .check-pill__mark,
.usp-temp check-pill .check-pill__mark {
  background: var(--accent-200);
  color: var(--ink);
}

.cmp-cell check-pill.cp--no {
    background: rgba(236, 102, 134, .45);
    border-color: var(--error-300);
  }
  .cmp-cell check-pill.cp--no .check-pill__mark {
    background: var(--error-300);
    position: relative;
  }
  .cmp-cell check-pill.cp--no .check-pill__mark::after {
    content: '';
    position: absolute;
    inset: 0;
    background: var(--ink);
    -webkit-mask: url(../media/raw/icons/plus.svg) no-repeat center/14px;
    mask: url(../media/raw/icons/plus.svg) no-repeat center/14px;
    transform: rotate(45deg);
  }
  /* A "no" that says why: the text comes back, so the padding does too. */
  .cmp-cell check-pill.cp--text {
    padding: var(--space-2) var(--space-4) var(--space-2) var(--space-2);
    gap: var(--space-2);
    font-size: .75rem;
  }

  /* ---------- the temperature accent ---------- */
  /* Three cells in the SAME grid as every row above, so each figure keeps
     standing under its own appliance. It was a panel — accent background,
     rounded, with a heading and a lede over three small labels — and that is
     not what the design does: it makes the accent look like a pull quote
     ABOUT the table instead of the table's last line. No box, no heading, and
     nothing marking a winner; 45 beside two 42s carries it.

     `.cmp-usp.cmp-grid` and not `.cmp-usp`: the grid is on the same element,
     and its `gap: var(--space-1)` would otherwise win on source order. */
  .cmp-usp { margin-top: var(--space-8); }
  .cmp-usp.cmp-grid { gap: var(--space-6); }
  .usp-temp { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
  /* The figure reads as a temperature: the mark is the thermometer icon rather
     than a degree sign, so it matches the ✓ and ✕ above it in weight. */
  .usp-temp check-pill { font-size: var(--text-h5); padding-right: var(--space-5); }
  .usp-temp check-pill .check-pill__mark::before {
    content: "";
    width: 14px;
    height: 14px;
    background: var(--ink);
    -webkit-mask: url(../media/raw/icons/temp.svg) no-repeat center/contain;
    mask: url(../media/raw/icons/temp.svg) no-repeat center/contain;
  }
  .usp-temp__title {
    font-family: var(--font-display);
    font-weight: var(--weight-heading);
    font-size: var(--text-h6);
    line-height: 1.3;
    margin: 0;
    max-width: 24ch;
    text-align: center;
  }

  .cmp-end { height: 1px; }

  /* ---------- phone ---------- */
  /* THE COLUMNS STAY. This used to drop everything to one column and label
     each cell with its appliance — one set of rows, reflowed. It reads as a
     list of three appliances repeated forty times, and a comparison that
     cannot be compared side by side is not one. The design keeps three
     columns for every row whose cell is a VALUE, and drops to one only where
     the cell is a sentence; those rows are named in the document.

     The head is replaced rather than reflowed, because it is a different
     object here — three layers, in this order:

       .cmp-mbar     a white strip, sticky at the very top, pulled back out of
                     the flow by a negative margin exactly its own height. It
                     paints nothing. It is what the rows disappear BEHIND.
       .cmp-cards--m the pictures, in normal flow, which scroll away.
       .cmp-fronts--m the names, sticky, lifted over the pictures' lower edge
                     by a negative top margin, and all that remains. */
  @media (max-width: 768px) {
    :scope {
      --mcard-h: 134px;
      --mfront-h: 57px;
      --mfront-top: 12px;
      --mbar-h: calc(var(--mfront-top) + var(--mfront-h) + var(--space-3));
    }
    .cmp-cols { display: none; }
    .cmp-sticky { display: none; }

    .cmp-mbar {
      display: block;
      position: sticky;
      top: 0;
      z-index: 4;
      height: var(--mbar-h);
      margin: var(--space-6) 0 calc(-1 * var(--mbar-h));
      background: var(--white);
    }

    .cmp-cards--m { display: grid; gap: var(--space-3); position: relative; z-index: 5; }
    .cmp-mcard {
      position: relative;
      display: block;
      height: var(--mcard-h);
      border-radius: var(--radius-md);
      overflow: hidden;
      /* Showing through wherever an appliance has no picture yet. */
      background: var(--grey-200);
    }
    /* An <img> rather than the design's background-image, for the reason the
       desktop bar gives: the picture is document content. */
    .cmp-mcard__photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
    .cmp-mcard__arrow {
      position: absolute;
      top: var(--space-3);
      right: var(--space-3);
      z-index: 1;
      width: 16px;
      height: 16px;
      background: var(--ink);
      -webkit-mask: url(../media/raw/icons/arrow-right.svg) no-repeat center/contain;
      mask: url(../media/raw/icons/arrow-right.svg) no-repeat center/contain;
    }

    .cmp-fronts--m {
      display: grid;
      gap: var(--space-3);
      position: sticky;
      top: var(--mfront-top);
      z-index: 6;
      margin-top: calc(-1 * var(--mfront-h));
      /* The layer spans the full width and sits over the pictures; only the
         panels themselves take the pointer back. */
      pointer-events: none;
    }
    .cmp-mfront {
      height: var(--mfront-h);
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
      padding: 0 var(--space-2);
      text-decoration: none;
      color: var(--ink);
      background: rgba(211, 229, 229, .45);
      -webkit-backdrop-filter: blur(6px);
      backdrop-filter: blur(6px);
      border: 1px solid var(--accent-200);
      border-radius: var(--radius-md);
      font-family: var(--font-display);
      font-weight: var(--weight-heading);
      font-size: var(--text-h6);
      line-height: 1.2;
      pointer-events: auto;
    }

    /* A value column is ~100px wide here, so the text stacks inside the cell. */
    .cmp-table--text .cmp-cell {
      font-size: .85rem;
      flex-direction: column;
      align-items: center;
      text-align: left;
    }

    /* The exception: full-width rows, each cell headed by its appliance. */
    .cmp-table--text .cmp-row__cells--stack { grid-template-columns: 1fr; gap: var(--space-4); }
    .cmp-table--text .cmp-row__cells--stack .cmp-cell {
      align-items: flex-start;
      justify-content: flex-start;
      text-align: left;
      padding-inline: 0;
    }
    .cmp-table--text .cmp-row__cells--stack .cmp-cell::before {
      content: attr(data-device);
      font-weight: var(--weight-body-semibold);
      font-size: .75rem;
      color: var(--ink);
      line-height: 1.2;
      margin-bottom: var(--space-1);
    }

    .cmp-usp.cmp-grid { grid-template-columns: 1fr; }
  }

  @media (prefers-reduced-motion: reduce) {
    .cmp-cols { transition: none; }
  }
}

/* ═══ sections/consumables ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .cons-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.cons-sec) {
/* ---- Консумативи: тясна текстова колона + широки карти ---- */
:scope{padding:var(--section-pad) var(--page-pad,48px)}
:scope h2{font-size:var(--text-h3);margin:0 0 var(--space-6)}
.consumables{display:grid;grid-template-columns:2fr 1fr;gap:var(--space-5);align-items:start}
.cons-aside{position:sticky;top:var(--space-6);min-height:90vh;border-radius:var(--radius-lg);overflow:hidden;display:flex;flex-direction:column;gap:var(--space-6);padding:var(--space-6);background:var(--white) url("../derived/web/media/web/backgrounds/beauty-method.webp") center/cover no-repeat;color:var(--ink)}
.cons-aside__bg{position:absolute;inset:0;z-index:0}
.cons-aside>h2{position:relative;z-index:2;font-size:var(--text-h3);margin:0}
.cons-aside::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;background:linear-gradient(to top,rgba(255,255,255,.8),rgba(255,255,255,0) 55%)}
.cons-aside__tags{position:relative;z-index:2;display:flex;flex-wrap:wrap;gap:var(--space-2)}
.cons-aside__body{position:relative;z-index:2;margin-top:auto;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-3)}
.cons-aside__body h4{font-size:var(--text-h4);margin:0}
.cons-aside__body p{margin:0;color:var(--ink);max-width:48ch}
/* По-малкото заглавие над картите — „Разходна норма за процедура". */
.cost-sub{font-size:var(--text-h5);margin:0 0 var(--space-4)}

/* Една карта на КАТЕГОРИЯ терапии, с няколко норми вътре. Дотук картата беше
   ЕДНА норма и трите се редяха една под друга; сега броят им е три и всяка е
   висока, затова остават в колона. */
/* Списъкът със съвместими продукти. Самият ред е в styles/product-row.css —
   тук е само колоната и въздухът под нея, преди заглавието на нормата. */
.cons-products{display:flex;flex-direction:column;margin:0 0 var(--space-7)}
.cost-grid{display:grid;grid-template-columns:1fr;gap:var(--space-4)}
.cost-card{background:var(--surface-accent-soft);border-radius:var(--radius-md);padding:var(--space-5)}
.cost-card h4{font-size:var(--text-h5);margin:0 0 var(--space-4)}

.cost-rows{margin:0;display:flex;flex-direction:column;gap:var(--space-4)}
/* Име и състав вляво, цена вдясно, на една базова линия. `align-items:baseline`,
   не center: цената е с друг кегел и центрирана би плувала спрямо името. */
.cost-row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-5)}
/* Чертата разделя нормите ВЪТРЕ в картата — между картите разделя фонът. */
.cost-row + .cost-row{border-top:1px solid var(--accent-200);padding-top:var(--space-4)}
.cost-row dt{margin:0;min-width:0}
.cost-row dd{margin:0;flex:0 0 auto;text-align:right}
.cost-card .c-name{font-weight:var(--weight-body-semibold);display:block}
.cost-card .c-detail{display:block;font-size:0.85rem;color:var(--text-secondary);line-height:var(--leading-body);margin-top:var(--space-1)}
.cost-card .c-price{font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h4);line-height:1;white-space:nowrap}
/* Мерната единица пада на свой ред: „2,23 – 3,19 € / процедура" на един ред
   изяжда половината карта, а двете са различни неща — число и мярка. */
.cost-card .c-price small{display:block;font-family:var(--font-body);font-weight:var(--weight-body-regular);font-size:0.85rem;color:var(--text-secondary);margin-top:var(--space-1)}
.cost-note{font-size:0.8rem;margin:var(--space-4) 0 var(--space-5)}

/* Отзивчивите правила за тази секция. Стояха в cta.css, извън всякакъв scope —
   остатък от разделянето на слетите стилове. Там не важаха: некоширано
   `.x` губи от коширано `.x` в собствения му файл, защото близостта по scope
   тежи над реда, а медия заявката не добавя тежест. */
@media (max-width:1024px){
.consumables{grid-template-columns:1fr}
.cost-grid{grid-template-columns:1fr}
/* `relative`, не `static` — същата причина като при .tech-aside: вътре стоят
   `.cons-aside__bg` и `::after`, и двете `inset: 0`, и без котва се мерят
   спрямо <main>, тоест се разпъват по цялата страница. */
.cons-aside{position:relative;top:auto}
}
/* На тесен екран името и цената се изправят: съставът е цяло изречение и на
   един ред с цената остава колона от по две думи. */
@media (max-width:600px){
.cost-row{flex-direction:column;gap:var(--space-2)}
.cost-row dd{text-align:left}
.cost-card .c-price small{display:inline;margin-left:var(--space-1);margin-top:0}
}
}

/* ═══ sections/contact-cta ═══ */
/* Scoped to this section's own root: a rule here cannot reach an
 * element outside .cta. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another. */
@scope (.cta) {
/* ---- Акт 3: CTA ---- */
/* Горното поле трябва да побере логото в увеличения му размер (104px × 2.6),
   за да не влиза върху картите, докато се смалява.

   The bottom is NOT the top's mirror, and was: 4x read as symmetry rather than
   as a measurement. Nothing sits below this section — it is the last child of
   main — so the margin is pure trailing space, and the footer already brings
   96px of padding-top of its own. 4x put 416px between the buttons and the
   footer's first line (256 margin + 64 padding + 96 footer). One unit leaves
   224, which is breathing room rather than a gap. */
:scope{margin-top:calc(var(--section-pad) * 4);margin-bottom:var(--section-pad);padding:var(--section-pad) var(--page-pad,48px) var(--space-8);
  display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-5)}
.cta-logo-wrap{width:104px;height:104px}
.cta-logo{display:block;width:104px;height:104px;transform-origin:left bottom}
:scope h2{margin:0;font-size:var(--text-h2);line-height:1.1;max-width:28ch}
.cta-actions{display:flex;flex-wrap:wrap;gap:var(--space-3)}
.cta-actions .lmed-btn{text-decoration:none}

@media (max-width:768px){
  :scope h2{font-size:var(--text-h3)}
}
}

/* ═══ sections/contact-details ═══ */
/* Scoped to this section's own root: a rule here cannot reach an
 * element outside .contacts-grid. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another. */
@scope (.contacts-grid) {
/* ---- Акт 1–2: полето от карти ---- */
:scope{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-5);
  align-items:start;padding:calc(84px + var(--space-5)) var(--page-pad,48px) 0}
.contacts-col{display:flex;flex-direction:column;gap:var(--space-5);min-width:0}

/* Общото стъкло на еднократните карти (Плащане, Работно време).
   Блурът е на ::before — transform-ите на колоната не го засягат. */
.c-card{position:relative;border:1px solid var(--ink);border-radius:var(--radius-md);
  padding:var(--space-4)}
.c-card::before{content:"";position:absolute;inset:0;z-index:-1;border-radius:inherit;
  background:rgba(255,255,255,.45);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.c-card > h2{margin:0;font-size:var(--text-h5);line-height:1.2}

/* Плащане */
.card--payment{display:flex;flex-direction:column;justify-content:space-between;
  gap:var(--space-8);min-height:456px}
.pay-rows{display:flex;flex-direction:column}
.pay-row{display:flex;align-items:center;gap:var(--space-4);padding:var(--space-3) 0}
.pay-row + .pay-row{border-top:1px solid var(--border-default)}
.pay-main{flex:1 1 auto;min-width:0}
.pay-label{font-size:1rem;line-height:1.4;color:var(--text-secondary)}
.pay-value{font-family:var(--font-display);font-weight:var(--weight-heading);
  font-size:1.15rem;line-height:1.35;word-break:break-word}
.pay-value.is-ph{font-family:var(--font-body);font-weight:var(--weight-body-regular);color:var(--grey-500)}
.pay-note{font-size:1rem;line-height:1.4;color:var(--accent-900);opacity:0;
  transition:opacity var(--duration-base) var(--ease-standard)}
.pay-row.is-copied .pay-note{opacity:1}
.is-off{opacity:.35;pointer-events:none}

/* Работно време */
.card--hours{display:flex;flex-direction:column;gap:var(--space-4)}
.hours-rows{display:flex;flex-direction:column}
.hours-row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-4);
  padding:var(--space-2) 0}
.hours-row + .hours-row{border-top:1px solid var(--border-default)}
.hours-row dt{font-size:1rem;color:var(--text-secondary)}
.hours-row dd{margin:0;font-family:var(--font-display);font-weight:var(--weight-heading);font-size:1.15rem}

/* Имейлът и телефонът в картата на отдела са текст, не подчертани връзки.
   Дизайнът ги рендира като обикновен текст — линковете ги добавихме ние, за
   да са кликаеми на телефон. Афордансът го носят двата бутона вдясно на
   картата, така че подчертаването само шуми в плътен блок с данни.
   Hover-ът остава: обратната връзка не е за сметка на вида. */
.cc-line a{ text-decoration: none; }
.cc-line a:hover{ color: var(--link-hover); }

/* ---- Breakpoints ---- */
@media (max-width:1024px){
:scope{grid-template-columns:1fr 1fr}
.card--payment{min-height:0}
}

@media (max-width:768px){
  :scope{grid-template-columns:1fr;padding-top:calc(72px + var(--space-4))}
  /* Обвивките на колоните се разтварят; order подрежда картите. */
  .contacts-col{display:contents}
  .card--payment{order:1}
  .card--dept{order:2}
  .card--office{order:3}
  .card--service{order:4}
  .card--hours{order:5}
}
}

/* ═══ sections/cosmetics-brand ═══ */
/* Марката: закачен лийд и индексът с категориите, който се плъзга върху него.
 *
 * Самата карта-лийд е в components.css — ползват я две секции, а @scope стига
 * само надолу от един корен. Тук е само КЪДЕ се закача и колко е висока.
 *
 * Механиката е тази на sections/categories.css: лийдът е sticky, индексът е
 * след него в потока и с по-висок слой, така че покриването идва от скрола.
 * Оттук нататък двете страници на сайта, които правят това, го правят еднакво. */
@scope (.cos-brand-sec) {

:scope{
  /* Височината на лийда. Едно число, защото секцията ПОД тази — cosmetics-invite
     — се издърпва нагоре с точно толкова, за да се открие нейният лийд, докато
     белият индекс отгоре си отива. Двете не могат да се разминат само ако всяка
     си държи своето в една променлива; тази е нейната. */
  --cos-brand-lead-h: 85svh;
  position: relative; z-index: 1;
  padding: 0 var(--page-pad, 48px);
  /* БЕЗ отстъп отдолу, и това е важно. Тук стоеше `margin-bottom: 30vh` —
     „въздух след индекса" — но поканата отдолу се издърпва нагоре с
     отрицателен марж, а съседни маржове се СГЪВАТ: 30vh и -85svh дават -55vh,
     не -85vh.

     Цената беше точно тази, от която поканата се оплакваше: изпреварването ѝ
     падаше с 273px, тоест лийдът ѝ започваше да се показва, преди да се е
     закачил, и първите два-три сантиметра скрол го носеха със себе си.

     Въздухът и без това не се виждаше — поканата го покрива целия. */
}
.cos-lead{ position: sticky; top: var(--space-7); height: var(--cos-brand-lead-h); z-index: 0; }

/* Бялото е на индекса, не на страницата: то е това, което скрива лийда отдолу. */
.cos-cats{
  position: relative; z-index: 1;
  background: var(--white);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}

/* Категорията НЕ е карта. Разделя се от следващата с чертата под последния си
   ред, така че последователните категории се четат като един непрекъснат
   индекс, а не като поредица кутии. */
.cos-cat{
  display: grid; grid-template-columns: 5fr 7fr; gap: var(--space-5);
  padding: var(--space-6) 0 var(--space-7);
}
.cos-cat:last-of-type{ padding-bottom: 0; }

/* Лявата колона се закача самостоятелно и стои, докато списъкът ѝ минава. */
.cos-cat__side{
  position: sticky; top: var(--space-7); align-self: start;
  height: var(--cos-brand-lead-h);
  border-radius: var(--radius-lg); overflow: hidden;
  padding: var(--space-5);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-1);
}
.cos-cat__bg{ position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center; }
.cos-cat__side h3, .cos-cat__side p, .cos-cat__tags{ position: relative; z-index: 1; }
.cos-cat__side h3{ margin: 0; font-size: var(--text-h4); line-height: 1.25; }
.cos-cat__side p{ margin: 0; line-height: 1.5; color: var(--ink); max-width: 46ch; }
/* `margin-top: auto` ги лепи за дъното на закачената карта. */
.cos-cat__tags{ margin-top: auto; display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* minmax(0) на грида не стига — колоната трябва да може и сама да се свие. */
.cos-cat__index{ min-width: 0; }

/* Продуктовият ред (.cos-item) се пресели в styles/product-row.css, нескоупнат:
   ползва го и секцията с консумативите на апаратна страница, а @scope стига
   само надолу от един корен. Тук остава само колоната, в която той стои. */

/* ---- Серии без продуктов ред: домашната линия ---- */
.cos-serie-list{ display: flex; flex-direction: column; gap: var(--space-5); padding: var(--space-4); }
.cos-serie h4{ margin: 0 0 var(--space-2); font-family: var(--font-display);
  font-weight: var(--weight-heading); font-size: var(--text-h6); }
.cos-serie p{ margin: 0; line-height: 1.5; color: var(--ink); }
.cos-serie__link{ align-self: flex-start; display: inline-flex; align-items: center;
  gap: var(--space-2); font-size: 1rem; color: var(--text-secondary); text-decoration: none;
  border-bottom: 1px solid var(--border-default); padding-bottom: 2px; }
.cos-serie__link:hover{ color: var(--text-primary); border-color: var(--border-strong); }

/* ---- Съвместими апарати ---- */
.cos-compat{ margin-top: var(--space-6); }
.cos-compat h4{ margin: 0 0 var(--space-4); font-size: var(--text-h5); line-height: 1.25; }
.cos-compat__tags{ display: flex; flex-wrap: wrap; gap: var(--space-4); }

/* ---- Под 1024px: една колона ---- */
/* Страницата губи страничния си отстъп, защото индексът вече е през цялата
   ширина и рамка около него само стеснява текста. */
@media (max-width: 1024px){
:scope{ --cos-brand-lead-h: 80svh; padding: 0; }
.cos-lead{ top: var(--space-4); }
.cos-cat{ grid-template-columns: 1fr; }
/* Две закачени колони една над друга се задържат взаимно — тази се пуска. */
.cos-cat__side{ position: relative; top: auto; }
}

@media (max-width: 768px){
/* Съотношение, не височина. 52svh мереше екрана, тоест една и съща снимка
   излизаше различно висока на всеки телефон; 4/5 я мери спрямо ширината на
   колоната, която на телефон е самата страница. `height: auto` е нужно —
   стойността от блока по-горе би бита aspect-ratio. */
.cos-cat__side{ height: auto; aspect-ratio: 4 / 5; }
}

}

/* ═══ sections/cosmetics-brands ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .cos-brands. The bundle is one stylesheet on every page, so without
 * this a name like .grid or .cta would silently restyle another section. */
@scope (.cos-brands) {
/* ---- Двете марки ---- */
:scope{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);
  padding: var(--space-8) var(--page-pad, 48px); }
.cos-brand{ position: relative; display: block; height: var(--cos-brand-h, 80svh);
  border-radius: var(--radius-md); overflow: hidden;
  text-decoration: none; color: var(--ink);
  transform: translateZ(0); transition: transform .5s cubic-bezier(.14, 0, 0, 1); }
a.cos-brand{ will-change: transform; }
a.cos-brand:hover, a.cos-brand:focus-visible{ transform: scale(1.016); }
a.cos-brand:focus-visible{ outline: 2px solid var(--ink); outline-offset: 3px; }
.cos-brand__bg{ position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%; object-fit: cover; }

.cos-brand__stage{ position: absolute; inset: 0; z-index: 1; }
.cos-brand__prod{ position: absolute; left: var(--l); top: var(--t);
  height: var(--cos-brand-prod-h, 60%); width: auto; display: block; }

/* Горе вдясно, на височината на словомарката. Тялото получава отстъп отдясно,
   за да не мине текстът под етикета — стойността е приблизителна ширина на
   етикета, не точна: абзацът и без това е ограничен до 44ch.

   Нулите са спрямо ТЯЛОТО, което е негов родител и е закотвено на
   `--space-5` от ръбовете на картата — тоест същият ъгъл, в който етикетът
   стоеше и когато беше абсолютен спрямо самата карта. */
.cos-brand__origin{ position: absolute; z-index: 3; top: 0; right: 0; }
/* Етикетът е със СТАНДАРТНИЯ си кегел. Тук стоеше едрият вариант — копие на
   уголемяването, което hero-то на апарата прави на всичките си тагове
   (sections/hero.css) — но там то е част от общ ефект, а тук беше единственият
   уголемен таг на страницата и стърчеше. Hero-то не е пипано. */

.cos-brand__body{ position: absolute; z-index: 2;
  left: var(--space-5); right: var(--space-5); top: var(--space-5);
  padding-right: 12ch;
  bottom: calc(var(--space-5) * 2 + 48px);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-5); }
.cos-brand__body p{ margin: 0; line-height: var(--leading-body); max-width: 44ch; }
.cos-brand__pills{ display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); }

/* Словомарките са набрани, докато дойдат PNG-тата на марките. */
.cos-brand__wm{ color: var(--ink); }
.cos-brand__wm--tbm{ display: flex; flex-direction: column; gap: .42em; width: min(300px, 80%);
  font-family: var(--font-display); font-weight: 400; font-size: 24px; letter-spacing: .2em; line-height: 1; }
.cos-brand__wm--tbm .wm-row{ display: flex; align-items: center; gap: .7em; }
.cos-brand__wm--tbm .wm-row i{ flex: 1 1 auto; min-width: 32px; height: 1px; background: currentColor; }
.cos-brand__wm--tbm .wm-row em{ flex: 0 0 auto; font-style: normal; }
.cos-brand__wm--cel{ font-family: var(--font-display); font-weight: 700; font-size: 56px;
  letter-spacing: -.035em; line-height: .8; }

.cos-brand__btn{ position: absolute; z-index: 3; left: var(--space-5); bottom: var(--space-5); }
/* Бутонът е етикет вътре в картата-връзка, затова hover-ът му се задейства
   от нея. Стойностите идват от buttons.css и не се пипат там. */
/* The whole card is the hover target, not the button, so the primary hover
   storyboard has to be re-triggered from the card — these rules mirror
   tokens/buttons.css rather than extending it.
   THE BASE COLOUR IS PART OF THAT STORYBOARD, and was missing here. The wipe
   covers the pill geometrically, but "covers" is a statement about centres and
   radii, not about the pixels where a circle's edge meets a 9999px corner — and
   what shows through there is the ink, as a dark fleck beside the button. Taking
   the base to accent as well leaves nothing dark to show through. Same fix, same
   reason, as the one on .lmed-btn--primary:hover itself.
   A copy of a storyboard drifts from it; this is that drift. Any further change
   to the primary hover has to be made in both places until they are one. */
a.cos-brand:hover .lmed-btn--primary,
a.cos-brand:focus-visible .lmed-btn--primary{ gap: var(--space-2); padding: var(--space-2) var(--space-5); background: var(--accent-200); }
a.cos-brand:hover .lmed-btn--primary .lmed-btn__fill,
a.cos-brand:focus-visible .lmed-btn--primary .lmed-btn__fill{ transform: translate(-50%, -50%) scale(16); }
a.cos-brand:hover .lmed-btn--primary .lmed-btn__badge,
a.cos-brand:focus-visible .lmed-btn--primary .lmed-btn__badge{ background: transparent; width: 1rem; }
a.cos-brand:hover .lmed-btn--primary .lmed-btn__icon,
a.cos-brand:focus-visible .lmed-btn--primary .lmed-btn__icon{ transform: rotate(360deg); }
a.cos-brand:hover .lmed-btn--primary .lmed-btn__label,
a.cos-brand:focus-visible .lmed-btn--primary .lmed-btn__label{ color: var(--ink); }

@media (max-height: 760px) and (min-width: 769px){
.cos-brand__body{ gap: var(--space-4); font-size: .9rem; }
.cos-brand__wm--tbm{ font-size: 20px; }
.cos-brand__wm--cel{ font-size: 44px; }
.cos-brand__pills{ gap: var(--space-3); font-size: .85rem; }
}
@media (max-height: 620px) and (min-width: 769px){
.cos-brand__body{ gap: var(--space-3); font-size: .82rem;
    top: var(--space-4); left: var(--space-4); right: var(--space-4); }
.cos-brand__wm--tbm{ font-size: 17px; }
.cos-brand__wm--cel{ font-size: 36px; }
.cos-brand__btn{ left: var(--space-4); bottom: var(--space-4); }
}

@media (prefers-reduced-motion: reduce){
.cos-brand{ transition: none; }
a.cos-brand:hover, a.cos-brand:focus-visible{ transform: translateZ(0); }
}
.cos-brand__prod { will-change: transform; }

/* Тесен екран. Стоеше в cosmetics-hero.css, извън всякакъв scope — остатък от
   разделянето. Там не важеше: некоширано `.cos-brand__prod` губи от кошираното
   в този файл, защото близостта по scope тежи над реда. `.cos-brands` е самият
   корен, затова тук е `:scope`. */
/* ЕДНА карта = банер към другата марка в дъното на брандова страница: през
   цялата ширина и наполовина по-нисък, за да не спори с индекса, който току-що
   е минал. Две карти = индексът на /kozmetika/, непроменен.

   Числото идва от шаблона, а не от отделен клас: секцията така или иначе знае
   колко марки рендира, а страница с една ги получава сама. */
:scope[data-count="1"]{
  grid-template-columns: 1fr;
  --cos-brand-h: 42svh;
  /* И слоевете растат: 60% от 80svh и 82% от 42svh не са едно и също число, а
     апаратите трябва да тежат еднакво и в двете кутии. Числата са от дизайна,
     не сметнати — банерът ги носи свои, защото кутията му е друга. */
  --cos-brand-prod-h: 82%;
}

@media (max-width: 768px){
:scope{ grid-template-columns: 1fr; gap: var(--space-5);
    padding: var(--space-7) var(--page-pad); }
/* На телефон банерът и индексът са едно и също: изправена карта през цялата
   ширина. Затова --cos-brand-h не участва.

   Съотношение, не височина. `min-height: 90svh` мереше екрана, тоест картата
   излизаше различно висока на всеки телефон; 9/16 я мери спрямо ширината на
   страницата. `height: auto` остава, защото стойността от правилото по-горе би
   бита aspect-ratio, а min-height си отива по същата причина — под него
   съотношението не се спазва. */
.cos-brand{ height: auto; aspect-ratio: 9 / 16; }
.cos-brand__prod{ height: auto; width: 105%; left: var(--lm, var(--l)); top: var(--tm, var(--t)); }
.cos-brand__wm--tbm{ font-size: 17px; width: min(240px, 86%); }
.cos-brand__wm--cel{ font-size: 38px; }
/* Отстъпът вдясно пада. На десктоп 12ch пазят тялото изпод етикета за произход
   в горния десен ъгъл; на една колона те не пазят НИЩО и струват много.

   Мерено при карта 328px: с отстъпа словомарката е 158px и абзацът 184px, без
   него — 240px и 288px. Етикетът се застъпва със словомарката и в двата случая,
   защото той няма мобилен вариант и остава горе вдясно, а словомарката е
   ограничена до 86% от картата, не от тялото. Тоест 104px ширина на абзаца
   отиваха за защита, която не се случва. */
.cos-brand__body{ padding-right: 0; }
/* ЕТИКЕТЪТ ВЛИЗА В ПОТОКА — първи ред на колоната, горе вляво, над
   словомарката. На широк екран той е в ъгъла срещу нея; на една колона там
   няма срещу какво да стои и просто се застъпваше с нея.

   Отстоянието до словомарката е `gap`-ът на тялото; собствено число не му
   трябва. */
.cos-brand__origin{ position: static; }
/* На тъч ховърът или не съществува, или залепва след тап — картата остава
   уголемена, докато не се тапне другаде. Тук, а не в cosmetics-hero.css,
   където стоеше и не можеше да улучи нищо. */
a.cos-brand:hover{ transform: translateZ(0); }
}
}

/* ═══ sections/cosmetics-form ═══ */
/* Формата за запитване. От стария експорт (form-cosmetics.html), едно към едно.
 *
 * Картата отляво се разкрива отляво надясно, а снимката в нея се отпуска от
 * scale(1.15) — двете тръгват заедно и свършват заедно. Полетата влизат след
 * тях, стъпаловидно, през --d.
 *
 * `is-in` слага scripts/page/cosmetics-form.js при зареждане. Без скрипт
 * страницата остава в началното си състояние, затова тук няма нищо, което да
 * СКРИВА съдържание трайно — clip-path и opacity са на декора и на анимацията,
 * а формата е в HTML-а и работи. */
@scope (.fc) {

:scope{ position: relative; }
.fc__dialog{ display: flex; align-items: flex-start; padding: 0 var(--page-pad, 48px); }

/* Десният ръб на картата стои на 33.7vw; левият се отдръпва с --page-pad,
   защото отстъпът вече идва от .fc__dialog. */
.fc__left{
  position: sticky; top: calc(84px + var(--space-4));
  flex: 0 0 calc(33.7vw - var(--page-pad, 48px));
  height: 80svh;
  overflow: hidden; border-radius: var(--radius-lg);
  padding: var(--space-5);
  /* `round` пази заоблените ъгли ПО ВРЕМЕ на разкриването — без него ъглите
     остават квадратни, докато анимацията върви. */
  clip-path: inset(0 100% 0 0 round var(--radius-lg));
  transition: clip-path .6s cubic-bezier(.15, 0, 0, 1);
}
.fc__bg{ position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transform: scale(1.15); transform-origin: 50% 50%;
  transition: transform .6s cubic-bezier(.15, 0, 0, 1); }
.fc__intro{ position: relative; z-index: 1; max-width: none; }
.fc__intro h1{ margin: 0; font-size: var(--text-h3); line-height: 1.15; }
.fc__intro p{ margin: var(--space-4) 0 0; line-height: var(--leading-body); }

.fc__panel{ flex: 1 1 auto; min-height: 100svh;
  padding: 0 0 var(--space-9) var(--space-7); }

:scope.is-in .fc__left{ clip-path: inset(0 round var(--radius-lg)); }
:scope.is-in .fc__bg{ transform: scale(1); }

.fc-form{ max-width: 624px; }
.fc-form > *{ opacity: 0; transform: translateY(16px);
  transition: opacity .5s cubic-bezier(.15, 0, 0, 1) var(--d, 0s),
              transform .5s cubic-bezier(.15, 0, 0, 1) var(--d, 0s); }
:scope.is-in .fc-form > *{ opacity: 1; transform: none; }
/* Стъпката е 90ms и започва след картата. Изписани поотделно, а не през
   calc(n * 90ms), защото nth-child не дава индекс за сметка. */
.fc-form > :nth-child(1){ --d: .50s }
.fc-form > :nth-child(2){ --d: .59s }
.fc-form > :nth-child(3){ --d: .68s }
.fc-form > :nth-child(4){ --d: .77s }
.fc-form > :nth-child(5){ --d: .86s }
.fc-form > :nth-child(6){ --d: .95s }
.fc-form > :nth-child(7){ --d: 1.04s }

/* Номерът на стъпката стои в собствена колона, за да се подравнят заглавията. */
.fc-form__head{ display: grid; grid-template-columns: 2.9rem 1fr;
  margin: var(--space-9) 0 var(--space-6); font-size: var(--text-h5); line-height: 1.25; }
.fc-form__head:first-child{ margin-top: 0; }
.fc-form__fields{ display: flex; flex-direction: column; gap: var(--space-2); }
/* Същата лява колона като на полетата — етикетът на групата ляга на тяхната
   линия, оттам и --input-label-w вместо свое число. */
.fc-form__group{ display: grid; grid-template-columns: var(--input-label-w, 7.75rem) 1fr;
  margin-top: var(--space-7); }
.fc-form__label{ font-size: var(--text-small); color: var(--grey-700);
  line-height: 1.2; padding-right: var(--space-2); }
.fc-form__opts{ display: flex; flex-direction: column; gap: var(--space-3); }

/* Десктоп: дванайсетте услуги в една колона са повече височина, отколкото
   панелът иска. `columns` ги подрежда ПО КОЛОНИ — азбучният ред се чете
   надолу, както в списък, а не през реда, — и сам балансира късите групи:
   петте вида бизнес се разделят горе-долу поравно, без да им се казва колко
   реда имат.

   `display: block` на хоста не е излишно: lmed-checkbox и lmed-radio-btn са
   custom elements, тоест `display: inline` по подразбиране. Във flex
   контейнера това беше без значение — flex блокира децата си, — а в колонен
   контейнер inline елемент тече като текст и се къса между колоните.
   Отстоянието е margin, защото `gap` важи за flex/grid, а това е нито едното. */
@media (min-width: 769px){
.fc-form__opts{ display: block; columns: 2; column-gap: var(--space-6); }
.fc-form__opts > *{ display: block; break-inside: avoid; margin-bottom: var(--space-3); }
}
.fc-form__note{ margin: var(--space-6) 0 0; font-size: var(--text-p); }
.fc-form__note.is-ok{ color: var(--ink); }
.fc-form__note.is-bad{ color: var(--error-500); }
/* The note sits above the button, so the button's own top margin collapses to
   nothing once there is something to say. */
.fc-form__note:not([hidden]) + .fc-form__submit{ margin-top: var(--space-5); }
.fc-form__submit{ margin-top: var(--space-9); }

@media (prefers-reduced-motion: reduce){
.fc__left, .fc__bg, .fc-form > *{ transition: none; }
.fc__left{ clip-path: none; }
}

@media (max-width: 768px){
:scope{ --page-pad: 16px; }
.fc__dialog{ flex-direction: column; padding: 0 var(--page-pad, 16px); }
/* Изправена, картата не се закача и не се разкрива — на един екран ширина
   разгръщането отляво надясно е движение без какво да покаже. */
.fc__left{ position: relative; top: auto; flex: 0 0 auto; width: 100%;
  aspect-ratio: auto; max-height: none; height: auto; min-height: 70svh;
  border-radius: var(--radius-lg); padding: var(--space-5); clip-path: none; }
.fc__panel{ min-height: 0; padding: var(--space-5) 0 var(--space-8); }
.fc__intro h1{ font-size: var(--text-h4); }
.fc-form__group{ grid-template-columns: 1fr; gap: var(--space-2); }
lmed-input{ display: block; }
}

}

/* ═══ sections/cosmetics-hero ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .cos-hero. The bundle is one stylesheet on every page, so without
 * this a name like .grid or .cta would silently restyle another section. */
@scope (.cos-hero) {
/* Козметика — индексът на двете марки. Портирано от kozmetika-v3.html.
 *
 * Три секции: hero с безкрайна лента, двете карти, и лепкавото CTA. Всичко
 * анимирано е само transform/opacity; скриптът не пипа геометрия.
 *
 * Без скрипт страницата е пълна и статична: лентата стои, слоевете стоят по
 * местата си, CTA-то е в крайното си състояние. За това се грижи CSS-ът тук —
 * началните състояния се задават от js/page/cosmetics.js, не оттук. */

/* ---- Hero ---- */
:scope{ position: relative; height: 100svh; overflow: hidden;
  padding: calc(84px + var(--space-2)) var(--page-pad, 48px) 0;
  --strip-h: min(83.5svh, 760px); --strip-gap-ratio: 0.115; }
.cos-hero__copy{ position: relative; z-index: 1; }
.cos-hero__copy h1{ margin: 0; font-size: var(--text-page-title); line-height: var(--leading-page-title); max-width: var(--measure-page-title); }
.cos-hero__copy p{ margin: var(--space-5) 0 0; max-width: var(--measure-lede); line-height: var(--leading-lede); }
.cos-hero__strip{ position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--strip-h); z-index: 2; pointer-events: none; }
.cos-hero__track{ display: flex; align-items: flex-end; height: 100%;
  gap: calc(var(--strip-h) * var(--strip-gap-ratio));
  transform: translate3d(0, 0, 0); }
.cos-hero__track img{ height: 100%; width: auto; display: block; flex: 0 0 auto;
  user-select: none; -webkit-user-drag: none; }

@media (max-width: 768px){
:scope{ --strip-h: 52svh; padding-top: calc(72px + var(--space-2)); }
/* `a.cos-brand:hover{transform:none}` стоеше тук и не важеше: вътре в
   @scope (.cos-hero) селекторът търси карта ВЪТРЕ в hero-то, каквато няма.
   Същият остатък от разделянето като .cos-brand__prod — виж бележката в
   cosmetics-brands.css, където го преместих. */
}
.cos-hero__track { will-change: transform; }
}

/* OUTSIDE the scope, necessarily: these selectors start above the root
 * (body:has(...)), beside it (an adjacent sibling), or target an element in a
 * DIFFERENT section. @scope only reaches DOWNWARD from its root, so inside the
 * block they would match nothing at all — silently. */
/* С пътека над него hero-то тръгва под нея: менюто вече е разчистено, а
   височината му е останалото до ръба — иначе лентата увисва точно с
   височината на пътеката под сгъвката. */
body:has(.breadcrumb) .cos-hero{ height: calc(100svh - var(--crumb-h)); padding-top: var(--space-2); }

@media (max-width: 768px){
body:has(.breadcrumb) .cos-hero{ padding-top: var(--space-2); }
}

/* ═══ sections/cosmetics-invite ═══ */
/* Поканата под индекса на марката — заявка за test box или обаждане.
 *
 * Издърпана е НАГОРЕ, точно колкото е висок собственият ѝ лийд, и стои на
 * по-нисък слой от секцията отгоре. Ефектът: лийдът ѝ вече е на екрана, скрит
 * зад белия индекс, и се открива, докато индексът си отива нагоре — вместо да
 * дойде отдолу като следващ блок.
 *
 * Оттам и --cos-invite-h: височината и издърпването са ЕДНО число. Разминат ли
 * се, между двете секции зейва или празнина, или скок.
 *
 * Издърпването трябва да е ТОЧНО колкото лийда, за да е закачен още преди да се
 * покаже: щом върхът на секцията стигне `top`, дъното на индекса отгоре стои
 * точно на дъното на лийда, тоест той е още изцяло покрит и оттам нататък само
 * се открива, без да мърда. По-малко изпреварване значи лийд, който първо върви
 * със скрола и чак после стиква.
 *
 * Затова и секцията отгоре няма margin-bottom — съседни маржове се сгъват и
 * нейният се вадеше от това число. Виж бележката там. */
@scope (.cos-invite) {

:scope{
  --cos-invite-h: 85svh;
  position: relative; z-index: 0;
  padding: 0 var(--page-pad, 48px);
  margin-top: calc(-1 * var(--cos-invite-h));
  margin-bottom: var(--space-9);
}
.cos-lead{ position: sticky; top: var(--space-7); height: var(--cos-invite-h); z-index: 0; }

/* Пътеката е празна нарочно: sticky се държи, докато има какво да минава покрай
   него, а под поканата няма съдържание. Без нея лийдът се закача и веднага се
   пуска.

   Дължината ѝ НЕ е свободно число. Колко може да се държи закачен е точно
   височината на секцията минус лийда, тоест самата пътека — а разкриването
   изяжда цял лийд скрол, защото белият индекс отгоре трябва да измине
   собствената височина на лийда, за да го открие докрай.

       пътека <  лийд   секцията си тръгва, преди да се е показала цялата
       пътека =  лийд   пуска се точно в мига, в който се открие
       пътека >  лийд   стои открита още толкова

   Тук беше 80svh при лийд 85svh — с 45px по-къса от нужното, и точно тези 45px
   не се показваха. Затова е изразена през него, а не в свое число: смени ли се
   височината на лийда, пътеката я следва. */
.cos-invite__runway{
  --cos-invite-dwell: 20svh;
  height: calc(var(--cos-invite-h) + var(--cos-invite-dwell));
  pointer-events: none;
}

@media (max-width: 1024px){
:scope{ --cos-invite-h: 90svh; padding: 0; }
.cos-lead{ top: var(--space-4); }
}

}

/* ═══ sections/cta-benefits ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .benefits. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.benefits) {
/* „Четирите неща" — CTA-то, което Козметика и Производители делят.
   Отделен лист, защото секцията е обща; в cosmetics.css името ѝ щеше да
   лъже за втората страница, която я ползва. */

:scope{ position: relative; height: 250svh; overflow-x: clip; }
/* Сцената не е цял екран: 70svh, залепена на 10svh от горния ръб — тоест
   центрирана, с по 15svh бяло отгоре и отдолу. На телефон не е залепена и
   двете не важат. */
.benefits__stage{ position: sticky; top: 10svh; height: 70svh;
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);
  padding: 0 var(--page-pad, 48px); align-items: center; }
.benefits__col--copy{ display: flex; align-items: center; }
.benefits__copy{ position: relative; z-index: 1; width: 100%;
  transform: translate3d(0, var(--copy-shift, 0px), 0);
  transition: transform .7s cubic-bezier(.15, 0, 0, 1); }
.benefits__title{ margin: 0; font-size: var(--text-h2); line-height: 1.15; }
.benefits__line{ display: block; width: fit-content; }
.benefits__p{ margin: var(--space-5) 0 0; max-width: 30rem; line-height: var(--leading-body); }
.benefits__btns{ display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-5); }
:scope.is-done .benefits__copy{ transform: translate3d(0, 0, 0); }
:scope.is-done .benefits__p, :scope.is-done .benefits__btns{ opacity: 1; transform: none; }
.benefits.is-instant .benefits__copy,
.benefits.is-instant .benefits__p,
:scope.is-instant .benefits__btns{ transition: none; }

.benefits__col--grid{ position: relative; display: flex; align-items: center; }
.benefits__cards{ position: relative; z-index: 2; width: 100%;
  display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 1fr; gap: var(--space-4); }
.benefits__mark{ position: absolute; z-index: 0; left: 50%; top: 50%;
  width: var(--mark-size, 171px); height: var(--mark-size, 171px);
  margin: calc(var(--mark-size, 171px) / -2) 0 0 calc(var(--mark-size, 171px) / -2);
  transform-origin: 50% 50%; }
.benefits__card{ position: relative;
  display: flex; flex-direction: column; justify-content: flex-end;
  min-height: 173px; padding: var(--space-4);
  border: 1px solid var(--accent-200); border-radius: var(--radius-md);
  background: rgba(255, 255, 255, .45);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.benefits__card h3{ margin: 0; font-size: var(--text-h4); line-height: 1.15; }
.benefits__card p{ margin: var(--space-2) 0 0; line-height: 1.2; }
.benefits__check{ position: absolute; top: var(--space-4); right: var(--space-4);
  width: 28px; height: 28px; border-radius: 50%; background: var(--accent-200);
  display: grid; place-items: center; color: var(--ink); font-size: .9rem; line-height: 1; }


.benefits__line { will-change: transform; }
/* Скрити са само когато скриптът ще ги покаже. Без него текстът и бутоните
   стоят видими — не се крие съдържание зад анимация. */
.benefits__p, .benefits__btns { opacity: 0; transform: translateY(16px);
  transition: opacity .7s cubic-bezier(.15, 0, 0, 1), transform .7s cubic-bezier(.15, 0, 0, 1); }
.benefits__btns { transition-delay: .14s; }
.benefits__mark { will-change: transform; }
.benefits__card { will-change: transform; }

@media (max-width: 768px) {
  :scope { height: auto; }
  .benefits__stage { position: static; height: auto;
    display: flex; flex-direction: column; gap: var(--space-5);
    padding: var(--space-8) var(--page-pad, 16px) var(--space-9); }
  .benefits__col--copy, .benefits__copy { display: contents; }
  .benefits__title { order: 1; font-size: var(--text-h3); }
  .benefits__col--grid { order: 2; }
  .benefits__p { order: 3; margin: 0; opacity: 1; transform: none; transition: none; }
  .benefits__btns { order: 4; margin: 0; opacity: 1; transform: none; transition: none; }
  .benefits__cards { gap: var(--space-3); }
  .benefits__card { min-height: 0; padding: var(--space-4); }
  .benefits__card h3 { font-size: var(--text-h6); }
}

@media (prefers-reduced-motion: reduce) {
  .benefits__p, .benefits__btns { opacity: 1; transform: none; transition: none; }
}
}

/* ═══ sections/cta ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .cta3d. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.cta3d) {
/* ---- CTA 3D: акт 1 (скрол) + акт 2 (CSS разпръскване) ---- */
:scope{position:relative;height:180vh;background:var(--white)}
.cta3d__stage{position:sticky;top:0;height:100vh;overflow:hidden;display:flex;align-items:center;justify-content:center}
/* The scene is centred by the stage, but it does not *read* centred, for two
   reasons that compound:

     - the box sits low by a steady 2.7% of the scene width (measured at
       viewport heights 700-1100, the ratio holds), because the scene's flow
       height counts the empty band above the absolutely-positioned planes;
     - every device render carries far more transparent padding at its top
       than its bottom — 150/78, 155/100, 224/111, 177/99 — so the ink sits
       lower again inside boxes that are already low.

   Measured on the painted result rather than the geometry: the ink centroid
   landed 57px below the viewport centre at a 900px viewport, which is 6.6%
   of the scene width. Lifting by that, expressed against the same width so
   it tracks the viewport.

   The factor is 0.132, twice the 6.6% measured, because the stage centres
   the item's MARGIN box: a -M top margin lifts the border box by M/2.

   A transform would be the obvious tool and is the wrong one here: it would
   make the scene a backdrop root and flatten .cta3d__card-glass. */
.cta3d__scene{position:relative;--scene-w:min(1100px,calc(100% - var(--page-pad,48px) * 2),96vh);width:var(--scene-w);margin-top:calc(var(--scene-w) * -0.132)}
.cta3d__logo{position:absolute;z-index:0;transform-origin:50% 50%;pointer-events:none}
.cta3d__logo-in{display:block;transform-origin:50% 50%;transition:transform 1s cubic-bezier(.15,0,.15,1),filter 1s cubic-bezier(.15,0,.15,1),opacity 1s cubic-bezier(.15,0,.15,1)}
.cta3d__logo svg{display:block;width:100%;height:auto}
.is-act2 .cta3d__logo-in{transform:scale(.62);opacity:0;filter:blur(14px)}
.cta3d__hero, .cta3d__plane{position:absolute;pointer-events:none}
.cta3d__hero{z-index:5}
.cta3d__hero-in, .cta3d__plane-in{position:relative;width:100%;aspect-ratio:1172 / 1303;transform-origin:0 0;transform:translate(var(--tx,0px),var(--ty,0px)) scale(var(--sc,1));filter:var(--f0,none);transition:transform 1s cubic-bezier(.15,0,.15,1),filter 1s cubic-bezier(.15,0,.15,1),opacity 1s cubic-bezier(.15,0,.15,1)}
.cta3d__plane-in{opacity:0}
.is-act2 .cta3d__hero-in, .is-act2 .cta3d__plane-in{transform:none;filter:var(--f1,none);opacity:1}
.cta3d__hero-in img, .cta3d__plane-in img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block}
.cta3d__slot--b{opacity:0;transition:opacity .12s linear}
.cta3d__scene.is-instant, .cta3d__scene.is-instant *{transition:none !important}
.cta3d__front{position:relative;z-index:6;margin-top:46%;box-sizing:border-box;transform:scale(1.424);transform-origin:50% 50%;transition:transform 1s cubic-bezier(.15,0,.15,1);pointer-events:none}
.is-act2 .cta3d__front{transform:none;pointer-events:auto}
.cta3d__card{position:relative;border:1px solid transparent;border-radius:var(--radius-lg);padding:var(--space-6);text-align:center}
.cta3d__card-glass{position:absolute;inset:-1px;z-index:-1;border:1px solid var(--accent-200);border-radius:var(--radius-lg);background:rgba(211,229,229,.55);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);opacity:0;transition:opacity 1s cubic-bezier(.15,0,.15,1),backdrop-filter 1s cubic-bezier(.15,0,.15,1),-webkit-backdrop-filter 1s cubic-bezier(.15,0,.15,1)}
.is-act2 .cta3d__card-glass{opacity:1;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.cta3d__card-body, .cta3d__contacts{opacity:0;filter:blur(7.5px);transition:opacity 1s cubic-bezier(.15,0,.15,1),filter 1s cubic-bezier(.15,0,.15,1)}
.is-act2 .cta3d__card-body, .is-act2 .cta3d__contacts{opacity:1;filter:none}
.cta3d__card-body h3{margin:0 0 var(--space-2)}
.cta3d__sub{margin:0 0 var(--space-5);font-weight:var(--weight-body-semibold)}
.cta3d__btns{display:flex;flex-wrap:wrap;gap:var(--space-4);justify-content:center}
.cta3d__contacts{margin-top:var(--space-5);display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));align-items:start;gap:var(--space-5)}
.cta3d__contacts > *{min-width:0}
.cta3d__contacts h6{margin:0 0 var(--space-2)}
.cta3d__brand{flex:0 0 auto;display:flex;align-items:center;gap:var(--space-2)}
.cta3d__brand .b-mark{width:26px;height:auto;display:block}
.cta3d__brand .b-type{width:100px;height:auto;display:block}
.cta3d__col{display:flex;flex-direction:column;gap:var(--space-1);color:var(--text-primary)}
.cta3d__col a{color:var(--text-primary);text-decoration:none;white-space:nowrap}
.cta3d__hours{display:grid;grid-template-columns:max-content max-content;justify-content:start;column-gap:var(--space-5);row-gap:var(--space-1)}
.cta3d--no-anim .cta3d__logo-in, .cta3d--no-anim .cta3d__hero-in, .cta3d--no-anim .cta3d__plane-in, .cta3d--no-anim .cta3d__front, .cta3d--no-anim .cta3d__card-glass, .cta3d--no-anim .cta3d__card-body, .cta3d--no-anim .cta3d__contacts{transition:none}
@media (prefers-reduced-motion:reduce){
:scope{height:auto}
.cta3d__stage{position:relative;top:auto;height:auto;padding:var(--space-9) 0}
}

@media (max-width:1024px){
.platform-cards, .packs{grid-template-columns:1fr}
.tech-results{padding-top:0}
}

/* ТЕЛЕФОН. Сцената става ПО-ШИРОКА от екрана и стейджът я реже — това е
   единственият лост, който вдига всичко наведнъж, защото скриптът мери
   `scene.offsetWidth` и всяко число в него е дял от нея: логото 0.52W,
   апаратът `HERO_W * D0/d * W`, височините `(HORIZON + BASE_K/d) * W`.

   Мерено при 360x640: апаратът отпред минава от 188 на 320px, логото от 171 на
   290, а крайните планове излизат извън екрана — на -163 и на 462. Точно това
   е и уговорката: настрани може да излизат.

   `flex-shrink: 0`, защото стейджът е flex и без него сцената се свиваше
   обратно до ширината на екрана — зададената `--scene-w` просто не важеше.

   Картата НЕ расте с нея: тя е дете на сцената и щеше да стане 558px широка,
   тоест да излезе извън страницата. Връща се на ширината на съдържанието. */
@media (max-width:768px){
/* Колко увисва сцената под долния ръб на стейджа — виж `margin-bottom` на
   сцената долу. Едно число на две места: сцената слиза с него, а секцията му
   пази място отдолу, за да не го покрие следващата. */
:scope{--cta-hang:calc(155vw * 0.345);margin-bottom:var(--cta-hang)}
.cta3d__scene{--scene-w:155vw;flex-shrink:0}
.cta3d__front{width:calc(100vw - var(--page-pad, 16px) * 2);margin-inline:auto}

/* КОМПОЗИЦИЯТА СТЪПВА НА ДЪНОТО на екрана, вместо да е центрирана в него.

   Сметката, която го налага: при 360x640 тя иска 786px — апаратът над картата
   237, картата 299, отстъп 20 и контактите 230. Стейджът е 640 с
   `overflow: hidden` и режеше последните 99: контактите се губеха под
   следващата секция.

   С `flex-end` долният ръб застава на дъното, тоест контактите са изцяло
   видими, а каквото не се побира, излиза НАГОРЕ и се отрязва там — апаратите,
   които и без това са отрязани отгоре. Цената е, че за апарата над картата
   остават 640 - 549 = 91px чисти; взаимното им разположение не се мени, той
   застъпва същите 39% от него.

   Първо го направих с `bottom: 0` вместо `top: 0` — лепене по дъно. Chrome НЕ
   го прилага на кутия, по-висока от екрана: мерено, дъното на стейджа си
   вървеше с хода от 839 до 327, тоест не се закова нито веднъж. Със същата
   кутия и `top: 0` стои на 0..640 през целия ход. Затова закотвянето си остава
   по връх, а разликата я прави подравняването. */
.cta3d__stage{align-items:flex-end;overflow:clip visible}

/* И ОТМЕСТЕНА НАДОЛУ с половин ширина на сцената. Отрицателният долен отстъп
   изважда толкова от маргин кутията, тъй че при подравняване по дъно самата
   сцена увисва под ръба на екрана с тази разлика.

   Числото е снето от макета (cta-ref-1, 360x640, пиксел в пиксел): там
   картата е на y284..582, апаратите над нея на y114..283, а под нея се вижда
   само марката на y603. С 0.345 излиза карта y284..583 и марка y603 — и двете
   котви съвпадат.

   Контактите остават под сгъвката, докато кадърът е закован — така е и в
   макета. Когато секцията пусне, те трябва да изплуват отдолу, а не да ги
   отреже следващата секция. За това са двете неща горе: стейджът реже само
   ВОДОРАВНО (`overflow: clip visible` — сцената е по-широка от екрана и
   страните трябва да се режат, но увисналото отдолу не), а секцията има долен
   отстъп колкото увисването. Мерено преди това: стейджът свършваше на y400,
   следващата секция почваше пак на y400, а контактите стигаха до y593 — 193px
   отрязани, точно колкото е увисването.

   `clip`, не `hidden`: при `hidden` по едната ос другата става `auto` и
   стейджът се превръща в скролиращ контейнер; `clip` оставя другата ос на
   `visible`. Отстъпът е margin, не padding, за да не мръдне нито височината на
   секцията, нито ходът, по който скриптът мери акт 1. */
.cta3d__scene{margin-bottom:calc(var(--cta-hang) * -1)}
}
}

/* ═══ sections/devices-head ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .dev-head. Добавѝ root тук, ако секцията някога порасне втори.
 *
 * Файлът нарочно е кратък. Почти всичко, което тази секция иска, вече го има:
 * заглавието се мери с токените на page-head, стъклото е третирането на
 * .regular-btn, а каре върху медия е .card.wide .panel. Тук стои само това,
 * което ги ПОДРЕЖДА — двете колони, кутията на филма и къде виси карето. */
@scope (.dev-head) {

/* Двете колони са по 50% и са ГОРЕ подравнени: копието започва на височината
   на филма, а под бутона остава въздух — това е, което пуска филтъра да се
   подаде в първия екран.

   --dev-head-film-h е числото, на което се разбира цялата секция; резервът от
   300px е фиксираното меню, пътеката, собственият padding-bottom и лентата с
   филтри, тоест всичко, което ДЕЛИ първия екран с нея. clamp пази филма да не
   смачка копието на нисък екран и да не изрита филтъра под сгъвката на висок. */
:scope{
  --dev-head-film-h: clamp(300px, calc(100svh - 230px), 620px);
  /* Скоростта на филма при ховър върху дясната колона. Тук, а не в скрипта, по
     същата причина, по която --par-* на range-head са тук: дизайнът решава
     КОЛКО, скриптът — КОГА. devices-head.js чете само тези три числа.
       --dev-head-rate-max      докъде стига playbackRate под курсора
       --dev-head-rate-attack   време до ~63% при влизане (краят е ~3× това)
       --dev-head-rate-release  същото при излизане; по-дълго, защото
                                догонването трябва да е незабавно, а връщането не */
  --dev-head-rate-max: 3.5;
  --dev-head-rate-attack: 30ms;
  --dev-head-rate-release: 90ms;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-7);
  align-items: start;
  /* Без отстъп отдолу: така височината на реда Е височината на секцията, и
     филмът, който я задава, я заема цялата. Въздухът до лентата с филтри е
     нейният собствен margin-top, а не втори отстъп тук. */
  padding: 0 var(--page-pad, 48px);
}

/* ---- Лявата колона: заглавие, параграф, бутон ---- */
.dev-head__copy{ display: flex; flex-direction: column; align-items: flex-start; }

/* Същите токени, с които page-head рисува заглавието на всеки друг секционен
   индекс: това е един хедър в две подредби, не два различни дизайна. */
:scope h1{
  font-size: var(--text-page-title); line-height: var(--leading-page-title);
  max-width: var(--measure-page-title); margin: 0 0 var(--space-5);
}
/* `lede` е името, с което page-head и about вече наричат този параграф, и
   мярката е същата. Размерът и водещият идват от body — не се повтарят. */
:scope .lede{ max-width: var(--measure-lede); line-height: var(--leading-lede); margin: 0; }
.dev-head__cta{ margin-top: var(--space-6); }

/* ---- Дясната колона: филмът и карето върху него ---- */
/* Стойката заема цялата колона и цялата височина на секцията: тя е ВИСОКИЯТ
   елемент в реда, така че --dev-head-film-h е и височината на хедъра. Резервът
   от 230px е това, което дели първия екран с нея — фиксираното меню, пътеката,
   лентата с филтри и въздухът до нея.

   Изрязване има и посоката му зависи от екрана, затова си струва да се знае
   МЕХАНИЗМЪТ, а не едно число. Клипът е 1.20; кутията е ширината на колоната
   върху тази височина. Излезе ли по-тясна от 1.20, cover мащабира по височина и
   реже отляво и отдясно; излезе ли по-широка — реже отгоре и отдолу.

   На 1905px широк екран кутията е 698×620, тоест 1.13, и се губят ~46px ширина
   (около 6%), разпределени симетрично. Обикалящият текст минава точно по ръба
   на кадъра, така че той е това, което плаща изрязването — ако лентите някога
   излязат накъсани, това е числото, което се гледа.

   Нулево изрязване се получава само ако височината идва от СЪОТНОШЕНИЕТО, а не
   от сгъвката — тогава обаче филмът не е висок колкото секцията. Двете не могат
   да са верни едновременно и височината е избраната. */
.dev-head__stage{
  position: relative;
  width: 100%; height: var(--dev-head-film-h);
}
/* Филмът носи собствения си бял фон, същия като на страницата, така че няма
   рамка и няма подложка — само закръгляне, с радиуса на всяка друга голяма
   карта. */
.dev-head__film{
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  border-radius: var(--radius-lg);
}

/* Карето е .card.wide .panel, преместено на другия ъгъл: стъклото е акцентното
   на дизайн системата — същата тройка, с която .regular-btn, lmed-tabs и
   icon-btn вече са направени — а мерките и отстъпът са тези на panel-а.

   Вътре във филма, не надвиснало под него. В дизайна виси под долния му ръб, но
   филмът трябва да е висок колкото секцията, а надвисналото каре беше точно
   това, което го скъсяваше — двете не могат да са верни едновременно. */
.dev-head__note{
  /* right: 0, а не отстъп навътре. Карето е най-дясното нещо в горната секция,
     а под него лентата с филтри, каруселът и картите на грида свършват на
     ръба на страницата (--page-pad). Всеки отстъп тук чупи точно тази линия —
     горната секция изглежда пораснала спрямо долната с колкото е отстъпът. */
  position: absolute; right: 0;
  bottom: var(--space-4);
  width: min(60%, var(--measure-lede));
  display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-4);
  border: 1px solid var(--accent-200);
  border-radius: var(--radius-md);
  background: rgba(211, 229, 229, .45);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  transition: background var(--duration-base) var(--ease-standard);
}
/* Под курсора карето става плътно. Цветът е същият — var(--accent-200) е
   точно rgba(211,229,229) без прозрачността — тоест не се сменя тон, а само
   се затваря. Замъгляването остава декларирано, но при плътен фон няма какво
   да замъглява; махането му на hover е излишен repaint. */
.dev-head__stage:hover .dev-head__note{ background: var(--accent-200); }
/* Гарнитурата, тежестта и водещият идват от base.css; само мярката е на
   дизайна, а тя е стъпка от скалата. */
.dev-head__note h2{ font-size: var(--text-h5); }
.dev-head__note p{ margin: 0; }

/* ---- Под 1024px: една колона ---- */
@media (max-width: 1024px){
:scope{
  grid-template-columns: 1fr;
  gap: var(--space-6);
}
/* Изправеният ред не дели първия екран с нищо, така че тук филмът получава
   мярката си от съотношението на клипа и не се реже изобщо. */
.dev-head__stage{ height: auto; aspect-ratio: 1280 / 1066; }
}

/* ---- Под 768px ---- */
@media (max-width: 768px){
/* Филмът ИЗЛИЗА от полето на страницата и кутията му е по-висока от клипа.
   Дотогава тя следваше 1.2 на клипа и височината идваше от ширината на
   колоната — на телефон това даваше апарат, който се губи. Квадрат през
   цялата ширина го рендира около 30% по-голям линейно, защото cover мащабира
   по височината (430/1066 срещу 398/1280 преди).

   Цената е около 17% изрязване по ширина: лентите с текст губят краищата си.
   На телефон това чете като кадриране, не като дефект — и е същият компромис
   като на десктоп, само по-голям. */
:scope{
  --dev-head-note-overlap: var(--space-8);
  /* ЕДИНСТВЕНИЯТ регулатор за големината на апарата на телефон. Кутията е през
     цялата ширина, тоест височината ѝ зависи само от това съотношение, а
     cover мащабира по височината — колкото по-висока кутия, толкова по-голям
     апарат и толкова повече изрязване по ширина:

       1 / 1     апаратът 1.30× спрямо преди, ~17% изрязана ширина
       1 / 1.2   1.56×, ~25%          ← сега
       1 / 1.4   1.82×, ~32%

     Изрязването пада върху КРАИЩАТА НА ЛЕНТИТЕ с текст, защото те минават по
     ръба на кадъра. Оттам се преценява докъде си струва. */
  --dev-head-film-aspect: 1 / 1.2;
}
.dev-head__stage{
  aspect-ratio: var(--dev-head-film-aspect);
  margin-inline: calc(-1 * var(--page-pad));
}
/* Отменя 1280/1066 от блока за 1024px — там височината идваше от съотношението,
   тук идва от стойката. */
.dev-head__film{ height: 100%; aspect-ratio: auto; object-fit: cover; }
/* Карето лежи ВЪРХУ долния ръб на филма, както на десктоп, вместо под него.
   Издърпано с отрицателен марж, а не absolute: така остава в потока и секцията
   продължава да го мери: с absolute височината ѝ пада до тази на филма и
   текстът излиза извън нея. */
/* Филмът излиза от двата ръба, карето НЕ. То си връща отстъпа, който стойката
   отменя, и пази заобления си ъгъл — застъпва долния край на филма като
   отделна карта, а не като лента през целия екран.

   Понеже е ДЕТЕ на стойката, без този марж `width: auto` му дава кутията на
   стойката, тоест цялата ширина на екрана. Оттам и маржът: --page-pad обратно
   отляво и отдясно. */
.dev-head__note{
  position: relative; z-index: 1;
  width: auto;
  margin: calc(-1 * var(--dev-head-note-overlap)) var(--page-pad) 0;
}
}
}


/* ═══ sections/equipment ═══ */
/* Екипировката (sections/equipment.liquid). Root е `.equip-sec`.
 *
 * Подредбата е тази на `results`: лявата колона се скролва, дясната стои
 * закачена и заема две трети. Числата са същите нарочно — двете секции стоят
 * една под друга на страницата на NOVAPRESS и разминаване в колоните би чело
 * като грешка.
 *
 * Самите карти са в styles/rf-card.css, карето — в styles/aside-card.css. И
 * двете нескоупнати, защото ги ползва повече от една секция; тук е само как
 * са подредени. */
@scope (.equip-sec) {
:scope{padding:var(--section-pad) var(--page-pad,48px)}
.equip{display:grid;grid-template-columns:1fr 2fr;gap:var(--space-5);align-items:start}
/* Колона 1 — заглавието, въведението и картите, една под друга. */
.equip-list{display:flex;flex-direction:column;gap:var(--space-4)}
.equip-list h2{font-size:var(--text-h2);margin:0}
.equip-intro{margin:0;line-height:var(--leading-body)}

/* Колона 2 — карето. Само че на тесен екран решетката става една колона и
   двете се редят една под друга. */
@media (max-width:1024px){
.equip{grid-template-columns:1fr}
}
/* На телефон редовете застават на същото разстояние, на което са и картите
   помежду си — иначе карето увисва по-далеч от тях, отколкото те една от
   друга. Същото правило и по същата причина като в results.css. */
@media (max-width:768px){
.equip{gap:var(--space-4)}
}
}

/* ═══ sections/finance ═══ */
/* Финансовите условия: заглавие и три usp карти под него.
 *
 * Самата карта е в components.css — ползва я и секция `about`. Тук е само
 * заглавието и мрежата. Root е `.fin-sec`. */
@scope (.fin-sec) {

/* ОТДОЛУ, не отгоре — обратно на конвенцията в останалите секции, и то по
   съседите си. Секцията стои между `roi` и `compare`, а те двете плащат от
   другата страна:

     roi     плаща ОТДОЛУ, както и `workload`. И двете започват със залепен
             слой над висока писта, тъй че горен падинг на секцията само би
             отместил пистата, без да добави въздух.
     compare не плаща НИКЪДЕ. На страницата на RF серията за него плаща
             `range-head` с долния си отстъп; тук преди него е тази секция.

   Докато плащаше отгоре, над заглавието се събираха 128px (64 от roi + 64 от
   тук), а под картите — нула: банерът с трите накрайника започваше залепен за
   тях. Мерено на 1360. */
:scope{ padding: 0 var(--page-pad, 48px) var(--section-pad); }
/* Заглавие на секция — h2, по правилото. */
/* 26ch = 666px, при което заглавието пада на два реда — както е в макета.
   При 24 „условия от Lmedical" се къса на трети. */
:scope > h2{ font-size: var(--text-h2); margin: 0 0 var(--space-6); max-width: 26ch; }

/* `1fr` редове, за да са трите карти еднакво високи: текстовете им са с много
   различна дължина, а дъната им трябва да четат от една линия. */
.fin-grid{ display: grid; grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr; gap: var(--space-4); }

@media (max-width: 1024px){
.fin-grid{ grid-template-columns: 1fr; grid-auto-rows: auto; }
}
@media (max-width: 768px){
:scope{ padding: 0 var(--space-4) var(--section-pad); }
:scope > h2{ font-size: var(--text-h3); }
}

}

/* ═══ sections/groups ═══ */
/* Апаратите по решение (sections/groups.liquid). Root е `.groups-sec`.
 *
 * Само рамката около сцените. Самите сцени са ui/range-stage и стиловете им са
 * в styles/range-stage.css, нескоупнати, защото ги ползва и `range-head`.
 *
 * Числата са на `range-head` нарочно: това Е нейната сцена и разминаване в
 * височината или в страничния падинг би чело като грешка между началната и
 * страницата на серията.
 */
@scope (.groups-sec) {
  /* Непрозрачен фон и слой над закования филм на hero-то. Без тях филмът се
     вижда зад групите: той е `position: fixed` и стои в екрана, след като
     секцията му е отминала. Виж бележката в home-hero.css — това е дългът на
     всяка секция под hero-то на началната. */
  :scope{ position: relative; z-index: 1; background: var(--white); }

  /* Групата заема екран, както и отварянето на страница за серия.
     
     ОТГОРЕ обаче плаща `--crumb-h`, което range-head не плаща. Навигацията е
     fixed и виси над съдържанието; на всяка друга страница пътеката стои между
     нея и <main> и изтласква текста под нея. Началната е коренът на езика и
     пътека няма — заглавието на първата група се изписваше ВЪРХУ логото.
     Същото число, от същия токен: така текстът застава там, където застава и
     на страницата за серия, само че без реда на пътеката в него.

     Падингът е ВЪТРЕ в 100svh (border-box е глобален), тъй че групата си остава
     точно екран. */
  .group-stage {
    position: relative;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    padding: var(--crumb-h) var(--page-pad) var(--space-7);
    overflow: hidden;
  }

  /* На телефон колоните ги няма — стилницата на сцената ги скрива — тъй че
     групата се свива до заглавието си и височината няма какво да пази.
     Горният отстъп остава: навигацията виси над съдържанието и там. */
  @media (max-width: 768px) {
    .group-stage { min-height: auto; padding-bottom: var(--space-8); }
  }
}

/* ═══ sections/hero ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .hero-shell. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.hero-shell) {
/* Половината от границата със следващата секция — същото като при всяка
   секция (виж --section-pad в base.css). МАРЖ, не отстъп: на десктоп
   `.hero-anchors` е абсолютен спрямо обвивката и стои на `bottom` от ръба на
   отстъпа ѝ, така че долен отстъп го смъква под картата. */
:scope{margin-bottom:var(--section-pad)}
/* ---- Hero: full-bleed фон под навигацията, 2 колони 50/50 ---- */
.hero{position:relative;min-height:min(78vh,620px);overflow:hidden;display:flex;flex-direction:column;background:var(--white);border-radius:var(--radius-lg);margin:0 var(--page-pad,48px)}
/* No background-image here on purpose. The design baked HERA's photograph
   into the shared hero section, so every other appliance using this section
   would inherit it; the picture is page data and comes from the document,
   inline on the element.

   Visible by default, hidden only once the document says script is running
   — the same rule as .rv. The design left it at opacity:0 unconditionally,
   which means no hero at all without JS. */
.hero-bg{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:cover;object-position:center;transform-origin:center;will-change:transform,opacity}
.hero-inner{position:relative;z-index:2;flex:1;width:100%;display:grid;grid-template-columns:1fr 1fr;gap:var(--space-2);padding:var(--space-6)}
.hero-col{display:flex;flex-direction:column;min-width:0}
.hero-col--left{justify-content:space-between;gap:var(--space-6)}
.hero-col--right{justify-content:flex-end;align-items:flex-end}
.hero-tags{align-self:flex-start;width:100%}
.hero-tags .tags{max-width:100%}
@media (min-width:1025px){.hero .tag{font-size:var(--text-p);padding:var(--space-2) var(--space-4);font-weight:var(--weight-body-semibold)}}
.hero-lead{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-1)}
h1.oversized{font-size:calc(var(--text-h1) * 1.377);line-height:1.02;margin:0}
.hero-sub{margin:0;font-size:var(--text-h6);font-family:var(--font-display);font-weight:var(--weight-heading);color:var(--text-primary);max-width:22em;line-height:1.35}
.hero-price{margin:0;font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h4)}
.hero-cta{margin:var(--space-2) 0 0}
.hero-origin{margin-bottom:auto}
@media (min-width:1025px){.hero .tag--icon{padding-left:var(--space-1)}}
:scope{position:relative}
.hero-anchors{display:flex;flex-wrap:wrap;gap:var(--space-3);justify-content:flex-end}
@media (min-width:1025px){.hero-anchors{position:absolute;z-index:3;right:calc(var(--page-pad,48px) + var(--space-6));bottom:var(--space-6)}}
@media (max-width:1024px){.hero-anchors{padding:var(--space-5) var(--page-pad,48px) 0}}
/* regular-btn — DS компонент (components/regular-btn.js) */
/* Hero intro reveal */
@keyframes heroReveal{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
.hero-reveal{opacity:0;animation:heroReveal .7s cubic-bezier(0.15,0,0,1) forwards}
@keyframes heroFade{from{opacity:0}to{opacity:1}}
.hero-reveal--fade{opacity:0;animation:heroFade .7s cubic-bezier(0.15,0,0,1) forwards}
@media (prefers-reduced-motion: reduce){.hero-bg{opacity:1 !important;transform:none !important;transition:none}.hero-reveal,.hero-reveal--fade{opacity:1;animation:none}}
.hero-bg{transform:scale(1.1);opacity:0;transition:opacity .8s cubic-bezier(0.15,0,0,1),transform .9s cubic-bezier(0.15,0,0,1)}
.hero-bg.loaded{opacity:1;transform:scale(1)}

/* Отзивчивите правила за тази секция. Стояха в cta.css, извън всякакъв scope —
   остатък от разделянето на слетите стилове. Там не важаха: некоширано
   `.x` губи от коширано `.x` в собствения му файл, защото близостта по scope
   тежи над реда, а медия заявката не добавя тежест. */
@media (max-width:1024px){
.hero-inner{grid-template-columns:1fr}
.hero-col--right{justify-content:flex-start;align-items:flex-start}
.hero-anchors{justify-content:flex-start}
.hero-origin{margin-bottom:0}
}
@media (max-width:768px){
/* Долният ръб на hero-то трябва да се вижда. Беше `min-height:600px;height:80vh`
   — подът надвиваше 80vh и при екран 640 hero-то излизаше 600 високо, а
   започва на 104 (лента + трохи), тоест дъното му падаше на 703. Сега височината
   се смята от това, което ОСТАВА на екрана.

   `svh`, не `vh`: svh е екранът с РАЗГЪНАТИ ленти на браузъра, тоест
   най-малкото, което ще стане. С vh (което на iOS е голямата височина) дъното
   пак се реже при първото показване, преди адресната лента да се свие.

   `min-height: 0` е задължително — иначе подът от 600 пак печели.

   Хоризонталната котва отдолу остава ОБЩА за всички апарати нарочно: къде стои
   апаратът в кадъра се решава в самия файл, не в кода. */
.hero{--hero-top:104px;min-height:0;height:calc(100svh - var(--hero-top) - var(--space-5))}
/* Anchored right on a phone, where the subject sits off-centre. Was
   `background-position-x:92%` plus `background-size:100vh` — the second of
   those sized the picture by the VIEWPORT HEIGHT, which on a narrow screen
   could come out shorter than the box and leave it uncovered. object-fit
   always covers, so only the anchor is needed. */
.hero-bg{object-position:92% center}
.hero-inner{display:flex;flex-direction:column}
.hero-col{display:contents}
.hero-origin{order:1;margin-bottom:0}
.hero-tags{order:2}
.hero-lead{order:3;margin-top:auto}
}
}

/* ═══ sections/home-cosmetics ═══ */
/* Козметиката на началната (sections/home-cosmetics.liquid). Root е `.hc-sec`.
 *
 * МАКЕТЪТ Е 1360x768 и всички мерки на продуктите са в неговите px. Сцената
 * е дясната половина — 680 широка, центърът ѝ на височина 384 — и в нея
 * 1 px от макета е `100cqw / 680`. Така купчината расте с ширината, както в
 * макета, без скрипт да я мери.
 */
@scope (.hc-sec) {

/* Без закачане: секцията просто минава. Текстът и бутонът са на 50vh от
   горния ѝ ръб — тоест в средата на екрана, щом тя опре горе, което е и
   краят на прехода.

   ОТДОЛУ Е ОТРЯЗАНА: свършва на 230px от макета под средата — докъдето
   стигат продуктите и сенките им във финала (219), плюс малко. Беше цял
   екран и под купчината оставаха ~200px празно, отгоре на отстъпа на
   футъра; последната секция на началната стоеше много по-далеч от него,
   отколкото на другите страници. Сцената остава висока колкото екрана, за
   да е центърът ѝ на 50vh, и стърчи под секцията — празна.

   `overflow-x: clip` — разпръснатите продукти излизат встрани. Вертикално не
   се реже: по средата на прехода долните още са под ръба.

   РАМКАТА. Макетът е 1360 с 48px поле, тоест съдържанието плюс по 48px от
   всяка страна. Над 1770px полето на сайта става 12vw и рамката се свива
   със същото — `--hc-inset`, — иначе текстът оставаше в тясната си колона,
   а продуктите растяха с цялата половина на екрана. До 1770 инсетът е 0. */
:scope{
  --hc-inset: calc(var(--page-pad, 48px) - 48px);
  position: relative;
  height: calc(50vh + (100vw - 2 * var(--hc-inset)) * 230 / 1360);
  display: grid; grid-template-columns: 1fr 1fr; align-items: start;
  padding-inline: var(--hc-inset);
  overflow-x: clip;
  background: var(--white);
  --hc-shift: 0;
}

/* ---- текстът ---- */
/* Над продуктите: в началото EGF стои зад заглавието. */
.hc-copy{
  position: relative; z-index: 10;
  top: 50vh; transform: translateY(-50%);
  padding: 0 48px;
  display: flex; flex-direction: column; align-items: flex-start;
}
/* Ширините пречупват като в макета: „…козметика / за оптимални…" и
   параграфът на три реда. В `ch` и `em`, за да следват кегела. */
.hc-copy h2{ margin: 0 0 var(--space-2); max-width: 23ch; }
.hc-copy p{ margin: 0 0 var(--space-4); max-width: 24.5em; color: var(--ink); }

/* ---- сцената ---- */
.hc-stage{
  position: absolute; z-index: 1;
  top: 0; height: 100vh; left: 50%; right: var(--hc-inset);
  container-type: inline-size;
  /* Стърчи под секцията върху горния край на футъра — не бива да хваща
     кликовете там. Бутонът си ги връща. */
  pointer-events: none;
}
/* Крайното място на картинката — горният ѝ ляв ъгъл в макета. Скриптът
   отмества и мащабира от тук, около центъра ѝ. */
.hc-prod{
  position: absolute; z-index: var(--i, 0);
  left: calc((var(--ex) - 680 + var(--hc-shift)) * 100cqw / 680);
  top: calc(50% + (var(--ey) - 384) * 100cqw / 680);
  width: calc(619 * 100cqw / 680); height: auto;
  aspect-ratio: 619 / 503;
  transform-origin: 50% 50%;
  pointer-events: none; user-select: none;
}
/* Бутонът е на x 935 в макета и на средата по височина — на нивото на
   текста. Над всички продукти. */
.hc-go{
  position: absolute; z-index: 10;
  left: calc((935 - 680 + var(--hc-shift)) * 100cqw / 680);
  top: 50%; transform: translateY(-50%);
  pointer-events: auto;
}

/* ---- телефон ---- */
/* Дизайн няма. Текстът е отгоре, сцената под него — същите пропорции, 680
   към 768, на цялата ширина. Купчината в макета е малко вляво от средата на
   сцената; тук е сама на реда и `--hc-shift` я връща в средата. Скриптът
   стеснява и разпръснатото, за да не излиза цялото извън екрана. */
@media (max-width: 768px){
:scope{ display: block; height: auto; padding-inline: 0; --hc-shift: 24; }
.hc-copy{ top: auto; transform: none; padding: var(--section-pad) var(--space-4) var(--space-5); }
.hc-copy h2{ font-size: var(--text-h3); max-width: none; }
.hc-stage{ position: relative; top: auto; height: auto; left: auto; right: auto; width: 100%; aspect-ratio: 680 / 768; }
/* Бутонът е в средата на сцената — купчината е сама на реда. */
.hc-go{ left: 50%; transform: translate(-50%, -50%); }
}

}

/* ═══ sections/home-groups ═══ */
/* Апаратите по решение на началната (sections/home-groups.liquid). Root е
 * `.hg-sec`.
 *
 * `@property` е ИЗВЪН `@scope`: регистрацията на свойство е глобална и в
 * scope блок не важи. Регистрирано е, за да може браузърът да анимира
 * `--hg-blind` — нерегистрирана променлива се сменя наведнъж, без преход.
 */
@property --hg-blind {
  syntax: '<percentage>';
  inherits: false;
  initial-value: -1%;
}

@scope (.hg-sec) {

:scope{ position: relative; z-index: 1; background: var(--white); }

/* Всички мерки на групата на едно място. Снети са от макета (1360x768):
     карта       170px висока, долният ѝ ръб на 48px от дъното на екрана
     стъпка      64px между две наслоени карти — заглавието с тага + 16px
     ширина      622px
   Ходът е по `--hg-step` на апарат: тригерът на всеки следващ идва след
   толкова скрол, а последният получава същото време, преди секцията да
   пусне. Същото число е `STEP` в scripts/page/home-groups.js — двете се
   сменят заедно.

   `--hg-lead` е скролът от горния ръб на секцията до първия тригер; мери го
   скриптът. На десктоп е ОТРИЦАТЕЛЕН — тригерът е, когато заглавието стигне
   средата на екрана, преди секцията да опре горе, — и ходът се скъсява
   със същото. */
.hg-group{
  --hg-card-h: 170px;
  --hg-peek: 64px;
  --hg-bottom: 48px;
  --hg-card-w: 622px;
  --hg-step: 50vh;
  --hg-travel: calc(max(var(--hg-lead, 0px), 0px) + var(--hg-n, 3) * var(--hg-step));
}
.hg-runway{ position: relative; }

/* ---- видеата ---- */
/* Отделен sticky слой, не дете на пина — виж бележката в партиала. */
.hg-film{ position: sticky; top: 0; height: 100vh; overflow: hidden; background: var(--white); }
.hg-layer{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; display: block;
  pointer-events: none;
  z-index: 0;
}
.hg-layer.is-active{ z-index: 1; }
.hg-blank{ background: var(--white); }
.hg-layer--ph{ background: var(--grey-200); }
/* Изправеният филм е само за телефон. */
.hg-layer--m{ display: none; }

/* Платното на прехода — над всички слоеве, видимо само докато тече. */
.hg-fx{
  position: absolute; inset: 0; z-index: 3;
  width: 100%; height: 100%; display: block;
  pointer-events: none; visibility: hidden;
}
.hg-fx.is-on{ visibility: visible; }

/* ЩОРИТЕ. Новият слой е отгоре и се разкрива през 25 вертикални ленти по
   4%, всяка с мек ръб от 1%. Пет пъти повече от кода, от който е пренесено —
   там лентите бяха 5 по 20%; ръбът е свит в същата пропорция, за да остане
   една четвърт от лентата.

   Спрямо онзи код ръбът е ОГРАНИЧЕН до края на лентата — `min(… + 1%, 4%)`.
   Без това в края прозрачната спирка отива извън периода, повтарящият
   градиент удължава периода си и остава полупрозрачна ивица; маската се маха
   с прещракване. Така при 4% лентата е изцяло плътна, а при -1% — изцяло
   прозрачна.

   Скриптът слага `is-revealing` (тоест -1%), а в следващия кадър `is-go` —
   преходът до 4% тръгва от там.

   Това е РЕЗЕРВНИЯТ път — когато няма WebGL. Посоката в лентата е същата
   като на растерната маска: напред всяка лента се отваря от десния си край
   (`to left`), на обратен скрол — от левия. Разминаването между лентите го
   няма, то е от маската. */
.hg-layer.is-revealing{
  z-index: 2;
  --hg-blind: -1%;
  -webkit-mask-image: repeating-linear-gradient(to left,
    #000 0, #000 var(--hg-blind), transparent min(calc(var(--hg-blind) + 1%), 4%), transparent 4%);
          mask-image: repeating-linear-gradient(to left,
    #000 0, #000 var(--hg-blind), transparent min(calc(var(--hg-blind) + 1%), 4%), transparent 4%);
  transition: --hg-blind .8s cubic-bezier(.25, 1, .5, 1);
}
.hg-layer.is-revealing.is-go{ --hg-blind: 4%; }
.hg-layer.is-revealing.is-back{
  -webkit-mask-image: repeating-linear-gradient(to right,
    #000 0, #000 var(--hg-blind), transparent min(calc(var(--hg-blind) + 1%), 4%), transparent 4%);
          mask-image: repeating-linear-gradient(to right,
    #000 0, #000 var(--hg-blind), transparent min(calc(var(--hg-blind) + 1%), 4%), transparent 4%);
}

/* ---- пинът ---- */
.hg-stage{ position: relative; z-index: 1; height: calc(100vh + var(--hg-travel)); margin-top: -100vh; }
.hg-pin{ position: sticky; top: 0; height: 100vh; }

/* ---- заглавието и хапчетата ---- */
/* На --space-9 (96px) от горния ръб на секцията, не на 48 от макета: при
   скрол нагоре навигацията се връща и закриваше заглавието. Докато секцията
   влиза, хапчетата са раздалечени и се събират към заглавието:
   `--hg-spread` е добавката към отстоянието и скриптът я смята от това
   колко още има до горния ръб. */
/* Отстоянието между заглавието и ПЪРВОТО хапче носи същата добавка като
   това между хапчетата — иначе първото стоеше залепено и се събираха само
   следващите.

   Кутията е половината от ширината на секцията; заглавието в нея е до 25ch,
   за да се пречупва на ред, а не да стига до средата на екрана. На телефон
   ограничението пада. */
.hg-copy{
  position: absolute; z-index: 2;
  top: var(--space-9); left: var(--page-pad, 48px);
  width: 50%;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: calc(var(--space-4) + var(--hg-spread, 0px));
}
.hg-copy h2{ font-size: var(--text-h2); max-width: 25ch; margin: 0; }
/* Лийдът под заглавието. Мярката е в `ch`, както при `.hh-lede` на героя, но
   по-широка: всеки ред тук избутва хапчетата към картите отдолу. */
.hg-lede{ margin: 0; max-width: 56ch; line-height: var(--leading-body); }
.hg-pills{
  display: flex; flex-direction: column; align-items: flex-start;
  gap: calc(var(--space-4) + var(--hg-spread, 0px));
}

/* ---- картите ---- */
/* Всички са в една кутия, закотвена на предната позиция — отляво page-pad,
   отдолу 48px — и стоят една върху друга. По-късната е отгоре (`--i`).

   Картите ПЪЛЗЯТ нагоре със скрола, много по-бавно от него: с една лента
   (`--hg-peek`) за един ход между два апарата, тоест ~14%. Когато предната
   се е вдигнала с цяла лента, отдолу влиза следващата и тръгва преходът —
   и стекът в този момент е точно стълбата от заглавия. Позицията пише
   скриптът в `transform`, на всеки кадър и без преход; влизането е в
   `translate` и тече във времето, затова двете не се бият. Еднаквата
   закована височина е това, което прави лентата точна. */
.hg-cards{
  position: absolute; z-index: 2;
  left: var(--page-pad, 48px); bottom: var(--hg-bottom);
  width: min(var(--hg-card-w), calc(100% - var(--page-pad, 48px) * 2));
  height: var(--hg-card-h);
}
.hg-card{
  position: absolute; inset: 0; z-index: var(--i, 0);
  box-sizing: border-box;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; column-gap: var(--space-4);
  padding: 20px var(--space-5);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .45);
  border: 1px solid var(--white);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  color: var(--ink); text-decoration: none;
  /* В покой — преди тригера си: отдолу и прозрачна. Влизането е slide-up +
     fade-in; видеото има своя преход. */
  opacity: 0; translate: 0 40px; pointer-events: none;
  transition: translate .6s var(--ease-standard), opacity .6s var(--ease-standard),
              background var(--duration-slow, .4s) var(--ease-standard);
}
.hg-card.is-shown{ opacity: 1; translate: 0 0; pointer-events: auto; }
.hg-card.is-front{ background: rgba(255, 255, 255, .8); }

/* ЗАДНИТЕ КАРТИ се виждат над предната само със заглавието и тъмния таг +
   16px; останалото е зад нея. Не се изрязва — предната е с размиване и .8
   плътност, тъй че задната прозира през нея размита, а не четлива.

   Над три се вижда само последните три — по-старата избледнява. */
.hg-card.is-gone{ opacity: 0; pointer-events: none; }

.hg-card__art{ grid-column: 1; align-self: center; }
.hg-card__art img{ display: block; height: 126px; width: auto; }
/* 16px между заглавието и описанието, не 8: видимата лента на задната карта
   е заглавието + 16px, тъй че при по-малко отстояние първият ред на
   описанието надничаше над предната. В макета то е ~18px по същата причина. */
.hg-card__body{
  grid-column: 2; align-self: stretch; min-width: 0;
  display: flex; flex-direction: column; gap: var(--space-4);
}
/* `line-height: 1`, за да е редът висок колкото самото заглавие — от него се
   мери стъпката: 20 отгоре + реда + 16 = 64. */
.hg-card__head{ display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.hg-card__head h3{ font-size: var(--text-h4); line-height: 1; margin: 0; }
.hg-card__desc{
  margin: 0; font-size: var(--text-p); line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.hg-card__tags{ margin-top: auto; }
/* Стрелката е на РЕДА НА ЗАГЛАВИЕТО, не в средата на картата. Бутонът е
   по-висок от този ред — 42px срещу 28-те, които h3 дава с `line-height: 1`,
   — тъй че се центрира спрямо реда, с половината разлика нагоре.

   Размерът е изписан със същите мерки, от които е сглобен самият бутон
   (`icon-btn` в components.css: padding var(--space-3) + иконка 1rem + 1px
   кант), за да не се разминат, ако някоя от тях се смени.

   Само на десктоп: на телефон бутонът остава долу вдясно, на реда на
   таговете — мерките там са други и `margin-top` се нулира. */
.hg-card{ --hg-go-size: calc(var(--space-3) * 2 + 1rem + 2px); }
.hg-card__go{
  grid-column: 3;
  align-self: start;
  margin-top: calc((var(--text-h4) - var(--hg-go-size)) / 2);
}

/* Ховърът на стрелката идва от ЦЯЛАТА карта. Тук, в CSS, а не през
   `hover-scope` на компонента: там закачането на слушателите е само в пътя,
   който строи бутона на клиента, а всички бутони на сайта са рендирани от
   сървъра (`data-ssr`) — `hover-scope` не прави нищо. Стойностите са тези на
   `icon-btn:hover` в components.css. */
.hg-card:hover .hg-card__go .icon-btn__el,
.hg-card:focus-visible .hg-card__go .icon-btn__el{
  background: var(--ink); border-color: var(--ink); color: var(--white);
}

/* ---- телефон ---- */
/* Заглавието си тръгва с обикновения скрол: пинът пада (`display: contents`)
   и копието минава в потока на сцената, вместо да е залепено над видеото.
   Видеото и картите идват, щом h2 излезе от екрана — хапчетата тогава още
   стоят горе, над видеото. Чакането на целия блок оставяше за миг празен бял
   екран. Затова ходът е скролът до дъното на h2 (`--hg-lead`, мери го
   скриптът) плюс по `--hg-step` на апарат.

   Картите лепнат сами, със своя `top`, на 12px от дъното. Мерки от макета
   (360x640): карта 174px, стъпка 60px. */
@media (max-width: 768px){
.hg-group{
  --hg-card-h: 174px;
  --hg-peek: 60px;
  --hg-bottom: var(--space-3);
  --hg-travel: calc(max(var(--hg-lead, 50vh), 0px) + var(--hg-n, 3) * var(--hg-step));
}
.hg-layer--d{ display: none; }
.hg-layer--m{ display: block; }
.hg-pin{ display: contents; }
.hg-copy{ position: relative; top: auto; left: auto; width: auto; padding: 48px var(--space-4) var(--space-6); }
.hg-copy h2{ font-size: var(--text-h3); max-width: none; }
.hg-cards{
  position: sticky; left: auto; bottom: auto;
  top: calc(100svh - var(--hg-bottom) - var(--hg-card-h));
  margin-inline: var(--space-4); width: auto;
}
/* Без изрезка; бутонът е долу вдясно, на реда на таговете. */
.hg-card{ grid-template-columns: minmax(0, 1fr) auto; padding: 20px var(--space-4) var(--space-4); }
.hg-card__art{ display: none; }
.hg-card__body{ grid-column: 1; }
.hg-card__go{ grid-column: 2; align-self: end; margin-top: 0; }
.hg-card__desc{ -webkit-line-clamp: 4; }
/* На телефон няма ховър — бутонът стои активен. */
.hg-card__go .icon-btn__el{ background: var(--ink); border-color: var(--ink); color: var(--white); }
}

/* Без движение: щорите и картите сменят състоянието си наведнъж. */
@media (prefers-reduced-motion: reduce){
.hg-card, .hg-layer{ transition: none !important; }
}

}

/* ═══ sections/home-hero ═══ */
/* Отварянето на началната (sections/home-hero.liquid). Root е `.home-hero`.
 *
 * Филмът е закован слой на целия екран; текстът върви с останалата страница.
 * Докато скролваш, филмът не помръдва — само се уголемява и размива, карано от
 * scripts/page/home-hero.js през двете custom properties долу.
 *
 * `position: fixed` върху `.hh-film` значи, че НИЩО над него в дървото не бива
 * да носи `transform`, `filter` или `will-change` — всяко от трите прави от
 * предшественика контейниращ блок и заковаването се превръща в обикновено
 * абсолютно позициониране. Затова `.rv` е върху текста, а не върху секцията.
 *
 * И второ, което всяка СЛЕДВАЩА секция на тази страница дължи: непрозрачен фон
 * и `z-index` над филма. Закован слой не свършва там, където свършва секцията
 * му — той стои в екрана, докато не го скрият. Белият панел на „Защо LMed" го
 * покрива, но е 474px при екран 911, тъй че под него се показваше отново, зад
 * групите. `data-past` долу го скрива чак когато hero-то е минало изцяло, а
 * дотам има цял екран, в който филмът лично не е покрит от нищо.
 */
@scope (.home-hero) {

:scope{
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: var(--crumb-h) var(--page-pad) var(--space-8);
  /* Докъде стигат уголемяването и размиването в края на пътя. Стоят тук, а не
     в скрипта: колко се приближава кадърът е дизайнерско решение, а скриптът
     само интерполира между 1 и това. */
  --hh-scale-to: 1.28;
  --hh-blur-to: 14px;
}

/* ---------- филмът ---------- */
/* БЕЗ `pointer-events: none` тук, колкото и да се проси на слой, който нищо не
   натиска. scripts/page/lazy.js решава дали да пусне филма с проба
   `elementFromPoint` ВЪРХУ РОДИТЕЛЯ на видеото — а кутия с изключени събития е
   невидима за пробата. С `none` и деветте ѝ точки връщаха секцията или
   заглавието, `visible()` връщаше false завинаги и `play()` не се викаше
   никога. Изключено е само самото видео, за да не се хваща за влачене. */
.hh-film{
  position: fixed;
  inset: 0;
  z-index: 0;
  overflow: hidden;
  background: var(--grey-200);
}
/* Кадърът е ИЗНЕСЕН отвъд кутията, защото размиването смесва и това, което е
   ОТВЪН нея — а отвън е прозрачно, тъй че по ръба се появява светла ивица.
   40px са достатъчни за blur(14px); кутията ги отрязва. */
.hh-video{
  position: absolute;
  inset: -40px;
  width: calc(100% + 80px);
  height: calc(100% + 80px);
  object-fit: cover;
  display: block;
  transform: scale(var(--hh-scale, 1));
  filter: blur(var(--hh-blur, 0px));
  transform-origin: 50% 45%;
  will-change: transform, filter;
  pointer-events: none;
}
/* Щом секцията е минала изцяло нагоре, филмът няма какво да прави в екрана:
   белият панел на „Защо LMed" отдавна го покрива, а под него идват секции без
   собствен фон, през които закованият слой би се показал отново. */
:scope[data-past] .hh-film{ visibility: hidden; }

/* ---------- текстът ---------- */
/* Широчината е ДЯЛ от страницата, а не мярка в `ch`: `ch` се смята спрямо
   шрифта на елемента, който го носи, а той тук е с кегела на текста — тъй че
   46ch върху блока даваха 370px и чупеха заглавието на пет реда вместо на три.
   Мярката за самото заглавие е на самото заглавие, долу, където `ch` значи
   каквото трябва.

   Дялът е таван, не ширина: ледето спира на своите 45ch, а заглавието — на
   своите 28ch или на дяла, което дойде първо. При 59% дялът идва пръв на
   всяка ширина, тъй че той е този, който реже заглавието, и закръглената част
   се пренася на два овала. Това е нарочно избрано: кутията оцелява при
   пренасяне, откакто е `inline` с `box-decoration-break: clone`. */
.hh-copy{ position: relative; z-index: 1; max-width: 59%; }

.hh-title{
  font-family: var(--font-display);
  font-weight: var(--weight-heading);
  font-size: var(--text-h1);
  line-height: 1.22;
  margin: 0;
  /* 28ch събира „Качествена естетична апаратура" на един ред и оставя
     закръглената част на свой. По-тясна мярка къса и нея. */
  max-width: 28ch;
}
/* Заоблено стъкло зад парче от заглавието. `inline-block`, за да се пренася
   като цяло: при `inline` фонът се къса на два реда и се получават две
   половини от овал.

   ЕДИН ЕЛЕМЕНТ — ЕДИН ОВАЛ, и документът дели дългата фраза на два записа
   заради това. Опитът беше точно обратният: един `inline` елемент с
   `box-decoration-break: clone`, който сам се пренася и дава на всяко парче
   пълен контур. Фонът наистина се цепи правилно, но `backdrop-filter` НЕ се
   цепи с него — то се прилага върху кутията на ЕЛЕМЕНТА, а тя е общата за
   всички парчета. Мерено: парчетата стояха на x=512 и x=230, а кутията беше
   x=230, y=554, 646x140 — един правоъгълник върху двата реда. Резултатът е
   размита дума между двата овала, която не е в нито един от тях.

   БЕЗ вертикален падинг. Кутията на inline-block без падинг е висока точно
   колкото собствения си ред, а той наследява `line-height` от заглавието —
   значи точно колкото е и редът на самото заглавие. Така кутиите на два
   съседни реда се ДОПИРАТ. Дотук тук стояха `padding: .1em` и
   `margin-block: -.1em`: падингът ги правеше по-високи от реда, отрицателният
   отстъп връщаше реда на мястото му, а кутиите се застъпваха.

   Стъкло, а не контур: полупрозрачно бяло с размиване отзад, същото като
   стъклените панели в картите. `.45` е стойността, с която сайтът рисува бяло
   стъкло другаде (`.card.wide .panel`).

   Едно за протокола: докато `.rv` на заглавието още тече, то носи
   `will-change: transform` и `transform` — и двете правят от него backdrop
   root, тъй че размиването тук е без действие за времето на прехода. Изчиства
   се на `transitionend` (виж бележката в scripts/page/interactions.js), а
   дотогава текстът и без това се появява. */
.hh-box{
  display: inline-block;
  white-space: nowrap;
  padding-inline: .4em;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, .45);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}

.hh-lede{
  margin: var(--space-5) 0 0;
  line-height: var(--leading-body);
  /* Тук `ch` е вярната мярка — параграфът е с кегела, спрямо който се смята. */
  max-width: 45ch;
}
.hh-cta{ margin-top: var(--space-5); }

@media (max-width: 768px){
:scope{ padding: var(--crumb-h) var(--space-4) var(--space-7); }
.hh-title{ font-size: var(--text-h2); max-width: none; }
.hh-copy{ max-width: none; }
/* По-тесен падинг, защото овалът не може да се пренася: при .4em „финансови
   условия" мери 332px, а на 360px екран с 16px улук са налични 328. Мярката
   е на най-тесния екран в макета, не на предпочитание. */
.hh-box{ padding-inline: .3em; }
}

/* Без движение: филмът не се уголемява и не се размива. Скриптът и без това не
   пипа свойствата при reduced-motion, но тук е и казано — стойността по
   подразбиране е спокойното състояние, а не начало на път. */
@media (prefers-reduced-motion: reduce){
.hh-video{ transform: none; filter: none; will-change: auto; }
}

}

/* ═══ sections/makers ═══ */
/* Производителите на началната (sections/makers.liquid). Root е `.makers-sec`.
 *
 * Едно каре с филм за фон: заглавието стъпва в горния ляв ъгъл, стъклената
 * карта — в долния десен. Между тях няма нищо, затова карето е решетка от два
 * реда, чийто среден ред е празният въздух.
 */
@scope (.makers-sec) {

/* Непрозрачен фон и слой над закования филм на hero-то — дългът на всяка
   секция под него. Виж бележката в home-hero.css. */
:scope{
  position: relative;
  z-index: 1;
  background: var(--white);
  padding: var(--section-pad) var(--page-pad, 48px) 0;
}

.mk-panel{
  position: relative;
  overflow: hidden;
  border-radius: var(--radius-lg);
  /* Височината идва от макета: карето заема почти целия екран, но не расте
     безкрайно на голям монитор. */
  min-height: min(82svh, 720px);
  padding: var(--space-6);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  /* Докато филмът го няма — сиво, с точния размер на карето. */
  background: var(--grey-200);
}

.mk-video{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
  pointer-events: none;
}

/* Заглавието лежи ВЪРХУ филма и е БЯЛО. В макета беше мастилено, защото там
   зад него е светла зала; истинският филм минава от почти черно до почти бяло
   точно под текста — мерена средна яркост на горния ляв ъгъл през кадрите:
   125, 195, 133, 139, 168, 49, 176, 41, 55, 138, 149 от 255.

   Бялото е по-доброто от двете за този диапазон, но не е решение за целия:
   на кадрите към 195 то на свой ред ще избледнява. Ако това започне да личи,
   следващото е тъмен воал в горния ляв ъгъл — градиент под текста, огледален
   на този, който вече изсветлява долната част за картата. */
.mk-title{
  position: relative;
  z-index: 1;
  color: var(--white);
  font-size: var(--text-h2);
  margin: 0;
  /* 22ch пречупва след „производство в" — двата реда от макета. При 16ch
     „производство" падаше на втория ред и заглавието ставаше на три. */
  max-width: 22ch;
}

/* Стъклената карта, долу вдясно. Същото стъкло като картите в сцената с
   апаратите и в заглавната секция — един облик за „нещо, което лежи върху
   нещо". */
.mk-card{
  position: relative;
  z-index: 1;
  align-self: flex-end;
  width: min(100%, 380px);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-5);
  border-radius: var(--radius-md);
  background: rgba(211, 229, 229, .45);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  border: 1px solid var(--accent-200);
}
.mk-card p{ margin: 0; line-height: var(--leading-body); }
.mk-card .lmed-btn{ margin-top: var(--space-2); align-self: flex-start; }

@media (max-width: 768px){
:scope{ padding: var(--section-pad) var(--space-4) 0; }
.mk-panel{ min-height: min(88svh, 620px); padding: var(--space-4); }
.mk-title{ font-size: var(--text-h3); max-width: none; }
/* Картата заема целия ред: 380px до ръба на телефон не оставя поле, а и
   долният десен ъгъл няма какво да значи, когато карето е широко колкото
   екрана. */
.mk-card{ align-self: stretch; width: auto; padding: var(--space-4); }
}

}

/* ═══ sections/mfr-about ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .mfr-about. The bundle is one stylesheet on every page, so without
 * this a name like .ac would silently restyle another section. */
@scope (.mfr-about) {
/* За LMedical — стек от sticky карти. От proizvoditeli-v3.
 *
 * САМАТА КАРТА е в components.css: същият стек ползва и секцията `about` на
 * страницата на апарат, а @scope стига само надолу от един корен. Тук остава
 * това, което е на СЕКЦИЯТА — решетката, лийдът и двата прага, на които
 * картите кацат.
 *
 * Скриптът (scripts/components/card-stack.js) мести само transform на картите
 * и opacity на фона; всичко останало, включително подредбата на стека, е тук
 * и в components.css. Трите променливи долу са контрактът между тях. */
:scope{position:relative;padding:var(--space-9) var(--page-pad);
  /* Нивото, на което каца активната карта. Скриптът я смята от sticky top на
     лийда плюс отстоянието до параграфа; тази стойност е само fallback, докато
     не е мерил. */
  --ac-top:148px;
  /* Височината на свитата лента, в която се вижда само цифрата. Механична
     константа = padding-top на картата + реда с цифрата + оптичен отстъп. */
  --ac-step:84px;
  --about-lead-top:var(--space-7)}

.mfr-about__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-4)}
.mfr-about__lead{grid-column:1;align-self:start;position:sticky;top:var(--about-lead-top)}
.mfr-about__lead h2{margin:0;font-size:var(--text-h3);line-height:1.15}
.mfr-about__lead p{margin:var(--space-5) 0 0;line-height:1.5}
/* Първата карта тръгва от долния край на лийда. Скриптът мери височината му и
   я подава като --stack-lead-h; fallback-ът е измерената стойност на дизайна,
   за да не подскочи, ако скриптът закъснее. */
.mfr-about__cards{grid-column:2 / -1;padding-top:calc(var(--stack-lead-h, 195px) + var(--space-7))}

@media (max-width:768px){
  /* Лийдът излиза от решетката и застава над картите; снимката минава отгоре,
     а текстът пада на дъното на картата. */
  :scope{--ac-top:calc(var(--space-9) * 2.5);--ac-step:70px}
  .mfr-about__grid{display:block}
  .mfr-about__lead{position:static}
  .mfr-about__lead h2{font-size:var(--text-h4)}
  .mfr-about__cards{padding-top:var(--space-9)}
}
}

/* ═══ sections/mfr-hero ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .mfr-hero. The bundle is one stylesheet on every page, so without
 * this a name like .grid or .cta would silently restyle another section. */
@scope (.mfr-hero) {
/* Производители — решетката, която се пресява. От proizvoditeli-v3.
 *
 * Височината е скролът: 270svh носи sticky стейдж от 100svh, тоест ~1.7
 * екрана скрол за цялата анимация. Клетките и логата ги прави
 * scripts/page/mfr-hero.js — тук са само формата и началните състояния.
 *
 * Без --page-pad fallback-и: токенът е дефиниран в tokens/spacing.css за
 * всяка ширина, а fallback, който се разминава с него, е по-лош от липсващ. */
:scope{position:relative;height:270svh;overflow-x:clip;
  --field-cols:12;--field-rows:8;--field-gap:var(--space-3);
  /* Симетрична рамка. Полето е центрирано в екрана — не закачено под менюто,
     защото менюто се крие при скрол и просветът му оставаше като дупка. */
  --field-margin:var(--space-6)}
.mfr-hero__stage{position:sticky;top:0;height:100svh}
/* Равни отстъпи горе и долу в стейдж от 100svh — центрирано по строеж, без
   изчисление. Плочката няма своя пропорция: 12x8 разделят това, което
   БРАУЗЪРЪТ дава, така че формата ѝ следва екрана, а не някоя резолюция. */
.mfr-hero__field{position:absolute;z-index:1;left:0;right:0;
  top:var(--field-margin);bottom:var(--field-margin);height:auto;display:grid;
  grid-template-columns:repeat(var(--field-cols),1fr);
  grid-template-rows:repeat(var(--field-rows),1fr);gap:var(--field-gap);
  padding:0 var(--page-pad)}
.mfr-hero__cell{position:relative;border-radius:var(--radius-sm);background:var(--grey-300);
  will-change:opacity,transform}
/* Само четирите ъгъла на решетката носят големия радиус — вътрешните клетки
   остават с малкия, за да чете полето като един блок, а не като 96 копчета. */
.mfr-hero__cell.is-tl{border-top-left-radius:var(--radius-lg)}
.mfr-hero__cell.is-tr{border-top-right-radius:var(--radius-lg)}
.mfr-hero__cell.is-bl{border-bottom-left-radius:var(--radius-lg)}
.mfr-hero__cell.is-br{border-bottom-right-radius:var(--radius-lg)}
.mfr-hero__ink{position:absolute;inset:0;border-radius:inherit;background:var(--ink);opacity:0;
  display:grid;place-items:center}
.mfr-hero__ink svg{height:52%;width:auto;display:block}
.mfr-hero__tag{position:absolute;top:calc(100% + var(--space-2));left:50%;transform:translateX(-50%);
  white-space:nowrap;font-size:1rem;font-weight:var(--weight-body-semibold);color:var(--ink);opacity:0}
/* Същото центриране и същата височина като полето, за да съвпадне горният
   ръб: копието тръгва от първия ред на решетката, а него го знае само
   изчислението горе. */
/* Същата рамка като полето, за да съвпаднат горните ръбове — копието тръгва
   от първия ред на решетката. */
.mfr-hero__copy{position:absolute;z-index:2;
  top:var(--field-margin);bottom:var(--field-margin);
  left:calc(var(--page-pad) + var(--space-6));
  padding-top:var(--space-5);
  display:flex;flex-direction:column;align-items:flex-start}
.mfr-hero__copy h1{margin:0;font-size:var(--text-h2);line-height:1.15;max-width:30rem}
.mfr-hero__copy p{margin:var(--space-4) 0 0;line-height:1.5;max-width:30rem}
.mfr-hero__criteria{display:flex;flex-direction:column;gap:var(--space-3);margin-top:var(--space-5)}
/* Началното състояние на критериите; скриптът ги пали един по един. */
.mfr-hero__crit{opacity:0;transform:translateX(-8px);will-change:opacity,transform}

@media (max-width:768px){
  /* Тесният екран сменя реда: решетката лепне, а копието минава ОТГОРЕ ѝ с
     отрицателен margin, вместо да стои отляво. Затова стейджът се разтваря —
     двете деца трябва да са в потока на секцията, не в общ sticky контейнер. */
  /* Тук решетката НЕ е центрирана: тя лепне под менюто, а копието ляга върху
     нея. Затова мобилното си пази своите --field-top/--field-h и не ползва
     --field-margin. */
  :scope{height:170svh;--field-gap:4px;--field-top:16svh;--field-h:85svh}
  .mfr-hero__stage{display:contents}
  .mfr-hero__field{position:sticky;top:var(--field-top);bottom:auto;
    height:var(--field-h);padding:0 var(--page-pad) var(--space-4);
    grid-template-columns:repeat(6,1fr);grid-template-rows:repeat(10,1fr)}
  .mfr-hero__copy{position:relative;top:auto;bottom:auto;left:auto;height:auto;
    margin-top:calc(-1 * var(--field-h));
    padding:var(--space-5) var(--page-pad) var(--space-6)}
  .mfr-hero__copy h1{font-size:var(--text-h3)}
  .mfr-hero__tag{top:50%;left:auto;transform:translateY(-50%)}
  .mfr-hero__tag.tag--right{left:calc(100% + var(--space-2))}
  .mfr-hero__tag.tag--left{right:calc(100% + var(--space-2))}
}

@media (prefers-reduced-motion: reduce){
  /* Скриптът излиза рано, така че CSS трябва да покаже КРАЯ на анимацията:
     решетката отсята, логата видими, критериите на място. Иначе секцията е
     три екрана празни сиви квадрати. */
  :scope{height:auto}
  .mfr-hero__stage{display:contents}
  .mfr-hero__field{position:relative;top:auto;height:100svh}
  .mfr-hero__copy{position:relative;top:auto;left:auto;height:auto;margin-top:0;
    padding:var(--space-5) var(--page-pad) var(--space-8)}
  .mfr-hero__field,.mfr-hero__copy{transition:none}
  .mfr-hero__cell{opacity:.12;transform:scale(.92)}
  .mfr-hero__cell--keep{opacity:1;transform:none}
  .mfr-hero__cell--keep .mfr-hero__ink,.mfr-hero__cell--keep .mfr-hero__tag{opacity:1}
  .mfr-hero__crit{opacity:1;transform:none}
}
}

/* ═══ sections/mfr ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .mfr. The bundle is one stylesheet on every page, so without this a
 * name like .usp or .series-card would silently restyle another section. */
@scope (.mfr) {
/* Производител — един блок на марка. От proizvoditeli-v3, където замени
 * лентите (manufacturer-bands).
 *
 * Картата е sticky над видеото: тялото се вдига над нея с бял фон и я
 * покрива, докато се скролва. Затова .mb е sticky, а не .mb__card — лепне
 * целият блок с видеото, иначе картата излиза от него.
 *
 * .spec-card и .dl-row идват от styles/spec-card.css — същият компонент като
 * на страница апарат, затова не е преписан тук. */
:scope{position:relative;padding:0 var(--page-pad);margin-top:var(--space-9)}
:scope .mb{position:sticky;top:var(--space-7);z-index:0}

.mb{--mb-pad:var(--space-6);
  position:relative;overflow:clip;border-radius:var(--radius-lg);
  height:85svh;min-height:fit-content;
  display:flex;align-items:flex-start;gap:0;padding:var(--mb-pad)}
.mb__video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
/* 0.3 от ширината ПЛЮС двата padding-а — картата стига до 30% от блока, не от
   съдържанието му, иначе на широк екран изглежда по-тясна, отколкото е зададена. */
.mb__card{position:relative;z-index:2;flex:0 0 calc((100% + 2 * var(--mb-pad)) * 0.3);
  display:flex;flex-direction:column;align-items:flex-start;justify-content:flex-start;
  gap:var(--space-4);
  padding:var(--space-5);
  border:1px solid #fff;border-radius:var(--radius-md);
  background:rgba(255,255,255,.45);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.mb__card h2{margin:0;font-size:var(--text-h3);line-height:1.15}
.mb__card p{margin:0;line-height:1.5;color:var(--ink)}
.mb__pills{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-3)}

/* Бялото тяло, което се качва над видеото. */
.mfr__body{position:relative;z-index:1;background:var(--white);
  border-radius:var(--radius-lg);padding:var(--space-6)}

.mfr-intro{display:grid;grid-template-columns:repeat(3,1fr);
  column-gap:var(--space-4);row-gap:var(--space-6)}
.mfr-intro__mark{grid-column:1;grid-row:1}
.mfr-intro__mark svg{height:96px;width:auto;display:block}
.mfr-intro__h{grid-column:2;grid-row:1;margin:0;font-size:var(--text-h4);line-height:1.15}
/* Чиповете дублират тези в картата и на широк екран са излишни; на тесен
   картата се свива и те поемат ролята — виж медия заявката долу. */
.mfr-intro__pills{display:none}
.mfr-intro__p{grid-row:2;margin:0;line-height:1.5}
.mfr-intro__p:nth-of-type(1){grid-column:2}
.mfr-intro__p:nth-of-type(2){grid-column:3}

/* Три карти, всяка изместена надолу спрямо предната. Мерките са в cqw, за да
   се смятат спрямо ШИРИНАТА на реда, не на екрана — иначе застъпването се
   разпада, щом тялото има друг padding. */
.usps{container-type:inline-size;
  display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-4);
  align-items:start;margin-top:var(--space-9)}
.usp{--usp-h:calc((100cqw - 2 * var(--space-4)) / 3 * 4 / 7);
  --usp-overlap:calc(var(--usp-h) * 0.21);
  --usp-stagger:calc(var(--usp-h) * 0.556);
  --usp-lift:calc(var(--usp-h) * 0.234);
  display:flex;flex-direction:column}
.usp:nth-child(2){margin-top:var(--usp-stagger)}
.usp:nth-child(3){margin-top:calc(var(--usp-stagger) * 2)}
.usp__img{display:block;width:100%;aspect-ratio:7/4;
  border-radius:var(--radius-md);overflow:clip}
.usp__img img{width:100%;height:100%;object-fit:cover;display:block}
.usp__panel{position:relative;z-index:1;
  margin-top:calc(-1 * var(--usp-overlap));
  padding:var(--space-5);
  border:1px solid var(--accent-200);border-radius:var(--radius-md);
  background:rgba(255,255,255,.65);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  will-change:transform;transition:transform var(--duration-base) var(--ease-standard)}
.usp__panel h4{margin:0 0 var(--space-3);font-size:var(--text-h4);line-height:1.15;overflow-wrap:anywhere}
.usp__panel p{margin:0;line-height:1.5}
.usp:hover .usp__panel,
.usp:focus-within .usp__panel{transform:translateY(calc(-1 * var(--usp-lift)))}

.mfr-certs{margin-top:var(--space-9)}
.cert-note{margin:var(--space-5) 0 0;line-height:1.5;max-width:72ch}

.series{margin-top:var(--space-9)}
.series-head{display:flex;align-items:center;justify-content:space-between;
  gap:var(--space-5);margin-bottom:var(--space-5)}
.series-head h2{margin:0;font-size:var(--text-h3);line-height:1.15}
.series-nav{display:flex;gap:var(--space-3)}
.series-nav icon-btn[disabled]{opacity:.35;pointer-events:none}
/* Лентата излиза от белия блок до ръба на страницата: --bleed е точно
   padding-ът на тялото плюс този на страницата. */
.series-strip{display:flex;gap:var(--space-4);overflow-x:auto;
  scroll-behavior:smooth;scrollbar-width:none;
  --bleed:calc(var(--space-6) + var(--page-pad));
  margin:0 calc(-1 * var(--bleed));
  padding:0 0 0 var(--bleed)}
.series-strip::after{content:"";flex:0 0 calc(var(--bleed) - var(--space-4));align-self:stretch}
.series-strip::-webkit-scrollbar{display:none}
.series-card{position:relative;flex:0 0 calc((66% + var(--bleed)) * 2 / 3);
  min-height:470px;overflow:clip;
  background:var(--grey-200);border-radius:var(--radius-md)}
/* Една серия не е лента — картата заема реда и нищо не се скролва. */
.series-strip--single{--bleed:0px;margin:0;padding:0;overflow-x:hidden}
.series-strip--single::after{display:none}
.series-strip--single .series-card{flex:0 0 100%}
.series-card__body{position:relative;z-index:1;
  width:44%;padding:var(--space-5);
  display:flex;flex-direction:column;align-items:flex-start}
.series-card__body h3{margin:0;font-size:var(--text-h4);line-height:1.15}
.series-card__body p{margin:var(--space-3) 0 var(--space-5);line-height:1.5}
.series-card__body .lmed-btn{text-decoration:none}
.series-card__img{position:absolute;z-index:0;
  right:0;bottom:0;
  width:50%;height:auto;display:block}

@media (max-width:768px){
  /* Страницата поема отстрани, тялото поема отвътре — иначе двата padding-а се
     събират и на телефон остава лента съдържание. */
  :scope{padding:0}
  .mfr__body{padding:var(--space-4)}
  .mb{--mb-pad:16px;height:85svh;flex-direction:column}
  .mb__card{flex:0 0 auto;width:100%;padding:var(--space-4)}
  .mb__pills{display:none}
  .mfr-intro{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-5)}
  .mfr-intro__mark,.mfr-intro__h,.mfr-intro__p{width:100%}
  .mfr-intro__h{font-size:var(--text-h5)}
  .mfr-intro__pills{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-4)}
  .usps{grid-template-columns:1fr;gap:var(--space-6);margin-top:var(--space-8)}
  .usp{--usp-h:calc(100cqw * 4 / 7)}
  .usp:nth-child(2),.usp:nth-child(3){margin-top:0}
  .usp:hover .usp__panel{transform:none}
  /* .mfr вече е с padding:0, така че --bleed е само padding-ът на белия блок. */
  .series-strip{--bleed:var(--space-4)}
  .series-card{flex:0 0 95%;min-height:0;display:flex;flex-direction:column}
  .series-card__body{width:100%;padding:var(--space-4)}
  .series-card__img{position:static;width:80%;margin-top:0;margin-left:auto}
  .series-head h2{font-size:var(--text-h4)}
}

@media (prefers-reduced-motion: reduce){
  .usp__panel{transition:none}
  .usp:hover .usp__panel{transform:none}
}
}

/* ═══ sections/page-head ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .page-head. */
@scope (.page-head) {
/* Апарати — каталог. Портирано от devices.html в дизайна.
 *
 * Картите са product-card-compact / product-card-wide и носят стиловете си
 * от components.css; тук е само мрежата, хедърът и състоянията на филтрите.
 * Лентата с филтри е в tokens/filters.css — тя е част от дизайн системата,
 * не от тази страница. */

/* Всяка вложена страница започва на 133px: пътеката сама разчиства фиксираното
   меню и свършва там. HERA започва там с hero-то си, каталогът — със
   заглавието, и двете съвпадат.
   Пътеката е съсед на <main>, не на .page-head, така че `+` не я вижда —
   оттук и :has() върху body. Ако браузър не го поддържа, остава вариантът
   с пътека, който е обичайният. */
/* Разстоянието под хедъра е ритъмът между секции, не произволно число:
   дизайнът дава 96px на Производители и ~56 на Апарати, а 96 вече беше
   отхвърлено като твърде много. --section-pad е стойността, на която този
   сайт се разбра, и е една и съща на всяка страница с такъв хедър. */
:scope{ padding: 0 var(--page-pad, 48px) var(--section-pad); }
:scope h1{ font-size: var(--text-page-title); line-height: var(--leading-page-title);
  max-width: var(--measure-page-title); margin: 0 0 var(--space-3); }
:scope .lede{ max-width: var(--measure-lede); font-size: 1rem;
  line-height: var(--leading-lede); margin: 0; }
}

/* OUTSIDE the scope, necessarily: these selectors start above the root
 * (body:has(...)), beside it (an adjacent sibling), or target an element in a
 * DIFFERENT section. @scope only reaches DOWNWARD from its root, so inside the
 * block they would match nothing at all — silently. */
/* Лентата с филтри идва веднага след хедъра; собственият ѝ отстъп отгоре би
   удвоил ритъма, който хедърът вече е задал. */
.page-head + .filters{ padding-top: 0; }
body:not(:has(.breadcrumb)) .page-head{ padding-top: calc(84px + var(--space-4)); }
@media (max-width: 768px){
body:not(:has(.breadcrumb)) .page-head{ padding-top: calc(72px + var(--space-4)); }
}

/* ═══ sections/physics ═══ */
/* Физиката на въздействието (sections/physics.liquid). Root е `.phys-sec`.
 *
 * Трите режима са три карти на един ред. Дотук секцията беше сцената на `roi`
 * — висока писта, залепен слой, табове и една лента под тях — и оттам идваха
 * числата ѝ. От онази сцена не е останало нищо, затова и числата тук са на
 * секция като всяка друга на тази страница: същият горен отстъп и същият
 * страничен падинг като `equipment` точно отгоре.
 *
 * Обликът на картата е този на ui/rf-card (бяла, с мастилена рамка), но
 * правилата са тук, а не там: този компонент се ползва от две други секции и
 * им е точно толкова, колкото им трябва. Виж бележката в partial-а. */
@scope (.phys-sec) {

:scope{ padding: var(--section-pad) var(--page-pad, 48px); }

.phys-title{ font-size: var(--text-h2); margin: 0 0 var(--space-5); }

/* Трите карти са равни по ширина и се разтягат до най-високата — `stretch` е
   подразбирането на решетката и точно то се иска: редът от тагове на всяка
   каца на дъното ѝ чрез `margin-top:auto` по-долу, тъй че трите реда тагове
   стоят на една линия. */
.phys-cards{ display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-4); }

.phys-card{
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  background: var(--white);
  border: 1px solid var(--ink);
  border-radius: var(--radius-lg);
}
/* Без hover: картата не е връзка и нищо в нея не се натиска. (ui/rf-card
   светва в accent-200, защото там картите стоят в колона, по която окото
   върви.) */
.phys-card h3{ font-size: var(--text-h5); margin: 0; }

/* Лентата. Кутията пази пропорцията на артборда, тъй че картата е с крайната
   си височина от първата рисунка и редът не подскача, докато файлът дойде. */
.phys-anim{ width: 100%; aspect-ratio: var(--phys-ratio); }
.phys-anim svg{ display: block; width: 100% !important; height: 100% !important; }
/* Докато файлът го няма, кутията е празна — `:empty` спира да важи в мига, в
   който lottie сложи своето <svg> вътре, тъй че сивото си отива само. */
.phys-anim:empty{ background: var(--grey-200); border-radius: var(--radius-md); }

/* Двата параграфа: дребният казва какво ПРАВИ режимът механично, нормалният
   какво значи това. И двата са мастилени — сивото тук би ги разделило на
   „важно" и „маловажно", каквото не са. */
.phys-card__kicker{ margin: 0; font-size: var(--text-small); line-height: var(--leading-body); }
.phys-card__text{ margin: 0; line-height: var(--leading-body); }
/* `margin-top:auto` вдига реда на дъното на картата — трите реда тагове стоят
   на една линия, независимо че параграфите са различно дълги. */
.phys-card__tags{ display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: auto; }

/* Три карти с текст не се побират на един ред на таблет: две и една отдолу е
   по-лошо от три една под друга, защото редът на режимите е редът в костюма. */
@media (max-width: 1024px){
.phys-cards{ grid-template-columns: 1fr; }
}

@media (max-width: 768px){
:scope{ padding: var(--section-pad) var(--space-4); }
.phys-title{ font-size: var(--text-h3); }
.phys-cards{ gap: var(--space-4); }
.phys-card{ padding: var(--space-4); }
.phys-anim{ aspect-ratio: var(--phys-ratio-m, var(--phys-ratio)); }
}

}

/* ═══ sections/platform ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .platform-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.platform-sec) {
/* ---- Платформа: технологии + sticky панел ---- */
/* Bottom padding was 0, making the boundary with the attachments section
   64px where every other one is 128. */
:scope{padding:var(--section-pad) var(--page-pad,48px)}
.platform-grid{display:grid;grid-template-columns:2fr 1fr;gap:var(--space-5);align-items:start}
.platform-intro h2{font-size:var(--text-h3);margin:0 0 var(--space-4)}
.platform-intro>p{margin:0 0 var(--space-6);max-width:46ch}
.platform-masonry{display:flex;gap:var(--space-5)}
.rf-col{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-5)}
.rf-col--offset{margin-top:calc(var(--space-9)*2)}
/* The card moved to styles/rf-card.css when sections/technologies started
   using it too — unscoped, because a scoped rule reaches only its own root. */
.platform-aside{position:sticky;top:var(--space-6);border-radius:var(--radius-lg);overflow:hidden;background:var(--white) url("../derived/web/media/web/backgrounds/platform.webp") top center/cover no-repeat;display:flex;flex-direction:column;gap:var(--space-6);padding:var(--space-6);min-height:90vh}
.platform-aside__head{display:flex;flex-direction:column;gap:var(--space-2)}
.platform-aside__num{font-size:var(--text-h1);font-weight:var(--weight-heading);font-family:var(--font-display);line-height:.9;margin:0}
.platform-aside__head h3{font-size:var(--text-h4);margin:0}
.platform-aside__panel{margin-top:auto;display:flex;flex-direction:column;gap:var(--space-5)}
.platform-aside__panel p{color:var(--ink);margin:0}
.platform-aside__panel .lmed-btn{align-self:flex-start}
@media (max-width:1024px){.platform-grid{grid-template-columns:1fr}.platform-masonry{flex-direction:column}.rf-col--offset{margin-top:0}.platform-aside{position:static}}
}

/* ═══ sections/quote ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .quote-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.quote-sec) {
/* ---- Отзив: чиста типография ---- */
:scope{padding:var(--section-pad) var(--page-pad,48px)}
.quote{max-width:820px;margin:0 auto;text-align:center}
.quote .quote-mark{width:44px;height:44px;border-radius:50%;background:var(--accent-200);display:flex;align-items:center;justify-content:center;margin:0 auto var(--space-5);font-family:var(--font-display);font-size:var(--text-h5);font-weight:var(--weight-heading)}
.quote blockquote{margin:0 0 var(--space-4);font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h4);line-height:1.35}
.quote figcaption{color:var(--text-secondary)}
}

/* ═══ sections/range-head ═══ */
/* Отварящата секция на страница за серия (sections/range-head.liquid).
 * Root е `.range-head`.
 *
 * Тук е само РАМКАТА. Самата сцена — текстът, колоните и четирите слоя на
 * зоната — е ui/range-stage и стиловете ѝ са в styles/range-stage.css,
 * нескоупнати, защото я ползва и секция `groups` на началната. Оттам излязоха
 * и двете `@keyframes`: те и без това не са правила за стил и не се скоупват.
 */
@scope (.range-head) {
  :scope {
    position: relative;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    padding: 0 var(--page-pad) var(--space-7);
    overflow: hidden;
  }

  /* На телефон сцената се свива до текста си и височината няма какво да пази. */
  @media (max-width: 768px) {
    :scope { min-height: auto; padding-bottom: var(--space-8); }
  }
}

/* Извън обхвата, защото стига нагоре до body — и само над телефонната граница,
   където обхватът отпуска височината изцяло.

   Първият екран трябва да свършва на ръба на прозореца. Дизайнът държи
   пътеката ВЪТРЕ в hero-то, тъй че неговите 100svh вече я съдържат; нашата е
   хром над <main>, тъй че същите 100svh слагат апаратите с височината на
   пътеката ПОД сгъвката и разпъват всичко, опънато към стенда — разкритата
   стая включително — със същото. Същото изваждане прави и `.cos-hero`, от
   същия токен, който breadcrumb.css съществува да държи честен. */
@media (min-width: 769px) {
  body:has(.breadcrumb) .range-head { min-height: calc(100svh - var(--crumb-h)); }
}

/* ═══ sections/related ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .related-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.related-sec) {
/* ---- Свързани апарати ---- */
:scope{padding:var(--section-pad) 0 0}
.related-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-5);margin:0 var(--page-pad,48px) var(--space-6)}
:scope h2{font-size:var(--text-h3);margin:0}
.related-nav{display:flex;gap:var(--space-3)}
.related-nav icon-btn[disabled]{opacity:.35;pointer-events:none}
.related-strip{display:flex;gap:var(--space-5);overflow-x:auto;padding:0 var(--page-pad,48px) var(--space-3);scroll-behavior:smooth;scrollbar-width:none}
.related-strip::-webkit-scrollbar{display:none}
/* Мерките на картата в лентата, на едно място. Широката е ДВЕ тесни плюс
   междината — така тя ляга точно върху два слота и лентата остава на решетка,
   каквато и да е стойността. Дотук числото беше 700 срещу 340×2+24=704; четирите
   пиксела не личаха, но правеха двете независими. */
:scope{
  --rel-card-h: 440px;
  --rel-card-w: 340px;
}
/* Всички карти са .dcard — същата, която решетката на /aparati/ рисува. Тук тя
   получава ЯВНИ ширина и височина, което изключва собственото ѝ aspect-ratio:
   в лента картите трябва да са с една височина, а не с една пропорция.

   Широката карта (product-card-wide, два слота) си отиде оттук: лентата
   четеше като два различни списъка, залепени един до друг. */
.related-strip .dcard{flex-shrink:0;width:var(--rel-card-w);height:var(--rel-card-h)}

/* Над ширината, за която е рисуван дизайнът (1360), картата расте. Дотам
   лентата заема екрана; над нея 340px карти върху 1920 четат като миниатюри,
   а мястото отстрани е точно това, което расте.

   Двете мерки се вдигат с един и същи дял — 1.30 — за да не се променят
   пропорциите на самата карта: 340×440 и 440×572 са 0.773 и 0.769. */
@media (min-width: 1361px){
:scope{
  --rel-card-h: 572px;
  --rel-card-w: 440px;
}
}

/* ---- Под 768px ---- */
/* Картата се свива, за да се ПОДАДЕ ръбът на следващата. Забитите 340px бяха
   по-широки от полето на телефон (360 − 32 = 328), тоест първата карта го
   изяждаше цялото и лентата изглеждаше като една карта, която не води никъде.

   Мярката е спрямо полето, не спрямо екрана: `100%` на flex елемент се смята
   срещу съдържателната кутия на лентата — видимата, не тази на скрола — така
   че --space-8 е буквално колкото остава видимо от следващата.

   Височината пада на `auto`, за да поеме картата собственото си 3/4. Забита,
   тя правеше 280×440, тоест 0.64 — по-тясна дори от съотношението си. */
@media (max-width: 768px){
.related-strip .dcard{
  width: calc(100% - var(--space-8));
  height: auto;
}
}
}

/* ═══ sections/results ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .tech-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.tech-sec) {
/* ---- Технология + резултати: cases + sticky аside ---- */
:scope{padding:var(--section-pad) var(--page-pad,48px)}
.tech{display:grid;grid-template-columns:1fr 2fr;gap:var(--space-5);align-items:start}
/* Колона 1 — случаи */
.cases{display:flex;flex-direction:column;gap:var(--space-4)}
.cases h2{font-size:var(--text-h3);margin:0}
.cases .sub{color:var(--ink);margin:0}
/* Четирите кадъра от третирането. Номерът идва от <ol> — списъкът Е
   последователност, затова броенето е негово, не на CSS брояч. */
.steps{list-style:none;margin:0 0 var(--space-4);padding:0;display:grid;grid-template-columns:repeat(4,1fr);gap:var(--space-4);counter-reset:step}
.step{counter-increment:step;display:flex;flex-direction:column;gap:var(--space-2)}
.step__art{width:100%;aspect-ratio:3/4;object-fit:cover;border-radius:var(--radius-md);display:block}
.step h3{font-size:var(--text-h6);margin:var(--space-2) 0 0}
.step h3::before{content:counter(step) ". ";color:var(--text-secondary);font-weight:var(--weight-body-regular)}
.step p{margin:0;font-size:0.9rem;line-height:var(--leading-body)}
@media (max-width:900px){.steps{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.steps{grid-template-columns:1fr}}

/* Тук стояха `.is-more{display:none}` и `.expanded .is-more{display:flex}` —
   пет от осемте случая бяха скрити зад бутон „Виж още". Бутонът си отиде, а с
   него и скриването: осемте случая се показват. Отиде си и правилото за
   .lmed-btn, защото в тази секция вече няма бутон. */
/* Режимите на работа — две карти под една друга в лявата колона, докато
   карето вдясно стои закачено. Рисунката е в акцентна кутия с фиксирана
   пропорция: тя РЕЗЕРВИРА мястото преди файла да дойде, тъй че картата е с
   крайната си височина от първата рисунка. */
.mode-card{ background: var(--white); border: 1px solid var(--ink);
  border-radius: var(--radius-lg); padding: var(--space-5);
  display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); }
.mode-card h3{ margin: 0; font-size: var(--text-h4); line-height: var(--leading-heading); }
/* 3/2 е пропорцията на самите чертежи (300×203), закръглена — разликата е под
   процент, тъй че `contain` не оставя видими полета. Тя е тук, за да РЕЗЕРВИРА
   кутията преди файла: без нея картата е с една височина преди рисунката и с
   друга след нея, и страницата подскача. */
.mode-card__art{ width: 100%; aspect-ratio: 3 / 2; object-fit: contain;
  display: block; }
.mode-card p{ margin: 0; line-height: var(--leading-body); }

/* Колона 2 — карето. Самото то е в styles/aside-card.css, нескоупнато: ползва
   го и секция `satisfaction`, а @scope стига само надолу от един корен. */

/* Отзивчивите правила за тази секция. Стояха в cta.css, извън всякакъв scope —
   остатък от разделянето на слетите стилове. Там не важаха: некоширано
   `.x` губи от коширано `.x` в собствения му файл, защото близостта по scope
   тежи над реда, а медия заявката не добавя тежест. */
@media (max-width:1024px){
.tech{grid-template-columns:1fr}
}
/* На телефон редовете на решетката застават на същото разстояние, на което са
   и картите с режимите помежду си — иначе карето с физиката увисва по-далеч от
   тях, отколкото те една от друга. */
@media (max-width:768px){
.tech{gap:var(--space-4)}
}
}

/* ═══ sections/roi ═══ */
/* Възвръщаемост на инвестицията: сцена с табове и lottie анимация, под нея
 * трите блока, които дойдоха от секцията с накрайниците. Root е `.roi-sec`. */
@scope (.roi-sec) {

:scope{
  padding: 0 var(--page-pad, 48px) var(--section-pad);
  /* Пистата. Дели се на три РАВНИ трети, независимо че частите на анимацията
     са 3/2/2 секунди — виж бележката в scripts/page/roi.js. 210vh оставя 1,1
     екрана невидим скрол. */
  --roi-runway: 210vh;
}

.roi-scene{ position: relative; height: var(--roi-runway); }
.roi-pin{
  position: sticky; top: 0; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--space-7);
  padding: calc(84px + var(--space-5)) 0 var(--space-7);
}

/* ---- Заглавие и табове ---- */
/* Заглавието вляво, барът вдясно на същия ред — както е в макета. `flex-end`
   по вертикала: барът е нисък и подравнен по последния ред на заглавието,
   иначе плува в средата му. */
.roi-head{ display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--space-6); flex-wrap: wrap; }
/* 17ch = 436px, при което първият ред е „Възвръщаемост на" — пречупването от
   макета. При 14ch „на" пада на втория ред. */
.roi-head h2{ font-size: var(--text-h2); margin: 0; max-width: 17ch; }
/* Барът не се свива под собствената си ширина: трите етикета са дълги и
   пречупени изглеждат като три реда, а не като бар. Затова СКРОЛВА кутията
   около него, а не самият той — по образеца на .fbar-tabs в каталога. */
.roi-tabs{ flex: 0 0 auto; }
/* `0 0 auto` на широк екран, за да е точно както беше — барът не се свива,
   а редът се пренася, ако някога не стигне място. Свиването идва чак при
   ≤1024, където кутията взима реда за себе си. */
.roi-tabs-scroll{ flex: 0 0 auto; max-width: 100%;
  overflow-x: auto; overflow-y: clip; overscroll-behavior-x: contain;
  scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.roi-tabs-scroll::-webkit-scrollbar{ display: none; }

/* ---- Анимацията ---- */
/* Пропорцията идва от документа през style атрибут и държи кутията, преди
   файлът да е пристигнал. Тук е само как се разстила в нея. */
.roi-anim{ width: 100%; aspect-ratio: var(--roi-ratio); }
.roi-anim svg{ display: block; width: 100% !important; height: 100% !important; }

/* ---- Параграфът ---- */
.roi-note{ margin: 0; max-width: 52ch; line-height: var(--leading-body); }

@media (max-width: 1024px){
/* Барът слиза под заглавието и се разтяга — три дълги етикета на един ред до
   заглавие вече не се побират. */
.roi-head{ flex-direction: column; align-items: stretch; gap: var(--space-5); }
.roi-head h2{ max-width: none; }
.roi-tabs-scroll{ flex: 1 1 auto; }
}

@media (max-width: 768px){
/* Без долно поле: следващата секция си носи своето и двете заедно правеха 96px
   граница — повече, отколкото иска това място. */
:scope{ padding: 0 var(--space-4) 0; }
/* `min-height: 0`: на телефон съдържанието е по-високо от екрана (заглавие,
   табове, изправена лента и параграф), тъй че центрирането в 100svh не
   центрираше нищо, а само добавяше въздух. */
.roi-pin{ min-height: 0; padding: var(--space-6) 0 var(--space-6); gap: var(--space-5); }
.roi-head h2{ font-size: var(--text-h3); }
/* Изправената лента — пропорцията ѝ идва от документа по същия начин. */
.roi-anim{ aspect-ratio: var(--roi-ratio-m, var(--roi-ratio)); }
}

}

/* ═══ sections/satisfaction ═══ */
/* Scoped to this section's own root: a rule here cannot reach an element
 * outside .sat-sec. The bundle is one stylesheet on every page, so without
 * this a name like .res-card would silently restyle another section. */
@scope (.sat-sec) {
/* ---- Ходът на третирането: мозайка + sticky каре ---- */
/* Без долен отстъп, за разлика от останалите секции: след нея идва
   сцената с натоварването (workload), чието заглавие стои навътре в пина. */
:scope{padding:var(--section-pad) var(--page-pad,48px) 0}
/* 2fr / 1fr — картите носят секцията, карето стои отстрани. Същото
   разпределение като platform на HERA, откъдето е и подредбата. */
.sat{display:grid;grid-template-columns:2fr 1fr;gap:var(--space-5);align-items:start}
.sat-main{display:flex;flex-direction:column;gap:var(--space-4)}
.sat-main h2{font-size:var(--text-h3);margin:0}
.sat-sub{color:var(--ink);margin:0;max-width:52ch}

/* Мозайката. Втората колона тръгва по-ниско, за да не се редят картите две по
   две на един ред — същото отместване като при накрайниците на HERA. */
.res-masonry{display:flex;gap:var(--space-5);margin-top:var(--space-4)}
.res-col{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-5)}
.res-col--offset{margin-top:calc(var(--space-9)*2)}
/* Картата — по мярката на .rf-card, за да не са два различни бордюра и два
   различни радиуса на една страница. Без ховър: тази никъде не е връзка. */
.res-card{background:var(--white);border:1px solid var(--ink);border-radius:var(--radius-lg);padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-2)}
/* Медицинското показание е акцентно и без рамка: то не е стъпка от
   третирането, а отделно твърдение, и цветът го казва преди текста. */
.res-card--accent{background:var(--accent-200);border-color:transparent}
.res-card__art{position:relative;border-radius:var(--radius-md);overflow:hidden;background:var(--grey-200)}
/* Пропорцията РЕЗЕРВИРА мястото преди файла да дойде — картата е с крайната си
   височина от първата рисунка, а кадър, който не се зареди, оставя сиво поле,
   вместо да срине картата. */
.res-card__art img{width:100%;aspect-ratio:16/9;object-fit:cover;display:block}
.res-card__n{position:absolute;top:var(--space-3);right:var(--space-4);font-family:var(--font-display);font-weight:var(--weight-heading);font-size:var(--text-h6);line-height:1;color:var(--ink)}
.res-card__art .tag--dark{position:absolute;top:var(--space-3);right:var(--space-3)}
.res-card h3{font-size:var(--text-h5);margin:0}
.res-card p{margin:0;font-size:0.9rem;line-height:var(--leading-body)}

@media (max-width:1024px){
.sat{grid-template-columns:1fr}
.res-col--offset{margin-top:0}
}
/* На телефон мозайката се изправя в една колона. Отместването отпада заедно с
   нея — то съществува само за да разминава две съседни колони.

   Колоните се РАЗТВАРЯТ с `display: contents`, за да станат картите едно ниво
   и да могат да се подредят. Иначе се наслагват цели: първо лявата с 1, 3 и
   петата, после дясната с 2 и 4 — тоест редът излиза 1, 3, 5, 2, 4.

   Редът идва от номера на картата (`--ord`), който партиалът и без това вече
   получава за надписа горе вдясно. Картата с медицинското показание няма
   номер и по подразбиране е 99, тоест последна. */
@media (max-width:768px){
.res-masonry{flex-direction:column;gap:var(--space-5)}
.res-col{display:contents}
.res-card{order:var(--ord,99)}
}
}

/* ═══ sections/series ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .series-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.series-sec) {
/* ---- Novasonix RF серия ---- */
:scope{padding:var(--section-pad) var(--page-pad,48px);display:flex;flex-direction:column;gap:var(--space-6)}
.series-copy{max-width:52ch}
/* space-4 to the subtitle - see the note in zones.css. */
.series-copy h2{font-size:var(--text-h2);margin:0 0 var(--space-4)}
.series-copy p{margin:0;color:var(--ink)}
.series-cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-5)}
.series-cards product-card-small{max-width:none;min-height:220px}
.series-cta{display:flex;justify-content:center}
@media(max-width:1024px){
.series-cards{grid-template-columns:1fr}
}
}

/* ═══ sections/solutions ═══ */
/* Апаратите по решение (sections/solutions.liquid). Root е `.sol-sec`.
 *
 * Всяка група е писта от два екрана със залепен слой от един: вторият екран е
 * ходът, по който заглавието се качва и хапчетата се подреждат, а картите през
 * това време стоят долу.
 *
 * Филмът е на ЦЯЛА ШИРИНА. Затова групата няма страничен падинг — носят го
 * текстът и картите поотделно, — а филмът е опънат по цялата ѝ кутия.
 */
@scope (.sol-sec) {

/* Непрозрачен фон и слой над закования филм на hero-то — дългът на всяка
   секция под него. Виж бележката в home-hero.css. */
:scope{ position: relative; z-index: 1; background: var(--white); }

/* Пистата е два екрана, пинът е един: разликата е ХОДЪТ, по който заглавието
   се качва. Един екран, както е поискано.

   ТРИ СЛОЯ, а не два. Филмът е sticky сам за себе си, сцената се качва върху
   него с отрицателен отстъп, а в нея стои пинът. Изглежда като заобиколен
   път, докато не стигнеш телефона: там заглавието трябва да си тръгва с
   обикновен скрол, а филмът да остане — и това е възможно само ако двете не
   са в един и същ залепен елемент. Същото устройство и по същата причина
   като `workload` на Leaseir.

   Височината се събира: филм 100svh + сцена (100svh + ход) − 100svh отстъп =
   100svh + ход. Толкова, колкото беше и преди разделянето. */
.sol-group{ --sol-travel: 100svh; }
.sol-runway{ position: relative; }

.sol-film{
  position: sticky; top: 0; height: 100svh;
  overflow: hidden;
  z-index: 0;
  /* Докато филмът го няма — сиво, с точния размер на сцената. */
  background: var(--grey-200);
}
.sol-video{
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  pointer-events: none;
}

.sol-stage{
  position: relative; z-index: 1;
  height: calc(100svh + var(--sol-travel));
  margin-top: -100svh;
}
.sol-pin{
  position: sticky; top: 0; height: 100svh;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: var(--crumb-h) 0 var(--space-7);
}

/* ---- заглавието и хапчетата ---- */
/* Движението е ЕДНОКРАТНО и на тригер, не карано от скрола. `.is-live` идва
   от скрипта в мига, в който пистата се закачи — тоест когато картите стъпят
   долу, — и оттам преходът върши всичко останало сам. Дотогава заглавието и
   хапчетата под него стоят заедно на средата на секцията.

   Дотук същото се возеше на скрола през `--sol-p`: то вървеше и назад, и
   спираше по средата, ако спреш по средата. Тригерът дава едно движение, което
   или се е случило, или не. */
.sol-copy{
  position: relative; z-index: 1;
  padding-inline: var(--page-pad, 48px);
  display: flex; flex-direction: column; gap: var(--space-5);
  align-items: flex-start;
}
.sol-copy h2{ font-size: var(--text-h2); margin: 0; max-width: 18ch; }
.sol-pills{ display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); }

/* Само над телефонната граница: там пинът пада и заглавието минава с
   обикновения скрол, тъй че няма какво да се качва. Правилата са в медия
   заявка, а не с по-силен селектор долу, защото `.sol-group.is-live .sol-copy h2`
   е по-специфично от голо `.sol-copy h2` и мобилното би загубило.

   Движението е върху ДЕЦАТА, не върху блока. Блокът би ги вдигнал наведнъж, а
   всяко хапче трябва да тръгне със свое закъснение — а закъснение се дава на
   елемента, който се движи.

   Оттам и защо ходът е в ПИКСЕЛИ, от скрипта: центрирането на блока се пишеше
   с `translateY(-50%)`, а върху дете процентът значи половината от НЕГОВАТА
   височина, не от блока. Скриптът мери блока веднъж и пише `--sol-rise`. */
@media (min-width: 769px){
.sol-copy h2,
.sol-pill{ transform: translateY(var(--sol-rise, 0px)); }
/* Преходът виси на `is-ready`, който скриптът вдига СЛЕД като е записал хода.
   Дотогава няма преход и покойната позиция се заема наведнъж — записването на
   хода е промяна на `transform` като всяка друга и иначе се изминаваше. */
:scope .sol-group.is-ready .sol-copy h2,
:scope .sol-group.is-ready .sol-pill{
  transition: transform var(--sol-anim, .9s) var(--ease-standard);
}
:scope .sol-group.is-live .sol-copy h2,
:scope .sol-group.is-live .sol-pill{ transform: none; }
/* Четирите тръгват ЕДНОВРЕМЕННО и всяко следващо пътува по-дълго — с .11s от
   предишното. Оттам и разликата спрямо закъснение: при закъснение хапчето
   стои неподвижно и чака реда си, тъй че движението се чете на стъпки. Тук
   всички са тръгнали от първия кадър и редицата се разтяга сама.

   Стъпката се прибавя към `--sol-anim`, а не се пише наготово, за да остане
   разликата вярна, ако основната продължителност се смени. */
:scope .sol-group.is-ready .sol-pill:nth-child(1){ transition-duration: calc(var(--sol-anim, .9s) + .11s); }
:scope .sol-group.is-ready .sol-pill:nth-child(2){ transition-duration: calc(var(--sol-anim, .9s) + .22s); }
:scope .sol-group.is-ready .sol-pill:nth-child(3){ transition-duration: calc(var(--sol-anim, .9s) + .33s); }
}

/* ---- картите ---- */
/* `align-items: end`, защото активната карта расте НАГОРЕ: дъното на реда е
   това, което стои на едно място. */
.sol-cards{
  position: relative; z-index: 1;
  padding-inline: var(--page-pad, 48px);
  display: grid;
  grid-template-columns: repeat(var(--sol-cols, 3), minmax(0, 1fr));
  gap: var(--space-4);
  align-items: end;
}
/* При една и при две карти те заемат по половина — не цялата ширина.
   `--sol-n` е броят им и служи на стека по-долу. */
.sol-group[data-count="1"] .sol-cards{ --sol-cols: 2; --sol-n: 1; }
.sol-group[data-count="2"] .sol-cards{ --sol-cols: 2; --sol-n: 2; }

/* ДВА РЕДА, не един. Редът с цената е пряко дете на картата, за да може на
   телефон да мине под ДВЕТЕ колони; тук, на широк екран, решетката го връща в
   дясната, под текста. Изрезката пък заема и двата реда, тъй че дъното ѝ си
   остава дъното на картата, както е в макета.

   `row-gap` е по-малък от `column-gap`: между изрезката и текста стои 16px,
   но между параграфа и реда с цената — 8, колкото и между редовете в текста. */
.sol-card{
  position: relative;
  display: grid;
  /* Колоната на изрезката е ЧИСЛО, не `auto`. И седемте изрезки са 790x1303 —
     една пропорция, — тъй че ширината следва от височината и може да се
     напише: 132 * 790/1303 = 80. Написана така, тя не зависи от това какво
     прави картинката вътре, а точно това трябваше: колоната е еднаква в двете
     състояния, както е и в макета (отстъп на текста 114 при активна и 110 при
     карта в покой). */
  grid-template-columns: var(--sol-art-w, 80px) minmax(0, 1fr);
  /* ОТГОРЕ, не отдолу. Текстът започва от горния ръб на картата; изрезката се
     нарежда спрямо него, не обратното. Дотук беше `end` и заглавието стоеше
     26px по-ниско от ръба, защото изрезката беше по-висока от текстовия блок
     (132 срещу 106) и дърпаше реда — въздух над заглавието, който в макета го
     няма. */
  align-items: start;
  column-gap: var(--space-4);
  row-gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-lg);
  background: rgba(255, 255, 255, .45);
  border: 1px solid var(--white);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background var(--duration-slow, .4s) var(--ease-standard);
}
/* Мястото за голямата изрезка. Клетката ѝ е с нулева височина, тъй че картата
   не знае за нея — а на активната карта изрезката е най-голяма и трябва да се
   побере. Само на активната: в покой картата се мери от текста си и остава
   ниска, както е и в макета. */
.sol-card.is-on{
  background: rgba(255, 255, 255, .8);
  /* + 2px за рамката: `min-height` се мери в border-box, тъй че падингът И
     рамката трябва да са в сметката, иначе изрезката подава точно с нея. */
  min-height: calc(var(--sol-art, 132px) + 2 * var(--space-4) + 2px);
}

/* Изрезката се уголемява на активната карта — но КЛЕТКАТА ѝ не се мени.
   Разликата е цялата тук: изрезката винаги ЗАЕМА мястото на голямото си
   състояние, а в покой само се свива с `transform` от центъра си. Тъй че
   `height` е едно число, не две, и решетката не помръдва.

   Дотук височината се менеше направо — 86px в покой, 132px на активната. А
   `width: auto` пази пропорцията, значи с височината се менеше и ширината:
   колоната скачаше от 52 на 80px, а `align-items: end` качваше изрезката
   нагоре, вместо да я уголемява на място. Мерено преди промяната: клетката
   беше 80x132 на активната карта и 52x86 на другите.

   Числата са две и се четат заедно: кутията е голямото състояние, а
   коефициентът е 86/132 — колкото беше малкото спрямо него. Смени ли се
   едното, другото се преcмята. Центрирана е, защото расте от центъра си:
   `flex-end` би я задържал на дъното и растежът щеше пак да е само нагоре. */
/* Кутията само ДЪРЖИ колоната. Изрезката вътре е извадена от потока, тъй че
   височината ѝ не участва в сметката за картата — картата се мери от текста
   си и остава ниска в покой, както е в макета (159 срещу 215 при активната). */
.sol-card__art{ grid-column: 1; grid-row: 1 / -1; }

/* Закована спрямо КАРТАТА, не спрямо клетката, и това не е дреболия.
   Опитах я с нулева по височина клетка и `align-self: center`: центърът тогава
   е центърът на РЕДОВЕТЕ на решетката, а той не съвпада с центъра на картата,
   щом `min-height` е добавил място, което редовете не са поели. Мерено:
   изрезката излизаше 14.75px над горния ръб на картата и стоеше на 48.75 от
   долния. Спрямо картата няма такъв разнобой.

   `left` е падингът на картата: първата колона започва оттам.

   `translate` и `transform` са РАЗДЕЛНИ нарочно — първото центрира, второто
   мащабира, и се прилагат в този ред. Събрани в едно `transform`, свиването
   щеше да влачи и центрирането. */
.sol-card__art img{
  position: absolute;
  left: var(--space-4);
  top: 50%;
  display: block;
  width: var(--sol-art-w, 80px);
  height: var(--sol-art, 132px);
  translate: 0 -50%;
  transform: scale(var(--sol-art-rest, .652));
  transform-origin: 50% 50%;
  transition: transform var(--duration-slow, .4s) var(--ease-standard);
}
.sol-card.is-on .sol-card__art img{ transform: none; }

.sol-card__body{ grid-column: 2; grid-row: 1; display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); min-width: 0; }
.sol-card__body h3{ font-size: var(--text-h4); margin: 0; }
.sol-card__desc{ margin: 0; line-height: var(--leading-body); }

/* Цената и бутонът съществуват винаги и се РАЗКРИВАТ на активната карта.
   `grid-template-rows` от 0fr до 1fr е това, което прави прехода плавен: с
   `display: none` няма какво да се анимира, а с фиксирана височина числото би
   трябвало да се познае.

   ЕДИН вътрешен елемент, а не двата направо. Решетка с шаблон от един ред и
   две деца слага второто в НЕЯВЕН ред, а той е `auto` — тъй че цената се
   свиваше, а бутонът си оставаше 58px висок и неактивната карта носеше 66px
   невидима височина. Мерено: тя излизаше по-ВИСОКА от активната. */
.sol-card__more{
  grid-column: 2; grid-row: 2;
  display: grid; grid-template-rows: 0fr;
  width: 100%;
  transition: grid-template-rows var(--duration-slow, .4s) var(--ease-standard);
}
/* Цената и бутонът са на ЕДИН ред, както е в макета: цената вляво, бутонът
   вдясно. `wrap` е за тясната карта — на две по 50% ширина има място, на три
   по трета при малък монитор може и да няма. */
.sol-card__more-in{
  overflow: hidden; min-height: 0;
  display: flex; flex-direction: row; flex-wrap: wrap;
  align-items: center; justify-content: space-between; gap: var(--space-4);
  opacity: 0;
  transition: opacity var(--duration-base) var(--ease-standard);
}
.sol-card.is-on .sol-card__more{ grid-template-rows: 1fr; }
.sol-card.is-on .sol-card__more-in{ opacity: 1; }
/* БЕЗ собствен горен отстъп: `.sol-card__body` вече дели децата си с `gap`, а
   собствен margin отгоре се СЪБИРА с него — мерено на телефон, от дъното на
   параграфа до цената излизаха 16px вместо 8. На широк екран пък той изместваше
   цената надолу спрямо бутона, с който е центрирана на един ред. */
.sol-card__price{ margin: 0; font-family: var(--font-display);
  font-weight: var(--weight-heading); font-size: var(--text-h5); }
.sol-card__more .lmed-btn{ flex: 0 0 auto; }

@media (max-width: 1024px){
.sol-copy h2{ max-width: none; }
/* Картата НЕ минава на една колона. Изрезката над текста значи, че при
   наслагването на телефон от покритата карта се вижда тя, а не името — а
   лентата, която остава да стърчи, е точно за името. Две колони докрай. */
/* Същите числа, свити: кутията е 104px, колоната 104*790/1303 = 63, а
   коефициентът 72/104. Записани на КАРТАТА, защото колоната ги чете оттам. */
.sol-card{ --sol-art: 104px; --sol-art-w: 63px; --sol-art-rest: .692; }
}

/* На телефон трите карти не се редят една до друга. НАСЛАГВАТ се — всяка
   покрива предишната и от нея остава лентата с името, — както картите на
   накрайниците на Leaseir. Всички са в активното си състояние: там няма
   показалец, който да избира една.

   Филмът пък се кара от СКРОЛА през цялата писта, тъй че частта му отговаря
   на картата, която се вижда. Логиката е в скрипта; тук е само подредбата. */
@media (max-width: 768px){
/* Редът с цената минава под ДВЕТЕ колони — под изрезката и под текста, — както
   е в референцията. Затова и изрезката се връща само на първия ред: иначе тя
   би се разпънала през новия и дъното ѝ би слязло под текста. */
.sol-card__more{ grid-column: 1 / -1; }
.sol-card__art{ grid-row: 1; }
/* На телефон изрезката се ВРЪЩА В ПОТОКА. Там редът с цената минава под двете
   колони, тъй че изрезката трябва да е центрирана спрямо ПЪРВИЯ РЕД, а не
   спрямо цялата карта — закована спрямо картата, тя би слязла под текста.

   И не се мени изобщо: всички карти са в активното си състояние, значи няма
   покойно, спрямо което да расте. Едно число, и коефициентът е изрично 1, за
   да не го поеме от блока за таблет. */
.sol-card{ --sol-art: 72px; --sol-art-w: 44px; --sol-art-rest: 1; }
.sol-card__art{ display: flex; align-items: center; justify-content: center; }
.sol-card__art img{ position: static; translate: none; transform: none; }
.sol-card.is-on{ min-height: 0; }

/* ПИНЪТ ПАДА. Заглавието и хапчетата си тръгват с обикновения скрол, вместо да
   стоят залепени над картите; залепени остават само картите и филмът, който си
   е отделен слой от самото начало. Същото и по същата причина като `workload`
   на Leaseir.

   `display: contents`, а не `position: static`: кутията на пина изчезва и
   заглавието и картите стават преки деца на СЦЕНАТА. Това е важното — sticky
   се ограничава от контейниращия си блок, а пин с авто височина няма в какво
   да лепи и картите биха си тръгнали нагоре заедно със заглавието. Сцената е
   висока два екрана и държи.

   Оттам и `is-live` не пипа нищо тук: заглавието не се качва, а минава, и
   хапчетата стоят подредени от самото начало. Класът се вдига и на телефон,
   но правилата, които го четат, са в `@media (min-width: 769px)`. */
.sol-pin{ display: contents; }

/* Картите да не си тръгват ЗАЛЕПЕНИ за дъното на филма.

   Филмът е sticky в пистата, картите — в сцената, а двете свършват на един и
   същ ред. Затова, щом пуснат, дъната им съвпадат буквално: мерено, разликата
   пада от 30px на 0 в мига на пускането и остава нула, докато секцията си
   отива. Падингът вдига дъното на съдържанието над дъното на сцената, тъй че
   картите пускат с толкова по-рано.

   Не удължава скрола: `box-sizing` е border-box, значи падингът влиза ВЪТРЕ в
   обявената височина на сцената — пистата остава същата и `progress()` не се
   мени. */
.sol-stage{ padding-bottom: var(--space-4); }

/* ПО-ДЪЛГА ПИСТА, и то според броя карти. На широк екран един екран стига:
   заглавието е залепено и не отнема ход. Тук то минава с обикновения скрол и
   изяжда началото — мерено, 462px на групата с три карти, — а при предишните
   100svh ходът беше 640px общо. Тоест докато блокът си отиде, филмът вече
   беше на 0.72, а частта на първия апарат свършва на 0.33: той минаваше
   закрит и не можеше да се види.

   Разделено на две: постоянна част за заглавието и по толкова на всеки
   апарат. Числото за настройка е 60svh — колко скрол получава един апарат.

   Броят е от `data-count`, а не от `--sol-n`: последният е написан на
   `.sol-cards`, а ходът виси на групата. */
.sol-group{ --sol-cards: 3; --sol-travel: calc(70svh + 60svh * var(--sol-cards)); }
.sol-group[data-count="1"]{ --sol-cards: 1; }
.sol-group[data-count="2"]{ --sol-cards: 2; }

.sol-copy{
  padding-inline: var(--space-4);
  padding-top: 34svh;
}
.sol-copy h2{ font-size: var(--text-h3); }
/* Стекът, същият като на накрайниците Single/Dual/Quad в `workload`: всяка
   следваща карта се качва върху предишната и ѝ оставя --sol-step видима —
   точно колкото реда с името. Всички са в една клетка, всяка избутана надолу с
   --i крачки; отрицателен margin не върши работа, защото процентът в margin се
   смята спрямо ШИРИНАТА на родителя, не спрямо височината на картата.

   Картите ИЗНИКВАТ ЕДНА ПО ЕДНА — `data-in` идва от скрипта на прага на своята
   част от филма, — а не всички наведнъж.

   `align-items: start`, а не `end`. На широк екран картите стъпват на обща
   ДОЛНА линия и активната расте нагоре; в стека това разваля стълбицата —
   по-високата карта тръгва по-нагоре и лентата ѝ става различна от другите.
   Мерено: 100px вместо 64. Тук общото е ГОРНОТО начало и стъпката е точна.

   Падингът долу прави място на изместените: последната е на (n−1) крачки. */
/* Картите лепнат сами, щом пинът го няма, и котвата им се СМЯТА, а не се
   избира: дотук стоеше `top: 40svh` — процент, който не знае колко е висок
   стекът, беше вярен най-много за едната група и вдигаше и двете твърде
   високо.

   Два пътя, които опитах и не вършат работа, за да не се пробват пак:

     `bottom` вместо `top` — sticky с `bottom` лепне, докато елементът е още
     НИСКО, и го пуска, щом естественото му място се вдигне над прага. Точно
     обратното на исканото; мерено, на 420px скрол стекът вече беше на 41px от
     върха.

     Кутия, висока екран, с долепено за дъното съдържание — закотвя точно, но
     ИЗЯЖДА ОБХВАТА на лепенето: sticky е ограничен от контейниращия блок, тъй
     че 638px кутия в 1276px сцена лепне най-много 171px. Картите си тръгваха,
     а секцията продължаваше още 638px.

   Падингът долу прави място на изместените: последната карта е на (n−1) крачки
   под първата.

   Стъпката е 56px, не 64: при три карти и 64 стекът свършваше на 634px при
   екран 638 — тоест третата карта опираше в ръба и на по-нисък телефон би
   излязла извън него. 56 стигат за реда с името и свиват стека с 16px. */
.sol-cards{
  --sol-step: 56px;
  /* Височината на ПОСЛЕДНАТА карта — тя е най-ниско в стека, тъй че нейното
     дъно е дъното на стека. Не най-високата: Hera е 185px, защото носи бутон,
     но е втора и я застига изместването на третата.

     Мерено на 360x640 с довършени преходи: 167px в групите с две и три карти,
     158px в тези с една. 166 работи за всички — дъното пада на 23px от ръба
     при първите и на 32px при вторите. */
  --sol-card-h: 166px;
  position: sticky;
  /* Дъното на стека застава на `--space-6` от ръба на екрана — еднакво при две
     и при три карти. `max` е предпазната мрежа: порасне ли картата от по-дълъг
     текст или се смали екранът, котвата не слиза под 24svh и стекът остава в
     кадър, макар и по-нагоре от исканото. */
  top: max(24svh, calc(100svh - var(--space-6) - var(--sol-card-h)
                       - var(--sol-step) * (var(--sol-n, 3) - 1)));
  padding-inline: var(--space-4);
  padding-bottom: calc(var(--sol-step) * (var(--sol-n, 3) - 1));
  display: grid; grid-template-columns: 1fr;
  align-items: start;
}
.sol-card{
  grid-area: 1 / 1;
  opacity: 0;
  transform: translateY(calc(var(--i) * var(--sol-step) + var(--space-7)));
  transition: opacity .5s var(--ease-standard), transform .5s var(--ease-standard),
              background var(--duration-slow, .4s) var(--ease-standard);
}
.sol-card[data-in]{ opacity: 1; transform: translateY(calc(var(--i) * var(--sol-step))); }

/* ПОКРИТАТА КАРТА ИЗБЛЕДНЯВА. Щом следващата е изникнала, от тази се вижда
   само лентата с името — и тя се връща на прозрачността в покой (.45), докато
   най-горната остава на .8.

   Условието е „има ли СЛЕД мен карта, която е изникнала" — оттам `:has(~ …)`.
   Не е `:not(:last-of-type)`: редът в разметката не казва коя е дошла, това го
   казва `data-in`, а той се вдига една по една със скрола.

   Специфичността е 0,3,0 срещу 0,2,0 на `.sol-card.is-on` горе, тъй че бие
   и без `!important`. На телефон всички карти носят `is-on` — там няма
   показалец, който да избира една, — затова правилото не може да се напише
   през него.

   Преходът е вече обявен горе, в `transition` на картата. */
.sol-card:has(~ .sol-card[data-in]){ background: rgba(255, 255, 255, .45); }

.sol-card__body h3{ font-size: var(--text-h5); }
}

/* Без движение стекът няма смисъл — карти, наслагани без да изникват, са просто
   скрити една зад друга. Тук те са обикновена колона. */
@media (prefers-reduced-motion: reduce){
.sol-copy h2{ transform: none !important; transition: none; }
.sol-pill{ transform: none !important; transition: none; }
.sol-card, .sol-card__art img, .sol-card__more{ transition: none; }
.sol-card{ opacity: 1; transform: none; }
@media (max-width: 768px){
.sol-cards{ display: flex; flex-direction: column; gap: var(--space-4); padding-bottom: 0; }
}
}

}

/* ═══ sections/specs ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .specs-sec. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.specs-sec) {
/* .spec-card and the .dl-* rows moved to styles/spec-card.css — three sections
   use them now and a scoped rule reaches only its own root. The --table and
   --brand variants below stay here: they are this section's. */
/* ---- Спецификации: fixed фон, скролващи карти + check-pills ---- */
/* Без долен отстъп, за разлика от останалите секции: след спецификациите
   на всяка страница идва CTA сцената, която носи свой въздух отгоре. */
:scope{padding:var(--section-pad) var(--page-pad,48px) 0}
.specs-stage{position:relative;display:flex;border-radius:var(--radius-lg);overflow:hidden;clip-path:inset(0 round var(--radius-lg));padding:var(--space-6);min-height:min(88vh,800px);background:var(--grey-200)}
.specs-bg{position:fixed;inset:0;background-position:center;background-size:cover;background-repeat:no-repeat;z-index:0;pointer-events:none}
.specs-grid{position:relative;z-index:1;flex:1;min-height:0;display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);gap:var(--space-6)}
/* overscroll-behavior was `contain`, which traps the wheel: this column is
   an inner scroller, but whenever its content fits — which it does at most
   desktop heights, scrollHeight and clientHeight both 939 — it cannot move
   and `contain` still refuses to pass the scroll to the page. Hovering the
   cards froze the page. `auto` keeps the inner scrolling and lets the page
   take over at the limit. */
.specs-cards{min-height:0;overflow-y:auto;overscroll-behavior:auto;display:flex;flex-direction:column;gap:var(--space-5);padding-right:var(--space-2);scrollbar-width:none}
.specs-cards::-webkit-scrollbar{display:none}
/* Картите замъгляват кадъра зад себе си. Самата карта си остава прозрачна —
   рамка без фон, — тъй че снимката се вижда през нея, само че размита и
   текстът върху нея се чете.

   ТУК, а не в styles/spec-card.css: същата карта се ползва и от лентата със
   сертификати на страницата с производителите, където зад нея няма кадър, а
   бяло — там замъгляването няма какво да размие и само би направило от картата
   собствен слой за нищо. Scope-ът е точно границата, по която двете се делят.

   ЦЕНАТА, платена съзнателно: елемент с `backdrop-filter` става backdrop root
   и всичко вътре в него няма какво да размива. Бутонът за разгъване долу вдясно
   си остава с фона и с рамката си, но неговият собствен `blur(4px)` е без
   действие. Пробвах да я избегна, като сложа замъгляването на псевдоелемент зад
   съдържанието — картата се счупи (личеше ръб на ъгъла, а на телефон фонът
   изобщо спираше да се размива), затова е върнато така.

   `-webkit-` върви с него: Safari още го иска с префикс. */
.spec-card{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}
.spec-table{display:flex;flex-direction:column}
.spec-card--table:not(.open) .spec-table{-webkit-mask-image:linear-gradient(to bottom,#000 60%,rgba(0,0,0,.25) 100%);mask-image:linear-gradient(to bottom,#000 60%,rgba(0,0,0,.25) 100%)}
.spec-card--table .sp-row:nth-child(n+6){max-height:0;padding-block:0;opacity:0;overflow:hidden;transition:max-height var(--duration-slow,.4s) var(--ease-standard),padding var(--duration-slow,.4s) var(--ease-standard),opacity var(--duration-base) var(--ease-standard)}
.spec-card--table.open .sp-row:nth-child(n+6){max-height:4rem;padding-block:var(--space-1);opacity:1}
.spec-card--table.open .spec-table{padding-bottom:var(--space-8)}
.spec-card--brand{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4)}
.spec-card--brand .sb-right{display:flex;align-items:center;gap:var(--space-4);padding-right:var(--space-1)}
/* Връзката е само дясната половина; без подчертаване, картата вече е рамка. */
a.sb-right{text-decoration:none;color:inherit}
.spec-card--brand .sb-logo{display:block;height:26px;width:auto}
.spec-card--brand icon-tag{margin-left:0}
.sp-row{display:flex;align-items:baseline;padding-block:var(--space-1)}
.sp-row .sp-k{margin:0;color:var(--text-secondary)}
.sp-row .sp-lead{flex:1;min-width:var(--space-4);margin:0 6px 5px;border-bottom:1px dotted var(--border-strong)}
.sp-row h6{margin:0;white-space:nowrap}
.spec-toggle{position:absolute;right:var(--space-5);bottom:var(--space-5)}
.specs-checks{display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;gap:var(--space-4)}

/* Отзивчивите правила за тази секция. Стояха в cta.css, извън всякакъв scope —
   остатък от разделянето на слетите стилове. Там не важаха: некоширано
   `.x` губи от коширано `.x` в собствения му файл, защото близостта по scope
   тежи над реда, а медия заявката не добавя тежест. */
@media (max-width:1024px){
.specs-grid{grid-template-columns:1fr}
.specs-stage{min-height:0;padding:var(--space-5)}
/* Тясно: фонът се мери по височина и се измества, за да остане уредът в
   кадър — правилото на дизайна, само че върху слоя, който носи снимката.
   Стоеше на .specs-stage, където от преместването на снимката насам няма
   изображение, тоест не правеше нищо. `auto` пази пропорцията; слоят е
   100vh висок, така че 100% и 100vh са едно и също тук. */
.specs-bg{background-size:auto 100%;background-position-x:83%}
.specs-cards{overflow:visible;max-height:none}
.specs-checks{align-items:flex-start;justify-content:flex-start}
}
@media (max-width:768px){
.specs-cards{padding-right:0}
.spec-card--table{margin-top:50vh}
.spec-card--brand{flex-wrap:wrap}
.spec-card--brand .sb-right{width:100%;justify-content:space-between;padding-right:0}
.sp-row{flex-direction:column;align-items:flex-start}
.sp-row .sp-lead{display:none}
.sp-row h6{white-space:normal}
}
}

/* ═══ sections/technologies ═══ */
/* Технологиите на платформата — пет карти в две колони.
 *
 * Картата е ТУК, а не в styles/rf-card.css: този дизайн я раздели от картата на
 * накрайниците и тя вече се ползва само от тази секция. rf-card.css остава
 * некскоупнат, защото platform продължава да го дели с… нищо друго, но това е
 * отделен разговор и отделен комит.
 *
 * Root е `.rf-tech`, не `.tech-sec`: sections/results.liquid вече държи това
 * име за друго нещо (резултати с видео отстрани). */
@scope (.rf-tech) {

/* Тук остава само МРЕЖАТА. Самата карта се премести в styles/components.css:
   ползва я и секцията с типовете кожа на Leaseir MHR, а @scope стига само
   надолу от един корен. Същият ход и същата причина като при .dcard. */

:scope{ padding: var(--section-pad) var(--page-pad, 48px); }
:scope > h2{ font-size: var(--text-h3); margin: 0 0 var(--space-6); max-width: 30ch; }

/* `1fr` редове изравняват втория с първия, а `stretch` по подразбиране пълни
   всеки ред — така петте карти са еднакво високи, въпреки че рисунките им са с
   различна дълбочина, а обясненията им са от два до четири реда. */
.rf-tech__grid{
  display: grid; grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: 1fr; gap: var(--space-5);
}


/* ---- Под 768px ---- */
/* Една колона, и картата се изправя: рисунката отива ГОРЕ, в потока, а
   обяснението стои отворено. Ховър няма какво да отвори, а и не се случва. */
@media (max-width: 768px){
:scope{ padding: var(--section-pad) var(--space-4); }
.rf-tech__grid{ grid-template-columns: 1fr; grid-auto-rows: auto; }
}

}

/* ═══ sections/video ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .video-band. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.video-band) {
/* ---- Видео: лента в page-pad ---- */
:scope{position:relative;margin:var(--section-pad) var(--page-pad,48px);height:max(70vh,480px);background:var(--grey-200);border-radius:var(--radius-lg);overflow:hidden}
:scope video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;background:var(--grey-200)}
:scope .video-titles{transition:opacity var(--duration-base) var(--ease-standard)}
:scope.is-playing .video-titles{opacity:0;pointer-events:none}
.video-titles{position:absolute;left:0;right:0;bottom:0;z-index:2;display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-5);padding:var(--space-9) var(--space-6) var(--space-6)}
.video-titles h2{margin:0;font-size:var(--text-h3);max-width:24ch}
@media(max-width:767px){
.video-titles{left:0;right:0;top:0;height:fit-content;gap:var(--space-3);padding:var(--space-4);border-radius:var(--radius-lg)}
}

/* Отзивчивите правила за тази секция. Стояха в cta.css, извън всякакъв scope —
   остатък от разделянето на слетите стилове. Там не важаха: некоширано
   `.x` губи от коширано `.x` в собствения му файл, защото близостта по scope
   тежи над реда, а медия заявката не добавя тежест. */
@media (max-width:768px){
:scope{height:80vh}
}
}

/* ═══ sections/why ═══ */
/* Защо LMed (sections/why.liquid). Root е `.why-sec`.
 *
 * Секцията е БЯЛ ПАНЕЛ, който се качва върху закования филм на hero-то. Оттам
 * трите неща, които я отличават от обикновена секция: непрозрачен фон,
 * закръглени горни ъгли и `z-index` над филма.
 *
 * Самите карти са ui/usp-card и стиловете им са в components.css — три секции
 * ги ползват. Тук е само редът, в който стоят.
 */
@scope (.why-sec) {

/* `relative` + `z-index`, за да мине над `.hh-film`, който е закован с
   `z-index: 0`. Без тях панелът се рисува ПОД филма и се вижда размит кадър
   върху картите.

   Панелът излиза нагоре изпод hero-то с отрицателен отстъп: стъпва върху
   последния екран на филма, а не под него.

   ЗАКРЪГЛЕНИЕТО е само на телефон — виж медия заявката долу. На широк екран
   горният ръб е прав. */
:scope{
  position: relative;
  z-index: 1;
  background: var(--white);
  /* И ОТДОЛУ, за разлика от конвенцията. Панелът е непрозрачен и стъпва върху
     закования филм на hero-то: без долен отстъп следващата секция започва
     веднага след картите и белият панел свършва без въздух. */
  padding: var(--section-pad) var(--page-pad, 48px) var(--section-pad);
}

.why{ display: flex; flex-direction: column; gap: var(--space-5); }
.why h2{ font-size: var(--text-h2); margin: 0; max-width: 20ch; }

/* `1fr` редове, за да са трите карти еднакво високи: текстовете им са с много
   различна дължина, а дъната им трябва да четат от една линия. Същото правило
   и по същата причина като във finance.css. */
.why-grid{ display: grid; grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr; gap: var(--space-4); }

.why-pills{ display: flex; flex-wrap: wrap; gap: var(--space-4); }

@media (max-width: 1024px){
.why-grid{ grid-template-columns: 1fr; grid-auto-rows: auto; }
}
@media (max-width: 768px){
:scope{
  padding: var(--section-pad) var(--space-4) var(--section-pad);
  /* Само тук. На телефон панелът се качва върху филма и заоблението показва,
     че под него има още кадър; на широк екран ръбът е прав. */
  border-radius: 32px 32px 0 0;
}
.why h2{ font-size: var(--text-h3); max-width: none; }
}

}

/* ═══ sections/workload ═══ */
/* Изборът на накрайник според натовареността.
 *
 * Горе сцена — sticky слой над висока писта, — под нея времената и остатъкът
 * от старата секция. Root е `.load-sec`. */
@scope (.load-sec) {

:scope{
  padding: 0 var(--page-pad, 48px) var(--section-pad);
  /* Пистата. Първата ѝ трета е качването на заглавието и събирането на
     рендерите, останалото — трите карти. 380vh значи малко под три екрана
     скрол, откакто сцената се закачи. */
  --load-runway: 380vh;
  /* Пише ги scripts/page/workload.js. `--load-p` е събирането на рендерите и
     качването на заглавието, `--load-c` — пистата на картите. По подразбиране
     и двете са 1, тъй че без скрипт секцията стои в крайното си положение. */
  --load-p: 1;
}

/* Сцената е контейнерът, в който рендерите стоят закачени. Свършва СЛЕД
   времената — затова те минават върху тях.

   `clip visible`: по хоризонтала реже, защото рендерите тръгват отвъд десния
   ръб и без това страницата тръгва настрани; по вертикала не, защото слоят с
   тях е по-висок от екрана и трябва да се вижда и над горния му ръб.
   `hidden` не върши работа за нито едно от двете — прави от блока скролируем
   контейнер и убива sticky-то вътре. */
.load-scene{ position: relative; overflow: clip visible;
  /* Излиза от падинга на страницата и си го връща като СВОЙ падинг. Разликата
     е в кое се реже: overflow клипва по padding box, тоест по ръба на екрана,
     а не 48px преди него. Дотук сцената беше вътре в падинга и рязваше
     рендерите с права вертикална черта преди ръба. */
  margin-inline: calc(var(--page-pad, 48px) * -1);
  padding-inline: var(--page-pad, 48px); }

/* ---- Рендерите ---- */
/* Истинска височина от един екран — иначе sticky-то се откача чак когато
   дъното на сцената стигне ГОРНИЯ ръб на екрана, тоест рендерите остават цял
   екран след като времената са минали. С реална височина се откачат, когато
   дъното ѝ стигне ДОЛНИЯ ръб, тоест си тръгват заедно със секцията.

   Екранът, който слоят яде от потока, се връща с отрицателен margin на
   сцената под него, а НЕ с margin-bottom тук: sticky смята долния си предел
   по margin box-а, тъй че отрицателен долен margin точно с височината му
   отменя предела и слоят пак остава залепен докрай. Точно това беше сбъркано.

   Ширината е на екрана, не на колоната: началното им положение е нарочно
   извън кадър и падингът на страницата няма работа да ги реже. */
.load-art{ position: sticky; top: 0; height: 100svh; z-index: 0; pointer-events: none; }
.load-art__in{
  position: absolute; top: 0; bottom: 0;
  left: 50%; width: 100vw; transform: translateX(-50%);
}
.load-art__n{
  position: absolute; top: 50%; left: 50%;
  width: 28vw; height: auto; display: block;
  /* Разстояние от активната карта × 3px. Пише го скриптът; по подразбиране
     нула, за да са резки, докато карта не е избрана. */
  filter: blur(var(--blur, 0px));
  transition: filter .45s var(--ease-standard);
  /* Началото и краят на пътя, на рендер. Числата са снети от макетите при
     1360×768: центровете в кадър 1 срещу кадър 4, преведени в проценти от
     екрана. Най-левият изминава най-малко, най-десният най-много — затова,
     движейки се наляво, те се събират.

     Смесването е в calc, а не в скрипта, защото е ОПИСАНИЕ на движението и
     мястото му е там, където се вижда до всичко останало. */
  --x: calc(var(--x0) * (1 - var(--load-p)) + var(--x1) * var(--load-p));
  --y: calc(var(--y0) * (1 - var(--load-p)) + var(--y1) * var(--load-p));
  transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y)));
}
/* Левият е най-ОТЗАД и най-ВИСОКО, десният най-отпред и най-ниско — така е в
   макета и това е, което прави редицата да изглежда като идваща към теб. */
.load-art__n:nth-child(1){ --x0:  2vw;  --x1:  -6vw; --y0: 14vh; --y1:  2vh; z-index: 1; }
.load-art__n:nth-child(2){ --x0: 31vw;  --x1:   5vw; --y0: 26vh; --y1:  5vh; z-index: 2; }
.load-art__n:nth-child(3){ --x0: 59vw;  --x1:  18vw; --y0: 34vh; --y1:  8vh; z-index: 3; }

/* ---- Сцената с текста и картите ---- */
.load-stage{ position: relative; z-index: 1; height: var(--load-runway); margin-top: -100svh; }
.load-pin{
  position: sticky; top: 0; height: 100svh;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: calc(84px + var(--space-5)) 0 var(--space-7);
}

/* ---- Заглавието ---- */
/* Тръгва ниско в екрана и се качва до горе, докато рендерите се събират —
   двете вървят на един и същ параметър, защото са едно движение. */
/* Без обща максимална ширина: тя стягаше и заглавието, и то падаше на три
   реда, докато в макета е на два. Всяко от двете си носи своята. */
.load-head{ position: relative; z-index: 1;
  transform: translateY(calc(52vh * (1 - var(--load-p)))); }
/* Мерено: целият надпис е 928px на един ред при този кегел, тъй че за два
   реда иска поне ~580. 24ch дава 614 и го пречупва след „според" — в макета
   пречупването е след „накрайник", но то иска ширина между 430 и 500, а там
   вторият ред не се побира и пада трети. Два реда е целта. */
.load-head h2{ font-size: var(--text-h2); margin: 0 0 var(--space-4); max-width: 24ch; }
.load-head p{ margin: 0; max-width: 46ch; line-height: var(--leading-body); }

/* ---- Картите ---- */
/* Картите и акцентът под тях са едно: `justify-content: space-between` на пина
   ги държи заедно на дъното, вместо акцентът да плува между заглавието и тях. */
.load-foot{ position: relative; z-index: 1; display: flex; flex-direction: column; gap: var(--space-4); }
.load-hl{ margin: 0; line-height: var(--leading-body); }

/* На ДЪНОТО на екрана, както е в макета — заглавието горе, картите долу. */
.load-cards{
  position: relative; z-index: 1;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5);
  align-items: end;
}
/* Стъкло: под картата има рендер и той трябва да се вижда. На ховър фонът
   става плътен — това е цялата разлика между двете състояния. */
.nz-card{
  display: grid; grid-template-columns: 1fr auto; gap: var(--space-1);
  padding: var(--space-5);
  border-radius: var(--radius-lg);
  border: 1px solid var(--accent-200);
  background: color-mix(in srgb, var(--accent-200) 45%, transparent);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  /* Влизането: отдолу нагоре с избледняване. Скриптът вдига `data-in`, когато
     пистата стигне неговия праг. */
  opacity: 0; transform: translateY(var(--space-7));
  transition: opacity .5s var(--ease-standard), transform .5s var(--ease-standard),
              background .25s var(--ease-standard);
}
.nz-card[data-in]{ opacity: 1; transform: none; }
.nz-card:hover{ background: var(--accent-200); }

.nz-card__main{ display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-3); min-width: 0; }
.nz-card__id{ display: flex; flex-direction: column; }
.nz-card__kicker{ margin: 0; font-size: var(--text-small); }
.nz-card__id h4{ margin: 0; font-size: var(--text-h3); line-height: var(--leading-heading); }
.nz-card__price{ margin: auto 0 0; font-family: var(--font-display);
  font-weight: var(--weight-heading); font-size: var(--text-h4); line-height: 1; }

/* Стойността над името ѝ — <dd> е пръв в потока, защото числото е това, което
   се чете. Редът вътре в двойката не е предписан, тъй че <dl> остава валиден. */
.nz-card__spec{ margin: 0; display: flex; flex-direction: column; gap: var(--space-3); text-align: right; }
.nz-card__spec > div{ display: flex; flex-direction: column; }
.nz-card__spec dd{ margin: 0; font-weight: var(--weight-body-semibold); white-space: nowrap; }
.nz-card__spec dt{ margin: 0; font-size: var(--text-small); }

/* ---- Времената ---- */
/* Отрицателният отстъп е това, което вкарва картите ВЪРХУ рендерите: пистата
   свършва, сцената се отлепя, а този блок се качва върху последния ѝ екран. */
/* Минава ВЪРХУ рендерите — те са закачени за цялата сцена, а този блок е
   последното в нея. Затова и картите му са полупрозрачни с backdrop-filter, а
   не плътни: под тях има какво да се види. */
.load-times{ position: relative; z-index: 1; padding-top: var(--space-7); }
.load-times > h3{ font-size: var(--text-h3); margin: 0 0 var(--space-5); max-width: 24ch; }
.load-times__grid{ display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.zone-time{
  position: relative;
  border-radius: var(--radius-lg);
  border: 1px solid var(--ink);
  background: rgba(255, 255, 255, .55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  padding: var(--space-5);
  transition: background .25s var(--ease-standard);
}
/* Не докрай плътен на ховър: под картата стои рендер и той трябва да остане
   загатнат, иначе картата се откъсва от сцената. */
.zone-time:hover{ background: rgba(255, 255, 255, .85); }
.zone-time__label{ margin: 0 0 var(--space-1); font-size: var(--text-small); color: var(--text-secondary); }
.zone-time__head{ margin-bottom: var(--space-5); }
.zone-time__head h4{ margin: 0; font-size: var(--text-h4); }
/* Тагът е в ъгъла на КУТИЯТА, подравнен с падинга ѝ — не до заглавието.
   Затова е изваден от потока: иначе височината на заглавието го мести. */
.zone-time__head .tag{ position: absolute; top: var(--space-5); right: var(--space-5); }
.zone-time table{ width: 100%; border-collapse: collapse; }
/* Без ляв падинг: чертите тръгват от ръба на съдържанието и текстът трябва да
   тръгва от същото място. С падинг първата колона стоеше навътре спрямо тях. */
.zone-time th, .zone-time td{ text-align: left; padding: var(--space-3) var(--space-4) var(--space-3) 0;
  border-bottom: 1px solid var(--border-default); font-weight: var(--weight-body-regular); }
.zone-time th:last-child, .zone-time td:last-child{ padding-right: 0; }
.zone-time thead th{ font-size: var(--text-small); color: var(--text-secondary); }
.zone-time tbody th{ font-weight: var(--weight-body-semibold); }
.zone-time tbody tr:last-child th, .zone-time tbody tr:last-child td{ border-bottom: 0; }
.zone-time .num{ white-space: nowrap; }

@media (max-width: 1024px){
.load-times__grid{ grid-template-columns: 1fr; }
}

@media (max-width: 768px){
:scope{ padding: 0 var(--space-4) var(--section-pad); --load-runway: 300vh; }
/* Рендерите отиват горе и картите тръгват изпод тях: на тесен екран няма как
   три карти да стоят една до друга, затова се НАСЛАГВАТ — всяка покрива
   предишната и от нея остава лентата с името. */
/* На телефон ПИНЪТ пада: заглавието и параграфът си тръгват с обикновения
   скрол, вместо да стоят залепени над картите и да се застъпват с тях.
   Залепено остава само дъното — картите — и слоят с рендерите, който си е
   отделен и sticky от самото начало.

   Затова и качването на заглавието отпада: то няма откъде да се качва, когато
   просто минава нагоре със страницата.

   `display: contents` на пина, а не `position: static`: кутията му изчезва и
   заглавието и дъното стават преки деца на ПИСТАТА. Това е важното — sticky се
   ограничава от контейниращия си блок, а пинът с авто височина няма в какво да
   лепи и картите си тръгваха нагоре заедно със заглавието. Пистата е 300vh и
   държи. */
.load-pin{ display: contents; }
/* Заглавието тръгва ПОД рендерите, не върху тях: те заемат горната половина на
   екрана (62vw широки, тоест ~324px високи, с център около 40svh), а 52svh го
   свалят точно под тях.

   Картите лепнат по-ниско по същата причина — горе е мястото на рендерите.
   34svh ги оставя между тях и долния ръб: блокът е около 390px висок, тъй че
   при екран 640 свършва на ~608 и се побира. */
.load-head{ transform: none; padding-top: 65svh; margin-bottom: var(--space-7); }
.load-foot{ position: sticky; top: 34svh; }
.load-art__n{ width: 62vw; }
/* Пътят на телефон. Две неща бяха сбъркани и двете личат в кадъра:

   Разстоянието в НАЧАЛОТО беше 32vw при рендери, широки 62vw — тоест те вече
   се застъпваха наполовина и нямаше откъде да се събират. Сега тръгват на
   65vw един от друг, колкото са и широки, тъй че Quad почва извън кадъра и
   влиза в него — както е на десктоп.

   В КРАЯ левият беше най-ниско, а десният най-високо. Обратното е: левият е
   най-отзад и най-високо, десният най-отпред и най-ниско — това прави
   редицата да изглежда като идваща към теб и така е на десктоп.

   Крайните стойности са СНЕТИ от макета за 360×640, а не подбрани на око:
   в него светещото прозорче на Quad стои на x 211..233, y 154..202. В самия
   файл то заема 0,045..0,155 от ширината и 0,354..0,506 от височината, тъй че
   от него се смята кутията, а от кутията — отместването. Другите две излизат
   от същата сметка. Разликата спрямо предишните числа е цялата в мястото,
   не във формата: разстоянието между тях си остава 27vw и 3vh, но групата
   стои с ~12vw по-надясно и ~8vh по-нагоре. */
.load-art__n:nth-child(1){ --x0: -20vw; --x1: -14vw; --y0:  0vh; --y1: -24.5vh; }
.load-art__n:nth-child(2){ --x0:  45vw; --x1:  13vw; --y0:  8vh; --y1: -21.5vh; }
.load-art__n:nth-child(3){ --x0: 110vw; --x1:  40vw; --y0: 16vh; --y1: -18.5vh; }
.load-head h2{ font-size: var(--text-h3); }
/* Стекът. Всяка следваща карта се качва върху предишната и ѝ оставя
   --nz-step видима — точно колкото реда с името. Отрицателният margin върши
   това без sticky: картите не се движат една спрямо друга след като са тук. */
.load-cards{ display: grid; grid-template-columns: 1fr; --nz-step: 72px;
  padding-bottom: calc(var(--nz-step) * 2); }
/* Всички в една клетка, всяка избутана надолу с --i крачки. Отрицателен
   margin не върши работа: процентът в margin се смята спрямо ШИРИНАТА на
   родителя, не спрямо височината на картата. */
.nz-card{ grid-area: 1 / 1; transform: translateY(calc(var(--i) * var(--nz-step) + var(--space-7))); }
.nz-card[data-in]{ transform: translateY(calc(var(--i) * var(--nz-step))); }
/* Редът в картата на телефон е ДРУГ — по макета: име, бадж, стойности, цена.
   На широк екран баджът е горе, а цената под името, защото има втора колона,
   която да поеме стойностите; в една колона това нарежда цената между името и
   тях и картата се чете на пресекулки.

   `display: contents` на вътрешния блок: кутията му изчезва и четирите неща
   стават преки деца на картата, тъй че `order` може да ги подреди всичките.
   Иначе стойностите са извън него и няма как да застанат между баджа и
   цената. */
.nz-card{ display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); }
.nz-card__main{ display: contents; }
.nz-card__id{ order: 1; }
/* Гъвкавият елемент е СПАНЪТ, не `lmed-tag-dark`: обвивката е `display:
   contents` и няма кутия, тъй че `order` върху нея не значи нищо. */
.nz-card lmed-tag-dark{ display: contents; }
.nz-card .tag.tag--dark{ order: 2; align-self: flex-start; }
.nz-card__spec{ order: 3; flex-direction: row; justify-content: space-between;
  gap: var(--space-4); text-align: left; }
.nz-card__price{ order: 4; margin: 0; }
.nz-card__id h4{ font-size: var(--text-h4); }
/* Повече въздух над „Ориентировъчно време за третиране": отгоре свършва стекът
   от карти, а под него рендерите още се виждат — без отстояние заглавието
   сяда върху тях. */
.load-times{ padding-top: var(--space-9); }
}

/* Скриптът излиза рано при reduced-motion, тъй че --load-p остава 1 и
   рендерите са в крайното си положение. Остава да се покажат картите. */
@media (prefers-reduced-motion: reduce){
.nz-card{ opacity: 1; transform: none; transition: none; }
.load-art__n{ transition: none; }
}

}

/* ═══ sections/zones ═══ */
/* Scoped to this section's own roots: a rule here cannot reach an element
 * outside .zones-band. The bundle is one stylesheet on every page, so
 * without this a name like .grid or .cta would silently restyle another
 * section. Add a root here when this section grows one. */
@scope (.zones-band) {
/* ---- Терапии: вертикални карти с scroll-обвързани pill-ове ---- */
:scope{padding:var(--section-pad) var(--page-pad,48px)}
.zones-head{max-width:640px;margin:0 auto var(--space-7);text-align:center}
/* space-4 to the subtitle, the value platform and results already use. It
   was space-2 here and space-3 in series: three sections, three different
   gaps for one relationship. */
.zones-head h2{margin:0 0 var(--space-4);font-size:var(--text-h3)}
.zones-head p{margin:0;font-size:var(--text-h6);font-family:var(--font-display);font-weight:var(--weight-heading)}
.zones{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-5)}
/* ТРИ карти: третата взима целия ред, вместо да остане сама в лявата колона.
   Не в трета колона: картата е висока (min-height 560) и на една трета от
   реда кадърът става ИЗПРАВЕН, а снимките са 16:9 и легнали — човек, легнал
   в костюма, се реже по средата. На цял ред кадърът си остава лежащ.

   `:nth-child(3):last-child` хваща само случая с точно три; HERA е с четири
   и не я засяга. */
.zones > :nth-child(3):last-child{grid-column:1 / -1}
@media (max-width:1023px){.zones{grid-template-columns:1fr}}
}

/* ═══ tokens/buttons ═══ */
/* L Medical — Button states
   Spec source: uploads/l-med-buttons2 for claude.pdf — match exactly.

   One deliberate deviation from that spec (2026-08-27): the secondary variant
   has NO fill — `transparent`, resting and disabled — where the PDF paints it
   white. On white surfaces the two are indistinguishable; on the grey and
   photographic panels (the platform aside, the video band) the white fill read
   as a hard pill sitting on top of the surface instead of belonging to it.
   Everything else below still matches the PDF, focus included: a secondary
   button still converges to solid ink when focused. Do not "correct" the
   secondary background back to white without checking those two sections.

   Shared anatomy (both variants):
   - pill (border-radius 9999px), padding 8px 16px 8px 8px
   - leading icon (1rem) inside a circle with 8px padding → circle = 1rem + 16px
   - 16px gap between icon circle and label; Inter 1rem semi-bold label
   - transition: all 0.5s cubic-bezier(0.14, 0, 0, 1) on every animated part

   Primary hover storyboard: the icon circle's background grows until it fills the
   whole button; the icon rotates 180deg; the text switches color; icon + text move
   closer together (8px gap) and toward the center of the button. */

.lmed-btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  gap: 16px;
  border: none;
  border-radius: 9999px;
  padding: 8px 16px 8px 8px;
  font-family: var(--font-body);
  font-weight: var(--weight-body-semibold);
  font-size: 1rem;
  cursor: pointer;
  transition: all 0.5s cubic-bezier(0.14, 0, 0, 1);
}
.lmed-btn:disabled {
  cursor: not-allowed;
}

.lmed-btn__badge {
  position: relative;
  z-index: 2;
  width: calc(1rem + 16px);
  height: calc(1rem + 16px);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: all 0.5s cubic-bezier(0.14, 0, 0, 1);
}
.lmed-btn__icon {
  width: 1rem;
  height: 1rem;
  display: block;
  /* The box is square and some of the icons are not. mail.svg is 14x16, so a
     forced square stretched it ~14% wider than it is drawn; call.svg is square
     to within 0.002% and never showed it, which is why this surfaced only when
     the nav button stopped dialling and started linking. arrow-down and the
     two social marks are the other non-square ones. `contain` keeps each icon
     its own shape inside the 1rem it is given. */
  object-fit: contain;
  transition: all 0.5s cubic-bezier(0.14, 0, 0, 1);
}
.lmed-btn__label {
  position: relative;
  z-index: 2;
  transition: all 0.5s cubic-bezier(0.14, 0, 0, 1);
}

/* The grow-from-the-icon fill circle (primary hover) */
.lmed-btn__fill {
  position: absolute;
  left: calc(8px + 0.5rem + 8px); /* centre of the icon circle */
  top: 50%;
  width: calc(1rem + 16px);
  height: calc(1rem + 16px);
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0);
  z-index: 1;
  transition: transform 0.5s cubic-bezier(0.14, 0, 0, 1);
}

/* ================= Primary ================= */

.lmed-btn--primary {
  background: var(--ink);
}
.lmed-btn--primary .lmed-btn__badge {
  background: var(--accent-200);
}
.lmed-btn--primary .lmed-btn__label {
  color: var(--white);
}
.lmed-btn--primary .lmed-btn__fill {
  background: var(--accent-200);
}

/* hover: icon-circle bg grows to fill the button; icon rotates 180deg;
   text switches color; gap tightens to 8px and content centres */
.lmed-btn--primary:hover:not(:disabled):not(:focus-visible) {
  gap: 8px;
  padding: 8px 24px;
  /* The ink goes to accent as well, underneath the circle.
     The wipe alone was meant to cover the pill and geometrically it does — 240px
     of radius against a farthest corner 121px away, reached about a fifth of
     the way through the half second. But "covers" is a statement about centres
     and radii, not about the pixels where a circle's edge meets a 9999px
     corner, and what showed through there was the ink: a dark fleck beside the
     button.
     With the base colour arriving at the same place there is nothing dark left
     to show through, whatever the edges do. The circle still does the wiping —
     it is opaque and it gets there first; this only decides what it wipes
     over. */
  background: var(--accent-200);
}
.lmed-btn--primary:hover:not(:disabled):not(:focus-visible) .lmed-btn__fill {
  transform: translate(-50%, -50%) scale(16);
}
.lmed-btn--primary:hover:not(:disabled):not(:focus-visible) .lmed-btn__badge {
  background: transparent;
  width: 1rem;
}
.lmed-btn--primary:hover:not(:disabled):not(:focus-visible) .lmed-btn__icon {
  transform: rotate(360deg);
}
.lmed-btn--primary:hover:not(:disabled):not(:focus-visible) .lmed-btn__label {
  color: var(--ink);
}

/* focus: solid ink, badge circle gone, plain white icon, white label */
.lmed-btn--primary:focus-visible {
  background: var(--ink);
  outline: none;
}
.lmed-btn--primary:focus-visible .lmed-btn__badge {
  background: transparent;
}
.lmed-btn--primary:focus-visible .lmed-btn__icon {
  filter: brightness(0) invert(1);
}
.lmed-btn--primary:focus-visible .lmed-btn__label {
  color: var(--white);
}

/* disabled: flat light grey */
.lmed-btn--primary:disabled {
  background: var(--grey-200);
}
.lmed-btn--primary:disabled .lmed-btn__badge {
  background: var(--grey-300);
}
.lmed-btn--primary:disabled .lmed-btn__icon {
  opacity: 0.35;
}
.lmed-btn--primary:disabled .lmed-btn__label {
  color: var(--grey-400);
}

/* ================= Secondary ================= */

/* No fill — see the deviation note at the top of this file.

   The blur is from the design system and was missing here. It is what makes a
   secondary button belong to a photographic panel rather than sit on it: over
   the Smart Time film in the tech aside, and over the appliance zones, the
   pill reads as glass with the picture softened behind it. That is also the
   design's own answer to the problem the no-fill deviation above was solving,
   so the two go together rather than pulling against each other. */
.lmed-btn--secondary {
  background: transparent;
  border: 1px solid var(--ink);
  padding: 7px 15px 7px 7px; /* 8px spec minus 1px border */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.lmed-btn--secondary .lmed-btn__badge {
  background: var(--accent-200);
}
.lmed-btn--secondary .lmed-btn__label {
  color: var(--ink);
}
.lmed-btn--secondary .lmed-btn__fill {
  display: none;
}

/* hover: icon circle turns ink with a white icon; everything else stays */
.lmed-btn--secondary:hover:not(:disabled):not(:focus-visible) .lmed-btn__badge {
  background: var(--ink);
}
.lmed-btn--secondary:hover:not(:disabled):not(:focus-visible) .lmed-btn__icon {
  filter: brightness(0) invert(1);
  transform: rotate(360deg);
}

/* focus: converges to solid ink like primary focus */
.lmed-btn--secondary:focus-visible {
  background: var(--ink);
  border-color: var(--ink);
  outline: none;
}
.lmed-btn--secondary:focus-visible .lmed-btn__badge {
  background: transparent;
}
.lmed-btn--secondary:focus-visible .lmed-btn__icon {
  filter: brightness(0) invert(1);
}
.lmed-btn--secondary:focus-visible .lmed-btn__label {
  color: var(--white);
}

/* disabled: no fill either, faint grey border, muted text, no badge fill */
.lmed-btn--secondary:disabled {
  background: transparent;
  border-color: var(--grey-300);
}
.lmed-btn--secondary:disabled .lmed-btn__badge {
  background: transparent;
}
.lmed-btn--secondary:disabled .lmed-btn__icon {
  opacity: 0.35;
}
.lmed-btn--secondary:disabled .lmed-btn__label {
  color: var(--grey-400);
}

/* ═══ tokens/colors ═══ */
/* L Medical — Color tokens
   Source: L-Medical-design-system---colors.jpg + L Medical branding 2cmpr.pdf
   Base palette: white/grey dominant, "Azure mist" teal accent, eggshell + ink secondaries,
   and four semantic ramps (error/success/warning/info). */

:root {
  /* ---- Base neutrals (dominant) ---- */
  --white: #ffffff;
  --grey-92: #ededed;

  /* ---- Grey ramp (full scale, dark -> light) ---- */
  --grey-900: #212121;
  --grey-800: #3d3d3d;
  --grey-700: #5b5b5b;
  --grey-600: #7a7a7a;
  --grey-500: #999999;
  --grey-400: #b7b7b7;
  --grey-300: #dbdbdb;
  --grey-200: #f2f2f2;

  /* ---- Ink (logo + primary text-on-light) ---- */
  --ink: #171717;

  /* ---- Accent: Azure mist (teal) ramp, dark -> light ---- */
  --accent-900: #5c7c78;
  --accent-700: #759693;
  --accent-500: #91afad;
  --accent-300: #b1c9c8;
  --accent-200: #d3e5e5; /* dominant accent swatch */
  --accent-100: #e9f4f4;

  /* ---- Secondary neutrals ---- */
  --eggshell: #f2eedf;
  --black: #000000;

  /* ---- Semantic: Error (red) ---- */
  --error-900: #860020;
  --error-700: #b3002b;
  --error-500: #e00036; /* base */
  --error-300: #ec6686;
  --error-100: #f9ccd7;

  /* ---- Semantic: Success (green) ---- */
  --success-900: #00682a;
  --success-700: #008a38;
  --success-500: #00ad46; /* base */
  --success-300: #66ce90;
  --success-100: #ccefda;

  /* ---- Semantic: Warning (amber) ---- */
  --warning-900: #8f6a00;
  --warning-700: #bf8d00;
  --warning-500: #efb000; /* base */
  --warning-300: #f5d066;
  --warning-100: #fcefcc;

  /* ---- Semantic: Info (indigo) ---- */
  --info-900: #2b2299;
  --info-700: #392ecc;
  --info-500: #4739ff; /* base */
  --info-300: #9188ff;
  --info-100: #dad7ff;

  /* ---- Semantic aliases ---- */
  --surface-page: var(--white);
  --surface-sunken: var(--grey-200);
  --surface-card: var(--white);
  --surface-accent: var(--accent-200);
  --surface-accent-soft: var(--accent-100);
  --surface-inverse: var(--ink);

  --text-primary: var(--ink);
  --text-secondary: var(--grey-700);
  --text-muted: var(--grey-500);
  --text-on-inverse: var(--white);
  --text-on-accent: var(--ink);

  --border-default: var(--grey-300);
  --border-strong: var(--grey-500);
  --border-accent: var(--accent-500);

  /* Links carry the brand's own ink, not a status colour. The design system
     export aliased these to the indigo *info* ramp, which is the semantic
     colour for informational states — it only stayed invisible because every
     anchor in the design is a component that sets its own colour. The first
     bare <a> on the site (mailto:/tel: in the contact cards) rendered as
     browser-blue. Every real link in the design is ink or grey with an accent
     hover, so that is what these now say. */
  --link: var(--text-primary);
  --link-hover: var(--accent-900);

  --state-error: var(--error-500);
  --state-success: var(--success-500);
  --state-warning: var(--warning-500);
  --state-info: var(--info-500);
}

/* ═══ tokens/filters ═══ */
/* L Medical — the catalogue filter zone.
 *
 * From aparati-v2: a sticky tab bar over full-width panels, one open at a time,
 * replacing the chip-and-dropdown bar. Unscoped on purpose — .fzone wraps both
 * the bar and the grid, and .grid is a scope root of its own in
 * sections/catalog.css, so a scope here would fence the two apart.
 *
 * How a panel opens: it is IN FLOW, directly under the bar, so it pushes the
 * grid down and nothing is ever hidden behind it.
 *
 * It used to overlay the grid instead, and the reason is worth keeping: an even
 * earlier version reserved room on the FIRST open and overlaid on every one
 * after, which read as two different controls depending on when you clicked.
 * Overlaying always was one way to make that consistent; reserving always is
 * the other, and it is the one the design draws. The mistake to avoid is
 * mixing them, not either of them.
 */

.fzone { position: relative; }
/* В нормалния поток. Барът беше sticky и с него идваха две неща, които вече
   ги няма: --fbar-shift, който го разминаваше с фиксираното меню, и
   плейсхолдърът #fbar-sentinel, по който скриптът разбираше, че е залепнал.
   Отплува нагоре със съдържанието като всичко друго, така че няма какво да се
   разминава и няма какво да се наблюдава.

   --space-6, не --space-5: полето над таба беше сборът от този margin (24) и
   вертикалния padding на .fbar-row (8). Padding-ът падна, за да е разстоянието
   ПОД таба на едно място, така че тук влиза цялата стойност — 32 остава 32. */
.fbar { margin-top: var(--space-6); }

.fbar-inner { position: relative; }
/* Без вертикален padding. Разстоянието от таба до картите трябва да е същото
   като между картите (--space-4), а то беше сбор от два отстъпа — долния тук и
   горния на .fpanel. Сбор не се настройва: махаш едното и оставяш другото да го
   владее само, иначе следващият, който пипне единия, разваля разстоянието, без
   да разбере откъде.

   Симетрично нула, а не асиметрично: редът е висок точно колкото хапката, така
   че броячът в него остава центриран върху нея. С 8 отгоре и 0 отдолу центърът
   на реда се разминава с центъра на хапката — точно разминаването, което вече
   беше поправяно веднъж. */
.fbar-row {
  position: relative;
  display: flex; align-items: center; justify-content: flex-start;
  padding: 0 var(--page-pad);
}
.fbar-tabs { display: flex; min-width: 0; }

/* Стрелката я няма. Тя беше подписът на разгъването — сочеше надолу „ще се
   отвори", обръщаше се при отворен панел — а разгъване вече не съществува:
   точно един панел е отворен винаги. Стрелка, която не може да значи нищо
   друго освен „натисни ме, за да свия това", е обещание, което барът не може
   да изпълни.

   Активният таб се чете от тъмната хапка, която компонентът мести — това е
   сигналът за таб бар. Иконата arrow-down-2.svg остава ползвана другаде.

   Правилата бяха ограничени до .fbar, така че падането им не пипа lmed-tabs
   на другите страници. */

/* ---------- panels ---------- */
/* В потока, след .fbar-row в разметката — оттам идва и редът на екрана.
   Беше absolute с top:0, тоест лягаше зад бара и се спускаше над грида; тогава
   и z-index-ите, и pointer-events-ите бяха нужни, за да не яде барът кликове и
   панелът да не гълта тези на грида. В потока няма какво да се припокрива.

   Грид с ЕДНА клетка, в която стоят всичките панели един върху друг. Оттам
   идва еднаквата височина: кутията е висока колкото НАЙ-ВИСОКИЯ панел,
   независимо кой е отворен, така че смяната на таб не мести грида под него.
   Измерено преди това: Терапии 202px, Технологии и Производител по 382 —
   180px подскок при всяко превключване.

   minmax(0, 1fr), а НЕ `auto` или бос `1fr`: инак пистата не може да падне под
   min-content на най-широкото си съдържание. .brandgrid е `1fr 1fr`, а `1fr`
   носи автоматичен минимум min-content — докато .fpanels беше block, кутията
   имаше определена ширина и това беше безопасно; като грид клетка колоните му
   се надуха до 1248px всяка и страницата получи хоризонтален скрол. Съседният
   .thergrid ползва minmax(0, 1fr) точно заради този капан. */
.fpanels { display: grid; grid-template-columns: minmax(0, 1fr); }

/* Всички в клетка 1/1 — това ги стека, вместо да ги нарежда.
   min-width: 0 върви с minmax(0, 1fr) отгоре: автоматичният минимум на грид
   елемент също е min-content, тоест и двете места трябва да разрешат свиването,
   иначе едното пак надува пистата. */
.fpanel {
  grid-area: 1 / 1;
  min-width: 0;
  background: rgba(255, 255, 255, .85);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  /* Барът вече не седи ВЪРХУ панела, а над него в потока, така че горният
     отстъп, който му правеше място (височина на таб + padding), отпада. */
  padding: var(--space-4) 0;
}

/* Скритите панели остават В РАЗМЕТКАТА, защото иначе не могат да дадат
   височина: `hidden` от lmed-tabs значи display:none, а елемент извън потока
   не мери нищо и стекът пак ще се свива до отворения.

   visibility:hidden прави точно каквото трябва — пази кутията в layout-а, но
   вади съдържанието от рисуването, от достъпността, от табване и от
   събитията, тоест трите неща, за които `hidden` служи, остават в сила.

   Тук `display` СЕ обявява нарочно, за да победи `[hidden]` от браузъра. На
   самия .fpanel го няма, така че отвореният панел е block по подразбиране —
   правило там би отворило всички. */
.fpanel[hidden] { display: block; visibility: hidden; }

/* The image behind an option card. Hatched where no photograph exists yet, so
   a missing asset reads as pending rather than broken. */
.ph {
  position: absolute; inset: 0;
  background:
    repeating-linear-gradient(45deg, rgba(23,23,23,.05) 0 1px, transparent 1px 9px),
    var(--accent-100);
  transition: transform .5s cubic-bezier(.15, 0, 0, 1);
}
.ph img, .ph video { display: block; width: 100%; height: 100%; object-fit: cover; }

/* The gap the design gives the grid under the bar. Not --section-pad: the bar
   and the grid are one control and the thing it controls, not two sections. */
.gridwrap { padding-top: var(--space-5); }

/* A real checkbox inside a pill — visually check-pill, semantically an input. */
.fpill {
  display: inline-flex; align-items: center; width: fit-content; max-width: 100%;
  background: rgba(211, 229, 229, .45);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  border: 1px solid var(--accent-200); border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-4) var(--space-2) var(--space-2);
  transition: background .5s cubic-bezier(.15, 0, 0, 1), border-color .5s cubic-bezier(.15, 0, 0, 1);
}
.fpill .cnt { font-weight: 400; color: var(--text-secondary); }

/* ---------- a panel of option cards (technologies, manufacturers) ---------- */
/* Кутията е през цялата ширина и отстъпите са с PADDING, не с margin: така
   картите продължават до ръба на екрана И в двете посоки, вместо да се режат на
   улиците. Padding-ът дава улица в двата КРАЯ на скрола — без него първата и
   последната карта опират в ръба на прозореца.

   Отстъпът беше с margin точно за да няма това изнасяне: тогавашният запис
   казва, че с padding картите минават под улиците на страницата. Това още е
   вярно и вече е ЖЕЛАНОТО — лентата чете като карусел, който продължава извън
   екрана, а не като нещо, отрязано в колоната. Тук имаше маска, която пазеше
   лявата улица чиста; падна съзнателно, не по невнимание.

   Хоризонталният скрол с колелото на мишката е в scripts/page/catalog.js —
   `overflow-x: auto` сам по себе си не отговаря на вертикално колело. */
.trow {
  display: flex; gap: var(--space-4);
  margin: 0;
  padding-inline: var(--page-pad);
  overflow-x: auto; overflow-y: clip; overscroll-behavior: contain;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.trow::-webkit-scrollbar { display: none; }
.tcard {
  position: relative; flex: 0 0 300px; aspect-ratio: 6 / 7;
  border-radius: var(--radius-md); overflow: clip; cursor: pointer;
}
.tcard__body { position: relative; padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
/* Без хоризонтален отстъп, по същата причина, по която го няма и .bcard__desc:
   носеше `0 var(--space-2)` и текстът започваше 8px по-навътре от хапчето над
   него. Тук няма знак долу, тоест лявата линия са само двата — но и двама са
   достатъчни, за да се вижда отместването. */
.tcard__desc { margin: 0; font-size: .9rem; line-height: 1.45; color: var(--ink); padding: 0; text-wrap: pretty; }
.tcard:hover .ph { transform: scale(1.05); }
.tcard:hover .fpill { background: rgba(255, 255, 255, .45); border-color: var(--white); }

/* ---------- a panel of plain pills (therapies, and any group whose options
   have no picture or description yet) ---------- */
.thergrid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  padding: 0 var(--page-pad);
}
.thercol { display: flex; flex-direction: column; gap: var(--space-4); align-items: flex-start; }

/* ---------- manufacturers ---------- */
.brandgrid {
  display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4);
  padding: 0 var(--page-pad);
}
.bcard {
  /* Отстъпът на картата е ЕДНО число. Ползват го и тялото, и знакът долу вляво
     — иначе следващият, който го промени на едното място, разминава двете, а
     логото тъкмо беше подравнявано веднъж заради това. */
  --bcard-pad: var(--space-4);
  position: relative; border-radius: var(--radius-md); overflow: clip; cursor: pointer;
  min-height: 350px; display: flex; flex-direction: column;
}
.bcard__body { position: relative; padding: var(--bcard-pad); display: flex; flex-direction: column; gap: var(--space-3); }
/* Без хоризонтален отстъп. Носеше `0 var(--space-2)`, тоест текстът започваше
   8px по-навътре от хапчето над него и от знака под него — трите се четат като
   една лява линия и нямаше причина един от тях да е отместен. Вертикалният
   ритъм идва от gap на тялото, не оттук. */
.bcard__desc { margin: 0; max-width: 42ch; font-size: .9rem; line-height: 1.45; color: var(--ink); padding: 0; text-wrap: pretty; }
.bcard__logo {
  /* КВАДРАТНА кутия. Кутията беше 96×56, а и двата знака са с viewBox 14×14,
     тоест квадратни — с object-fit: contain знакът се мереше по височината и от
     96-те широки се ползваха 56. Квадрат значи, че зададеният размер Е размерът
     на знака, а не таван, от който се вижда част. */
  --bcard-logo-size: 80px;
  position: relative;
  width: var(--bcard-logo-size); height: var(--bcard-logo-size);
  /* auto отгоре го бута до дъното на картата. Отляво и отдолу стои на отстъпа
     на .bcard__body, тоест на същата линия и същото поле, с които хапчето стои
     горе вляво — четири еднакви отстъпа в четирите ъгъла.
     Беше 24 отляво и 0 отдолу: нито подравнено с нещо (хапчето беше на 12,
     текстът на 20), нито с поле под себе си — знакът опираше в долния ръб. */
  margin: auto auto var(--bcard-pad) var(--bcard-pad);
}
.bcard__logo img { width: 100%; height: 100%; object-fit: contain; display: block; }
.bcard:hover .ph { transform: scale(1.05); }
.bcard:hover .fpill { background: rgba(255, 255, 255, .45); border-color: var(--white); }

/* The running total. Kept from the previous filter bar — v2 has per-group
   badges and a clear-all, but nothing that says how much of the catalogue you
   are currently looking at.

   Обикновен flex елемент в .fbar-row, избутан вдясно с margin-left: auto.
   Беше абсолютно позициониран срещу .fzone, защото барът беше sticky и
   броячът не биваше да пътува с него — виж catalog.liquid защо вече не е.

   Носеше и фиксирана височина 42px, „колкото таба". Табът е 46, така че
   броячът стоеше 2px над текста, с който трябва да е на една линия. Височина,
   която се ПОЗНАВА, е точно това, което се разминава; align-items на реда я
   мери. */
.grid-count {
  margin: 0 0 0 auto;
  font-size: .9rem; color: var(--text-secondary); white-space: nowrap;
}

@media (max-width: 768px) {
  /* The tabs no longer fit on one row, so THEY scroll — not the row, or the
     counter would scroll away with them. The active tab is scrolled into view
     by the script. */
  .fbar-tabs {
    overflow-x: auto; overflow-y: clip;
    overscroll-behavior-x: contain;
    scrollbar-width: none; -webkit-overflow-scrolling: touch;
    scroll-padding-inline: var(--page-pad);
  }
  .fbar-tabs::-webkit-scrollbar { display: none; }
  /* No room beside the tabs — they take the whole row here. Редът се пренася
     и броячът минава НАД табовете: order го качва, 100% ширина му дава свой
     ред. Хоризонталният отстъп идва от .fbar-row и не се добавя втори път. */
  .fbar-row { flex-wrap: wrap; }
  .grid-count { order: -1; width: 100%; margin: 0 0 var(--space-2); }
  .thergrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* .brandgrid is already one column from the 1024 block below. */
  .bcard { min-height: 260px; }
  .tcard { flex: 0 0 240px; }
}
@media (max-width: 1024px) {
  .brandgrid { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  /* .fbar-inner и .fpanel вече не се анимират изобщо. Остава снимката в
     картата на опцията, която е единственото движение тук. */
  .ph { transition: none; }
}

/* ═══ tokens/fonts ═══ */
/* L Medical — Webfonts
   IBM Plex Sans (headings, SemiBold 600) and Inter (body/UI, Regular 400).
   Static per-weight files used (not the variable TTFs) — the variable files' Cyrillic
   glyph mapping rendered incorrectly in-browser; static weights render Cyrillic correctly. */

@font-face {
  font-family: "IBM Plex Sans";
  src: url("../assets/fonts/IBMPlexSans-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("../assets/fonts/IBMPlexSans-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("../assets/fonts/IBMPlexSans-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("../assets/fonts/IBMPlexSans-Bold.woff2") format("woff2");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "IBM Plex Sans";
  src: url("../assets/fonts/IBMPlexSans-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Medium.woff2") format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-SemiBold.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Inter";
  src: url("../assets/fonts/Inter-Italic.woff2") format("woff2");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

:root {
  --font-display: "IBM Plex Sans", "Segoe UI", sans-serif;
  --font-body: "Inter", "Segoe UI", sans-serif;
}

/* ═══ tokens/nav ═══ */
/* L Medical — Site navigation (component styles)
   Used by components/navigation/SiteNav.jsx and ui_kits/website.
   Glass pill nav: logo left, link pill + primary CTA right; mobile = round menu btn + blur overlay. */

.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-5);
  padding: var(--space-5) var(--page-pad, 48px);
  transition: transform 0.35s cubic-bezier(0.14, 0, 0, 1);
}
.nav.nav--hidden { transform: translateY(-110%); }

.nav-pill {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-pill);
  padding: 0px 0px 0px var(--space-6);
  background: rgba(255, 255, 255, .4);
  backdrop-filter: blur(6px);
}

.nav-menu-btn {
  display: none;
  border-radius: 999px;
  border: 1px solid var(--border-default);
  background: rgba(255, 255, 255, .4);
  backdrop-filter: blur(6px);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  padding: var(--space-2) var(--space-4);
  /* <button> НЕ наследява цвят: UA му дава `buttontext`, тоест чисто черно.
     Без този ред currentColor в чертите по-долу е #000, а не мастиленото на
     системата — разлика, която се вижда до логото. */
  color: var(--ink);
}
.nav-menu-btn img { width: 16px; height: 16px; display: block; }
/* <span class="menu-anim"> е хостът на композицията: site-nav.js зарежда в него
 * media/raw/anim/menu-btn.json през lottie, който вече е вендорнат в бъндъла.
 * SVG-то, което lottie вкарва, носи собствените си мерки — тук е само кутията.
 *
 * Чертите отдолу са РЕЗЕРВА и се рисуват само докато хостът е ПРАЗЕН. Това не е
 * теоретичен случай: точно така изглеждаше бутонът, докато библиотеката не се
 * зареждаше от никъде — бяло кръгче без нищо в него. `:empty` пада от само себе
 * си в мига, в който lottie вкара своя <svg>, така че двете не могат да се
 * покажат заедно, а бутонът не може да остане празен, ако JSON-ът някога не се
 * дръпне. */
.nav-menu-btn .menu-anim {
  position: relative;
  width: 16px; height: 16px; display: block;
}
.nav-menu-btn .menu-anim svg { display: block; }
.nav-menu-btn .menu-anim:empty::before,
.nav-menu-btn .menu-anim:empty::after {
  content: ""; position: absolute; left: 0; right: 0;
  height: 2px; border-radius: 1px; background: currentColor;
  transition: transform var(--duration-base) var(--ease-standard);
}
/* Центрове на 5 и 11 в кутия от 16, тоест симетрични спрямо 8 — затова и
   двете се събират с еднакво отместване. */
.nav-menu-btn .menu-anim:empty::before { top: 4px; }
.nav-menu-btn .menu-anim:empty::after { top: 10px; }
body.menu-open .nav-menu-btn .menu-anim:empty::before { transform: translateY(3px) rotate(45deg); }
body.menu-open .nav-menu-btn .menu-anim:empty::after { transform: translateY(-3px) rotate(-45deg); }

.nav-logo { display: flex; align-items: center; gap: 0px; }
.nav-logo img { height: 44px; display: block; }
@media (max-width: 1440px) {
  .nav-logo img { height: 32px; }
}
.nav-logo .logo-type {
  transition: opacity 0.35s cubic-bezier(0.14, 0, 0, 1);
}
.nav.nav--scrolled .logo-type { opacity: 0; }

.nav-links { display: flex; align-items: center; gap: var(--space-6); list-style: none; margin: 0; padding: 0; }
.nav-links a { text-decoration: none; color: var(--text-primary); white-space: nowrap; }
.nav-links a.active { font-weight: var(--weight-body-semibold); }

.lang-switch { display: flex; align-items: center; gap: var(--space-1); font-size: 0.95rem; }
.lang-switch a { text-decoration: none; color: var(--text-muted); white-space: nowrap; }
.lang-switch a.active { color: var(--text-primary); font-weight: var(--weight-body-semibold); }
.lang-switch .lang-divider { width: 1px; height: 14px; background: var(--border-default); }

/* Hover на връзките в менюто. Дизайнът не даваше никакъв — трите набора стояха
   мъртви под мишката. Цветът е --link-hover, същият, към който отива всяка
   друга връзка в сайта, за да не се учи потребителят на две правила.
   Активната също реагира: тя си остава връзка, а „текуща страница" вече се
   чете от по-плътния шрифт. */
.nav-links a,
.lang-switch a,
.menu-overlay ul a { transition: color var(--duration-base) var(--ease-standard); }
.nav-links a:hover,
.lang-switch a:hover,
.menu-overlay ul a:hover { color: var(--link-hover); }

@media (max-width: 1024px) {
  .nav-pill { gap: var(--space-4); padding-left: var(--space-5); }
  .nav-links { gap: var(--space-4); }
}
@media (max-width: 768px) {
  .nav-pill { display: none; }
  .nav-menu-btn { display: flex; }
}

/* Mobile menu overlay */
.menu-overlay {
  position: fixed; inset: 0; z-index: 90;
  background: rgba(255, 255, 255, .75);
  backdrop-filter: blur(16px);
  display: none;
  flex-direction: column;
  justify-content: center;
  padding: 0 var(--page-pad, 16px);
  opacity: 0;
  transition: opacity 0.35s cubic-bezier(0.14, 0, 0, 1);
}
body.menu-open { overflow: hidden; }
body.menu-open .menu-overlay { display: flex; }
body.menu-open .menu-overlay.visible { opacity: 1; }
.menu-overlay ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-5); }
.menu-overlay ul a { text-decoration: none; color: var(--text-primary); font-family: var(--font-display); font-size: var(--text-h4); font-weight: var(--weight-body-regular); }
.menu-overlay ul a.active { font-weight: var(--weight-heading); }
.menu-overlay .lang-switch { margin-top: var(--space-7); font-size: 1.1rem; }

/* Toggled by .nav--hidden on every scroll direction change. One element,
   and it holds no backdrop-filter descendant. */
.nav{will-change:transform}

/* ═══ tokens/spacing ═══ */
/* L Medical — Spacing, radius, shadow, motion tokens.
   No explicit spacing/radius spec was provided; derived from the print collateral's
   generous margins, fully-rounded pill swatches, and quiet, restrained shadows. */

:root {
  /* Spacing scale (4px base) */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;

  /* Page horizontal padding — 16px ≤768px (set per-page), 48px default, 12vw ≥1770px */
  --page-pad: 48px;

  /* Radius — swatches in the color sheet are fully-rounded pills; cards/buttons use a
     softer, moderate radius consistent with the brand's calm, rounded-but-not-playful feel */
  --radius-sm: 12px;
  --radius-md: 24px;
  --radius-lg: 32px;
  --radius-pill: 999px;

  /* Shadow — subtle, low-contrast (matches the flat, quiet print aesthetic) */
  --shadow-sm: 0px 2px 4px 0px rgba(23, 23, 23, 0.12);
  --shadow-md: 0 4px 16px rgba(23, 23, 23, 0.08);
  --shadow-lg: 0 12px 32px rgba(23, 23, 23, 0.12);

  /* Motion — brand has no evidenced animation; keep transitions quick and quiet */
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1); /* @kind other */
  --duration-fast: 120ms; /* @kind other */
  --duration-base: 200ms; /* @kind other */
}

@media (min-width: 1770px) {
  :root {
    --page-pad: 12vw;
  }
}

/* Mobile gutter. Lived inside contacts.css's mobile block until the section
   stylesheets were scoped — where `:root` could never match, because the
   document root is not inside any section. It is a token, so it lives with
   the tokens. */
@media (max-width: 768px) {
  :root {
    /* Скалата се свива от --space-5 нагоре. Малките четири остават: 4/8/12/16
       са отстояния ВЪТРЕ в елемент — между иконка и надпис, между два тага — и
       те не зависят от ширината на екрана. Свива се това, което дели БЛОКОВЕ,
       защото то е и единственото, което на телефон изяжда съдържание.

       --section-pad виси на --space-8 (base.css), тоест ритъмът между секциите
       пада от 64 на 48, а границата между две съседни — от 128 на 96. Това е
       най-голямото движение тук и е нарочно: то беше и причината скалата да
       се свива. */
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 48px;
    --space-9: 64px;
    --page-pad: 16px;
  }
}

/* ═══ tokens/typography ═══ */
/* L Medical — Type scale
   Source: l-med-typeography.pdf. Base 1rem = 14px. Headings: IBM Plex Sans SemiBold (600).
   Body/small: Inter Regular (400). */

:root {
  --text-base-px: 14px;

  /* Стълбицата е ИЗЧИСЛЕНА, не изписана. Числата, които стояха тук, бяха точно
     тази стълбица — 1.25 → 1.5625 → 1.953 → 2.441 → 3.052 → 3.815 — но забити
     един по един, тоест смяната на отношението значеше преписване на шест реда
     и възможност едно от тях да остане старо. Сега отношението е на едно място.

     h6 е основата и всяко следващо стъпало е предишното по --scale-ratio.
     Десктопът излиза същият до последния знак: 17.5 / 21.9 / 27.3 / 34.2 /
     42.7 / 53.4px при основа 14px. */
  --scale-ratio: 1.25;

  --text-h6: 1.25rem;
  --text-h5: calc(var(--text-h6) * var(--scale-ratio));
  --text-h4: calc(var(--text-h5) * var(--scale-ratio));
  --text-h3: calc(var(--text-h4) * var(--scale-ratio));
  --text-h2: calc(var(--text-h3) * var(--scale-ratio));
  --text-h1: calc(var(--text-h2) * var(--scale-ratio));
  --text-p: 1rem;        /* 14px */
  --text-small: 0.8rem;  /* 11.2px */

  --weight-heading: 600;
  --weight-body-regular: 400;
  --weight-body-medium: 500;
  --weight-body-semibold: 600;

  --leading-heading: 1.15;
  --leading-body: 1.4;
}

/* На телефон стълбицата се свива ЦЯЛА — и основата, и отношението. Затова е
   тук, до стълбицата, а не при правило, което сменя един кегел: две числа
   местят шестте заглавия наведнъж.

     17.5 / 21.9 / 27.3 / 34.2 / 42.7 / 53.4   →   16.5 / 19.5 / 23.0 / 27.1 / 32.0 / 37.8

   Внимание при --text-page-title: той е var(--text-h1) в base.css и там има
   свой мобилен вариант към var(--text-h2). Двете се НАСЛАГВАТ, тоест на
   телефон заглавието на страница става h2 от свитата стълбица — 32px, не 42.7
   както беше. Ако това е много свиване, редът за page-title в base.css е
   мястото, не тук. */
@media (max-width: 768px) {
  :root {
    --scale-ratio: 1.18;
    --text-h6: 1.18rem;
  }
}

html {
  font-size: var(--text-base-px);
}

body {
  font-family: var(--font-body);
  font-weight: var(--weight-body-regular);
  font-size: var(--text-p);
  line-height: var(--leading-body);
  color: var(--text-primary);
  /* Disable OpenType 'locl' localized-form substitution: with lang="bg", IBM Plex Sans
     and Inter switch to authentic Bulgarian alternate glyphs (е.g. п/т/и take shapes that
     read as Latin n/m/u to non-Bulgarian eyes). That's a real, deliberate font feature —
     just not the look the brand's own print materials use (standard Cyrillic forms). */
  font-feature-settings: "locl" 0;
}

h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-display);
  font-weight: var(--weight-heading);
  line-height: var(--leading-heading);
  margin: 0;
  font-feature-settings: "locl" 0;
}

h1 { font-size: var(--text-h1); }
h2 { font-size: var(--text-h2); }
h3 { font-size: var(--text-h3); }
h4 { font-size: var(--text-h4); }
h5 { font-size: var(--text-h5); }
h6 { font-size: var(--text-h6); }

small { font-size: var(--text-small); }
