-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmoderne-product-overview-deck.html
More file actions
196 lines (171 loc) · 12.8 KB
/
Copy pathmoderne-product-overview-deck.html
File metadata and controls
196 lines (171 loc) · 12.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Moderne — Product Overview</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=Poppins:wght@300;400;500;600;700&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{
--midnight:#041834; --ink:#13203A;
--green:#85FE99; --green-ink:#08110A;
--slide-grad:linear-gradient(155deg,#F6F7FB 0%,#EEEFF6 55%,#E7E8F1 100%);
--head:#2A3142; --eyebrow:#3A4252; --lead:#5A6373; --lead-strong:#13203A;
--hair:rgba(30,36,51,0.12); --hair2:rgba(30,36,51,0.18);
--font-head:"Beausite","Poppins",system-ui,sans-serif;
--font-body:"Poppins",system-ui,sans-serif;
--mono:"Inter",system-ui,sans-serif;
}
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%;}
body{font-family:var(--font-body);background:#0e1424;display:flex;align-items:center;justify-content:center;overflow:hidden;-webkit-font-smoothing:antialiased;}
#stage{position:relative;width:1280px;height:720px;transform-origin:center center;border-radius:8px;overflow:hidden;box-shadow:0 24px 70px rgba(0,0,0,0.5);}
.slide{position:absolute;inset:0;display:none;}
.slide.active{display:block;}
.surface{position:absolute;inset:0;background:var(--slide-grad);}
.slide.dark .surface{background:var(--midnight);}
.bar{position:absolute;top:0;left:0;right:0;height:8px;z-index:4;}
.bp{position:absolute;inset:0;pointer-events:none;color:rgba(0,25,61,0.04);z-index:1;
-webkit-mask-image:linear-gradient(100deg, transparent 0%, transparent 46%, #000 84%);
mask-image:linear-gradient(100deg, transparent 0%, transparent 46%, #000 84%);}
.slide.dark .bp{color:rgba(255,255,255,0.045);}
.bp svg{width:100%;height:100%;display:block;}
.pad{position:absolute;inset:0;padding:60px 70px 52px;display:flex;flex-direction:column;z-index:2;}
.toprow{display:flex;justify-content:space-between;align-items:flex-start;}
.num{font-family:var(--mono);font-size:13.5px;font-weight:500;letter-spacing:1px;color:var(--lead);}
.slide.dark .num{color:rgba(244,241,233,0.55);}
.pill{background:var(--ink);color:#fff;font-size:13px;font-weight:600;padding:7px 16px;border-radius:999px;white-space:nowrap;}
.slide.dark .pill{background:rgba(255,255,255,0.14);}
.logo{display:flex;align-items:center;gap:11px;color:#fff;}
.logo .mark{width:29px;height:29px;}
.logo .word{font-family:var(--font-head);font-size:26px;font-weight:600;letter-spacing:-0.4px;}
.logo .tm{font-size:11px;font-weight:500;vertical-align:super;opacity:.8;}
.block{margin-top:26px;}
h1.disp{font-family:var(--font-head);font-weight:600;color:var(--head);line-height:0.98;}
.slide.dark h1.disp{color:#fff;font-weight:300;letter-spacing:-1.6px;}
.disp.xl{font-size:104px;letter-spacing:-3px;}
.disp.lg{font-size:74px;letter-spacing:-2px;line-height:1.0;}
.disp.md{font-size:58px;letter-spacing:-1.5px;line-height:1.03;}
.lead{font-size:22px;line-height:1.45;color:var(--lead);max-width:740px;margin-top:20px;font-weight:400;}
.lead strong{font-weight:600;color:var(--lead-strong);}
.slide.dark .lead{color:rgba(244,241,233,0.74);}
.slide.dark .lead strong{color:#fff;}
.feats{margin-top:28px;max-width:560px;}
.feat{display:flex;align-items:center;gap:13px;padding:13px 0;border-bottom:1px solid var(--hair);}
.feat:first-child{border-top:1px solid var(--hair2);}
.feat .dot{width:10px;height:10px;border-radius:50%;flex:none;}
.feat .lbl{font-size:18px;font-weight:600;color:var(--ink);letter-spacing:-0.2px;}
.spacer{flex:1;}
.foot{display:flex;align-items:center;justify-content:space-between;}
.next{display:inline-flex;align-items:center;gap:12px;color:#fff;border:none;font-family:inherit;font-size:15px;font-weight:600;padding:11px 13px 11px 22px;border-radius:999px;cursor:pointer;}
.next .circ{width:26px;height:26px;border-radius:50%;border:1.5px solid rgba(255,255,255,0.6);display:grid;place-items:center;}
.next .circ svg{width:13px;height:13px;}
.cta{display:inline-flex;align-items:center;gap:11px;background:var(--green);color:var(--green-ink);border:none;font-family:inherit;font-size:16px;font-weight:600;padding:13px 16px 13px 24px;border-radius:999px;cursor:pointer;}
.cta .circ{width:28px;height:28px;border-radius:50%;border:1.5px solid rgba(8,17,10,0.35);display:grid;place-items:center;}
.cta .circ svg{width:14px;height:14px;}
.counter{font-family:var(--mono);font-size:13px;color:var(--lead);}
.slide.dark .counter{color:rgba(244,241,233,0.5);}
.center{margin-top:auto;margin-bottom:auto;}
#dots{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);display:flex;gap:7px;z-index:50;}
#dots button{width:9px;height:9px;border-radius:50%;border:none;background:rgba(255,255,255,0.32);cursor:pointer;padding:0;}
#dots button.on{background:#fff;width:24px;border-radius:6px;}
.hint{position:fixed;bottom:15px;right:20px;font-family:var(--mono);color:rgba(255,255,255,0.4);font-size:12.5px;z-index:50;}
</style>
</head>
<body>
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
<symbol id="m-mark" viewBox="0 0 24 24"><path fill="currentColor" d="M22.3499 1.37436C22.1539 1.29304 21.9167 1.3337 21.762 1.49633L12.4793 10.7866C11.8707 5.47063 7.35314 1.3337 1.88666 1.3337C1.74227 1.3337 1.60818 1.39469 1.50504 1.49633C1.4019 1.59798 1.35033 1.73011 1.35033 1.88258V22.1505C1.35033 22.1505 1.35033 22.1708 1.35033 22.181C1.35033 22.2115 1.35033 22.2318 1.36064 22.2623C1.36064 22.2928 1.37096 22.3131 1.38127 22.3436V22.3639C1.38127 22.3843 1.4019 22.3944 1.4019 22.4046C1.41221 22.4249 1.43284 22.4554 1.44316 22.4757C1.45347 22.4961 1.4741 22.5164 1.49473 22.5367C1.51536 22.5571 1.53598 22.5774 1.55661 22.5876C1.57724 22.6079 1.59787 22.618 1.62881 22.6282C1.63913 22.6282 1.65975 22.6485 1.67007 22.6587C1.67007 22.6587 1.68038 22.6587 1.6907 22.6587C1.75258 22.679 1.81447 22.6994 1.87635 22.6994H22.1229C22.4221 22.6994 22.6593 22.4554 22.6593 22.1606V1.87242C22.6593 1.65896 22.5252 1.45567 22.3292 1.37436H22.3499ZM21.5969 3.17347V11.4677H13.3147L21.5969 3.17347ZM21.5969 16.5295H12.5515V12.5451H21.5969V16.5295ZM2.43331 20.8393V12.5451H10.7155L2.423 20.8393H2.43331ZM2.43331 2.43146C7.29126 2.7059 11.19 6.60905 11.4685 11.4677H2.43331V2.43146ZM11.4788 13.3074V21.6016H3.18624L11.4788 13.3074ZM12.5515 21.6016V17.6171H21.5969V21.6016H12.5515Z"/></symbol>
<symbol id="bp-grid" viewBox="0 0 1299 591"><path d="M937 587.243L937.301 587.522L1215.87 287.514L1215.57 287.236L1215.27 286.957L936.699 586.965L937 587.243Z" fill="currentColor"/><g fill="none" stroke="currentColor" stroke-width="1" vector-effect="non-scaling-stroke"><line x1="650.129" y1="450.83" x2="938.033" y2="450.83"/><rect x="649.41" y="287.41" width="649.18" height="300.18"/><rect x="649.719" y="0.41012" width="648.809" height="286.63"/><rect x="0.41012" y="286.958" width="649.18" height="300.704"/><path d="M939.033 1.99685L346 586.726"/><path d="M936 2L937 587"/><path d="M1215 288C1211.08 191.798 1152.48 -0.283366 936 1.00647"/><path d="M561.5 413.758C609.049 413.758 647.59 452.02 647.59 499.213C647.59 546.405 609.049 584.668 561.5 584.668C513.951 584.668 475.41 546.405 475.41 499.213C475.41 452.02 513.951 413.758 561.5 413.758Z"/></g></symbol>
</svg>
<script id="deckdata" type="application/json">
[
{"kind":"title","accent":"#85FE99","head":"Unleash the<br>100x developer","hc":"lg",
"lead":"<strong>Moderne</strong> auto-refactors and analyzes code across thousands of repositories, safely, at enterprise scale.","cta":"See the platform"},
{"kind":"product","accent":"#283AF7","num":"01 / 07","pill":"Platform","disp":"Platform","hc":"xl",
"lead":"<strong>One control plane</strong> for searching, fixing, and migrating across every repository at once.",
"feats":["Type-aware search","Automated remediation","Impact reporting"]},
{"kind":"product","accent":"#E7B136","num":"02 / 07","pill":"CLI","disp":"CLI","hc":"xl",
"lead":"<strong>Run the same recipes locally,</strong> no source code ever has to leave your machine.",
"feats":["Runs offline","Multi-repo analysis","Recipe parity"]},
{"kind":"product","accent":"#E8923C","num":"03 / 07 · Enter:","pill":"Agent tools","disp":"Trigrep","hc":"xl",
"lead":"<strong>Sub-second code search,</strong> built for agents and the developers who work alongside them.",
"feats":["Trigram-indexed","LST-aware","Enterprise-scoped"]},
{"kind":"product","accent":"#5AC36A","num":"04 / 07","pill":"Recipes","disp":"Recipes","hc":"xl",
"lead":"<strong>Composable, type-aware rules</strong> that change code correctly the first time, everywhere.",
"feats":["Search","Migrate","Onboard"]},
{"kind":"product","accent":"#B7995E","num":"05 / 07","pill":"DX","disp":"DX","hc":"xl",
"lead":"<strong>One workflow across CLI and IDE</strong> for teams that keep everything on-prem.",
"feats":["Air-gapped","CLI + IDE","Recipes & reporting"]},
{"kind":"product","accent":"#C21FD0","num":"06 / 07","pill":"Moddy","disp":"Moddy","hc":"xl",
"lead":"<strong>LLMs grounded in real code structure,</strong> so changes are safe, reviewable, and at scale.",
"feats":["LLM + LST","Multi-repo","Reviewable PRs"]},
{"kind":"product","accent":"#2DD4BF","num":"07 / 07","pill":"IDE plugins","disp":"IDE plugins","hc":"lg",
"lead":"<strong>Multi-repo search and recipe authoring</strong> right inside IntelliJ IDEA.",
"feats":["Code search","Recipe development","IntelliJ IDEA"]},
{"kind":"title","accent":"#85FE99","head":"Transform your codebase<br>in minutes, not months","hc":"md",
"lead":"Start at <strong>moderne.io</strong>, or explore the docs to go further.","cta":"Get started"}
]
</script>
<div id="stage"></div>
<div id="dots"></div>
<div class="hint">← → to navigate · F for fullscreen</div>
<script>
const slides = JSON.parse(document.getElementById('deckdata').textContent);
const stage = document.getElementById('stage');
const dotsWrap = document.getElementById('dots');
let cur = 0;
const arrow = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>`;
function render(){
const s = slides[cur], n = slides.length;
const isDark = s.kind === "title";
const accent = s.accent;
const last = cur === n - 1;
const bp = ``;
const cnt = `<span class="counter">${String(cur+1).padStart(2,'0')} / ${String(n).padStart(2,'0')}</span>`;
let inner;
if (isDark){
const cta = `<button class="cta" onclick="${last?'go(0)':'next()'}">${s.cta} <span class="circ" style="color:var(--green-ink)">${arrow}</span></button>`;
inner = `
<div class="toprow">
<div class="logo"><svg class="mark" style="color:#fff"><use href="#m-mark"/></svg><span class="word">Moderne<span class="tm">™</span></span></div>
<span class="num">Moderne · Product overview</span>
</div>
<div class="center">
<h1 class="disp ${s.hc}">${s.head}</h1>
<p class="lead">${s.lead}</p>
<div style="margin-top:34px">${cta}</div>
</div>
<div class="foot"><span></span>${cnt}</div>`;
} else {
const feats = `<div class="feats">` + s.feats.map(f =>
`<div class="feat"><span class="dot" style="background:${accent}"></span><span class="lbl">${f}</span></div>`).join("") + `</div>`;
const next = `<button class="next" style="background:${accent}" onclick="next()">Next slide <span class="circ">${arrow}</span></button>`;
inner = `
<div class="toprow"><span class="num">${s.num}</span><span class="pill">${s.pill}</span></div>
<div class="block"><h1 class="disp ${s.hc}">${s.disp}</h1><p class="lead">${s.lead}</p>${feats}</div>
<div class="spacer"></div>
<div class="foot">${next}${cnt}</div>`;
}
stage.innerHTML = `<div class="slide ${isDark?'dark':'light'} active">
<div class="surface"></div>${bp}
<div class="bar" style="background:${accent}"></div>
<div class="pad">${inner}</div>
</div>`;
[...dotsWrap.children].forEach((d,i)=> d.classList.toggle('on', i===cur));
}
function go(i){ cur=(i+slides.length)%slides.length; render(); }
function next(){ go(cur+1); }
function prev(){ go(cur-1); }
slides.forEach((_,i)=>{ const b=document.createElement('button'); b.onclick=()=>go(i); dotsWrap.appendChild(b); });
document.addEventListener('keydown', e=>{
if(e.key==='ArrowRight'||e.key===' '){ next(); e.preventDefault(); }
else if(e.key==='ArrowLeft'){ prev(); }
else if(e.key.toLowerCase()==='f'){ if(!document.fullscreenElement) document.documentElement.requestFullscreen(); else document.exitFullscreen(); }
});
function fit(){ const pad=40; const sx=(window.innerWidth-pad)/1280, sy=(window.innerHeight-pad)/720; stage.style.transform=`scale(${Math.min(sx,sy)})`; }
window.addEventListener('resize', fit); fit(); render();
</script>
</body>
</html>