Templates

Personal Portfolio

A dark, editorial portfolio for a designer or developer, with selected work, services, and a contact form.

Portfolio HTML CSS Free
Live preview View code

Use this free Mira Vale portfolio as a starting point for personal sites. The layout is a single HTML file with CSS variables for color, a project grid, and clearly marked copy you can replace.

What's included

  • Sticky navigation with a mobile menu
  • Hero with availability and a short bio
  • Selected work grid with CSS project placeholders
  • About, services, and collaborator quotes
  • Accessible contact form that does not pretend to submit to a backend

Responsive support

This template is built as a full page and adapts to desktop, tablet, and mobile widths. Use the live preview to check each viewport before you copy the code.

Template source

Copy the HTML below into your project. A short README in the template folder explains colors, content, and placeholder visuals.

<!--
  Mira Vale — Personal portfolio template
  See README.md in this folder for usage, colors, content, and placeholder visuals.
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Mira Vale — Product designer</title>
  <meta name="description" content="Portfolio of Mira Vale, a product designer working with early-stage teams on research, interface, and design systems.">
  <style>
    :root {
      --bg: #111111;
      --bg-raised: #1a1a1a;
      --ink: #f4efe6;
      --muted: #b8b0a4;
      --line: #2a2a2a;
      --accent: #e85d04;
      --accent-dark: #c2410c;
      --card: #181818;
      --radius: 16px;
      --font: "Iowan Old Style", "Palatino Linotype", Palatino, "Times New Roman", serif;
      --ui: "Avenir Next", "Segoe UI", sans-serif;
      --max: 1080px;
    }
    * { box-sizing: border-box; }
    html { scroll-behavior: smooth; }
    body {
      margin: 0;
      color: var(--ink);
      background: var(--bg);
      font-family: var(--ui);
      line-height: 1.55;
    }
    a { color: inherit; }
    button, input, textarea { font: inherit; color: inherit; }
    img { max-width: 100%; display: block; }
    .skip-link {
      position: absolute;
      left: 1rem;
      top: -40px;
      background: var(--accent);
      color: #fff;
      padding: 0.5rem 0.75rem;
      z-index: 20;
    }
    .skip-link:focus { top: 1rem; }
    .wrap {
      width: min(var(--max), calc(100% - 2rem));
      margin: 0 auto;
    }
    .site-header {
      position: sticky;
      top: 0;
      z-index: 10;
      background: rgba(17, 17, 17, 0.92);
      backdrop-filter: blur(16px);
      border-bottom: 1px solid var(--line);
    }
    .nav {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 1rem;
      min-height: 72px;
    }
    .logo {
      text-decoration: none;
      font-family: var(--font);
      font-weight: 700;
      letter-spacing: -0.03em;
      font-size: 1.2rem;
    }
    .nav-links { display: flex; align-items: center; gap: 1.25rem; }
    .nav-links a:not(.btn) { text-decoration: none; color: var(--muted); }
    .nav-links a:not(.btn):hover { color: var(--ink); }
    .nav-links .btn-primary { color: #fff; }
    .nav-links .btn-primary:hover { color: #fff; background: var(--accent-dark); }
    .nav-toggle {
      display: none;
      border: 1px solid var(--line);
      background: var(--card);
      border-radius: 10px;
      padding: 0.45rem 0.7rem;
    }
    .btn {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      border: 0;
      border-radius: 999px;
      padding: 0.8rem 1.2rem;
      text-decoration: none;
      font-weight: 600;
      cursor: pointer;
    }
    .btn-primary { background: var(--accent); color: #fff; }
    .btn-primary:hover { background: var(--accent-dark); }
    .btn-ghost { background: transparent; color: var(--ink); border: 1px solid var(--line); }
    .hero { padding: 5rem 0 3.5rem; }
    .eyebrow {
      color: var(--accent);
      font-weight: 700;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      font-size: 0.78rem;
      margin: 0 0 0.8rem;
    }
    h1, h2, h3 { font-family: var(--font); letter-spacing: -0.03em; line-height: 1.15; }
    h1 { font-size: clamp(2.6rem, 6vw, 4.8rem); margin: 0 0 1rem; max-width: 14ch; }
    h2 { font-size: clamp(1.8rem, 3vw, 2.5rem); margin: 0 0 0.8rem; }
    h3 { font-size: 1.2rem; margin: 0 0 0.4rem; }
    .lede { font-size: 1.15rem; color: var(--muted); max-width: 38rem; }
    .hero-actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.8rem; }
    .meta-row {
      display: flex;
      flex-wrap: wrap;
      gap: 1.5rem;
      margin-top: 2.5rem;
      color: var(--muted);
      font-size: 0.95rem;
    }
    .meta-row strong { display: block; color: var(--ink); }
    section { padding: 4rem 0; }
    .section-head { margin-bottom: 1.8rem; }
    .work-grid {
      display: grid;
      grid-template-columns: 1.2fr 0.8fr;
      gap: 1rem;
    }
    .project {
      background: var(--card);
      border: 1px solid var(--line);
      border-radius: var(--radius);
      overflow: hidden;
      text-decoration: none;
      display: flex;
      flex-direction: column;
    }
    .project-visual {
      min-height: 220px;
      padding: 1.2rem;
    }
    .project:nth-child(1) .project-visual { background: linear-gradient(135deg, #3f2e1f, #e85d04 80%); min-height: 280px; }
    .project:nth-child(2) .project-visual { background: linear-gradient(160deg, #1e293b, #64748b); }
    .project:nth-child(3) .project-visual { background: linear-gradient(160deg, #14532d, #86efac); }
    .project:nth-child(4) .project-visual { background: linear-gradient(160deg, #1e1b4b, #c4b5fd); }
    .chip {
      display: inline-block;
      background: rgba(255,255,255,0.14);
      border-radius: 999px;
      padding: 0.25rem 0.6rem;
      font-size: 0.8rem;
    }
    .bars { display: flex; align-items: end; gap: 0.4rem; height: 84px; margin-top: 2.4rem; }
    .bars span { width: 14px; border-radius: 6px 6px 2px 2px; background: rgba(255,255,255,0.55); display: block; }
    .project-body { padding: 1.2rem; }
    .project-body p { color: var(--muted); margin: 0; }
    .about-grid, .services, .quotes {
      display: grid;
      gap: 1rem;
    }
    .about-grid { grid-template-columns: 1.1fr 0.9fr; }
    .services { grid-template-columns: repeat(3, 1fr); }
    .quotes { grid-template-columns: 1fr 1fr; }
    .panel, .service, .quote {
      background: var(--card);
      border: 1px solid var(--line);
      border-radius: var(--radius);
      padding: 1.3rem;
    }
    .portrait {
      min-height: 280px;
      border-radius: var(--radius);
      background:
        radial-gradient(circle at 40% 30%, #e85d04 0 18%, transparent 19%),
        linear-gradient(180deg, #292524, #111);
      border: 1px solid var(--line);
    }
    .quote p { margin-top: 0; }
    .quote footer { color: var(--muted); margin-top: 1rem; }
    .contact-grid { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 1.5rem; }
    form { display: grid; gap: 0.85rem; }
    label { font-weight: 600; font-size: 0.92rem; }
    input, textarea {
      width: 100%;
      background: var(--bg);
      border: 1px solid var(--line);
      border-radius: 12px;
      padding: 0.75rem 0.9rem;
    }
    textarea { min-height: 140px; resize: vertical; }
    .form-status { min-height: 1.4em; color: var(--muted); }
    .site-footer {
      border-top: 1px solid var(--line);
      padding: 2rem 0 2.5rem;
      color: var(--muted);
    }
    .footer-row {
      display: flex;
      justify-content: space-between;
      gap: 1rem;
      flex-wrap: wrap;
    }
    .sr-only {
      position: absolute;
      width: 1px;
      height: 1px;
      overflow: hidden;
      clip: rect(0, 0, 0, 0);
    }
    :focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; }
    @media (max-width: 860px) {
      .work-grid, .about-grid, .services, .quotes, .contact-grid { grid-template-columns: 1fr; }
      .nav-toggle { display: inline-flex; }
      .nav-links {
        display: none;
        position: absolute;
        left: 1rem;
        right: 1rem;
        top: 72px;
        background: var(--card);
        border: 1px solid var(--line);
        border-radius: 16px;
        padding: 1rem;
        flex-direction: column;
        align-items: stretch;
      }
      .nav-links.is-open { display: flex; }
    }
  </style>
</head>
<body>
  <a class="skip-link" href="#main">Skip to content</a>
  <header class="site-header">
    <div class="wrap nav">
      <a class="logo" href="#top">Mira Vale</a>
      <button class="nav-toggle" type="button" aria-expanded="false" aria-controls="site-nav">Menu</button>
      <nav id="site-nav" class="nav-links" aria-label="Primary">
        <a href="#work">Work</a>
        <a href="#about">About</a>
        <a href="#services">Services</a>
        <a href="#notes">Notes</a>
        <a class="btn btn-primary" href="#contact">Get in touch</a>
      </nav>
    </div>
  </header>

  <main id="main">
    <section class="wrap hero" id="top">
      <p class="eyebrow">Product designer · Berlin and remote</p>
      <h1>Interfaces that make complex products feel obvious.</h1>
      <p class="lede">I help early-stage teams go from messy problem to a shipping interface: research, flows, UI, and a system the rest of the team can keep using.</p>
      <div class="hero-actions">
        <a class="btn btn-primary" href="#work">View selected work</a>
        <a class="btn btn-ghost" href="#contact">Book an intro call</a>
      </div>
      <div class="meta-row">
        <p><strong>Currently</strong> Independent, taking two new retainers</p>
        <p><strong>Previously</strong> Lattice, Tiny, local-first tools</p>
        <p><strong>Focus</strong> B2B SaaS, design systems, research</p>
      </div>
    </section>

    <section class="wrap" id="work" aria-labelledby="work-heading">
      <div class="section-head">
        <h2 id="work-heading">Selected work</h2>
        <p class="lede">A few recent projects. Replace the CSS panels with screenshots of your own product work.</p>
      </div>
      <div class="work-grid">
        <a class="project" href="#contact">
          <div class="project-visual" aria-hidden="true">
            <span class="chip">SaaS · 2025</span>
            <div class="bars">
              <span style="height:40%"></span><span style="height:70%"></span><span style="height:55%"></span>
              <span style="height:92%"></span><span style="height:64%"></span><span style="height:48%"></span>
            </div>
          </div>
          <div class="project-body">
            <h3>Harbor delivery board</h3>
            <p>Redesigned weekly planning for a 40-person product org. Cut status meetings from three to one.</p>
          </div>
        </a>
        <a class="project" href="#contact">
          <div class="project-visual" aria-hidden="true"><span class="chip">Fintech · 2025</span></div>
          <div class="project-body">
            <h3>Ledger onboarding</h3>
            <p>A five-step KYC flow that kept 22% more applicants through verification.</p>
          </div>
        </a>
        <a class="project" href="#contact">
          <div class="project-visual" aria-hidden="true"><span class="chip">Climate · 2024</span></div>
          <div class="project-body">
            <h3>Field notes map</h3>
            <p>A read-only map for researchers tagging sites without a GIS specialist in the room.</p>
          </div>
        </a>
        <a class="project" href="#contact">
          <div class="project-visual" aria-hidden="true"><span class="chip">System · 2024</span></div>
          <div class="project-body">
            <h3>Northbound UI kit</h3>
            <p>A Figma and CSS token set used across marketing, app, and docs.</p>
          </div>
        </a>
      </div>
    </section>

    <section class="wrap" id="about" aria-labelledby="about-heading">
      <div class="about-grid">
        <div>
          <h2 id="about-heading">About</h2>
          <p class="lede">I started in editorial design, then moved into product when I got tired of handing off mockups that never shipped. I still care about type, spacing, and whether a sentence earns its place.</p>
          <p>Most of my work is with teams of 8–40 people. I join for a defined problem, leave a system behind, and stay available for a monthly design review if you want it.</p>
        </div>
        <div class="portrait" role="img" aria-label="Placeholder portrait. Replace this block with a photo."></div>
      </div>
    </section>

    <section class="wrap" id="services" aria-labelledby="services-heading">
      <h2 id="services-heading">How we can work</h2>
      <div class="services">
        <article class="service">
          <h3>Product sprint</h3>
          <p>Two or four weeks on one problem: research, prototype, and a build-ready spec.</p>
        </article>
        <article class="service">
          <h3>Retainer</h3>
          <p>A set number of days each month for ongoing product and system work.</p>
        </article>
        <article class="service">
          <h3>Design critique</h3>
          <p>A recorded review of a flow you already have, with written notes you can share.</p>
        </article>
      </div>
    </section>

    <section class="wrap" id="notes" aria-labelledby="notes-heading">
      <h2 id="notes-heading">From collaborators</h2>
      <div class="quotes">
        <blockquote class="quote">
          <p>“Mira made the messy parts of our roadmap visible without turning the board into another status ritual.”</p>
          <footer>Sam Ori, Head of Product at Harbor</footer>
        </blockquote>
        <blockquote class="quote">
          <p>“We hired for screens and got a partner who asked better questions than we did.”</p>
          <footer>Leah Okonkwo, Founder at Field Notes</footer>
        </blockquote>
      </div>
    </section>

    <section class="wrap" id="contact" aria-labelledby="contact-heading">
      <div class="contact-grid">
        <div>
          <h2 id="contact-heading">Start a project</h2>
          <p class="lede">Tell me what you are building and when you need help. I reply within two working days.</p>
          <p>Prefer email? Use <a href="#contact-form">the form</a> — this demo does not send mail until you connect it.</p>
        </div>
        <form id="contact-form">
          <div>
            <label for="name">Name</label>
            <input id="name" name="name" type="text" autocomplete="name" required>
          </div>
          <div>
            <label for="email">Email</label>
            <input id="email" name="email" type="email" autocomplete="email" required>
          </div>
          <div>
            <label for="message">Project</label>
            <textarea id="message" name="message" required placeholder="What are you shipping, and what do you need from design?"></textarea>
          </div>
          <button class="btn btn-primary" type="submit">Send message</button>
          <p class="form-status" id="contact-status" role="status" aria-live="polite"></p>
        </form>
      </div>
    </section>
  </main>

  <footer class="site-footer">
    <div class="wrap footer-row">
      <p>© <span id="year"></span> Mira Vale. Portfolio template by Designyff.</p>
      <p><a href="#top">Back to top</a></p>
    </div>
  </footer>

  <script>
    document.getElementById('year').textContent = new Date().getFullYear();
    const toggle = document.querySelector('.nav-toggle');
    const nav = document.getElementById('site-nav');
    toggle.addEventListener('click', () => {
      const open = toggle.getAttribute('aria-expanded') === 'true';
      toggle.setAttribute('aria-expanded', String(!open));
      nav.classList.toggle('is-open', !open);
    });
    const form = document.getElementById('contact-form');
    const status = document.getElementById('contact-status');
    form.addEventListener('submit', (event) => {
      event.preventDefault();
      status.textContent = 'This demo form does not send data. Connect it to your email or form provider.';
      form.reset();
    });
  </script>
</body>
</html>
Cinematic Parallax Landing Page preview
Landing page HTML CSS JavaScript Premium $9

Cinematic Parallax Landing Page

A dark, cinematic architecture landing page with layered parallax, a horizontal project reel, and a commission form.

Creative Agency Landing Page preview
Landing page HTML CSS Free

Creative Agency Landing Page

A studio marketing page with case studies, capabilities, process, team, and a project inquiry form.

Restaurant Landing Page preview
Landing page HTML CSS Free

Restaurant Landing Page

A warm, responsive page for a neighborhood restaurant, with hours, a sample menu, and a reservation form.

Occasional updates with new UI components, page templates, and design resources.

Components and templates may be used in personal, commercial, and client projects. Do not redistribute or resell the original source. Terms of Service

Designyff © 2026 | Free UI components and page templates | Powered by  Tacko