octocode-cli 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +129 -28
- package/out/chunks/chunk-7476PETK.js +309 -0
- package/out/chunks/chunk-CVNNNSMQ.js +26 -0
- package/out/chunks/chunk-OQBJTZWK.js +60 -0
- package/out/chunks/chunk-UCZCF3BQ.js +9 -0
- package/out/chunks/command-help-specs-JZXVSLZ5.js +8 -0
- package/out/chunks/commands-XBFPLHSQ.js +8 -0
- package/out/chunks/help-P7TCOYAJ.js +10 -0
- package/out/chunks/main-help-ULF5PAQY.js +10 -0
- package/out/chunks/prompts-5E6VKRX5.js +8 -0
- package/out/chunks/spinner-URV2OX6O.js +8 -0
- package/out/chunks/tool-command-M6VA7P2F.js +8 -0
- package/out/octocode-cli.js +1 -1
- package/package.json +5 -3
- package/skills/README.md +60 -58
- package/skills/agentic-flow-best-practices/SKILL.md +280 -0
- package/skills/agentic-flow-best-practices/references/agent-collaboration-patterns.md +75 -0
- package/skills/agentic-flow-best-practices/references/pr-review-agent-example.md +47 -0
- package/skills/agentic-flow-best-practices/references/resources.md +112 -0
- package/skills/octocode-brainstorming/.env.example +11 -0
- package/skills/octocode-brainstorming/SKILL.md +262 -0
- package/skills/octocode-brainstorming/scripts/tavily-search.mjs +138 -0
- package/skills/octocode-chrome-devtools/README.md +541 -0
- package/skills/octocode-chrome-devtools/SKILL.md +197 -0
- package/skills/octocode-chrome-devtools/agents/openai.yaml +7 -0
- package/skills/octocode-chrome-devtools/references/CDP_AGENT_REFERENCE.md +401 -0
- package/skills/octocode-chrome-devtools/references/CHROME_FLAGS.md +234 -0
- package/skills/octocode-chrome-devtools/references/INTENTS.md +108 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_AUTH.md +179 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_AUTOMATION.md +214 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_DEBUG.md +329 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_ENVIRONMENT.md +237 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_INSPECT.md +263 -0
- package/skills/octocode-chrome-devtools/references/INTENTS_STORAGE_CONSENT.md +214 -0
- package/skills/octocode-chrome-devtools/references/RECOVERY.md +39 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS.md +43 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_ASYNC_WORKERS.md +345 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_BROWSER.md +403 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_OBSERVE.md +275 -0
- package/skills/octocode-chrome-devtools/references/SCRIPT_PATTERNS_SPECIAL.md +18 -0
- package/skills/octocode-chrome-devtools/scripts/cdp-runner.mjs +503 -0
- package/skills/octocode-chrome-devtools/scripts/cdp-sandbox.mjs +123 -0
- package/skills/octocode-chrome-devtools/scripts/cdp-template.mjs +81 -0
- package/skills/octocode-chrome-devtools/scripts/octocode-chrome-devtools.vpn.example.json +8 -0
- package/skills/octocode-chrome-devtools/scripts/open-browser.mjs +362 -0
- package/skills/octocode-chrome-devtools/scripts/sourcemap-resolver.mjs +193 -0
- package/skills/octocode-chrome-devtools/scripts/undercover.mjs +226 -0
- package/skills/octocode-design/README.md +2 -2
- package/skills/octocode-documentation-writer/README.md +1 -1
- package/skills/octocode-engineer/README.md +1 -1
- package/skills/octocode-engineer/SKILL.md +137 -306
- package/skills/octocode-engineer/references/cli-reference.md +13 -0
- package/skills/octocode-engineer/references/output-files.md +3 -3
- package/skills/octocode-engineer/scripts/run.js +146 -146
- package/skills/octocode-engineer/src/pipeline/main.ts +1 -17
- package/skills/octocode-engineer/src/pipeline/progress.ts +4 -0
- package/skills/octocode-engineer/src/reporting/summary-md.test.ts +48 -0
- package/skills/octocode-engineer/src/reporting/summary-md.ts +43 -2
- package/skills/octocode-install/SKILL.md +1 -1
- package/skills/octocode-pull-request-reviewer/README.md +5 -5
- package/skills/octocode-pull-request-reviewer/SKILL.md +1 -1
- package/skills/octocode-research/AGENTS.md +1 -1
- package/skills/octocode-research/README.md +2 -2
- package/skills/octocode-research/docs/ARCHITECTURE.md +1 -1
- package/skills/octocode-research/scripts/server.js +184 -239
- package/skills/octocode-research/src/routes/github.ts +4 -21
- package/skills/octocode-research/src/routes/local.ts +4 -21
- package/skills/octocode-research/src/utils/fileContentTransform.ts +44 -0
- package/skills/octocode-search-skill/SKILL.md +337 -0
- package/skills/octocode-search-skill/references/agent-skills-guide.md +177 -0
- package/skills/octocode-search-skill/references/discovery-surfaces.md +162 -0
- package/skills/octocode-search-skill/references/fetch-and-create-locally.md +57 -0
- package/skills/octocode-search-skill/references/install-reference.md +130 -0
- package/skills/octocode-search-skill/references/references-template.md +27 -0
- package/skills/octocode-search-skill/references/references.md +62 -0
- package/skills/octocode-slides/README.md +307 -0
- package/skills/octocode-slides/SKILL.md +410 -0
- package/skills/octocode-slides/references/01-brief.md +156 -0
- package/skills/octocode-slides/references/02-research.md +149 -0
- package/skills/octocode-slides/references/03-outline.md +172 -0
- package/skills/octocode-slides/references/04-design.md +301 -0
- package/skills/octocode-slides/references/05-implementation.md +213 -0
- package/skills/octocode-slides/references/06-review.md +258 -0
- package/skills/octocode-slides/references/animation.md +281 -0
- package/skills/octocode-slides/references/design-system.md +316 -0
- package/skills/octocode-slides/references/html-templates.md +673 -0
- package/skills/octocode-slides/references/image-generation.md +448 -0
- package/skills/octocode-slides/references/resources.md +840 -0
- package/skills/octocode-slides/references/slide-rules.md +541 -0
- package/skills/octocode-slides/references/wireframes.md +727 -0
- package/skills/octocode-slides/scripts/animation.js +182 -0
- package/skills/octocode-slides/scripts/base.css +353 -0
- package/skills/octocode-slides/scripts/base.html +655 -0
- package/skills/octocode-slides/scripts/generate_image.py +221 -0
- package/skills/octocode-slides/scripts/navbridge.js +79 -0
- package/skills/octocode-slides/scripts/presenter.js +316 -0
- package/skills/octocode-slides/scripts/slide.html +248 -0
- package/skills/octocode-stats/SKILL.md +73 -0
- package/skills/octocode-stats/assets/template.html +1332 -0
- package/skills/octocode-stats/scripts/build_dashboard.mjs +407 -0
- package/out/chunks/chunk-LH4AZJPA.js +0 -389
- package/out/chunks/command-help-specs-CQ3RBLP6.js +0 -8
- package/out/chunks/commands-M3QTWKWE.js +0 -51
- package/out/chunks/help-XPXP46ZT.js +0 -10
- package/out/chunks/main-help-HXFAFHPG.js +0 -10
- package/out/chunks/tool-command-VHFLPIHY.js +0 -8
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* animation.js — In-slide step animation engine for Octocode Slides
|
|
3
|
+
*
|
|
4
|
+
* Elements marked with [data-step] are "steps" — components revealed
|
|
5
|
+
* sequentially with → / Space / ↓ and hidden in reverse with ← / ↑.
|
|
6
|
+
*
|
|
7
|
+
* HOW IT WORKS
|
|
8
|
+
* ─────────────
|
|
9
|
+
* Steps are revealed before the slide advances to the next slide, and
|
|
10
|
+
* all steps must be hidden before the slide retreats to the previous one.
|
|
11
|
+
*
|
|
12
|
+
* This is achieved by intercepting keydown events in capture phase, before
|
|
13
|
+
* navbridge.js forwards them to the parent (index.html). When a step is
|
|
14
|
+
* consumed, stopImmediatePropagation() prevents navbridge from seeing the
|
|
15
|
+
* key — so the parent does not advance the slide. Once all steps are
|
|
16
|
+
* exhausted in either direction, the key passes through normally and the
|
|
17
|
+
* parent navigates to the next or previous slide.
|
|
18
|
+
*
|
|
19
|
+
* REQUIRED LOADING ORDER (in slide HTML, before </body>):
|
|
20
|
+
* <script src="../js/animation.js"></script> ← MUST come first
|
|
21
|
+
* <script src="../js/navbridge.js"></script> ← always last
|
|
22
|
+
*
|
|
23
|
+
* USAGE
|
|
24
|
+
* ─────
|
|
25
|
+
* Add data-step="N" to any element (N = 1-based display order):
|
|
26
|
+
*
|
|
27
|
+
* <li data-step="1">First point</li>
|
|
28
|
+
* <li data-step="2">Second point</li>
|
|
29
|
+
* <li data-step="3">Third point</li>
|
|
30
|
+
*
|
|
31
|
+
* If the value is absent or non-numeric, DOM order is used as the fallback.
|
|
32
|
+
* Elements without [data-step] are unaffected and always visible.
|
|
33
|
+
*
|
|
34
|
+
* CUSTOMISING ANIMATIONS
|
|
35
|
+
* ──────────────────────
|
|
36
|
+
* Override the default fade-up in the slide's local <style>:
|
|
37
|
+
*
|
|
38
|
+
* [data-step] { opacity: 0; transform: scale(0.95); transition: ... }
|
|
39
|
+
* [data-step].step-visible { opacity: 1; transform: scale(1); }
|
|
40
|
+
*
|
|
41
|
+
* Add staggered delays using CSS nth-of-type or by setting a custom
|
|
42
|
+
* transition-delay on each step element.
|
|
43
|
+
*
|
|
44
|
+
* OPTIONAL — step indicator dot bar
|
|
45
|
+
* ───────────────────────────────────
|
|
46
|
+
* Add data-step-indicator to the slide root (<div class="slide ...">)
|
|
47
|
+
* to enable a small dot bar that tracks the current step count:
|
|
48
|
+
*
|
|
49
|
+
* <div class="slide slide--content" data-step-indicator>
|
|
50
|
+
*
|
|
51
|
+
* See animation.md for full documentation.
|
|
52
|
+
*/
|
|
53
|
+
(function () {
|
|
54
|
+
/* Skip when not embedded in an iframe (e.g. opened standalone for debug). */
|
|
55
|
+
if (window.parent === window) return;
|
|
56
|
+
|
|
57
|
+
/* ── Inject default step CSS ──────────────────────────────────────────── */
|
|
58
|
+
var style = document.createElement('style');
|
|
59
|
+
style.textContent = [
|
|
60
|
+
/* Hidden state — all [data-step] elements start invisible */
|
|
61
|
+
'[data-step]{',
|
|
62
|
+
' opacity:0;',
|
|
63
|
+
' transform:translateY(14px);',
|
|
64
|
+
' transition:opacity 320ms cubic-bezier(.4,0,.2,1),',
|
|
65
|
+
' transform 320ms cubic-bezier(.4,0,.2,1);',
|
|
66
|
+
' will-change:opacity,transform;',
|
|
67
|
+
'}',
|
|
68
|
+
/* Visible state — added by showNext() */
|
|
69
|
+
'[data-step].step-visible{',
|
|
70
|
+
' opacity:1;',
|
|
71
|
+
' transform:translateY(0);',
|
|
72
|
+
'}',
|
|
73
|
+
/* Step indicator dot bar */
|
|
74
|
+
'.step-indicator{',
|
|
75
|
+
' display:flex;gap:6px;align-items:center;',
|
|
76
|
+
' position:absolute;bottom:18px;left:50%;transform:translateX(-50%);',
|
|
77
|
+
' z-index:20;pointer-events:none;',
|
|
78
|
+
'}',
|
|
79
|
+
'.step-dot{',
|
|
80
|
+
' width:6px;height:6px;border-radius:50%;',
|
|
81
|
+
' background:rgba(255,255,255,0.25);',
|
|
82
|
+
' transition:background 200ms ease,transform 200ms ease;',
|
|
83
|
+
'}',
|
|
84
|
+
'.step-dot.is-done{background:rgba(255,255,255,0.85);transform:scale(1.2);}'
|
|
85
|
+
].join('');
|
|
86
|
+
document.head.appendChild(style);
|
|
87
|
+
|
|
88
|
+
/* ── State ──────────────────────────────────────────────────────────── */
|
|
89
|
+
var steps = []; /* ordered [data-step] elements */
|
|
90
|
+
var currentStep = 0; /* how many steps are currently visible */
|
|
91
|
+
var indicator = null; /* dot bar element, if enabled */
|
|
92
|
+
|
|
93
|
+
/* ── Collect and sort steps ─────────────────────────────────────────── */
|
|
94
|
+
function collectSteps() {
|
|
95
|
+
var els = document.querySelectorAll('[data-step]');
|
|
96
|
+
|
|
97
|
+
steps = Array.prototype.slice.call(els).sort(function (a, b) {
|
|
98
|
+
var na = parseInt(a.getAttribute('data-step'), 10);
|
|
99
|
+
var nb = parseInt(b.getAttribute('data-step'), 10);
|
|
100
|
+
var aNaN = isNaN(na);
|
|
101
|
+
var bNaN = isNaN(nb);
|
|
102
|
+
/* Both non-numeric: keep DOM order (querySelectorAll is document order) */
|
|
103
|
+
if (aNaN && bNaN) return 0;
|
|
104
|
+
if (aNaN) return 1;
|
|
105
|
+
if (bNaN) return -1;
|
|
106
|
+
return na - nb;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
if (!steps.length) return;
|
|
110
|
+
|
|
111
|
+
/* Build optional dot indicator */
|
|
112
|
+
var slideRoot = document.querySelector('[data-step-indicator]');
|
|
113
|
+
if (slideRoot) {
|
|
114
|
+
indicator = document.createElement('div');
|
|
115
|
+
indicator.className = 'step-indicator';
|
|
116
|
+
steps.forEach(function () {
|
|
117
|
+
var dot = document.createElement('span');
|
|
118
|
+
dot.className = 'step-dot';
|
|
119
|
+
indicator.appendChild(dot);
|
|
120
|
+
});
|
|
121
|
+
slideRoot.appendChild(indicator);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ── Show next step ─────────────────────────────────────────────────── */
|
|
126
|
+
function showNext() {
|
|
127
|
+
if (currentStep >= steps.length) return false; /* all shown — pass through */
|
|
128
|
+
steps[currentStep].classList.add('step-visible');
|
|
129
|
+
if (indicator) {
|
|
130
|
+
indicator.children[currentStep].classList.add('is-done');
|
|
131
|
+
}
|
|
132
|
+
currentStep++;
|
|
133
|
+
return true; /* consumed */
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* ── Hide last visible step ─────────────────────────────────────────── */
|
|
137
|
+
function hideLast() {
|
|
138
|
+
if (currentStep <= 0) return false; /* none shown — pass through */
|
|
139
|
+
currentStep--;
|
|
140
|
+
steps[currentStep].classList.remove('step-visible');
|
|
141
|
+
if (indicator) {
|
|
142
|
+
indicator.children[currentStep].classList.remove('is-done');
|
|
143
|
+
}
|
|
144
|
+
return true; /* consumed */
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* ── Key sets ───────────────────────────────────────────────────────── */
|
|
148
|
+
var FORWARD = { ArrowRight: 1, ArrowDown: 1, ' ': 1 };
|
|
149
|
+
var BACKWARD = { ArrowLeft: 1, ArrowUp: 1 };
|
|
150
|
+
|
|
151
|
+
/* ── Keydown interceptor (capture phase, before navbridge) ──────────── */
|
|
152
|
+
/*
|
|
153
|
+
* Both animation.js and navbridge.js attach to document in capture phase.
|
|
154
|
+
* Because animation.js is loaded (and therefore registered) first, its
|
|
155
|
+
* handler runs before navbridge's. When a step is consumed, calling
|
|
156
|
+
* stopImmediatePropagation() prevents navbridge from seeing the event,
|
|
157
|
+
* so the parent (index.html) does not advance or retreat the slide.
|
|
158
|
+
*
|
|
159
|
+
* When no step is available (all shown going forward, none going back),
|
|
160
|
+
* the key is NOT consumed — it falls through to navbridge, which forwards
|
|
161
|
+
* it to the parent, and normal slide navigation occurs.
|
|
162
|
+
*/
|
|
163
|
+
document.addEventListener('keydown', function (e) {
|
|
164
|
+
if (!steps.length) return; /* this slide has no steps — no-op */
|
|
165
|
+
|
|
166
|
+
var consumed = false;
|
|
167
|
+
if (FORWARD[e.key]) consumed = showNext();
|
|
168
|
+
if (BACKWARD[e.key]) consumed = hideLast();
|
|
169
|
+
|
|
170
|
+
if (consumed) {
|
|
171
|
+
e.stopImmediatePropagation();
|
|
172
|
+
e.preventDefault();
|
|
173
|
+
}
|
|
174
|
+
}, true /* capture phase */);
|
|
175
|
+
|
|
176
|
+
/* ── Init ────────────────────────────────────────────────────────────── */
|
|
177
|
+
if (document.readyState === 'loading') {
|
|
178
|
+
document.addEventListener('DOMContentLoaded', collectSteps);
|
|
179
|
+
} else {
|
|
180
|
+
collectSteps();
|
|
181
|
+
}
|
|
182
|
+
})();
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/* base.css — layout, variables, all slide rules */
|
|
2
|
+
|
|
3
|
+
:root {
|
|
4
|
+
/* --- Colors (defaults; theme.css overrides) --- */
|
|
5
|
+
--bg: #0D1117;
|
|
6
|
+
--surface: #161B22;
|
|
7
|
+
--border: #30363D;
|
|
8
|
+
--accent: #39D353;
|
|
9
|
+
--text: #E6EDF3;
|
|
10
|
+
--muted: #7D8590;
|
|
11
|
+
--code-bg: #0D1117;
|
|
12
|
+
--code-text: #79C0FF;
|
|
13
|
+
|
|
14
|
+
/* --- Fonts (theme.css sets these) --- */
|
|
15
|
+
--font-head: system-ui, sans-serif;
|
|
16
|
+
--font-body: system-ui, sans-serif;
|
|
17
|
+
--font-mono: 'Courier New', monospace;
|
|
18
|
+
|
|
19
|
+
/* --- Type scale (responsive, no px overrides) --- */
|
|
20
|
+
--t-display: clamp(2.75rem, 5.5vw, 4.25rem); /* 44–68px — title/section */
|
|
21
|
+
--t-title: clamp(1.6rem, 3.5vw, 2.5rem); /* 26–40px — slide headings */
|
|
22
|
+
--t-sub: clamp(1.15rem, 2.5vw, 1.65rem); /* 18–26px — descriptions, sub-headings */
|
|
23
|
+
--t-body: clamp(1rem, 1.8vw, 1.2rem); /* 16–19px — bullets, paragraphs */
|
|
24
|
+
--t-small: clamp(0.75rem, 1.2vw, 0.9rem); /* 12–14px — captions, footers */
|
|
25
|
+
--t-code: clamp(0.82rem, 1.4vw, 1rem); /* 13–16px — code blocks */
|
|
26
|
+
|
|
27
|
+
/* --- Spacing (8px grid) --- */
|
|
28
|
+
--sp-1: 0.5rem; --sp-2: 1rem; --sp-3: 1.5rem;
|
|
29
|
+
--sp-4: 2rem; --sp-6: 3rem; --sp-8: 4rem;
|
|
30
|
+
|
|
31
|
+
/* --- Slide canvas --- */
|
|
32
|
+
--pad: var(--sp-8);
|
|
33
|
+
|
|
34
|
+
/* --- Radius --- */
|
|
35
|
+
--r-sm: 4px; --r-md: 8px; --r-lg: 16px;
|
|
36
|
+
|
|
37
|
+
/* --- Motion --- */
|
|
38
|
+
--fast: 150ms; --base: 300ms; --slow: 600ms;
|
|
39
|
+
--ease: cubic-bezier(0.22, 1, 0.36, 1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Reset */
|
|
43
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
44
|
+
|
|
45
|
+
/* Slide fills its iframe 100%×100% — scaling is on the stage wrapper */
|
|
46
|
+
html { width: 100%; height: 100%; }
|
|
47
|
+
body {
|
|
48
|
+
width: 100%; height: 100%;
|
|
49
|
+
font-family: var(--font-body);
|
|
50
|
+
color: var(--text);
|
|
51
|
+
background: var(--bg);
|
|
52
|
+
line-height: 1.6;
|
|
53
|
+
overflow: hidden; /* slides should never scroll — split content if it overflows */
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/* ============================================================ */
|
|
57
|
+
/* CANONICAL SLIDE SKELETON */
|
|
58
|
+
/* Every slide uses up to four regions, in this order: */
|
|
59
|
+
/* .slide-logo optional · brand mark, top-right (absolute) */
|
|
60
|
+
/* .slide-header optional · .title + .description */
|
|
61
|
+
/* .slide-content REQUIRED · smart flex body */
|
|
62
|
+
/* .slide-footer optional · source / page / link */
|
|
63
|
+
/* ============================================================ */
|
|
64
|
+
|
|
65
|
+
.slide {
|
|
66
|
+
width: 100%; height: 100%;
|
|
67
|
+
padding: var(--pad);
|
|
68
|
+
display: flex;
|
|
69
|
+
flex-direction: column;
|
|
70
|
+
background: var(--bg);
|
|
71
|
+
position: relative;
|
|
72
|
+
overflow: hidden;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* Region: logo (absolute top-right) */
|
|
76
|
+
.slide-logo {
|
|
77
|
+
position: absolute;
|
|
78
|
+
top: var(--sp-3);
|
|
79
|
+
right: var(--sp-4);
|
|
80
|
+
height: clamp(20px, 2.2vw, 30px);
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
z-index: 2;
|
|
84
|
+
opacity: 0.85;
|
|
85
|
+
}
|
|
86
|
+
.slide-logo img,
|
|
87
|
+
.slide-logo svg { height: 100%; width: auto; display: block; }
|
|
88
|
+
|
|
89
|
+
/* Region: header (title + description, stacked) */
|
|
90
|
+
.slide-header {
|
|
91
|
+
flex-shrink: 0;
|
|
92
|
+
margin-bottom: var(--sp-4);
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-direction: column;
|
|
95
|
+
gap: var(--sp-2);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* Region: content (smart flex body, fills remaining height) */
|
|
99
|
+
.slide-content {
|
|
100
|
+
flex: 1;
|
|
101
|
+
min-height: 0;
|
|
102
|
+
display: flex;
|
|
103
|
+
flex-direction: column;
|
|
104
|
+
gap: var(--sp-3);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* Region: footer (source, page number, link, attribution) */
|
|
108
|
+
.slide-footer {
|
|
109
|
+
flex-shrink: 0;
|
|
110
|
+
margin-top: var(--sp-4);
|
|
111
|
+
padding-top: var(--sp-3);
|
|
112
|
+
border-top: 1px solid var(--border);
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
justify-content: space-between;
|
|
116
|
+
gap: var(--sp-3);
|
|
117
|
+
font-size: var(--t-small);
|
|
118
|
+
color: var(--muted);
|
|
119
|
+
}
|
|
120
|
+
.slide-footer a { color: var(--accent); text-decoration: none; }
|
|
121
|
+
.slide-footer a:hover { text-decoration: underline; }
|
|
122
|
+
|
|
123
|
+
/* Smart flex modifiers for .slide-content (opt-in when default isn't right) */
|
|
124
|
+
.slide-content--center { justify-content: center; align-items: center; text-align: center; }
|
|
125
|
+
.slide-content--middle { justify-content: center; }
|
|
126
|
+
.slide-content--row { flex-direction: row; align-items: stretch; gap: var(--sp-6); }
|
|
127
|
+
.slide-content--grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-6); }
|
|
128
|
+
.slide-content--grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }
|
|
129
|
+
|
|
130
|
+
/* ---------- Typography classes ---------- */
|
|
131
|
+
.display {
|
|
132
|
+
font-family: var(--font-head);
|
|
133
|
+
font-size: var(--t-display);
|
|
134
|
+
font-weight: 700;
|
|
135
|
+
line-height: 1.12;
|
|
136
|
+
letter-spacing: -0.02em;
|
|
137
|
+
color: var(--accent);
|
|
138
|
+
}
|
|
139
|
+
.title {
|
|
140
|
+
font-family: var(--font-head);
|
|
141
|
+
font-size: var(--t-title);
|
|
142
|
+
font-weight: 700;
|
|
143
|
+
line-height: 1.2;
|
|
144
|
+
color: var(--text);
|
|
145
|
+
}
|
|
146
|
+
.description {
|
|
147
|
+
font-family: var(--font-body);
|
|
148
|
+
font-size: var(--t-sub);
|
|
149
|
+
font-weight: 400;
|
|
150
|
+
line-height: 1.4;
|
|
151
|
+
color: var(--muted);
|
|
152
|
+
}
|
|
153
|
+
.subtitle { font-size: var(--t-sub); color: var(--muted); }
|
|
154
|
+
.eyebrow {
|
|
155
|
+
font-size: var(--t-small);
|
|
156
|
+
color: var(--accent);
|
|
157
|
+
font-weight: 600;
|
|
158
|
+
letter-spacing: 0.08em;
|
|
159
|
+
text-transform: uppercase;
|
|
160
|
+
margin-bottom: var(--sp-2);
|
|
161
|
+
}
|
|
162
|
+
.meta { font-size: var(--t-small); color: var(--muted); margin-top: var(--sp-4); }
|
|
163
|
+
|
|
164
|
+
/* ---------- Slide type rules ---------- */
|
|
165
|
+
|
|
166
|
+
/* Centered types: vertically center the entire region stack.
|
|
167
|
+
.slide-content stops being greedy so the stack sizes to its content. */
|
|
168
|
+
.slide--title,
|
|
169
|
+
.slide--section,
|
|
170
|
+
.slide--quote,
|
|
171
|
+
.slide--closing { justify-content: center; }
|
|
172
|
+
|
|
173
|
+
.slide--title .slide-content,
|
|
174
|
+
.slide--section .slide-content,
|
|
175
|
+
.slide--quote .slide-content,
|
|
176
|
+
.slide--closing .slide-content { flex: 0 0 auto; }
|
|
177
|
+
|
|
178
|
+
/* Title and closing also center horizontally */
|
|
179
|
+
.slide--title,
|
|
180
|
+
.slide--closing { text-align: center; align-items: center; }
|
|
181
|
+
.slide--title .slide-header,
|
|
182
|
+
.slide--title .slide-content,
|
|
183
|
+
.slide--closing .slide-header,
|
|
184
|
+
.slide--closing .slide-content { align-items: center; }
|
|
185
|
+
.slide--title .meta { display: flex; justify-content: center; gap: var(--sp-2); }
|
|
186
|
+
|
|
187
|
+
/* Stats and agenda: header sits above; content vertically centered in body */
|
|
188
|
+
.slide--stats .slide-content,
|
|
189
|
+
.slide--agenda .slide-content { justify-content: center; }
|
|
190
|
+
|
|
191
|
+
/* Quote: extra horizontal padding for breathing room */
|
|
192
|
+
.slide--quote { padding: var(--sp-8) calc(var(--sp-8) * 1.5); text-align: center; }
|
|
193
|
+
.slide--quote .slide-content { align-items: center; }
|
|
194
|
+
|
|
195
|
+
/* Section: vertically centered, left-aligned (default text-align) */
|
|
196
|
+
.slide--section .slide-header { gap: var(--sp-3); }
|
|
197
|
+
.section-num { font-size: var(--t-small); color: var(--accent); font-weight: 700; letter-spacing: 0.1em; }
|
|
198
|
+
|
|
199
|
+
/* ---------- Component classes (used inside .slide-content) ---------- */
|
|
200
|
+
|
|
201
|
+
/* agenda */
|
|
202
|
+
.agenda-list { list-style: none; display: flex; flex-direction: column; gap: var(--sp-3); }
|
|
203
|
+
.agenda-list li { display: flex; align-items: center; gap: var(--sp-3); font-size: var(--t-body); }
|
|
204
|
+
.num { font-size: var(--t-small); color: var(--accent); font-weight: 700; min-width: 2.5rem; }
|
|
205
|
+
|
|
206
|
+
/* bullets (content slide) */
|
|
207
|
+
.bullets { list-style: none; display: flex; flex-direction: column; gap: var(--sp-3); }
|
|
208
|
+
.bullets li {
|
|
209
|
+
font-size: var(--t-body);
|
|
210
|
+
padding-left: var(--sp-4);
|
|
211
|
+
position: relative;
|
|
212
|
+
}
|
|
213
|
+
.bullets li::before { content: '→'; position: absolute; left: 0; color: var(--accent); }
|
|
214
|
+
|
|
215
|
+
/* two-column */
|
|
216
|
+
.col-heading { font-size: var(--t-sub); font-weight: 700; color: var(--accent); margin-bottom: var(--sp-3); }
|
|
217
|
+
.col ul { list-style: none; display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--t-body); }
|
|
218
|
+
|
|
219
|
+
/* quote */
|
|
220
|
+
.quote-mark { font-size: 6rem; line-height: 0.8; color: var(--accent); opacity: 0.25; font-family: Georgia, serif; }
|
|
221
|
+
.quote-text { font-size: var(--t-sub); font-style: italic; line-height: 1.5; margin: var(--sp-4) 0; }
|
|
222
|
+
.quote-attr { font-size: var(--t-small); color: var(--muted); }
|
|
223
|
+
|
|
224
|
+
/* code */
|
|
225
|
+
.code-block {
|
|
226
|
+
background: var(--code-bg);
|
|
227
|
+
border: 1px solid var(--border);
|
|
228
|
+
border-radius: var(--r-md);
|
|
229
|
+
padding: var(--sp-4);
|
|
230
|
+
font-family: var(--font-mono);
|
|
231
|
+
font-size: var(--t-code);
|
|
232
|
+
color: var(--code-text);
|
|
233
|
+
line-height: 1.6;
|
|
234
|
+
overflow: hidden;
|
|
235
|
+
flex: 1;
|
|
236
|
+
}
|
|
237
|
+
.code-caption { font-size: var(--t-small); color: var(--muted); margin-top: var(--sp-2); }
|
|
238
|
+
|
|
239
|
+
/* chart */
|
|
240
|
+
.bar-chart { display: flex; flex-direction: column; gap: var(--sp-3); flex: 1; }
|
|
241
|
+
.bar-row { display: flex; align-items: center; gap: var(--sp-3); }
|
|
242
|
+
.bar-label { font-size: var(--t-small); min-width: 8rem; color: var(--muted); }
|
|
243
|
+
.bar { flex: 1; height: 2.25rem; background: var(--surface); border-radius: var(--r-sm); position: relative; overflow: hidden; }
|
|
244
|
+
.bar::after {
|
|
245
|
+
content: '';
|
|
246
|
+
position: absolute; left: 0; top: 0;
|
|
247
|
+
width: var(--pct, 0%); height: 100%;
|
|
248
|
+
background: var(--accent);
|
|
249
|
+
border-radius: var(--r-sm);
|
|
250
|
+
transition: width var(--slow) var(--ease);
|
|
251
|
+
}
|
|
252
|
+
.bar span { position: absolute; right: var(--sp-2); top: 50%; transform: translateY(-50%); font-size: var(--t-small); font-weight: 700; z-index: 1; }
|
|
253
|
+
.chart-insight { font-size: var(--t-body); color: var(--muted); font-style: italic; margin-top: var(--sp-3); }
|
|
254
|
+
|
|
255
|
+
/* timeline */
|
|
256
|
+
.timeline { list-style: none; display: flex; flex-direction: column; gap: 0; position: relative; }
|
|
257
|
+
.timeline::before { content: ''; position: absolute; left: 0.55rem; top: 0; bottom: 0; width: 2px; background: var(--border); }
|
|
258
|
+
.tl-item { display: flex; gap: var(--sp-3); padding-bottom: var(--sp-4); position: relative; }
|
|
259
|
+
.tl-dot { width: 1.1rem; height: 1.1rem; min-width: 1.1rem; border-radius: 50%; background: var(--accent); margin-top: 0.25rem; z-index: 1; }
|
|
260
|
+
.tl-label { font-size: var(--t-small); color: var(--accent); font-weight: 700; display: block; }
|
|
261
|
+
|
|
262
|
+
/* comparison */
|
|
263
|
+
.comparison { display: grid; grid-template-columns: 1fr auto 1fr; gap: var(--sp-4); flex: 1; }
|
|
264
|
+
.cmp-divider { width: 1px; background: var(--border); }
|
|
265
|
+
.cmp-col h3 { font-size: var(--t-sub); font-weight: 700; margin-bottom: var(--sp-3); }
|
|
266
|
+
.cmp-before h3 { color: var(--muted); }
|
|
267
|
+
.cmp-after h3 { color: var(--accent); }
|
|
268
|
+
.cmp-col ul { list-style: none; display: flex; flex-direction: column; gap: var(--sp-2); font-size: var(--t-body); }
|
|
269
|
+
|
|
270
|
+
/* closing */
|
|
271
|
+
.closing-links { display: flex; gap: var(--sp-4); justify-content: center; margin-top: var(--sp-4); }
|
|
272
|
+
.closing-links a { color: var(--accent); font-size: var(--t-body); text-decoration: none; border-bottom: 1px solid currentColor; padding-bottom: 2px; }
|
|
273
|
+
|
|
274
|
+
/* stats */
|
|
275
|
+
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--sp-6); padding: var(--sp-4) 0; flex: 1; align-items: center; }
|
|
276
|
+
.stat-item { display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); }
|
|
277
|
+
.stat-value { font-family: var(--font-head); font-size: var(--t-display); font-weight: 700; color: var(--accent); line-height: 1; letter-spacing: -0.02em; }
|
|
278
|
+
.stat-label { font-size: var(--t-body); color: var(--muted); text-align: center; }
|
|
279
|
+
.stat-caption { font-size: var(--t-small); color: var(--muted); font-style: italic; margin-top: var(--sp-4); text-align: center; }
|
|
280
|
+
|
|
281
|
+
/* image (full-bleed) */
|
|
282
|
+
.slide--image { padding: 0; overflow: hidden; }
|
|
283
|
+
.slide--image img,
|
|
284
|
+
.slide--image video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
|
|
285
|
+
.image-overlay { position: absolute; inset: 0; background: linear-gradient(to bottom, transparent 40%, rgba(0,0,0,0.72) 100%); }
|
|
286
|
+
.image-caption { position: absolute; bottom: var(--sp-8); left: var(--sp-8); right: var(--sp-8); }
|
|
287
|
+
.slide--image .image-caption .display { color: #fff; text-shadow: 0 2px 12px rgba(0,0,0,0.5); }
|
|
288
|
+
.slide--image .image-caption .description { color: rgba(255,255,255,0.78); margin-top: var(--sp-2); }
|
|
289
|
+
|
|
290
|
+
/* image placeholder — used when user has not yet provided an image file */
|
|
291
|
+
.image-ph {
|
|
292
|
+
flex: 1;
|
|
293
|
+
border: 1.5px dashed var(--border);
|
|
294
|
+
border-radius: var(--r-md);
|
|
295
|
+
display: flex;
|
|
296
|
+
align-items: center;
|
|
297
|
+
justify-content: center;
|
|
298
|
+
background: var(--surface);
|
|
299
|
+
min-height: 180px;
|
|
300
|
+
color: var(--muted);
|
|
301
|
+
}
|
|
302
|
+
.image-ph-inner {
|
|
303
|
+
display: flex;
|
|
304
|
+
flex-direction: column;
|
|
305
|
+
align-items: center;
|
|
306
|
+
gap: var(--sp-2);
|
|
307
|
+
text-align: center;
|
|
308
|
+
padding: var(--sp-4);
|
|
309
|
+
}
|
|
310
|
+
.image-ph-label { font-size: var(--t-small); max-width: 28ch; line-height: 1.4; }
|
|
311
|
+
|
|
312
|
+
/* full-bleed placeholder — for slide--image type when image not yet provided */
|
|
313
|
+
.image-ph-bleed {
|
|
314
|
+
position: absolute;
|
|
315
|
+
inset: 0;
|
|
316
|
+
display: flex;
|
|
317
|
+
align-items: center;
|
|
318
|
+
justify-content: center;
|
|
319
|
+
background: var(--surface);
|
|
320
|
+
color: var(--muted);
|
|
321
|
+
font-size: var(--t-small);
|
|
322
|
+
font-family: var(--font-mono);
|
|
323
|
+
letter-spacing: 0.04em;
|
|
324
|
+
border: 2px dashed var(--border);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* Speaker notes — hidden in presentation */
|
|
328
|
+
.speaker-notes { display: none; }
|
|
329
|
+
|
|
330
|
+
/* ---------- Animations ---------- */
|
|
331
|
+
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
|
|
332
|
+
@keyframes slideUp { from { opacity: 0; transform: translateY(20px) } to { opacity: 1; transform: none } }
|
|
333
|
+
@keyframes popIn { from { opacity: 0; transform: scale(0.94) } to { opacity: 1; transform: none } }
|
|
334
|
+
|
|
335
|
+
.fade-in { animation: fadeIn var(--base) var(--ease) both; }
|
|
336
|
+
.slide-up { animation: slideUp var(--base) var(--ease) both; }
|
|
337
|
+
.pop-in { animation: popIn var(--fast) var(--ease) both; }
|
|
338
|
+
|
|
339
|
+
.delay-1 { animation-delay: 100ms; }
|
|
340
|
+
.delay-2 { animation-delay: 220ms; }
|
|
341
|
+
.delay-3 { animation-delay: 340ms; }
|
|
342
|
+
.delay-4 { animation-delay: 460ms; }
|
|
343
|
+
|
|
344
|
+
@media (prefers-reduced-motion: reduce) {
|
|
345
|
+
*, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/* Print / PDF export (headless Chrome: 1280×720 pages) */
|
|
349
|
+
@media print {
|
|
350
|
+
html, body { width: 1280px; height: 720px; overflow: hidden; }
|
|
351
|
+
.slide { width: 1280px; height: 720px; page-break-after: always; }
|
|
352
|
+
@page { size: 1280px 720px; margin: 0; }
|
|
353
|
+
}
|