624 lines
28 KiB
HTML
624 lines
28 KiB
HTML
|
|
<!doctype html>
|
|||
|
|
<html lang="en">
|
|||
|
|
<head>
|
|||
|
|
<meta charset="utf-8">
|
|||
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|||
|
|
<title>Carlos Arias — Agentic AI & Automation Engineer</title>
|
|||
|
|
|
|||
|
|
<!-- SOURCE OF TRUTH. Never hardcode a hex in this file. -->
|
|||
|
|
<link rel="stylesheet" href="../brand/tokens.css">
|
|||
|
|
|
|||
|
|
<style>
|
|||
|
|
*, *::before, *::after { box-sizing: border-box; }
|
|||
|
|
html { -webkit-text-size-adjust: 100%; }
|
|||
|
|
body {
|
|||
|
|
margin: 0; background: var(--ca-paper); color: var(--ca-ink);
|
|||
|
|
font-family: var(--ca-sans); font-size: var(--ca-s3);
|
|||
|
|
line-height: var(--ca-lh-body); -webkit-font-smoothing: antialiased;
|
|||
|
|
overflow-x: hidden;
|
|||
|
|
}
|
|||
|
|
a { color: inherit; }
|
|||
|
|
img { max-width: 100%; display: block; }
|
|||
|
|
.shell { max-width: 82rem; margin: 0 auto; padding: 0 var(--ca-gutter); }
|
|||
|
|
|
|||
|
|
/* ================= masthead ================= */
|
|||
|
|
/* The wordmark is absent while the hero signature holds the name,
|
|||
|
|
then fades in as it scrolls away. No redundancy on first screen. */
|
|||
|
|
.masthead {
|
|||
|
|
position: sticky; top: 0; z-index: 20;
|
|||
|
|
display: flex; align-items: center; gap: 1.25rem;
|
|||
|
|
padding: 1.5rem 0;
|
|||
|
|
border-bottom: var(--ca-hairline) solid transparent;
|
|||
|
|
transition: border-color var(--ca-dur-base) var(--ca-ease),
|
|||
|
|
background var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
/* Over the ink hero the bar is transparent with light type; once it
|
|||
|
|
passes onto paper it takes the paper ground. Borrowing only the
|
|||
|
|
two foreground tokens keeps the hexes in tokens.css. */
|
|||
|
|
.masthead:not(.stuck) {
|
|||
|
|
background: transparent;
|
|||
|
|
--ca-ink: var(--ca-ink-surface-fg);
|
|||
|
|
--ca-ink-3: var(--ca-ink-surface-fg-3);
|
|||
|
|
}
|
|||
|
|
.masthead.stuck {
|
|||
|
|
background: color-mix(in srgb, var(--ca-paper) 88%, transparent);
|
|||
|
|
backdrop-filter: blur(8px);
|
|||
|
|
border-bottom-color: var(--ca-rule);
|
|||
|
|
}
|
|||
|
|
.mark {
|
|||
|
|
display: flex; align-items: center; gap: .8rem; text-decoration: none;
|
|||
|
|
opacity: 0; transform: translateY(-6px);
|
|||
|
|
transition: opacity var(--ca-dur-slow) var(--ca-ease), transform var(--ca-dur-slow) var(--ca-ease);
|
|||
|
|
pointer-events: none;
|
|||
|
|
}
|
|||
|
|
.masthead.stuck .mark { opacity: 1; transform: none; pointer-events: auto; }
|
|||
|
|
.mark img { width: 124px; height: auto; }
|
|||
|
|
.seal {
|
|||
|
|
display: inline-flex; align-items: center; justify-content: center;
|
|||
|
|
width: 1.5rem; height: 1.5rem; flex: none;
|
|||
|
|
background: var(--ca-seal); color: #fff;
|
|||
|
|
font-family: var(--ca-serif); font-size: .8rem; line-height: 1;
|
|||
|
|
border-radius: var(--ca-radius);
|
|||
|
|
}
|
|||
|
|
.nav { margin-left: auto; display: flex; gap: 1.4rem; flex-wrap: wrap; justify-content: flex-end; }
|
|||
|
|
.nav a {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1);
|
|||
|
|
letter-spacing: .12em; text-transform: uppercase;
|
|||
|
|
color: var(--ca-ink-3); text-decoration: none;
|
|||
|
|
padding-bottom: 2px; border-bottom: 1px solid transparent;
|
|||
|
|
transition: color var(--ca-dur-base) var(--ca-ease), border-color var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.nav a:hover { color: var(--ca-ink); border-bottom-color: var(--ca-ink); }
|
|||
|
|
|
|||
|
|
/* ================= RULE BREAK 1 ==================
|
|||
|
|
The signature at monumental scale. Japanese calligraphy is
|
|||
|
|
not small and polite — a single stroke fills the paper.
|
|||
|
|
It writes itself, which is the whole thesis in one gesture. */
|
|||
|
|
/* Option A — the hero is an ink surface in both themes; everything
|
|||
|
|
below it is washi paper. A dramatic entrance resolving into
|
|||
|
|
restraint, rather than a dark rectangle pasted onto a light page. */
|
|||
|
|
.hero {
|
|||
|
|
position: relative;
|
|||
|
|
min-height: 92vh;
|
|||
|
|
margin-top: -5.5rem; /* the masthead floats over it */
|
|||
|
|
padding: 8rem 0 clamp(3.5rem, 7vw, 5.5rem);
|
|||
|
|
display: flex; flex-direction: column; justify-content: center;
|
|||
|
|
}
|
|||
|
|
/* kintsugi at the seam where ink meets paper */
|
|||
|
|
.hero::after {
|
|||
|
|
content: ""; position: absolute; left: 12%; bottom: -1px;
|
|||
|
|
width: 46px; height: 2px; background: var(--ca-ink-surface-seal); z-index: 3;
|
|||
|
|
}
|
|||
|
|
.hero-grid { display: block; }
|
|||
|
|
|
|||
|
|
#wash {
|
|||
|
|
position: absolute; inset: 0; width: 100%; height: 100%;
|
|||
|
|
z-index: 0; pointer-events: none;
|
|||
|
|
opacity: 0; transition: opacity 1.6s linear;
|
|||
|
|
}
|
|||
|
|
#wash.on { opacity: 1; }
|
|||
|
|
.hero-inner { position: relative; z-index: 1; }
|
|||
|
|
|
|||
|
|
.signature { margin: 0 0 clamp(1.75rem, 4vw, 2.75rem); }
|
|||
|
|
.signature img {
|
|||
|
|
width: 100%; max-width: 46rem; height: auto;
|
|||
|
|
clip-path: inset(0 100% 0 0);
|
|||
|
|
animation: write 2.1s cubic-bezier(.31, .06, .2, 1) .25s forwards;
|
|||
|
|
}
|
|||
|
|
@keyframes write { to { clip-path: inset(0 -2% 0 0); } }
|
|||
|
|
|
|||
|
|
.hero .eyebrow {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1);
|
|||
|
|
letter-spacing: .18em; text-transform: uppercase;
|
|||
|
|
color: var(--ca-ink-3); margin: 0 0 1.5rem;
|
|||
|
|
}
|
|||
|
|
/* NB: no `.hero h1` sizing rule — h1 is the signature block, and a
|
|||
|
|
max-width here would crush it. The tagline is a <p>. */
|
|||
|
|
.hero .sub {
|
|||
|
|
font-size: var(--ca-s3); line-height: 1.6; color: var(--ca-ink-3);
|
|||
|
|
max-width: 52ch; margin: 1.5rem 0 0;
|
|||
|
|
}
|
|||
|
|
.hero-links { display: flex; gap: 1.75rem; margin-top: 2.25rem; flex-wrap: wrap; align-items: center; }
|
|||
|
|
|
|||
|
|
/* delayed entrance, sequenced behind the signature */
|
|||
|
|
.seq { opacity: 0; transform: translateY(var(--ca-reveal-y)); }
|
|||
|
|
.seq.in { opacity: 1; transform: none;
|
|||
|
|
transition: opacity var(--ca-dur-slow) var(--ca-ease), transform var(--ca-dur-slow) var(--ca-ease); }
|
|||
|
|
|
|||
|
|
.cta {
|
|||
|
|
font-size: var(--ca-s2); font-weight: 500; text-decoration: none;
|
|||
|
|
background: var(--ca-ink); color: var(--ca-paper);
|
|||
|
|
border: 1px solid var(--ca-ink); border-radius: var(--ca-radius);
|
|||
|
|
padding: .8rem 1.4rem;
|
|||
|
|
transition: background var(--ca-dur-base) var(--ca-ease), color var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.cta:hover { background: transparent; color: var(--ca-ink); }
|
|||
|
|
.quiet-link {
|
|||
|
|
font-size: var(--ca-s2); text-decoration: none;
|
|||
|
|
border-bottom: 1px solid var(--ca-ink-4); padding-bottom: 3px;
|
|||
|
|
transition: border-color var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.quiet-link:hover { border-bottom-color: var(--ca-ink); }
|
|||
|
|
|
|||
|
|
/* ================= sections ================= */
|
|||
|
|
/* RULE BREAK 3 — kintsugi. The hairline rule is broken and the
|
|||
|
|
break is filled with vermillion rather than hidden. Wabi-sabi's
|
|||
|
|
actual philosophy: the repair is the beautiful part. */
|
|||
|
|
.band {
|
|||
|
|
padding: clamp(4rem, 8vw, 6.5rem) 0;
|
|||
|
|
border-top: var(--ca-hairline) solid var(--ca-rule);
|
|||
|
|
position: relative;
|
|||
|
|
}
|
|||
|
|
.band::before {
|
|||
|
|
content: ""; position: absolute; top: calc(var(--ca-hairline) * -1);
|
|||
|
|
height: var(--ca-hairline); width: 28px; background: var(--ca-seal);
|
|||
|
|
left: 12%;
|
|||
|
|
}
|
|||
|
|
.band:nth-of-type(even)::before { left: 63%; width: 18px; }
|
|||
|
|
.band:nth-of-type(3n)::before { left: 34%; width: 40px; }
|
|||
|
|
|
|||
|
|
/* ---- brush stroke emphasis ----
|
|||
|
|
A real sumi stroke: blunt where the brush lands, tapering as it
|
|||
|
|
lifts, with kasure (dry-brush breaks) trailing the tail. Drawn as
|
|||
|
|
a mask so the colour comes from --ca-seal and follows the theme.
|
|||
|
|
Applied to emphasis, never to every heading — brushing everything
|
|||
|
|
is the same as brushing nothing. */
|
|||
|
|
.brushed { position: relative; display: inline-block; white-space: nowrap; }
|
|||
|
|
.brushed::after {
|
|||
|
|
content: ""; position: absolute;
|
|||
|
|
left: -.12em; right: -.18em; bottom: -.26em; height: .3em;
|
|||
|
|
background-color: var(--ca-seal);
|
|||
|
|
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 20' preserveAspectRatio='none'%3E%3Cpath d='M3 8C70 4 150 3 230 4.5C300 5.8 355 8 395 11C398 11.6 398 12.6 394 13C350 14.4 295 14 225 13.2C150 12.4 70 13.5 5 17C1 17.4 0 9 3 8Z'/%3E%3Cpath d='M298 14.8C328 15.2 358 15.6 384 15.8' stroke='black' stroke-width='0.9' fill='none' opacity='0.5'/%3E%3Cpath d='M118 15.6C158 16.1 208 16.2 248 16' stroke='black' stroke-width='0.7' fill='none' opacity='0.35'/%3E%3C/svg%3E") no-repeat left center / 100% 100%;
|
|||
|
|
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 20' preserveAspectRatio='none'%3E%3Cpath d='M3 8C70 4 150 3 230 4.5C300 5.8 355 8 395 11C398 11.6 398 12.6 394 13C350 14.4 295 14 225 13.2C150 12.4 70 13.5 5 17C1 17.4 0 9 3 8Z'/%3E%3Cpath d='M298 14.8C328 15.2 358 15.6 384 15.8' stroke='black' stroke-width='0.9' fill='none' opacity='0.5'/%3E%3Cpath d='M118 15.6C158 16.1 208 16.2 248 16' stroke='black' stroke-width='0.7' fill='none' opacity='0.35'/%3E%3C/svg%3E") no-repeat left center / 100% 100%;
|
|||
|
|
clip-path: inset(0 100% 0 0);
|
|||
|
|
}
|
|||
|
|
/* The stroke paints on — same left-to-right gesture as the signature. */
|
|||
|
|
.in .brushed::after, .seq.in .brushed::after {
|
|||
|
|
clip-path: inset(0 0 0 0);
|
|||
|
|
transition: clip-path 900ms cubic-bezier(.31, .06, .2, 1) 160ms;
|
|||
|
|
}
|
|||
|
|
.mission .brushed::after { background-color: #fff; }
|
|||
|
|
|
|||
|
|
.band-head { display: flex; align-items: baseline; gap: 1.5rem; margin-bottom: 3rem; flex-wrap: wrap; }
|
|||
|
|
.band-head h2 {
|
|||
|
|
font-family: var(--ca-serif); font-weight: 400; font-size: var(--ca-s6);
|
|||
|
|
line-height: var(--ca-lh-head); margin: 0; letter-spacing: -.01em;
|
|||
|
|
}
|
|||
|
|
.band-head .aside {
|
|||
|
|
margin-left: auto; font-family: var(--ca-mono); font-size: var(--ca-s1);
|
|||
|
|
letter-spacing: .1em; text-transform: uppercase; color: var(--ca-ink-4);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* scroll reveal */
|
|||
|
|
.rv { opacity: 0; transform: translateY(var(--ca-reveal-y)); }
|
|||
|
|
.rv.in { opacity: 1; transform: none;
|
|||
|
|
transition: opacity var(--ca-dur-slow) var(--ca-ease), transform var(--ca-dur-slow) var(--ca-ease); }
|
|||
|
|
|
|||
|
|
/* ================= capabilities ================= */
|
|||
|
|
.caps { display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr)); gap: 0 3.5rem; }
|
|||
|
|
.cap-item { padding: 1.5rem 0; border-top: var(--ca-hairline) solid var(--ca-rule); }
|
|||
|
|
.cap-item h3 {
|
|||
|
|
font-family: var(--ca-serif); font-weight: 400; font-size: var(--ca-s5);
|
|||
|
|
line-height: var(--ca-lh-head); margin: 0 0 .5rem; letter-spacing: -.01em;
|
|||
|
|
}
|
|||
|
|
.cap-item p { margin: 0; font-size: var(--ca-s2); color: var(--ca-ink-3); max-width: 44ch; }
|
|||
|
|
|
|||
|
|
/* ================= work index ================= */
|
|||
|
|
.index { display: flex; flex-direction: column; }
|
|||
|
|
.entry {
|
|||
|
|
display: grid; grid-template-columns: 1.5rem minmax(0, 1fr) auto;
|
|||
|
|
align-items: baseline; gap: 0 1.5rem;
|
|||
|
|
padding: 1.6rem 0; border-bottom: var(--ca-hairline) solid var(--ca-rule);
|
|||
|
|
text-decoration: none; transition: border-color var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.entry:first-child { border-top: var(--ca-hairline) solid var(--ca-rule); }
|
|||
|
|
.entry .tick {
|
|||
|
|
color: var(--ca-seal); font-family: var(--ca-mono);
|
|||
|
|
opacity: 0; transform: translateX(-.4rem);
|
|||
|
|
transition: opacity var(--ca-dur-base) var(--ca-ease), transform var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.entry:hover .tick, .entry:focus-visible .tick { opacity: 1; transform: translateX(0); }
|
|||
|
|
.entry:hover, .entry:focus-visible { border-bottom-color: var(--ca-seal); }
|
|||
|
|
.entry .title {
|
|||
|
|
font-family: var(--ca-serif); font-weight: 400; font-size: var(--ca-s5);
|
|||
|
|
line-height: var(--ca-lh-head); letter-spacing: -.01em;
|
|||
|
|
}
|
|||
|
|
.entry .desc {
|
|||
|
|
grid-column: 2; font-size: var(--ca-s2); color: var(--ca-ink-3);
|
|||
|
|
margin-top: .5rem; max-width: 56ch;
|
|||
|
|
}
|
|||
|
|
.entry .yr {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1); color: var(--ca-ink-4);
|
|||
|
|
font-variant-numeric: tabular-nums; letter-spacing: .06em; white-space: nowrap;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ================= RULE BREAK 2 ==================
|
|||
|
|
One full-bleed vermillion moment. The 1–2% seal rule is held
|
|||
|
|
everywhere else on the site, which is exactly what lets this
|
|||
|
|
land. An exception only reads as intentional when the rule
|
|||
|
|
is otherwise absolute. */
|
|||
|
|
.mission {
|
|||
|
|
background: var(--ca-seal); color: #fff;
|
|||
|
|
padding: clamp(5rem, 12vw, 9rem) 0;
|
|||
|
|
margin: 0; position: relative;
|
|||
|
|
}
|
|||
|
|
.mission .shell { display: flex; flex-direction: column; gap: 2rem; align-items: flex-start; }
|
|||
|
|
.mission p {
|
|||
|
|
font-family: var(--ca-serif); font-weight: 400;
|
|||
|
|
font-size: clamp(2rem, 6vw, 4.209rem);
|
|||
|
|
line-height: 1.1; letter-spacing: -.02em;
|
|||
|
|
margin: 0; max-width: 17ch; text-wrap: balance;
|
|||
|
|
}
|
|||
|
|
.mission .attrib {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1);
|
|||
|
|
letter-spacing: .16em; text-transform: uppercase; opacity: .72;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ================= about ================= */
|
|||
|
|
.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3rem; }
|
|||
|
|
@media (min-width: 60rem) { .split { grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 5rem; } }
|
|||
|
|
.prose p { margin: 0 0 1.35rem; max-width: var(--ca-measure); color: var(--ca-ink-2); }
|
|||
|
|
.prose p:last-child { margin-bottom: 0; }
|
|||
|
|
.facts { margin: 0; align-self: start; display: flex; flex-direction: column; }
|
|||
|
|
.facts > div { padding: .9rem 0; border-bottom: var(--ca-hairline) solid var(--ca-rule); }
|
|||
|
|
.facts > div:first-child { border-top: var(--ca-hairline) solid var(--ca-rule); }
|
|||
|
|
.facts dt {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1); letter-spacing: .1em;
|
|||
|
|
text-transform: uppercase; color: var(--ca-ink-4); margin-bottom: .3rem;
|
|||
|
|
}
|
|||
|
|
.facts dd {
|
|||
|
|
margin: 0; font-family: var(--ca-serif); font-size: var(--ca-s4);
|
|||
|
|
line-height: 1.25; color: var(--ca-ink);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ================= concepts ================= */
|
|||
|
|
.concepts { display: flex; flex-wrap: wrap; gap: .6rem .5rem; max-width: 62rem; padding: 0; margin: 0; }
|
|||
|
|
.concepts li { list-style: none; }
|
|||
|
|
.concept {
|
|||
|
|
display: inline-block; font-family: var(--ca-mono); font-size: var(--ca-s1);
|
|||
|
|
letter-spacing: .06em; color: var(--ca-ink-3);
|
|||
|
|
border: var(--ca-hairline) solid var(--ca-rule); border-radius: var(--ca-radius);
|
|||
|
|
padding: .4rem .75rem;
|
|||
|
|
transition: border-color var(--ca-dur-base) var(--ca-ease), color var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.concept:hover { border-color: var(--ca-ink-3); color: var(--ca-ink); }
|
|||
|
|
|
|||
|
|
.industries {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1); letter-spacing: .1em;
|
|||
|
|
text-transform: uppercase; color: var(--ca-ink-4); line-height: 2;
|
|||
|
|
max-width: 62rem; margin: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ================= closing ================= */
|
|||
|
|
.closing { display: flex; flex-direction: column; gap: 2rem; align-items: flex-start; }
|
|||
|
|
.closing h2 {
|
|||
|
|
font-family: var(--ca-serif); font-weight: 400;
|
|||
|
|
font-size: clamp(1.777rem, 4.5vw, 3.157rem);
|
|||
|
|
line-height: var(--ca-lh-tight); margin: 0;
|
|||
|
|
max-width: 18ch; text-wrap: balance; letter-spacing: -.01em;
|
|||
|
|
}
|
|||
|
|
.closing .mailto {
|
|||
|
|
font-size: var(--ca-s4); text-decoration: none;
|
|||
|
|
border-bottom: 1px solid var(--ca-ink-4); padding-bottom: 4px;
|
|||
|
|
transition: border-color var(--ca-dur-base) var(--ca-ease);
|
|||
|
|
}
|
|||
|
|
.closing .mailto:hover { border-bottom-color: var(--ca-ink); }
|
|||
|
|
|
|||
|
|
footer {
|
|||
|
|
border-top: var(--ca-hairline) solid var(--ca-rule); padding: 2.25rem 0 4rem;
|
|||
|
|
display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
|
|||
|
|
}
|
|||
|
|
footer span, footer a {
|
|||
|
|
font-family: var(--ca-mono); font-size: var(--ca-s1); letter-spacing: .1em;
|
|||
|
|
text-transform: uppercase; color: var(--ca-ink-4); text-decoration: none;
|
|||
|
|
}
|
|||
|
|
footer a:hover { color: var(--ca-ink-2); }
|
|||
|
|
footer .right { margin-left: auto; display: flex; gap: 1.5rem; flex-wrap: wrap; }
|
|||
|
|
|
|||
|
|
a:focus-visible, .entry:focus-visible { outline: 2px solid var(--ca-seal); outline-offset: 4px; }
|
|||
|
|
.mission a:focus-visible { outline-color: #fff; }
|
|||
|
|
|
|||
|
|
@media (prefers-reduced-motion: reduce) {
|
|||
|
|
*, *::before, *::after { animation: none !important; transition: none !important; }
|
|||
|
|
.signature img { clip-path: none; }
|
|||
|
|
.seq, .rv { opacity: 1; transform: none; }
|
|||
|
|
.mark { opacity: 1; transform: none; pointer-events: auto; }
|
|||
|
|
.entry .tick { opacity: 1; transform: none; }
|
|||
|
|
#wash { display: none; }
|
|||
|
|
}
|
|||
|
|
@media (prefers-color-scheme: dark) { .mark img, .signature img { filter: invert(1); } }
|
|||
|
|
:root[data-theme="dark"] .mark img, :root[data-theme="dark"] .signature img { filter: invert(1); }
|
|||
|
|
:root[data-theme="light"] .mark img, :root[data-theme="light"] .signature img { filter: none; }
|
|||
|
|
/* ...except on the ink hero, where it is always white */
|
|||
|
|
.hero .signature img,
|
|||
|
|
:root[data-theme="light"] .hero .signature img,
|
|||
|
|
:root[data-theme="dark"] .hero .signature img { filter: invert(1); }
|
|||
|
|
.masthead:not(.stuck) .mark img,
|
|||
|
|
:root[data-theme="light"] .masthead:not(.stuck) .mark img { filter: invert(1); }
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
|
|||
|
|
<header class="masthead" id="masthead">
|
|||
|
|
<div class="shell" style="display:flex;align-items:center;gap:1.25rem;width:100%">
|
|||
|
|
<a class="mark" href="/">
|
|||
|
|
<img src="../.reference_files/CarlosArias-Brand-Logo.svg" alt="Carlos Arias">
|
|||
|
|
<span class="seal" aria-hidden="true">印</span>
|
|||
|
|
</a>
|
|||
|
|
<nav class="nav">
|
|||
|
|
<a href="#work">My Projects</a>
|
|||
|
|
<a href="/resume.pdf">Resume</a>
|
|||
|
|
<a href="#about">About</a>
|
|||
|
|
<a href="/blog">Blog</a>
|
|||
|
|
<a href="#contact">Contact Me</a>
|
|||
|
|
</nav>
|
|||
|
|
</div>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
<section class="hero ca-ink-surface">
|
|||
|
|
<canvas id="wash" aria-hidden="true"></canvas>
|
|||
|
|
<div class="shell hero-inner">
|
|||
|
|
<div class="hero-grid">
|
|||
|
|
|
|||
|
|
<div>
|
|||
|
|
<h1 class="signature" aria-label="Carlos Arias">
|
|||
|
|
<img src="../.reference_files/CarlosArias-Brand-Logo.svg" alt="">
|
|||
|
|
</h1>
|
|||
|
|
<div class="seq" id="seq1">
|
|||
|
|
<p class="eyebrow">Agentic AI & Automation Engineer</p>
|
|||
|
|
<p style="font-family:var(--ca-serif);font-weight:400;font-size:clamp(1.6rem,3.2vw,2.4rem);line-height:1.22;letter-spacing:-.01em;text-wrap:balance;margin:0;max-width:24ch">Autonomous systems that do the work teams used to do <span class="brushed">by hand.</span></p>
|
|||
|
|
<p class="sub">I design and build AI agents and intelligent business systems that automate complex workflows end to end. 26 years as a software engineer — since 2022, focused entirely on agentic AI.</p>
|
|||
|
|
<div class="hero-links">
|
|||
|
|
<a class="cta" href="#contact">Let's build your autonomous system →</a>
|
|||
|
|
<a class="quiet-link" href="#work">See the work</a>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<div class="shell">
|
|||
|
|
|
|||
|
|
<section class="band rv" id="expertise">
|
|||
|
|
<div class="band-head">
|
|||
|
|
<h2><span class="brushed">What I build</span></h2>
|
|||
|
|
<span class="aside">Capabilities</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="caps">
|
|||
|
|
<div class="cap-item"><h3>Agentic AI systems</h3><p>Multi-agent architectures where AI agents collaborate to solve complex business problems end to end.</p></div>
|
|||
|
|
<div class="cap-item"><h3>AI automation</h3><p>Replacing repetitive business processes with intelligent, autonomous workflows.</p></div>
|
|||
|
|
<div class="cap-item"><h3>Autonomous websites</h3><p>Sites that continuously improve their own SEO, content, UX, and conversions using AI.</p></div>
|
|||
|
|
<div class="cap-item"><h3>AI product engineering</h3><p>AI-first SaaS platforms designed and shipped from concept to production.</p></div>
|
|||
|
|
<div class="cap-item"><h3>Intelligent marketing systems</h3><p>AI that runs technical SEO, content planning, competitor research, and optimization on its own.</p></div>
|
|||
|
|
<div class="cap-item"><h3>Software architecture</h3><p>APIs, cloud architecture, automation pipelines, distributed systems, and scalable backends.</p></div>
|
|||
|
|
<div class="cap-item"><h3>Fractional CTO</h3><p>Technology leadership for startups building AI products.</p></div>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="band rv" id="work">
|
|||
|
|
<div class="band-head">
|
|||
|
|
<h2><span class="brushed">Current work</span></h2>
|
|||
|
|
<span class="aside">2014 — present</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="index">
|
|||
|
|
<a class="entry" href="#work">
|
|||
|
|
<span class="tick" aria-hidden="true">—</span>
|
|||
|
|
<span class="title">Agentic Marketing Platform</span>
|
|||
|
|
<span class="yr">In development</span>
|
|||
|
|
<span class="desc">An autonomous digital marketing platform where collaborative agents run technical SEO, competitor research, content planning, local SEO, analytics, and reporting — the full process, run by agents.</span>
|
|||
|
|
</a>
|
|||
|
|
<a class="entry" href="#work">
|
|||
|
|
<span class="tick" aria-hidden="true">—</span>
|
|||
|
|
<span class="title">Medellin.co</span>
|
|||
|
|
<span class="yr">2020 — present</span>
|
|||
|
|
<span class="desc">An AI-powered city platform using RAG, intelligent search, autonomous content generation, and AI assistants for travelers, expats, and local businesses.</span>
|
|||
|
|
</a>
|
|||
|
|
<a class="entry" href="#work">
|
|||
|
|
<span class="tick" aria-hidden="true">—</span>
|
|||
|
|
<span class="title">Snoopi.io</span>
|
|||
|
|
<span class="yr">2014 — present</span>
|
|||
|
|
<span class="desc">A geolocation SaaS platform delivering IP intelligence, APIs, and location services for developers and enterprise applications.</span>
|
|||
|
|
</a>
|
|||
|
|
<a class="entry" href="#work">
|
|||
|
|
<span class="tick" aria-hidden="true">—</span>
|
|||
|
|
<span class="title">Crawllr</span>
|
|||
|
|
<span class="yr">2025 — present</span>
|
|||
|
|
<span class="desc">An intelligent web crawler built for large-scale data collection, knowledge extraction, and AI indexing.</span>
|
|||
|
|
</a>
|
|||
|
|
<a class="entry" href="#work">
|
|||
|
|
<span class="tick" aria-hidden="true">—</span>
|
|||
|
|
<span class="title">Gabii</span>
|
|||
|
|
<span class="yr">In development</span>
|
|||
|
|
<span class="desc">An AI-powered relationship platform using intelligent profiling, compatibility analysis, and autonomous matchmaking.</span>
|
|||
|
|
</a>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<section class="mission rv">
|
|||
|
|
<div class="shell">
|
|||
|
|
<p>Build software that builds, improves, and manages software.</p>
|
|||
|
|
<span class="attrib">The mission</span>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<div class="shell">
|
|||
|
|
|
|||
|
|
<section class="band rv" id="about">
|
|||
|
|
<div class="split">
|
|||
|
|
<div class="prose">
|
|||
|
|
<p>I've been writing software since I was eight years old, on a Commodore 64 in 1988. Nearly four decades later the instinct is unchanged: if a process is repetitive, it should build and run itself.</p>
|
|||
|
|
<p>For 26 years I've worked as a Software Engineer, CTO, Product Engineer, and Technology Advisor across startups and enterprise — leading engineering teams and shipping platforms in FinTech, healthcare, SaaS, digital marketing, and geospatial technology. In FinTech since 2014, which means security and compliance aren't an afterthought: HIPAA, SOC 2, PCI.</p>
|
|||
|
|
<p>Since 2022 my focus has been singular. I don't bolt AI onto existing applications — I design systems where multiple agents collaborate: researching, planning, deciding, generating content, writing software, running QA, and optimizing continuously with minimal human intervention.</p>
|
|||
|
|
</div>
|
|||
|
|
<!-- The portrait now lives in the hero; repeating it here would
|
|||
|
|
be redundant. Facts carry more weight in this slot anyway. -->
|
|||
|
|
<dl class="facts">
|
|||
|
|
<div><dt>Writing code since</dt><dd>1988 — Commodore 64, age 8</dd></div>
|
|||
|
|
<div><dt>Professional experience</dt><dd>26 years</dd></div>
|
|||
|
|
<div><dt>FinTech since</dt><dd>2014</dd></div>
|
|||
|
|
<div><dt>Compliance</dt><dd>HIPAA · SOC 2 · PCI</dd></div>
|
|||
|
|
<div><dt>Focused on agentic AI since</dt><dd>2022</dd></div>
|
|||
|
|
</dl>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="band rv">
|
|||
|
|
<div class="band-head"><h2>Research & concepts</h2><span class="aside">Ongoing</span></div>
|
|||
|
|
<ul class="concepts">
|
|||
|
|
<li><span class="concept">Agentic websites</span></li>
|
|||
|
|
<li><span class="concept">Autonomous SEO systems</span></li>
|
|||
|
|
<li><span class="concept">Multi-agent collaboration</span></li>
|
|||
|
|
<li><span class="concept">AI product architecture</span></li>
|
|||
|
|
<li><span class="concept">Retrieval-augmented generation</span></li>
|
|||
|
|
<li><span class="concept">AI knowledge systems</span></li>
|
|||
|
|
<li><span class="concept">AI workflow orchestration</span></li>
|
|||
|
|
<li><span class="concept">AI-driven software development</span></li>
|
|||
|
|
<li><span class="concept">Self-healing applications</span></li>
|
|||
|
|
<li><span class="concept">Autonomous business systems</span></li>
|
|||
|
|
</ul>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="band rv">
|
|||
|
|
<div class="band-head"><h2>Industries</h2></div>
|
|||
|
|
<p class="industries">Artificial Intelligence · SaaS · FinTech · Healthcare · Legal Technology · Digital Marketing · Location Intelligence · Automation Platforms</p>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="band rv" id="contact">
|
|||
|
|
<div class="closing">
|
|||
|
|
<h2>Automation that actually <span class="brushed">runs itself.</span></h2>
|
|||
|
|
<a class="mailto" href="mailto:hi@carlosarias.com">hi@carlosarias.com</a>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<footer>
|
|||
|
|
<span>© 2026 Carlos Arias</span>
|
|||
|
|
<div class="right">
|
|||
|
|
<a href="https://github.com">GitHub</a>
|
|||
|
|
<a href="https://linkedin.com">LinkedIn</a>
|
|||
|
|
</div>
|
|||
|
|
</footer>
|
|||
|
|
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
(function () {
|
|||
|
|
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|||
|
|
|
|||
|
|
/* ---- masthead: wordmark appears once the hero signature leaves ---- */
|
|||
|
|
var mast = document.getElementById('masthead');
|
|||
|
|
function onScroll() {
|
|||
|
|
if (window.scrollY > window.innerHeight * 0.55) mast.classList.add('stuck');
|
|||
|
|
else mast.classList.remove('stuck');
|
|||
|
|
}
|
|||
|
|
window.addEventListener('scroll', onScroll, { passive: true });
|
|||
|
|
onScroll();
|
|||
|
|
|
|||
|
|
/* ---- sequenced hero entrance, behind the signature ---- */
|
|||
|
|
if (reduce) {
|
|||
|
|
document.querySelectorAll('.seq, .rv').forEach(function (el) { el.classList.add('in'); });
|
|||
|
|
} else {
|
|||
|
|
/* text settles as the signature finishes, portrait a beat later */
|
|||
|
|
setTimeout(function () {
|
|||
|
|
var s = document.getElementById('seq1');
|
|||
|
|
if (s) s.classList.add('in');
|
|||
|
|
}, 1450);
|
|||
|
|
|
|||
|
|
/* ---- scroll reveals ---- */
|
|||
|
|
var io = new IntersectionObserver(function (entries) {
|
|||
|
|
entries.forEach(function (e) {
|
|||
|
|
if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); }
|
|||
|
|
});
|
|||
|
|
}, { rootMargin: '0px 0px -12% 0px', threshold: 0.06 });
|
|||
|
|
document.querySelectorAll('.rv').forEach(function (el) { io.observe(el); });
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* ---- ink wash ----
|
|||
|
|
Ink diffusing into wet paper. Follows the cursor, and keeps
|
|||
|
|
moving on its own when nobody is touching it — the system runs
|
|||
|
|
whether or not you are watching. No particles, no nodes, no glow. */
|
|||
|
|
|
|||
|
|
if (reduce) return;
|
|||
|
|
var cv = document.getElementById('wash');
|
|||
|
|
if (!cv) return;
|
|||
|
|
var ctx = cv.getContext('2d');
|
|||
|
|
var W = 0, H = 0, dpr = Math.min(window.devicePixelRatio || 1, 2);
|
|||
|
|
var blooms = [], last = { x: 0, y: 0 }, t = 0;
|
|||
|
|
|
|||
|
|
function inkRGB() {
|
|||
|
|
/* Read from the hero, not :root — the hero is an ink surface, so its
|
|||
|
|
--ca-ink is the light value. Reading :root would paint near-black
|
|||
|
|
blooms onto a near-black ground and show nothing. */
|
|||
|
|
var raw = getComputedStyle(cv.parentElement).getPropertyValue('--ca-ink').trim();
|
|||
|
|
var m = raw.match(/^#?([0-9a-f]{6})$/i);
|
|||
|
|
if (!m) return [20, 21, 26];
|
|||
|
|
var n = parseInt(m[1], 16);
|
|||
|
|
return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
|||
|
|
}
|
|||
|
|
var ink = inkRGB();
|
|||
|
|
|
|||
|
|
function size() {
|
|||
|
|
var r = cv.getBoundingClientRect();
|
|||
|
|
W = r.width; H = r.height;
|
|||
|
|
cv.width = W * dpr; cv.height = H * dpr;
|
|||
|
|
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
|||
|
|
}
|
|||
|
|
size();
|
|||
|
|
window.addEventListener('resize', size);
|
|||
|
|
|
|||
|
|
function bloom(x, y, r, a) {
|
|||
|
|
blooms.push({ x: x, y: y, r: r, a: a, life: 1, grow: 0.4 + Math.random() * 0.7 });
|
|||
|
|
if (blooms.length > 90) blooms.shift();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
cv.parentElement.addEventListener('pointermove', function (e) {
|
|||
|
|
var r = cv.getBoundingClientRect();
|
|||
|
|
var x = e.clientX - r.left, y = e.clientY - r.top;
|
|||
|
|
var d = Math.hypot(x - last.x, y - last.y);
|
|||
|
|
if (d > 26) { bloom(x, y, 26 + Math.random() * 46, 0.05); last.x = x; last.y = y; }
|
|||
|
|
}, { passive: true });
|
|||
|
|
|
|||
|
|
function frame() {
|
|||
|
|
t += 0.006;
|
|||
|
|
ctx.clearRect(0, 0, W, H);
|
|||
|
|
|
|||
|
|
/* ambient drift — the page is never fully still */
|
|||
|
|
if (Math.random() < 0.012) {
|
|||
|
|
bloom(W * (0.1 + Math.random() * 0.8), H * (0.15 + Math.random() * 0.7),
|
|||
|
|
60 + Math.random() * 120, 0.022);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for (var i = blooms.length - 1; i >= 0; i--) {
|
|||
|
|
var b = blooms[i];
|
|||
|
|
b.life -= 0.0034;
|
|||
|
|
b.r += b.grow;
|
|||
|
|
if (b.life <= 0) { blooms.splice(i, 1); continue; }
|
|||
|
|
var alpha = b.a * b.life;
|
|||
|
|
var g = ctx.createRadialGradient(b.x, b.y, 0, b.x, b.y, b.r);
|
|||
|
|
g.addColorStop(0, 'rgba(' + ink[0] + ',' + ink[1] + ',' + ink[2] + ',' + alpha + ')');
|
|||
|
|
g.addColorStop(0.55,'rgba(' + ink[0] + ',' + ink[1] + ',' + ink[2] + ',' + alpha * 0.35 + ')');
|
|||
|
|
g.addColorStop(1, 'rgba(' + ink[0] + ',' + ink[1] + ',' + ink[2] + ',0)');
|
|||
|
|
ctx.fillStyle = g;
|
|||
|
|
ctx.beginPath(); ctx.arc(b.x, b.y, b.r, 0, Math.PI * 2); ctx.fill();
|
|||
|
|
}
|
|||
|
|
requestAnimationFrame(frame);
|
|||
|
|
}
|
|||
|
|
requestAnimationFrame(frame);
|
|||
|
|
setTimeout(function () { cv.classList.add('on'); }, 400);
|
|||
|
|
|
|||
|
|
/* re-read ink colour when the theme flips */
|
|||
|
|
new MutationObserver(function () { ink = inkRGB(); })
|
|||
|
|
.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
|
|||
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function () {
|
|||
|
|
setTimeout(function () { ink = inkRGB(); }, 50);
|
|||
|
|
});
|
|||
|
|
})();
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
</body>
|
|||
|
|
</html>
|