mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-11-02 13:12:50 +00:00
docs(readme): redesign README with animated SVG diagrams
Replace the ASCII workflow diagram with animated SVGs built from Pip's palette: a hero where Pip flies an application to its destination, the 69/20/1 application funnel as envelopes, the six-command route, and the /apply draft-review loop. Long reference material moves into collapsible sections; all content and the anchors SETUP.md links to are kept.
This commit is contained in:
1 parent
4b109c20c3
commit
e61fb6ea8b
5 files changed
+445
-114
No files matched your search
@@ -1,20 +1,39 @@
|
||||
<p align="center">
|
||||
<img src="assets/mascot/pip_flight_loop.gif" alt="Pip, the courier bird" width="200">
|
||||
<img src="assets/readme/hero.svg" alt="AI Job Search. Pip the courier bird carries an application along a flight path to its destination. The job search that runs on your machine." width="100%">
|
||||
</p>
|
||||
|
||||
# AI Job Search
|
||||
|
||||
*The job search that runs on your machine.*
|
||||
<p align="center">
|
||||
<a href="https://github.com/ai-job-search-dev/ai-job-search/actions/workflows/ci.yml"><img src="https://github.com/ai-job-search-dev/ai-job-search/actions/workflows/ci.yml/badge.svg" alt="CI" height="20"></a>
|
||||
|
||||
<a href="https://claude.com/claude-code"><img src="https://img.shields.io/badge/built_on-Claude_Code-2A9D8F?style=flat" alt="Built on Claude Code" height="20"></a>
|
||||
|
||||
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-2A9D8F?style=flat" alt="MIT license" height="20"></a>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://trendshift.io/repositories/43622?utm_source=trendshift-badge&utm_medium=badge&utm_campaign=badge-trendshift-43622" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/trendshift/repositories/43622/daily" alt="MadsLorentzen%2Fai-job-search | Trendshift" width="250" height="55"/></a>
|
||||
</p>
|
||||
|
||||
[](https://github.com/ai-job-search-dev/ai-job-search/actions/workflows/ci.yml)
|
||||
<p align="center">
|
||||
An AI-powered job application framework built on <a href="https://claude.com/claude-code">Claude Code</a>.<br>
|
||||
Fork it, fill in your profile, and let Claude evaluate job postings, tailor your CV,<br>
|
||||
write cover letters, and prepare you for interviews.
|
||||
</p>
|
||||
|
||||
An AI-powered job application framework built on [Claude Code](https://claude.com/claude-code). Fork it, fill in your profile, and let Claude evaluate job postings, tailor your CV, write cover letters, and prepare you for interviews.
|
||||
<p align="center">
|
||||
<a href="#quick-start"><b>Quick start</b></a>
|
||||
|
||||
<a href="#commands"><b>Commands</b></a>
|
||||
|
||||
<a href="#how-apply-works"><b>How /apply works</b></a>
|
||||
|
||||
<a href="#customization"><b>Customization</b></a>
|
||||
|
||||
<a href="SETUP.md"><b>Setup guide</b></a>
|
||||
</p>
|
||||
|
||||
> Note: This is an independent open-source project and is not affiliated with, endorsed by, sponsored by, or maintained by Anthropic. Anthropic and Claude Code are referenced only to describe the toolchain this workflow uses.
|
||||
> [!NOTE]
|
||||
> This is an independent open-source project and is not affiliated with, endorsed by, sponsored by, or maintained by Anthropic. Anthropic and Claude Code are referenced only to describe the toolchain this workflow uses.
|
||||
>
|
||||
> This project has **no affiliated cryptocurrency, token, or paid sponsorship program**. Anything claiming otherwise is unauthorized and should be treated as a scam. The only ways to support the project are the Ko-fi link below and contributing on GitHub.
|
||||
|
||||
@@ -22,6 +41,10 @@ An AI-powered job application framework built on [Claude Code](https://claude.co
|
||||
|
||||
I'm a geophysicist by training. When my position was cut in late 2025, I built this framework to run my own job search - the same `/scrape`, `/apply`, and `/interview` workflow in this repo, used weekly, on my own career. I was upfront about it with every employer I spoke to, and instead of counting against me, it usually sparked a genuine technical conversation.
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/readme/letters.svg" alt="69 envelopes for 69 tailored applications. 20 of them light up as first interviews, and one is sealed as the signed contract." width="100%">
|
||||
</p>
|
||||
|
||||
Sixty-nine tailored applications, twenty first interviews, and one signed contract later, I started as an AI engineer in June 2026. People kept asking whether this actually works. It got me hired. Now it's yours.
|
||||
|
||||
*The longer version, including the full application funnel, is on [LinkedIn](https://www.linkedin.com/in/mads-lorentzen/).*
|
||||
@@ -39,38 +62,39 @@ Sixty-nine tailored applications, twenty first interviews, and one signed contra
|
||||
|
||||
## What this is
|
||||
|
||||
A structured workflow that turns Claude Code into a full-stack job application assistant. The core workflow (self-profiling, fit evaluation, and the drafter-reviewer application pipeline) is **language- and country-agnostic**. The job portal search skills are built for the Danish market (Jobindex, Jobnet, Akademikernes Jobbank, etc.), but the pattern is designed to be swapped for your local job boards.
|
||||
A structured workflow that turns Claude Code into a full-stack job application assistant. Six commands carry you from an empty profile to a tracked result:
|
||||
|
||||
```
|
||||
/setup /scrape /apply <url>
|
||||
| | |
|
||||
v v v
|
||||
Fill in Search job Evaluate fit
|
||||
your profile portals Score & recommend
|
||||
| | |
|
||||
v v v
|
||||
Profile Present matches Draft CV + Cover Letter
|
||||
files ready with fit ratings (LaTeX, tailored)
|
||||
| |
|
||||
v v
|
||||
Pick a match Reviewer agent critiques
|
||||
-> /apply -> Revise -> Final output
|
||||
```
|
||||
<p align="center">
|
||||
<img src="assets/readme/route.svg" alt="The workflow in order: /setup builds your profile, /scrape finds new postings, /rank shortlists the fits, /apply tailors a CV and cover letter, /interview preps every round, /outcome tracks each result." width="100%">
|
||||
</p>
|
||||
|
||||
The core workflow (self-profiling, fit evaluation, and the drafter-reviewer application pipeline) is **language- and country-agnostic**. The job portal search skills are built for the Danish market (Jobindex, Jobnet, Akademikernes Jobbank, etc.), but the pattern is designed to be swapped for your local job boards.
|
||||
|
||||
The framework encodes career guidance best practices, including structured evaluation criteria, forward-looking cover letter framing, and optional salary benchmarking.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Claude Code](https://claude.com/claude-code) (CLI). Claude Code has no free tier: you need a Claude Pro/Max/Team subscription or Anthropic API credits (pay-per-token, usually cheaper for occasional use). Using a different agent tool (Codex, Antigravity, Gemini CLI)? Start at [`AGENTS.md`](AGENTS.md) - the portal search skills work there out of the box, and [community forks](https://github.com/ai-job-search-dev/ai-job-search/discussions/78) adapt the full workflow.
|
||||
- Python 3.10+
|
||||
- [Bun](https://bun.sh) (for job search CLI tools)
|
||||
- LaTeX distribution with `lualatex` and `xelatex`: [TeX Live](https://tug.org/texlive/), [MacTeX](https://tug.org/mactex/), [TinyTeX](https://yihui.org/tinytex/), or [MiKTeX](https://miktex.org/). The CV compiles with `lualatex` (pdflatex often fails on modern MiKTeX installs with `fontawesome5` font-expansion errors); the cover letter compiles with `xelatex` because `cover.cls` requires `fontspec`. If using a minimal TeX install such as TinyTeX or BasicTeX, install the extra packages listed in [SETUP.md](SETUP.md#minimal-tex-install-tinytexbasictex).
|
||||
- Optional: `pip install pypdf` for `/apply`'s ATS parseability check (BSD; no Poppler required). Poppler `pdftotext` remains a fallback (macOS: `brew install poppler`, Debian/Ubuntu: `apt install poppler-utils`, Windows: `choco install poppler`). If both are missing, the check degrades to a visual keyword review.
|
||||
|
||||
## Quick start
|
||||
|
||||
> 🎥 **Prefer to see it in action first?** [The Next New Thing did a hands-on walkthrough](https://www.youtube.com/watch?v=HoVxjMNFYv4) of how the workflow is actually used, from setup to a finished application (recorded August 2026 - commands may have evolved since).
|
||||
|
||||
### What you need
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **[Claude Code](https://claude.com/claude-code)** | The CLI. No free tier: a Claude Pro/Max/Team subscription or Anthropic API credits (pay-per-token, usually cheaper for occasional use). |
|
||||
| **Python 3.10+** | For the tools in `tools/`. |
|
||||
| **[Bun](https://bun.sh)** | Runs the job search CLI tools. |
|
||||
| **LaTeX** | A distribution with `lualatex` and `xelatex`: [TeX Live](https://tug.org/texlive/), [MacTeX](https://tug.org/mactex/), [TinyTeX](https://yihui.org/tinytex/), or [MiKTeX](https://miktex.org/). |
|
||||
| **pypdf** *(optional)* | `pip install pypdf` for `/apply`'s ATS parseability check. |
|
||||
|
||||
<details>
|
||||
<summary>Fine print: other agents, LaTeX engines, PDF text extraction</summary>
|
||||
|
||||
- **Using a different agent tool** (Codex, Antigravity, Gemini CLI)? Start at [`AGENTS.md`](AGENTS.md) - the portal search skills work there out of the box, and [community forks](https://github.com/ai-job-search-dev/ai-job-search/discussions/78) adapt the full workflow.
|
||||
- **LaTeX engines.** The CV compiles with `lualatex` (pdflatex often fails on modern MiKTeX installs with `fontawesome5` font-expansion errors); the cover letter compiles with `xelatex` because `cover.cls` requires `fontspec`. If using a minimal TeX install such as TinyTeX or BasicTeX, install the extra packages listed in [SETUP.md](SETUP.md#minimal-tex-install-tinytexbasictex).
|
||||
- **PDF text extraction.** `pypdf` is BSD-licensed and needs no Poppler. Poppler `pdftotext` remains a fallback (macOS: `brew install poppler`, Debian/Ubuntu: `apt install poppler-utils`, Windows: `choco install poppler`). If both are missing, the check degrades to a visual keyword review.
|
||||
|
||||
</details>
|
||||
|
||||
### 1. Fork and clone
|
||||
|
||||
```bash
|
||||
@@ -93,10 +117,15 @@ cd ai-job-search
|
||||
python3 tools/install_portal_clis.py # Windows: python tools\install_portal_clis.py
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>What the installer does</summary>
|
||||
|
||||
It runs `bun install` in every portal CLI under `.agents/skills/*/cli/` - discovered, not listed, so a portal you add with `/add-portal` or copy from another fork is included on a fresh clone. A CLI whose `package.json` declares an install-time lifecycle script is skipped and reported rather than run. `--dry-run` shows what it would install.
|
||||
|
||||
For `linkedin-search` and `freehire-search` the install is optional: both have zero runtime dependencies and run with plain `bun`; `bun install` only pulls TypeScript dev types.
|
||||
|
||||
</details>
|
||||
|
||||
### 3. Set up your profile
|
||||
|
||||
```bash
|
||||
@@ -129,11 +158,32 @@ If the URL can't be fetched (some job portals block automated access), you can p
|
||||
|
||||
This runs the full workflow: evaluate fit, draft CV + cover letter, review with a second agent, revise, and present the final output. The posting passes a deterministic integrity gate first (hidden text, invisible characters, instruction-shaped lines, hidden links), and its one-line verdict opens the evaluation; the agents that fetch and review read-only.
|
||||
|
||||
Postings are treated as untrusted input (the workflow follows no instructions embedded in them and fetches no links from their body), but agentic defenses are instruction-level, not a sandbox - on an unfamiliar job board, skim what was fetched and written before you hit send. Details in [SECURITY.md](SECURITY.md).
|
||||
> [!WARNING]
|
||||
> Postings are treated as untrusted input (the workflow follows no instructions embedded in them and fetches no links from their body), but agentic defenses are instruction-level, not a sandbox - on an unfamiliar job board, skim what was fetched and written before you hit send. Details in [SECURITY.md](SECURITY.md).
|
||||
|
||||
## Other commands
|
||||
## Commands
|
||||
|
||||
`/setup`, `/scrape`, and `/apply` form the core workflow. Ten more commands extend it once your profile is in place:
|
||||
`/setup`, `/scrape`, and `/apply` form the core workflow. Ten more commands extend it once your profile is in place.
|
||||
|
||||
| Command | What it does |
|
||||
|---|---|
|
||||
| **`/setup`** | Builds your profile from your documents, a pasted CV, or an interview |
|
||||
| **`/scrape`** | Searches job portals for postings that match your profile |
|
||||
| **`/apply`** | Evaluates fit, then drafts, reviews, and compiles a tailored CV and cover letter |
|
||||
| `/rank` | Batch-scores a scrape into a ranked shortlist |
|
||||
| `/interview` | Builds a stage-specific prep pack and runs a mock interview |
|
||||
| `/outcome` | Records results, archives what you sent, and drafts follow-ups |
|
||||
| `/gmail-sync` | Proposes application status updates from your Gmail |
|
||||
| `/notion-sync` | Publishes a read-only view of your pipeline to Notion |
|
||||
| `/html-report` | Generates an offline dashboard of your applications |
|
||||
| `/expand` | Adds competencies found in your public profiles and course syllabi |
|
||||
| `/upskill` | Maps your skill gaps and builds a learning plan |
|
||||
| `/add-template` | Registers your own CV or cover letter template |
|
||||
| `/add-portal` | Generates a search skill for a job board in your market |
|
||||
| `/reset` | Wipes profile data or documents - see [Starting over](#starting-over) |
|
||||
|
||||
<details>
|
||||
<summary><b>Full command reference</b></summary>
|
||||
|
||||
- **`/interview`** preps you for a scheduled interview on a tracked application. It builds a stage-specific prep pack from the application's archive (the exact posting, the CV and cover letter the interviewer actually read, feedback recorded from earlier rounds), researches the company and interviewers with a verify-before-use rule, maps likely questions to your STAR examples, and offers a mock interview following the roleplay protocol in `07-interview-prep.md`. Gaps get honest bridge answers, never invented experience.
|
||||
- **`/outcome`** records what happened to an application - interview stages, offers, rejections, silence. It archives the submitted CV, cover letter, and posting text into `documents/applications/<company>_<role>/`, keeps `outcome.md` in the format `/setup` Path A parses, and updates the tracker. It also owns the stretch before there is an outcome to record: `/outcome followup` surfaces open applications that have gone quiet (default 10 days), drafts a short channel-appropriate follow-up in your writing style using only claims from the materials you already submitted (drafts only, never sends; at most twice per application), and offers a thank-you note in the same turn an interview stage is recorded. Once a few applications resolve, it points you back to `/setup` to calibrate the fit framework from what actually got interviews.
|
||||
@@ -146,87 +196,14 @@ Postings are treated as untrusted input (the workflow follows no instructions em
|
||||
- **`/add-template`** registers your own CV or cover letter template (LaTeX, Typst, or another toolchain) in place of the stock ones. It captures the template's instructions (source extension, compile command, fonts, style rules, page limit), runs a mandatory test compile, and wires the template into `/apply`. See [Custom templates](#custom-templates) below.
|
||||
- **`/add-portal`** generates a job-portal search skill for a job board in your market. It investigates the portal (search URL pattern, result structure, access rules), scaffolds the CLI skill from the same structure as the shipped ones, and test-runs a live query before registering. See [Job search tools](#job-search-tools) below.
|
||||
|
||||
`/reset` is also available, see [Starting over](#starting-over) below.
|
||||
|
||||
## File structure
|
||||
|
||||
```
|
||||
ai-job-search/
|
||||
├── CLAUDE.md # Main candidate profile + workflow rules
|
||||
├── .claude/
|
||||
│ ├── commands/
|
||||
│ │ ├── apply.md # /apply workflow (drafter-reviewer)
|
||||
│ │ ├── setup.md # /setup onboarding (documents folder, CV import, or interview)
|
||||
│ │ ├── expand.md # /expand competency enrichment from documents and online presence
|
||||
│ │ ├── add-template.md # /add-template register custom templates (LaTeX, Typst, ...)
|
||||
│ │ ├── add-portal.md # /add-portal generate a job-portal search skill for your market
|
||||
│ │ ├── rank.md # /rank triage scraped jobs into a ranked shortlist
|
||||
│ │ ├── outcome.md # /outcome record application results, archive materials
|
||||
│ │ ├── gmail-sync.md # /gmail-sync auto-detect application status from Gmail
|
||||
│ │ ├── interview.md # /interview stage-specific prep pack + mock interview
|
||||
│ │ ├── html-report.md # /html-report generate application tracker dashboard
|
||||
│ │ ├── notion-sync.md # /notion-sync one-way pipeline view in a Notion database
|
||||
│ │ └── reset.md # /reset wipe profile data or documents folder
|
||||
│ ├── skills/
|
||||
│ │ ├── job-application-assistant/ # Core application skill
|
||||
│ │ │ ├── SKILL.md # Skill definition
|
||||
│ │ │ ├── 01-candidate-profile.md # Your education, experience, skills
|
||||
│ │ │ ├── 02-behavioral-profile.md# PI/DISC/personality assessment
|
||||
│ │ │ ├── 03-writing-style.md # Tone, structure, do's and don'ts
|
||||
│ │ │ ├── 04-job-evaluation.md # Scoring framework for job fit
|
||||
│ │ │ ├── 05-cv-templates.md # LaTeX CV structure + tailoring rules
|
||||
│ │ │ ├── 06-cover-letter-templates.md # LaTeX cover letter templates
|
||||
│ │ │ └── 07-interview-prep.md # STAR examples + interview framework
|
||||
│ │ ├── job-scraper/ # Job search orchestration
|
||||
│ │ └── upskill/ # /upskill skill gap analysis and learning plan
|
||||
│ └── settings.json # Claude Code permissions (shared, scoped)
|
||||
├── .agents/skills/ # Job portal CLI tools
|
||||
│ ├── jobbank-search/ # Akademikernes Jobbank (Denmark)
|
||||
│ ├── jobdanmark-search/ # Jobdanmark.dk (Denmark)
|
||||
│ ├── jobindex-search/ # Jobindex.dk (Denmark)
|
||||
│ ├── jobnet-search/ # Jobnet.dk (Denmark, government portal)
|
||||
│ ├── linkedin-search/ # LinkedIn public job listings (country-agnostic)
|
||||
│ └── freehire-search/ # freehire.me tech job aggregator (multi-market, REST API)
|
||||
├── cv/
|
||||
│ └── main_example.tex # moderncv LaTeX template
|
||||
├── cover_letters/
|
||||
│ ├── cover.cls # Custom cover letter LaTeX class
|
||||
│ ├── cover_example.tex # Example cover letter (structural reference + CI smoke test)
|
||||
│ └── OpenFonts/ # Lato + Raleway fonts
|
||||
├── templates/ # Custom templates registered via /add-template
|
||||
│ └── README.md # Folder layout instructions
|
||||
├── documents/ # Career source materials for /setup Path A and /expand
|
||||
│ ├── README.md # Folder layout instructions
|
||||
│ ├── cv/ # Master CV (PDF or .tex)
|
||||
│ ├── linkedin/ # LinkedIn profile export (PDF)
|
||||
│ ├── diplomas/ # Degree certificates and transcripts
|
||||
│ ├── references/ # Reference letters
|
||||
│ └── applications/ # Past application records (<company>_<role>/)
|
||||
├── .github/workflows/ci.yml # CI: LaTeX smoke compiles, skill lint, CLI typechecks
|
||||
├── salary_lookup.py # Salary benchmarking tool (BYO data)
|
||||
├── tools/
|
||||
│ ├── check_framework_version.py # CI check: framework_version bumped when skill files change
|
||||
│ ├── check_upstream_updates.py # Preview which personalized files an upstream update touches
|
||||
│ ├── convert_salary_excel.py # Convert salary Excel to JSON
|
||||
│ ├── fetch_page.py # GET-only browser-header retry for 403s (robots.txt enforced)
|
||||
│ ├── install_portal_clis.py # Install every discovered portal CLI (bun install)
|
||||
│ ├── lint_skills.py # CI lint for skills, commands, settings.json
|
||||
│ ├── posting_guard.py # Integrity gate: strip hidden text, flag injection-shaped lines
|
||||
│ ├── robots_check.py # Gate the browser-header retry against robots.txt
|
||||
│ ├── security_guards.py # CI guards: permission allow/ask/deny, skill grants, gitignore, manifests
|
||||
│ ├── upstream_triage.py # Sort upstream commits into worth-reviewing vs probably-skip
|
||||
│ ├── verify_layout.py # Measure a compiled PDF's page layout (holes, orphans, footer collisions)
|
||||
│ ├── verify_pdf.py # Verify a compiled PDF's page count and extractable text
|
||||
│ └── README_SALARY_TOOL.md # Salary tool setup instructions
|
||||
├── job_scraper/ # Scraper state (seen jobs, results)
|
||||
├── gmail_sync/ # /gmail-sync state (processed message IDs, last sync date)
|
||||
├── upskill/ # /upskill report output (markdown reports per run)
|
||||
├── job_search_tracker.csv # Application tracking spreadsheet
|
||||
└── SETUP.md # Detailed setup guide
|
||||
```
|
||||
</details>
|
||||
|
||||
## How `/apply` works
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/readme/apply.svg" alt="A job posting passes an integrity gate and fit evaluation, then loops through draft, review, revise, and compile plus inspect until the CV is exactly two pages, the cover letter one page, and the ATS text layer is checked." width="100%">
|
||||
</p>
|
||||
|
||||
The `/apply` command runs a **drafter-reviewer workflow** with mandatory PDF compilation:
|
||||
|
||||
1. **Parse** the job posting (URL or text)
|
||||
@@ -240,7 +217,8 @@ The `/apply` command runs a **drafter-reviewer workflow** with mandatory PDF com
|
||||
|
||||
All claims in the CV and cover letter are verified against your actual profile. The system never fabricates skills or experience.
|
||||
|
||||
### What makes this workflow different
|
||||
<details>
|
||||
<summary><b>What makes this workflow different</b></summary>
|
||||
|
||||
- **PDF verification loop.** Most LaTeX-resume templates produce "looks fine in the .tex" output that breaks in the PDF: job titles orphan to the next page, cover letters spill onto page 2, bullet fonts silently fall back to the body font. The `/apply` command compiles and visually inspects every PDF and applies targeted fixes (`\needspace`, `\enlargethispage`, font-matching wrappers for list items) until the layout is clean. This runs automatically on every application.
|
||||
- **ATS verification on the PDF text layer.** An ATS reads the PDF's embedded text, not the rendered page — and LaTeX can silently produce PDFs whose text extracts as garbage (icon glyphs where the email should be, interleaved lines from multi-column layouts). `/apply` extracts the compiled CV's text layer with `pdftotext` and verifies contact details, reading order, and the posting's keyword coverage against what a parser actually sees. Honesty rule enforced: a keyword the profile doesn't support is acknowledged as a gap, never stuffed in.
|
||||
@@ -248,6 +226,8 @@ All claims in the CV and cover letter are verified against your actual profile.
|
||||
- **Drafter-reviewer separation.** The drafter writes; a second Claude agent, spawned with a fresh context, researches the company and critiques the drafts. The drafter then revises. This catches missed keywords, weak framing, and generic language that a single pass often leaves in.
|
||||
- **Token-efficient reviewer dispatch.** The reviewer agent receives drafts inline rather than re-reading them, and the verification checklist runs once at the end of the workflow rather than being duplicated by both agents. Note: the new compile-and-inspect step in Step 5 spends some of those savings on PDF rendering and layout iteration — the workflow trades some end-to-end token cost for a real reduction in broken PDFs reaching the user.
|
||||
|
||||
</details>
|
||||
|
||||
## Customization
|
||||
|
||||
### Which files to edit manually
|
||||
@@ -315,7 +295,14 @@ Everything above adds up to an extension model, so here it is stated plainly. Th
|
||||
|
||||
1. **Portal skills** - the module system for job boards. Every `*-search` skill is a self-contained folder under `.agents/skills/` with the same contract (a `search`/`detail` CLI, `--format json|table|plain` output, an `enabled:` flag in its `SKILL.md`, its own tests). `/scrape` auto-discovers any installed skill that follows the contract - nothing to register, nothing to wire up. `/add-portal` generates new ones; the [community portal index](https://github.com/ai-job-search-dev/ai-job-search/discussions/78) catalogs the ones other forks have built.
|
||||
2. **Document templates** - `/add-template` registers any CV or cover-letter toolchain that compiles to PDF from the command line, LaTeX or otherwise.
|
||||
3. **Evaluation criteria** - deal-breakers and preferences in your profile are free-form, and the evaluation rubric scores against whatever you put there. "Strong parental-leave terms", "minimum salary X per my union's scale", "no on-call" - each is one profile line, no code, and it carries real weight in `/rank` and `/apply` fit evaluations. Language is the one deal-breaker type with dedicated, structured handling: `/setup` captures every language you work in and your level (asked directly, or inferred from your CV/LinkedIn export) into a `Languages` table, and the Language Gate (`04-job-evaluation.md`) hard-rejects a posting that requires a language you haven't declared at all, while flagging - not auto-rejecting - one that asks for a higher level than you declared in a language you do work in, so a borderline case (a strict "fluent" bar against your own B1/B2, say) gets your judgment instead of a silent drop.
|
||||
3. **Evaluation criteria** - deal-breakers and preferences in your profile are free-form, and the evaluation rubric scores against whatever you put there. "Strong parental-leave terms", "minimum salary X per my union's scale", "no on-call" - each is one profile line, no code, and it carries real weight in `/rank` and `/apply` fit evaluations.
|
||||
|
||||
<details>
|
||||
<summary>How the Language Gate handles language deal-breakers</summary>
|
||||
|
||||
Language is the one deal-breaker type with dedicated, structured handling: `/setup` captures every language you work in and your level (asked directly, or inferred from your CV/LinkedIn export) into a `Languages` table, and the Language Gate (`04-job-evaluation.md`) hard-rejects a posting that requires a language you haven't declared at all, while flagging - not auto-rejecting - one that asks for a higher level than you declared in a language you do work in, so a borderline case (a strict "fluent" bar against your own B1/B2, say) gets your judgment instead of a silent drop.
|
||||
|
||||
</details>
|
||||
|
||||
**Borrowing a portal skill from another fork** is the intended way to get a board that upstream doesn't ship: find it in the [portal index](https://github.com/ai-job-search-dev/ai-job-search/discussions/78), open that fork, and copy the one folder into your own `.agents/skills/`. Before you run it:
|
||||
|
||||
@@ -366,6 +353,89 @@ The framework supports two distinct modes of job searching:
|
||||
|
||||
To get the most from this, invest time during `/setup` in describing not just your experience, but what energized you, what drained you, and what you'd want more of. This context directly shapes how the system evaluates fit and which roles it surfaces during `/scrape`.
|
||||
|
||||
## File structure
|
||||
|
||||
<details>
|
||||
<summary>Show the repository layout</summary>
|
||||
|
||||
```
|
||||
ai-job-search/
|
||||
├── CLAUDE.md # Main candidate profile + workflow rules
|
||||
├── .claude/
|
||||
│ ├── commands/
|
||||
│ │ ├── apply.md # /apply workflow (drafter-reviewer)
|
||||
│ │ ├── setup.md # /setup onboarding (documents folder, CV import, or interview)
|
||||
│ │ ├── expand.md # /expand competency enrichment from documents and online presence
|
||||
│ │ ├── add-template.md # /add-template register custom templates (LaTeX, Typst, ...)
|
||||
│ │ ├── add-portal.md # /add-portal generate a job-portal search skill for your market
|
||||
│ │ ├── rank.md # /rank triage scraped jobs into a ranked shortlist
|
||||
│ │ ├── outcome.md # /outcome record application results, archive materials
|
||||
│ │ ├── gmail-sync.md # /gmail-sync auto-detect application status from Gmail
|
||||
│ │ ├── interview.md # /interview stage-specific prep pack + mock interview
|
||||
│ │ ├── html-report.md # /html-report generate application tracker dashboard
|
||||
│ │ ├── notion-sync.md # /notion-sync one-way pipeline view in a Notion database
|
||||
│ │ └── reset.md # /reset wipe profile data or documents folder
|
||||
│ ├── skills/
|
||||
│ │ ├── job-application-assistant/ # Core application skill
|
||||
│ │ │ ├── SKILL.md # Skill definition
|
||||
│ │ │ ├── 01-candidate-profile.md # Your education, experience, skills
|
||||
│ │ │ ├── 02-behavioral-profile.md# PI/DISC/personality assessment
|
||||
│ │ │ ├── 03-writing-style.md # Tone, structure, do's and don'ts
|
||||
│ │ │ ├── 04-job-evaluation.md # Scoring framework for job fit
|
||||
│ │ │ ├── 05-cv-templates.md # LaTeX CV structure + tailoring rules
|
||||
│ │ │ ├── 06-cover-letter-templates.md # LaTeX cover letter templates
|
||||
│ │ │ └── 07-interview-prep.md # STAR examples + interview framework
|
||||
│ │ ├── job-scraper/ # Job search orchestration
|
||||
│ │ └── upskill/ # /upskill skill gap analysis and learning plan
|
||||
│ └── settings.json # Claude Code permissions (shared, scoped)
|
||||
├── .agents/skills/ # Job portal CLI tools
|
||||
│ ├── jobbank-search/ # Akademikernes Jobbank (Denmark)
|
||||
│ ├── jobdanmark-search/ # Jobdanmark.dk (Denmark)
|
||||
│ ├── jobindex-search/ # Jobindex.dk (Denmark)
|
||||
│ ├── jobnet-search/ # Jobnet.dk (Denmark, government portal)
|
||||
│ ├── linkedin-search/ # LinkedIn public job listings (country-agnostic)
|
||||
│ └── freehire-search/ # freehire.me tech job aggregator (multi-market, REST API)
|
||||
├── assets/ # README artwork (Pip the mascot, animated SVG diagrams)
|
||||
├── cv/
|
||||
│ └── main_example.tex # moderncv LaTeX template
|
||||
├── cover_letters/
|
||||
│ ├── cover.cls # Custom cover letter LaTeX class
|
||||
│ ├── cover_example.tex # Example cover letter (structural reference + CI smoke test)
|
||||
│ └── OpenFonts/ # Lato + Raleway fonts
|
||||
├── templates/ # Custom templates registered via /add-template
|
||||
│ └── README.md # Folder layout instructions
|
||||
├── documents/ # Career source materials for /setup Path A and /expand
|
||||
│ ├── README.md # Folder layout instructions
|
||||
│ ├── cv/ # Master CV (PDF or .tex)
|
||||
│ ├── linkedin/ # LinkedIn profile export (PDF)
|
||||
│ ├── diplomas/ # Degree certificates and transcripts
|
||||
│ ├── references/ # Reference letters
|
||||
│ └── applications/ # Past application records (<company>_<role>/)
|
||||
├── .github/workflows/ci.yml # CI: LaTeX smoke compiles, skill lint, CLI typechecks
|
||||
├── salary_lookup.py # Salary benchmarking tool (BYO data)
|
||||
├── tools/
|
||||
│ ├── check_framework_version.py # CI check: framework_version bumped when skill files change
|
||||
│ ├── check_upstream_updates.py # Preview which personalized files an upstream update touches
|
||||
│ ├── convert_salary_excel.py # Convert salary Excel to JSON
|
||||
│ ├── fetch_page.py # GET-only browser-header retry for 403s (robots.txt enforced)
|
||||
│ ├── install_portal_clis.py # Install every discovered portal CLI (bun install)
|
||||
│ ├── lint_skills.py # CI lint for skills, commands, settings.json
|
||||
│ ├── posting_guard.py # Integrity gate: strip hidden text, flag injection-shaped lines
|
||||
│ ├── robots_check.py # Gate the browser-header retry against robots.txt
|
||||
│ ├── security_guards.py # CI guards: permission allow/ask/deny, skill grants, gitignore, manifests
|
||||
│ ├── upstream_triage.py # Sort upstream commits into worth-reviewing vs probably-skip
|
||||
│ ├── verify_layout.py # Measure a compiled PDF's page layout (holes, orphans, footer collisions)
|
||||
│ ├── verify_pdf.py # Verify a compiled PDF's page count and extractable text
|
||||
│ └── README_SALARY_TOOL.md # Salary tool setup instructions
|
||||
├── job_scraper/ # Scraper state (seen jobs, results)
|
||||
├── gmail_sync/ # /gmail-sync state (processed message IDs, last sync date)
|
||||
├── upskill/ # /upskill report output (markdown reports per run)
|
||||
├── job_search_tracker.csv # Application tracking spreadsheet
|
||||
└── SETUP.md # Detailed setup guide
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Contributing
|
||||
|
||||
Thinking about a PR? Read [CONTRIBUTING.md](CONTRIBUTING.md) first - it explains what gets merged, what lives in forks, and why.
|
||||
@@ -378,3 +448,8 @@ Thinking about a PR? Read [CONTRIBUTING.md](CONTRIBUTING.md) first - it explains
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
<p align="center">
|
||||
<img src="assets/mascot/pip_flight_loop.gif" alt="Pip, the courier bird" width="120"><br>
|
||||
<sub>Pip delivers. Good luck out there.</sub>
|
||||
</p>
|
||||
@@ -0,0 +1,48 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 440" width="1280" height="440" role="img" aria-labelledby="t d">
|
||||
<title id="t">How /apply works</title>
|
||||
<desc id="d">A job posting passes an integrity gate and fit evaluation, then loops through draft, review, revise, and compile plus inspect until the CV is exactly two pages, the cover letter one page, and the ATS text layer is checked.</desc>
|
||||
<style>
|
||||
.orbit{transform-box:view-box;transform-origin:640px 214px;animation:spin 6s linear infinite}
|
||||
.node{opacity:0}
|
||||
.flow{animation:flow 1.6s linear infinite}
|
||||
.out{animation:out 12s ease-out infinite}
|
||||
.o1{animation-delay:.25s}.o2{animation-delay:.5s}
|
||||
.write rect+rect{transform-box:fill-box;transform-origin:left;animation:write 6s ease-out infinite}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
@keyframes hit{0%{opacity:1}22%,100%{opacity:0}}
|
||||
@keyframes flow{to{stroke-dashoffset:-24}}
|
||||
@keyframes out{0%,45%{opacity:.18}52%,94%{opacity:1}100%{opacity:.18}}
|
||||
@keyframes write{0%{transform:scaleX(0)}40%,100%{transform:scaleX(1)}}
|
||||
.n0{animation:hit 6s linear -6.000s infinite}.n1{animation:hit 6s linear -4.500s infinite}.n2{animation:hit 6s linear -3.000s infinite}.n3{animation:hit 6s linear -1.500s infinite}
|
||||
@media (prefers-reduced-motion: reduce){*{animation:none!important}}
|
||||
@media (prefers-reduced-motion: reduce){.n0{opacity:1}.out{opacity:1}}
|
||||
</style>
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#0F2229"/><stop offset="1" stop-color="#15333C"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="glow" cx="0.5" cy="0.5" r="0.6">
|
||||
<stop offset="0" stop-color="#2A9D8F" stop-opacity=".30"/><stop offset="1" stop-color="#2A9D8F" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="card"><rect width="1280" height="440" rx="28"/></clipPath>
|
||||
|
||||
</defs>
|
||||
<g clip-path="url(#card)">
|
||||
<rect width="1280" height="440" fill="url(#bg)"/>
|
||||
<rect width="1280" height="440" fill="url(#glow)"/>
|
||||
<g class=""><rect x="120" y="128" width="120" height="160" rx="6" fill="#EEF3EF"/><rect x="132" y="144" width="53" height="6" rx="2" fill="#2b4a52"/><rect x="132" y="157" width="86" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="170" width="86" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="183" width="67" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="196" width="86" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="209" width="86" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="222" width="67" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="235" width="86" height="4" rx="2" fill="#a9bcb5"/><rect x="132" y="248" width="86" height="4" rx="2" fill="#a9bcb5"/></g>
|
||||
<text x="180" y="334" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="19" font-weight="600" fill="#EEF3EF">Job posting</text>
|
||||
<text x="180" y="362" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="16" fill="#EEF3EF" fill-opacity=".6">integrity gate + fit score</text>
|
||||
<path d="M262 214 H498" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2.5" stroke-linecap="round" stroke-dasharray="1 11" class="flow"/>
|
||||
<path d="M780 214 C 880 214, 900 196, 960 196" fill="none" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2.5" stroke-linecap="round" stroke-dasharray="1 11" class="flow"/>
|
||||
<circle cx="640" cy="214" r="118" fill="none" stroke="#9FE0CF" stroke-opacity=".22" stroke-width="2"/>
|
||||
<g class="orbit">
|
||||
<circle cx="640" cy="214" r="118" fill="none" stroke="#F4704F" stroke-width="3" stroke-linecap="round" stroke-dasharray="70 671.4" transform="rotate(142 640 214)"/>
|
||||
<circle cx="522" cy="214" r="7" fill="#F4704F"/>
|
||||
</g>
|
||||
<circle cx="522.0" cy="214.0" r="15" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".4" stroke-width="2"/><circle class="node n0" cx="522.0" cy="214.0" r="15" fill="#2A9D8F"/><text x="522.0" y="262.0" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="19" font-weight="600" fill="#EEF3EF">Draft</text><circle cx="640.0" cy="96.0" r="15" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".4" stroke-width="2"/><circle class="node n1" cx="640.0" cy="96.0" r="15" fill="#2A9D8F"/><text x="640.0" y="62.0" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="19" font-weight="600" fill="#EEF3EF">Review</text><circle cx="758.0" cy="214.0" r="15" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".4" stroke-width="2"/><circle class="node n2" cx="758.0" cy="214.0" r="15" fill="#2A9D8F"/><text x="758.0" y="262.0" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="19" font-weight="600" fill="#EEF3EF">Revise</text><circle cx="640.0" cy="332.0" r="15" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".4" stroke-width="2"/><circle class="node n3" cx="640.0" cy="332.0" r="15" fill="#2A9D8F"/><text x="640.0" y="380.0" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="19" font-weight="600" fill="#EEF3EF">Compile + inspect</text>
|
||||
<g class="write"><rect x="602" y="164" width="76" height="100" rx="6" fill="#EEF3EF"/><rect x="614" y="180" width="29" height="6" rx="2" fill="#2b4a52"/><rect x="614" y="193" width="47" height="4" rx="2" fill="#a9bcb5"/><rect x="614" y="206" width="47" height="4" rx="2" fill="#a9bcb5"/><rect x="614" y="219" width="36" height="4" rx="2" fill="#a9bcb5"/><rect x="614" y="232" width="47" height="4" rx="2" fill="#a9bcb5"/><rect x="614" y="245" width="47" height="4" rx="2" fill="#a9bcb5"/></g>
|
||||
<g class="out o0"><circle cx="1000" cy="96" r="16" fill="#2A9D8F"/><path d="M992 96 l6 6 l11 -12" fill="none" stroke="#EEF3EF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><text x="1030" y="103" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="20" fill="#EEF3EF">CV, exactly 2 pages</text></g><g class="out o1"><circle cx="1000" cy="196" r="16" fill="#2A9D8F"/><path d="M992 196 l6 6 l11 -12" fill="none" stroke="#EEF3EF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><text x="1030" y="203" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="20" fill="#EEF3EF">Cover letter, 1 page</text></g><g class="out o2"><circle cx="1000" cy="296" r="16" fill="#2A9D8F"/><path d="M992 296 l6 6 l11 -12" fill="none" stroke="#EEF3EF" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/><text x="1030" y="303" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="20" fill="#EEF3EF">ATS text layer checked</text></g>
|
||||
</g>
|
||||
<rect x=".5" y=".5" width="1279" height="439" rx="27.5" fill="none" stroke="#9FE0CF" stroke-opacity=".14"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,89 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 480" width="1280" height="480" role="img" aria-labelledby="t d">
|
||||
<title id="t">AI Job Search</title>
|
||||
<desc id="d">Pip the courier bird carries an application along a flight path to a destination pin. The job search that runs on your machine.</desc>
|
||||
<style>
|
||||
.contours{transform-box:view-box;transform-origin:1150px 132px;animation:spin 160s linear infinite}
|
||||
.flow{animation:flow 1.6s linear infinite}
|
||||
.trail{animation:trail 9s cubic-bezier(.45,.05,.4,1) infinite}
|
||||
.pip{offset-path:path("M 720 396 C 830 414, 860 262, 960 256 S 1030 182, 1060 166");offset-rotate:0deg;animation:fly 9s cubic-bezier(.45,.05,.4,1) infinite}
|
||||
.bob{animation:bob 1.1s ease-in-out infinite alternate}
|
||||
.ring{transform-box:fill-box;transform-origin:center;animation:ring 9s ease-out infinite}
|
||||
.ring2{animation-delay:.35s}
|
||||
.pin{transform-box:fill-box;transform-origin:50% 100%;animation:land 9s ease-out infinite}
|
||||
.cmd{opacity:0}
|
||||
.caret{animation:blink 1s steps(1) infinite}
|
||||
.rise{animation:rise 1.2s cubic-bezier(.2,.7,.2,1) both}
|
||||
.d1{animation-delay:.15s}.d2{animation-delay:.3s}
|
||||
@keyframes spin{to{transform:rotate(360deg)}}
|
||||
@keyframes flow{to{stroke-dashoffset:-24}}
|
||||
@keyframes fly{0%{offset-distance:0%;opacity:0}6%{opacity:1}70%{offset-distance:100%;opacity:1}78%,100%{offset-distance:100%;opacity:0}}
|
||||
@keyframes trail{0%{stroke-dashoffset:1;opacity:.9}70%{stroke-dashoffset:0;opacity:.9}90%,100%{stroke-dashoffset:0;opacity:0}}
|
||||
@keyframes bob{from{transform:translateY(-4px)}to{transform:translateY(4px)}}
|
||||
@keyframes ring{0%,68%{transform:scale(.2);opacity:0}72%{opacity:.8}96%,100%{transform:scale(2.6);opacity:0}}
|
||||
@keyframes land{0%,68%{transform:scale(1)}72%{transform:scale(1.22)}78%,100%{transform:scale(1)}}
|
||||
@keyframes show{0%,14.67%{opacity:1}16.67%,100%{opacity:0}}
|
||||
@keyframes blink{50%{opacity:0}}
|
||||
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
|
||||
.c0{animation:show 18.0s linear 0s infinite}.v0{animation:t0 18.0s 0s infinite}@keyframes t0{0%{transform:translateX(0);animation-timing-function:steps(6,end)}3.22%,100%{transform:translateX(83.2px)}}.c1{animation:show 18.0s linear 3s infinite}.v1{animation:t1 18.0s 3s infinite}@keyframes t1{0%{transform:translateX(0);animation-timing-function:steps(7,end)}3.53%,100%{transform:translateX(96.4px)}}.c2{animation:show 18.0s linear 6s infinite}.v2{animation:t2 18.0s 6s infinite}@keyframes t2{0%{transform:translateX(0);animation-timing-function:steps(5,end)}2.92%,100%{transform:translateX(70.0px)}}.c3{animation:show 18.0s linear 9s infinite}.v3{animation:t3 18.0s 9s infinite}@keyframes t3{0%{transform:translateX(0);animation-timing-function:steps(20,end)}7.50%,100%{transform:translateX(268.0px)}}.c4{animation:show 18.0s linear 12s infinite}.v4{animation:t4 18.0s 12s infinite}@keyframes t4{0%{transform:translateX(0);animation-timing-function:steps(10,end)}4.44%,100%{transform:translateX(136.0px)}}.c5{animation:show 18.0s linear 15s infinite}.v5{animation:t5 18.0s 15s infinite}@keyframes t5{0%{transform:translateX(0);animation-timing-function:steps(8,end)}3.83%,100%{transform:translateX(109.6px)}}
|
||||
@media (prefers-reduced-motion: reduce){*{animation:none!important}}
|
||||
@media (prefers-reduced-motion: reduce){.c0{opacity:1}.v0{transform:translateX(110px)}.pip{offset-distance:62%}.trail{stroke-dashoffset:0}}
|
||||
</style>
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#0F2229"/><stop offset="1" stop-color="#15333C"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="glow" cx="0.8" cy="0.2" r="0.6">
|
||||
<stop offset="0" stop-color="#2A9D8F" stop-opacity=".30"/><stop offset="1" stop-color="#2A9D8F" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="card"><rect width="1280" height="480" rx="28"/></clipPath>
|
||||
<linearGradient id="trailg" gradientUnits="userSpaceOnUse" x1="720" y1="396" x2="1060" y2="166">
|
||||
<stop offset="0" stop-color="#F4704F" stop-opacity="0"/><stop offset=".35" stop-color="#F4704F"/><stop offset="1" stop-color="#9FE0CF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g clip-path="url(#card)">
|
||||
<rect width="1280" height="480" fill="url(#bg)"/>
|
||||
<rect width="1280" height="480" fill="url(#glow)"/>
|
||||
<g class="contours" fill="none" stroke="#9FE0CF" stroke-opacity=".085" stroke-width="1.2">
|
||||
<path d="M1188.0 132.0 L1189.0 134.0 L1189.8 136.1 L1190.2 138.2 L1190.2 140.4 L1189.8 142.5 L1189.0 144.6 L1187.7 146.5 L1186.1 148.3 L1184.2 149.8 L1182.1 151.2 L1179.8 152.4 L1177.4 153.4 L1175.1 154.3 L1172.8 155.1 L1170.5 155.9 L1168.3 156.7 L1166.1 157.4 L1163.9 158.1 L1161.7 158.8 L1159.4 159.4 L1157.1 160.0 L1154.8 160.4 L1152.4 160.7 L1150.0 160.8 L1147.6 160.7 L1145.2 160.4 L1142.9 160.0 L1140.6 159.4 L1138.3 158.8 L1136.1 158.1 L1133.9 157.4 L1131.7 156.7 L1129.5 155.9 L1127.2 155.1 L1124.9 154.3 L1122.6 153.4 L1120.2 152.4 L1117.9 151.2 L1115.8 149.8 L1113.9 148.3 L1112.3 146.5 L1111.0 144.6 L1110.2 142.5 L1109.8 140.4 L1109.8 138.2 L1110.2 136.1 L1111.0 134.0 L1112.0 132.0 L1113.2 130.1 L1114.4 128.3 L1115.7 126.7 L1116.8 125.1 L1117.9 123.5 L1118.8 121.9 L1119.6 120.3 L1120.3 118.6 L1121.0 116.9 L1121.8 115.1 L1122.6 113.3 L1123.7 111.5 L1125.0 109.7 L1126.5 108.1 L1128.3 106.6 L1130.3 105.3 L1132.4 104.2 L1134.8 103.4 L1137.2 102.7 L1139.8 102.2 L1142.3 101.8 L1144.9 101.6 L1147.4 101.5 L1150.0 101.5 L1152.6 101.5 L1155.1 101.6 L1157.7 101.8 L1160.2 102.2 L1162.8 102.7 L1165.2 103.4 L1167.6 104.2 L1169.7 105.3 L1171.7 106.6 L1173.5 108.1 L1175.0 109.7 L1176.3 111.5 L1177.4 113.3 L1178.2 115.1 L1179.0 116.9 L1179.7 118.6 L1180.4 120.3 L1181.2 121.9 L1182.1 123.5 L1183.2 125.1 L1184.3 126.7 L1185.6 128.3 L1186.8 130.1 L1188.0 132.0Z"/>
|
||||
<path d="M1240.9 132.0 L1242.0 136.7 L1242.2 141.5 L1241.4 146.2 L1239.6 150.7 L1236.9 155.0 L1233.6 159.0 L1229.7 162.7 L1225.5 166.0 L1221.0 169.0 L1216.5 171.8 L1212.1 174.5 L1207.7 177.0 L1203.3 179.4 L1199.0 181.9 L1194.7 184.2 L1190.3 186.5 L1185.8 188.6 L1181.1 190.5 L1176.2 192.1 L1171.1 193.4 L1165.9 194.3 L1160.6 194.8 L1155.3 195.0 L1150.0 194.8 L1144.8 194.4 L1139.6 193.8 L1134.4 193.1 L1129.3 192.3 L1124.1 191.5 L1118.8 190.8 L1113.4 189.9 L1107.8 189.0 L1102.1 187.9 L1096.4 186.5 L1090.8 184.7 L1085.4 182.4 L1080.4 179.6 L1076.0 176.3 L1072.3 172.5 L1069.5 168.3 L1067.6 163.7 L1066.6 159.0 L1066.4 154.1 L1067.0 149.4 L1068.1 144.7 L1069.6 140.3 L1071.3 136.0 L1072.9 132.0 L1074.4 128.1 L1075.6 124.4 L1076.6 120.6 L1077.3 116.8 L1077.8 112.9 L1078.4 108.9 L1079.0 104.7 L1080.0 100.5 L1081.4 96.2 L1083.3 92.1 L1085.8 88.1 L1088.9 84.3 L1092.6 80.9 L1096.8 77.9 L1101.4 75.3 L1106.3 73.0 L1111.5 71.1 L1116.8 69.4 L1122.2 68.0 L1127.6 66.8 L1133.1 65.8 L1138.7 64.9 L1144.3 64.2 L1150.0 63.8 L1155.7 63.6 L1161.5 63.8 L1167.2 64.5 L1172.8 65.7 L1178.1 67.4 L1183.1 69.7 L1187.7 72.4 L1191.8 75.5 L1195.5 78.9 L1198.7 82.5 L1201.6 86.1 L1204.2 89.7 L1206.7 93.2 L1209.3 96.5 L1212.0 99.7 L1215.0 102.7 L1218.2 105.8 L1221.8 108.8 L1225.5 112.0 L1229.3 115.4 L1232.9 119.1 L1236.2 123.2 L1238.9 127.5 L1240.9 132.0Z"/>
|
||||
<path d="M1293.8 132.0 L1292.7 139.3 L1290.2 146.4 L1286.6 153.2 L1282.2 159.6 L1277.1 165.7 L1271.7 171.3 L1266.2 176.7 L1260.6 181.8 L1255.1 186.8 L1249.6 191.6 L1244.1 196.4 L1238.5 201.0 L1232.7 205.5 L1226.6 209.8 L1220.0 213.8 L1213.1 217.3 L1205.8 220.3 L1198.2 222.8 L1190.3 224.6 L1182.3 226.0 L1174.2 226.9 L1166.1 227.4 L1158.0 227.8 L1150.0 228.0 L1141.9 228.1 L1133.7 228.4 L1125.4 228.6 L1116.8 228.8 L1107.9 228.8 L1098.7 228.6 L1089.4 227.8 L1080.1 226.4 L1071.1 224.1 L1062.5 221.0 L1054.6 216.9 L1047.7 211.8 L1041.9 205.9 L1037.4 199.4 L1034.3 192.3 L1032.3 185.0 L1031.4 177.6 L1031.4 170.3 L1031.9 163.3 L1032.6 156.5 L1033.4 150.1 L1033.9 143.9 L1034.1 137.9 L1033.8 132.0 L1033.2 126.0 L1032.4 119.9 L1031.6 113.6 L1031.0 107.1 L1030.9 100.5 L1031.5 93.7 L1033.0 87.0 L1035.4 80.4 L1038.9 74.1 L1043.3 68.2 L1048.6 62.7 L1054.7 57.6 L1061.3 53.1 L1068.3 48.9 L1075.6 45.1 L1083.1 41.7 L1090.8 38.4 L1098.7 35.4 L1106.7 32.6 L1115.0 30.1 L1123.5 28.0 L1132.2 26.4 L1141.0 25.4 L1150.0 25.2 L1158.9 25.8 L1167.7 27.3 L1176.1 29.7 L1184.0 32.9 L1191.4 36.8 L1198.2 41.2 L1204.4 45.9 L1210.1 50.7 L1215.5 55.5 L1220.8 60.1 L1226.0 64.4 L1231.5 68.4 L1237.4 72.2 L1243.7 75.9 L1250.4 79.7 L1257.5 83.6 L1264.6 87.9 L1271.6 92.7 L1278.1 98.1 L1283.8 104.0 L1288.4 110.5 L1291.7 117.5 L1293.5 124.7 L1293.8 132.0Z"/>
|
||||
<path d="M1337.6 132.0 L1333.9 141.4 L1329.4 150.4 L1324.4 159.1 L1319.1 167.3 L1313.7 175.4 L1308.4 183.2 L1302.9 190.8 L1297.4 198.4 L1291.6 205.8 L1285.3 213.0 L1278.5 219.9 L1271.1 226.4 L1262.9 232.4 L1254.0 237.8 L1244.6 242.4 L1234.6 246.4 L1224.4 249.7 L1214.0 252.4 L1203.4 254.8 L1192.9 256.9 L1182.4 259.0 L1171.8 261.1 L1161.0 263.2 L1150.0 265.5 L1138.6 267.8 L1126.7 269.8 L1114.4 271.5 L1101.8 272.4 L1088.9 272.4 L1076.1 271.2 L1063.6 268.6 L1051.9 264.6 L1041.1 259.1 L1031.7 252.2 L1023.7 244.3 L1017.3 235.5 L1012.4 226.1 L1008.8 216.5 L1006.3 206.9 L1004.5 197.5 L1003.1 188.5 L1001.6 179.9 L999.9 171.7 L997.8 163.8 L995.2 156.0 L992.2 148.2 L988.9 140.2 L985.6 132.0 L982.7 123.4 L980.4 114.6 L979.2 105.5 L979.1 96.3 L980.4 87.1 L983.1 78.1 L987.2 69.4 L992.5 61.1 L998.9 53.2 L1006.1 45.9 L1013.9 38.9 L1022.2 32.3 L1030.8 26.0 L1039.7 19.9 L1049.0 14.1 L1058.6 8.6 L1068.7 3.4 L1079.2 -1.2 L1090.3 -5.2 L1101.8 -8.3 L1113.7 -10.3 L1125.8 -11.2 L1138.0 -10.7 L1150.0 -9.0 L1161.6 -6.2 L1172.7 -2.4 L1183.1 2.2 L1192.9 7.2 L1202.0 12.4 L1210.8 17.5 L1219.3 22.4 L1227.9 26.8 L1236.7 30.8 L1246.0 34.4 L1255.8 37.9 L1266.2 41.3 L1277.1 45.1 L1288.1 49.3 L1299.0 54.4 L1309.3 60.2 L1318.7 67.1 L1326.8 74.9 L1333.3 83.5 L1337.8 92.7 L1340.4 102.5 L1341.1 112.4 L1340.1 122.3 L1337.6 132.0Z"/>
|
||||
<path d="M1373.7 132.0 L1370.2 143.3 L1366.4 154.2 L1362.5 165.0 L1358.5 175.6 L1354.2 186.1 L1349.3 196.4 L1343.8 206.6 L1337.4 216.4 L1330.0 225.8 L1321.5 234.6 L1312.0 242.8 L1301.5 250.2 L1290.3 256.8 L1278.6 262.7 L1266.5 268.0 L1254.3 272.9 L1242.1 277.7 L1229.9 282.4 L1217.6 287.2 L1205.1 292.3 L1192.2 297.5 L1178.8 302.8 L1164.8 307.8 L1150.0 312.3 L1134.5 316.0 L1118.5 318.4 L1102.3 319.2 L1086.1 318.1 L1070.3 315.1 L1055.5 310.0 L1041.8 303.1 L1029.7 294.6 L1019.2 284.7 L1010.3 274.0 L1002.9 262.8 L996.8 251.5 L991.5 240.4 L986.6 229.8 L981.9 219.6 L976.8 210.0 L971.4 200.7 L965.3 191.7 L958.9 182.6 L952.1 173.4 L945.5 163.7 L939.2 153.6 L933.9 143.0 L929.7 132.0 L927.1 120.6 L926.2 109.0 L927.1 97.4 L929.6 85.9 L933.7 74.7 L939.1 63.9 L945.6 53.4 L952.9 43.2 L960.8 33.4 L969.3 23.8 L978.2 14.4 L987.5 5.3 L997.6 -3.6 L1008.3 -12.1 L1019.8 -19.9 L1032.3 -27.0 L1045.7 -32.9 L1060.0 -37.6 L1074.8 -40.7 L1090.1 -42.2 L1105.6 -42.2 L1120.9 -40.6 L1135.7 -37.8 L1150.0 -34.0 L1163.6 -29.6 L1176.5 -25.0 L1188.9 -20.5 L1201.0 -16.4 L1213.0 -12.9 L1225.4 -9.9 L1238.2 -7.5 L1251.7 -5.4 L1265.8 -3.2 L1280.6 -0.7 L1295.7 2.4 L1310.7 6.6 L1325.3 12.1 L1338.9 19.0 L1351.0 27.2 L1361.3 36.8 L1369.6 47.5 L1375.5 59.1 L1379.3 71.3 L1381.0 83.7 L1380.9 96.2 L1379.4 108.4 L1376.9 120.4 L1373.7 132.0Z"/>
|
||||
<path d="M1412.3 132.0 L1411.0 145.3 L1409.2 158.6 L1406.7 171.8 L1403.1 184.9 L1398.2 197.7 L1391.9 210.2 L1384.1 222.1 L1374.9 233.3 L1364.5 243.8 L1353.0 253.5 L1340.8 262.5 L1328.1 270.9 L1315.3 279.0 L1302.4 287.0 L1289.6 295.0 L1276.8 303.2 L1263.7 311.8 L1250.2 320.7 L1236.0 329.7 L1220.9 338.5 L1204.8 346.7 L1187.4 353.9 L1169.1 359.5 L1150.0 363.2 L1130.5 364.6 L1110.9 363.6 L1091.9 359.9 L1073.8 353.9 L1057.0 345.7 L1041.8 335.8 L1028.2 324.7 L1016.2 312.8 L1005.5 300.7 L995.7 288.8 L986.6 277.4 L977.6 266.5 L968.3 256.3 L958.7 246.5 L948.5 237.0 L937.8 227.6 L926.9 217.8 L916.1 207.6 L905.8 196.6 L896.6 185.0 L888.7 172.5 L882.6 159.5 L878.4 145.9 L876.3 132.0 L876.2 118.0 L877.8 104.0 L881.0 90.3 L885.3 76.7 L890.7 63.3 L896.7 50.2 L903.4 37.2 L910.8 24.3 L918.8 11.5 L927.7 -1.0 L937.8 -13.2 L949.1 -24.7 L961.9 -35.3 L976.1 -44.7 L991.8 -52.6 L1008.8 -58.8 L1026.6 -63.1 L1045.1 -65.6 L1063.7 -66.2 L1082.2 -65.4 L1100.2 -63.4 L1117.5 -60.6 L1134.1 -57.7 L1150.0 -54.9 L1165.5 -52.5 L1180.9 -50.9 L1196.4 -50.1 L1212.5 -49.9 L1229.3 -50.2 L1246.9 -50.4 L1265.2 -50.3 L1284.2 -49.2 L1303.2 -46.9 L1322.0 -42.9 L1340.0 -37.0 L1356.6 -29.1 L1371.3 -19.4 L1383.9 -8.0 L1394.2 4.8 L1402.0 18.5 L1407.6 32.9 L1411.3 47.6 L1413.4 62.3 L1414.3 76.8 L1414.4 91.0 L1414.0 104.9 L1413.3 118.5 L1412.3 132.0Z"/>
|
||||
<path d="M1458.0 132.0 L1457.5 147.7 L1455.3 163.4 L1451.3 178.7 L1445.4 193.7 L1437.6 208.2 L1428.3 221.9 L1417.7 235.0 L1406.2 247.4 L1394.1 259.2 L1381.9 270.8 L1369.8 282.3 L1357.8 294.1 L1345.8 306.1 L1333.6 318.7 L1321.0 331.6 L1307.5 344.8 L1292.8 357.8 L1276.5 370.3 L1258.6 381.6 L1239.0 391.2 L1218.0 398.6 L1195.8 403.3 L1172.9 405.1 L1150.0 403.9 L1127.5 399.7 L1105.9 393.0 L1085.7 384.1 L1067.0 373.7 L1049.8 362.3 L1034.0 350.5 L1019.2 338.9 L1005.1 327.7 L991.3 317.2 L977.4 307.5 L963.1 298.3 L948.3 289.4 L933.0 280.5 L917.5 271.2 L902.1 261.2 L887.2 250.3 L873.5 238.4 L861.2 225.3 L850.8 211.2 L842.6 196.3 L836.5 180.6 L832.5 164.6 L830.4 148.3 L830.0 132.0 L830.8 115.7 L832.7 99.4 L835.4 83.2 L838.8 67.0 L843.0 50.7 L848.1 34.5 L854.4 18.3 L862.3 2.4 L872.0 -12.9 L883.7 -27.4 L897.6 -40.6 L913.7 -52.3 L931.7 -62.1 L951.3 -69.9 L972.1 -75.7 L993.5 -79.4 L1015.0 -81.5 L1036.2 -82.3 L1056.8 -82.3 L1076.5 -81.9 L1095.5 -81.8 L1113.8 -82.3 L1131.9 -83.7 L1150.0 -86.0 L1168.6 -89.1 L1187.9 -92.7 L1208.2 -96.3 L1229.5 -99.5 L1251.6 -101.5 L1274.3 -102.0 L1297.0 -100.4 L1319.1 -96.5 L1340.2 -90.0 L1359.7 -81.1 L1377.1 -70.0 L1392.3 -57.0 L1405.1 -42.5 L1415.7 -27.0 L1424.2 -10.9 L1431.1 5.4 L1436.7 21.7 L1441.4 37.8 L1445.5 53.8 L1449.2 69.5 L1452.4 85.1 L1455.1 100.7 L1457.1 116.3 L1458.0 132.0Z"/>
|
||||
<path d="M1502.5 132.0 L1499.5 149.9 L1494.4 167.4 L1487.4 184.4 L1478.9 200.7 L1469.4 216.6 L1459.4 232.0 L1449.3 247.1 L1439.4 262.3 L1429.7 277.8 L1420.2 293.7 L1410.6 310.3 L1400.5 327.4 L1389.3 344.8 L1376.5 362.3 L1361.8 379.2 L1344.7 395.0 L1325.2 409.1 L1303.3 420.7 L1279.5 429.5 L1254.1 435.0 L1227.8 437.1 L1201.3 435.9 L1175.2 431.7 L1150.0 425.1 L1126.1 416.6 L1103.6 406.9 L1082.5 396.7 L1062.5 386.6 L1043.4 377.0 L1024.6 368.1 L1005.9 359.9 L986.8 352.4 L967.3 345.2 L947.4 338.0 L927.2 330.2 L907.1 321.5 L887.5 311.6 L868.9 300.2 L851.8 287.4 L836.6 273.1 L823.5 257.6 L812.6 241.0 L803.8 223.7 L796.9 205.8 L791.6 187.6 L787.6 169.2 L784.6 150.7 L782.5 132.0 L781.1 113.1 L780.6 94.1 L781.3 74.8 L783.5 55.4 L787.7 36.1 L794.2 17.1 L803.6 -1.3 L815.8 -18.5 L831.0 -34.2 L849.0 -48.2 L869.3 -60.0 L891.3 -69.8 L914.6 -77.4 L938.2 -83.3 L961.8 -87.7 L984.7 -91.3 L1006.7 -94.6 L1027.8 -98.1 L1048.0 -102.3 L1067.7 -107.5 L1087.3 -113.7 L1107.3 -120.9 L1128.1 -128.7 L1150.0 -136.5 L1173.2 -143.8 L1197.6 -149.9 L1223.0 -154.1 L1248.9 -155.9 L1274.8 -154.8 L1300.2 -150.8 L1324.3 -143.7 L1346.8 -133.9 L1367.4 -121.7 L1385.7 -107.6 L1401.9 -92.1 L1416.2 -75.6 L1428.8 -58.7 L1440.1 -41.6 L1450.5 -24.6 L1460.2 -7.7 L1469.3 9.2 L1477.8 26.1 L1485.6 43.1 L1492.4 60.4 L1497.8 78.0 L1501.5 95.9 L1503.1 113.9 L1502.5 132.0Z"/>
|
||||
<path d="M1536.4 132.0 L1531.3 151.5 L1525.2 170.5 L1518.7 189.2 L1512.1 207.7 L1505.9 226.2 L1500.2 245.2 L1494.9 264.6 L1489.5 284.9 L1483.6 305.8 L1476.4 327.4 L1467.3 349.0 L1455.7 370.4 L1440.9 390.8 L1422.9 409.4 L1401.6 425.7 L1377.3 439.0 L1350.4 448.9 L1321.7 455.2 L1291.9 458.0 L1261.8 457.5 L1232.2 454.3 L1203.5 449.0 L1176.1 442.3 L1150.0 435.0 L1125.1 427.8 L1101.2 421.0 L1077.9 414.9 L1054.6 409.6 L1031.2 405.0 L1007.4 400.6 L983.1 396.1 L958.4 390.8 L933.8 384.4 L909.5 376.5 L886.1 366.7 L864.0 355.1 L843.6 341.6 L825.2 326.4 L808.9 309.8 L794.5 292.1 L781.9 273.6 L770.8 254.5 L760.8 235.0 L751.8 215.2 L743.5 195.1 L736.0 174.5 L729.5 153.5 L724.4 132.0 L721.0 110.1 L720.2 87.9 L722.3 65.6 L727.8 43.8 L737.0 22.7 L750.0 2.8 L766.6 -15.5 L786.3 -31.8 L808.4 -46.0 L832.2 -58.2 L856.8 -68.6 L881.5 -77.4 L905.6 -85.4 L928.6 -93.0 L950.5 -100.9 L971.3 -109.5 L991.2 -119.1 L1010.9 -129.9 L1030.9 -141.7 L1051.7 -154.3 L1073.8 -166.9 L1097.5 -179.0 L1123.0 -189.7 L1150.0 -198.3 L1178.3 -204.2 L1207.2 -207.0 L1236.3 -206.3 L1264.8 -202.1 L1292.2 -194.8 L1318.1 -184.5 L1342.2 -172.0 L1364.4 -157.7 L1384.9 -142.2 L1403.8 -126.0 L1421.5 -109.4 L1438.2 -92.8 L1454.1 -76.0 L1469.4 -59.2 L1484.0 -42.1 L1497.7 -24.6 L1510.2 -6.5 L1521.0 12.1 L1529.7 31.5 L1536.1 51.3 L1539.9 71.5 L1541.1 91.8 L1539.8 112.1 L1536.4 132.0Z"/>
|
||||
<path d="M1566.5 132.0 L1565.0 153.2 L1564.1 174.5 L1563.9 196.2 L1564.2 218.6 L1564.7 241.8 L1564.5 265.9 L1563.0 290.9 L1559.2 316.3 L1552.3 341.7 L1541.5 366.3 L1526.5 389.6 L1507.2 410.6 L1483.7 428.8 L1456.6 443.6 L1426.6 454.9 L1394.6 462.5 L1361.6 466.7 L1328.4 468.0 L1295.8 467.1 L1264.3 464.7 L1234.1 461.6 L1205.1 458.4 L1177.2 455.7 L1150.0 453.7 L1123.1 452.4 L1096.0 451.7 L1068.6 451.2 L1040.6 450.4 L1012.2 448.7 L983.5 445.5 L954.9 440.5 L926.9 433.4 L900.0 423.9 L874.4 412.2 L850.5 398.4 L828.3 382.9 L807.9 366.0 L789.0 348.0 L771.4 329.3 L754.7 310.0 L738.8 290.2 L723.5 269.8 L708.9 248.8 L695.4 227.0 L683.3 204.4 L673.3 181.0 L666.1 156.7 L662.5 132.0 L662.9 107.1 L667.8 82.5 L677.2 58.6 L691.0 36.1 L708.6 15.1 L729.4 -3.9 L752.3 -21.0 L776.3 -36.3 L800.6 -50.1 L824.3 -62.9 L846.9 -75.4 L867.9 -88.0 L887.6 -101.4 L906.2 -115.8 L924.3 -131.4 L942.6 -148.2 L961.8 -165.7 L982.5 -183.4 L1005.3 -200.6 L1030.3 -216.4 L1057.7 -229.9 L1087.1 -240.6 L1118.1 -247.9 L1150.0 -251.4 L1182.2 -251.2 L1214.0 -247.4 L1245.0 -240.4 L1274.6 -230.7 L1302.8 -219.0 L1329.4 -205.9 L1354.8 -191.9 L1378.9 -177.3 L1402.2 -162.4 L1424.7 -147.2 L1446.5 -131.7 L1467.6 -115.7 L1487.6 -98.9 L1506.2 -81.2 L1523.1 -62.4 L1537.6 -42.6 L1549.6 -21.7 L1558.7 -0.0 L1565.0 22.1 L1568.6 44.5 L1569.9 66.9 L1569.6 88.9 L1568.2 110.6 L1566.5 132.0Z"/>
|
||||
<path d="M1615.2 132.0 L1622.6 156.2 L1630.2 181.3 L1637.3 207.6 L1642.9 235.0 L1645.8 263.3 L1645.0 291.9 L1639.7 320.4 L1629.2 347.8 L1613.3 373.5 L1592.2 396.6 L1566.3 416.7 L1536.4 433.4 L1503.7 446.6 L1469.1 456.4 L1433.8 463.3 L1398.6 467.8 L1364.2 470.8 L1331.1 473.0 L1299.3 475.0 L1268.6 477.4 L1238.8 480.4 L1209.4 484.1 L1179.9 488.3 L1150.0 492.5 L1119.4 496.3 L1088.1 499.0 L1056.1 500.0 L1024.0 498.9 L991.9 495.2 L960.5 488.9 L929.9 480.1 L900.7 468.9 L872.8 455.6 L846.2 440.8 L820.8 424.8 L796.4 407.8 L772.7 390.1 L749.4 371.7 L726.6 352.6 L704.4 332.7 L683.2 311.6 L663.4 289.2 L646.0 265.4 L631.7 240.3 L621.2 214.0 L615.4 186.9 L614.7 159.4 L619.2 132.0 L628.7 105.3 L642.7 79.9 L660.5 56.0 L680.8 33.9 L702.7 13.6 L724.8 -5.4 L746.4 -23.2 L766.6 -40.6 L785.2 -58.1 L802.0 -76.3 L817.4 -95.5 L832.2 -115.9 L847.0 -137.5 L862.8 -160.0 L880.4 -182.7 L900.6 -205.0 L923.7 -225.9 L949.9 -244.8 L979.1 -260.7 L1010.9 -273.0 L1044.5 -281.6 L1079.4 -286.1 L1114.8 -286.9 L1150.0 -284.3 L1184.5 -278.9 L1218.1 -271.2 L1250.5 -261.9 L1281.8 -251.5 L1312.1 -240.4 L1341.6 -228.8 L1370.5 -216.7 L1398.7 -203.9 L1426.1 -190.3 L1452.5 -175.5 L1477.5 -159.3 L1500.7 -141.5 L1521.5 -122.1 L1539.6 -101.2 L1554.8 -79.0 L1567.0 -55.8 L1576.5 -32.0 L1583.6 -8.1 L1589.1 15.7 L1593.7 39.3 L1598.1 62.5 L1602.9 85.5 L1608.5 108.6 L1615.2 132.0Z"/>
|
||||
</g>
|
||||
<g class="rise">
|
||||
<text x="88" y="196" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="84" font-weight="800" letter-spacing="-2.5" fill="#EEF3EF">AI Job Search</text>
|
||||
</g>
|
||||
<g class="rise d1">
|
||||
<text x="92" y="250" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="28" font-weight="500" fill="#9FE0CF" fill-opacity=".92">The job search that runs on your machine.</text>
|
||||
</g>
|
||||
<g class="rise d2">
|
||||
<rect x="92" y="306" width="440" height="52" rx="14" fill="#0A1A20" stroke="#9FE0CF" stroke-opacity=".16"/>
|
||||
<text x="114" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#F4704F">›</text>
|
||||
<g class="cmd c0"><text x="142" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" fill="#EEF3EF">/setup</text><g class="v0"><rect x="142" y="314" width="103" height="36" fill="#0A1A20"/><rect class="caret" x="142" y="320" width="11" height="26" rx="2" fill="#9FE0CF"/></g></g><g class="cmd c1"><text x="142" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" fill="#EEF3EF">/scrape</text><g class="v1"><rect x="142" y="314" width="116" height="36" fill="#0A1A20"/><rect class="caret" x="142" y="320" width="11" height="26" rx="2" fill="#9FE0CF"/></g></g><g class="cmd c2"><text x="142" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" fill="#EEF3EF">/rank</text><g class="v2"><rect x="142" y="314" width="90" height="36" fill="#0A1A20"/><rect class="caret" x="142" y="320" width="11" height="26" rx="2" fill="#9FE0CF"/></g></g><g class="cmd c3"><text x="142" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" fill="#EEF3EF">/apply <posting-url></text><g class="v3"><rect x="142" y="314" width="288" height="36" fill="#0A1A20"/><rect class="caret" x="142" y="320" width="11" height="26" rx="2" fill="#9FE0CF"/></g></g><g class="cmd c4"><text x="142" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" fill="#EEF3EF">/interview</text><g class="v4"><rect x="142" y="314" width="156" height="36" fill="#0A1A20"/><rect class="caret" x="142" y="320" width="11" height="26" rx="2" fill="#9FE0CF"/></g></g><g class="cmd c5"><text x="142" y="341" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" fill="#EEF3EF">/outcome</text><g class="v5"><rect x="142" y="314" width="130" height="36" fill="#0A1A20"/><rect class="caret" x="142" y="320" width="11" height="26" rx="2" fill="#9FE0CF"/></g></g>
|
||||
<text x="92" y="404" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="18" fill="#EEF3EF" fill-opacity=".55">Built on Claude Code. Your profile, your files, your machine.</text>
|
||||
</g>
|
||||
<path d="M 720 396 C 830 414, 860 262, 960 256 S 1030 182, 1060 166" fill="none" stroke="#9FE0CF" stroke-opacity=".32" stroke-width="2.5" stroke-linecap="round" stroke-dasharray="1 11" class="flow"/>
|
||||
<path d="M 720 396 C 830 414, 860 262, 960 256 S 1030 182, 1060 166" pathLength="1" fill="none" stroke="url(#trailg)" stroke-width="3" stroke-linecap="round" stroke-dasharray="1 1" class="trail"/>
|
||||
<g transform="translate(676 374)">
|
||||
<g transform="rotate(-8)"><rect x="0" y="10" width="46" height="32" rx="3" fill="#d9e3de" stroke="#9fb3ab" stroke-width="1.5"/><path d="M2 12 L23.0 27.6 L44 12" fill="none" stroke="#9fb3ab" stroke-width="1.6" stroke-linejoin="round"/></g>
|
||||
<g transform="rotate(4)"><rect x="8" y="2" width="46" height="32" rx="3" fill="#EEF3EF" stroke="#9fb3ab" stroke-width="1.5"/><path d="M10 4 L31.0 19.6 L52 4" fill="none" stroke="#9fb3ab" stroke-width="1.6" stroke-linejoin="round"/></g>
|
||||
</g>
|
||||
<circle class="ring" cx="1150" cy="132" r="26" fill="none" stroke="#F4704F" stroke-width="2"/>
|
||||
<circle class="ring ring2" cx="1150" cy="132" r="26" fill="none" stroke="#9FE0CF" stroke-width="1.5"/>
|
||||
<g class="pin">
|
||||
<path d="M1150 136 c-14-18-22-28-22-40 a22 22 0 0 1 44 0 c0 12-8 22-22 40z" fill="#F4704F"/>
|
||||
<circle cx="1150" cy="96" r="8" fill="#0F2229"/>
|
||||
</g>
|
||||
<ellipse cx="1150" cy="138" rx="12" ry="3.5" fill="#0A1A20" fill-opacity=".7"/>
|
||||
<g class="pip"><g class="bob">
|
||||
<image href="data:image/gif;base64,R0lGODlhMAIwAocAACqdjx9vZedvUZaboP///+Y5RiIzO/8A/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQJCwAHACwAAAAAMAIwAgAI/wAPCBxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqTJkyhTqlzJsqXLlzBjypxJs6bNmzhz6tzJs6fPn0CDCh1KtKjRo0iTKl3KtKnTp1CjSp1KtarVq1izat3KtavXr2DDih1LtqzZs2jTql3Ltq3bt3Djyp1Lt67du3jz6t3Lt6/fv4ADCx5MuLDhw4gTK17MuLHjx5AjS55MubLly5gza97MubPnz6BDix5NurTp06hTq17NurXr17Bjy55Nu7bt27hz697Nu7fv38CDCx9OvLjx48iTK1/OvLnz59CjS59Ovbr169iza9/Ovbv37+DDi/8fT768+fPo06tfz769+/fw48ufT7++/fv48+vfz7+///8ABijggAQWaOCBCCao4IIMNujggxBGKOGEFFZo4YUYZqjhhhx26OGHIIYo4ogklmjiiSimqOKKLLbo4oswxijjjDTWaOONOOao44489ujjj40NIOQAAQQgpJFAmjeAAUw2yWQASZa3pJNNQhnleFNSaYCVV4aXJZUDdCnel06GKSZ4ZDZp5pnepfkkm9+5uSWcbWrJ5Jp0TjckQVMGQCWXeUbnZpGEFmpooXgGapyfWgYAwKFF2jlnR0NWKqSiojH6J6SR2gloRnJWOSmmmmnqJKedNkqppFqSupmpVaL/KumnGIVKpauleiqrp6uy6iSumcH65K6qcmTrr8BeJuyWxP7Zq69MJqusrpzO+iy0iUoL2bKoLjuqRseqqS1l3HZL6KmW7klRuHeOO1m55h4qabYFpTvko4bO665k8MZ7rrUKsVptq/tG1q+/qYK5kMDy2lmwwdQi7K0B9BLkJ6wDE/ywYwcjrK9C3kIq6caPzSrxv1pWPFDIDadMcmMmn+ytygKxnK+dNL8sWMwnf5wQwze7rLNiPEvs80FyZnzr0IklLfPMCjndssJMHyZ1zzhHHXHLhTb6bdV7XW30rBUPirXDYPcltscCI2T22GinHXbRbLOq7kBv162x3Hmt//00yuLivXW8rPI99+B/J/zkpQf43ezShtslJAB0Jz6xQI4rDXnkcx1r+dRL92k5wJzPNTGzn3fN6wEXf0566XGdnnrQzi45++uwp5UutLOrrqrtqeOeu1nsntq74lU2jvroqw+P1umIM6/r8okL7/xY0Dd6fPa3N399Wdlvejy0w0rv7PdmhW/89uQH7z36YrEc/fjz+2s9/F7Jr/32tK//9/3444rN6ue+/f3vfQHMX+Uwxj+bHbBYCQSLA31XPvYR0FwAjCBWJgg46vVugfbLoAatwkHFNbCEcPuTvXI2QqagUHwWNCD9stZCqqDQVCcEofmoVkOp3NB/M4RhEP952EOo/DBW/ANaDDdXxKccsYJDBOIH49ZEJ4JQiie8YQrLVEUjXhGJWewgFs9GxC4uRYnVCmP/wFg9GmrkYuRrH6HsZcaFhCqEUEziBQlHxYzE8Y/YqmNCMkc7NepQb8jaiPoAeTRB8umQgDPkHjHYR4wskpFCc2S9IJkwSU5Sc4l8IyZH2S5NbnKSMowiG2VWOI5ckpSlNKXgUClEVeaRjEzECCxHycIqEpKCt+zeJ0U2Mo7sEpO9bOIvgZlFNLKymBs5JiOTWcRlBk2NU3vg3mr1SlhSs4fW9B02uTbFidwRAOhMpzrXyU51dutRdqtjOFU3zmuWUyLnbKc+98n/T3TG04zzrGez7hmRfPbzoAeFGkA5KdBuOZNt38QcqxBK0X4qtIsBbSjoxkg4WjUkVBUNaTsv6kuGapSYwzwUAFaoNUmJ9KXpJKkyTXrSNa4Sl4Fz20Rh+lKZVpOmNRXjTbeYU6TtlKch/SdGgRrUibnOjUb1FFJF6lNwMjWovtph4Ij0zqlO1VHuxBekWpjRpma1jULjllfXus+qoq+sWH0oIgOnVrba1Z3QjCBca3pWbXKRdVK9q2C9RdarNnVgfhVX0gQ72Ebib6+HJSdO27VYxtrVrd+DbGTF+UyXCcyyl3Us/DS72VQ9bV4GBe1XRftWw5ZWqENFnppSq1qe/xJ2hKQtbV9RmjKuQqq2a8XY4uh4vTu+Fq31+yxwl7tOzBrOVsdNLEedytzqotO5fINudDtLwFlZt7rYlZt2t0vU6Ybsu8wNb9rGS148djew6K2tesHG3vZS8pDeja98WRu54sWWvLvl7an0u1+o5k50sq2lfQNs0ycRWLXz5dyQtLhdOTZ4Sw8GbYRh1zH73rd+GbbshkvXYQ8/7k8hbp39itRT/qKvxCYWMIof3E0MU9XF33thjIE5YwLXGKwhHTHnRrlj2DqYxqQEckWFHDkiF/l0KU5yiw2cwFc+GcoZ/vGUM6lB/wazvb6KMpG3XMYEeu5fVw5zlqV8YyoH0P+4Mv6yWY/qY1LClMnPlSuF+arnwQqUnwEogJ0EMABCF9rQQhKAoodE6P7q2bUazWpjXUrmAetT0ZjOdAE2zelOe7rTjv5iKhes3NDCN8j5bacAPs3pTLv61asuQKjnB+mGSvqu5610lfYZa1Z7GtaalnWea03qVLM11yItNTt77esCANvVzp71qK98YkubulEwVfY6mf3rZ7862sNO6ZNvfe0eJ9XYj0ont1vt7W8LQNoKpna1j1xua5/71NvudLu9DW4JT1vecab3sdFNUW2rM9b7bne/4e1BgINy17iGoo2TTXB1Ozvh+47ovvLm8IcLPMQjVTJCV41xjOs71lX/IzaAKw7yqZb85dAW9tBUXmGWt5ynMM85yVMu7h3T+eZrJbnOTS5zndE8uj8HussvDvNNJ3zTPP93xyemdLsy++ncVnjRXwbjqSe96jBdt9OH7u6qcXzqPG4S2L0aALEzneyYXriJVkj3utv9bi2NN9ptvnaEtt3pzQ684EGdIi9L8/B6Hze++05VX8Md1ioyPOInj3ZkM/6lSr1SnybPeQt3nO+X52fmoyT5zh+z8qAPvT7xLKPSmx6WqF+86hOK4x25/vVO/nzqZ9/cvGoe98BPvM93z/t0tlJMtw8+IL1O/OJTzvekV770mS97548U+klaZkL1KPUYG9z6169k//abj+SjP9XzIgd/+LcZ/eor3amv/WP61d9W7AOpspeHv27jOH/6rz+X4+d+QKd/myV//ud39vcj+Md4BBhZBniA/SRCPLKAfdeAh/WAELhPEmh7X1d1Fjhn7ZOBoodA2bdC/fd+enZSYyaC6rSBvyeA6PWBccVIJ+h/Lth+djKADvVf2LSCLOhPJEgnIKV60sd/7JR2E8eCIYMrQxh6RRiCGhgzSniDAZiDRPiE5NZOUAiBS+gqTXh5WJiF7LSFB9iFpPKFjBeG32d8vCOCZogptLV2ash32eOGVHh/a6h0cwiDbCiGzveGcGiChiKHe2huIwgt/geI49Jha7ZRyv9Xgy3YhvSniNqiPpB4c2pEUUZmACLWO7QXhMliiT9YXWTYcoWyei61MaI4issVR2w1AAQQi7I4i7RYi7P4JfPnLQCgihjIiqrlimwHi7Y4jMSIi//nJLv4MKvoixBGPsEljMQYjbEoLLlYe6SyjMwIXEpkW9AojcPoJqjoZtKCjdmoYUbYU93ojbcoJFZ4hNYYiJZSV+XYjKWoiemojgTgJpMTjhA0NIL4W/MoWIgIU/fojYMSiwPAj+fDOZYXkGwnRyFVkN/oVAhZQUyyUixFYuTnkID2R0dIKOwkkbZ4OsIoJxpXNQ3JkUj1R7BId2JlJHVHi55SiyYZQCmpkl7/5SsiSQCL1I04Q5PvyDc3iZMraTfR2JO3mDJAKY65M5REmW1GSYxIiY+yWJP4o4tPeVk8NiRVOSTTJCRUmY9BKTdYmZWMNTMVeUxUaZXwU5ZmiVLine truncated
|
||||
</g></g>
|
||||
</g>
|
||||
<rect x=".5" y=".5" width="1279" height="479" rx="27.5" fill="none" stroke="#9FE0CF" stroke-opacity=".14"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 63 KiB |
@@ -0,0 +1,37 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 360" width="1280" height="360" role="img" aria-labelledby="t d">
|
||||
<title id="t">The author's own search</title>
|
||||
<desc id="d">69 envelopes for 69 tailored applications. 20 light up as first interviews, and one is sealed as the signed contract.</desc>
|
||||
<style>
|
||||
.env{animation:drop 14s cubic-bezier(.2,.8,.2,1) both infinite}
|
||||
.iv{animation:iv 14s ease-out both infinite}
|
||||
.ct{transform-box:fill-box;transform-origin:center;animation:ct 14s cubic-bezier(.3,1.6,.5,1) both infinite}
|
||||
.burst{transform-box:fill-box;transform-origin:center;animation:burst 14s ease-out both infinite}
|
||||
.l1{animation:lg1 14s ease-out both infinite}.l2{animation:lg2 14s ease-out both infinite}.l3{animation:lg3 14s ease-out both infinite}
|
||||
@keyframes drop{0%{opacity:0;transform:translateY(-10px)}4%,90%{opacity:1;transform:none}96%,100%{opacity:0;transform:none}}
|
||||
@keyframes iv{0%,24%{opacity:0}28%,88%{opacity:1}94%,100%{opacity:0}}
|
||||
@keyframes ct{0%,40%{opacity:0;transform:scale(.4)}44%,88%{opacity:1;transform:scale(1.18)}94%,100%{opacity:0;transform:scale(1.18)}}
|
||||
@keyframes burst{0%,42%{opacity:0;transform:scale(.3)}44%{opacity:.9}56%,100%{opacity:0;transform:scale(2.2)}}
|
||||
@keyframes lg1{0%,6%{opacity:0;transform:translateY(8px)}12%,90%{opacity:1;transform:none}96%,100%{opacity:0}}
|
||||
@keyframes lg2{0%,26%{opacity:0;transform:translateY(8px)}32%,90%{opacity:1;transform:none}96%,100%{opacity:0}}
|
||||
@keyframes lg3{0%,43%{opacity:0;transform:translateY(8px)}49%,90%{opacity:1;transform:none}96%,100%{opacity:0}}
|
||||
@media (prefers-reduced-motion: reduce){*{animation:none!important}}
|
||||
@media (prefers-reduced-motion: reduce){.burst{opacity:0}.ct{transform:scale(1.18)}}
|
||||
</style>
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#0F2229"/><stop offset="1" stop-color="#15333C"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="glow" cx="0.75" cy="1.0" r="0.6">
|
||||
<stop offset="0" stop-color="#2A9D8F" stop-opacity=".30"/><stop offset="1" stop-color="#2A9D8F" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="card"><rect width="1280" height="360" rx="28"/></clipPath>
|
||||
|
||||
</defs>
|
||||
<g clip-path="url(#card)">
|
||||
<rect width="1280" height="360" fill="url(#bg)"/>
|
||||
<rect width="1280" height="360" fill="url(#glow)"/>
|
||||
<g class="env" style="animation-delay:0.00s"><rect x="93.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M95.0 54 L112.0 66.3 L129.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.04s"><rect x="141.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M143.0 54 L160.0 66.3 L177.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.09s"><rect x="189.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M191.0 54 L208.0 66.3 L225.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.14s"><rect x="237.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M239.0 54 L256.0 66.3 L273.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/><g class="iv" style="animation-delay:0.08s"><rect x="237.0" y="52" width="38" height="26" rx="3" fill="#2A9D8F" stroke="#9FE0CF" stroke-width="1.5"/><path d="M239.0 54 L256.0 66.3 L273.0 54" fill="none" stroke="#9FE0CF" stroke-width="1.6" stroke-linejoin="round"/></g></g><g class="env" style="animation-delay:0.18s"><rect x="285.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M287.0 54 L304.0 66.3 L321.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/><g class="iv" style="animation-delay:0.11s"><rect x="285.0" y="52" width="38" height="26" rx="3" fill="#2A9D8F" stroke="#9FE0CF" stroke-width="1.5"/><path d="M287.0 54 L304.0 66.3 L321.0 54" fill="none" stroke="#9FE0CF" stroke-width="1.6" stroke-linejoin="round"/></g></g><g class="env" style="animation-delay:0.22s"><rect x="333.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M335.0 54 L352.0 66.3 L369.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/><g class="iv" style="animation-delay:0.13s"><rect x="333.0" y="52" width="38" height="26" rx="3" fill="#2A9D8F" stroke="#9FE0CF" stroke-width="1.5"/><path d="M335.0 54 L352.0 66.3 L369.0 54" fill="none" stroke="#9FE0CF" stroke-width="1.6" stroke-linejoin="round"/></g></g><g class="env" style="animation-delay:0.27s"><rect x="381.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M383.0 54 L400.0 66.3 L417.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/><g class="iv" style="animation-delay:0.16s"><rect x="381.0" y="52" width="38" height="26" rx="3" fill="#2A9D8F" stroke="#9FE0CF" stroke-width="1.5"/><path d="M383.0 54 L400.0 66.3 L417.0 54" fill="none" stroke="#9FE0CF" stroke-width="1.6" stroke-linejoin="round"/></g></g><g class="env" style="animation-delay:0.32s"><rect x="429.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M431.0 54 L448.0 66.3 L465.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.36s"><rect x="477.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M479.0 54 L496.0 66.3 L513.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.40s"><rect x="525.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M527.0 54 L544.0 66.3 L561.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/><g class="iv" style="animation-delay:0.24s"><rect x="525.0" y="52" width="38" height="26" rx="3" fill="#2A9D8F" stroke="#9FE0CF" stroke-width="1.5"/><path d="M527.0 54 L544.0 66.3 L561.0 54" fill="none" stroke="#9FE0CF" stroke-width="1.6" stroke-linejoin="round"/></g></g><g class="env" style="animation-delay:0.45s"><rect x="573.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M575.0 54 L592.0 66.3 L609.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.49s"><rect x="621.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M623.0 54 L640.0 66.3 L657.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/></g><g class="env" style="animation-delay:0.54s"><rect x="669.0" y="52" width="38" height="26" rx="3" fill="#1d3f49" stroke="#3d6664" stroke-width="1.5"/><path d="M671.0 54 L688.0 66.3 L705.0 54" fill="none" stroke="#4f7a77" stroke-width="1.6" stroke-linejoin="round"/><g class="iv" style="animation-delay:0.32s"><rect x="669.0" y="52" width="38" height="26" rx="3" fill="#2A9D8F" stroke="#9FE0CF" stroke-width="1.5"/><path d="M671.0Line truncated
|
||||
<g class="l1"><text x="93.0" y="258" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="56" font-weight="800" letter-spacing="-1.5" fill="#EEF3EF">69</text><text x="93.0" y="292" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="20" fill="#EEF3EF" fill-opacity=".75">tailored applications</text></g><g class="l2"><text x="513.0" y="258" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="56" font-weight="800" letter-spacing="-1.5" fill="#9FE0CF">20</text><text x="513.0" y="292" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="20" fill="#EEF3EF" fill-opacity=".75">first interviews</text></g><g class="l3"><text x="873.0" y="258" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="56" font-weight="800" letter-spacing="-1.5" fill="#F4704F">1</text><text x="873.0" y="292" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="20" fill="#EEF3EF" fill-opacity=".75">signed contract</text></g>
|
||||
</g>
|
||||
<rect x=".5" y=".5" width="1279" height="359" rx="27.5" fill="none" stroke="#9FE0CF" stroke-opacity=".14"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,82 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 256" width="1280" height="256" role="img" aria-labelledby="t d">
|
||||
<title id="t">The workflow</title>
|
||||
<desc id="d">Six commands in order: /setup builds your profile, /scrape finds new postings, /rank shortlists the fits, /apply tailors a CV and cover letter, /interview preps every round, /outcome tracks each result.</desc>
|
||||
<style>
|
||||
.pulse{transform-box:fill-box;transform-origin:center}
|
||||
.courier{animation:go 12s linear infinite}
|
||||
.flow{animation:flow 1.6s linear infinite}
|
||||
.done{animation:done 12s linear infinite}
|
||||
@keyframes go{0%{transform:translateX(0);opacity:0}3%{opacity:1}84%{transform:translateX(1020px);opacity:1}92%,100%{transform:translateX(1020px);opacity:0}}
|
||||
@keyframes done{0%{stroke-dashoffset:1}84%,93%{stroke-dashoffset:0;opacity:1}98%,100%{stroke-dashoffset:0;opacity:0}}
|
||||
@keyframes flow{to{stroke-dashoffset:-24}}
|
||||
.s0 .fill{animation:f0 12s linear infinite}.s0 .pulse{animation:p0 12s ease-out infinite}.s0 .lbl{animation:l0 12s linear infinite}@keyframes f0{0%,0.00%{opacity:0}0.60%,93%{opacity:1}98%,100%{opacity:0}}@keyframes p0{0%,0.00%{transform:scale(.6);opacity:0}0.60%{opacity:.9}9.00%,100%{transform:scale(2.3);opacity:0}}@keyframes l0{0%,0.00%{fill-opacity:.55}0.60%,93%{fill-opacity:1}98%,100%{fill-opacity:.55}}.s1 .fill{animation:f1 12s linear infinite}.s1 .pulse{animation:p1 12s ease-out infinite}.s1 .lbl{animation:l1 12s linear infinite}@keyframes f1{0%,16.79%{opacity:0}17.40%,93%{opacity:1}98%,100%{opacity:0}}@keyframes p1{0%,16.79%{transform:scale(.6);opacity:0}17.40%{opacity:.9}25.80%,100%{transform:scale(2.3);opacity:0}}@keyframes l1{0%,16.79%{fill-opacity:.55}17.40%,93%{fill-opacity:1}98%,100%{fill-opacity:.55}}.s2 .fill{animation:f2 12s linear infinite}.s2 .pulse{animation:p2 12s ease-out infinite}.s2 .lbl{animation:l2 12s linear infinite}@keyframes f2{0%,33.59%{opacity:0}34.20%,93%{opacity:1}98%,100%{opacity:0}}@keyframes p2{0%,33.59%{transform:scale(.6);opacity:0}34.20%{opacity:.9}42.60%,100%{transform:scale(2.3);opacity:0}}@keyframes l2{0%,33.59%{fill-opacity:.55}34.20%,93%{fill-opacity:1}98%,100%{fill-opacity:.55}}.s3 .fill{animation:f3 12s linear infinite}.s3 .pulse{animation:p3 12s ease-out infinite}.s3 .lbl{animation:l3 12s linear infinite}@keyframes f3{0%,50.39%{opacity:0}51.00%,93%{opacity:1}98%,100%{opacity:0}}@keyframes p3{0%,50.39%{transform:scale(.6);opacity:0}51.00%{opacity:.9}59.40%,100%{transform:scale(2.3);opacity:0}}@keyframes l3{0%,50.39%{fill-opacity:.55}51.00%,93%{fill-opacity:1}98%,100%{fill-opacity:.55}}.s4 .fill{animation:f4 12s linear infinite}.s4 .pulse{animation:p4 12s ease-out infinite}.s4 .lbl{animation:l4 12s linear infinite}@keyframes f4{0%,67.19%{opacity:0}67.80%,93%{opacity:1}98%,100%{opacity:0}}@keyframes p4{0%,67.19%{transform:scale(.6);opacity:0}67.80%{opacity:.9}76.20%,100%{transform:scale(2.3);opacity:0}}@keyframes l4{0%,67.19%{fill-opacity:.55}67.80%,93%{fill-opacity:1}98%,100%{fill-opacity:.55}}.s5 .fill{animation:f5 12s linear infinite}.s5 .pulse{animation:p5 12s ease-out infinite}.s5 .lbl{animation:l5 12s linear infinite}@keyframes f5{0%,83.99%{opacity:0}84.60%,93%{opacity:1}98%,100%{opacity:0}}@keyframes p5{0%,83.99%{transform:scale(.6);opacity:0}84.60%{opacity:.9}93.00%,100%{transform:scale(2.3);opacity:0}}@keyframes l5{0%,83.99%{fill-opacity:.55}84.60%,93%{fill-opacity:1}98%,100%{fill-opacity:.55}}
|
||||
@media (prefers-reduced-motion: reduce){*{animation:none!important}}
|
||||
@media (prefers-reduced-motion: reduce){.fill{opacity:1}.done{stroke-dashoffset:0}.courier{opacity:0}}
|
||||
</style>
|
||||
<defs>
|
||||
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0" stop-color="#0F2229"/><stop offset="1" stop-color="#15333C"/>
|
||||
</linearGradient>
|
||||
<radialGradient id="glow" cx="0.55" cy="0.0" r="0.6">
|
||||
<stop offset="0" stop-color="#2A9D8F" stop-opacity=".30"/><stop offset="1" stop-color="#2A9D8F" stop-opacity="0"/>
|
||||
</radialGradient>
|
||||
<clipPath id="card"><rect width="1280" height="256" rx="28"/></clipPath>
|
||||
|
||||
</defs>
|
||||
<g clip-path="url(#card)">
|
||||
<rect width="1280" height="256" fill="url(#bg)"/>
|
||||
<rect width="1280" height="256" fill="url(#glow)"/>
|
||||
<line x1="130" y1="92" x2="1150" y2="92" stroke="#9FE0CF" stroke-opacity=".3" stroke-width="2.5" stroke-linecap="round" stroke-dasharray="1 11" class="flow"/>
|
||||
<line x1="130" y1="92" x2="1150" y2="92" pathLength="1" stroke="#2A9D8F" stroke-width="3" stroke-dasharray="1 1" class="done"/>
|
||||
<g class="s0">
|
||||
<circle class="pulse" cx="130" cy="92" r="20" fill="none" stroke="#9FE0CF" stroke-width="2"/>
|
||||
<circle cx="130" cy="92" r="20" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2"/>
|
||||
<circle class="fill" cx="130" cy="92" r="20" fill="#2A9D8F"/>
|
||||
<circle cx="130" cy="92" r="6" fill="#EEF3EF"/>
|
||||
<text class="lbl" x="130" y="158" text-anchor="middle" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#9FE0CF">/setup</text>
|
||||
<text x="130" y="188" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="17" fill="#EEF3EF" fill-opacity=".72">Build your profile</text>
|
||||
</g>
|
||||
<g class="s1">
|
||||
<circle class="pulse" cx="334" cy="92" r="20" fill="none" stroke="#9FE0CF" stroke-width="2"/>
|
||||
<circle cx="334" cy="92" r="20" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2"/>
|
||||
<circle class="fill" cx="334" cy="92" r="20" fill="#2A9D8F"/>
|
||||
<circle cx="334" cy="92" r="6" fill="#EEF3EF"/>
|
||||
<text class="lbl" x="334" y="158" text-anchor="middle" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#9FE0CF">/scrape</text>
|
||||
<text x="334" y="188" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="17" fill="#EEF3EF" fill-opacity=".72">Find new postings</text>
|
||||
</g>
|
||||
<g class="s2">
|
||||
<circle class="pulse" cx="538" cy="92" r="20" fill="none" stroke="#9FE0CF" stroke-width="2"/>
|
||||
<circle cx="538" cy="92" r="20" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2"/>
|
||||
<circle class="fill" cx="538" cy="92" r="20" fill="#2A9D8F"/>
|
||||
<circle cx="538" cy="92" r="6" fill="#EEF3EF"/>
|
||||
<text class="lbl" x="538" y="158" text-anchor="middle" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#9FE0CF">/rank</text>
|
||||
<text x="538" y="188" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="17" fill="#EEF3EF" fill-opacity=".72">Shortlist the fits</text>
|
||||
</g>
|
||||
<g class="s3">
|
||||
<circle class="pulse" cx="742" cy="92" r="20" fill="none" stroke="#F4704F" stroke-width="2"/>
|
||||
<circle cx="742" cy="92" r="20" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2"/>
|
||||
<circle class="fill" cx="742" cy="92" r="20" fill="#F4704F"/>
|
||||
<circle cx="742" cy="92" r="6" fill="#EEF3EF"/>
|
||||
<text class="lbl" x="742" y="158" text-anchor="middle" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#F4704F">/apply</text>
|
||||
<text x="742" y="188" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="17" fill="#EEF3EF" fill-opacity=".72">Tailor CV + letter</text>
|
||||
</g>
|
||||
<g class="s4">
|
||||
<circle class="pulse" cx="946" cy="92" r="20" fill="none" stroke="#9FE0CF" stroke-width="2"/>
|
||||
<circle cx="946" cy="92" r="20" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2"/>
|
||||
<circle class="fill" cx="946" cy="92" r="20" fill="#2A9D8F"/>
|
||||
<circle cx="946" cy="92" r="6" fill="#EEF3EF"/>
|
||||
<text class="lbl" x="946" y="158" text-anchor="middle" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#9FE0CF">/interview</text>
|
||||
<text x="946" y="188" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="17" fill="#EEF3EF" fill-opacity=".72">Prep every round</text>
|
||||
</g>
|
||||
<g class="s5">
|
||||
<circle class="pulse" cx="1150" cy="92" r="20" fill="none" stroke="#9FE0CF" stroke-width="2"/>
|
||||
<circle cx="1150" cy="92" r="20" fill="#0F2229" stroke="#9FE0CF" stroke-opacity=".35" stroke-width="2"/>
|
||||
<circle class="fill" cx="1150" cy="92" r="20" fill="#2A9D8F"/>
|
||||
<circle cx="1150" cy="92" r="6" fill="#EEF3EF"/>
|
||||
<text class="lbl" x="1150" y="158" text-anchor="middle" font-family="ui-monospace,'SF Mono','JetBrains Mono','Cascadia Code',Menlo,Consolas,monospace" font-size="22" font-weight="700" fill="#9FE0CF">/outcome</text>
|
||||
<text x="1150" y="188" text-anchor="middle" font-family="ui-rounded,'SF Pro Rounded','Nunito','Varela Round','Segoe UI Variable Display','Segoe UI',system-ui,-apple-system,sans-serif" font-size="17" fill="#EEF3EF" fill-opacity=".72">Track each result</text>
|
||||
</g>
|
||||
<g class="courier"><rect x="113" y="42" width="34" height="24" rx="3" fill="#EEF3EF" stroke="#8aa39a" stroke-width="1.5"/><path d="M115 44 L130.0 55.2 L145 44" fill="none" stroke="#8aa39a" stroke-width="1.6" stroke-linejoin="round"/><circle cx="130" cy="57" r="4" fill="#E63946"/></g>
|
||||
</g>
|
||||
<rect x=".5" y=".5" width="1279" height="255" rx="27.5" fill="none" stroke="#9FE0CF" stroke-opacity=".14"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.7 KiB |
Reference in new issue
Block a user