{"id":66776,"date":"2025-08-26T21:27:08","date_gmt":"2025-08-26T19:27:08","guid":{"rendered":"https:\/\/www.diamantrad.com\/?page_id=66776"},"modified":"2026-04-01T15:02:40","modified_gmt":"2026-04-01T13:02:40","slug":"womens-bikes","status":"publish","type":"page","link":"https:\/\/www.diamantrad.com\/fi-FI\/bikes\/womens-bikes\/","title":{"rendered":"Womens bikes"},"content":{"rendered":"\n<div class=\"wp-block-cover\"><img data-dominant-color=\"8c7985\" data-has-transparency=\"false\" loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1688\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" class=\"wp-block-cover__image-background wp-image-53354 size-full not-transparent\" alt=\"Di 25 mahon lifestyle\" src=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-scaled.avif\" style=\"--dominant-color: #8c7985; object-position:77% 80%\" data-object-fit=\"cover\" data-object-position=\"77% 80%\" srcset=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-scaled.avif 2560w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-300x198.avif 300w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-1024x675.avif 1024w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-768x506.avif 768w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-1536x1013.avif 1536w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I0836_300dpi-2048x1350.avif 2048w\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-color-primary-background-color has-background-dim-30 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained\">\n<p class=\"has-text-align-center has-large-font-size wp-block-paragraph\"><\/p>\n\n\n<div class=\"lazyblock-cover-text-DkUhT wp-block-lazyblock-cover-text\"><div class=\"covertext container py-5 d-flex flex-column colorscheme-light justify-content-center\" id=\"covertext-DkUhT\">\r\n  <div class=\"lazyblock-inner-blocks\">\n\n<h2 class=\"wp-block-heading\">Naisten polkupy\u00f6r\u00e4t (midstep-py\u00f6r\u00e4t)<\/h2>\n\n<\/div>\r\n<\/div><\/div><\/div><\/div>\n\n\n<div class=\"lazyblock-nncontainer-ZH8ULh wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-ZH8ULh\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<p class=\"wp-block-paragraph\">P\u00e4\u00e4dyit t\u00e4lle sivulle, koska teit haun termill\u00e4 \u201dnaisten polkupy\u00f6r\u00e4t\u201d. Monet ihmiset (ehk\u00e4 sin\u00e4kin) saattavat k\u00e4ytt\u00e4\u00e4 termi\u00e4 \u201dnaisten polkupy\u00f6r\u00e4\u201d puhuessaan polkupy\u00f6rist\u00e4, joissa on madallettu (tai puuttuva) vaakaputki. Se ei haittaa. Kaikki, sek\u00e4 miehet ett\u00e4 naiset, voivat ostaa py\u00f6r\u00e4n, jossa on lowstep- tai midstep-runko, aktiiviseen tai vapaa-ajan ajeluun, s\u00e4hk\u00f6avustuksella tai ilman, mustana tai v\u00e4rikk\u00e4\u00e4n\u00e4 \u2013 riippumatta siit\u00e4, miten sin\u00e4 tai me py\u00f6r\u00e4t luokittelemme. Etsi vain tuotevalikoimastamme haluamasi step-through-malli, eli vaakaputketon py\u00f6r\u00e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">L\u00f6yd\u00e4t my\u00f6hemmin tekstist\u00e4 naisille valikoimiamme suosituksia ja vinkkej\u00e4, joista voi olla apua uuden polkupy\u00f6r\u00e4n ostossa. Ehk\u00e4 olet jo ymm\u00e4rt\u00e4nyt t\u00e4rkeimm\u00e4n asian: Rungon muoto ei oikeastaan m\u00e4\u00e4rit\u00e4 yht\u00e4\u00e4n mit\u00e4\u00e4n, sill\u00e4 kaikki Diamantin runkovaihtoehdot ovat unisex-malleja.<\/p>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n<div class=\"lazyblock-nncontainer-Zmm6dU wp-block-lazyblock-nncontainer\"><div class=\"section-light\">\r\n  <div class=\"container\" id=\"container-Zmm6dU\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n<div class=\"lazyblock-bikefinder-ZIVsca wp-block-lazyblock-bikefinder\"><template id=\"bikeTeaserComponent\">\n  <template x-if=\"frames.value.length\">\n    <div class=\"bikefinder-tile px-3 py-4 px-lg-4\" :class=\"classNames\">\n      <div class=\"bikefinder-tile-content\">\n        <a :href=\"selectedFrame.value.link\" class=\"bikefinder-title\">\n          <h4\n            class=\"mb-0\"\n            x-text=\"extractOrCleanString(selectedFrame.value.title)\"\n          ><\/h4>\n        <\/a>\n\n        <p\n          class=\"bikefinder-subtitle\"\n          x-text=\"$store.utils.t($store.utils.translations.frames[extractOrCleanString(selectedFrame.value.title, true)])\"\n        ><\/p>\n\n        <div\n          class=\"bikefinder-preis\"\n          x-text=\"getAbText() + ' ' + formatNumber(selectedFrame.value.price_lowest) + ' ' + getCurrency()\"\n        ><\/div>\n        <a :href=\"selectedFrame.value.link\" class=\"color-images mx-auto mb-4\"\n          ><picture>\n            <img\n              :src=\"selectedFrameImage.value\"\n              class=\"img-fluid lazy\"\n              :alt=\"selectedFrame.value.title\"\n          \/><\/picture>\n        <\/a>\n\n        <div class=\"bikefinder-controls mb-3\">\n          <div class=\"color-switch\">\n            <template x-for=\"(color, index) in selectedFrame.value.colors\">\n              <span\n                @click=\"onColorClicked(color)\"\n                :class=\"'bike-color-' + color.value.toLowerCase()\"\n                data-bs-toggle=\"tooltip\"\n                data-bs-placement=\"top\"\n                :title=\"color.description\"\n              ><\/span>\n            <\/template>\n          <\/div>\n\n          <div class=\"bikefinder-rahmen\">\n            <ul\n              class=\"nav nav-tabs\"\n              x-data=\"{ frames: framesAsGenerations ? selectedFrameByGeneration: frames }\"\n            >\n              <template x-for=\"(frame, index) in frames.value\">\n                <li\n                  class=\"nav-item\"\n                  @click=\"onFrameClicked(frame)\"\n                  x-show=\"!framesAsGenerations || isFrameInFiltered(frame)\"\n                >\n                  <span\n                    class=\"nav-link\"\n                    :class=\"selectedFrame.value.id == frame.id ? 'active' : ''\"\n                    x-data=\"{ meta: getFrameMeta(frame.frameType) }\"\n                  >\n                    <img\n                      width=\"48\"\n                      height=\"28\"\n                      :src=\"meta.icon\"\n                      data-bs-toggle=\"tooltip\"\n                      data-bs-placement=\"top\"\n                      :title=\"$store.utils.t(meta.text)\"\n                    \/>\n                  <\/span>\n                <\/li>\n              <\/template>\n            <\/ul>\n          <\/div>\n        <\/div>\n      <\/div>\n      <template x-if=\"framesAsGenerations\">\n        <div\n          x-data=\"generation({ generations: frames, generationClickedCallback: generationsCallback })\"\n        ><\/div>\n      <\/template>\n    <\/div>\n  <\/template>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\n      \"biketeaser\",\n      ({ frames, framesAsGenerations, framesMeta }) => ({\n        template: null,\n        frames: { value: frames },\n        selectedFrameByGeneration: { value: [] },\n        selectedFrame: { value: null },\n        framesMeta: framesMeta,\n        selectedFrameImage: {},\n        framesAsGenerations: framesAsGenerations,\n        generationsCallback: null,\n        classNames: \"\",\n        currentVariant: null,\n        init() {\n          this.setup();\n          this.$nextTick(() => {\n            this.mounted();\n            this.render();\n          });\n        },\n        setup() {\n          this.template = document.getElementById(\"bikeTeaserComponent\");\n        },\n        mounted() {\n          if (this.frames.value.length) {\n            if (this.framesAsGenerations) {\n              this.selectedFrameByGeneration.value = this.frames.value[0];\n              this.selectedFrame.value = this.frames.value[0];\n            } else {\n              this.selectedFrame.value = this.frames.value;\n            }\n\n            const frame = this.getFrameWithSpecialRecommendedRetailpriceOrFirst(\n              this.selectedFrame.value,\n            );\n\n            let variant = this.getVariantsWithKey(\n              frame,\n              \"special_recommended_retailprice\",\n            )[0];\n            if (!variant) {\n              variant = frame.variants[0];\n            }\n\n            const uniqueFrameImageOfVariant = this.getImageByVariant(\n              frame,\n              variant,\n            );\n\n            this.selectedFrame.value = frame;\n            this.selectedFrameImage = uniqueFrameImageOfVariant;\n\n            this.setClassNames(variant.id);\n          }\n          this.generationsCallback = this.onGenerationClicked.bind(this);\n        },\n        render() {\n          this.$el.innerHTML = this.template.innerHTML;\n        },\n        getFrameWithSpecialRecommendedRetailpriceOrFirst(frames) {\n          const frame = frames.find((frame) => {\n            return frame.hasOwnProperty(\"special_recommended_retailprice\");\n          });\n          return frame ? frame : frames[0];\n        },\n        getVariantsWithKey(frame, key, value = \"\") {\n          if (\n            frame.commonValues.hasOwnProperty(key) &&\n            (value ? frame.commonValues[key] === value : true)\n          ) {\n            return frame.variants;\n          }\n\n          return frame.variants.filter((variant) => {\n            return variant[key] && (value ? variant[key] === value : true);\n          });\n        },\n        getRecomendedRetailpriceVariantColor(color) {\n          const variantsWithPrice = this.getVariantsWithKey(\n            this.selectedFrame.value,\n            \"special_recommended_retailprice\",\n          );\n\n          const variantsWithColor = this.getVariantsWithKey(\n            this.selectedFrame.value,\n            \"primary_basecolour\",\n            color.value,\n          );\n\n          const variantsWithPriceIds = variantsWithPrice.map(\n            (variant) => variant.id,\n          );\n          let variant = variantsWithPrice.find((variant) =>\n            variantsWithPriceIds.includes(variant.id),\n          );\n          if (!variant) {\n            variant = variantsWithColor.length ? variantsWithColor[0] : this.selectedFrame.value.variants[0];\n          }\n\n          return {\n            value: variant ? variant.value : \"\",\n            variantId: variant ? variant.id : null,\n          };\n        },\n        getImageByVariant(frame, variant) {\n          if (!variant) {\n            return { value: frame?.commonValues?.pos_image, variantId: null };\n          }\n          const uniqueImage = frame.images?.find((image) => {\n            return image.value == variant[image.propertyPath];\n          });\n\n          return uniqueImage\n            ? { value: uniqueImage.value, variantId: variant.id }\n            : { value: frame.commonValues?.pos_image, variantId: variant.id };\n        },\n        isFrameInFiltered(frame) {\n          return frame.hasVariants.length ? true : false;\n        },\n        extractTextInBrackets(text) {\n          const match = text.match(\/\\((.*?)\\)\/);\n          return match ? match[1] : \"\";\n        },\n        onFrameClicked(frame) {\n          this.selectedFrame.value = frame;\n          const variantsWithPrice = this.getVariantsWithKey(\n            frame,\n            \"special_recommended_retailprice\",\n          );\n\n          const variantsWithPosImage = this.getVariantsWithKey(\n            frame,\n            \"pos_image\",\n          );\n\n          const variantsWithPriceIds = variantsWithPrice.map(\n            (variant) => variant.id,\n          );\n\n          let variant = variantsWithPrice.find((variant) =>\n            variantsWithPriceIds.includes(variant.id),\n          );\n          if (!variant) {\n            variant = frame.variants[0];\n          }\n\n          const uniqueFrameImageOfVariant = this.getImageByVariant(\n            frame,\n            variant,\n          );\n\n          this.selectedFrameImage = uniqueFrameImageOfVariant;\n          this.setClassNames(variant.id);\n        },\n        onGenerationClicked(generation) {\n          this.selectedFrameByGeneration.value = generation;\n          this.selectedFrame.value = this.selectedFrameByGeneration.value[0];\n          this.selectedFrameImage = this.selectedFrame.value.images[0];\n          this.setClassNames(this.selectedFrame.value.images[0].variantId);\n        },\n        onColorClicked(color) {\n          this.selectedFrameImage = this.selectedFrame.value.images.find(\n            (image) => image.variantId == color.variantId,\n          );\n\n          const colorRetailprice =\n            this.getRecomendedRetailpriceVariantColor(color);\n          this.setClassNames(colorRetailprice.variantId);\n        },\n        setClassNames(variantId) {\n          \/\/ Maybe many?\n          this.currentVariant = this.selectedFrame.value.variants.find(\n            (variant) => {\n              return variant.id === variantId;\n            },\n          );\n\n          let names = [];\n          if (this.isReducedPrice(this.currentVariant) && this.isLastChance()) {\n            names.push(\"sale\");\n            names.push(\"lastchance\");\n          } else if (this.isReducedPrice(this.currentVariant)) {\n            names.push(\"sale\");\n          } else if (this.isLastChance()) {\n            names.push(\"lastchance\");\n          }\n\n          if (this.isNewBike()) {\n            names.push(\"newbike\");\n          }\n          this.classNames = names.join(\" \");\n        },\n        getPriceText(price) {\n          return \"Ab \" + price + \" EUR\";\n        },\n        formatNumber(number) {\n          if (this.$store.utils.country === \"CH\") {\n            return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \"'\");\n          } else {\n            return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \".\");\n          }\n        },\n        getAbText() {\n          const lang = this.$store.utils.lang;\n          return (\n            {\n              da: \"Fra\",\n              de: \"Ab\",\n              en: \"From\",\n              fi: \"Alkaen\",\n              fr: \"\u00c0 partir de\",\n              nl: \"Vanaf\",\n              pl: \"Od\",\n              sv: \"Fr\u00e5n\",\n            }[lang] || \"Ab\"\n          );\n        },\n        getCurrency() {\n          const currencyMap = {\n            CH: \"CHF\",\n            DK: \"DKK\",\n            GB: \"GBP\",\n            PL: \"PLN\",\n            SE: \"SEK\",\n          };\n          const country = this.$store.utils.country;\n          return currencyMap[country] || \"EUR\";\n        },\n        isReducedPrice(variant) {\n          if (variant && variant.special_recommended_retailprice) {\n            return variant.special_recommended_retailprice;\n          }\n          return this.selectedFrame.value.specialRecommendedRetailprice.find(\n            (price) => price.variantId === this.selectedFrame.value.id,\n          );\n        },\n        isLastChance() {\n          return this.selectedFrame.value.lastchance;\n        },\n        isNewBike() {\n          return this.selectedFrame.value.newbike;\n        },\n        removeAllBrackets(str) {\n          const regex = \/\\[.*?\\]|\\(.*?\\)|\\{.*?\\}\/g;\n          return str.replace(regex, \"\");\n        },\n        extractBrackets(str) {\n          const regex = \/\\[.*?\\]|\\(.*?\\)|\\{.*?\\}\/g;\n\n          const matches = str.match(regex);\n\n          return matches || [];\n        },\n        getFrameMeta(frameType) {\n          return this.framesMeta[frameType] || { icon: '', text: '' };\n        },\n        extractOrCleanString(str, returnExtracted = false) {\n          if (!str) return \"\";\n          const pattern =\n            \/\\(?\\b(HCH|MIT|Lowstep|SCH|TIE|Midstep|Stepover|HER|TRA)\\b\\)?\/i;\n          const match = str.match(pattern);\n\n          if (match) {\n            return returnExtracted\n              ? match[1]\n              : str.replace(pattern, \"\").replace(\/\\s+\/g, \" \").trim();\n          }\n\n          return returnExtracted ? null : str.trim();\n        },\n      }),\n    );\n  });\n<\/script>\n<template id=\"generationComponent\">\n  <template x-if=\"getGenerationWithoutActive().length\">\n    <div class=\"dropdown bikefinder-generations\">\n      <button\n        class=\"btn btn-secondary dropdown-toggle p-0\"\n        type=\"button\"\n        :id=\"'dropdownGenerations-' + selectedGeneration.id\"\n        data-bs-toggle=\"dropdown\"\n        aria-expanded=\"false\"\n        x-text=\"$store.utils.t($store.utils.translations.futureGenerations)\"\n      ><\/button>\n      <div\n        class=\"dropdown-menu dropdown-generations\"\n        :aria-labelledby=\"'dropdownGenerations-' + selectedGeneration.id\"\n      >\n        <template\n          x-for=\"(generation, index) in getGenerationWithoutActive(generations)\"\n          :key=\"'genNav-' + index\"\n        >\n          <a\n            @click=\"onGenerationClicked(generation)\"\n            class=\"dropdown-item\"\n            x-text=\"mainTitle(generation)\"\n          ><\/a>\n        <\/template>\n      <\/div>\n    <\/div>\n  <\/template>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"generation\", ({ generations, generationClickedCallback }) => ({\n      template: null,\n      generations: generations,\n      selectedGeneration: {},\n      selectedFrameImage: {},\n      generationClickedCallback: generationClickedCallback,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"generationComponent\");\n      },\n      mounted() {\n        if (this.generations.value.length) {\n          this.selectedGeneration = this.generations.value[0];\n        }\n      },\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n      onGenerationClicked(generation) {\n        this.generationClickedCallback(generation);\n        this.selectedGeneration = generation;\n      },\n      active(generation, selectedGeneration) {\n        return generation === selectedGeneration;\n      },\n      getGenerationWithoutActive() {\n        return this.generations.value.filter(\n          (generation) => generation != this.selectedGeneration\n        );\n      },\n      getGenerationFrame(generation) {\n        return generation[0];\n      },\n      extractOrCleanString(str, returnExtracted = false) {\n        const pattern =\n          \/\\(?\\b(HCH|MIT|Lowstep|SCH|TIE|Midstep|Stepover|HER|TRA)\\b\\)?\/i;\n        const match = str.match(pattern);\n\n        if (match) {\n          return returnExtracted\n            ? match[1]\n            : str.replace(pattern, \"\").replace(\/\\s+\/g, \" \").trim();\n        }\n\n        return returnExtracted ? null : str.trim();\n      },\n      mainTitle(generation) {\n        let frame = this.getGenerationFrame(generation);\n        let title = this.extractOrCleanString(frame.title);\n        return (\n          title +\n          \" \" +\n          this.addModelYear(frame) +\n          \" - \" +\n          this.formatNumber(frame.price_lowest) +\n          \" \" +\n          this.getCurrency()\n        );\n      },\n      addModelYear(frame) {\n        if (frame.modelYear) {\n          return \" (\" + frame.modelYear + \")\";\n        }\n        return \"\";\n      },\n      getCurrency() {\n        const currencyMap = {\n          CH: \"CHF\",\n          DK: \"DKK\",\n          GB: \"GBP\",\n          PL: \"PLN\",\n          SE: \"SEK\",\n        };\n        const country = this.$store.utils.country;\n        return currencyMap[country] || \"EUR\";\n      },\n      formatNumber(number) {\n        if (this.$store.utils.country === \"CH\") {\n          return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \"'\");\n        } else {\n          return number.toString().replace(\/\\B(?=(\\d{3})+(?!\\d))\/g, \".\");\n        }\n      },\n    }));\n  });\n<\/script>\n<template id=\"filterComponent\">\n  <template x-if=\"showReset\">\n    <div id=\"filter\" class=\"bikefinder-filter mb-5 text-start\">\n      <h5 class=\"text-uppercase h-underline mt-4 position-relative\">\n        Filter\n        <div x-show=\"isFilterActive()\" class=\"small reset-filters\">\n          <span\n            @click=\"resetFilter()\"\n            class=\"btn-reset-filters\"\n            x-text=\"$store.utils.t($store.utils.translations.resetFilter)\"\n          >\n          <\/span>\n        <\/div>\n      <\/h5>\n      <div class=\"bike-counter mb-4\">\n        <span id=\"bikeCount\" x-text=\"countOfFilteredBikes.value\"><\/span> Bikes\n      <\/div>\n\n      <!-- Biketyp -->\n      <h5\n        class=\"mb-1\"\n        x-text=\"$store.utils.t($store.utils.translations.bikeType)\"\n      ><\/h5>\n      <div\n        class=\"small text-grey mb-2\"\n        x-text=\"$store.utils.t($store.utils.translations.bikeTypeSpeed)\"\n      ><\/div>\n      <div\n        x-key=\"'typeLineSelection'\"\n        x-data=\"lineselection(\n        { \n            items: typeFilterProps.sort((a, b) => a.context.order < b.context.order ? -1 : 1),\n            onSelected: onTypeSelected,\n            selectedFilter: selectedFilter,\n        }\n      )\"\n      ><\/div>\n\n      <template x-if=\"!hideBattery\">\n        <div class=\"bikefinder-filter-akku\">\n          <!-- Akku -->\n          <h5\n            class=\"mb-1\"\n            x-text=\"$store.utils.t($store.utils.translations.battery)\"\n          ><\/h5>\n          <div\n            class=\"small text-grey mb-2\"\n            x-text=\"$store.utils.t($store.utils.translations.unitBattery)\"\n          ><\/div>\n          <div\n            x-show=\"showReset\"\n            x-data=\"sliderselection(\n            { \n                items: batteryFilterProps,\n                onSelected: onBatterySelected,\n                id: 'battery-slider',\n                domLoaded: domLoaded,\n                options: { step: 100, values: true }\n            }\n          )\"\n          ><\/div>\n        <\/div>\n      <\/template>\n\n      <!-- Rahmenformen -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.frameShape)\"><\/h5>\n\n      <div\n        x-key=\"'frameLineSelection'\"\n        x-data=\"lineselection(\n        { \n            items: frameFilterProps.sort((a, b) => a.context.order < b.context.order ? -1 : 1),\n            onSelected: onFrameSelected,\n            selectedFilter: selectedFilter,\n        }\n      )\"\n      ><\/div>\n\n      <!-- Schaltung -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.gear)\"><\/h5>\n      <div\n        x-data=\"choiceselection(\n        { \n            items: gearFilterProps,\n            onSelected: onGearSelected \n        }\n      )\"\n      ><\/div>\n\n      <!-- Preis -->\n      <h5\n        class=\"mb-1\"\n        x-text=\"$store.utils.t($store.utils.translations.price)\"\n      ><\/h5>\n      <div\n        class=\"small text-grey mb-2\"\n        x-text=\"$store.utils.t($store.utils.translations.inCurrency)\"\n      ><\/div>\n      <div\n        x-data=\"sliderselection(\n        { \n            items: priceFilterProps,\n            onSelected: onPriceSelected,\n            id: 'price-slider',\n            domLoaded: domLoaded,\n            options: { step: 100 }\n        }\n      )\"\n      ><\/div>\n\n      <!-- Sale -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.sale)\"><\/h5>\n      <div\n        x-data=\"multiplechoiceselection(\n        { \n            items: saleFilterProps.concat(lastchanceFilterProps),\n            onSelected: onSaleOrLastchanceSelected \n        }\n      )\"\n      ><\/div>\n\n      <!-- Farben -->\n      <h5 x-text=\"$store.utils.t($store.utils.translations.color)\"><\/h5>\n      <div\n        x-data=\"colorselection(\n        { \n            items: colorFilterProps,\n            onSelected: onColorSelected \n        }\n      )\"\n      ><\/div>\n\n      <!-- Gewicht -->\n      <h5\n        class=\"mb-1\"\n        x-text=\"$store.utils.t($store.utils.translations.weight)\"\n      ><\/h5>\n      <div\n        class=\"small text-grey mb-2\"\n        x-text=\"$store.utils.t($store.utils.translations.unitWeight)\"\n      ><\/div>\n      <div\n        class=\"rslider\"\n        x-data=\"sliderselection(\n        { \n            items: weightFilterProps,\n            onSelected: onWeightSelected,\n            id: 'weight-slider',\n            domLoaded: domLoaded\n        }\n      )\"\n      ><\/div>\n    <\/div>\n  <\/template>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\n      \"filter\",\n      ({\n        frameFilterProps,\n        typeFilterProps,\n        batteryFilterProps,\n        gearFilterProps,\n        priceFilterProps,\n        weightFilterProps,\n        saleFilterProps,\n        lastchanceFilterProps,\n        newbikeFilterProps,\n        countOfFilteredBikes,\n        maxBikesCount,\n        colorFilterProps,\n        selectedFilter,\n        controller,\n      }) => ({\n        template: null,\n        frameFilterProps: frameFilterProps,\n        typeFilterProps: typeFilterProps,\n        batteryFilterProps: batteryFilterProps,\n        gearFilterProps: gearFilterProps,\n        priceFilterProps: priceFilterProps,\n        weightFilterProps: weightFilterProps,\n        saleFilterProps: saleFilterProps,\n        lastchanceFilterProps: lastchanceFilterProps,\n        newbikeFilterProps: newbikeFilterProps,\n        countOfFilteredBikes: countOfFilteredBikes,\n        maxBikesCount: maxBikesCount,\n        colorFilterProps: colorFilterProps,\n        selectedFrame: {},\n        selectedFrameImage: {},\n        controller: controller,\n        showReset: true,\n        domLoaded: false,\n        domUpdate: { value: 0 },\n        selectedFilter: selectedFilter,\n        hideBattery: false,\n        init() {\n          this.setup();\n          this.$nextTick(() => {\n            this.mounted();\n            this.render();\n          });\n        },\n        setup() {\n          this.template = document.getElementById(\"filterComponent\");\n        },\n        mounted() {},\n        render() {\n          this.$el.innerHTML = this.template.innerHTML;\n\n          document.addEventListener(\"DOMContentLoaded\", () => {\n            this.domLoaded = true;\n          });\n\n          this.$watch(\"selectedFilter\", (filter) => {\n            this.hideFilterSections(filter);\n          });\n        },\n        hideFilterSections(filter) {\n          \/\/ Hide Battery\n          const hideBattery = [\"Bike\", \"S-Pedelec\"].includes(\n            filter.properties?.category?.value\n          );\n\n          if (hideBattery) {\n            this.hideBattery = true;\n          } else {\n            this.hideBattery = false;\n          }\n        },\n        onFrameSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onTypeSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onBatterySelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onGearSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onPriceSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onWeightSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, initial);\n        },\n        onSaleOrLastchanceSelected(property, checked, initial = true) {\n          if (checked) {\n            this.controller.filterAddPropertyAction(property, initial);\n          } else {\n            this.controller.filterRemovePropertyAction(property);\n          }\n        },\n        onColorSelected(property, initial = true) {\n          this.controller.filterAddPropertyAction(property, true);\n        },\n        resetFilter() {\n          this.showReset = false;\n          this.controller.resetFilterAction();\n\n          this.$nextTick(() => {\n            this.showReset = true;\n          });\n        },\n        isFilterActive() {\n          return !this.selectedFilter.initial;\n        },\n      })\n    );\n  });\n<\/script>\n<template id=\"lineSelectionComponent\">\n  <div class=\"bikefilter-biketyp mb-4\">\n    <ul class=\"nav nav-tabs\">\n      <template x-for=\"(item, index) in items\">\n        <li class=\"nav-item\">\n          <button\n            @click=\"selected(item, index)\"\n            class=\"nav-link\"\n            :class=\"activeItem &#038;&#038; activeItem.value === item.value ? 'active' : ''\"\n            style=\"outline: none\"\n            data-bs-toggle=\"tooltip\"\n            data-placement=\"top\"\n            :title=\"$store.utils.t(item.context.text)\"\n          >\n            <template x-if=\"item.context &#038;&#038; item.context.type == 'icon'\">\n              <img :src=\"item.context.icon\" style=\"width: 48px; height: 28px\" \/>\n            <\/template>\n            <template x-if=\"item.context &#038;&#038; item.context.type == 'text'\">\n              <span\n                style=\"width: 48px; height: 28px\"\n                x-text=\"$store.utils.t(item.context.text)\"\n              ><\/span>\n            <\/template>\n          <\/button>\n        <\/li>\n      <\/template>\n    <\/ul>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"lineselection\", ({ items, onSelected, selectedFilter }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      selectedFilter: selectedFilter,\n      selectedIndex: -1,\n      activeItem: null,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"lineSelectionComponent\");\n      },\n      mounted() {\n        this.$watch(\"selectedFilter\", (filter) => {\n          this.activeItem = this.findActiveItem(filter);\n        });\n      },\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n      selected(item, index) {\n        this.selectedIndex = index;\n        this.onSelected(item, false);\n      },\n      findActiveItem(filter) {\n        if (this.items[0].propertyPath in filter.properties) {\n          let found = this.items.find((item) => {\n            return (\n              item.value === filter.properties[this.items[0].propertyPath].value\n            );\n          });\n          return found;\n        }\n      },\n    }));\n  });\n<\/script>\n<template id=\"sliderSelectionComponent\">\n\t<div :style=\"!sliderReady ? 'opacity: 0' : ''\" class=\"bikefilter-rahmenform mb-4 mt-3\">\n\t\t<div :style=\"!domLoaded &#038;&#038; !slider ? 'opacity: 0' : ''\">\n\t\t\t<input :id=\"id\" type=\"range\" \/>\n\t\t<\/div>\n\t<\/div>\n<\/template>\n\n<script>\n\tdocument.addEventListener(\"alpine:init\", () => {\n\t\tAlpine.data(\"sliderselection\", ({ items, onSelected, id, domLoaded, options = {} }) => ({\n\t\t\ttemplate: null,\n\t\t\titems: [],\n\t\t\tonSelected: onSelected,\n\t\t\tid: id,\n\t\t\tvalue: 0,\n\t\t\tslider: items,\n\t\t\tdomLoaded: domLoaded,\n\t\t\tmin: 0,\n\t\t\tmax: 0,\n\t\t\toptions: options,\n\t\t\tinitial: true,\n\t\t\tsliderReady: false,\n\t\t\tinit() {\n\t\t\t\tthis.setup();\n\t\t\t\tthis.$nextTick(() => {\n\t\t\t\t\tthis.mounted();\n\t\t\t\t\tthis.render();\n\t\t\t\t});\n\t\t\t},\n\t\t\tsetup() {\n\t\t\t\tthis.template = document.getElementById(\"sliderSelectionComponent\");\n\t\t\t},\n\t\t\tmounted() {\n\t\t\t\tif (items.length) {\n\t\t\t\t\tthis.items = items.sort((a, b) => (Number(a.value) > Number(b.value) ? 1 : -1));\n\n\t\t\t\t\tthis.min = this.items[0].value;\n\t\t\t\t\tthis.max = this.items.slice(-1)[0].value;\n\t\t\t\t\tthis.value = this.max;\n\t\t\t\t}\n\t\t\t},\n\t\t\trender() {\n\t\t\t\tthis.$el.innerHTML = this.template.innerHTML;\n\n\t\t\t\tdocument.addEventListener(\"DOMContentLoaded\", () => {\n\t\t\t\t\tthis.domLoaded = true;\n\t\t\t\t\tthis.initRangeSlider();\n\t\t\t\t});\n\n\t\t\t\tsetTimeout(() => {\n\t\t\t\t\tif (!this.domLoaded) {\n\t\t\t\t\t\tthis.initRangeSlider();\n\t\t\t\t\t}\n\t\t\t\t}, 400);\n\t\t\t},\n\t\t\tinitRangeSlider() {\n\t\t\t\tthis.domLoaded = true;\n\t\t\t\tthis.initial = true;\n\n\t\t\t\tconst min = this.roundMin(parseInt(this.min, 10));\n\t\t\t\tconst max = this.roundMax(parseInt(this.max, 10));\n\n\t\t\t\tthis.slider = new rSlider({\n\t\t\t\t\ttarget: \"#\" + this.id,\n\t\t\t\t\tvalues: options.values && options.values == true ? this.getAllValues() : { min: min, max: max },\n\t\t\t\t\trange: true,\n\t\t\t\t\ttooltip: true,\n\t\t\t\t\tstep: options.step ? options.step : 1,\n\t\t\t\t\tscale: false,\n\t\t\t\t\tlabels: true,\n\t\t\t\t\tvariableWidth: true,\n\t\t\t\t\tunit: \"kg\",\n\t\t\t\t\tset: [this.min, this.max],\n\t\t\t\t\tonChange: (vals) => {\n\t\t\t\t\t\t\/\/ vals is not correct so get from index\n\t\t\t\t\t\tlet min = Number(this.slider.conf.values[this.slider.values.start]);\n\t\t\t\t\t\tlet max = Number(this.slider.conf.values[this.slider.values.end]);\n\t\t\t\t\t\tthis.setValue(min, max);\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst sliderElements = document.querySelectorAll(\".rs-container\");\n\t\t\t\tsliderElements.forEach((element) => {\n\t\t\t\t\telement.addEventListener(\"mousedown\", () => {\n\t\t\t\t\t\tthis.initial = false;\n\t\t\t\t\t});\n\t\t\t\t\telement.addEventListener(\"touchstart\", () => {\n\t\t\t\t\t\tthis.initial = false;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tthis.sliderReady = true;\n\t\t\t},\n\t\t\tsetValue(min, max) {\n\t\t\t\tlet range = this.items.filter((item) => {\n\t\t\t\t\tconst itemValue = Number(item.value);\n\t\t\t\t\treturn itemValue >= min && itemValue <= max;\n\t\t\t\t});\n\t\t\t\tif (range.length === 0) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet maxOfRange = range.reduce((max, obj) => {\n\t\t\t\t\treturn Number(obj.value) > Number(max.value) ? obj : max;\n\t\t\t\t}, range[0]);\n\n\t\t\t\tlet minOfRange = range.reduce((min, obj) => {\n\t\t\t\t\treturn Number(obj.value) < Number(min.value) ? obj : min;\n\t\t\t\t}, range[0]);\n\n\t\t\t\tif (maxOfRange) {\n\t\t\t\t\tif (minOfRange) {\n\t\t\t\t\t\tmaxOfRange[\"min\"] = minOfRange.value;\n\t\t\t\t\t\tthis.select(maxOfRange, false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tselect(property) {\n\t\t\t\tthis.onSelected(property, this.initial);\n\t\t\t},\n\t\t\tgetAllValues() {\n\t\t\t\treturn this.items.map((item) => Number(item.value));\n\t\t\t},\n\t\t\troundMin(num) {\n\t\t\t\tif (num > 100) {\n\t\t\t\t\treturn Math.floor(num \/ 50) * 50;\n\t\t\t\t} else {\n\t\t\t\t\treturn Math.floor(num \/ 10) * 10;\n\t\t\t\t}\n\t\t\t},\n\t\t\troundMax(num) {\n\t\t\t\tif (num > 100) {\n\t\t\t\t\treturn Math.ceil(num \/ 50) * 50;\n\t\t\t\t} else {\n\t\t\t\t\treturn Math.ceil(num \/ 10) * 10;\n\t\t\t\t}\n\t\t\t},\n\t\t}));\n\t});\n<\/script>\n<template id=\"choiceSelectionComponent\">\n  <div class=\"bikefilter-schaltung mb-4\">\n    <fieldset>\n      <template x-for=\"(item, index) in items\">\n        <div class=\"form-check\">\n          <input\n            type=\"radio\"\n            :id=\"item.propertyPath + index\"\n            name=\"drone\"\n            value=\"huey\"\n            x-on:input.change=\"onSelected(item, false)\"\n            class=\"form-check-input\"\n          \/>\n          <label\n            :for=\"item.propertyPath + index\"\n            x-text=\"$store.utils.t(item.context.text)\"\n            class=\"form-check-label\"\n          ><\/label>\n        <\/div>\n      <\/template>\n    <\/fieldset>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"choiceselection\", ({ items, onSelected }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      value: 0,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"choiceSelectionComponent\");\n      },\n      mounted() {},\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n    }));\n  });\n<\/script>\n<template id=\"multipleChoiceSelectionComponent\">\n  <div class=\"bikefilter-schaltung mb-4\">\n    <fieldset>\n      <template x-for=\"(item, index) in items\">\n        <div class=\"form-check\">\n          <input\n            type=\"checkbox\"\n            :id=\"item.propertyPath + index\"\n            name=\"drone\"\n            value=\"huey\"\n            x-on:input.change=\"onSelected(item, $event.target.checked, false)\"\n            class=\"form-check-input\"\n          \/>\n          <label\n            :for=\"item.propertyPath + index\"\n            x-text=\"$store.utils.t(item.context.text)\"\n            class=\"form-check-label\"\n          ><\/label>\n        <\/div>\n      <\/template>\n    <\/fieldset>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"multiplechoiceselection\", ({ items, onSelected }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      value: 0,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\n          \"multipleChoiceSelectionComponent\"\n        );\n      },\n      mounted() {},\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n    }));\n  });\n<\/script>\n<template id=\"colorSelectionComponent\">\n  <div class=\"color-options mb-4\">\n    <ul class=\"ps-0\">\n      <template x-for=\"(item, index) in items\">\n        <li>\n          <button\n            @click=\"selected(item, index, false)\"\n            :class=\"'btn filter-color-' + item.value.toLowerCase() + ' ' + ((selectedIndex == index) ? 'active' : '')\"\n            data-bs-toggle=\"tooltip\"\n            data-placement=\"top\"\n            :title=\"item.description\"\n          ><\/button>\n        <\/li>\n      <\/template>\n    <\/ul>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\"colorselection\", ({ items, onSelected }) => ({\n      template: null,\n      items: items,\n      onSelected: onSelected,\n      selectedIndex: -1,\n      init() {\n        this.setup();\n        this.$nextTick(() => {\n          this.mounted();\n          this.render();\n        });\n      },\n      setup() {\n        this.template = document.getElementById(\"colorSelectionComponent\");\n      },\n      mounted() {},\n      render() {\n        this.$el.innerHTML = this.template.innerHTML;\n      },\n      selected(item, index, initial) {\n        this.selectedIndex = index;\n        this.onSelected(item, initial);\n      },\n    }));\n  });\n<\/script>\n<template id=\"bikefinderComponent\">\n  <div class=\"bikefinder\">\n    <div class=\"row\">\n      <div class=\"col-md-4 col-lg-3 bikefinder-filter-col\">\n        <button\n          class=\"btn btn-primary filter-toggle d-md-none mb-3\"\n          data-show=\"Filter anzeigen\"\n          data-hide=\"Filter ausblenden\"\n          x-text=\"$store.utils.t($store.utils.translations.showFilter)\"\n        ><\/button>\n\n        <div\n          class=\"bikefinder-filter-content\"\n          x-data=\"filter({ \n            frameFilterProps: uniquePropFrames(), \n            typeFilterProps: model.uniquePropTypes(), \n            batteryFilterProps: uniquePropBatteries(), \n            gearFilterProps: uniquePropGears(),\n            priceFilterProps: uniquePropPrices(),\n            weightFilterProps: uniquePropWeights(),\n            saleFilterProps: model.uniquePropSales(),\n            lastchanceFilterProps: model.uniquePropLastchance(),\n            newbikeFilterProps: model.uniquePropNewbike(),\n            countOfFilteredBikes: state.countOfFilteredBikes,\n            maxBikesCount: state.maxBikesCount,\n            colorFilterProps: uniquePropColors(),\n            selectedFilter: state.selectedFilter,\n            controller: controller\n          })\"\n        ><\/div>\n      <\/div>\n      <div class=\"col-md-8 col-lg-9\">\n        <div class=\"dropdown text-end dropdown-underline\">\n          <button\n            class=\"btn btn-secondary dropdown-toggle p-0 pb-1 me-3 me-md-4\"\n            type=\"button\"\n            id=\"dropdownSort\"\n            data-bs-toggle=\"dropdown\"\n            aria-haspopup=\"true\"\n            aria-expanded=\"false\"\n            x-text=\"$store.utils.t($store.utils.translations.sortBy)\"\n          ><\/button>\n\n          <div\n            class=\"dropdown-menu dropdown-menu-end dropdown-sort\"\n            aria-labelledby=\"dropdownSort\"\n          >\n            <a\n              @click=\"controller.sortNewestAlphaAction()\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'newestalpha' ? 'active' : ''\"\n              id=\"sort-newest-alpha\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByNewestAlpha)\"\n            ><\/a>\n            <a\n              @click=\"controller.sortAlphaAction()\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'alpha' ? 'active' : ''\"\n              id=\"sort-alpha\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByAlpha)\"\n            ><\/a>\n            <a\n              @click=\"controller.sortPriceAction()\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'priceASC' ? 'active' : 'peter'\"\n              id=\"sort-price-asc\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByAsc)\"\n            ><\/a>\n            <a\n              @click=\"controller.sortPriceAction(true)\"\n              class=\"dropdown-item\"\n              :class=\"state.currentSort == 'priceDESC' ? 'active' : 'peter'\"\n              id=\"sort-price-desc\"\n              x-text=\"$store.utils.t($store.utils.translations.sortByDesc)\"\n            ><\/a>\n          <\/div>\n        <\/div>\n        <template x-if=\"showBikeSort &#038;&#038; initialReady\">\n          <div\n            x-data=\"{ bikesByGenerations: state.filteredBikesGroupedByGenerations  }\"\n            class=\"bikefinder-bikes p-md-3 p-lg-4\"\n          >\n            <div\n              x-show=\"state.countOfFilteredBikes.value == 0\"\n              class=\"no-results\"\n            >\n              <span\n                x-text=\"$store.utils.t($store.utils.translations.noResults)\"\n              ><\/span>\n            <\/div>\n            <div class=\"bikefinder-grid\">\n              <template x-for=\"(value, index) in bikesByGenerations\">\n                <div\n                  x-data=\"biketeaser({ frames: bikesByGenerations[index], framesAsGenerations: true, framesMeta: model.frameFilterModel })\"\n                ><\/div>\n              <\/template>\n            <\/div>\n          <\/div>\n        <\/template>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/template>\n\n<script>\n  document.addEventListener(\"alpine:init\", () => {\n    Alpine.data(\n      \"bikefinder\",\n      ({\n        blockId,\n        model,\n        store,\n        state,\n        utils,\n        controller,\n        filterParamsResolver,\n      }) => ({\n        blockId: blockId,\n        model: model,\n        store: store,\n        state: state,\n        utils: utils,\n        controller: controller,\n        filterParamsResolver: filterParamsResolver,\n        showBikeSort: false,\n        initialReady: false,\n        init() {\n          this.setup();\n          this.$nextTick(() => {\n            this.mounted();\n            this.render();\n          });\n        },\n        setup() {\n          this.template = document.getElementById(\"bikefinderComponent\");\n        },\n        mounted() {\n          this.model.variantsToUniqueFramesAndFlattedVariants(\n            this.model.modules[this.blockId].bikes,\n            this.blockId\n          );\n\n          this.$watch(\"state.selectedFilter\", (value) => {\n            this.filter(value);\n          });\n\n          this.$watch(\"state.filteredBikesGroupedByGenerations\", (grouped) => {\n            this.reactiveBikeSort();\n          });\n\n          setTimeout(() => {\n            const { filters } = this.filterParamsResolver.defaultParams;\n            Object.keys(filters).forEach((key) => {\n              this.filterByParams(key, filters[key], true);\n            });\n            \/\/ wait to set all default filter properties - for resetFilterAction() -- to prevent watch updates on state.selectedFilter\n            this.state.defaultFilterProperties = JSON.stringify(\n              this.state.selectedFilter.properties\n            );\n\n            this.initialReady = true;\n          }, 1500);\n        },\n        render() {\n          this.$el.innerHTML = this.template.innerHTML;\n        },\n        filterByParams(key, value, initial) {\n          const propsMap = {\n            category: {\n              getProps: () => this.model.uniquePropTypes(),\n              keyName: \"value\",\n            },\n            primary_basecolour: {\n              getProps: () => this.uniquePropColors(),\n              keyName: \"value\",\n            },\n            frame_type: {\n              getProps: () => this.uniquePropFrames(),\n              keyName: \"value\",\n            },\n            \"bike_specifics.gear.gear_type\": {\n              getProps: () => this.uniquePropGears(),\n              keyName: \"value\",\n            },\n            \"ebike_specifics.battery_range.battery_capacity\": {\n              getProps: () => this.uniquePropBatteries(),\n              keyName: \"value\",\n            },\n          };\n\n          if (key in propsMap) {\n            const mapResult = propsMap[key];\n            const prop = mapResult\n              .getProps()\n              .find((prop) => prop[mapResult[\"keyName\"]] == value);\n            if (prop) {\n              this.controller.filterAddPropertyAction(prop, initial);\n            }\n\n            this.state.selectedFilter.initial = false;\n          }\n        },\n\n        filter(value) {\n          this.model.groupedFrames[this.blockId].forEach((group) => {\n            group.forEach((frame) => {\n              frame.filter(value);\n            });\n          });\n\n          this.state.filteredBikes =\n            this.controller.getOnlyBikesWhereFramesWithVariants(\n              this.model.groupedFrames[this.blockId]\n            );\n\n          const generations = this.controller.getGenerations(\n            this.state.filteredBikes\n          );\n          this.state.filteredBikesGroupedByGenerations = generations;\n\n          const countOfBikes = this.controller.calculateCountOfFilteredBikes(\n            this.blockId\n          );\n          if (this.state.selectedFilter.initial) {\n            this.state.maxBikesCount.value = countOfBikes;\n          }\n\n          this.state.countOfFilteredBikes.value = countOfBikes;\n          this.controller.sortNewestAlphaAction();\n\n          \/\/ Sync Filter\n          this.filterParamsResolver.setFiltersParams(\n            this.filterParamsResolver.getActiveFilters()\n          );\n        },\n        reactiveBikeSort() {\n          this.showBikeSort = false;\n          this.$nextTick(() => {\n            this.showBikeSort = true;\n          });\n        },\n        uniquePropFrames() {\n          return this.model.uniquePropFrames(this.blockId);\n        },\n        uniquePropBatteries() {\n          return this.model.uniquePropBatteries(this.blockId);\n        },\n        uniquePropGears() {\n          return this.model.uniquePropGears(this.blockId);\n        },\n        uniquePropPrices() {\n          return this.model.uniquePropPrices(this.blockId);\n        },\n        uniquePropWeights() {\n          return this.model.uniquePropWeights(this.blockId);\n        },\n        uniquePropColors() {\n          return this.model.uniquePropColors(this.blockId);\n        },\n      })\n    );\n  });\n<\/script>\n\n<style type=\"text\/css\">\n  body.modal-open {\n    padding-right: 0px !important;\n    overflow: auto !important;\n  }\n\n  body {\n    padding-right: 0 !important;\n  }\n\n  body.modal-open header,\n  body.modal-open .content {\n    padding-right: 0 !important;\n  }\n<\/style>\n<div x-data='bikefinder({ \n    blockId: \"ZIVsca\", \n    model: $store.bikefinderModel, \n    store: $store.bikefinderStore, \n    state: $store.bikefinderState, \n    utils: $store.utils, \n    controller: $store.bikefinderController,\n    filterParamsResolver: $store.bikefinderFilterParamsResolver })'>\n<\/div>\n<\/div>\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n<div class=\"lazyblock-nncontainer-2ldAbP wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-2ldAbP\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<h3 class=\"wp-block-heading\">Tarvitsevatko naiset erilaisia polkupy\u00f6ri\u00e4?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Naisten anatomia eroaa miesten anatomiasta. Miehet ovat keskim\u00e4\u00e4rin 15 % painavampia ja 10\u201315 cm pidempi\u00e4. Muut erot ovat kuitenkin t\u00e4rke\u00e4mpi\u00e4. Naisten lantio on leve\u00e4mpi ja py\u00f6re\u00e4mpi, ja se on hieman eteenp\u00e4in kallistunut. Vastineeksi naisten hartiat ovat yleens\u00e4 kapeammat. Saman pituisia naisia ja miehi\u00e4 verrattaessa naisten k\u00e4det ja jalat ovat yleens\u00e4 noin 10 % lyhyemm\u00e4t, mutta heid\u00e4n keskivartalonsa on noin 2\u20135 % pidempi. Ja kyll\u00e4, miehill\u00e4 on my\u00f6s keskim\u00e4\u00e4rin suuremmat k\u00e4det ja jalat.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vaikka fyysiset erot vaikuttavatkin py\u00f6r\u00e4n tuntumaan, erot eiv\u00e4t ole tarpeeksi suuria oikeuttamaan sukupuolieroteltuja py\u00f6r\u00e4malleja. Vain py\u00f6r\u00e4n sopivalla istuvuudella on v\u00e4li\u00e4. Moderneista py\u00f6rist\u00e4 l\u00f6ytyy niin monia tapoja luoda mahdollisimman ergonominen ajoasento, ett\u00e4 samanpituinen nainen ja mies voivat ajaa samalla py\u00f6r\u00e4ll\u00e4, vaikka heid\u00e4n ruumiinrakenteensa olisivatkin muuten hyvin erilaiset. Lukemalla lis\u00e4\u00e4 opit, miten se on mahdollista.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">T\u00e4st\u00e4 syyst\u00e4 emme myy &#8220;naisten polkupy\u00f6ri\u00e4&#8221;, vaan polkupy\u00f6ri\u00e4, joiden rungon stepover-korkeus on matalampi. Moderni merkki keskittyy t\u00e4rkeimpiin erottaviin tekij\u00f6ihin. Kyseess\u00e4 on \u201dmidstep\u201d- tai \u201dlowstep\u201d-runko, mutta ei \u201dstepover\u201d-runko.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Mink\u00e4 kokoinen py\u00f6r\u00e4 naisten kannattaa valita?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Diamant tarjoaa jokaisen py\u00f6r\u00e4ns\u00e4 2\u20134 koossa, ja geometria on kaikissa runkomalleissa sama. Esimerkiksi L-kokoinen midstep-runko on mitoiltaan sama kuin L-kokoinen highstep-runko.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Rungon koot ovat p\u00e4\u00e4llekk\u00e4isi\u00e4. 174 cm pituiselle, 81 cm sis\u00e4sauman omaavalle ajajalle sopii joko koko M tai L, riippuen ajajan henkil\u00f6kohtaisista mieltymyksist\u00e4 ja ruumiinrakenteesta. Kaksi 174 cm pitk\u00e4\u00e4 kuljettajaa voi tehd\u00e4 erilaisia p\u00e4\u00e4t\u00f6ksi\u00e4. T\u00e4t\u00e4 ei my\u00f6sk\u00e4\u00e4n pid\u00e4 unohtaa: Yksil\u00f6iden v\u00e4linen vaihtelu naisten ja miesten kesken on yht\u00e4 suurta kuin yksil\u00f6iden v\u00e4linen vaihtelu n\u00e4iden ryhmien v\u00e4lill\u00e4.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Runkogeometriamme on suunniteltu vastaamaan sek\u00e4 sukupuolten sis\u00e4ist\u00e4 ett\u00e4 v\u00e4list\u00e4 vaihtelua. Naiset valitsevat usein esimerkiksi kahdesta koosta pienemm\u00e4n, koska heid\u00e4n raajansa ovat keskim\u00e4\u00e4rin lyhyemm\u00e4t. Suosittelemme py\u00f6r\u00e4n sovittamista paikallisella j\u00e4lleenmyyj\u00e4ll\u00e4, jotta voit m\u00e4\u00e4ritt\u00e4\u00e4 henkil\u00f6kohtaiset asetukset.<\/p>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n\n<div class=\"wp-block-cover is-light\"><img data-dominant-color=\"b37d81\" data-has-transparency=\"false\" loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1707\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" class=\"wp-block-cover__image-background wp-image-53441 size-full not-transparent\" alt=\"Di 25 mahon lifestyle\" src=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-scaled.avif\" style=\"--dominant-color: #b37d81; object-position:44% 59%\" data-object-fit=\"cover\" data-object-position=\"44% 59%\" srcset=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-scaled.avif 2560w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-300x200.avif 300w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-1024x683.avif 1024w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-768x512.avif 768w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-1536x1024.avif 1536w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_25_Mahon_Lifestyle_67I7393_300dpi-2048x1365.avif 2048w\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-0 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained\">\n<p class=\"has-text-align-center has-large-font-size wp-block-paragraph\"><\/p>\n<\/div><\/div>\n\n\n<div class=\"lazyblock-nncontainer-Fk6lF wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-Fk6lF\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<h3 class=\"wp-block-heading\">26 tuuman kiekot vs. 28 tuuman kiekot: Totuus kiekkokokoista<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Historiallisessa \u201dnaisten py\u00f6r\u00e4ss\u00e4\u201d oli usein pienet 26 tuuman kiekot. Logiikka oli yht\u00e4 yksinkertainen kuin virheellinenkin: Jos naiset ovat lyhyempi\u00e4, heid\u00e4n on oltava l\u00e4hemp\u00e4n\u00e4 maata. Pohdi vaikka maastopy\u00f6rien kehityst\u00e4. Aiemmin niiss\u00e4 oli 26 tuuman kiekot, jotta painopiste oli matalammalla nopean polkuajon mahdollistamiseksi. Nyky\u00e4\u00e4n pienemm\u00e4t kiekot ovat korvautuneet suuremmilla 27,5\u201d ja 29\u201d kiekkoilla. Ne toimivat paremmin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Suuremmat kiekot tuntuvat mukavammilta. Ne rullaavat paremmin ep\u00e4tasaisilla pinnoilla ja reunakivill\u00e4. Keski\u00f6n ja takapy\u00f6r\u00e4n akselin v\u00e4linen et\u00e4isyys on pidempi \u2013 jyrkiss\u00e4 nousuissa etukiekot eiv\u00e4t irtoa maasta niin nopeasti. Trekking\u00ae- ja kaupunkipy\u00f6riss\u00e4, joiden tavaratelineiss\u00e4 kuljetetaan usein tavaraa, lis\u00e4pituus lis\u00e4\u00e4 turvallisuutta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kehon pituudella ei yleens\u00e4 ole vaikutusta kiekkokoon valintaan. Vain hyvin lyhyet henkil\u00f6t (noin 152 cm pituiset, sis\u00e4sauma 75 cm) hy\u00f6tyv\u00e4t pienemmist\u00e4 kiekoista. Heid\u00e4n pituuteensa sovitettuihin geometrioihin ei mahtuisi en\u00e4\u00e4 suurempia kiekkoja.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Vinkkej\u00e4 py\u00f6r\u00e4n istuvuuden s\u00e4\u00e4t\u00e4miseen naisille sopivaksi<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Naiset voivat s\u00e4\u00e4t\u00e4\u00e4 kuutta py\u00f6r\u00e4n osaa mukavuuden ja suorituskyvyn optimoimiseksi. Ohjaustanko (muoto ja leveys), vaihdevivut ja jarruvivut (sijainti), ohjainkannatin (pituus ja kulma), satula (sijainti, leveys ja muoto), poljinkammet (pituus) ja vaihdesuhde.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ohjaustangot<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Kapea ohjaustanko sopii kapeille hartioille. Ohjaustanko, jossa on vahvasti taaksep\u00e4in kaartuva muotoilu, luo entist\u00e4kin pystymm\u00e4n ajoasennon.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Vaihde- ja jarruvivut<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Jos k\u00e4tesi ovat pienet, voit muuttaa kaikkien vipujen tarkkaa sijaintia joustavasti. Joskus voit my\u00f6s muuttaa vivun ja ohjaustangon v\u00e4list\u00e4 et\u00e4isyytt\u00e4.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ohjainkannatin<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Ohjainkannattimen pituus ja kulma vaikuttavat yhdess\u00e4 siihen, kuinka pystyss\u00e4 tai ojennettuna istut py\u00f6r\u00e4ll\u00e4, mutta my\u00f6s siihen, kuinka ketter\u00e4sti py\u00f6r\u00e4 reagoi ohjaukseen. Jopa pienet muutokset, kuten 10 mm tai 3\u00b0, voivat muuttaa ajokokemustasi huomattavasti.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Satula<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Satula on yksi py\u00f6r\u00e4n joustavimmista osista. Paitsi korkeus, my\u00f6s kallistus ja vaakasuora suuntaus voivat vaihdella. Monet naiset \u2013 tosin eiv\u00e4t kaikki \u2013 suosivat leve\u00e4mpi\u00e4 satuloita. Hyvin koulutetun henkil\u00f6kunnan py\u00f6ritt\u00e4m\u00e4t py\u00f6r\u00e4liikkeet mittaavat aina optimaalisen satulan leveyden analysoimalla lantiosi painopisteet. Naiset, jotka tuntevat ajaessaan paljon painetta intiimialueellaan, hy\u00f6tyv\u00e4t yleens\u00e4 satuloista, joissa on aukko tai lyhyempi k\u00e4rki.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Poljinkampien pituus<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Poljinkampia on eripituisia. Pitk\u00e4t poljinkammet v\u00e4hent\u00e4v\u00e4t tehokkuutta. Ne voivat ajan my\u00f6t\u00e4 vahingoittaa polviasi. Jotkut naiset ja yh\u00e4 useammat miehet suosivat siksi vain 165 mm pitki\u00e4 tai jopa lyhyempi\u00e4 kampivarsia.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">V\u00e4lityssuhde<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Suurimman ja pienimm\u00e4n takarattaan sek\u00e4 eturattaan v\u00e4linen suhde m\u00e4\u00e4ritt\u00e4\u00e4 vaihdesuhteen. Koska naisten maksimaalinen teho on yleens\u00e4 pienempi, he hy\u00f6tyv\u00e4t v\u00e4hemm\u00e4n \u201draskaista\u201d vaihteista ja polkimien nopeammasta py\u00f6rimisest\u00e4 samalla nopeudella. Yhden eturattaan ratkaisumme pienent\u00e4v\u00e4t vaihteiden v\u00e4lisi\u00e4 hyppyj\u00e4 ja j\u00e4tt\u00e4v\u00e4t pois raskaimmat vaihteet.<\/p>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>\n\n\n<div class=\"wp-block-cover is-light\"><img data-dominant-color=\"a57b81\" data-has-transparency=\"false\" loading=\"lazy\" decoding=\"async\" width=\"2560\" height=\"1707\" sizes=\"auto, (max-width: 2560px) 100vw, 2560px\" class=\"wp-block-cover__image-background wp-image-55339 size-full not-transparent\" alt=\"My 24 zing trip lifestyle\" src=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-scaled.avif\" style=\"--dominant-color: #a57b81; object-position:58% 39%\" data-object-fit=\"cover\" data-object-position=\"58% 39%\" srcset=\"https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-scaled.avif 2560w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-300x200.avif 300w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-1024x683.avif 1024w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-768x512.avif 768w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-1536x1024.avif 1536w, https:\/\/www.diamantrad.com\/wp-content\/uploads\/2025\/03\/DI_24_Zing_Trip_Lifestyle_67I5238_300dpi-2048x1365.avif 2048w\" \/><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-0 has-background-dim\"><\/span><div class=\"wp-block-cover__inner-container is-layout-constrained wp-block-cover-is-layout-constrained\">\n<p class=\"has-text-align-center has-large-font-size wp-block-paragraph\"><\/p>\n<\/div><\/div>\n\n\n<div class=\"lazyblock-nncontainer-21p2W8 wp-block-lazyblock-nncontainer\"><div class=\"section-standard\">\r\n  <div class=\"container\" id=\"container-21p2W8\">\r\n    <div class=\"row\">\r\n      <div class=\"col py-4 py-lg-5\">\r\n        <div class=\"lazyblock-inner-blocks\">\n\n<h3 class=\"wp-block-heading\">\u201dNaisten polkupy\u00f6r\u00e4\u201d ja kori<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Korit ovat k\u00e4tev\u00e4 lis\u00e4varuste tavaroiden nopeaan ja k\u00e4tev\u00e4\u00e4n kuljettamiseen. Korin kiinnitt\u00e4miseen tarvitset sopivan tavaratelineen tai kiinnikkeen. Korin voi kiinnitt\u00e4\u00e4 kolmella tavalla. Onneksi kaikki kolme vaihtoehtoa ovat yhteensopivia kaikkien runkomallien kanssa. Ota yhteytt\u00e4 luotettavaan py\u00f6r\u00e4liikkeeseen ja l\u00f6yd\u00e4 suosikkikorisi heid\u00e4n huolellisesti kootusta valikoimastaan.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Voit kiinnitt\u00e4\u00e4 korin takatavaratelineeseen sovittimen avulla. Racktime- ja Basil (MIK) -merkkiset tavaratelineet tekev\u00e4t kiinnitt\u00e4misest\u00e4 erityisen helppoa. Haittapuoli: Et n\u00e4e tavaroita takatavaratelineell\u00e4. Takakiinnityksen etu on kuitenkin se, ett\u00e4 taakse kiinnitetty kori ei vaikuta ajettavuuteen eik\u00e4 py\u00f6r\u00e4n hallittavuuteen.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Vaihtoehtoisesti voit kiinnitt\u00e4\u00e4 korin halutessasi etutavaratelineeseen. Emme suosittele sit\u00e4 useimmille polkupy\u00f6rillemme. Vaikka matkatavarasi ovat etukiinnityksess\u00e4 k\u00e4tev\u00e4sti aina n\u00e4kyviss\u00e4, etukiinnitteiset korit eiv\u00e4t toimi hyvin etujousituksen kanssa.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Kolmas vaihtoehto on kiinnitt\u00e4\u00e4 kori ohjaustankoon. S\u00e4hk\u00f6py\u00f6riss\u00e4 n\u00e4ytt\u00f6 voi joskus est\u00e4\u00e4 t\u00e4llaisen asennuksen suorittamisen. Ongelman ratkaisemiseksi on saatavana erityisi\u00e4 ohjaustangon kiinnikkeit\u00e4. \u00c4l\u00e4 kuitenkaan pakkaa ohjaustankokoreja liian t\u00e4yteen, sill\u00e4 niiden korkea painopiste voi vaikuttaa ajon vakauteen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lopuksi: Millainen on paras mahdollinen naisten polkupy\u00f6r\u00e4?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Paras \u201dnaisten py\u00f6r\u00e4\u201d on se py\u00f6r\u00e4, joka sopii juuri sinun tarpeisiisi. Ymm\u00e4rr\u00e4mme, ett\u00e4 monet naiset suosivat midstep- ja lowstep-runkoja. Ymm\u00e4rr\u00e4mme my\u00f6s, ett\u00e4 naiset suosivat py\u00f6riss\u00e4\u00e4n usein kirkkaampia ja rohkeampia v\u00e4risuunnitteluvalintoja. Otamme t\u00e4m\u00e4n huomioon v\u00e4rivalikoimaamme kootessamme. Haluamme kuitenkin toistaa ja korostaa seuraavaa: Runko ei m\u00e4\u00e4rit\u00e4, mik\u00e4 on naisten py\u00f6r\u00e4 \u2013 sen m\u00e4\u00e4ritt\u00e4\u00e4 py\u00f6r\u00e4ilij\u00e4. Midstep- ja lowstep-polkupy\u00f6r\u00e4t sopivat kaikille, jotka arvostavat mukavuutta ja helppok\u00e4ytt\u00f6isyytt\u00e4 sukupuolesta riippumatta.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Ihmiset ovat erilaisia. Jos py\u00f6r\u00e4 ei tunnu hyv\u00e4lt\u00e4 koeajon aikana, pienet s\u00e4\u00e4t\u00f6toimenpiteet voivat parantaa tilannetta suuresti. Suosittelemme aina luotettavalla paikallisella j\u00e4lleenmyyj\u00e4ll\u00e4 k\u00e4ymist\u00e4 kaikille, jotka eiv\u00e4t ole varmoja siit\u00e4, miten py\u00f6r\u00e4 sovitetaan t\u00e4ydellisesti.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a role=\"button\" class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/www.diamantrad.com\/fi-FI\/bikes\/\">N\u00e4yt\u00e4 kaikki py\u00f6r\u00e4t<\/a><\/div>\n<\/div>\n\n<\/div>\r\n      <\/div>\r\n    <\/div>\r\n  <\/div>\r\n<\/div><\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":3,"featured_media":66784,"parent":65913,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_crdt_document":"","slim_seo":{"title":"Py\u00f6r\u00e4t naisille ja kaikki Diamantilta \u2013 tyylik\u00e4s ja dynaaminen","description":"Tutustu Diamantin naisten py\u00f6riin: tyylikk\u00e4\u00e4t, mukavat ja dynaamiset. Katso vastaavuusvalinta nyt."},"footnotes":""},"class_list":["post-66776","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/66776","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/comments?post=66776"}],"version-history":[{"count":4,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/66776\/revisions"}],"predecessor-version":[{"id":74887,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/66776\/revisions\/74887"}],"up":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/pages\/65913"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/media\/66784"}],"wp:attachment":[{"href":"https:\/\/www.diamantrad.com\/en-GB\/wp-json\/wp\/v2\/media?parent=66776"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}