Polish timeline v2: Inter typography, view-timeline scroll animations, animated counters, stagger reveals, expand toggle text, reduced-motion support, keyboard a11y

This commit is contained in:
Tony0410
2026-07-20 21:44:34 +08:00
parent 2c918ae39c
commit c144d6fced

View File

@@ -4,86 +4,130 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Career Arc · Anthony Martin</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{--green:#1a472a;--green-l:#2d7a47;--green-d:#0f2b1a;--gold:#d4a843;--cream:#f5f0e8;--dark:#0a0f0d;--text:#c8d6c0;--text-m:#7a9a7a;--card:#111f16;--card-border:#1a3a24;--spacing:clamp(40px,8vw,120px)}
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--dark);color:var(--text);overflow-x:hidden;-webkit-font-smoothing:antialiased}
:root{--green:#1a472a;--green-l:#2d7a47;--green-d:#0f2b1a;--gold:#d4a843;--gold-m:#b89230;--cream:#f5f0e8;--dark:#080a09;--surface:#0e1410;--card:#131e16;--card-hover:#182a1d;--border:rgba(26,71,42,0.25);--border-l:rgba(26,71,42,0.4);--text:#c8d6c0;--text-b:#e8f0e0;--text-m:#6a8a6a;--text-dim:#4a6a4a;--spacing:clamp(40px,8vw,120px);--radius:10px;--ease-out: cubic-bezier(0.22,1,0.36,1)}
body{font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;background:var(--dark);color:var(--text);overflow-x:hidden;-webkit-font-smoothing:antialiased;font-weight:400;line-height:1.6}
::selection{background:rgba(212,168,67,0.25);color:var(--cream)}
/* Hero */
.hero{min-height:100vh;display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;padding:2rem;position:relative}
.hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at 50% 100%,rgba(26,71,42,0.15) 0%,transparent 70%);pointer-events:none}
.hero h1{font-size:clamp(2.5rem,6vw,5rem);font-weight:800;color:var(--cream);letter-spacing:-0.03em;line-height:1.05;margin-bottom:0.5rem;animation:fadeUp 1s ease-out}
.hero::before{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at 50% 100%,rgba(26,71,42,0.18) 0%,transparent 70%);pointer-events:none}
.hero h1{font-size:clamp(2.8rem,6vw,5.5rem);font-weight:700;color:var(--text-b);letter-spacing:-0.03em;line-height:1.04;margin-bottom:0.6rem;text-wrap:balance}
.hero h1 span{color:var(--gold)}
.hero .sub{font-size:clamp(1rem,2vw,1.3rem);color:var(--text-m);margin-bottom:1.5rem;animation:fadeUp 1s ease-out 0.2s both}
.hero .tag{display:inline-block;background:var(--green);color:var(--cream);padding:0.4rem 1rem;border-radius:100px;font-size:0.8rem;font-weight:600;letter-spacing:0.05em;animation:fadeUp 1s ease-out 0.4s both}
.hero .scroll-hint{position:absolute;bottom:2rem;color:var(--text-m);font-size:0.75rem;display:flex;flex-direction:column;align-items:center;gap:0.5rem;animation:bounce 2s infinite}
.hero .scroll-hint svg{width:20px;height:20px}
.hero .sub{font-size:clamp(1rem,2vw,1.25rem);font-weight:400;color:var(--text-m);max-width:500px;margin-bottom:1.5rem;line-height:1.5}
.hero .tag{display:inline-flex;align-items:center;gap:0.5rem;background:rgba(26,71,42,0.2);border:1px solid var(--border-l);color:var(--cream);padding:0.4rem 1.2rem;border-radius:100px;font-size:0.8rem;font-weight:500;letter-spacing:0.02em}
.hero .tag .num{display:inline-block;min-width:1.2ch;text-align:right;font-weight:700;color:var(--gold)}
.hero .scroll-hint{position:absolute;bottom:2.5rem;color:var(--text-dim);font-size:0.7rem;display:flex;flex-direction:column;align-items:center;gap:0.4rem;cursor:pointer;transition:color 0.3s;letter-spacing:0.05em;text-transform:uppercase}
.hero .scroll-hint:hover{color:var(--text-m)}
.hero .scroll-hint .arrow{width:18px;height:18px;animation:bounce 2s var(--ease-out) infinite}
/* Now Banner */
.now-banner{background:linear-gradient(135deg,var(--green-d),var(--green));border:1px solid var(--green-l);border-radius:12px;padding:1.5rem 2rem;margin:0 auto var(--spacing);max-width:700px;text-align:center;position:relative}
.now-banner .label{font-size:0.7rem;text-transform:uppercase;letter-spacing:0.15em;color:var(--gold);font-weight:700}
.now-banner h2{font-size:1.4rem;color:var(--cream);margin:0.3rem 0}
.now-banner p{font-size:0.9rem;color:var(--text-m);line-height:1.5}
.now-banner .status-dot{display:inline-block;width:10px;height:10px;background:var(--gold);border-radius:50%;margin-right:0.4rem;animation:pulse 2s infinite}
/* Timeline */
.timeline-wrapper{max-width:900px;margin:0 auto;padding:0 1.5rem var(--spacing)}
.now-banner{position:relative;background:linear-gradient(135deg,rgba(15,30,20,0.9),rgba(26,71,42,0.3));border:1px solid var(--border-l);border-radius:12px;padding:1.5rem 2rem;margin:0 auto var(--spacing);max-width:700px;text-align:center;overflow:hidden}
.now-banner::before{content:'';position:absolute;top:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--gold-m),transparent)}
.now-banner .label{font-size:0.65rem;text-transform:uppercase;letter-spacing:0.15em;color:var(--gold);font-weight:600}
.now-banner .status-dot{display:inline-block;width:8px;height:8px;background:var(--gold);border-radius:50%;margin-right:0.35rem;animation:pulse 2s var(--ease-out) infinite;vertical-align:middle}
.now-banner h2{font-size:clamp(1.2rem,2vw,1.5rem);font-weight:600;color:var(--text-b);margin:0.4rem 0;letter-spacing:-0.01em;text-wrap:balance}
.now-banner p{font-size:0.85rem;color:var(--text);line-height:1.6;max-width:600px;margin:0 auto}
/* Timeline layout */
.timeline-wrapper{max-width:900px;margin:0 auto;padding:0 1.5rem var(--spacing);scrollbar-width:thin;scrollbar-color:var(--border) transparent}
.timeline{position:relative}
.timeline::before{content:'';position:absolute;left:50%;top:0;bottom:0;width:2px;background:linear-gradient(to bottom,var(--green-l),var(--gold),var(--green-l));transform:translateX(-50%)}
.timeline-item{position:relative;margin-bottom:3rem;opacity:0;transform:translateY(40px);transition:opacity 0.8s ease,transform 0.8s ease}
.timeline-item.visible{opacity:1;transform:translateY(0)}
.timeline-line{position:absolute;left:50%;top:0;bottom:0;width:2px;background:linear-gradient(to bottom,var(--green-l),var(--gold),rgba(212,168,67,0.1));transform:translateX(-50%)}
.timeline-item{position:relative;margin-bottom:3rem;opacity:0;transition:opacity 0.8s var(--ease-out),transform 0.8s var(--ease-out)}
.timeline-item.visible{opacity:1}
.timeline-item:nth-child(odd){transform:translateX(-30px)}
.timeline-item:nth-child(even){transform:translateX(30px)}
.timeline-item:nth-child(odd).visible{transform:translateX(0)}
.timeline-item:nth-child(even).visible{transform:translateX(0)}
.timeline-item:nth-child(odd) .timeline-card{margin-left:auto}
.timeline-dot{position:absolute;left:50%;top:2rem;width:16px;height:16px;background:var(--gold);border:3px solid var(--dark);border-radius:50%;transform:translateX(-50%);z-index:2;transition:transform 0.3s,box-shadow 0.3s}
.timeline-item.visible .timeline-dot{box-shadow:0 0 20px rgba(212,168,67,0.4)}
.timeline-card{width:calc(50% - 30px);background:var(--card);border:1px solid var(--card-border);border-radius:10px;padding:1.5rem;cursor:pointer;transition:border-color 0.3s,box-shadow 0.3s;position:relative}
.timeline-card:hover{border-color:var(--green-l);box-shadow:0 4px 20px rgba(26,71,42,0.2)}
.timeline-card .date{font-size:0.7rem;color:var(--gold);font-weight:700;text-transform:uppercase;letter-spacing:0.08em;margin-bottom:0.3rem}
.timeline-card .role{font-size:1.1rem;font-weight:700;color:var(--cream);margin-bottom:0.1rem}
.timeline-card .company{font-size:0.9rem;color:var(--green-l);font-weight:600;margin-bottom:0.2rem}
.timeline-card .location{font-size:0.75rem;color:var(--text-m);margin-bottom:0.6rem}
.timeline-card .summary{font-size:0.85rem;color:var(--text);line-height:1.6;margin-bottom:0.5rem}
.timeline-card .expand-btn{font-size:0.75rem;color:var(--green-l);cursor:pointer;font-weight:600;display:inline-flex;align-items:center;gap:0.3rem}
/* Progress badge */
.tl-progress{position:absolute;top:-2rem;left:50%;transform:translateX(-50%);font-size:0.65rem;color:var(--text-dim);letter-spacing:0.06em;text-transform:uppercase;white-space:nowrap;background:var(--surface);border:1px solid var(--border);border-radius:4px;padding:0.15rem 0.6rem}
.timeline-dot{position:absolute;left:50%;top:2rem;width:14px;height:14px;background:var(--green-l);border:2px solid var(--dark);border-radius:50%;transform:translateX(-50%) scale(1);z-index:2;transition:transform 0.4s var(--ease-out),box-shadow 0.4s var(--ease-out);box-shadow:0 0 0 0 rgba(45,122,71,0.3)}
.timeline-item.visible .timeline-dot{background:var(--gold);transform:translateX(-50%) scale(1.25);box-shadow:0 0 20px rgba(212,168,67,0.3)}
.timeline-card{width:calc(50% - 32px);background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:1.4rem 1.5rem;cursor:pointer;transition:border-color 0.3s var(--ease-out),background 0.3s var(--ease-out);position:relative}
.timeline-card:hover{background:var(--card-hover);border-color:var(--border-l)}
.timeline-card .date{font-size:0.65rem;font-weight:600;color:var(--gold);text-transform:uppercase;letter-spacing:0.08em;margin-bottom:0.3rem}
.timeline-card .role{font-size:1.05rem;font-weight:600;color:var(--text-b);margin-bottom:0.1rem;letter-spacing:-0.01em;text-wrap:balance}
.timeline-card .company{font-size:0.85rem;font-weight:500;color:var(--green-l);margin-bottom:0.15rem}
.timeline-card .location{font-size:0.7rem;color:var(--text-dim);margin-bottom:0.5rem;font-weight:400}
.timeline-card .summary{font-size:0.82rem;color:var(--text);line-height:1.6;font-weight:400;margin-bottom:0.5rem}
.timeline-card .expand-btn{font-size:0.72rem;font-weight:500;color:var(--green-l);cursor:pointer;display:inline-flex;align-items:center;gap:0.35rem;border:none;background:none;padding:0;transition:color 0.3s}
.timeline-card .expand-btn:hover{color:var(--gold)}
.timeline-card .details{max-height:0;overflow:hidden;transition:max-height 0.5s ease,opacity 0.4s ease;opacity:0}
.timeline-card .expand-btn .arrow{display:inline-block;transition:transform 0.3s var(--ease-out);font-size:0.6rem}
.timeline-card .expand-btn.open .arrow{transform:rotate(180deg)}
.timeline-card .details{max-height:0;overflow:hidden;transition:max-height 0.5s var(--ease-out),opacity 0.4s var(--ease-out);opacity:0}
.timeline-card .details.open{max-height:2000px;opacity:1}
.timeline-card .details ul{list-style:none;padding:0.8rem 0 0;border-top:1px solid var(--card-border)}
.timeline-card .details ul li{padding:0.4rem 0;font-size:0.8rem;color:var(--text);line-height:1.5;padding-left:1rem;position:relative}
.timeline-card .details ul li::before{content:'→';position:absolute;left:0;color:var(--gold)}
.timeline-card .details .tags{display:flex;flex-wrap:wrap;gap:0.4rem;padding-top:0.8rem;border-top:1px solid var(--card-border)}
.timeline-card .details .tags span{background:rgba(26,71,42,0.3);color:var(--text-m);font-size:0.7rem;padding:0.2rem 0.6rem;border-radius:4px;border:1px solid var(--card-border)}
/* Arrow connectors */
.timeline-item:nth-child(odd) .timeline-card::after{content:'';position:absolute;top:1.8rem;left:-8px;border:8px solid transparent;border-right-color:var(--card-border);z-index:1}
.timeline-item:nth-child(even) .timeline-card::after{content:'';position:absolute;top:1.8rem;right:-8px;border:8px solid transparent;border-left-color:var(--card-border);z-index:1}
/* Optional gap filler for short side */
.timeline-card .details ul{list-style:none;padding:0.8rem 0 0;border-top:1px solid var(--border)}
.timeline-card .details ul li{padding:0.35rem 0;font-size:0.78rem;color:var(--text);line-height:1.55;padding-left:1.2rem;position:relative;font-weight:400}
.timeline-card .details ul li::before{content:'→';position:absolute;left:0;color:var(--gold);font-weight:400}
.timeline-card .details .tags{display:flex;flex-wrap:wrap;gap:0.35rem;padding-top:0.7rem;border-top:1px solid var(--border)}
.timeline-card .details .tags span{background:rgba(26,71,42,0.25);color:var(--text-m);font-size:0.65rem;padding:0.2rem 0.55rem;border-radius:4px;border:1px solid transparent;letter-spacing:0.02em;transition:border-color 0.3s,color 0.3s}
.timeline-card .details .tags span:hover{border-color:var(--border-l);color:var(--cream)}
/* Connector arrows */
.timeline-item:nth-child(odd) .timeline-card::after{content:'';position:absolute;top:1.8rem;left:-7px;border:7px solid transparent;border-right-color:var(--border);z-index:1}
.timeline-item:nth-child(even) .timeline-card::after{content:'';position:absolute;top:1.8rem;right:-7px;border:7px solid transparent;border-left-color:var(--border);z-index:1}
.timeline-item:last-child{margin-bottom:0}
/* Education section */
/* Education */
.edu-section{max-width:700px;margin:0 auto var(--spacing);padding:0 1.5rem}
.edu-section h2{font-size:1.2rem;color:var(--gold);text-align:center;margin-bottom:1.5rem;text-transform:uppercase;letter-spacing:0.1em}
.edu-section h2{font-size:0.75rem;font-weight:600;color:var(--gold);text-align:center;margin-bottom:1.2rem;text-transform:uppercase;letter-spacing:0.12em}
.edu-grid{display:grid;grid-template-columns:1fr 1fr;gap:1rem}
.edu-card{background:var(--card);border:1px solid var(--card-border);border-radius:8px;padding:1.2rem;opacity:0;transform:translateY(20px);transition:opacity 0.6s ease,transform 0.6s ease}
.edu-card{background:var(--card);border:1px solid var(--border);border-radius:8px;padding:1.2rem 1.3rem;opacity:0;transform:translateY(15px);transition:opacity 0.6s var(--ease-out),transform 0.6s var(--ease-out)}
.edu-card.visible{opacity:1;transform:translateY(0)}
.edu-card h3{font-size:0.9rem;color:var(--cream);margin-bottom:0.2rem}
.edu-card .degree{font-size:0.8rem;color:var(--text-m);margin-bottom:0.1rem}
.edu-card .year{font-size:0.7rem;color:var(--green-l)}
.edu-card h3{font-size:0.85rem;font-weight:600;color:var(--text-b);margin-bottom:0.15rem}
.edu-card .degree{font-size:0.78rem;color:var(--text);margin-bottom:0.1rem;font-weight:400}
.edu-card .year{font-size:0.65rem;font-weight:500;color:var(--green-l)}
/* Skills */
.skills-section{max-width:700px;margin:0 auto var(--spacing);padding:0 1.5rem}
.skills-section h2{font-size:1.2rem;color:var(--gold);text-align:center;margin-bottom:1.5rem;text-transform:uppercase;letter-spacing:0.1em}
.skills-grid{display:flex;flex-wrap:wrap;gap:0.6rem;justify-content:center}
.skill-tag{background:var(--card);border:1px solid var(--card-border);border-radius:100px;padding:0.5rem 1rem;font-size:0.8rem;color:var(--text);opacity:0;transform:scale(0.9);transition:opacity 0.4s ease,transform 0.4s ease,border-color 0.3s}
.skills-section h2{font-size:0.75rem;font-weight:600;color:var(--gold);text-align:center;margin-bottom:1.2rem;text-transform:uppercase;letter-spacing:0.12em}
.skills-grid{display:flex;flex-wrap:wrap;gap:0.5rem;justify-content:center}
.skill-tag{background:var(--card);border:1px solid var(--border);border-radius:100px;padding:0.4rem 1rem;font-size:0.78rem;font-weight:400;color:var(--text);opacity:0;transform:scale(0.92);transition:opacity 0.4s var(--ease-out),transform 0.4s var(--ease-out),border-color 0.3s,color 0.3s}
.skill-tag.visible{opacity:1;transform:scale(1)}
.skill-tag:hover{border-color:var(--green-l);color:var(--cream)}
.skill-tag:hover{border-color:var(--border-l);color:var(--cream)}
/* Footer */
.footer{text-align:center;padding:2rem;color:var(--text-m);font-size:0.75rem;border-top:1px solid var(--card-border);max-width:700px;margin:0 auto}
.footer a{color:var(--green-l);text-decoration:none}
.footer{text-align:center;padding:2.5rem 1.5rem;color:var(--text-dim);font-size:0.7rem;border-top:1px solid var(--border);max-width:700px;margin:0 auto}
.footer a{color:var(--green-l);text-decoration:none;transition:color 0.3s}
.footer a:hover{color:var(--gold)}
/* Animations */
@keyframes fadeUp{from{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}
@keyframes bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.4}}
/* Mobile: full-width cards */
@keyframes bounce{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.35}}
@keyframes counterIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
.hero-entrance{animation:fadeUp 1s var(--ease-out) both}
.hero-entrance-1{animation:fadeUp 1s var(--ease-out) 0.15s both}
.hero-entrance-2{animation:fadeUp 1s var(--ease-out) 0.3s both}
.hero-entrance-3{animation:fadeUp 1s var(--ease-out) 0.6s both}
/* View-timeline scroll animation (progressive enhancement) */
@supports (animation-timeline: view()){
.timeline-item{opacity:0;transform:none;animation:tl-reveal linear both;animation-timeline:view();animation-range:entry 0% entry 40%}
.timeline-item:nth-child(odd){animation-name:tl-reveal-left}
.timeline-item:nth-child(even){animation-name:tl-reveal-right}
@keyframes tl-reveal{from{opacity:0;transform:translateY(30px)}to{opacity:1;transform:translateY(0)}}
@keyframes tl-reveal-left{from{opacity:0;transform:translateX(-20px) translateY(20px)}to{opacity:1;transform:translateX(0) translateY(0)}}
@keyframes tl-reveal-right{from{opacity:0;transform:translateX(20px) translateY(20px)}to{opacity:1;transform:translateX(0) translateY(0)}}
.timeline-line{animation:tl-line-grow linear both;animation-timeline:view();animation-range:entry 0% entry 80%;transform-origin:top}
@keyframes tl-line-grow{from{transform:scaleY(0) translateX(-50%)}to{transform:scaleY(1) translateX(-50%)}}
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce){
*,*::before,*::after{animation-duration:0.01ms!important;animation-iteration-count:1!important;transition-duration:0.01ms!important;scroll-behavior:auto!important}
.timeline-item{opacity:1!important;transform:none!important}
.skill-tag{opacity:1!important;transform:none!important}
.edu-card{opacity:1!important;transform:none!important}
.hero .scroll-hint .arrow{animation:none}
.now-banner .status-dot{animation:none}
}
/* Mobile */
@media(max-width:700px){
.timeline::before{left:20px}
.timeline-dot{left:20px}
.timeline-card{width:calc(100% - 50px);margin-left:50px!important}
.timeline-item:nth-child(odd) .timeline-card::after,.timeline-item:nth-child(even) .timeline-card::after{left:-8px;border:8px solid transparent;border-right-color:var(--card-border);right:auto}
.timeline-line{left:18px}
.timeline-dot{left:18px;width:12px;height:12px}
.tl-progress{left:18px;transform:none}
.timeline-card{width:calc(100% - 48px);margin-left:44px!important}
.timeline-item:nth-child(odd) .timeline-card::after,.timeline-item:nth-child(even) .timeline-card::after{left:-7px;border:7px solid transparent;border-right-color:var(--border);right:auto}
.timeline-item:nth-child(odd){transform:translateX(0)}
.timeline-item:nth-child(even){transform:translateX(0)}
.edu-grid{grid-template-columns:1fr}
.hero h1{letter-spacing:-0.02em}
}
</style>
</head>
@@ -91,36 +135,44 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
<!-- Hero -->
<section class="hero">
<h1>Career <span>Arc</span></h1>
<p class="sub">Marketing &amp; communications professional · Energy transition · Perth, WA</p>
<div class="tag">15+ years in energy · 3 companies · 6 roles</div>
<div class="scroll-hint">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 13l5 5 5-5M7 6l5 5 5-5"/></svg>
<span>Scroll to explore</span>
<h1 class="hero-entrance">Career <span>Arc</span></h1>
<p class="sub hero-entrance-1">Marketing &amp; communications professional · Energy transition · Perth, WA</p>
<div class="tag hero-entrance-2">
<span class="num" data-target="15">0</span><span>+ years in energy</span>
<span style="font-size:1.2em;color:var(--text-dim)">·</span>
<span class="num" data-target="3">0</span><span> companies</span>
<span style="font-size:1.2em;color:var(--text-dim)">·</span>
<span class="num" data-target="6">0</span><span> roles</span>
</div>
<div class="scroll-hint hero-entrance-3" onclick="document.querySelector('.now-banner')?.scrollIntoView({behavior:'smooth'})">
<svg class="arrow" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M7 13l5 5 5-5M7 6l5 5 5-5"/></svg>
<span>Explore</span>
</div>
</section>
<div class="timeline-wrapper">
<!-- Now Banner -->
<div class="now-banner" style="opacity:0;animation:fadeUp 1s ease-out 0.6s both">
<div class="label"><span class="status-dot"></span>Current Status</div>
<div class="now-banner" style="opacity:0;animation:fadeUp 1s var(--ease-out) 0.8s both">
<div class="label"><span class="status-dot"></span>Present</div>
<h2>Open to Opportunities</h2>
<p>Recently finished a Marketing Advisor role at Pacific Energy. Actively exploring corporate marketing, communications and digital strategy roles in Perth and across WA.</p>
</div>
<div class="timeline" id="timeline">
<div class="tl-progress" id="tl-progress"></div>
<!-- 1. Pacific Energy -->
<div class="timeline-item">
<div class="timeline-item" data-idx="1">
<div class="timeline-dot"></div>
<div class="timeline-card" onclick="this.querySelector('.details').classList.toggle('open')">
<div class="timeline-card" onclick="toggleDetails(this)">
<div class="date">Jun 2025 Jul 2026</div>
<div class="role">Marketing Advisor</div>
<div class="company">Pacific Energy</div>
<div class="location">Kewdale, Perth WA</div>
<div class="summary">Corporate marketing, digital content, technical communications, major events and marketing AI strategy for a leading energy infrastructure company.</div>
<div class="expand-btn">Show achievements</div>
<button class="expand-btn"><span class="arrow"></span> <span class="lb">Show achievements</span></button>
<div class="details">
<ul>
<li>Developed and rolled out a social media strategy and capability content series across LinkedIn and corporate channels</li>
@@ -138,15 +190,15 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
</div>
<!-- 2. Horizon Power -->
<div class="timeline-item">
<div class="timeline-item" data-idx="2">
<div class="timeline-dot"></div>
<div class="timeline-card" onclick="this.querySelector('.details').classList.toggle('open')">
<div class="timeline-card" onclick="toggleDetails(this)">
<div class="date">2019 Sep 2024</div>
<div class="role">Marketing Specialist</div>
<div class="company">Horizon Power</div>
<div class="location">Perth, WA</div>
<div class="summary">Integrated marketing, regulated communications, customer engagement and energy transition programs across WA's regional energy provider.</div>
<div class="expand-btn">Show achievements</div>
<button class="expand-btn"><span class="arrow"></span> <span class="lb">Show achievements</span></button>
<div class="details">
<ul>
<li>Led integrated marketing and customer communication campaigns across digital, social, email, direct mail, television, print and community channels</li>
@@ -164,15 +216,15 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
</div>
<!-- 3. Synergy: Energy Solutions Marketing Specialist -->
<div class="timeline-item">
<div class="timeline-item" data-idx="3">
<div class="timeline-dot"></div>
<div class="timeline-card" onclick="this.querySelector('.details').classList.toggle('open')">
<div class="timeline-card" onclick="toggleDetails(this)">
<div class="date">2015 2018</div>
<div class="role">Energy Solutions Marketing Specialist</div>
<div class="company">Synergy</div>
<div class="location">Perth, WA</div>
<div class="summary">Commercial growth and customer experience across renewable energy products, digital channels and agency management.</div>
<div class="expand-btn">Show achievements</div>
<button class="expand-btn"><span class="arrow"></span> <span class="lb">Show achievements</span></button>
<div class="details">
<ul>
<li>Led development of the SolarReturn proposition from research through launch, contributing to a 40% sales increase in year one</li>
@@ -188,15 +240,15 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
</div>
<!-- 4. Synergy: Business Segment Coordinator -->
<div class="timeline-item">
<div class="timeline-item" data-idx="4">
<div class="timeline-dot"></div>
<div class="timeline-card" onclick="this.querySelector('.details').classList.toggle('open')">
<div class="timeline-card" onclick="toggleDetails(this)">
<div class="date">2014 2015</div>
<div class="role">Business Segment Coordinator</div>
<div class="company">Synergy</div>
<div class="location">Perth, WA</div>
<div class="summary">Financial and portfolio management, enterprise communications and cross-functional coordination.</div>
<div class="expand-btn">Show achievements</div>
<button class="expand-btn"><span class="arrow"></span> <span class="lb">Show achievements</span></button>
<div class="details">
<ul>
<li>Managed Synergy's streetlighting portfolio and resolved $1.3 million in billing discrepancies through detailed contract and process reviews</li>
@@ -211,15 +263,15 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
</div>
<!-- 5. Synergy: Assistant Product Manager -->
<div class="timeline-item">
<div class="timeline-item" data-idx="5">
<div class="timeline-dot"></div>
<div class="timeline-card" onclick="this.querySelector('.details').classList.toggle('open')">
<div class="timeline-card" onclick="toggleDetails(this)">
<div class="date">2012 2014</div>
<div class="role">Assistant Product Manager, Industrial &amp; Commercial</div>
<div class="company">Synergy</div>
<div class="location">Perth, WA</div>
<div class="summary">Product and sales development for commercial renewable energy products, digital sales platforms and training.</div>
<div class="expand-btn">Show achievements</div>
<button class="expand-btn"><span class="arrow"></span> <span class="lb">Show achievements</span></button>
<div class="details">
<ul>
<li>Developed and launched the Synergy Sellback Program, enabling commercial customers to receive value from exported renewable energy</li>
@@ -234,15 +286,15 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
</div>
<!-- 6. Synergy: Billing Officer -->
<div class="timeline-item">
<div class="timeline-item" data-idx="6">
<div class="timeline-dot"></div>
<div class="timeline-card" onclick="this.querySelector('.details').classList.toggle('open')">
<div class="timeline-card" onclick="toggleDetails(this)">
<div class="date">2010 2012</div>
<div class="role">Billing Officer</div>
<div class="company">Synergy</div>
<div class="location">Perth, WA</div>
<div class="summary">Customer billing, enquiry management, dispute resolution and data accuracy in a regulated energy retail environment.</div>
<div class="expand-btn">Show achievements</div>
<button class="expand-btn"><span class="arrow"></span> <span class="lb">Show achievements</span></button>
<div class="details">
<ul>
<li>Managed billing enquiries, account corrections and dispute resolution for residential and small business customers</li>
@@ -305,42 +357,106 @@ body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;b
<div class="footer">
<p>Anthony Martin · <a href="https://anthony.martinwa.org" target="_blank">anthony.martinwa.org</a></p>
<p style="margin-top:0.3rem;font-size:0.7rem">Built by the Rhino in the Green Jacket · Jul 2026</p>
<p style="margin-top:0.3rem;font-size:0.65rem;color:var(--text-dim)">Built by the Rhino in the Green Jacket · Jul 2026</p>
</div>
<script>
// Scroll-triggered animations
// Animated counters
function animateCounters(){
document.querySelectorAll('.num[data-target]').forEach(el => {
const target=parseInt(el.dataset.target);
const dur=800; const start=performance.now();
el.textContent='0';
function frame(now){
const p=Math.min((now-start)/dur,1);
const eased=1-Math.pow(1-p,3);
el.textContent=Math.floor(0+(target-0)*eased);
if(p<1) requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
});
}
// Toggle details with button text
function toggleDetails(card){
const details=card.querySelector('.details');
const btn=card.querySelector('.expand-btn');
const lbl=btn?.querySelector('.lb');
const isOpen=details.classList.contains('open');
details.classList.toggle('open');
btn?.classList.toggle('open');
if(lbl) lbl.textContent=isOpen?'Show achievements':'Hide achievements';
}
// Scroll-triggered animations (fallback for non-view-timeline browsers)
if(!CSS.supports('animation-timeline','view()')){
const observer=new IntersectionObserver((entries)=>{
entries.forEach(entry=>{
if(entry.isIntersecting){
entry.target.classList.add('visible');
// Update progress
const items=document.querySelectorAll('.timeline-item');
const visible=document.querySelectorAll('.timeline-item.visible').length;
const prog=document.getElementById('tl-progress');
if(prog) prog.textContent='Role '+Math.min(visible,items.length)+' of '+items.length;
}
});
}, { threshold: 0.15, rootMargin: '0px 0px -50px 0px' });
},{threshold:0.12,rootMargin:'0px 0px -40px 0px'});
document.querySelectorAll('.timeline-item, .edu-card, .skill-tag').forEach(el=>observer.observe(el));
} else {
// View-timeline browsers: still track visible count via IntersectionObserver for progress
const progObserver=new IntersectionObserver((entries)=>{
entries.forEach(entry=>{
if(entry.isIntersecting){
const items=document.querySelectorAll('.timeline-item');
const visible=[...items].filter(i=>i.getBoundingClientRect().top<window.innerHeight).length;
const prog=document.getElementById('tl-progress');
if(prog) prog.textContent='Role '+Math.min(visible+1,items.length)+' of '+items.length;
}
});
},{threshold:0.1});
document.querySelectorAll('.timeline-item').forEach(el=>progObserver.observe(el));
}
// Stagger skill tags
document.querySelectorAll('.skill-tag').forEach((el,i)=>{
el.style.transitionDelay = (i * 0.05) + 's';
el.style.transitionDelay=(i*0.04)+'s';
});
// Timeline auto-scroll highlight
const items = document.querySelectorAll('.timeline-item');
// Active dot highlight
const dotObserver=new IntersectionObserver((entries)=>{
entries.forEach(entry=>{
const dot=entry.target.querySelector('.timeline-dot');
if(entry.isIntersecting){
entry.target.querySelector('.timeline-dot').style.transform = 'translateX(-50%) scale(1.3)';
dot.style.background='var(--gold)';
dot.style.transform='translateX(-50%) scale(1.25)';
dot.style.boxShadow='0 0 20px rgba(212,168,67,0.3)';
} else {
entry.target.querySelector('.timeline-dot').style.transform = 'translateX(-50%) scale(1)';
dot.style.background='';
dot.style.transform='';
dot.style.boxShadow='';
}
});
}, { threshold: 0.4 });
items.forEach(item => dotObserver.observe(item));
},{threshold:0.35});
document.querySelectorAll('.timeline-item').forEach(el=>dotObserver.observe(el));
// Smooth scroll for hero arrow
document.querySelector('.scroll-hint')?.addEventListener('click', () => {
document.querySelector('.now-banner')?.scrollIntoView({ behavior: 'smooth' });
// Init progress on load
(function initProg(){
const items=document.querySelectorAll('.timeline-item');
const prog=document.getElementById('tl-progress');
if(prog) prog.textContent='Role 0 of '+items.length;
})();
// Animate counters after hero entrance
setTimeout(animateCounters,900);
// Keyboard support for expandable cards
document.querySelectorAll('.timeline-card').forEach(card=>{
card.setAttribute('tabindex','0');
card.setAttribute('role','button');
card.addEventListener('keydown',e=>{
if(e.key==='Enter'||e.key===' '){e.preventDefault();toggleDetails(card);}
});
});
</script>
</body>