@jjlmoya/landings 0.4.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/package.json +65 -0
- package/scripts/copy-public-assets.mjs +44 -0
- package/src/components/PreviewNavSidebar.astro +102 -0
- package/src/components/PreviewToolbar.astro +139 -0
- package/src/entries.ts +9 -0
- package/src/env.d.ts +4 -0
- package/src/index.ts +12 -0
- package/src/landing/team/assets/ambar-chiquilla.webp +0 -0
- package/src/landing/team/assets/ambar.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pointing.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-05.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-06.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-07-locked.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-08-locked.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-09-locked.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-attitude.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-cover.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-expensive.webp +0 -0
- package/src/landing/team/assets/bob-model-book/bob-pose-final.webp +0 -0
- package/src/landing/team/assets/bob.webp +0 -0
- package/src/landing/team/assets/drac.webp +0 -0
- package/src/landing/team/assets/feedback.webp +0 -0
- package/src/landing/team/assets/gamebob-team-hero.png +0 -0
- package/src/landing/team/assets/gamebob-team-hero.webp +0 -0
- package/src/landing/team/assets/jjlmoya/jjlmoya-exhausted.webp +0 -0
- package/src/landing/team/assets/jjlmoya/tinder-profile-winked.webp +0 -0
- package/src/landing/team/assets/jjlmoya/tinder-profile.webp +0 -0
- package/src/landing/team/assets/master-plan-food.webp +0 -0
- package/src/landing/team/assets/master-plan-money.webp +0 -0
- package/src/landing/team/assets/master-plan-more-food.webp +0 -0
- package/src/landing/team/assets/master-plan-more-money.webp +0 -0
- package/src/landing/team/assets/master-plan-projects.webp +0 -0
- package/src/landing/team/assets/master-plan-tools.webp +0 -0
- package/src/landing/team/assets/memorial/ambar-chiquillo.webp +0 -0
- package/src/landing/team/assets/music/bob-techno.mp3 +0 -0
- package/src/landing/team/assets/seal-of-approval.webp +0 -0
- package/src/landing/team/assets/terra.webp +0 -0
- package/src/landing/team/assets/webcomic/scene-1.webp +0 -0
- package/src/landing/team/assets/webcomic/scene-2.webp +0 -0
- package/src/landing/team/assets/webcomic/scene-3.webp +0 -0
- package/src/landing/team/assets/webcomic/scene-4.webp +0 -0
- package/src/landing/team/components/BobMasterPlan.astro +118 -0
- package/src/landing/team/components/BobModelBook.astro +253 -0
- package/src/landing/team/components/BobModelBookFrame.astro +73 -0
- package/src/landing/team/components/CompanyWorks.astro +180 -0
- package/src/landing/team/components/HumanTouch.astro +262 -0
- package/src/landing/team/components/MasterPlanScene.astro +73 -0
- package/src/landing/team/components/MemoryWall.astro +46 -0
- package/src/landing/team/components/ProductManifesto.astro +46 -0
- package/src/landing/team/components/SupportTransition.astro +67 -0
- package/src/landing/team/components/TeamComicScenes.astro +67 -0
- package/src/landing/team/components/TeamHero.astro +42 -0
- package/src/landing/team/components/TeamRoster.astro +94 -0
- package/src/landing/team/entry.ts +23 -0
- package/src/landing/team/i18n/en.ts +278 -0
- package/src/landing/team/i18n/es.ts +278 -0
- package/src/landing/team/i18n/index.ts +12 -0
- package/src/landing/team/landing.astro +31 -0
- package/src/landing/team/styles/BehindJoke.css +55 -0
- package/src/landing/team/styles/BobMasterPlan.css +213 -0
- package/src/landing/team/styles/BobModelBook.css +709 -0
- package/src/landing/team/styles/CompanyWorks.css +652 -0
- package/src/landing/team/styles/HumanTouch.css +1190 -0
- package/src/landing/team/styles/MemoryWall.css +50 -0
- package/src/landing/team/styles/ProductManifesto.css +164 -0
- package/src/landing/team/styles/SupportTransition.css +291 -0
- package/src/landing/team/styles/TeamComicScenes.css +129 -0
- package/src/landing/team/styles/TeamHero.css +149 -0
- package/src/landing/team/styles/TeamRoster.css +75 -0
- package/src/landing/team/styles/team-landing.css +83 -0
- package/src/layouts/PreviewLayout.astro +110 -0
- package/src/pages/[locale]/[slug].astro +70 -0
- package/src/pages/[locale].astro +165 -0
- package/src/pages/index.astro +3 -0
- package/src/styles/global.css +37 -0
- package/src/styles/tokens.css +107 -0
- package/src/tests/diacritics_density.test.ts +62 -0
- package/src/tests/i18n_coverage.test.ts +32 -0
- package/src/tests/inverted_punctuation.test.ts +67 -0
- package/src/tests/landing-test-helpers.ts +89 -0
- package/src/tests/landing_exports.test.ts +29 -0
- package/src/tests/mocks/astro_mock.js +1 -0
- package/src/tests/no_en_dash.test.ts +45 -0
- package/src/tests/no_h1_in_components.test.ts +33 -0
- package/src/tests/pagespeed_best_practices.test.ts +143 -0
- package/src/tests/script_density.test.ts +57 -0
- package/src/tests/slug_language_code_format.test.ts +20 -0
- package/src/tests/slug_uniqueness.test.ts +74 -0
- package/src/tests/title_quality.test.ts +34 -0
- package/src/types.ts +38 -0
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jjlmoya/landings",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.ts",
|
|
9
|
+
"./entries": "./src/entries.ts",
|
|
10
|
+
"./team": "./src/landing/team/landing.astro",
|
|
11
|
+
"./team/entry": "./src/landing/team/entry.ts"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"scripts"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"postinstall": "node ./scripts/copy-public-assets.mjs",
|
|
22
|
+
"dev": "astro dev",
|
|
23
|
+
"start": "astro dev",
|
|
24
|
+
"build": "astro build",
|
|
25
|
+
"preview": "astro preview",
|
|
26
|
+
"astro": "astro",
|
|
27
|
+
"lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
|
|
28
|
+
"check": "astro check",
|
|
29
|
+
"type-check": "astro check",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"preversion": "npm run lint && npm run test",
|
|
32
|
+
"postversion": "git push && git push --tags",
|
|
33
|
+
"patch": "npm version patch",
|
|
34
|
+
"minor": "npm version minor",
|
|
35
|
+
"major": "npm version major"
|
|
36
|
+
},
|
|
37
|
+
"lint-staged": {
|
|
38
|
+
"*.{ts,tsx,astro}": [
|
|
39
|
+
"eslint --fix"
|
|
40
|
+
]
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@iconify-json/mdi": "^1.2.3",
|
|
44
|
+
"@jjlmoya/prompagate": "^1.1.0",
|
|
45
|
+
"@jjlmoya/utils-shared": "1.2.0",
|
|
46
|
+
"astro": "^6.1.2",
|
|
47
|
+
"astro-icon": "^1.1.0"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@astrojs/check": "^0.9.8",
|
|
51
|
+
"eslint": "^9.39.4",
|
|
52
|
+
"eslint-plugin-astro": "^1.6.0",
|
|
53
|
+
"eslint-plugin-no-comments": "^1.1.10",
|
|
54
|
+
"husky": "^9.1.7",
|
|
55
|
+
"lint-staged": "^16.4.0",
|
|
56
|
+
"postcss-html": "^1.8.1",
|
|
57
|
+
"schema-dts": "^1.1.2",
|
|
58
|
+
"stylelint": "^17.6.0",
|
|
59
|
+
"stylelint-config-standard": "^40.0.0",
|
|
60
|
+
"stylelint-declaration-strict-value": "^1.11.1",
|
|
61
|
+
"typescript": "^5.4.0",
|
|
62
|
+
"typescript-eslint": "^8.58.0",
|
|
63
|
+
"vitest": "^4.1.2"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { cp, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
5
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
6
|
+
const consumerRoot = process.env.INIT_CWD || process.cwd();
|
|
7
|
+
const publicRoot = join(consumerRoot, "public", "landings", "team");
|
|
8
|
+
const styleFiles = [
|
|
9
|
+
"team-landing.css",
|
|
10
|
+
"TeamHero.css",
|
|
11
|
+
"CompanyWorks.css",
|
|
12
|
+
"BobMasterPlan.css",
|
|
13
|
+
"TeamComicScenes.css",
|
|
14
|
+
"HumanTouch.css",
|
|
15
|
+
"ProductManifesto.css",
|
|
16
|
+
"BobModelBook.css",
|
|
17
|
+
"SupportTransition.css",
|
|
18
|
+
"MemoryWall.css",
|
|
19
|
+
"TeamRoster.css",
|
|
20
|
+
"BehindJoke.css",
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const copies = [
|
|
24
|
+
["src/landing/team/assets", "assets"],
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
await mkdir(publicRoot, { recursive: true });
|
|
28
|
+
|
|
29
|
+
for (const [from, to] of copies) {
|
|
30
|
+
await cp(join(packageRoot, from), join(publicRoot, to), {
|
|
31
|
+
recursive: true,
|
|
32
|
+
force: true,
|
|
33
|
+
errorOnExist: false,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const cssBundle = await Promise.all(
|
|
38
|
+
styleFiles.map(async (file) => {
|
|
39
|
+
const content = await readFile(join(packageRoot, "src", "landing", "team", "styles", file), "utf8");
|
|
40
|
+
return `/* ${file} */\n${content.trim()}\n`;
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
await writeFile(join(publicRoot, "team.css"), `${cssBundle.join("\n")}\n`);
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
---
|
|
2
|
+
interface NavItem {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
href: string;
|
|
6
|
+
isActive?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
10
|
+
categoryTitle: string;
|
|
11
|
+
apps?: NavItem[];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { categoryTitle, apps = [] } = Astro.props;
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
<nav class="preview-nav-sidebar">
|
|
18
|
+
<div class="sidebar-header">
|
|
19
|
+
<h3>{categoryTitle}</h3>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<ul class="apps-list">
|
|
23
|
+
{
|
|
24
|
+
apps.map((app) => (
|
|
25
|
+
<li>
|
|
26
|
+
<a href={app.href} class:list={["app-link", { active: app.isActive }]}>
|
|
27
|
+
<span class="app-title">{app.title}</span>
|
|
28
|
+
</a>
|
|
29
|
+
</li>
|
|
30
|
+
))
|
|
31
|
+
}
|
|
32
|
+
</ul>
|
|
33
|
+
</nav>
|
|
34
|
+
|
|
35
|
+
<style>
|
|
36
|
+
.preview-nav-sidebar {
|
|
37
|
+
display: flex;
|
|
38
|
+
flex-direction: column;
|
|
39
|
+
height: 100%;
|
|
40
|
+
background: var(--bg-surface, #0f172a);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.sidebar-header {
|
|
44
|
+
padding: 2rem 1.5rem 1.5rem;
|
|
45
|
+
border-bottom: 1px solid var(--border-color, #1e293b);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.sidebar-header h3 {
|
|
49
|
+
margin: 0;
|
|
50
|
+
font-size: 0.75rem;
|
|
51
|
+
font-weight: 900;
|
|
52
|
+
text-transform: uppercase;
|
|
53
|
+
letter-spacing: 0.1em;
|
|
54
|
+
color: var(--text-muted, #94a3b8);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.apps-list {
|
|
58
|
+
list-style: none;
|
|
59
|
+
margin: 0;
|
|
60
|
+
padding: 0.5rem 0;
|
|
61
|
+
display: flex;
|
|
62
|
+
flex-direction: column;
|
|
63
|
+
gap: 0.25rem;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.apps-list li {
|
|
67
|
+
margin: 0;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.app-link {
|
|
71
|
+
display: flex;
|
|
72
|
+
align-items: center;
|
|
73
|
+
padding: 0.75rem 1.5rem;
|
|
74
|
+
color: var(--text-muted, #94a3b8);
|
|
75
|
+
text-decoration: none;
|
|
76
|
+
font-size: 0.9375rem;
|
|
77
|
+
font-weight: 500;
|
|
78
|
+
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
|
|
79
|
+
border-left: 3px solid transparent;
|
|
80
|
+
position: relative;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.app-link:hover {
|
|
84
|
+
color: var(--text-base, #f1f5f9);
|
|
85
|
+
background: rgba(255, 255, 255, 0.08);
|
|
86
|
+
padding-left: 1.75rem;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.app-link.active {
|
|
90
|
+
color: var(--accent, #f43f5e);
|
|
91
|
+
background: rgba(244, 63, 94, 0.15);
|
|
92
|
+
border-left-color: var(--accent, #f43f5e);
|
|
93
|
+
font-weight: 600;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.app-title {
|
|
97
|
+
display: block;
|
|
98
|
+
overflow: hidden;
|
|
99
|
+
text-overflow: ellipsis;
|
|
100
|
+
white-space: nowrap;
|
|
101
|
+
}
|
|
102
|
+
</style>
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { KnownLocale } from '../types';
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
currentLocale: KnownLocale;
|
|
6
|
+
localeUrls?: Partial<Record<KnownLocale, string>>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const { currentLocale, localeUrls = {} } = Astro.props;
|
|
10
|
+
|
|
11
|
+
const otherLocales = Object.entries(localeUrls).filter(([l]) => l !== currentLocale) as [KnownLocale, string][];
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
<nav class="preview-toolbar">
|
|
15
|
+
{
|
|
16
|
+
otherLocales.length > 0 && (
|
|
17
|
+
<div class="locale-group">
|
|
18
|
+
<span class="locale-current">{currentLocale.toUpperCase()}</span>
|
|
19
|
+
{otherLocales.map(([locale, url]) => (
|
|
20
|
+
<a href={url} class="btn-locale">
|
|
21
|
+
{locale.toUpperCase()}
|
|
22
|
+
</a>
|
|
23
|
+
))}
|
|
24
|
+
</div>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
<button id="theme-toggle" class="btn-theme" aria-label="Toggle theme" title="Toggle theme">
|
|
29
|
+
<span class="theme-icon"></span>
|
|
30
|
+
</button>
|
|
31
|
+
</nav>
|
|
32
|
+
|
|
33
|
+
<script>
|
|
34
|
+
function initToolbar() {
|
|
35
|
+
const btn = document.getElementById("theme-toggle");
|
|
36
|
+
if (!btn) return;
|
|
37
|
+
|
|
38
|
+
const applyTheme = (theme: string) => {
|
|
39
|
+
document.documentElement.classList.remove("theme-light", "theme-dark");
|
|
40
|
+
document.documentElement.classList.add(theme);
|
|
41
|
+
localStorage.setItem("theme", theme);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
btn.addEventListener("click", () => {
|
|
45
|
+
const next = document.documentElement.classList.contains("theme-dark")
|
|
46
|
+
? "theme-light"
|
|
47
|
+
: "theme-dark";
|
|
48
|
+
applyTheme(next);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
initToolbar();
|
|
53
|
+
document.addEventListener("astro:after-swap", initToolbar);
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<style>
|
|
57
|
+
.preview-toolbar {
|
|
58
|
+
position: fixed;
|
|
59
|
+
top: 1rem;
|
|
60
|
+
right: 1.5rem;
|
|
61
|
+
display: flex;
|
|
62
|
+
align-items: center;
|
|
63
|
+
gap: 0.5rem;
|
|
64
|
+
z-index: 1000;
|
|
65
|
+
background: var(--bg-surface);
|
|
66
|
+
padding: 0.4rem;
|
|
67
|
+
border-radius: 1rem;
|
|
68
|
+
border: 1px solid var(--border-color);
|
|
69
|
+
backdrop-filter: blur(12px);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.locale-group {
|
|
73
|
+
display: flex;
|
|
74
|
+
align-items: center;
|
|
75
|
+
gap: 0.25rem;
|
|
76
|
+
padding-right: 0.5rem;
|
|
77
|
+
border-right: 1px solid var(--border-color);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.locale-current {
|
|
81
|
+
font-size: 0.7rem;
|
|
82
|
+
font-weight: 900;
|
|
83
|
+
color: var(--text-muted);
|
|
84
|
+
padding: 0.4rem 0.6rem;
|
|
85
|
+
letter-spacing: 0.08em;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
.btn-locale {
|
|
89
|
+
background: transparent;
|
|
90
|
+
border: 1px solid var(--border-color);
|
|
91
|
+
color: var(--text-main);
|
|
92
|
+
cursor: pointer;
|
|
93
|
+
padding: 0.4rem 0.7rem;
|
|
94
|
+
border-radius: 0.5rem;
|
|
95
|
+
font-weight: 700;
|
|
96
|
+
font-size: 0.7rem;
|
|
97
|
+
text-decoration: none;
|
|
98
|
+
letter-spacing: 0.08em;
|
|
99
|
+
transition: all 0.2s ease;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.btn-locale:hover {
|
|
103
|
+
border-color: var(--accent);
|
|
104
|
+
color: var(--accent);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.btn-theme {
|
|
108
|
+
background: transparent;
|
|
109
|
+
border: none;
|
|
110
|
+
cursor: pointer;
|
|
111
|
+
padding: 0.5rem;
|
|
112
|
+
border-radius: 0.6rem;
|
|
113
|
+
display: flex;
|
|
114
|
+
align-items: center;
|
|
115
|
+
justify-content: center;
|
|
116
|
+
transition: background 0.2s ease;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.btn-theme:hover {
|
|
120
|
+
background: rgba(255, 255, 255, 0.08);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.theme-icon {
|
|
124
|
+
display: block;
|
|
125
|
+
width: 16px;
|
|
126
|
+
height: 16px;
|
|
127
|
+
border-radius: 50%;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
:global(.theme-light) .theme-icon {
|
|
131
|
+
background: #f59e0b;
|
|
132
|
+
box-shadow: 0 0 8px #fbbf24;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
:global(.theme-dark) .theme-icon {
|
|
136
|
+
background: #94a3b8;
|
|
137
|
+
box-shadow: inset -4px -2px 0 #1e293b;
|
|
138
|
+
}
|
|
139
|
+
</style>
|
package/src/entries.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LandingDefinition } from './types';
|
|
2
|
+
import { teamEntry } from './landing/team/entry';
|
|
3
|
+
|
|
4
|
+
export const ALL_LANDING_DEFINITIONS: LandingDefinition[] = [
|
|
5
|
+
{
|
|
6
|
+
entry: teamEntry,
|
|
7
|
+
LandingComponent: () => import('./landing/team/landing.astro'),
|
|
8
|
+
}
|
|
9
|
+
];
|
package/src/env.d.ts
ADDED
package/src/index.ts
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MasterPlanScene from "./MasterPlanScene.astro";
|
|
3
|
+
import scene1 from "../assets/webcomic/scene-1.webp";
|
|
4
|
+
import scene2 from "../assets/webcomic/scene-2.webp";
|
|
5
|
+
import scene3 from "../assets/webcomic/scene-3.webp";
|
|
6
|
+
import scene4 from "../assets/webcomic/scene-4.webp";
|
|
7
|
+
import formulaMoney from "../assets/master-plan-money.webp";
|
|
8
|
+
import formulaFood from "../assets/master-plan-food.webp";
|
|
9
|
+
import formulaMoreMoney from "../assets/master-plan-more-money.webp";
|
|
10
|
+
import formulaMoreFood from "../assets/master-plan-more-food.webp";
|
|
11
|
+
import formulaTools from "../assets/master-plan-tools.webp";
|
|
12
|
+
import formulaProjects from "../assets/master-plan-projects.webp";
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
t: {
|
|
16
|
+
eyebrow: string;
|
|
17
|
+
title: string;
|
|
18
|
+
spainFood: string;
|
|
19
|
+
worldFood: string;
|
|
20
|
+
humanAssignment: string;
|
|
21
|
+
languagesLabel: string;
|
|
22
|
+
text: string;
|
|
23
|
+
quote: string;
|
|
24
|
+
closing: string;
|
|
25
|
+
scenes: {
|
|
26
|
+
label: string;
|
|
27
|
+
title: string;
|
|
28
|
+
text: string;
|
|
29
|
+
assetAlt: string;
|
|
30
|
+
formula: string[];
|
|
31
|
+
}[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const { t } = Astro.props;
|
|
36
|
+
|
|
37
|
+
const scenes = [
|
|
38
|
+
{
|
|
39
|
+
number: "01",
|
|
40
|
+
label: t.scenes[0]!.label,
|
|
41
|
+
title: t.scenes[0]!.title,
|
|
42
|
+
text: t.scenes[0]!.text,
|
|
43
|
+
visual: "money",
|
|
44
|
+
asset: scene1,
|
|
45
|
+
assetAlt: t.scenes[0]!.assetAlt,
|
|
46
|
+
formula: [
|
|
47
|
+
{ label: t.scenes[0]!.formula[0]!, asset: formulaMoney },
|
|
48
|
+
{ label: t.scenes[0]!.formula[1]!, asset: formulaFood },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
number: "02",
|
|
53
|
+
label: t.scenes[1]!.label,
|
|
54
|
+
title: t.scenes[1]!.title,
|
|
55
|
+
text: t.scenes[1]!.text,
|
|
56
|
+
visual: "bowl",
|
|
57
|
+
asset: scene2,
|
|
58
|
+
assetAlt: t.scenes[1]!.assetAlt,
|
|
59
|
+
formula: [
|
|
60
|
+
{ label: t.scenes[1]!.formula[0]!, asset: formulaMoreMoney },
|
|
61
|
+
{ label: t.scenes[1]!.formula[1]!, asset: formulaMoreFood },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
number: "03",
|
|
66
|
+
label: t.scenes[2]!.label,
|
|
67
|
+
title: t.scenes[2]!.title,
|
|
68
|
+
text: t.scenes[2]!.text,
|
|
69
|
+
visual: "map",
|
|
70
|
+
asset: scene3,
|
|
71
|
+
assetAlt: t.scenes[2]!.assetAlt,
|
|
72
|
+
formula: [
|
|
73
|
+
{ label: t.scenes[2]!.formula[0]!, asset: formulaTools },
|
|
74
|
+
{ label: t.scenes[2]!.formula[1]!, asset: formulaMoney },
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
number: "04",
|
|
79
|
+
label: t.scenes[3]!.label,
|
|
80
|
+
title: t.scenes[3]!.title,
|
|
81
|
+
text: t.scenes[3]!.text,
|
|
82
|
+
visual: "orders",
|
|
83
|
+
asset: scene4,
|
|
84
|
+
assetAlt: t.scenes[3]!.assetAlt,
|
|
85
|
+
formula: [
|
|
86
|
+
{ label: t.scenes[3]!.formula[0]!, asset: formulaProjects },
|
|
87
|
+
{ label: t.scenes[3]!.formula[1]!, asset: formulaMoreFood },
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
<section class="team-section master-plan" aria-labelledby="master-plan-title">
|
|
96
|
+
<div class="team-landing-inner">
|
|
97
|
+
<div class="master-plan-header">
|
|
98
|
+
<p class="team-section-eyebrow">{t.eyebrow}</p>
|
|
99
|
+
<h2 class="team-section-title" id="master-plan-title">{t.title}</h2>
|
|
100
|
+
<p class="team-section-text">
|
|
101
|
+
{t.text}
|
|
102
|
+
</p>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<div class="master-plan-strip" aria-label={t.languagesLabel}>
|
|
106
|
+
{
|
|
107
|
+
scenes.map((scene) => (
|
|
108
|
+
<MasterPlanScene scene={scene} />
|
|
109
|
+
))
|
|
110
|
+
}
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<p class="master-plan-punchline">
|
|
114
|
+
<span>{t.quote}</span>
|
|
115
|
+
<strong>{t.closing}</strong>
|
|
116
|
+
</p>
|
|
117
|
+
</div>
|
|
118
|
+
</section>
|