PRAKTICKÉ MESTSKÉ SUV

PLNÁ VÝBAVA. JEDNA CENA.

UŽ OD

16.890 EUR

115 EUR

VRÁTANE DPH
MESAČNĚ

PRAKTICKÉ MESTSKÉ SUV

PLNÁ VÝBAVA. JEDNA CENA.

UŽ OD

16.890 EUR

115 EUR

VRÁTANE DPH
MESAČNĚ

PLNÁ VÝBAVA. JEDNA CENA.

UŽ OD

16.890 EUR

115 EUR

VRÁTANE DPH
MESAČNĚ
MOTOR

1,5 T

VÝKON

100 kW

KRÚTIACI MOMENT

210 N·m

0-100 km/h

9,9 s

MESTSKÝ ŠTÝL A PRAKTICKOSŤ

X35 je obratný crossover, ktorý v sebe spája moderný dizajn a funkčnosť pre každý deň. Vďaka svojim kompaktným rozmerom a prehľadnému interiéru sa skvele hodí do mestskej premávky bez toho, aby robil kompromisy v pohodlí posádky alebo objeme batožinového priestoru.


ZÁRUKA

5 ROKOV

NEBO

100 000 KM

MESTSKÝ ŠTÝL A PRAKTICKOSŤ

X35 je obratný crossover, ktorý v sebe spája moderný dizajn a funkčnosť pre každý deň. Vďaka svojim kompaktným rozmerom a prehľadnému interiéru sa skvele hodí do mestskej premávky bez toho, aby robil kompromisy v pohodlí posádky alebo objeme batožinového priestoru.


ZÁRUKA

5 ROKOV

NEBO

100 000 KM

MESTSKÝ ŠTÝL A PRAKTICKOSŤ

X35 je obratný crossover, ktorý v sebe spája moderný dizajn a funkčnosť pre každý deň. Vďaka svojim kompaktným rozmerom a prehľadnému interiéru sa skvele hodí do mestskej premávky bez toho, aby robil kompromisy v pohodlí posádky alebo objeme batožinového priestoru.


ZÁRUKA

5 ROKOV

NEBO

100 000 KM

VÝHODNÉ FINANCOVANIE ALEBO POISTENIE BAIC PREMIUM

X35 OD 115 EUR MESAČNĚ

Zaobstarajte si BAIC X35 so zvýhodneným financovaním s úrokovou sadzbou 3,99 % alebo Poistenie BAIC Premium na 12 mesiacov za 99 Eur vrátane povinného zmluvného poistenia a havarijného poistenia.

3,99 %

VÝHODNÝ ÚROK

Už od 115 EUR

MESAČNĚ
ROČNÉ POISTNÉ LEN ZA

99 EUR

VÝHODNÉ FINANCOVANIE ALEBO POISTENIE BAIC PREMIUM

X35 OD 115 EUR MESAČNĚ

Zaobstarajte si BAIC X35 so zvýhodneným financovaním s úrokovou sadzbou 3,99 % alebo Poistenie BAIC Premium na 12 mesiacov za 99 Eur vrátane povinného zmluvného poistenia a havarijného poistenia.

3,99 %

VÝHODNÝ ÚROK

Už od 115 EUR

MESAČNĚ
ROČNÉ POISTNÉ LEN ZA

99 EUR

VÝHODNÉ FINANCOVANIE ALEBO POISTENIE BAIC PREMIUM

X35 OD 115 EUR MESAČNĚ

Zaobstarajte si BAIC X35 so zvýhodneným financovaním s úrokovou sadzbou 3,99 % alebo Poistenie BAIC Premium na 12 mesiacov za 99 Eur vrátane povinného zmluvného poistenia a havarijného poistenia.

3,99 %

VÝHODNÝ ÚROK

Už od 115 EUR

MESAČNĚ
ROČNÉ POISTNÉ LEN ZA

99 EUR

FARBY

360° MODEL

ČERVENÁ

BIELA

MODRÁ

FARBY

360° MODEL

ČERVENÁ

BIELA

MODRÁ

FARBY

360° MODEL

ČERVENÁ

BIELA

MODRÁ

FOTOGALÉRIA

Media
Media
Media
Media
Media
Media
Media
Media
Media
Media
Media
Media

VÝBAVA A TECHNICKÁ ŠPECIFIKÁCIA

Preskúmajte každý detail

TECHNICKÁ ŠPECIFIKÁCIA

OBSLUHA A BEZPEČNOSŤ

EXTERIÉR

VNÚTORNÁ VÝBAVA

SEDADLÁ

ZÁBAVA A KONEKTIVITA

ASISTENČNÉ SYSTÉMY

OSVETLENIE

MODEL

BAIC X35

KAROSÉRIA

päťmiestna, päťdverové SUV

MOTORIZÁCIA

radový zážihový preplňovaný štvorvalec vpredu naprieč

ZDVIHOVÝ OBJEM / MAX. VÝKON

1499 ccm, 100 kW/5500 min-1

KRÚTIACI MOMENT

210 N.m/1500–4500 1/min-1

PREVODOVKA / POHON

manuální šestistupňová/předních kol

ROZMERY (D X Š X V)

4325 x 1830 x 1640 mm

RÁZVOR NÁPRAV

2570 mm

SVETLÁ VÝŠKA PRI PLNOM NALOŽENÍ

180 mm

OBJEM BATOŽINOVÉHO PRIESTORU

390/1268 l

OBJEM PALIVOVEJ NÁDRŽE

46 l

HMOTNOSTI (PREVÁDZKOVÁ/CELKOVÁ)

1550/1970 kg

KOLESÁ A PNEUMATIKY

7 J 17/215/50 R17

MAX. RÝCHLOSŤ

180 km/h

ZRÝCHLENIE 0–100 KM/H

9,9 s

SPOTREBA (kombinovaná WLTP)

8,6 l

*

Informácie (cenníky, výbavy, špecifikácie) sú platné od 1. 9. 2025. Výrobca si vyhradzuje právo na ich zmenu či aktualizáciu. Všetky dáta, údaje a vyobrazenia sú určené iba na informačné účely a táto prezentácia nepredstavuje ponuku ani návrh na uzavretie zmluvy. Ponúkaná výbava a jej dostupnosť sa môžu v skutočnosti líšiť od obsahu uvedeného. Konkrétnu ponuku, prosím, konzultujte s autorizovaným partnerom BAIC. Spoločnosť GB Distribution CZ s.r.o. si vyhradzuje právo kedykoľvek zmeniť akýkoľvek detail výbavy či cenu. Spoločnosť je evidovaná v obchodnom registri vedenom Mestským súdom v Prahe, oddiel C, vložka C 418194, IČ: 22541951 DIČ: CZ22541951

TECHNICKÁ ŠPECIFIKÁCIA

OBSLUHA A BEZPEČNOSŤ

EXTERIÉR

VNÚTORNÁ VÝBAVA

SEDADLÁ

ZÁBAVA A KONEKTIVITA

ASISTENČNÉ SYSTÉMY

OSVETLENIE

MODEL

BAIC X35

KAROSÉRIA

päťmiestna, päťdverové SUV

MOTORIZÁCIA

radový zážihový preplňovaný štvorvalec vpredu naprieč

ZDVIHOVÝ OBJEM / MAX. VÝKON

1499 ccm, 100 kW/5500 min-1

KRÚTIACI MOMENT

210 N.m/1500–4500 1/min-1

PREVODOVKA / POHON

manuální šestistupňová/předních kol

ROZMERY (D X Š X V)

4325 x 1830 x 1640 mm

RÁZVOR NÁPRAV

2570 mm

SVETLÁ VÝŠKA PRI PLNOM NALOŽENÍ

180 mm

OBJEM BATOŽINOVÉHO PRIESTORU

390/1268 l

OBJEM PALIVOVEJ NÁDRŽE

46 l

HMOTNOSTI (PREVÁDZKOVÁ/CELKOVÁ)

1550/1970 kg

KOLESÁ A PNEUMATIKY

7 J 17/215/50 R17

MAX. RÝCHLOSŤ

180 km/h

ZRÝCHLENIE 0–100 KM/H

9,9 s

SPOTREBA (kombinovaná WLTP)

8,6 l

*

Informácie (cenníky, výbavy, špecifikácie) sú platné od 1. 9. 2025. Výrobca si vyhradzuje právo na ich zmenu či aktualizáciu. Všetky dáta, údaje a vyobrazenia sú určené iba na informačné účely a táto prezentácia nepredstavuje ponuku ani návrh na uzavretie zmluvy. Ponúkaná výbava a jej dostupnosť sa môžu v skutočnosti líšiť od obsahu uvedeného. Konkrétnu ponuku, prosím, konzultujte s autorizovaným partnerom BAIC. Spoločnosť GB Distribution CZ s.r.o. si vyhradzuje právo kedykoľvek zmeniť akýkoľvek detail výbavy či cenu. Spoločnosť je evidovaná v obchodnom registri vedenom Mestským súdom v Prahe, oddiel C, vložka C 418194, IČ: 22541951 DIČ: CZ22541951

TECHNICKÁ ŠPECIFIKÁCIA

OBSLUHA A BEZPEČNOSŤ

EXTERIÉR

VNÚTORNÁ VÝBAVA

SEDADLÁ

ZÁBAVA A KONEKTIVITA

ASISTENČNÉ SYSTÉMY

OSVETLENIE

MODEL

BAIC X35

KAROSÉRIA

päťmiestna, päťdverové SUV

MOTORIZÁCIA

radový zážihový preplňovaný štvorvalec vpredu naprieč

ZDVIHOVÝ OBJEM / MAX. VÝKON

1499 ccm, 100 kW/5500 min-1

KRÚTIACI MOMENT

210 N.m/1500–4500 1/min-1

PREVODOVKA / POHON

manuální šestistupňová/předních kol

ROZMERY (D X Š X V)

4325 x 1830 x 1640 mm

RÁZVOR NÁPRAV

2570 mm

SVETLÁ VÝŠKA PRI PLNOM NALOŽENÍ

180 mm

OBJEM BATOŽINOVÉHO PRIESTORU

390/1268 l

OBJEM PALIVOVEJ NÁDRŽE

46 l

HMOTNOSTI (PREVÁDZKOVÁ/CELKOVÁ)

1550/1970 kg

KOLESÁ A PNEUMATIKY

7 J 17/215/50 R17

MAX. RÝCHLOSŤ

180 km/h

ZRÝCHLENIE 0–100 KM/H

9,9 s

SPOTREBA (kombinovaná WLTP)

8,6 l

*

Informácie (cenníky, výbavy, špecifikácie) sú platné od 1. 9. 2025. Výrobca si vyhradzuje právo na ich zmenu či aktualizáciu. Všetky dáta, údaje a vyobrazenia sú určené iba na informačné účely a táto prezentácia nepredstavuje ponuku ani návrh na uzavretie zmluvy. Ponúkaná výbava a jej dostupnosť sa môžu v skutočnosti líšiť od obsahu uvedeného. Konkrétnu ponuku, prosím, konzultujte s autorizovaným partnerom BAIC. Spoločnosť GB Distribution CZ s.r.o. si vyhradzuje právo kedykoľvek zmeniť akýkoľvek detail výbavy či cenu. Spoločnosť je evidovaná v obchodnom registri vedenom Mestským súdom v Prahe, oddiel C, vložka C 418194, IČ: 22541951 DIČ: CZ22541951

TESTOVACIA JAZDA

Máte záujem si vozidlo vyskúšať
a otestovať, čo dokáže?

import {

startTransition,

useCallback,

useEffect,

useMemo,

useRef,

useState,

} from "react"

import { addPropertyControls, ControlType } from "framer"


// User request: make the InvestmentCalculator fully fluid and responsive down to

// ~300px container width, prevent horizontal overflow/clipping, allow row

// wrapping/stacking, scale/wrap large values and labels, and keep existing

// property controls/behavior intact.

// ────────────────────────────────────────────────────────────────

// The Julius Fund — Investment Calculator (v2 layout)

//

// Compounding: amount × (1 + rate)^years (annual)

// Currency toggle swaps the whole share class (own amount + own thresholds).

//

// THREE states by amount:

// directMin — normal direct entry (CZK 1,000,000 / EUR 125,000)

// floorMin — Codya Mix route floor (CZK 100,000). Between floor and

// direct: still calculated, Codya note shown.

// Below floor: Academy state (no results).

//

// LAYOUT (grid):

// TOP zone — 3 cols: "Your investment" | amount input | horizon slider

// Warnings (Codya / Academy) overflow across the full width

// of this top zone, under the input and horizon.

// BOTTOM zone — "After X years" on the left, scenario blocks on the right

// (13% + 16% top row, savings on its own row).

//

// FONTS: The Seasons (headings + big numbers), Avantt (body + toggle),

// Inter (micro labels). Custom fonts re-declared via @font-face.

//

// NUMBERS animate with ease-out-cubic count-up, firing on mount (both CZK

// and EUR) and on every value change (slider / currency).

// ────────────────────────────────────────────────────────────────


interface Props {

lowRate: number

highRate: number

savingsRate: number

directMinCZK: number

floorMinCZK: number

directMinEUR: number

floorMinEUR: number

defaultYears: number

countUpDuration: number

academyUrl: string

avanttUrl: string

seasonsUrl: string

headingFont: string

bodyFont: string

labelFont: string

sectionLabelFont: string

sectionLabelColor: string

sectionLabelSize: number

sectionLabelSpacing: number

scenarioLabelFont: string

scenarioLabelColor: string

scenarioLabelSize: number

scenarioLabelSpacing: number

ink: string

accent: string

gainColor: string

paper: string

line: string

sliderTrack: string

pillTrack: string

pillActiveBg: string

pillActiveText: string

pillInactiveText: string

style?: React.CSSProperties

}


function compound(amount: number, rate: number, years: number) {

return amount * Math.pow(1 + rate / 100, years)

}


function formatNumber(n: number, currency: "CZK" | "EUR") {

const locale = currency === "CZK" ? "cs-CZ" : "de-DE"

return new Intl.NumberFormat(locale, {

maximumFractionDigits: 0,

}).format(Math.round(n))

}


// Inject @font-face for a custom font from a woff2 URL.

function useFontFace(family: string, url?: string, id?: string) {

useEffect(() => {

if (!url) return

const styleId = id || `julius-face-${family.replace(/\s+/g, "-")}`

const existing = document.getElementById(styleId)

if (existing) existing.remove()

const style = document.createElement("style")

style.id = styleId

style.textContent = `@font-face{font-family:'${family}';src:url('${url}') format('woff2');font-weight:1 1000;font-style:normal;font-display:swap;}`

document.head.appendChild(style)

}, [family, url, id])

}


// Count-up hook. Animates to `target` over `duration`s with ease-out cubic,

// firing on mount and on target change. When `instant` is true for a given

// change (e.g. currency switch), it jumps straight to the value with no

// animation. Respects prefers-reduced-motion.

function useCountUp(target: number, duration: number, instant: boolean) {

const [display, setDisplay] = useState(0)

const fromRef = useRef(0)

const rafRef = useRef<number | null>(null)


useEffect(() => {

const reduce =

typeof window !== "undefined" &&

typeof window.matchMedia === "function" &&

window.matchMedia("(prefers-reduced-motion: reduce)").matches


const from = fromRef.current

const to = target


if (instant || reduce || duration <= 0 || from === to) {

startTransition(() => setDisplay(to))

fromRef.current = to

return

}


const start =

typeof performance !== "undefined" ? performance.now() : Date.now()

const durMs = duration * 1000


const tick = (now: number) => {

const p = Math.min(1, (now - start) / durMs)

const eased = 1 - Math.pow(1 - p, 3)

startTransition(() => setDisplay(from + (to - from) * eased))

if (p < 1) {

rafRef.current = requestAnimationFrame(tick)

} else {

fromRef.current = to

rafRef.current = null

}

}


rafRef.current = requestAnimationFrame(tick)

return () => {

if (rafRef.current !== null) cancelAnimationFrame(rafRef.current)

fromRef.current = display

}

// eslint-disable-next-line react-hooks/exhaustive-deps

}, [target, duration])


return display

}


function AnimatedNumber({

value,

currency,

duration,

instant,

prefix = "",

}: {

value: number

currency: "CZK" | "EUR"

duration: number

instant: boolean

prefix?: string

}) {

const animated = useCountUp(value, duration, instant)

return (

<>

{prefix}

{formatNumber(animated, currency)} {currency}

</>

)

}


// Animated whole-number (for the years in "After X years"). Counts up on

// slider change, jumps instantly on currency switch.

function AnimatedYears({

value,

duration,

instant,

}: {

value: number

duration: number

instant: boolean

}) {

const animated = useCountUp(value, duration, instant)

return <>{Math.round(animated)}</>

}


/**

* @framerSupportedLayoutWidth any-prefer-fixed

* @framerSupportedLayoutHeight auto

*/

export default function InvestmentCalculator(props: Props) {

const {

lowRate,

highRate,

savingsRate,

directMinCZK,

floorMinCZK,

directMinEUR,

floorMinEUR,

defaultYears,

countUpDuration,

academyUrl,

avanttUrl,

seasonsUrl,

headingFont,

bodyFont,

labelFont,

sectionLabelFont,

sectionLabelColor,

sectionLabelSize,

sectionLabelSpacing,

scenarioLabelFont,

scenarioLabelColor,

scenarioLabelSize,

scenarioLabelSpacing,

ink,

accent,

gainColor,

paper,

line,

sliderTrack,

pillTrack,

pillActiveBg,

pillActiveText,

pillInactiveText,

style,

} = props


useFontFace("Avantt", avanttUrl, "julius-avantt-face")

useFontFace("The Seasons Regular", seasonsUrl, "julius-seasons-face")


const [currency, setCurrency] = useState<"CZK" | "EUR">("CZK")

const [years, setYears] = useState(Math.max(3, defaultYears))

const [amountCZK, setAmountCZK] = useState(directMinCZK)

const [amountEUR, setAmountEUR] = useState(directMinEUR)

const rootRef = useRef<HTMLDivElement | null>(null)

const [containerWidth, setContainerWidth] = useState(1200)


// When the currency is switched, suppress the count-up for that render so

// numbers jump instead of animating. Slider/amount changes still animate.

const prevCurrency = useRef(currency)

const currencyChanged = prevCurrency.current !== currency

useEffect(() => {

prevCurrency.current = currency

}, [currency])


useEffect(() => {

if (typeof window === "undefined") return

const node = rootRef.current

if (!node || typeof ResizeObserver === "undefined") return


const observer = new ResizeObserver((entries) => {

const entry = entries[0]

const nextWidth = entry?.contentRect?.width

if (!nextWidth) return

startTransition(() => setContainerWidth(nextWidth))

})

observer.observe(node)


return () => observer.disconnect()

}, [])


const switchCurrency = useCallback((c: "CZK" | "EUR") => {

startTransition(() => setCurrency(c))

}, [])


const amount = currency === "CZK" ? amountCZK : amountEUR

const setAmount = currency === "CZK" ? setAmountCZK : setAmountEUR

const directMin = currency === "CZK" ? directMinCZK : directMinEUR

const floorMin = currency === "CZK" ? floorMinCZK : floorMinEUR


const belowFloor = amount < floorMin

const codyaRoute = amount >= floorMin && amount < directMin


const low = compound(amount, lowRate, years)

const high = compound(amount, highRate, years)

const savings = compound(amount, savingsRate, years)


const scenarios = useMemo(

() => [

{

label: `At ${lowRate}% p.a. gross`,

value: low,

gain: low - amount,

accented: true,

},

{

label: `At ${highRate}% p.a. gross`,

value: high,

gain: high - amount,

accented: true,

},

{

label: `Savings account at ${savingsRate}% p.a.`,

value: savings,

gain: savings - amount,

accented: false,

},

],

[amount, high, highRate, low, lowRate, savings, savingsRate]

)


const isPhone = containerWidth <= 380

const isTablet = containerWidth <= 860

const pagePadding = isPhone ? 14 : containerWidth <= 560 ? 20 : 30

const topGridColumns = isPhone

? "1fr"

: isTablet

? "1fr 1fr"

: "1fr 1fr 1fr"

const topWarningColumn = isPhone ? "1 / -1" : isTablet ? "1 / -1" : "2 / 4"

const bottomGridColumns = isPhone

? "1fr"

: isTablet

? "1fr 1fr"

: "1fr 1fr 1fr"

const numberFontSize = isPhone

? "clamp(22px, 10vw, 30px)"

: "clamp(28px, 5vw, 37px)"

const titleSize = isPhone ? "clamp(28px, 10vw, 37px)" : 37


// ── text style presets ──

const bodyStyle: React.CSSProperties = {

fontFamily: bodyFont,

fontWeight: 300,

letterSpacing: "-0.02em",

lineHeight: 1.5,

}

const headingStyle: React.CSSProperties = {

fontFamily: headingFont,

fontWeight: 400,

letterSpacing: "-0.03em",

lineHeight: 1.1,

}

const sectionLabelStyle: React.CSSProperties = {

fontFamily: sectionLabelFont,

color: sectionLabelColor,

fontSize: sectionLabelSize,

letterSpacing: sectionLabelSpacing,

fontWeight: 600,

textTransform: "uppercase",

}

const scenarioLabelStyle: React.CSSProperties = {

fontFamily: scenarioLabelFont,

color: scenarioLabelColor,

fontSize: scenarioLabelSize,

letterSpacing: scenarioLabelSpacing,

fontWeight: 600,

textTransform: "uppercase",

}


// Scenario block (label + big number + gain). Reused across the grid.

const ScenarioBlock = ({ s }: { s: (typeof scenarios)[number] }) => (

<div

style={{

width: "100%",

maxWidth: "100%",

minWidth: 0,

boxSizing: "border-box",

paddingLeft: 20,

paddingTop: 20,

paddingBottom: 20,

borderLeft: `2px solid ${s.accented ? accent : line}`,

}}

>

<div

style={{

...scenarioLabelStyle,

marginBottom: 14,

display: "inline-block",

maxWidth: "100%",

overflowWrap: "anywhere",

}}

>

{s.label}

</div>

<div

style={{

...headingStyle,

fontSize: numberFontSize,

marginBottom: 14,

lineHeight: 1.05,

maxWidth: "100%",

overflowWrap: "anywhere",

wordBreak: "break-word",

}}

>

<AnimatedNumber

value={s.value}

currency={currency}

duration={countUpDuration}

instant={currencyChanged}

/>

</div>

<div

style={{

fontFamily: sectionLabelFont,

fontSize: 11,

fontWeight: 600,

letterSpacing: 0.4,

textTransform: "uppercase",

color: ink,

maxWidth: "100%",

overflowWrap: "anywhere",

}}

>

GAIN{" "}

<span style={{ color: s.accented ? gainColor : ink }}>

<AnimatedNumber

value={s.gain}

currency={currency}

duration={countUpDuration}

instant={currencyChanged}

prefix="+"

/>

</span>

</div>

</div>

)


const targets = scenarios.filter((s) => s.accented)

const rest = scenarios.filter((s) => !s.accented)


return (

<div

ref={rootRef}

style={{

...style,

fontFamily: bodyFont,

color: ink,

background: paper,

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

padding: pagePadding,

position: "relative",

}}

>

{/* ── CZK / EUR toggle, top-left ───────────────── */}

<div

style={{

display: "inline-flex",

maxWidth: "100%",

marginBottom: 50,

background: pillTrack,

borderRadius: 999,

padding: 0,

overflow: "hidden",

boxSizing: "border-box",

}}

>

{(["CZK", "EUR"] as const).map((c) => {

const active = currency === c

return (

<button

key={c}

onClick={() => switchCurrency(c)}

style={{

flex: 1,

minWidth: 0,

maxWidth: 86,

padding: "10px 30px",

borderRadius: 999,

border: "none",

cursor: "pointer",

background: active

? pillActiveBg

: "transparent",

color: active

? pillActiveText

: pillInactiveText,

fontSize: 11,

fontWeight: 600,

letterSpacing: "1.12px",

textTransform: "uppercase",

fontFamily: labelFont,

transition:

"background 0.18s ease, color 0.18s ease",

}}

>

{c}

</button>

)

})}

</div>


{/* ── TOP ZONE: title | amount | horizon ────────── */}

<div

style={{

display: "grid",

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

gridTemplateColumns: topGridColumns,

columnGap: isPhone ? 18 : 48,

rowGap: 24,

alignItems: "start",

}}

>

{/* col 1 — title */}

<h2

style={{

...headingStyle,

fontSize: titleSize,

margin: 0,

maxWidth: "100%",

overflowWrap: "anywhere",

}}

>

Your investment

</h2>


{/* col 2 — amount input + min text */}

<div

style={{

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

}}

>

<div

style={{

display: "flex",

alignItems: "center",

flexWrap: isPhone ? "wrap" : "nowrap",

gap: 12,

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

}}

>

<input

type="text"

inputMode="numeric"

value={formatNumber(amount, currency)}

onChange={(e) => {

const raw = e.target.value.replace(/\D/g, "")

startTransition(() =>

setAmount(raw ? parseInt(raw, 10) : 0)

)

}}

style={{

flex: 1,

minWidth: 0,

width: "100%",

maxWidth: "100%",

padding: "14px 16px",

border: `1px solid ${belowFloor ? accent : line}`,

borderRadius: 0,

fontSize: 20,

fontFamily: "Avantt, sans-serif",

color: ink,

background: "#fff",

boxSizing: "border-box",

outline: "none",

}}

/>

<span

style={{

...bodyStyle,

fontSize: 15,

opacity: 0.7,

flexShrink: 0,

width: isPhone ? "100%" : "auto",

}}

>

{currency}

</span>

</div>

<p

style={{

...bodyStyle,

fontSize: 13,

opacity: 0.6,

margin: "12px 0 0",

// Reserve height for the longer (two-line) CZK text

// so switching to the shorter EUR copy doesn't

// shrink the layout.

minHeight: 40,

maxWidth: "100%",

overflowWrap: "anywhere",

}}

>

Minimum {formatNumber(directMin, currency)} {currency}

{currency === "CZK"

? ` – from ${formatNumber(floorMin, currency)} CZK via the Codya Mix program.`

: " for the EUR share class."}

</p>

</div>


{/* col 3 — horizon */}

<div

style={{

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

}}

>

<div

style={{

display: "flex",

justifyContent: "space-between",

alignItems: "baseline",

marginBottom: 16,

}}

>

<span style={{ ...headingStyle, fontSize: 20 }}>

Investment horizon

</span>

<span

style={{

...bodyStyle,

fontSize: 15,

opacity: 0.55,

}}

>

{years} {years === 1 ? "year" : "years"}

</span>

</div>

<input

type="range"

min={3}

max={10}

step={1}

value={years}

onChange={(e) =>

startTransition(() =>

setYears(parseInt(e.target.value, 10))

)

}

className="julius-horizon-slider"

style={{

width: "100%",

maxWidth: "100%",

accentColor: ink,

cursor: "pointer",

}}

/>

<div

style={{

display: "flex",

justifyContent: "space-between",

...bodyStyle,

fontSize: 13,

opacity: 0.55,

marginTop: 8,

}}

>

<span>3</span>

<span>10</span>

</div>

</div>


{/* Warning row — spans full width of the top zone, overflows

from under the input across to under the horizon. Only the

Codya note appears here (the Academy state replaces the

whole results area below). */}

{codyaRoute && (

<div

style={{

gridColumn: topWarningColumn,

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

marginTop: 4,

padding: "18px 20px",

border: `1px solid ${line}`,

background: "#fff",

}}

>

<div

style={{

...sectionLabelStyle,

color: accent,

marginBottom: 8,

overflowWrap: "anywhere",

}}

>

The Codya Mix route

</div>

<p

style={{

...bodyStyle,

fontSize: 14,

margin: 0,

opacity: 0.85,

overflowWrap: "anywhere",

}}

>

Below the direct minimum of{" "}

{formatNumber(directMin, currency)} {currency}, the

fund remains within reach: from{" "}

{formatNumber(floorMin, currency)} {currency} you

can invest via the Codya Mix program. Your

projection is calculated for this route.

</p>

</div>

)}

</div>


{/* ── BOTTOM ZONE ──────────────────────────────── */}

{belowFloor ? (

// Academy state — spans under the top zone

<div style={{ marginTop: 64, maxWidth: 560 }}>

<h3

style={{

...headingStyle,

fontSize: titleSize,

margin: "0 0 20px",

overflowWrap: "anywhere",

}}

>

Below the minimum — for now

</h3>

<p

style={{

...bodyStyle,

fontSize: 17,

opacity: 0.8,

margin: "0 0 28px",

overflowWrap: "anywhere",

}}

>

The fund is open to qualified investors from{" "}

{formatNumber(directMin, currency)} {currency}

{currency === "CZK"

? `, or from ${formatNumber(floorMin, currency)} CZK via the Codya Mix program`

: ""}

. Until then, the Academy is the best place to begin.

</p>

<a

href={academyUrl}

style={{

...sectionLabelStyle,

color: ink,

textDecoration: "none",

}}

>

Visit the Academy →

</a>

</div>

) : (

<div

style={{

display: "grid",

width: "100%",

maxWidth: "100%",

boxSizing: "border-box",

gridTemplateColumns: bottomGridColumns,

columnGap: isPhone ? 18 : 48,

rowGap: isPhone ? 28 : 64,

marginTop: 64,

}}

>

{/* row 1: "After X years" | 13% | 16% */}

<h3

style={{

...headingStyle,

fontSize: titleSize,

margin: 0,

maxWidth: "100%",

overflowWrap: "anywhere",

}}

>

After{" "}

<span style={{ color: accent }}>

<AnimatedYears

value={years}

duration={countUpDuration}

instant={currencyChanged}

/>

</span>{" "}

years

</h3>

<ScenarioBlock s={targets[0]} />

<ScenarioBlock s={targets[1]} />

{isTablet ? (

<div style={{ gridColumn: "1 / -1" }}>

<ScenarioBlock s={rest[0]} />

</div>

) : (

<>

{/* row 2: empty | savings | empty */}

<div />

<ScenarioBlock s={rest[0]} />

<div />

</>

)}

</div>

)}


{/* slider track styling — flat track in sliderTrack colour,

no outline; dark thumb */}

<style>{`

.julius-horizon-slider {

-webkit-appearance: none;

appearance: none;

height: 4px;

background: ${sliderTrack};

border: none;

outline: none;

border-radius: 999px;

}

.julius-horizon-slider::-webkit-slider-runnable-track {

height: 4px;

background: ${sliderTrack};

border: none;

border-radius: 999px;

}

.julius-horizon-slider::-moz-range-track {

height: 4px;

background: ${sliderTrack};

border: none;

border-radius: 999px;

}

.julius-horizon-slider::-webkit-slider-thumb {

-webkit-appearance: none;

appearance: none;

width: 16px;

height: 16px;

margin-top: -6px;

border-radius: 999px;

background: ${ink};

border: none;

cursor: pointer;

}

.julius-horizon-slider::-moz-range-thumb {

width: 16px;

height: 16px;

border-radius: 999px;

background: ${ink};

border: none;

cursor: pointer;

}

`}</style>

</div>

)

}


InvestmentCalculator.defaultProps = {

lowRate: 13,

highRate: 16,

savingsRate: 4,

directMinCZK: 1000000,

floorMinCZK: 100000,

directMinEUR: 125000,

floorMinEUR: 125000,

defaultYears: 3,

countUpDuration: 1.2,

academyUrl: "#",

avanttUrl:

"https://framerusercontent.com/assets/3KF8P1O24PUB30TMAunB2we02to.woff2",

seasonsUrl: "",

headingFont: "'The Seasons Regular', 'The Seasons', Georgia, serif",

bodyFont: "'Avantt', sans-serif",

labelFont: "'Inter', sans-serif",

sectionLabelFont: "'Inter', sans-serif",

sectionLabelColor: "#1B3A3A",

sectionLabelSize: 13,

sectionLabelSpacing: 0.4,

scenarioLabelFont: "'Inter', sans-serif",

scenarioLabelColor: "#1B3A3A",

scenarioLabelSize: 13,

scenarioLabelSpacing: 0.4,

ink: "#1B3A3A",

accent: "#C0512E",

gainColor: "#EE7233",

paper: "#F2EEE5",

line: "#D9D2C4",

sliderTrack: "#FFFEF8",

pillTrack: "#FFFEF8",

pillActiveBg: "#0E2A2F",

pillActiveText: "#F4F2ED",

pillInactiveText: "#0E2A2F",

}


addPropertyControls(InvestmentCalculator, {

lowRate: {

type: ControlType.Number,

title: "Low rate %",

min: 0,

max: 50,

step: 0.5,

},

highRate: {

type: ControlType.Number,

title: "High rate %",

min: 0,

max: 50,

step: 0.5,

},

savingsRate: {

type: ControlType.Number,

title: "Savings %",

min: 0,

max: 20,

step: 0.5,

},

directMinCZK: {

type: ControlType.Number,

title: "Direct min CZK",

min: 0,

step: 100000,

},

floorMinCZK: {

type: ControlType.Number,

title: "Floor min CZK",

min: 0,

step: 50000,

},

directMinEUR: {

type: ControlType.Number,

title: "Direct min EUR",

min: 0,

step: 5000,

},

floorMinEUR: {

type: ControlType.Number,

title: "Floor min EUR",

min: 0,

step: 5000,

},

defaultYears: {

type: ControlType.Number,

title: "Default years",

min: 3,

max: 10,

step: 1,

},

countUpDuration: {

type: ControlType.Number,

title: "Count-up duration",

min: 0,

max: 4,

step: 0.1,

displayStepper: true,

},

academyUrl: { type: ControlType.Link, title: "Academy URL" },

avanttUrl: {

type: ControlType.String,

title: "Avantt woff2 URL",

placeholder: "Leave empty if font is in project",

},

seasonsUrl: {

type: ControlType.String,

title: "Seasons woff2 URL",

placeholder: "Leave empty if font is in project",

},

headingFont: {

type: ControlType.String,

title: "Heading font",

placeholder: "'The Seasons', serif",

},

bodyFont: {

type: ControlType.String,

title: "Body font",

placeholder: "'Avantt', sans-serif",

},

labelFont: {

type: ControlType.String,

title: "Label font",

placeholder: "'Inter', sans-serif",

},

sectionLabelFont: {

type: ControlType.String,

title: "Section label font",

placeholder: "'Inter', sans-serif",

},

sectionLabelColor: {

type: ControlType.Color,

title: "Section label color",

},

sectionLabelSize: {

type: ControlType.Number,

title: "Section label size",

min: 8,

max: 24,

step: 1,

},

sectionLabelSpacing: {

type: ControlType.Number,

title: "Section label spacing",

min: -2,

max: 6,

step: 0.1,

displayStepper: true,

},

scenarioLabelFont: {

type: ControlType.String,

title: "Scenario label font",

placeholder: "'Inter', sans-serif",

},

scenarioLabelColor: {

type: ControlType.Color,

title: "Scenario label color",

},

scenarioLabelSize: {

type: ControlType.Number,

title: "Scenario label size",

min: 8,

max: 24,

step: 1,

},

scenarioLabelSpacing: {

type: ControlType.Number,

title: "Scenario label spacing",

min: -2,

max: 6,

step: 0.1,

displayStepper: true,

},

ink: { type: ControlType.Color, title: "Ink" },

accent: { type: ControlType.Color, title: "Accent (border)" },

gainColor: { type: ControlType.Color, title: "Gain color" },

paper: { type: ControlType.Color, title: "Paper" },

line: { type: ControlType.Color, title: "Line" },

sliderTrack: { type: ControlType.Color, title: "Slider track" },

pillTrack: { type: ControlType.Color, title: "Toggle track" },

pillActiveBg: { type: ControlType.Color, title: "Toggle active bg" },

pillActiveText: { type: ControlType.Color, title: "Toggle active text" },

pillInactiveText: {

type: ControlType.Color,

title: "Toggle inactive text",

},

})

GB Distribution SK s.r.o.,
oficiálny a výhradný importér
vozidiel BAIC pre slovenský trh

GB Distribution SK s.r.o.,
oficiálny a výhradný importér
vozidiel BAIC pre slovenský trh

GB Distribution SK s.r.o.,
oficiálny a výhradný importér
vozidiel BAIC pre slovenský trh