
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
Nadčasový štýl pre každý deň
Dizajn modelu X35 spája čisté, moderné línie s praktickou siluetou kompaktného mestského SUV.
FARBY
360° MODEL

ČERVENÁ
BIELA
MODRÁ
FARBY
360° MODEL

ČERVENÁ
BIELA
MODRÁ
FARBY
360° MODEL

ČERVENÁ
BIELA
MODRÁ
FOTOGALÉRIA












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
2026 © Všetky práva vyhradené

GB Distribution SK s.r.o.,
oficiálny a výhradný importér
vozidiel BAIC pre slovenský trh
2026 © Všetky práva vyhradené

GB Distribution SK s.r.o.,
oficiálny a výhradný importér
vozidiel BAIC pre slovenský trh
2026 © Všetky práva vyhradené