//Tijana Mijatović / Portfolio
I build things for curious people.
Frontend developer with full-stack experience and a background in design. I turn ideas into useful, engaging digital experiences.
// move your cursor — see what this page is made of
import Link from "next/link"
import { ArrowDownRight, ArrowUpRight } from "lucide-react"
import Container from "@/components/container"
import CodeLens from "@/components/code-lens"
export default function HomePage() {
return (
<main>
<section className="hero">
<Container>
<p className="eyebrow">
Tijana Mijatović / Portfolio
</p>
<h1 className="headline">
I build things for{" "}
<span className="accent">curious people.</span>
</h1>
<p className="lede">
Frontend developer with full-stack experience
and a background in design. I turn ideas into
useful, engaging digital experiences.
</p>
<div className="ctas">
<Link href="#selected-work" className="btn-solid">
Explore my work <ArrowDownRight size={20} />
</Link>
<Link href="/about" className="btn-ghost">
More about me <ArrowUpRight size={20} />
</Link>
</div>
</Container>
<CodeLens />
</section>
</main>
)
}export default function CodeLens() {
const lens = useRef<HTMLDivElement>(null)
useEffect(() => {
const hero = lens.current!.parentElement!
const pos = { x: 0, y: 0, r: 0 }
const target = { x: 0, y: 0, r: 0 }
const onMove = (e: PointerEvent) => {
const box = hero.getBoundingClientRect()
target.x = e.clientX - box.left
target.y = e.clientY - box.top
const clickable = (e.target as Element)
.closest("a, button")
target.r = clickable ? 0 : RADIUS
}
const tick = () => {
pos.x += (target.x - pos.x) * 0.2
pos.y += (target.y - pos.y) * 0.2
pos.r += (target.r - pos.r) * 0.15
lens.current!.style.setProperty("--x", `${pos.x}px`)
lens.current!.style.setProperty("--y", `${pos.y}px`)
lens.current!.style.setProperty("--r", `${pos.r}px`)
requestAnimationFrame(tick)
}
hero.addEventListener("pointermove", onMove)
requestAnimationFrame(tick)
}, [])
return <div ref={lens} className="code-lens" aria-hidden />
}import Link from "next/link"
import { ArrowDownRight, ArrowUpRight } from "lucide-react"
import Container from "@/components/container"
import CodeLens from "@/components/code-lens"
export default function HomePage() {
return (
<main>
<section className="hero">
<Container>
<p className="eyebrow">
Tijana Mijatović / Portfolio
</p>
<h1 className="headline">
I build things for{" "}
<span className="accent">curious people.</span>
</h1>
<p className="lede">
Frontend developer with full-stack experience
and a background in design. I turn ideas into
useful, engaging digital experiences.
</p>
<div className="ctas">
<Link href="#selected-work" className="btn-solid">
Explore my work <ArrowDownRight size={20} />
</Link>
<Link href="/about" className="btn-ghost">
More about me <ArrowUpRight size={20} />
</Link>
</div>
</Container>
<CodeLens />
</section>
</main>
)
}export default function CodeLens() {
const lens = useRef<HTMLDivElement>(null)
useEffect(() => {
const hero = lens.current!.parentElement!
const pos = { x: 0, y: 0, r: 0 }
const target = { x: 0, y: 0, r: 0 }
const onMove = (e: PointerEvent) => {
const box = hero.getBoundingClientRect()
target.x = e.clientX - box.left
target.y = e.clientY - box.top
const clickable = (e.target as Element)
.closest("a, button")
target.r = clickable ? 0 : RADIUS
}
const tick = () => {
pos.x += (target.x - pos.x) * 0.2
pos.y += (target.y - pos.y) * 0.2
pos.r += (target.r - pos.r) * 0.15
lens.current!.style.setProperty("--x", `${pos.x}px`)
lens.current!.style.setProperty("--y", `${pos.y}px`)
lens.current!.style.setProperty("--r", `${pos.r}px`)
requestAnimationFrame(tick)
}
hero.addEventListener("pointermove", onMove)
requestAnimationFrame(tick)
}, [])
return <div ref={lens} className="code-lens" aria-hidden />
}//01 / Selected work
Projects with a purpose.
//02 / A little about me
..:-=+*###%%%%%%%%@%%%@%%%%%%#####*#***= ..:-+#%@@@%@@%%%%%%%%%%%%%%#****++*+*******#%* ..-=#%@#: :*%%%%#%%#%#**++++*++++=------==+*#####%+ .:-+#@= %@%###%##+=::.:-===--:.:.........:::--+*#%- ..-+%% :%@%#%#*+--:...:---::.... ....::-=*#*: .:+#% =@@%%%*=::::...::-:.. ...:=*#*: :-*@ *@@@%#+--::....::-. .-*#%#. :=#* @@@@@#++=-:.....::. :#%%% .=## @@@@@%%#*+-:.. .::. :%@#. =*#%+ -++-=++#@@@%%*+-:....-. -### -*::**++++==+--==+%@%#*=:.. .:: =## **++=++*===-+---==*@%%=.:. :-. :*#+ ###++==*---:+:=-==+@@+.. =. .:--==+**++-:. .+#. #**#+-::=:::.+-=-=++%#:. :-. . .:+%%*+:. .+# +****-...-.. =-=-==+%=. =: .....::-+*#*+. .+% **++*. : +-=--==#. .-. ...:::::------=++. .+# =++++* : =-:---++ .:. ..........:::====-::. .++ =+++== : ::=:---+: : .=*#***#+++====+=-::. .. .*- =+++==:.... =:=::--+ : :=*##%#@@@%#++++=-:. ..:-=*###*-%. -=+++=++--: ==::::=: .: .::-+#%%+-##++=-:. .-=+***++*%@%. ===+=++=-:.. :=+::--= :. .:--==*=++*=.::. =##*+-:. .#@. =====**+==:...+=+:--+. .:. .:-====--:... =*=::.. -% ====*#*+*=-:::**====+ . .- ...... :-::... +* ===+##***+==-++*==+*= ......-. -#=#%*=::.-#= -==%%%#%**+++#++++*#. ......-. :*%#@*@#*+%*= -@@@%@%#***#**+**** ......-. =**==%@#%#*+ =@@@%#*###***##%: ....-. ::--=**%%##= =%%###%@%%###%* ..:. .... ..:::#@%** *#*#%@%@%%%%@: :. .... .. :@@+#+. *%@@@@%%%%%%. : .-:-***+-.. ... -@#%#+=. -#@@@@%#%*. .. .--:::::--==-. +###*++= .#%--:. .. .=#@#+:.....:*#%#*++: ..... . ..*+-:.....-*%%%#++= . .. . ... -:.....:-*@@@%#*+. ... . ..:+++==+===-.. :.....:-#@@@@@%*: .::. ... :-=--+**===+=-...::=%@@@@@@% .::.. . ........ .-***##*-:::=@@@@@@@# ..:-:. . ...::----:::.:-*#+-:=@@@@@@% .:---:.. . .:-==+*+=----=--:=%@@@%- ..:-===:.. . .:-=+***+=--:=#%@=. .::-=+*=:... .::----:=##**+++=-: ..::-=+**=::. .:::-*#**++=-::...:::--: ...::-=*##=-.. .:+%##*=-:............:...... -. ...::-=+*%#==-:...... ..=%@%#+-::..... .... .. +. ......:-=*##*##*+=--:::::*@@@*+=-:... . =-.. ......:-=+++*%%%##*+**#@@@@#++-::. .. :++#:.. .......:-===**#*++*@@@@@@@+*+-:. .: -++++=..... ........:--==++=-=+@@@@@%#++-:. .: -=+++=+...... ....::..--=---:::+@@@@@%+=-:. ..- =+==+=+=+....... ......:::::.. .=@%@@%%-=::. .: .+=++=+=+=: ....... ...... .+@*@%#*:::.. .: . +++===+==+........ .#%*%#*=.:.... .:
.+=-::. ==-:. .... .... +=-. . ..::......:--::::... +=:. .:-=++=-:::-====++*+++==----:. :=:. .:-=++++==-====++#%%%%##***+++===-.. =-. :-===+++++=+++***%%@@@@@@%%%#####*++==: =: .---==+++++=+*###%@@@@@@@@@@@%%%%%%%##*+= -. .:.:=+***++=*#%#%@@@@@@@@@@@@@@@%%%%%%%##*= =. .-+*+*++=**#%%@@@@@@@@@@@@@@@@%%%%%%%%%#*= . ..-... .-=+++++=+*##%%@@@@@@@@@@@@@@@%%%%%%%%%%%#*- .==.......::-::.. .-+=+**=+**#%%@@@@@@@@@@@@@@@@%%%%%%%%%%%%#*: .........::=::... :=+**#+=+*#%%@%%%%%%@@@@@@@@@@@%%%%%%%%%%%#*= .....:::-.+::... :=+*###-=*##*+--:::.. .:-=*%@@@%%%%%%%%%%%%#*+. . .---:===+:-::... =*#%##=-+#*+*#%@@@%%#+-:....+*%%%%%%%%%%%%##*+. -+++-*+**--:::.. :*%###*-=*#%%%%##**++====-.. .:+*#%%%%%%%%%##*+. .....+***+###%:-::::..+#%#***-+###**+===-----:::::..:=*#%%#########*+: ......#*##+%%%#:--:::..*%%#*#+++**++++**++==--:..::--=*##%##########*+. .....-***#+%%%==:--::.=%##*##=***+-.......::::....:-=+#%%%#********##+. .....-=++++#%%-=:---:.######%=*%#*-:... . .....::=+%@@%*+=--: .= ......::-=+*##*:-----.=%##*##*+#@@@#=--::. :: ....:==*%@@%+:.. .. .......:--=+**=::=--::%%#**#*=+%@@@@%+=::::.:...:=--+*#%@%*: .:-=**+ ..... :::-=+=::.-::.*##****+=*%@@@@@%#+-::...::===+***#@%#: :-===*#%%: ..... ...:---..::...****+**+-*%%@@@@@@##*++++=+*******#@%*=-=+******#:. :... . ..::.:.:.. :***+++++-+#%%@@@@@%%####%%##******#%@#- :. .-===- . ... ....:... +***++++=-+*##%%@@%@@@@@@@%%#*****##%%#= . .. .: . ... .***+++++=-+*##%%%@@@@@@@@@%%#****##%%%%*:..:: .. .:. =#****++++:+*###%%%@@@@@%%###****#%%@@@%%=--:: . . . .####****++-+*##%%%%%%%%##**+++***#%@@@@@%#++=-- .. =*###******-+*##%%%%%%##***+=++**++**##%%##****= :.. +##%#####**=**##%%%%%%%###%#=--:....-++*+=+****- ..... .+*#%######*=+*#%%%%%%%%@@@@@#=:--=----::.-+****.... ... ::-=*##%######++##%%%%%%@@@@@@@@%%%%#=: .=++++=-... ... =++=+*###%####*+###%##%%%@@@@@@@@@@@*+= .:==+++=-... ... =**+=*#########+*#####*+++*%%%%%%@@%*%#:-=====-:.. .. +##*==+*#######+******++=........:-=+##==+===-:. +##*+-=+**###***++********=::-::.......:=+==-: +%%#*+--=+******+*******++==+=+*+-... :=--:. *%%##+=-:-+*********#**++==-::::---++-. .--: *%%##*+-:::-++**#+######*+=::.. ..:-::.:--: *%%##*+=-:..:-=+***%%@@@@@%#+=:.. ..:--: : *%###**+=-:.. .-=++#%@@@@@@@@##*+=-:::--: ...... *#####*++=-::. .-=+#%@@@@@@%###**+=---. ..:--=====--::. *#####**+==--:. .:=+*##*##*####**=-. .:-=+++++++++++=++++=- .+#####***+==--:.. .::-====++***++: .:--=+++******++++*******+: :+**####**++====-:. ..:----=-. ..--=++**********##*%%%%###*+. .-=+**####**+++===--:... ... ..:-=+***********#%%%%@@%%%%#*+- ...==+****###**+++++==-::.. .. . .:-+***********#%%@@%@@@@@%%#*+= ....:==+++***##**++======--:.....::. ..:-=**####*****##%@@@@@@@@@@%##*+= .......+==+++***##***+++=====-::::--=-. :.:-=**#####*****#%%@@@@@@@@@@@%#*+=- :........*+==+++**####**+++++=----==+**=. ::-=+*#####******#%%@@@@@@@@@@@%##*+- :*.........=*++=+++**###*******++=+++*###=. .--==+**###*******##%@@@@@@@@@@@%##*+= +*#%..........*+++==++********##*******#%%#=. :+===++***********##%%@@@@@@@@@@%%#*+=
I like making complex ideas feel clear, useful, and enjoyable.
I study Creative Computing in Austria after a background in IT and New Media Design. This shapes how I work: I care about the code, the interface, and the person using it.
Read my story<section className="contact">
<Container>
<Eyebrow>03 / Get in touch</Eyebrow>
<h2>Have a project or opportunity in mind?</h2>
<div className="links">
<a href="mailto:timijatovic7@gmail.com">
<Mail size={21} /> Email me
</a>
<a href="https://github.com/Tijana0"
aria-label="GitHub">
<Github size={23} />
</a>
<a href="https://www.linkedin.com/in/tijana-m/"
aria-label="LinkedIn">
<Linkedin size={23} />
</a>
</div>
</Container>
</section>export default function Eyebrow({ children, className }) {
const content = typeof children === "string"
? children.replace(/^\s*\/\/\s*/, "")
: children
return (
<p className={cn("font-mono uppercase text-brand", className)}>
<span aria-hidden="true">{"//"}</span>
{content}
</p>
)
}

