nibula 1.6.0 → 1.6.1

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.
Files changed (99) hide show
  1. package/.eleventy.js +81 -81
  2. package/CHANGELOG.md +384 -377
  3. package/LICENSE +169 -169
  4. package/NOTICE +4 -4
  5. package/README.md +110 -110
  6. package/bin/create.js +505 -505
  7. package/bin/delegate.js +57 -57
  8. package/bin/nibula.js +302 -302
  9. package/docs/Assistant CLI.md +65 -65
  10. package/docs/Backend.md +201 -201
  11. package/docs/Components.md +140 -140
  12. package/docs/Creating pages.md +69 -69
  13. package/docs/Deploy.md +210 -210
  14. package/docs/Head and SEO.md +139 -139
  15. package/docs/Javascript.md +126 -126
  16. package/docs/Styling with SCSS.md +139 -139
  17. package/nginx.conf +113 -113
  18. package/package.json +69 -69
  19. package/src/backend/.htaccess +6 -6
  20. package/src/backend/_core/composer.json +5 -5
  21. package/src/backend/_core/composer.lock +492 -492
  22. package/src/backend/_core/index.js +267 -267
  23. package/src/backend/_core/index.php +160 -160
  24. package/src/backend/_core/init.js +52 -52
  25. package/src/backend/_core/init.php +33 -33
  26. package/src/backend/_core/modules/RateLimiter.js +58 -58
  27. package/src/backend/_core/modules/RateLimiter.php +30 -30
  28. package/src/backend/_core/modules/Response.js +59 -59
  29. package/src/backend/_core/modules/Response.php +48 -48
  30. package/src/backend/api/protected/example-protected.js +23 -23
  31. package/src/backend/api/protected/example-protected.php +16 -16
  32. package/src/backend/api/public/example-public.js +24 -24
  33. package/src/backend/api/public/example-public.php +16 -16
  34. package/src/backend/database/Database.js +46 -46
  35. package/src/backend/database/Database.php +23 -23
  36. package/src/backend/example.config.js +37 -37
  37. package/src/backend/example.config.php +37 -37
  38. package/src/backend/package.json +17 -17
  39. package/src/backend/web.config +43 -43
  40. package/src/frontend/.htaccess +51 -51
  41. package/src/frontend/404.njk +17 -17
  42. package/src/frontend/assets/brand/favicon.svg +54 -54
  43. package/src/frontend/assets/brand/logo.svg +54 -54
  44. package/src/frontend/components/global/footer.njk +25 -25
  45. package/src/frontend/components/global/header.njk +6 -6
  46. package/src/frontend/components/welcome.njk +115 -115
  47. package/src/frontend/index.njk +8 -8
  48. package/src/frontend/js/global.js +10 -10
  49. package/src/frontend/js/modules/exampleModule.js +2 -2
  50. package/src/frontend/js/pages/404.js +8 -8
  51. package/src/frontend/js/pages/homepage.js +8 -8
  52. package/src/frontend/layouts/base.njk +136 -136
  53. package/src/frontend/layouts/page-components.njk +13 -13
  54. package/src/frontend/llms.njk +17 -17
  55. package/src/frontend/robots.njk +7 -7
  56. package/src/frontend/scss/_global.scss +46 -46
  57. package/src/frontend/scss/_root.scss +13 -13
  58. package/src/frontend/scss/modules/_animations.scss +24 -24
  59. package/src/frontend/scss/modules/_footer.scss +28 -28
  60. package/src/frontend/scss/modules/_header.scss +26 -26
  61. package/src/frontend/scss/modules/_mobile.scss +29 -29
  62. package/src/frontend/scss/modules/_typography.scss +18 -18
  63. package/src/frontend/scss/modules/frameworks/_bootstrap.scss +109 -109
  64. package/src/frontend/scss/modules/frameworks/_bulma.scss +108 -108
  65. package/src/frontend/scss/modules/frameworks/_foundation.scss +137 -137
  66. package/src/frontend/scss/modules/frameworks/_uikit.scss +109 -109
  67. package/src/frontend/scss/pages/404.scss +27 -27
  68. package/src/frontend/scss/pages/homepage.scss +22 -22
  69. package/src/frontend/sitemap.njk +17 -17
  70. package/src/frontend/ts/global.ts +11 -11
  71. package/src/frontend/ts/modules/exampleModule.ts +2 -2
  72. package/src/frontend/ts/pages/404.ts +8 -8
  73. package/src/frontend/ts/pages/homepage.ts +8 -8
  74. package/src/frontend/web.config +51 -51
  75. package/tools/assistant.js +122 -122
  76. package/tools/buildJs.js +39 -39
  77. package/tools/cleanOutput.js +23 -23
  78. package/tools/cli/prompt.js +40 -40
  79. package/tools/cli/ui.js +87 -87
  80. package/tools/config/messages.json +80 -80
  81. package/tools/config/settings.json +130 -130
  82. package/tools/lib/colors.js +17 -17
  83. package/tools/lib/files.js +75 -75
  84. package/tools/lib/logger.js +22 -22
  85. package/tools/lib/outputPath.js +141 -141
  86. package/tools/lib/pageActions.js +146 -146
  87. package/tools/lib/pageArtifacts.js +46 -46
  88. package/tools/lib/pageComponents.js +88 -88
  89. package/tools/lib/pagesData.js +87 -87
  90. package/tools/lib/paths.js +63 -63
  91. package/tools/lib/project.js +54 -54
  92. package/tools/lib/text.js +47 -47
  93. package/tools/lib/validation.js +40 -40
  94. package/tools/res/templates/template.js +7 -7
  95. package/tools/res/templates/template.njk +8 -8
  96. package/tools/res/templates/template.scss +22 -22
  97. package/tools/res/templates/template.ts +8 -8
  98. package/tsconfig.json +24 -24
  99. package/src/frontend/scss/pages/prova.scss +0 -23
@@ -1,38 +1,38 @@
1
- <?php
2
- declare(strict_types=1);
3
-
4
- /**
5
- * Mirror of src/backend/example.config.js
6
- *
7
- * Versioned, secret-free template. On setup, copy this file to config.php and
8
- * fill in real values. config.php is git-ignored and stays local.
9
- */
10
-
11
- return [
12
- // Default key for protected endpoints that don't have a specific key in CUSTOM_ENDPOINT_KEYS
13
- 'GENERAL_API_KEY' => 'DEFAULT_KEY',
14
-
15
- // If you want to restrict access to protected endpoints to specific clients, define custom keys per endpoint.
16
- // For subfolder endpoints, use the relative path ('subfolder/endpoint')
17
- 'CUSTOM_ENDPOINT_KEYS' => [
18
- 'subfolder/example-protected' => 'custom-key',
19
- ],
20
-
21
- 'GENERAL_ALLOWED_ORIGINS' => [
22
- '*',
23
- // 'https://example.com',
24
- ],
25
-
26
- 'CUSTOM_ENDPOINT_ORIGINS' => [
27
- 'subfolder/example-protected' => ['https://app.example.com'],
28
- ],
29
-
30
- // Database configuration
31
- 'DB_HOST' => '127.0.0.1',
32
- 'DB_NAME' => 'example_db',
33
- 'DB_USER' => 'root',
34
- 'DB_PASS' => '',
35
-
36
- // Environment: 'production' hides error details; anything else = debug.
37
- 'APP_ENV' => 'production',
1
+ <?php
2
+ declare(strict_types=1);
3
+
4
+ /**
5
+ * Mirror of src/backend/example.config.js
6
+ *
7
+ * Versioned, secret-free template. On setup, copy this file to config.php and
8
+ * fill in real values. config.php is git-ignored and stays local.
9
+ */
10
+
11
+ return [
12
+ // Default key for protected endpoints that don't have a specific key in CUSTOM_ENDPOINT_KEYS
13
+ 'GENERAL_API_KEY' => 'DEFAULT_KEY',
14
+
15
+ // If you want to restrict access to protected endpoints to specific clients, define custom keys per endpoint.
16
+ // For subfolder endpoints, use the relative path ('subfolder/endpoint')
17
+ 'CUSTOM_ENDPOINT_KEYS' => [
18
+ 'subfolder/example-protected' => 'custom-key',
19
+ ],
20
+
21
+ 'GENERAL_ALLOWED_ORIGINS' => [
22
+ '*',
23
+ // 'https://example.com',
24
+ ],
25
+
26
+ 'CUSTOM_ENDPOINT_ORIGINS' => [
27
+ 'subfolder/example-protected' => ['https://app.example.com'],
28
+ ],
29
+
30
+ // Database configuration
31
+ 'DB_HOST' => '127.0.0.1',
32
+ 'DB_NAME' => 'example_db',
33
+ 'DB_USER' => 'root',
34
+ 'DB_PASS' => '',
35
+
36
+ // Environment: 'production' hides error details; anything else = debug.
37
+ 'APP_ENV' => 'production',
38
38
  ];
@@ -1,17 +1,17 @@
1
- {
2
- "name": "backend-node",
3
- "version": "1.0.0",
4
- "private": true,
5
- "description": "Node.js backend for a Nibula site. Coexists with the PHP backend; pick one at scaffold time. Front controller: _core/index.js.",
6
- "main": "_core/index.js",
7
- "type": "commonjs",
8
- "scripts": {
9
- "start": "node _core/index.js"
10
- },
11
- "engines": {
12
- "node": ">=18"
13
- },
14
- "dependencies": {
15
- "mysql2": "^3.11.0"
16
- }
17
- }
1
+ {
2
+ "name": "backend-node",
3
+ "version": "1.0.0",
4
+ "private": true,
5
+ "description": "Node.js backend for a Nibula site. Coexists with the PHP backend; pick one at scaffold time. Front controller: _core/index.js.",
6
+ "main": "_core/index.js",
7
+ "type": "commonjs",
8
+ "scripts": {
9
+ "start": "node _core/index.js"
10
+ },
11
+ "engines": {
12
+ "node": ">=18"
13
+ },
14
+ "dependencies": {
15
+ "mysql2": "^3.11.0"
16
+ }
17
+ }
@@ -1,44 +1,44 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!--
3
- IIS config for the Nibula backend folder.
4
-
5
- The front controller is the only reachable file: every other path is rewritten
6
- onto it and answered as an API request, so endpoint sources, config.php,
7
- migrations and vendor files are never served.
8
-
9
- httpErrors is set to PassThrough here, unlike the site root. Everything under
10
- this folder is the API, and the front controller already answers errors with
11
- its own JSON envelope (401 for a missing X-Api-Key, 404 for an unknown
12
- endpoint, 500 for an unhandled exception). Without PassThrough, IIS replaces
13
- those bodies with its own HTML and every API error reaches the client in the
14
- wrong format.
15
- -->
16
- <configuration>
17
- <system.webServer>
18
- <rewrite>
19
- <rules>
20
-
21
- <rule name="PassThroughCoreIndex" stopProcessing="true">
22
- <match url="^_core/index\.php$" ignoreCase="true" />
23
- <action type="None" />
24
- </rule>
25
-
26
- <rule name="RewriteToFrontController" stopProcessing="true">
27
- <match url="^(.*)$" ignoreCase="true" />
28
- <action type="Rewrite" url="_core/index.php" appendQueryString="true" />
29
- </rule>
30
-
31
- </rules>
32
- </rewrite>
33
-
34
- <directoryBrowse enabled="false" />
35
-
36
- <httpErrors errorMode="Custom" existingResponse="PassThrough" />
37
-
38
- <httpProtocol>
39
- <customHeaders>
40
- <remove name="WWW-Authenticate" />
41
- </customHeaders>
42
- </httpProtocol>
43
- </system.webServer>
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ IIS config for the Nibula backend folder.
4
+
5
+ The front controller is the only reachable file: every other path is rewritten
6
+ onto it and answered as an API request, so endpoint sources, config.php,
7
+ migrations and vendor files are never served.
8
+
9
+ httpErrors is set to PassThrough here, unlike the site root. Everything under
10
+ this folder is the API, and the front controller already answers errors with
11
+ its own JSON envelope (401 for a missing X-Api-Key, 404 for an unknown
12
+ endpoint, 500 for an unhandled exception). Without PassThrough, IIS replaces
13
+ those bodies with its own HTML and every API error reaches the client in the
14
+ wrong format.
15
+ -->
16
+ <configuration>
17
+ <system.webServer>
18
+ <rewrite>
19
+ <rules>
20
+
21
+ <rule name="PassThroughCoreIndex" stopProcessing="true">
22
+ <match url="^_core/index\.php$" ignoreCase="true" />
23
+ <action type="None" />
24
+ </rule>
25
+
26
+ <rule name="RewriteToFrontController" stopProcessing="true">
27
+ <match url="^(.*)$" ignoreCase="true" />
28
+ <action type="Rewrite" url="_core/index.php" appendQueryString="true" />
29
+ </rule>
30
+
31
+ </rules>
32
+ </rewrite>
33
+
34
+ <directoryBrowse enabled="false" />
35
+
36
+ <httpErrors errorMode="Custom" existingResponse="PassThrough" />
37
+
38
+ <httpProtocol>
39
+ <customHeaders>
40
+ <remove name="WWW-Authenticate" />
41
+ </customHeaders>
42
+ </httpProtocol>
43
+ </system.webServer>
44
44
  </configuration>
@@ -1,51 +1,51 @@
1
- Options -Indexes
2
- ErrorDocument 404 /404.html
3
- ErrorDocument 403 /404.html
4
-
5
- <IfModule mod_rewrite.c>
6
- RewriteEngine On
7
- RewriteBase /
8
-
9
- # Block sensitive files (web.config, dotfiles)
10
- RewriteRule ^(web\.config|\..*)$ /404.html [L,NC]
11
- </IfModule>
12
-
13
- # === /api routing — covers BOTH backends ====================================
14
- #
15
- # Apache (unlike nginx) cannot health-check an upstream, so it cannot auto-fall
16
- # back from Node to PHP. The behaviour is:
17
- #
18
- # - mod_proxy available -> /api is proxied to the Node backend (127.0.0.1:3000)
19
- # - mod_proxy NOT present -> /api is rewritten to the PHP front controller
20
- #
21
- # Typical shared hosting (Aruba, cPanel) has no mod_proxy, so it uses PHP
22
- # automatically. On a VPS running Node, mod_proxy sends /api to Node.
23
- #
24
- # If you are on a server that HAS mod_proxy but you want to use PHP, comment out
25
- # the mod_proxy block below.
26
-
27
- # --- Node backend (if mod_proxy is available) ---
28
- <IfModule mod_proxy.c>
29
- ProxyPreserveHost On
30
- ProxyPass /api/ http://127.0.0.1:3000/api/ retry=0
31
- ProxyPassReverse /api/ http://127.0.0.1:3000/api/
32
-
33
- <IfModule mod_headers.c>
34
- RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
35
- RequestHeader set X-Forwarded-Proto "https"
36
- </IfModule>
37
- </IfModule>
38
-
39
- # --- PHP backend (fallback when mod_proxy is absent) ---
40
- <IfModule mod_rewrite.c>
41
- RewriteEngine On
42
- RewriteBase /
43
- RewriteRule ^api/(.*)$ backend/_core/index.php [QSA,L]
44
- </IfModule>
45
-
46
- # === Static files ===========================================================
47
- <IfModule mod_rewrite.c>
48
- RewriteCond %{REQUEST_FILENAME} -f [OR]
49
- RewriteCond %{REQUEST_FILENAME} -d
50
- RewriteRule ^ - [L]
51
- </IfModule>
1
+ Options -Indexes
2
+ ErrorDocument 404 /404.html
3
+ ErrorDocument 403 /404.html
4
+
5
+ <IfModule mod_rewrite.c>
6
+ RewriteEngine On
7
+ RewriteBase /
8
+
9
+ # Block sensitive files (web.config, dotfiles)
10
+ RewriteRule ^(web\.config|\..*)$ /404.html [L,NC]
11
+ </IfModule>
12
+
13
+ # === /api routing — covers BOTH backends ====================================
14
+ #
15
+ # Apache (unlike nginx) cannot health-check an upstream, so it cannot auto-fall
16
+ # back from Node to PHP. The behaviour is:
17
+ #
18
+ # - mod_proxy available -> /api is proxied to the Node backend (127.0.0.1:3000)
19
+ # - mod_proxy NOT present -> /api is rewritten to the PHP front controller
20
+ #
21
+ # Typical shared hosting (Aruba, cPanel) has no mod_proxy, so it uses PHP
22
+ # automatically. On a VPS running Node, mod_proxy sends /api to Node.
23
+ #
24
+ # If you are on a server that HAS mod_proxy but you want to use PHP, comment out
25
+ # the mod_proxy block below.
26
+
27
+ # --- Node backend (if mod_proxy is available) ---
28
+ <IfModule mod_proxy.c>
29
+ ProxyPreserveHost On
30
+ ProxyPass /api/ http://127.0.0.1:3000/api/ retry=0
31
+ ProxyPassReverse /api/ http://127.0.0.1:3000/api/
32
+
33
+ <IfModule mod_headers.c>
34
+ RequestHeader set X-Forwarded-For "%{REMOTE_ADDR}s"
35
+ RequestHeader set X-Forwarded-Proto "https"
36
+ </IfModule>
37
+ </IfModule>
38
+
39
+ # --- PHP backend (fallback when mod_proxy is absent) ---
40
+ <IfModule mod_rewrite.c>
41
+ RewriteEngine On
42
+ RewriteBase /
43
+ RewriteRule ^api/(.*)$ backend/_core/index.php [QSA,L]
44
+ </IfModule>
45
+
46
+ # === Static files ===========================================================
47
+ <IfModule mod_rewrite.c>
48
+ RewriteCond %{REQUEST_FILENAME} -f [OR]
49
+ RewriteCond %{REQUEST_FILENAME} -d
50
+ RewriteRule ^ - [L]
51
+ </IfModule>
@@ -1,17 +1,17 @@
1
- ---
2
- title: "404"
3
- permalink: 404.html
4
- layout: base.njk
5
- ---
6
-
7
- <!-- !IMPORTANT -->
8
- <!-- This is the only page that you need to modify statically -->
9
-
10
- <div class="fade-in not-found">
11
- <h1>Oops! Page not found</h1>
12
- <a href="/">Return to homepage</a>
13
- </div>
14
-
15
-
16
- {# You can also add the includes you need here below
17
- {% include "component.njk" %} #}
1
+ ---
2
+ title: "404"
3
+ permalink: 404.html
4
+ layout: base.njk
5
+ ---
6
+
7
+ <!-- !IMPORTANT -->
8
+ <!-- This is the only page that you need to modify statically -->
9
+
10
+ <div class="fade-in not-found">
11
+ <h1>Oops! Page not found</h1>
12
+ <a href="/">Return to homepage</a>
13
+ </div>
14
+
15
+
16
+ {# You can also add the includes you need here below
17
+ {% include "component.njk" %} #}
@@ -1,54 +1,54 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
2
- <defs>
3
- <linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
4
- <stop offset="0" stop-color="#8b6fc4"/>
5
- <stop offset="0.5" stop-color="#c9a06a"/>
6
- <stop offset="1" stop-color="#f2c17a"/>
7
- </linearGradient>
8
- <linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
9
- <stop offset="0" stop-color="#6d4fa8"/>
10
- <stop offset="0.45" stop-color="#a978b0"/>
11
- <stop offset="0.75" stop-color="#e7a55f"/>
12
- <stop offset="1" stop-color="#f7d08a"/>
13
- </linearGradient>
14
- <linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
15
- <stop offset="0" stop-color="#f7d89a"/>
16
- <stop offset="0.55" stop-color="#e0a95f"/>
17
- <stop offset="1" stop-color="#b07d3e"/>
18
- </linearGradient>
19
- <linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
20
- <stop offset="0" stop-color="#3a2c63"/>
21
- <stop offset="1" stop-color="#2a2150"/>
22
- </linearGradient>
23
- </defs>
24
-
25
- <path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
26
- d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
27
- <path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
28
- d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
29
-
30
- <!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
31
- up right post, cut corner, down outer-right, close along the bottom -->
32
- <path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
33
- d="M148 362
34
- L148 150
35
- L206 150
36
- L312 300
37
- L312 150
38
- L370 150
39
- L370 205
40
- L340 205
41
- L340 362
42
- L282 362
43
- L206 255
44
- L206 362
45
- Z"/>
46
-
47
- <g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
48
- <path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
49
- <path fill="none" stroke-width="5" d="M338 313 L386 313"/>
50
- <path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
51
- <path fill="none" stroke-width="5" d="M366 342 L402 384"/>
52
- <circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
53
- </g>
54
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
2
+ <defs>
3
+ <linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#8b6fc4"/>
5
+ <stop offset="0.5" stop-color="#c9a06a"/>
6
+ <stop offset="1" stop-color="#f2c17a"/>
7
+ </linearGradient>
8
+ <linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
9
+ <stop offset="0" stop-color="#6d4fa8"/>
10
+ <stop offset="0.45" stop-color="#a978b0"/>
11
+ <stop offset="0.75" stop-color="#e7a55f"/>
12
+ <stop offset="1" stop-color="#f7d08a"/>
13
+ </linearGradient>
14
+ <linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
15
+ <stop offset="0" stop-color="#f7d89a"/>
16
+ <stop offset="0.55" stop-color="#e0a95f"/>
17
+ <stop offset="1" stop-color="#b07d3e"/>
18
+ </linearGradient>
19
+ <linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
20
+ <stop offset="0" stop-color="#3a2c63"/>
21
+ <stop offset="1" stop-color="#2a2150"/>
22
+ </linearGradient>
23
+ </defs>
24
+
25
+ <path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
26
+ d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
27
+ <path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
28
+ d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
29
+
30
+ <!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
31
+ up right post, cut corner, down outer-right, close along the bottom -->
32
+ <path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
33
+ d="M148 362
34
+ L148 150
35
+ L206 150
36
+ L312 300
37
+ L312 150
38
+ L370 150
39
+ L370 205
40
+ L340 205
41
+ L340 362
42
+ L282 362
43
+ L206 255
44
+ L206 362
45
+ Z"/>
46
+
47
+ <g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
48
+ <path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
49
+ <path fill="none" stroke-width="5" d="M338 313 L386 313"/>
50
+ <path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
51
+ <path fill="none" stroke-width="5" d="M366 342 L402 384"/>
52
+ <circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
53
+ </g>
54
+ </svg>
@@ -1,54 +1,54 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
2
- <defs>
3
- <linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
4
- <stop offset="0" stop-color="#8b6fc4"/>
5
- <stop offset="0.5" stop-color="#c9a06a"/>
6
- <stop offset="1" stop-color="#f2c17a"/>
7
- </linearGradient>
8
- <linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
9
- <stop offset="0" stop-color="#6d4fa8"/>
10
- <stop offset="0.45" stop-color="#a978b0"/>
11
- <stop offset="0.75" stop-color="#e7a55f"/>
12
- <stop offset="1" stop-color="#f7d08a"/>
13
- </linearGradient>
14
- <linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
15
- <stop offset="0" stop-color="#f7d89a"/>
16
- <stop offset="0.55" stop-color="#e0a95f"/>
17
- <stop offset="1" stop-color="#b07d3e"/>
18
- </linearGradient>
19
- <linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
20
- <stop offset="0" stop-color="#3a2c63"/>
21
- <stop offset="1" stop-color="#2a2150"/>
22
- </linearGradient>
23
- </defs>
24
-
25
- <path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
26
- d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
27
- <path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
28
- d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
29
-
30
- <!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
31
- up right post, cut corner, down outer-right, close along the bottom -->
32
- <path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
33
- d="M148 362
34
- L148 150
35
- L206 150
36
- L312 300
37
- L312 150
38
- L370 150
39
- L370 205
40
- L340 205
41
- L340 362
42
- L282 362
43
- L206 255
44
- L206 362
45
- Z"/>
46
-
47
- <g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
48
- <path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
49
- <path fill="none" stroke-width="5" d="M338 313 L386 313"/>
50
- <path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
51
- <path fill="none" stroke-width="5" d="M366 342 L402 384"/>
52
- <circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
53
- </g>
54
- </svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" role="img" aria-label="Nibula">
2
+ <defs>
3
+ <linearGradient id="nibulaShieldBorder" x1="0" y1="0" x2="1" y2="1">
4
+ <stop offset="0" stop-color="#8b6fc4"/>
5
+ <stop offset="0.5" stop-color="#c9a06a"/>
6
+ <stop offset="1" stop-color="#f2c17a"/>
7
+ </linearGradient>
8
+ <linearGradient id="nibulaN" x1="0" y1="1" x2="1" y2="0">
9
+ <stop offset="0" stop-color="#6d4fa8"/>
10
+ <stop offset="0.45" stop-color="#a978b0"/>
11
+ <stop offset="0.75" stop-color="#e7a55f"/>
12
+ <stop offset="1" stop-color="#f7d08a"/>
13
+ </linearGradient>
14
+ <linearGradient id="nibulaNib" x1="0" y1="0" x2="1" y2="1">
15
+ <stop offset="0" stop-color="#f7d89a"/>
16
+ <stop offset="0.55" stop-color="#e0a95f"/>
17
+ <stop offset="1" stop-color="#b07d3e"/>
18
+ </linearGradient>
19
+ <linearGradient id="nibulaField" x1="0" y1="0" x2="0.6" y2="1">
20
+ <stop offset="0" stop-color="#3a2c63"/>
21
+ <stop offset="1" stop-color="#2a2150"/>
22
+ </linearGradient>
23
+ </defs>
24
+
25
+ <path fill="none" stroke="url(#nibulaShieldBorder)" stroke-width="10" stroke-linejoin="round"
26
+ d="M256 40 L440 132 L440 320 L256 472 L72 320 L72 132 Z"/>
27
+ <path fill="url(#nibulaField)" stroke="url(#nibulaShieldBorder)" stroke-width="6" stroke-linejoin="round"
28
+ d="M256 66 L418 147 L418 310 L256 442 L94 310 L94 147 Z"/>
29
+
30
+ <!-- N as one closed outline: up left post, down inner-left, diagonal to inner-bottom-right,
31
+ up right post, cut corner, down outer-right, close along the bottom -->
32
+ <path fill="url(#nibulaN)" stroke="#1a1533" stroke-width="7" stroke-linejoin="round"
33
+ d="M148 362
34
+ L148 150
35
+ L206 150
36
+ L312 300
37
+ L312 150
38
+ L370 150
39
+ L370 205
40
+ L340 205
41
+ L340 362
42
+ L282 362
43
+ L206 255
44
+ L206 362
45
+ Z"/>
46
+
47
+ <g stroke="#1a1533" stroke-width="7" stroke-linejoin="round" stroke-linecap="round">
48
+ <path fill="url(#nibulaNib)" d="M326 300 L382 300 L392 326 L336 326 Z"/>
49
+ <path fill="none" stroke-width="5" d="M338 313 L386 313"/>
50
+ <path fill="url(#nibulaNib)" d="M336 326 L392 326 L428 414 L370 380 Z"/>
51
+ <path fill="none" stroke-width="5" d="M366 342 L402 384"/>
52
+ <circle cx="376" cy="360" r="6.5" fill="#1a1533" stroke="none"/>
53
+ </g>
54
+ </svg>
@@ -1,25 +1,25 @@
1
- <footer>
2
- <div>
3
- <h6>{{ site.title }}</h6>
4
- <p>{{ site.description }}</p>
5
- </div>
6
- <div>
7
- <h6>Legal</h6>
8
- <small>
9
- <ul>
10
- <li><a href="{{ site.legal.privacy }}">Privacy Policy</a></li>
11
- <li><a href="{{ site.legal.cookie }}">Cookie Policy</a></li>
12
- <li><a href="{{ site.legal.terms }}">Terms and conditions</a></li>
13
- </ul>
14
- </small>
15
- </div>
16
- <div>
17
- <h6>
18
- &copy; {{ site.legal.copyright.year }}
19
- {{ site.site_name }}
20
- </h6>
21
- <h6>
22
- {{ site.legal.copyright.text }}
23
- </h6>
24
- </div>
25
- </footer>
1
+ <footer>
2
+ <div>
3
+ <h6>{{ site.title }}</h6>
4
+ <p>{{ site.description }}</p>
5
+ </div>
6
+ <div>
7
+ <h6>Legal</h6>
8
+ <small>
9
+ <ul>
10
+ <li><a href="{{ site.legal.privacy }}">Privacy Policy</a></li>
11
+ <li><a href="{{ site.legal.cookie }}">Cookie Policy</a></li>
12
+ <li><a href="{{ site.legal.terms }}">Terms and conditions</a></li>
13
+ </ul>
14
+ </small>
15
+ </div>
16
+ <div>
17
+ <h6>
18
+ &copy; {{ site.legal.copyright.year }}
19
+ {{ site.site_name }}
20
+ </h6>
21
+ <h6>
22
+ {{ site.legal.copyright.text }}
23
+ </h6>
24
+ </div>
25
+ </footer>
@@ -1,7 +1,7 @@
1
- <header>
2
- <nav>
3
- <a class="logo" href="/">
4
- <img src="../../assets/brand/logo.svg" alt="{{ site.title }}" height="40">
5
- </a>
6
- </nav>
1
+ <header>
2
+ <nav>
3
+ <a class="logo" href="/">
4
+ <img src="../../assets/brand/logo.svg" alt="{{ site.title }}" height="40">
5
+ </a>
6
+ </nav>
7
7
  </header>