Compare commits

...

22 Commits

Author SHA1 Message Date
ce54138492 feat(home): add Learning & Projects sections; polish copy\n\n- Learning: personal/warm tone, Hebrew/Israel/Aviation updates\n- Projects: paragraph style (no boxes)\n- Hebrew support: add Noto Sans Hebrew, RTL handling, Heb.vue component\n- Remove Heebo; update CSS and deps 2025-08-16 14:54:26 -06:00
eb40610536 hosted on vercel 2025-08-16 13:51:09 -06:00
dac81fc223 chore: add Justfile with Vercel deploy and preview using remote builds 2025-08-16 13:31:36 -06:00
460617e424 add Justfile 2025-08-16 13:29:03 -06:00
590a372417 add .omni.yaml 2025-08-16 13:25:00 -06:00
6b21292003 added fonts 2025-08-16 13:24:41 -06:00
89a75c94ca docs: document favicon generation; chore: add generate-favicon script and yarn task 2025-08-16 13:22:00 -06:00
7e4b13606c feat: regenerate multi-size favicon.ico from new SVG 2025-08-16 13:15:32 -06:00
2250721be3 Enable Vercel Speed Insights for Nuxt app 2025-08-16 11:15:48 -06:00
e22584b600 Use <Analytics /> from '@vercel/analytics/nuxt' and remove custom plugin 2025-08-16 10:08:32 -06:00
758df7627a Add Vercel Analytics via client plugin; use Yarn lockfile and remove npm lockfile 2025-08-16 10:03:37 -06:00
738f5a348a feat: add SVG favicon with lowercase 'b' using site font; configure head to use it with .ico fallback 2025-08-16 09:50:31 -06:00
eff9aa55cf chore: commit pending changes (wrap pages in NuxtLayout, update ignores) 2025-08-16 09:37:10 -06:00
9642bfba10 chore(vercel): set Nitro preset to vercel for deployment 2025-08-16 09:33:23 -06:00
3dbfa95a0c content(home): use concise wording for Home section 2025-08-16 09:30:43 -06:00
9321d70e3d content(home): tweak phrasing (remove articles before CTO/Chief Architect) 2025-08-16 09:27:06 -06:00
8b8c83d002 content(home): update title to Staff Software Engineer at Ramp 2025-08-16 09:26:20 -06:00
63e1df5d01 style(font): use @fontsource-variable/roboto-slab and set family to 'Roboto Slab Variable' 2025-08-16 09:22:46 -06:00
f0d3a8ed30 style(font): add Roboto Slab via Google Fonts and global CSS to match existing site 2025-08-16 09:15:15 -06:00
57634adf42 refactor(style): remove Nuxt UI, switch to Bulma-only, update layout and homepage 2025-08-16 09:10:23 -06:00
6fb19ff89c feat(site): add default layout and homepage content mirroring existing site using Nuxt UI 2025-08-16 09:06:17 -06:00
00dad9fd3f feat(ui): add @nuxt/ui module and config 2025-08-16 09:03:36 -06:00
16 changed files with 3102 additions and 733 deletions

1
.gitignore vendored
View File

@@ -22,3 +22,4 @@ logs
.env
.env.*
!.env.example
.vercel

2
.omni.yaml Normal file
View File

@@ -0,0 +1,2 @@
up:
- just

12
Justfile Normal file
View File

@@ -0,0 +1,12 @@
set shell := ["zsh", "-c"]
deploy:
vercel pull --yes --environment=production
vercel --prod --yes
preview:
vercel pull --yes --environment=preview
vercel --yes
dev:
yarn dev

View File

@@ -73,3 +73,17 @@ bun run preview
```
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
## Favicons
The SVG favicon is the source of truth: `public/favicon.svg`.
Generate a multi-size `favicon.ico` from the SVG using rsvg-convert + ImageMagick:
```bash
yarn favicons
```
Notes:
- ImageMagick on macOS can have issues loading arbitrary TTFs by file path (RenderFreetype errors). To avoid font lookup issues entirely, this project rasterizes the SVG directly using `rsvg-convert` and then packages the sizes into a single ICO using ImageMagick.
- If browsers fail to load webfonts in an external SVG, consider converting the “b” glyph to paths inside the SVG to guarantee pixel-identical rendering across formats.

View File

@@ -1,6 +1,15 @@
<template>
<div>
<NuxtRouteAnnouncer />
<NuxtWelcome />
<Analytics />
<SpeedInsights />
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</div>
</template>
<script setup lang="ts">
import { Analytics } from '@vercel/analytics/nuxt'
import { SpeedInsights } from '@vercel/speed-insights/nuxt'
</script>

23
app/assets/css/main.css Normal file
View File

@@ -0,0 +1,23 @@
/* Match brosner.com font */
@import url("@fontsource-variable/roboto-slab/index.css");
@import url("@fontsource/noto-sans-hebrew/400.css");
@import url("@fontsource/noto-sans-hebrew/600.css");
html, body {
font-family: "Roboto Slab Variable", Roboto, "Helvetica Neue", Arial, sans-serif;
font-optical-sizing: auto;
}
/* Ensure navbar icons remain white like the original */
.icon > svg > path {
fill: #fff;
}
.hebrew, :lang(he) {
font-family: "Noto Sans Hebrew", system-ui, sans-serif;
}
:lang(he) {
direction: rtl;
unicode-bidi: isolate;
}

File diff suppressed because one or more lines are too long

9
app/components/Heb.vue Normal file
View File

@@ -0,0 +1,9 @@
<template>
<span class="hebrew" lang="he" dir="rtl"><slot /></span>
</template>
<script setup lang="ts">
// no-op
</script>

49
app/layouts/default.vue Normal file
View File

@@ -0,0 +1,49 @@
<template>
<div>
<nav class="navbar">
<div class="container">
<div class="navbar-brand"></div>
<div class="navbar-menu">
<div class="navbar-end">
<div class="navbar-item">
<div class="field is-grouped">
<p class="control">
<a href="https://github.com/brosner" class="button is-dark" target="_blank" rel="noopener">
<span class="icon">
<svg version="1.1" role="presentation" width="17.82857142857143" height="20.8" viewBox="0 0 1536 1792" class="fa-icon" style="font-size: 1.3em;"><path d="M768 128q209 0 385.5 103t279.5 279.5 103 385.5q0 251-146.5 451.5t-378.5 277.5q-27 5-40-7t-13-30q0-3 0.5-76.5t0.5-134.5q0-97-52-142 57-6 102.5-18t94-39 81-66.5 53-105 20.5-150.5q0-119-79-206 37-91-8-204-28-9-81 11t-92 44l-38 24q-93-26-192-26t-192 26q-16-11-42.5-27t-83.5-38.5-85-13.5q-45 113-8 204-79 87-79 206 0 85 20.5 150t52.5 105 80.5 67 94 39 102.5 18q-39 36-49 103-21 10-45 15t-57 5-65.5-21.5-55.5-62.5q-19-32-48.5-52t-49.5-24l-20-3q-21 0-29 4.5t-5 11.5 9 14 13 12l7 5q22 10 43.5 38t31.5 51l10 23q13 38 44 61.5t67 30 69.5 7 55.5-3.5l23-4q0 38 0.5 88.5t0.5 54.5q0 18-13 30t-40 7q-232-77-378.5-277.5t-146.5-451.5q0-209 103-385.5t279.5-279.5 385.5-103zM291 1231q3-7-7-12-10-3-13 2-3 7 7 12 9 6 13-2zM322 1265q7-5-2-16-10-9-16-3-7 5 2 16 10 10 16 3zM352 1310q9-7 0-19-8-13-17-6-9 5 0 18t17 7zM394 1352q8-8-4-19-12-12-20-3-9 8 4 19 12 12 20 3zM451 1377q3-11-13-16-15-4-19 7t13 15q15 6 19-6zM514 1382q0-13-17-11-16 0-16 11 0 13 17 11 16 0 16-11zM572 1372q-2-11-18-9-16 3-14 15t18 8 14-14z"></path></svg>
</span>
</a>
</p>
<p class="control">
<a href="https://www.threads.net/@brosner" class="button is-info" target="_blank" rel="noopener">
<span class="icon">
<svg version="1.1" role="presentation" width="19.314285714285717" height="20.8" viewBox="0 0 1664 1792" class="fa-icon" style="font-size: 1.3em;"><path d="M1620 408q-67 98-162 167 1 14 1 42 0 130-38 259.5t-115.5 248.5-184.5 210.5-258 146-323 54.5q-271 0-496-145 35 4 78 4 225 0 401-138-105-2-188-64.5t-114-159.5q33 5 61 5 43 0 85-11-112-23-185.5-111.5t-73.5-205.5v-4q68 38 146 41-66-44-105-115t-39-154q0-88 44-163 121 149 294.5 238.5t371.5 99.5q-8-38-8-74 0-134 94.5-228.5t228.5-94.5q140 0 236 102 109-21 205-78-37 115-142 178 93-10 186-50z"></path></svg>
</span>
</a>
</p>
</div>
</div>
</div>
</div>
</div>
</nav>
<main>
<slot />
</main>
<footer class="footer">
<div class="content is-small has-text-centered">
<p>
Site built with <a href="https://nuxt.com" target="_blank">Nuxt</a> and <a href="https://bulma.io" target="_blank">Bulma</a>. Hosted on <a href="https://vercel.com" target="_blank">Vercel</a>.
</p>
</div>
</footer>
</div>
</template>
<script setup lang="ts">
// no-op
</script>

78
app/pages/index.vue Normal file
View File

@@ -0,0 +1,78 @@
<template>
<div id="app" class="hello wrapper">
<section class="section">
<div class="container">
<h1 class="title is-1">Brian Rosner</h1>
</div>
</section>
<section class="section">
<div class="container">
<div class="columns">
<div class="column is-two-thirds content is-large">
<h2>Work</h2>
<p>
I am a Staff Software Engineer at
<a href="https://ramp.com/" target="_blank">Ramp</a>
working on the infrastructure team.
</p>
<p>
Previously, I was a Senior Software Engineer at Reddit, CTO at Gemr and Chief Architect at Eldarion.
</p>
<h2>Home</h2>
<p>
I live in <a href="https://en.wikipedia.org/wiki/Denver" target="_blank">Denver</a>,
<a href="https://en.wikipedia.org/wiki/Colorado" target="_blank">Colorado</a>. Im married to Hannah YabroveRosner. We have two kids, Eddie and Dylan, and three pets: Minnie and Jack (dogs) and Lily (cat).
</p>
</div>
</div>
</div>
</section>
<section class="section" id="learning">
<div class="container">
<div class="columns">
<div class="column is-two-thirds content is-large">
<h2>Learning</h2>
<p>These are some topics I am actively exploring:</p>
<h3 class="title is-4">Aviation</h3>
<p>I learn aviation through flight simsmostly MSFS 2020 (XPlane nostalgia is real). Im drawn to airliners; the A350 and 757 are my favorites.</p>
<h3 class="title is-4">Israel</h3>
<p>I visited Israel for the first time in December 2024. Im reconnecting with my familys Jewish roots, and I left with a deep appreciation for the country and its people.</p>
<h3 class="title is-4">Hebrew</h3>
<p><Heb>אני לומד עברית</Heb></p>
<p>Id love to be fluent. Im a little embarrassed that most of my study is Duolingo right nowbut it keeps me consistentand I lean on <a href="https://www.pealim.com/">Pealim</a> for vocab and verbs.</p>
</div>
</div>
</div>
</section>
<section class="section" id="projects">
<div class="container">
<div class="columns">
<div class="column is-two-thirds content is-large">
<h2>Projects</h2>
<h3 class="title is-4">Project Name</h3>
<p>Short description of what it is, why it exists, and your role.</p>
<h3 class="title is-4">Project Name</h3>
<p>Short description of what it is, why it exists, and your role.</p>
<h3 class="title is-4">Project Name</h3>
<p>Short description of what it is, why it exists, and your role.</p>
</div>
</div>
</div>
</section>
</div>
</template>
<script setup lang="ts">
definePageMeta({ layout: 'default' })
</script>

View File

@@ -1,5 +1,18 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
compatibilityDate: '2025-07-15',
devtools: { enabled: true }
devtools: { enabled: true },
modules: [],
css: ['bulma/css/bulma.min.css', '@/assets/css/main.css'],
nitro: {
preset: 'vercel'
},
app: {
head: {
link: [
{ rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' },
{ rel: 'alternate icon', type: 'image/x-icon', href: '/favicon.ico' }
]
}
}
})

View File

@@ -7,10 +7,17 @@
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"favicons": "bash tools/generate-favicon.sh",
"postinstall": "nuxt prepare"
},
"dependencies": {
"@fontsource-variable/roboto-slab": "^5.2.6",
"@fontsource/noto-sans-hebrew": "^5.2.6",
"@vercel/analytics": "^1.5.0",
"@vercel/speed-insights": "^1.2.0",
"bulma": "^1.0.4",
"nuxt": "^4.0.3",
"typescript": "^5.6.3",
"vue": "^3.5.18",
"vue-router": "^4.5.1"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 31 KiB

17
public/favicon.svg Normal file
View File

@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
<defs>
<style>
.bg { fill: #111111; }
.txt {
fill: #ffffff;
font-family: "Roboto Slab Variable", Roboto, "Helvetica Neue", Arial, sans-serif;
font-weight: 700;
font-size: 88px;
}
</style>
</defs>
<rect class="bg" x="0" y="0" width="128" height="128" rx="24" ry="24" />
<text class="txt" x="50%" y="50%" dominant-baseline="central" text-anchor="middle">b</text>
</svg>

After

Width:  |  Height:  |  Size: 499 B

40
tools/generate-favicon.sh Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/env bash
set -euo pipefail
# Generates a multi-size favicon.ico from public/favicon.svg
# Dependencies:
# - rsvg-convert (from librsvg)
# - ImageMagick (magick)
# macOS install:
# brew install librsvg imagemagick
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
SVG_PATH="${ROOT_DIR}/public/favicon.svg"
OUT_ICO_PATH="${ROOT_DIR}/public/favicon.ico"
if ! command -v rsvg-convert >/dev/null 2>&1; then
echo "ERROR: rsvg-convert not found. Install with: brew install librsvg" >&2
exit 1
fi
if ! command -v magick >/dev/null 2>&1; then
echo "ERROR: ImageMagick (magick) not found. Install with: brew install imagemagick" >&2
exit 1
fi
tmp_dir="$(mktemp -d)"
cleanup() { rm -rf "${tmp_dir}"; }
trap cleanup EXIT
sizes=(16 32 48 64)
pngs=()
for s in "${sizes[@]}"; do
out_png="${tmp_dir}/favicon-${s}.png"
rsvg-convert -w "${s}" -h "${s}" "${SVG_PATH}" -o "${out_png}"
pngs+=("${out_png}")
done
magick "${pngs[@]}" "${OUT_ICO_PATH}"
echo "Generated ${OUT_ICO_PATH}"

1487
yarn.lock

File diff suppressed because it is too large Load Diff