@notionhive/footers 0.1.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.
Files changed (197) hide show
  1. package/bin/footers.js +16 -0
  2. package/category.config.json +7 -0
  3. package/package.json +24 -0
  4. package/registry/footer-01.json +6 -0
  5. package/registry/footer-02.json +9 -0
  6. package/registry/footer-03.json +9 -0
  7. package/registry/footer-04.json +9 -0
  8. package/registry/footer-05.json +9 -0
  9. package/registry/footer-06.json +7 -0
  10. package/registry/footer-07.json +9 -0
  11. package/registry/footer-08.json +9 -0
  12. package/registry/footer-09.json +9 -0
  13. package/registry/footer-10.json +9 -0
  14. package/registry/footer-11.json +7 -0
  15. package/registry/footer-12.json +9 -0
  16. package/registry/footer-13.json +9 -0
  17. package/registry/footer-14.json +9 -0
  18. package/registry/footer-15.json +9 -0
  19. package/registry/footer-16.json +9 -0
  20. package/registry/footer-17.json +9 -0
  21. package/registry/footer-18.json +9 -0
  22. package/registry/footer-19.json +9 -0
  23. package/registry/footer-20.json +9 -0
  24. package/registry/footer-21.json +9 -0
  25. package/registry/footer-22.json +9 -0
  26. package/registry/footer-23.json +9 -0
  27. package/registry/footer-24.json +9 -0
  28. package/registry/footer-25.json +9 -0
  29. package/registry/footer-26.json +9 -0
  30. package/registry/footer-27.json +9 -0
  31. package/registry/footer-28.json +9 -0
  32. package/registry/footer-29.json +6 -0
  33. package/registry/footer-30.json +6 -0
  34. package/registry/index.json +263 -0
  35. package/templates/components/atoms/SafeImage/SafeImage.jsx +101 -0
  36. package/templates/components/atoms/SafeImage/index.js +1 -0
  37. package/templates/components/organisms/Footer01/Footer01.jsx +142 -0
  38. package/templates/components/organisms/Footer01/Footer01.propTypes.js +110 -0
  39. package/templates/components/organisms/Footer01/index.js +1 -0
  40. package/templates/components/organisms/Footer02/Footer02.jsx +136 -0
  41. package/templates/components/organisms/Footer02/Footer02.propTypes.js +112 -0
  42. package/templates/components/organisms/Footer02/index.js +1 -0
  43. package/templates/components/organisms/Footer03/Footer03.jsx +162 -0
  44. package/templates/components/organisms/Footer03/Footer03.propTypes.js +73 -0
  45. package/templates/components/organisms/Footer03/index.js +1 -0
  46. package/templates/components/organisms/Footer04/Footer04.jsx +128 -0
  47. package/templates/components/organisms/Footer04/Footer04.propTypes.js +93 -0
  48. package/templates/components/organisms/Footer04/index.js +1 -0
  49. package/templates/components/organisms/Footer05/Footer05.jsx +101 -0
  50. package/templates/components/organisms/Footer05/Footer05.propTypes.js +42 -0
  51. package/templates/components/organisms/Footer05/index.js +1 -0
  52. package/templates/components/organisms/Footer06/Footer06.jsx +170 -0
  53. package/templates/components/organisms/Footer06/Footer06.propTypes.js +53 -0
  54. package/templates/components/organisms/Footer06/index.js +1 -0
  55. package/templates/components/organisms/Footer07/Footer07.jsx +253 -0
  56. package/templates/components/organisms/Footer07/Footer07.propTypes.js +83 -0
  57. package/templates/components/organisms/Footer07/index.js +1 -0
  58. package/templates/components/organisms/Footer08/Footer08.jsx +183 -0
  59. package/templates/components/organisms/Footer08/Footer08.propTypes.js +92 -0
  60. package/templates/components/organisms/Footer08/index.js +1 -0
  61. package/templates/components/organisms/Footer09/Footer09.jsx +199 -0
  62. package/templates/components/organisms/Footer09/Footer09.propTypes.js +76 -0
  63. package/templates/components/organisms/Footer09/index.js +1 -0
  64. package/templates/components/organisms/Footer10/Footer10.jsx +172 -0
  65. package/templates/components/organisms/Footer10/Footer10.propTypes.js +38 -0
  66. package/templates/components/organisms/Footer10/index.js +1 -0
  67. package/templates/components/organisms/Footer11/Footer11.jsx +107 -0
  68. package/templates/components/organisms/Footer11/Footer11.propTypes.js +64 -0
  69. package/templates/components/organisms/Footer11/index.js +1 -0
  70. package/templates/components/organisms/Footer12/Footer12.jsx +122 -0
  71. package/templates/components/organisms/Footer12/Footer12.propTypes.js +94 -0
  72. package/templates/components/organisms/Footer12/index.js +1 -0
  73. package/templates/components/organisms/Footer13/Footer13.jsx +156 -0
  74. package/templates/components/organisms/Footer13/Footer13.propTypes.js +80 -0
  75. package/templates/components/organisms/Footer13/index.js +1 -0
  76. package/templates/components/organisms/Footer14/Footer14.jsx +157 -0
  77. package/templates/components/organisms/Footer14/Footer14.propTypes.js +60 -0
  78. package/templates/components/organisms/Footer14/index.js +1 -0
  79. package/templates/components/organisms/Footer15/Footer15.jsx +184 -0
  80. package/templates/components/organisms/Footer15/Footer15.propTypes.js +58 -0
  81. package/templates/components/organisms/Footer15/index.js +1 -0
  82. package/templates/components/organisms/Footer16/Footer16.jsx +87 -0
  83. package/templates/components/organisms/Footer16/Footer16.propTypes.js +73 -0
  84. package/templates/components/organisms/Footer16/index.js +1 -0
  85. package/templates/components/organisms/Footer17/Footer17.jsx +176 -0
  86. package/templates/components/organisms/Footer17/Footer17.propTypes.js +117 -0
  87. package/templates/components/organisms/Footer17/index.js +1 -0
  88. package/templates/components/organisms/Footer18/Footer18.jsx +236 -0
  89. package/templates/components/organisms/Footer18/Footer18.propTypes.js +92 -0
  90. package/templates/components/organisms/Footer18/index.js +1 -0
  91. package/templates/components/organisms/Footer19/Footer19.jsx +287 -0
  92. package/templates/components/organisms/Footer19/Footer19.propTypes.js +116 -0
  93. package/templates/components/organisms/Footer19/index.js +1 -0
  94. package/templates/components/organisms/Footer20/Footer20.jsx +201 -0
  95. package/templates/components/organisms/Footer20/Footer20.propTypes.js +70 -0
  96. package/templates/components/organisms/Footer20/index.js +1 -0
  97. package/templates/components/organisms/Footer21/Footer21.jsx +134 -0
  98. package/templates/components/organisms/Footer21/Footer21.propTypes.js +122 -0
  99. package/templates/components/organisms/Footer21/index.js +1 -0
  100. package/templates/components/organisms/Footer22/Footer22.jsx +136 -0
  101. package/templates/components/organisms/Footer22/Footer22.propTypes.js +58 -0
  102. package/templates/components/organisms/Footer22/index.js +1 -0
  103. package/templates/components/organisms/Footer23/Footer23.jsx +177 -0
  104. package/templates/components/organisms/Footer23/Footer23.propTypes.js +97 -0
  105. package/templates/components/organisms/Footer23/index.js +1 -0
  106. package/templates/components/organisms/Footer24/Footer24.jsx +192 -0
  107. package/templates/components/organisms/Footer24/Footer24.propTypes.js +132 -0
  108. package/templates/components/organisms/Footer24/index.js +1 -0
  109. package/templates/components/organisms/Footer25/Footer25.jsx +135 -0
  110. package/templates/components/organisms/Footer25/Footer25.propTypes.js +124 -0
  111. package/templates/components/organisms/Footer25/index.js +1 -0
  112. package/templates/components/organisms/Footer26/Footer26.jsx +167 -0
  113. package/templates/components/organisms/Footer26/Footer26.propTypes.js +54 -0
  114. package/templates/components/organisms/Footer26/index.js +1 -0
  115. package/templates/components/organisms/Footer27/Footer27.jsx +171 -0
  116. package/templates/components/organisms/Footer27/Footer27.propTypes.js +105 -0
  117. package/templates/components/organisms/Footer27/index.js +1 -0
  118. package/templates/components/organisms/Footer28/Footer28.jsx +98 -0
  119. package/templates/components/organisms/Footer28/Footer28.propTypes.js +96 -0
  120. package/templates/components/organisms/Footer28/index.js +1 -0
  121. package/templates/components/organisms/Footer29/Footer29.jsx +118 -0
  122. package/templates/components/organisms/Footer29/Footer29.propTypes.js +68 -0
  123. package/templates/components/organisms/Footer29/index.js +1 -0
  124. package/templates/components/organisms/Footer30/Footer30.jsx +92 -0
  125. package/templates/components/organisms/Footer30/Footer30.propTypes.js +51 -0
  126. package/templates/components/organisms/Footer30/index.js +1 -0
  127. package/templates/public/footer/footer02/payment-01.png +0 -0
  128. package/templates/public/footer/footer02/payment-02.png +0 -0
  129. package/templates/public/footer/footer02/payment-03.png +0 -0
  130. package/templates/public/footer/footer02/payment-04.png +0 -0
  131. package/templates/public/footer/footer02/payment-05.png +0 -0
  132. package/templates/public/footer/footer02/payment-06.png +0 -0
  133. package/templates/public/footer/footer02/payment-07.png +0 -0
  134. package/templates/public/footer/footer02/payment-08.png +0 -0
  135. package/templates/public/footer/footer02/payment-09.svg +5 -0
  136. package/templates/public/footer/footer02/payment-10.svg +11 -0
  137. package/templates/public/footer/footer02/payment-11.svg +22 -0
  138. package/templates/public/footer/footer02/payment-12.svg +25 -0
  139. package/templates/public/footer/footer02/payment-13.svg +10 -0
  140. package/templates/public/footer/footer02/payment-14.svg +36 -0
  141. package/templates/public/footer/footer02/payment-15.svg +18 -0
  142. package/templates/public/footer/footer02/payment-sprite-01.png +0 -0
  143. package/templates/public/footer/footer02/payment-sprite-02.png +0 -0
  144. package/templates/public/footer/footer02/payment-sprite-03.png +0 -0
  145. package/templates/public/footer/footer02/payment-sprite-04.png +0 -0
  146. package/templates/public/footer/footer02/payment-sprite-05.png +0 -0
  147. package/templates/public/footer/footer02/payment-sprite-06.png +0 -0
  148. package/templates/public/footer/footer03/logo-mask.png +0 -0
  149. package/templates/public/footer/footer03/logo.png +0 -0
  150. package/templates/public/footer/footer04/logo.svg +45 -0
  151. package/templates/public/footer/footer05/brand-watermark.png +0 -0
  152. package/templates/public/footer/footer07/logo.png +0 -0
  153. package/templates/public/footer/footer07/watch-hero.png +0 -0
  154. package/templates/public/footer/footer07/watch-overlay.png +0 -0
  155. package/templates/public/footer/footer08/logo.png +0 -0
  156. package/templates/public/footer/footer08/logo.svg +3 -0
  157. package/templates/public/footer/footer09/logo.svg +13 -0
  158. package/templates/public/footer/footer10/hero-image.png +0 -0
  159. package/templates/public/footer/footer10/hero-mask-download.svg +3 -0
  160. package/templates/public/footer/footer10/hero-mask.svg +3 -0
  161. package/templates/public/footer/footer12/logo-icon.svg +3 -0
  162. package/templates/public/footer/footer12/refugee-logo.png +0 -0
  163. package/templates/public/footer/footer13/logo.png +0 -0
  164. package/templates/public/footer/footer14/logo.png +0 -0
  165. package/templates/public/footer/footer15/logo.svg +19 -0
  166. package/templates/public/footer/footer16/logo.svg +6 -0
  167. package/templates/public/footer/footer17/logo-left.svg +11 -0
  168. package/templates/public/footer/footer17/logo-right.svg +36 -0
  169. package/templates/public/footer/footer18/logo.png +108 -0
  170. package/templates/public/footer/footer18/logo.svg +108 -0
  171. package/templates/public/footer/footer19/logo.png +0 -0
  172. package/templates/public/footer/footer19/payment-bkash.png +0 -0
  173. package/templates/public/footer/footer19/payment-mastercard.svg +12 -0
  174. package/templates/public/footer/footer19/payment-nagad.png +0 -0
  175. package/templates/public/footer/footer19/payment-nexus.png +0 -0
  176. package/templates/public/footer/footer19/payment-rocket.png +0 -0
  177. package/templates/public/footer/footer19/payment-upay.png +0 -0
  178. package/templates/public/footer/footer19/payment-visa.svg +6 -0
  179. package/templates/public/footer/footer20/bg.png +0 -0
  180. package/templates/public/footer/footer20/logo.png +0 -0
  181. package/templates/public/footer/footer21/logo.png +0 -0
  182. package/templates/public/footer/footer22/logo-icon.svg +10 -0
  183. package/templates/public/footer/footer22/logo-name.svg +5 -0
  184. package/templates/public/footer/footer22/logo-tagline.svg +5 -0
  185. package/templates/public/footer/footer23/logo-icon.svg +10 -0
  186. package/templates/public/footer/footer23/logo-name.svg +20 -0
  187. package/templates/public/footer/footer23/logo-tagline.svg +17 -0
  188. package/templates/public/footer/footer24/logo.svg +46 -0
  189. package/templates/public/footer/footer24/map.png +0 -0
  190. package/templates/public/footer/footer25/logo-icon.svg +15 -0
  191. package/templates/public/footer/footer25/logo-text.svg +42 -0
  192. package/templates/public/footer/footer25/map-pin.svg +7 -0
  193. package/templates/public/footer/footer25/map.png +0 -0
  194. package/templates/public/footer/footer26/logo-jpl.svg +5 -0
  195. package/templates/public/footer/footer26/logo.png +0 -0
  196. package/templates/public/footer/footer27/logo.png +0 -0
  197. package/templates/public/footer/footer28/logo.png +0 -0
@@ -0,0 +1,172 @@
1
+ "use client";
2
+
3
+ import { useState } from "react";
4
+ import { SafeImage } from "../../atoms/SafeImage";
5
+ import {
6
+ footer10DefaultProps,
7
+ footer10PropTypes,
8
+ } from "./Footer10.propTypes";
9
+
10
+ function ArrowUpRightIcon({ className = "", dark = false }) {
11
+ return (
12
+ <svg viewBox="0 0 20 20" fill="none" aria-hidden="true" className={className}>
13
+ <path
14
+ d="M5 15L15 5M15 5H7M15 5V13"
15
+ stroke={dark ? "#1f1f1f" : "currentColor"}
16
+ strokeWidth="1.5"
17
+ strokeLinecap="round"
18
+ strokeLinejoin="round"
19
+ />
20
+ </svg>
21
+ );
22
+ }
23
+
24
+ /**
25
+ * Footer10 — Verona dark contact footer with masked brand wordmark.
26
+ * Figma node 32:20616 at 1920px.
27
+ */
28
+ export function Footer10({
29
+ email = footer10DefaultProps.email,
30
+ addressLines = footer10DefaultProps.addressLines,
31
+ phone = footer10DefaultProps.phone,
32
+ socialLinks = footer10DefaultProps.socialLinks,
33
+ formData: controlledForm,
34
+ onFieldChange,
35
+ onSubmit,
36
+ submitLabel = footer10DefaultProps.submitLabel,
37
+ brandName = footer10DefaultProps.brandName,
38
+ className = "",
39
+ }) {
40
+ const [internalForm, setInternalForm] = useState({
41
+ name: "",
42
+ email: "",
43
+ message: "",
44
+ });
45
+ const form = controlledForm ?? internalForm;
46
+
47
+ const setField = (field, value) => {
48
+ onFieldChange?.(field, value);
49
+ if (!controlledForm) {
50
+ setInternalForm((prev) => ({ ...prev, [field]: value }));
51
+ }
52
+ };
53
+
54
+ const handleSubmit = (event) => {
55
+ event.preventDefault();
56
+ onSubmit?.(form);
57
+ };
58
+
59
+ return (
60
+ <footer
61
+ className={["relative w-full overflow-hidden bg-[#1f1f1f]", className]
62
+ .filter(Boolean)
63
+ .join(" ")}
64
+ data-footer="footer10"
65
+ >
66
+ <div className="pointer-events-none absolute inset-y-0 left-10 hidden w-px bg-white/10 xl:block" aria-hidden="true" />
67
+ <div className="pointer-events-none absolute inset-y-0 left-[615px] hidden w-px bg-white/10 xl:block" aria-hidden="true" />
68
+ <div className="pointer-events-none absolute inset-y-0 right-10 hidden w-px bg-white/10 xl:block" aria-hidden="true" />
69
+
70
+ <div className="relative mx-auto w-full max-w-[1920px] px-4 py-12 sm:px-6 md:px-10 lg:px-[60px] lg:py-16 xl:min-h-[1080px] xl:pb-0 xl:pt-40">
71
+ <div className="grid grid-cols-1 gap-12 lg:grid-cols-[minmax(0,1fr)_minmax(0,913px)] lg:gap-x-16 xl:gap-x-[32px]">
72
+ <div className="flex flex-col gap-10 xl:max-w-[535px]">
73
+ <a
74
+ href={`mailto:${email}`}
75
+ className="font-serif text-4xl font-light leading-none tracking-[-0.03em] text-white transition-opacity duration-200 ease-out hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2 sm:text-5xl xl:text-[72px] xl:tracking-[-2.16px]"
76
+ >
77
+ {email}
78
+ </a>
79
+
80
+ <div className="flex flex-col gap-6 text-base leading-[1.4] text-white">
81
+ <div className="opacity-80">
82
+ {addressLines.map((line) => (
83
+ <p key={line}>{line}</p>
84
+ ))}
85
+ </div>
86
+ <a
87
+ href={`tel:${phone.replace(/[^\d+]/g, "")}`}
88
+ className="opacity-80 transition-colors duration-200 ease-out hover:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2"
89
+ >
90
+ {phone}
91
+ </a>
92
+ </div>
93
+
94
+ <div className="flex flex-wrap gap-0">
95
+ {socialLinks.map((social) => (
96
+ <a
97
+ key={social.label}
98
+ href={social.href ?? "#"}
99
+ className="inline-flex h-11 items-center gap-2.5 rounded-full bg-white/[0.04] px-6 py-3.5 text-sm leading-none text-white transition-colors duration-200 ease-out hover:bg-white/[0.08] focus-visible:outline-2 focus-visible:outline-offset-2"
100
+ >
101
+ {social.label}
102
+ <ArrowUpRightIcon className="size-3" />
103
+ </a>
104
+ ))}
105
+ </div>
106
+ </div>
107
+
108
+ <form onSubmit={handleSubmit} className="flex flex-col gap-10 xl:pt-[35px]">
109
+ <div className="flex flex-col gap-[60px]">
110
+ {[
111
+ { field: "name", label: "Name" },
112
+ { field: "email", label: "Email", type: "email" },
113
+ { field: "message", label: "Message" },
114
+ ].map(({ field, label, type = "text" }) => (
115
+ <label key={field} className="flex flex-col border-b border-white/10 pb-[30px]">
116
+ <span className="text-xl leading-[1.4] text-white/60">{label}</span>
117
+ <input
118
+ type={type}
119
+ value={form[field]}
120
+ onChange={(e) => setField(field, e.target.value)}
121
+ className="mt-2 bg-transparent text-base text-white outline-none placeholder:text-white/40"
122
+ />
123
+ </label>
124
+ ))}
125
+ </div>
126
+
127
+ <button
128
+ type="submit"
129
+ className="inline-flex h-14 w-max items-center gap-2.5 rounded-full bg-white px-8 py-4 text-xl font-medium leading-none text-[#1f1f1f] transition-opacity duration-200 ease-out hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2"
130
+ >
131
+ {submitLabel}
132
+ <ArrowUpRightIcon className="size-5" dark />
133
+ </button>
134
+ </form>
135
+ </div>
136
+
137
+ <div className="relative mt-16 overflow-hidden sm:mt-24 xl:mt-[55px]">
138
+ <div
139
+ className="relative mx-auto flex min-h-[120px] w-full max-w-[1691px] items-end justify-center sm:min-h-[200px] xl:min-h-[429px]"
140
+ style={{
141
+ WebkitMaskImage: "url(/footer/footer10/hero-mask.svg)",
142
+ maskImage: "url(/footer/footer10/hero-mask.svg)",
143
+ WebkitMaskSize: "100% auto",
144
+ maskSize: "100% auto",
145
+ WebkitMaskRepeat: "no-repeat",
146
+ maskRepeat: "no-repeat",
147
+ WebkitMaskPosition: "center bottom",
148
+ maskPosition: "center bottom",
149
+ }}
150
+ >
151
+ <SafeImage
152
+ src="/footer/footer10/hero-image.png"
153
+ alt=""
154
+ fill
155
+ className="object-cover object-center"
156
+ />
157
+ <p
158
+ className="pointer-events-none absolute inset-0 flex items-end justify-center pb-0 font-serif text-[clamp(4rem,31vw,600px)] font-light leading-none tracking-[-0.03em] text-white/20"
159
+ aria-hidden="true"
160
+ >
161
+ {brandName}
162
+ </p>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </footer>
167
+ );
168
+ }
169
+
170
+ Footer10.propTypes = footer10PropTypes;
171
+
172
+ export default Footer10;
@@ -0,0 +1,38 @@
1
+ import PropTypes from "prop-types";
2
+
3
+ const socialShape = PropTypes.shape({
4
+ label: PropTypes.string.isRequired,
5
+ href: PropTypes.string,
6
+ });
7
+
8
+ export const footer10PropTypes = {
9
+ email: PropTypes.string,
10
+ addressLines: PropTypes.arrayOf(PropTypes.string),
11
+ phone: PropTypes.string,
12
+ socialLinks: PropTypes.arrayOf(socialShape),
13
+ formData: PropTypes.shape({
14
+ name: PropTypes.string,
15
+ email: PropTypes.string,
16
+ message: PropTypes.string,
17
+ }),
18
+ onFieldChange: PropTypes.func,
19
+ onSubmit: PropTypes.func,
20
+ submitLabel: PropTypes.string,
21
+ brandName: PropTypes.string,
22
+ className: PropTypes.string,
23
+ };
24
+
25
+ export const footer10DefaultProps = {
26
+ email: "hello@verona.com",
27
+ addressLines: ["De Meente 20, 2A", "8121 EV Olst"],
28
+ phone: "+31 (0)6 51897629",
29
+ socialLinks: [
30
+ { label: "Linkdin", href: "#" },
31
+ { label: "Instagram", href: "#" },
32
+ { label: "Dribbble", href: "#" },
33
+ ],
34
+ formData: undefined,
35
+ submitLabel: "Send Message",
36
+ brandName: "Verona",
37
+ className: "",
38
+ };
@@ -0,0 +1 @@
1
+ export { Footer10, default } from "./Footer10";
@@ -0,0 +1,107 @@
1
+ "use client";
2
+
3
+ import {
4
+ footer11DefaultProps,
5
+ footer11PropTypes,
6
+ } from "./Footer11.propTypes";
7
+
8
+ function LinkColumn({ column }) {
9
+ return (
10
+ <div className="flex min-w-0 flex-col gap-[30px]">
11
+ <p className="font-serif text-lg font-semibold leading-[1.1] text-black/90">
12
+ {column.title}
13
+ </p>
14
+ <ul className="flex flex-col gap-1.5">
15
+ {column.links.map((link) => (
16
+ <li key={link.label}>
17
+ <a
18
+ href={link.href ?? "#"}
19
+ className="text-lg leading-[1.2] text-black/80 transition-colors duration-200 ease-out hover:text-[#3919b8] focus-visible:outline-2 focus-visible:outline-offset-2"
20
+ >
21
+ {link.label}
22
+ </a>
23
+ </li>
24
+ ))}
25
+ </ul>
26
+ </div>
27
+ );
28
+ }
29
+
30
+ /**
31
+ * Footer11 — CIIRC light footer with brand + link columns.
32
+ * Figma node 32:20857 at 1920px.
33
+ */
34
+ export function Footer11({
35
+ brandName = footer11DefaultProps.brandName,
36
+ tagline = footer11DefaultProps.tagline,
37
+ copyright = footer11DefaultProps.copyright,
38
+ linkColumns = footer11DefaultProps.linkColumns,
39
+ siteByLabel = footer11DefaultProps.siteByLabel,
40
+ siteByHref = footer11DefaultProps.siteByHref,
41
+ privacyHref = footer11DefaultProps.privacyHref,
42
+ termsHref = footer11DefaultProps.termsHref,
43
+ className = "",
44
+ }) {
45
+ return (
46
+ <footer
47
+ className={["relative w-full overflow-hidden bg-[#e7f0f0]", className]
48
+ .filter(Boolean)
49
+ .join(" ")}
50
+ data-footer="footer11"
51
+ >
52
+ <div className="mx-auto w-full max-w-[1920px] px-4 py-12 sm:px-6 md:px-10 lg:px-20 xl:px-[140px] xl:py-[120px]">
53
+ <div className="flex flex-col gap-12 lg:flex-row lg:items-start lg:justify-between">
54
+ <div className="flex max-w-[345px] flex-col">
55
+ <p className="text-5xl font-black leading-none text-[#3919b8] sm:text-7xl xl:text-[100px]">
56
+ {brandName}
57
+ </p>
58
+ <div className="mt-[39px] flex flex-col gap-5">
59
+ <p className="text-lg leading-[1.2] text-black/80">{tagline}</p>
60
+ <p className="font-serif text-2xl font-semibold leading-[1.1] text-black/90 sm:text-[28px]">
61
+ {copyright}
62
+ </p>
63
+ </div>
64
+ </div>
65
+
66
+ <div className="grid grid-cols-1 gap-10 sm:grid-cols-3 sm:gap-[60px]">
67
+ {linkColumns.map((column) => (
68
+ <LinkColumn key={column.title} column={column} />
69
+ ))}
70
+ </div>
71
+ </div>
72
+
73
+ <div className="mt-[72px] border-t border-[#3919b8]/30 pt-[30px]">
74
+ <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
75
+ <p className="text-lg leading-[1.2] text-black/80">
76
+ Site by{" "}
77
+ <a
78
+ href={siteByHref ?? "#"}
79
+ className="text-[#3919b8] underline transition-colors duration-200 ease-out hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2"
80
+ >
81
+ {siteByLabel}
82
+ </a>
83
+ </p>
84
+ <div className="flex flex-wrap gap-[30px] text-lg leading-[1.2] text-black/80">
85
+ <a
86
+ href={privacyHref ?? "#"}
87
+ className="transition-colors duration-200 ease-out hover:text-[#3919b8] focus-visible:outline-2 focus-visible:outline-offset-2"
88
+ >
89
+ Privacy Policy
90
+ </a>
91
+ <a
92
+ href={termsHref ?? "#"}
93
+ className="transition-colors duration-200 ease-out hover:text-[#3919b8] focus-visible:outline-2 focus-visible:outline-offset-2"
94
+ >
95
+ Terms & Conditions
96
+ </a>
97
+ </div>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </footer>
102
+ );
103
+ }
104
+
105
+ Footer11.propTypes = footer11PropTypes;
106
+
107
+ export default Footer11;
@@ -0,0 +1,64 @@
1
+ import PropTypes from "prop-types";
2
+
3
+ const linkShape = PropTypes.shape({
4
+ label: PropTypes.string.isRequired,
5
+ href: PropTypes.string,
6
+ });
7
+
8
+ const columnShape = PropTypes.shape({
9
+ title: PropTypes.string.isRequired,
10
+ links: PropTypes.arrayOf(linkShape),
11
+ });
12
+
13
+ export const footer11PropTypes = {
14
+ brandName: PropTypes.string,
15
+ tagline: PropTypes.string,
16
+ copyright: PropTypes.string,
17
+ linkColumns: PropTypes.arrayOf(columnShape),
18
+ siteByLabel: PropTypes.string,
19
+ siteByHref: PropTypes.string,
20
+ privacyHref: PropTypes.string,
21
+ termsHref: PropTypes.string,
22
+ className: PropTypes.string,
23
+ };
24
+
25
+ export const footer11DefaultProps = {
26
+ brandName: "CIIRC",
27
+ tagline: "Working together for systems change",
28
+ copyright: "© 2026 CIIRC",
29
+ linkColumns: [
30
+ {
31
+ title: "Explore",
32
+ links: [
33
+ { label: "About CIIRC", href: "#" },
34
+ { label: "How CIIRC Works", href: "#" },
35
+ { label: "Focus Areas", href: "#" },
36
+ { label: "Impact & Learning", href: "#" },
37
+ { label: "News & Insights", href: "#" },
38
+ { label: "Resources", href: "#" },
39
+ ],
40
+ },
41
+ {
42
+ title: "Network",
43
+ links: [
44
+ { label: "Partners & Members", href: "#" },
45
+ { label: "Get Involved", href: "#" },
46
+ ],
47
+ },
48
+ {
49
+ title: "Socials",
50
+ links: [
51
+ { label: "X (Twitter)", href: "#" },
52
+ { label: "LinkedIn", href: "#" },
53
+ { label: "Facebook", href: "#" },
54
+ { label: "Instagram", href: "#" },
55
+ { label: "YouTube", href: "#" },
56
+ ],
57
+ },
58
+ ],
59
+ siteByLabel: "Notionhive",
60
+ siteByHref: "#",
61
+ privacyHref: "#",
62
+ termsHref: "#",
63
+ className: "",
64
+ };
@@ -0,0 +1 @@
1
+ export { Footer11, default } from "./Footer11";
@@ -0,0 +1,122 @@
1
+ "use client";
2
+
3
+ import SafeImage from "../../atoms/SafeImage";
4
+ import {
5
+ footer12DefaultProps,
6
+ footer12PropTypes,
7
+ } from "./Footer12.propTypes";
8
+
9
+ function LinkColumn({ column }) {
10
+ return (
11
+ <div className="flex min-w-0 flex-col gap-5">
12
+ <p className="text-base leading-[26px] text-white tracking-[0.08px]">{column.title}</p>
13
+ <ul className="flex flex-col gap-3 opacity-80">
14
+ {column.links.map((link) => (
15
+ <li key={link.label}>
16
+ <a
17
+ href={link.href ?? "#"}
18
+ className="font-mono text-sm uppercase leading-[34px] tracking-[-0.14px] text-white transition-colors duration-200 ease-out hover:opacity-100 focus-visible:outline-2 focus-visible:outline-offset-2"
19
+ >
20
+ {link.label}
21
+ </a>
22
+ </li>
23
+ ))}
24
+ </ul>
25
+ </div>
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Footer12 — Connectors Program dark multi-column footer with donate CTA.
31
+ * Figma node 32:20890 at 1920px.
32
+ */
33
+ export function Footer12({
34
+ logoIconSrc = footer12DefaultProps.logoIconSrc,
35
+ brandName = footer12DefaultProps.brandName,
36
+ ctaText = footer12DefaultProps.ctaText,
37
+ donateLabel = footer12DefaultProps.donateLabel,
38
+ donateHref = footer12DefaultProps.donateHref,
39
+ onDonateClick,
40
+ linkColumns = footer12DefaultProps.linkColumns,
41
+ copyright = footer12DefaultProps.copyright,
42
+ legalLinks = footer12DefaultProps.legalLinks,
43
+ partnerLogoSrc = footer12DefaultProps.partnerLogoSrc,
44
+ partnerLogoAlt = footer12DefaultProps.partnerLogoAlt,
45
+ className = "",
46
+ }) {
47
+ return (
48
+ <footer
49
+ className={["relative w-full overflow-hidden bg-[#0d0a08]", className]
50
+ .filter(Boolean)
51
+ .join(" ")}
52
+ data-footer="footer12"
53
+ >
54
+ <div className="mx-auto flex w-full max-w-[1920px] flex-col gap-8 px-4 pt-12 sm:px-6 md:px-10 lg:gap-10 lg:px-20 lg:pt-20 xl:px-[240px]">
55
+ <div className="flex flex-col gap-6 lg:flex-row lg:items-center lg:justify-between">
56
+ <div className="flex items-center gap-1">
57
+ <SafeImage
58
+ src={logoIconSrc}
59
+ alt=""
60
+ width={44}
61
+ height={44}
62
+ className="size-9 shrink-0 sm:size-11"
63
+ />
64
+ <span className="max-w-[130px] text-lg leading-[19px] tracking-[-0.42px] text-white sm:text-[21px]">
65
+ {brandName}
66
+ </span>
67
+ </div>
68
+ <div className="flex flex-col gap-4 sm:flex-row sm:items-center">
69
+ <p className="text-base leading-[34px] tracking-[0.08px] text-white">{ctaText}</p>
70
+ <a
71
+ href={donateHref ?? "#"}
72
+ onClick={onDonateClick}
73
+ className="inline-flex items-center justify-center bg-[#2b63fc] px-6 py-4 text-center font-mono text-sm uppercase tracking-[0.16px] text-white transition-colors duration-200 ease-out hover:opacity-90 focus-visible:outline-2 focus-visible:outline-offset-2 sm:px-[34px] sm:py-[22px] sm:text-base"
74
+ >
75
+ {donateLabel}
76
+ </a>
77
+ </div>
78
+ </div>
79
+
80
+ <div className="flex flex-col gap-10">
81
+ <div className="h-px w-full bg-white/20" />
82
+ <div className="grid grid-cols-1 gap-8 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-5 lg:justify-between lg:gap-6 xl:gap-0">
83
+ {linkColumns.map((column) => (
84
+ <LinkColumn key={column.title} column={column} />
85
+ ))}
86
+ </div>
87
+ </div>
88
+
89
+ <div className="flex flex-col gap-2">
90
+ <div className="h-px w-full bg-white/10" />
91
+ <div className="flex flex-col gap-4 border-t border-white/20 py-6 sm:flex-row sm:items-center sm:justify-between">
92
+ <p className="text-sm leading-[22px] text-white">{copyright}</p>
93
+ <div className="flex flex-wrap items-center gap-6 sm:gap-12">
94
+ {legalLinks.map((link) => (
95
+ <a
96
+ key={link.label}
97
+ href={link.href ?? "#"}
98
+ className="font-mono text-sm uppercase tracking-[-0.14px] text-white transition-colors duration-200 ease-out hover:opacity-80 focus-visible:outline-2 focus-visible:outline-offset-2"
99
+ >
100
+ {link.label}
101
+ </a>
102
+ ))}
103
+ {partnerLogoSrc ? (
104
+ <SafeImage
105
+ src={partnerLogoSrc}
106
+ alt={partnerLogoAlt}
107
+ width={126}
108
+ height={32}
109
+ className="h-6 w-auto max-w-[126px] sm:h-8"
110
+ />
111
+ ) : null}
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </footer>
117
+ );
118
+ }
119
+
120
+ Footer12.propTypes = footer12PropTypes;
121
+
122
+ export default Footer12;
@@ -0,0 +1,94 @@
1
+ import PropTypes from "prop-types";
2
+
3
+ const linkShape = PropTypes.shape({
4
+ label: PropTypes.string.isRequired,
5
+ href: PropTypes.string,
6
+ });
7
+
8
+ const columnShape = PropTypes.shape({
9
+ title: PropTypes.string.isRequired,
10
+ links: PropTypes.arrayOf(linkShape),
11
+ });
12
+
13
+ const legalLinkShape = PropTypes.shape({
14
+ label: PropTypes.string.isRequired,
15
+ href: PropTypes.string,
16
+ });
17
+
18
+ export const footer12PropTypes = {
19
+ logoIconSrc: PropTypes.string,
20
+ brandName: PropTypes.string,
21
+ ctaText: PropTypes.string,
22
+ donateLabel: PropTypes.string,
23
+ donateHref: PropTypes.string,
24
+ onDonateClick: PropTypes.func,
25
+ linkColumns: PropTypes.arrayOf(columnShape),
26
+ copyright: PropTypes.string,
27
+ legalLinks: PropTypes.arrayOf(legalLinkShape),
28
+ partnerLogoSrc: PropTypes.string,
29
+ partnerLogoAlt: PropTypes.string,
30
+ className: PropTypes.string,
31
+ };
32
+
33
+ export const footer12DefaultProps = {
34
+ logoIconSrc: "/footer/footer12/logo-icon.svg",
35
+ brandName: "Connectors Program",
36
+ ctaText: "You Can Help—Contribute Today!",
37
+ donateLabel: "Donate Now",
38
+ donateHref: "#",
39
+ linkColumns: [
40
+ {
41
+ title: "About Us",
42
+ links: [
43
+ { label: "Who We Are", href: "#" },
44
+ { label: "Our Leadership", href: "#" },
45
+ { label: "Our History", href: "#" },
46
+ ],
47
+ },
48
+ {
49
+ title: "Our Work",
50
+ links: [
51
+ { label: "Thematic Areas", href: "#" },
52
+ { label: "Projects & Programs", href: "#" },
53
+ { label: "Donors and Partners", href: "#" },
54
+ ],
55
+ },
56
+ {
57
+ title: "Global Presence",
58
+ links: [
59
+ { label: "Switzerland (HQ)", href: "#" },
60
+ { label: "Bangladesh", href: "#" },
61
+ { label: "India", href: "#" },
62
+ { label: "Kenya", href: "#" },
63
+ ],
64
+ },
65
+ {
66
+ title: "Our Impact",
67
+ links: [
68
+ { label: "Reports & Publications", href: "#" },
69
+ { label: "Impact Stories", href: "#" },
70
+ { label: "Blogs & Articles | Media", href: "#" },
71
+ { label: "Photo Gallery", href: "#" },
72
+ { label: "Video Gallery", href: "#" },
73
+ ],
74
+ },
75
+ {
76
+ title: "Get Involved",
77
+ links: [
78
+ { label: "Our Culture", href: "#" },
79
+ { label: "Career", href: "#" },
80
+ { label: "EOI & Tender", href: "#" },
81
+ { label: "FAQ", href: "#" },
82
+ { label: "Contact Us", href: "#" },
83
+ ],
84
+ },
85
+ ],
86
+ copyright: "© 2026 Connectors Program",
87
+ legalLinks: [
88
+ { label: "Privacy Notice", href: "#" },
89
+ { label: "Terms of Use", href: "#" },
90
+ ],
91
+ partnerLogoSrc: "/footer/footer12/refugee-logo.png",
92
+ partnerLogoAlt: "Refugee 613",
93
+ className: "",
94
+ };
@@ -0,0 +1 @@
1
+ export { Footer12, default } from "./Footer12";