/* ════════════════════════════════════════════════════════════
   kristofkarner.com — main.css
   A karnerkristof.hu téma vizuális nyelve, WordPress nélkül.
   ════════════════════════════════════════════════════════════ */

/* ── Reset ──────────────────────────────────────────────────── */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* ── Design tokens — light mode (default) ───────────────────── */
:root {
    --bg:          #ffffff;
    /* ── ABLAK-FELÜLET ─────────────────────────────────────────
       A keretes, „ablakban lévő" tartalmak háttere. Eddig négyféle
       megoldás élt egymás mellett: volt, aminek csak kerete volt, volt,
       aminek `--bg-alt` háttere, volt, aminek `color-mix`-szel kevert, és
       volt, aminek semmije. Innentől egy érték viszi mindet.

       Ami NEM kap felületet: a táblázat és a vélemény-kártya. Egy
       vonalazott adatsor nem ablak, hanem a szövegfolyam része — négy
       kitöltött rácscella pedig egyetlen szürke táblává olvadna, és a
       hajszál-elválasztók eltűnnének benne. */
    /* Semleges szürke: R=G=B, tehát tisztán a fekete és a fehér
       keveréke. Korábban #E9ECEF volt, amiben a kék hat egységgel a
       vörös fölött állt — az a hajlás Night Shift alatt is átütött,
       hidegkékre színezve az egész felületet. A világosság változatlan:
       az új érték ugyanazt a relatív luminanciát adja. */
    /* HIDEG szürke, nem semleges. Kristóf kifejezetten ezt kérte, és
       megindokolta: erős night shift mellett dolgozik, tehát a meleg
       hajlást nem tudja megítélni — inkább menjen a biztos irányba.
       R 233 < G 236 < B 239: a kékes csatorna a legmagasabb, barnás
       árnyalata nincs. (Egy párhuzamos munkamenet ezt közben #ECECEC-re,
       tehát tisztán semlegesre írta át — az teljesíti a „ne legyen meleg"
       felét, a „legyen hideg" felét nem.) A világosság gyakorlatilag
       azonos, a kontrasztarányok tehát nem mozdulnak: a legszűkebb 4,84. */
    --felulet:     #E9ECEF;
    --fg:          #000000;
    --fg-sub:      #444444;
    /* #888888 volt — fehéren 3,54:1, tehát AA ALATT. Nem ízlés kérdése
       volt, hanem mérési hiba: a lap minden halk felirata megbukott vele.
       A #666666 fehéren 5,74, felületen 4,82 — mindkettő átmegy. */
    --fg-muted:    #666666;
    --border:      rgba(0, 0, 0, 0.09);

    /* Apple-stílusú glass — sidebar és gombok */
    --glass-bg:    rgba(255, 255, 255, 0.82);
    --glass-blur:  saturate(180%) blur(20px);
    /* Nav item hover glass (sötétebb a sidebar light glasson belül) */
    --glass-item:  rgba(0, 0, 0, 0.055);

    /* Egyetlen család viszi az egész oldalt. A --font-display és a
       --font-mono megmarad NÉVNEK, mert a szabályok jelentése más:
       az egyik szerkezeti címke, a másik gépi kimenet. Ha valamelyik
       később megint külön betűt kap, itt kell átírni, nem 40 helyen.
       A „Mono tartalek" a fonts.css-ben metrikára igazított Courier
       New — a betűcsere így nem töri újra a sorokat. Nem külső kérés. */
    --font:         'IBM Plex Mono', 'Mono tartalek', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    --font-display: 'IBM Plex Mono', 'Mono tartalek', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
    --font-mono:    'IBM Plex Mono', 'Mono tartalek', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

    --text-xs:   0.82rem;
    --text-sm:   0.95rem;
    --text-base: 1.05rem;
    --mertek:    calc(var(--text-base) * 0.6 * 80);
    /* 1,3rem volt. A hosszú szövegek 13,1 és 20,8 képpont között szórtak
       — 1,59-szeres különbség KÉT BEKEZDÉS között. Innentől minden
       folyószöveg a `--text-base`, és ez a fok csak a cím alatti
       felvezetőé meg a h3-é marad. Monospace-nél a köztes fokozat külön
       is árt: a karakterrács osztása változik tőle, tehát két egymás
       alatti blokk függőleges oszlopai szétcsúsznak. */
    --text-lg:   1.15rem;
    --text-xl:   1.7rem;
    /* --text-2xl törölve: sehol nem hivatkozott rá szabály. */

    --space-1:   0.5rem;
    --space-2:   1rem;
    --space-3:   1.5rem;
    --space-4:   2rem;
    --space-6:   4rem;
    --space-8:   8rem;

    /* ── Oldalmargó — EGYETLEN arányos érték az egész honlapra ─────
       vw-alapú, hogy minden kijelzőn és minden page zoom-szinten
       ugyanakkora hányadot vigyen el a képernyőből. A clamp két vége nem
       ízlésbeli finomítás: az alsó a 320 pixeles kijelzőn tartja
       olvashatónak a sort, a felső akadályozza meg, hogy nagy monitoron a
       margó egye meg a tartalmat.

       Ami eddig hibás volt: négy különböző oldalmargó élt egymás mellett
       (container 8vw, 960 alatt fix 2rem, sidebar 1,5rem, footer 4rem), és
       960 pixelnél a fő margó 8vw-ről fix 2rem-re ESETT. Page zoomkor a
       CSS-viewport szűkül, tehát a nagyítás átvitte az oldalt ezen a
       ponton — és a margó a nagyítás pillanatában a felére csökkent. Ezt
       látta a szem úgy, hogy a tartalom hozzáér a szélhez. Breakpointon
       innentől EGYIK margó sem ugrik. */
    --margo:      clamp(1.25rem, 5.4vw, 7rem);
    /* A sidebar keskeny sáv: benne ugyanez az érték szétfeszítené a
       tartalmat, ezért a saját szélességéhez mért, visszafogottabb pár. */
    --margo-szuk: clamp(1rem, 2.1vw, 1.75rem);

    /* ── A menü függőleges térközei — a KÉPERNYŐ MAGASSÁGÁHOZ mérve ──
       Az oldalmargó `vw`-alapú, mert vízszintesen a szélesség a szűk
       keresztmetszet. A menüben fordítva: ott a MAGASSÁG fogy el. A
       sidebarban kilenc menüpont áll, fölöttük a monogram, alattuk a
       nyelvváltó — fix térközökkel ez 698 képpontot kért. Egy 1280×800-as
       laptopon a böngésző saját sávjai után ~640 marad, tehát az „Email"
       26 képponttal a képernyő alá csúszott, és mivel a fejléc
       `overflow`-ja `visible` volt, oda nem is lehetett görgetni. Mobilon
       ugyanez: a nyitott panel 743 képpontos ablakot igényelt, egy 667-es
       iPhone-on tehát az alja levágódott.

       Ezért a térközök `vh`-ra vannak kötve. A `clamp` felső vége a
       korábbi fix értéket adja vissza, és 800 képpont fölött pontosan az
       is jön ki — ahol eddig sem volt baj, ott semmi nem változik. Alacsony
       ablakban viszont arányosan összébb húzódnak, és a menü kifér.

       A `dvh` a második sorban azért van külön, mert iOS 15.4 előtt nem
       létezik: ott az első deklaráció marad érvényben. Ahol viszont van,
       ott pontosabb — a `vh` a mobil böngészőkben a NAGY viewporthoz
       mér, tehát épp akkor ad túl nagy térközt, amikor a címsáv látszik
       és a hely tényleg kevés. */
    --nav-koz:   clamp(0.4rem, 2vh, 1rem);      /* menüpontok között */
    --nav-koz:   clamp(0.4rem, 2dvh, 1rem);
    --nav-valt:  clamp(0.6rem, 3vh, 1.5rem);    /* csoporthatárnál */
    --nav-valt:  clamp(0.6rem, 3dvh, 1.5rem);
    --nav-jel:   clamp(0.3rem, 1vh, 0.5rem);    /* szoros sorok között */
    --nav-jel:   clamp(0.3rem, 1dvh, 0.5rem);
    --nav-logo:  clamp(1rem, 8vh, 4rem);        /* a monogram alatt */
    --nav-logo:  clamp(1rem, 8dvh, 4rem);
    --nav-pad:   clamp(1rem, 4vh, 2rem);        /* a fejléc pereme */
    --nav-pad:   clamp(1rem, 4dvh, 2rem);

    /* ── Keretes dobozok belső margója — szintén EGY érték ─────────
       Ugyanaz a történet, egy szinttel beljebb. A lapon tíz körbekeretezett
       vagy saját hátterű „ablak" van (adatlap, helyzet-blokk, tartalomjegyzék,
       jegyzet, vélemény, záró blokk, kód- és bizonyíték-blokk), és mindegyik
       MÁS vízszintes belső margót használt: 0, 16, 24 és 32 képpontot, három
       külön mobil felülírással. Egy táblázatnál javítva lett, a többinél nem.

       A legrosszabb eset az adatlap volt: a `padding: 0.6rem 0` miatt a
       szöveg 1 képpontra állt a saját keretétől — MINDEN eszközön, nem csak
       telefonon. A kereten belül nem volt hova lélegeznie a sornak.

       Innentől egyetlen arányos érték visz mindet, `--margo` mintájára: az
       arány marad, a lépték a kijelzőhöz igazodik. 375 pixelen 17, tableten
       18, asztali méreten 32 képpont. Nem kell hozzá mobil felülírás, tehát
       nincs hol elveszni. (A TÁBLÁZAT cellái szándékosan kimaradnak: ott a
       vízszintes padding nem keret-margó, hanem oszlopköz.) */
    --doboz-belso: clamp(1.05rem, 2.35vw, 2rem);

    --sidebar:   220px;  /* bal oldali nav szélessége */
    /* A hamburger ikon vonalvastagsága. Eredetileg a SZÖVEGES logó
       betűszárához volt mérve (IBM Plex Mono Regular, 0,089 em → 2,0
       képpont 1,4rem-es logónál), mert a fejlécben a kettő egymás
       mellett áll.

       A logó azóta inline SVG monogram lett, és annak KÉT vonalvastagsága
       van: a tömör K szára 5,1 képpont, a vonalas K kerete 0,7. Egyetlen
       „ugyanolyan vastag" érték tehát már nincs — a 2 képpont szándékosan
       a kettő között áll, és a monogram össz-súlyához illik. Ha a tömör
       szárhoz kell igazítani, ez az egy sor változik. */
    --logo-vonal: 2px;
    --divider:   1px solid var(--border);

    /* ── MOZGÁS: egy görbe, három tempó ──────────────────────
       Korábban tizenhat különböző időzítés volt a lapon, öt görbével
       — eseti döntések sora, nem rendszer. Monospace-nél ez feltűnőbb,
       mert a rács minden mozgást kimér: ha két szomszédos elem más
       ütemben vált, az nem árnyalat, hanem hiba.

       A tempót az dönti el, MIT csinál a mozgás:
         valasz  — amit a kéz vár: szín, opacitás, visszajelzés
         allapot — állapotváltás: keret, kiemelés, csúszó jelölő
         felulet — nagy felület: nyílás, kirajzolás, betűrajz

       A görbe egyetlen: gyors indulás, hosszú kifutás. Az oldal nem
       kapkod — a hosszabb átmenet a nézésre hív, nem a kattintásra. */
    --ease:        cubic-bezier(0.22, 0.61, 0.36, 1);
    --t-nyomas:    0.09s;   /* a lenyomás pillanata — még „azonnalinak" érződik,
                               de nincs kemény éle, amitől villanna */
    --t-valasz:    0.18s;
    --t-allapot:   0.42s;
    --t-felulet:   0.62s;

    --transition:  var(--t-allapot) var(--ease);

    /* ── KÉT szín ────────────────────────────────────────────
       A weberna.hu arculatából örökölve. Hármat próbáltunk, kettő
       maradt — és nem ízlésből: a sárga fehér háttéren 1,4:1
       kontrasztot ad, tehát vastag csíkként is olvashatatlan.

       A szereposztás egyszerű, és végig ez érvényes:
         KÉK   — a szerkezet: minden vonal, keret, sarokjel, sorszám
         BÍBOR — a kiemelés: ami a lényeg, és amit a kurzor érint

       A kék az egyetlen, ami mindkét sémán megáll (3,9 / 5,0). A
       bíbor fehéren kiváló (8,2), sötéten világosítva jó.
       ──────────────────────────────────────────────────────── */
    --brand-bibor: #8E245A;
    --brand-kek:   #208BAC;

    --szin-szerkezet: #1E7A99;   /* fehéren 4,9:1 — VONALRA */
    /* Ugyanaz a kék SZÖVEGKÉNT egy árnyalattal mélyebb: a vonal 4,9-en
       elég (küszöb 3), a felirat viszont 4,5-öt kér, és felületen a
       világosabb változat 4,10-re esne. */
    --szin-szerkezet-szoveg: #1B6E8B;
    --szin-kiemeles:  #8E245A;   /* fehéren 8,2:1 */

    /* A rács színe — a szerkezeti kékből, nagyon halkan. */
    --racs: rgba(30, 122, 153, 0.085);

    /* Vonalvastagságok. A terv vonalzóval készül: két érték van, és
       minden ezekből épül. Az első kiadás 2/3 px volt — Kristóf
       szerint „nem kivehető szemmel", ezért felment 3/5-re. Egy
       tervrajzon a vonal nem hajszál: látszania kell, hogy húzták. */
    --vonal-1: 3px;
    --vonal-2: 5px;

    /* Régi nevek, amíg a többi szabály átáll — a rétegváltó és a
       diagram-kiemelés is a kiemelő színt kapja. */
    --szin-melyseg:  var(--szin-kiemeles);
    --szin-rendszer: var(--szin-kiemeles);
    --szin-jelen:    var(--szin-szerkezet);

    /* ── A skála ─────────────────────────────────────────────
       A három szín egyetlen átmenetben, mindig ugyanabban a
       sorrendben. Egyszer telítetten (a sidebar jelében), és
       lehalkítva minden szekció-elválasztó vonalon — így a skála
       nem egy elszigetelt dísz, hanem az oldal gerincén fut végig.

       NINCS ÁTMENET. A színek tömör szakaszokban állnak egymás
       mellett, éles határral — ugyanaz az elv, mint a lekerekítés
       nélküli sarkoknál és a hajszálvonalaknál. Egy filmszalag
       kalibrációs sávja sem elmosott: külön kockák, éles vágással.

       A szegmenseket box-shadow adja, nem gradiens: egyetlen 18
       pixeles doboz, mellette két másolat eltolva. Nulla új elem,
       nulla átmenet.
       ──────────────────────────────────────────────────────── */
    --szegmens: 18px;
}

/* ── Dark mode — automatikus, device beállítás alapján ─────── */
@media (prefers-color-scheme: dark) {
    :root {
        --bg:       #0a0a0a;
        --felulet:  #1B1D1F;   /* ugyanaz a hideg hajlás, mint világosban */
        --szin-szerkezet-szoveg: #3BA6C7;   /* sötétben a vonal-kék átmegy szövegnek is */
        --fg:       #f0f0f0;
        --fg-sub:   #aaaaaa;
        --fg-muted: #888888;
        --border:   rgba(255, 255, 255, 0.09);
        --glass-bg:   rgba(10, 10, 10, 0.82);
        --glass-item: rgba(255, 255, 255, 0.09);

        /* Ugyanaz a két hue, a világosság a fekete háttérhez igazítva.
           A bíbor feketén 2,4:1 volna — világosítani kell; a kék bírja. */
        --szin-szerkezet: #3BA6C7;   /* feketén 6,8:1 */
        --szin-kiemeles:  #CF418A;   /* feketén 4,5:1 */
        --racs:           rgba(59, 166, 199, 0.11);
    }
}

/* ── Éjszaka — ugyanaz a hely, más idő ───────────────────────
   A sötét mód a KÉSZÜLÉK beállítását követi; ez a réteg a látogató
   ÓRÁJÁT. Este tíz és hajnali öt között az oldal lelassul és tompul.
   Nem másik design: ugyanaz a hely, később.

   A `data-ido="ejjel"` attribútumot a main.js teszi ki a <html>-re.
   JS nélkül nem történik semmi — a lap teljes értékű marad.

   FONTOS: a napszak SOSEM írja felül a séma-választást. Aki világos
   módot állított be a gépén, az éjjel sem kap feketét — az az ő
   döntése, nem a miénk. Világosban csak a ritmus lassul, a szín
   tompul és a szemcse erősödik; a sötétet a napszak mélyíti tovább.
   ─────────────────────────────────────────────────────────── */
:root[data-ido="ejjel"] {
    --t-nyomas:  0.12s;
    --t-valasz:  0.26s;
    --t-allapot: 0.62s;
    --t-felulet: 0.90s;
}

/* Világosban: nincs séma-váltás, csak halkul a kontraszt. */
@media (prefers-color-scheme: light) {
    :root[data-ido="ejjel"] {
        --bg:      #faf9f7;
        --fg-sub:  #565656;
        --accent:  #7a2b27;
    }
}

/* Sötétben: a napszak mélyíti, amit a séma már elkezdett. */
@media (prefers-color-scheme: dark) {
    :root[data-ido="ejjel"] {
        --bg:       #060606;
        --felulet:  #15171A;
        --fg:       #e6e6e6;
        --fg-sub:   #9a9a9a;
        --border:   rgba(255, 255, 255, 0.07);
        --glass-bg: rgba(6, 6, 6, 0.86);
        --accent:   #a8443d;
    }
}

/* ── Oldalak közti átúsztatás — natív, nulla JS ─────────────── */
@view-transition {
    navigation: auto;
}

/* ── A vágás — a keret áll, a kép cserélődik ──────────────────
   A lapváltás eddig a böngésző alapértelmezett keresztúsztatása volt,
   amiben a fix sidebar is benne úszott: a KERET villant, pedig mind a
   44 lapon bájtra ugyanaz. Nevesítve kimarad a gyökér pillanatképéből,
   tehát mozdulatlan marad — csak a kép cserélődik.

   Az átmenet RÖVID, és ennek technikai oka van, nem ízlésbeli: a
   szemcse a body::after-en ül, tehát benne van a STATIKUS pillanatképben
   — az átmenet teljes hosszán a vetítőgép befagy. Egy szemcse-ciklus
   0,5 s, ezért marad a teljes áttűnés 0,28 s-on. A lassú film nem attól
   lassú, hogy az átmenetei hosszúak, hanem hogy a gép egyenletesen jár.
   ─────────────────────────────────────────────────────────── */
:root {
    --vagas:       0.28s;   /* a két kép EGYSZERRE úszik, nem egymás után */
    --vagas-gorbe: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* Éjjel lassabb. A napszakot NEM a data-ido hozza ide: azt a defer-elt
   main.js teszi ki, ami az ÉRKEZŐ lapon később fut, mint ahogy ezek a
   szabályok feloldódnak. Ezért a RÉGI lap küldi át típusként — lásd a
   main.js pageswap-figyelőjét. */
:root:active-view-transition-type(ejjel) {
    --vagas:      0.36s;
}

/* A keret. Ez az egész lényege. */
.site-header { view-transition-name: keret; }

/* HU→EN váltásnál a keret tartalma mégis változik (más feliratok).
   Akkor is a lap ütemén cserélődjön, ne a böngésző 0,25 s-án. */
::view-transition-old(keret),
::view-transition-new(keret) {
    animation-duration:        var(--vagas);
    animation-timing-function: var(--vagas-gorbe);
}

/* A kép ÁTÚSZIK. Korábban vágás volt: a régi lap kiúszott, jött egy
   üres kocka, és utána úszott be az új. Ez szándékos filmes gesztus
   volt, de a gyakorlatban pislogásnak látszott — a lap egy pillanatra
   eltűnt a kattintás után.

   Most a böngésző saját áttűnése fut, csak a mi ütemünkön: a két kép
   EGYSZERRE úszik, nincs üres kocka. A szemcse-korlát így is áll — a
   teljes átmenet 0,28 s, egy szemcse-ciklus alatt (0,5 s), tehát a
   befagyott vetítőgép nem látszik meg. */
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration:        var(--vagas);
    animation-timing-function: var(--vagas-gorbe);
}

/* ── Szemcse — hangulat, tartalom nélkül ─────────────────────
   Egyetlen inline SVG-zaj, néhány száz bájt, nulla függőség.
   A teljes felület fölött ül, de nem fog egeret. Olyan halvány,
   hogy tudatosan alig észlelhető — csak a "sablon statikus oldal"
   érzetet veszi el. Nyomtatásban és mozgásérzékenységnél kikapcsol.

   A szemcse MOZOG: a statikus szemcse textúra, a mozgó szemcse film.
   Nyolc lépés fél másodperc alatt, steps(1) időzítéssel — így ugrik,
   nem úszik, ahogy a vetített kép. Nem a mintát cseréljük, hanem a
   pozícióját toljuk el: egy fájl elég, és a réteg a helyén marad.
   ─────────────────────────────────────────────────────────── */
/* A háttérrács kikerült (2026-07-28, Kristóf): a „terv" jelleget a
   vonalak, keretek és sarokjelek adják — a rács ehhez már fölösleges
   réteg volt. A --racs token megmarad, mert a fejmező és az adatlap
   belső elválasztói használják. */

body::after {
    content: '';
    position: fixed;
    inset: 0;
    z-index: 9999;
    pointer-events: none;
    opacity: 0.028;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: no-preference) {
    /* A szemcse szándékosan KÍVÜL van a tempó-skálán: nem átmenet, hanem
   textúra. A steps(1) attól lépdel, nem folyik — ez a filmszalag
   viselkedése, és pont ettől nem látszik CSS-animációnak. */
body::after { animation: grain 0.5s steps(1) infinite; }
}

@keyframes grain {
    0%   { background-position:   0px   0px; }
    12%  { background-position: -13px   7px; }
    25%  { background-position:   9px -17px; }
    37%  { background-position: -21px -11px; }
    50%  { background-position:  17px  13px; }
    62%  { background-position:  -7px  21px; }
    75%  { background-position:  23px  -5px; }
    87%  { background-position: -17px -23px; }
    100% { background-position:   0px   0px; }
}

@media (prefers-color-scheme: dark) {
    body::after { opacity: 0.045; }
}

/* Éjjel a szemcse erősebb — a rossz fényviszony a régi filmen is
   több zajt jelent. */
:root[data-ido="ejjel"] body::after { opacity: 0.062; }

/* ── Fokozott kontraszt ──────────────────────────────────────
   A helyes válasz a „több kontrasztot" kérésre nem mélyebb szürke,
   hanem KEVESEBB RÉTEG: a felület eltűnik, a keretek erősödnek. */
@media (prefers-contrast: more) {
    :root { --felulet: var(--bg); --border: rgba(0, 0, 0, 0.45); }
}

@media (prefers-contrast: more) and (prefers-color-scheme: dark) {
    :root { --felulet: var(--bg); --border: rgba(255, 255, 255, 0.45); }
}

/* ── Papír ──────────────────────────────────────────────────
   Ezt a lapot NYOMTATJÁK. Nem a kezdőlapot: az impresszumot és az
   adatkezelési tájékoztatót, amikből papíron jogi dokumentum lesz.
   Négy dolog romlott el nyomtatáskor, mind mérve, WebKitben, A4-en:

   1. SÖTÉT SÉMÁVAL A LAP OLVASHATATLAN. A böngésző a hátteret
      alapból nem nyomtatja — a papír fehér marad —, a szöveg viszont
      `rgb(240,240,240)` volt. Majdnem fehér szöveg fehér papíron.
      Ezért a papír MINDIG a világos séma tokenjeit kapja, akkor is,
      ha a látogató sötétben olvas.

   2. A CSUKOTT LENYÍLÓK TARTALMA ELVESZETT. A kezdőlapról 309 szó,
      egy esettanulmányról 382 — a GYIK válaszai és a technikai
      kibontások. Aki kinyomtatta, a kérdéseket kapta meg, a
      válaszokat nem.

   3. A SZAKASZOK FÉLIG ÁTTETSZŐN mentek papírra. Az előhívás
      scroll-vezérelt és `opacity: 0.48`-ról indul; papíron nincs
      görgetés, tehát mind a nyolc szakasz ott ragadt.

   4. A FIX OLDALSÁV az első lap negyedét vitte el egy kattinthatatlan
      menüre, a további lapokon pedig csak a 182 képpontos üres margó
      maradt belőle. */
@media print {
    /* 1 — a papír világos, függetlenül attól, amit a látogató lát */
    :root, :root[data-ido="ejjel"] {
        --bg:       #ffffff;
        --felulet:  #ffffff;
        --fg:       #000000;
        --fg-sub:   #333333;
        --fg-muted: #555555;
        --border:   rgba(0, 0, 0, 0.28);
        --szin-szerkezet:        #14607A;
        --szin-szerkezet-szoveg: #14607A;
        --szin-kiemeles:         #8E245A;
        --racs: transparent;
    }
    body { background: #ffffff; color: #000000; }
    body::after { display: none; }

    /* 2 — a lenyílók tartalma papírra kerül, a nyíl nem.
       A gyerekekre hiába írunk `display: block`-ot: mérve, a gyerek
       MAGA látszik (114 képpont magas, `content-visibility: visible`),
       csak épp egy rejtett tárolóban ül. Nem a gyereket kell nyitni,
       hanem a tárolót — az `::details-content` pszeudoelemet. WebKit
       26.5-ben működik. Ahol a böngésző még nem ismeri, ott figyelmen
       kívül hagyja: a lenyíló csukva marad, ahogy eddig is. */
    details::details-content {
        content-visibility: visible !important;
        display: block !important;
    }
    details summary { list-style: none; cursor: auto; }
    details summary::marker,
    details summary::-webkit-details-marker { display: none; }

    /* 3 — semmi nem marad félúton egy animációban */
    [class*="section-"], .case-diagram, .abra-mobil li, .ref-item, .doc-fact {
        opacity: 1 !important;
        transform: none !important;
        animation: none !important;
        clip-path: none !important;
    }

    /* 4 — a navigáció papíron dísz; a tartalom kapja a teljes lapot */
    .site-header, .skip-link, .nav-lang, .ref-preview { display: none !important; }
    .site-main { margin-left: 0 !important; padding-left: 0; padding-right: 0; }

    /* Oldaltörés — a címsor ne szakadjon el attól, amit bevezet */
    h1, h2, h3, h4, summary, .label { break-after: avoid; }
    tr, li, figure, blockquote, .doc-table, .case-situation, .case-diagram {
        break-inside: avoid;
    }
    p { orphans: 3; widows: 3; }

    /* A KÜLSŐ hivatkozás papíron cím nélkül értelmetlen — a belső nem,
       azt a látogató a saját lapján találja meg. Ezért csak a kifelé
       mutatók kapják meg a címüket. */
    main a[href^="http"]::after {
        content: " (" attr(href) ")";
        font-size: 0.82em;
        color: #555555;
        overflow-wrap: anywhere;
    }
}

/* ── Base ───────────────────────────────────────────────────── */
html {
    /* A gyökér betűméret 16 pixel marad egészen 1900-ig — ez a lap
       alaptempója, és minden rem-érték ebből származik. Az előző kísérlet
       (clamp 0,62vw-vel) már 1280 pixelen 20-ra vitte, ami az EGÉSZ lapot
       negyedével felnagyította: nem reszponzivitás volt, hanem nagyítás.

       Növekedés csak ott, ahol tényleg indokolt: 1900 pixel felett a
       nézőtávolság is nő, ott a 17-18 pixel olvashatóbb. A felső határ
       szándékosan alacsony. */
    font-size: 16px;
    scroll-behavior: smooth;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;

    /* Az iOS Safari „text autosizing"-ja alapból BEKAPCSOLVA van, és a
       szöveget a saját ítélete szerint felnagyítja — blokkonként,
       eltérő mértékben. A dobozok, a rácsrések és a rajzok NEM nőnek
       vele: csak a betű. Egy szoros elrendezésben ettől a szöveg
       kifut a helyéről, és rácsúszik arra, ami mellette van.
       Ez a lap tetején a legérzékenyebb: a cím `line-height: 1`-gyel
       áll, tehát a betű már alapból öt-nyolc képponttal a saját során
       KÍVÜLRE rajzolódik, a portré aljáig pedig csak 24-28 képpont a
       tartalék — mérve, három eszközméreten.

       A `100%` nem a nagyítást tiltja: a látogató oldalnagyítása
       (Safari „aA" menü) és a rendszerszintű szövegméret továbbra is
       hat. Csak azt kapcsolja ki, hogy a böngésző MAGÁTÓL, kérés
       nélkül írja felül a tervezett méretet. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
}

/* ── Vízszintes túlcsordulás elleni két alapszabály ───────────
   Ez a kettő együtt oldott meg egy 280 pixeles kijelzőn jelentkező
   hibát, ami a lapot vízszintesen görgethetővé tette.

   (1) A rács- és flex-elemek alapértelmezett `min-width: auto`-ja azt
   jelenti, hogy nem zsugorodnak a tartalmuk MINIMÁLIS szélessége alá.
   Egyetlen hosszú szó — e-mail-cím, webcím, összetett szó — így
   kifeszíti a rácsot a szülőjén túl, és onnantól az egész dokumentum
   szélesebb a képernyőnél. A `min-width: 0` engedi a zsugorodást.

   (2) A hosszú szó ettől még kilógna a saját sorából; az
   `overflow-wrap` engedélyezi a törést ott, ahol nincs szóköz.
   A `break-word` csak akkor tör, ha muszáj — a normál tördelést nem
   írja felül. */
:where(.about-grid, .hero-grid, .service-item, .ref-item, .ref-list,
       .testimonial-grid, /* ── A GALÉRIA JELENLEG NEM HASZNÁLT ─────────────────────────
   2026-08-04: az esettanulmányokból kikerültek a képek — Kristóf
   maga készíti újra őket, és a kísérőszöveget együtt írjuk meg.
   A stílus SZÁNDÉKOSAN itt marad: a galéria vissza fog jönni, és
   a törlés–visszaírás csak zaj lenne. A régi képek megvannak a
   `forras/eset-kepek/` alatt — nem a `src/`-ben, tehát nem kerülnek ki.
   ─────────────────────────────────────────────────────────── */
.case-galeria-racs, .doc-facts div,
       .faq-item, .case-next) > * {
    min-width: 0;
}

/* A LÁBLÉC szándékosan kimarad a fenti listából. Ott a három blokk
   (copyright · rovatlinkek · nyilvántartási szám) egy sorban áll, és a
   `min-width: 0` engedné őket a saját tartalmuk alá zsugorodni — ettől
   tört két-három sorba mindegyik, pedig bőven volt hely. Itt épp az
   ellenkezője kell: a blokkok NE essenek szét, a lábléc pedig inkább
   csomagoljon, ha tényleg elfogy a hely. */
.site-footer {
    flex-wrap: wrap;
    column-gap: var(--space-4);
}

/* A `max-content` egymagában TÚLLŐ: a linksor max-content szélessége
   telefonon 425 px volt egy 375 pixeles kijelzőn, és ettől lett az egész
   lap oldalra húzható — a lábléc, nem az ábrák. A `min()` megtartja a
   „ne törj feleslegesen" viselkedést, de a szülő szélességénél megállítja.
   A linksor pedig kifejezetten tördelendő elem: neki nulla a minimuma. */
.site-footer > * { min-width: min(100%, max-content); }
.site-footer > .footer-links { min-width: 0; }

/* Asztali meret: a copyright marad elol, ahogy eddig is volt - a
   dokumentum-sorrendet a MOBIL igenye dontotte el (ott a rovat-linkek
   jonnek eloszor, mert azok visznek tovabb a lapon; az alairas legalul
   zar). Ezt itt egyetlen `order` forditja vissza, markup nelkul. */
/* A hatar 1024 es nem 700: harom csoport egy sorban kb. 684 kepponot ker,
   es az oldalsav plusz a margok levonasa utan ennyi csak 1010 pixel folott
   marad. Alatta a lablec harom savba rendezodik, ott pedig az alairas
   ALUL a helyes - tehat ott nem szabad elorehozni. */
@media (min-width: 1024px) {
    .site-footer > .footer-copy { order: -1; }
}

.footer-links {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem var(--space-2);
    justify-content: center;
}

/* A lábléc egésze nagybetűs, az aláírás viszont nem: ott saját név áll,
   és a nagybetűsítés a „Kristóf" ékezeteit is átírja — a KRISTÓF sor
   kiabál, miközben a lábléc a leghalkabb eleme a lapnak. A rovatlinkek
   és a nyilvántartási szám maradnak nagybetűsek, azok címkék. */
.footer-copy {
    text-transform: none;
    letter-spacing: 0.01em;
}

body {
    overflow-wrap: break-word;
}

/* ── Görgethető sávok: a görgetés NEM láncolódik tovább ───────
   Az ábra, a táblázat és a kódblokk vízszintesen görgethető sáv. Érintőn
   ezek végén a böngésző alapból TOVÁBBADJA a mozdulatot a lapnak — a
   látogató végighúzza az ábrát, és a lendület a lapot rántja oldalra.
   Kívülről ez pontosan úgy néz ki, mintha az egész oldal görgethető
   lenne vízszintesen; az `overflow-x: clip` sem véd ellene, mert az a
   MÉRETET korlátozza, nem a gesztust.

   A `contain` a sáv határánál megállítja a láncot: ami a sávban indul,
   a sávban is marad. Függőlegesen viszont nem szabad megfogni — az
   ujj gyakran az ábrán keresztül görgeti a lapot lefelé. */
.case-diagram,
.doc-table-wrap,
.case-code pre,
.case-proof pre {
    overscroll-behavior-x: contain;
}

/* ── Kódblokk: tördelünk, nem görgetünk ─────────────────────
   A `pre-wrap` a MEGŐRZÖTT szóközöknél tör — a shell-parancsok és a PHP
   tele vannak velük, tehát a törés a legtöbb sornál természetes helyre
   esik. Az `anywhere` csak a szóköz nélküli, sávnál hosszabb tokent
   bontja meg.

   `clip` és nem `auto`: az `auto` néma visszaesést engedne, egy jövőbeli
   hosszú token újra görgethetővé tenné a sávot. A `clip` nem hoz létre
   görgetési kontextust, és a tördelés miatt sosem vág le semmit.

   A `letter-spacing` a `.doc-body`-ból öröklődne — display-tracking a
   kódban 12,8 képpanton rontja az 1/l és a ./, megkülönböztetését. */
.case-code pre,
.case-proof pre {
    overflow-x: clip;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    letter-spacing: normal;
    hyphens: none;
}

/* És látszódjon is, hogy van még: a görgetősáv a lap saját színeivel,
   vékonyan. Árnyékkal is meg lehetne oldani („scroll shadow"), de ezen
   a lapon sehol nincs árnyék — egy lágy szürke sáv idegen test volna.
   A sávot viszont maga a rendszer rajzolja, és a színe a mienk. */
.case-diagram,
.doc-table-wrap,
.case-code pre,
.case-proof pre {
    scrollbar-width: thin;
    scrollbar-color: var(--szin-szerkezet) transparent;
}

/* ── Vízszintes görgetés: sehol, semmilyen méreten ────────────
   Az `overflow-x: clip` a `hidden`-nel szemben NEM hoz létre görgetési
   kontextust, tehát a `position: sticky` és a horgony-ugrás megmarad —
   csak épp nincs mit oldalra húzni. A html ÉS a body is megkapja: egyedül
   a html-en a böngészők egy része a body-ra propagálja és elveszti. */
html, body {
    overflow-x: clip;
    max-width: 100%;
}

/* Nagyon nagy kijelzőn a nézőtávolság is nő — csak ITT emelünk, és keveset. */
@media (min-width: 1900px) { html { font-size: 17px; } }
@media (min-width: 2560px) { html { font-size: 18px; } }

body {
    font-family: var(--font);
    background-color: var(--bg);
    color: var(--fg);
    line-height: 1.6;
    min-height: 100vh;
}

a {
    color: inherit;
    text-decoration: none;
    /* A hover nem csak az átlátszóságot mozgatja: a törzsszöveg linkjei
       SZÍNT és ALÁHÚZÁS-SZÍNT is váltanak (.doc-body a, .faq-a a,
       .doc-toc a, .shift-cta, .case-next-mail). Ezek eddig kimaradtak a
       listából, tehát átmenet nélkül ugrottak — a lap leggyakoribb
       interakciója volt az egyetlen, ami nem a lap óráján futott. */
    transition: opacity var(--t-valasz) var(--ease),
                color var(--t-valasz) var(--ease),
                border-bottom-color var(--t-valasz) var(--ease);
}
a:hover { opacity: 0.45; }

img { max-width: 100%; display: block; }

/* Fókusz — billentyűzetes navigációhoz látható, egérrel nem */
:focus-visible {
    outline: 2px solid var(--fg);
    outline-offset: 3px;
}

/* Ugrás a tartalomra — képernyőolvasónak és Tab-nak */
.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 999;
    padding: var(--space-2) var(--space-3);
    background: var(--bg);
    border: var(--divider);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.skip-link:focus { left: var(--space-2); top: var(--space-2); }

/* ── Utility ────────────────────────────────────────────────── */
.text-muted { color: var(--fg-muted); }

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* Kis uppercase label — szekciók felett */
/* A szekciócímke a terven egy JELÖLÉS: kék, és mérővonal fut mellette
   a sor végéig — mint a rajzon a méretezés. A vonal a maradék helyet
   tölti ki, tehát magától igazodik a címke hosszához. */
.label {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    /* A sáv tartalmazhat hivatkozást is („Műhely · vissza a rovathoz").
       Wrap nélkül a kettő egy sorba kényszerül: 320 képpontnál 200%-os
       szöveg-nagyítással a hivatkozás tizenhat képponttal kilógott a
       képernyőből — mérve, WebKitben, csak az ANGOL lapokon, mert a
       „back to the section" hosszabb a magyar megfelelőjénél.
       A `min-width: 0` nem jó megoldás rá: azzal a hivatkozás
       harmincöt képpontra préselődik és betűnként tördel. */
    flex-wrap: wrap;
    row-gap: 0.15rem;
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--szin-szerkezet-szoveg);
}

.label::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--szin-szerkezet);
    opacity: 0.35;
}

/* ────────────────────────────────────────────────────────────
   SIDEBAR NAV
   ─────────────────────────────────────────────────────────── */
.site-header {
    position: fixed;
    top: 0; left: 0; bottom: 0;
    width: var(--sidebar);
    z-index: 100;
    display: flex;
    flex-direction: column;
    padding: var(--nav-pad) var(--margo-szuk);
    /* VÉGÁLLÁS, nem a normál működés. A `--nav-*` térközök 560 képpontos
       ablakig kiférnek; ez alatt (nagyon alacsony ablak, felnagyított
       rendszerbetű, 200%-os page zoom) már a betűk maguk nem férnek el, és
       azokat nem szabad zsugorítani. Ilyenkor a menü görgethető — nem szép,
       de mindig elérhető. Az `overscroll-behavior` tartja, hogy a görgetés
       ne folytatódjon a lap törzsében, amikor a menü végére ér. */
    overflow-y: auto;
    overscroll-behavior: contain;
    scrollbar-width: thin;
    /* Apple liquid glass */
    background: var(--glass-bg);
    backdrop-filter: var(--glass-blur);
    -webkit-backdrop-filter: var(--glass-blur);
    border-right: var(--divider);
}

/* A logó inline SVG, nem szöveg: a currentColor miatt a világos és a
   sötét mód magától helyes, és nincs érte külön hálózati kérés. A
   betűbeállítások azért maradnak, mert a jel MELLETT a link szöveges
   tartalma (a képernyőolvasónak szánt aria-label) is ide öröklődne, ha
   valaha visszakerülne. */
.nav-logo {
    display: inline-block;
    font-family: var(--font-display);
    font-size: 1.4rem;
    letter-spacing: 0.06em;
    line-height: 1;
    margin-bottom: var(--nav-logo);
    color: var(--fg);
}

/* A magasság a régi „KK" nagybetű-magasságához igazodik (1,4rem Bebas
   ≈ 1,02rem cap height), hogy a jel ugyanakkora optikai súllyal üljön a
   sarokban, mint a szöveg tette. A szélesség ebből adódik: a jel aránya
   1,86 : 1, tehát ~1,9rem — bőven belefér a 180 pixeles oldalsávba is. */
/* A negatív jelnél a MEZŐ magassága a mérvadó, nem a betűké: a
   monogram a jel magasságának 84%-át tölti ki, a többi a körülötte
   futó keret. Ezért 1,21rem — így a betűk maguk ugyanakkorák
   maradnak (1,02rem), mint a korábbi nyitott jelnél és a szöveges
   „KK"-nál voltak. Enélkül a logó optikailag zsugorodna. */
.nav-logo .kk-mark {
    display: block;
    /* A monogram a lap egyetlen márkajele — 1,21rem-en alig volt nagyobb
       a menüpontok betűjénél. Arányos érték: a keskeny mobilsávon is
       elfér (56 képpontos fejléc), asztalin pedig végre jel, nem lábjegyzet. */
    height: clamp(1.7rem, 2.6vw, 2.4rem);
    width: auto;
    overflow: visible;
}

.site-nav {
    display: flex;
    flex-direction: column;
    flex: 1;
    /* A flex-elemek alapból nem mennek a saját `min-content` magasságuk
       alá. Enélkül a nav akkor is a teljes tartalmát kérné, ha nincs rá
       hely — és így a benne lévő lista `overflow`-ja sosem lépne
       működésbe: a fejléc görögne helyette, a nyelvváltóval együtt. */
    min-height: 0;
    position: relative; /* szükséges a sliding highlight-hoz */
}

/* Sidebar alján — nyelvváltó + copy-email gomb */
.nav-bottom {
    margin-top: auto;
    padding-top: var(--nav-valt);
    /* NINCS elválasztó vonal. Az Írások/Műhely csoport fölött már fut
       egy hajszálvonal; egy másodikat közvetlenül alá tenni két vonalat
       ad száz képponton belül, ráadásul a kétszínű jel is elválaszt.
       Egy jel elég egy határhoz. */
    display: flex;
    flex-direction: column;
    gap: var(--nav-koz);
}

/* ── Színjel — a három szín egy helyen ───────────────────────
   A filmtekercs elején fut egy színkalibrációs sáv: nem a filmhez
   tartozik, hanem ahhoz, aki vetíti. Ez ugyanaz — szakmai jel, nem
   dísz, és jól megfér a szemcsével, ami szintén a filmből jön.

   A három szín a weberna.hu arculatából érkezik: itt jelennek meg
   telített értéken, egymás mellett, egyetlen 54 pixeles vonalban.
   Máshol az oldalon már csak külön-külön, jelentéssel.

   Pszeudoelem, tehát NULLA HTML-változás — a sidebar mind a
   negyvennégy lapon ott van, a jel velük együtt jelenik meg.
   ─────────────────────────────────────────────────────────── */
.nav-bottom::before {
    content: '';
    display: block;
    width: calc(var(--szegmens) * 2);
    height: var(--vonal-2);
    margin-bottom: var(--space-1);
    /* Két tömör szakasz, éles határral — NEM átmenet. Egyetlen doboz
       plusz egy box-shadow-másolat. Kék a szerkezet, bíbor a
       kiemelés: ugyanaz a szereposztás, mint mindenhol máshol. */
    background: var(--szin-szerkezet);
    box-shadow: calc(var(--szegmens) * 2) 0 0 var(--szin-kiemeles);
}

/* A jel SZÁNDÉKOSAN nem mozdul és nem reagál a kurzorra. Egy
   kalibrációs sáv sem villog: ott van, és kész. A mozgás elvonná a
   figyelmet arról, amiért a látogató jött.

   EGY kivétel: az első betöltéskor felépül — lásd a lap alján, a
   „VETÍTÉSINDÍTÁS" szakaszban. Egyszer, 0,6 másodperc, aztán soha. */

/* Közös mikro-tipográfia a sidebar aljára */
.copy-email,
.nav-lang {
    font-family: var(--font);
    font-size: 0.65rem;
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

/* „Email" — asztali oldalsávban kattintásra MÁSOL, a szöveg „Másolva"-ra
   vált; mobilon sima mailto-link. A jelölés mindkét esetben ugyanaz az
   `<a href="mailto:…">`, tehát JS nélkül is működik: a levelező megnyílik.
   Korábban `<button>` volt, ami JS nélkül semmit nem csinált. */
.copy-email {
    display: block;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    text-decoration: none;
    /* opacity transition a fade-in/out szövegváltáshoz */
    transition: color var(--transition), opacity var(--t-valasz) var(--ease);
    text-align: left;
}

.copy-email:hover { color: var(--fg); }

/* Nyelvváltó — HU / EN */
.nav-lang {
    display: flex;
    gap: var(--space-1);
    align-items: center;
}

.nav-lang a { transition: color var(--transition); }
.nav-lang a:hover { color: var(--fg); opacity: 1; }
.nav-lang [aria-current="true"] { color: var(--fg); }
.nav-lang .sep { color: var(--border); }

/* Hamburger — csak mobilon látszik */
.nav-toggle { display: none; }

/* ── Sidebar nav linkek + csúszó glass highlight ────────────── */
.site-nav ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--nav-koz);
    flex: 1;
}

/* HA GÖRGETNI KELL, A MENÜPONTOK GÖRÖGNEK — nem az egész oldalsáv.

   Ez az egyetlen oka annak, hogy a két lista körül van egy doboz: CSS-sel
   testvéreket nem lehet közös görgő területbe fogni, márpedig pont az
   kell. A nyelvváltó és az Email a dobozon KÍVÜL marad, tehát mindig a
   helyén van; ami elfogy, az a menüpontokból fogy, és azok görgethetők.

   Előbb a felső lista görgetésével próbáltam, doboz nélkül: 200%-os
   szöveg-nagyításnál elhasalt. Ott már a Referenciák–Írások–Műhely
   csoport sem fér ki, az viszont nem tudott görögni, tehát felcsúszott a
   panel alja mögé. Egy görgő terület kell, nem kettő.

   A `min-height: 0` nélkül a flex-elem nem megy a saját tartalma alá,
   tehát az `overflow` sosem lépne működésbe. A `4.5rem` alsó korlát
   tartja, hogy fekvő tájolásban se olvadjon el a lista. */
.nav-gorgo {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: min(4.5rem, 100%);
    overflow-y: auto;
    overscroll-behavior: contain;
}

/* ── A menü két fele ─────────────────────────────────────────
   A FELSŐ öt pont horgony: mindegyikhez tartozik egy kezdőlapi szekció,
   és minden ilyen szekció átvezet a saját, bővített lapjára. A látogató
   így egyetlen lapon átfutja a lényeget, és csak ott megy tovább, ahol
   tényleg többet akar tudni.

   Az ALSÓ három pont külön lapra visz, mert nincs kezdőlapi falatuk. A
   két rovathoz — Írások, Műhely — cikklista tartozik, azt nem érdemes a
   kezdőlapra másolni. A Referenciák pedig azért nem kaphat kezdőlapi
   szekciót, mert ott az ÜGYFÉLNEVEK szerepelnének: azok szándékosan
   csak a referencialapon állnak, különben a kezdőlap kezdene rangsorolni
   az ügyfelek saját brandnevére. A check.sh 9. szakasza ezt őrzi.

   A választóvonal tehát nem stílus, hanem jelentés: fölötte ami itt
   folytatódik, alatta ami máshol. */
.site-nav .nav-lapok {
    flex: 0 0 auto;
    margin-top: var(--nav-valt);
    padding-top: var(--nav-valt);
    border-top: var(--divider);
    gap: var(--nav-jel);
}

.site-nav li a[aria-current="page"] { color: var(--fg); }

.site-nav li {
    position: relative;
    z-index: 1;
}

.site-nav li a {
    display: block;
    padding: 0.3rem 0.55rem;
    margin: 0 -0.55rem;
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-muted);
    transition: color var(--transition);
}

.site-nav li:hover a {
    color: var(--fg);
    opacity: 1;    /* globális a:hover opacity felülírása */
}

/* A JS által létrehozott csúszó glass highlight elem */
.nav-highlight {
    position: absolute;
    /* A sidebar paddingjának kompenzálása, hogy a kiemelés a sáv teljes
       szélességét lefedje. Ennek EGYÜTT kell mozognia a paddinggel —
       amíg fix -1,5rem volt, addig arányos paddingnál elcsúszott. */
    left: calc(-1 * var(--margo-szuk));
    right: calc(-1 * var(--margo-szuk));
    background: var(--glass-item);
    backdrop-filter: saturate(140%) blur(6px);
    -webkit-backdrop-filter: saturate(140%) blur(6px);
    opacity: 0;
    pointer-events: none;
    z-index: 0;
    /* Smooth slide — cubic-bezier az iOS-szerű érzésért */
    transition: top var(--t-valasz) var(--ease),
                height var(--t-valasz) var(--ease),
                opacity var(--t-valasz) var(--ease);
}

/* A jelölővonal KÉT ÜTEMBEN érkezik — ez a mozdulat lényege.
   A szürke sáv csúszik, és amikor megérkezett, a bíbor vonal utána rajzolódik
   fel, fentről lefelé. Egy tervrajzon is ez a sorrend: előbb a vonalzó áll a
   helyére, aztán jön a ceruza.

   Miért pszeudoelem és nem border: a border-left színe animálható, a
   HOSSZA nem. A kirajzolódáshoz saját elem kell, amit a transform-origin
   mentén skálázni lehet — és a transform ráadásul nem kényszerít
   újratördelést, tehát a mozdulat a kompozitor rétegében marad. */
.nav-highlight::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--vonal-1);
    background: var(--szin-kiemeles);
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform var(--t-valasz) var(--ease) 0.06s;
}

/* Csak akkor rajzolódik ki, ha a sáv maga is látszik. Enélkül a vonal a
   rejtett sávon is felfutna, és a következő megjelenéskor már ott állna —
   a kétütemű mozdulat épp ettől veszne el.

   Az osztályt a JS teszi rá, nem a :hover dönti el. Így a vonal állapota
   azt követi, ami a sávval TÉNYLEGESEN történik, nem azt, hogy a kurzor
   éppen a nav fölött van-e — a kettő nem mindig ugyanaz (billentyűzetes
   navigáció, érintés utáni maradék hover, szintetikus esemény). */
.nav-highlight.is-lathato::before { transform: scaleY(1); }


/* ── A menüpont felirata hoverkor ────────────────────────────
   A betűköz egy hajszálnyit nyílik. Ez a mérnöki feliratok nyelve: egy
   tervrajzon a kiemelt megnevezés nem nagyobb betűvel van szedve, hanem
   ritkítva. Az érték szándékosan alig érzékelhető — nem effekt akar lenni,
   hanem annyi, amennyitől a sor „élesbe kapcsol".

   Azért nem font-weight vagy font-size: mindkettő ÚJRATÖRDELÉST okozna, és
   a menüpont beleugrana a következő sorba. A letter-spacing is szélesít, de
   a sáv fix szélességű, tehát nem mozdul el tőle semmi. */
.site-nav ul li a {
    transition: color var(--t-valasz) var(--ease),
                opacity var(--t-valasz) var(--ease),
                letter-spacing var(--t-valasz) var(--ease);
}

.site-nav ul li:hover a { letter-spacing: 0.105em; }

/* ── Galériaképek megjelenése ────────────────────────────────
   A lusta töltésű kép addig üres helyet foglal, aztán egyszerre ott van.
   Ez a legkeményebb váltás egy lapon: nulláról teljes kontrasztra, átmenet
   nélkül. A `content-visibility: auto` mellett a fade adja meg neki azt a
   pillanatot, amitől érkezésnek látszik, nem villanásnak. */
.case-galeria-elem img {
    animation: kep-erkezik var(--t-lassu, 0.5s) var(--ease) both;
}

@keyframes kep-erkezik {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Mobilon ne legyen highlight */
@media (max-width: 700px) {
    .nav-highlight { display: none; }
}


/* ── Érintési célpontok ──────────────────────────────────────
   A WCAG 2.2 (2.5.8) minimuma 24×24 CSS-pixel. A szövegfolyamba ágyazott
   hivatkozás kivétel — a nyelvváltó és a lábléc viszont nem az, és mérve
   17 és 21 pixel magas volt.

   A megoldás layout-semleges: a függőleges padding megnöveli a kattintható
   területet, az azonos mértékű negatív margó pedig visszaveszi a helyet,
   amit elfoglalna. A lap ettől nem mozdul, az ujj viszont célt talál. */
/* A célterületet PSZEUDOELEM adja, nem padding. A padding+negatív margó
   trükk elsőre kézenfekvő, de a `margin-block` felülírja az elem saját
   margóit — a sidebar logója ettől ráült a menüre, a lábléc linkjei pedig
   két sorba törtek. Egy abszolút pozicionált ::after viszont KÍVÜL van a
   folyamon: megnöveli a kattintható felületet anélkül, hogy egyetlen
   pixelnyit is mozdítana az elrendezésen. */
/* A logó NEM halványodik hoverre. Végigmérve nem mozdul, nem
   raszterizálódik újra és nem veszít szerkezetet — de az 55%-os
   fényességesés magán a márkajelen nyugtalanságnak olvasódik. Egy
   szövegbeli link halványodhat; a lap egyetlen jele ne viselkedjen
   úgy, mint egy link a bekezdésben. A kattinthatóságot a kurzor
   mutatja, a billentyűs fókuszt a fókuszgyűrű. */
.nav-logo:hover { opacity: 1; }

.nav-lang a,
.footer-links a,
.nav-logo {
    position: relative;
}

/* Érintőcél-minimum. A WCAG 2.2 (2.5.8) huszonnégy képpontot kér mindkét
   irányban; mérve a lábléc-linkek 21, az e-mail-cím 20 képpont magas volt.
   A `min-height` a DOBOZT növeli, a `inline-flex` pedig a szöveget középen
   tartja, tehát a sorköz és az elrendezés nem változik tőle. */
.footer-links a,
.contact-email,
.copy-email,
.nav-lang a,
.doc-back a,
.case-next-mail,
.label a {
    min-height: 24px;
    display: inline-flex;
    align-items: center;
}

/* A nyelvváltó két betűje önmagában 15 képpont széles — a szélességet
   is meg kell adni, nem csak a magasságot. A `::after` hitbox eddig is
   nagyobb volt nála, de a szabvány a LÁTHATÓ célra vonatkozik. */
.nav-lang a { min-width: 24px; justify-content: center; }

.nav-lang a::after,
.footer-links a::after,
.nav-logo::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: max(100%, 24px);
    height: max(100%, 24px);
}

/* ────────────────────────────────────────────────────────────
   MAIN CONTENT
   ─────────────────────────────────────────────────────────── */
.site-main {
    margin-left: var(--sidebar);
    /* Az oldalmargó ITT dől el, egy helyen, az egész lapra. A .container a
       sectionök osztálya, tehát ha a padding rajta ülne, minden szekció
       külön hordozná — és bármelyik kifelejtése néma törést okozna. */
    padding-inline: var(--margo);
    flex: 1;
    min-width: 0;
}

.container {
    width: 100%;
    /* 880 volt. Monospace-ben a hero-cím a saját oszlopához méretezi magát
       (11,5cqw), tehát a keret szélessége közvetlenül a névre fordul: 880-nál
       47 pixel, 980-nál 53. A 1440-es kijelzőn az oldalmargó így 170-ről
       120-ra csökken — az üresség eddig több helyet vitt, mint a tartalom. */
    max-width: 980px;
    /* Padding nincs: a szélső margót a .site-main adja (--margo). Így a bal
       és a jobb oldal ugyanabból az egy értékből származik, és nem tud
       szétcsúszni. Széles kijelzőn a max-width + auto margó veszi át. */
    margin: 0 auto;
}

/* ── Szekciók közös padding + felső vonal ───────────────────── */
.section-hero,
.section-about,
.section-services,
.section-process,
.section-refs,
.section-testimonials,
.section-contact {
    padding: var(--space-8) 0;
}

/* ── Szekcióhatár — vastag, kétszínű ─────────────────────────
   A hajszálvonal helyére 2 pixeles kék sáv kerül, a bal végén egy
   84 pixeles bíbor szakasszal. Ez a lap gerince: a kék a szerkezet,
   a bíbor a kezdet jelölése — mint a méretvonal végén a nyíl.

   A bíbor szakasz szekciónként oldalt vált (bal, jobb, bal…), így
   a lap ritmust kap anélkül, hogy bármi újat hozzáadnánk. A vonal
   maga végig ugyanaz.

   És megmozdul: a sáv akkor húzódik ki, amikor a szekció a nézetbe
   ér. Görgetés-vezérelt, tehát a látogató tempójában — nem magától
   indul, nem ismétlődik.
   ─────────────────────────────────────────────────────────── */
.section-about,
.section-services,
.section-process,
.section-refs,
.section-shift,
.section-testimonials,
.section-contact,
.section-faq {
    border-top: none;
    position: relative;
}

.section-about::before,
.section-services::before,
.section-process::before,
.section-refs::before,
.section-shift::before,
.section-testimonials::before,
.section-contact::before,
.section-faq::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--vonal-1);
    background: var(--szin-szerkezet);
    transform-origin: left center;
}

/* A bíbor kezdőszakasz — a méretvonal vége. Külön pszeudoelem, mert
   a színsáv teljes szélességű, ez pedig csak a szélén ül. */
.section-about::after,
.section-services::after,
.section-process::after,
.section-refs::after,
.section-shift::after,
.section-testimonials::after,
.section-contact::after,
.section-faq::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 84px;
    height: var(--vonal-1);
    background: var(--szin-kiemeles);
}

/* Váltakozva a másik oldalra — ettől lesz ritmusa a lapnak. */
.section-services::after,
.section-refs::after,
.section-testimonials::after,
.section-contact::after { left: auto; right: 0; }

/* A kirajzolódás. Csak ott, ahol a böngésző tudja, és csak ha a
   látogató nem kérte a mozgás mellőzését. Enélkül a szakasz
   egyszerűen ott van — semmi nem vész el. */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        html.js-anim .section-about::before,
        html.js-anim .section-services::before,
        html.js-anim .section-process::before,
        html.js-anim .section-refs::before,
        html.js-anim .section-shift::before,
        html.js-anim .section-testimonials::before,
        html.js-anim .section-contact::before,
        html.js-anim .section-faq::before {
            animation: szakasz-kirajzol linear both;
            animation-timeline: view();
            animation-range: entry 0% entry 30%;
        }
    }
}

@keyframes szakasz-kirajzol {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}

/* ── Ritmus — nem minden szekció egyforma ────────────────────
   Kilenc szekció azonos magassággal egyenletes, tehát unalmas. A
   lassú film attól működik, hogy a hosszú beállításokat rövidek
   szakítják meg. Semmi új elem itt — csak a levegő variálása.

   Lélegzik:  Referenciák, Kapcsolat — itt megáll az olvasó
   Sűrű:      Szolgáltatások, Munka menete — listák, gyorsan futnak
   ─────────────────────────────────────────────────────────── */
.section-refs,
.section-contact  { padding: calc(var(--space-8) * 1.55) 0; }

.section-services,
.section-process  { padding: calc(var(--space-8) * 0.55) 0; }

.section-shift    { padding: calc(var(--space-8) * 1.2) 0; }

/* ── Az ábrák mobil párja: lista, nem rajz ───────────────────
   A rendszerábrák viewBox-a 700 egység széles. Telefonon (335 képpont)
   ez 0,48-as lépték, tehát a 13 pixeles felirat 6,2 képpontként jelenne
   meg. A kerülőút eddig az volt, hogy az ábra megtartja a léptékét és a
   sáv vízszintesen görgethető — csakhogy egy ábrát oldalra húzogatni
   ugyanolyan rossz: a szem elveszti az összefüggést, és a lap úgy
   viselkedik, mintha vízszintesen görgethető volna.

   A harmadik út az, hogy telefonon ugyanaz a tartalom LISTA: ott a
   szöveg tördelhető, tehát nincs se görgetés, se zsugorítás. A blokkokat
   a `tools/abra-lista.py` generálja MAGÁBÓL az SVG-ből, tehát a két
   megjelenés nem tud szétcsúszni; a `check.sh` 19. szakasza őrzi.

   HÁROM elrendezés van, mert három dolgot állítanak az ábrák:
     · `abra-lanc`   — SORREND: egyik lépés a másik után (számozott)
     · `abra-halmaz` — EGYIDEJŰSÉG: több elem egy közös pont körül
                       (szándékosan számozatlan; a sorszám itt hamis
                       sorrendet állítana)
     · `abra-paros`  — SZEMBEÁLLÍTÁS: soronkénti megfeleltetés

   A két megjelenés közül mindig pontosan egy van a lapon; a másik
   `display: none`, tehát a képernyőolvasó sem mondja el kétszer. */
.abra-mobil { display: none; }

/* A záró jegyzet a mobil blokk RÉSZE, csak nem a listán belül áll — a
   `display: none` tehát nem érte el, és asztali méreten a rajz ALATT
   jelent meg egy magyarázó sor, ami ott fölösleges: azt a rajz maga
   mondja el. Ugyanaz a kapcsoló viszi, mint a listát. */
.fl-jegyzet { display: none; }

@media (max-width: 700px) {
    /* Csak azt a rajzot rejtjük el, amelyiknek VAN mobil párja. Ahol a
       lista nem készült el (a két olyan ábra, amin nincs is felirat),
       ott a rajz marad — kevesebb tartalom sehol nem lesz. */
    .case-diagram:has(+ .abra-mobil) { display: none; }

    .fl-jegyzet { display: block; }

    .abra-mobil {
        display: block;
        margin: var(--space-4) 0 var(--space-4);
        padding: 0;
        list-style: none;
        border-top: var(--divider);
    }

    /* Közös sor-anatómia mindhárom elrendezésre. Ugyanaz, mint a
       szolgáltatás- és a referencia-listánál: bal oldalon fix hely a
       jelzővonalnak, mellette a sorszám oszlopa, jobbra a szöveg. */
    /* A rács-elemek alapértelmezett `min-width: auto`-ja nem engedi a
       tartalmat a saját min-content mérete alá — nagyításon ezért lógott
       ki a `.fl-cim` és a `.fl-sub` (mérve: 205 képpont egy 295-ösben).
       A `minmax(0, 1fr)` ezt oldja fel, a `2.25rem` oszlop pedig `min()`-nel
       nem nő el a szöveg-nagyítással. */
    /* `anywhere`, nem `break-word`: az utóbbi NEM csökkenti a min-content
       méretet, csak a tényleges tördelést engedi — a rács ezért továbbra
       is a leghosszabb szó szélességével számol, és kilóg. Mérve 320
       képponton, 200%-on: a „másodpercekkel" szó vitte ki a sort. */
    .abra-lanc li > *,
    .abra-lanc-ag li > *,
    .abra-halmaz li > *,
    .abra-paros dd > *,
    .abra-mobil li > *,
    .abra-mobil dd > * { min-width: 0; overflow-wrap: anywhere; }

    .abra-mobil li,
    .abra-mobil dd { min-width: 0; }

    .abra-lanc li,
    .abra-halmaz li,
    .abra-paros dd {
        position: relative;
        display: grid;
        grid-template-columns: min(2.25rem, 15%) minmax(0, 1fr);
        column-gap: var(--space-2);
        row-gap: 0.3rem;
        margin: 0;
        padding: var(--space-2) 0 var(--space-2) var(--space-3);
        border-bottom: var(--divider);
    }

    /* Sorszám nélküli elrendezésben nincs mit tartani az első oszlopban. */
    .abra-halmaz li,
    .abra-paros dd { grid-template-columns: 1fr; }

    .abra-lanc li::before,
    .abra-halmaz li::before,
    .abra-paros dd::before {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        width: var(--vonal-1);
        background: var(--szin-szerkezet);
        opacity: 0.5;
    }

    /* Amelyik doboz a rajzon kiemelt, az itt is az. */
    .abra-lanc li.is-strong::before,
    .abra-halmaz li.is-strong::before,
    .abra-paros dd.is-strong::before {
        background: var(--szin-kiemeles);
        opacity: 1;
    }

    .fl-num {
        grid-column: 1;
        font-size: var(--text-xs);
        letter-spacing: 0.05em;
        color: var(--szin-szerkezet);
    }

    /* A rekeszek dokumentumsorrendben kerülnek egymás alá — így egy
       szabály viszi mindhárom elrendezést, és egy új rekesz (jegyzet,
       oldalcímke) nem kíván új `grid-row`-t. */
    .abra-lanc li > :not(.fl-num) { grid-column: 2; }

    .fl-cim {
        font-family: var(--font-display);
        font-size: 1.02rem;
        text-transform: uppercase;
        letter-spacing: -0.01em;
        line-height: 1.15;
        color: var(--fg);
    }

    .fl-sub {
        font-size: var(--text-xs);
        line-height: 1.55;
        color: var(--fg-muted);
    }

    /* Jóváhagyási pont, kapu, feltétel. A rajzon szaggatott vonal jelöli
       — itt szaggatott bal szegély, ugyanabban a kiemelő színben: ahol a
       folyamat MEGÁLL, amíg nincs válasz. */
    .fl-kapu {
        margin-top: 0.15rem;
        padding-left: var(--space-1);
        border-left: 2px dashed var(--szin-kiemeles);
        font-size: 0.72rem;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        color: var(--fg-muted);
    }

    /* Az ábrán kívül álló jegyzet — a rajzon a keret alatt fut, itt a
       lista alatt. */
    .fl-jegyzet {
        margin: var(--space-2) 0 0;
        font-size: 0.72rem;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        line-height: 1.5;
        color: var(--fg-muted);
    }

    /* ── Szembeállítás ──────────────────────────────────────────
       A térköz ASZIMMETRIKUS, és ez az elrendezés teljes indoklása: a
       páron BELÜL szoros, a szempontok KÖZÖTT tág. Ez az, ami a szemet
       soronként párosíttatja — egy egyenletes lista ugyanezt a tartalmat
       két különálló felsorolásként olvastatná. */
    .abra-paros { border-top: none; }

    .fl-szempont {
        margin-bottom: var(--space-3);
        border-top: var(--divider);
    }

    .abra-paros dd + dd { border-top: none; padding-top: 0; }
    .abra-paros dd { border-bottom: none; }

    /* Melyik oldalról van szó. Kisbetűs vezérszó a sor elején — a rajzon
       ezt az oszlop fejléce mondta meg. */
    .fl-oldal {
        display: block;
        font-size: 0.68rem;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--szin-szerkezet);
    }

    /* ── Két ág egymás alatt ────────────────────────────────────
       Akkor ez a helyes, ha a két oldal NEM sorolható párba: más a
       hosszuk, vagy nem egy magasságban futnak. Ilyenkor a soronkénti
       megfeleltetés hazugság volna — helyette két, külön címzett ág. */
    .abra-szembe { border-top: none; }

    .abra-szembe section + section { margin-top: var(--space-3); }

    .fl-cimke {
        margin: 0 0 var(--space-1);
        font-size: 0.72rem;
        font-weight: 500;
        letter-spacing: 0.08em;
        text-transform: uppercase;
        color: var(--szin-szerkezet);
    }

    .abra-lanc-ag {
        margin: 0;
        padding: 0;
        list-style: none;
        border-top: var(--divider);
    }

    .abra-lanc-ag li {
        position: relative;
        display: grid;
        grid-template-columns: 1fr;
        row-gap: 0.3rem;
        padding: var(--space-2) 0 var(--space-2) var(--space-3);
        border-bottom: var(--divider);
    }

    .abra-lanc-ag li::before {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        width: var(--vonal-1);
        background: var(--szin-szerkezet);
        opacity: 0.5;
    }

    .abra-lanc-ag li.is-strong::before {
        background: var(--szin-kiemeles);
        opacity: 1;
    }
}

/* ── Előhívás — a szekció nem érkezik, hanem előhívódik ──────
   Csak ott fut, ahol a böngésző támogatja; enélkül minden látszik. */
@supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
        /* A `html.js-anim` kapu ÚJ, és nem kozmetika: enélkül a
           main.js védőhálója (a fájl elején) soha nem tudta volna
           kimenteni a ragadt szekciót, mert a szabály nem is függött
           tőle. A védőháló levette a js-anim osztályt — és semmi nem
           történt. */
        html.js-anim .section-about,
        html.js-anim .section-services,
        html.js-anim .section-process,
        html.js-anim .section-refs,
        html.js-anim .section-shift,
        html.js-anim .section-testimonials,
        html.js-anim .section-faq,
        html.js-anim .section-contact {
            animation: reveal linear both;
            animation-timeline: view();
            animation-range: entry 0% entry 34%;
        }

        /* A ritmus átmegy a mozgásba: ugyanaz a három csoport, mint a
           szekció-paddingoknál. A sűrű szekcióknál az előhívás
           majdnem vágás, a lélegzőknél a leghosszabb. */
        html.js-anim .section-services,
        html.js-anim .section-process  { animation-range: entry 0% entry 20%; }

        html.js-anim .section-shift    { animation-range: entry 0% entry 44%; }

        html.js-anim .section-refs,
        html.js-anim .section-contact  { animation-range: entry 0% entry 52%; }
    }
}

/* Nincs elmozdulás: a translateY felületi gesztus, és pontosan az,
   amit minden sablon csinál. Marad a tiszta fény.

   És van PADLÓ: a szekció nem a semmiből érkezik, hanem előhívódik.
   A padló egyben a legjobb védőháló is — egy ragadt szekció legrosszabb
   esetben halványabb, nem ÜRES. Ez elvi védelem, nem utólagos mentés. */
@keyframes reveal {
    from { opacity: 0.48; }
    to   { opacity: 1; }
}

/* ────────────────────────────────────────────────────────────
   HERO
   ─────────────────────────────────────────────────────────── */
/* A hero a teljes első képernyőt kitölti, és a tartalma FÜGGŐLEGESEN
   KÖZÉPRE ül benne. Enélkül a portré és a cím a felső padding miatt a
   képernyő közepe alatt kezdődött, tehát a lap alsó harmada üresen
   maradt, miközben a szem följebb keresi a súlypontot.

   svh, nem vh: mobilon a vh a böngésző címsorával EGYÜTT számol, ezért
   ott a hero mindig magasabb lenne a valóban látható területnél. A vh
   előtte marad tartaléknak azoknak, akik az svh-t nem ismerik. */
.section-hero {
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* SZIMMETRIKUS függőleges padding. A közös szekció-szabályból 8rem
       jött alulra, felülre viszont 4rem — a középre igazítás így a
       különbség felével, 32 pixellel a képernyő közepe FÖLÉ tolta a
       tartalmat. Nem a centrálás volt hibás, hanem a két oldal eltérése. */
    padding-block: var(--space-4);
}

/* Alacsony ablakon (laptop + több eszköztár) a 2:3 portré magasabb, mint a
   képernyő, tehát semmilyen igazítás nem tudná középre tenni: a hero
   egyszerűen túlnyúlna. A kép magasságát ezért a látható területhez
   kötjük — a kivágás fentről tart, ahol az arc van.

   A 9rem tartalék a szimmetrikus paddingot fedi és egy keveset hagy alatta;
   14rem-mel a korlát a legtöbb laptopon már akkor is beavatkozott, amikor a
   kép egyébként elfért volna — attól lett kicsi a portré. */
.hero-image-wrap {
    max-height: calc(100svh - 6rem);
}

/* Hero — kétoszlopos rács: cím bal, kép jobb.
   A kép oszlopa a szélesebb: 2:3 arányban a szélesség másfélszerese a
   magasság, tehát a portré minden megnyert pixelt megsokszoroz. A cím
   ezzel nem jár rosszul — a mérete cqw-ben a SAJÁT oszlopához igazodik,
   tehát arányos marad, csak valamivel kisebb. */
.hero-grid {
    display: grid;
    grid-template-columns: 1fr 1.12fr;
    gap: var(--space-6);
    align-items: center;
}

/* A szövegoszlop MÉRETKÉRDÉSŐ konténer. Két dolgot old meg egyszerre:

   1. A cím egy sorban áll (white-space: nowrap), ezért a méretének a saját
      OSZLOPÁHOZ kell igazodnia, nem a képernyőhöz. A vw ezt nem tudja: a
      hero desktopon két hasábra oszlik, mobilon egyre — ugyanaz a vw-érték
      az egyikben belefér, a másikban kilóg. A cqw a konténer szélességének
      százaléka, tehát mindkét elrendezésben magától jó.

   2. Az inline-size típusú konténer nem a tartalmától kapja a szélességét.
      E nélkül a nowrap-es cím MIN-CONTENT szélessége (monospace-ben
      „Karner Kristóf" = 14 × 0,6em = 8,4em) felnyomta az 1fr sávot 941
      pixelre a 880-as rácsban, és a kép oszlopa nullára esett — a portré
      eltűnt. Ez volt a betűcsere egyetlen valódi elrendezés-kára. */
.hero-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    container-type: inline-size;
}

/* Cím — mixed-case, egy sorban minden eszközön.

   A méret nem képernyő-, hanem OSZLOPARÁNYOS. „Karner Kristóf" monospace
   betűvel pontosan 14 × 0,6em = 8,4em széles, tehát a saját oszlopába
   akkor fér bele, ha a betűméret legfeljebb 100cqw / 8,4 = 11,9cqw. A
   11,5cqw ezt tartja, egy kevés ráhagyással.

   Miért nem vw: a hero desktopon két hasáb, mobilon egy. Ugyanaz a
   vw-érték az egyikben belefér, a másikban kilóg — a korábbi 9,2vw pont
   ezen bukott el, amikor a betű arányosról monospace-re váltott. A cqw a
   SAJÁT oszlopához méri magát, tehát mindkét elrendezésben helyes marad,
   és nem kell újrakalibrálni, ha a rács változik. */
.hero-title {
    font-family: var(--font);
    font-size: min(7rem, 11.5cqw);
    white-space: nowrap;
    font-weight: 300;
    letter-spacing: 0;
    line-height: 1;
    margin-bottom: var(--space-3);
    color: var(--fg);
}

.hero-sub {
    font-size: var(--text-lg);
    font-weight: 300;
    color: var(--fg-sub);
    max-width: 46ch;
    line-height: 1.55;
    letter-spacing: 0;
}

/* Hero kép — portrait 2:3 arány.

   Az ARÁNYT egy KÖZTES doboz tartja, `padding-bottom`-mal, nem
   `aspect-ratio`-val. Ez fogta meg azt a hibát, amit Kristóf hónapokig
   tapasztalt régebbi iPhone-okon (iOS 15 és 16 egyaránt): a cím
   rácsúszott a portréra, a keret alja a felirat alatt folytatódott.

   Az ok a rács és az `aspect-ratio` SORRENDJE. A rács a sor magasságát
   az elem magasságából számolja — csakhogy az arányból számolt magasság
   csak a szélesség ismerete UTÁN áll elő. A régebbi WebKit a cellát még
   nulla magassággal mérte, a doboz viszont a tényleges méretével
   rajzolódott ki: túlnyúlt a celláján, és rálógott a következő sorra.
   A mai WebKit ezt időben újraszámolja — ezért nem lehetett
   reprodukálni tizenháromféle méréssel sem, csak Kristóf képernyőképe
   mutatta meg.

   A `padding-bottom` a SZÉLESSÉGHEZ viszonyul, ami már az első
   layout-körben ismert. Miért kell hozzá külön elem: a százalék mindig
   a SZÜLŐ szélességéhez mér, tehát ha ugyanazon az elemen ülne, amin a
   `max-width: 420px`, akkor a korlátozás előtti szélességgel számolna —
   fekvőben ettől 420×597-es „négyzet” lett. A köztes doboz már a
   korlátozott szélességet örökli. */
.hero-image-wrap {
    overflow: hidden;
}

.hero-image-box {
    position: relative;
    height: 0;
    padding-bottom: 150%;      /* 2:3 */
}

/* Keret a portré köré, ugyanazzal a hajszálvonallal, amivel a szekciók el
   vannak választva. A kivágás jobbra és alul kifut a képből; keret nélkül ez
   véletlen vágásnak látszik, kerettel viszont szándékos képkivágat.
   A keret MINDKÉT színsémában ott van — lásd a lentebbi megjegyzést. */
.hero-image-wrap:not(.is-placeholder) {
    border: var(--divider);
}

/* A portré átlátszó hátterű kivágás, ezért nincs körülötte keret: az alak
   közvetlenül a lapon áll. Sötét módban ettől a sötét zakó beleolvad a
   háttérbe, világosban a fehér — a kép mindkét sémát ugyanazzal a fájllal
   szolgálja ki.

   Az alsó elhalás CSAK sötét módban kell. Világos módban a keretes képkivágat
   a szándékolt megjelenés: ott a kivágás alja nem elhalványul, hanem a keret
   vonalánál ér véget. */
.hero-image {
    position: absolute;
    top: 0; right: 0; bottom: 0; left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* A doboz magasságát a képernyő korlátozza (max-height), tehát ritkán
       egyezik pontosan a kép 2:3 arányával. Ilyenkor a `cover` vág — és
       KÖZÉPRE igazítva a fejtetőt vágja le. Egy portrénál a felső él a
       fontos: az arc egészben marad, a zakó alja pedig elvágható. */
    object-position: center top;
    display: block;
}

/* Sötét módban UGYANEZ a keret marad, és nincs alsó elhalás. A korábbi
   megoldás ott levette a keretet, és a kép alját maszkkal halványította el —
   ettől a portré lebegett, míg világosban egy megrajzolt képkivágat volt.
   Két különböző megjelenés ugyanarra az elemre: a keret az, ami mindkettőben
   ugyanazt mondja — ez itt szándékos kivágat, nem véletlen vágás. */


/* Képhely, amíg nincs portré — nem törött kép, hanem jelölt üres hely */
.hero-image-wrap.is-placeholder {
    border: 1px dashed var(--border);
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--felulet);
}

.hero-image-wrap.is-placeholder span {
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-muted);
    text-align: center;
    padding: var(--space-2);
}

/* ────────────────────────────────────────────────────────────
   RÓLAM
   ─────────────────────────────────────────────────────────── */
.about-grid {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: var(--space-8);
    align-items: start;
}

.about-text {
    font-size: var(--text-base);
    font-weight: 300;
    line-height: 1.65;
    color: var(--fg-sub);
    letter-spacing: 0;
}

.about-text + .about-text { margin-top: var(--space-3); }

.about-text strong {
    color: var(--fg);
    font-weight: 500;
}

/* ────────────────────────────────────────────────────────────
   SZOLGÁLTATÁSOK — divider lista
   ─────────────────────────────────────────────────────────── */
.service-list {
    border-top: var(--divider);
    margin-top: var(--space-4);
}

.service-item {
    display: grid;
    grid-template-columns: 2.5rem 1fr auto;
    gap: var(--space-4);
    align-items: center;
    /* FIX bal hely a jelzővonalnak. Nem hoverre nő — így a rács
       oszlopai nem szűkülnek, és a szöveg nem tör újra. */
    padding: var(--space-3) 0 var(--space-3) var(--space-3);
    border-bottom: var(--divider);
    position: relative;
    transition: opacity var(--transition),
                border-color var(--transition);
}

.service-num {
    font-size: var(--text-xs);
    color: var(--fg-muted);
    letter-spacing: 0.05em;
    transition: color var(--transition);
}

/* ── A sorszámok ─────────────────────────────────────────────
   Alapban kékek — a szerkezet része, mint a rajzon a tételszámok.
   Amelyiken a kurzor áll, az bíborra vált: a kiemelés mindig azt
   jelöli, ami épp a lényeg. A hármas ciklus megszűnt a harmadik
   szín kiesésével; helyette egyetlen, következetes szabály. */
/* A referencia-sorszámok kikerültek a listából (2026-07-28, Kristóf):
   a sorrend maga hordozza az információt — legfelül a legfrissebb munka —,
   a szám csak zajt adott hozzá. A szolgáltatásoknál marad, ott a 01–04
   a szolgáltatás-kínálat tagolása, nem rangsor. */
.service-list .service-num { color: var(--szin-szerkezet); }

/* Amin a kurzor áll: bíbor, és a sor beljebb lép — mint amikor a
   tervrajzon rábökünk egy tételre. */
.service-list .service-item:hover .service-num { color: var(--szin-kiemeles); }

/* A hover NEM mozgatja a sort. Az első verzió padding-left-tel tolta
   beljebb, és két hibát okozott:

     1. A sor RÁCS (2.5rem 1fr auto auto). A bal padding növelése
        szűkíti az 1fr oszlopot, tehát a hosszabb nevek ÚJRATÖRNEK —
        a sor ugrál, ahogy az egér áthalad rajta.
     2. Az átmenet nem is futott le: a .ref-item saját szabálya
        felülírta a transition-listát, így a padding ugrott.

   Helyette DEDIKÁLT pszeudoelem a bal szélen, fix paddingben. Nem
   box-shadow: az inset árnyék rámegy a sorszámra (a rács első
   oszlopa a sor bal széléről indul), és a specificitása is nehezen
   követhető. A pszeudoelem külön elem, a saját helyén.

   Alapban scaleY(0) — magasságban nő ki, felülről lefelé, mint
   amikor a vonalzó mellett lehúzzák. */
.service-item::before,
.ref-item::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--vonal-2);
    background: var(--szin-kiemeles);
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform var(--transition);
}

.service-list .service-item:hover::before,
.ref-list     .ref-item:hover::before { transform: scaleY(1); }

.service-list .service-item:hover,
.ref-list     .ref-item:hover { border-bottom-color: var(--szin-szerkezet); }

/* A display-méretek Bebas Neue-hoz voltak szabva. A Bebas KESKENY
   display-betű: a nagybetű-magassága ugyanannyi (0,700em vs 0,698em),
   a szövege viszont 1,5–1,65× keskenyebb. Ugyanaz a pont-méret ezért
   monospace-ben ugyanolyan MAGAS, de másfélszer szélesebb sort ad.

   Ami ettől eltört: a kapcsolat e-mail címe 64 pixelen 960 pixelt kért
   a 880-as sorban, tehát KÉT SORBA tört, és a „Mi változik pontosan"
   gomb felirata is. A referencia-nevek a sor 73%-át foglalták.

   A méretek ezért 0,65-szörösükre mennek — pont az 1,55-ös szélesség-
   arány inverzére —, így a sorok ugyanannyi helyet foglalnak, mint a
   korábbi display betűvel. */
.service-name {
    font-family: var(--font-display);
    font-size: clamp(1.04rem, 2.27vw, 1.95rem);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: -0.01em;
    line-height: 1;
    color: var(--fg);
}

.service-desc {
    font-size: var(--text-base);
    color: var(--fg-muted);
    max-width: 32ch;
    text-align: right;
    line-height: 1.5;
    letter-spacing: 0.01em;
}

/* ────────────────────────────────────────────────────────────
   REFERENCIÁK
   ─────────────────────────────────────────────────────────── */
.ref-list {
    border-top: var(--divider);
    margin-top: var(--space-4);
}

/* ── „Csak egy dolog van élesben" ────────────────────────────
   Amint a kurzor a listára ér, minden sor elhalványul azon az
   egyen kívül, amelyiken áll. Ez a referenciáknál eddig is így
   volt; innentől a szolgáltatásoknál és a munkamenetnél is.

   Nem effekt: a nézés modellje. Egyszerre egy dolgot nézünk, a
   többi ott van, csak nincs élesben.
   ─────────────────────────────────────────────────────────── */
.service-list:hover .service-item,
.process-grid:hover .process-step { opacity: 0.3; }

.service-list .service-item:hover,
.process-grid .process-step:hover { opacity: 1; }

.process-step { transition: opacity var(--transition); }

.ref-item {
    display: grid;
    grid-template-columns: 1fr auto auto;   /* a sorszám-oszlop kiesett */
    gap: var(--space-4);
    align-items: center;
    /* FIX bal hely a jelzővonalnak — ugyanaz az elv, mint a
       szolgáltatás-listánál: a hover nem mozgat semmit. */
    padding: var(--space-3) 0 var(--space-3) var(--space-3);
    border-bottom: var(--divider);
    color: var(--fg);
    position: relative;
    /* A transition ITT áll, nem fentebb: ez a szabály később van a
       fájlban, tehát a korábbit felülírná — a jelzés átmenet nélkül
       ugrana. */
    transition: opacity var(--transition),
                border-color var(--transition);
    cursor: default;  /* pointer ha van link */
}

.ref-item[href]:not([href="#"]) { cursor: pointer; }

/* Hover: a nem hovered elemek halványulnak */
.ref-list:hover .ref-item { opacity: 0.28; }

/* A lista alján a gyűjtőoldalra vezető link. Tíz sor elfér a kezdőlapon, de
   aki mélyebbre menne, annak legyen egy hely, ahol mind ott van egyben. */
.ref-more {
    padding: var(--space-3) 0;
    font-size: var(--text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.ref-more a { color: var(--fg-muted); }
.ref-more a:hover { color: var(--fg); }
.ref-list .ref-item:hover  { opacity: 1; }

/* A .ref-num szabály törölve: a referenciákról lekerült a sorszám.
   A sorrend hordozza az információt — legfelül a legfrissebb munka. */

/* A sorszám hoverkor NEM vált színt: mostantól alapból is a saját
   ciklikus színén áll. Az „itt vagyok" jelzést a lista adja — a
   többi sor 0,28-ra halványul, ez a hoverált marad élesben. */

.ref-name {
    font-family: var(--font-display);
    font-size: clamp(1.04rem, 2.27vw, 1.95rem);
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: -0.01em;
    line-height: 1;
}

.ref-tag {
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

.ref-year {
    font-size: var(--text-xs);
    color: var(--fg-muted);
    letter-spacing: 0.05em;
    min-width: 2.5rem;
    text-align: right;
}

/* ── Hover előnézet — két ablak, kurzort követ ────────────────
   Két rekesz egy közös kereten belül: balra az ügyfél élő oldala,
   jobbra az a lap, ahová a kattintás visz. Az üvegháttér lekerült —
   két képet egymás mellett nem szabad átlátszó lapra tenni, mert a
   mögötte átsejlő szöveg pont a két kép különbségét mossa össze.
   A tömör háttér és a vastag kék keret ugyanabból a rendszerből jön,
   mint a szekció-vonalak: rárajzolt keret, nem lebegő buborék. */
/* A panel EGY ablak: a cikk lapjának képe. A második rekesz — az ügyfél
   élő oldala — szándékosan került ki: a lista névtelen esettanulmányokra
   mutat, egy felismerhető honlap képe viszont megnevezné az ügyfelet.
   A szélesség ezért harminc rem helyett tizennyolc. */
.ref-preview {
    position: fixed;
    top: 0; left: 0;
    width: 18rem;
    display: grid;
    grid-template-columns: 1fr;
    pointer-events: none;
    z-index: 200;
    opacity: 0;
    transform: translate(0, 0); /* JS frissíti */
    transition: opacity var(--t-valasz) var(--ease);
    background: var(--bg);
    border: var(--vonal-1) solid var(--szin-szerkezet);
    will-change: transform;
}

.ref-preview.is-visible { opacity: 1; }

.ref-ablak {
    margin: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* A kép ARÁNYA fix, hogy a panel ne ugráljon soronként — a képek
   ugyanabból a forrásból, ugyanazzal a kivágással készülnek. */
.ref-ablak img {
    width: 100%;
    aspect-ratio: 16 / 7;
    display: block;
}

/* A kép felső éléhez igazítva: a fejléc és a hero teszi felismerhetővé
   az oldalt, nem a közepe. */
.ref-ablak img { object-fit: cover; object-position: top center; }

/* A kép felső éléhez igazítva: a lap fejléce és címe teszi
   felismerhetővé a cikket, nem a közepe. */

/* ────────────────────────────────────────────────────────────
   AMI VÁLTOZIK — átvezető az AI-láthatóság cikkre
   A szövegréteg az about-grid/about-text stílusait használja újra;
   itt csak a szekció-keret és a CTA-link él.
   ─────────────────────────────────────────────────────────── */
/* A keret és a padding fentebb, a szekciók közös blokkjában van —
   ott, ahol a ritmus is dől el. */

/* ── Gomb — keretes, tervrajz-stílusban ──────────────────────
   Kék keret, és hoverkor balról jobbra kitöltődik. A kitöltés
   pszeudoelem, ami mögötte skálázódik — nem a háttérszín animál,
   tehát nem villan és nem terheli a festést. */
.shift-cta {
    display: inline-block;
    position: relative;
    z-index: 0;
    overflow: hidden;
    margin-top: var(--space-3);
    /* A vízszintes belső tér KORLÁTOZOTT: rem-ben nőne a szöveg-nagyítással,
       és 200%-on 48 képpont lenne oldalanként. Mérve: a gomb 411 képpont
       széles lett egy 295 képpontos szülőben. A `min()` a szülő
       arányához köti, tehát nagyításnál sem szalad el. */
    padding: 0.7rem min(1.5rem, 6%);
    /* Soha ne lógjon ki a szülőjéből, akármekkora a szöveg. */
    max-width: 100%;
    font-family: var(--font-display);
    font-size: clamp(0.72rem, 1.43vw, 0.98rem);
    text-transform: uppercase;
    letter-spacing: 0.01em;
    color: var(--fg);
    border: var(--vonal-1) solid var(--szin-szerkezet);
    /* A nyíl RAJZOLT, nem betű: a `→` (U+2192) nincs benne a
       betűkészlet-fájlokban, tehát tartalék betűből jönne, más
       metrikával — ettől csúszott el a szöveg mellett. A pszeudoelem
       ugyanabból a vonalból épül, mint a lap többi jele.

       Az `a` szabály átmenet-listáját ez FELÜLÍRJA — tehát ami itt nincs
       felsorolva, az ugrik. A hover az átlátszóságot is mozgatja, ezért
       annak is itt kell lennie. */
    white-space: nowrap;
    transition: color var(--transition),
                opacity var(--t-valasz) var(--ease);
}

.shift-cta::after {
    content: '';
    display: inline-block;
    width: 0.62em;
    height: 0.62em;
    margin-left: 0.6em;
    border-top: var(--vonal-1) solid currentColor;
    border-right: var(--vonal-1) solid currentColor;
    transform: rotate(45deg) translate(-0.06em, 0.06em);
    vertical-align: -0.02em;
}

.shift-cta::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--szin-szerkezet);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--transition);
}

.shift-cta:hover { color: var(--bg); opacity: 1; }
.shift-cta:hover::before { transform: scaleX(1); }
.shift-cta:active { transform: translateY(1px); transition-duration: var(--t-nyomas); }

/* A GYIK-válaszban álló link kapjon látható jelzést */

.faq-a a { border-bottom: 1px solid var(--border); }
.faq-a a:hover { border-bottom-color: var(--fg); opacity: 1; }
/* ────────────────────────────────────────────────────────────
   VÉLEMÉNYEK — 2×2 rács
   ─────────────────────────────────────────────────────────── */
.testimonial-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    border-top: var(--divider);
    border-left: var(--divider);
    margin-top: var(--space-4);
}

/* Páratlan számú véleménynél az utolsó a TELJES sort elfoglalja. Enélkül
   egy üres cella marad a rács jobb alsó sarkában — kerettel körberajzolva,
   tehát nem üres helynek, hanem hiányzó tartalomnak látszik. */
.testimonial-item:last-child:nth-child(odd) { grid-column: 1 / -1; }

.testimonial-item {
    padding: var(--space-4) var(--doboz-belso);
    border-right: var(--divider);
    border-bottom: var(--divider);
}

.testimonial-text {
    font-size: var(--text-base);
    font-weight: 300;
    line-height: 1.65;
    color: var(--fg-sub);
    letter-spacing: 0;
    margin-bottom: var(--space-2);
}

/* A csillag ALACSONYABB, mint a mellette álló nagybetűs felirat: a
   ★ jel magassága 0,52 em, a Plex Mono nagybetűjéé 0,71 em. Azonos
   betűméretnél tehát a csillagsor odalent lebeg. A 1,37-es szorzó a
   kettő hányadosa — így a csillag TETEJE a „GOOGLE" nagybetűinek
   tetejével egy vonalba kerül, mérve 9,46 vs 9,32 képpont.

   A `letter-spacing` visszavétele nem részletkérdés: a szülő 0,08 em
   ritkítása a nagyobb betűmérettel EGYÜTT nőne, és a csillagsor
   szétesne. */
.csillagok {
    font-size: 1.37em;
    line-height: 1;
    letter-spacing: 0.02em;
}

.testimonial-author {
    display: block;
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

/* ────────────────────────────────────────────────────────────
   KAPCSOLAT
   ─────────────────────────────────────────────────────────── */
.contact-block {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-top: var(--space-4);
}

.contact-email,
.contact-phone {
    font-family: var(--font-display);
    font-size: clamp(1.04rem, 2.93vw, 2.60rem);
    font-weight: 400;
    /* Az e-mail cím NEM megy nagybetűvel. Egy cím nem címke: a
       nagybetűs alak olvashatatlanabb (a @ és a pont körüli tagolás
       eltűnik), és másoláskor is félrevezető. */
    letter-spacing: -0.01em;
    line-height: 1.05;
    color: var(--fg);
    word-break: break-word;
    /* Eddig csak a globális `a:hover` átlátszósága mozdult rajta, ami egy
       ekkora, fehér feliratnál gyakorlatilag láthatatlan — a lap
       legfontosabb linkjén nem volt visszajelzés. Ugyanaz az aláhúzás,
       mint az esettanulmányok záró blokkjában lévő e-mail címen. */
    border-bottom: var(--vonal-1) solid transparent;
    transition: border-bottom-color var(--t-valasz) var(--ease),
                color var(--t-valasz) var(--ease),
                opacity var(--t-valasz) var(--ease);
}

.contact-email:hover,
.contact-email:focus-visible {
    border-bottom-color: var(--szin-kiemeles);
    opacity: 1;
}

.contact-note {
    margin-top: var(--space-3);
    font-size: var(--text-base);
    color: var(--fg-muted);
    max-width: var(--mertek);
    line-height: 1.65;
}

/* ────────────────────────────────────────────────────────────
   FOOTER
   ─────────────────────────────────────────────────────────── */
.site-footer {
    margin-left: var(--sidebar);
    /* Ugyanaz a --margo, mint a fő tartalomnál: a lábléc széle és a
       szekciók széle egy vonalban fut, bármilyen nagyításon. */
    padding: var(--space-3) var(--margo);
    /* A vonalat a ::before adja, kétszínűen — mint a szekcióknál. */
    border-top: none;
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

/* A lap záróvonala — ugyanaz a kétszínű sáv, mint a szekcióknál. */
.site-footer::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--vonal-1);
    background: var(--szin-szerkezet);
}

.site-footer::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 84px;
    height: var(--vonal-1);
    background: var(--szin-kiemeles);
}

/* ────────────────────────────────────────────────────────────
   GYIK / FAQ
   ─────────────────────────────────────────────────────────── */
/* A vonala fentebb, a szekciók közös blokkjában — ott, ahol a skála
   végigfut az összesen. Itt már csak a levegő. */
.section-faq {
    padding: var(--space-8) 0;
}

.faq-list {
    border-top: var(--divider);
    margin-top: var(--space-4);
}

/* A fiók a TÉNYLEGES magasságát nyitja, nem egy találomra választott
   plafont. A korábbi `max-height: 420px` némán levágta a hosszabb
   válaszokat: 320 pixeles képernyőn mérve négy válasz csonkult ezen a
   lapon, a leghosszabból 69 pixel hiányzott. Ez tartalomvesztés volt,
   nem ízléskérdés.

   A megoldás rács: a .faq-item pontosan két gyereket tartalmaz
   (h3 + p.faq-a) — mind a 196 példány, mind a 44 lapon ellenőrizve —,
   tehát a 0fr → 1fr átmenet a saját magasságára nyit. Nulla HTML-változás. */
/* A nyitás mechanizmusa NEM rács-fr. A `grid-template-rows: 0fr → 1fr`
   szép megoldás, de az `fr` egy MAGASSÁG NÉLKÜLI rácskonténerben
   motoronként máshogy oldódik fel — Chromiumban a tartalom magasságát
   adja, máshol nullát, és akkor a fiók egyszerűen nem nyílik ki. Egy
   akkordeon nem lehet motorfüggő.

   Helyette `max-height`: minden motorban ugyanaz, és a felső korlát
   (60rem = 960 képpont) bőven a leghosszabb válasz fölött van — az 647
   karakter, ami a legszűkebb telefonon is 600 alatt marad. */
.faq-item {
    border-bottom: var(--divider);
    overflow: hidden;
    /* Hely a nyitás-jelző vonalnak, fixen — a padding nem hoverre nő,
       tehát a szöveg nem tör újra, és a magasság-animáció nem ugrik. */
    padding-left: var(--space-3);
    position: relative;
}

/* A nyitott fiók bal oldalán kiemelő vonal, felülről lehúzva. */
.faq-item::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--vonal-2);
    background: var(--szin-kiemeles);
    transform: scaleY(0);
    transform-origin: top center;
    transition: transform var(--transition);
}

details.faq-item[open]::before { transform: scaleY(1); }

/* A cím a summary-n BELÜL áll, hogy a szerkezeti sorrend megmaradjon;
   a saját margóját és méretét viszont a sor adja, nem a doc-body. */
.faq-q > h3 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: relative;          /* a ::before függőleges vonala ehhez igazodik */
    margin: 0 !important;
    padding: 0 !important;
    border: 0 !important;
    font-size: inherit;
    font-weight: inherit;
    letter-spacing: inherit;
    line-height: inherit;
    color: inherit;
}




/* Kattintható kérdés sor — + ikon jobb szélen */
/* A kérdés natív `<summary>`. A böngésző alapértelmezett háromszögét
   levesszük — a lap saját jele a jobb szélen álló „+", ami nyitva
   „−"-ra fordul. A `list-style: none` a szabványos út, a
   `::-webkit-details-marker` a régebbi WebKitnek. */
.faq-q::-webkit-details-marker { display: none; }

/* A `<summary>` MARAD blokk-szintű. A `display: flex` rajta WebKitben
   megszünteti a nyitó-csukó viselkedést: a `<details>` egyszerűen nem
   kapcsol tőle. Nálam Chromiumban végig működött, ezért kerestem
   hetekig máshol — pedig ez volt az.

   A vízszintes elrendezést ezért a benne álló `<h3>` viszi, a jel pedig
   arra kerül. A summary dolga csak annyi, hogy kattintható legyen. */
.faq-q {
    display: block;
    list-style: none;
    cursor: pointer;
    width: 100%;
    padding: var(--space-3) 0;
    text-align: left;
    font-family: var(--font);
    font-size: var(--text-base);
    font-weight: 500;
    letter-spacing: 0;
    color: var(--fg);
    user-select: none;
    transition: color var(--transition);
}


/* + ikon → × amikor nyitva (rotate 45°) */
/* A + jel nem betű, hanem KÉT VONAL — a terven minden vonalzóval
   készül. A vízszintes az ::after, a függőleges a ::before; nyitáskor
   a függőleges elfordul, és marad a mínusz. */
.faq-q > h3::after {
    content: '';
    width: 13px;
    height: var(--vonal-1);
    background: var(--szin-szerkezet);
    flex-shrink: 0;
    margin-left: var(--space-3);
    transition: background var(--transition);
}

.faq-q > h3::before {
    content: '';
    position: absolute;
    right: 5.5px;
    width: var(--vonal-1);
    height: 13px;
    background: var(--szin-szerkezet);
    transition: transform var(--t-allapot) var(--ease),
                background var(--transition);
}

details.faq-item[open] .faq-q > h3::before { transform: rotate(90deg); }
details.faq-item[open] .faq-q > h3::after,
details.faq-item[open] .faq-q > h3::before { background: var(--szin-kiemeles); }

/* A nyitás-jelző vonal fentebb, a .faq-item saját szabályában van —
   egy komponensnek EGY helyen legyen a definíciója, különben a
   későbbi blokk csendben felülírja a transition-listát. Ez a fájl
   három ilyen duplikációt tartalmazott; ez volt az utolsó. */

/* A régi „+ betű elforgatása 45 fokkal" szabály helye. Az ikon
   mostantól két vonal: a vízszintes marad, a függőleges fordul el
   (lásd fentebb) — ezért itt nincs teendő. */

/* Válasz — csukott: max-height 0 + opacity 0, nyitott: kicsúszik */
/* Csukott állapotban a rács 0fr sora zárja, nyitottban a saját
   magassága nyílik. A `min-height: 0` nélkülözhetetlen: rács-elemnél
   az alapértelmezett min-content magasság padlót adna, és a fiók
   sosem záródna be teljesen. */
/* JS NÉLKÜL is működik: a nyitást a böngésző végzi. */
.faq-a {
    padding-bottom: 0;
    font-size: var(--text-base);
    color: var(--fg-muted);
    line-height: 1.7;
    max-width: var(--mertek);
}

/* ── A GYIK mozgása ─────────────────────────────────────────
   Az ÁLLAPOTOT a böngésző kezeli (natív `<details>`), ez itt csak a
   megjelenés. Két réteg, egymástól függetlenül:

   1. A tartalom beúszása — kulcskockás animáció, minden motorban fut.
   2. A magasság átmenete — `::details-content` + `interpolate-size`.
      Ezt csak az újabb motorok tudják; ahol nincs, ott a fiók
      magassága ugrik, a tartalom viszont akkor is beúszik.

   Egyik réteg sem befolyásolja, hogy a fiók nyílik-e. Ez a tanulság
   három elrontott nekifutásból: az animáció soha ne birtokolja az
   állapotot. */
details.faq-item[open] .faq-a {
    padding-bottom: var(--space-3);
    animation: faq-be var(--t-allapot) var(--ease) both;
}

@keyframes faq-be {
    from { opacity: 0; transform: translateY(-0.35rem); }
    to   { opacity: 1; transform: none; }
}

/* A nyitás–csukás magasság-átmenetét a JS méri ki és a Web Animations
   API futtatja — lásd `main.js`. Tisztán CSS-ből nem megoldható: az
   `auto` magasságra való átmenethez `interpolate-size: allow-keywords`
   kell, amit MÉRVE a WebKit 26.5 nem ismer. A `max-block-size`-os
   kerülőút sem jó: az átmenet ugyan lefut, de a doboz magassága végig
   változatlan marad, mert csukáskor a WebKit azonnal elrejti a
   tartalmat — mértem, 960px-től 0-ig fut a korlát, a doboz meg 76px.

   Amíg a magasság mozog, a `<details>` levágja a kilógó tartalmat. */
details.faq-item.is-mozog { overflow: clip; }

@media (prefers-reduced-motion: reduce) {
    details.faq-item.is-mozog { overflow: visible; }
}

/* ────────────────────────────────────────────────────────────
   DOKUMENTUM-OLDAL — adatkezelés, impresszum
   Hosszú szöveg: szűkebb sorhossz, nagyobb sorköz.
   ─────────────────────────────────────────────────────────── */
.section-doc {
    padding: var(--space-6) 0 var(--space-8);
    /* A KERET szélesedik 760-ról, a SZÖVEG viszont nem: a próza mértékét
       lentebb a .doc-body > p/ul/ol/h2/h3 tartja 72 karakteren. Így a
       táblázat, az ábra, a kód- és a bizonyíték-blokk kap 160 pixel
       többletet — épp azok, amik szűk nézetben ki is lógtak —, a
       bekezdés viszont ugyanolyan hosszú sorokban fut, mint eddig. */
    max-width: 920px;
}

.doc-title {
    font-family: var(--font);
    font-size: clamp(2rem, 4.5vw, 3.4rem);
    font-weight: 300;
    letter-spacing: 0;
    line-height: 1.05;
    margin: var(--space-3) 0 var(--space-2);
    color: var(--fg);
}

/* Hatályosság / verzió sor a cím alatt */
.doc-meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    padding-bottom: var(--space-3);
    border-bottom: var(--divider);
    margin-bottom: var(--space-4);
    font-size: var(--text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

/* Tartalomjegyzék */
/* Bevezeto bekezdes a jogi lapok elejen. Negy lapon all a HTML-ben, a
   CSS-ben viszont EGYETLEN szabaly sem vonatkozott ra - ugyanugy nezett
   ki, mint a torzsszoveg, tehat semmit nem vezetett be. */
.doc-lead {
    max-width: var(--mertek);
    margin-bottom: var(--space-3);
    font-size: var(--text-lg);
    font-weight: 300;
    line-height: 1.55;
    color: var(--fg-sub);
}

.doc-toc {
    margin-bottom: var(--space-6);
    padding: var(--space-3) var(--doboz-belso);
    background: var(--felulet);
    border: var(--divider);
}

.doc-toc ol {
    margin: var(--space-1) 0 0;
    /* Tiz tetelnel a ketjegyu sorszam 1,2rem-be mar nem fer be. */
    padding-left: 2.4rem;
    font-size: var(--text-sm);
    line-height: 1.9;
    color: var(--fg-sub);
}

.doc-toc a { border-bottom: 1px solid transparent; }
.doc-toc a:hover { border-bottom-color: var(--border); opacity: 1; color: var(--fg); }

/* Törzsszöveg */
/* A szöveg mértéke. Nem a kereten van, hanem a PRÓZA-elemeken: a
   táblázatnak, az ábrának és a kódblokknak több hely kell, egy bekezdésnek
   viszont nem. Monospace-nél a ch pontosan egy karakter, tehát ez a
   szabály azt mondja, amit jelent — a nyolcvan karakter itt nem önkényes
   szám, hanem a terminál-szélesség, amire ez az egész lap épül.

   A MÉRTÉK EGYETLEN ÉRTÉK, és a TÖRZS betűjéhez van szabva. Ez a lényeg,
   és korábban nem így volt: a `ch` mindig a SAJÁT elem betűméretéhez
   számol, tehát ugyanaz a `72ch` a bekezdésen 726 képpontot jelentett, a
   nagyobb betűs címsoron viszont 1175-öt. A címsor így nem is korlátozódott
   — kitöltötte a 920 képpontos keretet, és az ALATTA futó vonal jóval
   túlnyúlt a szövegen. Mérve, 1440 képpontos nézetben: a vonal 1290-ig
   ért, a szöveg 1095-ig. Ez az, ami a lapot „félig kitöltöttnek" mutatta.

   Ezért nem `ch`, hanem szorzat. A `@property` regisztráció NEM oldja meg
   — kipróbáltam: a `syntax: "<length>"` mellett is `80ch`-ként öröklődött
   tovább, tehát minden elem újra a saját betűjével számolta. A `calc`
   viszont a `--text-base` rem-értékéből dolgozik, így az eredmény egyetlen
   rem-hosszúság, ami minden gyereknél ugyanaz — és a szöveg-nagyítással
   együtt nő, ahogy kell.

   A 0.6 a monospace karakterszélessége em-ben. */
/* A mérték a GYÖKÉREN áll, mert nem csak a dokumentum-törzs használja:
   a GYIK válasza, a felvezetők és az ábrafeliratok ugyanennyit kapnak.
   Így a lapon EGY szélesség van, és a karakterszám alkalmazkodik a
   betűmérethez — nem fordítva. Nagyobb betűnél kevesebb karakter fér
   ugyanabba a szélességbe; pontosan ezt akarjuk egy felvezetőtől. */

.doc-body > p,
.doc-body > ul,
.doc-body > ol,
.doc-body > h2,
.doc-body > h3,
.doc-body > blockquote { max-width: var(--mertek); }

.doc-body {
    font-size: var(--text-base);
    line-height: 1.75;
    color: var(--fg-sub);
    letter-spacing: -0.01em;
}

.doc-body h2 {
    font-size: var(--text-xl);
    font-weight: 500;
    letter-spacing: 0;
    line-height: 1.2;
    color: var(--fg);
    margin: var(--space-6) 0 var(--space-2);
    padding-top: var(--space-3);
    border-top: var(--divider);
}

.doc-body h3 {
    /* Eddig pontosan akkora volt, mint a törzs — csak a vastagság
       választotta el. A `--text-lg` most a felvezetőé és a h3-é. */
    font-size: var(--text-lg);
    font-size: var(--text-base);
    font-weight: 500;
    letter-spacing: 0;
    color: var(--fg);
    margin: var(--space-4) 0 var(--space-1);
}

.doc-body p { margin-bottom: var(--space-2); }

.doc-body ul,
.doc-body ol {
    margin: 0 0 var(--space-2) 1.2rem;
}

.doc-body li { margin-bottom: 0.4rem; }

.doc-body strong { color: var(--fg); font-weight: 500; }

.doc-body a {
    border-bottom: 1px solid var(--border);
}
.doc-body a:hover { border-bottom-color: var(--fg); opacity: 1; color: var(--fg); }

/* Adatlap-szerű kulcs-érték blokk (adatkezelő adatai) */
/* Az adatlap a rajz FEJMEZŐJE: körbekeretezve, a címkék oszlopa
   elválasztva — ahogy egy műszaki rajz jobb alsó sarkában. */
.doc-facts {
    margin: var(--space-3) 0 var(--space-4);
    border: 1px solid var(--szin-szerkezet);
    background: var(--felulet);
}

.doc-facts div:last-child { border-bottom: 0; }
.doc-facts dt { border-right: var(--divider); padding-right: var(--space-2); }

.doc-facts div {
    display: grid;
    grid-template-columns: 190px 1fr;
    gap: var(--space-2);
    padding: calc(var(--doboz-belso) * 0.55) var(--doboz-belso);
    border-bottom: var(--divider);
    font-size: var(--text-sm);
}

.doc-facts dt {
    color: var(--fg-muted);
    font-size: var(--text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding-top: 2px;
}

.doc-facts dd { color: var(--fg); margin: 0; }

/* Táblázat — adatkezelési célok */
/* A töréspont a DOBOZ szélessége, nem a képernyőé — és ez itt nem
   szőrszálhasogatás: 700 pixel FÖLÖTT visszatér a 180–220 pixeles
   oldalsáv, tehát 701 pixelen KEVESEBB hely marad a tartalomnak
   (445 px), mint 700-on (335 + 2×20). Egy `max-width: 700px`
   médialekérdezés épp ott adná vissza a táblázat-formát, ahol a
   legszűkebb a hely. A container query azt kérdezi, ami számít:
   elfér-e a tábla a saját dobozában.

   Az `overflow-x: auto` biztonsági hálóként marad — ha valaha bekerül
   egy tördelhetetlen hosszú karakterlánc, az ITT görögjön, ne a lapot
   rántsa szét. Normál tartalomnál soha nem jelenik meg sáv. */
.doc-table-wrap {
    overflow-x: auto;
    margin: var(--space-3) 0 var(--space-4);
    container-type: inline-size;
    container-name: doc-tabla;
}

.doc-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
    /* `min-width: 520px` TÖRÖLVE: a feladatát a container query vette át,
       és két, egymással versengő szélesség-mechanizmus garantáltan
       félreértés. */
}

.doc-table th,
.doc-table td {
    text-align: left;
    vertical-align: top;
    /* Vízszintesen mindkét oldalon van belső tér: a bal oldali 0 miatt az
       első oszlop szövege korábban nekifeszült a táblázat szélének.
       A vízszintes érték `min()`-nel korlátozott: rem-ben nőne a
       szöveg-nagyítással, és háromoszlopos táblán 200%-on már csak a
       belső tér 192 képpontot vitt el. Mérve: 834 képpontos tábla egy
       596-os hasábban. */
    padding: 0.7rem min(var(--space-2), 2.5%);
    overflow-wrap: anywhere;
    border-bottom: var(--divider);
    line-height: 1.6;
}

.doc-table th {
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
    border-bottom: 1px solid var(--fg-muted);
    white-space: nowrap;
}

.doc-table td { color: var(--fg-sub); }

/* ── Négyoszlopos jogi tábla → soronként egy kártya ───────────
   820 alatt minden oszlopra 200 képpont alatt jutna: az már nem
   táblázat, csak négy szilánk. A fejlécsor NEM tűnik el, csak
   láthatatlan lesz — a képernyőolvasó tőle kapja az oszlop-
   hozzárendelést; `display: none` mellett a „Jogalap" és a „Cél"
   megkülönböztetése egyedül a CSS generált tartalmán múlna, az pedig
   nem kerül bele az akadálymentességi fába. */
@container doc-tabla (max-width: 820px) {
    .doc-table--kartya,
    .doc-table--kartya thead,
    .doc-table--kartya tbody,
    .doc-table--kartya tr,
    .doc-table--kartya td { display: block; width: 100%; }

    .doc-table--kartya thead {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }

    .doc-table--kartya tbody tr {
        margin-bottom: var(--space-2);
        border: var(--divider);
        background: var(--felulet);
    }

    .doc-table--kartya tbody tr:last-child { margin-bottom: 0; }

    .doc-table--kartya td {
        padding: 0.75rem var(--doboz-belso);
        border: 0;
        border-top: var(--divider);
        white-space: normal;
    }

    .doc-table--kartya tr td:first-child { border-top: 0; }

    /* Az oszlop neve a cella FÖLÉ kerül — ugyanaz a ritmus, mint az
       adatlapé: nagybetűs halvány kulcs, alatta az érték. */
    .doc-table--kartya td::before {
        content: attr(data-cimke);
        display: block;
        margin-bottom: 0.2rem;
        font-size: var(--text-xs);
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--fg-muted);
    }
}

/* ── Kétoszlopos kulcs-érték tábla → egymás alatt ─────────────
   Az „A munka számokban" blokkok. Markup-változtatás nélkül: a
   `:not()` választja el őket a négyoszlopos jogi tábláktól. */
@container doc-tabla (max-width: 560px) {
    .doc-table:not(.doc-table--kartya),
    .doc-table:not(.doc-table--kartya) tbody,
    .doc-table:not(.doc-table--kartya) tr,
    .doc-table:not(.doc-table--kartya) th,
    .doc-table:not(.doc-table--kartya) td { display: block; width: 100%; }

    .doc-table:not(.doc-table--kartya) tbody tr {
        padding: 0.8rem 0;
        border-bottom: var(--divider);
    }

    .doc-table:not(.doc-table--kartya) th,
    .doc-table:not(.doc-table--kartya) td {
        padding: 0;
        border: 0;
        white-space: normal;   /* a fejlécen ülő `nowrap` itt ellenség */
    }

    .doc-table:not(.doc-table--kartya) th { margin-bottom: 0.25rem; }
}

/* ── Esettanulmány-galéria ───────────────────────────────────
   A címblokk után, még az első ábra előtt: a látogató előbb lássa, mi
   épült, és csak utána olvassa, hogyan. A képek az élő oldal valódi
   szakaszai — nem illusztrációk, ezért nincs rajtuk se árnyék, se
   lekerekítés, csak hajszálkeret, mint a lap minden más mezőjén. */
.case-galeria { margin: var(--space-4) 0 var(--space-6); }

.case-galeria-cim {
    font-size: var(--text-xl);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--fg-muted);
    margin-bottom: var(--space-2);
}

/* RÁCS, nem oszlopok. A `columns` szép masonry-t adott, de a lusta töltésű
   képek magassága menet közben derül ki, és az oszlopelrendezés minden
   betöltéskor újraosztotta az elemeket — a képek látszólag maguktól
   ugráltak egymás alá. A rács oszlopa attól nem mozdul el, hogy egy kép
   később érkezik meg. */
.case-galeria-racs {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-3) var(--space-2);
    align-items: start;
}

.case-galeria-bev {
    font-size: var(--text-sm);
    color: var(--fg-muted);
    margin-bottom: var(--space-2);
}

.case-galeria-elem {
    margin: 0;
}

/* A kép nem nyílik külön ablakban: a galéria itt olvasnivaló, nem
   képnézegető. Egy új fül elvinné a látogatót a szöveg közepéről. */
.case-galeria-elem img {
    border: 1px solid var(--border);
}

/* A felirat teszi a galériát leírássá: megmondja, az oldal MELYIK részét
   mutatja a kép. Enélkül a képsor csak dísz volna. A bal oldali vonal
   ugyanaz a jel, mint a listákon — összeköti a képet a mondatával. */
.case-galeria-elem figcaption {
    font-size: var(--text-sm);
    line-height: 1.5;
    color: var(--fg-sub);
    padding: 0.55rem 0 0.1rem 0.7rem;
    border-left: var(--vonal-1) solid var(--szin-szerkezet);
    margin-top: 0.55rem;
}

/* Nincs aspect-ratio és nincs object-fit: a kép a SAJÁT arányában
   jelenik meg. Ez volt az előző változat legnagyobb hibája — 16:10-re
   vágta a 16:7-es felvételeket, tehát még egyszer levágta az aljukat. */
.case-galeria-elem img {
    display: block;
    width: 100%;
    height: auto;
}

/* A galéria egy hasábba. A `columns: 1` maradvány volt abból, amikor a
   rács még CSS-multicolumn-nal készült — grid-en a `columns` tulajdonság
   NEM csinál semmit, tehát telefonon is két oszlop maradt: 160 pixel
   széles képernyőképek, amiken semmi nem olvasható. Néma hiba, mert a
   szabály ott áll, csak nem arra a tulajdonságra vonatkozik, amire kell. */
@media (max-width: 700px) {
    .case-galeria-racs { grid-template-columns: 1fr; }
}

/* Kiemelt megjegyzés-doboz */
.doc-note {
    margin: var(--space-3) 0;
    padding: var(--space-3) var(--doboz-belso);
    border-left: 2px solid var(--fg);
    background: var(--felulet);
    font-size: var(--text-base);
    line-height: 1.7;
}

.doc-note strong { display: block; margin-bottom: 0.3rem; }

/* Vissza-link a lap alján */
.doc-back {
    margin-top: var(--space-6);
    padding-top: var(--space-3);
    border-top: var(--divider);
    font-size: var(--text-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

/* Footer jogi linkek */
.footer-links {
    display: flex;
    gap: var(--space-3);
    flex-wrap: wrap;
}

/* ────────────────────────────────────────────────────────────
   ESETTANULMÁNY
   A .doc-* stílusokra épül, csak a fejrészben tér el.
   ─────────────────────────────────────────────────────────── */
.case-title {
    font-family: var(--font);
    font-size: clamp(2.2rem, 5vw, 3.8rem);
    font-weight: 300;
    letter-spacing: 0;
    line-height: 1.02;
    margin: var(--space-3) 0 var(--space-2);
    color: var(--fg);
}

.case-sub {
    font-size: var(--text-lg);
    font-weight: 300;
    line-height: 1.5;
    letter-spacing: 0;
    color: var(--fg-sub);
    max-width: var(--mertek);
    margin-bottom: var(--space-4);
}

/* Bevezető bekezdés — nagyobb, mint a törzsszöveg */
.case-lead {
    font-size: var(--text-lg);
    font-weight: 300;
    line-height: 1.65;
    letter-spacing: 0;
    color: var(--fg-sub);
    padding-bottom: var(--space-4);
    border-bottom: var(--divider);
    margin-bottom: var(--space-4);
    /* 74 karakteres sorokat adott: a felvezetőnek ugyanaz a mértéke,
       mint a `.case-sub`-nak. */
    max-width: var(--mertek);
}

/* Idézet az ügyféltől / a saját ajánlatból */
.case-quote {
    margin: var(--space-4) 0;
    padding-left: var(--space-3);
    border-left: 2px solid var(--border);
    font-size: var(--text-base);
    font-style: italic;
    line-height: 1.7;
    color: var(--fg-sub);
}

.case-quote cite {
    display: block;
    margin-top: var(--space-1);
    font-style: normal;
    font-size: var(--text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

/* ── „Ha ez a helyzeted" blokk ───────────────────────────────
   Ez a lap legfontosabb eleme: egyszerre az, amit a látogató
   30 másodperc alatt elolvas, és amit egy nyelvi modell
   egészben ki tud emelni válaszként. Ezért áll elöl és ezért
   önmagában megálló.
   ─────────────────────────────────────────────────────────── */
/* A helyzet/megoldás/eredmény blokk a lap legfontosabb mezője:
   teljes keret, kék, a tetején vastag kiemeléssel. */
.case-situation {
    margin: var(--space-4) 0 var(--space-6);
    border: 1px solid var(--szin-szerkezet);
    border-top: var(--vonal-2) solid var(--szin-kiemeles);
    padding: 0 var(--doboz-belso);
    background: var(--felulet);
}

.case-situation > div {
    display: grid;
    /* A címke-oszlop KORLÁTOZOTT arányú, nem fix 150 képpont: 320 képpont
       széles képernyőn, 200%-os szöveg-nagyításon a fix érték a hely
       felét vitte el, és a `dd` 52 képponttal kilógott. A `minmax(0, 1fr)`
       pedig feloldja a rács alapértelmezett `min-width: auto`-ját, ami
       nem engedi a szöveget a saját min-content mérete alá. */
    grid-template-columns: min(150px, 34%) minmax(0, 1fr);
    gap: var(--space-3);
    padding: var(--space-3) 0;
}

/* Nagyításon a keret és a belső tér is szűkül, hogy a szövegnek maradjon hely. */
@media (max-width: 480px) {
    .case-situation > div { grid-template-columns: minmax(0, 1fr); row-gap: 0.35rem; }
}

.case-situation > div + div { border-top: var(--divider); }

.case-situation dd,
.case-situation dt { overflow-wrap: anywhere; }

.case-situation dt {
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--fg-muted);
    padding-top: 4px;
}

.case-situation dd {
    margin: 0;
    font-size: var(--text-base);
    line-height: 1.7;
    color: var(--fg-sub);
    letter-spacing: -0.01em;
}

.case-situation dd strong { color: var(--fg); font-weight: 500; }

/* ────────────────────────────────────────────────────────────
   RENDSZERÁBRA — a vizuális gerinc
   Nem illusztráció, hanem a megépített rendszer rajza. Minden
   esettanulmányhoz egy, azonos szabályokkal:
     · hajszálvékony vonal, semmi kitöltés, éles sarok
     · monokróm — mindent a currentColor visz, így a világos és
       sötét mód automatikusan helyes
     · sok üres tér, semmi dísz
     · a feliratok VALÓDI SZÖVEGEK az SVG-ben, nem kép — így a
       nyelvi modellek is olvassák (ez a GEO-hozadéka)
   ─────────────────────────────────────────────────────────── */
/* A görgethető ábradoboz nem szélesítheti a lapot: a benne lévő SVG
   saját minimális szélessége a rács-elem `min-width: auto`-ján keresztül
   kifeszítené a szülőt. A doboz maga mindig a rendelkezésre álló helyet
   veszi fel, a görgetés pedig BENNE történik. */
/* Az ábra KILÉP a próza kereteiből. A feliratok viewBox-egységben
   vannak, tehát a rendereltt méretük a rajz szélességével arányos: ha a
   rajz 20%-kal szélesebb, a 9,6 pixeles alcím is 20%-kal nagyobbnak
   látszik. A saját geometriája ennél többet nem enged — a dobozok a mai
   szövegre vannak szabva, a mérés szerint 5–8% a szabad tartalék. Ami
   ezen felül van, azt a rajzok újrarajzolása adná. */
.case-diagram {
    width: 100%;
    max-width: none;
    min-width: 0;
    margin: var(--space-6) 0;
    padding: var(--space-4) 0;
    border-top: var(--divider);
    border-bottom: var(--divider);
}

.case-diagram svg {
    display: block;
    width: 100%;
    height: auto;
    color: var(--fg-sub);
    overflow: visible;
}

/* A diagram-nyelv szabályai — minden ábrára egyformán */
.case-diagram .d-box {
    fill: none;
    stroke: currentColor;
    stroke-width: 1;
}

/* A rendszerábra is a terv része: minden vonal kék. A SORREND itt
   számít — a HTML-ben `class="d-box d-box-strong"` áll, tehát mindkét
   szabály illeszkedik, és azonos specificitásnál a későbbi nyer.
   Ezért kell a kiemelésnek utoljára jönnie. */
.case-diagram .d-box { stroke: var(--szin-szerkezet); }

/* ── A vonal és a nyílhegy ───────────────────────────────────
   A két szabály EGYBEN áll, mert szétszórva pont az történt, ami
   ellen a fenti komment szól: lentebb egy `stroke: currentColor` és
   egy `fill: currentColor` visszaírta mindkettőt szürkére. A komment
   azt állította, hogy „minden vonal kék", a lapon viszont szürkék
   voltak — a későbbi szabály nyert.

   A szár SOSEM kap kitöltést. Ez nem óvatosság: a `d-arrow` osztályon
   nincs `stroke`, csak `fill`, tehát ha egy NYITOTT útvonal kapja meg,
   a böngésző lezárja és kitölti. Egy „M95 120 V90 H350 V76" útvonalból
   így nem vonal lett, hanem egy nagy tömör ék — 72 helyen az oldalon.
   A szár mostantól `d-line`, a nyílhegy külön, zárt `d-arrow`. */
.case-diagram .d-line {
    fill: none;
    stroke: var(--szin-szerkezet);
    stroke-width: 1;
}

.case-diagram .d-arrow {
    fill: var(--szin-szerkezet);
    stroke: none;
}

/* A szív az ábrán: egyetlen doboz minden diagramon, bíborral és
   vastagabban. Ahol nincs doboz — például a testreszabás
   költséggörbéjén —, ott a VONAL viszi ezt a szerepet. */
.case-diagram .d-box-strong { stroke: var(--szin-kiemeles); stroke-width: var(--vonal-1); }
.case-diagram .d-line-strong { stroke: var(--szin-kiemeles); stroke-width: var(--vonal-1); }

/* Visszafelé menő ág: ami nem előre visz a folyamatban, hanem vissza —
   egy elbukott ellenőrzés, egy elvágott út. Szaggatott és bíbor, hogy a
   szem az előrehaladástól elkülönítse; a tervrajzokon ugyanígy jelölik
   azt, ami nem a fő vonal. */
.case-diagram .d-arrow-back {
    fill: none;
    stroke: var(--szin-kiemeles);
    stroke-width: 1.5;
    stroke-dasharray: 5 4;
}

.case-diagram .d-line-dash { stroke-dasharray: 3 3; opacity: 0.55; }

/* Kitöltött jel — ott használjuk, ahol azt kell mutatni, hogy egy sor
   egy oszlopra ÉRVÉNYES-e. Üres cella = nem érinti. Így nem kell hozzá
   se jelmagyarázat, se pipa-karakter (az nincs a betűkészletünkben). */
.case-diagram .d-fill { fill: var(--szin-kiemeles); stroke: none; }

/* ── A feliratméret a viewBox-tól FÜGGETLENÜL azonos a képernyőn ──
   Az SVG-ben a `font-size` felhasználói egységben mérődik, tehát ugyanaz
   a szám más ábrán MÁS méretben jelenik meg. Mérve: ugyanaz az osztály
   17,5px-től 29,1px-ig szórt, attól függően, milyen széles a rajz
   viewBoxa. Ez nem stílus volt, hanem véletlen.

   Az `--vb` — a rajz saját viewBox-szélessége, a `style` attribútumban —
   ezt kiegyenlíti. A szorzó a 920px-es hasábra van hitelesítve.

   Az arány szándékosan szűk: a leírás alig kisebb a címnél (17 : 15,5).
   Korábban 13,3 : 9,6 volt, vagyis 1,39× — ettől lett a kisebbik nehezen
   olvasható. A cím maga nem nőtt; a leírás jött fel hozzá. */
.case-diagram svg {
    --vb: 700;      /* a rajz saját viewBox-szélessége — az osztály írja felül */
    --hasab: 920;   /* ennyi képpont szélesen jelenik meg ténylegesen */
}

/* A viewBox-szélesség OSZTÁLYKÉNT, nem `style` attribútumként. Így az
   éles kiszolgálón a `style-src` nem kényszerül `unsafe-inline`-ra —
   a lap adatkezelési tájékoztatója azt állítja, hogy semmilyen külső
   erőforrást nem tölt be, és ezt egy szigorú CSP gépi szinten is
   kikényszeríti. Egy inline stílus-attribútum ezt a lakatot lazítaná
   fel, hetven ábra kedvéért. */
.case-diagram svg.vb-460 { --vb: 460; }
.case-diagram svg.vb-480 { --vb: 480; }
.case-diagram svg.vb-500 { --vb: 500; }
.case-diagram svg.vb-520 { --vb: 520; }
.case-diagram svg.vb-760 { --vb: 760; }

.case-diagram .d-label {
    fill: var(--fg);
    font-family: var(--font);
    font-size: calc(var(--vb) / var(--hasab) * 17px);
    font-weight: 500;
    letter-spacing: -0.01em;
}

.case-diagram .d-sub {
    fill: currentColor;
    font-family: var(--font);
    font-size: calc(var(--vb) / var(--hasab) * 15.5px);
    font-weight: 400;
    opacity: 0.75;
}

.case-diagram .d-note {
    fill: currentColor;
    font-family: var(--font);
    font-size: calc(var(--vb) / var(--hasab) * 13.5px);
    font-weight: 500;
    /* 0,08em volt: arányos betűnél a nagybetűs sor levegőt kér. Monospace
       viszont eleve egyenletes közű — a ritkítás itt csak 13% fölösleges
       szélesség volt, amitől két jegyzet ki is lógott. */
    letter-spacing: 0.02em;
    text-transform: uppercase;
    opacity: 0.6;
}


.case-diagram figcaption {
    margin-top: var(--space-3);
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--fg-muted);
    max-width: var(--mertek);
}

/* Mobilon az ábra nem zsugorodhat a felismerhetetlenségig.
   Az SVG feliratai viewBox-egységben vannak, tehát a lekicsinyítéssel EGYÜTT
   zsugorodnak: egy 700 egységes viewBox 311 px-en 0,44x — a 13px-es felirat
   így 5,8 px lesz. A viewBox-beli betűméret emelése nem segít (az is
   zsugorodik), viszont kilöki a feliratot a dobozából — mérve: a klinika-ábra
   „soronkénti mentés, jelzés" felirata 15px-nél 6 px-szel túlnyúlt.
   Ezért az ábra megtartja a minimális léptékét, és a sáv görgethető lesz —
   ugyanaz a minta, mint a táblázatoknál és a kódblokkoknál. */
@media (max-width: 700px) {
    .case-diagram {
        margin: var(--space-4) 0;
        overflow-x: auto;
    }
    .case-diagram svg { min-width: 600px; }

    /* A magas ábra korábban kivétel volt: nem görgetett, helyette a
       viewBox-beli betűméretet emeltük 17/14/13-ra. Ez arányos betűnél
       működött („a legszűkebb margó 81 egység"), monospace-ben viszont
       nincs meg az a margó — a 14px-es alcím a dobozon kívülre kerülne.
       Ezért a magas ábra is a többi mintáját követi: megtartja a léptékét,
       és a sáv görgethető. 600 px-es minimumon a 8px-es alcím 11,4
       képpontként jelenik meg — nagyobb, mint a korábbi kivétel adott. */
}

/* ────────────────────────────────────────────────────────────
   ÜGYFÉLVÉLEMÉNY az esettanulmányban
   Az érintett ügyfél saját Google-véleménye, a lap közepén — ott,
   ahol az olvasó már érti a munkát, és épp azt mérlegeli, megbízna-e.
   A forrásra mutató link nélkül ez csak egy állítás lenne.
   ─────────────────────────────────────────────────────────── */
.case-review {
    margin: var(--space-6) 0;
    padding: var(--space-4) var(--doboz-belso);
    border: 1px solid var(--border);
    border-left: 2px solid var(--fg);
    background: var(--felulet);
}

.case-review-stars {
    font-size: var(--text-sm);
    letter-spacing: 0.24em;
    color: var(--fg);
    margin-bottom: var(--space-2);
}

.case-review blockquote {
    font-size: var(--text-base);
    font-weight: 300;
    line-height: 1.6;
    letter-spacing: 0;
    color: var(--fg);
    margin: 0 0 var(--space-3);
}

.case-review figcaption {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: var(--space-1) var(--space-3);
    font-size: var(--text-xs);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
}

.case-review figcaption a {
    border-bottom: 1px solid var(--border);
}

.case-review figcaption a:hover {
    border-bottom-color: var(--fg);
    color: var(--fg);
    opacity: 1;
}

@media (max-width: 700px) {
    /* Csak a fuggoleges levego szukul; a vizszintes belso margot a
       `--doboz-belso` viszi. A roviditett `padding: X` mind a negy oldalt
       atirta volna - pont az egysegesseget torve el. */
    .case-review { padding-block: var(--space-3); }
}

/* ── Rétegváltó — innentől a technikai kibontás ──────────────
   Jelzés mindkét közönségnek: az embernek, hogy innentől nyugodtan
   abbahagyhatja; a nyelvi modellnek, hogy itt kezdődik a részletes,
   idézhető szakasz.
   ─────────────────────────────────────────────────────────── */
/* MÉLYSÉG — a rétegváltó vonala. Az a pont, ahol a lap emberi
   olvasmányról technikai kibontásra vált: a szöveg legjelentésesebb
   törése, tehát ez érdemli a legmélyebb színt. Bíbor.

   A fókusz-gyűrű SZÁNDÉKOSAN marad fekete: azt csak billentyűzetes
   navigációnál látni — dizájnelemként láthatatlan volna, és ott a
   kontraszt fontosabb, mint a karakter. */
.case-layer {
    margin: var(--space-8) 0 var(--space-6);
    padding-top: var(--space-4);
    border-top: 2px solid var(--szin-melyseg);
}

.case-layer h2 {
    margin-top: var(--space-2) !important;
    padding-top: 0 !important;
    border-top: none !important;
}

.case-layer-note {
    font-size: var(--text-base);
    line-height: 1.7;
    color: var(--fg-muted);
    max-width: var(--mertek);
    margin-top: var(--space-1);
}

/* Záró blokk — a látogató következő lépése */
/* ── Keret sarokjelekkel — a terv mezője ─────────────────────
   A doboz kék kerete és két bíbor sarokjel: a nyomdai vágójelek
   logikája. Ettől nem doboz lesz belőle, hanem MEZŐ egy terven.
   ─────────────────────────────────────────────────────────── */
.case-next {
    margin-top: var(--space-6);
    padding: var(--space-4) var(--doboz-belso);
    border: 1px solid var(--szin-szerkezet);
    background: var(--felulet);
    position: relative;
}

.case-next::before,
.case-next::after {
    content: '';
    position: absolute;
    width: 14px;
    height: 14px;
    border: var(--vonal-1) solid var(--szin-kiemeles);
}

.case-next::before { top: -1px;    left: -1px;  border-right: 0; border-bottom: 0; }
.case-next::after  { bottom: -1px; right: -1px; border-left: 0;  border-top: 0; }

.case-next p {
    font-size: var(--text-base);
    line-height: 1.7;
    margin-bottom: var(--space-2);
}

/* Az e-mail-cím SOHA nem nagybetűs. A cím a valóságban kisbetűs, és bár a
   levelezés a helyi részt technikailag kis- és nagybetű-érzékenyen kezelheti,
   a látogató azt írja le, amit lát — nagybetűs alakban pedig kétséges, hogy
   pontosan mit gépeljen be. Egy elérhetőség nem tipográfiai díszítés helye. */
.case-next a.case-next-mail {
    font-family: var(--font-display);
    font-size: clamp(1.2rem, 3vw, 1.9rem);
    letter-spacing: -0.01em;
    color: var(--fg);
    border-bottom: 1px solid var(--border);
    word-break: break-word;
}

.case-next a.case-next-mail:hover { border-bottom-color: var(--fg); opacity: 1; }

/* ────────────────────────────────────────────────────────────
   RESZPONZÍV — tablet és mobil
   ─────────────────────────────────────────────────────────── */
@media (max-width: 960px) {
    /* A 220 pixeles oldalsáv asztali arány: 1440-en a szélesség 15%-a.
       Tablet állóban (768) ugyanez már 29% — a képernyő majdnem harmada
       öt rövid menüpontnak, miközben a tartalomnak 469 pixel marad.
       A sáv innentől arányos: 768-on 169, 960-on 211 pixel. A menü
       ugyanaz marad, csak nem visz el a tartalom elől helyet.

       A clamp ALSÓ vége nem ízlés kérdése: a leghosszabb menüpont
       („Szolgáltatások") 139 pixel a saját dobozával együtt, a sávnak
       pedig 2×16 pixel belső margója van. 171 alatt tehát a menüpont
       kilógna a sávból — a 180 ezt tartja, tartalékkal. */
    :root { --sidebar: clamp(180px, 23vw, 220px); }

    .about-grid         { grid-template-columns: 1fr; gap: var(--space-3); }
    .ref-item           { grid-template-columns: 1fr auto; }
    .ref-year           { display: none; }

    /* A szolgáltatás LEÍRÁSA eddig egyszerűen eltűnt 960 alatt
       (`display: none`). Telefonon ettől négy csupasz szó maradt a
       szekcióból — „Rendszerek", „Karbantartás", „Google Ads",
       „AI-láthatóság" —, amiből a látogató nem tudja meg, mit takarnak.
       Épp azon a készüléken tűnt el a tartalom, ahol a legkevesebb
       türelem van a kitalálásra.

       Helyette a leírás a NÉV ALÁ kerül, a második oszlopba. Balra
       igazítva: a jobbra igazítás a kétoszlopos elrendezés logikája
       volt, ahol a szöveg a sor túlsó végén zárt — egyhasábosan az
       csak rongyos bal szélt adna. */
    .service-item {
        grid-template-columns: 2.5rem 1fr;
        gap: var(--space-1) var(--space-2);
        align-items: baseline;
    }

    .service-desc {
        grid-column: 2;
        text-align: left;
        max-width: none;
    }
    /* A .container padding-override-ja innen KIKERÜLT: ez volt az a lépcső,
       ami 960 pixelnél 8vw-ről 2rem-re rántotta a margót. A --margo
       arányos, tehát ezen a ponton nincs mit felülírni. */
    .hero-grid          { grid-template-columns: 1fr; gap: var(--space-4); }

    /* A cím mobilon MÁS mércét kíván. A cqw a saját oszlopához méretez, ami
       egyhasábos elrendezésben a teljes szélesség — a kétoszlopos rácsra
       hangolt 11,5cqw itt túl nagyra nő. A 9,2cqw ugyanazt az arányérzetet
       adja egyhasábosan, és a felső korlát megakadályozza, hogy tabletnél
       újra elszaladjon. */
    .hero-title {
        font-size: min(3.2rem, 9.2cqw);
        /* A `line-height: 1` mellett a betű a SAJÁT SORÁN KÍVÜLRE
           rajzolódik: mérve öt-nyolc képponttal fent és lent. A rács
           rése ezt nem tudja — az a sordobozzal számol, nem a betűvel.
           Álló tájolásban 27, fekvőben 24 képpont marad a portré aljáig.

           Ez a ráhagyás a betű tényleges rajzterületét adja vissza a
           dobozának. Azért `em` és nem képpont: ha a szöveg bármitől
           megnő — iOS-autosizing, rendszerszintű szövegméret,
           oldalnagyítás —, a ráhagyás vele együtt nő. Egy fix érték
           pont ott hagyna cserben, ahol a legnagyobb szükség van rá. */
        padding-top: 0.14em;
    }
    /* A korábbi 4/3-as doboz egy 2:3 arányú képet vágott, KÖZÉPRE igazítva —
       ettől a fejtető lecsúszott róla. Akkor ez volt a kisebb rossz, mert a
       kép alján elhalás futott, és a felülről igazítás azt az állra hozta
       volna: lebegő fej lett volna belőle.

       Az elhalás azóta megszűnt (a keret mindkét színsémában ott van), tehát
       a felülről igazítás akadálya elhárult. A doboz most közel négyzetes és
       a kép TETEJÉHEZ igazodik: a fej egészben marad, alatta a váll és a
       zakó — pontosan az, ami egy portréból számít. */
    /* Mobilon a doboz közel négyzetes: a fej egészben marad, alatta a
       váll és a zakó. Az arányt itt is a köztes doboz tartja. */
    .hero-image-wrap { max-width: 420px; }
    .hero-image-box  { padding-bottom: 100%; }
    .hero-image         { object-position: center top; }

    /* Egyhasábos elrendezésben a portré megy előre. Az arc az, ami egy
       személyes márkánál elsőként azonosít — a szöveg utána jön. A HTML
       sorrendje marad (a gép a nevet olvassa először), csak a MEGJELENÍTÉS
       cserél: ez a rács `order`-je, nem markup-változtatás. */
    .hero-image-wrap    { order: -1; }
}


/* ── Lábléc keskeny nézetben (960 alatt) ─────────────────────
   A középre zárt, tördelt linksor azért volt rendetlen, mert a sortörés
   helyét a SZÉLESSÉG döntötte el, nem a jelentés: az „Impresszum" azért
   került a rovatlinkek mellé, mert éppen elfért. Középre zárva ráadásul
   egyetlen éle sincs, amihez a szem igazodhatna — pedig a lap minden más
   szekciója a bal margó-vonalról indul.

   Innentől három sáv, súllyal csökkenő sorrendben: felül a két rovat
   teljes értékű célpontként, saját bal oldali jelzővonallal (ugyanaz a
   forma, mint a szolgáltatás- és referencialistán), alatta hajszálvonal
   mögött a három jogi link egy halk sorban, legalul a legkisebb betűs
   aláírás. A törés helyét a JELENTÉS adja.

   A határ 960 és nem 700: tablet állóban a három csoport már nem fér ki
   egy sorba, és a tördelés ott azt adta, hogy az aláírás és a rovatok egy
   sorban maradnak, a jogi linkek pedig alájuk esnek — épp a fordított
   rangsor. */
@media (max-width: 1023px) {
    .site-footer {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        text-align: left;
        padding: var(--space-3) var(--margo) var(--space-4);
    }


    .footer-links {
        justify-content: flex-start;
        gap: 0.35rem var(--space-3);
        margin-top: var(--space-2);
    }

    .footer-copy {
        margin-top: var(--space-2);
        font-size: 0.68rem;
        opacity: 0.75;
    }
}

@media (max-width: 700px) {
    /* Sidebar → top bar */
    :root {
        --sidebar: 0px;

        /* A függőleges ritmus asztali képernyőre készült. A 8rem-es
           alapból a Referenciák és a Kapcsolat 1,55-szörös levegőt kap:
           198 pixel fent ÉS lent. Egy 812 pixel magas telefonon ez a két
           üres sáv együtt majdnem fél képernyő — a látogató üres feketén
           görget végig, mielőtt a következő szekcióhoz érne.

           Az ARÁNYOK érintetlenek: a szorzók (1,55 · 1,2 · 0,55) ugyanazok
           maradnak, csak az alap kisebb. A ritmus tehát megmarad, a
           léptéke igazodik a képernyőhöz. */
        --space-8: 4.25rem;
    }

    body { display: block; }

    .site-header {
        position: fixed;
        top: 0; left: 0; right: 0; bottom: auto;
        width: 100%;
        height: 56px;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        /* A backdrop-filter CONTAINING BLOCKOT hoz létre a position: fixed
           leszármazottaknak. Emiatt a menü-overlay nem a képernyőhöz igazodott,
           hanem ehhez az 56 pixeles sávhoz: a nyitott menü 41 pixel magas lett,
           háttér nélkül, a menüpontok pedig kifolytak a lap szövegére.

           Mobilon nincs is szükség üvegre — a sáv tömör, a menü fölötte teljes
           képernyős. A szűrő levételével a fixed pozíció újra a viewporthoz
           mér. */
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        background: var(--bg);
        /* Itt a fejléc már teljes szélességű sáv, nem keskeny oszlop —
           tehát a fő margó jár neki, hogy a logó a tartalommal egy
           vonalban álljon. */
        padding: 0 var(--margo);
        border-right: none;
        border-bottom: var(--divider);
    }

    .nav-logo { margin-bottom: 0; }

    /* A menü nem BECSÚSZIK oldalról, hanem LEGÖRDÜL: a clip-path felülről
       nyitja ki a panelt, mint egy lehúzott tervrajzot. A különbség nem
       csak ízlés kérdése — csúsztatásnál a menüpontok a panellel EGYÜTT
       mozognak, tehát oldalról érkeznek a helyükre; itt a helyükön
       maradnak, és a lefutó él fedi fel őket. Ez az, ami a lap többi
       animációjával egy nyelvet beszél: sehol nem repül semmi.

       A `visibility` késleltetve vált vissza (`0s linear` a záró idő
       végén), különben a panel a záróanimáció alatt eltűnne, és a
       nyitás-zárás aszimmetrikussá válna. */
    /* ÜVEG HELYETT FELÜLET. Az asztali fejlécen azért ártalmatlan a
       `backdrop-filter`, mert NINCS mögötte semmi: a tartalom
       `margin-left: var(--sidebar)`-ral elkerüli a sávot, tehát ott az
       üveg gyakorlatilag textúra a lap alapszínén. Mobilon ugyanez a
       token egy TELJES KÉPERNYŐS panel mögé kerülne, a lap teljes
       szövegével — ugyanaz a recept, ellentétes eredmény: a menüpontok
       mögött folyton más világosságú folt úszna, és a teljes képernyős
       `backdrop-filter` a legdrágább dolog, amit egy telefon GPU-jától
       kérni lehet.

       A panel ehelyett a lap saját ABLAK-FELÜLETÉT kapja. Ugyanaz a
       fogalom, mint az adatlapon vagy a kódblokkon: ami a szövegfolyam
       fölé emelkedik, az más síkon van. A mélységet anyag és él mondja
       ki, nem optika. */
    .site-nav {
        /* Mobilon nagyobb a menüpontok betűje, tehát ugyanaz a kilenc sor
           több helyet kér — a térközök ezért itt szorosabbra vannak fogva,
           mint az oldalsávban. A `clamp` felső vége így is a korábbi
           1,5rem, tehát nagy képernyőn (tablet állóban) a látvány marad. */
        --nav-koz:  clamp(0.4rem, 1.9vh, 1.5rem);
        --nav-koz:  clamp(0.4rem, 1.9dvh, 1.5rem);
        --nav-valt: clamp(0.5rem, 2.2vh, 1.5rem);
        --nav-valt: clamp(0.5rem, 2.2dvh, 1.5rem);
        --nav-pad:  clamp(0.9rem, 2.4vh, 1.5rem);
        --nav-pad:  clamp(0.9rem, 2.4dvh, 1.5rem);

        position: fixed;
        inset: 56px 0 0 0;
        background: var(--felulet);
        padding: var(--nav-pad) var(--margo);
        flex-direction: column;
        border-right: none;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        transform: none;
        clip-path: inset(0 0 100% 0);
        visibility: hidden;
        transition: clip-path var(--t-allapot) var(--ease),
                    visibility 0s linear var(--t-allapot);
    }

    .site-nav.is-open {
        clip-path: inset(0 0 0 0);
        visibility: visible;
        transition: clip-path var(--t-allapot) var(--ease),
                    visibility 0s linear 0s;
    }

    /* A panel felső éle ugyanaz a kétszínű sáv, mint a szekcióké és a
       lábléceé: teljes szélességű kék szerkezeti vonal, rajta egy rövid
       bíbor szakasz. A nyitással együtt húzódik végig — a mozdulat maga
       a jelzés, hogy a panel most épül fel.

       Először csak a bíbor volt itt, teljes szélességben: az a lap
       leghangosabb eleme lett, pedig a menü nem esemény. A szereposztás
       mindenhol ugyanaz — kék a szerkezet, bíbor a kiemelés. */
    .site-nav::before,
    .site-nav::after {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        height: var(--vonal-1);
        transform: scaleX(0);
        transform-origin: left center;
        transition: transform var(--t-allapot) var(--ease);
    }

    .site-nav::before { width: 100%; background: var(--szin-szerkezet); }
    .site-nav::after  {
        width: calc(var(--szegmens) * 2);
        background: var(--szin-kiemeles);
        transition-delay: 0.12s;
    }

    .site-nav.is-open::before,
    .site-nav.is-open::after { transform: scaleX(1); }

    .site-nav ul {
        flex-direction: column;
        gap: var(--nav-koz);
        flex: 0;
    }

    .site-nav ul li a {
        font-size: var(--text-base);
        color: var(--fg);
    }

    /* A menüpontok lépcsőzetesen érkeznek, a lefutó él mögött. A
       késleltetés CSAK a nyitásra van: záráskor egyszerre tűnnek el, mert
       egy bezárás legyen rövid — a lassú kikapcsolás türelmetlenné tesz. */
    .site-nav ul li,
    .site-nav .nav-bottom {
        opacity: 0;
        transform: translateY(-0.4rem);
        transition: opacity var(--t-valasz) var(--ease),
                    transform var(--t-valasz) var(--ease);
    }

    .site-nav.is-open ul li,
    .site-nav.is-open .nav-bottom {
        opacity: 1;
        transform: none;
    }

    /* A LÉPCSŐZÉS KÉT LISTÁN FUT ÁT, FOLYAMATOSAN.

       A `:nth-child` listánként újraszámol, ezért a második listát külön
       kell folytatni — különben az alsó pontok a fölöttük állók ELŐTT
       érkeznének meg. Ez már kétszer elsült: a „Vélemények”
       beszúrásakor, és a Rólam áthelyezésekor.

       ITT KELL FIGYELNI: a sorok száma kötve van a menü hosszához ÉS a
       két csoport arányához. A check.sh 28. szakasza ezért számolja
       össze a menüpontokat és a szabályokat: ha új menüpont jön, szól. */
    .site-nav.is-open ul li:nth-child(1) { transition-delay: 0.10s; }
    .site-nav.is-open ul li:nth-child(2) { transition-delay: 0.15s; }
    .site-nav.is-open ul li:nth-child(3) { transition-delay: 0.20s; }
    .site-nav.is-open ul li:nth-child(4) { transition-delay: 0.25s; }
    .site-nav.is-open ul li:nth-child(5) { transition-delay: 0.30s; }

    .site-nav.is-open .nav-lapok li:nth-child(1) { transition-delay: 0.35s; }
    .site-nav.is-open .nav-lapok li:nth-child(2) { transition-delay: 0.40s; }
    .site-nav.is-open .nav-lapok li:nth-child(3) { transition-delay: 0.45s; }
    .site-nav.is-open .nav-bottom                { transition-delay: 0.50s; }

    /* Mobilon a nyelvváltó marad, az email-másolás nem kell. A blokk a
       panel ALJÁRA kerül (`margin-top: auto`), nem a menüpontok alá:
       teljes képernyős overlay-nél a lap alsó kétharmada különben üresen
       maradna, a nyelvváltó pedig a semmi közepén lógna.

       A KÉT SOR EGYMÁS MELLETT. Az oldalsávban egymás alatt állnak, mert
       ott a szélesség a szűk keresztmetszet; a telefon panelján fordítva,
       és két rövid elem alatt egy teljes sort elpazarolni 48 képpont —
       pont annyi, amennyi egy iPhone 8-on hiányzott. A rács HTML-változás
       nélkül rendezi át: a színjel a saját sorában marad, alatta balra a
       nyelvváltó, jobbra az Email.

       És ODARAGAD. Ez a garancia arra, amit a méret-igazítás önmagában
       nem tud megígérni: nagyon alacsony panelnál (régi kis készülék,
       fekvő tájolás, felnagyított rendszerbetű) a menüpontok görgethetők,
       de a panel ALJA mindig a helyén marad, nem csúszik a hajtás alá.
       Ezért kell alá felület is — enélkül a görgő menüpontok átlátszanának
       rajta. */
    .nav-bottom {
        border-top: none;
        margin-top: auto;
        padding-bottom: var(--nav-koz);

        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-areas: "jel jel"
                             "lang email";
        align-items: center;
        gap: var(--nav-jel) var(--nav-koz);
    }

    .nav-bottom::before { grid-area: jel; }
    .nav-bottom .nav-lang { grid-area: lang; }
    .nav-bottom .copy-email { grid-area: email; text-align: right; }

    /* FEKVŐ TÁJOLÁS — itt a ragadós alj többet árt, mint használ.

       Egy fekvő iPhone 8-on a panel 205 képpont magas. Kilenc menüpont
       oda semmilyen térközzel nem fér be: a betűk maguk többet kérnek.
       Ilyenkor a ragadós alj már nem megoldás, hanem akadály — a fölé
       csúszó menüpontokat eltakarná.

       A helyes viselkedés ezen a méreten a sima görgetés: az egész panel
       egyben mozog, minden elérhető, és semmi nem tűnik el más mögött.
       Nem szép, de fekvő tájolásban egy telefonon ez a várt működés.

       A tájolás-feltétel NEM elhagyható. Magában a `max-height: 480px`
       elkapja az álló tájolású kis telefont is — egy 320×454-es iPhone
       SE-n így pont a ragadós alj kapcsolt ki, és a nyelvváltó a hajtás
       alá került. Ott viszont van vízszintes szűkösség is, tehát a
       ragadós alj a helyes viselkedés. */
    @media (max-height: 480px) and (orientation: landscape) {
        /* Az elrendezés ELFORDUL a képernyővel. Ami álló tájolásban
           egymás alatt volt, itt egymás mellé kerül: a hat horgony két
           hasábba, mellettük a lapokra vivő csoport, a nyelvváltó pedig a
           saját sorába. Ugyanaz a kilenc menüpont, ugyanaz a betűméret —
           csak a rendelkezésre álló irányt használja. Egy fekvő iPhone
           8-on így 205 képpontból 180 kell, tehát görgetés nélkül elfér,
           és az alja is a helyén marad. */
        .nav-gorgo {
            flex-flow: row wrap;
            align-content: flex-start;
            column-gap: var(--space-4);
        }

        /* A hasábokhoz `display: block` kell — a `columns` flex-konténeren
           nem értelmezett. A sorok közét ezért itt margó adja, nem `gap`. */
        .nav-gorgo > ul:first-child {
            display: block;
            columns: 2;
            column-gap: var(--space-4);
            flex: 1 1 auto;
        }

        .nav-gorgo > ul:first-child li {
            margin-bottom: var(--nav-koz);
            break-inside: avoid;
        }

        /* A csoporthatár is elfordul: fölötte futó vonalból bal oldali
           lesz, mert most vízszintesen választ el. */
        .site-nav .nav-lapok {
            flex: 0 0 auto;
            margin-top: 0;
            padding-top: 0;
            border-top: none;
            border-left: var(--divider);
            padding-left: var(--nav-valt);
        }

        .nav-bottom { margin-top: var(--nav-valt); }
    }

    /* A sorok belső pereme is a magassághoz mért: nagy telefonon a
       korábbi 0,3rem, alacsony panelon szűkebb. Az érintőcél így sem
       megy 24 képpont alá — a menü-mérés ezt külön ellenőrzi. */
    .site-nav ul li a {
        padding-block: clamp(0.12rem, 0.65vh, 0.3rem);
        padding-block: clamp(0.12rem, 0.65dvh, 0.3rem);
    }
    /* Mobilon MEGMARAD, de mailto-linkként: ott a másolás értelmetlen —
       a telefonon úgyis a levelezőt akarod megnyitni, nem a vágólapra
       tenni. A viselkedést a JS választja szét, a jelölés ugyanaz. */


    /* A gomb. A két vonal ABSZOLÚT pozícióban ül, mindkettő a gomb
       közepén — nyitott állapotban csak elfordulnak, tehát pontosan a
       közepükön keresztezik egymást. A korábbi megoldás flex-sorban
       tartotta őket és `translate`-tel tolta vissza a helyükre: az így
       kapott X szárai nem egy pontban metszették egymást, és a kereszt
       enyhén elcsúszott. 44 px a gomb, mert az ujjnak ennyi kell. */
    .nav-toggle {
        display: block;
        position: relative;
        background: none;
        border: none;
        cursor: pointer;
        padding: 0;
        width: 44px;
        height: 44px;
        margin-right: -10px;
    }

    .nav-toggle span {
        position: absolute;
        left: 50%;
        top: 50%;
        width: 22px;
        height: var(--logo-vonal);
        background: var(--fg);
        transform-origin: center center;
        transition: transform var(--t-allapot) var(--ease),
                    width var(--t-allapot) var(--ease);
    }

    .nav-toggle span:first-child { transform: translate(-50%, -50%) translateY(-3.5px); }
    .nav-toggle span:last-child  { transform: translate(-50%, -50%) translateY(3.5px); }

    .nav-toggle.is-open span:first-child { transform: translate(-50%, -50%) rotate(45deg); }
    .nav-toggle.is-open span:last-child  { transform: translate(-50%, -50%) rotate(-45deg); }

    .site-main {
        margin-left: 0;
        padding-top: 56px;
    }

    .site-footer { margin-left: 0; }

    /* A fejléc itt már 56 pixeles felső sáv, amit a .site-main paddingja
       kitol — a hero magasságából tehát le kell vonni, különben a lap
       ennyivel túlnyúlik a képernyőn. (A mobil elrendezés finomhangolása
       külön menet; ez csak a túlnyúlást előzi meg.) */
    .section-hero { min-height: calc(100svh - 56px); }

    .testimonial-grid { grid-template-columns: 1fr; }

    /* Csak a függőleges levegő szűkül; a vízszintes belső margót a
       `--doboz-belso` viszi, ami magától arányos. */
    .testimonial-item { padding-block: var(--space-3); }

    /* A bal padding NEM eshet ki. A jelzővonal (::before) a sor bal
       szélén, `left: 0`-n áll, és a szöveget csak ez a padding tartja
       távol tőle — nélküle a vonal RÁFUT a referencia nevére. A rövidítő
       `padding: X 0` pontosan ezt tette: egyetlen érték elvette a bal
       oldali helyet. Ezért van itt mind a négy oldal kiírva. */
    .ref-item {
        grid-template-columns: 1fr;
        gap: var(--space-1);
        padding: var(--space-2) 0 var(--space-2) var(--space-3);
    }

    .ref-tag { display: none; }

    /* Lebegő képelőnézet érintőn nem működik — el is rejtjük */
    .ref-preview { display: none; }

    /* Dokumentum-oldal: a kulcs-érték rács egy oszlopba */
    /* Egy oszlopban a cimke-elvalaszto FUGGOLEGES vonal a semmibe lognana:
       a cimke fole kerul az ertek, tehat nincs mit elvalasztania. */
    .doc-facts div {
        grid-template-columns: 1fr;
        gap: 0.15rem;
        padding: var(--space-2) var(--doboz-belso);
    }

    .doc-facts dt { border-right: 0; padding-right: 0; }

    .doc-toc { padding-block: var(--space-3); }
}

/* ── Mozgásérzékenység ───────────────────────────────────────
   A `reduce` NEM azt jelenti, hogy „semmilyen animáció". A szó szerint
   ezt mondja: a felhasználó CSÖKKENTETT mozgást kér. A W3C útmutatója is
   így fogalmaz — a baj a NAGY, térbeli mozgás: eltolás, nagyítás,
   forgatás, parallaxis, görgetéshez kötött mozgás. Ezek okoznak
   szédülést és migrént. A szín- és átlátszóság-váltás nem: az nem
   kelt mozgásérzetet, viszont ettől érthető, hogy egy gomb reagált.

   Az eddigi szabály mindent kiütött egy `*`-os `!important`-tal. Két
   baja volt ezzel:

   1. A lap teljesen élettelenné vált — a hover nem jelzett vissza,
      a lenyíló ugrott, a menü villant. Ez nem akadálymentesség, hanem
      funkcióvesztés.
   2. iOS-en a KIS ENERGIÁJÚ MÓD is `reduce`-t jelent a Safarinak. Aki
      spórol az akkumulátorral — tehát bárki, bármikor —, ugyanezt a
      csupasz lapot kapta, pedig ő nem mozgásérzékenységet jelzett.

   Ami MARAD: átlátszóság, szín, keretszín, kitöltés — a visszajelzés.
   Ami MEGY: minden `transform` és a görgetéshez kötött mozgás; a
   szemcse-textúra pedig eleve csak `no-preference` alatt fut, mert az
   villódzás. A lenyílók magasság-animációját a JS a `matchMedia`-ból
   olvassa ki, és `reduce` alatt azonnalira vált. */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }

    /* Minden ELTOLÁS, NAGYÍTÁS, FORGATÁS azonnal a végállapotba ugrik. */
    *, *::before, *::after {
        transition-property: opacity, color, background-color, border-color,
                             outline-color, fill, stroke, box-shadow;
        animation: none !important;
        scroll-behavior: auto !important;
    }

    /* A visszajelzés-átmenet marad, csak rövidebb: érzékelhető, de nem
       elhúzódó. Késleltetés nincs — a lépcsőzetes megjelenés maga is
       mozgás-hatás, még ha az egyes elemek csak áttűnnek is. */
    *, *::before, *::after {
        transition-duration: var(--t-nyomas) !important;
        transition-delay: 0s !important;
    }

    /* Ami transformmal dolgozott, az a végállapotában induljon —
       különben elmozdulva ragadna. */
    html.js-anim [class*="section-"],
    .case-diagram,
    .abra-mobil li,
    .ref-item { opacity: 1 !important; transform: none !important; }

    @view-transition { navigation: none; }
}

/* Szituáció-blokk és záró blokk mobilon */
@media (max-width: 700px) {
    .case-situation > div {
        grid-template-columns: 1fr;
        gap: var(--space-1);
    }
    /* Csak a FÜGGŐLEGES levegő szűkül telefonon; a vízszintes belső
       margót a `--doboz-belso` viszi, egységesen minden eszközön. */
    .case-next { padding-block: var(--space-3); }
}

/* ────────────────────────────────────────────────────────────
   Kódrészlet — a technikai rétegben. Nincs syntax-highlight lib:
   a tartalom számít, nem a színezés. Vízszintesen görgethető.
   ──────────────────────────────────────────────────────────── */
.case-code {
    margin: var(--space-4) 0;
    border: 1px solid var(--border);
    background: var(--felulet);
}
.case-code-head {
    display: flex;
    justify-content: space-between;
    /* Szűk helyen inkább törjön két sorba, mint hogy kilógjon: nagyításon
       a fájlnév és a nyelv-címke együtt nem fért ki 320 képponton. */
    flex-wrap: wrap;
    gap: var(--space-2);
    padding: 0.55rem min(var(--doboz-belso), 4%);
    border-bottom: 1px solid var(--border);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
}
.case-code pre {
    margin: 0;
    padding: var(--space-3) var(--doboz-belso);
    overflow-x: auto;
    font: 0.8rem/1.55 var(--font-mono);
    color: var(--fg);
    tab-size: 4;
}
.case-code code { font: inherit; }

/* ────────────────────────────────────────────────────────────
   Bizonyíték-blokk — parancs és valódi kimenete. Ugyanaz a
   család, mint a kódrészlet, de a fejléce mondja: ez mérés.
   ──────────────────────────────────────────────────────────── */
.case-proof {
    margin: var(--space-4) 0;
    border: 1px solid var(--border);
    background: var(--felulet);
}
.case-proof-head {
    /* Ugyanaz a token, mint a blokk `pre`-jen - enelkul a fejlec felirata
       es alatta a kimenet nem all egy vonalban. */
    padding: 0.55rem var(--doboz-belso);
    border-bottom: 1px solid var(--border);
    font-size: 0.72rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--fg-muted);
}
.case-proof pre {
    margin: 0;
    padding: var(--space-3) var(--doboz-belso);
    overflow-x: auto;
    font: 0.8rem/1.55 var(--font-mono);
    color: var(--fg);
}
.case-proof .p-cmd { opacity: 0.6; }

/* ────────────────────────────────────────────────────────────
   Szerzői blokk — entitás-kötés a lap alján.
   ──────────────────────────────────────────────────────────── */
/* A név `white-space: nowrap`, tehát a sor bal fele fix szélességű. A
   mellette álló bekezdés flex-elem, aminek az alapértelmezett
   `min-width: auto`-ja nem engedi a saját min-content szélessége alá —
   így 280 pixeles kijelzőn (összecsukott Galaxy Z Fold) 22 pixellel
   kilógott a lapból. A `wrap` + `min-width: 0` páros egyben oldja meg:
   ha nincs hely egymás mellett, a bekezdés a név ALÁ kerül. */
.author-box {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1) var(--space-3);
    align-items: baseline;
    /* A `--space-5` NINCS definialva a :root-ban - a skala 1-2-3-4-6-8.
       Egy nem letezo custom property ervenytelenne teszi a deklaraciot,
       tehat a felso margo eddig NULLA volt, neman. */
    margin: var(--space-6) 0 0;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.author-box > * { min-width: 0; }
.author-box .a-name {
    font-family: var(--font-display);
    font-size: 1.15rem;
    letter-spacing: 0.04em;
    white-space: nowrap;
}
.author-box p { margin: 0; font-size: var(--text-sm); color: var(--fg-muted); }
.author-box a { color: inherit; }

/* ── Diagram-berajzolódás görgetésre ─────────────────────────
   A vonalak stroke-dashoffsettel "húzódnak ki", amikor az ábra
   a nézetbe ér. Mozgásérzékenységnél nincs animáció.            */
@media (prefers-reduced-motion: no-preference) {
    /* Csak akkor rejtünk az animációhoz, ha a JS jelen van (js-anim) —
       JS nélkül a diagram azonnal, teljesen látszik. */
    /* A berajzolódás normalizált úthosszon fut. Korábban fix 240 egység volt
       a minta — csakhogy a leghosszabb összekötő vonal 540 egység, tehát a
       vége felett a minta „off" fázisba fordult, és a vonal FÉLBEVÁGVA maradt
       az animáció után is. Mérve: 19 vonal volt hosszabb 240-nél.
       A pathLength="1" attribútummal minden vonal 0→1 tartományban rajzolódik,
       a tényleges hosszától függetlenül és egyenletes ütemben.
       A .d-line-dash SZÁNDÉKOSAN nem kap pathLength-et: annak a 3-3 egységes
       mintája user-egységben kell maradjon, különben egyetlen dash lenne. */
    html.js-anim .case-diagram svg .d-line {
        stroke-dasharray: 1;
        stroke-dashoffset: 1;
    }
    html.js-anim .case-diagram svg .d-line-dash { stroke-dasharray: 3 3; stroke-dashoffset: 0; }
    html.js-anim .case-diagram svg .d-arrow,
    html.js-anim .case-diagram svg .d-box,
    html.js-anim .case-diagram svg text { opacity: 0; transition: opacity var(--t-felulet) var(--ease) 0.45s; }
    html.js-anim .case-diagram.is-drawn svg .d-line {
        animation: case-draw var(--t-felulet) var(--ease) forwards;
    }
    html.js-anim .case-diagram.is-drawn svg .d-arrow,
    html.js-anim .case-diagram.is-drawn svg .d-box,
    html.js-anim .case-diagram.is-drawn svg text { opacity: 1; }
    @keyframes case-draw { to { stroke-dashoffset: 0; } }
}

/* ════════════════════════════════════════════════════════════
   LEÜTÉS ÉS LECSENGÉS — a kattintás pillanata

   A lapon eddig egyetlen elem sem jelezte a LENYOMÁST, csak a hovert
   — érintőképernyőn ez azt jelenti, hogy semmit.

   A leütés eredetileg 0s-os átmenettel érkezett, hogy azonnali legyen.
   Kristóf jelezte, hogy ettől VILLAN: a hover 0,42 s alatt épült fel,
   a lenyomás egy képkocka alatt letörölte, majd megint 0,42 s alatt
   jött vissza. A kemény él és a lassú visszatérés együtt adta a
   villanást — nem a mélység volt sok, hanem az átmenet hiánya.

   Most 0,09 s a leütés: a kézi reakcióidő alatt van, tehát ugyanúgy
   azonnalinak érződik, de nincs éle. A mutató-visszajelzés (szín,
   opacitás, aláhúzás) pedig 0,42-ről 0,18-ra jött — a lap lassúsága
   a nagy felületeké, nem a kurzor alatti elemeké.

   A blokk a fájl VÉGÉN áll, és ez nem ízlés kérdése: több érintett
   hover-szabály (.doc-body a:hover, .shift-cta:hover, .nav-lang
   a:hover, .site-nav li:hover a) azonos specificitású a párjával,
   tehát csak a későbbi forráspozíció győzi le őket.
   ════════════════════════════════════════════════════════════ */

/* A lecsengéshez a tulajdonságnak benne kell lennie az elem
   transition-listájában. Ezek a listák eddig csak azt tartalmazták,
   amit a hover mozgat — az opacity kimaradt belőlük. */
.site-nav li a,
.nav-lang a             { transition: color var(--t-valasz) var(--ease),
                                      opacity var(--t-valasz) var(--ease); }

/* Linkek — egy fokkal a hover 0,45-je alatt. */
a:active { opacity: 0.28; transition-duration: var(--t-nyomas); }

/* Az aláhúzott törzsszöveg-linkek hover-szabálya opacity: 1-et ír, és
   magasabb specificitású az a:active-nál — ezért itt külön, azonos
   szinten kell kimondani. Náluk nem az átlátszóság, hanem az aláhúzás
   elsötétedése a lenyomás jele. */
.doc-body a:active,
.doc-toc a:active,
.faq-a a:active,
.shift-cta:active,
.case-next a.case-next-mail:active,
.case-review figcaption a:active {
    opacity: 0.6;
    border-bottom-color: var(--fg);
    transition-duration: var(--t-nyomas);
}

/* Gombok — mindegyik eltér a saját hover-értékétől, különben a
   lenyomás nem különböztethető meg a rámutatástól. */
.copy-email:active,
.nav-lang a:active,
.site-nav li a:active      { opacity: 0.55; transition-duration: var(--t-nyomas); }

/* GYIK — a lap leggyakoribb interaktív eleme (196 db). A + ikon egy
   pixelt süllyed lenyomás alatt. A nyitott állapotnak SAJÁT szabály
   kell, azonos hosszúságú transform-listával: enélkül a böngésző
   mátrix-interpolációt végez, és az ikon megpördülne. */
/* Az ikon két vonala egy pixelt süllyed lenyomáskor. A függőleges
   vonalnak külön kell, mert nyitva már el van forgatva — ha csak
   translateY-t írnánk rá, a forgatás elveszne. */
.faq-q:active > h3::after,
.faq-q:active > h3::before {
    transform: translateY(1px);
    transition-duration: var(--t-nyomas);
}
details.faq-item[open] .faq-q:active > h3::before {
    transform: rotate(90deg) translateX(1px);
    transition-duration: var(--t-nyomas);
}

/* ════════════════════════════════════════════════════════════
   VETÍTÉSINDÍTÁS — a jel felépül

   A lap eddig egyszerűen ott volt. Ez az egyetlen belépő mozdulat,
   és a lehető legkisebb helyen történik: a sidebar alján a három
   színszakasz egymás után jelenik meg, balról jobbra.

   Miért pont ez: a vetítőgép a lámpával indul, nem a filmmel. A
   kalibrációs sáv az első, ami a vászonra kerül — utána jön a kép.
   A tartalom közben végig olvasható: a jel a lap SZÉLÉN van, nem
   takar semmit, és nem késleltet semmit.

   Egyszer fut, 0,62 másodperc, aztán soha többé.

   NEM mozdul, csak megjelenik. Az első verzióm clip-path-szal
   húzta ki balról jobbra — két hibával: (1) a clip-path a doboz
   határán vág, a box-shadow viszont AZON KÍVÜL van, tehát a kék és
   a sárga szakasz egyszerűen eltűnt; (2) Kristóf korábban kimondta,
   hogy a sidebaron mozgó szín elvonja a figyelmet — a húzás pont az
   lett volna. Marad a tiszta fény.
   ════════════════════════════════════════════════════════════ */
@media (prefers-reduced-motion: no-preference) {
    html.js-anim .nav-bottom::before {
        animation: jel-felepul var(--t-felulet) var(--ease) both;
    }
}

@keyframes jel-felepul {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── Épülő munka a referencialistán ──────────────────────────
   A lista élén egy FOLYAMATBAN lévő projekt áll, ami még nem
   publikált. Ez üzletileg jó jel — most is van munka —, de a
   látogatónak látnia kell, hogy nem kész oldalra kattint.

   A jelölés a kiemelő színt kapja: bal oldali vonal, ami ITT
   alapból is látszik (a többi soron csak hoverkor), és a
   státusz-címke is bíbor lesz. Egy elem, két jel, nulla új szöveg.
   ─────────────────────────────────────────────────────────── */
.ref-item.is-epul::before { transform: scaleY(1); }

.ref-item.is-epul .ref-tag {
    color: var(--szin-kiemeles);
    font-weight: 500;
}
