<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Gili Levinson — Portfolio</title>
<link rel="stylesheet" href="colors_and_type.css">
<link rel="stylesheet" href="site.css">
<script src="https://unpkg.com/react@18.3.1/umd/react.development.js" integrity="sha384-hD6/rw4ppMLGNu3tX5cjIb+uRZ7UkRJ6BPkLpg4hAu/6onKUg4lLsHAs9EBPT82L" crossorigin="anonymous"></script>
<script src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.development.js" integrity="sha384-u6aeetuaXnQ38mYT8rp6sbXaQe3NL9t+IBXmnYxwkUI2Hw4bsp2Wvmx4yRQF1uAm" crossorigin="anonymous"></script>
<script src="https://unpkg.com/@babel/standalone@7.29.0/babel.min.js" integrity="sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y" crossorigin="anonymous"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel" src="components/Primitives.jsx"></script>
<script type="text/babel" src="components/HeaderHero.jsx"></script>
<script type="text/babel" src="components/AboutWork.jsx"></script>
<script type="text/babel" src="components/ServicesContactFooter.jsx"></script>
<script type="text/babel">
function Site() {
const nav = (id) => {
const el = document.getElementById(id);
if (el) window.scrollTo({ top: el.offsetTop - 80, behavior: 'smooth' });
};
return (
<div className="site" id="top">
<Header onNav={nav}/>
<Hero/>
<Marquee/>
<About/>
<WorkSection/>
<ServicesGrid/>
<ContactSection/>
<Footer/>
</div>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(<Site/>);
</script>
</body>
</html>
/* Website UI Kit — Gili Levinson
Component-specific styles. Base tokens come from ../../colors_and_type.css
*/
/* --- Layout primitives ------------------------------------ */
.site { min-height: 100vh; background: var(--paper); position: relative; }
.gl-italic { font-style: italic; font-variation-settings: 'SOFT' 100, 'opsz' 144; }
.gl-eyebrow {
font-family: var(--font-body);
font-size: 12px; font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.14em;
color: var(--fg-muted);
display: inline-flex; align-items: center; gap: 8px;
}
.gl-tag {
display: inline-flex; padding: 6px 12px;
border: 1px solid var(--ink);
border-radius: var(--r-pill);
font-family: var(--font-body); font-size: 13px;
color: var(--ink); background: transparent;
}
.gl-btn {
display: inline-flex; align-items: center; gap: 8px;
font-family: var(--font-body); font-weight: 500; font-size: 16px;
padding: 14px 24px;
border-radius: var(--r-pill);
border: 2px solid var(--ink);
cursor: pointer;
background-image: none;
transition: transform 180ms var(--ease), background 300ms var(--ease), color 300ms var(--ease);
text-decoration: none;
}
.gl-btn--primary { background: var(--tomato); color: var(--paper); }
.gl-btn--primary:hover { background: var(--ink); color: var(--lime); }
.gl-btn--ghost { background: transparent; color: var(--ink); }
.gl-btn--ghost:hover { background: var(--ink); color: var(--lime); }
.gl-btn--lime { background: var(--lime); color: var(--ink); }
.gl-btn--lime:hover { background: var(--ink); color: var(--lime); }
.gl-btn:active { transform: scale(0.97); }
.gl-sticker {
display: inline-flex; align-items: center; justify-content: center;
border: 2px solid var(--ink); background: var(--lime); color: var(--ink);
font-family: var(--font-body); font-weight: 600;
font-size: 12px; text-transform: uppercase; letter-spacing: 0.12em;
padding: 8px 16px; border-radius: var(--r-pill);
box-shadow: var(--shadow-sticker);
transition: transform var(--dur-base) var(--ease);
}
.gl-sticker:hover { transform: rotate(3deg) scale(1.05) !important; }
.gl-scribble { position: relative; display: inline-block; white-space: nowrap; }
.gl-scribble__svg {
position: absolute; left: 0; right: 0; bottom: -0.08em;
width: 100%; height: 0.22em;
overflow: visible;
}
/* --- Header ----------------------------------------------- */
.gl-header {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
transition: background 300ms var(--ease), backdrop-filter 300ms var(--ease);
}
.gl-header.is-scrolled { background: rgba(245, 239, 228, 0.92); border-bottom: 1px solid var(--border); }
.gl-header__inner {
max-width: var(--page-max); margin: 0 auto;
padding: 20px var(--page-gutter);
display: flex; justify-content: space-between; align-items: center;
}
.gl-wordmark {
font-family: var(--font-display); font-size: 28px; font-weight: 500;
letter-spacing: -0.03em; color: var(--ink); text-decoration: none;
font-variation-settings: 'SOFT' 60, 'opsz' 60;
background-image: none;
}
.gl-nav { display: flex; align-items: center; gap: 36px; }
.gl-nav a {
font-family: var(--font-body); font-size: 16px; font-weight: 500;
color: var(--ink); text-decoration: none;
background-image: linear-gradient(var(--tomato), var(--tomato));
background-size: 0% 2px; background-repeat: no-repeat; background-position: 0 100%;
transition: background-size 300ms var(--ease);
}
.gl-nav a:hover { background-size: 100% 2px; }
/* --- Hero ------------------------------------------------- */
.gl-hero {
position: relative;
padding: 200px var(--page-gutter) 120px;
max-width: var(--page-max); margin: 0 auto;
min-height: 100vh;
display: flex; flex-direction: column; justify-content: center;
}
.gl-hero__tags {
display: flex; gap: 24px; margin-bottom: 40px;
}
.gl-hero__title {
font-family: var(--font-display);
font-size: clamp(64px, 13vw, 200px);
line-height: 0.88;
letter-spacing: -0.045em;
font-weight: 400;
font-variation-settings: 'SOFT' 80, 'opsz' 144;
margin: 0 0 60px; max-width: 90%;
text-wrap: pretty;
}
.gl-hero__foot {
display: flex; justify-content: space-between; align-items: flex-end; gap: 60px;
border-top: 1px solid var(--border); padding-top: 32px;
}
.gl-hero__lede { max-width: 440px; font-size: 18px; line-height: 1.5; margin: 0; }
.gl-hero__lede strong { color: var(--tomato); font-weight: 600; font-style: italic; font-family: var(--font-display); font-size: 1.3em; letter-spacing: -0.02em; }
.gl-hero__cta { display: flex; align-items: center; gap: 20px; flex-shrink: 0; }
.gl-hero__link { font-family: var(--font-hand); font-size: 28px; color: var(--ink); transform: rotate(-3deg); display:inline-block; text-decoration:none; background-image:none;}
.gl-hero__link:hover { color: var(--tomato); }
.gl-hero__sticker {
position: absolute; top: 150px; right: 80px;
width: 160px; height: 160px;
z-index: 1;
}
.gl-hero__scroll {
position: absolute; bottom: 40px; left: 50%; transform: translateX(-50%);
display: flex; flex-direction: column; align-items: center; gap: 10px;
font-family: var(--font-body); font-size: 11px; letter-spacing: 0.2em;
text-transform: uppercase; color: var(--fg-muted);
}
.gl-hero__scroll-dot {
width: 1px; height: 44px; background: var(--ink-40);
animation: scroll-pulse 1.8s var(--ease) infinite;
}
@keyframes scroll-pulse {
0% { transform: scaleY(0); transform-origin: top; }
50% { transform: scaleY(1); transform-origin: top; }
50.001% { transform-origin: bottom; }
100% { transform: scaleY(0); transform-origin: bottom; }
}
/* --- Marquee ---------------------------------------------- */
.gl-marquee {
background: var(--ink); color: var(--paper);
padding: 28px 0; overflow: hidden;
border-top: 2px solid var(--ink); border-bottom: 2px solid var(--ink);
}
.gl-marquee__track {
display: flex; gap: 48px; white-space: nowrap;
animation: marquee 32s linear infinite;
font-family: var(--font-display); font-size: 64px; font-weight: 400;
line-height: 1;
font-variation-settings: 'SOFT' 60, 'opsz' 144;
flex-shrink: 0;
}
.gl-marquee__item { display: inline-flex; align-items: center; gap: 48px; }
.gl-marquee__dot { width: 18px; height: 18px; background: var(--tomato); border-radius: 50%; display: inline-block; }
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-33.333%); } }
/* --- About ------------------------------------------------ */
.gl-about {
max-width: var(--page-max); margin: 0 auto;
padding: 160px var(--page-gutter);
}
.gl-about__grid { display: grid; grid-template-columns: 440px 1fr; gap: 96px; align-items: start; }
.gl-about__portrait { position: relative; }
.gl-portrait-placeholder {
width: 100%; aspect-ratio: 4/5;
background: linear-gradient(135deg, #E8422B 0%, #B82F1E 100%);
border-radius: var(--r-lg);
display: flex; align-items: flex-end; justify-content: center;
padding: 24px; color: rgba(245,239,228,0.7);
font-family: var(--font-body); font-size: 13px;
text-transform: uppercase; letter-spacing: 0.1em;
}
.gl-portrait-img {
width: 100%; aspect-ratio: 4/5; object-fit: cover;
border-radius: var(--r-lg);
border: 2px solid var(--ink);
box-shadow: var(--shadow-lift);
display: block;
filter: contrast(1.05) saturate(0.95);
}
.gl-portrait-img {
width: 100%; aspect-ratio: 4/5;
object-fit: cover; object-position: center 30%;
border-radius: var(--r-lg);
border: 2px solid var(--ink);
box-shadow: 10px 10px 0 var(--ink);
display: block;
filter: saturate(1.02) contrast(1.03);
}
.gl-about__title { font-family: var(--font-display); font-size: clamp(48px, 7vw, 96px); line-height: 0.95; letter-spacing: -0.035em; font-weight: 400; font-variation-settings: 'SOFT' 60, 'opsz' 144; margin: 16px 0 32px; }
.gl-about__p { font-size: 19px; line-height: 1.55; max-width: 56ch; color: var(--ink); margin: 0 0 48px; }
.gl-signature { list-style: none; padding: 0; margin: 0; border-top: 1px solid var(--border); }
.gl-signature li { display: flex; gap: 24px; padding: 18px 0; border-bottom: 1px solid var(--border); font-family: var(--font-body); font-size: 17px; align-items: baseline; }
.gl-signature__num { font-family: var(--font-display); font-size: 28px; color: var(--tomato); font-weight: 500; letter-spacing: -0.02em; width: 48px; flex-shrink: 0; }
/* --- Work (case studies) --------------------------------- */
.gl-work { max-width: var(--page-max); margin: 0 auto; padding: 120px var(--page-gutter); }
.gl-work__head { max-width: 720px; margin: 0 auto 80px; text-align: center; }
.gl-work__title { font-family: var(--font-display); font-size: clamp(48px, 7vw, 96px); line-height: 0.95; letter-spacing: -0.035em; font-weight: 400; margin: 16px 0 20px; font-variation-settings: 'SOFT' 60, 'opsz' 144; }
.gl-work__intro { font-size: 18px; line-height: 1.5; color: var(--fg-muted); margin: 0; max-width: 56ch; margin-inline: auto; }
.gl-work__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 40px; }
.gl-case {
background: var(--paper-deep); border: 1px solid var(--border);
border-radius: var(--r-lg); padding: 32px;
display: flex; flex-direction: column; gap: 20px;
transition: transform 400ms var(--ease), box-shadow 400ms var(--ease);
cursor: pointer;
}
.gl-case:hover { box-shadow: var(--shadow-lift); }
.gl-case--riso { background: var(--cream); border: 2px solid var(--ink); }
.gl-case__top { display: flex; justify-content: space-between; align-items: center; }
.gl-case__arrow { font-size: 24px; color: var(--tomato); }
.gl-case__title { font-family: var(--font-display); font-size: 52px; font-weight: 500; letter-spacing: -0.03em; line-height: 1; margin: 0; font-variation-settings: 'SOFT' 60, 'opsz' 120; }
.gl-case__sub { font-size: 16px; line-height: 1.5; color: var(--fg-muted); margin: 0; }
.gl-case__image { aspect-ratio: 16/10; border-radius: var(--r-md); overflow: hidden; background: var(--ink-blue); }
.gl-case__image-ph { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; color: rgba(245,239,228,0.5); font-family: var(--font-body); font-size: 12px; text-transform: uppercase; letter-spacing: 0.14em; background: repeating-linear-gradient(45deg, #18223A, #18223A 8px, #232e48 8px, #232e48 16px); }
.gl-case__gallery {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px;
margin: 8px 0 4px;
}
.gl-case__thumb {
aspect-ratio: 3/4;
border-radius: var(--r-md);
overflow: hidden;
border: 2px solid var(--ink);
box-shadow: 3px 3px 0 var(--ink);
background: var(--ink-blue);
transition: transform 400ms var(--ease);
}
.gl-case__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gl-case:hover .gl-case__thumb { transform: rotate(0deg) !important; }
.gl-case__metrics {
display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
border-top: 1px dashed var(--ink-25);
border-bottom: 1px dashed var(--ink-25);
padding: 16px 0; margin-top: 4px;
}
.gl-metric { display: flex; flex-direction: column; gap: 2px; }
.gl-metric__num {
font-family: var(--font-display);
font-size: 36px; line-height: 1; font-weight: 500;
color: var(--tomato); letter-spacing: -0.03em;
font-variation-settings: 'SOFT' 60, 'opsz' 120;
}
.gl-metric__unit { font-size: 0.55em; margin-left: 2px; color: var(--ink-60); }
.gl-metric__label {
font-family: var(--font-body);
font-size: 11px; text-transform: uppercase; letter-spacing: 0.12em;
color: var(--fg-muted); margin-top: 4px;
}
.gl-case__foot { display: flex; justify-content: space-between; align-items: flex-end; gap: 16px; margin-top: 8px; padding-top: 20px; border-top: 1px solid var(--border); }
.gl-case__tags { display: flex; gap: 6px; flex-wrap: wrap; }
.gl-case__meta { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; font-family: var(--font-body); font-size: 12px; color: var(--fg-muted); text-transform: uppercase; letter-spacing: 0.1em; }
/* --- Services --------------------------------------------- */
.gl-services {
background: var(--tomato); color: var(--paper);
padding: 160px var(--page-gutter);
margin-top: 80px;
position: relative;
}
.gl-services__head { max-width: var(--page-max); margin: 0 auto 80px; }
.gl-services__title { font-family: var(--font-display); font-size: clamp(56px, 9vw, 128px); line-height: 0.92; letter-spacing: -0.04em; font-weight: 400; margin: 16px 0 0; color: var(--paper); font-variation-settings: 'SOFT' 80, 'opsz' 144; }
.gl-services__grid { max-width: var(--page-max); margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0; border-top: 1px solid rgba(245,239,228,0.25); }
.gl-service { padding: 40px 32px; border-right: 1px solid rgba(245,239,228,0.25); }
.gl-service:last-child { border-right: 0; }
.gl-service__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 40px; }
.gl-service__num { font-family: var(--font-display); font-size: 20px; color: var(--lime); font-style: italic; }
.gl-service__arrow { font-size: 22px; color: var(--paper); }
.gl-service__title { font-family: var(--font-display); font-size: 56px; font-weight: 400; line-height: 1; margin: 0 0 24px; letter-spacing: -0.03em; color: var(--paper); font-variation-settings: 'SOFT' 80, 'opsz' 144; }
.gl-service__list { list-style: none; padding: 0; margin: 0; }
.gl-service__list li { font-family: var(--font-body); font-size: 15px; padding: 10px 0; border-bottom: 1px solid rgba(245,239,228,0.2); color: rgba(245,239,228,0.9); }
.gl-service__list li:last-child { border-bottom: 0; }
/* --- Contact ---------------------------------------------- */
.gl-contact {
background: var(--ink-blue); color: var(--paper);
padding: 160px var(--page-gutter);
}
.gl-contact__grid { max-width: var(--page-max); margin: 0 auto; display: grid; grid-template-columns: 1fr 1fr; gap: 80px; align-items: start; }
.gl-contact__title { font-family: var(--font-display); font-size: clamp(48px, 7vw, 104px); line-height: 0.95; letter-spacing: -0.035em; font-weight: 400; margin: 16px 0 32px; color: var(--paper); font-variation-settings: 'SOFT' 60, 'opsz' 144; }
.gl-contact__p { font-size: 18px; line-height: 1.5; color: rgba(245,239,228,0.7); margin: 0 0 48px; }
.gl-contact__direct { display: flex; flex-direction: column; gap: 24px; }
.gl-contact__email { font-family: var(--font-display); font-size: 36px; color: var(--lime); text-decoration: none; letter-spacing: -0.02em; background-image: none; font-variation-settings: 'SOFT' 60, 'opsz' 60;}
.gl-contact__email:hover { color: var(--paper); }
.gl-contact__socials { display: flex; gap: 18px; font-family: var(--font-body); font-size: 15px; }
.gl-contact__socials a { color: rgba(245,239,228,0.7); cursor: pointer; background-image: none; text-decoration: none;}
.gl-contact__socials a:hover { color: var(--lime); }
.gl-contact__form { display: flex; flex-direction: column; gap: 18px; }
.gl-contact__form label { display: flex; flex-direction: column; gap: 6px; }
.gl-contact__form label span { font-family: var(--font-body); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.14em; color: var(--lime); }
.gl-input {
font-family: var(--font-body); font-size: 16px;
padding: 14px 16px; border: 1px solid rgba(245,239,228,0.25);
border-radius: var(--r-md); background: rgba(245,239,228,0.04);
color: var(--paper); width: 100%; resize: vertical;
}
.gl-input:focus { outline: none; border-color: var(--lime); background: rgba(245,239,228,0.08); }
/* --- Footer ----------------------------------------------- */
.gl-footer { background: var(--ink); color: var(--paper); padding: 80px var(--page-gutter) 40px; }
.gl-footer__big { font-family: var(--font-display); font-size: clamp(48px, 10vw, 160px); line-height: 0.9; font-weight: 400; letter-spacing: -0.04em; font-variation-settings: 'SOFT' 80, 'opsz' 144; display: flex; flex-wrap: wrap; gap: 16px; }
.gl-footer__meta { display: flex; justify-content: space-between; margin-top: 80px; padding-top: 32px; border-top: 1px solid rgba(245,239,228,0.2); font-family: var(--font-body); font-size: 13px; color: rgba(245,239,228,0.5); }
/* --- Rotating sticker ----------------------------------- */
.rotate-slow { animation: rotate-sticker 14s linear infinite; }
@keyframes rotate-sticker { from { transform: rotate(0); } to { transform: rotate(360deg); } }
function Header({ onNav }) {
const [scrolled, setScrolled] = React.useState(false);
React.useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 40);
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
return (
<header className={`gl-header${scrolled ? ' is-scrolled' : ''}`}>
<div className="gl-header__inner">
<a href="#top" className="gl-wordmark">
gili levinson<span style={{ color: 'var(--tomato)' }}>.</span>
</a>
<nav className="gl-nav">
<a href="#work" onClick={(e)=>{e.preventDefault();onNav?.('work');}}>Work</a>
<a href="#about" onClick={(e)=>{e.preventDefault();onNav?.('about');}}>About</a>
<a href="#services" onClick={(e)=>{e.preventDefault();onNav?.('services');}}>Services</a>
<a href="index-he.html" className="gl-lang">עב ↗</a>
<a href="#contact" onClick={(e)=>{e.preventDefault();onNav?.('contact');}}>
<Button variant="primary">Let's talk →</Button>
</a>
</nav>
</div>
</header>
);
}
function Hero() {
return (
<section className="gl-hero">
<div className="gl-hero__tags">
<Eyebrow>✳ PORTFOLIO · 2026</Eyebrow>
<Eyebrow color="var(--fg-muted)">TEL AVIV ↔ EVERYWHERE</Eyebrow>
</div>
<h1 className="gl-hero__title">
<ScribbleUnderline>marketing</ScribbleUnderline><br/>
<span className="gl-italic">in motion.</span>
</h1>
<div className="gl-hero__foot">
<p className="gl-hero__lede">
I'm <strong>Gili</strong> — digital marketing & social strategist. Strategy first, then execution: production, creative direction, and managing creative freelancers. End-to-end, hands-on.
</p>
<div className="gl-hero__cta">
<Button variant="primary">See the work ↓</Button>
<a href="#contact" className="gl-hero__link">or just say hi →</a>
</div>
</div>
<img src={window.__resources.stickerAvailable} className="gl-hero__sticker rotate-slow" alt="Available for projects"/>
<div className="gl-hero__scroll">
<span>scroll</span>
<span className="gl-hero__scroll-dot"/>
</div>
</section>
);
}
function Marquee() {
const items = ['strategy', 'content', 'stills & video', 'vendor management', 'promotion', '& everything in between'];
const doubled = [...items, ...items, ...items];
return (
<section className="gl-marquee">
<div className="gl-marquee__track">
{doubled.map((t, i) => (
<span key={i} className="gl-marquee__item">
{i % 2 === 1 ? <span className="gl-italic" style={{ color: 'var(--tomato)' }}>{t}</span> : t}
<span className="gl-marquee__dot"/>
</span>
))}
</div>
</section>
);
}
Object.assign(window, { Header, Hero, Marquee });