Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
3ef3b63
docs: document field notes portfolio
SimpleCaci Jul 14, 2026
1c039d0
feat(portfolio): build applied systems field notes
SimpleCaci Jul 14, 2026
06df69f
feat(portfolio): build applied systems field notes
SimpleCaci Jul 14, 2026
f911983
feat(portfolio): build applied systems field notes
SimpleCaci Jul 14, 2026
963d820
feat(portfolio): build applied systems field notes
SimpleCaci Jul 14, 2026
647e012
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
a1202a2
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
5ea7f2d
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
ca37c54
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
3cbabcd
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
9e282b0
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
dad7e6c
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
70f09ce
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
b04e621
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
1d4cf15
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
eebed06
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
5fe3847
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
1bed771
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
40773df
feat(portfolio): complete editorial redesign
SimpleCaci Jul 15, 2026
cb17b4a
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
9eb53d7
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
412f799
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
748b76b
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
8992eb2
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
59905e8
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
f52c5e0
refactor(portfolio): remove unused interactions
SimpleCaci Jul 15, 2026
b09c859
test(portfolio): add static validation
SimpleCaci Jul 15, 2026
9bd099a
docs(portfolio): add crawl metadata
SimpleCaci Jul 15, 2026
85e370e
test(portfolio): add static validation
SimpleCaci Jul 15, 2026
125fcf8
docs(portfolio): add crawl metadata
SimpleCaci Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions .github/workflows/static-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Static checks

on:
pull_request:
push:
branches: [main]

permissions:
contents: read

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Validate pages, assets, links, and JSON
run: python scripts/validate_site.py

90 changes: 24 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,93 +1,51 @@
# Personal Portfolio

A personality-forward static portfolio for my projects, writing, and contact information.
Quinton's maintained public portfolio: a handcrafted static site about applied software systems, product thinking, and learning through projects.

The site uses a playful rope-and-cow visual theme while organizing project data separately from presentation code. It is intended to become the main public portfolio for SimpleCaci.
## Direction

> **Status:** active work in progress. The main pages, styling, project data, transitions, and custom cursor are present, but several sections still contain placeholder copy and links.
The design combines a technical field notebook with a restrained rope-and-ranch motif. It keeps the original cow mascot, but core navigation and content no longer depend on a custom cursor, animation, or JavaScript.

## Pages and features
The featured work spans geospatial mission data, computer vision, desktop product design, handwriting OCR, voice interaction, and browser-based pose estimation. Project status language is intentionally specific: a repository link is not presented as a verified deployment or demo.

- home page with animated hero and current-project cards
- project gallery populated from `data/projects.json`
- writings page
- contact page
- custom cursor, rope interaction, and page transitions
- responsive CSS structure and local visual assets
## Pages

- `index.html` - homepage, selected work, method, about, and contact callout
- `projects/` - JSON-backed project field notes with no-JavaScript and load-failure fallbacks
- `writings/` - honest archive placeholder until finished writing exists
- `contacts/` - verified public email and GitHub links

## Technology

- semantic HTML
- CSS
- vanilla JavaScript
- JSON-backed project/profile/writing data
- static hosting compatible

## Project structure

```text
index.html home
projects/ project gallery
writings/ writing links
contacts/ contact page
data/ profile, project, and writing content
js/ interactions and data rendering
css/ shared and page-specific styles
assets/ icons, project art, and visual theme
```
- responsive CSS with custom properties
- small progressive-enhancement JavaScript
- JSON-backed project content
- dependency-free static validation

## Run locally

No build step is required. Use a local server so JSON requests and relative links behave consistently:
No build step is required. Serve the repository root so JSON and relative paths behave like GitHub Pages:

```bash
python -m http.server 8000
```

Open [http://localhost:8000](http://localhost:8000).

## Content updates

Update portfolio content in:

- `data/profile.json`
- `data/projects.json`
- `data/writings.json`
Open <http://localhost:8000> and visit every public page.

Keep claims, project status, screenshots, and links accurate. Do not add placeholder awards, metrics, or deployments.
## Validate

## Validation status

No automated tests or CI workflow currently exist. Before publishing, manually check:

- every navigation and project link
- desktop and mobile layouts
- keyboard focus and reduced-motion behavior
- image alternative text
- missing JSON/image failure states
- contact details and external links
- the site with JavaScript disabled or unavailable

## Known unfinished work
```bash
python scripts/validate_site.py
```

- the home page contains generic introduction/project copy
- writing entries include example placeholders
- the contact page references an external image
- navigation/footer sections are incomplete
- metadata and page titles are generic
- no deployment workflow or custom-domain documentation exists
- the custom cursor and animation effects need accessibility fallbacks
The script checks page structure, local links and images, alternative text, external-tab safety, obvious placeholders or encoding corruption, and the project JSON schema. GitHub Actions runs the same check for pull requests and pushes to `main`.

## Roadmap
## Deployment

- replace placeholder copy with a concise developer narrative
- feature the strongest verified projects and case studies
- add consistent project screenshots
- finish navigation and footer
- add reduced-motion and keyboard-friendly behavior
- validate and deploy the static site
- connect the profile README to the finished portfolio
The repository is associated with <https://simplecaci.github.io/personal-portfolio/>. Confirm the GitHub Pages source and live response after merging; the repository does not contain a custom deployment action.

## Authorship

Designed and built by [SimpleCaci](https://github.com/SimpleCaci). A project license has not yet been selected.

124 changes: 7 additions & 117 deletions contacts/index.html
Original file line number Diff line number Diff line change
@@ -1,122 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="Contact Quinton" />
<title>Contact</title>

<link rel="icon" type="image/x-icon" href="../assets/icons/temp.ico" />

<!-- styles -->
<link rel="stylesheet" href="../css/global.css" />
<link rel="stylesheet" href="../css/index.css" />
<link rel="stylesheet" href="../css/contacts.css" />
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="description" content="Contact Quinton about software projects, technical ideas, or collaboration."><meta name="theme-color" content="#f3eddf"><meta property="og:type" content="website"><meta property="og:title" content="Contact - Quinton"><meta property="og:description" content="A direct way to reach Quinton or explore his public code."><meta name="twitter:card" content="summary"><title>Contact - Quinton</title><link rel="icon" href="../assets/icons/temp.ico"><link rel="stylesheet" href="../css/global.css"><link rel="stylesheet" href="../css/contacts.css">
</head>

<body>
<header>
<nav>
<!-- navigation -->
</nav>
</header>

<main>
<div id="cursor" aria-hidden="true"></div>
<div id="wipe" aria-hidden="true"></div>

<div class="top-bar-section">
<img
class="top-bar-image"
src="../assets/images/topImage.png"
alt="Top Bar Image"
loading="lazy"
decoding="async"
/>
<h1 class="page-title">/CONTACT</h1>
</div>

<section class="contacts">
<h1>Reach Out</h1>

<p class="contacts-intro">
Minimal. Direct. Human.
</p>

<!-- Primary contact cards -->
<div class="contact-cards">
<div class="contact-card">
<div class="contact-label">email</div>
<a
class="contact-link"
href="mailto:simplesimpleemailemail@gmail.com"
>
simplesimpleemailemail@gmail.com
</a>
<div class="contact-sub">best for collabs & opportunities</div>
</div>

<div class="contact-card">
<div class="contact-label">github</div>
<a
class="contact-link"
href="https://github.com/SimpleCaci"
target="_blank"
rel="noopener"
>
github.com/SimpleCaci
</a>
<div class="contact-sub">projects, experiments, code</div>
</div>
</div>

<!-- Extra info (light, optional but nice) -->
<div class="contact-meta">
<div class="meta-item">
<span class="meta-title">response time</span>
<span class="meta-value">1–3 days</span>
</div>
<div class="meta-item">
<span class="meta-title">timezone</span>
<span class="meta-value">PST</span>
</div>
<div class="meta-item">
<span class="meta-title">status</span>
<span class="meta-value">open to ideas</span>
</div>
</div>

<!-- Personality touch -->
<p class="contacts-small">
cow-approved communication only.
</p>

<img
class="work-in-progress-image"
src="https://images.fineartamerica.com/images/artworkimages/mediumlarge/1/cow-eating-fresh-grass-matthias-hauser.jpg"
alt="Cow QA"
loading="lazy"
decoding="async"
/>
</section>

<img
id="rope"
src="../assets/images/rope.png"
onerror="this.src='https://www.dummyimage.com/30x500/000/fff';"
draggable="false"
alt=""
aria-hidden="true"
/>
</main>

<footer>
<!-- footer -->
</footer>

<script src="../js/transition.js" defer></script>
<script src="../js/rope.js" defer></script>
<script src="../js/cursor.js" defer></script>
<script src="../js/titleAnimation.js" defer></script>
</body>
</html>
<a class="skip-link" href="#main">Skip to content</a>
<header class="site-header"><a class="wordmark" href="../index.html"><span class="wordmark-mark" aria-hidden="true">Q/</span><span>Quinton</span></a><nav class="desktop-nav" aria-label="Primary navigation"><a href="../index.html">Home</a><a href="../projects/index.html">Projects</a><a href="../writings/index.html">Writing</a><a href="../index.html#about">About</a><a href="./index.html" aria-current="page">Contact</a><a class="nav-github" href="https://github.com/SimpleCaci" target="_blank" rel="noopener noreferrer">GitHub ↗</a></nav><details class="mobile-nav"><summary aria-label="Open navigation">Menu</summary><nav class="mobile-nav-menu" aria-label="Mobile navigation"><a href="../index.html">Home</a><a href="../projects/index.html">Projects</a><a href="../writings/index.html">Writing</a><a href="../index.html#about">About</a><a href="./index.html" aria-current="page">Contact</a><a href="https://github.com/SimpleCaci" target="_blank" rel="noopener noreferrer">GitHub ↗</a></nav></details></header>
<main id="main" class="page-shell"><section class="contact-intro"><div><p class="eyebrow">Contact / Open channel</p><h1>Talk to a human, not a funnel.</h1></div><p>If you want to discuss a project, a technical idea, or something useful that should exist, email is the simplest route. Public code and experiments live on GitHub.</p></section><hr class="rope-rule"><section class="contact-layout" aria-labelledby="contact-options"><div><h2 id="contact-options" class="visually-hidden">Contact options</h2><div class="contact-list"><article class="contact-card"><h2>Email</h2><p>Best for project conversations and collaboration ideas.</p><a href="mailto:simplesimpleemailemail@gmail.com">simplesimpleemailemail@gmail.com</a></article><article class="contact-card"><h2>GitHub</h2><p>Repositories, experiments, documentation, and current technical work.</p><a href="https://github.com/SimpleCaci" target="_blank" rel="noopener noreferrer">github.com/SimpleCaci ↗</a></article></div><p class="privacy-note">This page uses only contact information that was already public in the portfolio repository. There is no tracking script or third-party contact form.</p></div><figure class="contact-mascot"><img src="../assets/images/cow.png" alt="" width="220" height="220"><figcaption>Cow-approved communication</figcaption></figure></section></main>
<footer class="site-footer"><p class="footer-note">Minimal. Direct. Human.</p><nav class="footer-nav" aria-label="Footer navigation"><a href="../index.html">Home</a><a href="../projects/index.html">Projects</a><a href="../writings/index.html">Writing</a><a href="./index.html">Contact</a><a href="https://github.com/SimpleCaci" target="_blank" rel="noopener noreferrer">GitHub ↗</a><span>&copy; <span data-current-year>2026</span></span></nav></footer><script src="../js/main.js" defer></script>
</body></html>

Loading
Loading