.zone-content {
    position: absolute;
    z-index: 3;
    /* A fenti info-sáv (kb. 3.8cqw magas) alatt kezdődik, a képernyő alsó
       széle fölött ér véget -- mindkét oldalon egy kis gap-pel -- és a
       kettő közötti magasságon belül görgethető. */
    top: 6cqw;
    bottom: 3cqw;
    left: 50%;
    transform: translateX(-50%);
    /* Kicsit szélesebb, mint korábban (30cqw), hogy a lista bal/jobb
       oldalán maradjon egy kis hézag a kijelölő-jelöknek (l.
       .zone-select-marker és .zone-chapters margója lent). */
    width: 34cqw;
    overflow-y: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    background: rgba(10, 14, 22, 0.84);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 1em;
    padding: 1.6cqw 1.8cqw;
    color: #e7ecf5;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    box-shadow: 0 0.5em 2em rgba(0, 0, 0, 0.5);
    font-size: 1cqw;
}

.zone-content::-webkit-scrollbar {
    display: none;
}

/* Zóna-fejléc: a zónanév és alatta a kisebb, értelmező "ZÓNA" felirat egy
   közös, félig áttetsző sávon, ami vízszintesen a panel széléig ér (a
   negatív oldalsó margó a .zone-content padding-jét ellensúlyozza). */
.zone-heading {
    margin: 0 -1.8cqw 1.8em;
    padding: 0.6em 1.8cqw 0.7em;
    background: rgba(255, 255, 255, 0.12);
    text-align: center;
}

.zone-title {
    font-size: 1.8em;
    margin: 0;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.zone-label {
    margin-top: 0.15em;
    color: #fff;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-size: 0.9em;
}

/* Állandó figyelmeztetés a pálya-lista alján: kicsi, de aranysárga, hogy
   feltűnjön, sok levegővel körülötte. */
.zone-dev-notice {
    margin: 0;
    padding: 2.5em 1em 1.5em;
    text-align: center;
    font-size: 0.95em;
    font-weight: 600;
    line-height: 1.5;
    letter-spacing: 0.02em;
    color: #f2c94c;
}

/* "Szem" gomb a jelenet jobb felső sarkában (l. plans/32,
   public/js/scene-shell.js toggleZoneView): a vezérlőelemek elrejtése, hogy
   a teljes háttérkép látsszon. Elrejtett állapotban (.is-active) a szemtől
   balra megjelenik a zóna neve, jobbra (a szemhez) igazítva. */
.zone-view {
    position: absolute;
    z-index: 10;
    top: 0.8cqw;
    right: 2cqw;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1cqw;
}

/* Ugyanaz a cím-betűtípus és körvonal, mint a hotspot-/gomb-feliratokon
   (l. scene.css .scene-hotspot-label). */
.zone-view-name {
    color: #fff;
    font-family: 'Denk One', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    font-size: 1.4cqw;
    letter-spacing: 0.02em;
    text-align: right;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .25s ease;
    -webkit-text-stroke: 0.05em rgba(30, 30, 30, 0.95);
    paint-order: stroke fill;
    text-shadow:
        -0.06em -0.06em 0 rgba(30, 30, 30, 0.95),
         0.06em -0.06em 0 rgba(30, 30, 30, 0.95),
        -0.06em  0.06em 0 rgba(30, 30, 30, 0.95),
         0.06em  0.06em 0 rgba(30, 30, 30, 0.95),
        0 0.15em 0.4em rgba(0, 0, 0, 0.95),
        0 0 0.9em rgba(0, 0, 0, 0.9);
}

.zone-view.is-active .zone-view-name {
    opacity: 1;
}

/* Az ikon a global tileset 8. sorának 1-3. pozíciója (0-tól: sor 7, oszlop
   0-2): nyitott / félig csukott / csukott szem. A kivágás a
   tileset-grid.css képlete; a három képkocka vízszintes pozíciója
   változóban, hogy a lenti pislogás-animáció csak ezek között váltson. */
.zone-view-toggle {
    --eye-open: calc(0 * var(--tileset-cell) / (var(--tileset-img-w) - var(--tileset-cell)) * 100%);
    --eye-half: calc(1 * var(--tileset-cell) / (var(--tileset-img-w) - var(--tileset-cell)) * 100%);
    --eye-closed: calc(2 * var(--tileset-cell) / (var(--tileset-img-w) - var(--tileset-cell)) * 100%);
    --eye-row: calc(7 * var(--tileset-cell) / (var(--tileset-img-h) - var(--tileset-cell)) * 100%);
    width: 2.6cqw;
    height: 2.6cqw;
    flex-shrink: 0;
    padding: 0;
    border: none;
    background-color: transparent;
    background-image: var(--tileset-global);
    background-repeat: no-repeat;
    background-size: calc(var(--tileset-img-w) / var(--tileset-cell) * 100%) calc(var(--tileset-img-h) / var(--tileset-cell) * 100%);
    background-position: var(--eye-open) var(--eye-row);
    cursor: pointer;
    filter: drop-shadow(0 0.2em 0.4em rgba(0, 0, 0, 0.5));
    transition: transform .15s ease;
    animation: zone-view-blink 10s step-end infinite;
}

.zone-view-toggle:hover {
    transform: scale(1.12);
}

/* Hosszan nyitott szem, ami időnként pislog egyet: az animáció oda-vissza
   végigmegy a három képkockán (kb. 70 ms/kocka). Egy 10 mp-es cikluson
   belül két, nem egyenlő közű pislogás van, hogy ne hasson gépiesnek. A
   `step-end` miatt a képkockák között nincs átcsúszás. */
@keyframes zone-view-blink {
    0%    { background-position: var(--eye-open) var(--eye-row); }
    27%   { background-position: var(--eye-half) var(--eye-row); }
    27.7% { background-position: var(--eye-closed) var(--eye-row); }
    28.4% { background-position: var(--eye-half) var(--eye-row); }
    29.1% { background-position: var(--eye-open) var(--eye-row); }
    85%   { background-position: var(--eye-half) var(--eye-row); }
    85.7% { background-position: var(--eye-closed) var(--eye-row); }
    86.4% { background-position: var(--eye-half) var(--eye-row); }
    87.1% { background-position: var(--eye-open) var(--eye-row); }
    100%  { background-position: var(--eye-open) var(--eye-row); }
}

.zone-chapters {
    display: flex;
    flex-direction: column;
    /* A .zone-content-nál hozzáadott plusz szélesség ide kerül, hézagként
       a lista két oldalán -- ide kerül a "kijelölt pálya" két mozgó
       jelölő-szimbóluma (l. .zone-select-marker, public/js/zone-level-select.js). */
    margin: 0 2.2em;
}

.zone-chapter-title {
    text-align: center;
    font-size: 1.3em;
    margin: 1.2em 0 0;
}

.zone-chapter:first-child .zone-chapter-title {
    margin-top: 0;
}

/* Fejezetcím-sáv: a cím középen marad, az infó-gomb a sáv jobb szélére
   kerül (l. plans/27 3. pont, public/js/chapter-info.js). */
.zone-chapter-header {
    position: relative;
}

/* Az ikon a global tileset "info" buboréka (4. sor 1. poz., 0-tól: sor 3,
   oszlop 0). A gomb mérete em-ben, a kivágás a tileset-grid.css képlete. */
.zone-chapter-info-btn {
    position: absolute;
    right: 0;
    /* 1.8em-ről 30%-kal nagyobb, a bottom úgy igazítva, hogy az ikon
       közepe a korábbi helyén maradjon. */
    bottom: -0.37em;
    width: 2.34em;
    height: 2.34em;
    padding: 0;
    border: none;
    background-color: transparent;
    background-image: var(--tileset-global);
    background-repeat: no-repeat;
    background-size: calc(var(--tileset-img-w) / var(--tileset-cell) * 100%) calc(var(--tileset-img-h) / var(--tileset-cell) * 100%);
    background-position:
        calc(0 * var(--tileset-cell) / (var(--tileset-img-w) - var(--tileset-cell)) * 100%)
        calc(3 * var(--tileset-cell) / (var(--tileset-img-h) - var(--tileset-cell)) * 100%);
    cursor: pointer;
    opacity: 0.7;
    filter: drop-shadow(0 0.1em 0.2em rgba(0, 0, 0, 0.5));
    transition: opacity .15s ease, transform .15s ease;
}

.zone-chapter-info-btn:hover {
    opacity: 1;
    transform: scale(1.12);
}

/* Még nem látott ismertető: nagyobb, gyorsan és rugalmasan pulzál, hogy a
   játékos megnyissa -- forgatás és ragyogás nélkül, hogy ne legyen
   túlságosan feltűnő. */
.zone-chapter-info-btn.is-unseen {
    width: 2.6em;
    height: 2.6em;
    bottom: -0.4em;
    opacity: 1;
    transform-origin: 50% 60%;
    animation: chapter-info-pulse 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) infinite;
}

@keyframes chapter-info-pulse {
    0%   { transform: scale(0.85); }
    25%  { transform: scale(1.2); }
    50%  { transform: scale(0.95); }
    75%  { transform: scale(1.3); }
    100% { transform: scale(0.85); }
}

.zone-chapter-divider {
    height: 1px;
    margin: 0.6em 0;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
}

.zone-level-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5em;
}

/* A <li> a pozicionálási kontextus a jobb-felső sarokból kilógó pipához
   (l. .zone-level-won-icon) -- így görgetéskor a pipa a saját sorával
   együtt mozog (18. terv 59. sor kérése). */
.zone-level-item {
    position: relative;
}

.zone-level-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6em;
    color: #f2f5fb;
    text-decoration: none;
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.16), rgba(255, 255, 255, 0.08));
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 0.5em;
    /* Kisebb fent/lent/jobb padding (felhasználói kérés), hogy a
       megnagyobbított feature-ikonoknak (l. .zone-level-feature-icon)
       jusson hely, a sor mégse nőjön feleslegesen -- a bal padding
       maradt, csak a jobb oldali, ikonokhoz közelebbi rész szűkült. */
    padding: 0.5em 0.6em 0.5em 1em;
    font-size: 1.05em;
    font-weight: 600;
    text-align: left;
    box-shadow: 0 0.15em 0.3em rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.15);
    transition: background .15s ease, transform .15s ease, border-color .15s ease;
}

.zone-level-heading {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.2em;
}

/* Csillagok a cím alatt (arany = megszerzett, szürke = még nem) -- l.
   components/tileset-grid.css. */
.zone-level-stars {
    display: flex;
    align-items: center;
    gap: 0.1em;
}

/* A pályán megszerezhető maximális XP: a csillagoktól jobbra, a sor
   folytatásaként, enyhén világosabb, lekerekített hátterű "pirula",
   sötét, vízszintesen középre igazított felirattal. */
.zone-level-max-xp {
    margin-left: 0.5em;
    padding: 0.1em 0.7em;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.72);
    color: #1a202c;
    font-size: 0.75em;
    font-weight: 500;
    text-align: center;
    white-space: nowrap;
}

/* A csillag-ikon kivágása a közös components/tileset-grid.css-ben van --
   itt csak a (kicsinyített) megjelenítési méret. */
.zone-level-star {
    width: 1.5em;
    height: 1.5em;
}

.zone-level-title {
    min-width: 0;
    font-size: 1.1em;
    margin-bottom: 0.2em;
}

.zone-level-link:hover {
    background: linear-gradient(180deg, rgba(255, 255, 255, 0.28), rgba(255, 255, 255, 0.14));
    border-color: rgba(255, 255, 255, 0.4);
    transform: translateY(-1px);
}

.zone-level-link.is-won {
    background: linear-gradient(180deg, rgba(74, 222, 128, 0.28), rgba(34, 197, 94, 0.14));
    border-color: rgba(74, 222, 128, 0.5);
}

.zone-level-link.is-won:hover {
    background: linear-gradient(180deg, rgba(74, 222, 128, 0.38), rgba(34, 197, 94, 0.2));
}

/* A kereten kívülre lóg ki jobbra és fölfelé is (18. terv 59. sor) -- a
   pozicionálási kontextus a szülő <li> (.zone-level-item), nem a
   görgethető lista, ezért görgetéskor a pipa a sorával együtt mozog. */
.zone-level-won-icon {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(35%, -45%);
    font-size: 1.1em;
    z-index: 1;
    filter: drop-shadow(0 0.1em 0.2em rgba(0, 0, 0, 0.6));
}

/* Feature-ikonok (kulcs+kapu / teleport / kalapács) a pálya-cím jobb
   szélén -- a tileset 6. sorából (0-alapon 5), l.
   public/css/components/tileset-grid.css és
   plans/19-item-kijelzes-es-ranghoz-rogzites-terv.md 5.5 pont. */
.zone-level-feature-icons {
    display: flex;
    /* Kisebb rés, hogy nagyobb ikonok is elférjenek (felhasználói kérés). */
    gap: 0.15em;
    flex-shrink: 0;
}

/* Lekerekített, világos háttér az ikon mögött -- ugyanaz a hatás, mint a
   "play" oldal leltár-tárgyainál (l. components/stats-panel.css
   .inventory-item), de mivel itt nincs valódi (canvas/img) tartalom, csak
   egy háttérkép-sprite, a padding+szín hozzáadásához KÉT réteget kell
   használni, külön-külön `background-origin`/`background-clip`-pel:
     1. réteg (felül): a tileset-csempe, `content-box`-ra klippelve -- ez
        a lényeg, e NÉLKÜL a böngésző az alap `background-clip:border-box`
        miatt a paddingbe (a világos háttér zónájába) is belefestette
        volna a felskálázott tileset-kép szomszédos celláinak szélét, ez
        okozta a korábbi "fölösleges rész látszik az ikonokon" hibát.
     2. réteg (alul): sima világos szín, `linear-gradient(#szín, #szín)`
        trükkel (a background-color-nak nincs saját, rétegenkénti
        origin/clip-je), `border-box`-ra klippelve -- ez tölti ki a
        TELJES dobozt, beleértve a paddinget is.
   L. plans/19-item-kijelzes-es-ranghoz-rogzites-terv.md 5.5 pont. */
.zone-level-feature-icon {
    /* Nagyobb ikon+háttér, a háttér paddingja pedig a mérethez képest is
       kisebb lett, mint korábban (felhasználói kérés) -- így az ikon
       aránylag nagyobb részt foglal el a lekerekített hátterén belül. */
    width: 2.2em;
    height: 2.2em;
    padding: 0.15em;
    box-sizing: content-box;
    flex-shrink: 0;
    border-radius: 6px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    background-image:
        var(--tileset-global),
        linear-gradient(#f7fafc, #f7fafc);
    background-origin: content-box, border-box;
    background-clip: content-box, border-box;
    background-size:
        calc(var(--tileset-img-w) / var(--tileset-cell) * 100%) calc(var(--tileset-img-h) / var(--tileset-cell) * 100%),
        100% 100%;
    background-position:
        calc(var(--tile-col, 0) * var(--tileset-cell) / (var(--tileset-img-w) - var(--tileset-cell)) * 100%) calc(var(--tile-row, 0) * var(--tileset-cell) / (var(--tileset-img-h) - var(--tileset-cell)) * 100%),
        0 0;
    background-repeat: no-repeat, no-repeat;
}

/* Még nem elérhető feature -- fakó/szürkített, hogy felhívja a figyelmet
   arra, hogy a pályán van olyan tárgy, amit a játékos jelenlegi rangján
   még nem használhat (D6 döntés, l. a terv 1. és 5.5 pontja). */
.zone-level-feature-icon.is-locked {
    filter: grayscale(1) opacity(0.45);
}

/* A szürkített ikonra egy lakat is kerül (ugyanaz a Font Awesome ikon,
   mint a zárolt pályák .zone-level-lock-icon-ja) -- l. plans/27 4. pont.
   A lakat az ikon TESTVÉRE a wrapperben, nem a gyereke, különben a fenti
   filter őt is elhalványítaná. */
.zone-level-feature-icon-wrap {
    position: relative;
    display: flex;
    flex-shrink: 0;
}

.zone-level-feature-lock {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 1.25em;
    color: #e2e8f0;
    filter: drop-shadow(0 0.1em 0.2em rgba(0, 0, 0, 0.8));
    pointer-events: none;
}

/* Szabály-jelvények (l. plans/21-szabalyok-sugo-terv.md 7. pont) -- a
   feature-ikonoktól BALRA, saját lekerekített hátterű csoportban, csak ha
   a pályán van legalább 1 bekapcsolt szabály. Sima Font Awesome ikonok
   (l. services/rules.js RULE_DEFINITIONS -- ugyanaz az ikon+szín pár, amit
   a "play" oldal info-panelje is használ), NINCS tileset-crop és NINCS
   "locked" állapot (a szabályok nem rang-küszöbösek). */
.zone-level-rule-icons {
    display: flex;
    align-items: center;
    gap: 0.3em;
    flex-shrink: 0;
    padding: 0.15em 0.5em;
    border-radius: 999px;
    background: rgba(247, 250, 252, 0.9);
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.zone-level-rule-icon {
    font-size: 1.2em;
    line-height: 1;
}

/* "Kijelölt pálya" -- két mozgó jelölő-szimbólum a lista bal/jobb
   oldalán (a .zone-chapters margója adja a helyet, l. fent), amik a
   billentyűzettel (Fel/Le) vagy egérrel (hover) kijelölt pálya-sor
   magasságára állnak -- l. public/js/zone-level-select.js. Mindkettő
   közvetlenül a .zone-content (position:absolute, tehát pozicionálási
   kontextus) gyereke, `top`-ot a JS állítja be a kijelölt <li>
   offsetTop-ja alapján -- mivel a .zone-content-tel EGYÜTT görgetnek
   (ugyanabban a scrollozható dobozban vannak), a jelölő automatikusan
   követi a listát görgetéskor is, külön kódolás nélkül. */
.zone-select-marker {
    position: absolute;
    top: 0;
    transform: translateY(-50%);
    color: #ffe58a;
    font-size: 1.1em;
    line-height: 1;
    text-shadow: 0 0.1em 0.3em rgba(0, 0, 0, 0.6);
    transition: top 0.15s ease;
    pointer-events: none;
    z-index: 2;
}

.zone-select-marker-left {
    left: 0.6em;
}

.zone-select-marker-right {
    right: 0.6em;
}

.zone-level-empty {
    text-align: center;
    color: rgba(255, 255, 255, 0.4);
    font-style: italic;
    padding: 0.5em 0.8em;
}

/* Rang-ünneplő popup -- a #rankup-overlay/#rankup-panel a nyerés-popup
   .win-overlay/.result-panel/.result-panel-btn osztályait használja
   (pages/play.css, mindig betöltve, l. config/scene-styles.js), itt csak a
   rá jellemző elemeket (filmszalag, cím, rangnév) definiáljuk -- l.
   plans/13-jatekos_fejlodese_terv.md 5.3 pont és a filmszalag-animáció
   kiegészítése (plans/19-item-kijelzes-es-ranghoz-rogzites-terv.md kapcsán).
   A `#rankup-panel` (ID-szelektor, NEM `.rankup-panel` class!) felülírja a
   megosztott `.result-panel` méretét/átlátszóságát -- ez a popup SOKKAL
   szélesebb és kevésbé átlátszó legyen, mint a nyerés/vereség popup
   (felhasználói kérés). FONTOS: az ID-szelektor szándékos -- a
   `pages/zone.css` a `config/scene-styles.js`-ben KORÁBBAN töltődik be,
   mint a `pages/play.css` (ahol a megosztott `.result-panel` van
   definiálva), ezért egy azonos specificitású `.rankup-panel` class-szabály
   VESZTENE a cascade-ben (forrás-sorrend dönt egyenlő specificitásnál) --
   az ID-szelektor magasabb specificitással garantáltan felülír, a
   betöltési sorrendtől függetlenül.

   Invertált, majdnem fehér panel (felhasználói kérés, korábban sötét
   volt) -- a benne lévő feliratok/elemek színét lentebb igazítottuk
   ehhez. */
#rankup-panel {
    width: 46em;
    max-width: 94vw;
    padding: 2.2em 2.2em 2.4em;
    background: rgba(245, 246, 248, 0.97);
    border-color: rgba(0, 0, 0, 0.12);
}

.rankup-panel-title {
    font-size: 1.3rem;
    color: #1a202c;
    text-align: center;
    font-family: 'Denk One', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

.rankup-panel-rankname {
    font-size: 1.05rem;
    font-weight: 600;
    color: #1a202c;
    text-align: center;
}

/* Sötét hátterű kör, jobb felső sarokban -- ez zárja a popupot ("Szuper!"
   gomb helyett, felhasználói döntés). A megosztott .popup-close-btn
   (l. lent) egy MÁR sötét panelhez (pl. Súgó popup) készült, világos
   körvonallal/átlátszó háttérrel -- az invertált (majdnem fehér)
   rangugró-panelen ez alig látszana, ezért itt felülírjuk sötét
   háttérre, fehér X-szel (felhasználói kérés). */
#rankup-close-btn {
    background: rgba(26, 32, 44, 0.85);
    border-color: rgba(26, 32, 44, 0.85);
    color: #fff;
}

#rankup-close-btn:hover {
    background: rgba(26, 32, 44, 0.95);
    border-color: rgba(26, 32, 44, 0.95);
}

/* Vékony, világos karikába foglalt X gomb a panel jobb felső sarkában --
   ez zárja a popupot ("Szuper!" gomb helyett, felhasználói döntés). Közös
   osztály a rang-ünneplő ÉS a Súgó popup bezáró gombjához -- utóbbi
   sötét panelen marad, ezért ott ez az alap (világos körvonalas) kinézet
   megfelelő, csak a fenti #rankup-close-btn kap egyedi felülírást. */
.popup-close-btn {
    position: absolute;
    top: 0.8em;
    right: 0.8em;
    width: 1.8em;
    height: 1.8em;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.5);
    border-radius: 50%;
    background: transparent;
    color: #fff;
    font-size: 1.1em;
    line-height: 1;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

.popup-close-btn:hover {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.8);
}

/* Az author `display: flex` (fent) különben felülírná a böngésző
   user-agent `[hidden] { display: none; }` alapszabályát (author normal
   > user-agent normal, függetlenül a specifitástól) -- e nélkül a gomb a
   `hidden` attribútum ellenére is látszana. Ugyanaz a hiba/javítás, mint
   a .win-overlay/.result-panel-nél (l. pages/play.css) -- ide azért
   kellett külön is felvenni, mert a Súgó popup kötelező módban ezt az
   attribútumot kapcsolja a gombra (l. public/js/help-panel.js
   updateCloseAvailability), hogy ne látsszon egy működésképtelen
   bezáró gomb. */
.popup-close-btn[hidden] {
    display: none;
}

/* Filmszalag: a korábban megszerzett medálok, a most megszerzett medál
   foglalata (majd maga a medál) és a hátralévő rangok foglalatai -- l.
   public/js/rank-celebration.js buildFilmstrip/animateFilmstrip.
   5 foglalatnyi látható terület; a szélek felé a mask-image-gradiens adja
   az "egyre átlátszóbb" hatást, FÜGGETLENÜL attól, hogy a szalag éppen hol
   tart a csúsztatásban (nem kell JS-ből számolt, soronkénti opacityt
   karbantartani). */
.rankup-filmstrip-viewport {
    width: 37.5em;
    max-width: 100%;
    overflow: hidden;
    /* Nagyobb gap a cím és a medálok között (felhasználói kérés) -- a
       .result-panel megosztott `gap`-je mellé, csak erre az egy helyre. */
    margin-top: 0.6em;
    /* Világos szürke sáv a medál-képsorozat mögött (felhasználói kérés)
       -- a lenti mask-image ezt is elhalványítja a szélek felé, ugyanúgy,
       mint magukat a medálokat, így a sáv "elfogyása" illeszkedik a
       filmszalag-effekthez. */
    /* Függőleges plusz hely, hogy a középső, felnagyított medál se
       vágódjon le az overflow:hidden miatt. */
    padding: 2.4em 0;
    background: #e2e8f0;
    border-radius: 0.8em;
    -webkit-mask-image: linear-gradient(to right, transparent, black 18%, black 82%, transparent);
    mask-image: linear-gradient(to right, transparent, black 18%, black 82%, transparent);
}

.rankup-filmstrip-track {
    display: flex;
    transition: transform 0.7s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform;
}

.rankup-medal-slot {
    flex: 0 0 7.5em;
    width: 7.5em;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* A középen kiemelt foglalat/medál kicsit nagyobb -- tiszta `transform:
   scale()`, ez nem tolja el a szomszédos foglalatok pozícióját (a
   layout-szélesség a .rankup-medal-slot fix `flex-basis`-a marad). */
.rankup-medal-slot-inner {
    position: relative;
    height: 7.2em;
    /* A medál-lap cellái álló arányúak (320x430, l. components/info-panel.css). */
    aspect-ratio: 320 / 430;
    transition: transform 0.5s ease;
}

.rankup-medal-slot.is-center {
    z-index: 1;
}

.rankup-medal-slot.is-center .rankup-medal-slot-inner {
    transform: scale(1.5);
}

.rankup-medal-slot-socket,
.rankup-medal-slot-medal {
    position: absolute;
    inset: 0;
    border-radius: 50%;
    transition: opacity 0.4s ease;
}

/* Szürke "foglalat" -- egy még el nem ért/most megszerzett, de még nem
   felfedett rang helye. Sötétebb (nem fehér-alapú) árnyalat, mert a
   világos szürke sávon (l. fent .rankup-filmstrip-viewport) egy fehér-
   alapú, áttetsző kör alig látszana. */
.rankup-medal-slot-socket {
    background: radial-gradient(circle at 35% 30%, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.02) 60%), rgba(0, 0, 0, 0.06);
    border: 1px solid rgba(0, 0, 0, 0.2);
    box-shadow: inset 0 0.15em 0.4em rgba(0, 0, 0, 0.15);
    opacity: 1;
}

.rankup-medal-slot-medal {
    opacity: 0;
    /* A medál saját (álló) alakja adja a formát, nem kör. */
    border-radius: 0;
}

/* .is-filled -- crossfade: a foglalat eltűnik, a tényleges medál
   megjelenik (l. animateFilmstrip: ez a class csak a csúsztatás VÉGÉN
   kerül a most megszerzett rang foglalatára, a korábban megszerzetteknél
   pedig már induláskor rajta van, átmenet nélkül). */
.rankup-medal-slot.is-filled .rankup-medal-slot-socket {
    opacity: 0;
}

.rankup-medal-slot.is-filled .rankup-medal-slot-medal {
    opacity: 1;
}

/* A korábbi "Új tárgy" (item-intro) popup beolvadt a Súgó popupba -- l.
   public/css/components/help-panel.css, help_html_repo/README.md. */

/* Zárolt pálya (a besorolása a következő feloldandó feature-nél is
   magasabb, l. plans/26): halványított, nem kattintható, lakat-jelöléssel. */
.zone-level-link.is-locked {
    opacity: 0.45;
    filter: grayscale(0.7);
    cursor: not-allowed;
    pointer-events: none;
}

.zone-level-lock-icon {
    position: absolute;
    top: 0;
    right: 0;
    transform: translate(35%, -45%);
    z-index: 1;
    color: #e2e8f0;
    filter: drop-shadow(0 0.1em 0.2em rgba(0, 0, 0, 0.6));
}

/* Zárolt pályánál a besorolás-jelző ikon helyén csak egy szürke, lekerekített
   alap áll, finom, átlós csíkozással, ikon nélkül: "nem láthatod, mi a
   következő utáni feature". Ugyanakkora, mint a feature-ikon háttere. */
.zone-level-feature-hidden {
    flex-shrink: 0;
    box-sizing: content-box;
    width: 2.2em;
    height: 2.2em;
    padding: 0.15em;
    border-radius: 6px;
    background-color: #8a94a3;
    background-image: repeating-linear-gradient(
        45deg,
        rgba(255, 255, 255, 0.14) 0,
        rgba(255, 255, 255, 0.14) 3px,
        rgba(0, 0, 0, 0.06) 3px,
        rgba(0, 0, 0, 0.06) 6px
    );
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
