Hello!

My name is Joana and I am a communication designer with experience in creating and editing digital content, and a passion for the world of creativity.I enjoy communicating ideas clearly and visually, and I find motivation in the challenge of transforming concepts into something simple and effective — creating, whether on paper, on screen or by sharing with others.My process is fueled by the pleasure of learning something new every day, of transforming ideas into images and seeking visual solutions to complex problems, as I believe that good communication brings us closer, inspires us and transforms what surrounds us.Porto, Portugal

My work

From pencil to marker, from Paint to Photoshop, from digital tablet to iPad, from the smallest projects and sketches to the most elaborate works, everything is a process for who I am today in the field.It's not easy to follow a single path when there are a thousand and one styles that attract and inspire us. But it's this pursuit that makes it all the more exciting.

What I bring to the table?

● Skilled in Ps, Ai and Id
● Creative Problem Solving
● Dedication, Responsibility and Reliable
● Willingness to Learn
● Board Games

Ready to build something amazing?

Joana F Bastos's portfolio, 2026


#01


Cartazes e bilhetes - 100 Clichés


2025 | Rebrand - Logo design for DRAPN, "..."


Peça: Eu, Tu, Ele, Nós, Vós, Eles


#02


Manual de Identidade Visual - DPAPN


2025 | Rebrand - Logo design for DRAPN, "..."


Texto


#03


Jardim da Pini's Logo


2023 | Rebrand - Logo design for the Jardim da Pini store, "Pin's Garden"


Rebranding of the visual identity created in 2015, as a way to modernize the brand image and align with the client's vision.Jardim da Pini is a store that produces and uses succulents and other species in Portugal.The client wanted an image (mascot) inspired by the Pinipons of the 1990s and Japanese design, with a "kawaii" (cute) style.


Jardim da Pini's STORE



#01


IceBreaker


2023 | Question generator/game, "IceBreaker"


IceBreaker is a question generator with over 400 questions across various categories, allowing you to share and create impactful connections through random questions and unexpected answers.The platform is currently fully in Portuguese.


ICEBREAKER


#02


Eye2Map


-


-


link


STORY TIME


Drawing, always been presentWith an architect for a father and a preschool teacher for a mother, drawing materials surrounded my space from a young age. Whether it was drawing on walls, painting from my mother's fashion magazines, or watching my father's drawings, my taste for them developed.


#01


Desamparo


2019 | Illustrated fanzine, "Helplessness"


Final result of the master's project, on the theme "narcissistic mother and the damage caused to her child".The final object is a fanzine, which presents the child's path from the mother's gestation, until the moment when s/he is freed from it. Accompanying each illustration is a random word that represents a characteristic of a narcissistic mother. Ironically, the word "amparo" (meaning "protection/support") refers to the name of the narcissistic mother who inspired the project and its title: "Desamparo" ("helplessness").The drawings were worked with graphite pencils, where different elements were drawn on different sheets. The separation served to later work the illustration to be printed in risography, in two colors.


DISSERTATION


#02


Article: A violência invisível das mães narcisistas


2021 | Illustrations for an article in the Público newspaper, "The invisible violence of narcissistic mothers"


(Four) Illustrations published in the article about narcissistic mothers, in the newspaper P2/Público, on August 22, 2021.Article by Patrícia Noronha.


ONLINE ARTICLE


#03


Article: Como é que eu vou pedir ajuda a um hospital, se o abuso acontece no hospital?


2023 | Illustrations for an article in the Público newspaper, "How am I supposed to ask a hospital for help if the abuse happens in the hospital?"


(Five) Illustrations published in the article on sexual abuse in hospitals, in the newspaper (paper) P2/Público, on June 12, 2023.Article by Cláudia Marques Santos. Side note: This article was nominated for the European Press Prize 2024, in the research category, being considered one of the five best journalistic works in Europe in 2023.


ONLINE ARTICLE

Studies:


#04


Copo de Leite, Mancha de Café


2017 | Picture book, "Glass of Milk, Coffee Stain"


Children's book written by me in 2014, and was reused in this project to create an illustrated editorial project (2017). The story includes a second story inside, written by the writer's character.


Studies:


#álbuns


● 2018 | Comic, "Submergir" (Submerge)


● 2019 | Illustrations, "Diário Visual" (Visual Diary)



INTRO


Some personal projects and exhibitions carried out over the years, with emphasis on the continuous work with the theme "narcissistic mothers", in order to support the victims of this still invisible reality.


#01


Filhas/os do Desamparo


Since 2020 | Personal project, "Child of Helplessness"
- For victims of narcissism


Experimental work/studies done during the development of the master's project, on the theme "narcissistic mother and the damage caused to the child", illustrating the child's suffering.After this experimental project during my master's dissertation, a succession of projects related to the topic of "narcissistic mothers" began. The project, called DESAMPARO (Helpleness), presents a collection of projects I developed on the topic of "children of narcissism."The projects are dedicated to victims of narcissistic parents, aiming to help combat this (still) invisible reality in our society.


PROJECTS

An invisible reality.


#02


Olhos são...


2018 | Work for exhibition, "Eyes are..."


In the specialization project in illustration I got to work with the "eye" theme, where the objective was to explore a metaphorical understanding of the organ.This was my final work of “Olho” (eye), to be exhibited at the Rectory of the University of Porto, in may 2018.


PHOTOS (1) | PHOTOS (2) | PHOTOS (3)

Studies, exploration of ideas:


#03


GlitchView


2015 | GlitchView


GlithView comes from a work proposal in the area of Multimedia Art, where I would have to propose and develop a project related to audiovisual.With the help of a programmer - João Bispo - was developed a program that creates glitches in images: "GlitchView". In the final presentation, the images created with the program were also used in a virtual reality viewer for the Android platform.


BLOG


Joana F Bastos

Digital designer.
Illustrator.
Something else.

const btn = document.querySelector(".menu-btn"); const menu = document.querySelector(".sidebar-menu"); btn.addEventListener("click", () => { btn.classList.toggle("active"); menu.classList.toggle("open"); }); /* Fecha o menu ao clicar em qualquer link */ document.querySelectorAll(".sidebar-menu a").forEach(link => { link.addEventListener("click", () => { menu.classList.remove("open"); btn.classList.remove("active"); }); });

Hello!

My name is Joana and I am a communication designer with experience in creating and editing digital content, and a passion for the world of creativity.

I enjoy communicating ideas clearly and visually, and I find motivation in the challenge of transforming concepts into something simple and effective — creating, whether on paper, on screen or by sharing with others.

My process is fueled by the pleasure of learning something new every day, of transforming ideas into images and seeking visual solutions to complex problems, as I believe that good communication brings us closer, inspires us and transforms what surrounds us.

___
Porto, Portugal


What I bring to the table:
● Skilled in Ps, Ai and Id
● Creative Problem Solving
● Dedication, Responsibility and Reliable
● Willingness to Learn
● Board Games

function toggleAccordion(button) { const content = button.nextElementSibling; const isOpen = content.style.display === "block"; content.style.display = isOpen ? "none" : "block"; button.classList.toggle("active"); button.innerHTML = isOpen ? " About me ▶" : "About me ▼"; }

● Skilled in Ps, Ai and Id
● Creative Problem Solving
● Dedication, Responsibility and Reliable
● Willingness to Learn
● Board Games

function toggleAccordion(button) { const content = button.nextElementSibling; const isOpen = content.style.display === "block"; content.style.display = isOpen ? "none" : "block"; button.classList.toggle("active"); button.innerHTML = isOpen ? " What I bring to the table ▶" : "What I bring to the table ▼"; }

Digital designer.
Illustrator.
Something else.

Joana F Bastos /_ Gallery

__

Graphic Design

Design UI

Illustration

Projects / Exhibitions

Ready to build something amazing?

Graphic/Editorial Design

Design UI/UX

Illustration

Projects


● 2017 | Illustrations, "O Rei Chuva" (The Rain King)

● Digital drawing, 2018:

v1
<!-- Google Fonts --> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&display=swap" rel="stylesheet">
<style> :root { color-scheme: light; }/* ---- MENU BASE ---- /
.sidebar { position: fixed; bottom: 0; left: 0; width: 100%; height: 80px; display: flex; flex-direction: row; justify-content: center; align-items: center; font-family: 'Inter', sans-serif; z-index: 999; opacity: 1; transition: opacity 0.4s ease; }
.sidebar.hidden { opacity: 0; pointer-events: none; }/ LINKS /
.sidebar a { flex: 1; display: flex; align-items: center; justify-content: center; text-decoration: none; font-size: 14px; font-weight: 400; letter-spacing: 0.05em; color: #fff; transition: all 0.3s ease; text-align: center; padding: 8px; box-sizing: border-box; }/
Hover /
.sidebar a:hover { transform: scale(1.05); z-index: 2; }/
Icon (Galeria) /
.sidebar .gallery { flex: 0 0 80px; background: #000; display: flex; align-items: center; justify-content: center; }.sidebar .gallery svg rect { stroke: #fff; fill: none; stroke-width: 2; transition: stroke 0.3s ease; }.sidebar .gallery:hover { background: #fff !important; }.sidebar .gallery:hover svg rect { stroke: #000; } /
Cores categorias /.sidebar .graphic-design { background: #F4E16B; color: #000; }.sidebar .design-ui { background: #BAF5D9; color: #000; } .sidebar.illustration { background: #FC6554; color: #000; }.sidebar .projects { background: #F8EFE8; color: #000; }/ ---- MOBILE ---- /
.menu-toggle { display: none; }@media(max-width: 768px)
{ /
Menu recolhe / .sidebar { height: 60px; transform: translateY(100%); transition: transform 0.35s ease, opacity 0.4s ease; } .sidebar.open { transform: translateY(0%); } .sidebar a { flex: 1; font-size: 12px; height: 100%; padding: 0; } .sidebar .gallery { flex: 0 0 60px; height: 60px; }/ BOTÃO HAMBÚRGUER /
.menu-toggle { display: flex; position: fixed; bottom: 10px; right: 10px; width: 48px; height: 48px; border-radius: 10px; background: #000; align-items: center; justify-content: center; z-index: 1000; cursor: pointer; }.menu-toggle span { width: 24px; height: 3px; background: #fff; display: block; border-radius: 2px; position: relative; }.menu-toggle span::before,.menu-toggle span::after { content: ""; position: absolute; width: 24px; height: 3px; background: #fff; border-radius: 2px; left: 0; }.menu-toggle span::before { top: -7px; } .menu-toggle span::after { top: 7px; } }</style><!-- MENU --> <div class="sidebar"> <a href="#gallery" class="gallery"><!-- Ícone galeria --> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <rect x="3" y="3" width="7" height="7"/> <rect x="14" y="3" width="7" height="7"/> <rect x="3" y="14" width="7" height="7"/> <rect x="14" y="14" width="7" height="7"/> </svg> </a><a href="#graphic-design" class="graphic-design">Graphic Design</a> <a href="#design-ui" class="design-ui">Design UI</a> <a href="#illustration" class="illustration">Illustration</a> <a href="#projects" class="projects">Projects / Exhibitions</a> </div><!-- Botão Mobile --> <div class="menu-toggle"><span></span></div> <script> let lastScroll = 0; const menu = document.querySelector(".sidebar"); const toggle = document.querySelector(".menu-toggle");/
Desktop: esconder ao descer / mostrar ao subir / window.addEventListener("scroll", () => { const currentScroll = window.pageYOffset; if (currentScroll > lastScroll) { menu.classList.add("hidden"); } else { menu.classList.remove("hidden"); } lastScroll = currentScroll; }); / Mobile: abrir/fechar / toggle.addEventListener("click", () => { menu.classList.toggle("open"); }); /Fechar ao clicar em qualquer item do menu */ document.querySelectorAll(".sidebar a").forEach(link => { link.addEventListener("click", () => { menu.classList.remove("open"); }); });
</script>

v2
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&display=swap" rel="stylesheet">
<style>
/* --- MENU LATERAL --- /
.sidebar {
position: fixed;
right: 20px;
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 14px;
z-index: 9999;
/ scroll hide/show /
opacity: 1;
transition: opacity 0.4s ease, transform 0.25s ease;
}.sidebar.hidden {
opacity: 0;
pointer-events: none;
}
/
LINKS /
.sidebar a {
text-decoration: none;
padding: 10px 18px;
border-radius: 30px;
font-size: 15px;
font-weight: 500;
font-family: Inter, sans-serif;
background: rgba(0,0,0,0.15);
color: #000;
backdrop-filter: blur(5px);
display: inline-flex;
justify-content: center;
align-items: center;
transition: transform 0.25s ease, background 0.25s ease;
min-width: 44px;
min-height: 44px;
}/
Hover tilt-right /
.sidebar a:hover {
transform: translateX(6px) rotate(2deg);
background: rgba(0,0,0,0.25);
}/
Ícones */
.icon-grid {
display: grid;
grid-template-columns: repeat(2, 7px);
grid-gap: 4px;
}.icon-grid span {
width: 7px;
height: 7px;
background: #000;
border-radius: 2px;
display: block;
}
.icon-top {
width: 0;
height: 0;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 11px solid #000;
}
</style>
<div class="sidebar">
<a href="#gallery" aria-label="Gallery" title="Gallery">
<div class="icon-grid" aria-hidden="true">
<span></span><span></span>
<span></span><span></span>
</div>
</a>
<a href="#graphicdesign">Graphic Design</a>
<a href="#design
ui">Design UI</a>
<a href="#illustration">Illustration</a>
<a href="#projects">Projects</a>
<a href="#contact">Contact</a>
<a href="https://joanafbastos-cv.carrd.co/" target="_blank" rel="noopener">CV</a>
<a href="#top" aria-label="Top" title="Top">
<span class="icon-top" aria-hidden="true"></span>
</a>
</div>
<script>
// Scroll suave
document.querySelectorAll('.sidebar a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function(e) {
const target = document.querySelector(this.getAttribute('href'));
if (!target) return;
e.preventDefault();
target.scrollIntoView({ behavior: 'smooth' });
});
});
// Scroll hide/show baseado no código antigo
let lastScroll = 0;
const menu = document.querySelector(".sidebar");
window.addEventListener("scroll", () => {
const currentScroll = window.pageYOffset || document.documentElement.scrollTop;
if (currentScroll > lastScroll) {
// A descer → esconde
menu.classList.add("hidden");
} else {
// A subir → mostra
menu.classList.remove("hidden");
}
lastScroll = Math.max(0, currentScroll);
});
</script>

v3
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&display=swap" rel="stylesheet">
<style>
/* --- BOTÃO HAMBÚRGUER --- /
.menu-btn {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
width: 46px;
height: 46px;
background: #fff;
border: 1px solid #000;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 2000;
transition: all 0.3s ease;
}
.menu-btn span,
.menu-btn span::before,
.menu-btn span::after {
width: 22px;
height: 2px;
background: #000;
display: block;
position: absolute;
transition: 0.3s ease;
}
.menu-btn span::before {
content: "";
transform: translateY(-6px);
}
.menu-btn span::after {
content: "";
transform: translateY(6px);
}
/
--- HOVER COM MENU FECHADO --- /
.menu-btn:not(.active):hover {
background: #000;
}.menu-btn:not(.active):hover span,
.menu-btn:not(.active):hover span::before,
.menu-btn:not(.active):hover span::after {
background: #fff;
}
/
--- ESTADO ATIVO (MENU ABERTO) → X BRANCO EM FUNDO PRETO --- /
.menu-btn.active {
background: #000;
}.menu-btn.active span {
background: transparent;
}
.menu-btn.active span::before,
.menu-btn.active span::after {
background: #fff;
}
.menu-btn.active span::before {
transform: rotate(45deg);
}
.menu-btn.active span::after {
transform: rotate(-45deg);
}
/
--- HOVER NO ESTADO ATIVO (INVERTER) --- /
.menu-btn.active:hover {
background: #f2f2f2;
}.menu-btn.active:hover span::before,
.menu-btn.active:hover span::after {
background: #000;
}
/
--- MENU LATERAL --- /
.sidebar-menu {
position: fixed;
right: -300px;
top: 0;
width: 300px;
height: 100vh;
background: #000;
color: #fff;
font-family: 'Inter', sans-serif;
display: flex;
flex-direction: column;
gap: 24px;
padding: 100px 20px;
box-sizing: border-box;
z-index: 1500;
transition: right 0.4s ease;
}.sidebar-menu.open {
right: 0;
}
/
Links /
.sidebar-menu a {
color: #fff;
text-decoration: none;
font-size: 18px;
font-weight: 400;
display: flex;
align-items: center;
gap: 12px;
}/
Ícone Galeria /
.icon-grid {
width: 18px;
display: grid;
grid-template-columns: repeat(2, 7px);
grid-gap: 4px;
}
.icon-grid span {
width: 7px;
height: 7px;
background: #fff;
display: block;
}/
Ícone seta (Top) /
.icon-up {
width: 0;
height: 0;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 11px solid #fff;
}
</style><!-- BOTÃO -->
<div class="menu-btn" aria-label="Abrir menu" role="button">
<span></span>
</div>
<!-- MENU LATERAL -->
<nav class="sidebar-menu">
<a href="#gallery">
<div class="icon-grid">
<span></span><span></span>
<span></span><span></span>
</div>
Gallery
</a>
<a href="#graphic-design">Graphic Design</a>
<a href="#design-ui">Design UI</a>
<a href="#illustration">Illustration</a>
<a href="#projects">Projects</a>
<a href="#about">About me</a>
<a href="https://joanafbastos-cv.carrd.co/" target="_blank">CV</a>
<a href="#top">
<span class="icon-up"></span>
Top
</a>
</nav>
<script>
const btn = document.querySelector(".menu-btn");
const menu = document.querySelector(".sidebar-menu");
btn.addEventListener("click", () => {
btn.classList.toggle("active");
menu.classList.toggle("open");
});
/
Fecha o menu ao clicar num link */
document.querySelectorAll(".sidebar-menu a").forEach(link => {
link.addEventListener("click", () => {
menu.classList.remove("open");
btn.classList.remove("active");
});
});
</script>

texto move<div id="brandingIntro">
<p>Digital designer.</p>
<p>Illustrator.</p>
<p>Something else.</p>
</div>
<style>
#brandingIntro {
position: fixed;
top: 45vh; /* Centro vertical aproximado /
left: 50%;
transform: translate(-50%, -50%) scale(1);
font-family: 'Inter', sans-serif;
text-align: center;
font-size: 38px;
font-weight: 700;
line-height: 1.25em;
letter-spacing: 0.5px;
color: #000;
z-index: 2000;
opacity: 1;
transition: transform 0.35s ease, opacity 0.35s ease;
pointer-events: none; /
não atrapalha cliques /
}
#brandingIntro p {
margin: 6px 0;
}
/
Mobile ajuste opcional */
@media (max-width: 768px) {
#brandingIntro {
font-size: 26px;
}
}
</style><script>
window.addEventListener("scroll", function () {
const block = document.getElementById("brandingIntro");
const scrollY = window.scrollY;
if (scrollY > 100) {
block.style.opacity = "0";
block.style.transform = "translate(-50%, -50%) scale(0.4)";
} else {
block.style.opacity = "1";
block.style.transform = "translate(-50%, -50%) scale(1)";
}
});
</script>

MENU HAMB<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&display=swap" rel="stylesheet">
<style>
/* --- BOTÃO HAMBÚRGUER --- /
.menu-btn {
position: fixed;
top: 50%;
right: 20px;
transform: translateY(-50%);
width: 46px;
height: 46px;
background: #f2f2f2;
border: 1px solid #000;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 2000;
transition: all 0.3s ease;
}
.menu-btn span,
.menu-btn span::before,
.menu-btn span::after {
width: 22px;
height: 2px;
background: #000;
display: block;
position: absolute;
transition: 0.3s ease;
}
.menu-btn span::before {
content: "";
transform: translateY(-6px);
}
.menu-btn span::after {
content: "";
transform: translateY(6px);
}
/
Hover (menu fechado) /
.menu-btn:not(.active):hover {
background: #000;
}.menu-btn:not(.active):hover span,
.menu-btn:not(.active):hover span::before,
.menu-btn:not(.active):hover span::after {
background: #fff;
}
/
Estado ativo (menu aberto) /
.menu-btn.active {
background: #000;
}.menu-btn.active span {
background: transparent;
}
.menu-btn.active span::before {
transform: rotate(45deg);
background: #fff;
}
.menu-btn.active span::after {
transform: rotate(-45deg);
background: #fff;
}
/
Hover quando ativo /
.menu-btn.active:hover {
background: #f2f2f2;
}.menu-btn.active:hover span::before,
.menu-btn.active:hover span::after {
background: #000;
}
/
--- MENU LATERAL --- /
.sidebar-menu {
position: fixed;
right: -300px;
top: 0;
width: 300px;
height: 100vh;
background: #000;
color: #fff;
font-family: 'Inter', sans-serif;
display: flex;
flex-direction: column;
gap: 24px;
padding: 100px 20px;
box-sizing: border-box;
z-index: 1500;
transition: right 0.4s ease;
}.sidebar-menu.open {
right: 0;
}
/
Links /
.sidebar-menu a {
color: #fff;
text-decoration: none;
font-size: 18px;
font-weight: 400;
display: flex;
align-items: center;
gap: 12px;
}/
Ícone Galeria /
.icon-grid {
width: 18px;
display: grid;
grid-template-columns: repeat(2, 7px);
grid-gap: 4px;
}
.icon-grid span {
width: 7px;
height: 7px;
background: #fff;
display: block;
}/
Ícone seta (Top) /
.icon-up {
width: 0;
height: 0;
border-left: 7px solid transparent;
border-right: 7px solid transparent;
border-bottom: 11px solid #fff;
}/
--- MEDIA QUERY MOBILE --- /
@media (max-width: 768px) {
.sidebar-menu {
width: 100%; /
barra lateral ocupa toda a largura /
height: 100vh; /
altura total /
top: 0;
right: -100%; /
fora da tela quando fechado /
padding: 80px 20px;
}.sidebar-menu.open {
right: 0; /
ocupa toda a tela /
}.sidebar-menu a {
font-size: 20px; /
links maiores no mobile /
}
}
</style><!-- BOTÃO -->
<div class="menu-btn" aria-label="Abrir menu" role="button">
<span></span>
</div>
<!-- MENU LATERAL -->
<nav class="sidebar-menu">
<a href="#gallery">
<div class="icon-grid">
<span></span><span></span>
<span></span><span></span>
</div>
Gallery
</a>
<a href="#graphic-design">Graphic Design</a>
<a href="#design-ui">Design UI</a>
<a href="#illustration">Illustration</a>
<a href="#projects">Projects</a>
<a href="#about">About Me</a>
<a href="https://joanafbastos-cv.carrd.co/" target="_blank">CV</a>
<a href="#top">
<span class="icon-up"></span>
Top
</a>
</nav>
<script>
const btn = document.querySelector(".menu-btn");
const menu = document.querySelector(".sidebar-menu");
btn.addEventListener("click", () => {
btn.classList.toggle("active");
menu.classList.toggle("open");
});
/
Fecha o menu ao clicar em qualquer link */
document.querySelectorAll(".sidebar-menu a").forEach(link => {
link.addEventListener("click", () => {
menu.classList.remove("open");
btn.classList.remove("active");
});
});
</script>

Sobre mim botão<!-- Google Fonts: Inter -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;700&display=swap" rel="stylesheet">
<style>
/* --- GERAL --- /
body {
margin: 0;
font-family: 'Inter', sans-serif;
}
/ --- BOTÃO PRINCIPAL "SOBRE MIM" --- /
.accordion-btn {
background-color: white;
color: black;
font-weight: 400;
font-size: 1rem;
letter-spacing: 0.025em;
padding: 1rem 2rem;
width: 100%;
border: 1px solid black;
text-align: center;
cursor: pointer;
margin-bottom: 1rem;
}.accordion-btn:hover,
.accordion-btn.active {
background-color: black;
color: white;
}
/
--- SECÇÃO EXPANDIDA --- /
.accordion-content {
display: none;
width: calc(100% - 2rem); /
2rem de margem de cada lado /
background-image: url('https://your-image-url.com/bg.jpg');
background-size: cover;
background-position: center;
margin: 4rem auto;
padding: 2rem;
}/
--- LAYOUT EM 1 COLUNA --- /
.accordion-inner {
display: flex;
flex-direction: column;
gap: 2rem;
}/
--- TEXTO --- /
.accordion-inner h3 {
font-size: 2rem;
font-weight: 700;
color: black;
line-height: 1.25;
letter-spacing: -0.075em;
margin-bottom: 1.5rem;
}.accordion-inner p {
font-size: 1rem;
font-weight: 300;
color: black;
line-height: 1.625;
letter-spacing: 0.025em;
margin-bottom: 2rem;
}
/
--- BOTÕES POR BAIXO DO TEXTO --- */
.accordion-buttons {
display: flex;
flex-direction: column;
gap: 1rem;
width: 100%;
}.accordion-buttons a {
background-color: white;
color: black;
border: 1px solid black;
padding: 1rem 2rem;
font-size: 1rem;
font-weight: 400;
letter-spacing: 0.025em;
text-decoration: none;
text-transform: uppercase;
transition: all 0.3s ease;
text-align: center;
}
.accordion-buttons a:hover {
background-color: black;
color: white;
transform: scale(1.03);
}
</style>
<!-- BOTÃO "SOBRE MIM" -->
<button class="accordion-btn" onclick="toggleAccordion(this)"> About me ▶</button>
<!-- SECÇÃO EXPANDIDA -->
<div class="accordion-content">
<div class="accordion-inner">
<!-- TEXTO -->
<h3>Hello!</h3>
<p>
My name is Joana and I am a communication designer with experience <strong>in creating and editing digital content</strong>, and <strong>a passion for the world of creativity.</strong>
<br><br>
I enjoy communicating ideas clearly and visually, and <strong>I find motivation in the challenge of transforming concepts into something simple and effective</strong> — creating, whether on paper, on screen or by sharing with others.
<br><br>
My process is fueled by the pleasure of learning something new every day, of transforming ideas into images and seeking visual solutions to complex problems, as I believe that good <strong>communication brings us closer, inspires us and transforms what surrounds us</strong>.
<br><br>
__<br>
<em>Porto, Portugal</em><br>
<br><br>
<strong>What I bring to the table:</strong><br>
● Skilled in Ps, Ai and Id<br>
● Creative Problem Solving<br>
● Dedication, Responsibility and Reliable<br>
● Willingness to Learn<br>
● Board Games
</p>
<!-- BOTÕES -->
<div class="accordion-buttons">
<a href="https://joanafbastos-cv.carrd.co/" target="
blank">CV</a>
<a href="#contact">Contact</a>
</div>
</div>
</div><script>
function toggleAccordion(button) {
const content = button.nextElementSibling;
const isOpen = content.style.display === "block";
content.style.display = isOpen ? "none" : "block";
button.classList.toggle("active");
button.innerHTML = isOpen ? " About me ▶" : "About me ▼";
}
</script>